[libshumate/tintou/compass] Compass: Add ShumateCompass
- From: Corentin Noël <corentinnoel src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libshumate/tintou/compass] Compass: Add ShumateCompass
- Date: Tue, 17 Aug 2021 10:22:42 +0000 (UTC)
commit 1339f34ee974421a0d6b3ea53ad3a2d9a9b8e625
Author: Corentin Noël <corentin noel collabora com>
Date: Tue Aug 17 12:18:31 2021 +0200
Compass: Add ShumateCompass
A simple widget to show the north when doing a rotation of the map.
data/compass.css | 8 +
data/icons/32x32/status/map-compass.svg | 25 +++
data/libshumate.gresource.xml | 2 +
demos/shumate-demo-window.c | 3 +
demos/shumate-demo-window.ui | 13 +-
shumate/meson.build | 2 +
shumate/shumate-compass.c | 263 ++++++++++++++++++++++++++++++++
shumate/shumate-compass.h | 46 ++++++
shumate/shumate.h | 1 +
9 files changed, 362 insertions(+), 1 deletion(-)
---
diff --git a/data/compass.css b/data/compass.css
new file mode 100644
index 0000000..1b34d6a
--- /dev/null
+++ b/data/compass.css
@@ -0,0 +1,8 @@
+map-compass image {
+ padding: 3px;
+ -gtk-icon-size: 32px;
+}
+
+map-compass {
+ margin: 6px;
+}
diff --git a/data/icons/32x32/status/map-compass.svg b/data/icons/32x32/status/map-compass.svg
new file mode 100644
index 0000000..eb29863
--- /dev/null
+++ b/data/icons/32x32/status/map-compass.svg
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+
+<svg
+ width="32"
+ height="32"
+ viewBox="0 0 8.4666667 8.4666667"
+ version="1.1"
+ id="svg5"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:svg="http://www.w3.org/2000/svg">
+ <defs
+ id="defs2" />
+ <g
+ id="layer1">
+ <path
+
style="fill:#ff0008;stroke:#000000;stroke-width:0.26458332;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.59953439;fill-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;paint-order:markers
fill stroke"
+ d="M 4.2333333,1.0583333 3.175,3.96536 5.2916667,3.97214 Z"
+ id="path1025" />
+ <path
+
style="fill:#ffffff;stroke:#000000;stroke-width:0.26458333;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:0.60000002;fill-opacity:1;stroke-miterlimit:4;stroke-dasharray:none;paint-order:markers
fill stroke"
+ d="M 4.2333333,7.4083334 3.175,4.5013267 5.2916667,4.4945067 Z"
+ id="path1025-3" />
+ </g>
+</svg>
diff --git a/data/libshumate.gresource.xml b/data/libshumate.gresource.xml
index aaad36e..6c26462 100644
--- a/data/libshumate.gresource.xml
+++ b/data/libshumate.gresource.xml
@@ -1,8 +1,10 @@
<?xml version="1.0" encoding="UTF-8"?>
<gresources>
<gresource prefix="/org/gnome/shumate/">
+ <file compressed="true">compass.css</file>
<file compressed="true">scale.css</file>
<file compressed="true">license.css</file>
<file compressed="true">point.css</file>
+ <file preprocess="xml-stripblanks">icons/32x32/status/map-compass.svg</file>
</gresource>
</gresources>
diff --git a/demos/shumate-demo-window.c b/demos/shumate-demo-window.c
index ba76af7..88b6e5c 100644
--- a/demos/shumate-demo-window.c
+++ b/demos/shumate-demo-window.c
@@ -28,6 +28,7 @@ struct _ShumateDemoWindow
GtkOverlay *overlay;
ShumateScale *scale;
ShumateLicense *license;
+ ShumateCompass *compass;
GtkDropDown *layers_dropdown;
ShumateMapSourceRegistry *registry;
@@ -121,6 +122,7 @@ shumate_demo_window_class_init (ShumateDemoWindowClass *klass)
gtk_widget_class_bind_template_child (widget_class, ShumateDemoWindow, overlay);
gtk_widget_class_bind_template_child (widget_class, ShumateDemoWindow, scale);
gtk_widget_class_bind_template_child (widget_class, ShumateDemoWindow, license);
+ gtk_widget_class_bind_template_child (widget_class, ShumateDemoWindow, compass);
gtk_widget_class_bind_template_child (widget_class, ShumateDemoWindow, layers_dropdown);
gtk_widget_class_bind_template_callback (widget_class, on_layers_dropdown_notify_selected);
}
@@ -153,6 +155,7 @@ shumate_demo_window_init (ShumateDemoWindow *self)
on_layers_dropdown_notify_selected (self, NULL, self->layers_dropdown);
shumate_scale_set_viewport (self->scale, viewport);
+ shumate_compass_set_viewport (self->compass, viewport);
/* Add the marker layers */
self->marker_layer = shumate_marker_layer_new (viewport);
diff --git a/demos/shumate-demo-window.ui b/demos/shumate-demo-window.ui
index 96c50a1..d2ee6d0 100644
--- a/demos/shumate-demo-window.ui
+++ b/demos/shumate-demo-window.ui
@@ -29,9 +29,20 @@
</object>
</child>
<child type="overlay">
- <object class="ShumateLicense" id="license">
+ <object class="GtkBox">
+ <property name="orientation">vertical</property>
<property name="halign">end</property>
<property name="valign">end</property>
+ <child>
+ <object class="ShumateCompass" id="compass">
+ <property name="halign">end</property>
+ </object>
+ </child>
+ <child>
+ <object class="ShumateLicense" id="license">
+ <property name="halign">end</property>
+ </object>
+ </child>
</object>
</child>
</object>
diff --git a/shumate/meson.build b/shumate/meson.build
index 84eee2b..4c9542a 100644
--- a/shumate/meson.build
+++ b/shumate/meson.build
@@ -1,5 +1,6 @@
libshumate_public_h = [
'shumate-coordinate.h',
+ 'shumate-compass.h',
'shumate-file-cache.h',
'shumate-layer.h',
'shumate-license.h',
@@ -27,6 +28,7 @@ libshumate_private_h = [
libshumate_sources = [
'shumate-coordinate.c',
+ 'shumate-compass.c',
'shumate-file-cache.c',
'shumate-kinetic-scrolling.c',
'shumate-layer.c',
diff --git a/shumate/shumate-compass.c b/shumate/shumate-compass.c
new file mode 100644
index 0000000..7fdc96c
--- /dev/null
+++ b/shumate/shumate-compass.c
@@ -0,0 +1,263 @@
+/*
+ * Copyright (C) 2020 Collabora Ltd. (https://www.collabora.com)
+ * Copyright (C) 2020 Corentin Noël <corentin noel collabora com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+/**
+ * SECTION:shumate-compass
+ * @short_description: A widget displaying a compass.
+ *
+ * A widget displaying a compass.
+ *
+ * # CSS nodes
+ *
+ * |[<!-- language="plain" -->
+ * map-compass
+ * ├── revealer
+ * ├──── image
+ * ]|
+ *
+ * ShumateCompass uses a single CSS node with name map-compass. It also uses an
+ * image named "map-compass".
+ */
+
+#include "config.h"
+
+#include "shumate-compass.h"
+
+struct _ShumateCompass
+{
+ GtkWidget parent_instance;
+
+ ShumateViewport *viewport;
+ GtkWidget *revealer;
+ GtkWidget *image;
+ double rotation;
+};
+
+G_DEFINE_TYPE (ShumateCompass, shumate_compass, GTK_TYPE_WIDGET)
+
+enum
+{
+ PROP_VIEWPORT = 1,
+ N_PROPERTIES,
+};
+
+static GParamSpec *obj_properties[N_PROPERTIES] = { NULL, };
+
+static void
+shumate_compass_on_rotation_changed (ShumateCompass *self)
+{
+ double rotation = shumate_viewport_get_rotation (self->viewport);
+ if (rotation != 0)
+ {
+ self->rotation = rotation;
+ gtk_widget_queue_draw (GTK_WIDGET (self));
+ }
+
+ gtk_revealer_set_reveal_child (GTK_REVEALER (self->revealer), rotation != 0);
+}
+
+static void
+on_viewport_props_changed (ShumateCompass *self,
+ G_GNUC_UNUSED GParamSpec *pspec,
+ ShumateViewport *viewport)
+{
+ shumate_compass_on_rotation_changed (self);
+}
+
+static void
+shumate_compass_dispose (GObject *object)
+{
+ ShumateCompass *self = (ShumateCompass *)object;
+
+ g_clear_object (&self->viewport);
+ g_clear_pointer (&self->revealer, gtk_widget_unparent);
+
+ G_OBJECT_CLASS (shumate_compass_parent_class)->dispose (object);
+}
+
+static void
+shumate_compass_get_property (GObject *object,
+ guint prop_id,
+ GValue *value,
+ GParamSpec *pspec)
+{
+ ShumateCompass *self = SHUMATE_COMPASS (object);
+
+ switch (prop_id)
+ {
+ case PROP_VIEWPORT:
+ g_value_set_object (value, self->viewport);
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+shumate_compass_set_property (GObject *object,
+ guint prop_id,
+ const GValue *value,
+ GParamSpec *pspec)
+{
+ ShumateCompass *self = SHUMATE_COMPASS (object);
+
+ switch (prop_id)
+ {
+ case PROP_VIEWPORT:
+ shumate_compass_set_viewport (self, g_value_get_object (value));
+ break;
+
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ }
+}
+
+static void
+shumate_compass_snapshot (GtkWidget *widget,
+ GtkSnapshot *snapshot)
+{
+ ShumateCompass *self = SHUMATE_COMPASS (widget);
+ graphene_point_t p;
+
+ p.x = gtk_widget_get_width (widget) / 2;
+ p.y = gtk_widget_get_height (widget) / 2;
+
+ gtk_snapshot_save (snapshot);
+ gtk_snapshot_translate (snapshot, &p);
+ gtk_snapshot_rotate (snapshot, self->rotation * 180 / G_PI);
+ p.x = -p.x;
+ p.y = -p.y;
+ gtk_snapshot_translate (snapshot, &p);
+ GTK_WIDGET_CLASS (shumate_compass_parent_class)->snapshot (widget, snapshot);
+ gtk_snapshot_restore (snapshot);
+}
+
+static void
+shumate_compass_class_init (ShumateCompassClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+ GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
+ GdkDisplay *display;
+
+ object_class->dispose = shumate_compass_dispose;
+ object_class->get_property = shumate_compass_get_property;
+ object_class->set_property = shumate_compass_set_property;
+
+ widget_class->snapshot = shumate_compass_snapshot;
+
+ /**
+ * ShumateCompass:viewport:
+ *
+ * The viewport to use.
+ */
+ obj_properties[PROP_VIEWPORT] =
+ g_param_spec_object ("viewport",
+ "The viewport",
+ "The viewport",
+ SHUMATE_TYPE_VIEWPORT,
+ G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS);
+
+ g_object_class_install_properties (object_class, N_PROPERTIES, obj_properties);
+
+ gtk_widget_class_set_css_name (widget_class, g_intern_static_string ("map-compass"));
+ gtk_widget_class_set_layout_manager_type (widget_class, GTK_TYPE_BIN_LAYOUT);
+
+ display = gdk_display_get_default ();
+ if (display)
+ {
+ GtkIconTheme *icon_theme;
+ g_autoptr(GtkCssProvider) provider = gtk_css_provider_new ();
+ gtk_css_provider_load_from_resource (provider, "/org/gnome/shumate/compass.css");
+ gtk_style_context_add_provider_for_display (display,
+ GTK_STYLE_PROVIDER (provider),
+ GTK_STYLE_PROVIDER_PRIORITY_FALLBACK);
+ icon_theme = gtk_icon_theme_get_for_display (display);
+ gtk_icon_theme_add_resource_path (icon_theme, "/org/gnome/shumate/icons");
+ }
+}
+
+static void
+shumate_compass_init (ShumateCompass *self)
+{
+ self->revealer = gtk_revealer_new ();
+ gtk_revealer_set_transition_type (GTK_REVEALER (self->revealer), GTK_REVEALER_TRANSITION_TYPE_CROSSFADE);
+ gtk_widget_insert_after (self->revealer, GTK_WIDGET (self), NULL);
+ self->image = gtk_image_new_from_icon_name ("map-compass");
+ gtk_revealer_set_child (GTK_REVEALER (self->revealer), self->image);
+}
+
+/**
+ * shumate_compass_new:
+ * @viewport: (nullable): a #ShumateViewport
+ *
+ * Creates an instance of #ShumateCompass.
+ *
+ * Returns: a new #ShumateCompass.
+ */
+ShumateCompass *
+shumate_compass_new (ShumateViewport *viewport)
+{
+ return SHUMATE_COMPASS (g_object_new (SHUMATE_TYPE_COMPASS,
+ "viewport", viewport,
+ NULL));
+}
+
+/**
+ * shumate_compass_set_viewport:
+ * @compass: a #ShumateCompass
+ * @viewport: (nullable): a #ShumateViewport
+ *
+ * Sets the compass viewport.
+ */
+void
+shumate_compass_set_viewport (ShumateCompass *compass,
+ ShumateViewport *viewport)
+{
+ g_return_if_fail (SHUMATE_IS_COMPASS (compass));
+
+ if (compass->viewport)
+ g_signal_handlers_disconnect_by_data (compass->viewport, compass);
+
+ if (g_set_object (&compass->viewport, viewport))
+ {
+ g_object_notify_by_pspec(G_OBJECT (compass), obj_properties[PROP_VIEWPORT]);
+ if (compass->viewport)
+ {
+ g_signal_connect_swapped (compass->viewport, "notify::rotation", G_CALLBACK
(on_viewport_props_changed), compass);
+ shumate_compass_on_rotation_changed (compass);
+ }
+ }
+}
+
+/**
+ * shumate_compass_get_viewport:
+ * @compass: a #ShumateCompass
+ *
+ * Gets the viewport used by the compass.
+ *
+ * Returns: (transfer none) (nullable): The #ShumateViewport used by the compass
+ */
+ShumateViewport *
+shumate_compass_get_viewport (ShumateCompass *compass)
+{
+ g_return_val_if_fail (SHUMATE_IS_COMPASS (compass), NULL);
+
+ return compass->viewport;
+}
diff --git a/shumate/shumate-compass.h b/shumate/shumate-compass.h
new file mode 100644
index 0000000..6765214
--- /dev/null
+++ b/shumate/shumate-compass.h
@@ -0,0 +1,46 @@
+/*
+ * Copyright (C) 2021 Collabora Ltd. (https://www.collabora.com)
+ * Copyright (C) 2021 Corentin Noël <corentin noel collabora com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#if !defined (__SHUMATE_SHUMATE_H_INSIDE__) && !defined (SHUMATE_COMPILATION)
+#error "Only <shumate/shumate.h> can be included directly."
+#endif
+
+#ifndef SHUMATE_COMPASS_H
+#define SHUMATE_COMPASS_H
+
+#include <shumate/shumate-viewport.h>
+
+#include <glib-object.h>
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define SHUMATE_TYPE_COMPASS (shumate_compass_get_type())
+
+G_DECLARE_FINAL_TYPE (ShumateCompass, shumate_compass, SHUMATE, COMPASS, GtkWidget)
+
+ShumateCompass *shumate_compass_new (ShumateViewport *viewport);
+
+ShumateViewport *shumate_compass_get_viewport (ShumateCompass *compass);
+void shumate_compass_set_viewport (ShumateCompass *compass,
+ ShumateViewport *viewport);
+
+G_END_DECLS
+
+#endif
diff --git a/shumate/shumate.h b/shumate/shumate.h
index dc4d3dc..0486d1a 100644
--- a/shumate/shumate.h
+++ b/shumate/shumate.h
@@ -36,6 +36,7 @@
#include "shumate/shumate-point.h"
#include "shumate/shumate-location.h"
#include "shumate/shumate-coordinate.h"
+#include "shumate/shumate-compass.h"
#include "shumate/shumate-marker.h"
#include "shumate/shumate-map.h"
#include "shumate/shumate-viewport.h"
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]