bit of work on slice settings ui

This commit is contained in:
Lars Brubaker 2016-04-21 17:24:56 -07:00
parent f1437247b0
commit edd2aa135f
3 changed files with 49 additions and 131 deletions

View file

@ -8,7 +8,6 @@ namespace MatterHackers.MatterControl
{ {
public class MHTextEditWidget : GuiWidget public class MHTextEditWidget : GuiWidget
{ {
private Stopwatch timeSinceLastTextChanged = new Stopwatch();
protected TextEditWidget actuallTextEditWidget; protected TextEditWidget actuallTextEditWidget;
protected TextWidget noContentFieldDescription = null; protected TextWidget noContentFieldDescription = null;
@ -29,9 +28,6 @@ namespace MatterHackers.MatterControl
HAnchor = HAnchor.FitToChildren; HAnchor = HAnchor.FitToChildren;
VAnchor = VAnchor.FitToChildren; VAnchor = VAnchor.FitToChildren;
actuallTextEditWidget.TextChanged += new EventHandler(internalTextEditWidget_TextChanged);
actuallTextEditWidget.InternalTextEditWidget.EditComplete += new EventHandler(InternalTextEditWidget_EditComplete);
noContentFieldDescription = new TextWidget(messageWhenEmptyAndNotSelected, textColor: RGBA_Bytes.Gray); noContentFieldDescription = new TextWidget(messageWhenEmptyAndNotSelected, textColor: RGBA_Bytes.Gray);
noContentFieldDescription.VAnchor = VAnchor.ParentBottom; noContentFieldDescription.VAnchor = VAnchor.ParentBottom;
noContentFieldDescription.AutoExpandBoundsToText = true; noContentFieldDescription.AutoExpandBoundsToText = true;
@ -54,39 +50,6 @@ namespace MatterHackers.MatterControl
} }
} }
private void InternalTextEditWidget_EditComplete(object sender, EventArgs e)
{
timeSinceLastTextChanged.Stop();
}
public void OnIdle(object state)
{
if (timeSinceLastTextChanged.IsRunning)
{
if (timeSinceLastTextChanged.Elapsed.TotalSeconds > 2)
{
if (actuallTextEditWidget.InternalTextEditWidget.TextHasChanged())
{
actuallTextEditWidget.InternalTextEditWidget.OnEditComplete(null);
}
timeSinceLastTextChanged.Stop();
}
if (!WidgetHasBeenClosed)
{
UiThread.RunOnIdle(OnIdle, 1);
}
}
}
private void internalTextEditWidget_TextChanged(object sender, EventArgs e)
{
if (!timeSinceLastTextChanged.IsRunning)
{
UiThread.RunOnIdle(OnIdle, 1);
}
timeSinceLastTextChanged.Restart();
}
public override void OnDraw(Graphics2D graphics2D) public override void OnDraw(Graphics2D graphics2D)
{ {
SetNoContentFieldDescriptionVisibility(); SetNoContentFieldDescriptionVisibility();

View file

@ -26,40 +26,35 @@ The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies, of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project. either expressed or implied, of the FreeBSD Project.
*/ */
//#define DO_IN_PLACE_EDIT
using MatterHackers.Agg; using MatterHackers.Agg;
using MatterHackers.Agg.Font;
using MatterHackers.Agg.UI; using MatterHackers.Agg.UI;
using MatterHackers.Agg.VertexSource; using MatterHackers.Agg.VertexSource;
using MatterHackers.Localizations; using MatterHackers.Localizations;
using MatterHackers.MatterControl.CustomWidgets; using MatterHackers.MatterControl.CustomWidgets;
using MatterHackers.MatterControl.DataStorage;
using MatterHackers.MatterControl.PrinterCommunication; using MatterHackers.MatterControl.PrinterCommunication;
using MatterHackers.VectorMath; using MatterHackers.VectorMath;
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using MatterHackers.MatterControl.DataStorage;
using System.Linq; using System.Linq;
namespace MatterHackers.MatterControl.SlicerConfiguration namespace MatterHackers.MatterControl.SlicerConfiguration
{ {
public class SliceSettingsWidget : GuiWidget public class SliceSettingsWidget : GuiWidget
{ {
private static List<string> settingToReloadUiWhenChanged = new List<string>() private static List<string> settingToReloadUiWhenChanged = new List<string>()
{ {
"extruder_count", "extruder_count",
"extruders_share_temperature", "extruders_share_temperature",
"has_fan", "has_fan",
"has_heated_bed", "has_heated_bed",
"has_sd_card_reader", "has_sd_card_reader",
"center_part_on_bed", "center_part_on_bed",
"has_hardware_leveling", "has_hardware_leveling",
"include_firmware_updater", "include_firmware_updater",
"print_leveling_required_to_print", "print_leveling_required_to_print",
"show_reset_connection", "show_reset_connection",
}; };
private TextImageButtonFactory buttonFactory = new TextImageButtonFactory(); private TextImageButtonFactory buttonFactory = new TextImageButtonFactory();
private SliceSettingsDetailControl sliceSettingsDetailControl; private SliceSettingsDetailControl sliceSettingsDetailControl;
@ -70,14 +65,9 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
private string activeMaterialPreset; private string activeMaterialPreset;
private string activeQualityPreset; private string activeQualityPreset;
private bool presetChanged = false; private bool presetChanged = false;
private TextWidget materialPresetLabel
{ private Button revertButton;
get; private TextImageButtonFactory textImageButtonFactory = new TextImageButtonFactory();
set;
}
Button revertButton;
private TextWidget qualityPresetLabel;
TextImageButtonFactory textImageButtonFactory = new TextImageButtonFactory();
public SliceSettingsWidget() public SliceSettingsWidget()
{ {
@ -102,7 +92,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
this.activeQualityPreset = settingsControlBar.activeQualityPreset; this.activeQualityPreset = settingsControlBar.activeQualityPreset;
pageTopToBottomLayout.AddChild(settingsControlBar); pageTopToBottomLayout.AddChild(settingsControlBar);
noConnectionMessageContainer = new AltGroupBox(new TextWidget(LocalizedString.Get("No Printer Selected"), pointSize: 18, textColor: ActiveTheme.Instance.SecondaryAccentColor)); noConnectionMessageContainer = new AltGroupBox(new TextWidget(LocalizedString.Get("No Printer Selected"), pointSize: 18, textColor: ActiveTheme.Instance.SecondaryAccentColor));
noConnectionMessageContainer.Margin = new BorderDouble(top: 10); noConnectionMessageContainer.Margin = new BorderDouble(top: 10);
noConnectionMessageContainer.BorderColor = ActiveTheme.Instance.PrimaryTextColor; noConnectionMessageContainer.BorderColor = ActiveTheme.Instance.PrimaryTextColor;
@ -320,7 +310,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
{ {
string subGroupTitle = subGroup.Name; string subGroupTitle = subGroup.Name;
int numberOfCopies = 1; int numberOfCopies = 1;
if (subGroup.Name == "Extruder X") if (subGroup.Name == "Extruder X")
{ {
numberOfCopies = ActiveSliceSettings.Instance.ExtruderCount; numberOfCopies = ActiveSliceSettings.Instance.ExtruderCount;
@ -382,15 +372,14 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
groupTabPage.AddChild(scrollOnGroupTab); groupTabPage.AddChild(scrollOnGroupTab);
groupTabs.AddTab(groupTabWidget); groupTabs.AddTab(groupTabWidget);
// Make sure we have the right scroll position when we create this view // Make sure we have the right scroll position when we create this view
// This code is not working yet. Scroll widgets get a scroll event when the tab becomes visible that is always reseting them. // This code is not working yet. Scroll widgets get a scroll event when the tab becomes visible that is always reseting them.
// So it is not usefull to enable this and in fact makes the tabs inconsistently scrolled. It is just here for reference. // 2015 04 16, LBB // So it is not usefull to enable this and in fact makes the tabs inconsistently scrolled. It is just here for reference. // 2015 04 16, LBB
if(false) if (false)
{ {
string settingsScrollPosition = "SliceSettingsWidget_{0}_{1}_ScrollPosition".FormatWith(category.Name, group.Name); string settingsScrollPosition = "SliceSettingsWidget_{0}_{1}_ScrollPosition".FormatWith(category.Name, group.Name);
UiThread.RunOnIdle(()=> UiThread.RunOnIdle(() =>
{ {
int scrollPosition = UserSettings.Instance.Fields.GetInt(settingsScrollPosition, -100000); int scrollPosition = UserSettings.Instance.Fields.GetInt(settingsScrollPosition, -100000);
if (scrollPosition != -100000) if (scrollPosition != -100000)
@ -558,10 +547,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
} }
} }
#if DO_IN_PLACE_EDIT
public static int SettingsIndexBeingEdited = 0;
#endif
private GuiWidget CreateSettingInfoUIControls(OrganizerSettingsData settingData, double minSettingNameWidth, int extruderIndex) private GuiWidget CreateSettingInfoUIControls(OrganizerSettingsData settingData, double minSettingNameWidth, int extruderIndex)
{ {
GuiWidget container = new GuiWidget(); GuiWidget container = new GuiWidget();
@ -592,8 +577,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
revertButton.VAnchor = VAnchor.ParentCenter; revertButton.VAnchor = VAnchor.ParentCenter;
revertButton.Margin = new BorderDouble(0, 0, 10, 0); revertButton.Margin = new BorderDouble(0, 0, 10, 0);
if (ActiveSliceSettings.Instance.Contains(settingData.SlicerConfigName)) if (ActiveSliceSettings.Instance.Contains(settingData.SlicerConfigName))
{ {
int intEditWidth = (int)(60 * TextWidget.GlobalPointSizeScaleRatio + .5); int intEditWidth = (int)(60 * TextWidget.GlobalPointSizeScaleRatio + .5);
@ -619,24 +602,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor; settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor;
settingName.VAnchor = Agg.UI.VAnchor.ParentCenter; settingName.VAnchor = Agg.UI.VAnchor.ParentCenter;
#if DO_IN_PLACE_EDIT
if (SettingsIndexBeingEdited != 0)
{
if (ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, SettingsIndexBeingEdited))
{
CheckBox removeFromSettingCheckBox = new CheckBox("");
removeFromSettingCheckBox.Checked = true;
removeFromSettingCheckBox.VAnchor = VAnchor.ParentCenter;
leftToRightLayout.AddChild(removeFromSettingCheckBox);
}
else
{
CheckBox addToSettingCheckBox = new CheckBox("");
addToSettingCheckBox.VAnchor = VAnchor.ParentCenter;
leftToRightLayout.AddChild(addToSettingCheckBox);
}
}
#endif
settingName.Width = minSettingNameWidth; settingName.Width = minSettingNameWidth;
leftToRightLayout.AddChild(settingName); leftToRightLayout.AddChild(settingName);
} }
@ -705,7 +670,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
if (ChangesMultipleOtherSettings) if (ChangesMultipleOtherSettings)
{ {
bool allTheSame = true; bool allTheSame = true;
string setting = ActiveSliceSettings.Instance.GetActiveValue(settingData.SetSettingsOnChange[0]); string setting = ActiveSliceSettings.Instance.GetActiveValue(settingData.SetSettingsOnChange[0]);
for (int i = 1; i < settingData.SetSettingsOnChange.Count; i++) for (int i = 1; i < settingData.SetSettingsOnChange.Count; i++)
{ {
string nextSetting = ActiveSliceSettings.Instance.GetActiveValue(settingData.SetSettingsOnChange[i]); string nextSetting = ActiveSliceSettings.Instance.GetActiveValue(settingData.SetSettingsOnChange[i]);
@ -718,7 +683,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
if (allTheSame && setting.EndsWith("mm")) if (allTheSame && setting.EndsWith("mm"))
{ {
double.TryParse(setting.Substring(0, setting.Length-2), out currentValue); double.TryParse(setting.Substring(0, setting.Length - 2), out currentValue);
doubleEditWidget.ActuallNumberEdit.Value = currentValue; doubleEditWidget.ActuallNumberEdit.Value = currentValue;
} }
else else
@ -732,7 +697,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
doubleEditWidget.ActuallNumberEdit.Value = currentValue; doubleEditWidget.ActuallNumberEdit.Value = currentValue;
} }
doubleEditWidget.ActuallNumberEdit.InternalTextEditWidget.MarkAsStartingState(); doubleEditWidget.ActuallNumberEdit.InternalTextEditWidget.MarkAsStartingState();
doubleEditWidget.ActuallNumberEdit.EnterPressed += (sender, e) => doubleEditWidget.ActuallNumberEdit.EnterPressed += (sender, e) =>
{ {
presetChanged = true; presetChanged = true;
@ -774,13 +739,13 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
double.TryParse(sliceSettingValue, out currentValue); double.TryParse(sliceSettingValue, out currentValue);
MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, allowNegatives: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++); MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, allowNegatives: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
doubleEditWidget.ToolTipText = settingData.HelpText; doubleEditWidget.ToolTipText = settingData.HelpText;
doubleEditWidget.ActuallNumberEdit.EnterPressed+= (sender, e) => doubleEditWidget.ActuallNumberEdit.EnterPressed += (sender, e) =>
{ {
presetChanged = true; presetChanged = true;
CreateSliceSettingContainer(container, settingData); CreateSliceSettingContainer(container, settingData);
SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString());
CallEventsOnSettingsChange(settingData); CallEventsOnSettingsChange(settingData);
}; };
doubleEditWidget.SelectAllOnFocus = true; doubleEditWidget.SelectAllOnFocus = true;
leftToRightLayout.AddChild(doubleEditWidget); leftToRightLayout.AddChild(doubleEditWidget);
leftToRightLayout.AddChild(getSettingInfoData(settingData)); leftToRightLayout.AddChild(getSettingInfoData(settingData));
@ -825,10 +790,10 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
int percentIndex = textEditWidget.Text.IndexOf("%"); int percentIndex = textEditWidget.Text.IndexOf("%");
if (percentIndex != -1) if (percentIndex != -1)
{ {
textEditWidget.SetSelection(0, percentIndex-1); textEditWidget.SetSelection(0, percentIndex - 1);
} }
}; };
content.AddChild(stringEdit); content.AddChild(stringEdit);
content.AddChild(getSettingInfoData(settingData)); content.AddChild(getSettingInfoData(settingData));
@ -907,7 +872,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
int mMIndex = textEditWidget.Text.IndexOf("mm"); int mMIndex = textEditWidget.Text.IndexOf("mm");
if (mMIndex != -1) if (mMIndex != -1)
{ {
textEditWidget.SetSelection(0, mMIndex-1); textEditWidget.SetSelection(0, mMIndex - 1);
} }
}; };
@ -987,7 +952,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
StyledDropDownList selectableOptions = new StyledDropDownList("None", maxHeight: 200); StyledDropDownList selectableOptions = new StyledDropDownList("None", maxHeight: 200);
selectableOptions.ToolTipText = settingData.HelpText; selectableOptions.ToolTipText = settingData.HelpText;
selectableOptions.Margin = new BorderDouble(); selectableOptions.Margin = new BorderDouble();
container.DebugShowBounds = true;
string[] listItems = settingData.ExtraSettings.Split(','); string[] listItems = settingData.ExtraSettings.Split(',');
foreach (string listItem in listItems) foreach (string listItem in listItems)
@ -1007,7 +971,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
CallEventsOnSettingsChange(settingData); CallEventsOnSettingsChange(settingData);
}; };
} }
leftToRightLayout.AddChild(selectableOptions); leftToRightLayout.AddChild(selectableOptions);
} }
break; break;
@ -1029,7 +993,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
} }
else else
{ {
SaveSetting(settingData.SlicerConfigName, "0"); SaveSetting(settingData.SlicerConfigName, "0");
// Now hide all of the settings that this control is associated with. // Now hide all of the settings that this control is associated with.
} }
@ -1037,7 +1000,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
}; };
leftToRightLayout.AddChild(checkBoxWidget); leftToRightLayout.AddChild(checkBoxWidget);
} }
break; break;
@ -1099,7 +1061,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
xEditWidget.SelectAllOnFocus = true; xEditWidget.SelectAllOnFocus = true;
xEditWidget.Margin = new BorderDouble(0, 0, 60, 0); xEditWidget.Margin = new BorderDouble(0, 0, 60, 0);
leftToRightLayout.AddChild(xEditWidget); leftToRightLayout.AddChild(xEditWidget);
} }
{ {
yEditWidget.ActuallNumberEdit.EnterPressed += (sender, e) => yEditWidget.ActuallNumberEdit.EnterPressed += (sender, e) =>
@ -1138,29 +1099,14 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
CreateSliceSettingContainer(container, settingData); CreateSliceSettingContainer(container, settingData);
container.AddChild(leftToRightLayout); container.AddChild(leftToRightLayout);
return container; return container;
} }
private void CreateSliceSettingContainer(GuiWidget container, OrganizerSettingsData settingData) private void CreateSliceSettingContainer(GuiWidget container, OrganizerSettingsData settingData)
{ {
//Initialize all widgets to be added to container //Initialize all widgets to be added to container
TextWidget qualityPresetLabel = new TextWidget(this.activeQualityPreset);
qualityPresetLabel.HAnchor = HAnchor.ParentRight;
qualityPresetLabel.VAnchor = VAnchor.ParentCenter;
qualityPresetLabel.TextColor = ActiveTheme.Instance.PrimaryTextColor;
qualityPresetLabel.Margin = new BorderDouble(10, 0, 0, 0);
qualityPresetLabel.PointSize = 8;
TextWidget materialPresetLabel = new TextWidget(this.activeMaterialPreset);
materialPresetLabel.HAnchor = HAnchor.ParentRight;
materialPresetLabel.VAnchor = VAnchor.ParentCenter;
materialPresetLabel.TextColor = ActiveTheme.Instance.PrimaryTextColor;
materialPresetLabel.Margin = new BorderDouble(10, 0, 0, 0);
materialPresetLabel.PointSize = 8;
RGBA_Bytes materialSettingBackgroundColor = new RGBA_Bytes(255, 127, 0, 108); RGBA_Bytes materialSettingBackgroundColor = new RGBA_Bytes(255, 127, 0, 108);
RGBA_Bytes userSettingBackgroundColor = new RGBA_Bytes(0, 0, 255, 108); RGBA_Bytes userSettingBackgroundColor = new RGBA_Bytes(68, 95, 220, 108);
RGBA_Bytes qualitySettingBackgroundColor = new RGBA_Bytes(255, 255, 0, 108); RGBA_Bytes qualitySettingBackgroundColor = new RGBA_Bytes(255, 255, 0, 108);
var presetLabel = container.Children<TextWidget>().FirstOrDefault(); var presetLabel = container.Children<TextWidget>().FirstOrDefault();
@ -1169,7 +1115,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
revertButton.HAnchor = HAnchor.ParentRight; revertButton.HAnchor = HAnchor.ParentRight;
revertButton.VAnchor = VAnchor.ParentCenter; revertButton.VAnchor = VAnchor.ParentCenter;
revertButton.Margin = new BorderDouble(0, 0, 10, 0); revertButton.Margin = new BorderDouble(0, 0, 10, 0);
revertButton.Click += (sender, e) => revertButton.Click += (sender, e) =>
{ {
presetChanged = false; presetChanged = false;
@ -1181,7 +1127,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
revertButton.Visible = false; revertButton.Visible = false;
presetLabel.Visible = true; presetLabel.Visible = true;
} }
if(ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, 2)) if (ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, 2))
{ {
presetChanged = false; presetChanged = false;
container.BackgroundColor = qualitySettingBackgroundColor; container.BackgroundColor = qualitySettingBackgroundColor;
@ -1196,9 +1142,8 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
{ {
if (!presetChanged) if (!presetChanged)
{ {
container.BackgroundColor = materialSettingBackgroundColor; container.BackgroundColor = materialSettingBackgroundColor;
container.AddChild(materialPresetLabel); container.AddChild(GetOverrideNameWidget(this.activeMaterialPreset));
revertButton.Visible = false; revertButton.Visible = false;
} }
else else
@ -1207,15 +1152,13 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
presetLabel.Visible = false; presetLabel.Visible = false;
revertButton.Visible = true; revertButton.Visible = true;
} }
} }
else if (ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, 2))
else if(ActiveSliceSettings.Instance.SettingExistsInLayer(settingData.SlicerConfigName, 2))
{ {
if (!presetChanged) if (!presetChanged)
{ {
container.BackgroundColor = qualitySettingBackgroundColor; container.BackgroundColor = qualitySettingBackgroundColor;
container.AddChild(qualityPresetLabel); container.AddChild(GetOverrideNameWidget(this.activeQualityPreset));
revertButton.Visible = false; revertButton.Visible = false;
} }
else else
@ -1231,6 +1174,19 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
} }
} }
private static TextWidget GetOverrideNameWidget(string presetName)
{
return new TextWidget(presetName)
{
HAnchor = HAnchor.ParentRight,
VAnchor = VAnchor.ParentBottom,
TextColor = ActiveTheme.Instance.SecondaryTextColor,
Margin = new BorderDouble(0, 0, 5, 0),
AutoExpandBoundsToText = true,
PointSize = 8,
};
}
private GuiWidget CreateQuickMenu(OrganizerSettingsData settingData, GuiWidget content, InternalTextEditWidget internalTextWidget) private GuiWidget CreateQuickMenu(OrganizerSettingsData settingData, GuiWidget content, InternalTextEditWidget internalTextWidget)
{ {
string sliceSettingValue = ActiveSliceSettings.Instance.GetActiveValue(settingData.SlicerConfigName); string sliceSettingValue = ActiveSliceSettings.Instance.GetActiveValue(settingData.SlicerConfigName);
@ -1319,7 +1275,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
SaveSetting(slicerConfigName, newValue); SaveSetting(slicerConfigName, newValue);
} }
protected void ReloadOptions(object sender, EventArgs e) protected void ReloadOptions(object sender, EventArgs e)
{ {
ApplicationController.Instance.ReloadAdvancedControlsPanel(); ApplicationController.Instance.ReloadAdvancedControlsPanel();

@ -1 +1 @@
Subproject commit 3452193e8124aa4d2b77881f579c82bc0646cea3 Subproject commit 61a5a7e92043e32f38aa4bda429a121bb2feacec