Revised Tabs

- Add tab close
- Show new tab on + tab button click
- Revise Close icon - only show circle on hover
- Add micro-thumbnails for sidebar prototype
- Issue MatterHackers/MCCentral#2243
Revise main tabs
- Issue MatterHackers/MCCentral#2242
Can't switch back from GCode2D view as all controls are lost
This commit is contained in:
John Lewin 2017-11-11 17:28:03 -08:00
parent b940bff02e
commit 69de19d4ca
14 changed files with 657 additions and 267 deletions

View file

@ -60,7 +60,7 @@ namespace MatterHackers.MatterControl
public int DefaultFontSize { get; } = 12;
private int shortButtonHeight = 25;
internal int shortButtonHeight = 25;
private int sideBarButtonWidth;
public int H1PointSize { get; set; } = 13;
@ -90,12 +90,6 @@ namespace MatterHackers.MatterControl
public TextImageButtonFactory imageConverterExpandMenuOptionFactory;
internal void SetPrinterTabStyles(MainTab printerTab)
{
printerTab.Margin = new BorderDouble(10, 0, 0, 5);
printerTab.Padding = new BorderDouble(8, 4, 12, 6);
}
public TextImageButtonFactory imageConverterButtonFactory;
public Color TabBodyBackground => new Color(ActiveTheme.Instance.TertiaryBackgroundColor, 175);
@ -135,9 +129,9 @@ namespace MatterHackers.MatterControl
}
else
{
restoreNormal = ColorCircle(size, new Color(128, 128, 128));
restoreNormal = ColorCircle(size, Color.Transparent);
}
restoreHover = ColorCircle(size, new Color(200, 0, 0));
restoreHover = ColorCircle(size, new Color("#DB4437"));
restorePressed = ColorCircle(size, new Color(255, 0, 0));
}
@ -412,9 +406,20 @@ namespace MatterHackers.MatterControl
ImageBuffer imageBuffer = new ImageBuffer(size, size);
Graphics2D normalGraphics = imageBuffer.NewGraphics2D();
Vector2 center = new Vector2(size / 2.0, size / 2.0);
normalGraphics.Circle(center, size / 2.0, color);
normalGraphics.Line(center + new Vector2(-size / 4.0, -size / 4.0), center + new Vector2(size / 4.0, size / 4.0), Color.White, 2 * GuiWidget.DeviceScale);
normalGraphics.Line(center + new Vector2(-size / 4.0, size / 4.0), center + new Vector2(size / 4.0, -size / 4.0), Color.White, 2 * GuiWidget.DeviceScale);
Color barColor;
if (color != Color.Transparent)
{
normalGraphics.Circle(center, size / 2.0, color);
barColor = Color.White;
}
else
{
barColor = new Color("#999");
}
normalGraphics.Line(center + new Vector2(-size / 4.0, -size / 4.0), center + new Vector2(size / 4.0, size / 4.0), barColor, 2 * GuiWidget.DeviceScale);
normalGraphics.Line(center + new Vector2(-size / 4.0, size / 4.0), center + new Vector2(size / 4.0, -size / 4.0), barColor, 2 * GuiWidget.DeviceScale);
return imageBuffer;
}

View file

@ -31,8 +31,10 @@ 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
{
@ -49,11 +51,13 @@ namespace MatterHackers.MatterControl
this.AnchorAll();
this.Name = "WidescreenPanel";
var theme = ApplicationController.Instance.Theme;
var library3DViewSplitter = new Splitter()
{
SplitterDistance = UserSettings.Instance.LibraryViewWidth,
SplitterWidth = ApplicationController.Instance.Theme.SplitterWidth,
SplitterBackground = ApplicationController.Instance.Theme.SplitterBackground
SplitterWidth = theme.SplitterWidth,
SplitterBackground = theme.SplitterBackground
};
library3DViewSplitter.AnchorAll();
@ -67,12 +71,21 @@ namespace MatterHackers.MatterControl
var leftNav = new FlowLayoutWidget(FlowDirection.TopToBottom);
leftNav.AnchorAll();
leftNav.AddChild(new BrandMenuButton()
var toolbar = new Toolbar(null, theme)
{
HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Fit,
MinimumSize = new Vector2(16, 16)
};
toolbar.SeparatorLine.BackgroundColor = ApplicationController.Instance.Theme.SlightShade;
toolbar.SeparatorLine.Height = 2;
toolbar.ActionBar.AddChild(new BrandMenuButton(theme)
{
MinimumSize = new VectorMath.Vector2(0, 34),
HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Fit
});
leftNav.AddChild(toolbar);
var partPreviewContent = new PartPreviewContent()
{
@ -80,7 +93,7 @@ namespace MatterHackers.MatterControl
HAnchor = HAnchor.Left | HAnchor.Right
};
leftNav.AddChild(new PrintLibraryWidget(partPreviewContent, ApplicationController.Instance.Theme));
leftNav.AddChild(new PrintLibraryWidget(partPreviewContent, theme));
// put in the left column
library3DViewSplitter.Panel1.AddChild(leftNav);
@ -90,56 +103,40 @@ namespace MatterHackers.MatterControl
}
}
public class BrandMenuButton : GuiWidget
public class BrandMenuButton : PopupButton
{
public BrandMenuButton()
public BrandMenuButton(ThemeConfig theme)
{
this.Padding = new BorderDouble(left: 2);
Name = "MatterControl BrandMenuButton";
var buttonView = new FlowLayoutWidget()
{
HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Fit,
Margin = 0
};
var buttonHeight = ApplicationController.Instance.Theme.ButtonHeight;
var iconContainer = new GuiWidget()
{
Width = buttonHeight,
Height = buttonHeight
};
iconContainer.AddChild(new ImageWidget(AggContext.StaticData.LoadIcon("mh-app-logo.png", IconColor.Theme))
{
VAnchor = VAnchor.Center,
HAnchor = HAnchor.Center
});
buttonView.AddChild(iconContainer);
buttonView.AddChild(new TextWidget(ApplicationController.Instance.ShortProductName, textColor: ActiveTheme.Instance.PrimaryTextColor)
{
Margin = 0,
VAnchor = VAnchor.Center
});
var popupButton = new PopupButton(buttonView)
{
VAnchor = VAnchor.Center,
HAnchor = HAnchor.Stretch,
Margin = 0
};
popupButton.PopupContent = new ApplicationSettingsWidget(ApplicationController.Instance.Theme.MenuButtonFactory)
this.Name = "MatterControl BrandMenuButton";
this.VAnchor = VAnchor.Stretch;
this.HAnchor = HAnchor.Stretch;
this.Margin = 0;
this.PopupContent = new ApplicationSettingsWidget(theme.MenuButtonFactory)
{
HAnchor = HAnchor.Absolute,
VAnchor = VAnchor.Fit,
VAnchor = VAnchor.Center,
Width = 500,
BackgroundColor = Color.White
};
this.AddChild(popupButton);
var row = new FlowLayoutWidget()
{
HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Stretch,
};
this.AddChild(row);
row.AddChild(new IconButton(AggContext.StaticData.LoadIcon("mh-app-logo.png", IconColor.Theme), theme)
{
VAnchor = VAnchor.Center,
Margin = new BorderDouble(right: 4),
Selectable = false
});
row.AddChild(new TextWidget(ApplicationController.Instance.ShortProductName, textColor: ActiveTheme.Instance.PrimaryTextColor)
{
VAnchor = VAnchor.Center
});
}
}

View file

@ -194,41 +194,55 @@ namespace MatterHackers.MatterControl.CustomWidgets
{
this.VAnchor = VAnchor.Fit;
this.HAnchor = HAnchor.Fit;
this.Padding = 4;
this.Padding = 2;
this.Margin = new BorderDouble(6, 0, 0, 6);
var container = new FlowLayoutWidget(FlowDirection.TopToBottom);
this.AddChild(container);
imageWidget = new ImageWidget(thumbWidth, thumbHeight)
{
AutoResize = false,
Name = "List Item Thumbnail",
BackgroundColor = item.ListView.ThumbnailBackground,
Margin = 0,
};
container.AddChild(imageWidget);
this.SetItemThumbnail(loadingImage);
int maxWidth = thumbWidth - 4;
var text = new TextWidget(item.Model.Name, 0, 0, 9, textColor: ActiveTheme.Instance.PrimaryTextColor)
if (thumbWidth < 75)
{
AutoExpandBoundsToText = false,
EllipsisIfClipped = true,
HAnchor = HAnchor.Center,
Margin = new BorderDouble(0, 0, 0, 3),
};
imageWidget = new ImageWidget(thumbWidth, thumbHeight)
{
AutoResize = false,
Name = "List Item Thumbnail",
BackgroundColor = item.ListView.ThumbnailBackground,
Margin = 0,
};
this.AddChild(imageWidget);
}
else
{
var container = new FlowLayoutWidget(FlowDirection.TopToBottom);
this.AddChild(container);
text.MaximumSize = new Vector2(maxWidth, 20);
if (text.Printer.LocalBounds.Width > maxWidth)
{
text.Width = maxWidth;
text.Text = item.Model.Name;
imageWidget = new ImageWidget(thumbWidth, thumbHeight)
{
AutoResize = false,
Name = "List Item Thumbnail",
BackgroundColor = item.ListView.ThumbnailBackground,
Margin = 0,
};
container.AddChild(imageWidget);
var text = new TextWidget(item.Model.Name, 0, 0, 9, textColor: ActiveTheme.Instance.PrimaryTextColor)
{
AutoExpandBoundsToText = false,
EllipsisIfClipped = true,
HAnchor = HAnchor.Center,
Margin = new BorderDouble(0, 0, 0, 3),
};
text.MaximumSize = new Vector2(maxWidth, 20);
if (text.Printer.LocalBounds.Width > maxWidth)
{
text.Width = maxWidth;
text.Text = item.Model.Name;
}
container.AddChild(text);
}
container.AddChild(text);
this.SetItemThumbnail(loadingImage);
}
public override async void OnLoad(EventArgs args)

View file

@ -431,7 +431,7 @@ namespace MatterHackers.MatterControl.PrintLibrary
var bedConfig = new BedConfig();
var newTab = partPreviewContent.CreatePartTab(firstItem.Name, bedConfig, theme);
if (newTab.TabPage is PartTabPage printerTab)
if (newTab.TabContent is PartTabPage printerTab)
{
bedConfig.Scene.Children.Modify(list =>
{
@ -606,6 +606,29 @@ namespace MatterHackers.MatterControl.PrintLibrary
},
});
menuActions.Add(new PrintItemAction()
{
Title = "View XSmall Icons".Localize(),
AlwaysEnabled = true,
Action = (selectedLibraryItems, listView) =>
{
listView.ListContentView = new IconListView(18);
listView.Reload().ConfigureAwait(false);
},
});
menuActions.Add(new PrintItemAction()
{
Title = "View Small Icons".Localize(),
AlwaysEnabled = true,
Action = (selectedLibraryItems, listView) =>
{
listView.ListContentView = new IconListView(70);
listView.Reload().ConfigureAwait(false);
},
});
menuActions.Add(new PrintItemAction()
{
Title = "View Icons".Localize(),

View file

@ -113,13 +113,14 @@
<Compile Include="Library\Providers\WritableContainer.cs" />
<Compile Include="Library\Widgets\ExpandCheckboxButton.cs" />
<Compile Include="Library\Widgets\InsertionGroup.cs" />
<Compile Include="PartPreviewWindow\NewTabButton.cs" />
<Compile Include="PartPreviewWindow\PartTabPage.cs" />
<Compile Include="PartPreviewWindow\PopupMenu.cs" />
<Compile Include="PartPreviewWindow\PopupMenuButton.cs" />
<Compile Include="PartPreviewWindow\IconTab.cs" />
<Compile Include="PartPreviewWindow\PopupButton.cs" />
<Compile Include="PartPreviewWindow\SectionWidget.cs" />
<Compile Include="PartPreviewWindow\SliceLayerSelector.cs" />
<Compile Include="PartPreviewWindow\Toolbar.cs" />
<Compile Include="PartPreviewWindow\View3D\Actions\IntersectionEditor.cs" />
<Compile Include="PartPreviewWindow\View3D\Actions\MeshWrapper.cs" />
<Compile Include="PartPreviewWindow\View3D\Actions\MeshWrapperOperation.cs" />

View file

@ -28,16 +28,11 @@ either expressed or implied, of the FreeBSD Project.
*/
using System;
using System.Diagnostics;
using System.Threading.Tasks;
using MatterHackers.Agg;
using MatterHackers.Agg.Transform;
using MatterHackers.Agg.UI;
using MatterHackers.Agg.VertexSource;
using MatterHackers.GCodeVisualizer;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.SlicerConfiguration;
using MatterHackers.MeshVisualizer;
using MatterHackers.RenderOpenGl;
using MatterHackers.RenderOpenGl.OpenGl;
using MatterHackers.VectorMath;

View file

@ -27,38 +27,161 @@ 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.Image;
using MatterHackers.Agg.UI;
using MatterHackers.Agg.VertexSource;
using MatterHackers.VectorMath;
using MatterHackers.Localizations;
namespace MatterHackers.MatterControl.PartPreviewWindow
{
public class MainTab : ThreeViewTab
public class MainTab : GuiWidget, ITab
{
public event EventHandler CloseClicked;
private SimpleTabs parentTabControl;
public MainTab(string tabLabel, SimpleTabs parentTabControl, GuiWidget tabContent, string tabImageUrl = null)
{
this.HAnchor = HAnchor.Fit;
this.VAnchor = VAnchor.Fit | VAnchor.Bottom;
this.Padding = 0;
this.Margin = 0;
this.TabContent = tabContent;
this.parentTabControl = parentTabControl;
this.AddChild(
new TabPill(tabLabel, ActiveTheme.Instance.PrimaryTextColor, tabImageUrl)
{
Margin = new BorderDouble(right: 16)
});
var closeButton = ApplicationController.Instance.Theme.CreateSmallResetButton();
closeButton.HAnchor = HAnchor.Right;
closeButton.Margin = new BorderDouble(right: 7, top: 1);
closeButton.Name = "Close Tab Button";
closeButton.ToolTipText = "Close".Localize();
closeButton.Click += (sender, e) =>
{
UiThread.RunOnIdle(() =>
{
this.CloseClicked?.Invoke(this, null);
});
};
this.AddChild(closeButton);
}
public GuiWidget TabContent { get; }
public static Color ActiveTabColor = ApplicationController.Instance.Theme.SlightShade;
public static Color InactiveTabColor = ApplicationController.Instance.Theme.PrimaryTabFillColor;
private static int tabInsetDistance = 14 / 2;
internal MainTab NextTab { get; set; }
internal MainTab PreviousTab { get; set; }
public override void OnDraw(Graphics2D graphics2D)
{
var rect = LocalBounds;
var centerY = rect.YCenter;
var siblings = this.Parent.Children.OfType<MainTab>().ToList();
int position = siblings.IndexOf(this);
//MainTab leftSibling = (position > 0) ? siblings[position - 1] : null;
//MainTab rightSibling = (position < siblings.Count - 1) ? siblings[position + 1] : null;
var activeTab = parentTabControl.ActiveTab;
bool isFirstTab = position == 0;
bool rightSiblingSelected = this.NextTab == activeTab;
// Tab - core
var tabShape = new VertexStorage();
tabShape.MoveTo(rect.Left, centerY);
tabShape.LineTo(rect.Left + tabInsetDistance, rect.Top);
tabShape.LineTo(rect.Right - tabInsetDistance, rect.Top);
tabShape.LineTo(rect.Right, centerY);
if (!rightSiblingSelected)
{
tabShape.LineTo(rect.Right, rect.Bottom);
}
tabShape.LineTo(rect.Right - tabInsetDistance, rect.Bottom);
tabShape.LineTo(rect.Left + tabInsetDistance, rect.Bottom);
if (isFirstTab)
{
tabShape.LineTo(rect.Left, rect.Bottom);
}
graphics2D.Render(
tabShape,
(this == activeTab) ? ActiveTabColor : InactiveTabColor);
if (!isFirstTab)
{
DrawTabLowerLeft(
graphics2D,
rect,
(this.PreviousTab == activeTab || this == activeTab) ? ActiveTabColor : InactiveTabColor);
}
if (rightSiblingSelected)
{
DrawTabLowerRight(graphics2D, rect, ActiveTabColor);
}
base.OnDraw(graphics2D);
}
public static void DrawTabLowerRight(Graphics2D graphics2D, RectangleDouble rect, Color color)
{
// Tab - right nub
var tabRight = new VertexStorage();
tabRight.MoveTo(rect.Right, rect.YCenter);
tabRight.LineTo(rect.Right, rect.Bottom);
tabRight.LineTo(rect.Right - tabInsetDistance, rect.Bottom);
graphics2D.Render(tabRight, color);
}
public static void DrawTabLowerLeft(Graphics2D graphics2D, RectangleDouble rect, Color color)
{
// Tab - left nub
var tabLeft = new VertexStorage();
tabLeft.MoveTo(rect.Left, rect.YCenter);
tabLeft.LineTo(rect.Left + tabInsetDistance, rect.Bottom);
tabLeft.LineTo(rect.Left, rect.Bottom);
graphics2D.Render(tabLeft, color);
}
private class TabPill : FlowLayoutWidget
{
private TextWidget label;
public TabPill(string tabTitle, Color textColor, string imageUrl = null)
{
var imageWidget = new ImageWidget(new ImageBuffer(16, 16))
{
Margin = new BorderDouble(right: 6),
VAnchor = VAnchor.Center
};
this.AddChild(imageWidget);
label = new TextWidget(tabTitle)
{
TextColor = textColor,
VAnchor = VAnchor.Center
};
this.AddChild(label);
this.Selectable = false;
this.Padding = new BorderDouble(10, 5, 10, 4);
if (!string.IsNullOrEmpty(imageUrl))
{
var imageWidget = new ImageWidget(new ImageBuffer(16, 16))
{
Margin = new BorderDouble(right: 6, bottom: 2),
VAnchor = VAnchor.Center
};
this.AddChild(imageWidget);
// Attempt to load image
try
{
@ -67,11 +190,18 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}
catch { }
}
label = new TextWidget(tabTitle)
{
TextColor = textColor,
VAnchor = VAnchor.Center
};
this.AddChild(label);
}
public Color TextColor
{
get => label.TextColor;
get => label.TextColor;
set => label.TextColor = value;
}
@ -81,46 +211,5 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
set => label.Text = value;
}
}
public MainTab(string tabTitle, string tabName, TabPage tabPage, string tabImageUrl = null)
: this(
new TabPill(tabTitle, new Color(ActiveTheme.Instance.PrimaryTextColor, 140), tabImageUrl),
new TabPill(tabTitle, ActiveTheme.Instance.PrimaryTextColor, tabImageUrl),
new TabPill(tabTitle, ActiveTheme.Instance.PrimaryTextColor, tabImageUrl),
tabName,
tabPage)
{
}
public MainTab(GuiWidget normalWidget, GuiWidget hoverWidget, GuiWidget pressedWidget, string tabName, TabPage tabPage)
: base(tabName, normalWidget, hoverWidget, pressedWidget, tabPage)
{
this.HAnchor = HAnchor.Fit;
this.VAnchor = VAnchor.Fit | VAnchor.Bottom;
}
public int BorderWidth { get; set; } = 1;
public int borderRadius { get; set; } = 4;
private Color activeTabColor = ApplicationController.Instance.Theme.SlightShade;
private Color inactiveTabColor = ApplicationController.Instance.Theme.PrimaryTabFillColor;
public override void OnDraw(Graphics2D graphics2D)
{
RectangleDouble borderRectangle = LocalBounds;
borderRectangle.ExpandToInclude(new Vector2(0, -15));
if (BorderWidth > 0)
{
var r = new RoundedRect(borderRectangle, this.borderRadius);
r.normalize_radius();
graphics2D.Render(
r,
selectedWidget.Visible ? activeTabColor : inactiveTabColor);
}
base.OnDraw(graphics2D);
}
}
}

View file

@ -27,6 +27,7 @@ of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System.Linq;
using MatterHackers.Agg;
using MatterHackers.Agg.Image;
using MatterHackers.Agg.UI;
@ -34,27 +35,38 @@ using MatterHackers.MatterControl.CustomWidgets;
namespace MatterHackers.MatterControl.PartPreviewWindow
{
public class IconTab : Tab
public class NewTabButton : GuiWidget
{
private IconButton iconButton;
private SimpleTabs parentTabControl;
public IconTab(string tabName, TabPage tabPage, ImageBuffer imageBuffer, ThemeConfig theme)
: base(tabName, tabPage)
public IconButton IconButton { get; }
public NewTabButton(ImageBuffer imageBuffer, SimpleTabs parentTabControl, ThemeConfig theme)
{
iconButton = new IconButton(imageBuffer, theme)
this.parentTabControl = parentTabControl;
this.HAnchor = HAnchor.Fit;
IconButton = new IconButton(imageBuffer, theme)
{
HAnchor = HAnchor.Left,
Height = theme.MicroButton.Options.FixedHeight,
Width = theme.MicroButton.Options.FixedHeight,
Selectable = false
Margin = new BorderDouble(left: 10),
};
this.AddChild(iconButton);
this.AddChild(IconButton);
}
protected override void OnTabIndexChanged()
public ITab LastTab { get; set; }
public override void OnDraw(Graphics2D graphics2D)
{
iconButton.BackgroundColor = (this.TabPage == TabBarContaningTab.GetActivePage()) ? ActiveTheme.Instance.TertiaryBackgroundColor : Color.Transparent;
base.OnTabIndexChanged();
MainTab.DrawTabLowerLeft(
graphics2D,
this.LocalBounds,
(parentTabControl.ActiveTab == this.LastTab) ? MainTab.ActiveTabColor : MainTab.InactiveTabColor);
base.OnDraw(graphics2D);
}
}
}

View file

@ -30,13 +30,12 @@ either expressed or implied, of the FreeBSD Project.
using System;
using System.Linq;
using MatterHackers.Agg;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.AboutPage;
using MatterHackers.MatterControl.CustomWidgets;
using MatterHackers.MatterControl.SettingsManagement;
using MatterHackers.MatterControl.SlicerConfiguration;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.PartPreviewWindow
{
@ -45,20 +44,33 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private EventHandler unregisterEvents;
private MainTab printerTab = null;
private TabControl tabControl;
private NewTabButton plusTabSelect;
private ChromeTabs tabControl;
public PartPreviewContent()
: base(FlowDirection.TopToBottom)
{
var printer = ApplicationController.Instance.ActivePrinter;
var theme = ApplicationController.Instance.Theme;
this.AnchorAll();
tabControl = ApplicationController.Instance.Theme.CreateTabControl(2);
var extensionArea = new FlowLayoutWidget();
tabControl.TabBar.TabIndexChanged += (s, e) =>
tabControl = new ChromeTabs(extensionArea, theme)
{
if (tabControl.GetTabPage(tabControl.SelectedTabIndex) is PartTabPage tabPage)
VAnchor = VAnchor.Stretch,
HAnchor = HAnchor.Stretch,
BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor,
NewTabPage = () =>
{
return new PlusTabPage(this, tabControl, theme);
}
};
tabControl.ActiveTabChanged += (s, e) =>
{
if (this.tabControl.ActiveTab?.TabContent is PartTabPage tabPage)
{
var dragDropData = ApplicationController.Instance.DragDropData;
@ -68,58 +80,27 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}
};
var separator = tabControl.Children<HorizontalLine>().FirstOrDefault();
separator.BackgroundColor = ApplicationController.Instance.Theme.SlightShade;
tabControl.TabBar.Padding = new BorderDouble(top: 4);
tabControl.TabBar.SeparatorLine.BackgroundColor = ApplicationController.Instance.Theme.SlightShade;
tabControl.TabBar.SeparatorLine.Height = 2;
Color selectedTabColor;
if (!UserSettings.Instance.IsTouchScreen)
{
tabControl.TabBar.BackgroundColor = ActiveTheme.Instance.PrimaryBackgroundColor;
selectedTabColor = ActiveTheme.Instance.TabLabelSelected;
}
else
{
tabControl.TabBar.BackgroundColor = ActiveTheme.Instance.TransparentLightOverlay;
selectedTabColor = ActiveTheme.Instance.SecondaryAccentColor;
}
Color selectedTabColor = ActiveTheme.Instance.TabLabelSelected;
// Add a tab for the current printer
if (ActiveSliceSettings.Instance.PrinterSelected)
{
string tabTitle = ActiveSliceSettings.Instance.GetValue(SettingsKey.printer_name);
printerTab = CreatePrinterTab(printer, theme, tabTitle);
tabControl.AddTab(printerTab);
}
else
{
this.CreatePartTab("New Part", printer.Bed, theme, 0);
this.CreatePartTab("New Part", printer.Bed, theme);
}
// TODO: add in the printers and designs that are currently open (or were open last run).
var plusTabSelect = new IconTab(
"Create New",
new TabPage(new PlusTabPage(this, printer, theme), "+"),
AggContext.StaticData.LoadIcon("fa-plus_12.png", IconColor.Theme),
theme);
plusTabSelect.VAnchor = VAnchor.Bottom;
plusTabSelect.MinimumSize = new VectorMath.Vector2(16, 16);
plusTabSelect.Margin = new BorderDouble(left: 10, top: 6);
plusTabSelect.Padding = 0;
plusTabSelect.ToolTipText = "Create New".Localize();
tabControl.AddTab(plusTabSelect);
tabControl.TabBar.AddChild(new HorizontalSpacer());
// add in the update available button
LinkButtonFactory linkButtonFactory = new LinkButtonFactory()
{
textColor = ActiveTheme.Instance.PrimaryTextColor,
fontSize = 12,
};
Button updateAvailableButton = linkButtonFactory.Generate("Update Available");
Button updateAvailableButton = theme.LinkButtonFactory.Generate("Update Available");
updateAvailableButton.Name = "Update Available Link";
updateAvailableButton.Visible = UpdateControlData.Instance.UpdateStatus == UpdateControlData.UpdateStatusStates.UpdateAvailable;
updateAvailableButton.ToolTipText = "There is a new update available for download".Localize();
@ -133,7 +114,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
DialogWindow.Show<CheckForUpdatesPage>();
});
});
tabControl.TabBar.AddChild(updateAvailableButton);
tabControl.AddChild(updateAvailableButton);
UpdateControlData.Instance.UpdateStatusChanged.RegisterEvent((s, e) =>
{
@ -141,17 +123,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}, ref unregisterEvents);
// this causes the update button to be centered
tabControl.TabBar.AddChild(new HorizontalSpacer());
// put in the login logout control
var rightPanelArea = new FlowLayoutWidget()
{
VAnchor = VAnchor.Stretch
};
var extensionArea = new FlowLayoutWidget();
rightPanelArea.AddChild(extensionArea);
//tabControl.TabBar.AddChild(new HorizontalSpacer());
//rightPanelArea.AddChild(
// new ImageWidget(
@ -161,7 +133,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
// DebugShowBounds = true
// });
tabControl.TabBar.AddChild(rightPanelArea);
//this.AddChild(tabControl);
this.AddChild(tabControl);
@ -171,7 +143,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
&& stringEvent.Data == SettingsKey.printer_name
&& printerTab != null)
{
printerTab.TabPage.Text = ActiveSliceSettings.Instance.GetValue(SettingsKey.printer_name);
printerTab.Text = ActiveSliceSettings.Instance.GetValue(SettingsKey.printer_name);
}
}, ref unregisterEvents);
@ -187,38 +159,36 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}, ref unregisterEvents);
}
private static MainTab CreatePrinterTab(PrinterConfig printer, ThemeConfig theme, string tabTitle)
private MainTab CreatePrinterTab(PrinterConfig printer, ThemeConfig theme, string tabTitle)
{
string oemName = printer.Settings.GetValue(SettingsKey.make);
OemSettings.Instance.OemUrls.TryGetValue(oemName, out string oemUrl);
var printerTab = new MainTab(
return new MainTab(
tabTitle,
"3D View Tab",
tabControl,
new PrinterTabPage(printer, theme, tabTitle.ToUpper()),
"https://www.google.com/s2/favicons?domain=" + oemUrl ?? "www.matterhackers.com");
printerTab.ToolTipText = "Preview 3D Design".Localize();
theme.SetPrinterTabStyles(printerTab);
return printerTab;
"https://www.google.com/s2/favicons?domain=" + oemUrl ?? "www.matterhackers.com")
{
Name = "3D View Tab",
MinimumSize = new Vector2(120, theme.shortButtonHeight)
};
}
internal MainTab CreatePartTab(string tabTitle, BedConfig sceneContext, ThemeConfig theme, int tabIndex = 1)
internal MainTab CreatePartTab(string tabTitle, BedConfig sceneContext, ThemeConfig theme)
{
var partTab = new MainTab(
tabTitle,
"newPart" + tabControl.TabCount,
tabControl,
new PartTabPage(null, sceneContext, theme, "xxxxx"),
"https://i.imgur.com/nkeYgfU.png");
"https://i.imgur.com/nkeYgfU.png")
{
Name = "newPart" + tabControl.AllTabs.Count(),
MinimumSize = new Vector2(120, theme.shortButtonHeight)
};
theme.SetPrinterTabStyles(partTab);
var margin = partTab.Margin;
partTab.Margin = new BorderDouble(1, margin.Bottom, 1, margin.Top);
tabControl.AddTab(partTab, tabPosition: tabIndex);
tabControl.SelectedTabIndex = tabIndex;
tabControl.AddTab(partTab);
return partTab;
}

View file

@ -71,7 +71,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
}
};
viewControls3D.OverflowMenu.DynamicPopupContent = this.GetViewControls3DOverflowMenu;
bool isPrinterType = this is PrinterTabPage;
// The 3D model view

View file

@ -40,7 +40,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
public class PlusTabPage : FlowLayoutWidget
{
public PlusTabPage(PartPreviewContent partPreviewContent, PrinterConfig printer, ThemeConfig theme)
public PlusTabPage(PartPreviewContent partPreviewContent, SimpleTabs simpleTabs, ThemeConfig theme)
: base(FlowDirection.TopToBottom)
{
this.HAnchor = HAnchor.Stretch;
@ -58,7 +58,11 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
createItemsSection.AddChild(createPart);
createPart.Click += (s, e) =>
{
partPreviewContent.CreatePartTab("New Part", new BedConfig(), theme);
UiThread.RunOnIdle(() =>
{
simpleTabs.RemoveTab(simpleTabs.ActiveTab);
partPreviewContent.CreatePartTab("New Part", new BedConfig(), theme);
});
};
var createPrinter = theme.ButtonFactory.Generate("Create Printer".Localize());
@ -67,20 +71,20 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
createPrinter.HAnchor = HAnchor.Left;
createPrinter.Click += (s, e) =>
{
if (ApplicationController.Instance.ActivePrinter.Connection.PrinterIsPrinting
UiThread.RunOnIdle(() =>
{
simpleTabs.RemoveTab(simpleTabs.ActiveTab);
if (ApplicationController.Instance.ActivePrinter.Connection.PrinterIsPrinting
|| ApplicationController.Instance.ActivePrinter.Connection.PrinterIsPaused)
{
UiThread.RunOnIdle(() =>
StyledMessageBox.ShowMessageBox("Please wait until the print has finished and try again.".Localize(), "Can't add printers while printing".Localize())
);
}
else
{
UiThread.RunOnIdle(() =>
{
StyledMessageBox.ShowMessageBox("Please wait until the print has finished and try again.".Localize(), "Can't add printers while printing".Localize());
}
else
{
DialogWindow.Show(PrinterSetup.GetBestStartPage(PrinterSetup.StartPageOptions.ShowMakeModel));
});
}
}
});
};
createItemsSection.AddChild(createPrinter);
@ -99,6 +103,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
if (!string.IsNullOrEmpty(result.FileName)
&& File.Exists(result.FileName))
{
simpleTabs.RemoveTab(simpleTabs.ActiveTab);
ImportSettingsPage.ImportFromExisting(result.FileName);
}
});
@ -122,8 +127,12 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
redeemDesignCode.HAnchor = HAnchor.Left;
redeemDesignCode.Click += (s, e) =>
{
// Implementation already does RunOnIdle
ApplicationController.Instance.RedeemDesignCode?.Invoke();
UiThread.RunOnIdle(() =>
{
simpleTabs.RemoveTab(simpleTabs.ActiveTab);
// Implementation already does RunOnIdle
ApplicationController.Instance.RedeemDesignCode?.Invoke();
});
};
otherItemsSection.AddChild(redeemDesignCode);
@ -133,8 +142,13 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
redeemShareCode.HAnchor = HAnchor.Left;
redeemShareCode.Click += (s, e) =>
{
// Implementation already does RunOnIdle
ApplicationController.Instance.EnterShareCode?.Invoke();
UiThread.RunOnIdle(() =>
{
simpleTabs.RemoveTab(simpleTabs.ActiveTab);
// Implementation already does RunOnIdle
ApplicationController.Instance.EnterShareCode?.Invoke();
});
};
otherItemsSection.AddChild(redeemShareCode);
@ -147,17 +161,22 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
shopButton.Margin = buttonSpacing;
shopButton.Click += (sender, e) =>
{
double activeFilamentDiameter = 0;
if (ActiveSliceSettings.Instance.PrinterSelected)
UiThread.RunOnIdle(() =>
{
activeFilamentDiameter = 3;
if (ActiveSliceSettings.Instance.GetValue<double>(SettingsKey.filament_diameter) < 2)
{
activeFilamentDiameter = 1.75;
}
}
simpleTabs.RemoveTab(simpleTabs.ActiveTab);
MatterControlApplication.Instance.LaunchBrowser("http://www.matterhackers.com/mc/store/redirect?d={0}&clk=mcs&a={1}".FormatWith(activeFilamentDiameter, OemSettings.Instance.AffiliateCode));
double activeFilamentDiameter = 0;
if (ActiveSliceSettings.Instance.PrinterSelected)
{
activeFilamentDiameter = 3;
if (ActiveSliceSettings.Instance.GetValue<double>(SettingsKey.filament_diameter) < 2)
{
activeFilamentDiameter = 1.75;
}
}
MatterControlApplication.Instance.LaunchBrowser("http://www.matterhackers.com/mc/store/redirect?d={0}&clk=mcs&a={1}".FormatWith(activeFilamentDiameter, OemSettings.Instance.AffiliateCode));
});
};
otherItemsSection.AddChild(shopButton);
}

View file

@ -53,7 +53,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private DoubleSolidSlider layerRenderRatioSlider;
private SystemWindow parentSystemWindow;
private SliceLayerSelector layerScrollbar;
private PrinterConfig printer;
internal PrinterConfig printer;
internal GCode3DWidget gcode3DWidget;
public PrinterTabPage(PrinterConfig printer, ThemeConfig theme, string tabTitle)
@ -281,7 +281,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
{
Visible = (this.ViewMode == PartViewMode.Layers2D)
};
view3DContainer.AddChild(gcode2DWidget);
view3DWidget.InteractionLayer.AddChild(gcode2DWidget);
viewControls3D.Layers2DButton.Enabled = true;
}

View file

@ -0,0 +1,268 @@
/*
Copyright (c) 2017, Lars Brubaker
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
The views and conclusions contained in the software and documentation are those
of the authors and should not be interpreted as representing official policies,
either expressed or implied, of the FreeBSD Project.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using MatterHackers.Agg.Platform;
using MatterHackers.Agg.UI;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.CustomWidgets;
using MatterHackers.VectorMath;
namespace MatterHackers.MatterControl.PartPreviewWindow
{
/// <summary>
/// A toolbar with an optional right anchored element and an ActionBar child to add actions to the bar
/// </summary>
public class Toolbar : Bar
{
public FlowLayoutWidget ActionBar { get; }
public HorizontalLine SeparatorLine { get; }
public Toolbar(GuiWidget rightAnchorItem, ThemeConfig theme, bool bottomBorder = true)
: base(rightAnchorItem, theme)
{
GuiWidget context = this;
this.ActionBar = new FlowLayoutWidget()
{
HAnchor = HAnchor.Stretch
};
if (bottomBorder)
{
var column = new FlowLayoutWidget(FlowDirection.TopToBottom)
{
HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Fit
};
this.AddChild(column, 0);
column.AddChild(this.ActionBar);
column.AddChild(this.SeparatorLine = new HorizontalLine(40));
}
else
{
this.AddChild(this.ActionBar, 0);
}
}
}
public interface ITab
{
GuiWidget TabContent { get; }
}
/// <summary>
/// A toolbar like item with an optional right anchored element
/// </summary>
public class Bar : GuiWidget
{
public Bar(GuiWidget rightAnchorItem, ThemeConfig theme)
{
if (rightAnchorItem != null)
{
rightAnchorItem.HAnchor |= HAnchor.Right;
this.AddChild(rightAnchorItem);
}
}
}
/// <summary>
/// A toolbar and associated tab body
/// </summary>
public class SimpleTabs : FlowLayoutWidget
{
public Toolbar TabBar { get; }
private GuiWidget body;
public SimpleTabs(GuiWidget rightAnchorItem, ThemeConfig theme, bool bottomBorder = true)
: base(FlowDirection.TopToBottom)
{
this.AddChild(TabBar = new Toolbar(rightAnchorItem, theme, bottomBorder)
{
HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Fit
});
this.AddChild(body = new GuiWidget()
{
HAnchor = HAnchor.Stretch,
VAnchor = VAnchor.Stretch,
});
}
public event EventHandler ActiveTabChanged;
private List<ITab> _allTabs = new List<ITab>();
public IEnumerable<ITab> AllTabs => _allTabs;
public void AddTab(GuiWidget tabWidget, int position)
{
var iTab = tabWidget as ITab;
_allTabs.Add(tabWidget as ITab);
tabWidget.Click += TabWidget_Click;
this.TabBar.ActionBar.AddChild(tabWidget, position);
this.body.AddChild(iTab.TabContent);
}
private void TabWidget_Click(object sender, MouseEventArgs e)
{
this.ActiveTab = sender as ITab;
}
internal void RemoveTab(ITab tab)
{
_allTabs.Remove(tab);
TabBar.ActionBar.RemoveChild(tab as GuiWidget);
body.RemoveChild(tab.TabContent);
ActiveTab = _allTabs.LastOrDefault();
}
private ITab _activeTab;
public ITab ActiveTab
{
get => _activeTab;
set
{
if (_activeTab != value)
{
_activeTab = value;
var clickedWidget = value as GuiWidget;
foreach (var tab in _allTabs)
{
tab.TabContent.Visible = (tab == clickedWidget);
}
this.OnActiveTabChanged();
}
}
}
protected virtual void OnActiveTabChanged()
{
this.ActiveTabChanged?.Invoke(this, null);
}
}
public class ChromeTabs : SimpleTabs
{
private NewTabButton plusTabButton;
public ChromeTabs(GuiWidget rightAnchorItem, ThemeConfig theme)
: base(rightAnchorItem, theme)
{
// TODO: add in the printers and designs that are currently open (or were open last run).
var leadingTabAdornment = new GuiWidget()
{
MinimumSize = new VectorMath.Vector2(16, theme.shortButtonHeight),
VAnchor = VAnchor.Bottom
};
leadingTabAdornment.AfterDraw += (s, e) =>
{
var firstItem = this.AllTabs.OfType<MainTab>().FirstOrDefault();
MainTab.DrawTabLowerRight(e.graphics2D, leadingTabAdornment.LocalBounds, (firstItem == this.ActiveTab) ? MainTab.ActiveTabColor : MainTab.InactiveTabColor);
};
this.TabBar.ActionBar.AddChild(leadingTabAdornment);
// TODO: add in the printers and designs that are currently open (or were open last run).
plusTabButton = new NewTabButton(
AggContext.StaticData.LoadIcon("fa-plus_12.png", IconColor.Theme),
this,
theme)
{
VAnchor = VAnchor.Bottom,
MinimumSize = new Vector2(16, theme.shortButtonHeight),
ToolTipText = "Create New".Localize()
};
plusTabButton.IconButton.Click += (s, e) =>
{
this.AddTab(
new MainTab("New Tab".Localize(), this, this.NewTabPage())
{
MinimumSize = new Vector2(0, theme.shortButtonHeight)
});
};
this.TabBar.ActionBar.AddChild(plusTabButton);
}
public void AddTab(GuiWidget tab)
{
var position = this.TabBar.ActionBar.GetChildIndex(plusTabButton);
if (tab is MainTab mainTab)
{
mainTab.PreviousTab = this.AllTabs.OfType<MainTab>().LastOrDefault();
if (mainTab.PreviousTab != null)
{
mainTab.PreviousTab.NextTab = mainTab;
}
this.AddTab(tab, position);
mainTab.CloseClicked += MainTab_CloseClicked;
this.ActiveTab = mainTab;
}
}
private void MainTab_CloseClicked(object sender, EventArgs e)
{
if (sender is ITab tab)
{
this.RemoveTab(sender as ITab);
if (tab.TabContent is PrinterTabPage printerTab)
{
printerTab.printer.Settings.Helpers.SetMarkedForDelete(true);
}
}
}
public Func<GuiWidget> NewTabPage { get; set; }
protected override void OnActiveTabChanged()
{
plusTabButton.LastTab = this.AllTabs.LastOrDefault();
base.OnActiveTabChanged();
}
}
}

View file

@ -30,15 +30,12 @@ either expressed or implied, of the FreeBSD Project.
using System;
using System.Diagnostics;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using MatterHackers.Agg;
using MatterHackers.Agg.UI;
using MatterHackers.GCodeVisualizer;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.CustomWidgets;
using MatterHackers.MatterControl.PrintQueue;
using MatterHackers.MatterControl.SlicerConfiguration;
namespace MatterHackers.MatterControl.PartPreviewWindow
{