Merge lp:~tkk2112/ctk/partial-new-css into lp:ctk
- partial-new-css
- Merge into trunk
Proposed by
Thomas Kristensen
Status: | Needs review |
---|---|
Proposed branch: | lp:~tkk2112/ctk/partial-new-css |
Merge into: | lp:ctk |
Diff against target: |
1276 lines (+796/-172) 12 files modified
configure.ac (+4/-6) ctk/Makefile.am (+1/-0) ctk/adjustment.vala (+7/-0) ctk/box.vala (+1/-1) ctk/button.vala (+6/-2) ctk/layout-manager.vala (+4/-4) ctk/scrollbar.vala (+1/-1) ctk/stylable.vala (+5/-7) ctk/style.vala (+120/-138) ctk/stylesheet.vala (+584/-0) ctk/text-entry.vala (+6/-2) ctk/widget.vala (+57/-11) |
To merge this branch: | bzr merge lp:~tkk2112/ctk/partial-new-css |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Ali Sabil | Pending | ||
Review via email: mp+24604@code.launchpad.net |
Commit message
Description of the change
partially implemented new css system
To post a comment you must log in.
Unmerged revisions
- 115. By Thomas Kristensen
-
Partially implemented the new stylesheet code.
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === modified file 'configure.ac' |
2 | --- configure.ac 2009-11-13 11:52:55 +0000 |
3 | +++ configure.ac 2010-05-03 20:12:42 +0000 |
4 | @@ -27,23 +27,21 @@ |
5 | GLIB_REQUIRED=2.16.0 |
6 | CLUTTER_REQUIRED=1.0.0 |
7 | GEE_REQUIRED=0.5.0 |
8 | -CCSS_REQUIRED=0.5.0 |
9 | |
10 | PKG_CHECK_MODULES(GLIB, glib-2.0 >= $GLIB_REQUIRED gobject-2.0 >= $GLIB_REQUIRED) |
11 | PKG_CHECK_MODULES(CLUTTER, clutter-1.0 >= $CLUTTER_REQUIRED) |
12 | PKG_CHECK_MODULES(GEE, gee-1.0 >= $GEE_REQUIRED) |
13 | -PKG_CHECK_MODULES(CCSS, ccss-1 >= $CCSS_REQUIRED) |
14 | |
15 | -CTK_PKG_DEPS="glib-2.0, gobject-2.0, clutter-1.0, gee-1.0, ccss-1" |
16 | +CTK_PKG_DEPS="glib-2.0, gobject-2.0, gio-2.0, clutter-1.0, gee-1.0" |
17 | AC_SUBST(CTK_PKG_DEPS) |
18 | |
19 | -CTK_VALAFLAGS="--pkg clutter-1.0 --pkg cogl-1.0 --pkg ccss-1 --pkg gee-1.0" |
20 | +CTK_VALAFLAGS="--pkg gio-2.0 --pkg clutter-1.0 --pkg cogl-1.0 --pkg gee-1.0" |
21 | AC_SUBST(CTK_VALAFLAGS) |
22 | |
23 | -CTK_CFLAGS="$GLIB_CFLAGS $CLUTTER_CFLAGS $GEE_CFLAGS $CCSS_CFLAGS" |
24 | +CTK_CFLAGS="$GLIB_CFLAGS $CLUTTER_CFLAGS $GEE_CFLAGS" |
25 | AC_SUBST(CTK_CFLAGS) |
26 | |
27 | -CTK_LIBS="$GLIB_LIBS $CLUTTER_LIBS $GEE_LIBS $CCSS_LIBS" |
28 | +CTK_LIBS="$GLIB_LIBS $CLUTTER_LIBS $GEE_LIBS" |
29 | AC_SUBST(CTK_LIBS) |
30 | |
31 | AC_CONFIG_FILES([Makefile |
32 | |
33 | === modified file 'ctk/Makefile.am' |
34 | --- ctk/Makefile.am 2010-01-24 14:59:58 +0000 |
35 | +++ ctk/Makefile.am 2010-05-03 20:12:42 +0000 |
36 | @@ -26,6 +26,7 @@ |
37 | scrollview.vala \ |
38 | stylable.vala \ |
39 | style.vala \ |
40 | + stylesheet.vala \ |
41 | text-entry.vala \ |
42 | texture-factory.vala \ |
43 | types.vala \ |
44 | |
45 | === modified file 'ctk/adjustment.vala' |
46 | --- ctk/adjustment.vala 2010-01-19 08:41:34 +0000 |
47 | +++ ctk/adjustment.vala 2010-05-03 20:12:42 +0000 |
48 | @@ -39,6 +39,7 @@ |
49 | this.value_changed_source = Idle.add_full (Clutter.PRIORITY_REDRAW, () => { |
50 | this.value_changed_source = 0; |
51 | this.notify_property ("value"); |
52 | + return false; |
53 | }); |
54 | } |
55 | } |
56 | @@ -60,6 +61,7 @@ |
57 | this.lower_changed_source = Idle.add_full (Clutter.PRIORITY_REDRAW, () => { |
58 | this.lower_changed_source = 0; |
59 | this.notify_property ("lower"); |
60 | + return false; |
61 | }); |
62 | } |
63 | this.clamp_page (this.lower, this.upper); |
64 | @@ -82,6 +84,7 @@ |
65 | this.upper_changed_source = Idle.add_full (Clutter.PRIORITY_REDRAW, () => { |
66 | this.upper_changed_source = 0; |
67 | this.notify_property ("upper"); |
68 | + return false; |
69 | }); |
70 | } |
71 | this.clamp_page (this.lower, this.upper); |
72 | @@ -104,6 +107,7 @@ |
73 | this.step_increment_changed_source = Idle.add_full (Clutter.PRIORITY_REDRAW, () => { |
74 | this.step_increment_changed_source = 0; |
75 | this.notify_property ("step-increment"); |
76 | + return false; |
77 | }); |
78 | } |
79 | } |
80 | @@ -125,6 +129,7 @@ |
81 | this.page_increment_changed_source = Idle.add_full (Clutter.PRIORITY_REDRAW, () => { |
82 | this.page_increment_changed_source = 0; |
83 | this.notify_property ("page-increment"); |
84 | + return false; |
85 | }); |
86 | } |
87 | } |
88 | @@ -146,6 +151,7 @@ |
89 | this.page_size_changed_source = Idle.add_full (Clutter.PRIORITY_REDRAW, () => { |
90 | this.page_size_changed_source = 0; |
91 | this.notify_property ("page-size"); |
92 | + return false; |
93 | }); |
94 | } |
95 | this.clamp_page (this.lower, this.upper); |
96 | @@ -238,6 +244,7 @@ |
97 | this.changed_source = Idle.add_full (Clutter.PRIORITY_REDRAW, () => { |
98 | this.changed_source = 0; |
99 | this.changed (); |
100 | + return false; |
101 | }); |
102 | } |
103 | } |
104 | |
105 | === modified file 'ctk/box.vala' |
106 | --- ctk/box.vala 2010-01-25 09:02:47 +0000 |
107 | +++ ctk/box.vala 2010-05-03 20:12:42 +0000 |
108 | @@ -70,7 +70,7 @@ |
109 | if (value != null) { |
110 | this._layout_manager = value; |
111 | this._layout_manager.set_container (this); |
112 | - this._layout_manager.layout_changed.connect (this.queue_relayout); |
113 | + this._layout_manager.layout_changed.connect (() => this.queue_relayout); |
114 | } |
115 | this.queue_relayout (); |
116 | } |
117 | |
118 | === modified file 'ctk/button.vala' |
119 | --- ctk/button.vala 2009-11-15 21:38:53 +0000 |
120 | +++ ctk/button.vala 2010-05-03 20:12:42 +0000 |
121 | @@ -71,11 +71,15 @@ |
122 | this._label = new Clutter.Text(); |
123 | |
124 | this.notify["font-family"].connect(() => { |
125 | - this._label.font_name = this.font_family + " " + this.font_size.to_string() + "px"; |
126 | + this._label.font_name = this.get_font_description (); |
127 | }); |
128 | |
129 | this.notify["font-size"].connect(() => { |
130 | - this._label.font_name = this.font_family + " " + this.font_size.to_string() + "px"; |
131 | + this._label.font_name = this.get_font_description (); |
132 | + }); |
133 | + |
134 | + this.notify["font-weight"].connect(() => { |
135 | + this._label.font_name = this.get_font_description (); |
136 | }); |
137 | |
138 | this.notify["color"].connect(() => { |
139 | |
140 | === modified file 'ctk/layout-manager.vala' |
141 | --- ctk/layout-manager.vala 2010-01-14 18:04:20 +0000 |
142 | +++ ctk/layout-manager.vala 2010-05-03 20:12:42 +0000 |
143 | @@ -96,7 +96,7 @@ |
144 | } |
145 | |
146 | public virtual Clutter.Alpha begin_animation (ulong mode, uint duration) requires (duration < 1000) { |
147 | - Clutter.Alpha alpha = (Clutter.Alpha) this.get_qdata (quark_layout_alpha); |
148 | + Clutter.Alpha alpha = this.get_qdata<Clutter.Alpha> (quark_layout_alpha); |
149 | if (alpha != null) { |
150 | alpha.mode = mode; |
151 | |
152 | @@ -121,7 +121,7 @@ |
153 | } |
154 | |
155 | public virtual double get_animation_progress () { |
156 | - Clutter.Alpha alpha = (Clutter.Alpha) this.get_qdata (quark_layout_alpha); |
157 | + Clutter.Alpha alpha = this.get_qdata<Clutter.Alpha> (quark_layout_alpha); |
158 | if (alpha == null) |
159 | return 1.0; |
160 | |
161 | @@ -129,7 +129,7 @@ |
162 | } |
163 | |
164 | public virtual void end_animation () { |
165 | - Clutter.Alpha alpha = (Clutter.Alpha) this.get_qdata (quark_layout_alpha); |
166 | + Clutter.Alpha alpha = this.get_qdata<Clutter.Alpha> (quark_layout_alpha); |
167 | if (alpha == null) |
168 | return; |
169 | |
170 | @@ -143,7 +143,7 @@ |
171 | } |
172 | |
173 | public LayoutMeta? get_child_meta (Clutter.Container container, Clutter.Actor actor) { |
174 | - LayoutMeta meta = (LayoutMeta) actor.get_qdata(quark_layout_meta); |
175 | + LayoutMeta meta = actor.get_qdata<LayoutMeta> (quark_layout_meta); |
176 | if (meta != null) { |
177 | var child = meta as Clutter.ChildMeta; |
178 | if (meta.manager == this && child.container == container && child.actor == actor) |
179 | |
180 | === modified file 'ctk/scrollbar.vala' |
181 | --- ctk/scrollbar.vala 2010-01-21 09:27:32 +0000 |
182 | +++ ctk/scrollbar.vala 2010-05-03 20:12:42 +0000 |
183 | @@ -35,7 +35,7 @@ |
184 | } |
185 | |
186 | this._adjustment = value; |
187 | - this._adjustment.changed.connect (this.queue_relayout); |
188 | + this._adjustment.changed.connect (() => this.queue_relayout); |
189 | this._adjustment.notify["value"].connect (this.update_handle_from_size); |
190 | this.queue_relayout (); |
191 | } |
192 | |
193 | === modified file 'ctk/stylable.vala' |
194 | --- ctk/stylable.vala 2009-11-03 12:28:33 +0000 |
195 | +++ ctk/stylable.vala 2010-05-03 20:12:42 +0000 |
196 | @@ -4,6 +4,7 @@ |
197 | * A Clutter UI toolkit |
198 | * |
199 | * Copyright (C) 2009 Ali Sabil |
200 | +* Copyright (C) 2010 Thomas Kristensen |
201 | * |
202 | * This library is free software; you can redistribute it and/or |
203 | * modify it under the terms of the GNU Lesser General Public |
204 | @@ -18,8 +19,8 @@ |
205 | * You should have received a copy of the GNU Lesser General Public |
206 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
207 | * |
208 | -* Author: |
209 | -* Ali Sabil <ali.sabil@gmail.com> |
210 | +* Author: Ali Sabil <ali.sabil@gmail.com> |
211 | +* Thomas Kristensen <thomas.k.kristensen@tandberg.com> |
212 | * |
213 | */ |
214 | |
215 | @@ -30,15 +31,12 @@ |
216 | set; |
217 | } |
218 | |
219 | - |
220 | public abstract void refresh (); |
221 | public abstract Stylable? get_style_container (); |
222 | public abstract Stylable? get_style_base (); |
223 | public abstract string? get_style_id (); |
224 | public abstract string? get_style_type (); |
225 | - [CCode (array_length = false, array_null_terminated = true)] |
226 | - public abstract string[]? get_style_classes (); |
227 | - [CCode (array_length = false, array_null_terminated = true)] |
228 | - public abstract string[]? get_style_pseudo_classes (); |
229 | + public abstract Gee.Set<string> get_style_classes (); |
230 | + public abstract Gee.Set<string> get_style_pseudo_classes (); |
231 | } |
232 | } |
233 | |
234 | === modified file 'ctk/style.vala' |
235 | --- ctk/style.vala 2010-01-24 17:06:13 +0000 |
236 | +++ ctk/style.vala 2010-05-03 20:12:42 +0000 |
237 | @@ -4,6 +4,7 @@ |
238 | * A Clutter UI toolkit |
239 | * |
240 | * Copyright (C) 2009 Ali Sabil |
241 | +* Copyright (C) 2010 Thomas Kristensen |
242 | * |
243 | * This library is free software; you can redistribute it and/or |
244 | * modify it under the terms of the GNU Lesser General Public |
245 | @@ -18,16 +19,23 @@ |
246 | * You should have received a copy of the GNU Lesser General Public |
247 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
248 | * |
249 | -* Author: |
250 | -* Ali Sabil <ali.sabil@gmail.com> |
251 | +* Author: Ali Sabil <ali.sabil@gmail.com> |
252 | +* Thomas Kristensen <thomas.k.kristensen@tandberg.com> |
253 | * |
254 | */ |
255 | |
256 | namespace Ctk { |
257 | - public class Style: Object { |
258 | + |
259 | + public enum FontWeight { |
260 | + NORMAL, |
261 | + BOLD, |
262 | + LIGHTER, |
263 | + BOLDER |
264 | + } |
265 | + |
266 | + public class Style: Object { |
267 | private static Style default_style; |
268 | - private CCss.Grammar grammar; |
269 | - private CCss.Stylesheet stylesheet; |
270 | + private Css.Stylesheet stylesheet; |
271 | |
272 | public signal void changed (); |
273 | |
274 | @@ -36,7 +44,7 @@ |
275 | if (rc_file == null) { |
276 | rc_file = Path.build_filename (Config.PACKAGE_DATADIR, "ctk", "style", "default.css"); |
277 | } |
278 | - this.load_stylesheet (rc_file, CCss.Stylesheet.Precedence.USER_AGENT); |
279 | + this.load_stylesheet (rc_file, Css.Stylesheet.Precedence.USER_AGENT); |
280 | } |
281 | |
282 | public static unowned Style get_default () { |
283 | @@ -46,11 +54,99 @@ |
284 | } |
285 | |
286 | public bool load_from_file (string filename) { |
287 | - return this.load_stylesheet (filename, CCss.Stylesheet.Precedence.AUTHOR); |
288 | + return this.load_stylesheet (filename, Css.Stylesheet.Precedence.AUTHOR); |
289 | } |
290 | |
291 | public new bool get_property (Stylable target, ParamSpec pspec, out Value value) { |
292 | - value.init (pspec.value_type); |
293 | + value.init (pspec.value_type); |
294 | + |
295 | + var properties = this.stylesheet.get_properties (target); |
296 | + |
297 | + stdout.printf("target=%s typeof(%s)\n", target.get_style_id (), target.get_style_type ()); |
298 | + stdout.printf("prop size=%d\n", properties.size); |
299 | + |
300 | + |
301 | + foreach (var p in properties) { |
302 | + stdout.printf("%s\n", p.key); |
303 | + } |
304 | + var css_value = properties[pspec.name]; |
305 | + |
306 | + |
307 | + |
308 | + if (css_value.source != null) |
309 | + stdout.printf("name=%s\n", css_value.source); |
310 | + if (css_value.value != null) |
311 | + stdout.printf("string=%s\n", css_value.value); |
312 | + if (pspec.name != null) |
313 | + stdout.printf("pname=%s\n", pspec.name); |
314 | + |
315 | + if (pspec.value_type == typeof (int)) { |
316 | + if (css_value.value != null) |
317 | + value.set_int (css_value.value.to_int ()); |
318 | + else |
319 | + value.set_int (0); |
320 | + return true; |
321 | + } else if (pspec.value_type == typeof (uint)) { |
322 | + if (css_value.value != null) |
323 | + value.set_uint (css_value.value.to_int ()); |
324 | + else |
325 | + value.set_uint (0); |
326 | + return true; |
327 | + } |
328 | + return false; |
329 | + /* else if (pspec.value_type == typeof (BorderImage)) { |
330 | + |
331 | + unowned Css.Property property; |
332 | + |
333 | + if (style.get_property ("border-image", out property)) { |
334 | + unowned Css.BorderImage border_image = (Css.BorderImage) property; |
335 | + |
336 | + BorderImage result = BorderImage (border_image.uri); |
337 | + |
338 | + if (result.uri != null) { |
339 | + int width, height; |
340 | + result.texture.get_base_size (out width, out height); |
341 | + |
342 | + result.top = (float) border_image.top.get_size (height); |
343 | + result.right = (float) border_image.right.get_size (width); |
344 | + result.bottom = (float) border_image.bottom.get_size (height); |
345 | + result.left = (float) border_image.left.get_size (width); |
346 | + } |
347 | + |
348 | + value.set_boxed (&result); |
349 | + return true; |
350 | + } |
351 | + } else if (pspec->value_type == MX_TYPE_FONT_WEIGHT) |
352 | + { |
353 | + g_value_init (value, pspec->value_type); |
354 | + |
355 | + mx_font_weight_set_from_string (value, css_value->string); |
356 | + } |
357 | + else |
358 | + { |
359 | + GValue strval = { 0, }; |
360 | + |
361 | + g_value_init (value, pspec->value_type); |
362 | + |
363 | + g_value_init (&strval, G_TYPE_STRING); |
364 | + g_value_set_string (&strval, css_value->string); |
365 | + |
366 | + if (!g_value_transform (&strval, value)) |
367 | + { |
368 | + g_warning ("Error setting property \"%s\" on \"%s\", could" |
369 | + " not transform \"%s\" from string to type %s", |
370 | + pspec->name, |
371 | + G_OBJECT_CLASS_NAME(G_OBJECT_GET_CLASS (stylable)), |
372 | + css_value->string, |
373 | + g_type_name (pspec->value_type)); |
374 | + } |
375 | + g_value_unset (&strval); |
376 | + }*/ |
377 | + } |
378 | + |
379 | + |
380 | + |
381 | +/* value.init (pspec.value_type); |
382 | |
383 | if (this.stylesheet != null) { |
384 | double number = 0.0; |
385 | @@ -96,10 +192,10 @@ |
386 | value.set_boxed (&padding); |
387 | return result; |
388 | } else if (pspec.value_type == typeof (BorderImage)) { |
389 | - unowned CCss.Property property; |
390 | + unowned Css.Property property; |
391 | |
392 | if (style.get_property ("border-image", out property)) { |
393 | - unowned CCss.BorderImage border_image = (CCss.BorderImage) property; |
394 | + unowned Css.BorderImage border_image = (Css.BorderImage) property; |
395 | |
396 | BorderImage result = BorderImage (border_image.uri); |
397 | |
398 | @@ -117,10 +213,10 @@ |
399 | return true; |
400 | } |
401 | } else if (pspec.value_type == typeof (Clutter.Texture)) { |
402 | - unowned CCss.Property property; |
403 | + unowned Css.Property property; |
404 | |
405 | if (style.get_property ("background-image", out property)) { |
406 | - unowned CCss.BackgroundImage background_image = (CCss.BackgroundImage) property; |
407 | + unowned Css.BackgroundImage background_image = (Css.BackgroundImage) property; |
408 | |
409 | if (background_image.uri != null) { |
410 | var result = TextureFactory.get_default ().get_texture (background_image.uri, true); |
411 | @@ -141,136 +237,22 @@ |
412 | } |
413 | } |
414 | } |
415 | - } |
416 | - return false; |
417 | - } |
418 | - |
419 | - private CCss.Style get_style (Stylable stylable) { |
420 | - var node = new Node (stylable); |
421 | - var style = this.stylesheet.query (node.get_internal_node ()); |
422 | - return style; |
423 | - } |
424 | - |
425 | - private bool load_stylesheet (string filename, CCss.Stylesheet.Precedence precedence) { |
426 | - if (!FileUtils.test (filename, FileTest.IS_REGULAR)) { |
427 | + }*/ |
428 | + |
429 | + private bool load_stylesheet (string filename, Css.Stylesheet.Precedence precedence) { |
430 | + if (!FileUtils.test (filename, FileTest.IS_REGULAR)) |
431 | return false; |
432 | - } |
433 | |
434 | - string path = Path.get_dirname (filename); |
435 | + var success = false; |
436 | if (this.stylesheet == null) { |
437 | - this.grammar = new CCss.Grammar.css (); |
438 | - |
439 | - var url_function = new CCss.Function ("url", url_handler); |
440 | - grammar.add_function (url_function); |
441 | - |
442 | - // FIXME: memory leak in path |
443 | - this.stylesheet = grammar.create_stylesheet_from_file (filename, (owned) path); |
444 | + this.stylesheet = new Css.Stylesheet (); |
445 | + success = this.stylesheet.add_from_file (filename, precedence); |
446 | } else { |
447 | - var url_function = new CCss.Function ("url", url_handler); |
448 | - this.grammar.add_function (url_function); |
449 | - this.stylesheet.add_from_file (filename, precedence, (owned) path); |
450 | - } |
451 | - this.changed (); |
452 | - return true; |
453 | - } |
454 | - |
455 | - private static string? url_handler (SList<string> args, void* user_data) { |
456 | - string? url = args.data; |
457 | - |
458 | - if (url == null || !url.has_prefix ("file://")) |
459 | - return null; |
460 | - |
461 | - url = url.substring (7); |
462 | - if (url[0] != '/' && user_data != null) { |
463 | - url = Path.build_filename ((string) user_data, url); |
464 | - } |
465 | - |
466 | - if (!FileUtils.test (url, FileTest.IS_REGULAR)) { |
467 | - url = null; |
468 | - } |
469 | - return url; |
470 | - } |
471 | - |
472 | - private class Node { |
473 | - private Stylable stylable; |
474 | - private static CCss.NodeClass node_class; |
475 | - private CCss.Node node; |
476 | - |
477 | - public Node (Stylable stylable) { |
478 | - this.stylable = stylable; |
479 | - |
480 | - this.node_class.get_container = Node.get_style_container; |
481 | - this.node_class.get_id = Node.get_style_id; |
482 | - this.node_class.get_type = Node.get_style_type; |
483 | - this.node_class.get_classes = Node.get_style_classes; |
484 | - this.node_class.get_pseudo_classes = Node.get_style_pseudo_classes; |
485 | - this.node_class.release = Node.style_release; |
486 | - |
487 | - this.node = new CCss.Node (this.node_class, 12, this); |
488 | - } |
489 | - |
490 | - public unowned CCss.Node get_internal_node () { |
491 | - return this.node; |
492 | - } |
493 | - |
494 | - private static CCss.Node? get_style_container (CCss.Node ccss_node) { |
495 | - Node node = ccss_node.get_user_data () as Node; |
496 | - |
497 | - if (node != null) { |
498 | - Stylable stylable = node.stylable; |
499 | - |
500 | - Clutter.Actor parent = (stylable as Clutter.Actor).get_parent (); |
501 | - if (parent != null) { |
502 | - return new CCss.Node (Node.node_class, 12, parent); |
503 | - } |
504 | - } |
505 | - |
506 | - return null; |
507 | - } |
508 | - |
509 | - private static string? get_style_id (CCss.Node ccss_node) { |
510 | - Node node = ccss_node.get_user_data () as Node; |
511 | - Stylable stylable = node.stylable; |
512 | - return stylable.get_style_id (); |
513 | - } |
514 | - |
515 | - private static string? get_style_type (CCss.Node ccss_node) { |
516 | - Node node = ccss_node.get_user_data () as Node; |
517 | - |
518 | - if (node != null) { |
519 | - Stylable stylable = node.stylable; |
520 | - return stylable.get_style_type (); |
521 | - } |
522 | - |
523 | - return null; |
524 | - } |
525 | - |
526 | - [CCode (array_length = false, array_null_terminated = true)] |
527 | - private static string[]? get_style_classes (CCss.Node ccss_node) { |
528 | - Node node = ccss_node.get_user_data () as Node; |
529 | - |
530 | - if (node != null) { |
531 | - Stylable stylable = node.stylable; |
532 | - return stylable.get_style_classes (); |
533 | - } |
534 | - |
535 | - return null; |
536 | - } |
537 | - |
538 | - [CCode (array_length = false, array_null_terminated = true)] |
539 | - private static string[]? get_style_pseudo_classes (CCss.Node ccss_node) { |
540 | - Node node = ccss_node.get_user_data () as Node; |
541 | - |
542 | - if (node != null) { |
543 | - Stylable stylable = node.stylable; |
544 | - return stylable.get_style_pseudo_classes (); |
545 | - } |
546 | - |
547 | - return null; |
548 | - } |
549 | - |
550 | - private static void style_release (CCss.Node ccss_node) { |
551 | - } |
552 | + success = this.stylesheet.add_from_file (filename, precedence); |
553 | + } |
554 | + if (success) |
555 | + this.changed (); |
556 | + return success; |
557 | } |
558 | } |
559 | } |
560 | |
561 | === added file 'ctk/stylesheet.vala' |
562 | --- ctk/stylesheet.vala 1970-01-01 00:00:00 +0000 |
563 | +++ ctk/stylesheet.vala 2010-05-03 20:12:42 +0000 |
564 | @@ -0,0 +1,584 @@ |
565 | +/* |
566 | + * Ctk |
567 | + * |
568 | + * A Clutter UI toolkit |
569 | + * |
570 | + * Copyright (C) 2009 Ali Sabil |
571 | + * Copyright (C) 2010 Thomas Kristensen |
572 | + * |
573 | + * This program is free software; you can redistribute it and/or modify it |
574 | + * under the terms and conditions of the GNU Lesser General Public License, |
575 | + * version 2.1, as published by the Free Software Foundation. |
576 | + * |
577 | + * This program is distributed in the hope it will be useful, but WITHOUT ANY |
578 | + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
579 | + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for |
580 | + * more details. |
581 | + * |
582 | + * You should have received a copy of the GNU Lesser General Public License |
583 | + * along with this program; if not, write to the Free Software Foundation, |
584 | + * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
585 | + * |
586 | + * Author: Thomas Kristensen <thomas.k.kristensen@tandberg.com> |
587 | + * |
588 | + * The most of the code was translated from C to Vala, the original code |
589 | + * had the following Copyright notice: |
590 | + */ |
591 | + |
592 | +/* |
593 | + * Copyright 2009 Intel Corporation. |
594 | + * |
595 | + * This program is free software; you can redistribute it and/or modify it |
596 | + * under the terms and conditions of the GNU Lesser General Public License, |
597 | + * version 2.1, as published by the Free Software Foundation. |
598 | + * |
599 | + * This program is distributed in the hope it will be useful, but WITHOUT ANY |
600 | + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS |
601 | + * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for |
602 | + * more details. |
603 | + * |
604 | + * You should have received a copy of the GNU Lesser General Public License |
605 | + * along with this program; if not, write to the Free Software Foundation, |
606 | + * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA. |
607 | + * |
608 | + * Author: Thomas Wood <thos@gnome.org> |
609 | + * |
610 | + */ |
611 | + |
612 | +namespace Ctk { |
613 | + namespace Css { |
614 | + |
615 | + public struct StyleSheetValue { |
616 | + string value; |
617 | + string source; |
618 | + } |
619 | + |
620 | + public class Stylesheet: Object { |
621 | + public enum Precedence { |
622 | + USER_AGENT, |
623 | + USER, |
624 | + AUTHOR |
625 | + } |
626 | + |
627 | + private Gee.ArrayList<Gee.HashMap?> styles; |
628 | + private Gee.ArrayList<Selector?> selectors; |
629 | + private Gee.ArrayList<string>? filenames; |
630 | + private Scanner scanner; |
631 | + private weak string filename; |
632 | + private int precedence; |
633 | + |
634 | + private struct Selector { |
635 | + string type; |
636 | + string id; |
637 | + string class; |
638 | + string pseudo_class; |
639 | + Selector? parent; |
640 | + Selector? ancestor; |
641 | + Gee.HashMap<string, string> style; |
642 | + string filename; |
643 | + int precedence; |
644 | + } |
645 | + |
646 | + private struct SelectorMatch { |
647 | + int id; |
648 | + int precedence; |
649 | + int score; |
650 | + } |
651 | + |
652 | + public Stylesheet () { |
653 | + this.styles = new Gee.ArrayList<Gee.HashMap?> (); |
654 | + this.selectors = new Gee.ArrayList<Selector?> (); |
655 | + this.filenames = new Gee.ArrayList<string> (); |
656 | + } |
657 | + |
658 | + public bool add_from_file (string filename, Precedence precedence) { |
659 | + if (!FileUtils.test (filename, FileTest.IS_REGULAR)) |
660 | + return false; |
661 | + |
662 | + if (this.filenames.contains (filename)) |
663 | + return false; |
664 | + |
665 | + this.filename = filename; |
666 | + this.precedence = (int) precedence; |
667 | + |
668 | + var result = parse_file (filename); |
669 | + |
670 | + if (result) |
671 | + this.filenames.add (filename); |
672 | + |
673 | + return result; |
674 | + } |
675 | + |
676 | + private int sort_selector_matches (SelectorMatch a, SelectorMatch b) { |
677 | + int precedence = a.precedence - b.precedence; |
678 | + if (precedence > 0) |
679 | + return precedence; |
680 | + return a.score - b.score; |
681 | + } |
682 | + |
683 | + |
684 | + public Gee.HashMap<string, StyleSheetValue?> get_properties (Stylable stylable) { |
685 | + stdout.printf("this.selectors size=%d\n", this.selectors.size); |
686 | + |
687 | + var matching_selectors = new Gee.ArrayList<SelectorMatch?> (); |
688 | + |
689 | + |
690 | + /* find matching selectors */ |
691 | + for (var i = 0; i < this.selectors.size; ++i) { |
692 | + Selector selector = this.selectors[i]; |
693 | + |
694 | + var score = node_matches_selector (selector, stylable); |
695 | + |
696 | + stdout.printf("Selector=%s, %s, %s, %s - score=%d", selector.id, selector.type, selector.class, selector.pseudo_class, score); |
697 | + |
698 | + if (score >= 0) { |
699 | + var selector_match = SelectorMatch (); |
700 | + selector_match.id = i; |
701 | + selector_match.precedence = selector.precedence; |
702 | + selector_match.score = score; |
703 | + matching_selectors.add (selector_match); |
704 | + } |
705 | + } |
706 | + |
707 | + /* score the selectors by their score */ |
708 | + matching_selectors.sort ((CompareFunc) sort_selector_matches); |
709 | + |
710 | + /* get properties from selector's styles */ |
711 | + var result = new Gee.HashMap<string, StyleSheetValue?> (str_hash, str_equal); |
712 | + |
713 | + foreach (var l in matching_selectors) { |
714 | + Selector selector = this.selectors[l.id]; |
715 | + |
716 | + foreach (var element in selector.style) { |
717 | + var style_sheet_value = StyleSheetValue (); |
718 | + style_sheet_value.source = selector.filename; |
719 | + style_sheet_value.value = element.value; |
720 | + |
721 | + result[element.key] = style_sheet_value; |
722 | + } |
723 | + |
724 | + } |
725 | + return result; |
726 | + } |
727 | + |
728 | + private int node_matches_selector (Selector selector, Stylable stylable) { |
729 | + var a = 0; |
730 | + var b = 0; |
731 | + var c = 0; |
732 | + |
733 | + /* get properties for this stylable */ |
734 | + var id = stylable.get_style_id (); |
735 | + var classes = stylable.get_style_classes (); |
736 | + var pseudo_classes = stylable.get_style_pseudo_classes (); |
737 | + var parent = stylable.get_style_container (); |
738 | + |
739 | + stdout.printf("target=%s (%s), selector=%s (%s)", id, stylable.get_style_type(), selector.id, selector.type); |
740 | + |
741 | + /* check type */ |
742 | + if (selector.type == null || selector.type[0] == '*') { |
743 | + /* null or universal selector match, but are ignored for score */ |
744 | + } else { |
745 | + var type = stylable.get_type (); |
746 | + var type_name = type.name (); |
747 | + var matched = 0; |
748 | + var depth = 10; |
749 | + |
750 | + while (type_name.len () > 0) { |
751 | + if (selector.type != type_name) { |
752 | + matched = depth; |
753 | + break; |
754 | + } else { |
755 | + type = type.parent (); |
756 | + type_name = type.name (); |
757 | + if (depth > 1) |
758 | + depth--; |
759 | + } |
760 | + } |
761 | + |
762 | + if (matched > 0) |
763 | + return -1; |
764 | + else |
765 | + c += depth; |
766 | + } |
767 | + |
768 | + /* check id */ |
769 | + if (id == null || selector.id != id) |
770 | + return -1; |
771 | + else |
772 | + a += 10; |
773 | + |
774 | + /* check psuedo_class */ |
775 | + if (pseudo_classes == null|| !(selector.pseudo_class in pseudo_classes)) |
776 | + return -1; |
777 | + else |
778 | + b += 10; |
779 | + |
780 | + /* check class */ |
781 | + if (classes == null || !(selector.class in classes)) |
782 | + return -1; |
783 | + else |
784 | + b += 10; |
785 | + |
786 | + /* check parent */ |
787 | + if (selector.parent != null) { |
788 | + if (parent == null) |
789 | + return -1; |
790 | + |
791 | + var parent_matches = node_matches_selector (selector.parent, parent); |
792 | + if (parent_matches < 0) |
793 | + return -1; |
794 | + |
795 | + /* increase the 'c' score, since the parent matched */ |
796 | + c += parent_matches; |
797 | + } |
798 | + |
799 | + /* check ancestor */ |
800 | + if (selector.ancestor != null) { |
801 | + if (parent == null) |
802 | + return -1; |
803 | + |
804 | + var ancestor = parent; |
805 | + while (ancestor != null) { |
806 | + var pparent = ancestor.get_style_container (); |
807 | + |
808 | + var ancestor_matches = node_matches_selector (selector.ancestor, ancestor); |
809 | + |
810 | + /* if one of the ancestors match, stop search and increase 'c' score */ |
811 | + if (ancestor_matches >= 0) { |
812 | + c += ancestor_matches; |
813 | + break; |
814 | + } |
815 | + |
816 | + ancestor = pparent; |
817 | + if (ancestor == null) |
818 | + return -1; |
819 | + } |
820 | + } |
821 | + return a * 10000 + b * 100 + c; |
822 | + } |
823 | + |
824 | + private bool parse_file (string filename) { |
825 | + var file = File.new_for_path (filename); |
826 | + |
827 | + if (!file.query_exists (null)) { |
828 | + stderr.printf ("File '%s' doesn't exist.\n", file.get_path ()); |
829 | + return false; |
830 | + } |
831 | + |
832 | + try { |
833 | + var in_stream = new DataInputStream (file.read (null)); |
834 | + var data = new StringBuilder (); |
835 | + |
836 | + string line; |
837 | + |
838 | + // Read lines until end of file (null) is reached |
839 | + while ((line = in_stream.read_line (null, null)) != null) { |
840 | + data.append (line); |
841 | + } |
842 | + |
843 | + return parse (data.str); |
844 | + |
845 | + } catch (Error e) { |
846 | + error ("%s", e.message); |
847 | + } |
848 | + return false; |
849 | + } |
850 | + |
851 | + |
852 | + private bool parse (string data) { |
853 | + |
854 | + this.scanner = new Scanner (null); |
855 | + this.scanner.config.cpair_comment_single = "\x01\n"; |
856 | + this.scanner.config.cset_identifier_nth = CharacterSet.a_2_z + "-_0123456789" + CharacterSet.A_2_Z + CharacterSet.LATINS + CharacterSet.LATINC; |
857 | + this.scanner.config.scan_float = false; /* allows scanning '.' */ |
858 | + this.scanner.config.scan_hex = false; |
859 | + this.scanner.config.scan_string_sq = false; |
860 | + this.scanner.config.scan_string_dq = false; |
861 | + |
862 | + this.scanner.input_text (data, (uint) data.len ()); |
863 | + |
864 | + var token = this.scanner.peek_next_token (); |
865 | + while (token != TokenType.EOF) { |
866 | + token = parse_block (); |
867 | + |
868 | + if (token != TokenType.NONE) |
869 | + break; |
870 | + |
871 | + token = this.scanner.peek_next_token (); |
872 | + } |
873 | + |
874 | + if (token == TokenType.EOF) |
875 | + return true; |
876 | + else |
877 | + this.scanner.unexp_token (token, null, null, null, "Error", true); |
878 | + |
879 | + return false; |
880 | + } |
881 | + |
882 | + private TokenType parse_block () { |
883 | + Gee.ArrayList<Selector?> list; |
884 | + var token = parse_ruleset (out list); |
885 | + |
886 | + if (token != TokenType.NONE) |
887 | + return token; |
888 | + |
889 | + /* create a hash table for the properties */ |
890 | + var table = new Gee.HashMap<string, string> (str_hash, direct_equal); |
891 | + token = parse_style (ref table); |
892 | + |
893 | + /* assign all the selectors to this style */ |
894 | + foreach (var l in list) |
895 | + l.style = table; |
896 | + |
897 | + |
898 | + this.styles.add (table); |
899 | + this.selectors.add_all (list); |
900 | + |
901 | + return token; |
902 | + } |
903 | + |
904 | + private TokenType parse_ruleset (out Gee.ArrayList<Selector?> selector_list) { |
905 | + selector_list = new Gee.ArrayList<Selector?> (); |
906 | + |
907 | + /* parse the first selector, then keep going until we find left curly */ |
908 | + var token = this.scanner.peek_next_token (); |
909 | + |
910 | + Selector? parent = null; |
911 | + Selector? selector = null; |
912 | + |
913 | + while (token != TokenType.LEFT_CURLY) { |
914 | + stdout.printf("token=%d\n", (int)token); |
915 | + switch ((int)token) { |
916 | + case TokenType.IDENTIFIER: |
917 | + case 42: // '*' |
918 | + case 35: // '#' |
919 | + case 46: // '.' |
920 | + case 58: // ':' |
921 | + if (selector != null) |
922 | + parent = selector; |
923 | + else |
924 | + parent = null; |
925 | + |
926 | + /* check if there was a previous selector and if so, the new one |
927 | + * should use the previous selector to match an ancestor */ |
928 | + |
929 | + selector = Selector (); |
930 | + selector.filename = this.filename.dup (); |
931 | + selector.precedence = this.precedence; |
932 | + selector_list.add (selector); |
933 | + |
934 | + if (parent != null) { |
935 | + selector_list.remove (parent); |
936 | + selector.ancestor = parent; |
937 | + } |
938 | + |
939 | + token = parse_simple_selector (ref selector); |
940 | + if (token != TokenType.NONE) |
941 | + return token; |
942 | + |
943 | + break; |
944 | + |
945 | + case 62: // '>' |
946 | + this.scanner.get_next_token (); |
947 | + if (selector == null) |
948 | + warning ("null parent when parsing '>'"); |
949 | + |
950 | + parent = selector; |
951 | + |
952 | + selector = Selector (); |
953 | + selector.filename = this.filename; |
954 | + selector_list.add (selector); |
955 | + |
956 | + /* remove parent from list of selectors and link it to the new selector */ |
957 | + selector.parent = parent; |
958 | + selector_list.remove (parent); |
959 | + |
960 | + token = parse_simple_selector (ref selector); |
961 | + if (token != TokenType.NONE) |
962 | + return token; |
963 | + |
964 | + break; |
965 | + |
966 | + case 44: // ',' |
967 | + this.scanner.get_next_token (); |
968 | + |
969 | + selector = Selector (); |
970 | + selector.filename = this.filename; |
971 | + selector_list.add (selector); |
972 | + |
973 | + token = parse_simple_selector (ref selector); |
974 | + if (token != TokenType.NONE) |
975 | + return token; |
976 | + |
977 | + break; |
978 | + |
979 | + default: |
980 | + this.scanner.get_next_token (); |
981 | + this.scanner.unexp_token (TokenType.ERROR, null, null, null, "Unhandled selector", true); |
982 | + return TokenType.LEFT_CURLY; |
983 | + } |
984 | + token = this.scanner.peek_next_token (); |
985 | + } |
986 | + |
987 | + return TokenType.NONE; |
988 | + } |
989 | + |
990 | + private TokenType parse_simple_selector (ref Selector selector) { |
991 | + /* parse optional type (either '*' or an identifier) */ |
992 | + var token = this.scanner.peek_next_token (); |
993 | + switch ((int) token) { |
994 | + case 42: // '*' |
995 | + token = this.scanner.get_next_token (); |
996 | + selector.type = "*"; |
997 | + break; |
998 | + case TokenType.IDENTIFIER: |
999 | + token = this.scanner.get_next_token (); |
1000 | + selector.type = this.scanner.value.identifier; |
1001 | + break; |
1002 | + default: |
1003 | + break; |
1004 | + } |
1005 | + |
1006 | + /* Here we look for '#', '.' or ':' and return if we find anything else */ |
1007 | + token = this.scanner.peek_next_token (); |
1008 | + while (token != TokenType.NONE) { |
1009 | + switch ((int) token) { |
1010 | + /* id */ |
1011 | + case 35: // '#' |
1012 | + token = this.scanner.get_next_token (); |
1013 | + token = this.scanner.get_next_token (); |
1014 | + if (token != TokenType.IDENTIFIER) |
1015 | + return TokenType.IDENTIFIER; |
1016 | + selector.id = this.scanner.value.identifier; |
1017 | + break; |
1018 | + /* class */ |
1019 | + case 46: // '.' |
1020 | + token = this.scanner.get_next_token (); |
1021 | + token = this.scanner.get_next_token (); |
1022 | + if (token != TokenType.IDENTIFIER) |
1023 | + return TokenType.IDENTIFIER; |
1024 | + selector.id = this.scanner.value.identifier; |
1025 | + break; |
1026 | + /* pseudo-class */ |
1027 | + case 58: // ':' |
1028 | + token = this.scanner.get_next_token (); |
1029 | + token = this.scanner.get_next_token (); |
1030 | + if (token != TokenType.IDENTIFIER) |
1031 | + return TokenType.IDENTIFIER; |
1032 | + selector.id = this.scanner.value.identifier; |
1033 | + break; |
1034 | + |
1035 | + /* unhandled */ |
1036 | + default: |
1037 | + return TokenType.NONE; |
1038 | + } |
1039 | + token = this.scanner.peek_next_token (); |
1040 | + } |
1041 | + return TokenType.NONE; |
1042 | + } |
1043 | + |
1044 | + private TokenType parse_style (ref Gee.HashMap<string, string> table) { |
1045 | + /* { */ |
1046 | + var token = this.scanner.get_next_token (); |
1047 | + if (token != TokenType.LEFT_CURLY) |
1048 | + return TokenType.LEFT_CURLY; |
1049 | + |
1050 | + /* keep going until we find '}' */ |
1051 | + token = this.scanner.peek_next_token (); |
1052 | + while (token != TokenType.RIGHT_CURLY) { |
1053 | + string? key = null; |
1054 | + string? value = null; |
1055 | + |
1056 | + token = parse_key_value (out key, out value); |
1057 | + if (token != TokenType.NONE) |
1058 | + return token; |
1059 | + |
1060 | + table[key] = value; |
1061 | + |
1062 | + token = this.scanner.peek_next_token (); |
1063 | + } |
1064 | + |
1065 | + /* } */ |
1066 | + token = this.scanner.get_next_token (); |
1067 | + if (token != TokenType.RIGHT_CURLY) |
1068 | + return TokenType.RIGHT_CURLY; |
1069 | + |
1070 | + return TokenType.NONE; |
1071 | + } |
1072 | + |
1073 | + private TokenType parse_key_value (out string? key, out string? value) { |
1074 | + bool start_with_dash = false; |
1075 | + string id_first = this.scanner.config.cset_identifier_first; |
1076 | + string id_nth = this.scanner.config.cset_identifier_nth; |
1077 | + bool scan_identifier_1char = this.scanner.config.scan_identifier_1char; |
1078 | + |
1079 | + /* parse property name */ |
1080 | + var token = this.scanner.get_next_token (); |
1081 | + |
1082 | + /* allow property names to start with '-' */ |
1083 | + if ((char) token == '-') { |
1084 | + /* FIXME: this will now ignore whitepsace and comments, but this should |
1085 | + * not be allowed in the middle of a property name! */ |
1086 | + token = this.scanner.get_next_token (); |
1087 | + start_with_dash = true; |
1088 | + } |
1089 | + |
1090 | + if (token != TokenType.IDENTIFIER) |
1091 | + return TokenType.IDENTIFIER; |
1092 | + |
1093 | + if (start_with_dash) |
1094 | + key = "-".concat (this.scanner.value.identifier); |
1095 | + else |
1096 | + key = this.scanner.value.identifier; |
1097 | + |
1098 | + token = this.scanner.get_next_token (); |
1099 | + if (token != ':') |
1100 | + return (TokenType) ':'; |
1101 | + |
1102 | + /* value parsing options */ |
1103 | + this.scanner.config.cset_identifier_first = CharacterSet.a_2_z + "#_-0123456789" + CharacterSet.A_2_Z + CharacterSet.LATINS + CharacterSet.LATINC; |
1104 | + this.scanner.config.cset_identifier_nth = this.scanner.config.cset_identifier_first; |
1105 | + this.scanner.config.scan_identifier_1char = true; |
1106 | + this.scanner.config.char_2_token = false; |
1107 | + this.scanner.config.cset_skip_characters = "\n"; |
1108 | + |
1109 | + /* parse value */ |
1110 | + while (this.scanner.next_value.char != ';') { |
1111 | + token = this.scanner.get_next_token (); |
1112 | + switch (token) { |
1113 | + case TokenType.IDENTIFIER: |
1114 | + value = value + this.scanner.value.identifier; |
1115 | + break; |
1116 | + case TokenType.CHAR: |
1117 | + var string_builder = new StringBuilder(value); |
1118 | + string_builder.append_c ((char) this.scanner.value.char); |
1119 | + value = string_builder.str; |
1120 | + break; |
1121 | + |
1122 | + default: |
1123 | + return (TokenType) ';'; |
1124 | + } |
1125 | + |
1126 | + token = this.scanner.peek_next_token (); |
1127 | + } |
1128 | + |
1129 | + /* semi colon */ |
1130 | + token = this.scanner.get_next_token (); |
1131 | + if (this.scanner.value.char != ';') |
1132 | + return (TokenType) ';'; |
1133 | + |
1134 | + /* we've come to the end of the value, so reset the options */ |
1135 | + this.scanner.config.cset_identifier_nth = id_nth; |
1136 | + this.scanner.config.cset_identifier_first = id_first; |
1137 | + this.scanner.config.scan_identifier_1char = scan_identifier_1char; |
1138 | + this.scanner.config.char_2_token = true; |
1139 | + this.scanner.config.cset_skip_characters = " \t\n"; |
1140 | + |
1141 | + /* strip the leading and trailing whitespace */ |
1142 | + value.strip (); |
1143 | + |
1144 | + return TokenType.NONE; |
1145 | + } |
1146 | + } |
1147 | + } |
1148 | +} |
1149 | |
1150 | === modified file 'ctk/text-entry.vala' |
1151 | --- ctk/text-entry.vala 2010-01-14 13:48:18 +0000 |
1152 | +++ ctk/text-entry.vala 2010-05-03 20:12:42 +0000 |
1153 | @@ -126,11 +126,15 @@ |
1154 | }); |
1155 | |
1156 | this.notify["font-family"].connect(() => { |
1157 | - this._text_actor.font_name = this.font_family + " " + this.font_size.to_string() + "px"; |
1158 | + this._text_actor.font_name = this.get_font_description (); |
1159 | }); |
1160 | |
1161 | this.notify["font-size"].connect(() => { |
1162 | - this._text_actor.font_name = this.font_family + " " + this.font_size.to_string() + "px"; |
1163 | + this._text_actor.font_name = this.get_font_description (); |
1164 | + }); |
1165 | + |
1166 | + this.notify["font-weight"].connect(() => { |
1167 | + this._text_actor.font_name = this.get_font_description (); |
1168 | }); |
1169 | |
1170 | this.notify["color"].connect(() => { |
1171 | |
1172 | === modified file 'ctk/widget.vala' |
1173 | --- ctk/widget.vala 2010-01-23 19:34:51 +0000 |
1174 | +++ ctk/widget.vala 2010-05-03 20:12:42 +0000 |
1175 | @@ -4,6 +4,7 @@ |
1176 | * A Clutter UI toolkit |
1177 | * |
1178 | * Copyright (C) 2009 Ali Sabil |
1179 | +* Copyright (C) 2010 Thomas Kristensen |
1180 | * |
1181 | * This library is free software; you can redistribute it and/or |
1182 | * modify it under the terms of the GNU Lesser General Public |
1183 | @@ -18,8 +19,8 @@ |
1184 | * You should have received a copy of the GNU Lesser General Public |
1185 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
1186 | * |
1187 | -* Author: |
1188 | -* Ali Sabil <ali.sabil@gmail.com> |
1189 | +* Author: Ali Sabil <ali.sabil@gmail.com> |
1190 | +* Thomas Kristensen <thomas.k.kristensen@tandberg.com> |
1191 | * |
1192 | */ |
1193 | |
1194 | @@ -108,6 +109,21 @@ |
1195 | private uint _font_size = 12; |
1196 | |
1197 | [CCode(notify = false)] |
1198 | + public FontWeight font_weight { |
1199 | + get { |
1200 | + return this._font_weight; |
1201 | + } |
1202 | + set { |
1203 | + if (this._font_weight != value) { |
1204 | + this._font_weight = value; |
1205 | + this.pending_relayout = true; |
1206 | + this.notify_property ("font-weight"); |
1207 | + } |
1208 | + } |
1209 | + } |
1210 | + private FontWeight _font_weight = FontWeight.NORMAL; |
1211 | + |
1212 | + [CCode(notify = false)] |
1213 | public Padding padding { |
1214 | get { |
1215 | return this.children_container.padding; |
1216 | @@ -338,6 +354,7 @@ |
1217 | this.get_property_from_style ("color"); |
1218 | this.get_property_from_style ("font-family"); |
1219 | this.get_property_from_style ("font-size"); |
1220 | + this.get_property_from_style ("font-weight"); |
1221 | this.get_property_from_style ("opacity"); |
1222 | this.get_property_from_style ("padding"); |
1223 | this.get_property_from_style ("border-image"); |
1224 | @@ -388,14 +405,43 @@ |
1225 | return ((Object) this).get_type().name(); |
1226 | } |
1227 | |
1228 | - [CCode (array_length = false, array_null_terminated = true)] |
1229 | - public string[]? get_style_classes () { |
1230 | - return (string[]) this.style_classes.to_array (); |
1231 | - } |
1232 | - |
1233 | - [CCode (array_length = false, array_null_terminated = true)] |
1234 | - public string[]? get_style_pseudo_classes () { |
1235 | - return (string[]) this.style_pseudo_classes.to_array (); |
1236 | - } |
1237 | + public Gee.Set<string> get_style_classes () { |
1238 | + return this.style_classes.read_only_view; |
1239 | + } |
1240 | + |
1241 | + public Gee.Set<string> get_style_pseudo_classes () { |
1242 | + return this.style_pseudo_classes.read_only_view; |
1243 | + } |
1244 | + |
1245 | + /* Utilities */ |
1246 | + |
1247 | + public string get_font_description () { |
1248 | + var font_description = new Pango.FontDescription (); |
1249 | + |
1250 | + font_description.set_family (this.font_family); |
1251 | + font_description.set_absolute_size (this.font_size * 1024 /* PANGO_SCALE */); |
1252 | + |
1253 | + var weight = Pango.Weight.NORMAL; |
1254 | + switch (this.font_weight) { |
1255 | + case FontWeight.BOLD: |
1256 | + weight = Pango.Weight.BOLD; |
1257 | + break; |
1258 | + case FontWeight.LIGHTER: |
1259 | + weight = Pango.Weight.LIGHT; |
1260 | + break; |
1261 | + case FontWeight.BOLDER: |
1262 | + weight = Pango.Weight.HEAVY; |
1263 | + break; |
1264 | + default: |
1265 | + weight = Pango.Weight.NORMAL; |
1266 | + break; |
1267 | + } |
1268 | + |
1269 | + font_description.set_weight (weight); |
1270 | + |
1271 | + var description_string = font_description.to_string (); |
1272 | + return description_string; |
1273 | + } |
1274 | + |
1275 | } |
1276 | } |