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