From a9e5e14c9dec8b7f549388a0ce92fb16d50c7b72 Mon Sep 17 00:00:00 2001 From: jrhodnik Date: Mon, 27 May 2019 07:02:20 -0400 Subject: [PATCH] More GUI stuff. Added input sanitization. Added GUI for actions. --- VDash/MainWindow.xaml.cs | 6 +- .../Actions/BringWindowToFrontAction.cs | 15 ++- VDash/Overlay/Actions/IOverlayAction.cs | 31 +++++ VDash/Overlay/Actions/IWindowAction.cs | 12 ++ VDash/Overlay/Actions/MaximizeWindowAction.cs | 11 +- VDash/Overlay/Actions/MinimizeWIndowAction.cs | 40 +++++++ VDash/Overlay/Actions/ResizeWindowAction.cs | 14 ++- VDash/Overlay/Actions/RestoreWindowAction.cs | 10 +- VDash/Overlay/Config/WindowOverlayConfig.cs | 5 + VDash/Overlay/IOverlay.cs | 3 - VDash/Overlay/WindowOverlay.cs | 8 +- VDash/UI/ActionEditors/IActionEditor.cs | 13 +++ .../ResizeWindowActionEditor.xaml | 34 ++++++ .../ResizeWindowActionEditor.xaml.cs | 108 ++++++++++++++++++ VDash/UI/CreateNewOverlay.xaml.cs | 15 +++ VDash/UI/IOverlayEditor.cs | 1 + VDash/UI/ISelectorEditor.cs | 13 +++ VDash/UI/MonitorOverlayEditor.xaml | 2 +- VDash/UI/MonitorOverlayEditor.xaml.cs | 10 ++ VDash/UI/OverlayEditor.xaml | 5 +- VDash/UI/OverlayEditor.xaml.cs | 28 ++++- VDash/UI/ProcessSelectorEditor.xaml.cs | 13 ++- VDash/UI/WindowOverlayEditor.xaml | 38 ++++++ VDash/UI/WindowOverlayEditor.xaml.cs | 95 ++++++++++++++- VDash/UI/WindowSelectorEditor.xaml.cs | 16 ++- VDash/VDash.csproj | 14 +++ VDash/packages.config | 1 + 27 files changed, 535 insertions(+), 26 deletions(-) create mode 100644 VDash/Overlay/Actions/IWindowAction.cs create mode 100644 VDash/Overlay/Actions/MinimizeWIndowAction.cs create mode 100644 VDash/UI/ActionEditors/IActionEditor.cs create mode 100644 VDash/UI/ActionEditors/ResizeWindowActionEditor.xaml create mode 100644 VDash/UI/ActionEditors/ResizeWindowActionEditor.xaml.cs create mode 100644 VDash/UI/ISelectorEditor.cs diff --git a/VDash/MainWindow.xaml.cs b/VDash/MainWindow.xaml.cs index 7a3095a..30c39d5 100644 --- a/VDash/MainWindow.xaml.cs +++ b/VDash/MainWindow.xaml.cs @@ -42,14 +42,16 @@ namespace VDash var ret = OpenVR.Init(ref initError, EVRApplicationType.VRApplication_Overlay); +#if !DEBUG if (initError != EVRInitError.None) { throw new Exception($"Error connecting to VR: {initError.ToString()}"); } +#endif lvOverlays.ItemsSource = OverlayManager.Overlays; - #region Debug +#region Debug //StartOverlayWindow("Discord"); @@ -75,7 +77,7 @@ namespace VDash //mo1.Create(); //MonitorOverlay mo2= new MonitorOverlay("right", "Right Monitor", displays[2]); //mo2.Create(); - #endregion +#endregion } private void btnAdd_Click(object sender, RoutedEventArgs e) diff --git a/VDash/Overlay/Actions/BringWindowToFrontAction.cs b/VDash/Overlay/Actions/BringWindowToFrontAction.cs index d216c3c..e638b5e 100644 --- a/VDash/Overlay/Actions/BringWindowToFrontAction.cs +++ b/VDash/Overlay/Actions/BringWindowToFrontAction.cs @@ -9,7 +9,8 @@ using VDash.Utilities; namespace VDash.Overlay.Actions { - public class BringWindowToFrontAction : IOverlayAction + [OverlayActionInfo("Bring Window to Front")] + public class BringWindowToFrontAction : IWindowAction { /// /// Unminimize the window if it's minimized. @@ -17,11 +18,18 @@ namespace VDash.Overlay.Actions public bool UnminimizeIfMinimized { get; set; } public bool Enabled { get; set; } = true; + public Type Editor { get; } = null; + public BringWindowToFrontAction(bool unminimizeIfMinimized) { UnminimizeIfMinimized = unminimizeIfMinimized; } + public BringWindowToFrontAction() + { + UnminimizeIfMinimized = true; + } + public void PreformAction(IOverlay intOverlay) { if (!Enabled) { return; } @@ -50,5 +58,10 @@ namespace VDash.Overlay.Actions User32.SetForegroundWindow(handle); } + public override string ToString() + { + var attribute = (OverlayActionInfo)this.GetType().GetCustomAttributes(typeof(OverlayActionInfo), false).Single(); + return attribute.Description; + } } } diff --git a/VDash/Overlay/Actions/IOverlayAction.cs b/VDash/Overlay/Actions/IOverlayAction.cs index 44b5d0a..d9f94d1 100644 --- a/VDash/Overlay/Actions/IOverlayAction.cs +++ b/VDash/Overlay/Actions/IOverlayAction.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Reflection; using System.Text; using System.Threading.Tasks; @@ -11,4 +12,34 @@ namespace VDash.Overlay.Actions void PreformAction(IOverlay overlay); bool Enabled { get; set; } } + + [AttributeUsage(AttributeTargets.Class, AllowMultiple = false)] + public class OverlayActionInfo : System.Attribute + { + public string Description { get; private set; } + public Type EditorType { get; private set; } + public OverlayActionInfo(string description, Type editorType) + { + Description = description; + EditorType = editorType; + } + + public OverlayActionInfo(string description) + { + Description = description; + EditorType = null; + } + + public static IEnumerable GetTypesWithAttribute() + { + var assembly = Assembly.GetExecutingAssembly(); + foreach (Type type in assembly.GetTypes()) + { + if (type.GetCustomAttributes(typeof(OverlayActionInfo), true).Length > 0) + { + yield return type; + } + } + } + } } diff --git a/VDash/Overlay/Actions/IWindowAction.cs b/VDash/Overlay/Actions/IWindowAction.cs new file mode 100644 index 0000000..8fc2b48 --- /dev/null +++ b/VDash/Overlay/Actions/IWindowAction.cs @@ -0,0 +1,12 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace VDash.Overlay.Actions +{ + public interface IWindowAction : IOverlayAction + { + } +} diff --git a/VDash/Overlay/Actions/MaximizeWindowAction.cs b/VDash/Overlay/Actions/MaximizeWindowAction.cs index 8edfbf0..67aade3 100644 --- a/VDash/Overlay/Actions/MaximizeWindowAction.cs +++ b/VDash/Overlay/Actions/MaximizeWindowAction.cs @@ -8,10 +8,11 @@ using VDash.Utilities; namespace VDash.Overlay.Actions { - public class MaximizeWindowAction : IOverlayAction + [OverlayActionInfo("Maximize Window")] + public class MaximizeWindowAction : IWindowAction { public bool Enabled { get; set; } - + public void PreformAction(IOverlay intOverlay) { if (!Enabled) { return; } @@ -30,5 +31,11 @@ namespace VDash.Overlay.Actions { User32.ShowWindow(handle, User32.ShowWindowCommands.Maximize); } + + public override string ToString() + { + var attribute = (OverlayActionInfo)this.GetType().GetCustomAttributes(typeof(OverlayActionInfo), false).Single(); + return attribute.Description; + } } } diff --git a/VDash/Overlay/Actions/MinimizeWIndowAction.cs b/VDash/Overlay/Actions/MinimizeWIndowAction.cs new file mode 100644 index 0000000..09a0fe2 --- /dev/null +++ b/VDash/Overlay/Actions/MinimizeWIndowAction.cs @@ -0,0 +1,40 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using VDash.Utilities; + +namespace VDash.Overlay.Actions +{ + [OverlayActionInfo("Minize Window")] + public class MinimizeWIndowAction : IWindowAction + { + public bool Enabled { get; set; } = true; + + public void PreformAction(IOverlay intOverlay) + { + if (!Enabled) { return; } + if (!intOverlay.GetType().IsAssignableFrom(typeof(WindowOverlay))) + { + Console.WriteLine("This action cannot be performed on a non-WindowOverlay overlay."); + return; + } + + WindowOverlay overlay = (WindowOverlay)intOverlay; + IntPtr handle = overlay.Config.Selector.GetWindowHandle(); + PreformAction(handle); + } + + public void PreformAction(IntPtr handle) + { + User32.ShowWindow(handle, User32.ShowWindowCommands.Minimize); + } + + public override string ToString() + { + var attribute = (OverlayActionInfo)this.GetType().GetCustomAttributes(typeof(OverlayActionInfo), false).Single(); + return attribute.Description; + } + } +} diff --git a/VDash/Overlay/Actions/ResizeWindowAction.cs b/VDash/Overlay/Actions/ResizeWindowAction.cs index dd47984..720bbb8 100644 --- a/VDash/Overlay/Actions/ResizeWindowAction.cs +++ b/VDash/Overlay/Actions/ResizeWindowAction.cs @@ -3,15 +3,17 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using VDash.UI.ActionEditors; using VDash.Utilities; namespace VDash.Overlay.Actions { - public class ResizeWindowAction : IOverlayAction + [OverlayActionInfo("Resize Window", typeof(ResizeWindowActionEditor))] + public class ResizeWindowAction : IWindowAction { public int NewWidth { get; set; } public int NewHeight { get; set; } - public bool Enabled { get; set; } + public bool Enabled { get; set; } = true; public ResizeWindowAction(int newWidth, int newHeight) { @@ -19,6 +21,8 @@ namespace VDash.Overlay.Actions NewHeight = newHeight; } + public ResizeWindowAction() { } + public void PreformAction(IOverlay intOverlay) { if (!Enabled) { return; } @@ -43,5 +47,11 @@ namespace VDash.Overlay.Actions User32.SetWindowPosFlags.IgnoreMove | User32.SetWindowPosFlags.IgnoreZOrder | User32.SetWindowPosFlags.DoNotChangeOwnerZOrder); } + + public override string ToString() + { + var attribute = (OverlayActionInfo)this.GetType().GetCustomAttributes(typeof(OverlayActionInfo), false).Single(); + return $"{attribute.Description} ({NewWidth}x{NewHeight})"; + } } } diff --git a/VDash/Overlay/Actions/RestoreWindowAction.cs b/VDash/Overlay/Actions/RestoreWindowAction.cs index 5173bca..d8f6a7e 100644 --- a/VDash/Overlay/Actions/RestoreWindowAction.cs +++ b/VDash/Overlay/Actions/RestoreWindowAction.cs @@ -7,9 +7,9 @@ using VDash.Utilities; namespace VDash.Overlay.Actions { - public class RestoreWindowAction : IOverlayAction + [OverlayActionInfo("Restore Window")] + public class RestoreWindowAction : IWindowAction { - public bool Enabled { get; set; } public void PreformAction(IOverlay intOverlay) @@ -30,6 +30,12 @@ namespace VDash.Overlay.Actions { User32.ShowWindow(handle, User32.ShowWindowCommands.Restore); } + + public override string ToString() + { + var attribute = (OverlayActionInfo)this.GetType().GetCustomAttributes(typeof(OverlayActionInfo), false).Single(); + return attribute.Description; + } } } diff --git a/VDash/Overlay/Config/WindowOverlayConfig.cs b/VDash/Overlay/Config/WindowOverlayConfig.cs index f80ca08..bd87101 100644 --- a/VDash/Overlay/Config/WindowOverlayConfig.cs +++ b/VDash/Overlay/Config/WindowOverlayConfig.cs @@ -1,8 +1,10 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; +using VDash.Overlay.Actions; using VDash.WindowSelectors; namespace VDash.Overlay.Config @@ -23,6 +25,9 @@ namespace VDash.Overlay.Config public string Name { get; set; } public string Key { get; set; } + public ObservableCollection OverlayShownActions { get; private set; } = new ObservableCollection(); + public ObservableCollection OverlayHiddenActions { get; private set; } = new ObservableCollection(); + public IWindowSelector Selector {get; set; } public bool UpdateDashboardName { get; set; } = false; public bool DestroyOnNoWindowFound { get; set; } = false; diff --git a/VDash/Overlay/IOverlay.cs b/VDash/Overlay/IOverlay.cs index 9f387ef..5b7516c 100644 --- a/VDash/Overlay/IOverlay.cs +++ b/VDash/Overlay/IOverlay.cs @@ -10,9 +10,6 @@ namespace VDash.Overlay event EventHandler OverlayShown; event EventHandler OverlayHidden; - List OverlayShownActions { get; } - List OverlayHiddenActions { get; } - ulong OverlayHandle { get; } IOverlayConfig OverlayConfig { get; } diff --git a/VDash/Overlay/WindowOverlay.cs b/VDash/Overlay/WindowOverlay.cs index 4e8941c..3883418 100644 --- a/VDash/Overlay/WindowOverlay.cs +++ b/VDash/Overlay/WindowOverlay.cs @@ -48,8 +48,8 @@ namespace VDash.Overlay //public IWindowSelector Selector { get; private set; } = null; - public List OverlayShownActions { get; private set; } = new List(); - public List OverlayHiddenActions { get; private set; } = new List(); + //public List OverlayShownActions { get; private set; } = new List(); + //public List OverlayHiddenActions { get; private set; } = new List(); char[] specialKeys = { '+', '^', '%', '~', '(', ')', '{', '}', '[', ']' }; @@ -341,7 +341,7 @@ namespace VDash.Overlay if (Config.Selector.WindowExists()) { - foreach (var action in OverlayShownActions) + foreach (var action in Config.OverlayShownActions) { action.PreformAction(this); } @@ -354,7 +354,7 @@ namespace VDash.Overlay if (Config.Selector.WindowExists()) { - foreach (var action in OverlayHiddenActions) + foreach (var action in Config.OverlayHiddenActions) { action.PreformAction(this); } diff --git a/VDash/UI/ActionEditors/IActionEditor.cs b/VDash/UI/ActionEditors/IActionEditor.cs new file mode 100644 index 0000000..4ecfce0 --- /dev/null +++ b/VDash/UI/ActionEditors/IActionEditor.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace VDash.UI.ActionEditors +{ + public interface IActionEditor + { + event EventHandler Submitted; + } +} diff --git a/VDash/UI/ActionEditors/ResizeWindowActionEditor.xaml b/VDash/UI/ActionEditors/ResizeWindowActionEditor.xaml new file mode 100644 index 0000000..8b43413 --- /dev/null +++ b/VDash/UI/ActionEditors/ResizeWindowActionEditor.xaml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + Width: + Height: + + + + + + + + + diff --git a/VDash/UI/ActionEditors/ResizeWindowActionEditor.xaml.cs b/VDash/UI/ActionEditors/ResizeWindowActionEditor.xaml.cs new file mode 100644 index 0000000..67ec6c9 --- /dev/null +++ b/VDash/UI/ActionEditors/ResizeWindowActionEditor.xaml.cs @@ -0,0 +1,108 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; +using System.Windows.Data; +using System.Windows.Documents; +using System.Windows.Input; +using System.Windows.Media; +using System.Windows.Media.Imaging; +using System.Windows.Navigation; +using System.Windows.Shapes; +using VDash.Overlay.Actions; + +namespace VDash.UI.ActionEditors +{ + /// + /// Interaction logic for ResizeWindowActionEditor.xaml + /// + public partial class ResizeWindowActionEditor : UserControl,IActionEditor + { + public event EventHandler Submitted; + public ResizeWindowAction Action { get; private set; } + + public static object[] Presets = + { + "Optional Presets...", + new ResizePreset("Small (640x480)", 640, 480), + new ResizePreset("Medium (1024x768)", 1024, 768), + new ResizePreset("Large (1400x1050)", 1400, 1050) + }; + + public ResizeWindowActionEditor(ResizeWindowAction action) + { + InitializeComponent(); + Action = action; + DataContext = Action; + cbPresets.ItemsSource = Presets; + } + + private void TextBlock_PreviewTextInput(object sender, TextCompositionEventArgs e) + { + foreach (var letter in e.Text) + { + if (!Char.IsNumber(letter)) + { + e.Handled = true; + return; + } + } + } + + private void TextBlock_PreviewKeyDown(object sender, KeyEventArgs e) + { + if(e.Key == Key.Space) + { + e.Handled = true; + return; + } + } + + private void btnOK_Click(object sender, RoutedEventArgs e) + { + if(Action.NewWidth <= 50 || Action.NewHeight == 50) + { + MessageBox.Show("Please enter a valid width and height.", "Input error", MessageBoxButton.OK, MessageBoxImage.Warning); + return; + } + Submitted?.Invoke(this, null); + } + + private void cbPresets_SelectionChanged(object sender, SelectionChangedEventArgs e) + { + //Skip description + if(cbPresets.SelectedItem.GetType() != typeof(ResizePreset)) + { + return; + } + + var item = (ResizePreset)cbPresets.SelectedItem; + + Action.NewWidth = item.Width; + Action.NewHeight = item.Height; + tbWidth.GetBindingExpression(TextBox.TextProperty).UpdateTarget(); + tbHeight.GetBindingExpression(TextBox.TextProperty).UpdateTarget(); + } + + internal class ResizePreset + { + public string Description { get; private set; } + public int Width { get; private set; } + public int Height { get; private set; } + + public ResizePreset(string description, int width, int height) + { + Description = description; + Width = width; + Height = height; + } + public override string ToString() + { + return Description; + } + } + } +} diff --git a/VDash/UI/CreateNewOverlay.xaml.cs b/VDash/UI/CreateNewOverlay.xaml.cs index 362f17b..9566202 100644 --- a/VDash/UI/CreateNewOverlay.xaml.cs +++ b/VDash/UI/CreateNewOverlay.xaml.cs @@ -42,6 +42,21 @@ namespace VDash.UI private void btnCreate_Click(object sender, RoutedEventArgs e) { + var editorControl = ((OverlayTypeWrapper)cbOverlayType.SelectedItem).Control; + var intConrol = (IOverlayEditor)editorControl; + string[] issues = intConrol.ValidateInput(); + if (issues.Count() != 0) + { + StringBuilder error = new StringBuilder(); + error.AppendLine("Please rectify the following issues:"); + foreach(var issue in issues) + { + error.AppendLine(issue); + } + MessageBox.Show(error.ToString(), "Input Error", MessageBoxButton.OK, MessageBoxImage.Warning); + return; + } + var wrapper = ((OverlayTypeWrapper)cbOverlayType.SelectedItem); var config = wrapper.Editor.Config; if (String.IsNullOrWhiteSpace(config.Key)) diff --git a/VDash/UI/IOverlayEditor.cs b/VDash/UI/IOverlayEditor.cs index 2a7ec5b..760c8db 100644 --- a/VDash/UI/IOverlayEditor.cs +++ b/VDash/UI/IOverlayEditor.cs @@ -11,5 +11,6 @@ namespace VDash.UI public interface IOverlayEditor { IOverlayConfig Config { get; } + string[] ValidateInput(); } } diff --git a/VDash/UI/ISelectorEditor.cs b/VDash/UI/ISelectorEditor.cs new file mode 100644 index 0000000..2211fc4 --- /dev/null +++ b/VDash/UI/ISelectorEditor.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace VDash.UI +{ + public interface ISelectorEditor + { + string[] ValidateInput(); + } +} diff --git a/VDash/UI/MonitorOverlayEditor.xaml b/VDash/UI/MonitorOverlayEditor.xaml index c98830e..12d4e01 100644 --- a/VDash/UI/MonitorOverlayEditor.xaml +++ b/VDash/UI/MonitorOverlayEditor.xaml @@ -24,7 +24,7 @@ - + diff --git a/VDash/UI/MonitorOverlayEditor.xaml.cs b/VDash/UI/MonitorOverlayEditor.xaml.cs index 61174b0..f731089 100644 --- a/VDash/UI/MonitorOverlayEditor.xaml.cs +++ b/VDash/UI/MonitorOverlayEditor.xaml.cs @@ -46,5 +46,15 @@ namespace VDash.UI { OverlayConfig.MonitorName = ((DisplayInfo)cbMontitor.SelectedItem).MonitorInfo.DeviceName; } + + public string[] ValidateInput() + { + List issues = new List(); + if(cbMontitor.SelectedItem == null) + { + issues.Add("Please select a monitor."); + } + return issues.ToArray(); + } } } diff --git a/VDash/UI/OverlayEditor.xaml b/VDash/UI/OverlayEditor.xaml index 327a661..0a0ecaf 100644 --- a/VDash/UI/OverlayEditor.xaml +++ b/VDash/UI/OverlayEditor.xaml @@ -17,8 +17,9 @@ - Overlay Width: + + Overlay Width: - + diff --git a/VDash/UI/OverlayEditor.xaml.cs b/VDash/UI/OverlayEditor.xaml.cs index d9d60a1..4ab5f2e 100644 --- a/VDash/UI/OverlayEditor.xaml.cs +++ b/VDash/UI/OverlayEditor.xaml.cs @@ -35,8 +35,32 @@ namespace VDash.UI private void tbWidth_PreviewTextInput(object sender, TextCompositionEventArgs e) { - Regex regex = new Regex(@"^[1-9]\d*(\.\d+)?$"); - e.Handled = regex.IsMatch(e.Text); + var dotcount = tbWidth.Text.Count(x => x == '.'); + foreach(var letter in e.Text) + { + if(!Char.IsDigit(letter) && letter != '.') + { + e.Handled = true; + } + if (dotcount >= 1 && e.Text.Contains(".")) + { + e.Handled = true; + return; + } + } + } + + private void tbWidth_PreviewKeyDown(object sender, KeyEventArgs e) + { + if(e.Key == Key.Space) + { + e.Handled = true; + } + } + + public string[] ValidateInput() + { + return Editor.ValidateInput(); } } } diff --git a/VDash/UI/ProcessSelectorEditor.xaml.cs b/VDash/UI/ProcessSelectorEditor.xaml.cs index 9bdcdee..b0d46be 100644 --- a/VDash/UI/ProcessSelectorEditor.xaml.cs +++ b/VDash/UI/ProcessSelectorEditor.xaml.cs @@ -19,7 +19,7 @@ namespace VDash.UI /// /// Interaction logic for ProcessSelectorEditor.xaml /// - public partial class ProcessSelectorEditor : UserControl + public partial class ProcessSelectorEditor : UserControl,ISelectorEditor { public FromProcessName Selector { get; private set; } public ProcessSelectorEditor(ref FromProcessName selector) @@ -28,5 +28,16 @@ namespace VDash.UI Selector = selector; DataContext = Selector; } + + public string[] ValidateInput() + { + List issues = new List(); + + if (String.IsNullOrWhiteSpace(Selector.ProcessName)) + { + issues.Add("You must enter a process name."); + } + return issues.ToArray(); + } } } diff --git a/VDash/UI/WindowOverlayEditor.xaml b/VDash/UI/WindowOverlayEditor.xaml index e510d9d..45a6c5d 100644 --- a/VDash/UI/WindowOverlayEditor.xaml +++ b/VDash/UI/WindowOverlayEditor.xaml @@ -18,6 +18,7 @@ + @@ -42,5 +43,42 @@ HorizontalAlignment="Left" VerticalAlignment="Center" IsChecked="{Binding UpdateDashboardName}"/> + + + + + + + + + + + + + + + + + + + On Dashboard Open: + + + + + + + + + + + On Dashboard Close: + + + + + + + diff --git a/VDash/UI/WindowOverlayEditor.xaml.cs b/VDash/UI/WindowOverlayEditor.xaml.cs index 27b14a3..adfc8bc 100644 --- a/VDash/UI/WindowOverlayEditor.xaml.cs +++ b/VDash/UI/WindowOverlayEditor.xaml.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Collections.ObjectModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -12,7 +13,9 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; +using VDash.Overlay.Actions; using VDash.Overlay.Config; +using VDash.UI.ActionEditors; using VDash.WindowSelectors; namespace VDash.UI @@ -22,7 +25,7 @@ namespace VDash.UI /// public partial class WindowOverlayEditor : UserControl,IOverlayEditor { - public WindowOverlayConfig OverlayConfig { get; set; } = new WindowOverlayConfig(); + public WindowOverlayConfig OverlayConfig { get; set; } public SelectorWrapper[] Selectors { get; private set; } = { @@ -30,14 +33,14 @@ namespace VDash.UI new SelectorWrapper("By Window Title", typeof(FromWindowTitle), typeof(WindowSelectorEditor)) }; - - public IOverlayConfig Config { get { return OverlayConfig; } } public WindowOverlayEditor() { InitializeComponent(); + OverlayConfig = new WindowOverlayConfig(); + OverlayConfig.OverlayShownActions.Add(new BringWindowToFrontAction(true)); DataContext = OverlayConfig; cbSelector.ItemsSource = Selectors; @@ -100,5 +103,91 @@ namespace VDash.UI OverlayConfig.Selector = wrapper.Selector; bdrSelector.Child = wrapper.Editor; } + + public string[] ValidateInput() + { + List issues = new List(); + if (String.IsNullOrWhiteSpace(Config.Name)) + { + issues.Add("Please enter a name."); + } + + if((SelectorWrapper)cbSelector.SelectedItem == null) + { + issues.Add("Please select a window selector."); + } + else + { + //Type selectorType = ((SelectorWrapper)cbSelector.SelectedItem).Editor; + var selectorEditor = (ISelectorEditor)((SelectorWrapper)cbSelector.SelectedItem).Editor; + issues.AddRange(selectorEditor.ValidateInput()); + } + return issues.ToArray(); + } + + private void ContextMenuBuilder(Collection col) + { + List items = new List(); + ContextMenu menu = new ContextMenu(); + menu.ItemsSource = items; + menu.Placement = System.Windows.Controls.Primitives.PlacementMode.MousePoint; + + foreach(var actionType in OverlayActionInfo.GetTypesWithAttribute()) + { + OverlayActionInfo attribute = (OverlayActionInfo)actionType.GetCustomAttributes(typeof(OverlayActionInfo), false).Single(); + if(attribute.EditorType == null) + { + var item = new MenuItem() { Header = attribute.Description }; + item.Click += (s, e) => { + IWindowAction action = (IWindowAction)Activator.CreateInstance(actionType); + col.Add(action); + }; + items.Add(item); + } + else + { + var item = new MenuItem() { Header = attribute.Description }; + IWindowAction action = (IWindowAction)Activator.CreateInstance(actionType); + IActionEditor editor = (IActionEditor)Activator.CreateInstance(attribute.EditorType, new object[] { action }); + item.ItemsSource = new object[] { new MenuItem() { Header = editor } }; + editor.Submitted += (s, e) => + { + col.Add(action); + menu.IsOpen = false; + }; + items.Add(item); + } + } + + menu.IsOpen = true; + } + + private void btnOnShowAdd_Click(object sender, RoutedEventArgs e) + { + ContextMenuBuilder(OverlayConfig.OverlayShownActions); + } + + private void btnOnShowRemove_Click(object sender, RoutedEventArgs e) + { + if(lvOnOpenActions.SelectedItem == null) + { + return; + } + OverlayConfig.OverlayShownActions.Remove((IWindowAction)lvOnOpenActions.SelectedItem); + } + + private void btnOnHideAdd_Click(object sender, RoutedEventArgs e) + { + ContextMenuBuilder(OverlayConfig.OverlayHiddenActions); + } + + private void btnOnHideRemove_Click(object sender, RoutedEventArgs e) + { + if (lvOnCloseActions.SelectedItem == null) + { + return; + } + OverlayConfig.OverlayHiddenActions.Remove((IWindowAction)lvOnCloseActions.SelectedItem); + } } } diff --git a/VDash/UI/WindowSelectorEditor.xaml.cs b/VDash/UI/WindowSelectorEditor.xaml.cs index 875f3db..6c2bbd8 100644 --- a/VDash/UI/WindowSelectorEditor.xaml.cs +++ b/VDash/UI/WindowSelectorEditor.xaml.cs @@ -19,7 +19,7 @@ namespace VDash.UI /// /// Interaction logic for WindowSelectorEditor.xaml /// - public partial class WindowSelectorEditor : UserControl + public partial class WindowSelectorEditor : UserControl,ISelectorEditor { public FromWindowTitle Selector { get; set; } @@ -36,5 +36,19 @@ namespace VDash.UI { Selector.SearchType = (FromWindowTitle.TitleSearchType)cbSearchType.SelectedItem; } + + public string[] ValidateInput() + { + List issues = new List(); + if (cbSearchType.SelectedItem == null) + { + issues.Add("You must select a search type."); + } + if (String.IsNullOrWhiteSpace(Selector.TitleFilter)) + { + issues.Add("You must enter search text."); + } + return issues.ToArray(); + } } } diff --git a/VDash/VDash.csproj b/VDash/VDash.csproj index 5aadc35..cc8a7a5 100644 --- a/VDash/VDash.csproj +++ b/VDash/VDash.csproj @@ -54,6 +54,9 @@ true + + ..\packages\log4net.2.0.8\lib\net45-full\log4net.dll + ..\packages\Newtonsoft.Json.12.0.2\lib\net45\Newtonsoft.Json.dll @@ -92,7 +95,9 @@ + + @@ -100,10 +105,15 @@ + + + ResizeWindowActionEditor.xaml + CreateNewOverlay.xaml + MonitorOverlayEditor.xaml @@ -136,6 +146,10 @@ MainWindow.xaml Code + + Designer + MSBuild:Compile + Designer MSBuild:Compile diff --git a/VDash/packages.config b/VDash/packages.config index 7baa7bb..2b01974 100644 --- a/VDash/packages.config +++ b/VDash/packages.config @@ -1,5 +1,6 @@  +