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

Revisions

View the latest version of libbirdfont/Table.vala.
Fix bugs in file dialog on windows
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, "Foreground 1"); 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 double o; 122 123 o = color ? 1 : 0.5; 124 cr.save (); 125 Theme.color_opacity (cr, "Background 10", o); 126 cr.rectangle (0, y * MainWindow.units, allocation.width, 25 * MainWindow.units); 127 cr.fill (); 128 cr.restore (); 129 130 if (row.has_delete_button ()) { 131 cr.save (); 132 Theme.color (cr, "Foreground 1"); 133 cr.set_line_width (1); 134 cr.move_to (10 * MainWindow.units, y + 15 * MainWindow.units); 135 cr.line_to (15 * MainWindow.units, y + 10 * MainWindow.units); 136 cr.move_to (10 * MainWindow.units, y + 10 * MainWindow.units); 137 cr.line_to (15 * MainWindow.units, y + 15 * MainWindow.units); 138 cr.stroke (); 139 cr.restore (); 140 } 141 142 return_if_fail (row.columns <= column_width.size); 143 144 x = 40 * MainWindow.units; 145 for (int i = 0; i < row.columns; i++) { 146 cr.save (); 147 Theme.color (cr, "Foreground 1"); 148 t = row.get_column (i); 149 t.widget_x = x; 150 t.widget_y = y + 3 * MainWindow.units; 151 t.draw (cr); 152 153 x += column_width.get (i); 154 155 cr.restore (); 156 } 157 } 158 159 public override void button_release (int button, double ex, double ey) { 160 double x = 0; 161 int column = -1; 162 Row? selected = null; 163 bool over_delete = false; 164 165 if (button != 1) { 166 return; 167 } 168 169 foreach (Row r in rows) { 170 if (r.y <= ey + scroll <= r.y + r.get_height ()) { 171 172 x = 0; 173 for (int i = 0; i < r.columns; i++) { 174 return_if_fail (0 <= i < column_width.size); 175 176 if (x <= ex < x + column_width.get (i)) { 177 column = i; 178 } 179 180 x += column_width.get (i); 181 } 182 183 over_delete = (ex < 18 && r.has_delete_button ()); 184 185 if (over_delete) { 186 column = -1; 187 } 188 189 if (!r.is_headline) { 190 selected = r; 191 } 192 193 break; 194 } 195 } 196 197 if (selected != null) { 198 selected_row ((!) selected, column, over_delete); 199 } 200 201 update_scrollbar (); 202 redraw_area (0, 0, allocation.width, allocation.height); 203 } 204 205 public override bool has_scrollbar () { 206 return true; 207 } 208 209 public override void scroll_wheel_down (double x, double y) { 210 scroll += 30; 211 212 if (scroll > page_height - allocation.height) { 213 scroll = page_height - allocation.height; 214 } 215 216 if (allocation.height > page_height) { 217 scroll = 0; 218 } 219 220 update_scrollbar (); 221 redraw_area (0, 0, allocation.width, allocation.height); 222 } 223 224 public override void scroll_wheel_up (double x, double y) { 225 scroll -= 30; 226 227 if (scroll < 0) { 228 scroll = 0; 229 } 230 231 update_scrollbar (); 232 redraw_area (0, 0, allocation.width, allocation.height); 233 } 234 235 public override void update_scrollbar () { 236 if (page_height == 0 || allocation.height >= page_height) { 237 MainWindow.set_scrollbar_size (0); 238 MainWindow.set_scrollbar_position (0); 239 } else { 240 MainWindow.set_scrollbar_size (allocation.height / page_height); 241 MainWindow.set_scrollbar_position (scroll / (page_height - allocation.height)); 242 } 243 } 244 245 public override void scroll_to (double percent) { 246 scroll = percent * (page_height - allocation.height); 247 248 if (scroll > page_height) { 249 scroll = (int) (page_height - allocation.height); 250 } 251 252 redraw_area (0, 0, allocation.width, allocation.height); 253 } 254 255 public override void selected_canvas () { 256 update_rows (); 257 update_scrollbar (); 258 } 259 } 260 261 } 262