The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

Tool.vala in libbirdfont

This file is a part of the Birdfont project.

Contributing

Send patches or pull requests to johan.mattsson.m@gmail.com.
Clone this repository: git clone https://github.com/johanmattssonm/birdfont.git

Revisions

View the latest version of libbirdfont/Tool.vala.
New color theme
1 /* 2 Copyright (C) 2012, 2014 Johan Mattsson 3 4 This library is free software; you can redistribute it and/or modify 5 it under the terms of the GNU Lesser General Public License as 6 published by the Free Software Foundation; either version 3 of the 7 License, or (at your option) any later version. 8 9 This library is distributed in the hope that it will be useful, but 10 WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 */ 14 15 using Cairo; 16 17 namespace BirdFont { 18 19 public class Tool : Widget { 20 21 public double x = 0; 22 public double y = 0; 23 public double w = 33 * Toolbox.get_scale (); 24 public double h = (33 / 1.11) * Toolbox.get_scale (); 25 26 double scale; 27 28 public bool active = false; 29 public bool selected = false; 30 31 Text icon_font; 32 33 public signal void select_action (Tool selected); 34 public signal void deselect_action (Tool selected); 35 36 public signal void press_action (Tool selected, int button, int x, int y); 37 public signal void double_click_action (Tool selected, int button, int x, int y); 38 public signal void move_action (Tool selected, int x, int y); 39 public signal void move_out_action (Tool selected); 40 public signal void release_action (Tool selected, int button, int x, int y); 41 42 /** Returns true if tool is listening for scroll wheel actions. */ 43 public signal bool scroll_wheel_up_action (Tool selected); 44 public signal bool scroll_wheel_down_action (Tool selected); 45 46 public signal void key_press_action (Tool selected, uint32 keyval); 47 public signal void key_release_action (Tool selected, uint32 keyval); 48 49 public signal void panel_press_action (Tool selected, uint button, double x, double y); 50 public signal void panel_release_action (Tool selected, uint button, double x, double y); 51 52 /** @return true is event is consumed. */ 53 public signal bool panel_move_action (Tool selected, double x, double y); 54 55 public signal void draw_action (Tool selected, Context cr, Glyph glyph); 56 57 public string name = ""; 58 59 static int next_id = 1; 60 61 int id; 62 63 public bool new_selection = false; 64 65 bool show_bg = true; 66 67 public string tip = ""; 68 69 // keyboard bindings 70 public uint modifier_flag; 71 public unichar key; 72 73 public bool persistent = false; 74 public bool editor_events = false; 75 76 bool waiting_for_tooltip = false; 77 bool showing_this_tooltip = false; 78 static Tool active_tooltip = new Tool (); 79 80 bool visible = true; 81 public bool is_tool_modifier = false; 82 83 /** Create tool with a certain name and load icon "name".png */ 84 public Tool (string? name = null, string tip = "") { 85 this.tip = tip; 86 87 icon_font = new Text (); 88 89 scale = w / 111.0; // scale to 320 dpi 90 91 if (name != null) { 92 set_icon ((!) name); 93 this.name = (!) name; 94 } 95 96 id = next_id; 97 next_id++; 98 99 panel_press_action.connect ((self, button, x, y) => { 100 }); 101 102 move_out_action.connect ((self) => { 103 MainWindow.get_toolbox ().hide_tooltip (); 104 active_tooltip.showing_this_tooltip = false; 105 }); 106 107 panel_move_action.connect ((self, x, y) => { 108 if (is_active ()) { 109 wait_for_tooltip (); 110 } 111 return false; 112 }); 113 } 114 115 public override double get_height () { 116 return 33 * scale; 117 } 118 119 public override double get_width () { 120 return 33 * scale; 121 } 122 123 public void set_tool_visibility (bool v) { 124 visible = v; 125 } 126 127 public bool tool_is_visible () { 128 return visible; 129 } 130 131 void wait_for_tooltip () { 132 TimeoutSource timer_show; 133 int timeout_interval = 1500; 134 135 if (active_tooltip != this) { 136 if (active_tooltip.showing_this_tooltip) { 137 timeout_interval = 1; 138 } 139 140 active_tooltip.showing_this_tooltip = false; 141 showing_this_tooltip = false; 142 active_tooltip = this; 143 144 if (!waiting_for_tooltip) { 145 waiting_for_tooltip = true; 146 timer_show = new TimeoutSource (timeout_interval); 147 timer_show.set_callback (() => { 148 if (tip != "" && active_tooltip.is_active () && !active_tooltip.showing_this_tooltip) { 149 show_tooltip (); 150 } 151 waiting_for_tooltip = false; 152 return waiting_for_tooltip; 153 }); 154 timer_show.attach (null); 155 } 156 } 157 } 158 159 public static void show_tooltip () { 160 TimeoutSource timer_hide; 161 Toolbox toolbox; 162 163 toolbox = MainWindow.get_toolbox (); 164 165 // hide tooltip label later 166 if (!active_tooltip.showing_this_tooltip) { 167 timer_hide = new TimeoutSource (1500); 168 timer_hide.set_callback (() => { 169 if (!active_tooltip.is_active ()) { 170 toolbox.hide_tooltip (); 171 active_tooltip.showing_this_tooltip = false; 172 active_tooltip = new Tool (); 173 } 174 return active_tooltip.showing_this_tooltip; 175 }); 176 timer_hide.attach (null); 177 } 178 179 active_tooltip.showing_this_tooltip = true; 180 181 toolbox.hide_tooltip (); 182 toolbox.show_tooltip (active_tooltip.tip, (int) active_tooltip.x, (int) active_tooltip.y); 183 } 184 185 public void set_icon (string name) { 186 bool found; 187 string icon_file; 188 189 icon_file = Theme.get_icon_file (); 190 icon_font = new Text ((!) name); 191 found = icon_font.load_font (icon_file); 192 icon_font.use_cache (true); 193 icon_font.set_font_size (35); 194 195 if (!found) { 196 warning (@"Icon font for toolbox was not found. ($(icon_file))"); 197 } 198 } 199 200 public bool is_active () { 201 return active; 202 } 203 204 public void set_show_background (bool bg) { 205 show_bg = bg; 206 } 207 208 public int get_id () { 209 return id; 210 } 211 212 public string get_name () { 213 return name; 214 } 215 216 public bool is_selected () { 217 return selected; 218 } 219 220 public string get_tip () { 221 return tip; 222 } 223 224 public new bool is_over (double xp, double yp) { 225 bool r = (x <= xp <= x + w && y <= yp <= y + h); 226 return r; 227 } 228 229 public bool set_selected (bool a) { 230 new_selection = true; 231 selected = a; 232 set_active (a); 233 234 if (!a) { 235 deselect_action (this); 236 } 237 238 return true; 239 } 240 241 /** @return true if this tool changes state, */ 242 public bool set_active (bool ac) { 243 bool ret = (active != ac); 244 active = ac; 245 return ret; 246 } 247 248 public override void draw (Context cr) { 249 double xt = x; 250 double yt = y; 251 252 double bgx, bgy; 253 double iconx, icony; 254 255 string border = "Button Border 3"; 256 string background = "Button Border 3"; 257 258 cr.save (); 259 260 bgx = xt; 261 bgy = yt; 262 263 // Button in four states 264 if (selected) { 265 border = "Button Border 1"; 266 background = "Button Background 1"; 267 } 268 269 if (selected && active) { 270 border = "Button Border 2"; 271 background = "Button Background 2"; 272 } 273 274 if (!selected) { 275 border = "Button Border 3"; 276 background = "Button Background 3"; 277 } 278 279 if (!selected && active) { 280 border = "Button Border 4"; 281 background = "Button Background 4"; 282 } 283 284 Theme.color (cr, background); 285 draw_rounded_rectangle (cr, bgx, bgy, 34, 28, 4); 286 cr.fill (); 287 288 cr.set_line_width (1); 289 Theme.color (cr, border); 290 draw_rounded_rectangle (cr, bgx, bgy, 34, 28, 4); 291 cr.stroke (); 292 293 iconx = bgx + w / 2 - icon_font.get_sidebearing_extent () / 2; 294 icony = bgy + h / 2 - icon_font.get_height () / 2; 295 296 if (!selected) { 297 Theme.text_color (icon_font, "Tool Foreground"); 298 } else { 299 Theme.text_color (icon_font, "Selected Tool Foreground"); 300 } 301 302 icon_font.widget_x = iconx; 303 icon_font.widget_y = icony; 304 305 icon_font.draw (cr); 306 307 cr.restore (); 308 } 309 310 /** Run pending events in main loop before continuing. */ 311 public static void @yield () { 312 int t = 0; 313 TimeoutSource time = new TimeoutSource (500); 314 bool timeout; 315 unowned MainContext context; 316 bool acquired; 317 318 if (TestBirdFont.is_slow_test ()) { 319 timeout = false; 320 321 time.set_callback (() => { 322 timeout = true; 323 return false; 324 }); 325 326 time.attach (null); 327 } else { 328 timeout = true; 329 } 330 331 context = MainContext.default (); 332 acquired = context.acquire (); 333 334 if (unlikely (!acquired)) { 335 warning ("Failed to acquire main loop.\n"); 336 return; 337 } 338 339 while (context.pending () || TestBirdFont.is_slow_test ()) { 340 context.iteration (true); 341 t++; 342 343 if (!context.pending () && TestBirdFont.is_slow_test ()) { 344 if (timeout) break; 345 } 346 } 347 348 context.release (); 349 } 350 351 public void set_persistent (bool p) { 352 persistent = p; 353 } 354 355 public virtual void before_undo () { 356 } 357 358 public virtual void after_undo () { 359 } 360 361 } 362 363 } 364