1
0
mirror of https://github.com/Artemis-RGB/Artemis synced 2026-02-04 10:53:31 +00:00

Fixed custom controls not responding to changes, fixed title bar interaciton

This commit is contained in:
Robert 2023-04-02 10:40:54 +02:00
parent 02e85af4af
commit 82b41425aa
20 changed files with 141 additions and 120 deletions

View File

@ -58,7 +58,7 @@ jobs:
- name: Setup .NET
uses: actions/setup-dotnet@v2
with:
dotnet-version: '6.0.x'
dotnet-version: '7.0.x'
- name: Publish Artemis
run: dotnet publish --configuration Release -p:Version=${{ needs.version.outputs.version-number }} --runtime ${{ matrix.rid }} --output build/${{ matrix.rid }} --self-contained Artemis/src/Artemis.UI.${{ matrix.csproj }}/Artemis.UI.${{ matrix.csproj }}.csproj
- name: Publish Plugins

View File

@ -28,6 +28,7 @@ public partial class ArtemisIcon : UserControl
InitializeComponent();
DetachedFromLogicalTree += OnDetachedFromLogicalTree;
LayoutUpdated += OnLayoutUpdated;
PropertyChanged += OnPropertyChanged;
}
private void Update()
@ -87,6 +88,12 @@ public partial class ArtemisIcon : UserControl
}
}
private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{
if (e.Property == IconProperty || e.Property == FillProperty)
Update();
}
private void OnDetachedFromLogicalTree(object? sender, LogicalTreeAttachmentEventArgs e)
{
if (Content is Image image && image.Source is IDisposable disposable)
@ -109,11 +116,7 @@ public partial class ArtemisIcon : UserControl
public object? Icon
{
get => GetValue(IconProperty);
set
{
SetValue(IconProperty, value);
Update();
}
set => SetValue(IconProperty, value);
}
/// <summary>
@ -129,11 +132,7 @@ public partial class ArtemisIcon : UserControl
public bool Fill
{
get => GetValue(FillProperty);
set
{
SetValue(FillProperty, value);
Update();
}
set => SetValue(FillProperty, value);
}
#endregion

View File

@ -38,12 +38,14 @@ public class DeviceVisualizer : Control
_deviceVisualizerLeds = new List<DeviceVisualizerLed>();
PointerReleased += OnPointerReleased;
PropertyChanged += OnPropertyChanged;
}
/// <inheritdoc />
public override void Render(DrawingContext drawingContext)
{
if (Device == null)
if (Device == null || _deviceBounds.Width == 0 || _deviceBounds.Height == 0)
return;
// Determine the scale required to fit the desired size of the control
@ -54,11 +56,11 @@ public class DeviceVisualizer : Control
{
// Scale the visualization in the desired bounding box
if (Bounds.Width > 0 && Bounds.Height > 0)
boundsPush = drawingContext.PushPreTransform(Matrix.CreateScale(scale, scale));
boundsPush = drawingContext.PushTransform(Matrix.CreateScale(scale, scale));
// Apply device rotation
using DrawingContext.PushedState translationPush = drawingContext.PushPreTransform(Matrix.CreateTranslation(0 - _deviceBounds.Left, 0 - _deviceBounds.Top));
using DrawingContext.PushedState rotationPush = drawingContext.PushPreTransform(Matrix.CreateRotation(Matrix.ToRadians(Device.Rotation)));
using DrawingContext.PushedState translationPush = drawingContext.PushTransform(Matrix.CreateTranslation(0 - _deviceBounds.Left, 0 - _deviceBounds.Top));
using DrawingContext.PushedState rotationPush = drawingContext.PushTransform(Matrix.CreateRotation(Matrix.ToRadians(Device.Rotation)));
// Render device and LED images
if (_deviceImage != null)
@ -75,7 +77,7 @@ public class DeviceVisualizer : Control
lock (_deviceVisualizerLeds)
{
// Apply device scale
using DrawingContext.PushedState scalePush = drawingContext.PushPreTransform(Matrix.CreateScale(Device.Scale, Device.Scale));
using DrawingContext.PushedState scalePush = drawingContext.PushTransform(Matrix.CreateScale(Device.Scale, Device.Scale));
foreach (DeviceVisualizerLed deviceVisualizerLed in _deviceVisualizerLeds)
deviceVisualizerLed.RenderGeometry(drawingContext, false);
}
@ -152,6 +154,12 @@ public class DeviceVisualizer : Control
OnClicked(e);
}
private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{
if (e.Property == DeviceProperty)
SetupForDevice();
}
private void DevicePropertyChanged(object? sender, PropertyChangedEventArgs e)
{
Dispatcher.UIThread.Post(SetupForDevice, DispatcherPriority.Background);
@ -176,11 +184,7 @@ public class DeviceVisualizer : Control
public ArtemisDevice? Device
{
get => GetValue(DeviceProperty);
set
{
SetValue(DeviceProperty, value);
SetupForDevice();
}
set => SetValue(DeviceProperty, value);
}
/// <summary>

View File

@ -23,7 +23,7 @@
</UserControl.Styles>
<Panel>
<controls:NumberBox Name="NumberBox"
<controls:NumberBox Name="InnerNumberBox"
AcceptsExpression="True"
LargeChange="{Binding $parent[sharedControls:DraggableNumberBox].LargeChange}"
SmallChange="{Binding $parent[sharedControls:DraggableNumberBox].SmallChange}"

View File

@ -68,11 +68,12 @@ public partial class DraggableNumberBox : UserControl
public DraggableNumberBox()
{
InitializeComponent();
NumberBox.Value = Value;
InnerNumberBox.Value = Value;
PointerPressed += OnPointerPressed;
PointerMoved += OnPointerMoved;
PointerReleased += OnPointerReleased;
PropertyChanged += OnPropertyChanged;
AddHandler(KeyUpEvent, HandleKeyUp, RoutingStrategies.Direct | RoutingStrategies.Tunnel | RoutingStrategies.Bubble, true);
}
@ -83,11 +84,7 @@ public partial class DraggableNumberBox : UserControl
public double Value
{
get => GetValue(ValueProperty);
set
{
SetValue(ValueProperty, value);
SetNumberBoxValue(value);
}
set => SetValue(ValueProperty, value);
}
/// <summary>
@ -165,11 +162,11 @@ public partial class DraggableNumberBox : UserControl
private void SetNumberBoxValue(double value)
{
if (!(Math.Abs(NumberBox.Value - Value) > 0.00001))
if (!(Math.Abs(InnerNumberBox.Value - Value) > 0.00001))
return;
_updating = true;
NumberBox.Value = Value;
InnerNumberBox.Value = Value;
_updating = false;
}
@ -182,7 +179,7 @@ public partial class DraggableNumberBox : UserControl
private void OnPointerPressed(object? sender, PointerPressedEventArgs e)
{
PointerPoint point = e.GetCurrentPoint(this);
_inputTextBox = NumberBox.FindDescendantOfType<TextBox>();
_inputTextBox = InnerNumberBox.FindDescendantOfType<TextBox>();
_moved = false;
_startX = point.Position.X;
_lastX = point.Position.X;
@ -247,6 +244,12 @@ public partial class DraggableNumberBox : UserControl
e.Handled = true;
}
private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{
if (e.Property == ValueProperty)
SetNumberBoxValue(Value);
}
private void NumberBox_OnValueChanged(NumberBox sender, NumberBoxValueChangedEventArgs args)
{
if (_updating)
@ -254,17 +257,17 @@ public partial class DraggableNumberBox : UserControl
if (args.NewValue < Minimum)
{
NumberBox.Value = Minimum;
InnerNumberBox.Value = Minimum;
return;
}
if (args.NewValue > Maximum)
{
NumberBox.Value = Maximum;
InnerNumberBox.Value = Maximum;
return;
}
if (Math.Abs(Value - NumberBox.Value) > 0.00001)
Value = NumberBox.Value;
if (Math.Abs(Value - InnerNumberBox.Value) > 0.00001)
Value = InnerNumberBox.Value;
}
}

View File

@ -30,21 +30,26 @@ public partial class EnumComboBox : UserControl
/// </summary>
public EnumComboBox()
{
PropertyChanged += OnPropertyChanged;
InitializeComponent();
}
private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{
if (e.Property == ValueProperty)
{
UpdateValues();
UpdateSelection();
}
}
/// <summary>
/// Gets or sets the currently selected value
/// </summary>
public object? Value
{
get => GetValue(ValueProperty);
set
{
SetValue(ValueProperty, value);
UpdateValues();
UpdateSelection();
}
set => SetValue(ValueProperty, value);
}
private void OnSelectionChanged(object? sender, SelectionChangedEventArgs e)

View File

@ -94,6 +94,8 @@ public class GradientPicker : TemplatedControl
SelectedColorStop = EditingColorGradient.ElementAtOrDefault(index);
});
PropertyChanged += OnPropertyChanged;
}
/// <summary>
@ -102,11 +104,7 @@ public class GradientPicker : TemplatedControl
public ColorGradient ColorGradient
{
get => GetValue(ColorGradientProperty);
set
{
SetValue(ColorGradientProperty, value);
ApplyToField();
}
set => SetValue(ColorGradientProperty, value);
}
/// <summary>
@ -342,4 +340,10 @@ public class GradientPicker : TemplatedControl
EditingColorGradient.Randomize(6);
SelectedColorStop = EditingColorGradient.First();
}
private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{
if (e.Property == ColorGradientProperty)
ApplyToField();
}
}

View File

@ -47,17 +47,19 @@ public class GradientPickerButton : TemplatedControl
private Button? _button;
private ColorGradient? _lastColorGradient;
/// <inheritdoc />
public GradientPickerButton()
{
PropertyChanged += OnPropertyChanged;
}
/// <summary>
/// Gets or sets the color gradient.
/// </summary>
public ColorGradient? ColorGradient
{
get => GetValue(ColorGradientProperty);
set
{
SetValue(ColorGradientProperty, value);
Subscribe();
}
set => SetValue(ColorGradientProperty, value);
}
/// <summary>
@ -175,6 +177,12 @@ public class GradientPickerButton : TemplatedControl
LinearGradientBrush.GradientStops = collection;
}
private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{
if (e.Property == ColorGradientProperty)
Subscribe();
}
#region Overrides of Visual
/// <inheritdoc />

View File

@ -19,18 +19,21 @@ namespace Artemis.UI.Shared;
/// </summary>
public partial class HotkeyBox : UserControl
{
private readonly TextBox _displayTextBox;
/// <summary>
/// Creates a new instance of the <see cref="HotkeyBox" /> class
/// </summary>
public HotkeyBox()
{
InitializeComponent();
PropertyChanged += OnPropertyChanged;
DisplayTextBox.KeyDown += DisplayTextBoxOnKeyDown;
DisplayTextBox.KeyUp += DisplayTextBoxOnKeyUp;
UpdateDisplayTextBox();
}
_displayTextBox = this.Find<TextBox>("DisplayTextBox");
_displayTextBox.KeyDown += DisplayTextBoxOnKeyDown;
_displayTextBox.KeyUp += DisplayTextBoxOnKeyUp;
private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{
if (e.Property == HotkeyProperty)
UpdateDisplayTextBox();
}
@ -64,8 +67,8 @@ public partial class HotkeyBox : UserControl
if (Hotkey?.Key != null)
display = string.IsNullOrEmpty(display) ? Hotkey.Key.ToString() : $"{display}+{Hotkey.Key}";
_displayTextBox.Text = display;
_displayTextBox.CaretIndex = _displayTextBox.Text?.Length ?? 0;
DisplayTextBox.Text = display;
DisplayTextBox.CaretIndex = DisplayTextBox.Text?.Length ?? 0;
}
private void Button_OnClick(object? sender, RoutedEventArgs e)
@ -101,11 +104,7 @@ public partial class HotkeyBox : UserControl
public Hotkey? Hotkey
{
get => GetValue(HotkeyProperty);
set
{
SetValue(HotkeyProperty, value);
UpdateDisplayTextBox();
}
set => SetValue(HotkeyProperty, value);
}
/// <summary>

View File

@ -69,6 +69,14 @@ public class SelectionRectangle : Control
{
AffectsRender<TextBlock>(BackgroundProperty, BorderBrushProperty, BorderThicknessProperty);
IsHitTestVisible = false;
PropertyChanged += OnPropertyChanged;
}
private void OnPropertyChanged(object? sender, AvaloniaPropertyChangedEventArgs e)
{
if (e.Property == InputElementProperty)
SubscribeToInputElement();
}
/// <summary>
@ -113,11 +121,7 @@ public class SelectionRectangle : Control
public InputElement? InputElement
{
get => GetValue(InputElementProperty);
set
{
SetValue(InputElementProperty, value);
SubscribeToInputElement();
}
set => SetValue(InputElementProperty, value);
}
/// <summary>

View File

@ -28,13 +28,6 @@
<Setter Property="ClipToBounds" Value="True" />
</Style>
<Style Selector="Border#TitleBar">
<Setter Property="Height" Value="40"></Setter>
</Style>
<Style Selector="Window:windows Border#TitleBar">
<Setter Property="Margin" Value="0 0 138 0"></Setter>
</Style>
<Style Selector="Border.card">
<Setter Property="Padding" Value="16" />
<Setter Property="Background" Value="{DynamicResource ControlFillColorDefaultBrush}" />

View File

@ -5,6 +5,7 @@
xmlns:controls="clr-namespace:FluentAvalonia.UI.Controls;assembly=FluentAvalonia"
xmlns:propertyInput="clr-namespace:Artemis.UI.DefaultTypes.PropertyInput"
xmlns:shared="clr-namespace:Artemis.UI.Shared.Converters;assembly=Artemis.UI.Shared"
xmlns:behaviors="clr-namespace:Artemis.UI.Shared.Behaviors;assembly=Artemis.UI.Shared"
mc:Ignorable="d" d:DesignWidth="200" d:DesignHeight="450"
x:Class="Artemis.UI.DefaultTypes.PropertyInput.SKColorPropertyInputView"
x:DataType="propertyInput:SKColorPropertyInputViewModel">
@ -13,9 +14,10 @@
<shared:SKColorToColorConverter x:Key="SKColorToColorConverter" />
</UserControl.Resources>
<Grid Height="24" ColumnDefinitions="*">
<TextBox Classes="condensed"
Text="{CompiledBinding InputValue, Converter={StaticResource SKColorToStringConverter}}"
Padding="2 2 30 2">
<TextBox Classes="condensed" Padding="2 2 30 2" FontFamily="Consolas">
<Interaction.Behaviors>
<behaviors:LostFocusTextBoxBindingBehavior Text="{CompiledBinding InputValue, Converter={StaticResource SKColorToStringConverter}}" />
</Interaction.Behaviors>
</TextBox>
<controls:ColorPickerButton Classes="contained-color-picker-button"
Color="{CompiledBinding InputValue, Converter={StaticResource SKColorToColorConverter}}"

View File

@ -10,8 +10,17 @@
Title="Artemis 2.0"
MinWidth="600"
MinHeight="400">
<windowing:AppWindow.Styles>
<Styles>
<Style Selector="Border#TitleBarContainer">
<Setter Property="Height" Value="40"></Setter>
</Style>
<Style Selector="windowing|AppWindow:windows Border#TitleBarContainer">
<Setter Property="Margin" Value="0 0 138 0"></Setter>
</Style>
</Styles>
</windowing:AppWindow.Styles>
<Panel Name="RootPanel">
<Border Name="DragHandle" Background="Transparent" Height="40" HorizontalAlignment="Stretch" VerticalAlignment="Top"/>
<DockPanel>
<ContentControl Name="SidebarContentControl" Content="{Binding SidebarViewModel}" DockPanel.Dock="Left" Width="240">
<ContentControl.Transitions>
@ -20,7 +29,7 @@
</Transitions>
</ContentControl.Transitions>
</ContentControl>
<Border Name="TitleBar" DockPanel.Dock="Top">
<Border Name="TitleBarContainer" DockPanel.Dock="Top">
<ContentControl Content="{Binding TitleBarViewModel}"/>
</Border>
<ContentControl Content="{Binding}" />

View File

@ -14,8 +14,6 @@ namespace Artemis.UI;
public partial class MainWindow : ReactiveAppWindow<RootViewModel>
{
private readonly Panel _rootPanel;
private readonly ContentControl _sidebarContentControl;
private bool _activated;
public MainWindow()
@ -24,12 +22,10 @@ public partial class MainWindow : ReactiveAppWindow<RootViewModel>
Activated += OnActivated;
Deactivated += OnDeactivated;
// ApplyWindowSize();
InitializeComponent();
ApplyWindowSize();
_rootPanel = this.Get<Panel>("RootPanel");
_sidebarContentControl = this.Get<ContentControl>("SidebarContentControl");
_rootPanel.LayoutUpdated += OnLayoutUpdated;
RootPanel.LayoutUpdated += OnLayoutUpdated;
#if DEBUG
this.AttachDevTools();
@ -57,21 +53,15 @@ public partial class MainWindow : ReactiveAppWindow<RootViewModel>
RootViewModel.WindowSizeSetting.Value.ApplyFromWindow(this);
}
// TODO: Replace with a media query once https://github.com/AvaloniaUI/Avalonia/pull/7938 is implemented
private void OnLayoutUpdated(object? sender, EventArgs e)
{
_sidebarContentControl.Width = _rootPanel.Bounds.Width >= 1800 ? 300 : 240;
SidebarContentControl.Width = RootPanel.Bounds.Width >= 1800 ? 300 : 240;
}
private void OnOpened(object? sender, EventArgs e)
{
Opened -= OnOpened;
// ICoreApplicationView coreAppTitleBar = this;
// if (coreAppTitleBar.TitleBar != null)
// {
// coreAppTitleBar.TitleBar.ExtendViewIntoTitleBar = true;
// SetTitleBar(this.Get<Border>("DragHandle"));
// }
TitleBar.ExtendsContentIntoTitleBar = true;
}
private void OnActivated(object? sender, EventArgs e)

View File

@ -84,11 +84,7 @@
</paz:ZoomBorder>
<Border CornerRadius="0 0 8 0" VerticalAlignment="Top" HorizontalAlignment="Left" Background="{DynamicResource ControlFillColorDefaultBrush}">
<StackPanel Orientation="Horizontal" Margin="8">
<shared:ProfileConfigurationIcon ConfigurationIcon="{CompiledBinding ProfileConfiguration.Icon}"
Foreground="{DynamicResource ToolTipForeground}"
Width="18"
Height="18"
Margin="0 0 5 0" />
<shared:ProfileConfigurationIcon ConfigurationIcon="{CompiledBinding ProfileConfiguration.Icon}" Width="18" Height="18" Margin="0 0 5 0" />
<TextBlock Text="{CompiledBinding ProfileConfiguration.Name}" />
</StackPanel>
</Border>

View File

@ -3,15 +3,18 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:windowing="clr-namespace:FluentAvalonia.UI.Windowing;assembly=FluentAvalonia"
xmlns:profileEditor="clr-namespace:Artemis.UI.Screens.ProfileEditor"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.ProfileEditor.ProfileEditorTitleBarView">
<Grid ColumnDefinitions="Auto,*,Auto">
<ContentControl Grid.Row="0" Grid.Column="0" Content="{Binding MenuBarViewModel}" />
<!-- This border enables dragging the window in between the menu and the buttons-->
<Border Grid.Row="0" Grid.Column="1" VerticalAlignment="Stretch" HorizontalAlignment="Stretch" Background="Transparent" IsHitTestVisible="False" />
<Button Grid.Column="2" Classes="title-bar-button" Command="{Binding ShowDebugger}" HorizontalAlignment="Right" VerticalAlignment="Top">
x:Class="Artemis.UI.Screens.ProfileEditor.ProfileEditorTitleBarView"
x:DataType="profileEditor:ProfileEditorTitleBarViewModel">
<Grid ColumnDefinitions="*,Auto">
<ContentControl Grid.Row="0" Grid.Column="0" Content="{CompiledBinding MenuBarViewModel}" windowing:AppWindow.AllowInteractionInTitleBar="True" HorizontalAlignment="Left" />
<Button Grid.Column="1" Classes="title-bar-button"
Command="{CompiledBinding ShowDebugger}"
HorizontalAlignment="Right"
VerticalAlignment="Top"
windowing:AppWindow.AllowInteractionInTitleBar="True">
<avalonia:MaterialIcon Kind="Bug" />
</Button>
</Grid>

View File

@ -3,9 +3,10 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia"
xmlns:windowing="clr-namespace:FluentAvalonia.UI.Windowing;assembly=FluentAvalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
x:Class="Artemis.UI.Screens.Root.DefaultTitleBarView">
<Button Classes="title-bar-button" Command="{Binding ShowDebugger}" VerticalAlignment="Top" HorizontalAlignment="Right">
<Button Classes="title-bar-button" Command="{Binding ShowDebugger}" VerticalAlignment="Top" HorizontalAlignment="Right" windowing:AppWindow.AllowInteractionInTitleBar="True" >
<avalonia:MaterialIcon Kind="Bug"></avalonia:MaterialIcon>
</Button>
</UserControl>

View File

@ -25,7 +25,7 @@
Margin="10 2"
Items="{CompiledBinding SidebarScreens}"
SelectedItem="{CompiledBinding SelectedSidebarScreen}" />
<Separator Grid.Row="2" Margin="8" Height="1" Background="#FF6c6c6c" />
<Border Grid.Row="2" Margin="8" Height="1" Background="{DynamicResource ButtonBorderBrush}"></Border>
<!-- Categories -->
<ScrollViewer Grid.Row="3" VerticalScrollBarVisibility="Auto">
@ -39,7 +39,7 @@
</ScrollViewer>
<!-- Bottom buttons -->
<Separator Grid.Row="4" Margin="8" />
<Border Grid.Row="4" Margin="8" Height="1" Background="{DynamicResource ButtonBorderBrush}"></Border>
<WrapPanel Grid.Row="5" Orientation="Horizontal" HorizontalAlignment="Left" Margin="5 0 5 5">
<controls:HyperlinkButton Classes="icon-button"
Width="44"

View File

@ -44,6 +44,7 @@
</TextBox>
<TextBlock Classes="h4" Text="{CompiledBinding TestValue}"/>
<controls1:NumberBox Value="{CompiledBinding TestValue}"/>
<controls:DraggableNumberBox Value="{CompiledBinding TestValue}"/>
<controls:DraggableNumberBox Value="{CompiledBinding TestValue}" Classes="condensed"/>

View File

@ -3,7 +3,7 @@
xmlns:styling="clr-namespace:FluentAvalonia.Styling;assembly=FluentAvalonia"
xmlns:avalonia="clr-namespace:Material.Icons.Avalonia;assembly=Material.Icons.Avalonia">
<!-- Third party styles -->
<styling:FluentAvaloniaTheme PreferSystemTheme="False" RequestedTheme="Dark"/>
<styling:FluentAvaloniaTheme PreferSystemTheme="False" PreferUserAccentColor="True"/>
<avalonia:MaterialIconStyles />
<!-- <FluentTheme Mode="Dark"></FluentTheme> -->