First pass of interface tour is ready

issue: MatterHackers/MCCentral#4561
Create new startup Ui walk through to show users where ui elements can be found
This commit is contained in:
Lars Brubaker 2018-11-29 09:53:48 -08:00
parent a1b7870565
commit 9d6db74793
8 changed files with 180 additions and 76 deletions

View file

@ -811,7 +811,7 @@ namespace MatterHackers.MatterControl
{
UiThread.RunOnIdle(() =>
{
TourOverlay.ShowSite(this.MainView.TopmostParent(), Theme, 0);
TourOverlay.ShowSite(this.MainView.TopmostParent(), 0);
});
}
@ -3178,6 +3178,14 @@ If you experience adhesion problems, please re-run leveling."
{
await applicationController.Tasks.Execute(task.Title, task.Action);
}
//if (UserSettings.Instance.get(UserSettingsKey.ShownWelcomMessage) != "true")
{
UiThread.RunOnIdle(() =>
{
DialogWindow.Show<WelcomePage>();
});
}
}
catch
{

View file

@ -104,7 +104,8 @@ namespace MatterHackers.MatterControl.PrintLibrary
Margin = theme.ButtonSpacing,
ToolTipText = "Import Printer".Localize(),
Height = forcedHeight,
Width = forcedHeight
Width = forcedHeight,
Name = "Import Printer Button"
};
importPrinter.Click += (s, e) => UiThread.RunOnIdle(() =>
{

View file

@ -56,7 +56,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private Toolbar statusBar;
private FlowLayoutWidget tasksContainer;
private GuiWidget stretchStatusPanel;
private LinkLabel seeWhatsNewButton;
private LinkLabel updateAvailableButton;
public MainViewWidget(ThemeConfig theme)
@ -99,23 +98,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
// Force common padding into top region
tabControl.TabBar.Padding = theme.TabbarPadding.Clone(top: theme.TabbarPadding.Top * 2, bottom: 0);
// add in a what's new button
seeWhatsNewButton = new LinkLabel("What's New...".Localize(), theme)
{
Name = "What's New Link",
ToolTipText = "See what's new in this version of MatterControl".Localize(),
VAnchor = VAnchor.Center,
Margin = new BorderDouble(10, 0),
TextColor = theme.TextColor
};
seeWhatsNewButton.Click += (s, e) => UiThread.RunOnIdle(() =>
{
UserSettings.Instance.set(UserSettingsKey.LastReadWhatsNew, JsonConvert.SerializeObject(DateTime.Now));
DialogWindow.Show(new HelpPage("What's New"));
});
tabControl.TabBar.ActionArea.AddChild(seeWhatsNewButton);
// add in the update available button
updateAvailableButton = new LinkLabel("Update Available".Localize(), theme)
{
@ -395,12 +377,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
private void SetLinkButtonsVisibility (object s, StringEventArgs e)
{
if (UserSettings.Instance.HasLookedAtWhatsNew())
{
// hide it
seeWhatsNewButton.Visible = false;
}
if (UpdateControlData.Instance.UpdateStatus == UpdateControlData.UpdateStatusStates.UpdateAvailable)
{
if (!updateAvailableButton.Visible)
@ -408,9 +384,6 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
updateAvailableButton.Visible = true;
UiThread.RunOnIdle(this.ShowUpdateAvailableAnimation);
// if we are going to show the update link hide the whats new link no matter what
seeWhatsNewButton.Visible = false;
}
}
else
@ -484,6 +457,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
BorderColor = theme.SlightShade,
Cursor = Cursors.Hand,
ToolTipText = "Theme".Localize(),
Name = "Theme Select Button"
};
themePanel.AddChild(

View file

@ -287,6 +287,7 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
Margin = new BorderDouble(0, 0, 10, 35),
VAnchor = VAnchor.Top,
HAnchor = HAnchor.Right,
Name = "Tumble Cube Control"
};
this.InteractionLayer.AddChild(tumbleCubeControl);
@ -296,7 +297,8 @@ namespace MatterHackers.MatterControl.PartPreviewWindow
HAnchor = HAnchor.Right | HAnchor.Fit,
VAnchor = VAnchor.Top | VAnchor.Fit,
//Margin = new BorderDouble(top: tumbleCubeControl.Height + tumbleCubeControl.Margin.Height + 2),
BackgroundColor = theme.MinimalShade
BackgroundColor = theme.MinimalShade,
Name = "View Options Bar"
};
this.InteractionLayer.AddChild(viewOptionsBar);

View file

@ -12,6 +12,7 @@ namespace MatterHackers.MatterControl
{
public static class UserSettingsKey
{
public const string ActiveThemeName = nameof(ActiveThemeName);
public const string AfterPrintFinishedPlaySound = nameof(AfterPrintFinishedPlaySound);
public const string AfterPrintFinishedSendEmail = nameof(AfterPrintFinishedSendEmail);
public const string AfterPrintFinishedSendTextMessage = nameof(AfterPrintFinishedSendTextMessage);
@ -21,13 +22,12 @@ namespace MatterHackers.MatterControl
public const string ConfigurePrinter_CurrentTab = nameof(ConfigurePrinter_CurrentTab);
public const string ConfigurePrinterTabVisible = nameof(ConfigurePrinterTabVisible);
public const string ControlsTabVisible = nameof(ControlsTabVisible);
public const string TerminalTabVisible = nameof(TerminalTabVisible);
public const string CredentialsInvalid = nameof(CredentialsInvalid);
public const string CredentialsInvalidReason = nameof(CredentialsInvalidReason);
public const string defaultRenderSetting = nameof(defaultRenderSetting);
public const string SnapGridDistance = nameof(SnapGridDistance);
public const string DisplayedTip_LoadFilament = nameof(DisplayedTip_LoadFilament);
public const string EditorPanelExpanded = nameof(EditorPanelExpanded);
public const string FavoritesBarExpansion= nameof(FavoritesBarExpansion);
public const string GCodeLineColorStyle = nameof(GCodeLineColorStyle);
public const string GcodeModelView = nameof(GcodeModelView);
public const string GcodeViewerHideExtruderOffsets = nameof(GcodeViewerHideExtruderOffsets);
@ -45,30 +45,30 @@ namespace MatterHackers.MatterControl
public const string NotificationEmailAddress = nameof(NotificationEmailAddress);
public const string NotificationPhoneNumber = nameof(NotificationPhoneNumber);
public const string OpenScadPath = nameof(OpenScadPath);
public const string PopupLibraryWidth = nameof(PopupLibraryWidth);
public const string PrintHistoryFilterShowCompleted = nameof(PrintHistoryFilterShowCompleted);
public const string PrintNotificationsEnabled = nameof(PrintNotificationsEnabled);
public const string PrintNotificationsIncludeImage = nameof(PrintNotificationsIncludeImage);
public const string PublicProfilesSha = nameof(PublicProfilesSha);
public const string ScalePanelExpanded = nameof(ScalePanelExpanded);
public const string SceneTreeRatio = nameof(SceneTreeRatio);
public const string SelectedObjectEditorHeight = nameof(SelectedObjectEditorHeight);
public const string SelectedObjectPanelWidth = nameof(SelectedObjectPanelWidth);
public const string SelectionTreeViewPanelExpanded = nameof(SelectionTreeViewPanelExpanded);
public const string ShowContainers = nameof(ShowContainers);
public const string SliceSettingsTabIndex = nameof(SliceSettingsTabIndex);
public const string SliceSettingsTabPinned = nameof(SliceSettingsTabPinned);
public const string SliceSettingsWidget_CurrentTab = nameof(SliceSettingsWidget_CurrentTab);
public const string SliceSettingsWidth = nameof(SliceSettingsWidth);
public const string PopupLibraryWidth = nameof(PopupLibraryWidth);
public const string SnapGridDistance = nameof(SnapGridDistance);
public const string SoftwareLicenseAccepted = nameof(SoftwareLicenseAccepted);
public const string TerminalAutoUppercase = nameof(TerminalAutoUppercase);
public const string TerminalFilterOutput = nameof(TerminalFilterOutput);
public const string TerminalTabVisible = nameof(TerminalTabVisible);
public const string ThemeName = nameof(ThemeName);
public const string ThumbnailRenderingMode = nameof(ThumbnailRenderingMode);
public const string UpdateFeedType = nameof(UpdateFeedType);
public const string LastReadWhatsNew = nameof(LastReadWhatsNew);
public const string ActiveThemeName = nameof(ActiveThemeName);
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 FavoritesBarExpansion= nameof(FavoritesBarExpansion);
public const string ShownWelcomMessage = nameof(ShownWelcomMessage);
}
public class UserSettings
@ -121,26 +121,6 @@ namespace MatterHackers.MatterControl
}
}
public bool HasLookedAtWhatsNew()
{
// If the last time what's new link was clicked is older than the main application show the button
string filePath = Assembly.GetExecutingAssembly().Location;
DateTime installTime = new FileInfo(filePath).LastWriteTime;
var lastReadWhatsNew = UserSettings.Instance.get(UserSettingsKey.LastReadWhatsNew);
DateTime whatsNewReadTime = installTime;
if (!string.IsNullOrWhiteSpace(lastReadWhatsNew))
{
try
{
whatsNewReadTime = JsonConvert.DeserializeObject<DateTime>(lastReadWhatsNew);
}
catch { }
}
return whatsNewReadTime > installTime;
}
public string Language { get; private set; }
public UserSettingsFields Fields { get; private set; } = new UserSettingsFields();

View file

@ -65,12 +65,12 @@ namespace MatterControlLib.SetupWizard
HAnchor = HAnchor.Absolute,
VAnchor = VAnchor.Fit,
Padding = new BorderDouble(5),
BackgroundColor = Color.White
BackgroundColor = theme.BackgroundColor
};
this.AddChild(content);
content.AddChild(new WrappedTextWidget(Description)
content.AddChild(new WrappedTextWidget(Description, textColor: theme.TextColor)
{
Margin = new BorderDouble(5)
});
@ -89,7 +89,7 @@ namespace MatterControlLib.SetupWizard
{
var topWindow = this.TopmostParent();
this.Close();
ShowSite(topWindow, theme, nextSiteIndex);
ShowSite(topWindow, nextSiteIndex);
};
buttonRow.AddChild(nextButton);
}
@ -103,7 +103,42 @@ namespace MatterControlLib.SetupWizard
// and last, set the size
var childBounds = GetChildBounds();
content.Size = new Vector2(250, content.Height);
content.Position = new Vector2(childBounds.Left, childBounds.Bottom - content.Size.Y);
if(childBounds.Right >= this.Width - content.Width - 5)
{
var left = childBounds.Right - content.Width;
if (childBounds.Bottom < this.Height / 2)
{
if (childBounds.Bottom - content.Size.Y < 0)
{
// position above
content.Position = new Vector2(left, childBounds.Top);
}
else
{
// position content to the left of site
content.Position = new Vector2(left, childBounds.Top - content.Size.Y);
}
}
else
{
// position content under site
content.Position = new Vector2(left, childBounds.Bottom - content.Size.Y);
}
}
else
{
if(childBounds.Bottom < this.Height / 2)
{
// position content to the right of site
content.Position = new Vector2(childBounds.Right, childBounds.Top - content.Size.Y);
}
else
{
// position content under site
content.Position = new Vector2(childBounds.Left, childBounds.Bottom - content.Size.Y);
}
}
this.Focus();
@ -120,14 +155,13 @@ namespace MatterControlLib.SetupWizard
{
var topWindow = this.TopmostParent();
this.Close();
ShowSite(topWindow, theme, nextSiteIndex);
ShowSite(topWindow, nextSiteIndex);
}
base.OnKeyDown(keyEvent);
}
public override void OnDraw(Graphics2D graphics2D)
{
DoubleBuffer = true;
var dimRegion = new VertexStorage();
dimRegion.MoveTo(LocalBounds.Left, LocalBounds.Bottom);
dimRegion.LineTo(LocalBounds.Right, LocalBounds.Bottom);
@ -149,8 +183,8 @@ namespace MatterControlLib.SetupWizard
base.OnDraw(graphics2D);
graphics2D.Render(new Stroke(new RoundedRect(GetChildBounds(), 3), 4), Color.Red);
graphics2D.Render(new Stroke(new RoundedRect(GetContentBounds(), 3), 4), Color.Red);
graphics2D.Render(new Stroke(new RoundedRect(GetChildBounds(), 3), 4), theme.PrimaryAccentColor);
graphics2D.Render(new Stroke(new RoundedRect(GetContentBounds(), 3), 4), theme.PrimaryAccentColor);
}
private RectangleDouble GetContentBounds()
@ -167,15 +201,25 @@ namespace MatterControlLib.SetupWizard
return childBounds;
}
public static void ShowSite(GuiWidget window, ThemeConfig theme, int siteIndex)
public static void ShowSite(GuiWidget window, int siteIndex)
{
var tourSites = new List<(string site, string description)>();
tourSites.Add(("Open File Button", "Add parts from your hard drive to the bed"));
tourSites.Add(("LibraryView", "Drag primitives to the bed to create your own designs"));
tourSites.Add(("Add Content Menu", "Browse your library to find parts you have previously designed"));
tourSites.Add(("Make Support Button", "Create custom supports. Turn any object on the bed into support material"));
tourSites.Add(("Open File Button", "Add parts from your hard drive to the bed."));
tourSites.Add(("LibraryView", "Drag primitives to the bed to create your own designs."));
tourSites.Add(("Add Content Menu", "Browse your library to find parts you have previously designed."));
tourSites.Add(("Make Support Button", "Create custom supports. Turn any object on the bed into support material."));
tourSites.Add(("Create Printer", "Setup a printer for the first time. Dozens of profiles are available to give you optimized settings."));
tourSites.Add(("Theme Select Button", "Change your color theme anytime you want."));
tourSites.Add(("Authentication Sign In", "Click here to sign into you MatterHackers account."));
tourSites.Add(("MatterControl BrandMenuButton", "Here you can find application settings, help docs, updates and more."));
tourSites.Add(("View Options Bar", "Reset the view, change viewing modes, hide and show the bed, and adjust the grid snap."));
tourSites.Add(("Tumble Cube Control", "Adjust the position of your view. You can also snap to specific views by clicking the cube."));
tourSites.Add(("Print Button", "Click here to start a print. This will also help you setup a printer if needed."));
tourSites.Add(("PrintPopupMenu", "Click here to start a print."));
tourSites.Add(("Hotend 0", "Your printers hotend controls. Set your temperatures, materials and load & unload filament."));
tourSites.Add(("Slice Settings Sidebar", "Have compete control of your printer with the ability to adjust individual print settings."));
if(siteIndex >= tourSites.Count)
if (siteIndex >= tourSites.Count)
{
siteIndex -= tourSites.Count;
}
@ -203,7 +247,7 @@ namespace MatterControlLib.SetupWizard
if (targetWidget != null)
{
var tourOverlay = new TourOverlay(targetWidget, tourSites[siteIndex].description, theme, siteIndex + 1);
var tourOverlay = new TourOverlay(targetWidget, tourSites[siteIndex].description, ApplicationController.Instance.MenuTheme, siteIndex + 1);
window.AddChild(tourOverlay);
}
}

View file

@ -0,0 +1,95 @@
/*
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 MatterControlLib.SetupWizard;
using MatterHackers.Agg;
using MatterHackers.Agg.UI;
using MatterHackers.Localizations;
using MatterHackers.MatterControl.CustomWidgets;
namespace MatterHackers.MatterControl
{
public class WelcomePage : DialogPage
{
public WelcomePage()
: base("Done".Localize())
{
this.WindowTitle = "MatterControl".Localize();
this.HeaderText = "Welcome to MatterControl".Localize();
var welcome = @"Thank you for installing MatterControl. We are excited to help you bring your ideas to life. This new version includes hundreds of improvmets and new features.
Features:
Simple Setup
Automatic Leveling
Built in 3D Design Tools
Customizable Supports
SMS / Email Notifications
Enhanced 64 Bit support
Click 'Next' to for a quick tour of the interface";
var textWidget = new WrappedTextWidget(welcome)
{
Margin = new BorderDouble(left: 10, top: 10),
TextColor = theme.TextColor,
HAnchor = HAnchor.Stretch
};
contentRow.AddChild(textWidget);
var nextButton = new TextButton("Next".Localize(), theme)
{
Name = "Next Button",
BackgroundColor = theme.MinimalShade
};
nextButton.Click += (s, e) =>
{
this.DialogWindow.CloseOnIdle();
UiThread.RunOnIdle(() =>
{
TourOverlay.ShowSite(ApplicationController.Instance.MainView.TopmostParent(), 0);
});
};
this.AddPageAction(nextButton);
}
public override void OnClosed(EventArgs e)
{
UserSettings.Instance.set(UserSettingsKey.ShownWelcomMessage, "true");
base.OnClosed(e);
}
}
}

@ -1 +1 @@
Subproject commit 42a557dfab09fb93e9ac58a5646c353fb6122cc5
Subproject commit d2dbc0f1321aa252a2cb08d03da12a0b13fb2201