Extract SliceSettings popover code for reuse in validation errors
- Issue MatterHackers/MCCentral#4878
This commit is contained in:
parent
f2e8a9d4ec
commit
67e72aec57
2 changed files with 103 additions and 94 deletions
|
|
@ -48,6 +48,11 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
private Color hoverColor;
|
||||
private bool fullRowSelect;
|
||||
private GuiWidget settingsLabel;
|
||||
|
||||
private Popover popoverBubble = null;
|
||||
private static Popover activePopover = null;
|
||||
private SystemWindow systemWindow = null;
|
||||
|
||||
protected ImageWidget imageWidget;
|
||||
|
||||
public GuiWidget ActionWidget { get; set; }
|
||||
|
|
@ -56,6 +61,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
{
|
||||
using (this.LayoutLock())
|
||||
{
|
||||
this.HelpText = helpText;
|
||||
this.theme = theme;
|
||||
this.fullRowSelect = fullRowSelect;
|
||||
|
||||
|
|
@ -119,12 +125,15 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
};
|
||||
}
|
||||
|
||||
public string HelpText { get; protected set; }
|
||||
|
||||
public ArrowDirection ArrowDirection { get; set; } = ArrowDirection.Right;
|
||||
|
||||
public override void AddChild(GuiWidget childToAdd, int indexInChildrenList = -1)
|
||||
{
|
||||
if (fullRowSelect)
|
||||
{
|
||||
childToAdd.Selectable = false;
|
||||
childToAdd.Selectable = false;
|
||||
}
|
||||
|
||||
base.AddChild(childToAdd, indexInChildrenList);
|
||||
|
|
@ -136,10 +145,20 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
set => base.BackgroundColor = value;
|
||||
}
|
||||
|
||||
|
||||
public override void OnLoad(EventArgs args)
|
||||
{
|
||||
systemWindow = this.Parents<SystemWindow>().FirstOrDefault();
|
||||
base.OnLoad(args);
|
||||
}
|
||||
|
||||
public override void OnMouseEnterBounds(MouseEventArgs mouseEvent)
|
||||
{
|
||||
mouseInBounds = true;
|
||||
this.Invalidate();
|
||||
|
||||
this.ShowPopover(this);
|
||||
|
||||
base.OnMouseEnterBounds(mouseEvent);
|
||||
}
|
||||
|
||||
|
|
@ -148,7 +167,89 @@ namespace MatterHackers.MatterControl.CustomWidgets
|
|||
mouseInBounds = false;
|
||||
|
||||
this.Invalidate();
|
||||
|
||||
if (popoverBubble != null)
|
||||
{
|
||||
// Allow a moment to elapse to determine if the mouse is within the bubble or has returned to this control, close otherwise
|
||||
UiThread.RunOnIdle(() =>
|
||||
{
|
||||
// Skip close if we are FirstWidgetUnderMouse
|
||||
if (this.FirstWidgetUnderMouse)
|
||||
{
|
||||
// Often we get OnMouseLeaveBounds when the mouse is still within bounds (as child mouse events are processed)
|
||||
// If the mouse is in bounds of this widget, abort the popover close below
|
||||
return;
|
||||
}
|
||||
|
||||
// Close the popover as long as it doesn't contain the mouse
|
||||
if (!popoverBubble.ContainsFirstUnderMouseRecursive())
|
||||
{
|
||||
// Close any active popover bubble
|
||||
popoverBubble?.Close();
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
|
||||
base.OnMouseLeaveBounds(mouseEvent);
|
||||
}
|
||||
|
||||
|
||||
protected virtual void ExtendPopover(SliceSettingsPopover popover)
|
||||
{
|
||||
}
|
||||
|
||||
protected void ShowPopover(SettingsRow settingsRow)
|
||||
{
|
||||
// Only display popovers when we're the active widget, exit if we're not first under mouse
|
||||
if (systemWindow == null
|
||||
|| !this.ContainsFirstUnderMouseRecursive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int arrowOffset = (int)(settingsRow.Height / 2);
|
||||
|
||||
var popover = new SliceSettingsPopover(this.ArrowDirection, new BorderDouble(15, 10), 7, arrowOffset)
|
||||
{
|
||||
HAnchor = HAnchor.Fit,
|
||||
VAnchor = VAnchor.Fit,
|
||||
TagColor = theme.ResolveColor(AppContext.Theme.BackgroundColor, AppContext.Theme.AccentMimimalOverlay.WithAlpha(50)),
|
||||
};
|
||||
|
||||
popover.AddChild(new WrappedTextWidget(settingsRow.HelpText, pointSize: theme.DefaultFontSize - 1, textColor: AppContext.Theme.TextColor)
|
||||
{
|
||||
Width = 400 * GuiWidget.DeviceScale,
|
||||
HAnchor = HAnchor.Fit,
|
||||
});
|
||||
|
||||
bool alignLeft = (this.ArrowDirection == ArrowDirection.Right);
|
||||
|
||||
// after a certain amount of time make the popover close (just like a tool tip)
|
||||
double closeSeconds = Math.Max(1, (settingsRow.HelpText.Length / 50.0)) * 5;
|
||||
|
||||
this.ExtendPopover(popover);
|
||||
|
||||
activePopover?.Close();
|
||||
|
||||
activePopover = popover;
|
||||
|
||||
systemWindow.ShowPopover(
|
||||
new MatePoint(settingsRow)
|
||||
{
|
||||
Mate = new MateOptions(alignLeft ? MateEdge.Left : MateEdge.Right, MateEdge.Top),
|
||||
AltMate = new MateOptions(alignLeft ? MateEdge.Left : MateEdge.Right, MateEdge.Bottom),
|
||||
Offset = new RectangleDouble(12, 0, 12, 0)
|
||||
},
|
||||
new MatePoint(popover)
|
||||
{
|
||||
Mate = new MateOptions(alignLeft ? MateEdge.Right : MateEdge.Left, MateEdge.Top),
|
||||
AltMate = new MateOptions(alignLeft ? MateEdge.Left : MateEdge.Right, MateEdge.Bottom),
|
||||
//Offset = new RectangleDouble(12, 0, 12, 0)
|
||||
},
|
||||
secondsToClose: closeSeconds);
|
||||
|
||||
popoverBubble = popover;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -78,8 +78,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
|
||||
private SettingsContext settingsContext;
|
||||
|
||||
public string HelpText { get; }
|
||||
|
||||
private PrinterConfig printer;
|
||||
private SliceSettingData settingData;
|
||||
|
||||
|
|
@ -88,8 +86,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
private GuiWidget restoreArea;
|
||||
private GuiWidget restoreButton = null;
|
||||
|
||||
private Popover popoverBubble = null;
|
||||
private SystemWindow systemWindow = null;
|
||||
private ValidationWrapper validationWrapper;
|
||||
|
||||
public SliceSettingsRow(PrinterConfig printer, SettingsContext settingsContext, SliceSettingData settingData, ThemeConfig theme, bool fullRowSelect = false)
|
||||
|
|
@ -98,7 +94,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
this.printer = printer;
|
||||
this.settingData = settingData;
|
||||
this.settingsContext = settingsContext;
|
||||
this.HelpText = settingData.HelpText;
|
||||
|
||||
using (this.LayoutLock())
|
||||
{
|
||||
|
|
@ -271,54 +266,12 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
base.OnClick(mouseEvent);
|
||||
}
|
||||
|
||||
public override void OnLoad(EventArgs args)
|
||||
{
|
||||
systemWindow = this.Parents<SystemWindow>().FirstOrDefault();
|
||||
base.OnLoad(args);
|
||||
}
|
||||
|
||||
public ArrowDirection ArrowDirection { get; set; } = ArrowDirection.Right;
|
||||
|
||||
public UIField UIField { get; internal set; }
|
||||
|
||||
public override void OnMouseEnterBounds(MouseEventArgs mouseEvent)
|
||||
protected override void ExtendPopover(SliceSettingsPopover popover)
|
||||
{
|
||||
this.ShowPopover(this);
|
||||
|
||||
base.OnMouseEnterBounds(mouseEvent);
|
||||
}
|
||||
|
||||
private void ShowPopover(SliceSettingsRow settingsRow)
|
||||
{
|
||||
// Only display popovers when we're the active widget, exit if we're not first under mouse
|
||||
if (systemWindow == null
|
||||
|| !this.ContainsFirstUnderMouseRecursive())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int arrowOffset = (int)(settingsRow.Height / 2);
|
||||
|
||||
var popover = new SliceSettingsPopover(this.ArrowDirection, new BorderDouble(15, 10), 7, arrowOffset)
|
||||
{
|
||||
HAnchor = HAnchor.Fit,
|
||||
VAnchor = VAnchor.Fit,
|
||||
TagColor = theme.ResolveColor(AppContext.Theme.BackgroundColor, AppContext.Theme.AccentMimimalOverlay.WithAlpha(50)),
|
||||
};
|
||||
|
||||
popover.AddChild(new WrappedTextWidget(settingsRow.HelpText, pointSize: theme.DefaultFontSize - 1, textColor: AppContext.Theme.TextColor)
|
||||
{
|
||||
Width = 400 * GuiWidget.DeviceScale,
|
||||
HAnchor = HAnchor.Fit,
|
||||
});
|
||||
|
||||
bool alignLeft = (this.ArrowDirection == ArrowDirection.Right);
|
||||
|
||||
string mapsTo = "";
|
||||
|
||||
// after a certain amount of time make the popover close (just like a tool tip)
|
||||
double closeSeconds = Math.Max(1, (settingsRow.HelpText.Length / 50.0)) * 5;
|
||||
|
||||
if (printer.EngineMappingsMatterSlice.MappedSettings.FirstOrDefault(m => m.CanonicalSettingsName == settingData.SlicerConfigName) is AsPercentOfReferenceOrDirect percentReference)
|
||||
{
|
||||
mapsTo = " -> " + percentReference.ExportedName;
|
||||
|
|
@ -412,54 +365,9 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
|
|||
Margin = new BorderDouble(top: 10)
|
||||
});
|
||||
#endif
|
||||
activePopover?.Close();
|
||||
|
||||
activePopover = popover;
|
||||
|
||||
systemWindow.ShowPopover(
|
||||
new MatePoint(settingsRow)
|
||||
{
|
||||
Mate = new MateOptions(alignLeft ? MateEdge.Left : MateEdge.Right, MateEdge.Top),
|
||||
AltMate = new MateOptions(alignLeft ? MateEdge.Left : MateEdge.Right, MateEdge.Bottom),
|
||||
Offset = new RectangleDouble(12, 0, 12, 0)
|
||||
},
|
||||
new MatePoint(popover)
|
||||
{
|
||||
Mate = new MateOptions(alignLeft ? MateEdge.Right : MateEdge.Left, MateEdge.Top),
|
||||
AltMate = new MateOptions(alignLeft ? MateEdge.Left : MateEdge.Right, MateEdge.Bottom),
|
||||
//Offset = new RectangleDouble(12, 0, 12, 0)
|
||||
},
|
||||
secondsToClose: closeSeconds);
|
||||
|
||||
popoverBubble = popover;
|
||||
}
|
||||
|
||||
public override void OnMouseLeaveBounds(MouseEventArgs mouseEvent)
|
||||
{
|
||||
if (popoverBubble != null)
|
||||
{
|
||||
// Allow a moment to elapse to determine if the mouse is withing the bubble or has returned to this control, close otherwise
|
||||
UiThread.RunOnIdle(() =>
|
||||
{
|
||||
// Skip close if we are FirstWidgetUnderMouse
|
||||
if (this.FirstWidgetUnderMouse)
|
||||
{
|
||||
// Often we get OnMouseLeaveBounds when the mouse is still within bounds (as child mouse events are processed)
|
||||
// If the mouse is in bounds of this widget, abort the popover close below
|
||||
return;
|
||||
}
|
||||
|
||||
// Close the popover as long as it doesn't contain the mouse
|
||||
if (!popoverBubble.ContainsFirstUnderMouseRecursive())
|
||||
{
|
||||
// Close any active popover bubble
|
||||
popoverBubble?.Close();
|
||||
}
|
||||
}, 1);
|
||||
}
|
||||
|
||||
base.OnMouseLeaveBounds(mouseEvent);
|
||||
}
|
||||
|
||||
public void UpdateStyle()
|
||||
{
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue