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