Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions Pinta.Core/Extensions/Gtk/GtkExtensions.Widget.cs
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,22 @@ public static Gtk.Entry GetEntry (this Gtk.ComboBox box)
return (Gtk.Entry) box.Child!;
}

/// <summary>
/// Helper function to return whether the text field of a Gtk.Entry has focus (i.e. is
/// currently being edited). Gtk.Entry.HasFocus does not match this.
/// </summary>
public static bool IsEditingText (this Gtk.Entry entry)
{
Gtk.Widget? entryText = entry.GetFirstChild ();

if (entryText is null) {
Console.Error.WriteLine ("Failed to find child text widget for Gtk.Entry");
return false;
}

return entryText.HasFocus;
}

/// <summary>
/// Configures a spin button to immediately activate the default widget after pressing Enter,
/// by configuring the editable text field.
Expand Down
19 changes: 6 additions & 13 deletions Pinta.Core/Extensions/ToolBarComboBox.cs
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
//
// ToolBarComboBox.cs
//
//
// Author:
// Jonathan Pobst <[email protected]>
//
//
// Copyright (c) 2010 Jonathan Pobst
//
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
Expand Down Expand Up @@ -84,14 +84,7 @@ private void ComboBox_OnChanged (Gtk.ComboBox _, EventArgs __)
if (!ComboBox.HasEntry)
return;

Gtk.Widget? entryText = ComboBox.GetEntry ().GetFirstChild ();

if (entryText is null) {
Console.Error.WriteLine ("Failed to find child text widget for Gtk.Entry");
return;
}

if (!entryText.HasFocus) {
if (!ComboBox.GetEntry ().IsEditingText ()) {
GLib.Functions.IdleAdd (0, () => {
if (PintaCore.Workspace.HasOpenDocuments)
PintaCore.Workspace.ActiveWorkspace.GrabFocusToCanvas ();
Expand Down
203 changes: 48 additions & 155 deletions Pinta.Gui.Widgets/Widgets/ColorPickerDialog.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
using System;
using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
Expand Down Expand Up @@ -37,9 +36,6 @@ enum ColorSurfaceType
const int SMALL_SLIDER_WIDTH = 150;
const int SMALL_SPACING = 2;

const int CPS_PADDING_HEIGHT = 10;
const int CPS_PADDING_WIDTH = 14;

private readonly Gtk.Box top_box;
private readonly Gtk.Box swatch_box;
private readonly Gtk.Box color_display_box;
Expand Down Expand Up @@ -344,8 +340,10 @@ internal ColorPickerDialog (

// Handles the ColorPickerSliders + Hex entry.

Color initialColor = ExtractTargetedColor (adjustable, primarySelected);

Gtk.Entry hexEntry = new () {
Text_ = ExtractTargetedColor (adjustable, true).ToHex (),
Text_ = initialColor.ToHex (),
MaxWidthChars = 10,
};
hexEntry.OnChanged += HexEntry_OnChanged;
Expand All @@ -359,175 +357,73 @@ internal ColorPickerDialog (
hexBox.Append (hexLabel);
hexBox.Append (hexEntry);

ColorPickerSlider.Settings cpsArgs = new () {
Text = string.Empty,
TopWindow = this,
SliderPaddingHeight = CPS_PADDING_HEIGHT,
SliderPaddingWidth = CPS_PADDING_WIDTH,
SliderWidth = slider_width,
MaxWidthChars = 3,
};

ColorPickerSlider hueSlider = new (
settings: cpsArgs with {
Max = 360,
Text = Translations.GetString ("Hue"),
InitialValue = ExtractTargetedColor (adjustable, true).ToHsv ().Hue,
}
ColorPickerSlider.Component.Hue,
initialColor,
slider_width
);
hueSlider.Gradient.SetDrawFunc (
(_, c, w, h) => hueSlider.DrawGradient (
c,
w,
h,
ColorGradient.Create (
startColor: CurrentColor.CopyHsv (hue: 0),
endColor: CurrentColor.CopyHsv (hue: 360),
range: NumberRange.Create<double> (0, 360),
new Dictionary<double, Color> {
[60] = CurrentColor.CopyHsv (hue: 60),
[120] = CurrentColor.CopyHsv (hue: 120),
[180] = CurrentColor.CopyHsv (hue: 180),
[240] = CurrentColor.CopyHsv (hue: 240),
[300] = CurrentColor.CopyHsv (hue: 300),
}
)
)
);
hueSlider.OnValueChange += (sender, args) => {
CurrentColor = CurrentColor.CopyHsv (hue: args.Value);
hueSlider.OnColorChanged += (_, _) => {
CurrentColor = hueSlider.Color;
UpdateView ();
};

ColorPickerSlider saturationSlider = new (
settings: cpsArgs with {
Max = 100,
Text = Translations.GetString ("Sat"),
InitialValue = ExtractTargetedColor (adjustable, true).ToHsv ().Sat * 100.0,
}
ColorPickerSlider.Component.Saturation,
initialColor,
slider_width
);
saturationSlider.Gradient.SetDrawFunc (
(_, c, w, h) => saturationSlider.DrawGradient (
c,
w,
h,
ColorGradient.Create (
CurrentColor.CopyHsv (sat: 0),
CurrentColor.CopyHsv (sat: 1))
)
);
saturationSlider.OnValueChange += (sender, args) => {
CurrentColor = CurrentColor.CopyHsv (sat: args.Value / 100.0);
saturationSlider.OnColorChanged += (_, _) => {
CurrentColor = saturationSlider.Color;
UpdateView ();
};

ColorPickerSlider valueSlider = new (
settings: cpsArgs with {
Max = 100,
Text = Translations.GetString ("Value"),
InitialValue = ExtractTargetedColor (adjustable, true).ToHsv ().Val * 100.0,
}
);
valueSlider.Gradient.SetDrawFunc (
(_, c, w, h) => valueSlider.DrawGradient (
c,
w,
h,
ColorGradient.Create (
CurrentColor.CopyHsv (value: 0),
CurrentColor.CopyHsv (value: 1))
)
ColorPickerSlider.Component.Value,
initialColor,
slider_width
);
valueSlider.OnValueChange += (sender, args) => {
CurrentColor = CurrentColor.CopyHsv (value: args.Value / 100.0);
valueSlider.OnColorChanged += (_, _) => {
CurrentColor = valueSlider.Color;
UpdateView ();
};

ColorPickerSlider redSlider = new (
settings: cpsArgs with {
Max = 255,
Text = Translations.GetString ("Red"),
InitialValue = ExtractTargetedColor (adjustable, true).R * 255.0,
}
ColorPickerSlider.Component.Red,
initialColor,
slider_width
);
redSlider.Gradient.SetDrawFunc (
(_, c, w, h) => redSlider.DrawGradient (
c,
w,
h,
ColorGradient.Create (
CurrentColor with { R = 0 },
CurrentColor with { R = 1 })
)
);
redSlider.OnValueChange += (sender, args) => {
CurrentColor = CurrentColor with { R = args.Value / 255.0 };
redSlider.OnColorChanged += (_, _) => {
CurrentColor = redSlider.Color;
UpdateView ();
};

ColorPickerSlider greenSlider = new (
settings: cpsArgs with {
Max = 255,
Text = Translations.GetString ("Green"),
InitialValue = ExtractTargetedColor (adjustable, true).G * 255.0,
}
);
greenSlider.Gradient.SetDrawFunc (
(_, c, w, h) => greenSlider.DrawGradient (
c,
w,
h,
ColorGradient.Create (
CurrentColor with { G = 0 },
CurrentColor with { G = 1 })
)
ColorPickerSlider.Component.Green,
initialColor,
slider_width
);
greenSlider.OnValueChange += (sender, args) => {
CurrentColor = CurrentColor with { G = args.Value / 255.0 };
greenSlider.OnColorChanged += (_, _) => {
CurrentColor = greenSlider.Color;
UpdateView ();
};

ColorPickerSlider blueSlider = new (
settings: cpsArgs with {
Max = 255,
Text = Translations.GetString ("Blue"),
InitialValue = ExtractTargetedColor (adjustable, true).B * 255.0,
}
ColorPickerSlider.Component.Blue,
initialColor,
slider_width
);
blueSlider.Gradient.SetDrawFunc (
(_, c, w, h) => blueSlider.DrawGradient (
c,
w,
h,
ColorGradient.Create (
CurrentColor with { B = 0 },
CurrentColor with { B = 1 })
)
);
blueSlider.OnValueChange += (sender, args) => {
CurrentColor = CurrentColor with { B = args.Value / 255.0 };
blueSlider.OnColorChanged += (_, _) => {
CurrentColor = blueSlider.Color;
UpdateView ();
};

ColorPickerSlider alphaSlider = new (
settings: cpsArgs with {
Max = 255,
Text = Translations.GetString ("Alpha"),
InitialValue = ExtractTargetedColor (adjustable, true).A * 255.0,
}
);
alphaSlider.Gradient.SetDrawFunc (
(_, c, w, h) => alphaSlider.DrawGradient (
c,
w,
h,
ColorGradient.Create (
CurrentColor with { A = 0 },
CurrentColor with { A = 1 })
)
ColorPickerSlider.Component.Alpha,
initialColor,
slider_width
);
alphaSlider.OnValueChange += (sender, args) => {
CurrentColor = CurrentColor with { A = args.Value / 255.0 };
alphaSlider.OnColorChanged += (_, _) => {
CurrentColor = alphaSlider.Color;
UpdateView ();
};

Expand Down Expand Up @@ -889,29 +785,26 @@ private void CycleColors ()
UpdateView ();
}


private void UpdateView ()
{
// Redraw picker surfaces
picker_surface_cursor.QueueDraw ();
picker_surface.QueueDraw ();

// Redraw cps
HsvColor hsv = CurrentColor.ToHsv ();

hue_slider.SetValue (hsv.Hue);
saturation_slider.SetValue (hsv.Sat * 100.0);
value_slider.SetValue (hsv.Val * 100.0);

red_slider.SetValue (CurrentColor.R * 255.0);
green_slider.SetValue (CurrentColor.G * 255.0);
blue_slider.SetValue (CurrentColor.B * 255.0);
alpha_slider.SetValue (CurrentColor.A * 255.0);
// Update sliders with current color
Color current = CurrentColor;
hue_slider.Color = current;
saturation_slider.Color = current;
value_slider.Color = current;
red_slider.Color = current;
green_slider.Color = current;
blue_slider.Color = current;
alpha_slider.Color = current;


// Update hex
if (GetFocus ()?.Parent != hex_entry)
hex_entry.SetText (CurrentColor.ToHex ());
hex_entry.SetText (current.ToHex ());

// Redraw palette displays
foreach (var display in color_displays)
Expand Down
Loading
Loading