Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/xamarin/Xamarin.PropertyEditing.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLarry Ewing <lewing@xamarin.com>2018-04-28 01:07:53 +0300
committerLarry Ewing <lewing@microsoft.com>2018-07-16 22:05:49 +0300
commite0301b2bcf120f07f2452549ba0a6c1eb51bcf0b (patch)
tree2c02fb95c0e882c4d17c3e1f2887c5b9f3e2ce14 /Xamarin.PropertyEditing.Mac
parentaeac432cda69abd44d738750a5b144bfbfb72799 (diff)
Extract and rename a bunch of classes
Diffstat (limited to 'Xamarin.PropertyEditing.Mac')
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/Custom/BrushTabViewController.cs310
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/Custom/ChannelEditor.cs272
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/Custom/ChannelEditorType.cs10
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/Custom/ColorComponentEditor.cs305
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/Custom/CommandMenuItem.cs2
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/Custom/CommonBrushLayer.cs92
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/Custom/CommonBrushView.cs7
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/Custom/CommonGradientBrushLayer.cs62
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/Custom/DrawingExtensions.cs2
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/Custom/EmptyBrushEditorViewController.cs28
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialBrushEditorViewController.cs43
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialColorLayer.cs66
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialView.cs197
-rw-r--r--Xamarin.PropertyEditing.Mac/Controls/Custom/SolidColorBrushEditor.cs147
-rw-r--r--Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj8
15 files changed, 813 insertions, 738 deletions
diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/BrushTabViewController.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/BrushTabViewController.cs
index 7f775f8..f56f787 100644
--- a/Xamarin.PropertyEditing.Mac/Controls/Custom/BrushTabViewController.cs
+++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/BrushTabViewController.cs
@@ -1,9 +1,6 @@
-using System;
-using System.Collections.Generic;
+using System.Collections.Generic;
using System.ComponentModel;
-using System.Linq;
using AppKit;
-using CoreAnimation;
using CoreGraphics;
using Foundation;
using Xamarin.PropertyEditing.Drawing;
@@ -11,303 +8,6 @@ using Xamarin.PropertyEditing.ViewModels;
namespace Xamarin.PropertyEditing.Mac
{
- class MaterialBrushEditorViewController : PropertyViewController <BrushPropertyViewModel>
- {
- MaterialView materialEditor;
-
- public MaterialBrushEditorViewController ()
- {
- PreferredContentSize = new CGSize (200, 230);
- }
-
- public override void OnPropertyChanged (object sender, PropertyChangedEventArgs e)
- {
- switch (e.PropertyName) {
- case nameof (BrushPropertyViewModel.Value):
- case nameof (BrushPropertyViewModel.MaterialDesign):
- if (materialEditor != null)
- materialEditor.ViewModel = ViewModel;
- break;
- }
- }
-
- public override void OnViewModelChanged (BrushPropertyViewModel oldModel)
- {
- if (materialEditor != null)
- materialEditor.ViewModel = ViewModel;
- }
-
- public class MaterialColorLayer : CATextLayer
- {
- public MaterialColorLayer ()
- {
- AddSublayer (Selection);
- }
-
- CATextLayer Selection { get; } = new CATextLayer () {
- CornerRadius = 3
- };
-
- string text;
- public string Text {
- get => text;
- set {
- text = value;
- SetNeedsLayout ();
- }
- }
-
- CommonColor materialColor;
- public new CommonColor BackgroundColor
- {
- get => materialColor;
- set
- {
- materialColor = value;
- base.BackgroundColor = materialColor.ToCGColor ();
- }
- }
-
- bool isSelected;
- public bool IsSelected {
- get => isSelected;
- set {
- if (isSelected == value)
- return;
- isSelected = value;
- SetNeedsLayout ();
- }
- }
-
- public override void LayoutSublayers ()
- {
- base.LayoutSublayers ();
- //String = isSelected ? "" : text;
- Selection.String = text;
- Selection.Frame = Frame.Bounds ().Border (new CommonThickness (3));
- Selection.BorderWidth = isSelected ? 2 : 0;
- Selection.BorderColor = ForegroundColor;
- Selection.ForegroundColor = ForegroundColor;
- Selection.FontSize = FontSize;
- Selection.ContentsScale = ContentsScale;
- Selection.TextAlignmentMode = TextAlignmentMode;
- }
- }
-
- public class MaterialView : NSView
- {
- public override bool IsFlipped => true;
-
- readonly string[] ColorNames = {
- "50",
- "100",
- "200",
- "300",
- "400",
- "500",
- "600",
- "700",
- "800",
- "900"
- };
-
- readonly string [] AccentNames = {
- "A100",
- "A200",
- "A400",
- "A700"
- };
-
- readonly string [] BlackWhite = {
- "White",
- "Black"
- };
-
- public MaterialView () : base ()
- {
- Initialize ();
- }
-
- void Initialize () {
- WantsLayer = true;
- }
-
- BrushPropertyViewModel viewModel;
- public BrushPropertyViewModel ViewModel
- {
- get => viewModel;
- set {
- viewModel = value;
- NeedsLayout = true;
- }
- }
-
- public MaterialDesignColorViewModel MaterialDesign
- {
- get => ViewModel?.MaterialDesign;
- }
-
- public override void Layout ()
- {
- if (Layer?.Sublayers != null)
- foreach (var l in Layer.Sublayers)
- l.RemoveFromSuperLayer ();
-
- if (MaterialDesign == null)
- return;
-
- var colors = MaterialDesign.Palettes.Select (p => new { p.Name, Color = p.MainColor }).ToArray ();
- int col = 0;
- nfloat x = 0;
- nfloat y = 6;
- var width = (Frame.Width - 54) / 10;
- var height = (Frame.Height - 49) / 4;
-
- foreach (var p in colors) {
- var frame = new CGRect (x, y, width, height);
- var selectedColor = p.Color.Lightness > 0.58 ? NSColor.Black : NSColor.White;
- var l = new MaterialColorLayer {
- Frame = frame,
- ForegroundColor = selectedColor.CGColor,
- BackgroundColor = p.Color,
- CornerRadius = 3,
- BorderColor = new CGColor (.5f, .5f, .5f, .5f),
- MasksToBounds = false,
- IsSelected = MaterialDesign.Color == p.Color
- };
-
- Layer.AddSublayer (l);
- x += width + 6;
- col++;
- if (col >= 10) {
- x = 0;
- y += height + 6;
- col = 0;
- }
- }
-
- Layer.AddSublayer (new CATextLayer {
- ForegroundColor = NSColor.ControlText.CGColor,
- Frame = new CGRect (x, y + 6, Frame.Width, 25),
- String = MaterialDesign.ColorName,
- FontSize = NSFont.SmallSystemFontSize,
- ContentsScale = Window?.Screen?.BackingScaleFactor ?? NSScreen.MainScreen.BackingScaleFactor
- });
-
- y += 25;
- x = 0;
- width = Frame.Width / MaterialDesign.NormalColorScale.Count ();
- var names = MaterialDesign.NormalColorScale.Count () > 2 ? ColorNames : BlackWhite;
- var normal = new CALayer {
- CornerRadius = 3,
- MasksToBounds = true,
- Frame = new CGRect (x, y, Frame.Width, height),
- BorderColor = new CGColor (.5f, .5f, .5f, .5f),
- BorderWidth = 1
- };
-
- Layer.AddSublayer (normal);
- foreach (var n in MaterialDesign.NormalColorScale.Zip (names, (c, name) => new { Name = name, Color = c.Value })) {
- var frame = new CGRect (x, y, width, height);
- var selectedColor = n.Color.Lightness > 0.58 ? NSColor.Black : NSColor.White;
- var l = new MaterialColorLayer {
- BackgroundColor = n.Color,
- ForegroundColor = selectedColor.CGColor,
- Frame = new CGRect (x, 0, width, height),
- Text = n.Name,
- FontSize = 12,
- ContentsScale = NSScreen.MainScreen.BackingScaleFactor,
- TextAlignmentMode = CATextLayerAlignmentMode.Center,
- IsSelected = MaterialDesign.Color == n.Color
- };
- normal.AddSublayer (l);
- x += width;
- }
-
- if (MaterialDesign.AccentColorScale.Count () <= 0)
- return;
-
- y += height + 6;
- x = 0;
-
- var accent = new CALayer {
- CornerRadius = 3,
- MasksToBounds = true,
- Frame = new CGRect (x, y, Frame.Width, height),
- BorderColor = new CGColor (.5f, .5f, .5f, .5f),
- BorderWidth = 1
- };
- Layer.AddSublayer (accent);
- width = Frame.Width / MaterialDesign.AccentColorScale.Count ();
- foreach (var n in MaterialDesign.AccentColorScale.Zip (AccentNames, (c, n) => new { Name = n, Color = c.Value })) {
- var frame = new CGRect (x, y, width, height);
- var selectedColor = n.Color.Lightness > 0.58 ? NSColor.Black : NSColor.White;
- var l = new MaterialColorLayer {
- BackgroundColor = n.Color,
- ForegroundColor = selectedColor.CGColor,
- Frame = new CGRect (x, 0, width, height),
- Text = n.Name,
- FontSize = 12,
- ContentsScale = NSScreen.MainScreen.BackingScaleFactor,
- TextAlignmentMode = CATextLayerAlignmentMode.Center,
- IsSelected = ViewModel.Solid.Color == n.Color,
- };
-
- accent.AddSublayer (l);
- x += width;
- }
- }
-
- public override void MouseDown (NSEvent theEvent)
- {
- UpdateFromEvent (theEvent);
- }
-
- public void UpdateFromEvent (NSEvent theEvent)
- {
- var location = ConvertPointToLayer (ConvertPointFromView (theEvent.LocationInWindow, null));
-
- foreach (var layer in Layer.Sublayers) {
- var hit = layer.HitTest (location);
- for (var c = hit; c != null; c = c.SuperLayer) {
- var editor = c as MaterialColorLayer;
- if (editor != null) {
- ViewModel.Solid.Color = editor.BackgroundColor;
- NeedsLayout = true;
- }
- }
- }
- }
- }
-
- public override void LoadView ()
- {
- View = materialEditor = new MaterialView {
- ViewModel = ViewModel
- };
- }
- }
-
- class EmptyBrushEditorViewController : PropertyViewController<BrushPropertyViewModel>
- {
- NSButton brushEditor;
-
- public EmptyBrushEditorViewController ()
- {
- PreferredContentSize = new CGSize (100, 100);
- }
-
- public override void LoadView ()
- {
- View = brushEditor = new NSButton {
- Title = "Edit"
- };
- brushEditor.Activated += (o, e) => {
- ViewModel.SelectedBrushType = CommonBrushType.Solid;
- };
- }
- }
-
class BrushTabViewController : PropertyTabViewController<BrushPropertyViewModel>
{
Dictionary<CommonBrushType, int> BrushTypeTable = new Dictionary<CommonBrushType, int> ();
@@ -331,7 +31,7 @@ namespace Xamarin.PropertyEditing.Mac
BrushTypeTable.Clear ();
if (ViewModel == null)
return;
-
+
foreach (var key in ViewModel.BrushTypes.Keys) {
var item = new NSTabViewItem ();
item.Label = key;
@@ -394,7 +94,7 @@ namespace Xamarin.PropertyEditing.Mac
var brushController = item.ViewController as PropertyViewController<BrushPropertyViewModel>;
if (brushController != null)
brushController.ViewModel = ViewModel;
-
+
if (inhibitSelection)
return;
@@ -405,11 +105,11 @@ namespace Xamarin.PropertyEditing.Mac
{
if (inhibitSelection)
return;
-
+
base.DidSelect (tabView, item);
ViewModel.SelectedBrushType = ViewModel.BrushTypes[item.Label];
}
-
+
public override void ViewDidLoad()
{
var old = View.Frame;
diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/ChannelEditor.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/ChannelEditor.cs
new file mode 100644
index 0000000..a3aad7e
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/ChannelEditor.cs
@@ -0,0 +1,272 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using CoreAnimation;
+using CoreGraphics;
+using Xamarin.PropertyEditing.Drawing;
+
+namespace Xamarin.PropertyEditing.Mac
+{
+ public abstract class ChannelEditor
+ {
+ public string Name { get; }
+ public double MinimumValue { get; }
+ public double MaximumValue { get; }
+ public double IncrementValue { get; }
+
+ static IEnumerable<double> LerpSteps (double min, double max, int steps)
+ => Enumerable.Range (0, steps).Select (v => {
+ var pos = v / (double)steps;
+ return max * pos - min * (1 - pos);
+ });
+
+ public ChannelEditor (string name, double min, double max, double increment)
+ {
+ MinimumValue = min;
+ MaximumValue = max;
+ IncrementValue = increment;
+ Name = name;
+ }
+
+ public void UpdateGradientLayer (CAGradientLayer layer, CommonColor color)
+ {
+ var c = color.UpdateRGB (a: 255);
+
+ layer.Colors = LerpSteps (MinimumValue, MaximumValue, 7)
+ .Select (value => UpdateColorFromValue (c, value).ToCGColor ()).ToArray ();
+ }
+
+ public double InvLerp (CGPoint start, CGPoint end, CGPoint loc)
+ {
+ var a = new CGVector (end.X - start.X, end.Y - start.Y);
+ var b = new CGVector (loc.X - start.X, loc.Y - start.Y);
+ var dot = a.dx * b.dx + a.dy * b.dy;
+ var len = Math.Sqrt (a.dx * a.dx + a.dy * a.dy);
+ return dot / len;
+ }
+
+ public static double InvLerp (double start, double end, double value)
+ => (value - start) / (end - start);
+
+ public static double Lerp (double start, double end, double amount)
+ => end * amount - start * (1 - amount);
+
+ public static CGPoint Lerp (CGPoint start, CGPoint end, double amount)
+ => new CGPoint (
+ start.X + (end.X - start.X) * amount,
+ start.Y + (end.Y - start.Y) * amount);
+
+ public double ValueFromLocation (CAGradientLayer layer, CGPoint loc)
+ {
+ var rect = layer.Frame;
+ var unitLoc = new CGPoint (
+ (loc.X - rect.X) / rect.Width,
+ (loc.Y - rect.Y) / rect.Height);
+
+ return Clamp (Lerp (MinimumValue, MaximumValue, InvLerp (layer.StartPoint, layer.EndPoint, unitLoc)));
+ }
+
+ public CommonColor UpdateColorFromLocation (CAGradientLayer layer, CommonColor color, CGPoint loc)
+ => UpdateColorFromValue (color, ValueFromLocation (layer, loc));
+
+ public CGPoint LocationFromColor (CAGradientLayer layer, CommonColor color)
+ {
+ var pos = ValueFromColor (color);
+
+ var amount = InvLerp (MinimumValue, MaximumValue, pos);
+ var unitLoc = Lerp (layer.StartPoint, layer.EndPoint, amount);
+
+ return new CGPoint (
+ layer.Frame.X + unitLoc.X * layer.Frame.Width,
+ layer.Frame.Y + unitLoc.Y * layer.Frame.Height);
+ }
+
+ public double Clamp (double value)
+ => Math.Max (MinimumValue, Math.Min (MaximumValue, value));
+
+ public abstract CommonColor UpdateColorFromValue (CommonColor color, double value);
+ public abstract double ValueFromColor (CommonColor color);
+ }
+
+ class RedChannelEditor : ChannelEditor
+ {
+ public RedChannelEditor () : base ("R", 0d, 255d, 1d)
+ {
+ }
+
+ public override double ValueFromColor (CommonColor color)
+ => (double)color.R;
+
+ public override CommonColor UpdateColorFromValue (CommonColor color, double value)
+ => color.UpdateRGB (r: (byte)Clamp (value));
+ }
+
+ class GreenChannelEditor : ChannelEditor
+ {
+ public GreenChannelEditor () : base ("G", 0d, 255d, 1d)
+ {
+ }
+
+ public override double ValueFromColor (CommonColor color)
+ => (double)color.G;
+
+ public override CommonColor UpdateColorFromValue (CommonColor color, double value)
+ => color.UpdateRGB (g: (byte)Clamp (value));
+ }
+
+ class BlueChannelEditor : ChannelEditor
+ {
+ public BlueChannelEditor () : base ("B", 0d, 255d, 1d)
+ {
+ }
+
+ public override double ValueFromColor (CommonColor color)
+ => (double)color.B;
+
+ public override CommonColor UpdateColorFromValue (CommonColor color, double value)
+ => color.UpdateRGB (b: (byte)Clamp (value));
+ }
+
+ class AlphaChannelEditor : ChannelEditor
+ {
+ public AlphaChannelEditor () : base ("A", 0d, 255d, 1d)
+ {
+ }
+
+ public override double ValueFromColor (CommonColor color)
+ => (double)color.A;
+
+ public override CommonColor UpdateColorFromValue (CommonColor color, double value)
+ => color.UpdateRGB (a: (byte)Clamp (value));
+ }
+
+ class CyanChannelEditor : ChannelEditor
+ {
+ public CyanChannelEditor () : base ("C", 0d, 1d, .01d)
+ {
+ }
+
+ public override double ValueFromColor (CommonColor color)
+ => color.C;
+
+ public override CommonColor UpdateColorFromValue (CommonColor color, double value)
+ => color.UpdateCMYK (c: Clamp (value));
+ }
+
+ class MagentaChannelEditor : ChannelEditor
+ {
+ public MagentaChannelEditor () : base ("M", 0d, 1d, .01d)
+ {
+ }
+
+ public override double ValueFromColor (CommonColor color)
+ => color.M;
+
+ public override CommonColor UpdateColorFromValue (CommonColor color, double value)
+ => color.UpdateCMYK (m: Clamp (value));
+ }
+
+ class YellowChannelEditor : ChannelEditor
+ {
+ public YellowChannelEditor () : base ("Y", 0d, 1d, .01d)
+ {
+ }
+
+ public override double ValueFromColor (CommonColor color)
+ => color.Y;
+
+ public override CommonColor UpdateColorFromValue (CommonColor color, double value)
+ => color.UpdateCMYK (y: Clamp (value));
+ }
+
+ class BlackChannelEditor : ChannelEditor
+ {
+ public BlackChannelEditor () : base ("K", 0d, 1d, .01d)
+ {
+ }
+
+ public override double ValueFromColor (CommonColor color)
+ => color.K;
+
+ public override CommonColor UpdateColorFromValue (CommonColor color, double value)
+ => color.UpdateCMYK (k: Clamp (value));
+ }
+
+ class HsbHueChannelEditor : ChannelEditor
+ {
+ public HsbHueChannelEditor () : base ("H", 0d, 360d, 1d)
+ {
+ }
+
+ public override double ValueFromColor (CommonColor color)
+ => color.Hue;
+
+ public override CommonColor UpdateColorFromValue (CommonColor color, double value)
+ => color.UpdateHSB (hue: Clamp (value));
+ }
+
+ class HsbSaturationChannelEditor : ChannelEditor
+ {
+ public HsbSaturationChannelEditor () : base ("S", 0d, 1d, .01d)
+ {
+ }
+
+ public override double ValueFromColor (CommonColor color)
+ => color.Saturation;
+
+ public override CommonColor UpdateColorFromValue (CommonColor color, double value)
+ => color.UpdateHSB (saturation: Clamp (value));
+ }
+
+ class HsbBrightnessChannelEditor : ChannelEditor
+ {
+ public HsbBrightnessChannelEditor () : base ("B", 0d, 1d, .01d)
+ {
+ }
+
+ public override double ValueFromColor (CommonColor color)
+ => color.Brightness;
+
+ public override CommonColor UpdateColorFromValue (CommonColor color, double value)
+ => color.UpdateHSB (brightness: Clamp (value));
+ }
+
+ class HlsHueChannelEditor : ChannelEditor
+ {
+ public HlsHueChannelEditor () : base ("H", 0d, 360d, 1d)
+ {
+ }
+
+ public override double ValueFromColor (CommonColor color)
+ => color.Hue;
+
+ public override CommonColor UpdateColorFromValue (CommonColor color, double value)
+ => color.UpdateHLS (hue: Clamp (value));
+ }
+
+ class HlsLightnessChannelEditor : ChannelEditor
+ {
+ public HlsLightnessChannelEditor () : base ("L", 0d, 1d, .01d)
+ {
+ }
+
+ public override double ValueFromColor (CommonColor color)
+ => (double)color.Lightness;
+
+ public override CommonColor UpdateColorFromValue (CommonColor color, double value)
+ => color.UpdateHLS (lightness: Clamp (value));
+ }
+
+ class HlsSaturationChannelEditor : ChannelEditor
+ {
+ public HlsSaturationChannelEditor () : base ("S", 0d, 1d, .01d)
+ {
+ }
+
+ public override double ValueFromColor (CommonColor color)
+ => (double)color.Saturation;
+
+ public override CommonColor UpdateColorFromValue (CommonColor color, double value)
+ => color.UpdateHLS (saturation: Clamp (value));
+ }
+}
diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/ChannelEditorType.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/ChannelEditorType.cs
new file mode 100644
index 0000000..c9747fe
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/ChannelEditorType.cs
@@ -0,0 +1,10 @@
+namespace Xamarin.PropertyEditing.Mac
+{
+ public enum ChannelEditorType
+ {
+ RGB,
+ HLS,
+ HSB,
+ CMYK
+ };
+}
diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/ColorComponentEditor.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/ColorComponentEditor.cs
index 8d47998..8dbb03c 100644
--- a/Xamarin.PropertyEditing.Mac/Controls/Custom/ColorComponentEditor.cs
+++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/ColorComponentEditor.cs
@@ -1,5 +1,4 @@
using System;
-using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using AppKit;
@@ -41,7 +40,7 @@ namespace Xamarin.PropertyEditing.Mac
public CAGradientLayer Gradient { get; set; }
}
- ComponentSet CreateEditor (ComponentEditor editor)
+ ComponentSet CreateEditor (ChannelEditor editor)
{
var ce = new ComponentSet {
Label = new UnfocusableTextField {
@@ -72,33 +71,33 @@ namespace Xamarin.PropertyEditing.Mac
switch (type) {
case ChannelEditorType.HSB:
return new[] {
- CreateEditor (new HsbHueComponentEditor ()),
- CreateEditor (new HsbSaturationComponentEditor ()),
- CreateEditor (new HsbBrightnessComponentEditor ()),
- CreateEditor (new AlphaComponentEditor ())
+ CreateEditor (new HsbHueChannelEditor ()),
+ CreateEditor (new HsbSaturationChannelEditor ()),
+ CreateEditor (new HsbBrightnessChannelEditor ()),
+ CreateEditor (new AlphaChannelEditor ())
};
case ChannelEditorType.HLS:
return new[] {
- CreateEditor (new HlsHueComponentEditor ()),
- CreateEditor (new HlsLightnessComponentEditor ()),
- CreateEditor (new HlsSaturationComponentEditor ()),
- CreateEditor (new AlphaComponentEditor ())
+ CreateEditor (new HlsHueChannelEditor ()),
+ CreateEditor (new HlsLightnessChannelEditor ()),
+ CreateEditor (new HlsSaturationChannelEditor ()),
+ CreateEditor (new AlphaChannelEditor ())
};
case ChannelEditorType.RGB:
return new[] {
- CreateEditor (new RedComponentEditor ()),
- CreateEditor (new GreenComponentEditor ()),
- CreateEditor (new BlueComponentEditor ()),
- CreateEditor (new AlphaComponentEditor ())
+ CreateEditor (new RedChannelEditor ()),
+ CreateEditor (new GreenChannelEditor ()),
+ CreateEditor (new BlueChannelEditor ()),
+ CreateEditor (new AlphaChannelEditor ())
};
default:
case ChannelEditorType.CMYK:
return new[] {
- CreateEditor (new CyanComponentEditor ()),
- CreateEditor (new MagentaComponentEditor ()),
- CreateEditor (new YellowComponentEditor ()),
- CreateEditor (new BlackComponentEditor ()),
- CreateEditor (new AlphaComponentEditor ())
+ CreateEditor (new CyanChannelEditor ()),
+ CreateEditor (new MagentaChannelEditor ()),
+ CreateEditor (new YellowChannelEditor ()),
+ CreateEditor (new BlackChannelEditor ()),
+ CreateEditor (new AlphaChannelEditor ())
};
}
}
@@ -233,9 +232,7 @@ namespace Xamarin.PropertyEditing.Mac
var editorFrame = new CGRect (labelFrame.Right, labelFrame.Y, frame.Width - labelFrame.Right, DefaultControlHeight);
var yOffset = DefaultControlHeight + DefaultGradientHeight + 3;
-
foreach (var e in Editors) {
- //e.Label.TopAnchor.ConstraintEqualToAnchor (this.TopAnchor);
e.Label.Frame = labelFrame;
e.Editor.Frame = editorFrame;
e.Gradient.Frame = new CGRect (editorFrame.X, editorFrame.Y - DefaultGradientHeight, editorFrame.Width - 16, DefaultGradientHeight);
@@ -247,90 +244,9 @@ namespace Xamarin.PropertyEditing.Mac
}
}
- public abstract class ComponentEditor
- {
- public string Name { get; }
- public double MinimumValue { get; }
- public double MaximumValue { get; }
- public double IncrementValue { get; }
-
- static IEnumerable<double> LerpSteps (double min, double max, int steps)
- => Enumerable.Range (0, steps).Select (v => {
- var pos = v / (double)steps;
- return max * pos - min * (1 - pos);
- });
-
- public ComponentEditor (string name, double min, double max, double increment)
- {
- MinimumValue = min;
- MaximumValue = max;
- IncrementValue = increment;
- Name = name;
- }
-
- public void UpdateGradientLayer (CAGradientLayer layer, CommonColor color)
- {
- var c = color.UpdateRGB (a: 255);
-
- layer.Colors = LerpSteps (MinimumValue, MaximumValue, 7)
- .Select (value => UpdateColorFromValue (c, value).ToCGColor ()).ToArray ();
- }
-
- public double InvLerp (CGPoint start, CGPoint end, CGPoint loc)
- {
- var a = new CGVector (end.X - start.X, end.Y - start.Y);
- var b = new CGVector (loc.X - start.X, loc.Y - start.Y);
- var dot = a.dx * b.dx + a.dy * b.dy;
- var len = Math.Sqrt (a.dx * a.dx + a.dy * a.dy);
- return dot / len;
- }
-
- public static double InvLerp (double start, double end, double value)
- => (value - start) / (end - start);
-
- public static double Lerp (double start, double end, double amount)
- => end * amount - start * (1 - amount);
-
- public static CGPoint Lerp (CGPoint start, CGPoint end, double amount)
- => new CGPoint (
- start.X + (end.X - start.X) * amount,
- start.Y + (end.Y - start.Y) * amount);
-
- public double ValueFromLocation (CAGradientLayer layer, CGPoint loc)
- {
- var rect = layer.Frame;
- var unitLoc = new CGPoint (
- (loc.X - rect.X) / rect.Width,
- (loc.Y - rect.Y) / rect.Height);
-
- return Clamp (Lerp (MinimumValue, MaximumValue, InvLerp (layer.StartPoint, layer.EndPoint, unitLoc)));
- }
-
- public CommonColor UpdateColorFromLocation (CAGradientLayer layer, CommonColor color, CGPoint loc)
- => UpdateColorFromValue (color, ValueFromLocation (layer, loc));
-
- public CGPoint LocationFromColor (CAGradientLayer layer, CommonColor color)
- {
- var pos = ValueFromColor (color);
-
- var amount = InvLerp (MinimumValue, MaximumValue, pos);
- var unitLoc = Lerp (layer.StartPoint, layer.EndPoint, amount);
-
- return new CGPoint (
- layer.Frame.X + unitLoc.X * layer.Frame.Width,
- layer.Frame.Y + unitLoc.Y * layer.Frame.Height);
- }
-
- public double Clamp (double value)
- => Math.Max (MinimumValue, Math.Min (MaximumValue, value));
-
- public abstract CommonColor UpdateColorFromValue (CommonColor color, double value);
- public abstract double ValueFromColor (CommonColor color);
- }
-
class ComponentSpinEditor : NumericSpinEditor
{
- public ComponentSpinEditor (ComponentEditor component)
+ public ComponentSpinEditor (ChannelEditor component)
{
ComponentEditor = component;
MinimumValue = component.MinimumValue;
@@ -339,187 +255,6 @@ namespace Xamarin.PropertyEditing.Mac
Digits = 2;
}
- public ComponentEditor ComponentEditor { get; }
- }
-
- class RedComponentEditor : ComponentEditor
- {
- public RedComponentEditor () : base ("R", 0d, 255d, 1d)
- {
- }
-
- public override double ValueFromColor (CommonColor color)
- => (double)color.R;
-
- public override CommonColor UpdateColorFromValue (CommonColor color, double value)
- => color.UpdateRGB (r: (byte)Clamp (value));
- }
-
- class GreenComponentEditor : ComponentEditor
- {
- public GreenComponentEditor () : base ("G", 0d, 255d, 1d)
- {
- }
-
- public override double ValueFromColor (CommonColor color)
- => (double)color.G;
-
- public override CommonColor UpdateColorFromValue (CommonColor color, double value)
- => color.UpdateRGB (g: (byte)Clamp (value));
- }
-
- class BlueComponentEditor : ComponentEditor
- {
- public BlueComponentEditor () : base ("B", 0d, 255d, 1d)
- {
- }
-
- public override double ValueFromColor (CommonColor color)
- => (double)color.B;
-
- public override CommonColor UpdateColorFromValue (CommonColor color, double value)
- => color.UpdateRGB (b: (byte)Clamp (value));
- }
-
- class AlphaComponentEditor : ComponentEditor
- {
- public AlphaComponentEditor () : base ("A", 0d, 255d, 1d)
- {
- }
-
- public override double ValueFromColor (CommonColor color)
- => (double)color.A;
-
- public override CommonColor UpdateColorFromValue (CommonColor color, double value)
- => color.UpdateRGB (a: (byte)Clamp (value));
- }
-
- class CyanComponentEditor : ComponentEditor
- {
- public CyanComponentEditor () : base ("C", 0d, 1d, .01d)
- {
- }
-
- public override double ValueFromColor (CommonColor color)
- => color.C;
-
- public override CommonColor UpdateColorFromValue (CommonColor color, double value)
- => color.UpdateCMYK (c: Clamp (value));
- }
-
- class MagentaComponentEditor : ComponentEditor
- {
- public MagentaComponentEditor () : base ("M", 0d, 1d, .01d)
- {
- }
-
- public override double ValueFromColor (CommonColor color)
- => color.M;
-
- public override CommonColor UpdateColorFromValue (CommonColor color, double value)
- => color.UpdateCMYK (m: Clamp (value));
- }
-
- class YellowComponentEditor : ComponentEditor
- {
- public YellowComponentEditor () : base ("Y", 0d, 1d, .01d)
- {
- }
-
- public override double ValueFromColor (CommonColor color)
- => color.Y;
-
- public override CommonColor UpdateColorFromValue (CommonColor color, double value)
- => color.UpdateCMYK (y: Clamp (value));
- }
-
- class BlackComponentEditor : ComponentEditor
- {
- public BlackComponentEditor () : base ("K", 0d, 1d, .01d)
- {
- }
-
- public override double ValueFromColor (CommonColor color)
- => color.K;
-
- public override CommonColor UpdateColorFromValue (CommonColor color, double value)
- => color.UpdateCMYK (k: Clamp (value));
- }
-
- class HsbHueComponentEditor : ComponentEditor {
- public HsbHueComponentEditor () : base ("H", 0d, 360d, 1d)
- {
- }
-
- public override double ValueFromColor (CommonColor color)
- => color.Hue;
-
- public override CommonColor UpdateColorFromValue (CommonColor color, double value)
- => color.UpdateHSB (hue: Clamp (value));
- }
-
- class HsbSaturationComponentEditor : ComponentEditor
- {
- public HsbSaturationComponentEditor () : base ("S", 0d, 1d, .01d)
- {
- }
-
- public override double ValueFromColor (CommonColor color)
- => color.Saturation;
-
- public override CommonColor UpdateColorFromValue (CommonColor color, double value)
- => color.UpdateHSB (saturation: Clamp (value));
- }
-
- class HsbBrightnessComponentEditor : ComponentEditor
- {
- public HsbBrightnessComponentEditor () : base ("B", 0d, 1d, .01d)
- {
- }
-
- public override double ValueFromColor (CommonColor color)
- => color.Brightness;
-
- public override CommonColor UpdateColorFromValue (CommonColor color, double value)
- => color.UpdateHSB (brightness: Clamp (value));
- }
-
- class HlsHueComponentEditor : ComponentEditor
- {
- public HlsHueComponentEditor () : base ("H", 0d, 360d, 1d)
- {
- }
-
- public override double ValueFromColor (CommonColor color)
- => color.Hue;
-
- public override CommonColor UpdateColorFromValue (CommonColor color, double value)
- => color.UpdateHLS (hue: Clamp (value));
- }
-
- class HlsLightnessComponentEditor : ComponentEditor
- {
- public HlsLightnessComponentEditor () : base ("L", 0d, 1d, .01d)
- {
- }
-
- public override double ValueFromColor (CommonColor color)
- => (double)color.Lightness;
-
- public override CommonColor UpdateColorFromValue (CommonColor color, double value)
- => color.UpdateHLS (lightness: Clamp (value));
- }
-
- class HlsSaturationComponentEditor : ComponentEditor
- {
- public HlsSaturationComponentEditor () : base ("S", 0d, 1d, .01d)
- {
- }
-
- public override double ValueFromColor (CommonColor color)
- => (double)color.Saturation;
-
- public override CommonColor UpdateColorFromValue (CommonColor color, double value)
- => color.UpdateHLS (saturation: Clamp (value));
+ public ChannelEditor ComponentEditor { get; }
}
}
diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/CommandMenuItem.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/CommandMenuItem.cs
index fd1039a..c945a80 100644
--- a/Xamarin.PropertyEditing.Mac/Controls/Custom/CommandMenuItem.cs
+++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/CommandMenuItem.cs
@@ -50,7 +50,7 @@ namespace Xamarin.PropertyEditing.Mac
private void CanExecuteChanged (object sender, EventArgs e)
{
- if(sender is ICommand cmd)
+ if (sender is ICommand cmd)
this.Enabled = cmd.CanExecute (null);
}
}
diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/CommonBrushLayer.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/CommonBrushLayer.cs
new file mode 100644
index 0000000..1325567
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/CommonBrushLayer.cs
@@ -0,0 +1,92 @@
+using System;
+using AppKit;
+using CoreAnimation;
+using CoreGraphics;
+using Xamarin.PropertyEditing.Drawing;
+
+namespace Xamarin.PropertyEditing.Mac
+{
+ class CommonBrushLayer : CALayer
+ {
+ public CommonBrushLayer ()
+ {
+ this.CornerRadius = 3;
+ this.BorderColor = new CGColor (.5f, .5f, .5f, .5f);
+ this.BorderWidth = 1;
+ MasksToBounds = true;
+ }
+
+ CALayer brushLayer;
+ CALayer BrushLayer
+ {
+ get => brushLayer;
+ set
+ {
+ if (brushLayer != null)
+ brushLayer.RemoveFromSuperLayer ();
+
+ brushLayer = value;
+
+ if (brushLayer != null)
+ AddSublayer (brushLayer);
+ }
+ }
+
+ CommonBrush brush;
+ public CommonBrush Brush
+ {
+ get => brush;
+ set
+ {
+ brush = value;
+ BrushLayer = CreateBrushLayer (brush);
+ Opacity = brush == null ? 0 : 1;
+ }
+ }
+
+ public static CALayer CreateBrushLayer (CommonBrush brush)
+ {
+ switch (brush) {
+ case CommonSolidBrush solid:
+ return new CALayer {
+ BackgroundColor = solid.Color.ToCGColor (),
+ Opacity = (float)solid.Opacity
+ };
+ case CommonGradientBrush gradient:
+ return new CommonGradientBrushLayer {
+ Opacity = (float)gradient.Opacity
+ };
+ default:
+ return new CALayer {
+ BackgroundColor = NSColor.Clear.CGColor
+ };
+ }
+ }
+
+ public override void LayoutSublayers ()
+ {
+ base.LayoutSublayers ();
+ BrushLayer.Frame = new CGRect (0, 0, Frame.Width, Frame.Height);
+ Contents = DrawingExtensions.GenerateCheckerboard (Frame);
+ }
+
+ public NSImage RenderPreview ()
+ {
+ var scale = this.ContentsScale;
+ nint h = (nint)(this.Bounds.Height * scale);
+ nint w = (nint)(this.Bounds.Width * scale);
+ nint bytesPerRow = w * 4;
+
+ if (h <= 0 || w <= 0)
+ return null;
+
+ using (var colorSpace = CGColorSpace.CreateGenericRgb ())
+ using (var context = new CGBitmapContext (IntPtr.Zero, w, h, 8, bytesPerRow, colorSpace, CGImageAlphaInfo.PremultipliedLast)) {
+ this.RenderInContext (context);
+ using (var image = context.ToImage ()) {
+ return new NSImage (image, new CGSize (w, h));
+ }
+ }
+ }
+ }
+}
diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/CommonBrushView.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/CommonBrushView.cs
index f303228..f9c355c 100644
--- a/Xamarin.PropertyEditing.Mac/Controls/Custom/CommonBrushView.cs
+++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/CommonBrushView.cs
@@ -12,7 +12,7 @@ namespace Xamarin.PropertyEditing.Mac
set => (Layer as CommonBrushLayer).Brush = value;
}
- public CommonBrushView () : base ()
+ public CommonBrushView ()
{
Initialize ();
}
@@ -22,6 +22,11 @@ namespace Xamarin.PropertyEditing.Mac
Initialize ();
}
+ public CommonBrushView (IntPtr handle) : base (handle)
+ {
+ Initialize ();
+ }
+
void Initialize () {
WantsLayer = true;
Layer = new CommonBrushLayer
diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/CommonGradientBrushLayer.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/CommonGradientBrushLayer.cs
new file mode 100644
index 0000000..5b18fb9
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/CommonGradientBrushLayer.cs
@@ -0,0 +1,62 @@
+using System;
+using System.Linq;
+using CoreAnimation;
+using CoreGraphics;
+using Xamarin.PropertyEditing.Drawing;
+
+namespace Xamarin.PropertyEditing.Mac
+{
+ class CommonGradientBrushLayer : CALayer
+ {
+ public CommonGradientBrushLayer ()
+ {
+ }
+
+ public CommonGradientBrushLayer (IntPtr handle) : base ()
+ {
+ }
+
+ CommonGradientBrush brush;
+ public CommonGradientBrush Brush
+ {
+ get => brush;
+ set
+ {
+ brush = value;
+ SetNeedsDisplay ();
+ }
+ }
+
+ public override void DrawInContext (CGContext ctx)
+ {
+ ctx.SaveState ();
+
+ var colorspace = CGColorSpace.CreateDeviceRGB ();
+ var colors = Brush.GradientStops.Select (stop => stop.Color.ToCGColor ()).ToArray ();
+ var locations = Brush.GradientStops.Select (stop => (nfloat)stop.Offset).ToArray ();
+
+ var gradient = new CGGradient (colorspace, colors, locations);
+ var center = new CGPoint (Bounds.Width / 2f, Bounds.Height / 2f);
+ var radius = (float)Math.Min (Bounds.Width / 2.0, Bounds.Height / 2.0);
+
+ switch (Brush) {
+ case CommonLinearGradientBrush linear:
+ ctx.DrawLinearGradient (
+ gradient,
+ new CGPoint (0, 0),
+ new CGPoint (0, Bounds.Width),
+ CGGradientDrawingOptions.None);
+ break;
+ case CommonRadialGradientBrush radial:
+ ctx.DrawRadialGradient (
+ gradient,
+ startCenter: center,
+ startRadius: 0f,
+ endCenter: center,
+ endRadius: radius,
+ options: CGGradientDrawingOptions.None);
+ break;
+ }
+ }
+ }
+}
diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/DrawingExtensions.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/DrawingExtensions.cs
index e8cd5c9..bf812c2 100644
--- a/Xamarin.PropertyEditing.Mac/Controls/Custom/DrawingExtensions.cs
+++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/DrawingExtensions.cs
@@ -40,8 +40,6 @@ namespace Xamarin.PropertyEditing.Mac
public static CGColor ToCGColor (this CommonColor color)
=> new CGColor (color.R / 255f, color.G / 255f, color.B / 255f, color.A / 255f);
-
-
public static NSColor ToNSColor (this CommonColor color)
=> NSColor.FromRgba (color.R, color.G, color.B, color.A);
diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/EmptyBrushEditorViewController.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/EmptyBrushEditorViewController.cs
new file mode 100644
index 0000000..ca91629
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/EmptyBrushEditorViewController.cs
@@ -0,0 +1,28 @@
+using AppKit;
+using CoreGraphics;
+using Xamarin.PropertyEditing.Drawing;
+using Xamarin.PropertyEditing.ViewModels;
+
+namespace Xamarin.PropertyEditing.Mac
+{
+ class EmptyBrushEditorViewController : PropertyViewController<BrushPropertyViewModel>
+ {
+ NSButton brushEditor;
+
+ public EmptyBrushEditorViewController ()
+ {
+ PreferredContentSize = new CGSize (100, 100);
+ }
+
+ public override void LoadView ()
+ {
+ View = brushEditor = new NSButton {
+ Title = "Edit"
+ };
+
+ brushEditor.Activated += (o, e) => {
+ ViewModel.SelectedBrushType = CommonBrushType.Solid;
+ };
+ }
+ }
+}
diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialBrushEditorViewController.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialBrushEditorViewController.cs
new file mode 100644
index 0000000..cde9f35
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialBrushEditorViewController.cs
@@ -0,0 +1,43 @@
+using System;
+using System.ComponentModel;
+using System.Linq;
+using AppKit;
+using CoreGraphics;
+using Xamarin.PropertyEditing.ViewModels;
+
+namespace Xamarin.PropertyEditing.Mac
+{
+ class MaterialBrushEditorViewController : PropertyViewController <BrushPropertyViewModel>
+ {
+ MaterialView materialEditor;
+
+ public MaterialBrushEditorViewController ()
+ {
+ PreferredContentSize = new CGSize (200, 230);
+ }
+
+ public override void OnPropertyChanged (object sender, PropertyChangedEventArgs e)
+ {
+ switch (e.PropertyName) {
+ case nameof (BrushPropertyViewModel.Value):
+ case nameof (BrushPropertyViewModel.MaterialDesign):
+ if (materialEditor != null)
+ materialEditor.ViewModel = ViewModel;
+ break;
+ }
+ }
+
+ public override void OnViewModelChanged (BrushPropertyViewModel oldModel)
+ {
+ if (materialEditor != null)
+ materialEditor.ViewModel = ViewModel;
+ }
+
+ public override void LoadView ()
+ {
+ View = materialEditor = new MaterialView {
+ ViewModel = ViewModel
+ };
+ }
+ }
+}
diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialColorLayer.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialColorLayer.cs
new file mode 100644
index 0000000..042e7f9
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialColorLayer.cs
@@ -0,0 +1,66 @@
+using CoreAnimation;
+using Xamarin.PropertyEditing.Drawing;
+
+namespace Xamarin.PropertyEditing.Mac
+{
+ class MaterialColorLayer : CATextLayer
+ {
+ public MaterialColorLayer ()
+ {
+ AddSublayer (Selection);
+ }
+
+ CATextLayer Selection { get; } = new CATextLayer () {
+ CornerRadius = 3
+ };
+
+ string text;
+ public string Text
+ {
+ get => text;
+ set
+ {
+ text = value;
+ SetNeedsLayout ();
+ }
+ }
+
+ CommonColor materialColor;
+ public new CommonColor BackgroundColor
+ {
+ get => materialColor;
+ set
+ {
+ materialColor = value;
+ base.BackgroundColor = materialColor.ToCGColor ();
+ }
+ }
+
+ bool isSelected;
+ public bool IsSelected
+ {
+ get => isSelected;
+ set
+ {
+ if (isSelected == value)
+ return;
+ isSelected = value;
+ SetNeedsLayout ();
+ }
+ }
+
+ public override void LayoutSublayers ()
+ {
+ base.LayoutSublayers ();
+ //String = isSelected ? "" : text;
+ Selection.String = text;
+ Selection.Frame = Frame.Bounds ().Border (new CommonThickness (3));
+ Selection.BorderWidth = isSelected ? 2 : 0;
+ Selection.BorderColor = ForegroundColor;
+ Selection.ForegroundColor = ForegroundColor;
+ Selection.FontSize = FontSize;
+ Selection.ContentsScale = ContentsScale;
+ Selection.TextAlignmentMode = TextAlignmentMode;
+ }
+ }
+}
diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialView.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialView.cs
new file mode 100644
index 0000000..b48bb41
--- /dev/null
+++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/MaterialView.cs
@@ -0,0 +1,197 @@
+using System;
+using System.Linq;
+using AppKit;
+using CoreAnimation;
+using CoreGraphics;
+using Xamarin.PropertyEditing.ViewModels;
+
+namespace Xamarin.PropertyEditing.Mac
+{
+ class MaterialView : NSView
+ {
+ public override bool IsFlipped => true;
+
+ readonly string[] ColorNames = {
+ "50",
+ "100",
+ "200",
+ "300",
+ "400",
+ "500",
+ "600",
+ "700",
+ "800",
+ "900"
+ };
+
+ readonly string[] AccentNames = {
+ "A100",
+ "A200",
+ "A400",
+ "A700"
+ };
+
+ readonly string[] BlackWhite = {
+ "White",
+ "Black"
+ };
+
+ public MaterialView () : base ()
+ {
+ Initialize ();
+ }
+
+ void Initialize ()
+ {
+ WantsLayer = true;
+ }
+
+ BrushPropertyViewModel viewModel;
+ public BrushPropertyViewModel ViewModel
+ {
+ get => viewModel;
+ set
+ {
+ viewModel = value;
+ NeedsLayout = true;
+ }
+ }
+
+ public MaterialDesignColorViewModel MaterialDesign
+ {
+ get => ViewModel?.MaterialDesign;
+ }
+
+ public override void Layout ()
+ {
+ if (Layer?.Sublayers != null)
+ foreach (var l in Layer.Sublayers)
+ l.RemoveFromSuperLayer ();
+
+ if (MaterialDesign == null)
+ return;
+
+ var colors = MaterialDesign.Palettes.Select (p => new { p.Name, Color = p.MainColor }).ToArray ();
+ int col = 0;
+ nfloat x = 0;
+ nfloat y = 6;
+ var width = (Frame.Width - 54) / 10;
+ var height = (Frame.Height - 49) / 4;
+
+ foreach (var p in colors) {
+ var frame = new CGRect (x, y, width, height);
+ var selectedColor = p.Color.Lightness > 0.58 ? NSColor.Black : NSColor.White;
+ var l = new MaterialColorLayer {
+ Frame = frame,
+ ForegroundColor = selectedColor.CGColor,
+ BackgroundColor = p.Color,
+ CornerRadius = 3,
+ BorderColor = new CGColor (.5f, .5f, .5f, .5f),
+ MasksToBounds = false,
+ IsSelected = MaterialDesign.Color == p.Color
+ };
+
+ Layer.AddSublayer (l);
+ x += width + 6;
+ col++;
+ if (col >= 10) {
+ x = 0;
+ y += height + 6;
+ col = 0;
+ }
+ }
+
+ Layer.AddSublayer (new CATextLayer {
+ ForegroundColor = NSColor.ControlText.CGColor,
+ Frame = new CGRect (x, y + 6, Frame.Width, 25),
+ String = MaterialDesign.ColorName,
+ FontSize = NSFont.SmallSystemFontSize,
+ ContentsScale = Window?.Screen?.BackingScaleFactor ?? NSScreen.MainScreen.BackingScaleFactor
+ });
+
+ y += 25;
+ x = 0;
+ width = Frame.Width / MaterialDesign.NormalColorScale.Count ();
+ var names = MaterialDesign.NormalColorScale.Count () > 2 ? ColorNames : BlackWhite;
+ var normal = new CALayer {
+ CornerRadius = 3,
+ MasksToBounds = true,
+ Frame = new CGRect (x, y, Frame.Width, height),
+ BorderColor = new CGColor (.5f, .5f, .5f, .5f),
+ BorderWidth = 1
+ };
+
+ Layer.AddSublayer (normal);
+ foreach (var n in MaterialDesign.NormalColorScale.Zip (names, (c, name) => new { Name = name, Color = c.Value })) {
+ var frame = new CGRect (x, y, width, height);
+ var selectedColor = n.Color.Lightness > 0.58 ? NSColor.Black : NSColor.White;
+ var l = new MaterialColorLayer {
+ BackgroundColor = n.Color,
+ ForegroundColor = selectedColor.CGColor,
+ Frame = new CGRect (x, 0, width, height),
+ Text = n.Name,
+ FontSize = 12,
+ ContentsScale = NSScreen.MainScreen.BackingScaleFactor,
+ TextAlignmentMode = CATextLayerAlignmentMode.Center,
+ IsSelected = MaterialDesign.Color == n.Color
+ };
+ normal.AddSublayer (l);
+ x += width;
+ }
+
+ if (MaterialDesign.AccentColorScale.Count () <= 0)
+ return;
+
+ y += height + 6;
+ x = 0;
+
+ var accent = new CALayer {
+ CornerRadius = 3,
+ MasksToBounds = true,
+ Frame = new CGRect (x, y, Frame.Width, height),
+ BorderColor = new CGColor (.5f, .5f, .5f, .5f),
+ BorderWidth = 1
+ };
+ Layer.AddSublayer (accent);
+ width = Frame.Width / MaterialDesign.AccentColorScale.Count ();
+ foreach (var n in MaterialDesign.AccentColorScale.Zip (AccentNames, (c, n) => new { Name = n, Color = c.Value })) {
+ var frame = new CGRect (x, y, width, height);
+ var selectedColor = n.Color.Lightness > 0.58 ? NSColor.Black : NSColor.White;
+ var l = new MaterialColorLayer {
+ BackgroundColor = n.Color,
+ ForegroundColor = selectedColor.CGColor,
+ Frame = new CGRect (x, 0, width, height),
+ Text = n.Name,
+ FontSize = 12,
+ ContentsScale = NSScreen.MainScreen.BackingScaleFactor,
+ TextAlignmentMode = CATextLayerAlignmentMode.Center,
+ IsSelected = ViewModel.Solid.Color == n.Color,
+ };
+
+ accent.AddSublayer (l);
+ x += width;
+ }
+ }
+
+ public override void MouseDown (NSEvent theEvent)
+ {
+ UpdateFromEvent (theEvent);
+ }
+
+ public void UpdateFromEvent (NSEvent theEvent)
+ {
+ var location = ConvertPointToLayer (ConvertPointFromView (theEvent.LocationInWindow, null));
+
+ foreach (var layer in Layer.Sublayers) {
+ var hit = layer.HitTest (location);
+ for (var c = hit; c != null; c = c.SuperLayer) {
+ var editor = c as MaterialColorLayer;
+ if (editor != null) {
+ ViewModel.Solid.Color = editor.BackgroundColor;
+ NeedsLayout = true;
+ }
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/Xamarin.PropertyEditing.Mac/Controls/Custom/SolidColorBrushEditor.cs b/Xamarin.PropertyEditing.Mac/Controls/Custom/SolidColorBrushEditor.cs
index 6f7d350..56d942c 100644
--- a/Xamarin.PropertyEditing.Mac/Controls/Custom/SolidColorBrushEditor.cs
+++ b/Xamarin.PropertyEditing.Mac/Controls/Custom/SolidColorBrushEditor.cs
@@ -103,147 +103,6 @@ namespace Xamarin.PropertyEditing.Mac
abstract public void UpdateFromLocation (EditorInteraction viewModel, CGPoint location);
}
- class CommonGradientBrushLayer : CALayer
- {
- public CommonGradientBrushLayer ()
- {
- }
-
- public CommonGradientBrushLayer (IntPtr handle) : base ()
- {
- }
-
- CommonGradientBrush brush;
- public CommonGradientBrush Brush
- {
- get => brush;
- set {
- brush = value;
- SetNeedsDisplay ();
- }
- }
-
- public override void DrawInContext (CGContext ctx)
- {
- ctx.SaveState ();
-
- var colorspace = CGColorSpace.CreateDeviceRGB ();
- var colors = Brush.GradientStops.Select (stop => stop.Color.ToCGColor ()).ToArray ();
- var locations = Brush.GradientStops.Select (stop => (nfloat)stop.Offset).ToArray ();
-
- var gradient = new CGGradient (colorspace, colors, locations);
- var center = new CGPoint (Bounds.Width / 2f, Bounds.Height / 2f);
- var radius = (float)Math.Min (Bounds.Width / 2.0, Bounds.Height / 2.0);
-
- switch (Brush) {
- case CommonLinearGradientBrush linear:
- ctx.DrawLinearGradient (
- gradient,
- new CGPoint (0, 0),
- new CGPoint (0, Bounds.Width),
- CGGradientDrawingOptions.None);
- break;
- case CommonRadialGradientBrush radial:
- ctx.DrawRadialGradient (
- gradient,
- startCenter: center,
- startRadius: 0f,
- endCenter: center,
- endRadius: radius,
- options: CGGradientDrawingOptions.None);
- break;
- }
- }
- }
-
- class CommonBrushLayer : CALayer
- {
- public CommonBrushLayer ()
- {
- this.CornerRadius = 3;
- this.BorderColor = new CGColor (.5f, .5f, .5f, .5f);
- this.BorderWidth = 1;
- MasksToBounds = true;
- }
-
- CALayer brushLayer;
- CALayer BrushLayer {
- get => brushLayer;
- set {
- if (brushLayer != null)
- brushLayer.RemoveFromSuperLayer ();
-
- brushLayer = value;
-
- if (brushLayer != null)
- AddSublayer (brushLayer);
- }
- }
-
- CommonBrush brush;
- public CommonBrush Brush {
- get => brush;
- set {
- brush = value;
- BrushLayer = CreateBrushLayer (brush);
- Opacity = brush == null ? 0 : 1;
- }
- }
-
- public static CALayer CreateBrushLayer (CommonBrush brush)
- {
- switch (brush) {
- case CommonSolidBrush solid:
- return new CALayer {
- BackgroundColor = solid.Color.ToCGColor (),
- Opacity = (float)solid.Opacity
- };
- case CommonGradientBrush gradient:
- return new CommonGradientBrushLayer {
- Opacity = (float)gradient.Opacity
- };
- default:
- return new CALayer {
- BackgroundColor = NSColor.Clear.CGColor
- };
- }
- }
-
- public override void LayoutSublayers ()
- {
- base.LayoutSublayers ();
- BrushLayer.Frame = new CGRect (0, 0, Frame.Width, Frame.Height);
- Contents = DrawingExtensions.GenerateCheckerboard (Frame);
- }
-
- public NSImage RenderPreview ()
- {
- var scale = this.ContentsScale;
- nint h = (nint)(this.Bounds.Height * scale);
- nint w = (nint)(this.Bounds.Width * scale);
- nint bytesPerRow = w * 4;
-
- if (h <= 0 || w <= 0)
- return null;
-
- using (var colorSpace = CGColorSpace.CreateGenericRgb ())
- using (var context = new CGBitmapContext (IntPtr.Zero, w, h, 8, bytesPerRow, colorSpace, CGImageAlphaInfo.PremultipliedLast)) {
- this.RenderInContext (context);
- using (var image = context.ToImage ()) {
- return new NSImage (image, new CGSize (w, h));
- }
- }
- }
- }
-
- public enum ChannelEditorType
- {
- RGB,
- HLS,
- HSB,
- CMYK
- };
-
class HistoryLayer : ColorEditorLayer
{
const float Margin = 3;
@@ -305,8 +164,8 @@ namespace Xamarin.PropertyEditing.Mac
const float GripRadius = 4;
const float BorderRadius = 3;
const float Margin = 3;
- ComponentEditor saturationEditor = new HsbSaturationComponentEditor ();
- ComponentEditor brightnessEditor = new HsbBrightnessComponentEditor ();
+ ChannelEditor saturationEditor = new HsbSaturationChannelEditor ();
+ ChannelEditor brightnessEditor = new HsbBrightnessChannelEditor ();
public ShadeLayer ()
{
@@ -407,7 +266,7 @@ namespace Xamarin.PropertyEditing.Mac
const float Margin = 3;
const float BorderRadius = 3;
const float GripRadius = 3;
- ComponentEditor hueEditor = new HsbHueComponentEditor ();
+ ChannelEditor hueEditor = new HsbHueChannelEditor ();
public CGColor GripColor
{
diff --git a/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj b/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj
index 45427ab..534033b 100644
--- a/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj
+++ b/Xamarin.PropertyEditing.Mac/Xamarin.PropertyEditing.Mac.csproj
@@ -105,6 +105,14 @@
<Compile Include="Controls\Custom\ColorComponentTabVewController.cs" />
<Compile Include="Controls\Custom\ColorComponentViewController.cs" />
<Compile Include="Controls\Custom\NotifyingViewAdaptor.cs" />
+ <Compile Include="Controls\Custom\MaterialBrushEditorViewController.cs" />
+ <Compile Include="Controls\Custom\MaterialView.cs" />
+ <Compile Include="Controls\Custom\MaterialColorLayer.cs" />
+ <Compile Include="Controls\Custom\EmptyBrushEditorViewController.cs" />
+ <Compile Include="Controls\Custom\ChannelEditorType.cs" />
+ <Compile Include="Controls\Custom\ChannelEditor.cs" />
+ <Compile Include="Controls\Custom\CommonBrushLayer.cs" />
+ <Compile Include="Controls\Custom\CommonGradientBrushLayer.cs" />
</ItemGroup>
<ItemGroup>
<Folder Include="Controls\" />