2017-10-18 22:49:03 -07:00
|
|
|
|
/*
|
|
|
|
|
|
Copyright (c) 2017, 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 System;
|
2017-10-17 12:35:24 -07:00
|
|
|
|
using System.Collections.Generic;
|
2019-03-19 18:20:54 -07:00
|
|
|
|
using System.Linq;
|
2017-10-17 12:35:24 -07:00
|
|
|
|
using MatterHackers.Agg;
|
2016-06-01 18:17:11 -07:00
|
|
|
|
using MatterHackers.Agg.UI;
|
|
|
|
|
|
using MatterHackers.VectorMath;
|
|
|
|
|
|
|
|
|
|
|
|
namespace MatterHackers.MatterControl
|
|
|
|
|
|
{
|
2017-11-08 15:56:37 -08:00
|
|
|
|
public class DialogWindow : SystemWindow
|
2016-06-01 18:17:11 -07:00
|
|
|
|
{
|
2017-11-08 15:56:37 -08:00
|
|
|
|
private DialogPage activePage;
|
2016-12-29 06:55:12 -08:00
|
|
|
|
private EventHandler unregisterEvents;
|
2020-06-24 17:54:16 -07:00
|
|
|
|
private static Dictionary<(Type, int), DialogWindow> allWindows = new Dictionary<(Type, int), DialogWindow>();
|
2018-10-13 17:58:54 -07:00
|
|
|
|
private ThemeConfig theme;
|
2016-06-08 16:52:56 -07:00
|
|
|
|
|
2019-03-19 18:20:54 -07:00
|
|
|
|
protected DialogWindow()
|
2016-06-08 16:52:56 -07:00
|
|
|
|
: base(500 * GuiWidget.DeviceScale, 500 * GuiWidget.DeviceScale)
|
|
|
|
|
|
{
|
2018-10-13 17:58:54 -07:00
|
|
|
|
theme = ApplicationController.Instance.Theme;
|
2018-07-12 09:22:28 -07:00
|
|
|
|
|
2016-06-10 15:26:25 -07:00
|
|
|
|
this.AlwaysOnTopOfMain = true;
|
2020-07-22 08:05:39 -07:00
|
|
|
|
this.MinimumSize = new Vector2(200 * GuiWidget.DeviceScale, 200 * GuiWidget.DeviceScale);
|
2018-10-20 22:21:00 -07:00
|
|
|
|
this.SetBackgroundColor();
|
2018-06-18 09:43:20 -07:00
|
|
|
|
|
2018-07-12 09:22:28 -07:00
|
|
|
|
var defaultPadding = theme.DefaultContainerPadding;
|
2018-06-18 09:43:20 -07:00
|
|
|
|
this.Padding = new BorderDouble(defaultPadding, defaultPadding, defaultPadding, 2);
|
2016-06-01 18:17:11 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-03-25 15:25:10 -07:00
|
|
|
|
public bool UseChildWindowSize { get; protected set; } = true;
|
|
|
|
|
|
|
2020-06-24 17:54:16 -07:00
|
|
|
|
public static void Close(Type type, int instanceIndex = 0)
|
2016-06-08 18:26:08 -07:00
|
|
|
|
{
|
2020-06-24 17:54:16 -07:00
|
|
|
|
if (allWindows.TryGetValue((type, instanceIndex), out DialogWindow existingWindow))
|
2016-06-08 18:26:08 -07:00
|
|
|
|
{
|
|
|
|
|
|
existingWindow.Close();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-11-08 15:56:37 -08:00
|
|
|
|
public static void Show<PanelType>() where PanelType : DialogPage, new()
|
2016-06-08 16:52:56 -07:00
|
|
|
|
{
|
2017-11-08 15:56:37 -08:00
|
|
|
|
DialogWindow wizardWindow = GetWindow(typeof(PanelType));
|
2017-08-23 15:51:29 -07:00
|
|
|
|
var newPanel = wizardWindow.ChangeToPage<PanelType>();
|
2017-10-17 12:35:24 -07:00
|
|
|
|
wizardWindow.Title = newPanel.WindowTitle;
|
|
|
|
|
|
|
|
|
|
|
|
SetSizeAndShow(wizardWindow, newPanel);
|
2016-07-13 17:12:45 -07:00
|
|
|
|
}
|
2016-06-08 16:52:56 -07:00
|
|
|
|
|
2020-06-24 17:54:16 -07:00
|
|
|
|
public static DialogWindow Show(DialogPage wizardPage, int instanceIndex = 0)
|
2016-07-13 17:12:45 -07:00
|
|
|
|
{
|
2020-06-24 17:54:16 -07:00
|
|
|
|
DialogWindow wizardWindow = GetWindow(wizardPage.GetType(), instanceIndex);
|
2017-08-23 15:51:29 -07:00
|
|
|
|
wizardWindow.Title = wizardPage.WindowTitle;
|
2017-10-17 12:35:24 -07:00
|
|
|
|
|
|
|
|
|
|
SetSizeAndShow(wizardWindow, wizardPage);
|
|
|
|
|
|
|
2016-07-13 17:12:45 -07:00
|
|
|
|
wizardWindow.ChangeToPage(wizardPage);
|
2018-05-23 17:54:31 -07:00
|
|
|
|
|
|
|
|
|
|
return wizardWindow;
|
2016-06-08 16:52:56 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-04-04 17:18:52 -07:00
|
|
|
|
public static DialogWindow Show(IStagedSetupWizard setupWizard, bool advanceToIncompleteStage = false)
|
2019-03-20 13:10:26 -07:00
|
|
|
|
{
|
2019-04-04 17:18:12 -07:00
|
|
|
|
var type = setupWizard.GetType();
|
2020-06-24 17:54:16 -07:00
|
|
|
|
var instanceIndex = 0;
|
2019-03-20 13:10:26 -07:00
|
|
|
|
|
2019-04-04 17:18:12 -07:00
|
|
|
|
var wizardWindow = new StagedSetupWindow(setupWizard);
|
2020-08-13 11:15:30 -07:00
|
|
|
|
setupWizard.StagedSetupWindow = wizardWindow;
|
2020-06-24 17:54:16 -07:00
|
|
|
|
wizardWindow.Closed += (s, e) => allWindows.Remove((type, instanceIndex));
|
|
|
|
|
|
allWindows[(type, instanceIndex)] = wizardWindow;
|
2019-03-20 13:10:26 -07:00
|
|
|
|
|
2019-04-04 17:18:12 -07:00
|
|
|
|
wizardWindow.Size = setupWizard.WindowSize;
|
2019-03-25 15:35:36 -07:00
|
|
|
|
|
2019-04-04 17:18:12 -07:00
|
|
|
|
var homePage = setupWizard.HomePageGenerator();
|
2019-03-20 15:20:56 -07:00
|
|
|
|
SetSizeAndShow(wizardWindow, homePage);
|
|
|
|
|
|
|
2019-05-14 17:45:27 -07:00
|
|
|
|
setupWizard.AutoAdvance = advanceToIncompleteStage;
|
|
|
|
|
|
|
2019-04-04 17:18:52 -07:00
|
|
|
|
if (advanceToIncompleteStage)
|
|
|
|
|
|
{
|
|
|
|
|
|
wizardWindow.NextIncompleteStage();
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
wizardWindow.ChangeToPage(homePage);
|
|
|
|
|
|
}
|
2019-03-20 13:10:26 -07:00
|
|
|
|
|
|
|
|
|
|
return wizardWindow;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-02-16 13:55:27 -08:00
|
|
|
|
public static DialogWindow Show(ISetupWizard setupWizard)
|
|
|
|
|
|
{
|
|
|
|
|
|
DialogWindow wizardWindow = GetWindow(setupWizard.GetType());
|
2019-03-19 18:14:03 -07:00
|
|
|
|
wizardWindow.Title = setupWizard.Title;
|
2019-02-16 13:55:27 -08:00
|
|
|
|
|
2019-03-06 18:03:38 -08:00
|
|
|
|
if (setupWizard.WindowSize != Vector2.Zero)
|
|
|
|
|
|
{
|
|
|
|
|
|
wizardWindow.Size = setupWizard.WindowSize;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-03-20 13:19:55 -07:00
|
|
|
|
SetSizeAndShow(wizardWindow, setupWizard.Current);
|
2019-02-16 13:55:27 -08:00
|
|
|
|
|
2019-03-20 13:19:55 -07:00
|
|
|
|
wizardWindow.ChangeToPage(setupWizard.Current);
|
2019-02-16 13:55:27 -08:00
|
|
|
|
|
2019-03-01 17:43:04 -08:00
|
|
|
|
// Set focus to ensure Enter/Esc key handlers are caught
|
2019-03-20 13:19:55 -07:00
|
|
|
|
setupWizard.Current.Focus();
|
2019-03-01 17:43:04 -08:00
|
|
|
|
|
2019-02-16 13:55:27 -08:00
|
|
|
|
EventHandler windowClosed = null;
|
2019-03-01 17:43:04 -08:00
|
|
|
|
EventHandler<KeyEventArgs> windowKeyDown = null;
|
2019-02-16 13:55:27 -08:00
|
|
|
|
|
|
|
|
|
|
windowClosed = (s, e) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
setupWizard.Dispose();
|
|
|
|
|
|
wizardWindow.Closed -= windowClosed;
|
2019-03-01 17:43:04 -08:00
|
|
|
|
wizardWindow.KeyDown -= windowKeyDown;
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
windowKeyDown = (s, e) =>
|
|
|
|
|
|
{
|
|
|
|
|
|
switch (e.KeyCode)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Auto-advance to next page on enter key
|
|
|
|
|
|
case Keys.Enter:
|
2019-03-20 13:19:55 -07:00
|
|
|
|
if (setupWizard.Current is WizardPage currentPage && currentPage.NextButton.Enabled)
|
2019-03-01 17:43:04 -08:00
|
|
|
|
{
|
2019-03-20 13:19:55 -07:00
|
|
|
|
UiThread.RunOnIdle(() => currentPage.NextButton.InvokeClick());
|
2019-03-01 17:43:04 -08:00
|
|
|
|
}
|
2020-05-25 09:54:50 -07:00
|
|
|
|
|
2019-03-01 17:43:04 -08:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2019-02-16 13:55:27 -08:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
wizardWindow.Closed += windowClosed;
|
2019-03-01 17:43:04 -08:00
|
|
|
|
wizardWindow.KeyDown += windowKeyDown;
|
2019-02-16 13:55:27 -08:00
|
|
|
|
|
|
|
|
|
|
return wizardWindow;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2017-10-17 12:35:24 -07:00
|
|
|
|
// Allow the WizardPage MinimumSize to override our MinimumSize
|
|
|
|
|
|
public override Vector2 MinimumSize
|
|
|
|
|
|
{
|
|
|
|
|
|
get => activePage?.MinimumSize ?? base.MinimumSize;
|
|
|
|
|
|
set => base.MinimumSize = value;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-03-06 18:03:38 -08:00
|
|
|
|
public static void SetSizeAndShow(DialogWindow dialogWindow, DialogPage wizardPage)
|
2017-10-17 12:35:24 -07:00
|
|
|
|
{
|
2019-04-03 16:53:10 -07:00
|
|
|
|
if (dialogWindow.UseChildWindowSize
|
2019-03-06 18:03:38 -08:00
|
|
|
|
&& wizardPage.WindowSize != Vector2.Zero)
|
2017-10-17 12:35:24 -07:00
|
|
|
|
{
|
2019-03-06 18:03:38 -08:00
|
|
|
|
dialogWindow.Size = wizardPage.WindowSize;
|
2017-10-17 12:35:24 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-03-06 18:03:38 -08:00
|
|
|
|
dialogWindow.AlwaysOnTopOfMain = wizardPage.AlwaysOnTopOfMain;
|
2017-10-18 22:49:03 -07:00
|
|
|
|
|
2019-03-06 18:03:38 -08:00
|
|
|
|
dialogWindow.ShowAsSystemWindow();
|
2017-10-17 12:35:24 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2020-06-24 17:54:16 -07:00
|
|
|
|
public static bool IsOpen(Type type, int instanceIndex = 0) => allWindows.ContainsKey((type, instanceIndex));
|
2016-07-21 13:49:22 -07:00
|
|
|
|
|
2020-06-24 17:54:16 -07:00
|
|
|
|
private static DialogWindow GetWindow(Type type, int instanceIndex = 0)
|
2016-07-13 17:12:45 -07:00
|
|
|
|
{
|
2020-06-24 17:54:16 -07:00
|
|
|
|
if (allWindows.TryGetValue((type, instanceIndex), out DialogWindow wizardWindow))
|
2016-07-13 17:12:45 -07:00
|
|
|
|
{
|
|
|
|
|
|
wizardWindow.BringToFront();
|
2018-04-19 12:39:38 -07:00
|
|
|
|
wizardWindow.Focus();
|
2016-07-13 17:12:45 -07:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2017-11-08 15:56:37 -08:00
|
|
|
|
wizardWindow = new DialogWindow();
|
2020-06-24 17:54:16 -07:00
|
|
|
|
wizardWindow.Closed += (s, e) => allWindows.Remove((type, instanceIndex));
|
|
|
|
|
|
allWindows[(type, instanceIndex)] = wizardWindow;
|
2016-07-13 17:12:45 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return wizardWindow;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-05-14 22:37:24 -07:00
|
|
|
|
public virtual void ClosePage(bool allowAbort = true)
|
2019-03-20 16:05:06 -07:00
|
|
|
|
{
|
|
|
|
|
|
// Close this dialog window
|
2019-07-06 13:24:57 -07:00
|
|
|
|
this.CloseOnIdle();
|
2019-03-20 16:05:06 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2018-08-23 16:44:11 -07:00
|
|
|
|
public override void OnClosed(EventArgs e)
|
2016-06-08 16:52:56 -07:00
|
|
|
|
{
|
2016-12-09 10:40:01 -08:00
|
|
|
|
unregisterEvents?.Invoke(this, null);
|
2016-06-08 16:52:56 -07:00
|
|
|
|
base.OnClosed(e);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-03-19 18:20:54 -07:00
|
|
|
|
public virtual void ChangeToPage(DialogPage pageToChangeTo)
|
2016-06-15 11:49:57 -07:00
|
|
|
|
{
|
2017-10-17 12:35:24 -07:00
|
|
|
|
activePage = pageToChangeTo;
|
|
|
|
|
|
|
2018-06-19 15:02:25 -07:00
|
|
|
|
pageToChangeTo.DialogWindow = this;
|
2021-01-29 16:44:47 -08:00
|
|
|
|
this.CloseChildren();
|
2016-12-09 12:09:28 -08:00
|
|
|
|
this.AddChild(pageToChangeTo);
|
2018-11-28 17:40:11 -08:00
|
|
|
|
|
2016-12-09 12:09:28 -08:00
|
|
|
|
this.Invalidate();
|
2016-06-15 11:49:57 -07:00
|
|
|
|
}
|
|
|
|
|
|
|
2019-05-09 13:19:47 -07:00
|
|
|
|
public virtual void OnCancel(out bool abortCancel)
|
|
|
|
|
|
{
|
|
|
|
|
|
abortCancel = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-03-19 18:20:54 -07:00
|
|
|
|
public virtual DialogPage ChangeToPage<PanelType>() where PanelType : DialogPage, new()
|
2016-06-07 17:23:41 -07:00
|
|
|
|
{
|
2018-10-13 17:58:54 -07:00
|
|
|
|
var panel = new PanelType
|
|
|
|
|
|
{
|
|
|
|
|
|
DialogWindow = this
|
|
|
|
|
|
};
|
|
|
|
|
|
this.ChangeToPage(panel);
|
2016-12-09 10:40:01 -08:00
|
|
|
|
|
|
|
|
|
|
// in the event of a reload all make sure we rebuild the contents correctly
|
2019-07-06 08:00:03 -07:00
|
|
|
|
ApplicationController.Instance.DoneReloadingAll.RegisterEvent((s,e) =>
|
2016-12-09 10:40:01 -08:00
|
|
|
|
{
|
2018-10-13 17:58:54 -07:00
|
|
|
|
// 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;
|
|
|
|
|
|
|
2016-12-09 10:40:01 -08:00
|
|
|
|
// fix the main window background color if needed
|
2018-10-20 22:21:00 -07:00
|
|
|
|
this.SetBackgroundColor();
|
2016-12-09 10:40:01 -08:00
|
|
|
|
|
|
|
|
|
|
// find out where the contents we put in last time are
|
2019-07-03 20:39:01 -07:00
|
|
|
|
int thisIndex = Children.IndexOf(panel);
|
2021-01-29 16:44:47 -08:00
|
|
|
|
this.RemoveChildren();
|
2017-10-18 22:49:03 -07:00
|
|
|
|
|
2016-12-09 10:40:01 -08:00
|
|
|
|
// make new content with the possibly changed theme
|
2018-10-13 17:58:54 -07:00
|
|
|
|
var newPanel = new PanelType
|
|
|
|
|
|
{
|
|
|
|
|
|
DialogWindow = this
|
|
|
|
|
|
};
|
|
|
|
|
|
this.AddChild(newPanel, thisIndex);
|
2019-07-06 13:24:57 -07:00
|
|
|
|
panel.CloseOnIdle();
|
2017-10-18 22:49:03 -07:00
|
|
|
|
|
2016-12-09 10:40:01 -08:00
|
|
|
|
// remember the new content
|
|
|
|
|
|
panel = newPanel;
|
2019-07-06 08:00:03 -07:00
|
|
|
|
}, ref unregisterEvents);
|
2017-08-23 15:51:29 -07:00
|
|
|
|
|
|
|
|
|
|
return panel;
|
2016-06-07 17:23:41 -07:00
|
|
|
|
}
|
2018-10-20 22:21:00 -07:00
|
|
|
|
|
|
|
|
|
|
private void SetBackgroundColor()
|
|
|
|
|
|
{
|
2018-11-03 09:50:09 -07:00
|
|
|
|
this.BackgroundColor = theme.BackgroundColor;
|
2018-10-20 22:21:00 -07:00
|
|
|
|
}
|
2016-06-01 18:17:11 -07:00
|
|
|
|
}
|
|
|
|
|
|
}
|