The Birdfont Source Code


All Repositories / birdfont.git / blob – RSS feed

Theme.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/Theme.vala.
More color settings
1 /* 2 Copyright (C) 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 Bird; 16 using Cairo; 17 18 namespace BirdFont { 19 20 public class Theme : GLib.Object { 21 22 static Gee.HashMap<string, Color> colors; 23 public static Gee.ArrayList<string> color_list; 24 public static Gee.ArrayList<string> themes; 25 public static string current_theme; 26 27 public static void text_color (Text text, string name) { 28 Color c; 29 30 if (unlikely (!colors.has_key (name))) { 31 warning (@"Theme does not have a color for $name"); 32 return; 33 } 34 35 c = colors.get (name); 36 text.set_source_rgba (c.r, c.g, c.b, c.a); 37 } 38 39 public static void color (Context cr, string name) { 40 Color c; 41 42 if (unlikely (!colors.has_key (name))) { 43 warning (@"Theme does not have a color for $name"); 44 return; 45 } 46 47 c = colors.get (name); 48 cr.set_source_rgba (c.r, c.g, c.b, c.a); 49 } 50 51 public static void color_opacity (Context cr, string name, double opacity) { 52 Color c; 53 54 if (unlikely (!colors.has_key (name))) { 55 warning (@"Theme does not have a color for $name"); 56 return; 57 } 58 59 c = colors.get (name); 60 cr.set_source_rgba (c.r, c.g, c.b, opacity); 61 } 62 63 public static void text_color_opacity (Text text, string name, double opacity) { 64 Color c; 65 66 if (unlikely (!colors.has_key (name))) { 67 warning (@"Theme does not have a color for $name"); 68 return; 69 } 70 71 c = colors.get (name); 72 text.set_source_rgba (c.r, c.g, c.b, opacity); 73 } 74 75 public static Color get_color (string name) { 76 Color c; 77 78 if (unlikely (!colors.has_key (name))) { 79 warning (@"Theme does not have a color for $name"); 80 return new Color (0, 0, 0, 1); 81 } 82 83 return colors.get (name); 84 } 85 86 public static void set_default_colors () { 87 current_theme = ""; 88 89 color_list = new Gee.ArrayList<string> (); 90 colors = new Gee.HashMap<string, Color> (); 91 themes = new Gee.ArrayList<string> (); 92 93 Theme.set_default_color ("Stroke Color", 0, 0, 0, 1); 94 Theme.set_default_color ("Handle Color", 0, 0, 0, 1); 95 Theme.set_default_color ("Fill Color", 0.5, 0.5, 0.5, 1); 96 97 Theme.set_default_color ("Background 1", 1, 1, 1, 1); 98 Theme.set_default_color ("Background 2", 101 / 255.0, 108 / 255.0, 116 / 255.0, 1); 99 Theme.set_default_color ("Background 3", 38 / 255.0, 39 / 255.0, 43 / 255.0, 1); 100 Theme.set_default_color ("Background 4", 51 / 255.0, 54 / 255.0, 59 / 255.0, 1); 101 Theme.set_default_color ("Background 5", 0.3, 0.3, 0.3, 1); 102 Theme.set_default_color ("Background 6", 224/255.0, 224/255.0, 224/255.0, 1); 103 Theme.set_default_color ("Background 7", 56 / 255.0, 59 / 255.0, 65 / 255.0, 1); 104 Theme.set_default_color ("Background 8", 55/255.0, 55/255.0, 55/255.0, 1); 105 Theme.set_default_color ("Background 9", 72/255.0, 72/255.0, 72/255.0, 1); 106 107 Theme.set_default_color ("Foreground 1", 0, 0, 0, 1); 108 Theme.set_default_color ("Foreground 2", 101 / 255.0, 108 / 255.0, 116 / 255.0, 1); 109 Theme.set_default_color ("Foreground 3", 26 / 255.0, 30 / 255.0, 32 / 255.0, 1); 110 Theme.set_default_color ("Foreground 4", 40 / 255.0, 57 / 255.0, 65 / 255.0, 1); 111 Theme.set_default_color ("Foreground 5", 70 / 255.0, 77 / 255.0, 83 / 255.0, 1); 112 Theme.set_default_color ("Foreground Inverted", 1, 1, 1, 1); 113 114 Theme.set_default_color ("Highlighted 1", 234 / 255.0, 77 / 255.0, 26 / 255.0, 1); 115 116 Theme.set_default_color ("Highlighted Guide", 0, 0, 0.3, 1); 117 Theme.set_default_color ("Guide 1", 0.7, 0.7, 0.8, 1); 118 Theme.set_default_color ("Guide 2", 0.7, 0, 0, 0.5); 119 Theme.set_default_color ("Guide 3", 120 / 255.0, 68 / 255.0, 120 / 255.0, 120 / 255.0); 120 121 Theme.set_default_color ("Grid",0.2, 0.6, 0.2, 0.2); 122 123 Theme.set_default_color ("Background Glyph", 0.2, 0.2, 0.2, 0.5); 124 125 Theme.set_default_color ("Tool Border 1", 38 / 255.0, 39 / 255.0, 43 / 255.0, 1); 126 Theme.set_default_color ("Tool Background 1", 14 / 255.0, 16 / 255.0, 17 / 255.0, 1); 127 128 Theme.set_default_color ("Tool Border 2", 38 / 255.0, 39 / 255.0, 43 / 255.0, 1); 129 Theme.set_default_color ("Tool Background 2", 26 / 255.0, 30 / 255.0, 32 / 255.0, 1); 130 131 Theme.set_default_color ("Tool Border 3", 38 / 255.0, 39 / 255.0, 43 / 255.0, 1); 132 Theme.set_default_color ("Tool Background 3", 44 / 255.0, 47 / 255.0, 51 / 255.0, 1); 133 134 Theme.set_default_color ("Tool Border 4", 38 / 255.0, 39 / 255.0, 43 / 255.0, 1); 135 Theme.set_default_color ("Tool Background 4", 33 / 255.0, 36 / 255.0, 39 / 255.0, 1); 136 137 Theme.set_default_color ("Button Foreground", 101 / 255.0, 108 / 255.0, 116 / 255.0, 1); 138 139 N_("Stroke Color"); 140 N_("Handle Color"); 141 N_("Fill Color"); 142 143 N_("Background 1"); 144 N_("Background 2"); 145 N_("Background 3"); 146 N_("Background 4"); 147 N_("Background 5"); 148 N_("Background 6"); 149 N_("Background 7"); 150 N_("Background 8"); 151 N_("Background 9"); 152 153 N_("Foreground 1"); 154 N_("Foreground 2"); 155 N_("Foreground 3"); 156 N_("Foreground 4"); 157 N_("Foreground 5"); 158 N_("Foreground Inverted"); 159 160 N_("Highlighted 1"); 161 N_("Highlighted Guide"); 162 163 N_("Grid"); 164 165 N_("Guide 1"); 166 N_("Guide 2"); 167 N_("Guide 3"); 168 169 N_("Tool Border 1"); 170 N_("Tool Background 1"); 171 N_("Tool Border 2"); 172 N_("Tool Background 2"); 173 N_("Tool Border 3"); 174 N_("Tool Background 3"); 175 N_("Tool Border 4"); 176 N_("Tool Background 4"); 177 178 N_("Button Foreground"); 179 180 add_theme_files (); 181 } 182 183 static void add_theme_files () { 184 FileEnumerator enumerator; 185 FileInfo? file_info; 186 string file_name; 187 File dir; 188 189 dir = BirdFont.get_settings_directory (); 190 191 themes.clear (); 192 themes.add ("default.theme"); 193 themes.add ("high_contrast.theme"); 194 195 try { 196 enumerator = dir.enumerate_children (FileAttribute.STANDARD_NAME, 0); 197 while ((file_info = enumerator.next_file ()) != null) { 198 file_name = ((!) file_info).get_name (); 199 200 if (file_name.has_suffix (".theme")) { 201 themes.add (file_name); 202 } 203 } 204 } catch (Error e) { 205 warning (e.message); 206 } 207 } 208 209 public static void set_default_color (string name, double r, double g, double b, double a) { 210 color_list.add (name); 211 colors.set (name, new Color (r, g, b, a)); 212 write_theme (); // FIXME: don't overwrite color 213 } 214 215 public static void save_color (string name, double r, double g, double b, double a) { 216 colors.set (name, new Color (r, g, b, a)); 217 write_theme (); 218 } 219 220 public static void load_theme (string theme_file) { 221 File default_theme; 222 File user_theme; 223 224 user_theme = get_child (BirdFont.get_settings_directory (), theme_file); 225 if (user_theme.query_exists ()) { 226 current_theme = theme_file; 227 parse_theme (user_theme); 228 return; 229 } 230 231 default_theme = SearchPaths.find_file (null, theme_file); 232 if (default_theme.query_exists ()) { 233 current_theme = theme_file; 234 parse_theme (default_theme); 235 return; 236 } 237 238 warning (@"Theme not found: $theme_file"); 239 } 240 241 public static void write_theme () { 242 DataOutputStream os; 243 File file; 244 int i; 245 string base_name; 246 247 if (current_theme == "") { 248 warning ("No name for theme."); 249 return; 250 } 251 252 if (current_theme == "default.theme" || current_theme == "high_contrast.theme") { 253 current_theme = "custom.theme"; 254 255 file = get_child (BirdFont.get_settings_directory (), current_theme); 256 i = 2; 257 base_name = "custom"; 258 while (file.query_exists ()) { 259 current_theme = @"$(base_name)_theme_$(i).theme"; 260 file = get_child (BirdFont.get_settings_directory (), current_theme); 261 i++; 262 } 263 } 264 265 file = get_child (BirdFont.get_settings_directory (), current_theme); 266 267 try { 268 if (file.query_exists ()) { 269 file.delete (); 270 } 271 } catch (GLib.Error e) { 272 warning (e.message); 273 } 274 275 try { 276 os = new DataOutputStream (file.create (FileCreateFlags.REPLACE_DESTINATION)); 277 os.put_string ("""<?xml version="1.0" encoding="utf-8" standalone="yes"?>"""); 278 os.put_string ("\n"); 279 280 os.put_string ("<theme>\n"); 281 foreach (string name in colors.keys) { 282 Color color = colors.get (name); 283 284 os.put_string ("\t<color "); 285 286 os.put_string (@"name=\"$(Markup.escape_text (name))\" "); 287 os.put_string (@"red=\"$(color.r)\" "); 288 os.put_string (@"green=\"$(color.g)\" "); 289 os.put_string (@"blue=\"$(color.b)\" "); 290 os.put_string (@"alpha=\"$(color.a)\""); 291 292 os.put_string ("/>\n"); 293 } 294 os.put_string ("</theme>\n"); 295 296 os.close (); 297 } catch (GLib.Error e) { 298 warning (e.message); 299 } 300 301 add_theme_files (); 302 } 303 304 static void parse_theme (File f) { 305 string xml_data; 306 XmlParser parser; 307 308 try { 309 FileUtils.get_contents((!) f.get_path (), out xml_data); 310 parser = new XmlParser (xml_data); 311 parse_colors (parser.get_root_tag ()); 312 } catch (GLib.Error e) { 313 warning (e.message); 314 } 315 } 316 317 static void parse_colors (Tag tag) { 318 foreach (Tag t in tag) { 319 if (t.get_name () == "color") { 320 parse_color (t.get_attributes ()); 321 } 322 } 323 } 324 325 static void parse_color (Attributes attributes) { 326 string name = ""; 327 double r = 0; 328 double g = 0; 329 double b = 0; 330 double a = 1; 331 332 foreach (Attribute attr in attributes) { 333 if (attr.get_name () == "name") { 334 name = attr.get_content (); 335 } 336 337 if (attr.get_name () == "red") { 338 r = double.parse (attr.get_content ()); 339 } 340 341 if (attr.get_name () == "green") { 342 g = double.parse (attr.get_content ()); 343 } 344 345 if (attr.get_name () == "blue") { 346 b = double.parse (attr.get_content ()); 347 } 348 349 if (attr.get_name () == "alpha") { 350 a = double.parse (attr.get_content ()); 351 } 352 } 353 354 colors.set (name, new Color (r, g, b, a)); 355 } 356 357 public static void add_new_theme (SettingsDisplay d) { 358 TextListener listener; 359 360 listener = new TextListener (t_("New theme"), "", t_("Set")); 361 362 listener.signal_text_input.connect ((text) => { 363 if (text != "") { 364 current_theme = text + ".theme"; 365 themes.add (current_theme); 366 } 367 }); 368 369 listener.signal_submit.connect (() => { 370 TabContent.hide_text_input (); 371 write_theme (); 372 d.create_setting_items (); 373 }); 374 375 TabContent.show_text_input (listener); 376 } 377 } 378 379 } 380