The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

DrawingTools.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/DrawingTools.vala.
Enable stroke be default
1 /* 2 Copyright (C) 2012, 2013, 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 DrawingTools : ToolCollection { 21 GlyphCanvas glyph_canvas; 22 23 public Gee.ArrayList<Expander> expanders = new Gee.ArrayList<Expander> (); 24 25 Expander draw_tools; 26 public static Expander grid_expander; 27 Expander shape_tools; 28 public static Expander draw_tool_modifiers; 29 public static Expander stroke_expander; 30 public static Expander zoombar_tool; 31 public static Expander view_tools; 32 public static Expander guideline_tools; 33 34 public static PointType point_type = PointType.DOUBLE_CURVE; 35 36 public static Tool add_stroke; 37 public static SpinButton object_stroke; 38 Tool outline; 39 40 public static MoveTool move_tool; 41 public static PenTool pen_tool; 42 43 public static BezierTool bezier_tool; 44 PointTool point_tool; 45 public static ZoomTool zoom_tool; 46 public static ResizeTool resize_tool; 47 public static TrackTool track_tool; 48 public static BackgroundTool move_background; 49 public static Tool move_canvas; 50 51 static Tool quadratic_points; 52 static Tool cubic_points; 53 static Tool double_points; 54 static Tool convert_points; 55 56 public static CutBackgroundTool cut_background; 57 Tool show_bg; 58 Tool bg_selection; 59 SpinButton background_threshold; 60 public static SpinButton background_scale; 61 Tool high_contrast_background; 62 SpinButton auto_trace_resolution; 63 Tool auto_trace; 64 SpinButton auto_trace_simplify; 65 Tool delete_background; 66 67 Tool rectangle; 68 Tool circle; 69 70 Tool help_lines; 71 Tool xheight_help_lines; 72 Tool background_help_lines; 73 74 SpinButton x_coordinate; 75 SpinButton y_coordinate; 76 SpinButton rotation; 77 SpinButton width; 78 SpinButton height; 79 SpinButton skew; 80 81 Tool tie_handles; 82 Tool reflect_handle; 83 Tool create_line; 84 Tool close_path_tool; 85 86 Tool delete_button; 87 public Tool insert_point_on_path_tool; 88 Tool undo_tool; 89 Tool select_all_button; 90 91 OrientationTool reverse_path_tool; 92 Tool move_layer; 93 Tool flip_vertical; 94 Tool flip_horizontal; 95 96 public ZoomBar zoom_bar; 97 98 public DrawingTools (GlyphCanvas main_glyph_canvas) { 99 bool selected_line; 100 101 glyph_canvas = main_glyph_canvas; 102 103 background_scale = new SpinButton (); 104 105 draw_tools = new Expander (t_("Drawing Tools")); 106 draw_tool_modifiers = new Expander (t_("Control Point")); 107 stroke_expander = new Expander (t_("Stroke")); 108 shape_tools = new Expander (t_("Geometrical Shapes")); 109 zoombar_tool = new Expander (t_("Zoom")); 110 view_tools = new Expander (); 111 guideline_tools = new Expander (t_("Guidelines & Grid")); 112 113 Expander font_name = new Expander (); 114 Expander key_tools = new Expander (); // tools on android 115 Expander test_tools = new Expander (); 116 Expander grid = new Expander (t_("Grid Size")); 117 118 grid_expander = grid; 119 120 // font name 121 font_name.add_tool (new FontName ()); 122 123 // Draw tools 124 bezier_tool = new BezierTool ("bezier_tool"); 125 bezier_tool.select_action.connect ((self) => { 126 update_drawing_and_background_tools (self); 127 }); 128 draw_tools.add_tool (bezier_tool); 129 130 pen_tool = new PenTool ("pen_tool"); 131 pen_tool.select_action.connect ((self) => { 132 update_drawing_and_background_tools (self); 133 }); 134 draw_tools.add_tool (pen_tool); 135 136 point_tool = new PointTool ("point_tool"); 137 point_tool.select_action.connect ((self) => { 138 update_drawing_and_background_tools (self); 139 }); 140 draw_tools.add_tool (point_tool); 141 142 zoom_tool = new ZoomTool ("zoom_tool"); 143 zoom_tool.select_action.connect ((self) => { 144 update_drawing_and_background_tools (self); 145 }); 146 draw_tools.add_tool (zoom_tool); 147 148 move_tool = new MoveTool ("move"); 149 move_tool.select_action.connect ((self) => { 150 update_drawing_and_background_tools (self); 151 }); 152 draw_tools.add_tool (move_tool); 153 154 resize_tool = new ResizeTool ("resize"); 155 resize_tool.select_action.connect ((self) => { 156 update_drawing_and_background_tools (self); 157 }); 158 draw_tools.add_tool (resize_tool); 159 160 track_tool = new TrackTool ("track"); // draw outline on freehand 161 track_tool.select_action.connect ((self) => { 162 update_drawing_and_background_tools (self); 163 }); 164 draw_tools.add_tool (track_tool); 165 166 move_background = new BackgroundTool ("move_background"); 167 move_background.select_action.connect ((self) => { 168 update_drawing_and_background_tools (self); 169 }); 170 draw_tools.add_tool (move_background); 171 172 move_canvas = new Tool ("move_canvas", t_("Move canvas")); 173 move_canvas.select_action.connect ((self) => { 174 update_drawing_and_background_tools (self); 175 }); 176 draw_tools.add_tool (move_canvas); 177 178 // Tools on android 179 // Delete key 180 delete_button = new Tool ("delete_button", t_("Delete")); 181 delete_button.select_action.connect ((self) => { 182 TabContent.key_press (Key.DEL); 183 }); 184 key_tools.add_tool (delete_button); 185 186 // Select all points or paths 187 select_all_button = new Tool ("select_all", t_("Select all points or paths")); 188 select_all_button.select_action.connect ((self) => { 189 Glyph g = MainWindow.get_current_glyph (); 190 191 if (point_tool.is_selected () 192 || pen_tool.is_selected () 193 || track_tool.is_selected ()) { 194 pen_tool.select_all_points (); 195 g.open_path (); 196 } else { 197 DrawingTools.move_tool.select_all_paths (); 198 } 199 }); 200 key_tools.add_tool (select_all_button); 201 202 // Undo 203 undo_tool = new Tool ("undo_tool", t_("Undo")); 204 undo_tool.select_action.connect ((self) => { 205 TabContent.undo (); 206 }); 207 key_tools.add_tool (undo_tool); 208 209 bool insert_points = false; 210 insert_point_on_path_tool = new Tool ("new_point_on_path", t_("Insert new points on path")); 211 insert_point_on_path_tool.select_action.connect ((self) => { 212 insert_points = !insert_points; 213 insert_point_on_path_tool.set_selected (insert_points); 214 }); 215 insert_point_on_path_tool.set_persistent (true); 216 key_tools.add_tool (insert_point_on_path_tool); 217 218 // quadratic Bézier points 219 quadratic_points = new Tool ("quadratic_points", t_("Create quadratic Bézier curves")); 220 quadratic_points.select_action.connect ((self) => { 221 point_type = PointType.QUADRATIC; 222 Preferences.set ("point_type", "quadratic_points"); 223 update_type_selection (); 224 }); 225 draw_tool_modifiers.add_tool (quadratic_points); 226 227 // cubic Bézier points 228 cubic_points = new Tool ("cubic_points", t_("Create cubic Bézier curves")); 229 cubic_points.select_action.connect ((self) => { 230 point_type = PointType.CUBIC; 231 Preferences.set ("point_type", "cubic_points"); 232 update_type_selection (); 233 }); 234 draw_tool_modifiers.add_tool (cubic_points); 235 236 // two quadratic points off curve points for each quadratic control point 237 double_points = new Tool ("double_points", t_("Quadratic path with two line handles")); 238 double_points.select_action.connect ((self) => { 239 point_type = PointType.DOUBLE_CURVE; 240 Preferences.set ("point_type", "double_points"); 241 update_type_selection (); 242 }); 243 draw_tool_modifiers.add_tool (double_points); 244 245 // convert point 246 convert_points = new Tool ("convert_point", t_("Convert selected points")); 247 convert_points.select_action.connect ((self) => { 248 PenTool.convert_point_types (); 249 GlyphCanvas.redraw (); 250 update_type_selection (); 251 PenTool.reset_stroke (); 252 }); 253 convert_points.set_persistent (false); 254 draw_tool_modifiers.add_tool (convert_points); 255 256 // x coordinate 257 x_coordinate = new SpinButton ("x_coordinate", t_("X coordinate")); 258 x_coordinate.set_big_number (true); 259 x_coordinate.set_int_value ("0.000"); 260 x_coordinate.set_int_step (0.1); 261 x_coordinate.set_min (-999.99); 262 x_coordinate.set_max (999.99); 263 x_coordinate.show_icon (true); 264 x_coordinate.set_persistent (false); 265 x_coordinate.new_value_action.connect((self) => { 266 Glyph glyph = MainWindow.get_current_glyph (); 267 double x, y, w, h; 268 double delta; 269 270 glyph.selection_boundaries (out x, out y, out w, out h); 271 delta = x_coordinate.get_value () - x + glyph.left_limit; 272 273 foreach (Path path in glyph.active_paths) { 274 path.move (delta, 0); 275 } 276 277 GlyphCanvas.redraw (); 278 }); 279 draw_tool_modifiers.add_tool (x_coordinate); 280 281 move_tool.objects_moved.connect (() => { 282 Glyph glyph = MainWindow.get_current_glyph (); 283 x_coordinate.set_value_round (MoveTool.selection_box_center_x 284 - (MoveTool.selection_box_width / 2) 285 - glyph.left_limit, true, false); 286 }); 287 288 move_tool.selection_changed.connect (() => { 289 Glyph glyph = MainWindow.get_current_glyph (); 290 x_coordinate.set_value_round (MoveTool.selection_box_center_x 291 - (MoveTool.selection_box_width / 2) 292 - glyph.left_limit, true, false); 293 }); 294 295 move_tool.objects_deselected.connect (() => { 296 x_coordinate.set_value_round (0, true, false); 297 x_coordinate.hide_value (); 298 }); 299 300 // y coordinate 301 y_coordinate = new SpinButton ("y_coordinate", t_("Y coordinate")); 302 y_coordinate.set_big_number (true); 303 y_coordinate.set_int_value ("0.000"); 304 y_coordinate.set_int_step (0.1); 305 y_coordinate.set_min (-999.99); 306 y_coordinate.set_max (999.99); 307 y_coordinate.show_icon (true); 308 y_coordinate.set_persistent (false); 309 y_coordinate.new_value_action.connect((self) => { 310 double x, y, w, h; 311 Glyph glyph = MainWindow.get_current_glyph (); 312 Font font = BirdFont.get_current_font (); 313 314 glyph.selection_boundaries (out x, out y, out w, out h); 315 316 foreach (Path path in glyph.active_paths) { 317 path.move (0, y_coordinate.get_value () - (y - h) - font.base_line); 318 } 319 320 GlyphCanvas.redraw (); 321 }); 322 draw_tool_modifiers.add_tool (y_coordinate); 323 324 move_tool.objects_moved.connect (() => { 325 Font font = BirdFont.get_current_font (); 326 y_coordinate.set_value_round (MoveTool.selection_box_center_y 327 - (MoveTool.selection_box_height / 2) 328 + font.base_line, true, false); 329 }); 330 331 move_tool.selection_changed.connect (() => { 332 Font font = BirdFont.get_current_font (); 333 y_coordinate.set_value_round (MoveTool.selection_box_center_y 334 - (MoveTool.selection_box_height / 2) 335 + font.base_line, true, false); 336 }); 337 338 move_tool.objects_deselected.connect (() => { 339 y_coordinate.set_value_round (0, true, false); 340 y_coordinate.hide_value (); 341 }); 342 343 // rotation 344 rotation = new SpinButton ("rotation", t_("Rotation")); 345 rotation.set_big_number (true); 346 rotation.set_int_value ("0.000"); 347 rotation.set_int_step (0.1); 348 rotation.set_min (-360); 349 rotation.set_max (360); 350 rotation.show_icon (true); 351 rotation.set_persistent (false); 352 rotation.new_value_action.connect ((self) => { 353 double x, y, w, h; 354 Glyph glyph = MainWindow.get_current_glyph (); 355 double angle = (self.get_value () / 360) * 2 * PI; 356 Path last_path; 357 glyph.selection_boundaries (out x, out y, out w, out h); 358 359 x += w / 2; 360 y -= h / 2; 361 362 if (glyph.active_paths.size > 0) { 363 last_path = glyph.active_paths.get (glyph.active_paths.size - 1); 364 resize_tool.rotate_selected_paths (angle - last_path.rotation, x, y); 365 } 366 367 GlyphCanvas.redraw (); 368 }); 369 370 resize_tool.objects_rotated.connect ((angle) => { 371 rotation.set_value_round (angle, true, false); 372 PenTool.reset_stroke (); 373 }); 374 375 move_tool.objects_deselected.connect (() => { 376 rotation.set_value_round (0, true, false); 377 rotation.hide_value (); 378 }); 379 380 draw_tool_modifiers.add_tool (rotation); 381 382 // skew 383 skew = new SpinButton ("skew", t_("Skew")); 384 skew.set_big_number (true); 385 skew.set_int_value ("0.000"); 386 skew.set_int_step (1); 387 skew.set_min (-100); 388 skew.set_max (100); 389 skew.show_icon (true); 390 skew.set_persistent (false); 391 skew.new_value_action.connect ((self) => { 392 resize_tool.skew (-skew.get_value ()); 393 PenTool.reset_stroke (); 394 GlyphCanvas.redraw (); 395 }); 396 397 move_tool.objects_moved.connect (() => { 398 Glyph glyph = MainWindow.get_current_glyph (); 399 double d; 400 401 if (glyph.active_paths.size > 0) { 402 d = glyph.active_paths.get (0).skew; 403 resize_tool.last_skew = d; 404 skew.set_value_round (-d, true, false); 405 } 406 }); 407 408 move_tool.objects_deselected.connect (() => { 409 skew.set_value_round (0, true, false); 410 skew.hide_value (); 411 }); 412 413 draw_tool_modifiers.add_tool (skew); 414 415 // width 416 width = new SpinButton ("width", t_("Width")); 417 width.set_big_number (true); 418 width.set_int_value ("0.0000"); 419 width.set_int_step (0.01); 420 width.show_icon (true); 421 width.set_persistent (false); 422 width.new_value_action.connect ((self) => { 423 double x, y, w, h; 424 Glyph glyph; 425 double new_size; 426 427 glyph = MainWindow.get_current_glyph (); 428 glyph.selection_boundaries (out x, out y, out w, out h); 429 430 new_size = self.get_value () / w; 431 432 if (self.get_value () > 0 && new_size != 1) { 433 resize_tool.resize_selected_paths (new_size); 434 } 435 436 GlyphCanvas.redraw (); 437 }); 438 draw_tool_modifiers.add_tool (width); 439 440 // height 441 height = new SpinButton ("height", t_("Height")); 442 height.set_big_number (true); 443 height.set_int_value ("0.0000"); 444 height.set_int_step (0.01); 445 height.show_icon (true); 446 height.set_persistent (false); 447 height.new_value_action.connect ((self) => { 448 double x, y, w, h; 449 Glyph glyph; 450 double new_size; 451 452 glyph = MainWindow.get_current_glyph (); 453 glyph.selection_boundaries (out x, out y, out w, out h); 454 455 new_size = self.get_value () / h; 456 457 if (self.get_value () > 0 && new_size != 1) { 458 resize_tool.resize_selected_paths (new_size); 459 } 460 461 GlyphCanvas.redraw (); 462 }); 463 draw_tool_modifiers.add_tool (height); 464 465 resize_tool.objects_resized.connect ((w, h) => { 466 height.set_value_round (h, true, false); 467 width.set_value_round (w, true, false); 468 }); 469 470 move_tool.objects_deselected.connect (() => { 471 width.set_value_round (0, true, false); 472 width.hide_value (); 473 474 height.set_value_round (0, true, false); 475 height.hide_value (); 476 }); 477 478 move_tool.objects_moved.connect (() => { 479 width.set_value_round (MoveTool.selection_box_width, true, false); 480 height.set_value_round (MoveTool.selection_box_height, true, false); 481 }); 482 483 // tie edit point handles 484 tie_handles = new Tool ("tie_point", t_("Tie curve handles for the selected edit point")); 485 tie_handles.select_action.connect ((self) => { 486 bool tie, end_point; 487 EditPoint p; 488 489 if (PenTool.move_selected_handle) { 490 p = PenTool.active_handle.parent; 491 tie = !p.tie_handles; 492 493 // don't tie end points 494 foreach (Path path in MainWindow.get_current_glyph ().active_paths) { 495 if (path.is_open ()) { 496 if (p == path.get_first_point () || p == path.get_last_point ()) { 497 tie = false; 498 } 499 } 500 } 501 502 if (tie) { 503 p.process_tied_handle (); 504 p.set_reflective_handles (false); 505 } 506 507 p.set_tie_handle (tie); 508 509 PenTool.handle_selection.path.update_region_boundaries (); 510 } else { 511 foreach (PointSelection ep in PenTool.selected_points) { 512 tie = !ep.point.tie_handles; 513 514 end_point = ep.point == ep.path.get_first_point () 515 || ep.point == ep.path.get_last_point (); 516 517 if (!ep.path.is_open () || !end_point) { 518 if (tie) { 519 ep.point.process_tied_handle (); 520 ep.point.set_reflective_handles (false); 521 } 522 523 ep.point.set_tie_handle (tie); 524 ep.path.update_region_boundaries (); 525 } 526 } 527 } 528 529 MainWindow.get_current_glyph ().update_view (); 530 PenTool.reset_stroke (); 531 }); 532 draw_tool_modifiers.add_tool (tie_handles); 533 534 // symmetrical handles 535 reflect_handle = new Tool ("symmetric", t_("Symmetrical handles")); 536 reflect_handle.select_action.connect ((self) => { 537 bool symmetrical, end_point; 538 PointSelection ep; 539 if (PenTool.selected_points.size > 0) { 540 ep = PenTool.selected_points.get (0); 541 symmetrical = ep.point.reflective_point; 542 543 foreach (PointSelection p in PenTool.selected_points) { 544 end_point = p.point == p.path.get_first_point () 545 || p.point == p.path.get_last_point (); 546 547 if (!p.path.is_open () || !end_point) { 548 p.point.set_reflective_handles (!symmetrical); 549 p.point.process_symmetrical_handles (); 550 551 if (symmetrical) { 552 ep.point.set_tie_handle (false); 553 } 554 555 p.path.update_region_boundaries (); 556 } 557 } 558 MainWindow.get_current_glyph ().update_view (); 559 } 560 561 PenTool.reset_stroke (); 562 }); 563 draw_tool_modifiers.add_tool (reflect_handle); 564 565 create_line = new Tool ("create_line", t_("Convert segment to line.")); 566 create_line.select_action.connect ((self) => { 567 PenTool.convert_segment_to_line (); 568 MainWindow.get_current_glyph ().update_view (); 569 PenTool.reset_stroke (); 570 }); 571 draw_tool_modifiers.add_tool (create_line); 572 573 reverse_path_tool = new OrientationTool ("reverse_path", t_("Create counter from outline")); 574 draw_tool_modifiers.add_tool (reverse_path_tool); 575 576 // close path 577 close_path_tool = new Tool ("close_path", t_("Close path")); 578 close_path_tool.select_action.connect ((self) => { 579 Tool current; 580 Glyph g; 581 582 current = MainWindow.get_toolbox ().get_current_tool (); 583 584 if (current is BezierTool) { 585 ((BezierTool) current).stop_drawing (); 586 } 587 588 PenTool.reset_stroke (); 589 590 g = MainWindow.get_current_glyph (); 591 g.close_path (); 592 g.clear_active_paths (); 593 594 self.set_selected (false); 595 GlyphCanvas.redraw (); 596 }); 597 draw_tool_modifiers.add_tool (close_path_tool); 598 599 move_layer = new Tool ("move_layer", t_("Move to path to the bottom layer")); 600 move_layer.select_action.connect ((self) => { 601 Glyph g = MainWindow.get_current_glyph (); 602 603 foreach (Path p in g.active_paths) { 604 g.path_list.remove (p); 605 g.path_list.insert (0, p); 606 } 607 }); 608 draw_tool_modifiers.add_tool (move_layer); 609 610 flip_vertical = new Tool ("flip_vertical", t_("Flip path vertically")); 611 flip_vertical.select_action.connect ((self) => { 612 MoveTool.flip_vertical (); 613 MainWindow.get_current_glyph ().update_view (); 614 PenTool.reset_stroke (); 615 }); 616 draw_tool_modifiers.add_tool (flip_vertical); 617 618 flip_horizontal = new Tool ("flip_horizontal", t_("Flip path horizontally")); 619 flip_horizontal.select_action.connect ((self) => { 620 MoveTool.flip_horizontal (); 621 MainWindow.get_current_glyph ().update_view (); 622 PenTool.reset_stroke (); 623 }); 624 draw_tool_modifiers.add_tool (flip_horizontal); 625 626 // background tools 627 background_scale = new SpinButton ("scale_background", t_("Set size for background image")); 628 background_scale.show_icon (true); 629 background_scale.set_int_value ("1.000"); 630 631 background_scale.new_value_action.connect((self) => { 632 background_scale.select_action (self); 633 }); 634 635 background_scale.select_action.connect((self) => { 636 SpinButton sb = (SpinButton) self; 637 Glyph g = MainWindow.get_current_glyph (); 638 BackgroundImage? img = g.get_background_image (); 639 double s = sb.get_value (); 640 BackgroundImage i; 641 double xc, yc; 642 643 if (img != null) { 644 i = (!) img; 645 xc = i.img_middle_x; 646 yc = i.img_middle_y; 647 648 i.set_img_scale (s, s); 649 650 i.img_middle_x = xc; 651 i.img_middle_y = yc; 652 } 653 654 GlyphCanvas.redraw (); 655 }); 656 657 draw_tool_modifiers.add_tool (background_scale); 658 659 cut_background = new CutBackgroundTool ("cut_background"); 660 cut_background.select_action.connect ((self) => { 661 update_drawing_and_background_tools (self); 662 }); 663 draw_tool_modifiers.add_tool (cut_background); 664 665 show_bg = new Tool ("show_background", t_("Show/hide background image")); 666 show_bg.select_action.connect ((self) => { 667 update_drawing_and_background_tools (self); 668 }); 669 show_bg.select_action.connect ((self) => { 670 Glyph g = MainWindow.get_current_glyph (); 671 g.set_background_visible (!g.get_background_visible ()); 672 GlyphCanvas.redraw (); 673 }); 674 draw_tool_modifiers.add_tool (show_bg); 675 676 bg_selection = new Tool ("insert_background", t_("Insert a new background image")); 677 bg_selection.select_action.connect ((self) => { 678 update_drawing_and_background_tools (self); 679 }); 680 681 bg_selection.select_action.connect((self) => { 682 if (MainWindow.get_current_display () is Glyph) { 683 BackgroundTool.import_background_image (); 684 } 685 }); 686 687 bg_selection.set_show_background (true); 688 draw_tool_modifiers.add_tool (bg_selection); 689 690 high_contrast_background = new Tool ("high_contrast_background", t_("High contrast")); 691 high_contrast_background.select_action.connect ((self) => { 692 Glyph g = MainWindow.get_current_glyph (); 693 BackgroundImage? bg = g.get_background_image (); 694 BackgroundImage b; 695 696 if (bg != null) { 697 b = (!) bg; 698 b.set_high_contrast (!b.high_contrast); 699 b.update_background (); 700 } 701 }); 702 draw_tool_modifiers.add_tool (high_contrast_background); 703 704 background_threshold = new SpinButton ("contrast_threshold", t_("Set background threshold")); 705 background_threshold.show_icon (true); 706 background_threshold.set_value_round (1); 707 708 background_threshold.new_value_action.connect ((self) => { 709 Glyph g = MainWindow.get_current_glyph (); 710 BackgroundImage? bg = g.get_background_image (); 711 BackgroundImage b; 712 713 if (bg != null) { 714 b = (!) bg; 715 b.set_threshold (background_threshold.get_value ()); 716 b.update_background (); 717 } 718 }); 719 720 draw_tool_modifiers.add_tool (background_threshold); 721 722 auto_trace_resolution = new SpinButton ("auto_trace_resolution", t_("Amount of autotrace details")); 723 auto_trace_resolution.set_value_round (1); 724 auto_trace_resolution.show_icon (true); 725 726 auto_trace_resolution.new_value_action.connect ((self) => { 727 Glyph g = MainWindow.get_current_glyph (); 728 BackgroundImage? bg = g.get_background_image (); 729 BackgroundImage b; 730 731 if (bg != null) { 732 b = (!) bg; 733 b.set_trace_resolution (auto_trace_resolution.get_value ()); 734 b.update_background (); 735 } 736 }); 737 738 draw_tool_modifiers.add_tool (auto_trace_resolution); 739 740 auto_trace_simplify = new SpinButton ("auto_trace_simplify", t_("Autotrace simplification")); 741 auto_trace_simplify.set_value_round (0.5); 742 auto_trace_simplify.show_icon (true); 743 744 auto_trace_simplify.new_value_action.connect ((self) => { 745 Glyph g = MainWindow.get_current_glyph (); 746 BackgroundImage? bg = g.get_background_image (); 747 BackgroundImage b; 748 749 if (bg != null) { 750 b = (!) bg; 751 b.set_trace_simplification (auto_trace_simplify.get_value ()); 752 } 753 }); 754 755 draw_tool_modifiers.add_tool (auto_trace_simplify); 756 757 auto_trace = new Tool ("autotrace", t_("Autotrace background image")); 758 auto_trace.select_action.connect ((self) => { 759 Task t = new Task (); 760 t.task.connect (auto_trace_background); 761 MainWindow.native_window.run_background_thread (t); 762 }); 763 764 draw_tool_modifiers.add_tool (auto_trace); 765 766 delete_background = new Tool ("delete_background", t_("Delete background image")); 767 delete_background.select_action.connect ((self) => { 768 MainWindow.get_current_glyph ().delete_background (); 769 }); 770 771 draw_tool_modifiers.add_tool (delete_background); 772 773 // add stroke to path 774 add_stroke = new Tool ("apply_stroke", t_("Apply stroke")); 775 add_stroke.select_action.connect ((self) => { 776 Font f; 777 Glyph g = MainWindow.get_current_glyph (); 778 StrokeTool.add_stroke = !StrokeTool.add_stroke; 779 StrokeTool.stroke_width = object_stroke.get_value (); 780 781 add_stroke.selected = StrokeTool.add_stroke; 782 783 GlyphCanvas.redraw (); 784 g.store_undo_state (); 785 786 if (StrokeTool.add_stroke) { 787 foreach (Path p in g.active_paths) { 788 p.stroke = StrokeTool.stroke_width; 789 } 790 } else { 791 foreach (Path p in g.active_paths) { 792 p.stroke = 0; 793 } 794 } 795 796 f = BirdFont.get_current_font (); 797 f.settings.set_setting ("apply_stroke", @"$(StrokeTool.add_stroke)"); 798 799 add_stroke.selected = StrokeTool.add_stroke; 800 }); 801 stroke_expander.add_tool (add_stroke); 802 add_stroke.selected = StrokeTool.add_stroke; 803 804 // edit stroke width 805 object_stroke = new SpinButton ("object_stroke", t_("Stroke width")); 806 object_stroke.set_big_number (true); 807 object_stroke.set_value_round (2); 808 object_stroke.set_max (0.01); 809 object_stroke.set_max (50); 810 811 object_stroke.new_value_action.connect((self) => { 812 Font f; 813 Glyph g = MainWindow.get_current_glyph (); 814 815 bool tool = resize_tool.is_selected () 816 || move_tool.is_selected () 817 || pen_tool.is_selected () 818 || track_tool.is_selected () 819 || point_tool.is_selected () 820 || bezier_tool.is_selected (); 821 822 StrokeTool.stroke_width = object_stroke.get_value (); 823 824 if (tool && StrokeTool.add_stroke) { 825 foreach (Path p in g.active_paths) { 826 p.stroke = StrokeTool.stroke_width; 827 p.reset_stroke (); 828 } 829 } 830 831 f = BirdFont.get_current_font (); 832 f.settings.set_setting ("stroke_width", object_stroke.get_display_value ()); 833 834 GlyphCanvas.redraw (); 835 }); 836 stroke_expander.add_tool (object_stroke); 837 838 move_tool.selection_changed.connect (() => { 839 update_stroke_settings (); 840 }); 841 842 move_tool.objects_moved.connect (() => { 843 update_stroke_settings (); 844 }); 845 846 // create outline from path 847 outline = new Tool ("stroke_to_outline", t_("Create outline form stroke")); 848 outline.select_action.connect ((self) => { 849 StrokeTool.stroke_selected_paths (); 850 outline.set_selected (false); 851 }); 852 stroke_expander.add_tool (outline); 853 854 if (BirdFont.has_argument ("--test")) { 855 Tool test_case = new Tool ("test_case"); 856 test_case.select_action.connect((self) => { 857 if (self.is_selected ()) { 858 if (TestBirdFont.is_running ()) { 859 TestBirdFont.pause (); 860 } else { 861 TestBirdFont.continue (); 862 } 863 } 864 }); 865 test_tools.add_tool (test_case); 866 867 Tool slow_test = new Tool ("slow_test"); 868 slow_test.select_action.connect((self) => { 869 bool s = TestBirdFont.is_slow_test (); 870 TestBirdFont.set_slow_test (!s); 871 s = TestBirdFont.is_slow_test (); 872 self.set_selected (s); 873 }); 874 875 test_tools.add_tool (slow_test); 876 877 // Run from commad line 878 string? st = BirdFont.get_argument ("--test"); 879 if (st != null && ((!)st).char_count () > 0) { 880 IdleSource idle = new IdleSource (); 881 882 idle.set_callback (() => { 883 MainWindow.get_toolbox ().select_tool (test_case); 884 return false; 885 }); 886 887 idle.attach (null); 888 } 889 890 if (BirdFont.has_argument ("--slow")) { 891 MainWindow.get_toolbox ().select_tool (slow_test); 892 } 893 894 } 895 896 // guide lines, grid and other guidlines 897 help_lines = new Tool ("help_lines", t_("Show guidelines")); 898 help_lines.select_action.connect ((self) => { 899 bool h; 900 h = GlyphCanvas.get_current_glyph ().get_show_help_lines (); 901 GlyphCanvas.get_current_glyph ().set_show_help_lines (!h); 902 self.set_selected (!h); 903 GlyphCanvas.get_current_glyph ().redraw_help_lines (); 904 }); 905 selected_line = GlyphCanvas.get_current_glyph ().get_show_help_lines (); 906 help_lines.set_selected (selected_line); 907 guideline_tools.add_tool (help_lines); 908 909 xheight_help_lines = new Tool ("show_xheight_helplines", t_("Show more guidelines")); 910 xheight_help_lines.select_action.connect ((self) => { 911 Glyph g = MainWindow.get_current_glyph (); 912 bool v = !g.get_xheight_lines_visible (); 913 g.set_xheight_lines_visible (v); 914 self.set_selected (v); 915 GlyphCanvas.redraw (); 916 917 if (v && !help_lines.is_selected ()) { 918 MainWindow.get_toolbox ().select_tool (help_lines); 919 } 920 }); 921 selected_line = GlyphCanvas.get_current_glyph ().get_xheight_lines_visible (); 922 xheight_help_lines.set_selected (selected_line); 923 guideline_tools.add_tool (xheight_help_lines); 924 925 background_help_lines = new Tool ("background_help_lines", t_("Show guidelines at top and bottom margin")); 926 background_help_lines.select_action.connect ((self) => { 927 Glyph g = MainWindow.get_current_glyph (); 928 bool v = !g.get_margin_lines_visible (); 929 g.set_margin_lines_visible (v); 930 self.set_selected (v); 931 GlyphCanvas.redraw (); 932 933 if (v && !help_lines.is_selected ()) { 934 MainWindow.get_toolbox ().select_tool (help_lines); 935 } 936 }); 937 selected_line = GlyphCanvas.get_current_glyph ().get_margin_lines_visible (); 938 background_help_lines.set_selected (selected_line); 939 guideline_tools.add_tool (background_help_lines); 940 941 Tool new_grid = new GridTool ("show_grid"); 942 guideline_tools.add_tool (new_grid); 943 944 // Zoom tools 945 zoom_bar = new ZoomBar (); 946 zoom_bar.new_zoom.connect ((z) => { 947 Glyph g = MainWindow.get_current_glyph (); 948 double zoom = 20 * z + 1; 949 double xc, yc, nxc, nyc; 950 951 xc = Glyph.path_coordinate_x (Glyph.xc ()); 952 yc = Glyph.path_coordinate_y (Glyph.yc ()); 953 954 g.set_zoom (zoom); 955 956 nxc = Glyph.path_coordinate_x (Glyph.xc ()); 957 nyc = Glyph.path_coordinate_y (Glyph.yc ()); 958 959 g.view_offset_x -= nxc - xc; 960 g.view_offset_y += nyc - yc; 961 962 GlyphCanvas.redraw (); 963 }); 964 zoombar_tool.add_tool (zoom_bar); 965 966 Tool reset_zoom = new Tool ("zoom_1_1", t_("Zoom Out More")); 967 reset_zoom.select_action.connect ((self) => { 968 zoom_tool.store_current_view (); 969 glyph_canvas.get_current_display ().reset_zoom (); 970 glyph_canvas.redraw_area(0, 0, GlyphCanvas.allocation.width, GlyphCanvas.allocation.height); 971 }); 972 view_tools.add_tool (reset_zoom); 973 reset_zoom.set_tool_visibility (false); 974 975 Tool full_glyph = new Tool ("full_glyph", t_("Show full glyph")); 976 full_glyph.select_action.connect((self) => { 977 zoom_tool.store_current_view (); 978 zoom_tool.zoom_full_glyph (); 979 }); 980 view_tools.add_tool (full_glyph); 981 982 Tool zoom_boundaries = new Tool ("zoom_boundaries", t_("Fit in view")); 983 zoom_boundaries.select_action.connect((self) => { 984 zoom_tool.store_current_view (); 985 glyph_canvas.get_current_display ().zoom_max (); 986 }); 987 view_tools.add_tool (zoom_boundaries); 988 989 Tool zoom_bg = new Tool ("zoom_background_image", t_("Zoom in on background image")); 990 zoom_bg.select_action.connect((self) => { 991 if (MainWindow.get_current_glyph ().get_background_image () != null) { 992 zoom_tool.store_current_view (); 993 ZoomTool.zoom_full_background_image (); 994 glyph_canvas.redraw_area(0, 0, GlyphCanvas.allocation.width, GlyphCanvas.allocation.height); 995 } 996 }); 997 view_tools.add_tool (zoom_bg); 998 999 Tool zoom_prev = new Tool ("prev", t_("Previous view")); 1000 zoom_prev.select_action.connect((self) => { 1001 zoom_tool.previous_view (); 1002 }); 1003 view_tools.add_tool (zoom_prev); 1004 1005 Tool zoom_next = new Tool ("next", t_("Next view")); 1006 zoom_next.select_action.connect((self) => { 1007 zoom_tool.next_view (); 1008 }); 1009 view_tools.add_tool (zoom_next); 1010 zoom_next.set_tool_visibility (false); 1011 1012 // shape tools 1013 circle = new CircleTool ("circle"); 1014 circle.select_action.connect ((self) => { 1015 update_drawing_and_background_tools (self); 1016 }); 1017 shape_tools.add_tool (circle); 1018 1019 rectangle = new RectangleTool ("rectangle"); 1020 rectangle.select_action.connect ((self) => { 1021 update_drawing_and_background_tools (self); 1022 }); 1023 shape_tools.add_tool (rectangle); 1024 1025 add_expander (font_name); 1026 add_expander (draw_tools); 1027 1028 if (BirdFont.android) { 1029 add_expander (key_tools); 1030 } 1031 1032 add_expander (draw_tool_modifiers); 1033 1034 add_expander (stroke_expander); 1035 1036 add_expander (guideline_tools); 1037 add_expander (grid); 1038 add_expander (zoombar_tool); 1039 add_expander (view_tools); 1040 add_expander (shape_tools); 1041 1042 // Fixa: add_expander (trace); 1043 if (BirdFont.has_argument ("--test")) { 1044 add_expander (test_tools); 1045 } 1046 1047 draw_tools.set_persistent (true); 1048 draw_tools.set_unique (false); 1049 1050 stroke_expander.set_persistent (true); 1051 stroke_expander.set_unique (false); 1052 1053 key_tools.set_persistent (false); 1054 key_tools.set_unique (false); 1055 1056 draw_tool_modifiers.set_persistent (true); 1057 draw_tool_modifiers.set_unique (false); 1058 1059 test_tools.set_persistent (true); 1060 1061 guideline_tools.set_persistent (true); 1062 guideline_tools.set_unique (false); 1063 1064 grid.set_persistent (true); 1065 grid.set_unique (true); 1066 1067 shape_tools.set_persistent (true); 1068 shape_tools.set_unique (true); 1069 1070 // let these tools progagate events even when other tools are selected 1071 foreach (Tool t in draw_tools.tool) { 1072 t.editor_events = true; 1073 } 1074 1075 foreach (Tool t in shape_tools.tool) { 1076 t.editor_events = true; 1077 t.persistent = true; 1078 } 1079 1080 move_background.editor_events = true; 1081 cut_background.editor_events = true; 1082 move_canvas.editor_events = true; 1083 1084 move_background.persistent = true; 1085 cut_background.persistent = true; 1086 move_canvas.persistent = true; 1087 1088 // Default selection 1089 IdleSource idle = new IdleSource (); 1090 idle.set_callback (() => { 1091 Toolbox tb = MainWindow.get_toolbox (); 1092 1093 tb.reset_active_tool (); 1094 update_drawing_and_background_tools (bezier_tool); 1095 tb.select_tool (bezier_tool); 1096 tb.set_current_tool (bezier_tool); 1097 1098 set_point_type_from_preferences (); 1099 1100 if (GlyphCanvas.get_current_glyph ().get_show_help_lines ()) { 1101 help_lines.set_selected (true); 1102 help_lines.set_active (false); 1103 } 1104 1105 add_new_grid (1); 1106 add_new_grid (2); 1107 add_new_grid (4); 1108 1109 MainWindow.get_toolbox ().move (0, 0); 1110 1111 return false; 1112 }); 1113 idle.attach (null); 1114 1115 // update selelction when the user switches tab 1116 MainWindow.get_tab_bar ().signal_tab_selected.connect((tab) => { 1117 Glyph glyph; 1118 1119 if (tab.get_display () is Glyph) { 1120 glyph = (Glyph) tab.get_display (); 1121 show_bg.set_selected (glyph.get_background_visible ()); 1122 update_line_selection (glyph); 1123 } 1124 }); 1125 } 1126 1127 public static void update_stroke_settings () { 1128 bool stroke = false; 1129 Glyph g = MainWindow.get_current_glyph (); 1130 1131 foreach (Path p in g.active_paths) { 1132 if (p.stroke > 0) { 1133 stroke = true; 1134 } 1135 } 1136 1137 add_stroke.selected = stroke; 1138 StrokeTool.add_stroke = stroke; 1139 // FIXME: This is slow: Toolbox.redraw_tool_box (); 1140 } 1141 1142 void auto_trace_background () { 1143 Glyph g = MainWindow.get_current_glyph (); 1144 BackgroundImage? bg = g.get_background_image (); 1145 BackgroundImage b; 1146 PathList pl; 1147 1148 if (bg != null) { 1149 b = (!) bg; 1150 pl = b.autotrace (); 1151 foreach (Path p in pl.paths) { 1152 g.add_path (p); 1153 } 1154 } 1155 } 1156 1157 void update_line_selection (Glyph glyph) { 1158 help_lines.set_selected (glyph.get_show_help_lines ()); 1159 xheight_help_lines.set_selected (glyph.get_xheight_lines_visible ()); 1160 background_help_lines.set_selected (glyph.get_margin_lines_visible ()); 1161 } 1162 1163 public static void set_point_type_from_preferences () { 1164 string type = Preferences.get ("point_type"); 1165 if (type == "double_points") { 1166 Toolbox.select_tool_by_name ("double_points"); 1167 } else if (type == "quadratic_points") { 1168 Toolbox.select_tool_by_name ("quadratic_points"); 1169 } if (type == "cubic_points") { 1170 Toolbox.select_tool_by_name ("cubic_points"); 1171 } 1172 } 1173 1174 void hide_all_modifiers () { 1175 x_coordinate.set_tool_visibility (false); 1176 y_coordinate.set_tool_visibility (false); 1177 rotation.set_tool_visibility (false); 1178 width.set_tool_visibility (false); 1179 height.set_tool_visibility (false); 1180 skew.set_tool_visibility (false); 1181 reverse_path_tool.set_tool_visibility (false); 1182 move_layer.set_tool_visibility (false); 1183 flip_vertical.set_tool_visibility (false); 1184 flip_horizontal.set_tool_visibility (false); 1185 1186 tie_handles.set_tool_visibility (false); 1187 reflect_handle.set_tool_visibility (false); 1188 create_line.set_tool_visibility (false); 1189 close_path_tool.set_tool_visibility (false); 1190 1191 quadratic_points.set_tool_visibility (false); 1192 cubic_points.set_tool_visibility (false); 1193 double_points.set_tool_visibility (false); 1194 convert_points.set_tool_visibility (false); 1195 1196 cut_background.set_tool_visibility (false); 1197 show_bg.set_tool_visibility (false); 1198 bg_selection.set_tool_visibility (false); 1199 background_threshold.set_tool_visibility (false); 1200 background_scale.set_tool_visibility (false); 1201 high_contrast_background.set_tool_visibility (false); 1202 auto_trace_resolution.set_tool_visibility (false); 1203 auto_trace.set_tool_visibility (false); 1204 auto_trace_simplify.set_tool_visibility (false); 1205 delete_background.set_tool_visibility (false); 1206 } 1207 1208 void show_background_tool_modifiers () { 1209 draw_tool_modifiers.set_headline (t_("Background Tools")); 1210 1211 cut_background.set_tool_visibility (true); 1212 show_bg.set_tool_visibility (true); 1213 bg_selection.set_tool_visibility (true); 1214 background_threshold.set_tool_visibility (true); 1215 background_scale.set_tool_visibility (true); 1216 high_contrast_background.set_tool_visibility (true); 1217 auto_trace_resolution.set_tool_visibility (true); 1218 auto_trace.set_tool_visibility (true); 1219 auto_trace_simplify.set_tool_visibility (true); 1220 delete_background.set_tool_visibility (true); 1221 } 1222 1223 void show_point_tool_modifiers () { 1224 draw_tool_modifiers.set_headline (t_("Control Points")); 1225 1226 tie_handles.set_tool_visibility (true); 1227 reflect_handle.set_tool_visibility (true); 1228 create_line.set_tool_visibility (true); 1229 close_path_tool.set_tool_visibility (true); 1230 1231 quadratic_points.set_tool_visibility (true); 1232 cubic_points.set_tool_visibility (true); 1233 double_points.set_tool_visibility (true); 1234 convert_points.set_tool_visibility (true); 1235 1236 reverse_path_tool.set_tool_visibility (true); 1237 } 1238 1239 void show_object_tool_modifiers () { 1240 draw_tool_modifiers.set_headline (t_("Object Tools")); 1241 1242 x_coordinate.set_tool_visibility (true); 1243 y_coordinate.set_tool_visibility (true); 1244 rotation.set_tool_visibility (true); 1245 width.set_tool_visibility (true); 1246 height.set_tool_visibility (true); 1247 skew.set_tool_visibility (true); 1248 1249 reverse_path_tool.set_tool_visibility (true); 1250 move_layer.set_tool_visibility (true); 1251 flip_vertical.set_tool_visibility (true); 1252 flip_horizontal.set_tool_visibility (true); 1253 } 1254 1255 public void update_drawing_and_background_tools (Tool current_tool) { 1256 IdleSource idle = new IdleSource (); 1257 1258 idle.set_callback (() => { 1259 Glyph g = MainWindow.get_current_glyph (); 1260 1261 hide_all_modifiers (); 1262 1263 move_background.set_selected (false); 1264 cut_background.set_selected (false); 1265 1266 bezier_tool.set_selected (false); 1267 pen_tool.set_selected (false); 1268 point_tool.set_selected (false); 1269 zoom_tool.set_selected (false); 1270 move_tool.set_selected (false); 1271 resize_tool.set_selected (false); 1272 track_tool.set_selected (false); 1273 move_canvas.set_selected (false); 1274 delete_background.set_selected (false); 1275 1276 show_bg.set_selected (g.get_background_visible ()); 1277 show_bg.set_active (false); 1278 bg_selection.set_selected (false); 1279 background_scale.set_active (false); 1280 1281 rectangle.set_selected (false); 1282 circle.set_selected (false); 1283 1284 reverse_path_tool.set_selected (false); 1285 move_layer.set_selected (false); 1286 flip_vertical.set_selected (false); 1287 flip_horizontal.set_selected (false); 1288 1289 current_tool.set_selected (true); 1290 1291 if (resize_tool.is_selected () || move_tool.is_selected ()) { 1292 show_object_tool_modifiers (); 1293 } else if (bezier_tool.is_selected () 1294 || pen_tool.is_selected () 1295 || point_tool.is_selected () 1296 || track_tool.is_selected ()) { 1297 show_point_tool_modifiers (); 1298 } else if (move_background.is_selected () 1299 || cut_background.is_selected () 1300 || show_bg.is_selected () 1301 || high_contrast_background.is_selected () 1302 || auto_trace.is_selected ()) { 1303 show_background_tool_modifiers (); 1304 } 1305 1306 MainWindow.get_toolbox ().update_expanders (); 1307 Toolbox.redraw_tool_box (); 1308 1309 return false; 1310 }); 1311 1312 idle.attach (null); 1313 } 1314 1315 void update_type_selection () { 1316 IdleSource idle = new IdleSource (); 1317 1318 // Do this in idle, after the animation 1319 idle.set_callback (() => { 1320 Font f = BirdFont.get_current_font (); 1321 1322 quadratic_points.set_selected (false); 1323 cubic_points.set_selected (false); 1324 double_points.set_selected (false); 1325 1326 switch (point_type) { 1327 case PointType.QUADRATIC: 1328 quadratic_points.set_selected (true); 1329 f.settings.set_setting ("point_type", "quadratic"); 1330 break; 1331 case PointType.CUBIC: 1332 cubic_points.set_selected (true); 1333 f.settings.set_setting ("point_type", "cubic"); 1334 break; 1335 case PointType.DOUBLE_CURVE: 1336 double_points.set_selected (true); 1337 f.settings.set_setting ("point_type", "double_curve"); 1338 break; 1339 } 1340 1341 convert_points.set_selected (false); 1342 1343 Toolbox.redraw_tool_box (); 1344 return false; 1345 }); 1346 1347 idle.attach (null); 1348 } 1349 1350 public static void set_default_point_type (string type) { 1351 if (type == "quadratic") { 1352 quadratic_points.set_selected (true); 1353 point_type = PointType.QUADRATIC; 1354 } else if (type == "cubic") { 1355 cubic_points.set_selected (true); 1356 point_type = PointType.CUBIC; 1357 } else if (type == "double_curve") { 1358 double_points.set_selected (true); 1359 point_type = PointType.DOUBLE_CURVE; 1360 } 1361 } 1362 1363 public override Gee.ArrayList<Expander> get_expanders () { 1364 return expanders; 1365 } 1366 1367 /** Insert new points of this type. */ 1368 public static PointType get_selected_point_type () { 1369 return point_type; 1370 } 1371 1372 public void remove_all_grid_buttons () { 1373 grid_expander.tool.clear (); 1374 1375 GridTool.sizes.clear (); 1376 1377 MainWindow.get_toolbox ().update_expanders (); 1378 MainWindow.get_toolbox ().redraw (0, 0, Toolbox.allocation_width, Toolbox.allocation_height); 1379 } 1380 1381 public void parse_grid (string spin_button_value) { 1382 SpinButton sb = add_new_grid (); 1383 sb.set_value (spin_button_value); 1384 MainWindow.get_toolbox ().select_tool (sb); 1385 } 1386 1387 public static SpinButton add_new_grid (double size = 2) { 1388 SpinButton grid_width = new SpinButton ("grid_width", t_("Set size for grid")); 1389 Toolbox tb = MainWindow.get_toolbox (); 1390 1391 grid_width.new_value_action.connect((self) => { 1392 grid_width.select_action (grid_width); 1393 }); 1394 1395 grid_width.select_action.connect((self) => { 1396 SpinButton sb = (SpinButton) self; 1397 GridTool.set_grid_width (sb.get_value ()); 1398 GlyphCanvas.redraw (); 1399 }); 1400 1401 grid_expander.add_tool (grid_width); 1402 1403 GridTool.sizes.add (grid_width); 1404 1405 grid_width.set_value_round (size); 1406 1407 tb.update_expanders (); 1408 1409 tb.redraw (0, 0, Toolbox.allocation_width, Toolbox.allocation_height); 1410 1411 tb.select_tool (grid_width); 1412 grid_width.set_active (false); 1413 1414 return grid_width; 1415 } 1416 1417 public void remove_current_grid () { 1418 Tool grid_width; 1419 Toolbox tb = MainWindow.get_toolbox (); 1420 1421 foreach (Tool t in grid_expander.tool) { 1422 if (t.is_selected () && t is SpinButton) { 1423 GridTool.sizes.remove ((SpinButton)t); 1424 grid_expander.tool.remove (t); 1425 break; 1426 } 1427 } 1428 1429 if (grid_expander.tool.size > 0) { 1430 grid_width = grid_expander.tool.get (grid_expander.tool.size - 1); 1431 tb.select_tool (grid_width); 1432 grid_width.set_active (false); 1433 } 1434 1435 MainWindow.get_toolbox ().update_expanders (); 1436 tb.redraw (0, 0, Toolbox.allocation_width, Toolbox.allocation_height); 1437 } 1438 1439 private void add_expander (Expander e) { 1440 expanders.add (e); 1441 } 1442 1443 public override Gee.ArrayList<string> get_displays () { 1444 Gee.ArrayList<string> d = new Gee.ArrayList<string> (); 1445 d.add ("Glyph"); 1446 return d; 1447 } 1448 } 1449 1450 } 1451