The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

DescriptionDisplay.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/DescriptionDisplay.vala.
Switch keyboard focus with tab key in name and description tab
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 Math; 17 18 namespace BirdFont { 19 20 public class DescriptionDisplay : FontDisplay { 21 22 double scroll = 0; 23 double content_height = 1; 24 WidgetAllocation allocation; 25 Gee.ArrayList<Widget> focus_ring = new Gee.ArrayList<Widget> (); 26 int focus_index = 0; 27 28 Widget? keyboard_focus = null; 29 30 TextArea postscript_name; 31 TextArea name; 32 TextArea style; 33 CheckBox bold; 34 CheckBox italic; 35 TextArea weight; 36 TextArea full_name; 37 TextArea unique_id; 38 TextArea version; 39 TextArea description; 40 TextArea copyright; 41 42 Gee.ArrayList<Widget> widgets; 43 44 private static bool disable_copyright = false; 45 46 public DescriptionDisplay () { 47 double margin = 12 * MainWindow.units; 48 double label_size = 20 * MainWindow.units; 49 double label_margin = 4 * MainWindow.units; 50 Headline headline; 51 Font font = BirdFont.get_current_font (); 52 53 allocation = new WidgetAllocation (); 54 55 widgets = new Gee.ArrayList<Widget> (); 56 57 postscript_name = new LineTextArea (label_size); 58 name = new LineTextArea (label_size); 59 style = new LineTextArea (label_size); 60 weight = new LineTextArea (label_size); 61 full_name = new LineTextArea (label_size); 62 unique_id = new LineTextArea (label_size); 63 version = new LineTextArea (label_size); 64 description = new TextArea (label_size); 65 copyright = new TextArea (label_size); 66 67 headline = new Headline (t_("Name and Description")); 68 headline.margin_bottom = 20 * MainWindow.units; 69 widgets.add (headline); 70 71 widgets.add (new Text (t_("PostScript Name"), label_size, label_margin)); 72 postscript_name.margin_bottom = margin; 73 postscript_name.set_text (font.postscript_name); 74 postscript_name.text_changed.connect ((t) => { 75 font.postscript_name = t; 76 font.touch (); 77 }); 78 widgets.add (postscript_name); 79 focus_ring.add (postscript_name); 80 81 widgets.add (new Text (t_("Name"), label_size, label_margin)); 82 name.margin_bottom = margin; 83 name.set_text (font.name); 84 name.text_changed.connect ((t) => { 85 font.name = t; 86 font.touch (); 87 }); 88 widgets.add (name); 89 focus_ring.add (name); 90 91 widgets.add (new Text (t_("Style"), label_size, label_margin)); 92 style.margin_bottom = 1.5 * margin; 93 style.set_text (font.subfamily); 94 style.text_changed.connect ((t) => { 95 font.subfamily = t; 96 font.touch (); 97 }); 98 widgets.add (style); 99 focus_ring.add (style); 100 101 bold = new CheckBox (t_("Bold"), label_size); 102 bold.updated.connect ((c) => { 103 font.bold = c; 104 font.touch (); 105 }); 106 bold.checked = font.bold; 107 widgets.add (bold); 108 focus_ring.add (bold); 109 110 italic = new CheckBox (t_("Italic"), label_size); 111 italic.updated.connect ((c) => { 112 font.italic = c; 113 font.touch (); 114 }); 115 italic.checked = font.italic; 116 italic.margin_bottom = margin; 117 widgets.add (italic); 118 focus_ring.add (italic); 119 120 widgets.add (new Text (t_("Weight"), label_size, label_margin)); 121 weight.margin_bottom = margin; 122 weight.set_text (font.get_weight ()); 123 weight.text_changed.connect ((t) => { 124 font.set_weight (t); 125 font.touch (); 126 }); 127 widgets.add (weight); 128 focus_ring.add (weight); 129 130 widgets.add (new Text (t_("Full Name (Name and Style)"), label_size, label_margin)); 131 full_name.margin_bottom = margin; 132 full_name.set_text (font.full_name); 133 full_name.text_changed.connect ((t) => { 134 font.full_name = t; 135 font.touch (); 136 }); 137 widgets.add (full_name); 138 focus_ring.add (full_name); 139 140 widgets.add (new Text (t_("Unique Identifier"), label_size, label_margin)); 141 unique_id.margin_bottom = margin; 142 unique_id.set_text (font.unique_identifier); 143 unique_id.text_changed.connect ((t) => { 144 font.unique_identifier = t; 145 font.touch (); 146 }); 147 widgets.add (unique_id); 148 focus_ring.add (unique_id); 149 150 widgets.add (new Text (t_("Version"), label_size, label_margin)); 151 version.margin_bottom = margin; 152 version.set_text (font.version); 153 version.text_changed.connect ((t) => { 154 font.version = t; 155 font.touch (); 156 }); 157 widgets.add (version); 158 focus_ring.add (version); 159 160 widgets.add (new Text (t_("Description"), label_size, label_margin)); 161 description.margin_bottom = margin; 162 description.set_text (font.description); 163 description.scroll.connect (scroll_event); 164 description.text_changed.connect ((t) => { 165 font.description = t; 166 font.touch (); 167 }); 168 widgets.add (description); 169 focus_ring.add (description); 170 171 widgets.add (new Text (t_("Copyright"), label_size, label_margin)); 172 copyright.margin_bottom = margin; 173 copyright.set_text (font.copyright); 174 copyright.scroll.connect (scroll_event); 175 copyright.text_changed.connect ((t) => { 176 font.copyright = t; 177 font.touch (); 178 }); 179 copyright.set_editable (!disable_copyright); 180 widgets.add (copyright); 181 focus_ring.add (copyright); 182 183 set_focus (postscript_name); 184 } 185 186 public static void set_copyright_editable (bool t) { 187 disable_copyright = !t; 188 } 189 190 public override void draw (WidgetAllocation allocation, Context cr) { 191 this.allocation = allocation; 192 193 layout (); 194 195 // background 196 cr.save (); 197 cr.rectangle (0, 0, allocation.width, allocation.height); 198 cr.set_line_width (0); 199 200 Theme.color (cr, "Background 4"); 201 202 cr.fill (); 203 cr.stroke (); 204 cr.restore (); 205 206 foreach (Widget w in widgets) { 207 if (w.is_on_screen ()) { 208 if (w is Text) { 209 cr.save (); 210 Theme.color (cr, "Foreground 1"); 211 w.draw (cr); 212 cr.restore (); 213 } else { 214 w.draw (cr); 215 } 216 } 217 } 218 } 219 220 void layout () { 221 double y = -scroll; 222 223 foreach (Widget w in widgets) { 224 w.widget_x = 17 * MainWindow.units; 225 w.widget_y = y; 226 w.allocation = allocation; 227 228 if (w is TextArea) { 229 ((TextArea) w).layout (); 230 } 231 232 y += w.get_height () + w.margin_bottom; 233 } 234 235 content_height = y + scroll; 236 update_scrollbar (); 237 } 238 239 public void scroll_event (double p) { 240 scroll += p; 241 layout (); 242 GlyphCanvas.redraw (); 243 } 244 245 public override void key_press (uint keyval) { 246 Widget focus; 247 248 if (keyval == Key.SHIFT_TAB) { 249 focus_previous (); 250 } else if (keyval == Key.TAB) { 251 focus_next (); 252 } else if (keyboard_focus != null) { 253 focus = (!) keyboard_focus; 254 focus.key_press (keyval); 255 } 256 257 GlyphCanvas.redraw (); 258 } 259 260 void focus_previous () { 261 focus_index--; 262 263 if (focus_index < 0) { 264 focus_index = 0; 265 } 266 267 set_focus (focus_ring.get (focus_index)); 268 } 269 270 void focus_next () { 271 focus_index++; 272 273 if (focus_index >= focus_ring.size) { 274 focus_index = focus_ring.size - 1; 275 } 276 277 set_focus (focus_ring.get (focus_index)); 278 } 279 280 public override void button_press (uint button, double x, double y) { 281 Widget t; 282 Widget old; 283 CheckBox c; 284 285 foreach (Widget w in widgets) { 286 if (w.is_over (x, y)) { 287 if (w is TextArea) { 288 t = (TextArea) w; 289 if (keyboard_focus != null && (!) keyboard_focus != t) { 290 old = (!) keyboard_focus; 291 old.focus (false); 292 } 293 294 set_focus (t); 295 t.button_press (button, x, y); 296 } else if (w is CheckBox) { 297 c = (CheckBox) w; 298 c.set_checked (!c.checked); 299 } 300 } 301 } 302 303 GlyphCanvas.redraw (); 304 } 305 306 public void set_focus (Widget w) { 307 Widget old; 308 309 if (keyboard_focus != null && (!) keyboard_focus != w) { 310 old = (!) keyboard_focus; 311 old.focus (false); 312 } 313 314 keyboard_focus = w; 315 w.focus (true); 316 317 focus_index = focus_ring.index_of (w); 318 319 if (!(0 <= focus_index < focus_ring.size)) { 320 focus_index = 0; 321 } 322 } 323 324 public override void button_release (int button, double x, double y) { 325 Widget t; 326 327 if (keyboard_focus != null) { 328 t = (!) keyboard_focus; 329 set_focus (t); 330 t.button_release (button, x, y); 331 } 332 333 GlyphCanvas.redraw (); 334 } 335 336 public override void motion_notify (double x, double y) { 337 Widget t; 338 339 if (keyboard_focus != null) { 340 t = (!) keyboard_focus; 341 if (t.motion (x, y)) { 342 GlyphCanvas.redraw (); 343 } 344 } 345 } 346 347 public override string get_label () { 348 return t_("Name and Description"); 349 } 350 351 public override string get_name () { 352 return "Description"; 353 } 354 355 public override bool has_scrollbar () { 356 return true; 357 } 358 359 public override void scroll_wheel_down (double x, double y) { 360 scroll += 25 * MainWindow.units; 361 362 if (scroll + allocation.height >= content_height) { 363 scroll = content_height - allocation.height; 364 } 365 366 update_scrollbar (); 367 GlyphCanvas.redraw (); 368 } 369 370 public override void scroll_wheel_up (double x, double y) { 371 scroll -= 25 * MainWindow.units; 372 373 if (scroll < 0) { 374 scroll = 0; 375 } 376 377 update_scrollbar (); 378 GlyphCanvas.redraw (); 379 } 380 381 public override void selected_canvas () { 382 copyright.set_editable (!disable_copyright); 383 update_scrollbar (); 384 GlyphCanvas.redraw (); 385 } 386 387 public override void update_scrollbar () { 388 double h = content_height - allocation.height; 389 MainWindow.set_scrollbar_size (allocation.height / content_height); 390 MainWindow.set_scrollbar_position (scroll / h); 391 } 392 393 public override void scroll_to (double percent) { 394 double h = content_height - allocation.height; 395 scroll = percent * h; 396 GlyphCanvas.redraw (); 397 } 398 } 399 400 } 401