The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

TableLayout.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
Add *nix as OS tag heads/master
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 TableLayout : FontDisplay { 21 22 public double scroll = 0; 23 public double content_height = 1; 24 public WidgetAllocation allocation = new WidgetAllocation (); 25 public Gee.ArrayList<Widget> widgets = new Gee.ArrayList<Widget> (); 26 public Gee.ArrayList<Widget> focus_ring = new Gee.ArrayList<Widget> (); 27 public int focus_index = 0; 28 bool ignore_input = true; 29 30 public Widget? keyboard_focus = null; 31 32 public TableLayout () { 33 } 34 35 public override void draw (WidgetAllocation allocation, Context cr) { 36 this.allocation = allocation; 37 38 layout (); 39 40 // background 41 cr.save (); 42 cr.rectangle (0, 0, allocation.width, allocation.height); 43 cr.set_line_width (0); 44 45 Theme.color (cr, "Default Background"); 46 47 cr.fill (); 48 cr.stroke (); 49 cr.restore (); 50 51 foreach (Widget w in widgets) { 52 if (w.is_on_screen ()) { 53 if (w is Text) { 54 cr.save (); 55 Theme.color (cr, "Foreground 1"); 56 w.draw (cr); 57 cr.restore (); 58 } else { 59 w.draw (cr); 60 } 61 } 62 } 63 } 64 65 void layout () { 66 double y = -scroll; 67 68 foreach (Widget w in widgets) { 69 w.widget_x = 17 * MainWindow.units; 70 w.widget_y = y; 71 w.allocation = allocation; 72 73 if (w is TextArea) { 74 ((TextArea) w).layout (); 75 } 76 77 y += w.get_height () + w.margin_bottom; 78 } 79 80 content_height = y + scroll; 81 update_scrollbar (); 82 } 83 84 public void scroll_event (double p) { 85 scroll += p; 86 layout (); 87 GlyphCanvas.redraw (); 88 } 89 90 public override void key_press (uint keyval) { 91 Widget focus; 92 93 if (keyval == Key.SHIFT_TAB) { 94 focus_previous (); 95 } else if (keyval == Key.TAB) { 96 focus_next (); 97 } else if (keyboard_focus != null) { 98 focus = (!) keyboard_focus; 99 focus.key_press (keyval); 100 } 101 102 GlyphCanvas.redraw (); 103 } 104 105 void focus_previous () { 106 focus_index--; 107 108 if (focus_index < 0) { 109 focus_index = 0; 110 } 111 112 set_focus (focus_ring.get (focus_index)); 113 } 114 115 void focus_next () { 116 focus_index++; 117 118 if (focus_index >= focus_ring.size) { 119 focus_index = focus_ring.size - 1; 120 } 121 122 set_focus (focus_ring.get (focus_index)); 123 } 124 125 public override void button_press (uint button, double x, double y) { 126 Widget t; 127 Widget old; 128 CheckBox c; 129 130 if (ignore_input) { 131 printd (@"Ignoring extra clicks."); 132 return; 133 } 134 135 foreach (Widget w in widgets) { 136 if (w.is_over (x, y)) { 137 if (w is TextArea) { 138 t = (TextArea) w; 139 if (keyboard_focus != null && (!) keyboard_focus != t) { 140 old = (!) keyboard_focus; 141 old.focus (false); 142 } 143 144 set_focus (t); 145 t.button_press (button, x, y); 146 } else if (w is CheckBox) { 147 c = (CheckBox) w; 148 c.set_checked (!c.checked); 149 } else { 150 w.button_press (button, x, y); 151 } 152 } 153 } 154 155 GlyphCanvas.redraw (); 156 } 157 158 public void set_focus (Widget w) { 159 Widget old; 160 161 if (keyboard_focus != null && (!) keyboard_focus != w) { 162 old = (!) keyboard_focus; 163 old.focus (false); 164 } 165 166 keyboard_focus = w; 167 w.focus (true); 168 169 focus_index = focus_ring.index_of (w); 170 171 if (!(0 <= focus_index < focus_ring.size)) { 172 focus_index = 0; 173 } 174 175 update_scrollbar (); 176 GlyphCanvas.redraw (); 177 } 178 179 public override void button_release (int button, double x, double y) { 180 Widget t; 181 182 if (ignore_input) { 183 printd (@"Ignoring extra clicks."); 184 return; 185 } 186 187 if (keyboard_focus != null) { 188 t = (!) keyboard_focus; 189 set_focus (t); 190 t.button_release (button, x, y); 191 } 192 193 foreach (Widget w in widgets) { 194 if (w.is_over (x, y)) { 195 w.button_release (button, x, y); 196 } 197 } 198 199 GlyphCanvas.redraw (); 200 } 201 202 public override void motion_notify (double x, double y) { 203 Widget t; 204 205 if (keyboard_focus != null) { 206 t = (!) keyboard_focus; 207 if (t.motion (x, y)) { 208 GlyphCanvas.redraw (); 209 } 210 } 211 } 212 213 public override string get_label () { 214 return t_("Name and Description"); 215 } 216 217 public override string get_name () { 218 return "Description"; 219 } 220 221 public override bool has_scrollbar () { 222 return true; 223 } 224 225 public override void scroll_wheel (double x, double y, double pixeldelta, double dy) { 226 scroll -= dy * MainWindow.units; 227 228 if (scroll + allocation.height >= content_height) { 229 scroll = content_height - allocation.height; 230 231 if (scroll < 0) { 232 scroll = 0; 233 } 234 } 235 236 if (scroll < 0) { 237 scroll = 0; 238 } 239 240 update_scrollbar (); 241 GlyphCanvas.redraw (); 242 } 243 244 public override void selected_canvas () { 245 ignore_input = true; 246 247 TimeoutSource input_delay = new TimeoutSource (250); 248 input_delay.set_callback(() => { 249 ignore_input = false; 250 return false; 251 }); 252 input_delay.attach (null); 253 254 KeyBindings.set_require_modifier (true); 255 update_scrollbar (); 256 GlyphCanvas.redraw (); 257 } 258 259 public override void update_scrollbar () { 260 double h = content_height - allocation.height; 261 MainWindow.set_scrollbar_size (allocation.height / content_height); 262 MainWindow.set_scrollbar_position (scroll / h); 263 } 264 265 public override void scroll_to (double percent) { 266 double h = content_height - allocation.height; 267 scroll = percent * h; 268 GlyphCanvas.redraw (); 269 } 270 271 public override bool needs_modifier () { 272 return true; 273 } 274 275 public override void double_click (uint button, double x, double y) { 276 Widget t; 277 278 if (ignore_input) { 279 printd (@"Ignoring extra clicks."); 280 return; 281 } 282 283 if (keyboard_focus != null) { 284 t = (!) keyboard_focus; 285 set_focus (t); 286 t.double_click (button, x, y); 287 } 288 289 foreach (Widget w in widgets) { 290 if (w.is_over (x, y)) { 291 w.double_click (button, x, y); 292 } 293 } 294 295 GlyphCanvas.redraw (); 296 } 297 } 298 299 } 300