Branch data Line data Source code
1 : : /*
2 : : * Copyright (C) 2008-2009 Pierre-Luc Beaudoin <pierre-luc@pierlux.com>
3 : : * Copyright (C) 2010-2013 Jiri Techet <techet@gmail.com>
4 : : * Copyright (C) 2019 Marcus Lundblad <ml@update.uu.se>
5 : : * Copyright (C) 2020 Collabora, Ltd. (https://www.collabora.com)
6 : : * Copyright (C) 2020 Corentin Noël <corentin.noel@collabora.com>
7 : : *
8 : : * This library is free software; you can redistribute it and/or
9 : : * modify it under the terms of the GNU Lesser General Public
10 : : * License as published by the Free Software Foundation; either
11 : : * version 2.1 of the License, or (at your option) any later version.
12 : : *
13 : : * This library is distributed in the hope that it will be useful,
14 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 : : * Lesser General Public License for more details.
17 : : *
18 : : * You should have received a copy of the GNU Lesser General Public
19 : : * License along with this library; if not, write to the Free Software
20 : : * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21 : : */
22 : :
23 : : /**
24 : : * ShumateTile:
25 : : *
26 : : * An object that represents map tiles. Tiles are loaded by a [class@MapSource].
27 : : */
28 : :
29 : : #include "shumate-tile.h"
30 : :
31 : : #include "shumate-enum-types.h"
32 : : #include "shumate-marshal.h"
33 : :
34 : : #include <math.h>
35 : : #include <gdk/gdk.h>
36 : : #include <gio/gio.h>
37 : :
38 : : struct _ShumateTile
39 : : {
40 : : GObject parent_instance;
41 : :
42 : : guint x; /* The x position on the map (in pixels) */
43 : : guint y; /* The y position on the map (in pixels) */
44 : : guint size; /* The tile's width and height (only support square tiles */
45 : : guint zoom_level; /* The tile's zoom level */
46 : :
47 : : ShumateState state; /* The tile state: loading, validation, done */
48 : : gboolean fade_in;
49 : :
50 : : double scale_factor;
51 : :
52 : : GdkPaintable *paintable;
53 : : GPtrArray *symbols;
54 : : };
55 : :
56 [ + + + - ]: 225 : G_DEFINE_TYPE (ShumateTile, shumate_tile, G_TYPE_OBJECT);
57 : :
58 : : enum
59 : : {
60 : : PROP_X = 1,
61 : : PROP_Y,
62 : : PROP_ZOOM_LEVEL,
63 : : PROP_SIZE,
64 : : PROP_STATE,
65 : : PROP_FADE_IN,
66 : : PROP_PAINTABLE,
67 : : PROP_SCALE_FACTOR,
68 : : N_PROPERTIES
69 : : };
70 : :
71 : : static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
72 : :
73 : : static void
74 : 0 : shumate_tile_get_property (GObject *object,
75 : : guint property_id,
76 : : GValue *value,
77 : : GParamSpec *pspec)
78 : : {
79 : 0 : ShumateTile *self = SHUMATE_TILE (object);
80 : :
81 [ # # # # : 0 : switch (property_id)
# # # #
# ]
82 : : {
83 : 0 : case PROP_X:
84 : 0 : g_value_set_uint (value, shumate_tile_get_x (self));
85 : 0 : break;
86 : :
87 : 0 : case PROP_Y:
88 : 0 : g_value_set_uint (value, shumate_tile_get_y (self));
89 : 0 : break;
90 : :
91 : 0 : case PROP_ZOOM_LEVEL:
92 : 0 : g_value_set_uint (value, shumate_tile_get_zoom_level (self));
93 : 0 : break;
94 : :
95 : 0 : case PROP_SIZE:
96 : 0 : g_value_set_uint (value, shumate_tile_get_size (self));
97 : 0 : break;
98 : :
99 : 0 : case PROP_STATE:
100 : 0 : g_value_set_enum (value, shumate_tile_get_state (self));
101 : 0 : break;
102 : :
103 : 0 : case PROP_FADE_IN:
104 : 0 : g_value_set_boolean (value, shumate_tile_get_fade_in (self));
105 : 0 : break;
106 : :
107 : 0 : case PROP_PAINTABLE:
108 : 0 : g_value_set_object (value, shumate_tile_get_paintable (self));
109 : 0 : break;
110 : :
111 : 0 : case PROP_SCALE_FACTOR:
112 : 0 : g_value_set_double (value, self->scale_factor);
113 : 0 : break;
114 : :
115 : 0 : default:
116 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
117 : : }
118 : 0 : }
119 : :
120 : :
121 : : static void
122 : 96 : shumate_tile_set_property (GObject *object,
123 : : guint property_id,
124 : : const GValue *value,
125 : : GParamSpec *pspec)
126 : : {
127 : 96 : ShumateTile *self = SHUMATE_TILE (object);
128 : :
129 [ + + + + : 96 : switch (property_id)
- - - -
- ]
130 : : {
131 : 24 : case PROP_X:
132 : 24 : shumate_tile_set_x (self, g_value_get_uint (value));
133 : 24 : break;
134 : :
135 : 24 : case PROP_Y:
136 : 24 : shumate_tile_set_y (self, g_value_get_uint (value));
137 : 24 : break;
138 : :
139 : 24 : case PROP_ZOOM_LEVEL:
140 : 24 : shumate_tile_set_zoom_level (self, g_value_get_uint (value));
141 : 24 : break;
142 : :
143 : 24 : case PROP_SIZE:
144 : 24 : shumate_tile_set_size (self, g_value_get_uint (value));
145 : 24 : break;
146 : :
147 : 0 : case PROP_STATE:
148 : 0 : shumate_tile_set_state (self, g_value_get_enum (value));
149 : 0 : break;
150 : :
151 : 0 : case PROP_FADE_IN:
152 : 0 : shumate_tile_set_fade_in (self, g_value_get_boolean (value));
153 : 0 : break;
154 : :
155 : 0 : case PROP_PAINTABLE:
156 : 0 : shumate_tile_set_paintable (self, g_value_get_object (value));
157 : 0 : break;
158 : :
159 : 0 : case PROP_SCALE_FACTOR:
160 : 0 : shumate_tile_set_scale_factor (self, g_value_get_double (value));
161 : 0 : break;
162 : :
163 : 0 : default:
164 : 0 : G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
165 : : }
166 : 96 : }
167 : :
168 : :
169 : : static void
170 : 24 : shumate_tile_dispose (GObject *object)
171 : : {
172 : 24 : ShumateTile *self = SHUMATE_TILE (object);
173 : :
174 [ + + ]: 24 : g_clear_object (&self->paintable);
175 [ - + ]: 24 : g_clear_pointer (&self->symbols, g_ptr_array_unref);
176 : :
177 : 24 : G_OBJECT_CLASS (shumate_tile_parent_class)->dispose (object);
178 : 24 : }
179 : :
180 : :
181 : : static void
182 : 7 : shumate_tile_class_init (ShumateTileClass *klass)
183 : : {
184 : 7 : GObjectClass *object_class = G_OBJECT_CLASS (klass);
185 : :
186 : 7 : object_class->get_property = shumate_tile_get_property;
187 : 7 : object_class->set_property = shumate_tile_set_property;
188 : 7 : object_class->dispose = shumate_tile_dispose;
189 : :
190 : : /**
191 : : * ShumateTile:x:
192 : : *
193 : : * The x position of the tile
194 : : */
195 : 14 : obj_properties[PROP_X] =
196 : 7 : g_param_spec_uint ("x",
197 : : "x",
198 : : "The X position of the tile",
199 : : 0,
200 : : G_MAXUINT,
201 : : 0,
202 : : G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
203 : :
204 : : /**
205 : : * ShumateTile:y:
206 : : *
207 : : * The y position of the tile
208 : : */
209 : 14 : obj_properties[PROP_Y] =
210 : 7 : g_param_spec_uint ("y",
211 : : "y",
212 : : "The Y position of the tile",
213 : : 0,
214 : : G_MAXUINT,
215 : : 0,
216 : : G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
217 : :
218 : : /**
219 : : * ShumateTile:zoom-level:
220 : : *
221 : : * The zoom level of the tile
222 : : */
223 : 14 : obj_properties[PROP_ZOOM_LEVEL] =
224 : 7 : g_param_spec_uint ("zoom-level",
225 : : "Zoom Level",
226 : : "The zoom level of the tile",
227 : : 0,
228 : : G_MAXUINT,
229 : : 0,
230 : : G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
231 : :
232 : : /**
233 : : * ShumateTile:size:
234 : : *
235 : : * The size of the tile in pixels
236 : : */
237 : 14 : obj_properties[PROP_SIZE] =
238 : 7 : g_param_spec_uint ("size",
239 : : "Size",
240 : : "The size of the tile",
241 : : 0,
242 : : G_MAXUINT,
243 : : 256,
244 : : G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
245 : :
246 : : /**
247 : : * ShumateTile:state:
248 : : *
249 : : * The state of the tile
250 : : */
251 : 14 : obj_properties[PROP_STATE] =
252 : 7 : g_param_spec_enum ("state",
253 : : "State",
254 : : "The state of the tile",
255 : : SHUMATE_TYPE_STATE,
256 : : SHUMATE_STATE_NONE,
257 : : G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
258 : :
259 : : /**
260 : : * ShumateTile:fade-in:
261 : : *
262 : : * Specifies whether the tile should fade in when loading
263 : : */
264 : 14 : obj_properties[PROP_FADE_IN] =
265 : 7 : g_param_spec_boolean ("fade-in",
266 : : "Fade In",
267 : : "Tile should fade in",
268 : : FALSE,
269 : : G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
270 : :
271 : : /**
272 : : * ShumateTile:paintable:
273 : : *
274 : : * The [iface@Gdk.Paintable] backing the tile
275 : : */
276 : 14 : obj_properties[PROP_PAINTABLE] =
277 : 7 : g_param_spec_object ("paintable",
278 : : "Paintable",
279 : : "Paintable",
280 : : GDK_TYPE_PAINTABLE,
281 : : G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
282 : :
283 : : /**
284 : : * ShumateTile:scale-factor:
285 : : *
286 : : * The scale factor of the widget the tile will be displayed in.
287 : : *
288 : : * Since: 1.1
289 : : */
290 : 14 : obj_properties[PROP_SCALE_FACTOR] =
291 : 7 : g_param_spec_double ("scale-factor",
292 : : "scale-factor",
293 : : "scale-factor",
294 : : G_MINDOUBLE, G_MAXDOUBLE, 1.0,
295 : : G_PARAM_READWRITE | G_PARAM_EXPLICIT_NOTIFY | G_PARAM_STATIC_STRINGS);
296 : :
297 : 7 : g_object_class_install_properties (object_class,
298 : : N_PROPERTIES,
299 : : obj_properties);
300 : 7 : }
301 : :
302 : :
303 : : static void
304 : 24 : shumate_tile_init (ShumateTile *self)
305 : : {
306 : 24 : self->state = SHUMATE_STATE_NONE;
307 : 24 : self->scale_factor = 1.0;
308 : 24 : }
309 : :
310 : : /**
311 : : * shumate_tile_new:
312 : : *
313 : : * Creates an instance of #ShumateTile.
314 : : *
315 : : * Returns: a new #ShumateTile
316 : : */
317 : : ShumateTile *
318 : 0 : shumate_tile_new (void)
319 : : {
320 : 0 : return g_object_new (SHUMATE_TYPE_TILE, NULL);
321 : : }
322 : :
323 : :
324 : : /**
325 : : * shumate_tile_new_full:
326 : : * @x: the x position
327 : : * @y: the y position
328 : : * @size: the size in pixels
329 : : * @zoom_level: the zoom level
330 : : *
331 : : * Creates an instance of #ShumateTile.
332 : : *
333 : : * Returns: a #ShumateTile
334 : : */
335 : : ShumateTile *
336 : 24 : shumate_tile_new_full (guint x,
337 : : guint y,
338 : : guint size,
339 : : guint zoom_level)
340 : : {
341 : 24 : return g_object_new (SHUMATE_TYPE_TILE,
342 : : "x", x,
343 : : "y", y,
344 : : "zoom-level", zoom_level,
345 : : "size", size,
346 : : NULL);
347 : : }
348 : :
349 : :
350 : : /**
351 : : * shumate_tile_get_x:
352 : : * @self: the #ShumateTile
353 : : *
354 : : * Gets the tile's x position.
355 : : *
356 : : * Returns: the tile's x position
357 : : */
358 : : guint
359 : 66 : shumate_tile_get_x (ShumateTile *self)
360 : : {
361 [ + - ]: 66 : g_return_val_if_fail (SHUMATE_TILE (self), 0);
362 : :
363 : 66 : return self->x;
364 : : }
365 : :
366 : :
367 : : /**
368 : : * shumate_tile_set_x:
369 : : * @self: the #ShumateTile
370 : : * @x: the position
371 : : *
372 : : * Sets the tile's x position
373 : : */
374 : : void
375 : 24 : shumate_tile_set_x (ShumateTile *self,
376 : : guint x)
377 : : {
378 [ + - ]: 24 : g_return_if_fail (SHUMATE_TILE (self));
379 : :
380 [ - + ]: 24 : if (self->x == x)
381 : : return;
382 : :
383 : 0 : self->x = x;
384 : 0 : g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_X]);
385 : : }
386 : :
387 : :
388 : : /**
389 : : * shumate_tile_get_y:
390 : : * @self: the #ShumateTile
391 : : *
392 : : * Gets the tile's y position.
393 : : *
394 : : * Returns: the tile's y position
395 : : */
396 : : guint
397 : 66 : shumate_tile_get_y (ShumateTile *self)
398 : : {
399 [ + - ]: 66 : g_return_val_if_fail (SHUMATE_TILE (self), 0);
400 : :
401 : 66 : return self->y;
402 : : }
403 : :
404 : :
405 : : /**
406 : : * shumate_tile_set_y:
407 : : * @self: the #ShumateTile
408 : : * @y: the position
409 : : *
410 : : * Sets the tile's y position
411 : : */
412 : : void
413 : 24 : shumate_tile_set_y (ShumateTile *self,
414 : : guint y)
415 : : {
416 [ + - ]: 24 : g_return_if_fail (SHUMATE_TILE (self));
417 : :
418 [ - + ]: 24 : if (self->y == y)
419 : : return;
420 : :
421 : 0 : self->y = y;
422 : 0 : g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_Y]);
423 : : }
424 : :
425 : :
426 : : /**
427 : : * shumate_tile_get_zoom_level:
428 : : * @self: the #ShumateTile
429 : : *
430 : : * Gets the tile's zoom level.
431 : : *
432 : : * Returns: the tile's zoom level
433 : : */
434 : : guint
435 : 66 : shumate_tile_get_zoom_level (ShumateTile *self)
436 : : {
437 [ + - ]: 66 : g_return_val_if_fail (SHUMATE_TILE (self), 0);
438 : :
439 : 66 : return self->zoom_level;
440 : : }
441 : :
442 : :
443 : : /**
444 : : * shumate_tile_set_zoom_level:
445 : : * @self: the #ShumateTile
446 : : * @zoom_level: the zoom level
447 : : *
448 : : * Sets the tile's zoom level
449 : : */
450 : : void
451 : 24 : shumate_tile_set_zoom_level (ShumateTile *self,
452 : : guint zoom_level)
453 : : {
454 [ + - ]: 24 : g_return_if_fail (SHUMATE_TILE (self));
455 : :
456 [ + + ]: 24 : if (self->zoom_level == zoom_level)
457 : : return;
458 : :
459 : 3 : self->zoom_level = zoom_level;
460 : 3 : g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_ZOOM_LEVEL]);
461 : : }
462 : :
463 : :
464 : : /**
465 : : * shumate_tile_get_size:
466 : : * @self: the #ShumateTile
467 : : *
468 : : * Gets the tile's size.
469 : : *
470 : : * Returns: the tile's size in pixels
471 : : */
472 : : guint
473 : 3 : shumate_tile_get_size (ShumateTile *self)
474 : : {
475 [ + - ]: 3 : g_return_val_if_fail (SHUMATE_TILE (self), 0);
476 : :
477 : 3 : return self->size;
478 : : }
479 : :
480 : :
481 : : /**
482 : : * shumate_tile_set_size:
483 : : * @self: the #ShumateTile
484 : : * @size: the size in pixels
485 : : *
486 : : * Sets the tile's size
487 : : */
488 : : void
489 : 24 : shumate_tile_set_size (ShumateTile *self,
490 : : guint size)
491 : : {
492 [ + - ]: 24 : g_return_if_fail (SHUMATE_TILE (self));
493 : :
494 [ + - ]: 24 : if (self->size == size)
495 : : return;
496 : :
497 : 24 : self->size = size;
498 : 24 : g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_SIZE]);
499 : : }
500 : :
501 : :
502 : : /**
503 : : * shumate_tile_get_state:
504 : : * @self: the #ShumateTile
505 : : *
506 : : * Gets the current state of tile loading.
507 : : *
508 : : * Returns: the tile's #ShumateState
509 : : */
510 : : ShumateState
511 : 0 : shumate_tile_get_state (ShumateTile *self)
512 : : {
513 [ # # ]: 0 : g_return_val_if_fail (SHUMATE_TILE (self), SHUMATE_STATE_NONE);
514 : :
515 : 0 : return self->state;
516 : : }
517 : :
518 : :
519 : : /**
520 : : * shumate_tile_set_state:
521 : : * @self: the #ShumateTile
522 : : * @state: a #ShumateState
523 : : *
524 : : * Sets the tile's #ShumateState
525 : : */
526 : : void
527 : 27 : shumate_tile_set_state (ShumateTile *self,
528 : : ShumateState state)
529 : : {
530 [ + - ]: 27 : g_return_if_fail (SHUMATE_TILE (self));
531 : :
532 [ + + ]: 27 : if (state == self->state)
533 : : return;
534 : :
535 : 12 : self->state = state;
536 : 12 : g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_STATE]);
537 : : }
538 : :
539 : :
540 : : /**
541 : : * shumate_tile_get_fade_in:
542 : : * @self: the #ShumateTile
543 : : *
544 : : * Checks whether the tile should fade in.
545 : : *
546 : : * Returns: the return value determines whether the tile should fade in when loading.
547 : : */
548 : : gboolean
549 : 0 : shumate_tile_get_fade_in (ShumateTile *self)
550 : : {
551 [ # # ]: 0 : g_return_val_if_fail (SHUMATE_TILE (self), FALSE);
552 : :
553 : 0 : return self->fade_in;
554 : : }
555 : :
556 : :
557 : : /**
558 : : * shumate_tile_set_fade_in:
559 : : * @self: the #ShumateTile
560 : : * @fade_in: determines whether the tile should fade in when loading
561 : : *
562 : : * Sets the flag determining whether the tile should fade in when loading
563 : : */
564 : : void
565 : 27 : shumate_tile_set_fade_in (ShumateTile *self,
566 : : gboolean fade_in)
567 : : {
568 [ + - ]: 27 : g_return_if_fail (SHUMATE_TILE (self));
569 : :
570 [ - + ]: 27 : if (self->fade_in == fade_in)
571 : : return;
572 : :
573 : 0 : self->fade_in = fade_in;
574 : 0 : g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_FADE_IN]);
575 : : }
576 : :
577 : : /**
578 : : * shumate_tile_get_paintable:
579 : : * @self: the [class@Tile]
580 : : *
581 : : * Get the [iface@Gdk.Paintable] representing this tile.
582 : : *
583 : : * Returns: (transfer none) (nullable): A [iface@Gdk.Paintable]
584 : : */
585 : : GdkPaintable *
586 : 39 : shumate_tile_get_paintable (ShumateTile *self)
587 : : {
588 [ + - ]: 39 : g_return_val_if_fail (SHUMATE_TILE (self), NULL);
589 : :
590 : 39 : return self->paintable;
591 : : }
592 : :
593 : : /**
594 : : * shumate_tile_set_paintable:
595 : : * @self: the [class@Tile]
596 : : * @paintable: a [iface@Gdk.Paintable]
597 : : *
598 : : * Sets the [iface@Gdk.Paintable] representing this tile.
599 : : */
600 : : void
601 : 39 : shumate_tile_set_paintable (ShumateTile *self,
602 : : GdkPaintable *paintable)
603 : : {
604 [ + - ]: 39 : g_return_if_fail (SHUMATE_TILE (self));
605 : :
606 [ + + ]: 39 : if (g_set_object (&self->paintable, paintable))
607 : 12 : g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_PAINTABLE]);
608 : : }
609 : :
610 : :
611 : : /**
612 : : * shumate_tile_get_scale_factor:
613 : : * @self: a [class@Tile]
614 : : *
615 : : * Gets the scale factor of the tile.
616 : : *
617 : : * Returns: the scale factor
618 : : *
619 : : * Since: 1.1
620 : : */
621 : : double
622 : 3 : shumate_tile_get_scale_factor (ShumateTile *self)
623 : : {
624 [ + - ]: 3 : g_return_val_if_fail (SHUMATE_IS_TILE (self), 1.0);
625 : 3 : return self->scale_factor;
626 : : }
627 : :
628 : :
629 : : /**
630 : : * shumate_tile_set_scale_factor:
631 : : * @self: the [class@Tile]
632 : : * @scale_factor: the scale factor
633 : : *
634 : : * Sets the scale factor of the tile.
635 : : *
636 : : * Since: 1.1
637 : : */
638 : : void
639 : 0 : shumate_tile_set_scale_factor (ShumateTile *self,
640 : : double scale_factor)
641 : : {
642 [ # # ]: 0 : g_return_if_fail (SHUMATE_IS_TILE (self));
643 [ # # ]: 0 : g_return_if_fail (scale_factor >= G_MINDOUBLE);
644 : :
645 [ # # ]: 0 : if (self->scale_factor == scale_factor)
646 : : return;
647 : :
648 : 0 : self->scale_factor = scale_factor;
649 : 0 : g_object_notify_by_pspec (G_OBJECT (self), obj_properties[PROP_SCALE_FACTOR]);
650 : : }
651 : :
652 : :
653 : :
654 : : void
655 : 27 : shumate_tile_set_symbols (ShumateTile *self, GPtrArray *symbols)
656 : : {
657 [ + - ]: 27 : g_return_if_fail (SHUMATE_IS_TILE (self));
658 : :
659 [ - + ]: 27 : g_clear_pointer (&self->symbols, g_ptr_array_unref);
660 [ - + ]: 27 : if (symbols != NULL)
661 : 0 : self->symbols = g_ptr_array_ref (symbols);
662 : : }
663 : :
664 : :
665 : : GPtrArray *
666 : 27 : shumate_tile_get_symbols (ShumateTile *self)
667 : : {
668 [ + - ]: 27 : g_return_val_if_fail (SHUMATE_IS_TILE (self), NULL);
669 : :
670 : 27 : return self->symbols;
671 : : }
|