The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

Expander.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/Expander.vala.
Revert "Stroke settings"
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 Expander : GLib.Object { 21 22 private static const double HEADLINE_MARGIN = 6; 23 24 public double x = 7; 25 public double y = 5; 26 public double scroll = 0; 27 28 public double w = 6; 29 public double h = 5; 30 31 public double margin = 0; 32 33 protected double opacity = 0; 34 35 protected bool active = false; 36 37 public Gee.ArrayList<Tool> tool; 38 39 bool persist = false; 40 bool unique = false; 41 42 double content_height = 0; 43 44 string? headline; 45 46 public bool visible = true; 47 48 public Expander (string? headline = null) { 49 this.headline = headline; 50 tool = new Gee.ArrayList<Tool> (); 51 } 52 53 public void set_headline (string? h) { 54 headline = h; 55 } 56 57 public double get_content_height () { 58 return content_height; 59 } 60 61 /** Returns true if tools can be used with the current canvas after 62 * they have been selectes and false if they are a commands to be executed. 63 */ 64 public bool is_persistent () { 65 return persist; 66 } 67 68 /** Returns true if all other tools in thid expander should be deselected 69 * when a tool is selected. 70 */ 71 public bool is_unique () { 72 return unique; 73 } 74 75 public void set_persistent (bool p) { 76 persist = p; 77 } 78 79 public void set_unique (bool u) { 80 unique = u; 81 } 82 83 public void update_tool_position () { 84 double scale = Toolbox.get_scale (); 85 double margin_small = 5 * scale; 86 double xt = x; 87 double yt = y + scroll + margin_small; 88 bool new_row = false; 89 bool has_visible_tools = false; 90 Tool previous; 91 bool first_row; 92 93 foreach (Tool t in tool) { 94 if (t.tool_is_visible ()) { 95 has_visible_tools = true; 96 break; 97 } 98 } 99 100 if (!has_visible_tools) { 101 content_height = 0; 102 return; 103 } 104 105 foreach (Tool t in tool) { 106 if (t is ZoomBar) { 107 t.w = Toolbox.allocation_width * scale; 108 t.h = 7 * scale; 109 } else if (t is LabelTool) { 110 t.w = Toolbox.allocation_width * scale; 111 t.h = 15 * scale; 112 } else if (t is FontName) { 113 t.w = Toolbox.allocation_width * scale; 114 t.h = 20 * scale; 115 } else if (t is KerningRange) { 116 t.w = Toolbox.allocation_width * scale; 117 t.h = 17 * scale; 118 } else { 119 t.w = 33 * scale; 120 t.h = (33 / 1.11) * scale; 121 } 122 } 123 124 if (tool.size > 0) { 125 content_height = tool.get (0).h + margin_small; 126 } else { 127 content_height = 0; 128 } 129 130 if (headline != null && tool.size > 0) { 131 yt += 17 * scale + HEADLINE_MARGIN; 132 content_height += 17 * scale + HEADLINE_MARGIN; 133 } 134 135 if (tool.size > 0) { 136 previous = tool.get (0); 137 first_row = true; 138 foreach (Tool t in tool) { 139 if (t.tool_is_visible ()) { 140 new_row = xt + t.w > Toolbox.allocation_width - 7 * scale; 141 142 if (new_row && !first_row) { 143 content_height += previous.h + margin_small; 144 xt = x; 145 yt += previous.h + 7 * scale; 146 } 147 148 t.x = xt; 149 t.y = yt; 150 151 xt += t.w + 7 * scale; 152 153 previous = t; 154 first_row = false; 155 } 156 } 157 } 158 } 159 160 public void set_scroll (double scroll) { 161 this.scroll = scroll; 162 } 163 164 public void set_offset (double ty) { 165 y = ty; 166 update_tool_position (); 167 } 168 169 public void add_tool (Tool t, int position = -1) { 170 if (position < 0) { 171 tool.add (t); 172 } else { 173 return_if_fail (position <= tool.size); 174 tool.insert (position, t); 175 } 176 177 update_tool_position (); 178 179 t.select_action.connect ((selected) => { 180 MainWindow.get_toolbox ().redraw ((int) x, (int) y, (int) w + 300, (int) (h + margin)); 181 182 if (is_unique ()) { 183 foreach (var deselected in tool) { 184 if (selected.get_id () != deselected.get_id ()) { 185 deselected.set_selected (false); 186 } 187 } 188 } 189 190 if (!selected.new_selection && selected.persistent) { 191 if (is_persistent ()) { 192 selected.set_selected (true); 193 } else { 194 selected.set_selected (false); 195 } 196 } 197 198 if (!is_persistent () && !selected.persistent) { 199 var time = new TimeoutSource(200); 200 time.set_callback(() => { 201 selected.set_selected (false); 202 MainWindow.get_toolbox ().redraw ((int) x, (int) y, (int) w + 300, (int) (h + margin)); 203 return false; 204 }); 205 time.attach(null); 206 } 207 208 selected.new_selection = false; 209 }); 210 } 211 212 public bool is_over (double xp, double yp) { 213 double yt = y + scroll + 2; 214 return yt - 7 <= yp <= yt + 7 && xp < 17; 215 } 216 217 public bool set_active (bool a) { 218 bool r = (active != a); 219 opacity = (a) ? 1 : 0; 220 active = a; 221 return r; 222 } 223 224 public void draw (int wd, int hd, Context cr) { 225 double yt = y + scroll + 2; 226 Text title; 227 228 if (tool.size > 0) { 229 if (headline != null) { 230 title = new Text (); 231 title.set_text ((!) headline); 232 title.use_cache (true); 233 Theme.text_color (title, "Text Foreground"); 234 title.set_font_size (17 * Toolbox.get_scale ()); 235 title.draw_at_baseline (cr, x, yt + HEADLINE_MARGIN + 13 * Toolbox.get_scale ()); 236 } 237 } 238 } 239 240 public void draw_content (int w, int h, Context cr) { 241 cr.save (); 242 foreach (Tool t in tool) { 243 if (t.tool_is_visible ()) { 244 t.draw (cr); 245 } 246 } 247 cr.restore (); 248 } 249 250 } 251 252 } 253