The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

VersionList.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/VersionList.vala.
Add a button for closing paths
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 using Cairo; 16 using Math; 17 18 namespace BirdFont { 19 20 public class VersionList : DropMenu { 21 public int current_version_id = -1; 22 GlyphCollection glyph_collection; 23 24 public Gee.ArrayList<Glyph> glyphs; 25 26 public VersionList (Glyph? g = null, GlyphCollection glyph_collection) { 27 base (); 28 29 this.glyph_collection = glyph_collection; 30 glyphs = new Gee.ArrayList<Glyph> (); 31 set_direction (MenuDirection.POP_UP); 32 33 MenuAction ma = add_item (t_("New version")); 34 ma.has_delete_button = false; 35 ma.action = (self) => { 36 return_if_fail (self.parent != null); 37 return_if_fail (glyphs.size > 0); 38 39 BirdFont.get_current_font ().touch (); 40 41 add_new_version (); 42 current_version_id = glyphs.get (glyphs.size - 1).version_id; 43 }; 44 45 // delete one version 46 signal_delete_item.connect ((index) => { 47 int current_version; 48 Font font = BirdFont.get_current_font (); 49 OverView over_view = MainWindow.get_overview (); 50 51 font.touch (); 52 53 index--; // first item is the add new action 54 55 // delete the entire glyph if the last remaining version is removed 56 if (glyphs.size == 1) { 57 over_view.store_undo_state (glyph_collection.copy ()); 58 font.delete_glyph (glyph_collection); 59 return; 60 } 61 62 return_if_fail (0 <= index < glyphs.size); 63 64 font.deleted_glyphs.add (glyph_collection.get_current ()); 65 66 over_view.store_undo_state (glyph_collection.copy ()); 67 glyphs.remove_at (index); 68 69 recreate_index (); 70 71 current_version = get_current_version_index (); 72 if (index == current_version) { 73 set_selected_item (get_action_no2 ()); // select the first glyph if the current glyph is deleted 74 } else if (index < current_version) { 75 return_if_fail (0 <= current_version - 1 < glyphs.size); 76 current_version_id = glyphs.get (current_version - 1).version_id; 77 } 78 }); 79 80 if (g != null) { 81 add_glyph ((!) g); 82 } 83 } 84 85 private int get_current_version_index () { 86 int i = 0; 87 foreach (Glyph g in glyphs) { 88 if (g.version_id == current_version_id) { 89 return i; 90 } 91 i++; 92 } 93 return i; 94 } 95 96 public void set_selected_version (int version_id) { 97 current_version_id = version_id; 98 update_selection (); 99 } 100 101 public Glyph get_current () { 102 Glyph? gl = null; 103 104 foreach (Glyph g in glyphs) { 105 if (g.version_id == current_version_id) { 106 return g; 107 } 108 } 109 110 if (unlikely (glyphs.size > 0)) { 111 warning (@"Can not find current glyph for id $current_version_id"); 112 gl = glyphs.get (glyphs.size - 1); 113 set_selected_version (((!) gl).version_id); 114 return (!) gl; 115 } 116 117 if (unlikely (glyphs.size == 0 && current_version_id == -1)) { 118 warning (@"No glyphs added to collection"); 119 gl = new Glyph.no_lines ("", '\0'); 120 } 121 122 return (!) gl; 123 } 124 125 public void add_new_version () { 126 Glyph g = get_current (); 127 Glyph new_version = g.copy (); 128 new_version.version_id = get_last_id () + 1; 129 add_glyph (new_version); 130 } 131 132 public int get_last_id () { 133 return_val_if_fail (glyphs.size > 0, 1); 134 return glyphs.get (glyphs.size - 1).version_id; 135 } 136 137 private void set_selected_item (MenuAction ma) { 138 int i = ma.index; 139 Glyph current_glyph; 140 Glyph g; 141 142 return_if_fail (0 <= i < glyphs.size); 143 g = glyphs.get (i); 144 145 current_version_id = g.version_id; 146 147 return_if_fail (ma.parent != null); 148 149 ((!)ma.parent).deselect_all (); 150 ma.set_selected (true); 151 152 reload_all_open_glyphs (); 153 154 if (!is_null (BirdFont.current_glyph_collection)) { 155 current_glyph = MainWindow.get_current_glyph (); 156 g.set_allocation (current_glyph.allocation); 157 g.set_default_zoom (); 158 } 159 } 160 161 /** Reload a glyph when a new version is selected. Updates the path 162 * in glyph view, not from disk but from the glyph table. 163 */ 164 void reload_all_open_glyphs () { 165 TabBar b; 166 Tab tab; 167 Tab? tn; 168 Glyph glyph; 169 Glyph updated_glyph; 170 Glyph? ug; 171 Font font = BirdFont.get_current_font (); 172 StringBuilder uni = new StringBuilder (); 173 174 if (is_null (MainWindow.get_tab_bar ())) { 175 return; 176 } 177 178 b = MainWindow.get_tab_bar (); 179 180 for (int i = 0; i < b.get_length (); i++) { 181 tn = b.get_nth (i); 182 183 if (tn == null) { 184 warning ("tab is null"); 185 return; 186 } 187 188 tab = (!) tn; 189 190 if (! (tab.get_display () is Glyph)) { 191 continue; 192 } 193 194 glyph = (Glyph) tab.get_display (); 195 uni.truncate (0); 196 uni.append_unichar (glyph.unichar_code); 197 ug = font.get_glyph (uni.str); 198 199 if (ug == null) { 200 return; 201 } 202 203 updated_glyph = (!) ug; 204 tab.set_display (updated_glyph); 205 updated_glyph.view_zoom = glyph.view_zoom; 206 updated_glyph.view_offset_x = glyph.view_offset_x; 207 updated_glyph.view_offset_y = glyph.view_offset_y; 208 } 209 } 210 211 public void add_glyph (Glyph new_version, bool selected = true) { 212 MenuAction ma; 213 int v; 214 215 v = new_version.version_id; 216 glyphs.add (new_version); 217 218 ma = add_item (t_("Version") + @" $v"); 219 ma.index = (int) glyphs.size - 1; 220 221 ma.action = (self) => { 222 Font font = BirdFont.get_current_font (); 223 set_selected_item (self); 224 font.touch (); 225 }; 226 227 if (selected) { 228 set_selected_item (ma); 229 } 230 231 update_selection (); 232 } 233 234 bool has_version (int id) { 235 foreach (Glyph g in glyphs) { 236 if (g.version_id == id) { 237 return true; 238 } 239 } 240 return false; 241 } 242 243 void update_selection () { 244 if (has_version (current_version_id)) { 245 set_selected_item (get_action_index (get_current_version_index () + 1)); // the first item is the "new version" 246 } 247 } 248 249 } 250 251 } 252