GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 21.1% 67 / 0 / 317
Functions: 23.1% 9 / 0 / 39
Branches: 6.3% 9 / 0 / 142

shumate/shumate-path-layer.c
Line Branch Exec Source
1 /*
2 * Copyright (C) 2008-2009 Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
3 * Copyright (C) 2011-2013 Jiri Techet <techet@gmail.com>
4 * Copyright (C) 2019 Marcus Lundblad <ml@update.uu.se>
5 *
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
15 *
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19 */
20
21 /**
22 * ShumatePathLayer:
23 *
24 * A layer displaying line path between inserted [iface@Location] objects
25 *
26 * This layer shows a connection between inserted objects implementing the
27 * [iface@Location] interface. This means that both [class@Marker]
28 * objects and [class@Coordinate] objects can be inserted into the layer.
29 * Of course, custom objects implementing the [iface@Location] interface
30 * can be used as well.
31 */
32
33 #include "shumate-path-layer.h"
34
35 #include "shumate-enum-types.h"
36
37 #include <gdk/gdk.h>
38 #include <gtk/gtk.h>
39 #include <glib.h>
40
41 enum
42 {
43 PROP_CLOSED_PATH = 1,
44 PROP_STROKE_WIDTH,
45 PROP_STROKE_COLOR,
46 PROP_FILL,
47 PROP_FILL_COLOR,
48 PROP_STROKE,
49 PROP_OUTLINE_WIDTH,
50 PROP_OUTLINE_COLOR,
51 N_PROPERTIES
52 };
53
54 static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
55
56 static GdkRGBA DEFAULT_FILL_COLOR = { 0.8, 0.0, 0.0, 0.67 };
57 static GdkRGBA DEFAULT_STROKE_COLOR = { 0.64, 0.0, 0.0, 1.0 };
58 static GdkRGBA DEFAULT_OUTLINE_COLOR = { 1.0, 0.8, 0.8, 1.0 };
59
60 struct _ShumatePathLayer
61 {
62 ShumateLayer parent_instance;
63
64 gboolean closed_path;
65 GdkRGBA *stroke_color;
66 gboolean fill;
67 GdkRGBA *fill_color;
68 gboolean stroke;
69 double stroke_width;
70 GdkRGBA *outline_color;
71 double outline_width;
72 GArray *dashes; /* float */
73
74 GList *nodes; /* ShumateLocation */
75 };
76
77
4/6
shumate_path_layer_class_intern_init:
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 2 times.
shumate_path_layer_get_type:
✓ Branch 2 → 3 taken 2 times.
✓ Branch 2 → 7 taken 5 times.
✓ Branch 4 → 5 taken 2 times.
✗ Branch 4 → 7 not taken.
11 G_DEFINE_TYPE (ShumatePathLayer, shumate_path_layer, SHUMATE_TYPE_LAYER);
78
79 static void
80 ✗ on_viewport_changed (ShumatePathLayer *self,
81 GParamSpec *pspec,
82 ShumateViewport *view)
83 {
84 ✗ g_assert (SHUMATE_IS_PATH_LAYER (self));
85
86 ✗ gtk_widget_queue_draw (GTK_WIDGET (self));
87 ✗ }
88
89
90 static void
91 ✗ shumate_path_layer_get_property (GObject *object,
92 guint property_id,
93 G_GNUC_UNUSED GValue *value,
94 GParamSpec *pspec)
95 {
96 ✗ ShumatePathLayer *self = SHUMATE_PATH_LAYER (object);
97
98 ✗ switch (property_id)
99 {
100 ✗ case PROP_CLOSED_PATH:
101 ✗ g_value_set_boolean (value, self->closed_path);
102 ✗ break;
103
104 ✗ case PROP_FILL:
105 ✗ g_value_set_boolean (value, self->fill);
106 ✗ break;
107
108 ✗ case PROP_STROKE:
109 ✗ g_value_set_boolean (value, self->stroke);
110 ✗ break;
111
112 ✗ case PROP_FILL_COLOR:
113 ✗ g_value_set_boxed (value, self->fill_color);
114 ✗ break;
115
116 ✗ case PROP_STROKE_COLOR:
117 ✗ g_value_set_boxed (value, self->stroke_color);
118 ✗ break;
119
120 ✗ case PROP_STROKE_WIDTH:
121 ✗ g_value_set_double (value, self->stroke_width);
122 ✗ break;
123
124 ✗ case PROP_OUTLINE_COLOR:
125 ✗ g_value_set_boxed (value, self->outline_color);
126 ✗ break;
127
128 ✗ case PROP_OUTLINE_WIDTH:
129 ✗ g_value_set_double (value, self->outline_width);
130 ✗ break;
131
132 ✗ default:
133 ✗ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
134 }
135 ✗ }
136
137
138 static void
139 ✗ shumate_path_layer_set_property (GObject *object,
140 guint property_id,
141 const GValue *value,
142 GParamSpec *pspec)
143 {
144 ✗ switch (property_id)
145 {
146 ✗ case PROP_CLOSED_PATH:
147 ✗ shumate_path_layer_set_closed (SHUMATE_PATH_LAYER (object),
148 g_value_get_boolean (value));
149 ✗ break;
150
151 ✗ case PROP_FILL:
152 ✗ shumate_path_layer_set_fill (SHUMATE_PATH_LAYER (object),
153 g_value_get_boolean (value));
154 ✗ break;
155
156 ✗ case PROP_STROKE:
157 ✗ shumate_path_layer_set_stroke (SHUMATE_PATH_LAYER (object),
158 g_value_get_boolean (value));
159 ✗ break;
160
161 ✗ case PROP_FILL_COLOR:
162 ✗ shumate_path_layer_set_fill_color (SHUMATE_PATH_LAYER (object),
163 ✗ g_value_get_boxed (value));
164 ✗ break;
165
166 ✗ case PROP_STROKE_COLOR:
167 ✗ shumate_path_layer_set_stroke_color (SHUMATE_PATH_LAYER (object),
168 ✗ g_value_get_boxed (value));
169 ✗ break;
170
171 ✗ case PROP_STROKE_WIDTH:
172 ✗ shumate_path_layer_set_stroke_width (SHUMATE_PATH_LAYER (object),
173 ✗ g_value_get_double (value));
174 ✗ break;
175
176 ✗ case PROP_OUTLINE_COLOR:
177 ✗ shumate_path_layer_set_outline_color (SHUMATE_PATH_LAYER (object),
178 ✗ g_value_get_boxed (value));
179 ✗ break;
180
181 ✗ case PROP_OUTLINE_WIDTH:
182 ✗ shumate_path_layer_set_outline_width (SHUMATE_PATH_LAYER (object),
183 ✗ g_value_get_double (value));
184 ✗ break;
185
186 ✗ default:
187 ✗ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
188 }
189 ✗ }
190
191
192 static void
193 4 shumate_path_layer_dispose (GObject *object)
194 {
195 4 ShumatePathLayer *self = SHUMATE_PATH_LAYER (object);
196 4 ShumateViewport *viewport = shumate_layer_get_viewport (SHUMATE_LAYER (self));
197
198 4 g_signal_handlers_disconnect_by_data (viewport, self);
199
200
1/2
✗ Branch 4 → 5 not taken.
✓ Branch 4 → 6 taken 4 times.
4 if (self->nodes)
201 ✗ shumate_path_layer_remove_all (SHUMATE_PATH_LAYER (object));
202
203 4 G_OBJECT_CLASS (shumate_path_layer_parent_class)->dispose (object);
204 4 }
205
206 static void
207 6 shumate_path_layer_constructed (GObject *object)
208 {
209 6 ShumatePathLayer *self = SHUMATE_PATH_LAYER (object);
210 6 ShumateViewport *viewport;
211
212 6 G_OBJECT_CLASS (shumate_path_layer_parent_class)->constructed (object);
213
214 6 viewport = shumate_layer_get_viewport (SHUMATE_LAYER (self));
215 6 g_signal_connect_swapped (viewport, "notify", G_CALLBACK (on_viewport_changed), self);
216 6 }
217
218
219 static void
220 4 shumate_path_layer_finalize (GObject *object)
221 {
222 4 ShumatePathLayer *self = SHUMATE_PATH_LAYER (object);
223
224
1/2
✓ Branch 2 → 3 taken 4 times.
✗ Branch 2 → 4 not taken.
4 g_clear_pointer (&self->stroke_color, gdk_rgba_free);
225
1/2
✓ Branch 4 → 5 taken 4 times.
✗ Branch 4 → 6 not taken.
4 g_clear_pointer (&self->outline_color, gdk_rgba_free);
226
1/2
✓ Branch 6 → 7 taken 4 times.
✗ Branch 6 → 8 not taken.
4 g_clear_pointer (&self->fill_color, gdk_rgba_free);
227
1/2
✓ Branch 8 → 9 taken 4 times.
✗ Branch 8 → 10 not taken.
4 g_clear_pointer (&self->dashes, g_array_unref);
228
229 4 G_OBJECT_CLASS (shumate_path_layer_parent_class)->finalize (object);
230 4 }
231
232 static void
233 ✗ shumate_path_layer_snapshot (GtkWidget *widget,
234 GtkSnapshot *snapshot)
235 {
236 ✗ ShumatePathLayer *self = (ShumatePathLayer *)widget;
237 ✗ ShumateViewport *viewport;
238 ✗ g_autoptr(GskPathBuilder) builder = NULL;
239 ✗ g_autoptr(GskPath) path = NULL;
240 ✗ int width, height;
241 ✗ gboolean first = TRUE;
242 ✗ GList *elem;
243
244 ✗ width = gtk_widget_get_width (widget);
245 ✗ height = gtk_widget_get_height (widget);
246 ✗ viewport = shumate_layer_get_viewport (SHUMATE_LAYER (self));
247
248 ✗ if (!gtk_widget_get_visible (widget) || width <= 0 || height <= 0)
249 return;
250
251 ✗ builder = gsk_path_builder_new ();
252 ✗ for (elem = self->nodes; elem != NULL; elem = elem->next)
253 {
254 ✗ ShumateLocation *location = SHUMATE_LOCATION (elem->data);
255 ✗ double x, y, lat, lon;
256
257 ✗ lat = shumate_location_get_latitude (location);
258 ✗ lon = shumate_location_get_longitude (location);
259 ✗ shumate_viewport_location_to_widget_coords (viewport, widget, lat, lon, &x, &y);
260
261 ✗ if (first)
262 {
263 ✗ gsk_path_builder_move_to (builder, x, y);
264 ✗ first = FALSE;
265 }
266 else
267 {
268 ✗ gsk_path_builder_line_to (builder, x, y);
269 }
270 }
271
272 ✗ if (first)
273 ✗ return;
274
275 ✗ if (self->closed_path)
276 ✗ gsk_path_builder_close (builder);
277
278 ✗ path = gsk_path_builder_free_to_path (g_steal_pointer (&builder));
279
280 ✗ if (self->fill)
281 ✗ gtk_snapshot_append_fill (snapshot, path,
282 GSK_FILL_RULE_WINDING,
283 ✗ self->fill_color);
284
285 ✗ if (self->stroke)
286 {
287 /* width of the backgroud-colored part of the stroke,
288 * will be reduced by the outline, when that is set (non-zero)
289 */
290 ✗ double inner_width = self->stroke_width - 2 * self->outline_width;
291
292 ✗ if (self->outline_width > 0)
293 {
294 ✗ g_autoptr(GskStroke) stroke = gsk_stroke_new (self->stroke_width);
295
296 ✗ gsk_stroke_set_line_join (stroke, GSK_LINE_JOIN_BEVEL);
297 ✗ gsk_stroke_set_dash (stroke,
298 ✗ (const float *) self->dashes->data,
299 ✗ self->dashes->len);
300
301 ✗ gtk_snapshot_append_stroke (snapshot, path, stroke,
302 ✗ self->outline_color);
303 }
304
305 ✗ if (inner_width > 0)
306 {
307 ✗ g_autoptr(GskStroke) stroke = gsk_stroke_new (inner_width);
308
309 ✗ gsk_stroke_set_line_join (stroke, GSK_LINE_JOIN_BEVEL);
310 ✗ gsk_stroke_set_dash (stroke,
311 ✗ (const float *) self->dashes->data,
312 ✗ self->dashes->len);
313
314 ✗ gtk_snapshot_append_stroke (snapshot, path, stroke,
315 ✗ self->stroke_color);
316 }
317 }
318 }
319
320 static char *
321 ✗ shumate_path_layer_get_debug_text (ShumateLayer *layer)
322 {
323 ✗ ShumatePathLayer *self = SHUMATE_PATH_LAYER (layer);
324 ✗ return g_strdup_printf ("%d nodes", g_list_length (self->nodes));
325 }
326
327 static void
328 2 shumate_path_layer_class_init (ShumatePathLayerClass *klass)
329 {
330 2 GObjectClass *object_class = G_OBJECT_CLASS (klass);
331 2 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
332 2 ShumateLayerClass *layer_class = SHUMATE_LAYER_CLASS (klass);
333
334 2 object_class->finalize = shumate_path_layer_finalize;
335 2 object_class->dispose = shumate_path_layer_dispose;
336 2 object_class->constructed = shumate_path_layer_constructed;
337 2 object_class->get_property = shumate_path_layer_get_property;
338 2 object_class->set_property = shumate_path_layer_set_property;
339
340 2 widget_class->snapshot = shumate_path_layer_snapshot;
341
342 2 layer_class->get_debug_text = shumate_path_layer_get_debug_text;
343
344 /**
345 * ShumatePathLayer:closed:
346 *
347 * The shape is a closed path
348 */
349 4 obj_properties[PROP_CLOSED_PATH] =
350 2 g_param_spec_boolean ("closed", NULL, NULL,
351 FALSE,
352 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
353
354 /**
355 * ShumatePathLayer:fill:
356 *
357 * The shape should be filled
358 */
359 4 obj_properties[PROP_FILL] =
360 2 g_param_spec_boolean ("fill", NULL, NULL,
361 FALSE,
362 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
363
364 /**
365 * ShumatePathLayer:stroke:
366 *
367 * The shape should be stroked
368 */
369 4 obj_properties[PROP_STROKE] =
370 2 g_param_spec_boolean ("stroke", NULL, NULL,
371 TRUE,
372 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
373
374 /**
375 * ShumatePathLayer:stroke-color:
376 *
377 * The path's stroke color
378 */
379 4 obj_properties[PROP_STROKE_COLOR] =
380 2 g_param_spec_boxed ("stroke-color", NULL, NULL,
381 GDK_TYPE_RGBA,
382 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
383
384 /**
385 * ShumatePathLayer:fill-color:
386 *
387 * The path's fill color
388 */
389 4 obj_properties[PROP_FILL_COLOR] =
390 2 g_param_spec_boxed ("fill-color", NULL, NULL,
391 GDK_TYPE_RGBA,
392 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
393
394 /**
395 * ShumatePathLayer:stroke-width:
396 *
397 * The path's stroke width (in pixels)
398 */
399 4 obj_properties[PROP_STROKE_WIDTH] =
400 2 g_param_spec_double ("stroke-width", NULL, NULL,
401 0,
402 100.0,
403 2.0,
404 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
405
406 /**
407 * ShumatePathLayer:outline-color:
408 *
409 * The path's outline color
410 */
411 4 obj_properties[PROP_OUTLINE_COLOR] =
412 2 g_param_spec_boxed ("outline-color", NULL, NULL,
413 GDK_TYPE_RGBA,
414 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
415
416 /**
417 * ShumatePathLayer:outline-width:
418 *
419 * The path's outline width (in pixels)
420 */
421 4 obj_properties[PROP_OUTLINE_WIDTH] =
422 2 g_param_spec_double ("outline-width", NULL, NULL,
423 0,
424 50.0,
425 0.0,
426 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
427
428 2 g_object_class_install_properties (object_class,
429 N_PROPERTIES,
430 obj_properties);
431 2 }
432
433 static void
434 6 shumate_path_layer_init (ShumatePathLayer *self)
435 {
436 6 self->fill = FALSE;
437 6 self->stroke = TRUE;
438 6 self->stroke_width = 2.0;
439 6 self->outline_width = 0.0;
440 6 self->nodes = NULL;
441 6 self->dashes = g_array_new (FALSE, TRUE, sizeof(float));
442
443 6 self->fill_color = gdk_rgba_copy (&DEFAULT_FILL_COLOR);
444 6 self->stroke_color = gdk_rgba_copy (&DEFAULT_STROKE_COLOR);
445 6 self->outline_color = gdk_rgba_copy (&DEFAULT_OUTLINE_COLOR);
446 6 }
447
448 /**
449 * shumate_path_layer_new:
450 * @viewport: the [class@Viewport]
451 *
452 * Creates a new instance of [class@PathLayer].
453 *
454 * Returns: a new instance of [class@PathLayer].
455 */
456 ShumatePathLayer *
457 6 shumate_path_layer_new (ShumateViewport *viewport)
458 {
459 6 return g_object_new (SHUMATE_TYPE_PATH_LAYER,
460 "viewport", viewport,
461 NULL);
462 }
463
464 static void
465 ✗ position_notify (ShumateLocation *location,
466 GParamSpec *pspec,
467 ShumatePathLayer *self)
468 {
469 ✗ gtk_widget_queue_draw (GTK_WIDGET (self));
470 ✗ }
471
472 static void
473 ✗ add_node (ShumatePathLayer *self,
474 ShumateLocation *location,
475 gboolean prepend,
476 guint position)
477 {
478 ✗ g_signal_connect (G_OBJECT (location), "notify::latitude", G_CALLBACK (position_notify), self);
479
480 ✗ if (prepend)
481 ✗ self->nodes = g_list_prepend (self->nodes, g_object_ref_sink (location));
482 else
483 ✗ self->nodes = g_list_insert (self->nodes, g_object_ref_sink (location), position);
484
485 ✗ gtk_widget_queue_draw (GTK_WIDGET (self));
486 ✗ }
487
488
489 /**
490 * shumate_path_layer_add_node:
491 * @self: a [class@PathLayer]
492 * @location: a [iface@Location]
493 *
494 * Adds a [iface@Location] object to the layer.
495 * The node is prepended to the list.
496 */
497 void
498 ✗ shumate_path_layer_add_node (ShumatePathLayer *self,
499 ShumateLocation *location)
500 {
501 ✗ g_return_if_fail (SHUMATE_IS_PATH_LAYER (self));
502 ✗ g_return_if_fail (SHUMATE_IS_LOCATION (location));
503
504 ✗ add_node (self, location, TRUE, 0);
505 }
506
507
508 /**
509 * shumate_path_layer_remove_all:
510 * @self: a [class@PathLayer]
511 *
512 * Removes all [iface@Location] objects from the layer.
513 */
514 void
515 ✗ shumate_path_layer_remove_all (ShumatePathLayer *self)
516 {
517 ✗ GList *elem;
518
519 ✗ g_return_if_fail (SHUMATE_IS_PATH_LAYER (self));
520
521 ✗ for (elem = self->nodes; elem != NULL; elem = elem->next)
522 {
523 ✗ GObject *node = G_OBJECT (elem->data);
524
525 ✗ g_signal_handlers_disconnect_by_func (node,
526 G_CALLBACK (position_notify), self);
527
528 ✗ g_object_unref (node);
529 }
530
531 ✗ g_clear_pointer (&self->nodes, g_list_free);
532 ✗ gtk_widget_queue_draw (GTK_WIDGET (self));
533 }
534
535
536 /**
537 * shumate_path_layer_get_nodes:
538 * @self: a [class@PathLayer]
539 *
540 * Gets a copy of the list of all [iface@Location] objects inserted into the layer. You should
541 * free the list but not its contents.
542 *
543 * Returns: (transfer container) (element-type ShumateLocation): the list
544 */
545 GList *
546 ✗ shumate_path_layer_get_nodes (ShumatePathLayer *self)
547 {
548 ✗ GList *lst;
549
550 ✗ g_return_val_if_fail (SHUMATE_IS_PATH_LAYER (self), NULL);
551
552 ✗ lst = g_list_copy (self->nodes);
553 ✗ return g_list_reverse (lst);
554 }
555
556 /**
557 * shumate_path_layer_remove_node:
558 * @self: a [class@PathLayer]
559 * @location: a [iface@Location]
560 *
561 * Removes the [iface@Location] object from the layer.
562 */
563 void
564 ✗ shumate_path_layer_remove_node (ShumatePathLayer *self,
565 ShumateLocation *location)
566 {
567 ✗ g_return_if_fail (SHUMATE_IS_PATH_LAYER (self));
568 ✗ g_return_if_fail (SHUMATE_IS_LOCATION (location));
569
570 ✗ g_signal_handlers_disconnect_by_func (G_OBJECT (location), G_CALLBACK (position_notify), self);
571
572 ✗ self->nodes = g_list_remove (self->nodes, location);
573 ✗ g_object_unref (location);
574 ✗ gtk_widget_queue_draw (GTK_WIDGET (self));
575 }
576
577 /**
578 * shumate_path_layer_insert_node:
579 * @self: a [class@PathLayer]
580 * @location: a [iface@Location]
581 * @position: position in the list where the [iface@Location] object should be inserted
582 *
583 * Inserts a [iface@Location] object to the specified position.
584 */
585 void
586 ✗ shumate_path_layer_insert_node (ShumatePathLayer *self,
587 ShumateLocation *location,
588 guint position)
589 {
590 ✗ g_return_if_fail (SHUMATE_IS_PATH_LAYER (self));
591 ✗ g_return_if_fail (SHUMATE_IS_LOCATION (location));
592
593 ✗ add_node (self, location, FALSE, position);
594 }
595
596 /**
597 * shumate_path_layer_set_fill_color:
598 * @self: a [class@PathLayer]
599 * @color: (nullable): The path's fill color or %NULL to reset to the
600 * default color. The color parameter is copied.
601 *
602 * Set the path's fill color.
603 */
604 void
605 ✗ shumate_path_layer_set_fill_color (ShumatePathLayer *self,
606 const GdkRGBA *color)
607 {
608 ✗ g_return_if_fail (SHUMATE_IS_PATH_LAYER (self));
609
610 ✗ if (self->fill_color != NULL)
611 ✗ gdk_rgba_free (self->fill_color);
612
613 ✗ if (color == NULL)
614 ✗ color = &DEFAULT_FILL_COLOR;
615
616 ✗ self->fill_color = gdk_rgba_copy (color);
617 ✗ g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_FILL_COLOR]);
618
619 ✗ gtk_widget_queue_draw (GTK_WIDGET (self));
620 }
621
622
623 /**
624 * shumate_path_layer_get_fill_color:
625 * @self: a [class@PathLayer]
626 *
627 * Gets the path's fill color.
628 *
629 * Returns: the path's fill color.
630 */
631 GdkRGBA *
632 ✗ shumate_path_layer_get_fill_color (ShumatePathLayer *self)
633 {
634 ✗ g_return_val_if_fail (SHUMATE_IS_PATH_LAYER (self), NULL);
635
636 ✗ return self->fill_color;
637 }
638
639
640 /**
641 * shumate_path_layer_set_stroke_color:
642 * @self: a [class@PathLayer]
643 * @color: (nullable): The path's stroke color or %NULL to reset to the
644 * default color. The color parameter is copied.
645 *
646 * Set the path's stroke color.
647 */
648 void
649 ✗ shumate_path_layer_set_stroke_color (ShumatePathLayer *self,
650 const GdkRGBA *color)
651 {
652 ✗ g_return_if_fail (SHUMATE_IS_PATH_LAYER (self));
653
654 ✗ if (self->stroke_color != NULL)
655 ✗ gdk_rgba_free (self->stroke_color);
656
657 ✗ if (color == NULL)
658 ✗ color = &DEFAULT_STROKE_COLOR;
659
660 ✗ self->stroke_color = gdk_rgba_copy (color);
661 ✗ g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_STROKE_COLOR]);
662
663 ✗ gtk_widget_queue_draw (GTK_WIDGET (self));
664 }
665
666
667 /**
668 * shumate_path_layer_get_stroke_color:
669 * @self: a [class@PathLayer]
670 *
671 * Gets the path's stroke color.
672 *
673 * Returns: the path's stroke color.
674 */
675 GdkRGBA *
676 ✗ shumate_path_layer_get_stroke_color (ShumatePathLayer *self)
677 {
678 ✗ g_return_val_if_fail (SHUMATE_IS_PATH_LAYER (self), NULL);
679
680 ✗ return self->stroke_color;
681 }
682
683 /**
684 * shumate_path_layer_set_outline_color:
685 * @self: a [class@PathLayer]
686 * @color: (nullable): The path's outline color or %NULL to reset to the
687 * default color. The color parameter is copied.
688 *
689 * Set the path's outline color.
690 */
691 void
692 ✗ shumate_path_layer_set_outline_color (ShumatePathLayer *self,
693 const GdkRGBA *color)
694 {
695 ✗ g_return_if_fail (SHUMATE_IS_PATH_LAYER (self));
696
697 ✗ if (self->outline_color != NULL)
698 ✗ gdk_rgba_free (self->outline_color);
699
700 ✗ if (color == NULL)
701 ✗ color = &DEFAULT_OUTLINE_COLOR;
702
703 ✗ self->outline_color = gdk_rgba_copy (color);
704 ✗ g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_OUTLINE_COLOR]);
705
706 ✗ gtk_widget_queue_draw (GTK_WIDGET (self));
707 }
708
709 /**
710 * shumate_path_layer_get_outline_color:
711 * @self: a [class@PathLayer]
712 *
713 * Gets the path's outline color.
714 *
715 * Returns: the path's outline color.
716 */
717 GdkRGBA *
718 ✗ shumate_path_layer_get_outline_color (ShumatePathLayer *self)
719 {
720 ✗ g_return_val_if_fail (SHUMATE_IS_PATH_LAYER (self), NULL);
721
722 ✗ return self->outline_color;
723 }
724
725 /**
726 * shumate_path_layer_set_stroke:
727 * @self: a [class@PathLayer]
728 * @value: if the path is stroked
729 *
730 * Sets the path to be stroked
731 */
732 void
733 ✗ shumate_path_layer_set_stroke (ShumatePathLayer *self,
734 gboolean value)
735 {
736 ✗ g_return_if_fail (SHUMATE_IS_PATH_LAYER (self));
737
738 ✗ self->stroke = value;
739 ✗ g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_STROKE]);
740
741 ✗ gtk_widget_queue_draw (GTK_WIDGET (self));
742 }
743
744
745 /**
746 * shumate_path_layer_get_stroke:
747 * @self: a [class@PathLayer]
748 *
749 * Checks whether the path is stroked.
750 *
751 * Returns: %TRUE if the path is stroked, %FALSE otherwise.
752 */
753 gboolean
754 ✗ shumate_path_layer_get_stroke (ShumatePathLayer *self)
755 {
756 ✗ g_return_val_if_fail (SHUMATE_IS_PATH_LAYER (self), FALSE);
757
758 ✗ return self->stroke;
759 }
760
761
762 /**
763 * shumate_path_layer_set_fill:
764 * @self: a [class@PathLayer]
765 * @value: if the path is filled
766 *
767 * Sets the path to be filled
768 */
769 void
770 ✗ shumate_path_layer_set_fill (ShumatePathLayer *self,
771 gboolean value)
772 {
773 ✗ g_return_if_fail (SHUMATE_IS_PATH_LAYER (self));
774
775 ✗ self->fill = value;
776 ✗ g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_FILL]);
777
778 ✗ gtk_widget_queue_draw (GTK_WIDGET (self));
779 }
780
781
782 /**
783 * shumate_path_layer_get_fill:
784 * @self: a [class@PathLayer]
785 *
786 * Checks whether the path is filled.
787 *
788 * Returns: %TRUE if the path is filled, %FALSE otherwise.
789 */
790 gboolean
791 ✗ shumate_path_layer_get_fill (ShumatePathLayer *self)
792 {
793 ✗ g_return_val_if_fail (SHUMATE_IS_PATH_LAYER (self), FALSE);
794
795 ✗ return self->fill;
796 }
797
798
799 /**
800 * shumate_path_layer_set_stroke_width:
801 * @self: a [class@PathLayer]
802 * @value: the width of the stroke (in pixels)
803 *
804 * Sets the width of the stroke
805 */
806 void
807 ✗ shumate_path_layer_set_stroke_width (ShumatePathLayer *self,
808 double value)
809 {
810 ✗ g_return_if_fail (SHUMATE_IS_PATH_LAYER (self));
811
812 ✗ self->stroke_width = value;
813 ✗ g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_STROKE_WIDTH]);
814
815 ✗ gtk_widget_queue_draw (GTK_WIDGET (self));
816 }
817
818
819 /**
820 * shumate_path_layer_get_stroke_width:
821 * @self: a [class@PathLayer]
822 *
823 * Gets the width of the stroke.
824 *
825 * Returns: the width of the stroke
826 */
827 double
828 ✗ shumate_path_layer_get_stroke_width (ShumatePathLayer *self)
829 {
830 ✗ g_return_val_if_fail (SHUMATE_IS_PATH_LAYER (self), 0);
831
832 ✗ return self->stroke_width;
833 }
834
835 /**
836 * shumate_path_layer_set_outline_width:
837 * @self: a [class@PathLayer]
838 * @value: the width of the outline (in pixels)
839 *
840 * Sets the width of the outline
841 */
842 void
843 ✗ shumate_path_layer_set_outline_width (ShumatePathLayer *self,
844 double value)
845 {
846 ✗ g_return_if_fail (SHUMATE_IS_PATH_LAYER (self));
847
848 ✗ self->outline_width = value;
849 ✗ g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_OUTLINE_WIDTH]);
850
851 ✗ gtk_widget_queue_draw (GTK_WIDGET (self));
852 }
853
854
855 /**
856 * shumate_path_layer_get_outline_width:
857 * @self: a [class@PathLayer]
858 *
859 * Gets the width of the outline.
860 *
861 * Returns: the width of the outline
862 */
863 double
864 ✗ shumate_path_layer_get_outline_width (ShumatePathLayer *self)
865 {
866 ✗ g_return_val_if_fail (SHUMATE_IS_PATH_LAYER (self), 0);
867
868 ✗ return self->outline_width;
869 }
870
871 /**
872 * shumate_path_layer_set_closed:
873 * @self: a [class@PathLayer]
874 * @value: %TRUE to make the path closed
875 *
876 * Makes the path closed.
877 */
878 void
879 ✗ shumate_path_layer_set_closed (ShumatePathLayer *self,
880 gboolean value)
881 {
882 ✗ g_return_if_fail (SHUMATE_IS_PATH_LAYER (self));
883
884 ✗ self->closed_path = value;
885 ✗ g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_CLOSED_PATH]);
886
887 ✗ gtk_widget_queue_draw (GTK_WIDGET (self));
888 }
889
890
891 /**
892 * shumate_path_layer_get_closed:
893 * @self: a [class@PathLayer]
894 *
895 * Gets information whether the path is closed.
896 *
897 * Returns: %TRUE when the path is closed, %FALSE otherwise
898 */
899 gboolean
900 ✗ shumate_path_layer_get_closed (ShumatePathLayer *self)
901 {
902 ✗ g_return_val_if_fail (SHUMATE_IS_PATH_LAYER (self), FALSE);
903
904 ✗ return self->closed_path;
905 }
906
907
908 /**
909 * shumate_path_layer_set_dash:
910 * @self: a [class@PathLayer]
911 * @dash_pattern: (element-type guint) (nullable): list of integer values
912 * representing lengths of dashes/spaces
913 *
914 * Sets dashed line pattern in a way similar to gsk_stroke_set_dash(). This
915 * method supports only integer values for segment lengths. The values have to be
916 * passed inside the data pointer of the list (using the %GUINT_TO_POINTER conversion)
917 *
918 * Pass %NULL to use solid line.
919 */
920 void
921 ✗ shumate_path_layer_set_dash (ShumatePathLayer *self,
922 GList *dash_pattern)
923 {
924 ✗ GList *iter = NULL;
925
926 ✗ g_return_if_fail (SHUMATE_IS_PATH_LAYER (self));
927
928 ✗ g_array_set_size (self->dashes, 0);
929 ✗ if (dash_pattern == NULL)
930 return;
931
932 ✗ for (iter = dash_pattern; iter != NULL; iter = iter->next)
933 {
934 ✗ float val = (float) GPOINTER_TO_UINT (iter->data);
935 ✗ g_array_append_val (self->dashes, val);
936 }
937 }
938
939
940 /**
941 * shumate_path_layer_get_dash:
942 * @self: a [class@PathLayer]
943 *
944 * Returns the list of dash segment lengths.
945 *
946 * Returns: (transfer full) (element-type guint) (nullable): the list
947 */
948 GList *
949 ✗ shumate_path_layer_get_dash (ShumatePathLayer *self)
950 {
951 ✗ GList *list = NULL;
952 ✗ guint i;
953
954 ✗ g_return_val_if_fail (SHUMATE_IS_PATH_LAYER (self), NULL);
955
956 ✗ for (i = 0; i < self->dashes->len; i++)
957 ✗ list = g_list_append (list, GUINT_TO_POINTER ((guint) g_array_index (self->dashes, float, i)));
958
959 return list;
960 }
961