Skip to content

Commit

Permalink
Implement a global Color Picker (#432)
Browse files Browse the repository at this point in the history
* port color picker widget from https://github.com/RonnyDo/ColorPicker

* prevent cursor flickering by reducing the max zoom level

* add eye dropper to FillItem

* fix linting issues

* update eyedropper button icon and add a tooltip

* fix typo

* move CorlorPicker to utils

* add eyedropper to border item

* fix lint issues

* [WIP] color picker global action

* remove unnecessary method calls

* implement color picker global action

* fix color picker licence and indentation

* update meson.build

* fix issue with some listeners not being triggered

Co-authored-by: Alessandro <[email protected]>
  • Loading branch information
isneezy and Alecaddd authored Sep 3, 2020
1 parent fd73696 commit cba933a
Show file tree
Hide file tree
Showing 6 changed files with 446 additions and 4 deletions.
32 changes: 30 additions & 2 deletions src/Layouts/Partials/BorderItem.vala
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,14 @@
* along with Akira. If not, see <https://www.gnu.org/licenses/>.
*
* Authored by: Alessandro "alecaddd" Castellani <[email protected]>
* Authored by: Ivan "isneezy" Vilanculo <[email protected]>
*/

public class Akira.Layouts.Partials.BorderItem : Gtk.Grid {
public weak Akira.Window window { get; construct; }

private Gtk.Grid color_chooser;
private Gtk.Button eyedropper_button;
private Gtk.Button hidden_button;
private Gtk.Button delete_button;
private Gtk.Image hidden_button_icon;
Expand All @@ -31,6 +33,7 @@ public class Akira.Layouts.Partials.BorderItem : Gtk.Grid {
public Akira.Partials.ColorField color_container;
private Gtk.Popover color_popover;
private Gtk.Grid color_picker;
private Akira.Utils.ColorPicker eyedropper;
private Gtk.ColorChooserWidget color_chooser_widget;

public Akira.Models.BordersItemModel model { get; construct; }
Expand Down Expand Up @@ -165,6 +168,15 @@ public class Akira.Layouts.Partials.BorderItem : Gtk.Grid {
color_chooser.attach (color_container, 1, 0, 1, 1);
color_chooser.attach (tickness_container, 2, 0, 1, 1);

eyedropper_button = new Gtk.Button ();
eyedropper_button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
eyedropper_button.get_style_context ().add_class ("button-rounded");
eyedropper_button.can_focus = false;
eyedropper_button.valign = Gtk.Align.CENTER;
eyedropper_button.set_tooltip_text (_("Pick color"));
eyedropper_button.add (new Gtk.Image.from_icon_name ("preferences-color-symbolic",
Gtk.IconSize.SMALL_TOOLBAR));

hidden_button = new Gtk.Button ();
hidden_button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
hidden_button.get_style_context ().add_class ("button-rounded");
Expand All @@ -191,20 +203,36 @@ public class Akira.Layouts.Partials.BorderItem : Gtk.Grid {
color_popover.add (color_picker);

attach (color_chooser, 0, 0, 1, 1);
attach (hidden_button, 1, 0, 1, 1);
attach (delete_button, 2, 0, 1, 1);
attach (eyedropper_button, 1, 0, 1, 1);
attach (hidden_button, 2, 0, 1, 1);
attach (delete_button, 3, 0, 1, 1);

set_color_chooser_color ();
set_button_color ();
}

private void create_event_bindings () {
eyedropper_button.clicked.connect (on_eyedropper_click);
delete_button.clicked.connect (on_delete_item);
hidden_button.clicked.connect (toggle_visibility);
model.notify.connect (on_model_changed);
color_chooser_widget.notify["rgba"].connect (on_color_changed);
}

private void on_eyedropper_click () {
eyedropper = new Akira.Utils.ColorPicker ();
eyedropper.show_all ();

eyedropper.picked.connect ((picked_color) => {
color_chooser_widget.set_rgba (picked_color);
eyedropper.close ();
});

eyedropper.cancelled.connect (() => {
eyedropper.close ();
});
}

private void on_model_changed () {
model.item.reset_colors ();
set_button_color ();
Expand Down
32 changes: 30 additions & 2 deletions src/Layouts/Partials/FillItem.vala
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
*
* Authored by: Giacomo "giacomoalbe" Alberini <[email protected]>
* Authored by: Alessandro "alecaddd" Castellani <[email protected]>
* Authored by: Ivan "isneezy" Vilanculo <[email protected]>
*/

public class Akira.Layouts.Partials.FillItem : Gtk.Grid {
public weak Akira.Window window { get; construct; }

private Gtk.Grid fill_chooser;
private Gtk.Button eyedropper_button;
private Gtk.Button hidden_button;
private Gtk.Button delete_button;
private Gtk.Image hidden_button_icon;
Expand All @@ -33,6 +35,7 @@ public class Akira.Layouts.Partials.FillItem : Gtk.Grid {
private Gtk.Popover color_popover;
private Gtk.Grid color_picker;
private Gtk.ColorChooserWidget color_chooser_widget;
private Akira.Utils.ColorPicker eyedropper;

public Akira.Models.FillsItemModel model { get; construct; }

Expand Down Expand Up @@ -167,6 +170,15 @@ public class Akira.Layouts.Partials.FillItem : Gtk.Grid {
fill_chooser.attach (color_container, 1, 0, 1, 1);
fill_chooser.attach (opacity_container, 2, 0, 1, 1);

eyedropper_button = new Gtk.Button ();
eyedropper_button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
eyedropper_button.get_style_context ().add_class ("button-rounded");
eyedropper_button.can_focus = false;
eyedropper_button.valign = Gtk.Align.CENTER;
eyedropper_button.set_tooltip_text (_("Pick color"));
eyedropper_button.add (new Gtk.Image.from_icon_name ("preferences-color-symbolic",
Gtk.IconSize.SMALL_TOOLBAR));

hidden_button = new Gtk.Button ();
hidden_button.get_style_context ().add_class (Gtk.STYLE_CLASS_FLAT);
hidden_button.get_style_context ().add_class ("button-rounded");
Expand All @@ -193,20 +205,36 @@ public class Akira.Layouts.Partials.FillItem : Gtk.Grid {
color_popover.add (color_picker);

attach (fill_chooser, 0, 0, 1, 1);
attach (hidden_button, 1, 0, 1, 1);
attach (delete_button, 2, 0, 1, 1);
attach (eyedropper_button, 1, 0, 1, 1);
attach (hidden_button, 2, 0, 1, 1);
attach (delete_button, 3, 0, 1, 1);

set_color_chooser_color ();
set_button_color ();
}

private void create_event_bindings () {
eyedropper_button.clicked.connect (on_eyedropper_click);
delete_button.clicked.connect (on_delete_item);
hidden_button.clicked.connect (toggle_visibility);
model.notify.connect (on_model_changed);
color_chooser_widget.notify["rgba"].connect (on_color_changed);
}

private void on_eyedropper_click () {
eyedropper = new Akira.Utils.ColorPicker ();
eyedropper.show_all ();

eyedropper.picked.connect ((picked_color) => {
color_chooser_widget.set_rgba (picked_color);
eyedropper.close ();
});

eyedropper.cancelled.connect (() => {
eyedropper.close ();
});
}

private void on_model_changed () {
model.item.reset_colors ();
set_button_color ();
Expand Down
39 changes: 39 additions & 0 deletions src/Services/ActionManager.vala
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
* along with Akira. If not, see <https://www.gnu.org/licenses/>.
*
* Authored by: Alessandro "Alecaddd" Castellani <[email protected]>
* Authored by: Ivan "isneezy" Vilanculo <[email protected]>
*/

public class Akira.Services.ActionManager : Object {
Expand Down Expand Up @@ -64,6 +65,7 @@ public class Akira.Services.ActionManager : Object {
public const string ACTION_FLIP_V = "action_flip_v";
public const string ACTION_ESCAPE = "action_escape";
public const string ACTION_SHORTCUTS = "action_shortcuts";
public const string ACTION_PICK_COLOR = "action_pick_color";

public static Gee.MultiMap<string, string> action_accelerators = new Gee.HashMultiMap<string, string> ();
public static Gee.MultiMap<string, string> typing_accelerators = new Gee.HashMultiMap<string, string> ();
Expand Down Expand Up @@ -101,6 +103,7 @@ public class Akira.Services.ActionManager : Object {
{ ACTION_FLIP_V, action_flip_v },
{ ACTION_ESCAPE, action_escape },
{ ACTION_SHORTCUTS, action_shortcuts },
{ ACTION_PICK_COLOR, action_pick_color },
};

public ActionManager (Akira.Application akira_app, Akira.Window window) {
Expand Down Expand Up @@ -137,6 +140,7 @@ public class Akira.Services.ActionManager : Object {
action_accelerators.set (ACTION_FLIP_H, "<Control>bracketleft");
action_accelerators.set (ACTION_FLIP_V, "<Control>bracketright");
action_accelerators.set (ACTION_SHORTCUTS, "F1");
action_accelerators.set (ACTION_PICK_COLOR, "<Alt>c");

typing_accelerators.set (ACTION_ESCAPE, "Escape");
typing_accelerators.set (ACTION_ARTBOARD_TOOL, "a");
Expand Down Expand Up @@ -452,6 +456,41 @@ public class Akira.Services.ActionManager : Object {
dialog.present ();
}

private void action_pick_color () {
weak Akira.Lib.Canvas canvas = window.main_window.main_canvas.canvas;
// Interrupt if no item is selected.
if (canvas.selected_bound_manager.selected_items.length () == 0) {
return;
}
foreach (var item in canvas.selected_bound_manager.selected_items) {
// Hide the ghost bound manager.
item.bounds_manager.hide ();
}
bool is_holding_shift = false;
var color_picker = new Akira.Utils.ColorPicker ();
color_picker.show_all ();
color_picker.key_pressed.connect (e => {
is_holding_shift = e.keyval == Gdk.Key.Shift_L;
});
color_picker.key_released.connect (e => {
is_holding_shift = e.keyval == Gdk.Key.Shift_L;
});
color_picker.cancelled.connect (() => {
color_picker.close ();
});
color_picker.picked.connect (color => {
foreach (var item in canvas.selected_bound_manager.selected_items) {
if (is_holding_shift) {
item.border_color_string = Utils.Color.rgba_to_hex_string (color);
} else {
item.color_string = Utils.Color.rgba_to_hex_string (color);
}
item.load_colors ();
}
color_picker.close ();
});
}

public static void action_from_group (string action_name, ActionGroup? action_group) {
action_group.activate_action (action_name, null);
}
Expand Down
4 changes: 4 additions & 0 deletions src/Utils/Color.vala
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ public class Akira.Utils.Color : Object {
var rgba = Gdk.RGBA ();
rgba.parse (rgba_string);

return rgba_to_hex_string (rgba);
}

public static string rgba_to_hex_string (Gdk.RGBA rgba) {
return "#%02x%02x%02x".printf (
(int) (rgba.red * 255),
(int) (rgba.green * 255),
Expand Down
Loading

0 comments on commit cba933a

Please sign in to comment.