mattercontrol/SlicerConfiguration/SlicePresetsWindow/SlicePresetDetailWidget.cs
2014-10-11 15:11:26 -07:00

1046 lines
No EOL
50 KiB
C#

/*
Copyright (c) 2014, Lars Brubaker
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Text;
using MatterHackers.Agg;
using MatterHackers.Agg.UI;
using MatterHackers.VectorMath;
using MatterHackers.Agg.Image;
using MatterHackers.MatterControl.DataStorage;
using MatterHackers.MatterControl.FieldValidation;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.CustomWidgets;
namespace MatterHackers.MatterControl.SlicerConfiguration
{
public class SlicePresetDetailWidget : GuiWidget
{
TextImageButtonFactory buttonFactory = new TextImageButtonFactory();
LinkButtonFactory linkButtonFactory = new LinkButtonFactory();
SlicePresetsWindow windowController;
TextWidget presetNameError;
MHTextEditWidget presetNameInput;
Button savePresetButton;
Button duplicatePresetButton;
Button importPresetButton;
Button exportPresetButton;
int tabIndexForItem = 0;
public SlicePresetDetailWidget(SlicePresetsWindow windowController)
{
this.windowController = windowController;
this.AnchorAll();
if (this.windowController.ActivePresetLayer == null)
{
initSlicePreset();
}
linkButtonFactory.fontSize = 8;
linkButtonFactory.textColor = ActiveTheme.Instance.SecondaryAccentColor;
buttonFactory = new TextImageButtonFactory();
buttonFactory.normalTextColor = ActiveTheme.Instance.PrimaryTextColor;
buttonFactory.hoverTextColor = ActiveTheme.Instance.PrimaryTextColor;
buttonFactory.disabledTextColor = ActiveTheme.Instance.PrimaryTextColor;
buttonFactory.pressedTextColor = ActiveTheme.Instance.PrimaryTextColor;
buttonFactory.borderWidth = 0;
AddElements();
AddHandlers();
}
void AddHandlers()
{
savePresetButton.Click += new ButtonBase.ButtonEventHandler(savePresets_Click);
duplicatePresetButton.Click += new ButtonBase.ButtonEventHandler(duplicatePresets_Click);
importPresetButton.Click += new ButtonBase.ButtonEventHandler(importPresets_Click);
exportPresetButton.Click += new ButtonBase.ButtonEventHandler(exportPresets_Click);
}
void AddElements()
{
FlowLayoutWidget mainContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);
mainContainer.Padding = new BorderDouble(3);
mainContainer.AnchorAll();
mainContainer.AddChild(GetTopRow());
mainContainer.AddChild(GetMiddleRow());
mainContainer.AddChild(GetBottomRow());
this.AddChild(mainContainer);
}
FlowLayoutWidget GetTopRow()
{
FlowLayoutWidget metaContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);
metaContainer.HAnchor = HAnchor.ParentLeftRight;
metaContainer.Padding = new BorderDouble(0, 3);
FlowLayoutWidget firstRow = new FlowLayoutWidget();
firstRow.HAnchor = HAnchor.ParentLeftRight;
TextWidget labelText = new TextWidget("Edit Preset:".FormatWith(windowController.filterLabel.Localize()), pointSize: 14);
labelText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
labelText.VAnchor = VAnchor.ParentCenter;
labelText.Margin = new BorderDouble(right: 4);
presetNameInput = new MHTextEditWidget(windowController.ActivePresetLayer.settingsCollectionData.Name);
presetNameInput.HAnchor = HAnchor.ParentLeftRight;
firstRow.AddChild(labelText);
firstRow.AddChild(presetNameInput);
presetNameError = new TextWidget("This is an error message", 0, 0, 10);
presetNameError.TextColor = RGBA_Bytes.Red;
presetNameError.HAnchor = HAnchor.ParentLeftRight;
presetNameError.Margin = new BorderDouble(top: 3);
presetNameError.Visible = false;
FlowLayoutWidget secondRow = new FlowLayoutWidget();
secondRow.HAnchor = HAnchor.ParentLeftRight;
secondRow.AddChild(new GuiWidget(labelText.Width + 4,1));
secondRow.AddChild(presetNameError);
metaContainer.AddChild(firstRow);
metaContainer.AddChild(secondRow);
return metaContainer;
}
SettingsDropDownList categoryDropDownList;
SettingsDropDownList groupDropDownList;
SettingsDropDownList settingDropDownList;
FlowLayoutWidget addSettingsContainer;
PresetListControl settingsRowContainer;
FlowLayoutWidget errorMessageContainer;
FlowLayoutWidget GetMiddleRow()
{
FlowLayoutWidget container = new FlowLayoutWidget();
container.HAnchor = HAnchor.ParentLeftRight;
container.VAnchor = Agg.UI.VAnchor.ParentBottomTop;
container.BackgroundColor = ActiveTheme.Instance.SecondaryBackgroundColor;
FlowLayoutWidget topBottomContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);
topBottomContainer.AnchorAll();
FlowLayoutWidget addContainer = new FlowLayoutWidget(FlowDirection.TopToBottom);
addContainer.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor;
addContainer.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
TextWidget errorMessage = new TextWidget("Oops! Please select a setting first.", pointSize:10);
errorMessage.TextColor = ActiveTheme.Instance.SecondaryAccentColor;
errorMessageContainer = new FlowLayoutWidget();
errorMessageContainer.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
errorMessageContainer.BackgroundColor = ActiveTheme.Instance.TransparentDarkOverlay;
errorMessageContainer.Visible = false;
errorMessageContainer.Padding = new BorderDouble(3);
errorMessageContainer.AddChild(new HorizontalSpacer());
errorMessageContainer.AddChild(errorMessage);
errorMessageContainer.AddChild(new HorizontalSpacer());
addSettingsContainer = new FlowLayoutWidget();
addSettingsContainer.Padding = new BorderDouble(3);
addSettingsContainer.BackgroundColor = ActiveTheme.Instance.TransparentDarkOverlay;
addSettingsContainer.HAnchor = HAnchor.ParentLeftRight;
PopulateAddSettingRow();
addContainer.AddChild(addSettingsContainer);
addContainer.AddChild(errorMessageContainer);
settingsRowContainer = new PresetListControl();
settingsRowContainer.HAnchor = HAnchor.ParentLeftRight;
LoadSettingsRows();
topBottomContainer.AddChild(addContainer);
topBottomContainer.AddChild(settingsRowContainer);
container.AddChild(topBottomContainer);
return container;
}
FlowLayoutWidget GetBottomRow()
{
FlowLayoutWidget container = new FlowLayoutWidget();
container.HAnchor = HAnchor.ParentLeftRight;
container.Margin = new BorderDouble(top: 3);
savePresetButton = buttonFactory.Generate(LocalizedString.Get("Save"));
duplicatePresetButton = buttonFactory.Generate(LocalizedString.Get("Duplicate"));
importPresetButton = buttonFactory.Generate(LocalizedString.Get("Import"));
exportPresetButton = buttonFactory.Generate(LocalizedString.Get("Export"));
Button cancelButton = buttonFactory.Generate(LocalizedString.Get("Cancel"));
cancelButton.Click += (sender, e) =>
{
UiThread.RunOnIdle((state) =>
{
windowController.ChangeToSlicePresetList();
});
};
container.AddChild(savePresetButton);
//Only show duplicate/import/export buttons if setting has been saved.
if (windowController.ActivePresetLayer.settingsCollectionData.Id != 0)
{
container.AddChild(duplicatePresetButton);
container.AddChild(importPresetButton);
container.AddChild(exportPresetButton);
}
container.AddChild(new HorizontalSpacer());
container.AddChild(cancelButton);
return container;
}
Dictionary<string, string> settingLayoutData = new Dictionary<string,string>(); //Setting config name, setting 'full' display name (with category/group)
Dictionary<string, string> SettingNameLookup
{
get
{
if (settingLayoutData.Count == 0)
{
PopulateLayoutDictionary();
}
return settingLayoutData;
}
}
void PopulateLayoutDictionary()
{
string UserLevel = "Advanced"; //Show all settings
for (int categoryIndex = 0; categoryIndex < SliceSettingsOrganizer.Instance.UserLevels[UserLevel].CategoriesList.Count; categoryIndex++)
{
OrganizerCategory category = SliceSettingsOrganizer.Instance.UserLevels[UserLevel].CategoriesList[categoryIndex];
for (int groupIndex = 0; groupIndex < category.GroupsList.Count; groupIndex++)
{
OrganizerGroup group = category.GroupsList[groupIndex];
for (int subGroupIndex = 0; subGroupIndex < group.SubGroupsList.Count; subGroupIndex++)
{
OrganizerSubGroup subgroup = group.SubGroupsList[subGroupIndex];
for (int settingIndex = 0; settingIndex < subgroup.SettingDataList.Count; settingIndex++)
{
OrganizerSettingsData setting = subgroup.SettingDataList[settingIndex];
string settingDisplayName = "{0} > {1} > {2}".FormatWith(category.Name, group.Name, setting.PresentationName).Replace("\\n","").Replace(":","");
settingLayoutData[setting.SlicerConfigName] = settingDisplayName;
}
}
}
}
}
void PopulateAddSettingRow(int categoryDefaultIndex = -1, int groupDefaultIndex = -1,string settingDefaultConfigName = "-1")
{
errorMessageContainer.Visible = false;
categoryDropDownList = new SettingsDropDownList("- Select Category -");
categoryDropDownList.Margin = new BorderDouble(right:3);
categoryDropDownList.MinimumSize = new Vector2(categoryDropDownList.LocalBounds.Width, categoryDropDownList.LocalBounds.Height);
categoryDropDownList.VAnchor = Agg.UI.VAnchor.ParentCenter;
categoryDropDownList.Height = 24;
groupDropDownList = new SettingsDropDownList("- Select Group -");
groupDropDownList.Margin = new BorderDouble(right: 3);
groupDropDownList.MinimumSize = new Vector2(groupDropDownList.LocalBounds.Width, groupDropDownList.LocalBounds.Height);
groupDropDownList.VAnchor = Agg.UI.VAnchor.ParentCenter;
groupDropDownList.Height = 24;
settingDropDownList = new SettingsDropDownList("- Select Setting -");
settingDropDownList.Margin = new BorderDouble(right: 3);
settingDropDownList.MinimumSize = new Vector2(settingDropDownList.LocalBounds.Width, settingDropDownList.LocalBounds.Height);
settingDropDownList.VAnchor = Agg.UI.VAnchor.ParentCenter;
settingDropDownList.HAnchor = Agg.UI.HAnchor.ParentLeftRight;
settingDropDownList.AlignToRightEdge = true;
settingDropDownList.Height = 24;
string selectedCategoryValue = "{0}:-1:-1".FormatWith(categoryDefaultIndex);
string selectedGroupValue = "{0}:{1}:-1".FormatWith(categoryDefaultIndex, groupDefaultIndex);
string selectedSettingValue = "{0}:{1}:{2}".FormatWith(categoryDefaultIndex, groupDefaultIndex, settingDefaultConfigName);
string UserLevel = "Advanced"; //Show all settings
for (int categoryIndex = 0; categoryIndex < SliceSettingsOrganizer.Instance.UserLevels[UserLevel].CategoriesList.Count; categoryIndex++)
{
OrganizerCategory category = SliceSettingsOrganizer.Instance.UserLevels[UserLevel].CategoriesList[categoryIndex];
//Always add all categories
MenuItem categoryMenuItem = categoryDropDownList.AddItem(category.Name, "{0}:-1:-1".FormatWith(categoryIndex));
categoryMenuItem.Selected += new EventHandler(OnItemSelected);
for (int groupIndex = 0; groupIndex < category.GroupsList.Count; groupIndex++)
{
OrganizerGroup group = category.GroupsList[groupIndex];
string groupValue = "{0}:{1}:-1".FormatWith(categoryIndex, groupIndex);
//Add groups if within selected category or no category selected
if (categoryIndex == categoryDefaultIndex || categoryDefaultIndex == -1)
{
MenuItem groupMenuItem = groupDropDownList.AddItem(group.Name,groupValue);
groupMenuItem.Selected += new EventHandler(OnItemSelected);
}
for (int subGroupIndex = 0; subGroupIndex < group.SubGroupsList.Count; subGroupIndex++)
{
OrganizerSubGroup subgroup = group.SubGroupsList[subGroupIndex];
for (int settingIndex = 0; settingIndex < subgroup.SettingDataList.Count; settingIndex++)
{
//Add settings if within selected category and group or no category selected
if (selectedGroupValue == groupValue || (groupDefaultIndex == -1 && categoryIndex == categoryDefaultIndex) || categoryDefaultIndex == -1)
{
OrganizerSettingsData setting = subgroup.SettingDataList[settingIndex];
if (setting.DataEditType != OrganizerSettingsData.DataEditTypes.HARDWARE_PRESENT)
{
string itemValue = "{0}:{1}:{2}".FormatWith(categoryIndex, groupIndex, setting.SlicerConfigName);
string itemName = setting.PresentationName.Replace("\\n", "").Replace(":", "");
if (setting.ExtraSettings.Trim() != "" && setting.DataEditType != OrganizerSettingsData.DataEditTypes.LIST)
{
itemName = "{0} ({1})".FormatWith(itemName, setting.ExtraSettings.Replace("\\n", " "));
}
MenuItem settingMenuItem = settingDropDownList.AddItem(itemName, itemValue);
settingMenuItem.Selected += new EventHandler(OnItemSelected);
settingMenuItem.Selected += new EventHandler(OnSettingSelected);
}
}
}
}
}
}
if (categoryDefaultIndex != -1)
{
categoryDropDownList.SelectedValue = selectedCategoryValue;
}
if (groupDefaultIndex != -1)
{
groupDropDownList.SelectedValue = selectedGroupValue;
}
if (settingDefaultConfigName != "-1")
{
settingDropDownList.SelectedValue = selectedSettingValue;
}
addSettingsContainer.RemoveAllChildren();
addSettingsContainer.AddChild(categoryDropDownList);
addSettingsContainer.AddChild(groupDropDownList);
addSettingsContainer.AddChild(settingDropDownList);
//addSettingsContainer.AddChild(addButton);
}
void OnItemSelected(object sender, EventArgs e)
{
MenuItem item = (MenuItem)sender;
string[] valueArray = item.Value.Split(':');
UiThread.RunOnIdle((state) =>
{
PopulateAddSettingRow(Int32.Parse(valueArray[0]), Int32.Parse(valueArray[1]), valueArray[2]);
});
}
void LoadSettingsRows()
{
settingsRowContainer.RemoveScrollChildren();
UiThread.RunOnIdle((state) =>
{
foreach (KeyValuePair<String, DataStorage.SliceSetting> item in this.windowController.ActivePresetLayer.settingsDictionary)
{
OrganizerSettingsData settingData = SliceSettingsOrganizer.Instance.GetSettingsData(item.Key);
FlowLayoutWidget row = GetSettingsRow(settingData, item.Value.Value);
row.Padding = new BorderDouble(3, 3, 3, 6);
settingsRowContainer.AddChild(row);
HorizontalLine horizontalLine = new HorizontalLine();
horizontalLine.BackgroundColor = ActiveTheme.Instance.SecondaryTextColor;
settingsRowContainer.AddChild(horizontalLine);
}
});
}
OrganizerSettingsData addRowSettingData;
void OnSettingSelected(object sender, EventArgs e)
{
MenuItem item = (MenuItem)sender;
string[] valueArray = item.Value.Split(':');
string configName = valueArray[2];
addRowSettingData = SliceSettingsOrganizer.Instance.GetSettingsData(configName);
AddSettingToPreset();
}
void AddSettingToPreset()
{
UiThread.RunOnIdle((state) =>
{
if (addRowSettingData != null)
{
if (!this.windowController.ActivePresetLayer.settingsDictionary.ContainsKey(addRowSettingData.SlicerConfigName))
{
DataStorage.SliceSetting sliceSetting = new DataStorage.SliceSetting();
sliceSetting.Name = addRowSettingData.SlicerConfigName;
sliceSetting.Value = ActiveSliceSettings.Instance.GetActiveValue(addRowSettingData.SlicerConfigName); //populate with current
sliceSetting.SettingsCollectionId = this.windowController.ActivePresetLayer.settingsCollectionData.Id;
this.windowController.ActivePresetLayer.settingsDictionary[addRowSettingData.SlicerConfigName] = sliceSetting;
OnSettingsChanged();
HasUncommittedChanges = true;
}
addRowSettingData = null;
PopulateAddSettingRow(-1, -1, "-1");
LoadSettingsRows();
duplicatePresetButton.Visible = false;
exportPresetButton.Visible = false;
}
else
{
errorMessageContainer.Visible = true;
}
});
}
void OnSettingsChanged()
{
SettingsChanged.CallEvents(this, null);
}
private void SaveSetting(string slicerConfigName, string value)
{
SaveValue(slicerConfigName, value);
}
List<SliceSetting> SliceSettingsToRemoveOnCommit = new List<SliceSetting>();
void RemoveSetting(string configName)
{
UiThread.RunOnIdle((state) =>
{
if (this.windowController.ActivePresetLayer.settingsDictionary.ContainsKey(configName))
{
DataStorage.SliceSetting item = this.windowController.ActivePresetLayer.settingsDictionary[configName];
SliceSettingsToRemoveOnCommit.Add(item);
this.windowController.ActivePresetLayer.settingsDictionary.Remove(configName);
OnSettingsChanged();
}
LoadSettingsRows();
});
}
bool HasUncommittedChanges;
public RootedObjectEventHandler CommitStatusChanged = new RootedObjectEventHandler();
public RootedObjectEventHandler SettingsChanged = new RootedObjectEventHandler();
public void SaveValue(string keyName, string keyValue)
{
if (this.windowController.ActivePresetLayer.settingsDictionary.ContainsKey(keyName)
&& this.windowController.ActivePresetLayer.settingsDictionary[keyName].Value != keyValue)
{
this.windowController.ActivePresetLayer.settingsDictionary[keyName].Value = keyValue;
OnSettingsChanged();
HasUncommittedChanges = true;
}
else
{
DataStorage.SliceSetting sliceSetting = new DataStorage.SliceSetting();
sliceSetting.Name = keyName;
sliceSetting.Value = keyValue;
sliceSetting.SettingsCollectionId = this.windowController.ActivePresetLayer.settingsCollectionData.Id;
this.windowController.ActivePresetLayer.settingsDictionary[keyName] = sliceSetting;
OnSettingsChanged();
HasUncommittedChanges = true;
}
}
public void CommitChanges()
{
foreach (KeyValuePair<String, DataStorage.SliceSetting> item in this.windowController.ActivePresetLayer.settingsDictionary)
{
//Ensure that each setting's collection id matches current collection id (ie for new presets)
if (item.Value.SettingsCollectionId != windowController.ActivePresetLayer.settingsCollectionData.Id)
{
item.Value.SettingsCollectionId = windowController.ActivePresetLayer.settingsCollectionData.Id;
}
item.Value.Commit();
}
foreach (SliceSetting item in SliceSettingsToRemoveOnCommit)
{
item.Delete();
}
}
private FlowLayoutWidget GetSettingsRow(OrganizerSettingsData settingData, string sliceSettingValue = null)
{
FlowLayoutWidget container = new FlowLayoutWidget();
container.HAnchor = HAnchor.ParentLeftRight;
double minSettingNameWidth = 400;
if (ActiveSliceSettings.Instance.Contains(settingData.SlicerConfigName))
{
int intEditWidth = 60;
int doubleEditWidth = 60;
int vectorXYEditWidth = 60;
int multiLineEditHeight = 60;
//Get the current value as a default value
if (sliceSettingValue == null)
{
sliceSettingValue = ActiveSliceSettings.Instance.GetActiveValue(settingData.SlicerConfigName);
}
//Get the presentation name from the SettingNameLookup
TextWidget settingName = new TextWidget(SettingNameLookup[settingData.SlicerConfigName], pointSize:10);
settingName.AutoExpandBoundsToText = false;
settingName.EllipsisIfClipped = true;
settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor;
settingName.VAnchor = Agg.UI.VAnchor.ParentCenter;
settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.Height);
settingName.Width = minSettingNameWidth;
container.AddChild(settingName);
switch (settingData.DataEditType)
{
case OrganizerSettingsData.DataEditTypes.INT:
{
int currentValue = 0;
int.TryParse(sliceSettingValue, out currentValue);
MHNumberEdit intEditWidget = new MHNumberEdit(currentValue, pixelWidth: intEditWidth, tabIndex: tabIndexForItem++);
intEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
container.AddChild(intEditWidget);
container.AddChild(getSettingInfoData(settingData));
}
break;
case OrganizerSettingsData.DataEditTypes.DOUBLE:
{
double currentValue = 0;
double.TryParse(sliceSettingValue, out currentValue);
MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowNegatives: true, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
container.AddChild(doubleEditWidget);
container.AddChild(getSettingInfoData(settingData));
}
break;
case OrganizerSettingsData.DataEditTypes.POSITIVE_DOUBLE:
{
double currentValue = 0;
double.TryParse(sliceSettingValue, out currentValue);
MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
container.AddChild(doubleEditWidget);
container.AddChild(getSettingInfoData(settingData));
}
break;
case OrganizerSettingsData.DataEditTypes.OFFSET:
{
double currentValue = 0;
double.TryParse(sliceSettingValue, out currentValue);
MHNumberEdit doubleEditWidget = new MHNumberEdit(currentValue, allowDecimals: true, allowNegatives: true, pixelWidth: doubleEditWidth, tabIndex: tabIndexForItem++);
doubleEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((NumberEdit)sender).Value.ToString()); };
container.AddChild(doubleEditWidget);
container.AddChild(getSettingInfoData(settingData));
}
break;
case OrganizerSettingsData.DataEditTypes.DOUBLE_OR_PERCENT:
{
MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 60, tabIndex: tabIndexForItem++);
stringEdit.ActualTextEditWidget.EditComplete += (sender, e) =>
{
TextEditWidget textEditWidget = (TextEditWidget)sender;
string text = textEditWidget.Text;
text = text.Trim();
bool isPercent = text.Contains("%");
if (isPercent)
{
text = text.Substring(0, text.IndexOf("%"));
}
double result;
double.TryParse(text, out result);
text = result.ToString();
if (isPercent)
{
text += "%";
}
textEditWidget.Text = text;
SaveSetting(settingData.SlicerConfigName, textEditWidget.Text);
};
container.AddChild(stringEdit);
container.AddChild(getSettingInfoData(settingData));
}
break;
case OrganizerSettingsData.DataEditTypes.CHECK_BOX:
{
CheckBox checkBoxWidget = new CheckBox("");
checkBoxWidget.VAnchor = Agg.UI.VAnchor.ParentBottom;
checkBoxWidget.TextColor = ActiveTheme.Instance.PrimaryTextColor;
checkBoxWidget.Checked = (sliceSettingValue == "1");
checkBoxWidget.CheckedStateChanged += (sender, e) =>
{
if (((CheckBox)sender).Checked)
{
SaveSetting(settingData.SlicerConfigName, "1");
}
else
{
SaveSetting(settingData.SlicerConfigName, "0");
}
};
container.AddChild(checkBoxWidget);
}
break;
case OrganizerSettingsData.DataEditTypes.STRING:
{
MHTextEditWidget stringEdit = new MHTextEditWidget(sliceSettingValue, pixelWidth: 120, tabIndex: tabIndexForItem++);
stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text); };
container.AddChild(stringEdit);
}
break;
case OrganizerSettingsData.DataEditTypes.MULTI_LINE_TEXT:
{
string convertedNewLines = sliceSettingValue.Replace("\\n", "\n");
MHTextEditWidget stringEdit = new MHTextEditWidget(convertedNewLines, pointSize:10, pixelWidth: 280, pixelHeight: multiLineEditHeight, multiLine: true, tabIndex: tabIndexForItem++);
stringEdit.ActualTextEditWidget.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, ((TextEditWidget)sender).Text.Replace("\n", "\\n")); };
container.AddChild(stringEdit);
}
break;
case OrganizerSettingsData.DataEditTypes.LIST:
{
StyledDropDownList selectableOptions = new StyledDropDownList("None", Direction.Down);
selectableOptions.Margin = new BorderDouble();
string[] listItems = settingData.ExtraSettings.Split(',');
foreach (string listItem in listItems)
{
MenuItem newItem = selectableOptions.AddItem(listItem);
if (newItem.Text == sliceSettingValue)
{
selectableOptions.SelectedLabel = sliceSettingValue;
}
newItem.Selected += (sender, e) =>
{
MenuItem menuItem = ((MenuItem)sender);
SaveSetting(settingData.SlicerConfigName, menuItem.Text);
};
}
container.AddChild(selectableOptions);
}
break;
case OrganizerSettingsData.DataEditTypes.HARDWARE_PRESENT:
// this is not editable for a detail setting (quality or material)
break;
case OrganizerSettingsData.DataEditTypes.VECTOR2:
{
string[] xyValueStrings = sliceSettingValue.Split(',');
if (xyValueStrings.Length != 2)
{
xyValueStrings = new string[] { "0", "0" };
}
double currentXValue = 0;
double.TryParse(xyValueStrings[0], out currentXValue);
MHNumberEdit xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
double currentYValue = 0;
double.TryParse(xyValueStrings[1], out currentYValue);
MHNumberEdit yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
{
xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString()); };
container.AddChild(xEditWidget);
TextWidget xText = new TextWidget("x");
xText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
xText.Margin = new BorderDouble(5, 0);
container.AddChild(xText);
}
{
yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "," + yEditWidget.ActuallNumberEdit.Value.ToString()); };
container.AddChild(yEditWidget);
TextWidget yText = new TextWidget("y");
yText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
yText.Margin = new BorderDouble(5, 0);
container.AddChild(yText);
}
}
break;
case OrganizerSettingsData.DataEditTypes.OFFSET2:
{
string[] xyValueStrings = sliceSettingValue.Split('x');
if (xyValueStrings.Length != 2)
{
xyValueStrings = new string[] { "0", "0" };
}
double currentXValue = 0;
double.TryParse(xyValueStrings[0], out currentXValue);
MHNumberEdit xEditWidget = new MHNumberEdit(currentXValue, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
double currentYValue = 0;
double.TryParse(xyValueStrings[1], out currentYValue);
MHNumberEdit yEditWidget = new MHNumberEdit(currentYValue, allowDecimals: true, allowNegatives: true, pixelWidth: vectorXYEditWidth, tabIndex: tabIndexForItem++);
{
xEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString()); };
container.AddChild(xEditWidget);
TextWidget xText = new TextWidget("x");
xText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
xText.Margin = new BorderDouble(5, 0);
container.AddChild(xText);
}
{
yEditWidget.ActuallNumberEdit.EditComplete += (sender, e) => { SaveSetting(settingData.SlicerConfigName, xEditWidget.ActuallNumberEdit.Value.ToString() + "x" + yEditWidget.ActuallNumberEdit.Value.ToString()); };
container.AddChild(yEditWidget);
TextWidget yText = new TextWidget("y");
yText.TextColor = ActiveTheme.Instance.PrimaryTextColor;
yText.Margin = new BorderDouble(5, 0);
container.AddChild(yText);
}
}
break;
default:
TextWidget missingSetting = new TextWidget(String.Format("Missing the setting for '{0}'.", settingData.DataEditType.ToString()));
missingSetting.TextColor = ActiveTheme.Instance.PrimaryTextColor;
missingSetting.BackgroundColor = RGBA_Bytes.Red;
container.AddChild(missingSetting);
break;
}
}
else // the setting we think we are adding is not in the config.ini it may have been depricated
{
TextWidget settingName = new TextWidget(String.Format("Setting '{0}' not found in config.ini", settingData.SlicerConfigName));
settingName.TextColor = ActiveTheme.Instance.PrimaryTextColor;
settingName.MinimumSize = new Vector2(minSettingNameWidth, settingName.MinimumSize.y);
container.AddChild(settingName);
container.BackgroundColor = RGBA_Bytes.Red;
}
container.AddChild(new HorizontalSpacer());
Button removeLink = linkButtonFactory.Generate("remove");
removeLink.Click += (sender, e) => {
RemoveSetting(settingData.SlicerConfigName);
};
removeLink.VAnchor = Agg.UI.VAnchor.ParentCenter;
container.AddChild(removeLink);
return container;
}
private TextWidget getSettingInfoData(OrganizerSettingsData settingData)
{
string extraSettings = settingData.ExtraSettings;
extraSettings = extraSettings.Replace("\\n", "\n");
TextWidget dataTypeInfo = new TextWidget(extraSettings, pointSize: 10);
dataTypeInfo.TextColor = ActiveTheme.Instance.PrimaryTextColor;
dataTypeInfo.Margin = new BorderDouble(5, 0);
return dataTypeInfo;
}
private bool ValidatePresetsForm()
{
ValidationMethods validationMethods = new ValidationMethods();
List<FormField> formFields = new List<FormField> { };
FormField.ValidationHandler[] stringValidationHandlers = new FormField.ValidationHandler[] { validationMethods.StringIsNotEmpty };
FormField.ValidationHandler[] nameValidationHandlers = new FormField.ValidationHandler[] { validationMethods.StringIsNotEmpty, validationMethods.StringHasNoSpecialChars };
formFields.Add(new FormField(presetNameInput, presetNameError, stringValidationHandlers));
bool formIsValid = true;
foreach (FormField formField in formFields)
{
formField.FieldErrorMessageWidget.Visible = false;
bool fieldIsValid = formField.Validate();
if (!fieldIsValid)
{
formIsValid = false;
}
}
return formIsValid;
}
void initSlicePreset()
{
int noExistingPresets = ExistingPresetsCount() + 1;
Dictionary<string, DataStorage.SliceSetting> settingsDictionary = new Dictionary<string, DataStorage.SliceSetting>();
DataStorage.SliceSettingsCollection collection = new DataStorage.SliceSettingsCollection();
if (ActivePrinterProfile.Instance.ActivePrinter != null)
{
collection.Name = string.Format("{0} ({1})", windowController.filterLabel, noExistingPresets.ToString());
collection.Tag = windowController.filterTag;
collection.PrinterId = ActivePrinterProfile.Instance.ActivePrinter.Id;
}
windowController.ActivePresetLayer = new SettingsLayer(collection, settingsDictionary);
}
public int ExistingPresetsCount()
{
string query = string.Format("SELECT COUNT(*) FROM SliceSettingsCollection WHERE Tag = '{0}';", windowController.filterTag);
string result = Datastore.Instance.dbSQLite.ExecuteScalar<string>(query);
return Convert.ToInt32(result);
}
void savePresets_Click(object sender, MouseEventArgs mouseEvent)
{
UiThread.RunOnIdle((state) =>
{
if (ValidatePresetsForm())
{
saveActivePresets();
windowController.functionToCallOnSave(this, null);
windowController.ChangeToSlicePresetList();
ActiveSliceSettings.Instance.LoadAllSettings();
ApplicationController.Instance.ReloadAdvancedControlsPanel();
}
});
}
void duplicatePresets_Click(object sender, MouseEventArgs mouseEvent)
{
UiThread.RunOnIdle((state) =>
{
DataStorage.SliceSettingsCollection duplicateCollection = new SliceSettingsCollection();
duplicateCollection.Name = string.Format("{0} (copy)".FormatWith(windowController.ActivePresetLayer.settingsCollectionData.Name));
duplicateCollection.Tag = windowController.ActivePresetLayer.settingsCollectionData.Tag;
duplicateCollection.PrinterId = windowController.ActivePresetLayer.settingsCollectionData.PrinterId;
Dictionary<string, DataStorage.SliceSetting> settingsDictionary = new Dictionary<string, DataStorage.SliceSetting>();
IEnumerable<DataStorage.SliceSetting> settingsList = this.windowController.GetCollectionSettings(windowController.ActivePresetLayer.settingsCollectionData.Id);
foreach (DataStorage.SliceSetting s in settingsList)
{
settingsDictionary[s.Name] = s;
}
SettingsLayer duplicateLayer = new SettingsLayer(duplicateCollection, settingsDictionary);
windowController.ActivePresetLayer = duplicateLayer;
windowController.ChangeToSlicePresetDetail();
});
}
string configFileExtension = "slice";
void importPresets_Click(object sender, MouseEventArgs mouseEvent)
{
OpenFileDialogParams openParams = new OpenFileDialogParams("Load Slice Preset|*.slice;*.ini");
openParams.ActionButtonLabel = "Load Slice Preset";
openParams.Title = "MatterControl: Select A File";
FileDialog.OpenFileDialog(openParams, onLoadPreset);
}
void onLoadPreset(OpenFileDialogParams openParams)
{
if (openParams.FileNames != null)
{
Dictionary<string, DataStorage.SliceSetting> settingsDictionary = new Dictionary<string, DataStorage.SliceSetting>();
try
{
if (File.Exists(openParams.FileName))
{
string[] lines = System.IO.File.ReadAllLines(openParams.FileName);
foreach (string line in lines)
{
//Ignore commented lines
if (!line.StartsWith("#"))
{
string[] settingLine = line.Split('=');
string keyName = settingLine[0].Trim();
string settingDefaultValue = settingLine[1].Trim();
DataStorage.SliceSetting sliceSetting = new DataStorage.SliceSetting();
sliceSetting.Name = keyName;
sliceSetting.Value = settingDefaultValue;
sliceSetting.SettingsCollectionId = windowController.ActivePresetLayer.settingsCollectionData.Id;
settingsDictionary.Add(keyName, sliceSetting);
}
}
windowController.ActivePresetLayer.settingsDictionary = settingsDictionary;
LoadSettingsRows();
}
}
catch (Exception e)
{
// Error loading configuration
}
}
}
void exportPresets_Click(object sender, MouseEventArgs mouseEvent)
{
UiThread.RunOnIdle(SaveAs);
}
void SaveAs(object state)
{
string documentsPath = System.Environment.GetFolderPath(System.Environment.SpecialFolder.Personal);
SaveFileDialogParams saveParams = new SaveFileDialogParams("Save Slice Preset|*." + configFileExtension, documentsPath);
saveParams.FileName = presetNameInput.Text;
FileDialog.SaveFileDialog(saveParams, onSaveFileSelected);
}
void onSaveFileSelected(SaveFileDialogParams saveParams)
{
if (saveParams.FileName != null)
{
GenerateConfigFile(saveParams.FileName);
}
}
public void GenerateConfigFile(string fileName)
{
List<string> configFileAsList = new List<string>();
foreach (KeyValuePair<String, DataStorage.SliceSetting> setting in windowController.ActivePresetLayer.settingsDictionary)
{
string settingString = string.Format("{0} = {1}", setting.Value.Name, setting.Value.Value);
configFileAsList.Add(settingString);
}
string configFileAsString = string.Join("\n", configFileAsList.ToArray());
FileStream fs = new FileStream(fileName, FileMode.Create);
StreamWriter sw = new System.IO.StreamWriter(fs);
sw.Write(configFileAsString);
sw.Close();
}
void saveActivePresets()
{
windowController.ActivePresetLayer.settingsCollectionData.Name = presetNameInput.Text;
windowController.ActivePresetLayer.settingsCollectionData.Commit();
CommitChanges();
}
}
class PresetListControl : ScrollableWidget
{
FlowLayoutWidget topToBottomItemList;
public PresetListControl()
{
this.AnchorAll();
this.AutoScroll = true;
this.ScrollArea.HAnchor |= Agg.UI.HAnchor.ParentLeftRight;
topToBottomItemList = new FlowLayoutWidget(FlowDirection.TopToBottom);
topToBottomItemList.HAnchor = Agg.UI.HAnchor.Max_FitToChildren_ParentWidth;
topToBottomItemList.Margin = new BorderDouble(top: 3);
base.AddChild(topToBottomItemList);
}
public void RemoveScrollChildren()
{
topToBottomItemList.RemoveAllChildren();
}
public override void AddChild(GuiWidget child, int indexInChildrenList = -1)
{
FlowLayoutWidget itemHolder = new FlowLayoutWidget();
itemHolder.Margin = new BorderDouble(0, 0, 0, 0);
itemHolder.HAnchor = Agg.UI.HAnchor.Max_FitToChildren_ParentWidth;
itemHolder.AddChild(child);
itemHolder.VAnchor = VAnchor.FitToChildren;
topToBottomItemList.AddChild(itemHolder, indexInChildrenList);
}
}
public class SettingsDropDownList : DropDownList
{
static RGBA_Bytes whiteSemiTransparent = new RGBA_Bytes(255, 255, 255, 100);
static RGBA_Bytes whiteTransparent = new RGBA_Bytes(255, 255, 255, 0);
public SettingsDropDownList(string noSelectionString, Direction direction = Direction.Down)
: base(noSelectionString, whiteTransparent, whiteSemiTransparent, direction, maxHeight: 300)
{
//this.HAnchor = HAnchor.ParentLeftRight;
this.TextColor = ActiveTheme.Instance.PrimaryTextColor;
this.MenuItemsBorderWidth = 1;
this.MenuItemsBackgroundColor = RGBA_Bytes.White;
this.MenuItemsBorderColor = ActiveTheme.Instance.SecondaryTextColor;
this.MenuItemsPadding = new BorderDouble(10, 4, 10, 6);
this.MenuItemsBackgroundHoverColor = ActiveTheme.Instance.PrimaryAccentColor;
this.MenuItemsTextHoverColor = ActiveTheme.Instance.PrimaryTextColor;
this.BorderWidth = 1;
this.BorderColor = ActiveTheme.Instance.SecondaryTextColor;
this.HoverColor = whiteSemiTransparent;
this.BackgroundColor = new RGBA_Bytes(255, 255, 255, 0);
mainControlText.VAnchor = VAnchor.ParentCenter;
}
}
}