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