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