Revise theme support

This commit is contained in:
John Lewin 2018-10-13 17:58:54 -07:00
parent 7ba684ef8d
commit ee936efb8a
57 changed files with 1562 additions and 458 deletions

View file

@ -0,0 +1,241 @@
/*
Copyright (c) 2018, Kevin Pope, John Lewin
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 MatterHackers.Agg;
using MatterHackers.Agg.Image;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI;
using MatterHackers.MatterControl.PartPreviewWindow;
namespace MatterHackers.MatterControl.ConfigurationPage
{
public class ThemeColorPanel : FlowLayoutWidget
{
private Color lastColor;
private AccentColorsWidget colorSelector;
private IColorTheme _themeProvider;
private GuiWidget previewButtonPanel;
public ThemeColorPanel(ThemeConfig activeTheme)
: base (FlowDirection.TopToBottom)
{
string currentProviderName = UserSettings.Instance.get(UserSettingsKey.ThemeName) ?? "";
if (AppContext.ThemeProviders.TryGetValue(currentProviderName, out IColorTheme currentProvider))
{
_themeProvider = currentProvider;
}
else
{
_themeProvider = AppContext.ThemeProviders.Values.First();
}
this.SelectionColor = activeTheme.GetBorderColor(80);
// Add color selector
this.AddChild(colorSelector = new AccentColorsWidget(this)
{
Margin = new BorderDouble(activeTheme.DefaultContainerPadding, 0)
});
this.AddChild(previewButtonPanel = new FlowLayoutWidget()
{
HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Fit,
BackgroundColor = this.SelectionColor,
Padding = new BorderDouble(left: colorSelector.ColorButtons.First().Border.Left)
});
this.CreateThemeModeButtons();
}
public ImageBuffer CheckMark { get; } = AggContext.StaticData.LoadIcon("426.png", 16, 16, invertImage: true);
public Color SelectionColor { get; private set; }
public IColorTheme ThemeProvider
{
get => _themeProvider;
set
{
_themeProvider = value;
var previewColor = _themeProvider.Colors.First();
colorSelector.RebuildColorButtons();
this.CreateThemeModeButtons();
this.PreviewTheme(previewColor);
}
}
private void CreateThemeModeButtons()
{
previewButtonPanel.CloseAllChildren();
var theme = AppContext.Theme;
var accentColor = theme.Colors.PrimaryAccentColor;
if (!_themeProvider.Colors.Contains(accentColor))
{
accentColor = _themeProvider.DefaultColor;
}
var activeMode = UserSettings.Instance.get(UserSettingsKey.ThemeMode);
foreach (var mode in _themeProvider.Modes)
{
var themeset = _themeProvider.GetTheme(mode, accentColor);
previewButtonPanel.AddChild(new ThemePreviewButton(themeset.Theme, this)
{
HAnchor = HAnchor.Absolute,
VAnchor = VAnchor.Absolute,
Width = 80,
Height = 65,
Mode = mode,
Margin = new BorderDouble(theme.DefaultContainerPadding, theme.DefaultContainerPadding, 0, theme.DefaultContainerPadding),
Border = 1,
IsActive = mode == activeMode,
BorderColor = theme.GetBorderColor(20),
});
}
}
public void PreviewTheme(Color sourceAccentColor)
{
foreach (var previewButton in previewButtonPanel.Children<ThemePreviewButton>())
{
previewButton.PreviewThemeColor(sourceAccentColor);
}
}
public void SetThemeColor(Color accentColor, string mode = null)
{
lastColor = accentColor;
foreach (var colorButton in colorSelector.ColorButtons)
{
colorButton.BorderColor = (colorButton.SourceColor == accentColor) ? Color.White : Color.Transparent;
}
if (mode == null)
{
mode = this.ThemeProvider.DefaultMode;
var lastMode = UserSettings.Instance.get(UserSettingsKey.ThemeMode);
if (this.ThemeProvider.Modes.Contains(lastMode))
{
mode = lastMode;
}
}
Console.WriteLine("Getting/setting theme for " + accentColor.Html);
AppContext.SetTheme(this.ThemeProvider.GetTheme(mode, accentColor));
previewButtonPanel.BackgroundColor = this.SelectionColor;
}
public class AccentColorsWidget : FlowLayoutWidget
{
private int containerHeight = (int)(20 * GuiWidget.DeviceScale);
private ThemeColorPanel themeColorPanel;
public AccentColorsWidget(ThemeColorPanel themeColorPanel)
{
this.Padding = new BorderDouble(2, 0);
this.themeColorPanel = themeColorPanel;
this.RebuildColorButtons();
}
private List<ColorButton> colorButtons = new List<ColorButton>();
public IEnumerable<ColorButton> ColorButtons => colorButtons;
public void RebuildColorButtons()
{
this.CloseAllChildren();
colorButtons.Clear();
bool firstItem = true;
foreach (var color in themeColorPanel.ThemeProvider.Colors)
{
var colorButton = CreateThemeButton(color);
colorButton.Width = containerHeight;
colorButton.BorderColor = (color == AppContext.Theme.Colors.SourceColor) ? themeColorPanel.SelectionColor : Color.Transparent;
colorButtons.Add(colorButton);
if (firstItem)
{
firstItem = false;
colorButton.Margin = colorButton.Margin.Clone(left: 0);
}
this.AddChild(colorButton);
}
}
public ColorButton CreateThemeButton(Color color)
{
var colorButton = new ColorButton(color)
{
Cursor = Cursors.Hand,
Width = containerHeight,
Height = containerHeight,
Border = 5,
};
colorButton.Click += (s, e) =>
{
themeColorPanel.SetThemeColor(colorButton.BackgroundColor);
};
colorButton.MouseEnterBounds += (s, e) =>
{
foreach(var button in this.ColorButtons)
{
button.BorderColor = (button == colorButton) ? themeColorPanel.SelectionColor : Color.Transparent;
}
themeColorPanel.PreviewTheme(colorButton.BackgroundColor);
};
return colorButton;
}
}
}
}

View file

@ -66,6 +66,8 @@ namespace MatterHackers.GCodeVisualizer
public ExtrusionColors ExtrusionColors { get; } = null;
public Color Gray { get; set; }
public GCodeRenderer(GCodeFile gCodeFileToDraw)
{
if (gCodeFileToDraw != null)
@ -133,11 +135,26 @@ namespace MatterHackers.GCodeVisualizer
double layerThickness = gCodeFileToDraw.GetLayerHeight(layerToCreate);
Color extrusionColor = ExtrusionColors.GetColorForSpeed((float)currentInstruction.FeedRate);
renderFeaturesForLayer.Add(new RenderFeatureExtrusion(previousInstruction.Position, currentInstruction.Position, currentInstruction.ExtruderIndex, currentInstruction.FeedRate, currentInstruction.EPosition - previousInstruction.EPosition, gCodeFileToDraw.GetFilamentDiameter(), layerThickness, extrusionColor));
renderFeaturesForLayer.Add(
new RenderFeatureExtrusion(
previousInstruction.Position,
currentInstruction.Position,
currentInstruction.ExtruderIndex,
currentInstruction.FeedRate,
currentInstruction.EPosition - previousInstruction.EPosition,
gCodeFileToDraw.GetFilamentDiameter(),
layerThickness,
extrusionColor,
this.Gray));
}
else
{
renderFeaturesForLayer.Add(new RenderFeatureTravel(previousInstruction.Position, currentInstruction.Position, currentInstruction.ExtruderIndex, currentInstruction.FeedRate));
renderFeaturesForLayer.Add(
new RenderFeatureTravel(
previousInstruction.Position,
currentInstruction.Position,
currentInstruction.ExtruderIndex,
currentInstruction.FeedRate));
}
}
}

View file

@ -41,11 +41,13 @@ namespace MatterHackers.GCodeVisualizer
private float extrusionVolumeMm3;
private float layerHeight;
private Color color;
private Color gray;
public RenderFeatureExtrusion(Vector3 start, Vector3 end, int extruderIndex, double travelSpeed, double totalExtrusionMm, double filamentDiameterMm, double layerHeight, Color color)
public RenderFeatureExtrusion(Vector3 start, Vector3 end, int extruderIndex, double travelSpeed, double totalExtrusionMm, double filamentDiameterMm, double layerHeight, Color color, Color gray)
: base(start, end, extruderIndex, travelSpeed)
{
this.color = color;
this.gray = gray;
double filamentRadius = filamentDiameterMm / 2;
double areaSquareMm = (filamentRadius * filamentRadius) * Math.PI;
@ -98,7 +100,7 @@ namespace MatterHackers.GCodeVisualizer
}
else if (renderInfo.CurrentRenderType.HasFlag(RenderType.GrayColors))
{
lineColor = ActiveTheme.Instance.IsDarkTheme ? Color.DarkGray : Color.Gray;
lineColor = this.gray;
}
else
{

View file

@ -29,13 +29,17 @@
private void InitializeComponent()
{
this.splitContainer1 = new System.Windows.Forms.SplitContainer();
this.debugTextWidget = new System.Windows.Forms.CheckBox();
this.tabControl1 = new System.Windows.Forms.TabControl();
this.tabPage1 = new System.Windows.Forms.TabPage();
this.aggTreeView = new System.Windows.Forms.TreeView();
this.tabPage2 = new System.Windows.Forms.TabPage();
this.sceneTreeView = new System.Windows.Forms.TreeView();
this.tabPage3 = new System.Windows.Forms.TabPage();
this.themeTreeView = new System.Windows.Forms.TreeView();
this.btnSaveTheme = new System.Windows.Forms.Button();
this.propertyGrid1 = new System.Windows.Forms.PropertyGrid();
this.debugTextWidget = new System.Windows.Forms.CheckBox();
this.btnApply = new System.Windows.Forms.Button();
((System.ComponentModel.ISupportInitialize)(this.splitContainer1)).BeginInit();
this.splitContainer1.Panel1.SuspendLayout();
this.splitContainer1.Panel2.SuspendLayout();
@ -43,6 +47,7 @@
this.tabControl1.SuspendLayout();
this.tabPage1.SuspendLayout();
this.tabPage2.SuspendLayout();
this.tabPage3.SuspendLayout();
this.SuspendLayout();
//
// splitContainer1
@ -65,10 +70,23 @@
this.splitContainer1.SplitterWidth = 3;
this.splitContainer1.TabIndex = 0;
//
// debugTextWidget
//
this.debugTextWidget.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.debugTextWidget.AutoSize = true;
this.debugTextWidget.Location = new System.Drawing.Point(489, 3);
this.debugTextWidget.Name = "debugTextWidget";
this.debugTextWidget.Size = new System.Drawing.Size(116, 17);
this.debugTextWidget.TabIndex = 2;
this.debugTextWidget.Text = "Debug TextWidget";
this.debugTextWidget.UseVisualStyleBackColor = true;
this.debugTextWidget.CheckedChanged += new System.EventHandler(this.debugTextWidget_CheckedChanged);
//
// tabControl1
//
this.tabControl1.Controls.Add(this.tabPage1);
this.tabControl1.Controls.Add(this.tabPage2);
this.tabControl1.Controls.Add(this.tabPage3);
this.tabControl1.Dock = System.Windows.Forms.DockStyle.Fill;
this.tabControl1.Location = new System.Drawing.Point(0, 0);
this.tabControl1.Name = "tabControl1";
@ -108,7 +126,7 @@
this.tabPage2.Location = new System.Drawing.Point(4, 22);
this.tabPage2.Name = "tabPage2";
this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
this.tabPage2.Size = new System.Drawing.Size(546, 606);
this.tabPage2.Size = new System.Drawing.Size(600, 606);
this.tabPage2.TabIndex = 1;
this.tabPage2.Text = "Scene";
this.tabPage2.UseVisualStyleBackColor = true;
@ -122,11 +140,45 @@
this.sceneTreeView.Location = new System.Drawing.Point(3, 3);
this.sceneTreeView.Margin = new System.Windows.Forms.Padding(2);
this.sceneTreeView.Name = "sceneTreeView";
this.sceneTreeView.Size = new System.Drawing.Size(540, 600);
this.sceneTreeView.Size = new System.Drawing.Size(594, 600);
this.sceneTreeView.TabIndex = 2;
this.sceneTreeView.DrawNode += new System.Windows.Forms.DrawTreeNodeEventHandler(this.SceneTreeView_DrawNode);
this.sceneTreeView.AfterSelect += new System.Windows.Forms.TreeViewEventHandler(this.SceneTreeView_AfterSelect);
//
// tabPage3
//
this.tabPage3.Controls.Add(this.btnApply);
this.tabPage3.Controls.Add(this.themeTreeView);
this.tabPage3.Controls.Add(this.btnSaveTheme);
this.tabPage3.Location = new System.Drawing.Point(4, 22);
this.tabPage3.Name = "tabPage3";
this.tabPage3.Padding = new System.Windows.Forms.Padding(3);
this.tabPage3.Size = new System.Drawing.Size(600, 606);
this.tabPage3.TabIndex = 2;
this.tabPage3.Text = "Theme";
this.tabPage3.UseVisualStyleBackColor = true;
//
// themeTreeView
//
this.themeTreeView.Anchor = ((System.Windows.Forms.AnchorStyles)(((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Left)
| System.Windows.Forms.AnchorStyles.Right)));
this.themeTreeView.FullRowSelect = true;
this.themeTreeView.HideSelection = false;
this.themeTreeView.Location = new System.Drawing.Point(3, 3);
this.themeTreeView.Margin = new System.Windows.Forms.Padding(2);
this.themeTreeView.Name = "themeTreeView";
this.themeTreeView.Size = new System.Drawing.Size(592, 253);
this.themeTreeView.TabIndex = 2;
//
// btnSaveTheme
//
this.btnSaveTheme.Location = new System.Drawing.Point(519, 322);
this.btnSaveTheme.Name = "btnSaveTheme";
this.btnSaveTheme.Size = new System.Drawing.Size(75, 23);
this.btnSaveTheme.TabIndex = 0;
this.btnSaveTheme.Text = "Save Theme";
this.btnSaveTheme.UseVisualStyleBackColor = true;
//
// propertyGrid1
//
this.propertyGrid1.Dock = System.Windows.Forms.DockStyle.Fill;
@ -138,17 +190,15 @@
this.propertyGrid1.TabIndex = 0;
this.propertyGrid1.PropertyValueChanged += new System.Windows.Forms.PropertyValueChangedEventHandler(this.propertyGrid1_PropertyValueChanged);
//
// debugTextWidget
// btnApply
//
this.debugTextWidget.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Right)));
this.debugTextWidget.AutoSize = true;
this.debugTextWidget.Location = new System.Drawing.Point(489, 3);
this.debugTextWidget.Name = "debugTextWidget";
this.debugTextWidget.Size = new System.Drawing.Size(116, 17);
this.debugTextWidget.TabIndex = 2;
this.debugTextWidget.Text = "Debug TextWidget";
this.debugTextWidget.UseVisualStyleBackColor = true;
this.debugTextWidget.CheckedChanged += new System.EventHandler(this.debugTextWidget_CheckedChanged);
this.btnApply.Location = new System.Drawing.Point(438, 322);
this.btnApply.Name = "btnApply";
this.btnApply.Size = new System.Drawing.Size(75, 23);
this.btnApply.TabIndex = 3;
this.btnApply.Text = "Apply";
this.btnApply.UseVisualStyleBackColor = true;
this.btnApply.Click += new System.EventHandler(this.btnApply_Click);
//
// InspectForm
//
@ -159,6 +209,7 @@
this.Margin = new System.Windows.Forms.Padding(2);
this.Name = "InspectForm";
this.Text = "InspectForm";
this.Load += new System.EventHandler(this.InspectForm_Load);
this.splitContainer1.Panel1.ResumeLayout(false);
this.splitContainer1.Panel1.PerformLayout();
this.splitContainer1.Panel2.ResumeLayout(false);
@ -167,6 +218,7 @@
this.tabControl1.ResumeLayout(false);
this.tabPage1.ResumeLayout(false);
this.tabPage2.ResumeLayout(false);
this.tabPage3.ResumeLayout(false);
this.ResumeLayout(false);
}
@ -181,5 +233,9 @@
private System.Windows.Forms.TabPage tabPage2;
private System.Windows.Forms.TreeView sceneTreeView;
private System.Windows.Forms.CheckBox debugTextWidget;
private System.Windows.Forms.TabPage tabPage3;
private System.Windows.Forms.Button btnSaveTheme;
private System.Windows.Forms.TreeView themeTreeView;
private System.Windows.Forms.Button btnApply;
}
}

View file

@ -340,7 +340,7 @@ namespace MatterHackers.MatterControl
private void systemWindow_AfterDraw(object sender, EventArgs e)
{
if (this.Inspecting
if (this.Inspecting
&& !inspectedSystemWindow.HasBeenClosed
&& tabControl1.SelectedIndex == 0)
{
@ -415,7 +415,7 @@ namespace MatterHackers.MatterControl
{
//var item = node.Tag as IObject3D;
e.Graphics.FillRectangle(
(sceneTreeView.SelectedNode == node) ? SystemBrushes.Highlight : Brushes.Transparent,
(sceneTreeView.SelectedNode == node) ? SystemBrushes.Highlight : Brushes.Transparent,
node.Bounds);
TextRenderer.DrawText(
@ -443,6 +443,7 @@ namespace MatterHackers.MatterControl
{
scene.DebugItem = null;
}
}
private void debugTextWidget_CheckedChanged(object sender, EventArgs e)
@ -464,5 +465,43 @@ namespace MatterHackers.MatterControl
base.OnKeyUp(e);
}
private void InspectForm_Load(object sender, EventArgs e1)
{
var rootNode = new TreeNode("Theme");
var themeNode = new TreeNode("Theme");
var menuThemeNode = new TreeNode("MenuTheme");
rootNode.Nodes.Add(themeNode);
rootNode.Nodes.Add(menuThemeNode);
themeTreeView.Nodes.Add(rootNode);
rootNode.Expand();
themeTreeView.AfterSelect += (s, e) =>
{
if (e.Node == rootNode)
{
propertyGrid1.SelectedObject = MatterControl.AppContext.ThemeSet;
}
else if (e.Node == themeNode)
{
propertyGrid1.SelectedObject = MatterControl.AppContext.Theme;
}
else if (e.Node == menuThemeNode)
{
propertyGrid1.SelectedObject = MatterControl.AppContext.MenuTheme;
}
};
}
private void btnApply_Click(object sender, EventArgs e)
{
ApplicationController.Instance.ReloadAll();
}
}
}

View file

@ -135,6 +135,8 @@ namespace MatterHackers.MatterControl
var linkIcon = AggContext.StaticData.LoadIcon("fa-link_16.png", 16, 16, theme.InvertIcons);
SectionWidget section = null;
foreach (var item in data.OrderBy(i => i.Name))
{
var linkButton = new IconButton(linkIcon, theme);
@ -143,21 +145,26 @@ namespace MatterHackers.MatterControl
ApplicationController.Instance.LaunchBrowser(item.Url);
});
var section = new SectionWidget(item.Title ?? item.Name, new LazyLicenseText(item.Name, theme), theme, linkButton, expanded: false)
section = new SectionWidget(item.Title ?? item.Name, new LazyLicenseText(item.Name, theme), theme, linkButton, expanded: false)
{
HAnchor = HAnchor.Stretch
};
licensePanel.AddChild(section);
}
// Apply a bottom border to the last time for balance
if (section != null)
{
section.Border = section.Border.Clone(bottom: 1);
}
var scrollable = new ScrollableWidget(autoScroll: true)
{
HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Stretch,
Margin = new BorderDouble(bottom: 10),
Border = new BorderDouble(top: 1),
BorderColor = new Color(theme.Colors.SecondaryTextColor, 50)
};
scrollable.ScrollArea.HAnchor = HAnchor.Stretch;
scrollable.AddChild(licensePanel);
contentRow.AddChild( scrollable);

View file

@ -1,4 +1,33 @@
using System;
/*
Copyright (c) 2018, Lars Brubaker, John Lewin, Greg Diaz
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 MatterHackers.Agg;
using MatterHackers.Agg.UI;
@ -111,7 +140,7 @@ namespace MatterHackers.MatterControl
additionalInfoContainer = new FlowLayoutWidget(FlowDirection.TopToBottom)
{
BackgroundColor = theme.Colors.SecondaryBackgroundColor,
BackgroundColor = theme.MinimalShade,
HAnchor = HAnchor.Stretch,
Padding = new BorderDouble(left: 6, top: 6),
Visible = false

View file

@ -71,7 +71,6 @@ namespace MatterHackers.MatterControl.ActionBar
Width = 300,
HAnchor = HAnchor.Absolute,
VAnchor = VAnchor.Fit,
BackgroundColor = theme.Colors.PrimaryBackgroundColor,
Padding = new BorderDouble(12, 0)
};

View file

@ -230,8 +230,7 @@ namespace MatterHackers.MatterControl.ActionBar
Width = 350,
HAnchor = HAnchor.Absolute,
VAnchor = VAnchor.Fit,
BackgroundColor = theme.Colors.PrimaryBackgroundColor,
Padding = new BorderDouble(12, 0)
Padding = new BorderDouble(12, 0),
};
var container = new FlowLayoutWidget(FlowDirection.TopToBottom)

View file

@ -81,6 +81,7 @@ namespace MatterHackers.MatterControl
using MatterHackers.VectorMath;
using MatterHackers.VectorMath.TrackBall;
using Newtonsoft.Json.Converters;
using Newtonsoft.Json.Serialization;
using SettingsManagement;
[JsonConverter(typeof(StringEnumConverter))]
@ -119,6 +120,102 @@ namespace MatterHackers.MatterControl
/// The root SystemWindow
/// </summary>
public static SystemWindow RootSystemWindow { get; internal set; }
public static ThemeConfig Theme => themeset.Theme;
public static ThemeConfig MenuTheme => themeset.MenuTheme;
private static ThemeSet themeset;
public static ThemeSet ThemeSet => themeset;
public static Dictionary<string, IColorTheme> ThemeProviders = new Dictionary<string, IColorTheme>()
{
{ "Classic" , new ClassicColorsTheme() },
{ "Solarized", new SolarizedTheme() },
};
public static IColorTheme GetColorProvider(string key)
{
if (ThemeProviders.TryGetValue(key, out IColorTheme themeProvider))
{
return themeProvider;
}
return ThemeProviders.Values.First();
}
static AppContext()
{
// Load theme
try
{
if (File.Exists(ProfileManager.Instance.ProfileThemeSetPath))
{
themeset = JsonConvert.DeserializeObject<ThemeSet>(File.ReadAllText(ProfileManager.Instance.ProfileThemeSetPath));
}
}
catch { }
if (themeset == null)
{
var themeProvider = ThemeProviders.Values.First();
var defaultColor = themeProvider.Colors.First();
themeset = themeProvider.GetTheme("Dark", defaultColor);
}
DefaultThumbView.ThumbColor = new Color(themeset.Theme.Colors.PrimaryTextColor, 30);
ActiveTheme.Instance = themeset.Theme.Colors;
(ActiveTheme.Instance as ThemeColors).DisabledColor = themeset.Theme.GetBorderColor(20);
}
public static void SetTheme(ThemeSet themeSet)
{
themeset = themeSet;
//var theme = ApplicationController.ThemeProvider.GetTheme(color);
File.WriteAllText(
ProfileManager.Instance.ProfileThemeSetPath,
JsonConvert.SerializeObject(
themeset,
Formatting.Indented,
new JsonSerializerSettings
{
ContractResolver = new WritablePropertiesOnlyResolver()
}));
UiThread.RunOnIdle(() =>
{
UserSettings.Instance.set(UserSettingsKey.ActiveThemeName, themeset.ThemeName);
//Set new user selected Default
ActiveTheme.Instance = themeset.Theme.Colors;
(ActiveTheme.Instance as ThemeColors).DisabledColor = themeset.Theme.GetBorderColor(20);
// Explicitly fire ReloadAll in response to user interaction
ApplicationController.Instance.ReloadAll();
});
}
private class WritablePropertiesOnlyResolver : DefaultContractResolver
{
protected override IList<JsonProperty> CreateProperties(Type type, MemberSerialization memberSerialization)
{
IList<JsonProperty> props = base.CreateProperties(type, memberSerialization);
return props.Where(p => p.Writable).ToList();
}
}
}
public class ThemeSet
{
public string ThemeName { get; set; }
public ThemeConfig Theme { get; set; }
public ThemeConfig MenuTheme { get; set; }
}
public class ApplicationController
@ -127,9 +224,9 @@ namespace MatterHackers.MatterControl
private Dictionary<Type, HashSet<IObject3DEditor>> objectEditorsByType;
public ThemeConfig Theme { get; set; }
public ThemeConfig Theme => AppContext.Theme;
public ThemeConfig MenuTheme { get; set; }
public ThemeConfig MenuTheme => AppContext.MenuTheme;
public RunningTasksConfig Tasks { get; set; } = new RunningTasksConfig();
@ -841,10 +938,9 @@ namespace MatterHackers.MatterControl
public ApplicationController()
{
// Initialize the AppContext theme object which will sync its content with Agg ActiveTheme changes
this.Theme = new ThemeConfig();
this.Thumbnails = new ThumbnailsConfig(this.Theme);
this.MenuTheme = new ThemeConfig();
this.RebuildSceneOperations(this.Theme);
HelpArticle helpArticle = null;
@ -860,13 +956,6 @@ namespace MatterHackers.MatterControl
this.HelpArticles = helpArticle ?? new HelpArticle();
ActiveTheme.ThemeChanged.RegisterEvent((s, e) =>
{
ChangeToTheme(ActiveTheme.Instance);
}, ref unregisterEvents);
this.ChangeToTheme(ActiveTheme.Instance);
Object3D.AssetsPath = Path.Combine(ApplicationDataStorage.Instance.ApplicationLibraryDataPath, "Assets");
using (var meshSteam = AggContext.StaticData.OpenStream(Path.Combine("Stls", "missing.stl")))
@ -1349,28 +1438,6 @@ namespace MatterHackers.MatterControl
}
}
private void ChangeToTheme(IThemeColors themeColors)
{
this.Theme.RebuildTheme(themeColors);
var json = JsonConvert.SerializeObject(ActiveTheme.Instance);
var clonedColors = JsonConvert.DeserializeObject<ThemeColors>(json);
clonedColors.IsDarkTheme = false;
clonedColors.Name = "MenuColors";
clonedColors.PrimaryTextColor = new Color("#222");
clonedColors.SecondaryTextColor = new Color("#666");
clonedColors.PrimaryBackgroundColor = new Color("#fff");
clonedColors.SecondaryBackgroundColor = new Color("#ddd");
clonedColors.TertiaryBackgroundColor = new Color("#ccc");
this.MenuTheme.RebuildTheme(clonedColors);
this.RebuildSceneOperations(this.Theme);
AggContext.StaticData.PurgeCache();
}
public bool RunAnyRequiredPrinterSetup(PrinterConfig printer, ThemeConfig theme)
{
if (PrintLevelingData.NeedsToBeRun(printer))
@ -1637,23 +1704,6 @@ namespace MatterHackers.MatterControl
ApplicationSettings.Instance.ReleaseClientToken();
}
internal static void LoadTheme()
{
string activeThemeName = UserSettings.Instance.get(UserSettingsKey.ActiveThemeName);
if (!string.IsNullOrEmpty(activeThemeName))
{
ActiveTheme.Instance = ActiveTheme.GetThemeColors(activeThemeName);
}
else if (!string.IsNullOrEmpty(OemSettings.Instance.ThemeColor))
{
ActiveTheme.Instance = ActiveTheme.GetThemeColors(OemSettings.Instance.ThemeColor);
}
else
{
ActiveTheme.Instance = ActiveTheme.GetThemeColors("Blue - Light");
}
}
public static ApplicationController Instance
{
get
@ -2645,18 +2695,15 @@ namespace MatterHackers.MatterControl
var systemWindow = new RootSystemWindow(width, height);
// Load theme
ApplicationController.LoadTheme();
var overlay = new GuiWidget()
{
BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor
BackgroundColor = AppContext.Theme.ActiveTabColor,
};
overlay.AnchorAll();
systemWindow.AddChild(overlay);
var mutedAccentColor = new Color(ActiveTheme.Instance.PrimaryAccentColor, 185).OverlayOn(Color.White).ToColor();
var mutedAccentColor = AppContext.Theme.SplashAccentColor;
var spinner = new LogoSpinner(overlay, rotateX: -0.05)
{
@ -2673,7 +2720,7 @@ namespace MatterHackers.MatterControl
};
overlay.AddChild(progressPanel);
progressPanel.AddChild(statusText = new TextWidget("", textColor: ActiveTheme.Instance.PrimaryTextColor)
progressPanel.AddChild(statusText = new TextWidget("", textColor: AppContext.Theme.Colors.PrimaryTextColor)
{
MinimumSize = new Vector2(200, 30),
HAnchor = HAnchor.Center,

View file

@ -487,7 +487,11 @@ namespace MatterHackers.MatterControl
new Vector4(jerkVelocity, jerkVelocity, jerkVelocity, jerkVelocity),
new Vector4(multiplier, multiplier, multiplier, multiplier),
cancellationToken, progressReporter);
this.GCodeRenderer = new GCodeRenderer(loadedGCode);
this.GCodeRenderer = new GCodeRenderer(loadedGCode)
{
Gray = AppContext.Theme.Colors.IsDarkTheme ? Color.DarkGray : Color.Gray
};
this.RenderInfo = new GCodeRenderInfo(
0,

View file

@ -41,7 +41,6 @@ namespace MatterHackers.MatterControl
using MatterHackers.MatterControl.PartPreviewWindow;
using MatterHackers.MatterControl.PrinterCommunication;
using MatterHackers.VectorMath;
using Newtonsoft.Json;
public class ThemeConfig
{
@ -72,7 +71,7 @@ namespace MatterHackers.MatterControl
/// <summary>
/// Indicates if icons should be inverted due to black source images on a dark theme
/// </summary>
public bool InvertIcons => this.Colors.IsDarkTheme;
public bool InvertIcons => this?.Colors.IsDarkTheme ?? false;
internal void ApplyPrimaryActionStyle(GuiWidget guiWidget)
{
@ -138,20 +137,18 @@ namespace MatterHackers.MatterControl
}
}
public IThemeColors Colors { get; set; } = new ThemeColors();
public ThemeColors Colors { get; set; } = new ThemeColors();
public PresetColors PresetColors { get; set; } = new PresetColors();
public Color SlightShade { get; } = new Color(0, 0, 0, 40);
public Color MinimalShade { get; } = new Color(0, 0, 0, 15);
public Color Shade { get; } = new Color(0, 0, 0, 120);
public Color DarkShade { get; } = new Color(0, 0, 0, 190);
public Color MinimalHighlight { get; } = new Color(255, 255, 255, 15);
public Color SlightShade { get; set; }
public Color MinimalShade { get; set; }
public Color Shade { get; set; }
public Color DarkShade { get; set; }
public Color ActiveTabColor { get; set; }
public Color TabBarBackground { get; set; }
public Color InactiveTabColor { get; set; }
public Color InteractionLayerOverlayColor { get; private set; }
public Color InteractionLayerOverlayColor { get; set; }
public TextWidget CreateHeading(string text)
{
@ -161,8 +158,8 @@ namespace MatterHackers.MatterControl
};
}
public Color SplitterBackground { get; private set; } = new Color(0, 0, 0, 60);
public Color TabBodyBackground { get; private set; }
public Color SplitterBackground { get; set; } = new Color(0, 0, 0, 60);
public Color TabBodyBackground { get; set; }
public Color ToolbarButtonBackground { get; set; } = Color.Transparent;
public Color ToolbarButtonHover => this.SlightShade;
public Color ToolbarButtonDown => this.MinimalShade;
@ -173,6 +170,11 @@ namespace MatterHackers.MatterControl
public ImageBuffer GeneratingThumbnailIcon { get; private set; }
public Color LightTextColor { get; set; }
public Color BorderColor { get; set; }
public Color DisabledColor { get; set; }
public Color SplashAccentColor { get; set; }
public GuiWidget CreateSearchButton()
{
return new IconButton(AggContext.StaticData.LoadIcon("icon_search_24x24.png", 16, 16, this.InvertIcons), this)
@ -184,49 +186,27 @@ namespace MatterHackers.MatterControl
public ThemeConfig()
{
this.SeparatorMargin = (this.ButtonSpacing * 2).Clone(left: this.ButtonSpacing.Right);
this.RebuildTheme();
}
public void RebuildTheme(IThemeColors colors)
public void SetDefaults()
{
this.DisabledColor = new Color(this.LightTextColor, 50);
this.SplashAccentColor = new Color(this.Colors.PrimaryAccentColor, 185).OverlayOn(Color.White).ToColor();
}
public void RebuildTheme()
{
int size = (int)(16 * GuiWidget.DeviceScale);
if (AggContext.OperatingSystem == OSType.Android)
{
restoreNormal = ColorCircle(size, new Color(200, 0, 0));
}
else
{
restoreNormal = ColorCircle(size, Color.Transparent);
}
// On Android, use red icon as no hover events, otherwise transparent and red on hover
restoreNormal = ColorCircle(size, (AggContext.OperatingSystem == OSType.Android) ? new Color(200, 0, 0) : Color.Transparent);
restoreHover = ColorCircle(size, new Color("#DB4437"));
restorePressed = ColorCircle(size, new Color(255, 0, 0));
this.Colors = colors;
this.GeneratingThumbnailIcon = AggContext.StaticData.LoadIcon("building_thumbnail_40x40.png", 40, 40, this.InvertIcons);
DefaultThumbView.ThumbColor = new Color(colors.PrimaryTextColor, 30);
this.TabBodyBackground = this.ResolveColor(
colors.TertiaryBackgroundColor,
new Color(
Color.White,
(colors.IsDarkTheme) ? 3 : 25));
this.ActiveTabColor = this.TabBodyBackground;
this.TabBarBackground = this.ActiveTabColor.AdjustLightness(0.85).ToColor();
this.ThumbnailBackground = Color.Transparent;
this.AccentMimimalOverlay = new Color(this.Colors.PrimaryAccentColor, 50);
// Active tab color with slight transparency
this.InteractionLayerOverlayColor = new Color(this.ActiveTabColor, 240);
float alpha0to1 = (colors.IsDarkTheme ? 20 : 60) / 255.0f;
this.InactiveTabColor = ResolveColor(colors.PrimaryBackgroundColor, new Color(Color.White, this.SlightShade.alpha));
this.SplitterBackground = this.ActiveTabColor.AdjustLightness(0.87).ToColor();
DefaultThumbView.ThumbColor = new Color(this.Colors.PrimaryTextColor, 30);
}
public JogControls.MoveButton CreateMoveButton(PrinterConfig printer, string label, PrinterConnection.Axis axis, double movementFeedRate, bool levelingButtons = false)
@ -316,7 +296,7 @@ namespace MatterHackers.MatterControl
public Color GetBorderColor(int alpha)
{
return new Color(this.Colors.SecondaryTextColor, alpha);
return new Color(this.BorderColor, alpha);
}
// Compute a fixed color from a source and a target alpha

View file

@ -0,0 +1,58 @@
/*
Copyright (c) 2018, Kevin Pope, John Lewin
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 MatterHackers.MatterControl;
namespace MatterHackers.Agg.UI
{
public static class ActiveTheme
{
public static RootedObjectEventHandler ThemeChanged = new RootedObjectEventHandler();
private static IThemeColors activeTheme = ThemeColors.Create(new Color(172, 25, 61) /* Classic Red */);
public static IThemeColors Instance
{
get => activeTheme;
set
{
if (value != activeTheme)
{
activeTheme = value;
OnThemeChanged();
}
}
}
private static void OnThemeChanged()
{
ThemeChanged?.CallEvents(null, null);
}
}
}

View file

@ -0,0 +1,143 @@
/*
Copyright (c) 2018, Lars Brubaker, John Lewin
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 MatterHackers.Agg;
using MatterHackers.Agg.UI;
namespace MatterHackers.MatterControl
{
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
public class ClassicColorsTheme : IColorTheme
{
public ClassicColorsTheme()
{
this.Colors = namedColors.Values.Take(namedColors.Count / 2);
this.DefaultColor = namedColors["Red - Dark"];
this.DefaultMode = "Dark";
this.Modes = new[] { "Dark", "Light" };
}
public Color DefaultColor { get; }
public string DefaultMode { get; }
public IEnumerable<Color> Colors { get; }
public IEnumerable<string> Modes { get; }
private static Dictionary<string, Color> namedColors = new Dictionary<string, Color>()
{
//Dark themes
{ "Red - Dark", new Color(172, 25, 61) },
{ "Pink - Dark", new Color(220, 79, 173) },
{ "Orange - Dark", new Color(255, 129, 25) },
{ "Green - Dark", new Color(0, 138, 23) },
{ "Blue - Dark", new Color(0, 75, 139) },
{ "Teal - Dark", new Color(0, 130, 153) },
{ "Light Blue - Dark", new Color(93, 178, 255) },
{ "Purple - Dark", new Color(70, 23, 180) },
{ "Magenta - Dark", new Color(140, 0, 149) },
{ "Grey - Dark", new Color(88, 88, 88) },
//Light themes
{ "Red - Light", new Color(172, 25, 61) },
{ "Pink - Light", new Color(220, 79, 173) },
{ "Orange - Light", new Color(255, 129, 25) },
{ "Green - Light", new Color(0, 138, 23) },
{ "Blue - Light", new Color(0, 75, 139) },
{ "Teal - Light", new Color(0, 130, 153) },
{ "Light Blue - Light", new Color(93, 178, 255) },
{ "Purple - Light", new Color(70, 23, 180) },
{ "Magenta - Light", new Color(140, 0, 149) },
{ "Grey - Light", new Color(88, 88, 88) },
};
public ThemeSet GetTheme(string mode, Color accentColor)
{
bool darkTheme = mode == "Dark";
Console.WriteLine("Requesting theme for " + accentColor.Html);
var colors = ThemeColors.Create(accentColor, darkTheme);
Console.WriteLine("Generated: PrimaryAccent: " + colors.PrimaryAccentColor + " source: " + colors.SourceColor);
return ThemeFromColors(colors, darkTheme);
}
public static ThemeSet ThemeFromColors(ThemeColors colors, bool darkTheme)
{
var json = JsonConvert.SerializeObject(colors);
var clonedColors = JsonConvert.DeserializeObject<ThemeColors>(json);
clonedColors.IsDarkTheme = false;
clonedColors.PrimaryTextColor = new Color("#222");
clonedColors.PrimaryBackgroundColor = new Color("#fff");
return new ThemeSet()
{
Theme = BuildTheme(colors, darkTheme),
MenuTheme = BuildTheme(clonedColors, darkTheme)
};
}
private static ThemeConfig BuildTheme(ThemeColors colors, bool darkTheme)
{
var theme = new ThemeConfig();
theme.Colors = colors;
theme.SlightShade = new Color(0, 0, 0, 40);
theme.MinimalShade = new Color(0, 0, 0, 15);
theme.Shade = new Color(0, 0, 0, 120);
theme.DarkShade = new Color(0, 0, 0, 190);
theme.ActiveTabColor = theme.ResolveColor(
new Color(darkTheme ? "#3E3E3E" : "#BEBEBE"),
new Color(
Color.White,
(colors.IsDarkTheme) ? 3 : 25));
theme.TabBarBackground = theme.ActiveTabColor.AdjustLightness(0.85).ToColor();
theme.ThumbnailBackground = theme.MinimalShade;
theme.AccentMimimalOverlay = new Color(theme.Colors.PrimaryAccentColor, 50);
theme.InteractionLayerOverlayColor = new Color(theme.ActiveTabColor, 240);
theme.InactiveTabColor = theme.ResolveColor(theme.ActiveTabColor, new Color(Color.White, theme.MinimalShade.alpha));
theme.SplitterBackground = theme.ActiveTabColor.AdjustLightness(0.87).ToColor();
theme.BorderColor = new Color(darkTheme ? "#C8C8C8" : "#333");
theme.SplashAccentColor = theme.Colors.PrimaryAccentColor;
theme.PresetColors = new PresetColors();
return theme;
}
}
}

View file

@ -0,0 +1,44 @@
/*
Copyright (c) 2018, John Lewin
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 MatterHackers.Agg;
namespace MatterHackers.MatterControl
{
using System.Collections.Generic;
public interface IColorTheme
{
string DefaultMode { get; }
Color DefaultColor { get; }
ThemeSet GetTheme(string mode, Color accentColor);
IEnumerable<Color> Colors { get; }
IEnumerable<string> Modes { get; }
}
}

View file

@ -0,0 +1,46 @@
/*
Copyright (c) 2016, Kevin Pope, John Lewin
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;
namespace MatterHackers.Agg.UI
{
public interface IThemeColors
{
bool IsDarkTheme { get; }
Color PrimaryBackgroundColor { get; }
Color PrimaryTextColor { get; }
Color PrimaryAccentColor { get; }
Color DisabledColor { get; }
}
}

View file

@ -0,0 +1,243 @@
/*
Copyright (c) 2018, John Lewin
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 MatterHackers.Agg;
using MatterHackers.Agg.UI;
namespace MatterHackers.MatterControl
{
using System.Collections.Generic;
using Agg.Image;
public class SolarizedTheme : IColorTheme
{
private SolarizedColors solarized = new SolarizedColors();
public SolarizedTheme()
{
this.Colors = new[]
{
solarized.Blue,
solarized.Cyan,
solarized.Green,
solarized.Magenta,
solarized.Orange,
solarized.Red,
solarized.Violet,
solarized.Yellow
};
this.DefaultColor = solarized.Yellow;
this.DefaultMode = "Dark";
this.Modes = new[] { "Dark", "Light" };
}
public Color DefaultColor { get; }
public string DefaultMode { get; }
public IEnumerable<Color> Colors { get; }
public IEnumerable<string> Modes { get; }
public ThemeSet GetTheme(string mode, Color accentColor)
{
bool darkTheme = mode == "Dark";
var baseColors = darkTheme ? solarized.Dark : solarized.Light;
return new ThemeSet()
{
Theme = new ThemeConfig()
{
Colors = new ThemeColors()
{
IsDarkTheme = darkTheme,
PrimaryBackgroundColor = new Color("#003F69"),
PrimaryTextColor = baseColors.Base0,
PrimaryAccentColor = accentColor,
SourceColor = accentColor
},
PresetColors = new PresetColors()
{
MaterialPreset = new Color("#FF7F00"),
QualityPreset = new Color("#FFFF00"),
UserOverride = new Color("#445FDC96")
},
SlightShade = new Color("#00000028"),
MinimalShade = new Color("#0000000F"),
Shade = new Color("#00000078"),
DarkShade = new Color("#000000BE"),
ActiveTabColor = baseColors.Base03,
TabBarBackground = baseColors.Base03.Blend(Color.Black, darkTheme ? 0.4 : 0.1),
//TabBarBackground = new Color(darkTheme ? "#00212B" : "#EEE8D5"),
InactiveTabColor = baseColors.Base02,
InteractionLayerOverlayColor = new Color(baseColors.Base03, 240),
SplitterBackground = baseColors.Base02,
TabBodyBackground = new Color("#00000000"),
ToolbarButtonBackground = new Color("#00000000"),
ThumbnailBackground = new Color("#00000000"),
AccentMimimalOverlay = new Color(accentColor, 80),
BorderColor = baseColors.Base0,
SplashAccentColor = new Color("#eee")
},
MenuTheme = (darkTheme) ? this.DarkMenu(baseColors, accentColor) : this.LightMenu(baseColors, accentColor)
};
}
private ThemeConfig LightMenu(BaseColors baseColors, Color accentColor)
{
var backgroundColor = new Color("#f1f1f1");
return new ThemeConfig()
{
Colors = new ThemeColors()
{
IsDarkTheme = false,
PrimaryBackgroundColor = backgroundColor,
PrimaryTextColor = new Color("#555"),
PrimaryAccentColor = accentColor,
SourceColor = accentColor
},
PresetColors = new PresetColors()
{
MaterialPreset = new Color("#FF7F00"),
QualityPreset = new Color("#FFFF00"),
UserOverride = new Color("#445FDC96")
},
SlightShade = new Color("#00000028"),
MinimalShade = new Color("#0000000F"),
Shade = new Color("#00000078"),
DarkShade = new Color("#000000BE"),
ActiveTabColor = backgroundColor,
TabBarBackground = new Color("#B1B1B1"),
InactiveTabColor = new Color("#D0D0D0"),
InteractionLayerOverlayColor = new Color("#D0D0D0F0"),
SplitterBackground = new Color("#B5B5B5"),
TabBodyBackground = new Color("#00000000"),
ToolbarButtonBackground = new Color("#00000000"),
ThumbnailBackground = new Color("#00000000"),
AccentMimimalOverlay = new Color(accentColor, 80),
BorderColor = new Color("#666666"),
};
}
private ThemeConfig DarkMenu(BaseColors baseColors, Color accentColor)
{
var backgroundColor = new Color("#2d2f31");
return new ThemeConfig()
{
Colors = new ThemeColors()
{
IsDarkTheme = true,
PrimaryBackgroundColor = backgroundColor,
PrimaryTextColor = baseColors.Base1,
PrimaryAccentColor = accentColor,
SourceColor = accentColor
},
PresetColors = new PresetColors()
{
MaterialPreset = new Color("#FF7F00"),
QualityPreset = new Color("#FFFF00"),
UserOverride = new Color("#445FDC96")
},
SlightShade = new Color("#00000028"),
MinimalShade = new Color("#0000000F"),
Shade = new Color("#00000078"),
DarkShade = new Color("#000000BE"),
ActiveTabColor = backgroundColor,
TabBarBackground = new Color("#B1B1B1"),
InactiveTabColor = new Color("#D0D0D0"),
InteractionLayerOverlayColor = new Color("#D0D0D0F0"),
SplitterBackground = new Color("#B5B5B5"),
TabBodyBackground = new Color("#00000000"),
ToolbarButtonBackground = new Color("#00000000"),
ThumbnailBackground = new Color("#00000000"),
AccentMimimalOverlay = new Color(accentColor, 80),
BorderColor = new Color("#c8c8c8"),
};
}
public Color GetAdjustedAccentColor(Color accentColor, Color backgroundColor)
{
return ThemeColors.GetAdjustedAccentColor(accentColor, backgroundColor);
}
private class SolarizedColors
{
public BaseColors Dark { get; } = new BaseColors()
{
Base03 = new Color("#002b36"),
Base02 = new Color("#073642"),
Base01 = new Color("#586e75"),
Base00 = new Color("#657b83"),
Base0 = new Color("#839496"),
Base1 = new Color("#93a1a1"),
Base2 = new Color("#eee8d5"),
Base3 = new Color("#fdf6e3")
};
public BaseColors Light { get; } = new BaseColors()
{
Base03 = new Color("#fdf6e3"),
Base02 = new Color("#eee8d5"),
Base01 = new Color("#93a1a1"),
Base00 = new Color("#839496"),
Base0 = new Color("#657b83"),
Base1 = new Color("#586e75"),
Base2 = new Color("#073642"),
Base3 = new Color("#002b36")
};
public Color Yellow { get; } = new Color("#b58900");
public Color Orange { get; } = new Color("#cb4b16");
public Color Red { get; } = new Color("#dc322f");
public Color Magenta { get; } = new Color("#d33682");
public Color Violet { get; } = new Color("#6c71c4");
public Color Blue { get; } = new Color("#268bd2");
public Color Cyan { get; } = new Color("#2aa198");
public Color Green { get; } = new Color("#859900");
}
private class BaseColors
{
public Color Base03 { get; set; }
public Color Base02 { get; set; }
public Color Base01 { get; set; }
public Color Base00 { get; set; }
public Color Base0 { get; set; }
public Color Base1 { get; set; }
public Color Base2 { get; set; }
public Color Base3 { get; set; }
}
}
}

View file

@ -0,0 +1,67 @@
/*
Copyright (c) 2016, Kevin Pope, John Lewin
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;
namespace MatterHackers.Agg.UI
{
public class ThemeColors: IThemeColors
{
public bool IsDarkTheme { get; set; }
public Color PrimaryBackgroundColor { get; set; }
public Color PrimaryTextColor { get; set; }
public Color PrimaryAccentColor { get; set; }
public Color SourceColor { get; set; }
public Color DisabledColor { get; set; }
public static ThemeColors Create(Color accentColor, bool darkTheme = true)
{
var primaryBackgroundColor = new Color(darkTheme ? "#444" : "#D0D0D0");
return new ThemeColors
{
IsDarkTheme = darkTheme,
PrimaryBackgroundColor = primaryBackgroundColor,
PrimaryTextColor = new Color(darkTheme ? "#FFFFFF" : "#222"),
PrimaryAccentColor = GetAdjustedAccentColor(accentColor, primaryBackgroundColor),
SourceColor = accentColor,
};
}
public static Color GetAdjustedAccentColor(Color accentColor, Color backgroundColor)
{
return accentColor.AdjustContrast(backgroundColor).ToColor();
}
}
}

View file

@ -27,14 +27,11 @@ of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System;
using MatterHackers.Agg;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI;
using MatterHackers.MatterControl.ConfigurationPage;
using MatterHackers.MatterControl.CustomWidgets;
using MatterHackers.MatterControl.PartPreviewWindow;
using MatterHackers.MatterControl.PrintLibrary;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl
@ -54,7 +51,7 @@ namespace MatterHackers.MatterControl
this.AnchorAll();
this.Name = "WidescreenPanel";
this.BackgroundColor = theme.Colors.PrimaryBackgroundColor;
this.BackgroundColor = theme.ActiveTabColor;
// Push TouchScreenMode into GuiWidget
GuiWidget.TouchScreenMode = UserSettings.Instance.IsTouchScreen;
@ -83,6 +80,7 @@ namespace MatterHackers.MatterControl
HAnchor = HAnchor.Absolute,
VAnchor = VAnchor.Fit,
Width = 500,
MinimumSize = new Vector2(400, 0)
};
var row = new FlowLayoutWidget()

View file

@ -75,9 +75,6 @@ namespace MatterHackers.MatterControl.ConfigurationPage
};
this.AddSettingsRow(updateMatterControl);
this.AddChild(new SettingsItem("Theme".Localize(), new GuiWidget(), theme));
this.AddChild(this.GetThemeControl());
var aboutMatterControl = new SettingsItem("About".Localize() + " MatterControl", theme);
if (IntPtr.Size == 8)
{
@ -130,70 +127,5 @@ namespace MatterHackers.MatterControl.ConfigurationPage
this.AddChild(widget);
widget.Padding = widget.Padding.Clone(right: 10);
}
private FlowLayoutWidget GetThemeControl()
{
var container = new FlowLayoutWidget(FlowDirection.TopToBottom)
{
Margin = new BorderDouble(left: 30)
};
// Determine if we should set the dark or light version of the theme
var activeThemeIndex = ActiveTheme.AvailableThemes.IndexOf(ApplicationController.Instance.Theme.Colors);
var midPoint = ActiveTheme.AvailableThemes.Count / 2;
int darkThemeIndex;
int lightThemeIndex;
bool isLightTheme = activeThemeIndex >= midPoint;
if (isLightTheme)
{
lightThemeIndex = activeThemeIndex;
darkThemeIndex = activeThemeIndex - midPoint;
}
else
{
darkThemeIndex = activeThemeIndex;
lightThemeIndex = activeThemeIndex + midPoint;
}
var darkPreview = new ThemePreviewButton(ActiveTheme.AvailableThemes[darkThemeIndex], !isLightTheme)
{
HAnchor = HAnchor.Absolute,
VAnchor = VAnchor.Absolute,
Width = 80,
Height = 65,
Margin = new BorderDouble(5, 15, 10, 10)
};
var lightPreview = new ThemePreviewButton(ActiveTheme.AvailableThemes[lightThemeIndex], isLightTheme)
{
HAnchor = HAnchor.Absolute,
VAnchor = VAnchor.Absolute,
Width = 80,
Height = 65,
Margin = new BorderDouble(5, 15, 10, 10)
};
// Add color selector
container.AddChild(new ThemeColorSelectorWidget(darkPreview, lightPreview)
{
Margin = new BorderDouble(right: 5)
});
var themePreviews = new FlowLayoutWidget()
{
HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Fit
};
themePreviews.AddChild(darkPreview);
themePreviews.AddChild(lightPreview);
container.AddChild(themePreviews);
return container;
}
}
}

View file

@ -0,0 +1,241 @@
/*
Copyright (c) 2018, Kevin Pope, John Lewin
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 MatterHackers.Agg;
using MatterHackers.Agg.Image;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI;
using MatterHackers.MatterControl.PartPreviewWindow;
namespace MatterHackers.MatterControl.ConfigurationPage
{
public class ThemeColorPanel : FlowLayoutWidget
{
private Color lastColor;
private AccentColorsWidget colorSelector;
private IColorTheme _themeProvider;
private GuiWidget previewButtonPanel;
public ThemeColorPanel(ThemeConfig activeTheme)
: base (FlowDirection.TopToBottom)
{
string currentProviderName = UserSettings.Instance.get(UserSettingsKey.ThemeName) ?? "";
if (AppContext.ThemeProviders.TryGetValue(currentProviderName, out IColorTheme currentProvider))
{
_themeProvider = currentProvider;
}
else
{
_themeProvider = AppContext.ThemeProviders.Values.First();
}
this.SelectionColor = activeTheme.GetBorderColor(80);
// Add color selector
this.AddChild(colorSelector = new AccentColorsWidget(this)
{
Margin = new BorderDouble(activeTheme.DefaultContainerPadding, 0)
});
this.AddChild(previewButtonPanel = new FlowLayoutWidget()
{
HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Fit,
BackgroundColor = this.SelectionColor,
Padding = new BorderDouble(left: colorSelector.ColorButtons.First().Border.Left)
});
this.CreateThemeModeButtons();
}
public ImageBuffer CheckMark { get; } = AggContext.StaticData.LoadIcon("426.png", 16, 16, invertImage: true);
public Color SelectionColor { get; private set; }
public IColorTheme ThemeProvider
{
get => _themeProvider;
set
{
_themeProvider = value;
var previewColor = _themeProvider.Colors.First();
colorSelector.RebuildColorButtons();
this.CreateThemeModeButtons();
this.PreviewTheme(previewColor);
}
}
private void CreateThemeModeButtons()
{
previewButtonPanel.CloseAllChildren();
var theme = AppContext.Theme;
var accentColor = theme.Colors.PrimaryAccentColor;
if (!_themeProvider.Colors.Contains(accentColor))
{
accentColor = _themeProvider.DefaultColor;
}
var activeMode = UserSettings.Instance.get(UserSettingsKey.ThemeMode);
foreach (var mode in _themeProvider.Modes)
{
var themeset = _themeProvider.GetTheme(mode, accentColor);
previewButtonPanel.AddChild(new ThemePreviewButton(themeset.Theme, this)
{
HAnchor = HAnchor.Absolute,
VAnchor = VAnchor.Absolute,
Width = 80,
Height = 65,
Mode = mode,
Margin = new BorderDouble(theme.DefaultContainerPadding, theme.DefaultContainerPadding, 0, theme.DefaultContainerPadding),
Border = 1,
IsActive = mode == activeMode,
BorderColor = theme.GetBorderColor(20),
});
}
}
public void PreviewTheme(Color sourceAccentColor)
{
foreach (var previewButton in previewButtonPanel.Children<ThemePreviewButton>())
{
previewButton.PreviewThemeColor(sourceAccentColor);
}
}
public void SetThemeColor(Color accentColor, string mode = null)
{
lastColor = accentColor;
foreach (var colorButton in colorSelector.ColorButtons)
{
colorButton.BorderColor = (colorButton.SourceColor == accentColor) ? Color.White : Color.Transparent;
}
if (mode == null)
{
mode = this.ThemeProvider.DefaultMode;
var lastMode = UserSettings.Instance.get(UserSettingsKey.ThemeMode);
if (this.ThemeProvider.Modes.Contains(lastMode))
{
mode = lastMode;
}
}
Console.WriteLine("Getting/setting theme for " + accentColor.Html);
AppContext.SetTheme(this.ThemeProvider.GetTheme(mode, accentColor));
previewButtonPanel.BackgroundColor = this.SelectionColor;
}
public class AccentColorsWidget : FlowLayoutWidget
{
private int containerHeight = (int)(20 * GuiWidget.DeviceScale);
private ThemeColorPanel themeColorPanel;
public AccentColorsWidget(ThemeColorPanel themeColorPanel)
{
this.Padding = new BorderDouble(2, 0);
this.themeColorPanel = themeColorPanel;
this.RebuildColorButtons();
}
private List<ColorButton> colorButtons = new List<ColorButton>();
public IEnumerable<ColorButton> ColorButtons => colorButtons;
public void RebuildColorButtons()
{
this.CloseAllChildren();
colorButtons.Clear();
bool firstItem = true;
foreach (var color in themeColorPanel.ThemeProvider.Colors)
{
var colorButton = CreateThemeButton(color);
colorButton.Width = containerHeight;
colorButton.BorderColor = (color == AppContext.Theme.Colors.SourceColor) ? themeColorPanel.SelectionColor : Color.Transparent;
colorButtons.Add(colorButton);
if (firstItem)
{
firstItem = false;
colorButton.Margin = colorButton.Margin.Clone(left: 0);
}
this.AddChild(colorButton);
}
}
public ColorButton CreateThemeButton(Color color)
{
var colorButton = new ColorButton(color)
{
Cursor = Cursors.Hand,
Width = containerHeight,
Height = containerHeight,
Border = 5,
};
colorButton.Click += (s, e) =>
{
themeColorPanel.SetThemeColor(colorButton.BackgroundColor);
};
colorButton.MouseEnterBounds += (s, e) =>
{
foreach(var button in this.ColorButtons)
{
button.BorderColor = (button == colorButton) ? themeColorPanel.SelectionColor : Color.Transparent;
}
themeColorPanel.PreviewTheme(colorButton.BackgroundColor);
};
return colorButton;
}
}
}
}

View file

@ -1,5 +1,5 @@
/*
Copyright (c) 2017, John Lewin
Copyright (c) 2018, John Lewin
All rights reserved.
Redistribution and use in source and binary forms, with or without
@ -28,8 +28,6 @@ either expressed or implied, of the FreeBSD Project.
*/
using MatterHackers.Agg;
using MatterHackers.Agg.ImageProcessing;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI;
using MatterHackers.VectorMath;
@ -38,17 +36,24 @@ namespace MatterHackers.MatterControl.ConfigurationPage
public class ThemePreviewButton : GuiWidget
{
private GuiWidget accentColor;
private Color activeColor;
private GuiWidget secondaryBackground;
private GuiWidget tertiaryBackground;
private GuiWidget icon1;
private GuiWidget icon2;
private GuiWidget icon3;
private string themeName = "";
private ThemeConfig theme;
private ImageWidget activeIcon;
public ThemePreviewButton(IThemeColors theme, bool isActive)
public ThemePreviewButton(ThemeConfig theme, ThemeColorPanel themeColorPanel)
{
this.theme = theme;
activeColor = theme.Colors.SourceColor;
var primaryAccentColor = theme.Colors.PrimaryAccentColor;
this.Padding = 8;
this.BackgroundColor = theme.PrimaryBackgroundColor;
this.BackgroundColor = theme.ActiveTabColor;
this.Cursor = Cursors.Hand;
secondaryBackground = new GuiWidget()
@ -57,7 +62,7 @@ namespace MatterHackers.MatterControl.ConfigurationPage
VAnchor = VAnchor.Stretch,
Margin = new BorderDouble(0),
Width = 20,
BackgroundColor = theme.SecondaryBackgroundColor,
BackgroundColor = theme.MinimalShade,
};
this.AddChild(secondaryBackground);
@ -67,7 +72,7 @@ namespace MatterHackers.MatterControl.ConfigurationPage
VAnchor = VAnchor.Absolute | VAnchor.Top,
Height = 6,
Margin = new BorderDouble(left: 25),
BackgroundColor = theme.PrimaryAccentColor,
BackgroundColor = primaryAccentColor,
};
this.AddChild(accentColor);
@ -78,7 +83,7 @@ namespace MatterHackers.MatterControl.ConfigurationPage
Height = 8,
Width = 8,
Margin = new BorderDouble(left: 6, top: 6),
BackgroundColor = theme.PrimaryAccentColor,
BackgroundColor = primaryAccentColor,
};
this.AddChild(icon1);
@ -89,7 +94,7 @@ namespace MatterHackers.MatterControl.ConfigurationPage
Height = 8,
Width = 8,
Margin = new BorderDouble(left: 6, top: 20),
BackgroundColor = theme.PrimaryAccentColor,
BackgroundColor = primaryAccentColor,
};
this.AddChild(icon2);
@ -100,7 +105,7 @@ namespace MatterHackers.MatterControl.ConfigurationPage
Height = 8,
Width = 8,
Margin = new BorderDouble(left: 6, top: 34),
BackgroundColor = theme.PrimaryAccentColor,
BackgroundColor = primaryAccentColor,
};
this.AddChild(icon3);
@ -110,49 +115,53 @@ namespace MatterHackers.MatterControl.ConfigurationPage
VAnchor = VAnchor.Absolute | VAnchor.Top,
Height = 37,
Margin = new BorderDouble(left: 25, top: 12),
BackgroundColor = theme.TertiaryBackgroundColor,
BackgroundColor = theme.SlightShade,
};
this.AddChild(tertiaryBackground);
if (isActive)
this.AddChild(activeIcon = new ImageWidget(themeColorPanel.CheckMark)
{
this.AddChild(new ImageWidget(AggContext.StaticData.LoadIcon("426.png", 16, 16, invertImage: true))
{
HAnchor = HAnchor.Absolute,
VAnchor = VAnchor.Absolute,
OriginRelativeParent = new Vector2(45, 20)
});
}
HAnchor = HAnchor.Absolute,
VAnchor = VAnchor.Absolute,
OriginRelativeParent = new Vector2(45, 20),
Visible = false
});
var overlay = new GuiWidget();
overlay.AnchorAll();
overlay.Cursor = Cursors.Hand;
var overlay = new GuiWidget
{
VAnchor = VAnchor.Stretch,
HAnchor = HAnchor.Stretch,
Cursor = Cursors.Hand
};
overlay.Click += (s, e) =>
{
ThemeColorSelectorWidget.SetTheme(this.themeName);
UserSettings.Instance.set(UserSettingsKey.ThemeMode, this.Mode);
// Activate the theme
themeColorPanel.SetThemeColor(activeColor, this.Mode);
};
this.AddChild(overlay);
}
public void SetThemeColors(IThemeColors theme)
public bool IsActive
{
accentColor.BackgroundColor = theme.PrimaryAccentColor;
icon1.BackgroundColor = theme.PrimaryAccentColor;
icon2.BackgroundColor = theme.PrimaryAccentColor;
icon3.BackgroundColor = theme.PrimaryAccentColor;
tertiaryBackground.BackgroundColor = theme.TertiaryBackgroundColor;
secondaryBackground.BackgroundColor = theme.SecondaryBackgroundColor;
this.BackgroundColor = theme.PrimaryBackgroundColor;
this.themeName = theme.Name;
get => activeIcon.Visible;
set => activeIcon.Visible = value;
}
public override void OnClick(MouseEventArgs mouseEvent)
public string Mode { get; internal set; }
public void PreviewThemeColor(Color sourceColor)
{
ThemeColorSelectorWidget.SetTheme(this.themeName);
base.OnClick(mouseEvent);
var adjustedAccentColor = sourceColor;
accentColor.BackgroundColor = adjustedAccentColor;
icon1.BackgroundColor = adjustedAccentColor;
icon2.BackgroundColor = adjustedAccentColor;
icon3.BackgroundColor = adjustedAccentColor;
activeColor = adjustedAccentColor;
}
}
}

View file

@ -225,7 +225,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
{
Name = item.key + " Tab",
InactiveTabColor = Color.Transparent,
ActiveTabColor = theme.TabBodyBackground
ActiveTabColor = theme.ActiveTabColor
};
tab.CloseClicked += (s, e) =>
@ -253,6 +253,7 @@ namespace MatterHackers.MatterControl.CustomWidgets
Width = this.ConstrainedWidth,
VAnchor = VAnchor.Stretch,
HAnchor = HAnchor.Right,
BackgroundColor = theme.ActiveTabColor,
SpliterBarColor = theme.SplitterBackground,
SplitterWidth = theme.SplitterWidth,
};

View file

@ -1,144 +0,0 @@
/*
Copyright (c) 2017, Kevin Pope, John Lewin
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.Linq;
using MatterHackers.Agg;
using MatterHackers.Agg.UI;
using MatterHackers.MatterControl.ConfigurationPage;
using MatterHackers.MatterControl.SlicerConfiguration;
namespace MatterHackers.MatterControl
{
public class ThemeColorSelectorWidget : FlowLayoutWidget
{
private ThemePreviewButton darkPreviewButton;
private ThemePreviewButton lightPreviewButton;
private int containerHeight = (int)(30 * GuiWidget.DeviceScale + .5);
private int colorSelectSize = (int)(28 * GuiWidget.DeviceScale + .5);
public ThemeColorSelectorWidget(ThemePreviewButton darkPreview, ThemePreviewButton lightPreview)
{
this.Padding = new BorderDouble(2, 0);
this.darkPreviewButton = darkPreview;
this.lightPreviewButton = lightPreview;
int themeCount = ActiveTheme.AvailableThemes.Count;
var allThemes = ActiveTheme.AvailableThemes;
int index = 0;
for (int x = 0; x < themeCount / 2; x++)
{
var themeButton = CreateThemeButton(allThemes[index], index);
themeButton.Width = containerHeight;
this.AddChild(themeButton);
index++;
}
this.Width = containerHeight * (themeCount / 2);
}
private int hoveredThemeIndex = 0;
private int midPoint = ActiveTheme.AvailableThemes.Count / 2;
public Button CreateThemeButton(IThemeColors darkTheme, int darkThemeIndex)
{
var normal = new GuiWidget(colorSelectSize, colorSelectSize);
normal.BackgroundColor = darkTheme.SourceColor;
var hover = new GuiWidget(colorSelectSize, colorSelectSize);
hover.BackgroundColor = darkTheme.SourceColor;
var pressed = new GuiWidget(colorSelectSize, colorSelectSize);
pressed.BackgroundColor = darkTheme.SourceColor;
var disabled = new GuiWidget(colorSelectSize, colorSelectSize);
int lightThemeIndex = darkThemeIndex + midPoint;
var lightTheme = ActiveTheme.AvailableThemes[lightThemeIndex];
var colorButton = new Button(0, 0, new ButtonViewStates(normal, hover, pressed, disabled));
colorButton.Cursor = Cursors.Hand;
colorButton.Click += (s, e) =>
{
// Determine if we should set the dark or light version of the theme
var activeThemeIndex = ActiveTheme.AvailableThemes.IndexOf(ActiveTheme.Instance);
bool useLightTheme = activeThemeIndex >= midPoint;
SetTheme(darkThemeIndex, useLightTheme);
};
colorButton.MouseEnterBounds += (s, e) =>
{
darkPreviewButton.SetThemeColors(darkTheme);
lightPreviewButton.SetThemeColors(lightTheme);
hoveredThemeIndex = darkThemeIndex;
};
colorButton.MouseLeaveBounds += (s, e) =>
{
// darkPreviewButton.SetThemeColors(ActiveTheme.Instance);
};
return colorButton;
}
private static void SetTheme(int themeIndex, bool useLightTheme)
{
if (useLightTheme)
{
themeIndex += (ActiveTheme.AvailableThemes.Count / 2);
}
// save it for this printer
SetTheme(ActiveTheme.AvailableThemes[themeIndex].Name);
}
public static void SetTheme(string themeName)
{
UiThread.RunOnIdle(() =>
{
UserSettings.Instance.set(UserSettingsKey.ActiveThemeName, themeName);
//Set new user selected Default
ActiveTheme.Instance = ActiveTheme.GetThemeColors(themeName);
// Explicitly fire ReloadAll in response to user interaction
ApplicationController.Instance.ReloadAll();
});
}
}
}

View file

@ -120,7 +120,7 @@ namespace MatterHackers.MatterControl.EeProm
var settingsAreaScrollBox = new ScrollableWidget(true);
settingsAreaScrollBox.ScrollArea.HAnchor |= HAnchor.Stretch;
settingsAreaScrollBox.AnchorAll();
settingsAreaScrollBox.BackgroundColor = ActiveTheme.Instance.SecondaryBackgroundColor;
settingsAreaScrollBox.BackgroundColor = theme.MinimalShade;
topToBottom.AddChild(settingsAreaScrollBox);
settingsColumn = new FlowLayoutWidget(FlowDirection.TopToBottom)

View file

@ -89,7 +89,7 @@ namespace MatterHackers.MatterControl.Library
public static ImageBuffer AlphaToPrimaryAccent(this ImageBuffer sourceImage)
{
return sourceImage.AnyAlphaToColor(ActiveTheme.Instance.PrimaryAccentColor);
return sourceImage.AnyAlphaToColor(AppContext.Theme.Colors.PrimaryAccentColor);
}
}
}

View file

@ -562,7 +562,7 @@ namespace MatterHackers.MatterControl.PrintLibrary
PointSize = 8,
HAnchor = HAnchor.Right,
VAnchor = VAnchor.Bottom,
TextColor = ActiveTheme.Instance.SecondaryTextColor,
TextColor = theme.BorderColor,
Margin = new BorderDouble(6),
AutoExpandBoundsToText = true,
};

View file

@ -46,6 +46,7 @@ using MatterHackers.MatterControl.Library;
using MatterHackers.MatterControl.PartPreviewWindow;
using MatterHackers.MatterControl.PrinterCommunication;
using MatterHackers.MatterControl.PrintQueue;
using Newtonsoft.Json;
namespace MatterHackers.MatterControl.PrintLibrary
{
@ -457,7 +458,7 @@ namespace MatterHackers.MatterControl.PrintLibrary
PointSize = 8,
HAnchor = HAnchor.Right,
VAnchor = VAnchor.Bottom,
TextColor = ActiveTheme.Instance.SecondaryTextColor,
TextColor = theme.LightTextColor,
Margin = new BorderDouble(6),
AutoExpandBoundsToText = true,
};
@ -830,7 +831,7 @@ namespace MatterHackers.MatterControl.PrintLibrary
var feedbackWindow = new SavePartsSheetFeedbackWindow(
printItems.Count(),
printItems.FirstOrDefault()?.Name,
ActiveTheme.Instance.PrimaryBackgroundColor);
theme.ActiveTabColor);
var currentPartsInQueue = new PartsSheet(printItems, saveParams.FileName);
currentPartsInQueue.UpdateRemainingItems += feedbackWindow.StartingNextPart;

View file

@ -70,8 +70,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
this.printer = printer;
options = printer.Bed.RendererOptions;
this.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor;
this.LocalBounds = new RectangleDouble(0, 0, 100, 100);
this.AnchorAll();

View file

@ -70,7 +70,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
return materialControl;
};
materialColorButton = new ColorButton(MaterialRendering.Color(initialMaterialIndex, theme.MinimalHighlight))
materialColorButton = new ColorButton(MaterialRendering.Color(initialMaterialIndex, theme.BorderColor))
{
Width = scaledButtonSize,
Height = scaledButtonSize,

View file

@ -64,14 +64,14 @@ namespace MatterHackers.MatterControl
librarySelectorWidget = new ListView(libraryNavContext, new IconListView(theme, 75), theme)
{
BackgroundColor = ActiveTheme.Instance.TertiaryBackgroundColor,
BackgroundColor = theme.MinimalShade,
ShowItems = true,
ContainerFilter = (container) => !container.IsReadOnly,
};
// put in the bread crumb widget
breadCrumbWidget = new FolderBreadCrumbWidget(librarySelectorWidget, theme);
breadCrumbWidget.BackgroundColor = ActiveTheme.Instance.TertiaryBackgroundColor;
breadCrumbWidget.BackgroundColor = theme.MinimalShade;
contentRow.AddChild(breadCrumbWidget);
contentRow.BackgroundColor = Color.Transparent;

View file

@ -68,7 +68,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
var scaledButtonSize = 16 * GuiWidget.DeviceScale;
buttonView.AddChild(new ColorButton(MaterialRendering.Color(extruderIndex, theme.MinimalHighlight))
buttonView.AddChild(new ColorButton(MaterialRendering.Color(extruderIndex, theme.BorderColor))
{
Width = scaledButtonSize,
Height = scaledButtonSize,

View file

@ -65,7 +65,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
VAnchor = VAnchor.Stretch,
HAnchor = HAnchor.Stretch,
BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor,
BackgroundColor = theme.ActiveTabColor,
BorderColor = theme.MinimalShade,
Border = new BorderDouble(left: 1),
};
@ -279,9 +279,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
HAnchor = HAnchor.Fit,
VAnchor = VAnchor.Fit,
BackgroundColor = theme.TabBarBackground,
Border = new BorderDouble(right: 1),
BorderColor = theme.MinimalShade,
Padding = theme.TabbarPadding.Clone(right: 0)
Padding = theme.TabbarPadding.Clone(right: theme.DefaultContainerPadding)
};
tabControl.TabBar.ActionArea.AddChild(brandMenu, 0);

View file

@ -152,8 +152,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
leftToRight.AddChild(view3DContainer);
view3DWidget.BackgroundColor = ActiveTheme.Instance.TertiaryBackgroundColor;
if (sceneContext.World.RotationMatrix == Matrix4X4.Identity)
{
this.view3DWidget.ResetView();

View file

@ -56,7 +56,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
this.theme = theme;
this.VAnchor = VAnchor.Fit;
this.HAnchor = HAnchor.Fit;
this.BackgroundColor = theme.Colors.PrimaryBackgroundColor;
}
public HorizontalLine CreateHorizontalLine()
@ -429,7 +428,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
// Inflate padding to match the target (MenuGutterWidth) after scale operation in assignment
this.Padding = new BorderDouble(left: Math.Ceiling(theme.MenuGutterWidth / GuiWidget.DeviceScale) , right: 15);
this.BackgroundColor = theme.Colors.PrimaryBackgroundColor;
this.HAnchor = HAnchor.MaxFitOrStretch;
this.VAnchor = VAnchor.Fit;
this.MinimumSize = new Vector2(150 * GuiWidget.DeviceScale, theme.ButtonHeight);

View file

@ -42,7 +42,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
public PopupMenuButton(ThemeConfig theme)
{
this.theme = theme;
this.DisabledColor = new Color(theme.Colors.SecondaryTextColor, 50);
this.DisabledColor = theme.DisabledColor;
this.HoverColor = theme.MinimalShade;
}
@ -58,7 +58,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
viewWidget.BackgroundColor = Color.Transparent;
this.theme = theme;
this.DisabledColor = new Color(theme.Colors.SecondaryTextColor, 50);
this.DisabledColor = theme.DisabledColor;
this.HoverColor = theme.ToolbarButtonHover;
this.BackgroundColor = theme.ToolbarButtonBackground;
@ -113,7 +113,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
dropArrow,
LocalBounds.Right - DropArrow.ArrowHeight * 2 - 2,
LocalBounds.Center.Y + DropArrow.ArrowHeight / 2,
this.Enabled ? theme.Colors.SecondaryTextColor : this.DisabledColor);
this.Enabled ? theme.BorderColor : this.DisabledColor);
}
}

View file

@ -81,7 +81,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
VAnchor = VAnchor.Absolute | VAnchor.Bottom,
FillColor = ActiveTheme.Instance.PrimaryAccentColor,
BorderColor = Color.Transparent,
BackgroundColor = ActiveTheme.Instance.TertiaryBackgroundColor,
Margin = new BorderDouble(32, 7, theme.ButtonHeight * 2 + 14, 0),
};
rowContainer.AddChild(progressBar);

View file

@ -72,7 +72,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
var toolbar = new LeftClipFlowLayoutWidget()
{
BackgroundColor = theme.TabBodyBackground,
BackgroundColor = theme.ActiveTabColor,
Padding = theme.ToolbarPadding,
HAnchor = HAnchor.Fit,
VAnchor = VAnchor.Fit

View file

@ -151,11 +151,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
for (var i = 0; i < numberOfStripes * 2; i++)
{
var thickness = ix / numberOfStripes;
graphics2D.Line(
i * thickness + thickness / 2 - ix,
0,
i * thickness + thickness / 2,
i * thickness + thickness / 2 - ix,
0,
i * thickness + thickness / 2,
ix,
Color.Gray,
0.05);
@ -164,6 +164,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
base.OnDraw(graphics2D);
}
public Color SourceColor { get; set; }
}
public static class ColorExtensions

View file

@ -73,8 +73,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
var column = new FlowLayoutWidget(FlowDirection.TopToBottom)
{
Padding = 10,
BackgroundColor = menuTheme.Colors.PrimaryBackgroundColor
Padding = theme.DefaultContainerPadding,
};
column.AddChild(new TextWidget("Options".Localize(), textColor: menuTheme.Colors.PrimaryTextColor)

View file

@ -104,7 +104,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
this.printer = printer;
this.theme = theme;
this.Name = "View3DWidget";
this.BackgroundColor = theme.ActiveTabColor;
this.BackgroundColor = theme.ResolveColor(theme.ActiveTabColor, new Color(Color.Black, 20));
this.HAnchor = HAnchor.Stretch; // HAnchor.MaxFitOrStretch,
this.VAnchor = VAnchor.Stretch; // VAnchor.MaxFitOrStretch

View file

@ -275,7 +275,7 @@ namespace MatterHackers.MatterControl.PrinterControls
Padding = new BorderDouble(3),
HAnchor = HAnchor.Fit,
VAnchor = VAnchor.Center,
BackgroundColor = ActiveTheme.Instance.SecondaryBackgroundColor,
BackgroundColor = theme.MinimalShade,
Height = 20
};
this.AddChild(zOffsetStreamContainer);
@ -306,7 +306,7 @@ namespace MatterHackers.MatterControl.PrinterControls
double zoffset = printerSettings.GetValue<double>(SettingsKey.baby_step_z_offset);
bool hasOverriddenZOffset = (zoffset != 0);
zOffsetStreamContainer.BackgroundColor = (allowRemoveButton && hasOverriddenZOffset) ? theme.PresetColors.UserOverride : ActiveTheme.Instance.SecondaryBackgroundColor;
zOffsetStreamContainer.BackgroundColor = (allowRemoveButton && hasOverriddenZOffset) ? theme.PresetColors.UserOverride : theme.MinimalShade;
clearZOffsetButton.Visible = allowRemoveButton && hasOverriddenZOffset;
zOffsetStreamDisplay.Text = zoffset.ToString("0.##");

View file

@ -101,7 +101,7 @@ namespace MatterHackers.MatterControl
textScrollWidget = new TextScrollWidget(printer, printer.Connection.TerminalLog.PrinterLines)
{
BackgroundColor = theme.Colors.SecondaryBackgroundColor,
BackgroundColor = theme.MinimalShade,
TextColor = theme.Colors.PrimaryTextColor,
HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Stretch,

View file

@ -28,30 +28,29 @@ either expressed or implied, of the FreeBSD Project.
*/
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using MatterHackers.Agg;
using MatterHackers.Agg.Image;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.ConfigurationPage;
using MatterHackers.MatterControl.CustomWidgets;
using MatterHackers.MatterControl.DataStorage;
using MatterHackers.MatterControl.SlicerConfiguration;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl
{
public partial class ApplicationSettingsPage : DialogPage
{
private ThemeColorPanel themeColorPanel;
public ApplicationSettingsPage()
{
this.AlwaysOnTopOfMain = true;
this.WindowTitle = this.HeaderText = "MatterControl " + "Settings".Localize();
this.WindowSize = new Vector2(500 * GuiWidget.DeviceScale, 500 * GuiWidget.DeviceScale);
this.WindowSize = new Vector2(700 * GuiWidget.DeviceScale, 600 * GuiWidget.DeviceScale);
contentRow.Padding = contentRow.Padding.Clone(top: 0);
@ -283,12 +282,54 @@ namespace MatterHackers.MatterControl
this.AddSettingsRow(section, generalPanel);
themeColorPanel = new ThemeColorPanel(theme)
{
HAnchor = HAnchor.Stretch
};
var droplist = new DropDownList("Custom", theme.Colors.PrimaryTextColor, maxHeight: 200, pointSize: theme.DefaultFontSize)
{
BorderColor = theme.GetBorderColor(75),
Margin = new BorderDouble(0, 0, 10, 0)
};
int i = 0;
foreach (var item in AppContext.ThemeProviders)
{
var newItem = droplist.AddItem(item.Key);
if (item.Value == themeColorPanel.ThemeProvider)
{
droplist.SelectedIndex = i;
}
i++;
}
droplist.SelectionChanged += (s, e) =>
{
if (AppContext.ThemeProviders.TryGetValue(droplist.SelectedValue, out IColorTheme provider))
{
themeColorPanel.ThemeProvider = provider;
UserSettings.Instance.set(UserSettingsKey.ThemeName, droplist.SelectedValue);
}
};
var themeRow = new SettingsItem("Theme".Localize(), droplist, theme);
generalPanel.AddChild(themeRow);
generalPanel.AddChild(themeColorPanel);
themeColorPanel.Border = themeRow.Border;
themeColorPanel.BorderColor = themeRow.BorderColor;
themeRow.Border = 0;
var advancedPanel = new FlowLayoutWidget(FlowDirection.TopToBottom)
{
Margin = new BorderDouble(2, 0)
};
var sectionWidget = new SectionWidget("Advanced", advancedPanel, theme, serializationKey: "ApplicationSettings-Advanced", expanded: false)
var sectionWidget = new SectionWidget("Advanced".Localize(), advancedPanel, theme, serializationKey: "ApplicationSettings-Advanced", expanded: false)
{
Name = "Advanced Section",
HAnchor = HAnchor.Stretch,
@ -356,6 +397,18 @@ namespace MatterHackers.MatterControl
advancedPanel.Children<SettingsItem>().First().Border = new BorderDouble(0, 1);
}
public void BeforePopup()
{
// Refresh theme mode buttons
string activeMode = UserSettings.Instance.get(UserSettingsKey.ThemeMode);
foreach (var button in themeColorPanel.Children[1].Children<ThemePreviewButton>())
{
button.IsActive = activeMode == button.Mode;
button.PreviewThemeColor(theme.Colors.SourceColor);
}
}
private void AddSettingsRow(GuiWidget widget, GuiWidget container)
{
container.AddChild(widget);

View file

@ -66,6 +66,8 @@ namespace MatterHackers.MatterControl
public const string SceneTreeRatio = nameof(SceneTreeRatio);
public const string SelectedObjectEditorHeight = nameof(SelectedObjectEditorHeight);
public const string SelectionTreeViewPanelExpanded = nameof(SelectionTreeViewPanelExpanded);
public const string ThemeName = nameof(ThemeName);
public const string ThemeMode = nameof(ThemeMode);
}
public class UserSettings

View file

@ -61,7 +61,7 @@ namespace MatterHackers.MatterControl
this.HAnchor = HAnchor.Stretch;
this.VAnchor = VAnchor.Stretch;
this.BackgroundColor = theme.Colors.PrimaryBackgroundColor;
this.BackgroundColor = theme.ActiveTabColor;
if (cancelButtonText == null)
{

View file

@ -38,19 +38,18 @@ namespace MatterHackers.MatterControl
public class DialogWindow : SystemWindow
{
private DialogPage activePage;
private EventHandler unregisterEvents;
private static Dictionary<Type, DialogWindow> allWindows = new Dictionary<Type, DialogWindow>();
private ThemeConfig theme;
private DialogWindow()
: base(500 * GuiWidget.DeviceScale, 500 * GuiWidget.DeviceScale)
{
var theme = ApplicationController.Instance.Theme;
theme = ApplicationController.Instance.Theme;
this.AlwaysOnTopOfMain = true;
this.MinimumSize = new Vector2(200, 200);
this.BackgroundColor = theme.Colors.PrimaryBackgroundColor;
this.BackgroundColor = theme.ActiveTabColor;
var defaultPadding = theme.DefaultContainerPadding;
this.Padding = new BorderDouble(defaultPadding, defaultPadding, defaultPadding, 2);
@ -141,24 +140,32 @@ namespace MatterHackers.MatterControl
public DialogPage ChangeToPage<PanelType>() where PanelType : DialogPage, new()
{
PanelType panel = new PanelType();
panel.DialogWindow = this;
ChangeToPage(panel);
var panel = new PanelType
{
DialogWindow = this
};
this.ChangeToPage(panel);
// in the event of a reload all make sure we rebuild the contents correctly
ApplicationController.Instance.DoneReloadingAll.RegisterEvent((s,e) =>
{
// Normal theme references are safe to hold in widgets because they're rebuild on ReloadAll. DialogWindow
// survives and must refresh its reference on reload
theme = ApplicationController.Instance.Theme;
// fix the main window background color if needed
BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor;
this.BackgroundColor = theme.ActiveTabColor;
// find out where the contents we put in last time are
int thisIndex = GetChildIndex(panel);
RemoveAllChildren();
this.RemoveAllChildren();
// make new content with the possibly changed theme
PanelType newPanel = new PanelType();
newPanel.DialogWindow = this;
AddChild(newPanel, thisIndex);
var newPanel = new PanelType
{
DialogWindow = this
};
this.AddChild(newPanel, thisIndex);
panel.CloseOnIdle();
// remember the new content

View file

@ -75,6 +75,9 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
[JsonIgnore]
private string UserProfilesDirectory => GetProfilesDirectoryForUser(this.UserName);
[JsonIgnore]
public string ProfileThemeSetPath => Path.Combine(UserProfilesDirectory, "themeset.json");
/// <summary>
/// The user specific path to the Profiles document
/// </summary>
@ -534,10 +537,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
printerSettings.ID = guid;
printerSettings.DocumentVersion = PrinterSettings.LatestVersion;
printerSettings.UserLayer[SettingsKey.printer_name.ToString()] = printerName;
//If the active printer has no theme we set it to the current theme color
printerSettings.UserLayer[SettingsKey.active_theme_name] = ActiveTheme.Instance.Name;
printerSettings.UserLayer[SettingsKey.printer_name] = printerName;
// Add to Profiles - fires ProfileManager.Save due to ObservableCollection event listener
Instance.Profiles.Add(new PrinterInfo

View file

@ -45,7 +45,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
public static class SettingsKey
{
public const string active_quality_key = nameof(active_quality_key);
public const string active_theme_name = nameof(active_theme_name);
public const string auto_connect = nameof(auto_connect);
public const string auto_release_motors = nameof(auto_release_motors);
public const string baby_step_z_offset = nameof(baby_step_z_offset);

View file

@ -54,8 +54,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
: base (FlowDirection.TopToBottom)
{
this.printer = printer;
this.BackgroundColor = theme.TabBodyBackground;
this.settingsContext = settingsContext;
settingsControlBar = new PresetsToolbar(printer, theme)
@ -574,7 +572,7 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
var row = new FlowLayoutWidget()
{
BackgroundColor = theme.Colors.TertiaryBackgroundColor,
BackgroundColor = theme.SlightShade,
Padding = new BorderDouble(5),
Margin = new BorderDouble(3, 20, 3, 0),
HAnchor = HAnchor.Stretch,

View file

@ -73,7 +73,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
Name = "com_port Field",
// Prevent droplist interaction when connected
Enabled = canChangeComPort,
TextColor = canChangeComPort ? ActiveTheme.Instance.PrimaryTextColor : new Color(ActiveTheme.Instance.PrimaryTextColor, 150),
BorderColor = theme.GetBorderColor(75)
};
@ -90,7 +89,6 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
{
canChangeComPort = !printer.Connection.IsConnected && printer.Connection.CommunicationState != CommunicationStates.AttemptingToConnect;
dropdownList.Enabled = canChangeComPort;
dropdownList.TextColor = canChangeComPort ? ActiveTheme.Instance.PrimaryTextColor : new Color(ActiveTheme.Instance.PrimaryTextColor, 150);
if (printer.Connection.ComPort != dropdownList.SelectedLabel)
{

View file

@ -59,9 +59,8 @@ namespace MatterHackers.MatterControl.SlicerConfiguration
printer.Connection.CommunicationStateChanged.RegisterEvent((s, e) =>
{
canChangeComPort = !printer.Connection.IsConnected && printer.Connection.CommunicationState != CommunicationStates.AttemptingToConnect;
dropdownList.TextColor = theme.Colors.PrimaryTextColor;
dropdownList.Enabled = canChangeComPort;
dropdownList.TextColor = canChangeComPort ? theme.Colors.PrimaryTextColor : new Color(theme.Colors.PrimaryTextColor, 150);
dropdownList.BorderColor = canChangeComPort ? theme.Colors.SecondaryTextColor : new Color(theme.Colors.SecondaryTextColor, 150);
}, ref unregisterEvents);
// Release event listener on close

View file

@ -453,6 +453,7 @@ namespace JsonPath
}
}
// Invoke property to get value
var propertyValue = propertyInfo.GetGetMethod().Invoke(value, null);
if (!string.IsNullOrEmpty(typeFilter) && propertyValue is IEnumerable items)

@ -1 +1 @@
Subproject commit 9b89d41acd249a345b071849db9eca6e213644ab
Subproject commit 39f80f89d4e11b134815db53676eac5d2d7838b2

View file

@ -26,7 +26,7 @@ namespace MatterControl.Tests.MatterControl
var theme = new ThemeConfig()
{
Colors = ActiveTheme.Instance
Colors = ActiveTheme.Instance as ThemeColors
};
// Whitelist on non-OEM builds should contain all printers

View file

@ -878,10 +878,7 @@ namespace MatterControl.Tests.MatterControl
{
this.BackgroundColor = new Color(56, 56, 56);
Theme = new ThemeConfig()
{
Colors = ActiveTheme.Instance
};
Theme = new ThemeConfig();
this.Padding = new BorderDouble(left: 120, bottom: 10, right: 10, top: 10);

View file

@ -259,7 +259,6 @@ namespace MatterControl.Tests.MatterControl
MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4));
var theme = new ThemeConfig();
theme.RebuildTheme(ActiveTheme.Instance);
var field = new ComPortField(new PrinterConfig(PrinterSettings.Empty), theme);
@ -319,7 +318,7 @@ namespace MatterControl.Tests.MatterControl
MatterControlUtilities.OverrideAppDataLocation(TestContext.CurrentContext.ResolveProjectPath(4));
var theme = new ThemeConfig();
theme.RebuildTheme(ActiveTheme.Instance);
theme.RebuildTheme();
await ValidateAgainstValueMap<MultilineStringField>(
(field) => (field.Content as MHTextEditWidget).ActualTextEditWidget.Text,