Commit 75a88bd
Color picker
Changed files (7)
modifiedlibbirdfont/Color.valaaddedlibbirdfont/ColorPicker.valamodifiedlibbirdfont/ColorTool.valamodifiedlibbirdfont/Expander.valamodifiedlibbirdfont/FileTools.valamodifiedlibbirdfont/Glyph.valamodifiedlibbirdfont/LabelTool.vala
Diff
@@ -26,6 +26,48 @@ public class Color { this.b = b; this.a = a; }++ public Color.hsba (double h, double s, double b, double a) {+ double q, p;++ if (s == 0) {+ r = b;+ g = b;+ this.b = b;+ } else {+ q = b < 0.5 ? b * (1 + s) : b + s - b * s;+ p = 2 * b - q;+ r = hue_to_rgb(p, q, h + 1f/3);+ g = hue_to_rgb(p, q, h);+ this.b = hue_to_rgb(p, q, h - 1f/3);+ }+ + this.a = a;+ }++ static double hue_to_rgb (double p, double q, double t){+ if(t < 0) {+ t += 1;+ }+ + if(t > 1) {+ t -= 1;+ }+ + if(t < 1.0 / 6) {+ return p + (q - p) * 6 * t;+ } + + if(t < 1.0 / 2) {+ return q;+ }+ + if(t < 2.0 / 3) {+ return p + (q - p) * (2f/3 - t) * 6;+ }+ + return p;+ } public static Color black () { return new Color (0, 0, 0, 1);new file mode 100644@@ -0,0 +1,174 @@+/*+ Copyright (C) 2015 Johan Mattsson++ This library is free software; you can redistribute it and/or modify + it under the terms of the GNU Lesser General Public License as + published by the Free Software Foundation; either version 3 of the + License, or (at your option) any later version.++ This library is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details.+*/++using Cairo;++namespace BirdFont {++public class ColorPicker : Tool {+ + double hue = 0;+ double s = 0;+ double b = 0;+ double a = 1;++ public signal void color_updated ();+ + bool update_color = false;+ public double bar_height;+ + int selected_bar = 0;+ + public ColorPicker (string tooltip = "") {+ base (null, tooltip);+ + bar_height = 22 * Toolbox.get_scale ();+ h = 4 * bar_height;+ + color_updated.connect (() => {+ redraw ();+ GlyphCanvas.redraw ();+ });++ panel_press_action.connect ((selected, button, tx, ty) => { + if (y <= ty <= y + 4 * bar_height) {+ update_color = true;+ selected_bar = (int) Math.rint ((ty - y) / bar_height);+ set_color_from_pointer (tx);+ }+ });++ panel_move_action.connect ((selected, button, tx, ty) => {+ if (update_color) {+ set_color_from_pointer (tx);+ }+ + return false;+ });++ panel_release_action.connect ((selected, button, tx, ty) => {+ update_color = false;+ });+ }+ + public void set_color_from_pointer (double tx) {+ + if (tx > Toolbox.allocation_width) {+ tx = Toolbox.allocation_width;+ }+ + if (tx < 0) {+ tx = 0;+ }+ + if (selected_bar == 0) {+ hue = (double) tx / Toolbox.allocation_width;+ } else if (selected_bar == 1) {+ s = (double) tx / Toolbox.allocation_width;+ } else if (selected_bar == 2) {+ b = (double) tx / Toolbox.allocation_width;+ } else if (selected_bar == 3) {+ a = (double) tx / Toolbox.allocation_width;+ }+ + redraw (); + }+ + public Color get_color () {+ return new Color.hsba (hue, s, b, a);+ }+ + public void signal_color_updated () {+ color_updated ();+ }+ + public override void draw_tool (Context cr, double px, double py) {+ draw_bars (cr, px, py);+ draw_dial (cr, px, py, 0, hue);+ draw_dial (cr, px, py, 1, s);+ draw_dial (cr, px, py, 2, b);+ draw_dial (cr, px, py, 3, a);+ }+ + public void draw_bars (Context cr, double px, double py) {+ double scale = Toolbox.get_scale ();+ double x = this.x - px;+ double y = this.y - py;+ double step = 1.0 / Toolbox.allocation_width;+ Color c;+ + for (double p = 0; p < 1; p += step) {+ c = new Color.hsba (p, 1, 0.5, 1);+ cr.save ();+ cr.set_source_rgba (c.r, c.g, c.b, c.a);+ cr.rectangle (p * Toolbox.allocation_width, y, scale, bar_height);+ cr.fill ();+ cr.restore ();++ c = new Color.hsba (hue, p, 0.5, 1);+ cr.save ();+ cr.set_source_rgba (c.r, c.g, c.b, c.a);+ cr.rectangle (p * Toolbox.allocation_width, y + bar_height, scale, bar_height);+ cr.fill ();+ cr.restore ();++ c = new Color.hsba (hue, s, p, 1);+ cr.save ();+ cr.set_source_rgba (c.r, c.g, c.b, c.a);+ cr.rectangle (p * Toolbox.allocation_width, y + 2 * bar_height, scale, bar_height);+ cr.fill ();+ cr.restore ();+ + c = new Color.hsba (hue, s, b, p);+ cr.save ();+ cr.set_source_rgba (c.r, c.g, c.b, c.a);+ cr.rectangle (p * Toolbox.allocation_width, y + 3 * bar_height, scale, bar_height);+ cr.fill ();+ cr.restore ();+ }+ }+ + void draw_dial (Context cr, double px, double py, int bar_index, double val) {+ double x = this.x - px;+ double y = this.y - py;+ double scale = Toolbox.get_scale ();+ double p;+ + p = bar_index * bar_height;+ + cr.save ();+ cr.set_line_width (1 * scale);+ cr.set_source_rgba (1, 1, 1, 1);+ cr.move_to (val * Toolbox.allocation_width - 3 * scale, y + p + bar_height);+ cr.line_to (val * Toolbox.allocation_width, y + p + bar_height - 2 * scale);+ cr.line_to (val * Toolbox.allocation_width + 3 * scale, y + p + bar_height);+ cr.stroke_preserve ();+ cr.set_source_rgba (0, 0, 0, 1);+ cr.fill ();+ cr.restore ();+ + cr.save ();+ cr.set_line_width (1 * scale);+ cr.set_source_rgba (1, 1, 1, 1);+ cr.move_to (val * Toolbox.allocation_width - 3 * scale, y + p);+ cr.line_to (val * Toolbox.allocation_width, y + p + 2 * scale);+ cr.line_to (val * Toolbox.allocation_width + 3 * scale, y + p);+ cr.stroke_preserve ();+ cr.set_source_rgba (0, 0, 0, 1);+ cr.fill ();+ cr.restore ();+ }+}++}@@ -43,7 +43,6 @@ public class ColorTool : Tool { } public void signal_color_updated () {- print (get_color ().to_string ()); color_updated (); } @@ -127,6 +127,9 @@ public class Expander : GLib.Object { } else if (t is LayerLabel) { t.w = Toolbox.allocation_width * scale; t.h = 21 * scale;+ } else if (t is ColorPicker) {+ t.w = Toolbox.allocation_width * scale;+ t.h = 4 * ((ColorPicker) t).bar_height; } else { t.w = 33 * scale; t.h = (33 / 1.11) * scale;@@ -151,6 +154,10 @@ public class Expander : GLib.Object { if (t.tool_is_visible ()) { new_row = xt + t.w > Toolbox.allocation_width - 7 * scale; + if (t is ColorPicker) {+ content_height += t.h;+ }+ if (t is ZoomBar) { t.x = xt; t.y = yt;@@ -162,7 +169,7 @@ public class Expander : GLib.Object { if (previous is ZoomBar) { content_height += t.h; }- + if (new_row && !first_row) { content_height += previous.h; xt = x;@@ -88,6 +88,8 @@ public class FileTools : ToolCollection { } } + themes.add_tool (new ColorPicker ());+ expanders.add (font_name); expanders.add (file_tools); expanders.add (themes);@@ -2216,9 +2216,12 @@ public class Glyph : FontDisplay { GlyphCollection? g; GlyphCollection gc; Glyph glyph;+ Gee.ArrayList<string> s;+ SpacingData sd; - foreach (string l in font.get_spacing ()- .get_all_connections ((!) unichar_code.to_string ())) {+ sd = font.get_spacing ();+ s = sd.get_all_connections ((!) unichar_code.to_string ());+ foreach (string l in s) { if (l != (!) unichar_code.to_string ()) { g = font.get_glyph_collection (l); if (g != null) {@@ -2239,9 +2242,13 @@ public class Glyph : FontDisplay { GlyphCollection? g; GlyphCollection gc; Glyph glyph;+ Gee.ArrayList<string> s;+ SpacingData sd; - foreach (string l in font.get_spacing ()- .get_all_connections ((!) unichar_code.to_string ())) {+ sd = font.get_spacing ();+ s = sd.get_all_connections ((!) unichar_code.to_string ());+ + foreach (string l in s) { if (l != (!) unichar_code.to_string ()) { g = font.get_glyph_collection (l); if (g != null) {@@ -66,7 +66,7 @@ public class LabelTool : Tool { if (is_selected ()) { cr.save (); Theme.color (cr, "Menu Background");- cr.rectangle (0, y - 2 * Toolbox.get_scale (), w, h ); // labels overlap with 2 pixels+ cr.rectangle (0, y - 2 * Toolbox.get_scale (), w, h); // labels overlap with 2 pixels cr.fill (); cr.restore (); }