diff --git a/src/Artemis.UI/Artemis.UI.csproj b/src/Artemis.UI/Artemis.UI.csproj index 8c434df45..e47df1dd8 100644 --- a/src/Artemis.UI/Artemis.UI.csproj +++ b/src/Artemis.UI/Artemis.UI.csproj @@ -152,7 +152,8 @@ - + + @@ -161,7 +162,7 @@ - + True True diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileEditorPanelViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileEditorPanelViewModel.cs index 77a81d739..d783ef8f2 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileEditorPanelViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileEditorPanelViewModel.cs @@ -1,4 +1,5 @@ -using Stylet; +using Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement; +using Stylet; namespace Artemis.UI.Screens.Module.ProfileEditor { @@ -13,5 +14,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor public virtual void ActiveProfileUpdated() { } + + public virtual void ProfileElementSelected(ProfileElementViewModel profileElement) + { + } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileEditorView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileEditorView.xaml index 8a96256e6..c96765e37 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileEditorView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileEditorView.xaml @@ -20,7 +20,6 @@ - @@ -31,7 +30,7 @@ - + @@ -60,7 +59,7 @@ - + @@ -89,7 +88,7 @@ - + diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileEditorViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileEditorViewModel.cs index b585ca6f9..4add86c02 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileEditorViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileEditorViewModel.cs @@ -13,6 +13,7 @@ using Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions; using Artemis.UI.Screens.Module.ProfileEditor.ElementProperties; using Artemis.UI.Screens.Module.ProfileEditor.LayerElements; using Artemis.UI.Screens.Module.ProfileEditor.ProfileElements; +using Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement; using Artemis.UI.Screens.Module.ProfileEditor.Visualization; using Artemis.UI.Services.Interfaces; using Stylet; @@ -195,12 +196,18 @@ namespace Artemis.UI.Screens.Module.ProfileEditor Module.ChangeActiveProfile(activeProfile); } - public void OnProfileUpdated() + public void OnProfileUpdated(ProfileEditorPanelViewModel source = null) { _profileService.UpdateProfile(SelectedProfile, true); - foreach (var panelViewModel in Items) + foreach (var panelViewModel in Items.Where(p => p != source)) panelViewModel.ActiveProfileUpdated(); } + + public void OnProfileElementSelected(ProfileElementViewModel profileElement, ProfileEditorPanelViewModel source = null) + { + foreach (var panelViewModel in Items.Where(p => p != source)) + panelViewModel.ProfileElementSelected(profileElement); + } } } \ No newline at end of file diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileElements/ProfileElementsView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileElements/ProfileElementsView.xaml index 5e37f9a0b..9a6814083 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileElements/ProfileElementsView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileElements/ProfileElementsView.xaml @@ -10,6 +10,8 @@ xmlns:dd="urn:gong-wpf-dragdrop" xmlns:profileElements="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.ProfileElements" xmlns:profileElement="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement" + xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" + xmlns:utilities="clr-namespace:Artemis.UI.Utilities" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance {x:Type profileElements:ProfileElementsViewModel}}"> @@ -32,6 +34,9 @@ dd:DragDrop.IsDragSource="True" dd:DragDrop.IsDropTarget="True" dd:DragDrop.DropHandler="{Binding}"> + + + diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileElements/ProfileElementsViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileElements/ProfileElementsViewModel.cs index 14cd2c6ff..fd2c92c42 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileElements/ProfileElementsViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/ProfileElements/ProfileElementsViewModel.cs @@ -8,6 +8,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements { public class ProfileElementsViewModel : ProfileEditorPanelViewModel, IDropTarget { + private ProfileElementViewModel _selectedProfileElement; + public ProfileElementsViewModel() { CreateRootFolderViewModel(); @@ -15,6 +17,16 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements public FolderViewModel RootFolder { get; set; } + public ProfileElementViewModel SelectedProfileElement + { + get => _selectedProfileElement; + set + { + _selectedProfileElement = value; + ProfileEditorViewModel.OnProfileElementSelected(_selectedProfileElement, this); + } + } + public void DragOver(IDropInfo dropInfo) { var dragDropType = GetDragDropType(dropInfo); @@ -53,7 +65,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements break; } - ProfileEditorViewModel.OnProfileUpdated(); + ProfileEditorViewModel.OnProfileUpdated(this); } // ReSharper disable once UnusedMember.Global - Called from view @@ -74,6 +86,15 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements base.ActiveProfileChanged(); } + public override void ProfileElementSelected(ProfileElementViewModel profileElement) + { + // Don't set it using the setter or that will trigger the event again + _selectedProfileElement = profileElement; + NotifyOfPropertyChange(() => SelectedProfileElement); + + base.ProfileElementSelected(profileElement); + } + private void CreateRootFolderViewModel() { if (!(ProfileEditorViewModel?.SelectedProfile?.Children?.FirstOrDefault() is Folder folder)) diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileView.xaml b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileView.xaml index 085e29ed0..2c79669d9 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileView.xaml +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileView.xaml @@ -6,7 +6,7 @@ xmlns:s="https://github.com/canton7/Stylet" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:profileEditor="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.Visualization" - xmlns:observers="clr-namespace:Artemis.UI.Observers" + xmlns:utilities="clr-namespace:Artemis.UI.Utilities" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance {x:Type profileEditor:ProfileViewModel}}"> @@ -44,9 +44,9 @@ MouseDown="{s:Action EditorGridMouseClick}" MouseMove="{s:Action EditorGridMouseMove}" Cursor="{Binding Cursor}" - observers:SizeObserver.Observe="True" - observers:SizeObserver.ObservedWidth="{Binding PanZoomViewModel.CanvasWidth, Mode=OneWayToSource}" - observers:SizeObserver.ObservedHeight="{Binding PanZoomViewModel.CanvasHeight, Mode=OneWayToSource}"> + utilities:SizeObserver.Observe="True" + utilities:SizeObserver.ObservedWidth="{Binding PanZoomViewModel.CanvasWidth, Mode=OneWayToSource}" + utilities:SizeObserver.ObservedHeight="{Binding PanZoomViewModel.CanvasHeight, Mode=OneWayToSource}"> diff --git a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs index d13a1888f..4625f8c9c 100644 --- a/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs +++ b/src/Artemis.UI/Screens/Module/ProfileEditor/Visualization/ProfileViewModel.cs @@ -6,6 +6,7 @@ using System.Windows.Input; using System.Windows.Media; using Artemis.Core.Events; using Artemis.Core.Models.Surface; +using Artemis.Core.Plugins.Models; using Artemis.Core.Services; using Artemis.Core.Services.Storage.Interfaces; using Artemis.UI.Extensions; @@ -20,10 +21,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization { public class ProfileViewModel : ProfileEditorPanelViewModel { + private readonly ISettingsService _settingsService; private readonly TimerUpdateTrigger _updateTrigger; public ProfileViewModel(ISurfaceService surfaceService, ISettingsService settingsService) { + _settingsService = settingsService; Devices = new ObservableCollection(); Execute.PostToUIThread(() => { @@ -48,6 +51,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization public ObservableCollection Devices { get; set; } public RectangleGeometry SelectionRectangle { get; set; } public PanZoomViewModel PanZoomViewModel { get; set; } + public PluginSetting HighlightSelectedLayer { get; set; } + public PluginSetting PauseRenderingOnFocusLoss { get; set; } + public Cursor Cursor { get; set; } private void OnActiveSurfaceConfigurationChanged(object sender, SurfaceConfigurationEventArgs e) @@ -106,12 +112,18 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization protected override void OnActivate() { + HighlightSelectedLayer = _settingsService.GetSetting("ProfileEditor.HighlightSelectedLayer", true); + PauseRenderingOnFocusLoss = _settingsService.GetSetting("ProfileEditor.PauseRenderingOnFocusLoss", true); + _updateTrigger.Start(); base.OnActivate(); } - + protected override void OnDeactivate() { + HighlightSelectedLayer.Save(); + PauseRenderingOnFocusLoss.Save(); + _updateTrigger.Stop(); base.OnDeactivate(); } @@ -172,7 +184,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization profileLedViewModel.SelectionStatus = SelectionStatus.None; } } - + _mouseDragStatus = MouseDragStatus.None; } @@ -180,7 +192,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization { if (IsPanKeyDown()) return; - + var selectedRect = new Rect(_mouseDragStartPoint, position); SelectionRectangle.Rect = selectedRect; diff --git a/src/Artemis.UI/Screens/RootViewModel.cs b/src/Artemis.UI/Screens/RootViewModel.cs index a151bcc44..b3c67d8c8 100644 --- a/src/Artemis.UI/Screens/RootViewModel.cs +++ b/src/Artemis.UI/Screens/RootViewModel.cs @@ -1,5 +1,7 @@ -using System.Collections.Generic; +using System; +using System.Collections.Generic; using System.ComponentModel; +using System.Diagnostics; using System.Linq; using System.Threading.Tasks; using System.Windows.Controls; @@ -11,6 +13,7 @@ using Artemis.UI.Screens.News; using Artemis.UI.Screens.Settings; using Artemis.UI.Screens.SurfaceEditor; using Artemis.UI.Screens.Workshop; +using MahApps.Metro.Controls; using Stylet; namespace Artemis.UI.Screens diff --git a/src/Artemis.UI/Stylet/NinjectBootstrapper.cs b/src/Artemis.UI/Stylet/NinjectBootstrapper.cs index 1478aeb0e..b7bf3f9dc 100644 --- a/src/Artemis.UI/Stylet/NinjectBootstrapper.cs +++ b/src/Artemis.UI/Stylet/NinjectBootstrapper.cs @@ -1,9 +1,7 @@ using System; using System.Collections.Generic; using System.Reflection; -using System.Windows.Threading; using Ninject; -using Serilog; using Stylet; namespace Artemis.UI.Stylet diff --git a/src/Artemis.UI/Utilities/BindableSelectedItemBehavior.cs b/src/Artemis.UI/Utilities/BindableSelectedItemBehavior.cs new file mode 100644 index 000000000..90a44188d --- /dev/null +++ b/src/Artemis.UI/Utilities/BindableSelectedItemBehavior.cs @@ -0,0 +1,47 @@ +using System.Windows; +using System.Windows.Controls; +using System.Windows.Interactivity; + +namespace Artemis.UI.Utilities +{ + public class BindableSelectedItemBehavior : Behavior + { + protected override void OnAttached() + { + base.OnAttached(); + + AssociatedObject.SelectedItemChanged += OnTreeViewSelectedItemChanged; + } + + protected override void OnDetaching() + { + base.OnDetaching(); + + if (AssociatedObject != null) AssociatedObject.SelectedItemChanged -= OnTreeViewSelectedItemChanged; + } + + private void OnTreeViewSelectedItemChanged(object sender, RoutedPropertyChangedEventArgs e) + { + SelectedItem = e.NewValue; + } + + #region SelectedItem Property + + public object SelectedItem + { + get => GetValue(SelectedItemProperty); + set => SetValue(SelectedItemProperty, value); + } + + public static readonly DependencyProperty SelectedItemProperty = + DependencyProperty.Register("SelectedItem", typeof(object), typeof(BindableSelectedItemBehavior), new UIPropertyMetadata(null, OnSelectedItemChanged)); + + private static void OnSelectedItemChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e) + { + var item = e.NewValue as TreeViewItem; + if (item != null) item.SetValue(TreeViewItem.IsSelectedProperty, true); + } + + #endregion + } +} \ No newline at end of file diff --git a/src/Artemis.UI/Observers/SizeObserver.cs b/src/Artemis.UI/Utilities/SizeObserver.cs similarity index 98% rename from src/Artemis.UI/Observers/SizeObserver.cs rename to src/Artemis.UI/Utilities/SizeObserver.cs index 055958a23..0dcb66bf5 100644 --- a/src/Artemis.UI/Observers/SizeObserver.cs +++ b/src/Artemis.UI/Utilities/SizeObserver.cs @@ -1,6 +1,6 @@ using System.Windows; -namespace Artemis.UI.Observers +namespace Artemis.UI.Utilities { public static class SizeObserver { diff --git a/src/Artemis.UI/DebugTriggers/TriggerTracing.cs b/src/Artemis.UI/Utilities/TriggerTracing.cs similarity index 99% rename from src/Artemis.UI/DebugTriggers/TriggerTracing.cs rename to src/Artemis.UI/Utilities/TriggerTracing.cs index fd66ceab2..e8f6120ec 100644 --- a/src/Artemis.UI/DebugTriggers/TriggerTracing.cs +++ b/src/Artemis.UI/Utilities/TriggerTracing.cs @@ -20,7 +20,7 @@ using System.Windows.Media.Animation; // // As this works on anything that inherits from TriggerBase, it will also work on . -namespace Artemis.UI.DebugTriggers +namespace Artemis.UI.Utilities { #if DEBUG