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