The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

Table.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
Circle boundaries heads/master
1 /* 2 Copyright (C) 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 /** Table functions. */ 21 public abstract class Table : FontDisplay { 22 23 double scroll = 0; 24 double page_height = 0; 25 Gee.ArrayList<int> column_width = new Gee.ArrayList<int> (); 26 27 public WidgetAllocation allocation = new WidgetAllocation (); 28 29 public abstract void update_rows (); 30 public abstract Gee.ArrayList<Row> get_rows (); 31 public abstract void selected_row (Row row, int column, bool delete_button); 32 33 Gee.ArrayList<Row> rows = new Gee.ArrayList<Row> (); 34 35 public override void draw (WidgetAllocation allocation, Context cr) { 36 bool color = (scroll + 1 % 2) == 0; 37 38 if (allocation.width != this.allocation.width 39 || allocation.height != this.allocation.height) { 40 this.allocation = allocation; 41 update_rows (); 42 update_scrollbar (); 43 } 44 45 layout (); 46 47 cr.save (); 48 Theme.color (cr, "Background 1"); 49 cr.rectangle (0, 0, allocation.width, allocation.height); 50 cr.fill (); 51 cr.restore (); 52 53 foreach (Row r in rows) { 54 if (scroll < r.y < scroll + allocation.height 55 || scroll < r.y + r.get_height () < scroll + allocation.height) { 56 57 if (r.is_headline) { 58 draw_headline (allocation, cr, r, r.y - scroll); 59 } else { 60 draw_row (allocation, cr, r, r.y - scroll, color, true); 61 } 62 63 color = !color; 64 } 65 } 66 } 67 68 public void layout () { 69 int width; 70 71 rows = get_rows (); 72 73 column_width.clear (); 74 75 for (int i = 0; i <= Row.MAX_COLUMNS; i++) { 76 column_width.add (0); 77 } 78 79 page_height = 0; 80 foreach (Row row in rows) { 81 return_if_fail (row.columns <= column_width.size); 82 83 for (int i = 0; i < row.columns; i++) { 84 width = (int) row.get_column (i).get_sidebearing_extent (); 85 width += (int) (10 * MainWindow.units); 86 87 if (width < 100 * MainWindow.units) { 88 width = (int) (100 * MainWindow.units); 89 } 90 91 if (width > column_width.get (i)) { 92 column_width.set (i, width); 93 } 94 } 95 96 row.y = page_height; 97 page_height += row.get_height (); 98 } 99 } 100 101 private void draw_headline (WidgetAllocation allocation, Context cr, 102 Row row, double y) { 103 104 Text t; 105 106 cr.save (); 107 Theme.color (cr, "Text Foreground"); 108 t = row.get_column (0); 109 t.widget_x = 40 * MainWindow.units; 110 t.widget_y = y + 45 * MainWindow.units; 111 t.draw (cr); 112 cr.restore (); 113 114 } 115 116 private void draw_row (WidgetAllocation allocation, Context cr, 117 Row row, double y, bool color, bool dark) { 118 119 Text t; 120 double x; 121 122 cr.save (); 123 124 if (color) { 125 Theme.color (cr, "Table Background 2"); 126 } else { 127 Theme.color (cr, "Table Background 1"); 128 } 129 130 cr.rectangle (0, y, allocation.width, 25 * MainWindow.units); 131 cr.fill (); 132 cr.restore (); 133 134 if (row.has_delete_button ()) { 135 cr.save (); 136 Theme.color (cr, "Foreground 1"); 137 cr.set_line_width (1); 138 cr.move_to (10 * MainWindow.units, y + 15 * MainWindow.units); 139 cr.line_to (15 * MainWindow.units, y + 10 * MainWindow.units); 140 cr.move_to (10 * MainWindow.units, y + 10 * MainWindow.units); 141 cr.line_to (15 * MainWindow.units, y + 15 * MainWindow.units); 142 cr.stroke (); 143 cr.restore (); 144 } 145 146 return_if_fail (row.columns <= column_width.size); 147 148 x = 40 * MainWindow.units; 149 for (int i = 0; i < row.columns; i++) { 150 cr.save (); 151 Theme.color (cr, "Foreground 1"); 152 t = row.get_column (i); 153 t.widget_x = x; 154 t.widget_y = y + 3 * MainWindow.units; 155 t.draw (cr); 156 157 x += column_width.get (i); 158 159 cr.restore (); 160 } 161 } 162 163 public override void button_release (int button, double ex, double ey) { 164 double x = 0; 165 int column = -1; 166 Row? selected = null; 167 bool over_delete = false; 168 169 if (button != 1) { 170 return; 171 } 172 173 foreach (Row r in rows) { 174 if (r.y <= ey + scroll <= r.y + r.get_height ()) { 175 176 x = 0; 177 for (int i = 0; i < r.columns; i++) { 178 return_if_fail (0 <= i < column_width.size); 179 180 if (x <= ex < x + column_width.get (i)) { 181 column = i; 182 } 183 184 x += column_width.get (i); 185 } 186 187 over_delete = (ex < 18 && r.has_delete_button ()); 188 189 if (over_delete) { 190 column = -1; 191 } 192 193 if (!r.is_headline) { 194 selected = r; 195 } 196 197 break; 198 } 199 } 200 201 if (selected != null) { 202 selected_row ((!) selected, column, over_delete); 203 } 204 205 update_scrollbar (); 206 redraw_area (0, 0, allocation.width, allocation.height); 207 } 208 209 public override bool has_scrollbar () { 210 return true; 211 } 212 213 public override void scroll_wheel (double x, double y, double pixeldelta, double dy) { 214 scroll -= dy * MainWindow.units; 215 216 if (scroll > page_height - allocation.height) { 217 scroll = page_height - allocation.height; 218 } 219 220 if (allocation.height > page_height) { 221 scroll = 0; 222 } 223 224 if (scroll < 0) { 225 scroll = 0; 226 } 227 228 update_scrollbar (); 229 redraw_area (0, 0, allocation.width, allocation.height); 230 } 231 232 public override void update_scrollbar () { 233 if (page_height == 0 || allocation.height >= page_height) { 234 MainWindow.set_scrollbar_size (0); 235 MainWindow.set_scrollbar_position (0); 236 } else { 237 MainWindow.set_scrollbar_size (allocation.height / page_height); 238 MainWindow.set_scrollbar_position (scroll / (page_height - allocation.height)); 239 } 240 } 241 242 public override void scroll_to (double percent) { 243 scroll = percent * (page_height - allocation.height); 244 245 if (scroll > page_height) { 246 scroll = (int) (page_height - allocation.height); 247 } 248 249 redraw_area (0, 0, allocation.width, allocation.height); 250 } 251 252 public override void selected_canvas () { 253 update_rows (); 254 update_scrollbar (); 255 } 256 } 257 258 } 259