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