[fractal/fractal-next] content: Implement markdown popover



commit bff60b06077a84c0bf212ae4340f12efe5bfe026
Author: Veli Tasali <veli tasali gmail com>
Date:   Sat May 8 18:14:24 2021 +0300

    content: Implement markdown popover
    
    Closes https://gitlab.gnome.org/GNOME/fractal/-/issues/765.

 data/org.gnome.FractalNext.gschema.xml.in     |  5 ++
 data/resources/resources.gresource.xml        |  1 +
 data/resources/ui/content-markdown-popover.ui | 85 +++++++++++++++++++++++++++
 data/resources/ui/content.ui                  |  8 ++-
 po/POTFILES.in                                |  2 +
 src/meson.build                               |  1 +
 src/session/content/content.rs                | 29 ++++++++-
 src/session/content/markdown_popover.rs       | 83 ++++++++++++++++++++++++++
 src/session/content/mod.rs                    |  2 +
 9 files changed, 213 insertions(+), 3 deletions(-)
---
diff --git a/data/org.gnome.FractalNext.gschema.xml.in b/data/org.gnome.FractalNext.gschema.xml.in
index 4b0033f1..bee2631d 100644
--- a/data/org.gnome.FractalNext.gschema.xml.in
+++ b/data/org.gnome.FractalNext.gschema.xml.in
@@ -16,5 +16,10 @@
       <summary>Default window maximized behaviour</summary>
       <description></description>
     </key>
+    <key name="markdown-enabled" type="b">
+      <default>true</default>
+      <summary>Enable markdown formatting</summary>
+      <description>Whether or not to do markdown formatting when sending messages</description>
+    </key>
   </schema>
 </schemalist>
diff --git a/data/resources/resources.gresource.xml b/data/resources/resources.gresource.xml
index 037753ad..de778fa9 100644
--- a/data/resources/resources.gresource.xml
+++ b/data/resources/resources.gresource.xml
@@ -7,6 +7,7 @@
     <file compressed="true" preprocess="xml-stripblanks" 
alias="content-message-row.ui">ui/content-message-row.ui</file>
     <file compressed="true" preprocess="xml-stripblanks" 
alias="content-divider-row.ui">ui/content-divider-row.ui</file>
     <file compressed="true" preprocess="xml-stripblanks" 
alias="content-state-row.ui">ui/content-state-row.ui</file>
+    <file compressed="true" preprocess="xml-stripblanks" 
alias="content-markdown-popover.ui">ui/content-markdown-popover.ui</file>
     <file compressed="true" preprocess="xml-stripblanks" alias="login.ui">ui/login.ui</file>
     <file compressed="true" preprocess="xml-stripblanks" alias="session.ui">ui/session.ui</file>
     <file compressed="true" preprocess="xml-stripblanks" alias="sidebar.ui">ui/sidebar.ui</file>
diff --git a/data/resources/ui/content-markdown-popover.ui b/data/resources/ui/content-markdown-popover.ui
new file mode 100644
index 00000000..e5195fcc
--- /dev/null
+++ b/data/resources/ui/content-markdown-popover.ui
@@ -0,0 +1,85 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <template class="MarkdownPopover" parent="GtkPopover">
+    <property name="child">
+      <object class="GtkBox">
+        <property name="margin-start">6</property>
+        <property name="margin-end">6</property>
+        <property name="margin-top">6</property>
+        <property name="margin-bottom">6</property>
+        <property name="spacing">12</property>
+        <property name="orientation">vertical</property>
+        <child>
+          <object class="GtkBox">
+            <property name="spacing">42</property>
+            <child>
+              <object class="GtkLabel">
+                <property name="label" translatable="yes">_Markdown</property>
+                <property name="use-underline">True</property>
+                <property name="mnemonic-widget">switch</property>
+              </object>
+            </child>
+            <child>
+              <object class="GtkSwitch" id="switch">
+                <property name="halign">end</property>
+                <property name="active" bind-source="MarkdownPopover" bind-property="markdown-enabled" 
bind-flags="sync-create | bidirectional"/>
+              </object>
+            </child>
+          </object>
+        </child>
+        <child>
+          <object class="GtkGrid">
+            <property name="row_spacing">6</property>
+            <property name="column_spacing">42</property>
+            <property name="sensitive" bind-source="MarkdownPopover" bind-property="markdown-enabled" 
bind-flags="sync-create"/>
+            <child>
+              <object class="GtkLabel">
+                <property name="label" translatable="yes">&gt; quote</property>
+                <layout>
+                  <property name="column">1</property>
+                  <property name="row">1</property>
+                </layout>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="label" translatable="yes">**bold**</property>
+                <attributes>
+                  <attribute name="weight" value="bold"/>
+                </attributes>
+                <layout>
+                  <property name="column">0</property>
+                  <property name="row">1</property>
+                </layout>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="halign">start</property>
+                <property name="label" translatable="yes">`code`</property>
+                <layout>
+                  <property name="column">1</property>
+                  <property name="row">0</property>
+                </layout>
+              </object>
+            </child>
+            <child>
+              <object class="GtkLabel">
+                <property name="halign">start</property>
+                <property name="label" translatable="yes">*italic*</property>
+                <attributes>
+                  <attribute name="style" value="italic"/>
+                </attributes>
+                <layout>
+                  <property name="column">0</property>
+                  <property name="row">0</property>
+                </layout>
+              </object>
+            </child>
+          </object>
+        </child>
+      </object>
+    </property>
+  </template>
+</interface>
+
diff --git a/data/resources/ui/content.ui b/data/resources/ui/content.ui
index 612ccb46..bbe493d3 100644
--- a/data/resources/ui/content.ui
+++ b/data/resources/ui/content.ui
@@ -89,8 +89,14 @@
                   </object>
                 </child>
                 <child>
-                  <object class="GtkButton">
+                  <object class="GtkMenuButton" id="markdown_button">
+                    <property name="direction">up</property>
                     <property name="icon-name">format-justify-left-symbolic</property>
+                    <property name="popover">
+                      <object class="MarkdownPopover">
+                        <property name="markdown-enabled" bind-source="Content" 
bind-property="markdown-enabled" bind-flags="sync-create | bidirectional"/>
+                      </object>
+                    </property>
                   </object>
                 </child>
                 <child>
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 24731eae..e9636663 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -8,6 +8,7 @@ data/org.gnome.FractalNext.metainfo.xml.in.in
 data/resources/ui/content-divider-row.ui
 data/resources/ui/content-item-row-menu.ui
 data/resources/ui/content-item.ui
+data/resources/ui/content-markdown-popover.ui
 data/resources/ui/content-message-row.ui
 data/resources/ui/content-state-row.ui
 data/resources/ui/content.ui
@@ -35,6 +36,7 @@ src/session/categories/mod.rs
 src/session/content/content.rs
 src/session/content/divider_row.rs
 src/session/content/item_row.rs
+src/session/content/markdown_popover.rs
 src/session/content/message_row.rs
 src/session/content/mod.rs
 src/session/content/state_row.rs
diff --git a/src/meson.build b/src/meson.build
index c75e983f..d40c17af 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -35,6 +35,7 @@ sources = files(
   'session/content/content.rs',
   'session/content/divider_row.rs',
   'session/content/item_row.rs',
+  'session/content/markdown_popover.rs',
   'session/content/message_row.rs',
   'session/content/mod.rs',
   'session/content/state_row.rs',
diff --git a/src/session/content/content.rs b/src/session/content/content.rs
index 91d73eac..0a60d149 100644
--- a/src/session/content/content.rs
+++ b/src/session/content/content.rs
@@ -1,13 +1,13 @@
+use crate::session::{content::ItemRow, content::MarkdownPopover, room::Room};
 use adw::subclass::prelude::*;
 use gtk::{
     gdk, glib, glib::clone, glib::signal::Inhibit, prelude::*, subclass::prelude::*,
     CompositeTemplate,
 };
 
-use crate::session::{content::ItemRow, room::Room};
-
 mod imp {
     use super::*;
+    use crate::Application;
     use glib::subclass::InitializingObject;
     use std::cell::{Cell, RefCell};
 
@@ -25,6 +25,8 @@ mod imp {
         pub scrolled_window: TemplateChild<gtk::ScrolledWindow>,
         #[template_child]
         pub message_entry: TemplateChild<sourceview::View>,
+        #[template_child]
+        pub markdown_button: TemplateChild<gtk::MenuButton>,
     }
 
     #[glib::object_subclass]
@@ -35,6 +37,7 @@ mod imp {
 
         fn class_init(klass: &mut Self::Class) {
             ItemRow::static_type();
+            MarkdownPopover::static_type();
             Self::bind_template(klass);
             klass.set_accessible_role(gtk::AccessibleRole::Group);
 
@@ -70,6 +73,13 @@ mod imp {
                         Room::static_type(),
                         glib::ParamFlags::READWRITE | glib::ParamFlags::EXPLICIT_NOTIFY,
                     ),
+                    glib::ParamSpec::new_boolean(
+                        "markdown-enabled",
+                        "Markdown enabled",
+                        "Whether or not to do markdown formatting when sending messages",
+                        false,
+                        glib::ParamFlags::READWRITE,
+                    ),
                 ]
             });
 
@@ -92,6 +102,15 @@ mod imp {
                     let room = value.get().unwrap();
                     obj.set_room(room);
                 }
+                "markdown-enabled" => {
+                    let md_enabled = value.get().unwrap();
+                    self.md_enabled.set(md_enabled);
+                    self.markdown_button.set_icon_name(if md_enabled {
+                        "format-indent-more-symbolic"
+                    } else {
+                        "format-justify-left-symbolic"
+                    });
+                }
                 _ => unimplemented!(),
             }
         }
@@ -100,6 +119,7 @@ mod imp {
             match pspec.name() {
                 "compact" => self.compact.get().to_value(),
                 "room" => obj.room().to_value(),
+                "markdown-enabled" => self.md_enabled.get().to_value(),
                 _ => unimplemented!(),
             }
         }
@@ -140,6 +160,11 @@ mod imp {
             let (start_iter, end_iter) = self.message_entry.buffer().bounds();
             obj.action_set_enabled("content.send-text-message", start_iter != end_iter);
 
+            let settings = Application::default().settings();
+            settings
+                .bind("markdown-enabled", obj, "markdown-enabled")
+                .build();
+
             self.parent_constructed(obj);
         }
     }
diff --git a/src/session/content/markdown_popover.rs b/src/session/content/markdown_popover.rs
new file mode 100644
index 00000000..0fae4a38
--- /dev/null
+++ b/src/session/content/markdown_popover.rs
@@ -0,0 +1,83 @@
+use gtk::{glib, prelude::*, subclass::prelude::*, CompositeTemplate};
+
+pub mod imp {
+    use super::*;
+    use glib::subclass::InitializingObject;
+    use std::cell::Cell;
+
+    #[derive(Debug, Default, CompositeTemplate)]
+    #[template(resource = "/org/gnome/FractalNext/content-markdown-popover.ui")]
+    pub struct MarkdownPopover {
+        pub markdown_enabled: Cell<bool>,
+    }
+
+    #[glib::object_subclass]
+    impl ObjectSubclass for MarkdownPopover {
+        const NAME: &'static str = "MarkdownPopover";
+        type Type = super::MarkdownPopover;
+        type ParentType = gtk::Popover;
+
+        fn class_init(klass: &mut Self::Class) {
+            Self::bind_template(klass);
+            klass.set_accessible_role(gtk::AccessibleRole::Dialog);
+        }
+
+        fn instance_init(obj: &InitializingObject<Self>) {
+            obj.init_template();
+        }
+    }
+
+    impl ObjectImpl for MarkdownPopover {
+        fn properties() -> &'static [glib::ParamSpec] {
+            use once_cell::sync::Lazy;
+            static PROPERTIES: Lazy<Vec<glib::ParamSpec>> = Lazy::new(|| {
+                vec![glib::ParamSpec::new_boolean(
+                    "markdown-enabled",
+                    "Markdown enabled",
+                    "Whether or not to do markdown formatting when sending messages",
+                    false,
+                    glib::ParamFlags::READWRITE,
+                )]
+            });
+
+            PROPERTIES.as_ref()
+        }
+
+        fn set_property(
+            &self,
+            _: &Self::Type,
+            _id: usize,
+            value: &glib::Value,
+            pspec: &glib::ParamSpec,
+        ) {
+            match pspec.name() {
+                "markdown-enabled" => {
+                    let markdown_enabled = value.get().unwrap();
+                    self.markdown_enabled.set(markdown_enabled);
+                }
+                _ => unimplemented!(),
+            }
+        }
+
+        fn property(&self, _: &Self::Type, _id: usize, pspec: &glib::ParamSpec) -> glib::Value {
+            match pspec.name() {
+                "markdown-enabled" => self.markdown_enabled.get().to_value(),
+                _ => unimplemented!(),
+            }
+        }
+    }
+
+    impl WidgetImpl for MarkdownPopover {}
+    impl PopoverImpl for MarkdownPopover {}
+}
+
+glib::wrapper! {
+    pub struct MarkdownPopover(ObjectSubclass<imp::MarkdownPopover>)
+        @extends gtk::Widget, gtk::Popover, @implements gtk::Accessible;
+}
+
+impl MarkdownPopover {
+    pub fn new() -> Self {
+        glib::Object::new(&[]).expect("Failed to create MarkdownPopover")
+    }
+}
diff --git a/src/session/content/mod.rs b/src/session/content/mod.rs
index 6831a481..40ec26b2 100644
--- a/src/session/content/mod.rs
+++ b/src/session/content/mod.rs
@@ -1,11 +1,13 @@
 mod content;
 mod divider_row;
 mod item_row;
+mod markdown_popover;
 mod message_row;
 mod state_row;
 
 pub use self::content::Content;
 use self::divider_row::DividerRow;
 use self::item_row::ItemRow;
+use self::markdown_popover::MarkdownPopover;
 use self::message_row::MessageRow;
 use self::state_row::StateRow;


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