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 Font font; 160 double gx, gy; 161 double x1, x2, y1, y2; 162 double scale_box; 163 double w, h; 164 double glyph_width, glyph_height; 165 Surface s; 166 Context c; 167 OverView o; 168 Color color = Color.black (); 169 170 font = BirdFont.get_current_font (); 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 g = ((!) gl).get_current (); 181 } else { 182 o = MainWindow.get_overview (); 183 g = FontCache.fallback_font.get_glyph (character); 184 color = Theme.get_color ("Overview Glyph"); 185 } 186 187 g.boundaries (out x1, out y1, out x2, out y2); 188 189 glyph_width = x2 - x1; 190 glyph_height = y2 - y1; 191 192 gx = ((w / glyph_scale) - glyph_width) / 2; 193 gy = (h / glyph_scale) - 25 / glyph_scale; 194 195 c.save (); 196 c.scale (glyph_scale, glyph_scale); 197 198 g.add_help_lines (); 199 200 c.translate (gx - g.get_lsb () - Glyph.xc (), g.get_baseline () + gy - Glyph.yc ()); 201 202 g.draw_paths (c, color); 203 c.restore (); 204 205 cr.save (); 206 cr.set_source_surface (s, x, y - h); 207 cr.paint (); 208 cr.restore (); 209 } 210 211 public bool has_icons () { 212 return width > 50; 213 } 214 215 public void draw_caption (Context cr) { 216 StringBuilder name = new StringBuilder (); 217 Cairo.Pattern p; 218 string text; 219 Text label; 220 221 name.append_unichar (character); 222 223 cr.save (); 224 225 cr.rectangle (x + 1, y + height - 20, width - 2, 20 - 1); 226 227 if (!selected) { 228 p = new Cairo.Pattern.linear (0.0, y + height - 20, 0.0, y + height); 229 Theme.gradient (p, "Overview Item 1", "Overview Item 2"); 230 cr.set_source (p); 231 } else { 232 Theme.color (cr, "Selected Overview Item"); 233 } 234 235 cr.fill (); 236 237 if (has_icons ()) { 238 draw_menu (cr); 239 draw_character_info_icon (cr); 240 } 241 242 text = (glyphs == null) 243 ? name.str 244 : ((!) glyphs).get_current ().name; 245 246 double w = has_icons () ? width - 43 : width; 247 label = new Text (text, 17); 248 label.truncate (w); 249 label.use_cache (true); 250 251 if (selected) { 252 Theme.text_color (label, "Overview Selected Foreground"); 253 } else { 254 Theme.text_color (label, "Overview Foreground"); 255 } 256 257 label.draw_at_baseline (cr, x + 0.08 * width, y + height - 6); 258 } 259 260 private void draw_character_info_icon (Context cr) { 261 double px = x + width - 17; 262 double py = y + height - 21; 263 info.set_position (px, py); 264 info.draw_icon (cr, selected); 265 } 266 267 public void hide_menu () { 268 GlyphCollection g; 269 270 if (glyphs != null) { 271 g = (!) glyphs; 272 g.get_version_list ().menu_visible = false; 273 } 274 } 275 276 private void draw_menu (Context cr) { 277 GlyphCollection g; 278 DropMenu menu; 279 280 if (glyphs == null) { 281 return; 282 } 283 284 if (selected) { 285 Theme.text_color (icon, "Overview Selected Foreground"); 286 } else { 287 Theme.text_color (icon, "Overview Foreground"); 288 } 289 290 icon.draw_at_top (cr, x + width - 32, y + height - 19); 291 292 g = (!) glyphs; 293 menu = g.get_version_list (); 294 menu.draw_menu (cr); 295 menu.set_position (x + width - 21, y + height - 18); 296 } 297 } 298 299 } 300