The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

OverViewItem.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/OverViewItem.vala.
Default zoom for new glyph versions
1 /* 2 Copyright (C) 2012 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 OverViewItem : GLib.Object { 21 public unichar character = '\0'; 22 public GlyphCollection? glyphs; 23 public double x; 24 public double y; 25 public bool selected = false; 26 public CharacterInfo info; 27 28 public static double DEFAULT_WIDTH = 100; 29 public static double DEFAULT_HEIGHT = 130; 30 public static double DEFAULT_MARGIN = 20; 31 32 public static double width = 100; 33 public static double height = 130; 34 public static double margin = 20; 35 36 public static double glyph_scale = 1.0; 37 38 VersionList version_menu; 39 Text icon; 40 41 public OverViewItem (GlyphCollection? glyphs, unichar character, double x, double y) { 42 this.x = x; 43 this.y = y; 44 this.character = character; 45 this.glyphs = glyphs; 46 this.info = new CharacterInfo (character, glyphs); 47 48 icon = new Text ("dropdown_menu", 17); 49 icon.load_font ("icons.bf"); 50 icon.use_cache (true); 51 52 if (glyphs != null) { 53 version_menu = new VersionList ((!) glyphs); 54 version_menu.add_glyph_item.connect ((glyph) => { 55 ((!) glyphs).insert_glyph (glyph, true); 56 }); 57 58 version_menu.signal_delete_item.connect ((glyph_index) => { 59 OverView v = MainWindow.get_overview (); 60 version_menu = new VersionList ((!) glyphs); 61 v.update_item_list (); 62 GlyphCanvas.redraw (); 63 }); 64 } else { 65 version_menu = new VersionList (new GlyphCollection (character, (!) character.to_string ())); 66 } 67 } 68 69 public string get_name () { 70 StringBuilder s; 71 72 if (glyphs != null) { 73 return ((!) glyphs).get_name (); 74 } 75 76 s = new StringBuilder (); 77 s.append_unichar (character); 78 79 return s.str; 80 } 81 82 public void set_selected (bool s) { 83 selected = s; 84 } 85 86 public static double full_width () { 87 return width + margin; 88 } 89 90 public static double full_height () { 91 return height + margin; 92 } 93 94 public bool click (uint button, double px, double py) { 95 bool a; 96 GlyphCollection g; 97 bool s = (x <= px <= x + width) && (y <= py <= y + height); 98 99 if (has_icons () && glyphs != null) { 100 g = (!) glyphs; 101 102 a = version_menu.menu_item_action (px, py); // select one item on the menu 103 if (a) { 104 return s; 105 } 106 107 version_menu.menu_icon_action (px, py); // click in the open menu 108 } 109 110 if (has_icons () && info.is_over_icon (px, py)) { 111 MainWindow.get_overview ().set_character_info (info); 112 } 113 114 return s; 115 } 116 117 public bool double_click (uint button, double px, double py) { 118 selected = (x <= px <= x + width) && (y <= py <= y + height); 119 return selected; 120 } 121 122 public bool is_on_screen (WidgetAllocation allocation) { 123 return y + height > 0 && y < allocation.height; 124 } 125 126 public void draw (WidgetAllocation allocation, Context cr) { 127 if (!is_on_screen (allocation)) { 128 return; 129 } 130 131 cr.save (); 132 Theme.color (cr, "Background 1"); 133 cr.rectangle (x, y, width, height); 134 cr.fill (); 135 cr.restore (); 136 137 cr.save (); 138 Theme.color (cr, "Overview Item Border"); 139 cr.rectangle (x, y, width, height); 140 cr.set_line_width (1); 141 cr.stroke (); 142 cr.restore (); 143 144 draw_thumbnail (cr, glyphs, x, y + height); 145 draw_caption (cr); 146 } 147 148 public void adjust_scale () { 149 double x1, x2, y1, y2, glyph_width, glyph_height, scale, gx; 150 Glyph g; 151 Font font; 152 153 if (glyphs != null) { 154 font = BirdFont.get_current_font (); 155 g = ((!) glyphs).get_current (); 156 g.boundaries (out x1, out y1, out x2, out y2); 157 158 glyph_width = x2 - x1; 159 glyph_height = y2 - y1; 160 161 if (glyph_scale == 1) { 162 // caption height is 20 163 glyph_scale = (height - 20) / (font.top_limit - font.bottom_limit); 164 } 165 166 scale = glyph_scale; 167 gx = ((width / scale) - glyph_width) / 2; 168 169 if (gx < 0) { 170 glyph_scale = 1 + 2 * gx / width; 171 } 172 } 173 } 174 175 private void draw_thumbnail (Context cr, GlyphCollection? gl, double x, double y) { 176 Glyph g; 177 Glyph? glyph; 178 Font font; 179 double gx, gy; 180 double x1, x2, y1, y2; 181 double scale_box; 182 double w, h; 183 double glyph_width, glyph_height; 184 Surface s; 185 Context c; 186 OverView o; 187 Color color = Color.black (); 188 189 w = width; 190 h = height; 191 192 scale_box = width / DEFAULT_WIDTH; 193 194 s = new Surface.similar (cr.get_target (), Content.COLOR_ALPHA, (int) w, (int) h - 20); 195 c = new Context (s); 196 197 if (gl != null) { 198 font = BirdFont.get_current_font (); 199 g = ((!) gl).get_current (); 200 201 c.save (); 202 g.boundaries (out x1, out y1, out x2, out y2); 203 204 glyph_width = x2 - x1; 205 glyph_height = y2 - y1; 206 207 gx = ((w / glyph_scale) - glyph_width) / 2; 208 gy = (h / glyph_scale) - 25 / glyph_scale; 209 210 c.save (); 211 c.scale (glyph_scale, glyph_scale); 212 213 g.add_help_lines (); 214 215 c.translate (gx - g.get_lsb () - Glyph.xc (), g.get_baseline () + gy - Glyph.yc ()); 216 217 g.draw_paths (c, color); 218 c.restore (); 219 } else { 220 c.save (); 221 Text fallback = new Text (); 222 Theme.text_color (fallback, "Overview Glyph"); 223 fallback.set_text ((!) character.to_string ()); 224 double font_size = height * 0.8; 225 fallback.set_font_size (font_size); 226 227 gx = (width - fallback.get_extent ()) / 2.0; 228 gy = height - 30; 229 fallback.set_font_size (font_size); 230 fallback.draw_at_baseline (c, gx, gy); 231 c.restore (); 232 } 233 234 cr.save (); 235 cr.set_source_surface (s, x, y - h); 236 cr.paint (); 237 cr.restore (); 238 } 239 240 public bool has_icons () { 241 return width > 50; 242 } 243 244 public void draw_caption (Context cr) { 245 StringBuilder name = new StringBuilder (); 246 Cairo.Pattern p; 247 string text; 248 Text label; 249 250 name.append_unichar (character); 251 252 cr.save (); 253 254 cr.rectangle (x + 1, y + height - 20, width - 2, 20 - 1); 255 256 if (!selected) { 257 p = new Cairo.Pattern.linear (0.0, y + height - 20, 0.0, y + height); 258 Theme.gradient (p, "Overview Item 1", "Overview Item 2"); 259 cr.set_source (p); 260 } else { 261 Theme.color (cr, "Selected Overview Item"); 262 } 263 264 cr.fill (); 265 266 if (has_icons ()) { 267 draw_menu (cr); 268 draw_character_info_icon (cr); 269 } 270 271 text = (glyphs == null) 272 ? name.str 273 : ((!) glyphs).get_current ().name; 274 275 double w = has_icons () ? width - 43 : width; 276 label = new Text (text, 17); 277 label.truncate (w); 278 label.use_cache (true); 279 280 if (selected) { 281 Theme.text_color (label, "Overview Selected Foreground"); 282 } else { 283 Theme.text_color (label, "Overview Foreground"); 284 } 285 286 label.draw_at_baseline (cr, x + 0.08 * width, y + height - 6); 287 } 288 289 private void draw_character_info_icon (Context cr) { 290 double px = x + width - 17; 291 double py = y + height - 21; 292 info.set_position (px, py); 293 info.draw_icon (cr, selected); 294 } 295 296 public void hide_menu () { 297 version_menu.menu_visible = false; 298 } 299 300 private void draw_menu (Context cr) { 301 GlyphCollection g; 302 303 if (glyphs == null) { 304 return; 305 } 306 307 if (selected) { 308 Theme.text_color (icon, "Overview Selected Foreground"); 309 } else { 310 Theme.text_color (icon, "Overview Foreground"); 311 } 312 313 icon.draw_at_top (cr, x + width - 32, y + height - 19); 314 315 version_menu.set_position (x + width - 21, y + height - 18); 316 version_menu.draw_menu (cr); 317 } 318 } 319 320 } 321