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