diff --git a/AvaloniaColorPicker/AvaloniaColorPicker.csproj b/AvaloniaColorPicker/AvaloniaColorPicker.csproj index 7b83e27..499040b 100644 --- a/AvaloniaColorPicker/AvaloniaColorPicker.csproj +++ b/AvaloniaColorPicker/AvaloniaColorPicker.csproj @@ -8,7 +8,7 @@ true University of Bristol A colour picker control for Avalonia, with support for RGB, HSB and CIELAB colour spaces, palettes and colour blindness simulation. - 1.1.0 + 1.2.0 LGPL-3.0-only https://github.com/arklumpus/ColorPicker icon.png diff --git a/AvaloniaColorPicker/ColorPicker.axaml b/AvaloniaColorPicker/ColorPicker.axaml index fd0e692..13d81eb 100644 --- a/AvaloniaColorPicker/ColorPicker.axaml +++ b/AvaloniaColorPicker/ColorPicker.axaml @@ -74,7 +74,7 @@ - + @@ -130,7 +130,7 @@ - + @@ -163,15 +163,15 @@ - + - RGB - HSB - L*a*b* + RGB + HSB + L*a*b* - + @@ -221,27 +221,27 @@ - RGB + RGB - R: - + R: + - G: - + G: + - B: - + B: + - HSB + HSB - H: - + H: + - S: - + S: + - B: - + B: + @@ -261,28 +261,28 @@ - CIELAB + CIELAB - L*: - + L*: + - a*: - + a*: + - b*: - + b*: + - Transparency + Transparency - A: - + A: + - Hex + Hex - # - + # + - + @@ -301,7 +301,7 @@ - + diff --git a/AvaloniaColorPicker/ColorPicker.axaml.cs b/AvaloniaColorPicker/ColorPicker.axaml.cs index 8dcdd5c..8a42cd0 100644 --- a/AvaloniaColorPicker/ColorPicker.axaml.cs +++ b/AvaloniaColorPicker/ColorPicker.axaml.cs @@ -91,9 +91,208 @@ public static void ResetDefaultPalettes() } } - internal enum ColorSpaces + /// + /// Defines the property. + /// + public static readonly StyledProperty IsPaletteVisibleProperty = AvaloniaProperty.Register(nameof(IsPaletteVisible), true); + + /// + /// Determines whether the palette selector is visible or not. + /// + public bool IsPaletteVisible + { + get { return GetValue(IsPaletteVisibleProperty); } + set { SetValue(IsPaletteVisibleProperty, value); } + } + + /// + /// Defines the property. + /// + public static readonly StyledProperty IsColourBlindnessSelectorVisibleProperty = AvaloniaProperty.Register(nameof(IsColourBlindnessSelectorVisible), true); + + /// + /// Determines whether the colour blindness selector is visible or not. + /// + public bool IsColourBlindnessSelectorVisible + { + get { return GetValue(IsColourBlindnessSelectorVisibleProperty); } + set { SetValue(IsColourBlindnessSelectorVisibleProperty, value); } + } + + /// + /// Defines the property. + /// + public static readonly StyledProperty IsHexVisibleProperty = AvaloniaProperty.Register(nameof(IsHexVisible), true); + + /// + /// Determines whether the hex value text box is visible or not. + /// + public bool IsHexVisible + { + get { return GetValue(IsHexVisibleProperty); } + set { SetValue(IsHexVisibleProperty, value); } + } + + /// + /// Defines the property. + /// + public static readonly StyledProperty IsAlphaVisibleProperty = AvaloniaProperty.Register(nameof(IsAlphaVisible), true); + + /// + /// Determines whether the alpha value text box and slider are visible or not. + /// + public bool IsAlphaVisible + { + get { return GetValue(IsAlphaVisibleProperty); } + set { SetValue(IsAlphaVisibleProperty, value); } + } + + /// + /// Defines the property. + /// + public static readonly StyledProperty IsCIELABVisibleProperty = AvaloniaProperty.Register(nameof(IsCIELABVisible), true); + + /// + /// Determines whether the CIELAB component text boxes are visible or not. + /// + public bool IsCIELABVisible + { + get { return GetValue(IsCIELABVisibleProperty); } + set { SetValue(IsCIELABVisibleProperty, value); } + } + + /// + /// Defines the property. + /// + public static readonly StyledProperty IsHSBVisibleProperty = AvaloniaProperty.Register(nameof(IsHSBVisible), true); + + /// + /// Determines whether the HSB component text boxes are visible or not. + /// + public bool IsHSBVisible + { + get { return GetValue(IsHSBVisibleProperty); } + set { SetValue(IsHSBVisibleProperty, value); } + } + + /// + /// Defines the property. + /// + public static readonly StyledProperty IsRGBVisibleProperty = AvaloniaProperty.Register(nameof(IsRGBVisible), true); + + /// + /// Determines whether RGB component text boxes are visible or not. + /// + public bool IsRGBVisible + { + get { return GetValue(IsRGBVisibleProperty); } + set { SetValue(IsRGBVisibleProperty, value); } + } + + /// + /// Defines the property. + /// + public static readonly StyledProperty IsColourSpacePreviewVisibleProperty = AvaloniaProperty.Register(nameof(IsColourSpacePreviewVisible), true); + + /// + /// Determines whether the colour space preview is visible or not. + /// + public bool IsColourSpacePreviewVisible + { + get { return GetValue(IsColourSpacePreviewVisibleProperty); } + set { SetValue(IsColourSpacePreviewVisibleProperty, value); } + } + + /// + /// Defines the property. + /// + public static readonly StyledProperty IsColourSpaceSelectorVisibleProperty = AvaloniaProperty.Register(nameof(IsColourSpaceSelectorVisible), true); + + /// + /// Determines whether the colour space selector is visible or not. + /// + public bool IsColourSpaceSelectorVisible + { + get { return GetValue(IsColourSpaceSelectorVisibleProperty); } + set { SetValue(IsColourSpaceSelectorVisibleProperty, value); } + } + + /// + /// Defines the property. + /// + public static readonly StyledProperty IsCIELABSelectableProperty = AvaloniaProperty.Register(nameof(IsCIELABSelectable), true); + + /// + /// Determines whether the CIELAB colour space can be selected or not. + /// + public bool IsCIELABSelectable + { + get { return GetValue(IsCIELABSelectableProperty); } + set { SetValue(IsCIELABSelectableProperty, value); } + } + + /// + /// Defines the property. + /// + public static readonly StyledProperty IsHSBSelectableProperty = AvaloniaProperty.Register(nameof(IsHSBSelectable), true); + + /// + /// Determines whether the HSB colour space can be selected or not. + /// + public bool IsHSBSelectable + { + get { return GetValue(IsHSBSelectableProperty); } + set { SetValue(IsHSBSelectableProperty, value); } + } + + /// + /// Defines the property. + /// + public static readonly StyledProperty IsRGBSelectableProperty = AvaloniaProperty.Register(nameof(IsRGBSelectable), true); + + /// + /// Determines whether the RGB colour space can be selected or not. + /// + public bool IsRGBSelectable + { + get { return GetValue(IsRGBSelectableProperty); } + set { SetValue(IsRGBSelectableProperty, value); } + } + + + /// + /// Defines the property. + /// + public static readonly StyledProperty ColorSpaceProperty = AvaloniaProperty.Register(nameof(ColorSpace), ColorSpaces.HSB); + + /// + /// The currently selected colour space. + /// + public ColorSpaces ColorSpace + { + get { return GetValue(ColorSpaceProperty); } + set { SetValue(ColorSpaceProperty, value); } + } + + /// + /// Describes the possible colour spaces. + /// + public enum ColorSpaces { - RGB, HSB, LAB + /// + /// The RGB colour space. + /// + RGB, + + /// + /// The HSB colour space. + /// + HSB, + + /// + /// The CIELAB colour space. + /// + LAB } internal enum ColorComponents @@ -236,9 +435,6 @@ private int b } } - - - private ColorSpaces ColorSpace { get; set; } = ColorSpaces.HSB; private ColorComponents ColorComponent { get; set; } = ColorComponents.H; /// @@ -388,42 +584,6 @@ public ColorPicker() BuildColorInterface(true); }; - this.FindControl("ColorSpaceComboBox").SelectionChanged += (s, e) => - { - switch (this.FindControl("ColorSpaceComboBox").SelectedIndex) - { - case 0: - ColorSpace = ColorSpaces.RGB; - this.FindControl("Dim1Toggle").Content = "R"; - this.FindControl("Dim2Toggle").Content = "G"; - this.FindControl("Dim3Toggle").Content = "B"; - break; - case 1: - ColorSpace = ColorSpaces.HSB; - this.FindControl("Dim1Toggle").Content = "H"; - this.FindControl("Dim2Toggle").Content = "S"; - this.FindControl("Dim3Toggle").Content = "B"; - break; - case 2: - ColorSpace = ColorSpaces.LAB; - this.FindControl("Dim1Toggle").Content = "L*"; - this.FindControl("Dim2Toggle").Content = "a*"; - this.FindControl("Dim3Toggle").Content = "b*"; - break; - } - - if (this.FindControl("Dim1Toggle").IsChecked != true) - { - this.FindControl("Dim1Toggle").IsChecked = true; - } - else - { - this.FindControl("Dim1Toggle").IsChecked = false; - this.FindControl("Dim1Toggle").IsChecked = true; - } - - }; - this.FindControl("HexagonColor1").PointerPressed += HexagonPressed; this.FindControl("HexagonColor2").PointerPressed += HexagonPressed; this.FindControl("HexagonColor3").PointerPressed += HexagonPressed; @@ -579,6 +739,78 @@ protected override void OnPropertyChanged(AvaloniaPropertyChangedEventArgs { UpdateDependingOnAlpha(true); } + else if (change.Property == IsAlphaVisibleProperty) + { + if (change.NewValue.GetValueOrDefault()) + { + this.FindControl("MainGrid").ColumnDefinitions[3].Width = new GridLength(15, GridUnitType.Pixel); + this.FindControl("MainGrid").ColumnDefinitions[4].Width = new GridLength(24, GridUnitType.Pixel); + } + else + { + this.FindControl("MainGrid").ColumnDefinitions[3].Width = new GridLength(0, GridUnitType.Pixel); + this.FindControl("MainGrid").ColumnDefinitions[4].Width = new GridLength(0, GridUnitType.Pixel); + } + } + else if (change.Property == ColorSpaceProperty) + { + switch (ColorSpace) + { + case ColorSpaces.RGB: + this.FindControl("Dim1Toggle").Content = "R"; + this.FindControl("Dim2Toggle").Content = "G"; + this.FindControl("Dim3Toggle").Content = "B"; + break; + case ColorSpaces.HSB: + this.FindControl("Dim1Toggle").Content = "H"; + this.FindControl("Dim2Toggle").Content = "S"; + this.FindControl("Dim3Toggle").Content = "B"; + break; + case ColorSpaces.LAB: + this.FindControl("Dim1Toggle").Content = "L*"; + this.FindControl("Dim2Toggle").Content = "a*"; + this.FindControl("Dim3Toggle").Content = "b*"; + break; + } + + if (this.FindControl("Dim1Toggle").IsChecked != true) + { + this.FindControl("Dim1Toggle").IsChecked = true; + } + else + { + this.FindControl("Dim1Toggle").IsChecked = false; + this.FindControl("Dim1Toggle").IsChecked = true; + } + } + + if (change.Property == IsAlphaVisibleProperty || change.Property == IsHexVisibleProperty || change.Property == IsCIELABVisibleProperty || change.Property == IsColourBlindnessSelectorVisibleProperty) + { + if (!IsAlphaVisible && !IsHexVisible && !IsCIELABVisible && !IsColourBlindnessSelectorVisible) + { + this.FindControl("MainGrid").ColumnDefinitions[9].Width = new GridLength(0, GridUnitType.Pixel); + this.FindControl("MainGrid").ColumnDefinitions[10].Width = new GridLength(0, GridUnitType.Pixel); + } + else + { + this.FindControl("MainGrid").ColumnDefinitions[9].Width = new GridLength(15, GridUnitType.Pixel); + this.FindControl("MainGrid").ColumnDefinitions[10].Width = new GridLength(180, GridUnitType.Pixel); + } + } + + if (change.Property == IsRGBVisibleProperty || change.Property == IsHSBVisibleProperty || change.Property == IsColourBlindnessSelectorVisibleProperty) + { + if (!IsRGBVisible && !IsHSBVisible && !IsColourBlindnessSelectorVisible) + { + this.FindControl("MainGrid").ColumnDefinitions[7].Width = new GridLength(0, GridUnitType.Pixel); + this.FindControl("MainGrid").ColumnDefinitions[8].Width = new GridLength(0, GridUnitType.Pixel); + } + else + { + this.FindControl("MainGrid").ColumnDefinitions[7].Width = new GridLength(15, GridUnitType.Pixel); + this.FindControl("MainGrid").ColumnDefinitions[8].Width = new GridLength(180, GridUnitType.Pixel); + } + } } private void InitializeComponent() diff --git a/AvaloniaColorPicker/ColorPickerWindow.axaml.cs b/AvaloniaColorPicker/ColorPickerWindow.axaml.cs index fe93ab3..0c956bd 100644 --- a/AvaloniaColorPicker/ColorPickerWindow.axaml.cs +++ b/AvaloniaColorPicker/ColorPickerWindow.axaml.cs @@ -73,6 +73,123 @@ public Color? PreviousColor } } + /// + /// Determines whether the palette selector is visible or not. + /// + public bool IsPaletteVisible + { + get => this.FindControl("ColorPicker").IsPaletteVisible; + set { this.FindControl("ColorPicker").IsPaletteVisible = value; } + } + + /// + /// Determines whether the colour blindness selector is visible or not. + /// + public bool IsColourBlindnessSelectorVisible + { + get => this.FindControl("ColorPicker").IsColourBlindnessSelectorVisible; + set { this.FindControl("ColorPicker").IsColourBlindnessSelectorVisible = value; } + } + + /// + /// Determines whether the hex value text box is visible or not. + /// + public bool IsHexVisible + { + get => this.FindControl("ColorPicker").IsHexVisible; + set { this.FindControl("ColorPicker").IsHexVisible = value; } + } + + /// + /// Determines whether the alpha value text box and slider are visible or not. + /// + public bool IsAlphaVisible + { + get => this.FindControl("ColorPicker").IsAlphaVisible; + set { this.FindControl("ColorPicker").IsAlphaVisible = value; } + } + + /// + /// Determines whether the CIELAB component text boxes are visible or not. + /// + public bool IsCIELABVisible + { + get => this.FindControl("ColorPicker").IsCIELABVisible; + set { this.FindControl("ColorPicker").IsCIELABVisible = value; } + } + + /// + /// Determines whether the HSB component text boxes are visible or not. + /// + public bool IsHSBVisible + { + get => this.FindControl("ColorPicker").IsHSBVisible; + set { this.FindControl("ColorPicker").IsHSBVisible = value; } + } + + /// + /// Determines whether RGB component text boxes are visible or not. + /// + public bool IsRGBVisible + { + get => this.FindControl("ColorPicker").IsRGBVisible; + set { this.FindControl("ColorPicker").IsRGBVisible = value; } + } + + /// + /// Determines whether the colour space preview is visible or not. + /// + public bool IsColourSpacePreviewVisible + { + get => this.FindControl("ColorPicker").IsColourSpacePreviewVisible; + set { this.FindControl("ColorPicker").IsColourSpacePreviewVisible = value; } + } + + /// + /// Determines whether the colour space selector is visible or not. + /// + public bool IsColourSpaceSelectorVisible + { + get => this.FindControl("ColorPicker").IsColourSpaceSelectorVisible; + set { this.FindControl("ColorPicker").IsColourSpaceSelectorVisible = value; } + } + + /// + /// Determines whether the CIELAB colour space can be selected or not. + /// + public bool IsCIELABSelectable + { + get => this.FindControl("ColorPicker").IsCIELABSelectable; + set { this.FindControl("ColorPicker").IsCIELABSelectable = value; } + } + + /// + /// Determines whether the HSB colour space can be selected or not. + /// + public bool IsHSBSelectable + { + get => this.FindControl("ColorPicker").IsHSBSelectable; + set { this.FindControl("ColorPicker").IsHSBSelectable = value; } + } + + /// + /// Determines whether the RGB colour space can be selected or not. + /// + public bool IsRGBSelectable + { + get => this.FindControl("ColorPicker").IsRGBSelectable; + set { this.FindControl("ColorPicker").IsRGBSelectable = value; } + } + + /// + /// The currently selected colour space. + /// + public ColorPicker.ColorSpaces ColorSpace + { + get => this.FindControl("ColorPicker").ColorSpace; + set { this.FindControl("ColorPicker").ColorSpace = value; } + } + private bool Result = false; /// diff --git a/ColorButtonDemo/ColorButtonDemo.csproj b/ColorButtonDemo/ColorButtonDemo.csproj index 296237e..a516116 100644 --- a/ColorButtonDemo/ColorButtonDemo.csproj +++ b/ColorButtonDemo/ColorButtonDemo.csproj @@ -6,6 +6,6 @@ - + diff --git a/ColorPickerDemo/ColorPickerDemo.csproj b/ColorPickerDemo/ColorPickerDemo.csproj index 108b0c9..e127f93 100644 --- a/ColorPickerDemo/ColorPickerDemo.csproj +++ b/ColorPickerDemo/ColorPickerDemo.csproj @@ -6,6 +6,6 @@ - + diff --git a/Readme.md b/Readme.md index a03cdd2..ca144ca 100644 --- a/Readme.md +++ b/Readme.md @@ -6,7 +6,7 @@ The library contains three main controls: -* The `ColorPicker` class represents the core of the library: a color picker control that lets users specify a color in RGB, HSB or CIELAB components, either as raw values, or by using a 1-D slider combined with a 2-D surface. It can simulate how the colours would look when viewed by people with various kinds of color-blindness and it can suggest, for any given colour, a lighter and darker shade of the colour, as well as a "contrasting colour" that is stands up against it, even when viewed by colour-blind people. It has a "palette" feature to store user-defined colours that persist between sessions and are shared between all applications using this control). Seven predefined palettes are also provided. +* The `ColorPicker` class represents the core of the library: a color picker control that lets users specify a color in RGB, HSB or CIELAB components, either as raw values, or by using a 1-D slider combined with a 2-D surface. It can simulate how the colours would look when viewed by people with various kinds of color-blindness and it can suggest, for any given colour, a lighter and darker shade of the colour, as well as a "contrasting colour" that stands up against it, even when viewed by colour-blind people. It has a "palette" feature to store user-defined colours that persist between sessions and are shared between all applications using this control). Seven predefined palettes are also provided. * The `ColorPickerWindow` class represents a window containing a `ColorPicker` and two buttons (`OK` and `Cancel`); this can be used as a dialog window to let users choose a colour. * The `ColorButton` class represents a button displaying the currently selected colour, which can be clicked to choose another colour from the current palette or from a `ColorPickerWindow`. @@ -194,6 +194,82 @@ The `ColourButton` control (where `T` inherits from `Window` and implements ` grid.Children.Add(new ColorButton()) ``` +## Hiding parts of the interface + +It is possible to hide some elements from the interface, if they are not needed. This can be achieved by using a number of properties of the `ColorPicker` and `ColorWindow` classes. The image below gives an overview of the controls that can be hidden and of the properties that determine their visibility. + + + +In summary: + +* `IsPaletteVisible` determines the visibility of the palette selector. +* `IsColourBlindnessSelectorVisible` determines the visibility of the colour blindness mode selector. +* `IsHexVisible` determines the visibility of the hex value selector. +* `IsAlphaVisible` determines the visibility of the alpha selector and of the alpha slider. +* `IsCIELABVisible` determines the visibility of the `L*`, `a*` and `b*` text boxes. +* `IsHSBVisible` determines the visibility of the `H`, `S` and `B` text boxes. +* `IsRGBVisible` determines the visibility of the `R`, `G` and `B` text boxes. +* `IsColourSpacePreviewVisible` determines the visibility of the 3D colour space. +* `IsColourSpaceSelectorVisible` determines the visibility of the colour space selection drop down. + +Furthermore, the following properties can be used to determine which colour spaces can be selected by the user (if the colour space selector is visible): + +* `IsCIELABSelectable` determines whether the CIELAB colour space can be selected. +* `IsHSBSelectable` determines whether the HSB colour space can be selected. +* `IsRGBSelectable` determines whether the RGB colour space can be selected. + +If you disable the HSB colour space, you may also want to change the colour space that is selected initially, by using the `ColorSpace` property. + +If you are using the `ColorPicker` or `ColorPickerWindow` controls directly, you can simply set these properties on the control. If you are instead using the `ColourButton` control, you will have to create a class that inherits from `ColorPickerWindow` to set the value of these properties, and then use the generic version of the `ColorButton` control. For example: + +``` CSharp +using Avalonia; +using Avalonia.Controls; +using Avalonia.Markup.Xaml; + +namespace ColorButtonDemo +{ + public class MainWindow : Window + { + public MainWindow() + { + InitializeComponent(); + } + + private void InitializeComponent() + { + AvaloniaXamlLoader.Load(this); + + // Create the ColourButton that shows a MyColorPickerWindow. + AvaloniaColorPicker.ColorButton button = new AvaloniaColorPicker.ColorButton(); + + // Add the ColorButton to the interface. + Grid.SetRow(button, 1); + Grid.SetColumn(button, 1); + this.FindControl("MainGrid").Children.Add(button); + } + + // Class that inherits from ColorPickerWindow and sets the value of some properties. + private class MyColorPickerWindow : AvaloniaColorPicker.ColorPickerWindow + { + // Set the value of the properties. + private void SetProperties() + { + // Hide the alpha selector. + this.IsAlphaVisible = false; + + // Hide the CIELAB component elements. + this.IsCIELABVisible = false; + } + + // Make sure that both constructors call the SetProperties method. + public MyColorPickerWindow() : base() => SetProperties(); + public MyColorPickerWindow(Avalonia.Media.Color? previousColour) : base(previousColour) => SetProperties(); + } + } +} +``` + ## Source code The source code for the library is available in this repository. In addition to the `AvaloniaColorPicker` library project and the two demo applications, the repository also contains a project for an application that is used to generate the `LabColorSpace.bin` cache file that is used by `AvaloniaColorPicker` to display 3D "sections" of the CIELAB colour space. \ No newline at end of file diff --git a/parts.svg b/parts.svg new file mode 100644 index 0000000..ded7358 --- /dev/null +++ b/parts.svg @@ -0,0 +1,267 @@ + + + + + + + + + + image/svg+xml + + + + + + + + + + IsAlphaVisible + + IsCIELABVisible + + IsRGBVisible + + IsHSBVisible + + IsHexVisible + IsAlphaVisible + + + IsColourBlindnessSelectorVisible + + IsPaletteVisible + + IsColourSpaceSelectorVisible + + + IsColourSpacePreviewVisible + + +