From 92f32ea98583a3fb8a1d2b0f6e67982eb0bc737a Mon Sep 17 00:00:00 2001 From: Ian C Date: Sun, 28 Jun 2020 21:07:12 +0000 Subject: Got working redraw for SpriteEdit control, plus misc dev. --- SpriteEd/Main.storyboard | 93 ++++++++++++++--- SpriteEd/NSSpriteEdit.cs | 193 +++++++++++++++++++++++++++++++++++- SpriteEd/Util.cs | 24 +++++ SpriteEd/ViewController.cs | 47 ++++++++- SpriteEd/ViewController.designer.cs | 48 +++++++-- 5 files changed, 379 insertions(+), 26 deletions(-) diff --git a/SpriteEd/Main.storyboard b/SpriteEd/Main.storyboard index b6d561e..bf0d76a 100644 --- a/SpriteEd/Main.storyboard +++ b/SpriteEd/Main.storyboard @@ -685,11 +685,12 @@ - + - + - + + @@ -707,11 +708,11 @@ - + - + @@ -720,41 +721,107 @@ - + - + - - + + - + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - + - + diff --git a/SpriteEd/NSSpriteEdit.cs b/SpriteEd/NSSpriteEdit.cs index 4f6d0c5..605e69f 100644 --- a/SpriteEd/NSSpriteEdit.cs +++ b/SpriteEd/NSSpriteEdit.cs @@ -29,16 +29,90 @@ namespace SpriteEd [Register("NSSpriteEdit")] public class NSSpriteEdit : NSControl { + /// + /// The drawing mode for the sprite control. + /// + public enum DrawingMode + { + /// + /// Draw single points. + /// + Point, + + /// + /// Draw lines. + /// + Line, + + /// + /// Draw a rectangle. + /// + Rect, + + /// + /// Draw a filled rectangle. + /// + FilledRect, + + /// + /// Draw a circle. + /// + Circle, + + /// + /// Draw a filled circle. + /// + FilledCircle + } + + private Sprite m_sprite; + private int m_cx; + private int m_cy; + /// /// The sprite being edited. /// - public Sprite Sprite {get;set;} + public Sprite Sprite + { + set + { + m_sprite = value; + NeedsDisplay = true; + } + } + + /// + /// Set the drawing mode. + /// + public DrawingMode Mode {private get; set;} + + /// + /// The sprite palette. + /// + public Palette Palette {private get; set;} + + /// + /// The palette colour to use for drawing. + /// + public uint Colour {private get; set;} + + /// + /// Whether the sprite has double width pixels. + /// + public bool DoubleWidth {get; set;} + + /// + /// Whether the sprite has double height pixels. + /// + public bool DoubleHeight {get; set;} /// /// Default constructor /// public NSSpriteEdit() { + m_cx = -1; + m_cy = -1; Init(); } @@ -67,6 +141,99 @@ namespace SpriteEd LayerContentsRedrawPolicy = NSViewLayerContentsRedrawPolicy.OnSetNeedsDisplay; } + private uint BlockSizeX + { + get + { + uint bx = m_sprite.Width * (DoubleWidth ? 2u : 1u); + uint s = (uint)Math.Min(Frame.Width, Frame.Height); + + if (!(DoubleWidth ^ DoubleHeight)) + { + return s/bx * (DoubleWidth ? 2u : 1u); + } + else if (DoubleWidth) + { + return s/bx * 2u; + } + else + { + return s/bx / 2u; + } + } + } + + private uint BlockSizeY + { + get + { + uint by = m_sprite.Height * (DoubleHeight ? 2u : 1u); + uint s = (uint)Math.Min(Frame.Width, Frame.Height); + + if (!(DoubleWidth ^ DoubleHeight)) + { + return s/by * (DoubleHeight ? 2u : 1u); + } + else if (DoubleWidth) + { + return s/by / 2u; + } + else + { + return s/by * 2u; + } + } + } + + private void DrawGrid(CGContext context, uint x, uint y) + { + uint bsx = BlockSizeX; + uint bsy = BlockSizeY; + Colour white = new Colour(255, 255, 255); + + x *= bsx; + y = (uint)Frame.Height - y * bsy; + + DrawLine(context, x, y, x + bsx, y, white); + DrawLine(context, x + bsx, y, x + bsx, y - bsy, white); + DrawLine(context, x + bsx, y - bsy, x, y - bsy, white); + DrawLine(context, x, y - bsy, x, y, white); + } + + private void DrawCell(CGContext context, uint x, uint y, Colour colour) + { + uint bsx = BlockSizeX; + uint bsy = BlockSizeY; + + x *= bsx; + y = (uint)Frame.Height - (y + 1) * bsy; + + CGRect rect = new CGRect(x + 1, y + 1, bsx - 1, bsy - 1); + + DrawFilledRect(context, rect, colour); + } + + private void DrawFilledRect(CGContext context, CGRect rect, Colour colour) + { + using (CGColor cgcol = Util.ColourCG(colour)) + { + context.SetFillColor(cgcol); + context.FillRect(rect); + } + } + + private void DrawLine(CGContext context, uint x1, uint y1, uint x2, uint y2, Colour colour) + { + using (CGColor cgcol = Util.ColourCG(colour)) + { + context.SetLineWidth(1.0f); + context.SetStrokeColor(cgcol); + context.MoveTo(x1, y1); + context.AddLineToPoint(x2, y2); + context.DrawPath(CGPathDrawingMode.Stroke); + } + } + /// /// Redraw the control. /// @@ -76,6 +243,30 @@ namespace SpriteEd base.DrawRect (dirtyRect); // TODO: Draw control + if (m_sprite != null) + { + CGContext context = NSGraphicsContext.CurrentContext.GraphicsPort; + + Colour black = new Colour(); + + DrawFilledRect(context, dirtyRect, black); + + context.ClipToRect(dirtyRect); + + for(uint x = 0; x < m_sprite.Width; x++) + { + for (uint y = 0; y < m_sprite.Height; y++) + { + DrawGrid(context, x, y); + DrawCell(context, x, y, Palette[m_sprite[x,y]]); + } + } + + if (m_cx != -1 && m_cx != -1) + { + DrawCell(context, (uint)m_cx, (uint)m_cy, Palette[Colour]); + } + } } } } diff --git a/SpriteEd/Util.cs b/SpriteEd/Util.cs index cca9c47..dff6e3e 100644 --- a/SpriteEd/Util.cs +++ b/SpriteEd/Util.cs @@ -17,6 +17,7 @@ using System; using System.IO; using AppKit; +using CoreGraphics; namespace SpriteEd { @@ -94,5 +95,28 @@ namespace SpriteEd alert.RunModal(); } + + /// + /// Convert a sprite Colour into an NSColor + /// + /// The colour. + /// + public static NSColor ColourNS(Colour c) + { + return NSColor.FromDeviceRgb(c.Red, c.Green, c.Blue); + } + + /// + /// Convert a Colour into a CGColor. + /// + /// The colour. + /// + public static CGColor ColourCG(Colour c) + { + return CGColor.CreateSrgb((float)c.Red / 255.0f, + (float)c.Green / 255.0f, + (float)c.Blue / 255.0f, + 1.0f); + } } } diff --git a/SpriteEd/ViewController.cs b/SpriteEd/ViewController.cs index 82732a3..8b4aca1 100644 --- a/SpriteEd/ViewController.cs +++ b/SpriteEd/ViewController.cs @@ -34,14 +34,28 @@ namespace SpriteEd { base.ViewDidLoad(); - m_SpriteNumber.IntValue = 0; - m_Stepper.IntValue = 0; + m_SpriteStepper.IntValue = 0; m_Palette = new Palette(2); m_Palette[0] = new Colour(0, 0, 0); m_Palette[1] = new Colour(255, 255, 255); + m_ColourStepper.IntValue = 1; + + m_ColourStepper.MaxValue = m_Palette.Size - 1; + m_SpriteSet = new SpriteSet(8, 8, m_Palette, false, false); + + m_SpriteEdit.Palette = m_Palette; + m_SpriteEdit.DoubleWidth = m_SpriteSet.DoubleWidth; + m_SpriteEdit.DoubleHeight = m_SpriteSet.DoubleHeight; + m_SpriteEdit.Sprite = m_SpriteSet[(byte)m_SpriteNumber.IntValue]; + m_SpriteEdit.Mode = NSSpriteEdit.DrawingMode.Point; + + m_SpriteSet[0][0,0] = 1; + + OnColourStepper(m_ColourStepper); + OnSpriteStepper(m_SpriteStepper); } public override NSObject RepresentedObject @@ -57,13 +71,40 @@ namespace SpriteEd } } - partial void OnStepper(NSObject sender) + partial void OnSpriteStepper(NSObject sender) { NSStepper stepper = sender as NSStepper; if (stepper != null) { m_SpriteNumber.IntValue = stepper.IntValue; + m_SpriteEdit.Sprite = m_SpriteSet[(byte)stepper.IntValue]; + } + } + + partial void OnColourStepper(NSObject sender) + { + NSStepper stepper = sender as NSStepper; + + if (stepper != null) + { + m_ColourNumber.IntValue = stepper.IntValue; + m_SpriteEdit.Colour = (uint)stepper.IntValue; + + using (NSColor c = Util.ColourNS(m_Palette[(uint)stepper.IntValue])) + { + m_ColourLabel.TextColor = c; + } + } + } + + partial void OnDrawingMode(NSObject sender) + { + NSPopUpButton button = sender as NSPopUpButton; + + if (button != null) + { + m_SpriteEdit.Mode = (NSSpriteEdit.DrawingMode)(int)button.SelectedTag; } } } diff --git a/SpriteEd/ViewController.designer.cs b/SpriteEd/ViewController.designer.cs index 9ea3fc9..2de4b18 100644 --- a/SpriteEd/ViewController.designer.cs +++ b/SpriteEd/ViewController.designer.cs @@ -12,6 +12,15 @@ namespace SpriteEd [Register ("ViewController")] partial class ViewController { + [Outlet] + AppKit.NSTextField m_ColourLabel { get; set; } + + [Outlet] + AppKit.NSTextField m_ColourNumber { get; set; } + + [Outlet] + AppKit.NSStepper m_ColourStepper { get; set; } + [Outlet] SpriteEd.NSSpriteEdit m_SpriteEdit { get; set; } @@ -19,27 +28,48 @@ namespace SpriteEd AppKit.NSTextField m_SpriteNumber { get; set; } [Outlet] - AppKit.NSStepper m_Stepper { get; set; } + AppKit.NSStepper m_SpriteStepper { get; set; } + + [Action ("OnColourStepper:")] + partial void OnColourStepper (Foundation.NSObject sender); + + [Action ("OnDrawingMode:")] + partial void OnDrawingMode (Foundation.NSObject sender); - [Action ("OnStepper:")] - partial void OnStepper (Foundation.NSObject sender); + [Action ("OnSpriteStepper:")] + partial void OnSpriteStepper (Foundation.NSObject sender); void ReleaseDesignerOutlets () { - if (m_SpriteNumber != null) { - m_SpriteNumber.Dispose (); - m_SpriteNumber = null; + if (m_ColourLabel != null) { + m_ColourLabel.Dispose (); + m_ColourLabel = null; + } + + if (m_ColourNumber != null) { + m_ColourNumber.Dispose (); + m_ColourNumber = null; } - if (m_Stepper != null) { - m_Stepper.Dispose (); - m_Stepper = null; + if (m_ColourStepper != null) { + m_ColourStepper.Dispose (); + m_ColourStepper = null; } if (m_SpriteEdit != null) { m_SpriteEdit.Dispose (); m_SpriteEdit = null; } + + if (m_SpriteNumber != null) { + m_SpriteNumber.Dispose (); + m_SpriteNumber = null; + } + + if (m_SpriteStepper != null) { + m_SpriteStepper.Dispose (); + m_SpriteStepper = null; + } } } } -- cgit v1.2.3