diff --git a/ImageSrc/BlueChevron.xcf b/ImageSrc/BlueChevron.xcf deleted file mode 100644 index c1732ab..0000000 Binary files a/ImageSrc/BlueChevron.xcf and /dev/null differ diff --git a/SourceGen/DisasmProject.cs b/SourceGen/DisasmProject.cs index cf33d83..d54dd61 100644 --- a/SourceGen/DisasmProject.cs +++ b/SourceGen/DisasmProject.cs @@ -103,6 +103,14 @@ namespace SourceGen { /// /// Visualization sets. Uses file offset as key. /// + /// + /// TODO(maybe): certain operations must be performed on the set of all visualizations + /// or the set of all animations, requiring a double "foreach" with an "is" clause. + /// It might be simpler and more efficient overall to split this into three lists: one + /// for visualizations (perhaps keyed by serial number), one for animations, and one + /// for VisualizationSet objects (the latter required to establish ordering). The + /// primary argument against is that this makes undo/redo more complicated. + /// public SortedList VisualizationSets { get; private set; } /// diff --git a/SourceGen/Res/BlueChevron.png b/SourceGen/Res/BlueChevron.png deleted file mode 100644 index 4c41364..0000000 Binary files a/SourceGen/Res/BlueChevron.png and /dev/null differ diff --git a/SourceGen/SourceGen.csproj b/SourceGen/SourceGen.csproj index 79bbca7..e0b3755 100644 --- a/SourceGen/SourceGen.csproj +++ b/SourceGen/SourceGen.csproj @@ -430,8 +430,5 @@ - - - \ No newline at end of file diff --git a/SourceGen/Visualization.cs b/SourceGen/Visualization.cs index c6c85db..b2280c5 100644 --- a/SourceGen/Visualization.cs +++ b/SourceGen/Visualization.cs @@ -77,7 +77,7 @@ namespace SourceGen { /// public bool HasImage { get { - return CachedImage != BROKEN_IMAGE && CachedImage != ANIM_IMAGE; + return CachedImage != BROKEN_IMAGE && CachedImage != ANIM_OVERLAY_IMAGE; } } @@ -87,8 +87,11 @@ namespace SourceGen { public static readonly BitmapImage BROKEN_IMAGE = new BitmapImage(new Uri("pack://application:,,,/Res/RedX.png")); - internal static readonly BitmapImage ANIM_IMAGE = - new BitmapImage(new Uri("pack://application:,,,/Res/BlueChevron.png")); + /// + /// Image to overlay on animation visualizations. + /// + internal static readonly BitmapSource ANIM_OVERLAY_IMAGE = + VisualizationAnimation.GenerateAnimOverlayImage(); /// /// Serial number, for reference from other Visualization objects. Not serialized. diff --git a/SourceGen/VisualizationAnimation.cs b/SourceGen/VisualizationAnimation.cs index 1d68383..c0740ea 100644 --- a/SourceGen/VisualizationAnimation.cs +++ b/SourceGen/VisualizationAnimation.cs @@ -80,7 +80,7 @@ namespace SourceGen { mSerialNumbers.Add(serial); } - CachedImage = ANIM_IMAGE; // default to this + CachedImage = ANIM_OVERLAY_IMAGE; // default to this } /// @@ -93,7 +93,7 @@ namespace SourceGen { public void GenerateImage(SortedList visSets) { const int IMAGE_SIZE = 64; - CachedImage = ANIM_IMAGE; + CachedImage = ANIM_OVERLAY_IMAGE; if (mSerialNumbers.Count == 0) { return; @@ -113,16 +113,16 @@ namespace SourceGen { DrawingVisual visual = new DrawingVisual(); //RenderOptions.SetBitmapScalingMode(visual, BitmapScalingMode.NearestNeighbor); - DrawingContext dc = visual.RenderOpen(); - dc.DrawImage(vis.CachedImage, imgBounds); - dc.DrawImage(ANIM_IMAGE, new Rect(0, 0, IMAGE_SIZE, IMAGE_SIZE)); - dc.Close(); + using (DrawingContext dc = visual.RenderOpen()) { + dc.DrawImage(vis.CachedImage, imgBounds); + dc.DrawImage(ANIM_OVERLAY_IMAGE, new Rect(0, 0, IMAGE_SIZE, IMAGE_SIZE)); + } RenderTargetBitmap bmp = new RenderTargetBitmap(IMAGE_SIZE, IMAGE_SIZE, 96.0, 96.0, PixelFormats.Pbgra32); bmp.Render(visual); CachedImage = bmp; - Debug.WriteLine("RENDERED " + Tag); + //Debug.WriteLine("RENDERED " + Tag); } /// @@ -176,6 +176,35 @@ namespace SourceGen { return somethingRemoved; } + public static BitmapSource GenerateAnimOverlayImage() { + const int IMAGE_SIZE = 128; + + // Glowy "high tech" blue. + SolidColorBrush outlineBrush = new SolidColorBrush(Color.FromArgb(255, 0, 216, 255)); + SolidColorBrush fillBrush = new SolidColorBrush(Color.FromArgb(128, 0, 182, 215)); + + DrawingVisual visual = new DrawingVisual(); + using (DrawingContext dc = visual.RenderOpen()) { + // Thanks: https://stackoverflow.com/a/29249100/294248 + Point p1 = new Point(IMAGE_SIZE * 5 / 8, IMAGE_SIZE / 2); + Point p2 = new Point(IMAGE_SIZE * 3 / 8, IMAGE_SIZE / 4); + Point p3 = new Point(IMAGE_SIZE * 3 / 8, IMAGE_SIZE * 3 / 4); + StreamGeometry sg = new StreamGeometry(); + using (StreamGeometryContext sgc = sg.Open()) { + sgc.BeginFigure(p1, true, true); + PointCollection points = new PointCollection() { p2, p3 }; + sgc.PolyLineTo(points, true, true); + } + sg.Freeze(); + dc.DrawGeometry(fillBrush, new Pen(outlineBrush, 3), sg); + } + + RenderTargetBitmap bmp = new RenderTargetBitmap(IMAGE_SIZE, IMAGE_SIZE, 96.0, 96.0, + PixelFormats.Pbgra32); + bmp.Render(visual); + return bmp; + } + public static bool operator ==(VisualizationAnimation a, VisualizationAnimation b) { if (ReferenceEquals(a, b)) {