[fractal] message-location: Move location view logic in LocationViewer component



commit 7592994a9699939b3202d58f4581286b5ebbde80
Author: Kévin Commaille <zecakeh tedomum fr>
Date:   Sun Apr 24 17:28:11 2022 +0200

    message-location: Move location view logic in LocationViewer component
    
    Part-of: <https://gitlab.gnome.org/GNOME/fractal/-/merge_requests/1085>

 data/resources/resources.gresource.xml             |   1 +
 data/resources/style.css                           |  18 ++--
 data/resources/ui/components-location-viewer.ui    |  20 ++++
 data/resources/ui/content-message-location.ui      |  17 +---
 po/POTFILES.in                                     |   2 +-
 src/components/location_viewer.rs                  | 102 +++++++++++++++++++++
 src/components/mod.rs                              |   2 +
 .../content/room_history/message_row/location.rs   |  56 +----------
 8 files changed, 141 insertions(+), 77 deletions(-)
---
diff --git a/data/resources/resources.gresource.xml b/data/resources/resources.gresource.xml
index 9b335e605..7308ecd5e 100644
--- a/data/resources/resources.gresource.xml
+++ b/data/resources/resources.gresource.xml
@@ -38,6 +38,7 @@
     <file compressed="true" preprocess="xml-stripblanks" 
alias="components-editable-avatar.ui">ui/components-editable-avatar.ui</file>
     <file compressed="true" preprocess="xml-stripblanks" 
alias="components-entry-row.ui">ui/components-entry-row.ui</file>
     <file compressed="true" preprocess="xml-stripblanks" 
alias="components-loading-listbox-row.ui">ui/components-loading-listbox-row.ui</file>
+    <file compressed="true" preprocess="xml-stripblanks" 
alias="components-location-viewer.ui">ui/components-location-viewer.ui</file>
     <file compressed="true" preprocess="xml-stripblanks" 
alias="components-media-content-viewer.ui">ui/components-media-content-viewer.ui</file>
     <file compressed="true" preprocess="xml-stripblanks" 
alias="components-password-entry-row.ui">ui/components-password-entry-row.ui</file>
     <file compressed="true" preprocess="xml-stripblanks" 
alias="components-reaction-chooser.ui">ui/components-reaction-chooser.ui</file>
diff --git a/data/resources/style.css b/data/resources/style.css
index 5ff488677..47fd9d1d4 100644
--- a/data/resources/style.css
+++ b/data/resources/style.css
@@ -177,6 +177,15 @@ media-content-viewer controls {
   min-width: 300px;
 }
 
+location-viewer .map {
+  border-radius: 6px;
+  background-color: @borders;
+}
+
+location-viewer .map-marker {
+  color: @accent_color;
+}
+
 
 /* Login */
 
@@ -388,15 +397,6 @@ login {
   font-size: 3em;
 }
 
-.room-history .event-content .location .map {
-  border-radius: 6px;
-  background-color: @borders;
-}
-
-.room-history .event-content .location .map-marker {
-  color: @accent_color;
-}
-
 .room-history .event-content .thumbnail {
   border-radius: 6px;
   background-color: @borders;
diff --git a/data/resources/ui/components-location-viewer.ui b/data/resources/ui/components-location-viewer.ui
new file mode 100644
index 000000000..7ada0f635
--- /dev/null
+++ b/data/resources/ui/components-location-viewer.ui
@@ -0,0 +1,20 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <object class="GtkImage" id="marker_img">
+    <property name="icon-name">map-marker-symbolic</property>
+    <property name="pixel-size">32</property>
+    <style>
+      <class name="map-marker" />
+    </style>
+  </object>
+  <template class="ComponentsLocationViewer" parent="AdwBin">
+    <property name="child">
+      <object class="ShumateSimpleMap" id="map">
+        <property name="overflow">GTK_OVERFLOW_HIDDEN</property>
+        <style>
+          <class name="map"/>
+        </style>
+      </object>
+    </property>
+  </template>
+</interface>
diff --git a/data/resources/ui/content-message-location.ui b/data/resources/ui/content-message-location.ui
index c4eb804ea..0eea651c0 100644
--- a/data/resources/ui/content-message-location.ui
+++ b/data/resources/ui/content-message-location.ui
@@ -1,23 +1,8 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <interface>
-  <object class="GtkImage" id="marker_img">
-    <property name="icon-name">map-marker-symbolic</property>
-    <property name="pixel-size">32</property>
-    <style>
-      <class name="map-marker" />
-    </style>
-  </object>
   <template class="ContentMessageLocation" parent="GtkWidget">
     <child>
-      <object class="ShumateSimpleMap" id="map">
-        <property name="overflow">GTK_OVERFLOW_HIDDEN</property>
-        <style>
-          <class name="map"/>
-        </style>
-      </object>
+      <object class="ComponentsLocationViewer" id="location"/>
     </child>
-    <style>
-      <class name="location" />
-    </style>
   </template>
 </interface>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index c9386489b..8fac1dbeb 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -42,6 +42,7 @@ data/resources/ui/qr-code-scanner.ui
 # Rust files
 src/application.rs
 src/components/editable_avatar.rs
+src/components/location_viewer.rs
 src/components/media_content_viewer.rs
 src/error_page.rs
 src/login/mod.rs
@@ -57,7 +58,6 @@ src/session/content/room_details/member_page/mod.rs
 src/session/content/room_details/mod.rs
 src/session/content/room_history/item_row.rs
 src/session/content/room_history/message_row/audio.rs
-src/session/content/room_history/message_row/location.rs
 src/session/content/room_history/message_row/media.rs
 src/session/content/room_history/message_row/mod.rs
 src/session/content/room_history/mod.rs
diff --git a/src/components/location_viewer.rs b/src/components/location_viewer.rs
new file mode 100644
index 000000000..fe52b9c4f
--- /dev/null
+++ b/src/components/location_viewer.rs
@@ -0,0 +1,102 @@
+use adw::{prelude::*, subclass::prelude::*};
+use gtk::{glib, subclass::prelude::*, CompositeTemplate};
+use shumate::prelude::*;
+
+use crate::i18n::gettext_f;
+
+mod imp {
+    use glib::subclass::InitializingObject;
+
+    use super::*;
+
+    #[derive(Debug, Default, CompositeTemplate)]
+    #[template(resource = "/org/gnome/Fractal/components-location-viewer.ui")]
+    pub struct LocationViewer {
+        #[template_child]
+        pub map: TemplateChild<shumate::SimpleMap>,
+        #[template_child]
+        pub marker_img: TemplateChild<gtk::Image>,
+        pub marker: shumate::Marker,
+    }
+
+    #[glib::object_subclass]
+    impl ObjectSubclass for LocationViewer {
+        const NAME: &'static str = "ComponentsLocationViewer";
+        type Type = super::LocationViewer;
+        type ParentType = adw::Bin;
+
+        fn class_init(klass: &mut Self::Class) {
+            Self::bind_template(klass);
+            klass.set_css_name("location-viewer");
+        }
+
+        fn instance_init(obj: &InitializingObject<Self>) {
+            obj.init_template();
+        }
+    }
+
+    impl ObjectImpl for LocationViewer {
+        fn constructed(&self, obj: &Self::Type) {
+            self.marker.set_child(Some(&*self.marker_img));
+
+            let registry = shumate::MapSourceRegistry::with_defaults();
+            let source = registry.by_id(&shumate::MAP_SOURCE_OSM_MAPNIK).unwrap();
+            self.map.set_map_source(Some(&source));
+
+            let viewport = self.map.viewport().unwrap();
+            viewport.set_zoom_level(12.0);
+            let marker_layer = shumate::MarkerLayer::new(&viewport);
+            marker_layer.add_marker(&self.marker);
+            self.map.add_overlay_layer(&marker_layer);
+
+            // Hide the scale
+            self.map.scale().unwrap().hide();
+            self.parent_constructed(obj);
+        }
+    }
+
+    impl WidgetImpl for LocationViewer {}
+    impl BinImpl for LocationViewer {}
+}
+
+glib::wrapper! {
+    /// A widget displaying a location message in the timeline.
+    pub struct LocationViewer(ObjectSubclass<imp::LocationViewer>)
+        @extends gtk::Widget, adw::Bin, @implements gtk::Accessible;
+}
+
+impl LocationViewer {
+    /// Create a new location message.
+    #[allow(clippy::new_without_default)]
+    pub fn new() -> Self {
+        glib::Object::new(&[]).expect("Failed to create LocationViewer")
+    }
+
+    pub fn set_geo_uri(&self, uri: &str) {
+        let imp = self.imp();
+
+        let mut uri = uri.trim_start_matches("geo:").split(',');
+        let latitude = uri
+            .next()
+            .and_then(|lat_s| lat_s.parse::<f64>().ok())
+            .unwrap_or_default();
+        let longitude = uri
+            .next()
+            .and_then(|lon_s| lon_s.parse::<f64>().ok())
+            .unwrap_or_default();
+
+        imp.map
+            .viewport()
+            .unwrap()
+            .set_location(latitude, longitude);
+        imp.marker.set_location(latitude, longitude);
+
+        self.update_property(&[gtk::accessible::Property::Description(&gettext_f(
+            "Location at latitude {latitude} and longitude {longitude}",
+            &[
+                ("latitude", &latitude.to_string()),
+                ("longitude", &longitude.to_string()),
+            ],
+        ))]);
+    }
+}
diff --git a/src/components/mod.rs b/src/components/mod.rs
index 41bf54e25..4c151b617 100644
--- a/src/components/mod.rs
+++ b/src/components/mod.rs
@@ -12,6 +12,7 @@ mod entry_row;
 mod in_app_notification;
 mod label_with_widgets;
 mod loading_listbox_row;
+mod location_viewer;
 mod media_content_viewer;
 mod password_entry_row;
 mod pill;
@@ -37,6 +38,7 @@ pub use self::{
     in_app_notification::InAppNotification,
     label_with_widgets::LabelWithWidgets,
     loading_listbox_row::LoadingListBoxRow,
+    location_viewer::LocationViewer,
     media_content_viewer::{ContentType, MediaContentViewer},
     password_entry_row::PasswordEntryRow,
     pill::Pill,
diff --git a/src/session/content/room_history/message_row/location.rs 
b/src/session/content/room_history/message_row/location.rs
index 7abd86da0..4b1b10398 100644
--- a/src/session/content/room_history/message_row/location.rs
+++ b/src/session/content/room_history/message_row/location.rs
@@ -1,8 +1,7 @@
 use adw::{prelude::*, subclass::prelude::*};
 use gtk::{glib, subclass::prelude::*, CompositeTemplate};
-use shumate::prelude::*;
 
-use crate::i18n::gettext_f;
+use crate::components::LocationViewer;
 
 mod imp {
     use glib::subclass::InitializingObject;
@@ -13,10 +12,7 @@ mod imp {
     #[template(resource = "/org/gnome/Fractal/content-message-location.ui")]
     pub struct MessageLocation {
         #[template_child]
-        pub map: TemplateChild<shumate::SimpleMap>,
-        #[template_child]
-        pub marker_img: TemplateChild<gtk::Image>,
-        pub marker: shumate::Marker,
+        pub location: TemplateChild<LocationViewer>,
     }
 
     #[glib::object_subclass]
@@ -35,26 +31,8 @@ mod imp {
     }
 
     impl ObjectImpl for MessageLocation {
-        fn constructed(&self, obj: &Self::Type) {
-            self.marker.set_child(Some(&*self.marker_img));
-
-            let registry = shumate::MapSourceRegistry::with_defaults();
-            let source = registry.by_id(&shumate::MAP_SOURCE_OSM_MAPNIK).unwrap();
-            self.map.set_map_source(Some(&source));
-
-            let viewport = self.map.viewport().unwrap();
-            viewport.set_zoom_level(12.0);
-            let marker_layer = shumate::MarkerLayer::new(&viewport);
-            marker_layer.add_marker(&self.marker);
-            self.map.add_overlay_layer(&marker_layer);
-
-            // Hide the scale
-            self.map.scale().unwrap().hide();
-            self.parent_constructed(obj);
-        }
-
         fn dispose(&self, _obj: &Self::Type) {
-            self.map.unparent();
+            self.location.unparent();
         }
     }
 
@@ -69,7 +47,7 @@ mod imp {
         }
 
         fn size_allocate(&self, _widget: &Self::Type, width: i32, height: i32, baseline: i32) {
-            self.map
+            self.location
                 .size_allocate(&gtk::Allocation::new(0, 0, width, height), baseline)
         }
     }
@@ -89,30 +67,6 @@ impl MessageLocation {
     }
 
     pub fn set_geo_uri(&self, uri: &str) {
-        let imp = self.imp();
-
-        let mut uri = uri.trim_start_matches("geo:").split(',');
-        let latitude = uri
-            .next()
-            .and_then(|lat_s| lat_s.parse::<f64>().ok())
-            .unwrap_or_default();
-        let longitude = uri
-            .next()
-            .and_then(|lon_s| lon_s.parse::<f64>().ok())
-            .unwrap_or_default();
-
-        imp.map
-            .viewport()
-            .unwrap()
-            .set_location(latitude, longitude);
-        imp.marker.set_location(latitude, longitude);
-
-        self.update_property(&[gtk::accessible::Property::Description(&gettext_f(
-            "Location at latitude {latitude} and longitude {longitude}",
-            &[
-                ("latitude", &latitude.to_string()),
-                ("longitude", &longitude.to_string()),
-            ],
-        ))]);
+        self.imp().location.set_geo_uri(uri);
     }
 }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]