GCC Code Coverage Report


Directory: ./
Coverage: low: ≥ 0% medium: ≥ 75.0% high: ≥ 90.0%
Coverage Exec / Excl / Total
Lines: 20.4% 19 / 0 / 93
Functions: 28.6% 4 / 0 / 14
Branches: 15.6% 5 / 0 / 32

shumate/shumate-compass.c
Line Branch Exec Source
1 /*
2 * Copyright (C) 2020 Collabora Ltd. (https://www.collabora.com)
3 * Copyright (C) 2020 Corentin Noël <corentin.noel@collabora.com>
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2.1 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the Free Software
17 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19
20 /**
21 * ShumateCompass:
22 *
23 * A widget displaying a compass.
24 *
25 * # CSS nodes
26 *
27 * ```
28 * map-compass
29 * ├── revealer
30 * ├──── image
31 * ```
32 *
33 * `ShumateCompass` uses a single CSS node with name map-compass. It also uses an
34 * image named "map-compass".
35 */
36
37 #include "shumate-compass.h"
38
39 struct _ShumateCompass
40 {
41 GtkWidget parent_instance;
42
43 ShumateViewport *viewport;
44 GtkWidget *revealer;
45 GtkWidget *image;
46 double rotation;
47 };
48
49
4/6
shumate_compass_class_intern_init:
✗ Branch 3 → 4 not taken.
✓ Branch 3 → 5 taken 1 time.
shumate_compass_get_type:
✓ Branch 2 → 3 taken 1 time.
✓ Branch 2 → 7 taken 1 time.
✓ Branch 4 → 5 taken 1 time.
✗ Branch 4 → 7 not taken.
4 G_DEFINE_TYPE (ShumateCompass, shumate_compass, GTK_TYPE_WIDGET)
50
51 enum
52 {
53 PROP_VIEWPORT = 1,
54 N_PROPERTIES,
55 };
56
57 static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
58
59 static void
60 ✗ shumate_compass_on_rotation_changed (ShumateCompass *self)
61 {
62 ✗ double rotation = shumate_viewport_get_rotation (self->viewport);
63 ✗ if (rotation != 0)
64 {
65 ✗ self->rotation = rotation;
66 ✗ gtk_widget_queue_draw (GTK_WIDGET (self));
67 }
68
69 ✗ gtk_revealer_set_reveal_child (GTK_REVEALER (self->revealer), rotation != 0);
70 ✗ }
71
72 static void
73 ✗ on_viewport_props_changed (ShumateCompass *self,
74 G_GNUC_UNUSED GParamSpec *pspec,
75 ShumateViewport *viewport)
76 {
77 ✗ shumate_compass_on_rotation_changed (self);
78 ✗ }
79
80 static void
81 ✗ shumate_compass_dispose (GObject *object)
82 {
83 ✗ ShumateCompass *self = (ShumateCompass *)object;
84
85 ✗ g_clear_object (&self->viewport);
86 ✗ g_clear_pointer (&self->revealer, gtk_widget_unparent);
87
88 ✗ G_OBJECT_CLASS (shumate_compass_parent_class)->dispose (object);
89 ✗ }
90
91 static void
92 ✗ shumate_compass_get_property (GObject *object,
93 guint prop_id,
94 GValue *value,
95 GParamSpec *pspec)
96 {
97 ✗ ShumateCompass *self = SHUMATE_COMPASS (object);
98
99 ✗ switch (prop_id)
100 {
101 ✗ case PROP_VIEWPORT:
102 ✗ g_value_set_object (value, self->viewport);
103 ✗ break;
104
105 ✗ default:
106 ✗ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
107 }
108 ✗ }
109
110 static void
111 ✗ shumate_compass_set_property (GObject *object,
112 guint prop_id,
113 const GValue *value,
114 GParamSpec *pspec)
115 {
116 ✗ ShumateCompass *self = SHUMATE_COMPASS (object);
117
118 ✗ switch (prop_id)
119 {
120 ✗ case PROP_VIEWPORT:
121 ✗ shumate_compass_set_viewport (self, g_value_get_object (value));
122 ✗ break;
123
124 ✗ default:
125 ✗ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
126 }
127 ✗ }
128
129 static void
130 ✗ shumate_compass_snapshot (GtkWidget *widget,
131 GtkSnapshot *snapshot)
132 {
133 ✗ ShumateCompass *self = SHUMATE_COMPASS (widget);
134 ✗ graphene_point_t p;
135
136 ✗ p.x = gtk_widget_get_width (widget) / 2;
137 ✗ p.y = gtk_widget_get_height (widget) / 2;
138
139 ✗ gtk_snapshot_save (snapshot);
140 ✗ gtk_snapshot_translate (snapshot, &p);
141 ✗ gtk_snapshot_rotate (snapshot, self->rotation * 180 / G_PI);
142 ✗ p.x = -p.x;
143 ✗ p.y = -p.y;
144 ✗ gtk_snapshot_translate (snapshot, &p);
145 ✗ GTK_WIDGET_CLASS (shumate_compass_parent_class)->snapshot (widget, snapshot);
146 ✗ gtk_snapshot_restore (snapshot);
147 ✗ }
148
149 static void
150 1 shumate_compass_class_init (ShumateCompassClass *klass)
151 {
152 1 GObjectClass *object_class = G_OBJECT_CLASS (klass);
153 1 GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
154 1 GdkDisplay *display;
155
156 1 object_class->dispose = shumate_compass_dispose;
157 1 object_class->get_property = shumate_compass_get_property;
158 1 object_class->set_property = shumate_compass_set_property;
159
160 1 widget_class->snapshot = shumate_compass_snapshot;
161
162 /**
163 * ShumateCompass:viewport:
164 *
165 * The viewport to use.
166 */
167 2 obj_properties[PROP_VIEWPORT] =
168 1 g_param_spec_object ("viewport", NULL, NULL,
169 SHUMATE_TYPE_VIEWPORT,
170 G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
171
172 1 g_object_class_install_properties (object_class, N_PROPERTIES, obj_properties);
173
174 1 gtk_widget_class_set_css_name (widget_class, "map-compass");
175 1 gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
176
177 1 display = gdk_display_get_default ();
178
1/2
✗ Branch 9 → 10 not taken.
✓ Branch 9 → 12 taken 1 time.
1 if (display)
179 {
180 ✗ GtkIconTheme *icon_theme = gtk_icon_theme_get_for_display (display);
181 ✗ gtk_icon_theme_add_resource_path (icon_theme, "/org/gnome/shumate/icons");
182 }
183 1 }
184
185 static void
186 ✗ shumate_compass_init (ShumateCompass *self)
187 {
188 ✗ self->revealer = gtk_revealer_new ();
189 ✗ gtk_revealer_set_transition_type (GTK_REVEALER (self->revealer), GTK_REVEALER_TRANSITION_TYPE_CROSSFADE);
190 ✗ gtk_widget_insert_after (self->revealer, GTK_WIDGET (self), NULL);
191 ✗ self->image = gtk_image_new_from_icon_name ("map-compass");
192 ✗ gtk_image_set_icon_size (GTK_IMAGE (self->image), GTK_ICON_SIZE_LARGE);
193 ✗ gtk_revealer_set_child (GTK_REVEALER (self->revealer), self->image);
194 ✗ }
195
196 /**
197 * shumate_compass_new:
198 * @viewport: (nullable): a #ShumateViewport
199 *
200 * Creates an instance of #ShumateCompass.
201 *
202 * Returns: a new #ShumateCompass.
203 */
204 ShumateCompass *
205 ✗ shumate_compass_new (ShumateViewport *viewport)
206 {
207 ✗ return SHUMATE_COMPASS (g_object_new (SHUMATE_TYPE_COMPASS,
208 "viewport", viewport,
209 NULL));
210 }
211
212 /**
213 * shumate_compass_set_viewport:
214 * @compass: a [class@Compass]
215 * @viewport: (nullable): a [class@Viewport]
216 *
217 * Sets the compass viewport.
218 */
219 void
220 ✗ shumate_compass_set_viewport (ShumateCompass *compass,
221 ShumateViewport *viewport)
222 {
223 ✗ g_return_if_fail (SHUMATE_IS_COMPASS (compass));
224 ✗ g_return_if_fail (viewport == NULL || SHUMATE_IS_VIEWPORT (viewport));
225
226 ✗ if (compass->viewport == viewport)
227 return;
228
229 ✗ if (compass->viewport)
230 ✗ g_signal_handlers_disconnect_by_data (compass->viewport, compass);
231
232 ✗ g_set_object (&compass->viewport, viewport);
233
234 ✗ if (compass->viewport)
235 {
236 ✗ g_signal_connect_swapped (compass->viewport, "notify::rotation", G_CALLBACK (on_viewport_props_changed), compass);
237 ✗ shumate_compass_on_rotation_changed (compass);
238 }
239
240 ✗ g_object_notify_by_pspec (G_OBJECT (compass), obj_properties[PROP_VIEWPORT]);
241 }
242
243 /**
244 * shumate_compass_get_viewport:
245 * @compass: a #ShumateCompass
246 *
247 * Gets the viewport used by the compass.
248 *
249 * Returns: (transfer none) (nullable): The #ShumateViewport used by the compass
250 */
251 ShumateViewport *
252 ✗ shumate_compass_get_viewport (ShumateCompass *compass)
253 {
254 ✗ g_return_val_if_fail (SHUMATE_IS_COMPASS (compass), NULL);
255
256 ✗ return compass->viewport;
257 }
258