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