1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2025-12-13 05:48:35 +00:00

Implement element selection event within profile editor VMs

This commit is contained in:
Robert 2019-11-27 20:56:07 +01:00
parent 0b56fd9088
commit bf729b64fd
13 changed files with 120 additions and 22 deletions

View File

@ -152,7 +152,8 @@
<Compile Include="Converters\InverseBooleanConverter.cs" /> <Compile Include="Converters\InverseBooleanConverter.cs" />
<Compile Include="Converters\NullToImageConverter.cs" /> <Compile Include="Converters\NullToImageConverter.cs" />
<Compile Include="Converters\NullToVisibilityConverter.cs" /> <Compile Include="Converters\NullToVisibilityConverter.cs" />
<Compile Include="DebugTriggers\TriggerTracing.cs" /> <Compile Include="Utilities\BindableSelectedItemBehavior.cs" />
<Compile Include="Utilities\TriggerTracing.cs" />
<Compile Include="Exceptions\ArtemisCoreException.cs" /> <Compile Include="Exceptions\ArtemisCoreException.cs" />
<Compile Include="Extensions\RgbColorExtensions.cs" /> <Compile Include="Extensions\RgbColorExtensions.cs" />
<Compile Include="Extensions\RgbRectangleExtensions.cs" /> <Compile Include="Extensions\RgbRectangleExtensions.cs" />
@ -161,7 +162,7 @@
<Compile Include="Ninject\Factories\IModuleViewModelFactory.cs" /> <Compile Include="Ninject\Factories\IModuleViewModelFactory.cs" />
<Compile Include="Ninject\Factories\IProfileEditorViewModelFactory.cs" /> <Compile Include="Ninject\Factories\IProfileEditorViewModelFactory.cs" />
<Compile Include="Ninject\UIModule.cs" /> <Compile Include="Ninject\UIModule.cs" />
<Compile Include="Observers\SizeObserver.cs" /> <Compile Include="Utilities\SizeObserver.cs" />
<Compile Include="Properties\Resources.Designer.cs"> <Compile Include="Properties\Resources.Designer.cs">
<AutoGen>True</AutoGen> <AutoGen>True</AutoGen>
<DesignTime>True</DesignTime> <DesignTime>True</DesignTime>

View File

@ -1,4 +1,5 @@
using Stylet; using Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement;
using Stylet;
namespace Artemis.UI.Screens.Module.ProfileEditor namespace Artemis.UI.Screens.Module.ProfileEditor
{ {
@ -13,5 +14,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
public virtual void ActiveProfileUpdated() public virtual void ActiveProfileUpdated()
{ {
} }
public virtual void ProfileElementSelected(ProfileElementViewModel profileElement)
{
}
} }
} }

View File

@ -20,7 +20,6 @@
</ResourceDictionary> </ResourceDictionary>
</UserControl.Resources> </UserControl.Resources>
<!-- Blue -->
<Grid Margin="16"> <Grid Margin="16">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<!-- Left side --> <!-- Left side -->
@ -31,7 +30,7 @@
<ColumnDefinition Width="{Binding SidePanelsWidth.Value, Mode=TwoWay}" MinWidth="100" /> <ColumnDefinition Width="{Binding SidePanelsWidth.Value, Mode=TwoWay}" MinWidth="100" />
</Grid.ColumnDefinitions> </Grid.ColumnDefinitions>
<!-- Left side (orange) --> <!-- Left side -->
<Grid Grid.Row="0" Grid.Column="0"> <Grid Grid.Row="0" Grid.Column="0">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<!-- Introduction --> <!-- Introduction -->
@ -60,7 +59,7 @@
<!-- Bottom panels resize --> <!-- Bottom panels resize -->
<GridSplitter Grid.Row="2" Grid.Column="0" Height="5" HorizontalAlignment="Stretch" Cursor="SizeNS" Margin="0 5" /> <GridSplitter Grid.Row="2" Grid.Column="0" Height="5" HorizontalAlignment="Stretch" Cursor="SizeNS" Margin="0 5" />
<!-- Bottom panels (green) --> <!-- Bottom panels -->
<Grid Grid.Row="3"> <Grid Grid.Row="3">
<Grid.ColumnDefinitions> <Grid.ColumnDefinitions>
<!-- Layer elements --> <!-- Layer elements -->
@ -89,7 +88,7 @@
<!-- Side panels resize --> <!-- Side panels resize -->
<GridSplitter Grid.Row="0" Grid.Column="1" Width="5" HorizontalAlignment="Stretch" Cursor="SizeWE" Margin="5 35 5 0" /> <GridSplitter Grid.Row="0" Grid.Column="1" Width="5" HorizontalAlignment="Stretch" Cursor="SizeWE" Margin="5 35 5 0" />
<!-- Side panels (orange) --> <!-- Side panels -->
<Grid Grid.Row="0" Grid.Column="2"> <Grid Grid.Row="0" Grid.Column="2">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<!-- Profile selection --> <!-- Profile selection -->

View File

@ -13,6 +13,7 @@ using Artemis.UI.Screens.Module.ProfileEditor.DisplayConditions;
using Artemis.UI.Screens.Module.ProfileEditor.ElementProperties; using Artemis.UI.Screens.Module.ProfileEditor.ElementProperties;
using Artemis.UI.Screens.Module.ProfileEditor.LayerElements; using Artemis.UI.Screens.Module.ProfileEditor.LayerElements;
using Artemis.UI.Screens.Module.ProfileEditor.ProfileElements; 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.Screens.Module.ProfileEditor.Visualization;
using Artemis.UI.Services.Interfaces; using Artemis.UI.Services.Interfaces;
using Stylet; using Stylet;
@ -195,12 +196,18 @@ namespace Artemis.UI.Screens.Module.ProfileEditor
Module.ChangeActiveProfile(activeProfile); Module.ChangeActiveProfile(activeProfile);
} }
public void OnProfileUpdated() public void OnProfileUpdated(ProfileEditorPanelViewModel source = null)
{ {
_profileService.UpdateProfile(SelectedProfile, true); _profileService.UpdateProfile(SelectedProfile, true);
foreach (var panelViewModel in Items) foreach (var panelViewModel in Items.Where(p => p != source))
panelViewModel.ActiveProfileUpdated(); panelViewModel.ActiveProfileUpdated();
} }
public void OnProfileElementSelected(ProfileElementViewModel profileElement, ProfileEditorPanelViewModel source = null)
{
foreach (var panelViewModel in Items.Where(p => p != source))
panelViewModel.ProfileElementSelected(profileElement);
}
} }
} }

View File

@ -10,6 +10,8 @@
xmlns:dd="urn:gong-wpf-dragdrop" xmlns:dd="urn:gong-wpf-dragdrop"
xmlns:profileElements="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.ProfileElements" xmlns:profileElements="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.ProfileElements"
xmlns:profileElement="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.ProfileElements.ProfileElement" 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" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance {x:Type profileElements:ProfileElementsViewModel}}"> d:DataContext="{d:DesignInstance {x:Type profileElements:ProfileElementsViewModel}}">
@ -32,6 +34,9 @@
dd:DragDrop.IsDragSource="True" dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True" dd:DragDrop.IsDropTarget="True"
dd:DragDrop.DropHandler="{Binding}"> dd:DragDrop.DropHandler="{Binding}">
<i:Interaction.Behaviors>
<utilities:BindableSelectedItemBehavior SelectedItem="{Binding SelectedProfileElement, Mode=TwoWay}" />
</i:Interaction.Behaviors>
<TreeView.Resources> <TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type profileElement:FolderViewModel}" ItemsSource="{Binding Children}"> <HierarchicalDataTemplate DataType="{x:Type profileElement:FolderViewModel}" ItemsSource="{Binding Children}">
<ContentControl s:View.Model="{Binding}" /> <ContentControl s:View.Model="{Binding}" />

View File

@ -8,6 +8,8 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
{ {
public class ProfileElementsViewModel : ProfileEditorPanelViewModel, IDropTarget public class ProfileElementsViewModel : ProfileEditorPanelViewModel, IDropTarget
{ {
private ProfileElementViewModel _selectedProfileElement;
public ProfileElementsViewModel() public ProfileElementsViewModel()
{ {
CreateRootFolderViewModel(); CreateRootFolderViewModel();
@ -15,6 +17,16 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
public FolderViewModel RootFolder { get; set; } public FolderViewModel RootFolder { get; set; }
public ProfileElementViewModel SelectedProfileElement
{
get => _selectedProfileElement;
set
{
_selectedProfileElement = value;
ProfileEditorViewModel.OnProfileElementSelected(_selectedProfileElement, this);
}
}
public void DragOver(IDropInfo dropInfo) public void DragOver(IDropInfo dropInfo)
{ {
var dragDropType = GetDragDropType(dropInfo); var dragDropType = GetDragDropType(dropInfo);
@ -53,7 +65,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
break; break;
} }
ProfileEditorViewModel.OnProfileUpdated(); ProfileEditorViewModel.OnProfileUpdated(this);
} }
// ReSharper disable once UnusedMember.Global - Called from view // ReSharper disable once UnusedMember.Global - Called from view
@ -74,6 +86,15 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.ProfileElements
base.ActiveProfileChanged(); 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() private void CreateRootFolderViewModel()
{ {
if (!(ProfileEditorViewModel?.SelectedProfile?.Children?.FirstOrDefault() is Folder folder)) if (!(ProfileEditorViewModel?.SelectedProfile?.Children?.FirstOrDefault() is Folder folder))

View File

@ -6,7 +6,7 @@
xmlns:s="https://github.com/canton7/Stylet" xmlns:s="https://github.com/canton7/Stylet"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
xmlns:profileEditor="clr-namespace:Artemis.UI.Screens.Module.ProfileEditor.Visualization" 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" mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" d:DesignHeight="450" d:DesignWidth="800"
d:DataContext="{d:DesignInstance {x:Type profileEditor:ProfileViewModel}}"> d:DataContext="{d:DesignInstance {x:Type profileEditor:ProfileViewModel}}">
@ -44,9 +44,9 @@
MouseDown="{s:Action EditorGridMouseClick}" MouseDown="{s:Action EditorGridMouseClick}"
MouseMove="{s:Action EditorGridMouseMove}" MouseMove="{s:Action EditorGridMouseMove}"
Cursor="{Binding Cursor}" Cursor="{Binding Cursor}"
observers:SizeObserver.Observe="True" utilities:SizeObserver.Observe="True"
observers:SizeObserver.ObservedWidth="{Binding PanZoomViewModel.CanvasWidth, Mode=OneWayToSource}" utilities:SizeObserver.ObservedWidth="{Binding PanZoomViewModel.CanvasWidth, Mode=OneWayToSource}"
observers:SizeObserver.ObservedHeight="{Binding PanZoomViewModel.CanvasHeight, Mode=OneWayToSource}"> utilities:SizeObserver.ObservedHeight="{Binding PanZoomViewModel.CanvasHeight, Mode=OneWayToSource}">
<Grid.Background> <Grid.Background>
<VisualBrush TileMode="Tile" Stretch="Uniform" Viewport="{Binding PanZoomViewModel.BackgroundViewport}" ViewportUnits="Absolute"> <VisualBrush TileMode="Tile" Stretch="Uniform" Viewport="{Binding PanZoomViewModel.BackgroundViewport}" ViewportUnits="Absolute">

View File

@ -6,6 +6,7 @@ using System.Windows.Input;
using System.Windows.Media; using System.Windows.Media;
using Artemis.Core.Events; using Artemis.Core.Events;
using Artemis.Core.Models.Surface; using Artemis.Core.Models.Surface;
using Artemis.Core.Plugins.Models;
using Artemis.Core.Services; using Artemis.Core.Services;
using Artemis.Core.Services.Storage.Interfaces; using Artemis.Core.Services.Storage.Interfaces;
using Artemis.UI.Extensions; using Artemis.UI.Extensions;
@ -20,10 +21,12 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
{ {
public class ProfileViewModel : ProfileEditorPanelViewModel public class ProfileViewModel : ProfileEditorPanelViewModel
{ {
private readonly ISettingsService _settingsService;
private readonly TimerUpdateTrigger _updateTrigger; private readonly TimerUpdateTrigger _updateTrigger;
public ProfileViewModel(ISurfaceService surfaceService, ISettingsService settingsService) public ProfileViewModel(ISurfaceService surfaceService, ISettingsService settingsService)
{ {
_settingsService = settingsService;
Devices = new ObservableCollection<ProfileDeviceViewModel>(); Devices = new ObservableCollection<ProfileDeviceViewModel>();
Execute.PostToUIThread(() => Execute.PostToUIThread(() =>
{ {
@ -48,6 +51,9 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
public ObservableCollection<ProfileDeviceViewModel> Devices { get; set; } public ObservableCollection<ProfileDeviceViewModel> Devices { get; set; }
public RectangleGeometry SelectionRectangle { get; set; } public RectangleGeometry SelectionRectangle { get; set; }
public PanZoomViewModel PanZoomViewModel { get; set; } public PanZoomViewModel PanZoomViewModel { get; set; }
public PluginSetting<bool> HighlightSelectedLayer { get; set; }
public PluginSetting<bool> PauseRenderingOnFocusLoss { get; set; }
public Cursor Cursor { get; set; } public Cursor Cursor { get; set; }
private void OnActiveSurfaceConfigurationChanged(object sender, SurfaceConfigurationEventArgs e) private void OnActiveSurfaceConfigurationChanged(object sender, SurfaceConfigurationEventArgs e)
@ -106,12 +112,18 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
protected override void OnActivate() protected override void OnActivate()
{ {
HighlightSelectedLayer = _settingsService.GetSetting("ProfileEditor.HighlightSelectedLayer", true);
PauseRenderingOnFocusLoss = _settingsService.GetSetting("ProfileEditor.PauseRenderingOnFocusLoss", true);
_updateTrigger.Start(); _updateTrigger.Start();
base.OnActivate(); base.OnActivate();
} }
protected override void OnDeactivate() protected override void OnDeactivate()
{ {
HighlightSelectedLayer.Save();
PauseRenderingOnFocusLoss.Save();
_updateTrigger.Stop(); _updateTrigger.Stop();
base.OnDeactivate(); base.OnDeactivate();
} }
@ -172,7 +184,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
profileLedViewModel.SelectionStatus = SelectionStatus.None; profileLedViewModel.SelectionStatus = SelectionStatus.None;
} }
} }
_mouseDragStatus = MouseDragStatus.None; _mouseDragStatus = MouseDragStatus.None;
} }
@ -180,7 +192,7 @@ namespace Artemis.UI.Screens.Module.ProfileEditor.Visualization
{ {
if (IsPanKeyDown()) if (IsPanKeyDown())
return; return;
var selectedRect = new Rect(_mouseDragStartPoint, position); var selectedRect = new Rect(_mouseDragStartPoint, position);
SelectionRectangle.Rect = selectedRect; SelectionRectangle.Rect = selectedRect;

View File

@ -1,5 +1,7 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.ComponentModel; using System.ComponentModel;
using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading.Tasks; using System.Threading.Tasks;
using System.Windows.Controls; using System.Windows.Controls;
@ -11,6 +13,7 @@ using Artemis.UI.Screens.News;
using Artemis.UI.Screens.Settings; using Artemis.UI.Screens.Settings;
using Artemis.UI.Screens.SurfaceEditor; using Artemis.UI.Screens.SurfaceEditor;
using Artemis.UI.Screens.Workshop; using Artemis.UI.Screens.Workshop;
using MahApps.Metro.Controls;
using Stylet; using Stylet;
namespace Artemis.UI.Screens namespace Artemis.UI.Screens

View File

@ -1,9 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Reflection; using System.Reflection;
using System.Windows.Threading;
using Ninject; using Ninject;
using Serilog;
using Stylet; using Stylet;
namespace Artemis.UI.Stylet namespace Artemis.UI.Stylet

View File

@ -0,0 +1,47 @@
using System.Windows;
using System.Windows.Controls;
using System.Windows.Interactivity;
namespace Artemis.UI.Utilities
{
public class BindableSelectedItemBehavior : Behavior<TreeView>
{
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<object> 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
}
}

View File

@ -1,6 +1,6 @@
using System.Windows; using System.Windows;
namespace Artemis.UI.Observers namespace Artemis.UI.Utilities
{ {
public static class SizeObserver public static class SizeObserver
{ {

View File

@ -20,7 +20,7 @@ using System.Windows.Media.Animation;
// //
// As this works on anything that inherits from TriggerBase, it will also work on <MultiTrigger>. // As this works on anything that inherits from TriggerBase, it will also work on <MultiTrigger>.
namespace Artemis.UI.DebugTriggers namespace Artemis.UI.Utilities
{ {
#if DEBUG #if DEBUG