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 if (BirdFont.has_argument ("--test")) { 1035 add_expander (stroke_expander); 1036 } 1037 1038 add_expander (guideline_tools); 1039 add_expander (grid); 1040 add_expander (zoombar_tool); 1041 add_expander (view_tools); 1042 add_expander (shape_tools); 1043 1044 // Fixa: add_expander (trace); 1045 if (BirdFont.has_argument ("--test")) { 1046 add_expander (test_tools); 1047 } 1048 1049 draw_tools.set_persistent (true); 1050 draw_tools.set_unique (false); 1051 1052 stroke_expander.set_persistent (true); 1053 stroke_expander.set_unique (false); 1054 1055 key_tools.set_persistent (false); 1056 key_tools.set_unique (false); 1057 1058 draw_tool_modifiers.set_persistent (true); 1059 draw_tool_modifiers.set_unique (false); 1060 1061 test_tools.set_persistent (true); 1062 1063 guideline_tools.set_persistent (true); 1064 guideline_tools.set_unique (false); 1065 1066 grid.set_persistent (true); 1067 grid.set_unique (true); 1068 1069 shape_tools.set_persistent (true); 1070 shape_tools.set_unique (true); 1071 1072 // let these tools progagate events even when other tools are selected 1073 foreach (Tool t in draw_tools.tool) { 1074 t.editor_events = true; 1075 } 1076 1077 foreach (Tool t in shape_tools.tool) { 1078 t.editor_events = true; 1079 t.persistent = true; 1080 } 1081 1082 move_background.editor_events = true; 1083 cut_background.editor_events = true; 1084 move_canvas.editor_events = true; 1085 1086 move_background.persistent = true; 1087 cut_background.persistent = true; 1088 move_canvas.persistent = true; 1089 1090 // Default selection 1091 IdleSource idle = new IdleSource (); 1092 idle.set_callback (() => { 1093 Toolbox tb = MainWindow.get_toolbox (); 1094 1095 tb.reset_active_tool (); 1096 update_drawing_and_background_tools (bezier_tool); 1097 tb.select_tool (bezier_tool); 1098 tb.set_current_tool (bezier_tool); 1099 1100 set_point_type_from_preferences (); 1101 1102 if (GlyphCanvas.get_current_glyph ().get_show_help_lines ()) { 1103 help_lines.set_selected (true); 1104 help_lines.set_active (false); 1105 } 1106 1107 add_new_grid (1); 1108 add_new_grid (2); 1109 add_new_grid (4); 1110 1111 MainWindow.get_toolbox ().move (0, 0); 1112 1113 return false; 1114 }); 1115 idle.attach (null); 1116 1117 // update selelction when the user switches tab 1118 MainWindow.get_tab_bar ().signal_tab_selected.connect((tab) => { 1119 Glyph glyph; 1120 1121 if (tab.get_display () is Glyph) { 1122 glyph = (Glyph) tab.get_display (); 1123 show_bg.set_selected (glyph.get_background_visible ()); 1124 update_line_selection (glyph); 1125 } 1126 }); 1127 } 1128 1129 public static void update_stroke_settings () { 1130 bool stroke = false; 1131 Glyph g = MainWindow.get_current_glyph (); 1132 1133 foreach (Path p in g.active_paths) { 1134 if (p.stroke > 0) { 1135 stroke = true; 1136 } 1137 } 1138 1139 add_stroke.selected = stroke; 1140 StrokeTool.add_stroke = stroke; 1141 // FIXME: This is slow: Toolbox.redraw_tool_box (); 1142 } 1143 1144 void auto_trace_background () { 1145 Glyph g = MainWindow.get_current_glyph (); 1146 BackgroundImage? bg = g.get_background_image (); 1147 BackgroundImage b; 1148 PathList pl; 1149 1150 if (bg != null) { 1151 b = (!) bg; 1152 pl = b.autotrace (); 1153 foreach (Path p in pl.paths) { 1154 g.add_path (p); 1155 } 1156 } 1157 } 1158 1159 void update_line_selection (Glyph glyph) { 1160 help_lines.set_selected (glyph.get_show_help_lines ()); 1161 xheight_help_lines.set_selected (glyph.get_xheight_lines_visible ()); 1162 background_help_lines.set_selected (glyph.get_margin_lines_visible ()); 1163 } 1164 1165 public static void set_point_type_from_preferences () { 1166 string type = Preferences.get ("point_type"); 1167 if (type == "double_points") { 1168 Toolbox.select_tool_by_name ("double_points"); 1169 } else if (type == "quadratic_points") { 1170 Toolbox.select_tool_by_name ("quadratic_points"); 1171 } if (type == "cubic_points") { 1172 Toolbox.select_tool_by_name ("cubic_points"); 1173 } 1174 } 1175 1176 void hide_all_modifiers () { 1177 x_coordinate.set_tool_visibility (false); 1178 y_coordinate.set_tool_visibility (false); 1179 rotation.set_tool_visibility (false); 1180 width.set_tool_visibility (false); 1181 height.set_tool_visibility (false); 1182 skew.set_tool_visibility (false); 1183 reverse_path_tool.set_tool_visibility (false); 1184 move_layer.set_tool_visibility (false); 1185 flip_vertical.set_tool_visibility (false); 1186 flip_horizontal.set_tool_visibility (false); 1187 1188 tie_handles.set_tool_visibility (false); 1189 reflect_handle.set_tool_visibility (false); 1190 create_line.set_tool_visibility (false); 1191 close_path_tool.set_tool_visibility (false); 1192 1193 quadratic_points.set_tool_visibility (false); 1194 cubic_points.set_tool_visibility (false); 1195 double_points.set_tool_visibility (false); 1196 convert_points.set_tool_visibility (false); 1197 1198 cut_background.set_tool_visibility (false); 1199 show_bg.set_tool_visibility (false); 1200 bg_selection.set_tool_visibility (false); 1201 background_threshold.set_tool_visibility (false); 1202 background_scale.set_tool_visibility (false); 1203 high_contrast_background.set_tool_visibility (false); 1204 auto_trace_resolution.set_tool_visibility (false); 1205 auto_trace.set_tool_visibility (false); 1206 auto_trace_simplify.set_tool_visibility (false); 1207 delete_background.set_tool_visibility (false); 1208 } 1209 1210 void show_background_tool_modifiers () { 1211 draw_tool_modifiers.set_headline (t_("Background Tools")); 1212 1213 cut_background.set_tool_visibility (true); 1214 show_bg.set_tool_visibility (true); 1215 bg_selection.set_tool_visibility (true); 1216 background_threshold.set_tool_visibility (true); 1217 background_scale.set_tool_visibility (true); 1218 high_contrast_background.set_tool_visibility (true); 1219 auto_trace_resolution.set_tool_visibility (true); 1220 auto_trace.set_tool_visibility (true); 1221 auto_trace_simplify.set_tool_visibility (true); 1222 delete_background.set_tool_visibility (true); 1223 } 1224 1225 void show_point_tool_modifiers () { 1226 draw_tool_modifiers.set_headline (t_("Control Points")); 1227 1228 tie_handles.set_tool_visibility (true); 1229 reflect_handle.set_tool_visibility (true); 1230 create_line.set_tool_visibility (true); 1231 close_path_tool.set_tool_visibility (true); 1232 1233 quadratic_points.set_tool_visibility (true); 1234 cubic_points.set_tool_visibility (true); 1235 double_points.set_tool_visibility (true); 1236 convert_points.set_tool_visibility (true); 1237 1238 reverse_path_tool.set_tool_visibility (true); 1239 } 1240 1241 void show_object_tool_modifiers () { 1242 draw_tool_modifiers.set_headline (t_("Object Tools")); 1243 1244 x_coordinate.set_tool_visibility (true); 1245 y_coordinate.set_tool_visibility (true); 1246 rotation.set_tool_visibility (true); 1247 width.set_tool_visibility (true); 1248 height.set_tool_visibility (true); 1249 skew.set_tool_visibility (true); 1250 1251 reverse_path_tool.set_tool_visibility (true); 1252 move_layer.set_tool_visibility (true); 1253 flip_vertical.set_tool_visibility (true); 1254 flip_horizontal.set_tool_visibility (true); 1255 } 1256 1257 public void update_drawing_and_background_tools (Tool current_tool) { 1258 IdleSource idle = new IdleSource (); 1259 1260 idle.set_callback (() => { 1261 Glyph g = MainWindow.get_current_glyph (); 1262 1263 hide_all_modifiers (); 1264 1265 move_background.set_selected (false); 1266 cut_background.set_selected (false); 1267 1268 bezier_tool.set_selected (false); 1269 pen_tool.set_selected (false); 1270 point_tool.set_selected (false); 1271 zoom_tool.set_selected (false); 1272 move_tool.set_selected (false); 1273 resize_tool.set_selected (false); 1274 track_tool.set_selected (false); 1275 move_canvas.set_selected (false); 1276 delete_background.set_selected (false); 1277 1278 show_bg.set_selected (g.get_background_visible ()); 1279 show_bg.set_active (false); 1280 bg_selection.set_selected (false); 1281 background_scale.set_active (false); 1282 1283 rectangle.set_selected (false); 1284 circle.set_selected (false); 1285 1286 reverse_path_tool.set_selected (false); 1287 move_layer.set_selected (false); 1288 flip_vertical.set_selected (false); 1289 flip_horizontal.set_selected (false); 1290 1291 current_tool.set_selected (true); 1292 1293 if (resize_tool.is_selected () || move_tool.is_selected ()) { 1294 show_object_tool_modifiers (); 1295 } else if (bezier_tool.is_selected () 1296 || pen_tool.is_selected () 1297 || point_tool.is_selected () 1298 || track_tool.is_selected ()) { 1299 show_point_tool_modifiers (); 1300 } else if (move_background.is_selected () 1301 || cut_background.is_selected () 1302 || show_bg.is_selected () 1303 || high_contrast_background.is_selected () 1304 || auto_trace.is_selected ()) { 1305 show_background_tool_modifiers (); 1306 } 1307 1308 MainWindow.get_toolbox ().update_expanders (); 1309 Toolbox.redraw_tool_box (); 1310 1311 return false; 1312 }); 1313 1314 idle.attach (null); 1315 } 1316 1317 void update_type_selection () { 1318 IdleSource idle = new IdleSource (); 1319 1320 // Do this in idle, after the animation 1321 idle.set_callback (() => { 1322 Font f = BirdFont.get_current_font (); 1323 1324 quadratic_points.set_selected (false); 1325 cubic_points.set_selected (false); 1326 double_points.set_selected (false); 1327 1328 switch (point_type) { 1329 case PointType.QUADRATIC: 1330 quadratic_points.set_selected (true); 1331 f.settings.set_setting ("point_type", "quadratic"); 1332 break; 1333 case PointType.CUBIC: 1334 cubic_points.set_selected (true); 1335 f.settings.set_setting ("point_type", "cubic"); 1336 break; 1337 case PointType.DOUBLE_CURVE: 1338 double_points.set_selected (true); 1339 f.settings.set_setting ("point_type", "double_curve"); 1340 break; 1341 } 1342 1343 convert_points.set_selected (false); 1344 1345 Toolbox.redraw_tool_box (); 1346 return false; 1347 }); 1348 1349 idle.attach (null); 1350 } 1351 1352 public static void set_default_point_type (string type) { 1353 if (type == "quadratic") { 1354 quadratic_points.set_selected (true); 1355 point_type = PointType.QUADRATIC; 1356 } else if (type == "cubic") { 1357 cubic_points.set_selected (true); 1358 point_type = PointType.CUBIC; 1359 } else if (type == "double_curve") { 1360 double_points.set_selected (true); 1361 point_type = PointType.DOUBLE_CURVE; 1362 } 1363 } 1364 1365 public override Gee.ArrayList<Expander> get_expanders () { 1366 return expanders; 1367 } 1368 1369 /** Insert new points of this type. */ 1370 public static PointType get_selected_point_type () { 1371 return point_type; 1372 } 1373 1374 public void remove_all_grid_buttons () { 1375 grid_expander.tool.clear (); 1376 1377 GridTool.sizes.clear (); 1378 1379 MainWindow.get_toolbox ().update_expanders (); 1380 MainWindow.get_toolbox ().redraw (0, 0, Toolbox.allocation_width, Toolbox.allocation_height); 1381 } 1382 1383 public void parse_grid (string spin_button_value) { 1384 SpinButton sb = add_new_grid (); 1385 sb.set_value (spin_button_value); 1386 MainWindow.get_toolbox ().select_tool (sb); 1387 } 1388 1389 public static SpinButton add_new_grid (double size = 2) { 1390 SpinButton grid_width = new SpinButton ("grid_width", t_("Set size for grid")); 1391 Toolbox tb = MainWindow.get_toolbox (); 1392 1393 grid_width.new_value_action.connect((self) => { 1394 grid_width.select_action (grid_width); 1395 }); 1396 1397 grid_width.select_action.connect((self) => { 1398 SpinButton sb = (SpinButton) self; 1399 GridTool.set_grid_width (sb.get_value ()); 1400 GlyphCanvas.redraw (); 1401 }); 1402 1403 grid_expander.add_tool (grid_width); 1404 1405 GridTool.sizes.add (grid_width); 1406 1407 grid_width.set_value_round (size); 1408 1409 tb.update_expanders (); 1410 1411 tb.redraw (0, 0, Toolbox.allocation_width, Toolbox.allocation_height); 1412 1413 tb.select_tool (grid_width); 1414 grid_width.set_active (false); 1415 1416 return grid_width; 1417 } 1418 1419 public void remove_current_grid () { 1420 Tool grid_width; 1421 Toolbox tb = MainWindow.get_toolbox (); 1422 1423 foreach (Tool t in grid_expander.tool) { 1424 if (t.is_selected () && t is SpinButton) { 1425 GridTool.sizes.remove ((SpinButton)t); 1426 grid_expander.tool.remove (t); 1427 break; 1428 } 1429 } 1430 1431 if (grid_expander.tool.size > 0) { 1432 grid_width = grid_expander.tool.get (grid_expander.tool.size - 1); 1433 tb.select_tool (grid_width); 1434 grid_width.set_active (false); 1435 } 1436 1437 MainWindow.get_toolbox ().update_expanders (); 1438 tb.redraw (0, 0, Toolbox.allocation_width, Toolbox.allocation_height); 1439 } 1440 1441 private void add_expander (Expander e) { 1442 expanders.add (e); 1443 } 1444 1445 public override Gee.ArrayList<string> get_displays () { 1446 Gee.ArrayList<string> d = new Gee.ArrayList<string> (); 1447 d.add ("Glyph"); 1448 return d; 1449 } 1450 } 1451 1452 } 1453