Nearly fully implemented surface rearranging

This commit is contained in:
SpoinkyNL committed 2019-08-25 22:26:10 +02:00
1 parent 171f63a1db
commit 9184bbdec2
9 files changed
+175 -547

No files matched your search

@@ -4,12 +4,15 @@ using System.Windows;
using System.Windows.Input;
using RGB.NET.Core;
using Stylet;
using Point = System.Windows.Point;
namespace Artemis.UI.ViewModels.Controls.RgbDevice
{
public class RgbDeviceViewModel : PropertyChangedBase
{
private readonly List<RgbLedViewModel> _leds;
private double _dragOffsetX;
private double _dragOffsetY;
public RgbDeviceViewModel(IRGBDevice device)
{
@@ -38,6 +41,44 @@ namespace Artemis.UI.ViewModels.Controls.RgbDevice
rgbLedViewModel.ColorsEnabled = enabled;
}
public void StartMouseDrag(Point mouseStartPosition)
{
_dragOffsetX = Device.Location.X - mouseStartPosition.X;
_dragOffsetY = Device.Location.Y - mouseStartPosition.Y;
}
public void UpdateMouseDrag(Point mousePosition)
{
var roundedX = Math.Round((mousePosition.X + _dragOffsetX) / 10, 0, MidpointRounding.AwayFromZero) * 10;
var roundedY = Math.Round((mousePosition.Y + _dragOffsetY) / 10, 0, MidpointRounding.AwayFromZero) * 10;
this.Device.Location = new RGB.NET.Core.Point(roundedX, roundedY);
}
public void FinishMouseDrag(Point mouseEndPosition)
{
// TODO: Save and update
}
// ReSharper disable once UnusedMember.Global - Called from view
public void MouseEnter()
{
if (SelectionStatus == SelectionStatus.None)
{
SelectionStatus = SelectionStatus.Hover;
Cursor = Cursors.Hand;
}
}
// ReSharper disable once UnusedMember.Global - Called from view
public void MouseLeave()
{
if (SelectionStatus == SelectionStatus.Hover)
{
SelectionStatus = SelectionStatus.None;
Cursor = Cursors.Arrow;
}
}
public Rect DeviceRectangle => new Rect(Device.Location.X, Device.Location.Y, Device.Size.Width, Device.Size.Height);
}
@@ -20,7 +20,6 @@ namespace Artemis.UI.ViewModels.Controls.RgbDevice
Update();
}
[DoNotNotify]
public Led Led { get; }
public double X { get; private set; }
@@ -97,6 +96,8 @@ namespace Artemis.UI.ViewModels.Controls.RgbDevice
{
if (ColorsEnabled)
{
if (Led.Id == LedId.Keyboard_Y)
Console.WriteLine();
var newColor = Led.Color.ToMediaColor();
SetColor(newColor);
}
@@ -30,7 +30,7 @@ namespace Artemis.UI.ViewModels.Screens
foreach (var surfaceDevice in _rgbService.Surface.Devices)
{
var device = new RgbDeviceViewModel(surfaceDevice) {Cursor = Cursors.Hand};
device.SetColorsEnabled(false);
// device.SetColorsEnabled(false);
Devices.Add(device);
}
@@ -48,7 +48,7 @@ namespace Artemis.UI.ViewModels.Screens
if (Devices.All(d => d.Device != e.Device))
{
var device = new RgbDeviceViewModel(e.Device) {Cursor = Cursors.Hand};
device.SetColorsEnabled(false);
// device.SetColorsEnabled(false);
Devices.Add(device);
}
});
@@ -60,67 +60,112 @@ namespace Artemis.UI.ViewModels.Screens
rgbDeviceViewModel.Update();
}
#region Selection
#region Mouse actions
private bool _editorSelecting;
private Point _selectionStartPoint;
private MouseDragStatus _mouseDragStatus;
private Point _mouseDragStartPoint;
private void StartSelection(Point position)
private void StartMouseDrag(Point position)
{
_selectionStartPoint = position;
_editorSelecting = true;
// If drag started on top of a device, initialise dragging
var device = Devices.LastOrDefault(d => d.DeviceRectangle.Contains(position));
if (device != null)
{
_mouseDragStatus = MouseDragStatus.Dragging;
// If the device is not selected, deselect others and select only this one
if (device.SelectionStatus != SelectionStatus.Selected)
{
foreach (var others in Devices)
others.SelectionStatus = SelectionStatus.None;
device.SelectionStatus = SelectionStatus.Selected;
}
foreach (var selectedDevice in Devices.Where(d => d.SelectionStatus == SelectionStatus.Selected))
selectedDevice.StartMouseDrag(position);
}
// Start multi-selection
else
{
_mouseDragStatus = MouseDragStatus.Selecting;
_mouseDragStartPoint = position;
}
SelectionRectangle.Rect = new Rect();
// While dragging always show an arrow to avoid cursor flicker
Mouse.OverrideCursor = Cursors.Arrow;
// Any time dragging starts, start with a new rect
SelectionRectangle.Rect = new Rect();
}
private void StopSelection(Point position)
private void StopMouseDrag(Point position)
{
_editorSelecting = false;
Mouse.OverrideCursor = null;
var selectedRect = new Rect(_selectionStartPoint, position);
foreach (var device in Devices)
if (_mouseDragStatus == MouseDragStatus.Dragging)
{
if (device.DeviceRectangle.IntersectsWith(selectedRect))
device.SelectionStatus = SelectionStatus.Selected;
else
device.SelectionStatus = SelectionStatus.None;
}
else
{
var selectedRect = new Rect(_mouseDragStartPoint, position);
foreach (var device in Devices)
{
if (device.DeviceRectangle.IntersectsWith(selectedRect))
device.SelectionStatus = SelectionStatus.Selected;
else
device.SelectionStatus = SelectionStatus.None;
}
}
Mouse.OverrideCursor = null;
_mouseDragStatus = MouseDragStatus.None;
}
private void UpdateSelection(Point position)
{
var selectedRect = new Rect(_selectionStartPoint, position);
SelectionRectangle.Rect = selectedRect;
foreach (var device in Devices)
lock (Devices)
{
if (device.DeviceRectangle.IntersectsWith(selectedRect))
device.SelectionStatus = SelectionStatus.Selected;
else
device.SelectionStatus = SelectionStatus.None;
var selectedRect = new Rect(_mouseDragStartPoint, position);
SelectionRectangle.Rect = selectedRect;
foreach (var device in Devices)
{
if (device.DeviceRectangle.IntersectsWith(selectedRect))
device.SelectionStatus = SelectionStatus.Selected;
else
device.SelectionStatus = SelectionStatus.None;
}
}
}
private void MoveSelected(Point position)
{
foreach (var device in Devices.Where(d => d.SelectionStatus == SelectionStatus.Selected))
device.UpdateMouseDrag(position);
}
// ReSharper disable once UnusedMember.Global - Called from view
public void EditorGridMouseClick(object sender, MouseEventArgs e)
{
var position = e.GetPosition((IInputElement) sender);
if (e.LeftButton == MouseButtonState.Pressed)
StartSelection(position);
StartMouseDrag(position);
else
StopSelection(position);
StopMouseDrag(position);
}
// ReSharper disable once UnusedMember.Global - Called from view
public void EditorGridMouseMove(object sender, MouseEventArgs e)
{
if (!_editorSelecting)
return;
var position = e.GetPosition((IInputElement) sender);
UpdateSelection(position);
if (_mouseDragStatus == MouseDragStatus.Dragging)
MoveSelected(position);
else if (_mouseDragStatus == MouseDragStatus.Selecting)
UpdateSelection(position);
}
#endregion
}
internal enum MouseDragStatus
{
None,
Selecting,
Dragging
}
}
@@ -4,12 +4,13 @@
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:rgbDevice="clr-namespace:Artemis.UI.ViewModels.Controls.RgbDevice"
xmlns:xaml="https://github.com/canton7/Stylet"
xmlns:s="https://github.com/canton7/Stylet"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance rgbDevice:RgbDeviceViewModel}"
d:DesignHeight="450" d:DesignWidth="800"
Cursor="{Binding Cursor}">
<UserControl.Resources></UserControl.Resources>
Cursor="{Binding Cursor}"
MouseEnter="{s:Action MouseEnter}"
MouseLeave="{s:Action MouseLeave}">
<Grid>
<Image Source="{Binding Device.DeviceInfo.Image}" />
<ItemsControl ItemsSource="{Binding Leds}">
@@ -26,42 +27,54 @@
</ItemsControl.ItemContainerStyle>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Width="{Binding Width}" Height="{Binding Height}" xaml:View.Model="{Binding}" />
<ContentControl Width="{Binding Width}" Height="{Binding Height}" s:View.Model="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
<Rectangle Width="Auto" Height="Auto" StrokeThickness="1">
<Rectangle Width="Auto" Height="Auto" StrokeThickness="2">
<Rectangle.Stroke>
<SolidColorBrush Color="{StaticResource IdealForegroundColor}"/>
</Rectangle.Stroke>
<Rectangle.Fill>
<SolidColorBrush Color="{StaticResource IdealForegroundColor}" Opacity="0.25"/>
</Rectangle.Fill>
<Rectangle.Style>
<Style TargetType="Rectangle">
<Style.Triggers>
<DataTrigger Binding="{Binding SelectionStatus}" Value="{x:Static rgbDevice:SelectionStatus.Hover}">
<Setter Property="Rectangle.Fill">
<Setter.Value>
<SolidColorBrush Color="{DynamicResource IdealForegroundColor}" Opacity="0.25" />
</Setter.Value>
</Setter>
<Setter Property="Rectangle.Stroke" Value="{DynamicResource IdealForegroundColorBrush}"/>
<DataTrigger.EnterActions>
<StopStoryboard BeginStoryboardName="ToSelected"></StopStoryboard>
<BeginStoryboard x:Name="ToHover">
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" To="{StaticResource IdealForegroundColor}" Duration="0:0:0.25" />
<ColorAnimation Storyboard.TargetProperty="(Rectangle.Stroke).(SolidColorBrush.Color)" To="{StaticResource IdealForegroundColor}" Duration="0:0:0.25" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding SelectionStatus}" Value="{x:Static rgbDevice:SelectionStatus.Selected}">
<Setter Property="Rectangle.Fill">
<Setter.Value>
<SolidColorBrush Color="{DynamicResource Primary400}" Opacity="0.25" />
</Setter.Value>
</Setter>
<Setter Property="Rectangle.Stroke" Value="{DynamicResource PrimaryHueLightBrush}" />
<DataTrigger.EnterActions>
<StopStoryboard BeginStoryboardName="ToHover"></StopStoryboard>
<BeginStoryboard x:Name="ToSelected">
<Storyboard>
<ColorAnimation Storyboard.TargetProperty="(Rectangle.Fill).(SolidColorBrush.Color)" To="{StaticResource Primary400}" Duration="0:0:0.25" />
<ColorAnimation Storyboard.TargetProperty="(Rectangle.Stroke).(SolidColorBrush.Color)" To="{StaticResource Primary400}" Duration="0:0:0.25" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
</DataTrigger>
<DataTrigger Binding="{Binding SelectionStatus}" Value="{x:Static rgbDevice:SelectionStatus.None}">
<DataTrigger.EnterActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="1" To="0" Duration="0:0:0.25" />
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:0.25" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.EnterActions>
<DataTrigger.ExitActions>
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0" To="1" Duration="0:0:0.25" />
<DoubleAnimation Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:0.25" />
</Storyboard>
</BeginStoryboard>
</DataTrigger.ExitActions>