The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

Toolbox.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/Toolbox.vala.
Platform independent tool tip
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 using Math; 17 18 namespace BirdFont { 19 20 public class Toolbox : GLib.Object { 21 public static ToolCollection current_set; 22 23 public static DrawingTools drawing_tools; 24 public static KerningTools kerning_tools; 25 public static PreviewTools preview_tools; 26 public static OverviewTools overview_tools; 27 public static BackgroundTools background_tools; 28 public static HiddenTools hidden_tools; 29 30 Tool current_tool; 31 32 public Tool press_tool; 33 34 public signal void redraw (int x, int y, int w, int h); 35 36 public static int allocation_width = 0; 37 public static int allocation_height = 0; 38 39 /** Scrolling with scroll wheel */ 40 bool scrolling_toolbox = false; 41 42 /** Scroll with touch pad. */ 43 bool scrolling_touch = false; 44 double scroll_y = 0; 45 46 public List<ToolCollection> tool_sets = new List<ToolCollection> (); 47 48 static double scale = 1; 49 50 public Toolbox (GlyphCanvas glyph_canvas, TabBar tab_bar) { 51 current_tool = new Tool ("no_icon"); 52 press_tool = new Tool (null); 53 54 drawing_tools = new DrawingTools (glyph_canvas); 55 kerning_tools = new KerningTools (); 56 preview_tools = new PreviewTools (); 57 overview_tools = new OverviewTools (); 58 background_tools = new BackgroundTools (); 59 hidden_tools = new HiddenTools (); 60 61 tool_sets.append (drawing_tools); 62 tool_sets.append (kerning_tools); 63 tool_sets.append (preview_tools); 64 tool_sets.append (overview_tools); 65 tool_sets.append (background_tools); 66 tool_sets.append (hidden_tools); // tools without a button 67 68 current_set = drawing_tools; 69 70 tab_bar.signal_tab_selected.connect ((tab) => { 71 string tab_name = tab.get_display ().get_name (); 72 set_toolbox_from_tab (tab_name, tab); 73 }); 74 75 update_expanders (); 76 } 77 78 public static void set_toolbox_from_tab (string tab_name, Tab? t = null) { 79 if (tab_name == "Kerning") { 80 current_set = (ToolCollection) kerning_tools; 81 } else if (tab_name == "Preview") { 82 current_set = (ToolCollection) preview_tools; 83 } else if (tab_name == "Overview") { 84 current_set = (ToolCollection) overview_tools; 85 } else if (tab_name == "Backgrounds") { 86 current_set = (ToolCollection) background_tools; 87 } else if (t != null && ((!) t).get_display () is Glyph) { 88 current_set = (ToolCollection) drawing_tools; 89 } else { 90 current_set = new EmptySet (); 91 } 92 93 MainWindow.get_toolbox ().update_expanders (); 94 redraw_tool_box (); 95 } 96 97 public static Tool get_move_tool () { 98 return DrawingTools.move_tool; 99 } 100 101 public static void set_object_stroke (double width) { 102 DrawingTools.object_stroke.set_value_round (width); 103 redraw_tool_box (); 104 } 105 106 public static void set_allocation (int w, int h) { 107 if (w != allocation_width || allocation_height != h) { 108 allocation_width = w; 109 allocation_height = h; 110 111 scale = Toolbox.allocation_width / 160.0; 112 113 Toolbox.redraw_tool_box (); 114 } 115 } 116 117 public void press (uint button, double x, double y) { 118 if (MenuTab.suppress_event) { 119 warn_if_test ("Event suppressed"); 120 return; 121 } 122 123 foreach (Expander exp in current_set.get_expanders ()) { 124 foreach (Tool t in exp.tool) { 125 if (t.tool_is_visible () && t.is_over (x, y)) { 126 t.panel_press_action (t, button, x, y); 127 press_tool = t; 128 } 129 } 130 } 131 132 scrolling_touch = true; 133 scroll_y = y; 134 } 135 136 public void release (uint button, double x, double y) { 137 bool active; 138 139 if (MenuTab.suppress_event) { 140 warn_if_test ("Event suppressed"); 141 return; 142 } 143 144 foreach (Expander exp in current_set.get_expanders ()) { 145 foreach (Tool t in exp.tool) { 146 if (t.tool_is_visible ()) { 147 active = t.is_over (x, y); 148 149 if (active) { 150 if (press_tool == t) { 151 select_tool (t); 152 } 153 } 154 155 t.panel_release_action (t, button, x, y); 156 } 157 } 158 } 159 160 scrolling_touch = false; 161 } 162 163 public void scroll_up (double x, double y) { 164 bool action = false; 165 166 if (MenuTab.suppress_event) { 167 warn_if_test ("Event suppressed"); 168 return; 169 } 170 171 if (!scrolling_toolbox) { 172 foreach (Expander exp in current_set.get_expanders ()) { 173 foreach (Tool t in exp.tool) { 174 if (t.tool_is_visible () && t.is_over (x, y)) { 175 action = t.scroll_wheel_up_action (t); 176 press_tool = t; 177 } 178 } 179 } 180 } 181 182 if (!action) { 183 scroll_current_set (35); 184 } 185 186 redraw_tool_box (); 187 } 188 189 void scroll_current_set (double d) { 190 current_set.scroll += d; 191 192 if (current_set.scroll > 0) { 193 current_set.scroll = 0; 194 } 195 196 if (current_set.content_height < allocation_height) { 197 current_set.scroll = 0; 198 } else if (current_set.content_height + current_set.scroll < allocation_height) { 199 current_set.scroll = allocation_height - current_set.content_height; 200 } 201 202 update_expanders (); 203 suppress_scroll (); 204 } 205 206 public void scroll_down (double x, double y) { 207 bool action = false; 208 209 if (!scrolling_toolbox) { 210 foreach (Expander exp in current_set.get_expanders ()) { 211 foreach (Tool t in exp.tool) { 212 if (t.tool_is_visible () && t.is_over (x, y)) { 213 action = t.scroll_wheel_down_action (t); 214 press_tool = t; 215 } 216 } 217 } 218 } 219 220 if (!action) { 221 scroll_current_set (-35); 222 } 223 224 redraw_tool_box (); 225 } 226 227 void suppress_scroll () { 228 scrolling_toolbox = true; 229 230 Timeout.add (2000, () => { 231 scrolling_toolbox = false; 232 return false; 233 }); 234 } 235 236 public void move (double x, double y) { 237 bool update; 238 bool a; 239 bool consumed = false; 240 bool active; 241 242 foreach (Expander exp in current_set.get_expanders ()) { 243 a = exp.is_over (x, y); 244 update = exp.set_active (a); 245 246 if (update) { 247 redraw ((int) exp.x - 10, (int) exp.y - 10, (int) (exp.x + exp.w + 10), (int) (exp.y + exp.h + 10)); 248 } 249 250 251 foreach (Tool t in exp.tool) { 252 if (t.tool_is_visible ()) { 253 active = t.is_over (x, y); 254 255 if (!active && t.is_active ()) { 256 t.move_out_action (t); 257 } 258 259 update = t.set_active (active); 260 261 if (update) { 262 redraw (0, 0, allocation_width, allocation_height); 263 } 264 265 if (t.panel_move_action (t, x, y)) { 266 consumed = true; 267 } 268 } 269 } 270 } 271 272 if (scrolling_touch && !consumed && BirdFont.android) { 273 scroll_current_set (y - scroll_y); 274 scroll_y = y; 275 redraw_tool_box (); 276 } 277 } 278 279 public static void redraw_tool_box () { 280 if (MenuTab.suppress_event) { 281 warn_if_test ("Don't redraw toolbox when background thread is running."); 282 return; 283 } 284 285 Toolbox t = MainWindow.get_toolbox (); 286 if (!is_null (t)) { 287 t.redraw (0, 0, allocation_width, allocation_height); 288 } 289 } 290 291 public void reset_active_tool () { 292 foreach (Expander exp in current_set.get_expanders ()) { 293 foreach (Tool t in exp.tool) { 294 t.set_active (false); 295 } 296 } 297 } 298 299 public Tool? get_active_tool () { 300 foreach (Expander exp in current_set.get_expanders ()) { 301 foreach (Tool t in exp.tool) { 302 if (t.is_active ()) { 303 return t; 304 } 305 } 306 } 307 308 return null; 309 } 310 311 public void set_current_tool (Tool tool) { 312 if (tool.editor_events) { 313 current_tool = tool; 314 } 315 } 316 317 public Tool get_current_tool () { 318 return current_tool; 319 } 320 321 public void select_tool (Tool tool) { 322 bool update; 323 324 foreach (Expander exp in current_set.get_expanders ()) { 325 foreach (Tool t in exp.tool) { 326 if (tool.get_id () == t.get_id ()) { 327 if (!t.tool_is_visible ()) { 328 warning ("Tool is hidden"); 329 } else { 330 update = false; 331 332 update = tool.set_selected (true); 333 if (tool.persistent) { 334 update = tool.set_active (true); 335 } 336 337 tool.select_action (tool); 338 339 if (update) { 340 redraw ((int) exp.x - 10, (int) exp.y - 10, allocation_width, (int) (allocation_height - exp.y + 10)); 341 } 342 343 set_current_tool (tool); 344 } 345 } 346 } 347 348 } 349 } 350 351 public Tool get_tool (string name) { 352 foreach (ToolCollection tc in tool_sets) { 353 foreach (Expander e in tc.get_expanders ()) { 354 foreach (Tool t in e.tool) { 355 if (t.get_name () == name) { 356 return t; 357 } 358 } 359 } 360 } 361 362 warning ("No tool found for name \"%s\".\n", name); 363 364 return new Tool ("no_icon"); 365 } 366 367 public static void set_tool_visible (string name, bool visible) { 368 Toolbox tb = MainWindow.get_toolbox (); 369 Tool t = tb.get_tool (name); 370 t.set_tool_visibility (visible); 371 tb.update_expanders (); 372 Toolbox.redraw_tool_box (); 373 } 374 375 public static void select_tool_by_name (string name) { 376 Toolbox b = MainWindow.get_toolbox (); 377 378 if (is_null (b)) { 379 return; 380 } 381 382 b.select_tool (b.get_tool (name)); 383 } 384 385 public static void set_scale (double s) { 386 scale = s; 387 } 388 389 public static double get_scale () { 390 return scale; 391 } 392 393 public void set_default_tool_size () { 394 foreach (ToolCollection t in tool_sets) { 395 foreach (Expander e in t.get_expanders ()) { 396 e.update_tool_position (); 397 } 398 } 399 } 400 401 public void update_expanders () { 402 double pos; 403 404 foreach (Expander e in current_set.get_expanders ()) { 405 e.set_scroll (current_set.scroll); 406 } 407 408 pos = 4 * get_scale (); 409 foreach (Expander e in current_set.get_expanders ()) { 410 e.set_offset (pos); 411 412 pos += e.get_content_height () + 4 * get_scale (); 413 414 current_set.content_height = pos; 415 416 if (BirdFont.android) { 417 current_set.content_height *= 1.15; 418 } 419 } 420 421 foreach (Expander e in current_set.get_expanders ()) { 422 e.set_active (false); 423 } 424 } 425 426 private void draw_expanders (int w, int h, Context cr) { 427 foreach (Expander e in current_set.get_expanders ()) { 428 e.draw (w, h, cr); 429 e.draw_content (w, h, cr); 430 } 431 } 432 433 public void draw (int w, int h, Context cr) { 434 EmptySet empty_set; 435 ImageSurface bg; 436 double scale_x, scale_y, scale; 437 438 if (current_set is EmptySet) { 439 empty_set = (EmptySet) current_set; 440 441 if (empty_set.background != null) { 442 bg = (!) empty_set.background; 443 444 scale_x = (double) allocation_width / bg.get_width (); 445 scale_y = (double) allocation_height / bg.get_height (); 446 447 scale = fmax (scale_x, scale_y); 448 449 cr.save (); 450 cr.scale (scale, scale); 451 cr.set_source_surface (bg, 0, 0); 452 cr.paint (); 453 cr.restore (); 454 455 draw_expanders (w, h, cr); 456 } 457 } else { 458 cr.save (); 459 460 cr.rectangle (0, 0, w, h); 461 cr.set_line_width (0); 462 Theme.color (cr, "Background 4"); 463 cr.fill (); 464 465 draw_expanders (w, h, cr); 466 467 cr.restore (); 468 } 469 } 470 471 public class EmptySet : ToolCollection { 472 473 public ImageSurface? background; 474 Gee.ArrayList<Expander> expanders; 475 476 public EmptySet () { 477 background = Icons.get_icon ("corvus_monedula.png"); 478 expanders = new Gee.ArrayList<Expander> (); 479 } 480 481 public override Gee.ArrayList<Expander> get_expanders () { 482 return expanders; 483 } 484 } 485 486 } 487 488 } 489