diff --git a/CommonWPF/CommonWPF.csproj b/CommonWPF/CommonWPF.csproj
index 101b77e..a452ff1 100644
--- a/CommonWPF/CommonWPF.csproj
+++ b/CommonWPF/CommonWPF.csproj
@@ -48,6 +48,9 @@
+
+ FrameAnimationControl.xaml
+
@@ -79,6 +82,10 @@
+
+ Designer
+ MSBuild:Compile
+
MSBuild:Compile
Designer
diff --git a/CommonWPF/FrameAnimationControl.xaml b/CommonWPF/FrameAnimationControl.xaml
new file mode 100644
index 0000000..778441e
--- /dev/null
+++ b/CommonWPF/FrameAnimationControl.xaml
@@ -0,0 +1,37 @@
+
+
+
+
+
+
+
+
diff --git a/CommonWPF/FrameAnimationControl.xaml.cs b/CommonWPF/FrameAnimationControl.xaml.cs
new file mode 100644
index 0000000..c01be07
--- /dev/null
+++ b/CommonWPF/FrameAnimationControl.xaml.cs
@@ -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 {
+ ///
+ /// 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.
+ ///
+ public partial class FrameAnimationControl : UserControl {
+ ///
+ /// List of bitmaps to be displayed.
+ ///
+ public List 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 mBitmaps;
+
+ ///
+ /// How long to wait before showing next bitmap.
+ ///
+ 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;
+
+ ///
+ /// True if the animation is currently running.
+ ///
+ public bool IsRunning {
+ get { return mTimer.IsEnabled; }
+ }
+
+ ///
+ /// Index of next image to display.
+ ///
+ private int mNext;
+
+ ///
+ /// Dispatcher-linked timer object.
+ ///
+ private DispatcherTimer mTimer;
+
+
+ ///
+ /// Constructor, invoked from XAML.
+ ///
+ 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++;
+ }
+ }
+}
diff --git a/SourceGen/VisualizationAnimation.cs b/SourceGen/VisualizationAnimation.cs
index 8f47b95..237a0ca 100644
--- a/SourceGen/VisualizationAnimation.cs
+++ b/SourceGen/VisualizationAnimation.cs
@@ -29,6 +29,16 @@ namespace SourceGen {
/// view angles.
///
public class VisualizationAnimation : Visualization {
+ ///
+ /// Frame delay parameter.
+ ///
+ public const string FRAME_DELAY_MSEC_PARAM = "frame-delay-msec";
+
+ ///
+ /// Fake visualization generation identifier.
+ ///
+ public const string ANIM_VIS_GEN = "(animation)";
+
///
/// Serial numbers of visualizations, e.g. bitmap frames.
///
@@ -60,5 +70,18 @@ namespace SourceGen {
mSerialNumbers = visSerialNumbers;
}
+
+ ///
+ /// Returns true if this visualization holds a reference to the specified serial number.
+ ///
+ 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;
+ }
}
}
diff --git a/SourceGen/WpfGui/EditBitmapAnimation.xaml b/SourceGen/WpfGui/EditBitmapAnimation.xaml
index 96a50a2..44b8793 100644
--- a/SourceGen/WpfGui/EditBitmapAnimation.xaml
+++ b/SourceGen/WpfGui/EditBitmapAnimation.xaml
@@ -20,10 +20,12 @@ limitations under the License.
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:SourceGen.WpfGui"
+ xmlns:common="clr-namespace:CommonWPF;assembly=CommonWPF"
mc:Ignorable="d"
Title="Edit Bitmap Animation"
SizeToContent="WidthAndHeight" ResizeMode="NoResize"
- ShowInTaskbar="False" WindowStartupLocation="CenterOwner">
+ ShowInTaskbar="False" WindowStartupLocation="CenterOwner"
+ Closing="Window_Closing">
@@ -31,10 +33,23 @@ limitations under the License.
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
@@ -45,10 +60,10 @@ limitations under the License.
-
+
-
@@ -83,7 +99,7 @@ limitations under the License.
-
-
-
-
-
-
-
+
+
+
+
+
+
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
-
+
diff --git a/SourceGen/WpfGui/EditBitmapAnimation.xaml.cs b/SourceGen/WpfGui/EditBitmapAnimation.xaml.cs
index 946d79a..a4d5d66 100644
--- a/SourceGen/WpfGui/EditBitmapAnimation.xaml.cs
+++ b/SourceGen/WpfGui/EditBitmapAnimation.xaml.cs
@@ -17,9 +17,10 @@ using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
+using System.Diagnostics;
using System.Runtime.CompilerServices;
-using System.Text;
using System.Windows;
+using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
@@ -29,6 +30,21 @@ namespace SourceGen.WpfGui {
/// Bitmap animation visualization editor.
///
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
+
+ ///
+ /// New/edited animation, only valid when dialog result is true.
+ ///
+ public VisualizationAnimation NewAnim { get; private set; }
+
+ private int mSetOffset;
+ private SortedList mEditedList;
+ private VisualizationAnimation mOrigAnim;
+
+ private Brush mDefaultLabelColor = SystemColors.WindowTextBrush;
+ private Brush mErrorLabelColor = Brushes.Red;
+
///
/// True if current contents represent a valid visualization animation. Determines
/// whether the OK button is enabled.
@@ -45,14 +61,68 @@ namespace SourceGen.WpfGui {
public ObservableCollection VisAnimItems { get; private set; } =
new ObservableCollection();
+ ///
+ /// Visualization tag.
+ ///
+ 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;
+
///
/// Time between frames, in milliseconds.
///
- public int FrameDelayTimeMsec {
+ public string FrameDelayTimeMsec {
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
public event PropertyChangedEventHandler PropertyChanged;
@@ -60,26 +130,271 @@ namespace SourceGen.WpfGui {
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
+
///
/// Constructor.
///
- ///
- public EditBitmapAnimation(Window owner) {
+ public EditBitmapAnimation(Window owner, int setOffset,
+ SortedList editedList, VisualizationAnimation origAnim) {
InitializeComponent();
Owner = owner;
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 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) {
+ Dictionary visGenParams = new Dictionary(1);
+ visGenParams.Add(VisualizationAnimation.FRAME_DELAY_MSEC_PARAM, mFrameDelayIntMsec);
+ List serials = new List(VisAnimItems.Count);
+ foreach (Visualization vis in VisAnimItems) {
+ serials.Add(vis.SerialNumber);
+ }
+
+ NewAnim = new VisualizationAnimation(TagString, VisualizationAnimation.ANIM_VIS_GEN,
+ new ReadOnlyDictionary(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) {
-
+ AddSelection();
}
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();
+ }
+
+ ///
+ /// Adds an item to the animation list, moving it from the source list.
+ ///
+ 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();
+ }
+
+ ///
+ /// Removes an item from the animation list, moving it to the source list.
+ ///
+ 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();
+ }
+
+ ///
+ /// Clears the animation list.
+ ///
+ 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();
+ }
+
+ ///
+ /// Repositions an item in the animation list, moving it up one slot.
+ ///
+ 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();
+ }
+
+ ///
+ /// Repositions an item in the animation list, moving it down one slot.
+ ///
+ 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();
+ }
+ }
+ }
+
+ ///
+ /// Updates the frame animation control's parameters. Stops the animation if something
+ /// looks wrong.
+ ///
+ /// True if all is well, false if something is wrong and the animation
+ /// should not be started.
+ private bool RefreshAnim() {
+ if (VisAnimItems.Count == 0 || mFrameDelayIntMsec <= 0) {
+ previewAnim.Stop();
+ return false;
+ }
+
+ List bitmaps = new List(VisAnimItems.Count);
+ foreach (Visualization vis in VisAnimItems) {
+ bitmaps.Add(vis.CachedImage);
+ }
+ previewAnim.Bitmaps = bitmaps;
+ previewAnim.IntervalMsec = mFrameDelayIntMsec;
+ return true;
}
}
}
diff --git a/SourceGen/WpfGui/EditVisualization.xaml b/SourceGen/WpfGui/EditVisualization.xaml
index 683f024..b942eb8 100644
--- a/SourceGen/WpfGui/EditVisualization.xaml
+++ b/SourceGen/WpfGui/EditVisualization.xaml
@@ -120,12 +120,13 @@ limitations under the License.
SelectionChanged="VisComboBox_SelectionChanged"/>
+ Text="Tag:"/>
-
+
diff --git a/SourceGen/WpfGui/EditVisualization.xaml.cs b/SourceGen/WpfGui/EditVisualization.xaml.cs
index d506d8f..7cc90c8 100644
--- a/SourceGen/WpfGui/EditVisualization.xaml.cs
+++ b/SourceGen/WpfGui/EditVisualization.xaml.cs
@@ -33,7 +33,7 @@ namespace SourceGen.WpfGui {
///
public partial class EditVisualization : Window, INotifyPropertyChanged {
///
- /// Dialog result.
+ /// New/edited visualization, only valid when dialog result is true.
///
public Visualization NewVis { get; private set; }
@@ -44,7 +44,8 @@ namespace SourceGen.WpfGui {
private Visualization mOrigVis;
///
- /// 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".
///
private static string sLastVisIdent = string.Empty;
@@ -187,6 +188,7 @@ namespace SourceGen.WpfGui {
mScriptSupport = new ScriptSupport(this);
mProject.PrepareScripts(mScriptSupport);
+ // this will initialize mTagLabelBrush
if (vis != null) {
TagString = vis.Tag;
} else {
@@ -464,7 +466,8 @@ namespace SourceGen.WpfGui {
}
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)) {
// 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.
@@ -478,23 +481,6 @@ namespace SourceGen.WpfGui {
}
}
- ///
- /// Finds a Visualization with a matching tag, searching across all sets in the
- /// edited list.
- ///
- /// Tag to search for.
- /// Matching Visualization, or null if not found.
- private Visualization FindVisualizationByTag(string tag) {
- foreach (KeyValuePair 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) {
VisualizationItem item = (VisualizationItem)visComboBox.SelectedItem;
if (item == null) {
diff --git a/SourceGen/WpfGui/EditVisualizationSet.xaml.cs b/SourceGen/WpfGui/EditVisualizationSet.xaml.cs
index 2403516..7d9490c 100644
--- a/SourceGen/WpfGui/EditVisualizationSet.xaml.cs
+++ b/SourceGen/WpfGui/EditVisualizationSet.xaml.cs
@@ -167,11 +167,13 @@ namespace SourceGen.WpfGui {
}
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) {
return;
}
- // TODO(xyzzy)
+ VisualizationList.Add(dlg.NewAnim);
+ visualizationGrid.SelectedIndex = VisualizationList.Count - 1;
}
private void EditButton_Click(object sender, RoutedEventArgs e) {
@@ -184,16 +186,27 @@ namespace SourceGen.WpfGui {
return;
}
Visualization item = (Visualization)visualizationGrid.SelectedItem;
+ Visualization newVis;
- EditVisualization dlg = new EditVisualization(this, mProject, mFormatter, mOffset,
- CreateEditedSetList(), item);
- if (dlg.ShowDialog() != true) {
- return;
+ if (item is VisualizationAnimation) {
+ EditBitmapAnimation dlg = new EditBitmapAnimation(this, mOffset,
+ CreateEditedSetList(), (VisualizationAnimation)item);
+ 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);
VisualizationList.Remove(item);
- VisualizationList.Insert(index, dlg.NewVis);
+ VisualizationList.Insert(index, newVis);
visualizationGrid.SelectedIndex = index;
okButton.Focus();
@@ -223,7 +236,7 @@ namespace SourceGen.WpfGui {
private void DownButton_Click(object sender, RoutedEventArgs e) {
Visualization item = (Visualization)visualizationGrid.SelectedItem;
int index = VisualizationList.IndexOf(item);
- Debug.Assert(index < VisualizationList.Count - 1);
+ Debug.Assert(index >= 0 && index < VisualizationList.Count - 1);
VisualizationList.Remove(item);
VisualizationList.Insert(index + 1, item);
visualizationGrid.SelectedIndex = index + 1;
@@ -265,5 +278,23 @@ namespace SourceGen.WpfGui {
}
return mixList;
}
+
+ ///
+ /// Finds a Visualization with a matching tag, searching across all sets in the
+ /// edited list.
+ ///
+ /// Tag to search for.
+ /// Matching Visualization, or null if not found.
+ public static Visualization FindVisualizationByTag(SortedList list,
+ string tag) {
+ foreach (KeyValuePair kvp in list) {
+ foreach (Visualization vis in kvp.Value) {
+ if (vis.Tag == tag) {
+ return vis;
+ }
+ }
+ }
+ return null;
+ }
}
}