The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

AbstractMenu.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/AbstractMenu.vala.
Parse more style attributes in SVG files
1 /* 2 Copyright (C) 2014 2015 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 B; 17 18 namespace BirdFont { 19 20 /** Interface for events from native window to the current tab. */ 21 public class AbstractMenu : GLib.Object { 22 23 public bool show_menu { 24 get { 25 return menu_visibility; 26 } 27 28 set { 29 string tab_name; 30 31 menu_visibility = value; 32 current_menu = top_menu; 33 34 if (menu_visibility) { 35 tab_name = MainWindow.get_tab_bar ().get_selected_tab ().get_display ().get_name (); 36 if (tab_name == "Preview") { 37 MenuTab.select_overview (); 38 } 39 } 40 } 41 } 42 43 public bool menu_visibility = false; 44 public SubMenu top_menu; 45 46 SubMenu current_menu; 47 WidgetAllocation allocation = new WidgetAllocation (); 48 49 double width = 250 * MainWindow.units; 50 double height = 25 * MainWindow.units; 51 52 public Gee.HashMap<string, MenuItem> menu_items = new Gee.HashMap<string, MenuItem> (); 53 public Gee.ArrayList<MenuItem> sorted_menu_items = new Gee.ArrayList<MenuItem> (); 54 55 public AbstractMenu () { 56 } 57 58 public ToolItem? get_item_for_tool (Tool t) { 59 ToolItem tm; 60 61 foreach (MenuItem item in sorted_menu_items) { 62 if (item is ToolItem) { 63 tm = (ToolItem) item; 64 65 if (tm.tool == t) { 66 return tm; 67 } 68 } 69 } 70 71 return null; 72 } 73 74 public void process_key_binding_events (uint keyval) { 75 string display; 76 FontDisplay current_display = MainWindow.get_current_display (); 77 ToolItem tm; 78 unichar lower_keyval = ((unichar) keyval).tolower (); 79 80 foreach (MenuItem item in sorted_menu_items) { 81 if (item.key.tolower () == lower_keyval && item.modifiers == KeyBindings.modifier) { 82 83 display = current_display.get_name (); 84 85 if (current_display is Glyph) { 86 display = "Glyph"; 87 } 88 89 if (!current_display.needs_modifier () || item.modifiers != NONE) { 90 if (!SettingsDisplay.update_key_bindings 91 && item.in_display (display) 92 && !(item is ToolItem)) { 93 item.action (); 94 return; 95 } 96 97 if (item is ToolItem) { 98 tm = (ToolItem) item; 99 100 if (tm.in_display (display)) { 101 if (tm.tool.editor_events) { 102 MainWindow.get_toolbox ().set_current_tool (tm.tool); 103 tm.tool.select_action (tm.tool); 104 return; 105 } else { 106 tm.tool.select_action (tm.tool); 107 return; 108 } 109 } 110 } 111 } 112 } 113 } 114 } 115 116 public void load_key_bindings () { 117 File default_key_bindings = SearchPaths.find_file (null, "key_bindings.xml"); 118 File user_key_bindings = get_child (BirdFont.get_settings_directory (), "key_bindings.xml"); 119 120 if (default_key_bindings.query_exists ()) { 121 parse_key_bindings (default_key_bindings); 122 } 123 124 if (user_key_bindings.query_exists ()) { 125 parse_key_bindings (user_key_bindings); 126 } 127 } 128 129 public void parse_key_bindings (File f) { 130 string xml_data; 131 XmlParser parser; 132 133 try { 134 FileUtils.get_contents((!) f.get_path (), out xml_data); 135 parser = new XmlParser (xml_data); 136 parse_bindings (parser.get_root_tag ()); 137 } catch (GLib.Error e) { 138 warning (e.message); 139 } 140 } 141 142 public void parse_bindings (Tag tag) { 143 foreach (Tag t in tag) { 144 if (t.get_name () == "action") { 145 parse_binding (t.get_attributes ()); 146 } 147 } 148 } 149 150 public void parse_binding (Attributes attr) { 151 uint modifier = NONE; 152 unichar key = '\0'; 153 string action = ""; 154 MenuItem menu_action; 155 MenuItem? ma; 156 157 foreach (Attribute a in attr) { 158 if (a.get_name () == "key") { 159 key = a.get_content ().get_char (0); 160 } 161 162 if (a.get_name () == "ctrl" && a.get_content () == "true") { 163 modifier |= CTRL; 164 } 165 166 if (a.get_name () == "alt" && a.get_content () == "true") { 167 modifier |= ALT; 168 } 169 170 if (a.get_name () == "command" && a.get_content () == "true") { 171 modifier |= LOGO; 172 } 173 174 if (a.get_name () == "shift" && a.get_content () == "true") { 175 modifier |= SHIFT; 176 } 177 178 if (a.get_name () == "action") { 179 action = a.get_content (); 180 } 181 } 182 183 ma = menu_items.get (action); 184 if (ma != null) { 185 menu_action = (!) ma; 186 menu_action.modifiers = modifier; 187 menu_action.key = key; 188 } 189 } 190 191 public MenuItem add_menu_item (string label, string description = "", string display = "") { 192 MenuItem i = new MenuItem (label, description); 193 194 if (description != "") { 195 menu_items.set (description, i); 196 sorted_menu_items.add (i); 197 } 198 199 if (display != "") { 200 i.add_display (display); 201 } 202 203 return i; 204 } 205 206 public void button_release (int button, double ex, double ey) { 207 double y = 0; 208 double x = allocation.width - width; 209 210 if (button == 1) { 211 foreach (MenuItem item in current_menu.items) { 212 if (x <= ex < allocation.width && y <= ey <= y + height) { 213 item.action (); 214 GlyphCanvas.redraw (); 215 return; 216 } 217 218 y += height; 219 } 220 221 menu_visibility = false; 222 current_menu = (!) top_menu; 223 GlyphCanvas.redraw (); 224 } 225 } 226 227 public void add_tool_key_bindings () { 228 ToolItem tool_item; 229 foreach (ToolCollection tool_set in MainWindow.get_toolbox ().tool_sets) { 230 foreach (Expander e in tool_set.get_expanders ()) { 231 foreach (Tool t in e.tool) { 232 tool_item = new ToolItem (t); 233 if (tool_item.identifier != "" && !has_menu_item (tool_item.identifier)) { 234 menu_items.set (tool_item.identifier, tool_item); 235 sorted_menu_items.add (tool_item); 236 } 237 238 foreach (string d in tool_set.get_displays ()) { 239 tool_item.add_display (d); 240 } 241 } 242 } 243 } 244 } 245 246 public bool has_menu_item (string identifier) { 247 foreach (MenuItem mi in sorted_menu_items) { 248 if (mi.identifier == identifier) { 249 return true; 250 } 251 } 252 253 return false; 254 } 255 256 public void set_menu (SubMenu m) { 257 current_menu = m; 258 GlyphCanvas.redraw (); 259 } 260 261 public double layout_width () { 262 Text key_binding = new Text (); 263 double font_size = 17 * MainWindow.units;; 264 double w; 265 266 width = 0; 267 foreach (MenuItem item in current_menu.items) { 268 key_binding.set_text (item.get_key_bindings ()); 269 270 item.label.set_font_size (font_size); 271 key_binding.set_font_size (font_size); 272 273 w = item.label.get_extent (); 274 w += key_binding.get_extent (); 275 w += 3 * height * MainWindow.units; 276 277 if (w > width) { 278 width = w; 279 } 280 } 281 282 return width; 283 } 284 285 public void draw (WidgetAllocation allocation, Context cr) { 286 double y; 287 double x; 288 double label_x; 289 double label_y; 290 double font_size; 291 Text key_binding; 292 double binding_extent; 293 294 width = layout_width (); 295 296 key_binding = new Text (); 297 298 x = allocation.width - width; 299 y = 0; 300 font_size = 17 * MainWindow.units; 301 this.allocation = allocation; 302 303 foreach (MenuItem item in current_menu.items) { 304 cr.save (); 305 Theme.color (cr, "Menu Background"); 306 cr.rectangle (x, y, width, height); 307 cr.fill (); 308 cr.restore (); 309 310 cr.save (); 311 label_x = allocation.width - width + 0.7 * height * MainWindow.units; 312 label_y = y + font_size - 1 * MainWindow.units; 313 Theme.text_color (item.label, "Menu Foreground"); 314 item.label.draw_at_baseline (cr, label_x, label_y); 315 316 key_binding.set_text (item.get_key_bindings ()); 317 key_binding.set_font_size (font_size); 318 binding_extent = key_binding.get_extent (); 319 label_x = x + width - binding_extent - 0.6 * height * MainWindow.units; 320 key_binding.set_font_size (font_size); 321 Theme.text_color (key_binding, "Menu Foreground"); 322 key_binding.draw_at_baseline (cr, label_x, label_y); 323 324 y += height; 325 } 326 } 327 328 public void write_key_bindings () { 329 DataOutputStream os; 330 File file; 331 bool has_ctrl, has_alt, has_command, has_shift; 332 333 file = get_child (BirdFont.get_settings_directory (), "key_bindings.xml"); 334 335 try { 336 if (file.query_exists ()) { 337 file.delete (); 338 } 339 } catch (GLib.Error e) { 340 warning (e.message); 341 } 342 343 try { 344 os = new DataOutputStream (file.create (FileCreateFlags.REPLACE_DESTINATION)); 345 os.put_string ("""<?xml version="1.0" encoding="utf-8" standalone="yes"?>"""); 346 os.put_string ("\n"); 347 348 os.put_string ("<bindings>\n"); 349 350 foreach (MenuItem item in sorted_menu_items) { 351 os.put_string ("\t<action "); 352 353 os.put_string (@"key=\"$((!)item.key.to_string ())\" "); 354 355 has_ctrl = (item.modifiers & CTRL) > 0; 356 os.put_string (@"ctrl=\"$(has_ctrl.to_string ())\" "); 357 358 has_alt = (item.modifiers & ALT) > 0; 359 os.put_string (@"alt=\"$(has_alt.to_string ())\" "); 360 361 has_command = (item.modifiers & LOGO) > 0; 362 os.put_string (@"command=\"$(has_command.to_string ())\" "); 363 364 has_shift = (item.modifiers & SHIFT) > 0; 365 os.put_string (@"shift=\"$(has_shift.to_string ())\" "); 366 367 os.put_string (@"action=\"$(item.identifier)\" "); 368 369 os.put_string ("/>\n"); 370 } 371 os.put_string ("</bindings>\n"); 372 373 os.close (); 374 } catch (GLib.Error e) { 375 warning (e.message); 376 } 377 } 378 379 public void set_current_menu (SubMenu menu) { 380 current_menu = menu; 381 } 382 } 383 384 } 385