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

Revisions

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