1 | /* GTK - The GIMP Toolkit |
2 | * Copyright (C) 2011 Red Hat, Inc. |
3 | * |
4 | * This library is free software; you can redistribute it and/or |
5 | * modify it under the terms of the GNU Lesser General Public |
6 | * License as published by the Free Software Foundation; either |
7 | * version 2 of the License, or (at your option) any later version. |
8 | * |
9 | * This library is distributed in the hope that it will be useful, |
10 | * but 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 | * You should have received a copy of the GNU Lesser General Public |
15 | * License along with this library. If not, see <http://www.gnu.org/licenses/>. |
16 | */ |
17 | |
18 | #include "config.h" |
19 | |
20 | #include "gtkcsscornervalueprivate.h" |
21 | #include "gtkcssnumbervalueprivate.h" |
22 | #include "gtkcssdimensionvalueprivate.h" |
23 | |
24 | struct _GtkCssValue { |
25 | GTK_CSS_VALUE_BASE |
26 | GtkCssValue *x; |
27 | GtkCssValue *y; |
28 | }; |
29 | |
30 | static void |
31 | gtk_css_value_corner_free (GtkCssValue *value) |
32 | { |
33 | _gtk_css_value_unref (value: value->x); |
34 | _gtk_css_value_unref (value: value->y); |
35 | |
36 | g_slice_free (GtkCssValue, value); |
37 | } |
38 | |
39 | static GtkCssValue * |
40 | gtk_css_value_corner_compute (GtkCssValue *corner, |
41 | guint property_id, |
42 | GtkStyleProvider *provider, |
43 | GtkCssStyle *style, |
44 | GtkCssStyle *parent_style) |
45 | { |
46 | GtkCssValue *x, *y; |
47 | |
48 | x = _gtk_css_value_compute (value: corner->x, property_id, provider, style, parent_style); |
49 | y = _gtk_css_value_compute (value: corner->y, property_id, provider, style, parent_style); |
50 | if (x == corner->x && y == corner->y) |
51 | { |
52 | _gtk_css_value_unref (value: x); |
53 | _gtk_css_value_unref (value: y); |
54 | return _gtk_css_value_ref (value: corner); |
55 | } |
56 | |
57 | return _gtk_css_corner_value_new (x, y); |
58 | } |
59 | |
60 | static gboolean |
61 | gtk_css_value_corner_equal (const GtkCssValue *corner1, |
62 | const GtkCssValue *corner2) |
63 | { |
64 | return _gtk_css_value_equal (value1: corner1->x, value2: corner2->x) |
65 | && _gtk_css_value_equal (value1: corner1->y, value2: corner2->y); |
66 | } |
67 | |
68 | static GtkCssValue * |
69 | gtk_css_value_corner_transition (GtkCssValue *start, |
70 | GtkCssValue *end, |
71 | guint property_id, |
72 | double progress) |
73 | { |
74 | GtkCssValue *x, *y; |
75 | |
76 | x = _gtk_css_value_transition (start: start->x, end: end->x, property_id, progress); |
77 | if (x == NULL) |
78 | return NULL; |
79 | y = _gtk_css_value_transition (start: start->y, end: end->y, property_id, progress); |
80 | if (y == NULL) |
81 | { |
82 | _gtk_css_value_unref (value: x); |
83 | return NULL; |
84 | } |
85 | |
86 | return _gtk_css_corner_value_new (x, y); |
87 | } |
88 | |
89 | static void |
90 | gtk_css_value_corner_print (const GtkCssValue *corner, |
91 | GString *string) |
92 | { |
93 | _gtk_css_value_print (value: corner->x, string); |
94 | if (!_gtk_css_value_equal (value1: corner->x, value2: corner->y)) |
95 | { |
96 | g_string_append_c (string, ' '); |
97 | _gtk_css_value_print (value: corner->y, string); |
98 | } |
99 | } |
100 | |
101 | static const GtkCssValueClass GTK_CSS_VALUE_CORNER = { |
102 | "GtkCssCornerValue" , |
103 | gtk_css_value_corner_free, |
104 | gtk_css_value_corner_compute, |
105 | gtk_css_value_corner_equal, |
106 | gtk_css_value_corner_transition, |
107 | NULL, |
108 | NULL, |
109 | gtk_css_value_corner_print |
110 | }; |
111 | |
112 | GtkCssValue * |
113 | _gtk_css_corner_value_new (GtkCssValue *x, |
114 | GtkCssValue *y) |
115 | { |
116 | GtkCssValue *result; |
117 | |
118 | if (_gtk_css_value_equal (value1: x, value2: y)) |
119 | { |
120 | _gtk_css_value_unref (value: y); |
121 | return x; |
122 | } |
123 | |
124 | result = _gtk_css_value_new (GtkCssValue, >K_CSS_VALUE_CORNER); |
125 | result->x = x; |
126 | result->y = y; |
127 | |
128 | return result; |
129 | } |
130 | |
131 | GtkCssValue * |
132 | _gtk_css_corner_value_parse (GtkCssParser *parser) |
133 | { |
134 | GtkCssValue *x, *y; |
135 | |
136 | x = _gtk_css_number_value_parse (parser, |
137 | flags: GTK_CSS_POSITIVE_ONLY |
138 | | GTK_CSS_PARSE_PERCENT |
139 | | GTK_CSS_PARSE_LENGTH); |
140 | if (x == NULL) |
141 | return NULL; |
142 | |
143 | if (!gtk_css_number_value_can_parse (parser)) |
144 | y = _gtk_css_value_ref (value: x); |
145 | else |
146 | { |
147 | y = _gtk_css_number_value_parse (parser, |
148 | flags: GTK_CSS_POSITIVE_ONLY |
149 | | GTK_CSS_PARSE_PERCENT |
150 | | GTK_CSS_PARSE_LENGTH); |
151 | if (y == NULL) |
152 | { |
153 | _gtk_css_value_unref (value: x); |
154 | return NULL; |
155 | } |
156 | } |
157 | |
158 | return _gtk_css_corner_value_new (x, y); |
159 | } |
160 | |
161 | double |
162 | _gtk_css_corner_value_get_x (const GtkCssValue *corner, |
163 | double one_hundred_percent) |
164 | { |
165 | if (corner->class != >K_CSS_VALUE_CORNER) |
166 | return _gtk_css_number_value_get (number: corner, one_hundred_percent); |
167 | |
168 | g_return_val_if_fail (corner != NULL, 0.0); |
169 | g_return_val_if_fail (corner->class == >K_CSS_VALUE_CORNER, 0.0); |
170 | |
171 | return _gtk_css_number_value_get (number: corner->x, one_hundred_percent); |
172 | } |
173 | |
174 | double |
175 | _gtk_css_corner_value_get_y (const GtkCssValue *corner, |
176 | double one_hundred_percent) |
177 | { |
178 | if (corner->class != >K_CSS_VALUE_CORNER) |
179 | return _gtk_css_number_value_get (number: corner, one_hundred_percent); |
180 | |
181 | g_return_val_if_fail (corner != NULL, 0.0); |
182 | g_return_val_if_fail (corner->class == >K_CSS_VALUE_CORNER, 0.0); |
183 | |
184 | return _gtk_css_number_value_get (number: corner->y, one_hundred_percent); |
185 | } |
186 | |
187 | gboolean |
188 | gtk_css_corner_value_is_zero (const GtkCssValue *corner) |
189 | { |
190 | if (corner->class != >K_CSS_VALUE_CORNER) |
191 | return gtk_css_dimension_value_is_zero (value: corner); |
192 | |
193 | return gtk_css_dimension_value_is_zero (value: corner->x) && |
194 | gtk_css_dimension_value_is_zero (value: corner->y); |
195 | } |
196 | |