The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

MenuTab.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/MenuTab.vala.
Suppress zoom when canvas is moving
1 /* 2 Copyright (C) 2012, 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 namespace BirdFont { 16 17 public class MenuTab : FontDisplay { 18 19 /** Ignore input events when the background thread is running. 20 * 21 * Do always check the return value of set_suppress_event when this 22 * variable is updated. 23 * 24 * This variable is used only in the gui thread. 25 */ 26 public static bool suppress_event; 27 28 /** True if the background thread is running. */ 29 public static bool background_thread; 30 31 /** A notification sent when the file has been saved. */ 32 public static SaveCallback save_callback; 33 34 /** A notification sent when the file has been loaded. */ 35 public static LoadCallback load_callback; 36 37 /** A notification sent when the file has been loaded. */ 38 public static ExportCallback export_callback; 39 40 public MenuTab () { 41 save_callback = new SaveCallback (); 42 save_callback.is_done = true; 43 44 load_callback = new LoadCallback (); 45 export_callback = new ExportCallback (); 46 47 suppress_event = false; 48 background_thread = false; 49 } 50 51 public static void set_save_callback (SaveCallback c) { 52 if (!save_callback.is_done) { 53 warning ("Prevoius save command has not finished"); 54 } 55 56 save_callback = c; 57 } 58 59 public static void start_background_thread () { 60 if (!set_suppress_event (true)) { 61 warning ("suppressed event"); 62 return; 63 } 64 65 TabBar.start_wheel (); 66 } 67 68 public static void stop_background_thread () { 69 IdleSource idle = new IdleSource (); 70 idle.set_callback (() => { 71 set_suppress_event (false); 72 TabBar.stop_wheel (); 73 GlyphCanvas.redraw (); 74 return false; 75 }); 76 idle.attach (null); 77 } 78 79 public static bool validate_metadata () { 80 Font font = BirdFont.get_current_font (); 81 string m = t_("Missing metadata in font:") + "\n "; 82 83 if (font.postscript_name == "") { 84 MainWindow.show_message (m + t_("PostScript Name")); 85 return false; 86 } 87 88 if (font.name == "") { 89 MainWindow.show_message (m + t_("Name")); 90 return false; 91 } 92 93 if (font.subfamily == "") { 94 MainWindow.show_message (m + t_("Style")); 95 return false; 96 } 97 98 if (font.full_name == "") { 99 MainWindow.show_message (m + t_("Full Name (Name and Style)")); 100 return false; 101 } 102 103 if (font.unique_identifier == "") { 104 MainWindow.show_message (m + t_("Unique Identifier")); 105 return false; 106 } 107 108 return true; 109 } 110 111 public static void export_fonts_in_background () { 112 if (suppress_event 113 || !MainWindow.native_window.can_export () 114 || !validate_metadata ()) { 115 return; 116 } 117 118 MenuTab.export_callback = new ExportCallback (); 119 MenuTab.export_callback.export_fonts_in_background (); 120 } 121 122 public static bool set_suppress_event (bool e) { 123 if (suppress_event && e) { 124 warning ("suppress_event is already set"); 125 return false; 126 } 127 background_thread = e; 128 suppress_event = e; 129 return true; 130 } 131 132 public override string get_label () { 133 return t_("Menu"); 134 } 135 136 public override string get_name () { 137 return "Menu"; 138 } 139 140 public static void select_overview () { 141 if (suppress_event) { 142 warn_if_test ("Event suppressed"); 143 return; 144 } 145 146 if (BirdFont.get_current_font ().is_empty ()) { 147 show_default_characters (); 148 } else { 149 MainWindow.get_tab_bar ().add_unique_tab (new OverView ()); 150 MainWindow.get_tab_bar ().select_tab_name ("Overview"); 151 } 152 } 153 154 public static void signal_file_exported () { 155 IdleSource idle = new IdleSource (); 156 idle.set_callback (() => { 157 export_callback.file_exported (); 158 return false; 159 }); 160 idle.attach (null); 161 } 162 163 public static void signal_file_saved () { 164 IdleSource idle = new IdleSource (); 165 idle.set_callback (() => { 166 save_callback.file_saved (); 167 return false; 168 }); 169 idle.attach (null); 170 } 171 172 public static void signal_file_loaded () { 173 IdleSource idle = new IdleSource (); 174 idle.set_callback (() => { 175 load_callback.file_loaded (); 176 MainWindow.native_window.font_loaded (); 177 return false; 178 }); 179 idle.attach (null); 180 } 181 182 public static void set_font_setting_from_tools (Font f) { 183 f.background_scale = DrawingTools.background_scale.get_display_value (); 184 185 f.grid_width.clear (); 186 187 foreach (SpinButton s in GridTool.sizes) { 188 f.grid_width.add (s.get_display_value ()); 189 } 190 } 191 192 // FIXME: background thread 193 public static void save_as_bfp () { 194 FileChooser fc = new FileChooser (); 195 196 if (suppress_event) { 197 warn_if_test ("Event suppressed"); 198 return; 199 } 200 201 if (!set_suppress_event (true)) { 202 return; 203 } 204 205 fc.file_selected.connect((fn) => { 206 Font f = BirdFont.get_current_font (); 207 208 if (fn != null) { 209 f.init_bfp ((!) fn); 210 } 211 212 set_suppress_event (false); 213 }); 214 215 MainWindow.file_chooser (t_("Save"), fc, FileChooser.SAVE); 216 } 217 218 public static void new_file () { 219 Font font; 220 SaveDialogListener dialog = new SaveDialogListener (); 221 222 if (suppress_event) { 223 warn_if_test ("Event suppressed"); 224 return; 225 } 226 227 font = BirdFont.get_current_font (); 228 229 dialog.signal_discard.connect (() => { 230 MainWindow.close_all_tabs (); 231 232 BirdFont.new_font (); 233 MainWindow.native_window.font_loaded (); 234 235 show_default_characters (); 236 237 GlyphCanvas.redraw (); 238 }); 239 240 dialog.signal_save.connect (() => { 241 MenuTab.save_callback = new SaveCallback (); 242 MenuTab.save_callback.file_saved.connect (() => { 243 dialog.signal_discard (); 244 }); 245 save_callback.save (); 246 }); 247 248 dialog.signal_cancel.connect (() => { 249 MainWindow.hide_dialog (); 250 }); 251 252 if (!font.is_modified ()) { 253 dialog.signal_discard (); 254 } else { 255 MainWindow.show_dialog (new SaveDialog (dialog)); 256 } 257 258 return; 259 } 260 261 public static void quit () { 262 if (suppress_event) { 263 warn_if_test ("Event suppressed"); 264 return; 265 } 266 267 TabContent.hide_text_input (); 268 269 SaveDialogListener dialog = new SaveDialogListener (); 270 Font font = BirdFont.get_current_font (); 271 272 Preferences.save (); 273 274 dialog.signal_discard.connect (() => { 275 ensure_main_loop_is_empty (); 276 MainWindow.native_window.quit (); 277 }); 278 279 dialog.signal_save.connect (() => { 280 MenuTab.set_save_callback (new SaveCallback ()); 281 MenuTab.save_callback.file_saved.connect (() => { 282 ensure_main_loop_is_empty (); 283 MainWindow.native_window.quit (); 284 }); 285 save_callback.save (); 286 }); 287 288 dialog.signal_cancel.connect (() => { 289 MainWindow.hide_dialog (); 290 }); 291 292 if (!font.is_modified ()) { 293 dialog.signal_discard (); 294 } else { 295 MainWindow.show_dialog (new SaveDialog (dialog)); 296 } 297 } 298 299 public static void show_description () { 300 MainWindow.get_tab_bar ().add_unique_tab (new DescriptionDisplay ()); 301 } 302 303 public static void show_kerning_context () { 304 if (suppress_event) { 305 warn_if_test ("Event suppressed"); 306 return; 307 } 308 309 KerningDisplay kd = MainWindow.get_kerning_display (); 310 MainWindow.get_tab_bar ().add_unique_tab (kd); 311 } 312 313 public static void show_spacing_tab () { 314 if (suppress_event) { 315 warn_if_test ("Event suppressed"); 316 return; 317 } 318 319 SpacingTab s = MainWindow.get_spacing_tab (); 320 MainWindow.get_tab_bar ().add_unique_tab (s); 321 } 322 323 public static void show_ligature_tab () { 324 if (suppress_event) { 325 warn_if_test ("Event suppressed"); 326 return; 327 } 328 329 LigatureList d = MainWindow.get_ligature_display (); 330 MainWindow.get_tab_bar ().add_unique_tab (d); 331 } 332 333 public static void preview () { 334 Font font = BirdFont.get_current_font (); 335 336 if (suppress_event) { 337 warn_if_test ("Event suppressed"); 338 return; 339 } 340 341 if (font.font_file == null) { 342 save_callback = new SaveCallback (); 343 save_callback.file_saved.connect (() => { 344 show_preview_tab (); 345 }); 346 save_callback.save (); 347 } else { 348 show_preview_tab (); 349 } 350 } 351 352 public static void show_preview_tab () { 353 OverWriteDialogListener dialog = new OverWriteDialogListener (); 354 TabBar tab_bar = MainWindow.get_tab_bar (); 355 FontFormat format = BirdFont.get_current_font ().format; 356 357 if (suppress_event) { 358 warn_if_test ("Event suppressed"); 359 return; 360 } 361 362 dialog.overwrite_signal.connect (() => { 363 KeyBindings.set_modifier (NONE); 364 tab_bar.add_unique_tab (new Preview (), true); 365 PreviewTools.update_preview (); 366 }); 367 368 if ((format == FontFormat.SVG || format == FontFormat.FREETYPE) && !OverWriteDialogListener.dont_ask_again) { 369 MainWindow.native_window.set_overwrite_dialog (dialog); 370 } else { 371 dialog.overwrite (); 372 } 373 } 374 375 /** Display the language selection tab. */ 376 public static void select_language () { 377 if (suppress_event) { 378 warn_if_test ("Event suppressed"); 379 return; 380 } 381 382 MainWindow.get_tab_bar ().add_unique_tab (new LanguageSelectionTab ()); 383 } 384 385 public static void use_current_glyph_as_background () { 386 if (suppress_event) { 387 warn_if_test ("Event suppressed"); 388 return; 389 } 390 391 Glyph.background_glyph = MainWindow.get_current_glyph (); 392 393 if (MainWindow.get_current_display () is OverView) { 394 Glyph.background_glyph = MainWindow.get_overview ().get_current_glyph (); 395 } 396 } 397 398 public static void reset_glyph_background () { 399 Glyph.background_glyph = null; 400 } 401 402 public static void remove_all_kerning_pairs () { 403 if (suppress_event) { 404 warn_if_test ("Event suppressed"); 405 return; 406 } 407 408 KerningClasses classes = BirdFont.get_current_font ().get_kerning_classes (); 409 classes.remove_all_pairs (); 410 KerningTools.update_kerning_classes (); 411 } 412 413 public static void list_all_kerning_pairs () { 414 if (suppress_event) { 415 warn_if_test ("Event suppressed"); 416 return; 417 } 418 419 MainWindow.get_tab_bar ().add_unique_tab (new KerningList ()); 420 } 421 422 public static void ensure_main_loop_is_empty () { 423 unowned MainContext context; 424 bool acquired; 425 426 context = MainContext.default (); 427 acquired = context.acquire (); 428 429 if (unlikely (!acquired)) { 430 warning ("Failed to acquire main loop.\n"); 431 return; 432 } 433 434 while (context.pending ()) { 435 context.iteration (true); 436 } 437 context.release (); 438 } 439 440 public static void save_as () { 441 if (MenuTab.suppress_event || !save_callback.is_done) { 442 warn_if_test ("Event suppressed"); 443 return; 444 } 445 446 MenuTab.set_save_callback (new SaveCallback ()); 447 MenuTab.save_callback.save_as(); 448 } 449 450 public static void save () { 451 if (MenuTab.suppress_event && !save_callback.is_done) { 452 warn_if_test ("Event suppressed"); 453 return; 454 } 455 456 MenuTab.set_save_callback (new SaveCallback ()); 457 MenuTab.save_callback.save (); 458 } 459 460 public static void load () { 461 if (MenuTab.suppress_event) { 462 warn_if_test ("Event suppressed"); 463 return; 464 } 465 466 MenuTab.load_callback = new LoadCallback (); 467 MenuTab.load_callback.load (); 468 } 469 470 public static void move_to_baseline () { 471 if (suppress_event) { 472 warn_if_test ("Event suppressed"); 473 return; 474 } 475 476 DrawingTools.move_tool.move_to_baseline (); 477 } 478 479 public static void show_file_dialog_tab (string title, FileChooser action) { 480 MainWindow.get_tab_bar ().add_tab (new FileDialogTab (title, action)); 481 } 482 483 public static void simplify_path () { 484 if (suppress_event) { 485 warn_if_test ("Event suppressed"); 486 return; 487 } 488 489 Task t = new Task (); 490 t.task.connect (simplify); 491 MainWindow.native_window.run_background_thread (t); 492 } 493 494 private static void simplify () { 495 Glyph g = MainWindow.get_current_glyph (); 496 Gee.ArrayList<Path> paths = new Gee.ArrayList<Path> (); 497 498 // selected objects 499 foreach (Path p in g.active_paths) { 500 paths.add (PenTool.simplify (p, false, PenTool.simplification_threshold)); 501 } 502 503 // selected segments 504 if (paths.size == 0) { 505 foreach (Path p in g.path_list) { 506 g.add_active_path (p); 507 } 508 509 foreach (Path p in g.active_paths) { 510 paths.add (PenTool.simplify (p, true, PenTool.simplification_threshold)); 511 } 512 } 513 514 g.store_undo_state (); 515 516 foreach (Path p in g.active_paths) { 517 g.path_list.remove (p); 518 } 519 520 foreach (Path p in g.active_paths) { 521 g.path_list.remove (p); 522 } 523 524 foreach (Path p in paths) { 525 g.add_path (p); 526 g.add_active_path (p); 527 } 528 529 g.active_paths.clear (); 530 g.update_view (); 531 } 532 533 public static void show_spacing_class_tab () { 534 SpacingClassTab t = MainWindow.get_spacing_class_tab (); 535 MainWindow.get_tab_bar ().add_unique_tab (t); 536 } 537 538 public static void add_ligature () { 539 TextListener listener; 540 string ligature_name = ""; 541 542 if (suppress_event) { 543 warn_if_test ("Event suppressed"); 544 return; 545 } 546 547 listener = new TextListener (t_("Name"), "", t_("Add ligature")); 548 549 listener.signal_text_input.connect ((text) => { 550 ligature_name = text; 551 }); 552 553 listener.signal_submit.connect (() => { 554 Font font = BirdFont.get_current_font (); 555 GlyphCollection? fg; 556 Glyph glyph; 557 GlyphCollection glyph_collection; 558 OverView o = MainWindow.get_overview (); 559 560 fg = font.get_glyph_collection_by_name (ligature_name); 561 562 if (fg == null) { 563 glyph_collection = new GlyphCollection ('\0', ligature_name); 564 565 glyph = new Glyph (ligature_name, '\0'); 566 glyph_collection.set_unassigned (true); 567 glyph_collection.insert_glyph (glyph, true); 568 569 font.add_glyph_collection (glyph_collection); 570 } 571 572 o.display_all_available_glyphs (); 573 o.scroll_to_glyph (ligature_name); 574 575 TabContent.hide_text_input (); 576 show_all_available_characters (); 577 }); 578 579 TabContent.show_text_input (listener); 580 } 581 582 public static void show_default_characters () { 583 MainWindow.get_tab_bar ().add_unique_tab (new OverView ()); 584 OverView o = MainWindow.get_overview (); 585 GlyphRange gr = new GlyphRange (); 586 587 if (!BirdFont.get_current_font ().initialised) { 588 MenuTab.new_file (); 589 } 590 591 DefaultCharacterSet.use_default_range (gr); 592 o.set_glyph_range (gr); 593 594 MainWindow.get_tab_bar ().select_tab_name ("Overview"); 595 } 596 597 public static void show_all_available_characters () { 598 MainWindow.get_tab_bar ().add_unique_tab (new OverView ()); 599 600 if (!BirdFont.get_current_font ().initialised) { 601 MenuTab.new_file (); 602 } 603 604 MainWindow.get_tab_bar ().select_tab_name ("Overview"); 605 OverviewTools.show_all_available_characters (); 606 } 607 608 public static void show_background_tab () { 609 BackgroundTab bt; 610 611 if (suppress_event) { 612 warn_if_test ("Event suppressed"); 613 return; 614 } 615 616 bt = BackgroundTab.get_instance (); 617 MainWindow.get_tab_bar ().add_unique_tab (bt); 618 } 619 620 public static void show_settings_tab () { 621 MainWindow.get_tab_bar ().add_unique_tab (new SettingsDisplay ()); 622 } 623 624 public static void show_guide_tab () { 625 MainWindow.get_tab_bar ().add_unique_tab (new GuideTab ()); 626 } 627 } 628 629 } 630