mirror of
https://github.com/fadden/6502bench.git
synced 2024-06-12 08:29:29 +00:00
Progress on animated visualizations
Visualization editor dialog is fully functional. Add/remove, up/down, tag/interval timer editing, and animated preview are now working.
This commit is contained in:
parent
9f9e518afc
commit
fef7668b63
|
@ -48,6 +48,9 @@
|
||||||
<Reference Include="PresentationFramework" />
|
<Reference Include="PresentationFramework" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Compile Include="FrameAnimationControl.xaml.cs">
|
||||||
|
<DependentUpon>FrameAnimationControl.xaml</DependentUpon>
|
||||||
|
</Compile>
|
||||||
<Compile Include="Helper.cs" />
|
<Compile Include="Helper.cs" />
|
||||||
<Compile Include="InverseBooleanConverter.cs" />
|
<Compile Include="InverseBooleanConverter.cs" />
|
||||||
<Compile Include="MultiKeyInputGesture.cs" />
|
<Compile Include="MultiKeyInputGesture.cs" />
|
||||||
|
@ -79,6 +82,10 @@
|
||||||
</None>
|
</None>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
<Page Include="FrameAnimationControl.xaml">
|
||||||
|
<SubType>Designer</SubType>
|
||||||
|
<Generator>MSBuild:Compile</Generator>
|
||||||
|
</Page>
|
||||||
<Page Include="WorkProgress.xaml">
|
<Page Include="WorkProgress.xaml">
|
||||||
<Generator>MSBuild:Compile</Generator>
|
<Generator>MSBuild:Compile</Generator>
|
||||||
<SubType>Designer</SubType>
|
<SubType>Designer</SubType>
|
||||||
|
|
37
CommonWPF/FrameAnimationControl.xaml
Normal file
37
CommonWPF/FrameAnimationControl.xaml
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
<!--
|
||||||
|
Copyright 2019 faddenSoft
|
||||||
|
|
||||||
|
Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
you may not use this file except in compliance with the License.
|
||||||
|
You may obtain a copy of the License at
|
||||||
|
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
|
||||||
|
Unless required by applicable law or agreed to in writing, software
|
||||||
|
distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
See the License for the specific language governing permissions and
|
||||||
|
limitations under the License.
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!--
|
||||||
|
Basic usage:
|
||||||
|
<common:FrameAnimationControl Name="previewAnim" Width="256" Height="256"/>
|
||||||
|
|
||||||
|
You must explicitly Stop() the animation, or it will continue to run forever.
|
||||||
|
|
||||||
|
Thanks: https://blogs.claritycon.com/wpf-image-sequencer-for-png-sequences-4c826f7d4462
|
||||||
|
-->
|
||||||
|
<UserControl x:Class="CommonWPF.FrameAnimationControl"
|
||||||
|
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||||
|
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||||
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
|
xmlns:local="clr-namespace:CommonWPF"
|
||||||
|
mc:Ignorable="d"
|
||||||
|
Background="Transparent"
|
||||||
|
d:DesignHeight="128" d:DesignWidth="128">
|
||||||
|
<Grid>
|
||||||
|
<Image Name="theImage"/>
|
||||||
|
</Grid>
|
||||||
|
</UserControl>
|
111
CommonWPF/FrameAnimationControl.xaml.cs
Normal file
111
CommonWPF/FrameAnimationControl.xaml.cs
Normal file
|
@ -0,0 +1,111 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2019 faddenSoft
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Diagnostics;
|
||||||
|
using System.Windows.Controls;
|
||||||
|
using System.Windows.Media.Imaging;
|
||||||
|
using System.Windows.Threading;
|
||||||
|
|
||||||
|
namespace CommonWPF {
|
||||||
|
/// <summary>
|
||||||
|
/// The Frame Animation control provides a simple way to display a series of images.
|
||||||
|
/// (Think of an animated GIF.)
|
||||||
|
///
|
||||||
|
/// Set Bitmaps and IntervalMsec, then call Start.
|
||||||
|
/// </summary>
|
||||||
|
public partial class FrameAnimationControl : UserControl {
|
||||||
|
/// <summary>
|
||||||
|
/// List of bitmaps to be displayed.
|
||||||
|
/// </summary>
|
||||||
|
public List<BitmapSource> Bitmaps {
|
||||||
|
get { return mBitmaps; }
|
||||||
|
set {
|
||||||
|
if (value == null || value.Count == 0) {
|
||||||
|
throw new ArgumentException("Invalid bitmap list");
|
||||||
|
}
|
||||||
|
mBitmaps = value;
|
||||||
|
if (mNext >= value.Count) {
|
||||||
|
mNext = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private List<BitmapSource> mBitmaps;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// How long to wait before showing next bitmap.
|
||||||
|
/// </summary>
|
||||||
|
public int IntervalMsec {
|
||||||
|
get { return mIntervalMsec; }
|
||||||
|
set {
|
||||||
|
if (value < 1) {
|
||||||
|
throw new ArgumentException("Invalid interval " + value);
|
||||||
|
}
|
||||||
|
mIntervalMsec = value;
|
||||||
|
mTimer.Interval = TimeSpan.FromMilliseconds(value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private int mIntervalMsec = 100;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// True if the animation is currently running.
|
||||||
|
/// </summary>
|
||||||
|
public bool IsRunning {
|
||||||
|
get { return mTimer.IsEnabled; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Index of next image to display.
|
||||||
|
/// </summary>
|
||||||
|
private int mNext;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Dispatcher-linked timer object.
|
||||||
|
/// </summary>
|
||||||
|
private DispatcherTimer mTimer;
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Constructor, invoked from XAML.
|
||||||
|
/// </summary>
|
||||||
|
public FrameAnimationControl() {
|
||||||
|
InitializeComponent();
|
||||||
|
|
||||||
|
mTimer = new DispatcherTimer(DispatcherPriority.Render);
|
||||||
|
mTimer.Interval = TimeSpan.FromMilliseconds(IntervalMsec);
|
||||||
|
mTimer.Tick += Tick;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Start() {
|
||||||
|
mTimer.Start();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Stop() {
|
||||||
|
mTimer.Stop();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Tick(object sender, EventArgs e) {
|
||||||
|
if (mBitmaps == null) {
|
||||||
|
throw new InvalidOperationException("Must set bitmaps before starting");
|
||||||
|
}
|
||||||
|
if (mNext >= mBitmaps.Count) {
|
||||||
|
mNext = 0;
|
||||||
|
}
|
||||||
|
theImage.Source = mBitmaps[mNext];
|
||||||
|
mNext++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -29,6 +29,16 @@ namespace SourceGen {
|
||||||
/// view angles.
|
/// view angles.
|
||||||
/// </remarks>
|
/// </remarks>
|
||||||
public class VisualizationAnimation : Visualization {
|
public class VisualizationAnimation : Visualization {
|
||||||
|
/// <summary>
|
||||||
|
/// Frame delay parameter.
|
||||||
|
/// </summary>
|
||||||
|
public const string FRAME_DELAY_MSEC_PARAM = "frame-delay-msec";
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Fake visualization generation identifier.
|
||||||
|
/// </summary>
|
||||||
|
public const string ANIM_VIS_GEN = "(animation)";
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Serial numbers of visualizations, e.g. bitmap frames.
|
/// Serial numbers of visualizations, e.g. bitmap frames.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -60,5 +70,18 @@ namespace SourceGen {
|
||||||
|
|
||||||
mSerialNumbers = visSerialNumbers;
|
mSerialNumbers = visSerialNumbers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Returns true if this visualization holds a reference to the specified serial number.
|
||||||
|
/// </summary>
|
||||||
|
public bool ContainsSerial(int serial) {
|
||||||
|
// Linear search. We don't do this a lot and our lists our short, so okay for now.
|
||||||
|
foreach (int ser in mSerialNumbers) {
|
||||||
|
if (ser == serial) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,10 +20,12 @@ limitations under the License.
|
||||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||||
xmlns:local="clr-namespace:SourceGen.WpfGui"
|
xmlns:local="clr-namespace:SourceGen.WpfGui"
|
||||||
|
xmlns:common="clr-namespace:CommonWPF;assembly=CommonWPF"
|
||||||
mc:Ignorable="d"
|
mc:Ignorable="d"
|
||||||
Title="Edit Bitmap Animation"
|
Title="Edit Bitmap Animation"
|
||||||
SizeToContent="WidthAndHeight" ResizeMode="NoResize"
|
SizeToContent="WidthAndHeight" ResizeMode="NoResize"
|
||||||
ShowInTaskbar="False" WindowStartupLocation="CenterOwner">
|
ShowInTaskbar="False" WindowStartupLocation="CenterOwner"
|
||||||
|
Closing="Window_Closing">
|
||||||
|
|
||||||
<Grid Margin="8">
|
<Grid Margin="8">
|
||||||
<Grid.RowDefinitions>
|
<Grid.RowDefinitions>
|
||||||
|
@ -31,10 +33,23 @@ limitations under the License.
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<!-- top section: bitmap visualization selection -->
|
<!-- top section: tag entry -->
|
||||||
<Grid Grid.Row="0">
|
<StackPanel Grid.Row="0">
|
||||||
|
<StackPanel Orientation="Horizontal">
|
||||||
|
<TextBlock Margin="0,0,4,0" Text="Tag:"/>
|
||||||
|
<TextBox Width="250" Margin="4,1,0,0"
|
||||||
|
Text="{Binding TagString, UpdateSourceTrigger=PropertyChanged}"
|
||||||
|
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<TextBlock Text="• Must be unique, 2+ chars" Margin="30,0,0,0" Foreground="{Binding TagLabelBrush}"/>
|
||||||
|
</StackPanel>
|
||||||
|
|
||||||
|
<!-- upper-middle section: bitmap visualization selection -->
|
||||||
|
<Grid Grid.Row="1" Margin="0,8,0,0">
|
||||||
<Grid.ColumnDefinitions>
|
<Grid.ColumnDefinitions>
|
||||||
<ColumnDefinition Width="*"/>
|
<ColumnDefinition Width="*"/>
|
||||||
<ColumnDefinition Width="Auto"/>
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
@ -45,10 +60,10 @@ limitations under the License.
|
||||||
<RowDefinition Height="Auto"/>
|
<RowDefinition Height="Auto"/>
|
||||||
</Grid.RowDefinitions>
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
<TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3"
|
<TextBlock Grid.Column="0" Grid.Row="0" Grid.ColumnSpan="3" Margin="0,0,0,4"
|
||||||
Text="Select bitmap visualizations to use as animation frames:"/>
|
Text="Select visualizations to use as animation frames:"/>
|
||||||
|
|
||||||
<DataGrid Grid.Column="0" Grid.Row="1" Name="visSourceGrid"
|
<DataGrid Grid.Column="0" Grid.Row="1" Name="visSourceGrid" Width="251" Height="300"
|
||||||
IsReadOnly="True"
|
IsReadOnly="True"
|
||||||
ItemsSource="{Binding VisSourceItems}"
|
ItemsSource="{Binding VisSourceItems}"
|
||||||
FontFamily="{StaticResource GeneralMonoFont}"
|
FontFamily="{StaticResource GeneralMonoFont}"
|
||||||
|
@ -59,6 +74,7 @@ limitations under the License.
|
||||||
HeadersVisibility="Column"
|
HeadersVisibility="Column"
|
||||||
CanUserReorderColumns="False"
|
CanUserReorderColumns="False"
|
||||||
SelectionMode="Single"
|
SelectionMode="Single"
|
||||||
|
SelectionChanged="VisSourceGrid_SelectionChanged"
|
||||||
MouseDoubleClick="VisSourceGrid_MouseDoubleClick">
|
MouseDoubleClick="VisSourceGrid_MouseDoubleClick">
|
||||||
<DataGrid.Resources>
|
<DataGrid.Resources>
|
||||||
<!-- make the no-focus color the same as the in-focus color -->
|
<!-- make the no-focus color the same as the in-focus color -->
|
||||||
|
@ -83,7 +99,7 @@ limitations under the License.
|
||||||
</DataGrid.Columns>
|
</DataGrid.Columns>
|
||||||
</DataGrid>
|
</DataGrid>
|
||||||
|
|
||||||
<DataGrid Grid.Column="2" Grid.Row="1" Name="visAnimGrid"
|
<DataGrid Grid.Column="2" Grid.Row="1" Name="visAnimGrid" Width="251" Height="300"
|
||||||
IsReadOnly="True"
|
IsReadOnly="True"
|
||||||
ItemsSource="{Binding VisAnimItems}"
|
ItemsSource="{Binding VisAnimItems}"
|
||||||
FontFamily="{StaticResource GeneralMonoFont}"
|
FontFamily="{StaticResource GeneralMonoFont}"
|
||||||
|
@ -94,6 +110,7 @@ limitations under the License.
|
||||||
HeadersVisibility="Column"
|
HeadersVisibility="Column"
|
||||||
CanUserReorderColumns="False"
|
CanUserReorderColumns="False"
|
||||||
SelectionMode="Single"
|
SelectionMode="Single"
|
||||||
|
SelectionChanged="VisAnimGrid_SelectionChanged"
|
||||||
MouseDoubleClick="VisAnimGrid_MouseDoubleClick">
|
MouseDoubleClick="VisAnimGrid_MouseDoubleClick">
|
||||||
<DataGrid.Resources>
|
<DataGrid.Resources>
|
||||||
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}"
|
<SolidColorBrush x:Key="{x:Static SystemColors.InactiveSelectionHighlightBrushKey}"
|
||||||
|
@ -116,30 +133,67 @@ limitations under the License.
|
||||||
</DataGrid.Columns>
|
</DataGrid.Columns>
|
||||||
</DataGrid>
|
</DataGrid>
|
||||||
|
|
||||||
<StackPanel Grid.Column="1" Grid.Row="1" Height="200">
|
<StackPanel Grid.Column="1" Grid.Row="1">
|
||||||
<Button Content="Add →" Width="70" Margin="4,24,4,4"/>
|
<Button Content="Add →" Width="70" Margin="4,24,4,4"
|
||||||
<Button Content="← Remove" Width="70" Margin="4,0,4,4"/>
|
IsEnabled="{Binding IsAddEnabled}" Click="AddButton_Click"/>
|
||||||
<Button Content="Clear" Width="70" Margin="4,4,4,4"/>
|
<Button Content="← Remove" Width="70" Margin="4,0,4,4"
|
||||||
<Button Content="Up ↑" Width="70" Margin="4,20,4,4"/>
|
IsEnabled="{Binding IsRemoveEnabled}" Click="RemoveButton_Click"/>
|
||||||
<Button Content="Down ↓" Width="70" Margin="4,0,4,4"/>
|
<Button Content="Clear" Width="70" Margin="4,4,4,4"
|
||||||
|
IsEnabled="{Binding IsRemoveEnabled}" Click="ClearButton_Click"/>
|
||||||
|
<Button Content="Up ↑" Width="70" Margin="4,20,4,4"
|
||||||
|
IsEnabled="{Binding IsUpEnabled}" Click="UpButton_Click"/>
|
||||||
|
<Button Content="Down ↓" Width="70" Margin="4,0,4,4"
|
||||||
|
IsEnabled="{Binding IsDownEnabled}" Click="DownButton_Click"/>
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<!-- middle section: parameters -->
|
<!-- lower-middle section: parameters -->
|
||||||
<Grid Grid.Row="1" Margin="0,8,0,0">
|
<Grid Grid.Row="2" Margin="0,8,0,0">
|
||||||
<StackPanel Orientation="Horizontal">
|
<Grid.RowDefinitions>
|
||||||
<TextBlock Text="Frame delay (msec):" Margin="0,1,0,0"/>
|
<RowDefinition Height="Auto"/>
|
||||||
<TextBox Width="40" MaxLength="5" Margin="4,0,0,0"
|
<RowDefinition Height="Auto"/>
|
||||||
Text="{Binding FrameDelayTimeMsec, FallbackValue=88888}" />
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<StackPanel Grid.Row="1" Orientation="Horizontal">
|
||||||
</StackPanel>
|
</StackPanel>
|
||||||
|
|
||||||
|
<Grid Grid.Row="0">
|
||||||
|
<Grid.ColumnDefinitions>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
<ColumnDefinition Width="Auto"/>
|
||||||
|
</Grid.ColumnDefinitions>
|
||||||
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<TextBlock Grid.Column="0" Grid.Row="2" HorizontalAlignment="Right" Margin="0,1,4,0"
|
||||||
|
Text="Frame delay (msec):" Foreground="{Binding FrameDelayLabelBrush}"/>
|
||||||
|
<TextBox Grid.Column="1" Grid.Row="2" Width="40" HorizontalAlignment="Left" Margin="0,0,0,0"
|
||||||
|
Text="{Binding FrameDelayTimeMsec, UpdateSourceTrigger=PropertyChanged, FallbackValue=88888}"
|
||||||
|
MaxLength="5"/>
|
||||||
|
</Grid>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<!-- bottom section: preview -->
|
<!-- bottom section: preview -->
|
||||||
<Grid Grid.Row="2" Margin="0,8,0,0">
|
<Grid Grid.Row="3" Margin="0,8,0,0">
|
||||||
<TextBlock Text="Preview:"/>
|
<Grid.RowDefinitions>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
<RowDefinition Height="Auto"/>
|
||||||
|
</Grid.RowDefinitions>
|
||||||
|
|
||||||
|
<Border Grid.Row="0" BorderBrush="Black" BorderThickness="1"
|
||||||
|
HorizontalAlignment="Center" VerticalAlignment="Center"
|
||||||
|
Background="{StaticResource CheckerBackground}">
|
||||||
|
<common:FrameAnimationControl Name="previewAnim" Width="256" Height="256"
|
||||||
|
RenderOptions.BitmapScalingMode="NearestNeighbor"/>
|
||||||
|
</Border>
|
||||||
|
<Button Grid.Row="1" Width="120" Content="Start / Stop" Margin="0,4,0,0"
|
||||||
|
Click="showPreviewClick" IsEnabled="{Binding IsPreviewEnabled}"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
||||||
<DockPanel Grid.Row="3" Margin="0,8,0,0" LastChildFill="False">
|
<DockPanel Grid.Row="4" Margin="0,8,0,0" LastChildFill="False">
|
||||||
<Button DockPanel.Dock="Right" Content="Cancel" Width="70" Margin="8,0,0,0" IsCancel="True"/>
|
<Button DockPanel.Dock="Right" Content="Cancel" Width="70" Margin="8,0,0,0" IsCancel="True"/>
|
||||||
<Button DockPanel.Dock="Right" Grid.Column="1" Content="OK" Width="70"
|
<Button DockPanel.Dock="Right" Grid.Column="1" Content="OK" Width="70"
|
||||||
IsDefault="True" IsEnabled="{Binding IsValid}" Click="OkButton_Click"/>
|
IsDefault="True" IsEnabled="{Binding IsValid}" Click="OkButton_Click"/>
|
||||||
|
|
|
@ -17,9 +17,10 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Collections.ObjectModel;
|
using System.Collections.ObjectModel;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Runtime.CompilerServices;
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
|
||||||
using System.Windows;
|
using System.Windows;
|
||||||
|
using System.Windows.Controls;
|
||||||
using System.Windows.Input;
|
using System.Windows.Input;
|
||||||
using System.Windows.Media;
|
using System.Windows.Media;
|
||||||
using System.Windows.Media.Imaging;
|
using System.Windows.Media.Imaging;
|
||||||
|
@ -29,6 +30,21 @@ namespace SourceGen.WpfGui {
|
||||||
/// Bitmap animation visualization editor.
|
/// Bitmap animation visualization editor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class EditBitmapAnimation : Window, INotifyPropertyChanged {
|
public partial class EditBitmapAnimation : Window, INotifyPropertyChanged {
|
||||||
|
private const int MAX_FRAME_DELAY = 10000; // 10 sec, in ms
|
||||||
|
private const int DEFAULT_FRAME_DELAY = 100; // 0.1 sec, in ms
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// New/edited animation, only valid when dialog result is true.
|
||||||
|
/// </summary>
|
||||||
|
public VisualizationAnimation NewAnim { get; private set; }
|
||||||
|
|
||||||
|
private int mSetOffset;
|
||||||
|
private SortedList<int, VisualizationSet> mEditedList;
|
||||||
|
private VisualizationAnimation mOrigAnim;
|
||||||
|
|
||||||
|
private Brush mDefaultLabelColor = SystemColors.WindowTextBrush;
|
||||||
|
private Brush mErrorLabelColor = Brushes.Red;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// True if current contents represent a valid visualization animation. Determines
|
/// True if current contents represent a valid visualization animation. Determines
|
||||||
/// whether the OK button is enabled.
|
/// whether the OK button is enabled.
|
||||||
|
@ -45,14 +61,68 @@ namespace SourceGen.WpfGui {
|
||||||
public ObservableCollection<Visualization> VisAnimItems { get; private set; } =
|
public ObservableCollection<Visualization> VisAnimItems { get; private set; } =
|
||||||
new ObservableCollection<Visualization>();
|
new ObservableCollection<Visualization>();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Visualization tag.
|
||||||
|
/// </summary>
|
||||||
|
public string TagString {
|
||||||
|
get { return mTagString; }
|
||||||
|
set { mTagString = value; OnPropertyChanged(); UpdateControls(); }
|
||||||
|
}
|
||||||
|
private string mTagString;
|
||||||
|
|
||||||
|
// Text turns red on error.
|
||||||
|
public Brush TagLabelBrush {
|
||||||
|
get { return mTagLabelBrush; }
|
||||||
|
set { mTagLabelBrush = value; OnPropertyChanged(); }
|
||||||
|
}
|
||||||
|
private Brush mTagLabelBrush;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Time between frames, in milliseconds.
|
/// Time between frames, in milliseconds.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public int FrameDelayTimeMsec {
|
public string FrameDelayTimeMsec {
|
||||||
get { return mFrameDelayTimeMsec; }
|
get { return mFrameDelayTimeMsec; }
|
||||||
set { mFrameDelayTimeMsec = value; OnPropertyChanged(); }
|
set { mFrameDelayTimeMsec = value; OnPropertyChanged(); UpdateControls(); }
|
||||||
}
|
}
|
||||||
private int mFrameDelayTimeMsec;
|
private string mFrameDelayTimeMsec;
|
||||||
|
private int mFrameDelayIntMsec = -1;
|
||||||
|
|
||||||
|
public Brush FrameDelayLabelBrush {
|
||||||
|
get { return mFrameDelayLabelBrush; }
|
||||||
|
set { mFrameDelayLabelBrush = value; OnPropertyChanged(); }
|
||||||
|
}
|
||||||
|
private Brush mFrameDelayLabelBrush;
|
||||||
|
|
||||||
|
public bool IsAddEnabled {
|
||||||
|
get { return mIsAddEnabled; }
|
||||||
|
set { mIsAddEnabled = value; OnPropertyChanged(); }
|
||||||
|
}
|
||||||
|
private bool mIsAddEnabled;
|
||||||
|
|
||||||
|
public bool IsRemoveEnabled {
|
||||||
|
get { return mIsRemoveEnabled; }
|
||||||
|
set { mIsRemoveEnabled = value; OnPropertyChanged(); }
|
||||||
|
}
|
||||||
|
private bool mIsRemoveEnabled;
|
||||||
|
|
||||||
|
public bool IsUpEnabled {
|
||||||
|
get { return mIsUpEnabled; }
|
||||||
|
set { mIsUpEnabled = value; OnPropertyChanged(); }
|
||||||
|
}
|
||||||
|
private bool mIsUpEnabled;
|
||||||
|
|
||||||
|
public bool IsDownEnabled {
|
||||||
|
get { return mIsDownEnabled; }
|
||||||
|
set { mIsDownEnabled = value; OnPropertyChanged(); }
|
||||||
|
}
|
||||||
|
private bool mIsDownEnabled;
|
||||||
|
|
||||||
|
public bool IsPreviewEnabled {
|
||||||
|
get { return mIsPreviewEnabled; }
|
||||||
|
set { mIsPreviewEnabled = value; OnPropertyChanged(); }
|
||||||
|
}
|
||||||
|
private bool mIsPreviewEnabled;
|
||||||
|
|
||||||
|
|
||||||
// INotifyPropertyChanged implementation
|
// INotifyPropertyChanged implementation
|
||||||
public event PropertyChangedEventHandler PropertyChanged;
|
public event PropertyChangedEventHandler PropertyChanged;
|
||||||
|
@ -60,26 +130,271 @@ namespace SourceGen.WpfGui {
|
||||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Constructor.
|
/// Constructor.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="owner"></param>
|
public EditBitmapAnimation(Window owner, int setOffset,
|
||||||
public EditBitmapAnimation(Window owner) {
|
SortedList<int, VisualizationSet> editedList, VisualizationAnimation origAnim) {
|
||||||
InitializeComponent();
|
InitializeComponent();
|
||||||
Owner = owner;
|
Owner = owner;
|
||||||
DataContext = this;
|
DataContext = this;
|
||||||
|
|
||||||
|
mSetOffset = setOffset;
|
||||||
|
mEditedList = editedList;
|
||||||
|
mOrigAnim = origAnim;
|
||||||
|
|
||||||
|
// this will cause initialization of the Brush properties
|
||||||
|
FrameDelayTimeMsec = DEFAULT_FRAME_DELAY.ToString();
|
||||||
|
if (origAnim != null) {
|
||||||
|
TagString = origAnim.Tag;
|
||||||
|
int frameDelay = PluginCommon.Util.GetFromObjDict(origAnim.VisGenParams,
|
||||||
|
VisualizationAnimation.FRAME_DELAY_MSEC_PARAM, DEFAULT_FRAME_DELAY);
|
||||||
|
} else {
|
||||||
|
TagString = "anim" + mSetOffset.ToString("x6");
|
||||||
|
}
|
||||||
|
|
||||||
|
PopulateItemLists();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void PopulateItemLists() {
|
||||||
|
foreach (KeyValuePair<int, VisualizationSet> kvp in mEditedList) {
|
||||||
|
foreach (Visualization vis in kvp.Value) {
|
||||||
|
if (vis is VisualizationAnimation) {
|
||||||
|
// disallow animations with animations
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (mOrigAnim != null && mOrigAnim.ContainsSerial(vis.SerialNumber)) {
|
||||||
|
VisAnimItems.Add(vis);
|
||||||
|
} else {
|
||||||
|
VisSourceItems.Add(vis);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (VisSourceItems.Count > 0) {
|
||||||
|
visSourceGrid.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
if (VisAnimItems.Count > 0) {
|
||||||
|
visAnimGrid.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Window_Closing(object sender, CancelEventArgs e) {
|
||||||
|
previewAnim.Stop();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OkButton_Click(object sender, RoutedEventArgs e) {
|
private void OkButton_Click(object sender, RoutedEventArgs e) {
|
||||||
|
Dictionary<string, object> visGenParams = new Dictionary<string, object>(1);
|
||||||
|
visGenParams.Add(VisualizationAnimation.FRAME_DELAY_MSEC_PARAM, mFrameDelayIntMsec);
|
||||||
|
|
||||||
|
List<int> serials = new List<int>(VisAnimItems.Count);
|
||||||
|
foreach (Visualization vis in VisAnimItems) {
|
||||||
|
serials.Add(vis.SerialNumber);
|
||||||
|
}
|
||||||
|
|
||||||
|
NewAnim = new VisualizationAnimation(TagString, VisualizationAnimation.ANIM_VIS_GEN,
|
||||||
|
new ReadOnlyDictionary<string, object>(visGenParams), serials);
|
||||||
|
|
||||||
|
DialogResult = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private void UpdateControls() {
|
||||||
|
IsValid = true;
|
||||||
|
|
||||||
|
if (!int.TryParse(FrameDelayTimeMsec, out int frameDelay) ||
|
||||||
|
frameDelay <= 0 || frameDelay > MAX_FRAME_DELAY) {
|
||||||
|
mFrameDelayIntMsec = -1;
|
||||||
|
FrameDelayLabelBrush = mErrorLabelColor;
|
||||||
|
IsValid = false;
|
||||||
|
} else {
|
||||||
|
mFrameDelayIntMsec = frameDelay;
|
||||||
|
FrameDelayLabelBrush = mDefaultLabelColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isSourceItemSelected = (visSourceGrid.SelectedItem != null);
|
||||||
|
bool isAnimItemSelected = (visAnimGrid.SelectedItem != null);
|
||||||
|
IsAddEnabled = VisSourceItems.Count > 0 && isSourceItemSelected;
|
||||||
|
IsRemoveEnabled = VisAnimItems.Count > 0 && isAnimItemSelected;
|
||||||
|
IsUpEnabled = isAnimItemSelected && visAnimGrid.SelectedIndex != 0;
|
||||||
|
IsDownEnabled = isAnimItemSelected &&
|
||||||
|
visAnimGrid.SelectedIndex != VisAnimItems.Count - 1;
|
||||||
|
IsPreviewEnabled = VisAnimItems.Count > 0;
|
||||||
|
|
||||||
|
string trimTag = Visualization.TrimAndValidateTag(TagString, out bool tagOk);
|
||||||
|
Visualization match =
|
||||||
|
EditVisualizationSet.FindVisualizationByTag(mEditedList, trimTag);
|
||||||
|
if (match != null && (mOrigAnim == null || trimTag != mOrigAnim.Tag)) {
|
||||||
|
// Another vis already has this tag. We're checking the edited list, so we'll
|
||||||
|
// be current with edits to this or other Visualizations in the same set.
|
||||||
|
tagOk = false;
|
||||||
|
}
|
||||||
|
if (!tagOk) {
|
||||||
|
TagLabelBrush = mErrorLabelColor;
|
||||||
|
IsValid = false;
|
||||||
|
} else {
|
||||||
|
TagLabelBrush = mDefaultLabelColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshAnim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void VisSourceGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) {
|
||||||
|
UpdateControls();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void VisAnimGrid_SelectionChanged(object sender, SelectionChangedEventArgs e) {
|
||||||
|
UpdateControls();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void VisSourceGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
|
private void VisSourceGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
|
||||||
|
AddSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void VisAnimGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
|
private void VisAnimGrid_MouseDoubleClick(object sender, MouseButtonEventArgs e) {
|
||||||
|
RemoveSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void AddButton_Click(object sender, RoutedEventArgs e) {
|
||||||
|
AddSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void RemoveButton_Click(object sender, RoutedEventArgs e) {
|
||||||
|
RemoveSelection();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Adds an item to the animation list, moving it from the source list.
|
||||||
|
/// </summary>
|
||||||
|
private void AddSelection() {
|
||||||
|
if (!IsAddEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Visualization item = (Visualization)visSourceGrid.SelectedItem;
|
||||||
|
int index = VisSourceItems.IndexOf(item);
|
||||||
|
Debug.Assert(index >= 0);
|
||||||
|
VisSourceItems.Remove(item);
|
||||||
|
VisAnimItems.Add(item);
|
||||||
|
|
||||||
|
if (index == VisSourceItems.Count) {
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
if (index >= 0) {
|
||||||
|
visSourceGrid.SelectedIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visAnimGrid.SelectedIndex < 0) {
|
||||||
|
visAnimGrid.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshAnim();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Removes an item from the animation list, moving it to the source list.
|
||||||
|
/// </summary>
|
||||||
|
private void RemoveSelection() {
|
||||||
|
if (!IsRemoveEnabled) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Visualization item = (Visualization)visAnimGrid.SelectedItem;
|
||||||
|
int index = VisAnimItems.IndexOf(item);
|
||||||
|
Debug.Assert(index >= 0);
|
||||||
|
VisAnimItems.Remove(item);
|
||||||
|
VisSourceItems.Add(item);
|
||||||
|
|
||||||
|
if (index == VisAnimItems.Count) {
|
||||||
|
index--;
|
||||||
|
}
|
||||||
|
if (index >= 0) {
|
||||||
|
visAnimGrid.SelectedIndex = index;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visSourceGrid.SelectedIndex < 0) {
|
||||||
|
visSourceGrid.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshAnim();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Clears the animation list.
|
||||||
|
/// </summary>
|
||||||
|
private void ClearButton_Click(object sender, RoutedEventArgs e) {
|
||||||
|
Debug.Assert(IsRemoveEnabled);
|
||||||
|
|
||||||
|
while (VisAnimItems.Count > 0) {
|
||||||
|
Visualization item = VisAnimItems[0];
|
||||||
|
VisAnimItems.Remove(item);
|
||||||
|
VisSourceItems.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (visSourceGrid.SelectedIndex < 0) {
|
||||||
|
visSourceGrid.SelectedIndex = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
RefreshAnim();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Repositions an item in the animation list, moving it up one slot.
|
||||||
|
/// </summary>
|
||||||
|
private void UpButton_Click(object sender, RoutedEventArgs e) {
|
||||||
|
Visualization item = (Visualization)visAnimGrid.SelectedItem;
|
||||||
|
int index = VisAnimItems.IndexOf(item);
|
||||||
|
Debug.Assert(index > 0);
|
||||||
|
VisAnimItems.Remove(item);
|
||||||
|
VisAnimItems.Insert(index - 1, item);
|
||||||
|
visAnimGrid.SelectedIndex = index - 1;
|
||||||
|
|
||||||
|
//RefreshAnim();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Repositions an item in the animation list, moving it down one slot.
|
||||||
|
/// </summary>
|
||||||
|
private void DownButton_Click(object sender, RoutedEventArgs e) {
|
||||||
|
Visualization item = (Visualization)visAnimGrid.SelectedItem;
|
||||||
|
int index = VisAnimItems.IndexOf(item);
|
||||||
|
Debug.Assert(index >= 0 && index < VisAnimItems.Count - 1);
|
||||||
|
VisAnimItems.Remove(item);
|
||||||
|
VisAnimItems.Insert(index + 1, item);
|
||||||
|
visAnimGrid.SelectedIndex = index + 1;
|
||||||
|
|
||||||
|
//RefreshAnim();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void showPreviewClick(object sender, RoutedEventArgs e) {
|
||||||
|
if (previewAnim.IsRunning) {
|
||||||
|
previewAnim.Stop();
|
||||||
|
} else {
|
||||||
|
if (RefreshAnim()) {
|
||||||
|
previewAnim.Start();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Updates the frame animation control's parameters. Stops the animation if something
|
||||||
|
/// looks wrong.
|
||||||
|
/// </summary>
|
||||||
|
/// <returns>True if all is well, false if something is wrong and the animation
|
||||||
|
/// should not be started.</returns>
|
||||||
|
private bool RefreshAnim() {
|
||||||
|
if (VisAnimItems.Count == 0 || mFrameDelayIntMsec <= 0) {
|
||||||
|
previewAnim.Stop();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<BitmapSource> bitmaps = new List<BitmapSource>(VisAnimItems.Count);
|
||||||
|
foreach (Visualization vis in VisAnimItems) {
|
||||||
|
bitmaps.Add(vis.CachedImage);
|
||||||
|
}
|
||||||
|
previewAnim.Bitmaps = bitmaps;
|
||||||
|
previewAnim.IntervalMsec = mFrameDelayIntMsec;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -120,12 +120,13 @@ limitations under the License.
|
||||||
SelectionChanged="VisComboBox_SelectionChanged"/>
|
SelectionChanged="VisComboBox_SelectionChanged"/>
|
||||||
|
|
||||||
<TextBlock Grid.Column="0" Grid.Row="1" HorizontalAlignment="Right" Margin="0,0,4,0"
|
<TextBlock Grid.Column="0" Grid.Row="1" HorizontalAlignment="Right" Margin="0,0,4,0"
|
||||||
Text="Tag:" Foreground="{Binding TagLabelBrush}"/>
|
Text="Tag:"/>
|
||||||
<TextBox Grid.Column="1" Grid.Row="1" Width="250" Margin="0,1,0,0" HorizontalAlignment="Left"
|
<TextBox Grid.Column="1" Grid.Row="1" Width="250" Margin="0,1,0,0" HorizontalAlignment="Left"
|
||||||
Text="{Binding TagString, UpdateSourceTrigger=PropertyChanged}"
|
Text="{Binding TagString, UpdateSourceTrigger=PropertyChanged}"
|
||||||
FontFamily="{StaticResource GeneralMonoFont}"/>
|
FontFamily="{StaticResource GeneralMonoFont}"/>
|
||||||
|
|
||||||
<TextBlock Grid.Column="1" Grid.Row="2" Text="• Must be unique, 2+ chars"/>
|
<TextBlock Grid.Column="1" Grid.Row="2" Text="• Must be unique, 2+ chars"
|
||||||
|
Foreground="{Binding TagLabelBrush}"/>
|
||||||
|
|
||||||
<TextBlock Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" Margin="0,10,0,4" Text="Preview:"/>
|
<TextBlock Grid.Column="0" Grid.Row="3" Grid.ColumnSpan="2" Margin="0,10,0,4" Text="Preview:"/>
|
||||||
</Grid>
|
</Grid>
|
||||||
|
|
|
@ -33,7 +33,7 @@ namespace SourceGen.WpfGui {
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public partial class EditVisualization : Window, INotifyPropertyChanged {
|
public partial class EditVisualization : Window, INotifyPropertyChanged {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Dialog result.
|
/// New/edited visualization, only valid when dialog result is true.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public Visualization NewVis { get; private set; }
|
public Visualization NewVis { get; private set; }
|
||||||
|
|
||||||
|
@ -44,7 +44,8 @@ namespace SourceGen.WpfGui {
|
||||||
private Visualization mOrigVis;
|
private Visualization mOrigVis;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Identifier for last visualizer we used, for the benefit of "new".
|
/// Visualization generation identifier for the last visualizer we used, for the benefit
|
||||||
|
/// of "new".
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private static string sLastVisIdent = string.Empty;
|
private static string sLastVisIdent = string.Empty;
|
||||||
|
|
||||||
|
@ -187,6 +188,7 @@ namespace SourceGen.WpfGui {
|
||||||
mScriptSupport = new ScriptSupport(this);
|
mScriptSupport = new ScriptSupport(this);
|
||||||
mProject.PrepareScripts(mScriptSupport);
|
mProject.PrepareScripts(mScriptSupport);
|
||||||
|
|
||||||
|
// this will initialize mTagLabelBrush
|
||||||
if (vis != null) {
|
if (vis != null) {
|
||||||
TagString = vis.Tag;
|
TagString = vis.Tag;
|
||||||
} else {
|
} else {
|
||||||
|
@ -464,7 +466,8 @@ namespace SourceGen.WpfGui {
|
||||||
}
|
}
|
||||||
|
|
||||||
string trimTag = Visualization.TrimAndValidateTag(TagString, out bool tagOk);
|
string trimTag = Visualization.TrimAndValidateTag(TagString, out bool tagOk);
|
||||||
Visualization match = FindVisualizationByTag(trimTag);
|
Visualization match =
|
||||||
|
EditVisualizationSet.FindVisualizationByTag(mEditedList, trimTag);
|
||||||
if (match != null && (mOrigVis == null || trimTag != mOrigVis.Tag)) {
|
if (match != null && (mOrigVis == null || trimTag != mOrigVis.Tag)) {
|
||||||
// Another vis already has this tag. We're checking the edited list, so we'll
|
// Another vis already has this tag. We're checking the edited list, so we'll
|
||||||
// be current with edits to this or other Visualizations in the same set.
|
// be current with edits to this or other Visualizations in the same set.
|
||||||
|
@ -478,23 +481,6 @@ namespace SourceGen.WpfGui {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Finds a Visualization with a matching tag, searching across all sets in the
|
|
||||||
/// edited list.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="tag">Tag to search for.</param>
|
|
||||||
/// <returns>Matching Visualization, or null if not found.</returns>
|
|
||||||
private Visualization FindVisualizationByTag(string tag) {
|
|
||||||
foreach (KeyValuePair<int, VisualizationSet> kvp in mEditedList) {
|
|
||||||
foreach (Visualization vis in kvp.Value) {
|
|
||||||
if (vis.Tag == tag) {
|
|
||||||
return vis;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
private void VisComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
|
private void VisComboBox_SelectionChanged(object sender, SelectionChangedEventArgs e) {
|
||||||
VisualizationItem item = (VisualizationItem)visComboBox.SelectedItem;
|
VisualizationItem item = (VisualizationItem)visComboBox.SelectedItem;
|
||||||
if (item == null) {
|
if (item == null) {
|
||||||
|
|
|
@ -167,11 +167,13 @@ namespace SourceGen.WpfGui {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void NewBitmapAnimationButton_Click(object sender, RoutedEventArgs e) {
|
private void NewBitmapAnimationButton_Click(object sender, RoutedEventArgs e) {
|
||||||
EditBitmapAnimation dlg = new EditBitmapAnimation(this);
|
EditBitmapAnimation dlg = new EditBitmapAnimation(this, mOffset,
|
||||||
|
CreateEditedSetList(), null);
|
||||||
if (dlg.ShowDialog() != true) {
|
if (dlg.ShowDialog() != true) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// TODO(xyzzy)
|
VisualizationList.Add(dlg.NewAnim);
|
||||||
|
visualizationGrid.SelectedIndex = VisualizationList.Count - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void EditButton_Click(object sender, RoutedEventArgs e) {
|
private void EditButton_Click(object sender, RoutedEventArgs e) {
|
||||||
|
@ -184,16 +186,27 @@ namespace SourceGen.WpfGui {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Visualization item = (Visualization)visualizationGrid.SelectedItem;
|
Visualization item = (Visualization)visualizationGrid.SelectedItem;
|
||||||
|
Visualization newVis;
|
||||||
|
|
||||||
EditVisualization dlg = new EditVisualization(this, mProject, mFormatter, mOffset,
|
if (item is VisualizationAnimation) {
|
||||||
CreateEditedSetList(), item);
|
EditBitmapAnimation dlg = new EditBitmapAnimation(this, mOffset,
|
||||||
if (dlg.ShowDialog() != true) {
|
CreateEditedSetList(), (VisualizationAnimation)item);
|
||||||
return;
|
if (dlg.ShowDialog() != true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
newVis = dlg.NewAnim;
|
||||||
|
} else {
|
||||||
|
EditVisualization dlg = new EditVisualization(this, mProject, mFormatter, mOffset,
|
||||||
|
CreateEditedSetList(), item);
|
||||||
|
if (dlg.ShowDialog() != true) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
newVis = dlg.NewVis;
|
||||||
}
|
}
|
||||||
|
|
||||||
int index = VisualizationList.IndexOf(item);
|
int index = VisualizationList.IndexOf(item);
|
||||||
VisualizationList.Remove(item);
|
VisualizationList.Remove(item);
|
||||||
VisualizationList.Insert(index, dlg.NewVis);
|
VisualizationList.Insert(index, newVis);
|
||||||
visualizationGrid.SelectedIndex = index;
|
visualizationGrid.SelectedIndex = index;
|
||||||
|
|
||||||
okButton.Focus();
|
okButton.Focus();
|
||||||
|
@ -223,7 +236,7 @@ namespace SourceGen.WpfGui {
|
||||||
private void DownButton_Click(object sender, RoutedEventArgs e) {
|
private void DownButton_Click(object sender, RoutedEventArgs e) {
|
||||||
Visualization item = (Visualization)visualizationGrid.SelectedItem;
|
Visualization item = (Visualization)visualizationGrid.SelectedItem;
|
||||||
int index = VisualizationList.IndexOf(item);
|
int index = VisualizationList.IndexOf(item);
|
||||||
Debug.Assert(index < VisualizationList.Count - 1);
|
Debug.Assert(index >= 0 && index < VisualizationList.Count - 1);
|
||||||
VisualizationList.Remove(item);
|
VisualizationList.Remove(item);
|
||||||
VisualizationList.Insert(index + 1, item);
|
VisualizationList.Insert(index + 1, item);
|
||||||
visualizationGrid.SelectedIndex = index + 1;
|
visualizationGrid.SelectedIndex = index + 1;
|
||||||
|
@ -265,5 +278,23 @@ namespace SourceGen.WpfGui {
|
||||||
}
|
}
|
||||||
return mixList;
|
return mixList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Finds a Visualization with a matching tag, searching across all sets in the
|
||||||
|
/// edited list.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="tag">Tag to search for.</param>
|
||||||
|
/// <returns>Matching Visualization, or null if not found.</returns>
|
||||||
|
public static Visualization FindVisualizationByTag(SortedList<int, VisualizationSet> list,
|
||||||
|
string tag) {
|
||||||
|
foreach (KeyValuePair<int, VisualizationSet> kvp in list) {
|
||||||
|
foreach (Visualization vis in kvp.Value) {
|
||||||
|
if (vis.Tag == tag) {
|
||||||
|
return vis;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user