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