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

Various Gradient Tool Improvements

- Fix Implementation of the "Toggle Gradient" button.
- Add confirmation popup for the clear gradient button.
- Move buttons to above gradient (thanks Cheerpipe!)
This commit is contained in:
Luke Taylor 2021-04-30 12:04:21 -04:00
parent e8bcff542a
commit 695a3a6867
2 changed files with 126 additions and 81 deletions

View File

@ -60,8 +60,79 @@
</StackPanel> </StackPanel>
<Separator Grid.Row="1" Margin="0 5" /> <Separator Grid.Row="1" Margin="0 5" />
<StackPanel Grid.Row="2" Margin="0 5" ClipToBounds="False"> <StackPanel Grid.Row="2" Margin="0 5" ClipToBounds="False">
<Grid>
<TextBlock Margin="0 5">Gradient</TextBlock> <TextBlock Margin="0 5">Gradient</TextBlock>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right">
<Button Style="{StaticResource MaterialDesignFlatButton}"
Margin="0 0 5 4"
Padding="0"
Command="{s:Action SpreadColorStops}"
ToolTip="Spread Stops" IsEnabled="{Binding HasMoreThanOneStop}"
HorizontalAlignment="Left"
Height="25" Width="25">
<materialDesign:PackIcon Kind="ArrowLeftRight"/>
</Button>
<Button Style="{StaticResource MaterialDesignFlatButton}"
Margin="0 0 5 4"
Padding="0"
Command="{s:Action ToggleSeam}"
ToolTip="Toggle Seamless" IsEnabled="{Binding HasMoreThanOneStop}"
HorizontalAlignment="Left"
Height="25" Width="25">
<materialDesign:PackIcon Kind="SineWave"/>
</Button>
<Button Style="{StaticResource MaterialDesignFlatButton}"
Margin="0 0 5 4"
Padding="0"
Command="{s:Action FlipColorStops}"
ToolTip="Flip Stops" IsEnabled="{Binding HasMoreThanOneStop}"
HorizontalAlignment="Left"
Height="25" Width="25">
<materialDesign:PackIcon Kind="FlipHorizontal"/>
</Button>
<Button Style="{StaticResource MaterialDesignFlatButton}"
Margin="0 0 5 4"
Padding="0"
Command="{s:Action RotateColorStops}"
ToolTip="Rotate Stops (shift to invert)" IsEnabled="{Binding HasMoreThanOneStop}"
HorizontalAlignment="Left"
Height="25" Width="25">
<materialDesign:PackIcon Kind="AxisZRotateCounterclockwise"/>
</Button>
<Button Style="{StaticResource MaterialDesignFlatButton}"
Margin="0 0 5 4"
Padding="0"
Command="{s:Action ShowClearGradientPopup}"
ToolTip="Clear All Color Stops" IsEnabled="{Binding HasMoreThanOneStop}"
HorizontalAlignment="Left"
Height="25" Width="25"
x:Name="ClearGradientButton">
<StackPanel>
<materialDesign:PackIcon Kind="DeleteSweep"/>
</StackPanel>
</Button>
<Popup
AllowsTransparency="True"
Placement="Right"
VerticalOffset="-25"
HorizontalOffset="-5"
CustomPopupPlacementCallback="{x:Static materialDesign:CustomPopupPlacementCallbackHelper.LargePopupCallback}"
PlacementTarget="{Binding ElementName=ClearGradientButton}"
StaysOpen="False"
PopupAnimation="Fade"
IsOpen="{Binding ClearGradientPopupOpen, Mode=OneWay}">
<materialDesign:Card Margin="30" Padding="12" materialDesign:ShadowAssist.ShadowDepth="Depth4" >
<StackPanel HorizontalAlignment="Center">
<TextBlock Style="{StaticResource MaterialDesignSubtitle2TextBlock}" TextAlignment="Center" Margin="0 0 0 10">Clear Gradient?</TextBlock>
<StackPanel Orientation="Horizontal">
<Button Command="{s:Action HideClearGradientPopup}" Style="{StaticResource MaterialDesignOutlinedButton}" Margin="0 0 10 0">No</Button>
<Button Command="{s:Action ClearGradientAndHide}">Yes</Button>
</StackPanel>
</StackPanel>
</materialDesign:Card>
</Popup>
</StackPanel>
</Grid>
<Border Background="{StaticResource Checkerboard}"> <Border Background="{StaticResource Checkerboard}">
<Rectangle x:Name="Preview" Height="40" shared:SizeObserver.Observe="True" shared:SizeObserver.ObservedWidth="{Binding PreviewWidth, Mode=OneWayToSource}"> <Rectangle x:Name="Preview" Height="40" shared:SizeObserver.Observe="True" shared:SizeObserver.ObservedWidth="{Binding PreviewWidth, Mode=OneWayToSource}">
<Rectangle.Fill> <Rectangle.Fill>
@ -90,67 +161,6 @@
</DataTemplate> </DataTemplate>
</ItemsControl.ItemTemplate> </ItemsControl.ItemTemplate>
</ItemsControl> </ItemsControl>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0">
<Button Style="{StaticResource MaterialDesignOutlinedButton}"
Margin="0 4 8 8"
Command="{s:Action SpreadColorStops}"
ToolTip="Spread Stops" IsEnabled="{Binding HasMoreThanOneStop}"
HorizontalAlignment="Left"
Height="25" Width="100">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="DistributeHorizontalCenter"/>
<TextBlock Margin="6 0 0 0">Spread</TextBlock>
</StackPanel>
</Button>
<Button Style="{StaticResource MaterialDesignOutlinedButton}"
Margin="0 4 8 8"
Command="{s:Action RotateColorStops}"
ToolTip="Rotate Stops" IsEnabled="{Binding HasMoreThanOneStop}"
HorizontalAlignment="Left"
Height="25" Width="100">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="AxisZRotateCounterclockwise" />
<TextBlock Margin="6 0 0 0">Rotate</TextBlock>
</StackPanel>
</Button>
<Button Style="{StaticResource MaterialDesignOutlinedButton}"
Margin="0 4 8 8"
Command="{s:Action FlipColorStops}"
IsEnabled="{Binding HasMoreThanOneStop}"
HorizontalAlignment="Left"
Height="25" Width="100" ToolTip="Flip Stops">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="FlipHorizontal"/>
<TextBlock Margin="6 0 0 0">Flip</TextBlock>
</StackPanel>
</Button>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Margin="0">
<Button Style="{StaticResource MaterialDesignOutlinedButton}"
Margin="0 0 8 0"
Command="{s:Action ToggleSeam}"
IsEnabled="{Binding HasMoreThanOneStop}"
HorizontalAlignment="Left"
Height="25" Width="100" ToolTip="Toggle Seam">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="ArrowSplitVertical"/>
<TextBlock Margin="6 0 0 0">Seam</TextBlock>
</StackPanel>
</Button>
<Button Style="{StaticResource MaterialDesignOutlinedButton}"
Margin="0 0 8 0"
Command="{s:Action ClearGradient}"
IsEnabled="{Binding HasMoreThanOneStop}"
HorizontalAlignment="Left"
Height="25" Width="100" ToolTip="Clear Gradient">
<StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="DeleteSweep"/>
<TextBlock Margin="6 0 0 0">Clear</TextBlock>
</StackPanel>
</Button>
</StackPanel>
<TextBlock Margin="0 6 0 0" FontWeight="Bold">Selected stop:</TextBlock> <TextBlock Margin="0 6 0 0" FontWeight="Bold">Selected stop:</TextBlock>
<Grid Margin="0 5"> <Grid Margin="0 5">
@ -170,7 +180,7 @@
<Label HorizontalAlignment="Center">Location:</Label> <Label HorizontalAlignment="Center">Location:</Label>
<TextBox Width="30" <TextBox Width="30"
Text="{Binding SelectedColorStopViewModel.OffsetPercent}" Text="{Binding SelectedColorStopViewModel.OffsetPercent, UpdateSourceTrigger=PropertyChanged}"
IsEnabled="{Binding HasSelectedColorStopViewModel}" IsEnabled="{Binding HasSelectedColorStopViewModel}"
materialDesign:HintAssist.Hint="0" materialDesign:HintAssist.Hint="0"
Margin="5 0 0 0" /> Margin="5 0 0 0" />
@ -184,6 +194,9 @@
Command="{s:Action RemoveColorStop}" Command="{s:Action RemoveColorStop}"
CommandParameter="{Binding SelectedColorStopViewModel}" CommandParameter="{Binding SelectedColorStopViewModel}"
ToolTip="Delete Selected Stop"> ToolTip="Delete Selected Stop">
<Button.Resources>
<SolidColorBrush x:Key="PrimaryHueMidBrush" Color="#c94848"/>
</Button.Resources>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<materialDesign:PackIcon Kind="Delete"/> <materialDesign:PackIcon Kind="Delete"/>
<TextBlock Margin="4 0 0 0">Delete</TextBlock> <TextBlock Margin="4 0 0 0">Delete</TextBlock>

View File

@ -1,4 +1,5 @@
using System.Collections.Generic; using System;
using System.Collections.Generic;
using System.Collections.Specialized; using System.Collections.Specialized;
using System.ComponentModel; using System.ComponentModel;
using System.Linq; using System.Linq;
@ -44,6 +45,8 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
public bool HasSelectedColorStopViewModel => SelectedColorStopViewModel != null; public bool HasSelectedColorStopViewModel => SelectedColorStopViewModel != null;
public bool HasMoreThanOneStop => ColorStopViewModels.Count > 1; public bool HasMoreThanOneStop => ColorStopViewModels.Count > 1;
private bool popupOpen = false;
public bool ClearGradientPopupOpen => popupOpen;
public ColorGradient ColorGradient { get; } public ColorGradient ColorGradient { get; }
@ -91,6 +94,7 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
NotifyOfPropertyChange(nameof(HasMoreThanOneStop)); NotifyOfPropertyChange(nameof(HasMoreThanOneStop));
} }
#region Gradient Tools
public void SpreadColorStops() public void SpreadColorStops()
{ {
List<ColorStopViewModel> stops = ColorStopViewModels.OrderBy(x => x.OffsetFloat).ToList(); List<ColorStopViewModel> stops = ColorStopViewModels.OrderBy(x => x.OffsetFloat).ToList();
@ -129,39 +133,67 @@ namespace Artemis.UI.Shared.Screens.GradientEditor
if (ColorGradient.IsSeamless()) if (ColorGradient.IsSeamless())
{ {
// Remove the last stop // Remove the last stop
ColorStopViewModel? stop = ColorStopViewModels.OrderBy(x => x.OffsetFloat).Last(); ColorStopViewModel? stopToRemove = ColorStopViewModels.OrderBy(x => x.OffsetFloat).Last();
if (stop == SelectedColorStopViewModel) SelectColorStop(null); if (stopToRemove == SelectedColorStopViewModel) SelectColorStop(null);
ColorStopViewModels.Remove(stopToRemove);
ColorGradient.Remove(stopToRemove.ColorStop);
// Uncompress the stops if there is still more than one
List<ColorStopViewModel> stops = ColorStopViewModels.OrderBy(x => x.OffsetFloat).ToList();
if (stops.Count >= 2)
{
float multiplier = stops.Count/(stops.Count - 1f);
foreach (ColorStopViewModel stop in stops)
stop.OffsetFloat = Math.Min(stop.OffsetFloat * multiplier, 100f);
}
ColorStopViewModels.Remove(stop);
ColorGradient.Remove(stop.ColorStop);
// Distribute the stops if there is still more than one
if (ColorGradient.Count > 1)
SpreadColorStops();
} }
else else
{ {
// Compress existing stops to the left
List<ColorStopViewModel> stops = ColorStopViewModels.OrderBy(x => x.OffsetFloat).ToList();
float multiplier = (stops.Count - 1f)/stops.Count;
foreach (ColorStopViewModel stop in stops)
stop.OffsetFloat *= multiplier;
// Add a stop to the end that is the same color as the first stop // Add a stop to the end that is the same color as the first stop
ColorGradientStop stop = new(ColorGradient.First().Color, 100); ColorGradientStop newStop = new(ColorGradient.First().Color, 1f);
ColorGradient.Add(stop); ColorGradient.Add(newStop);
ColorStopViewModel viewModel = new(this, stop); int index = ColorGradient.IndexOf(newStop);
ColorStopViewModels.Add(viewModel); ColorStopViewModel viewModel = new(this, newStop);
ColorStopViewModels.Insert(index, viewModel);
NotifyOfPropertyChange(nameof(HasMoreThanOneStop));
// Distribute the stops
SpreadColorStops();
} }
} }
public void ShowClearGradientPopup()
{
popupOpen = true;
NotifyOfPropertyChange(nameof(ClearGradientPopupOpen));
}
public void HideClearGradientPopup()
{
popupOpen = false;
NotifyOfPropertyChange(nameof(ClearGradientPopupOpen));
}
public void ClearGradientAndHide()
{
ClearGradient();
HideClearGradientPopup();
}
public void ClearGradient() public void ClearGradient()
{ {
ColorGradient.Clear(); ColorGradient.Clear();
ColorStopViewModels.Clear(); ColorStopViewModels.Clear();
} }
#endregion
public Point GetPositionInPreview(object sender, MouseEventArgs e) public Point GetPositionInPreview(object sender, MouseEventArgs e)
{ {
Canvas? parent = VisualTreeUtilities.FindParent<Canvas>((DependencyObject) sender, null); Canvas? parent = VisualTreeUtilities.FindParent<Canvas>((DependencyObject) sender, null);