[meld] meld.ui.notebook: Reimplement our notebook label widget



commit 18207602b2982066a5b27c12b768f4ea748f6c11
Author: Kai Willadsen <kai willadsen gmail com>
Date:   Fri Jan 4 10:08:13 2019 +1000

    meld.ui.notebook: Reimplement our notebook label widget
    
    This started as a migration to a simple template, but now it's basically
    a complete rewrite to use properties and bindings.

 meld/meldwindow.py                  |   4 +-
 meld/resources/ui/notebook-label.ui |  52 +++++++++++++++
 meld/ui/notebook.py                 |   3 +-
 meld/ui/notebooklabel.py            | 128 ++++++++++++++++--------------------
 4 files changed, 110 insertions(+), 77 deletions(-)
---
diff --git a/meld/meldwindow.py b/meld/meldwindow.py
index 27ce4b28..ed776226 100644
--- a/meld/meldwindow.py
+++ b/meld/meldwindow.py
@@ -340,7 +340,7 @@ class MeldWindow(Gtk.ApplicationWindow):
 
         if newdoc:
             nbl = self.notebook.get_tab_label(newdoc)
-            self.set_title(nbl.get_label_text())
+            self.set_title(nbl.props.label_text)
         else:
             self.set_title("Meld")
 
@@ -503,7 +503,7 @@ class MeldWindow(Gtk.ApplicationWindow):
                 page.on_file_changed(filename)
 
     def _append_page(self, page, icon):
-        nbl = NotebookLabel(icon, "", lambda b: page.on_delete_event())
+        nbl = NotebookLabel(icon_name=icon, page=page)
         self.notebook.append_page(page, nbl)
 
         # Change focus to the newly created page only if the user is on a
diff --git a/meld/resources/ui/notebook-label.ui b/meld/resources/ui/notebook-label.ui
new file mode 100644
index 00000000..7103912e
--- /dev/null
+++ b/meld/resources/ui/notebook-label.ui
@@ -0,0 +1,52 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<interface>
+  <!-- interface-requires gtk+ 3.20 -->
+  <template class="NotebookLabel" parent="GtkEventBox">
+    <property name="events">GDK_BUTTON_PRESS_MASK</property>
+    <signal name="button-press-event" handler="on_label_button_press_event" swapped="no"/>
+    <child>
+      <object class="GtkBox" id="box">
+        <property name="visible">True</property>
+        <property name="can_focus">False</property>
+        <property name="has_focus">False</property>
+        <property name="orientation">horizontal</property>
+        <child type="center">
+          <object class="GtkLabel" id="label">
+            <property name="single_line_mode">True</property>
+            <property name="visible">True</property>
+          </object>
+        </child>
+        <child>
+          <object class="GtkImage" id="icon">
+            <property name="visible">True</property>
+            <property name="icon-size">1</property>
+          </object>
+          <packing>
+            <property name="pack_type">start</property>
+          </packing>
+        </child>
+        <child>
+          <object class="GtkButton" id="close_button">
+            <property name="visible">True</property>
+            <property name="relief">none</property>
+            <property name="focus-on-click">False</property>
+            <property name="tooltip_text" translatable="yes">Close Tab</property>
+            <property name="image">close_symbolic_image</property>
+            <signal name="clicked" handler="on_close_button_clicked" swapped="no"/>
+            <style>on_close_button_clicked
+              <class name="small-button"/>
+              <class name="flat"/>
+            </style>
+          </object>
+          <packing>
+            <property name="pack_type">end</property>
+          </packing>
+        </child>
+      </object>
+    </child>
+  </template>
+  <object class="GtkImage" id="close_symbolic_image">
+    <property name="visible">True</property>
+    <property name="icon_name">window-close-symbolic</property>
+  </object>
+</interface>
diff --git a/meld/ui/notebook.py b/meld/ui/notebook.py
index a29a3d5e..47d37c84 100644
--- a/meld/ui/notebook.py
+++ b/meld/ui/notebook.py
@@ -157,8 +157,7 @@ class MeldNotebook(Gtk.Notebook):
 
     def on_label_changed(self, page, text, tooltip):
         nbl = self.get_tab_label(page)
-        nbl.set_label_text(text)
-        nbl.set_tooltip_text(tooltip)
+        nbl.props.label_text = text
 
         # Only update the window title if the current page is active
         if self.get_current_page() == self.page_num(page):
diff --git a/meld/ui/notebooklabel.py b/meld/ui/notebooklabel.py
index 5d36e22f..a1b11d63 100644
--- a/meld/ui/notebooklabel.py
+++ b/meld/ui/notebooklabel.py
@@ -1,5 +1,5 @@
 # Copyright (C) 2002-2009 Stephen Kennedy <stevek gnome org>
-# Copyright (C) 2008-2009, 2013 Kai Willadsen <kai willadsen gmail com>
+# Copyright (C) 2008-2009, 2013, 2019 Kai Willadsen <kai willadsen gmail com>
 #
 # This program is free software: you can redistribute it and/or modify
 # it under the terms of the GNU General Public License as published by
@@ -15,79 +15,61 @@
 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 from gi.repository import Gdk
-from gi.repository import Gio
+from gi.repository import GObject
 from gi.repository import Gtk
-from gi.repository import Pango
 
-from meld.conf import _
-
-
-class NotebookLabel(Gtk.HBox):
-    __gtype_name__ = "NotebookLabel"
-
-    tab_width_in_chars = 30
-
-    def __init__(self, iconname, text, onclose):
-        super().__init__(homogeneous=False, spacing=4)
-
-        label = Gtk.Label(label=text)
-        # FIXME: ideally, we would use custom ellipsization that ellipsized the
-        # two paths separately, but that requires significant changes to label
-        # generation in many different parts of the code
-        label.set_ellipsize(Pango.EllipsizeMode.MIDDLE)
-        label.set_single_line_mode(True)
-        label.set_alignment(0.0, 0.5)
-        label.set_padding(0, 0)
-
-        style_context = self.get_style_context()
-        style_context.save()
-        style_context.set_state(Gtk.StateFlags.NORMAL)
-        font_desc = style_context.get_font(style_context.get_state())
-        style_context.restore()
-
-        context = self.get_pango_context()
-        metrics = context.get_metrics(font_desc, context.get_language())
-        char_width = metrics.get_approximate_char_width() / Pango.SCALE
-        valid, w, h = Gtk.icon_size_lookup_for_settings(
-            self.get_settings(), Gtk.IconSize.MENU)
-        # FIXME: PIXELS replacement
-        self.set_size_request(
-            self.tab_width_in_chars * char_width + 2 * w, -1)
-
-        button = Gtk.Button()
-        button.set_relief(Gtk.ReliefStyle.NONE)
-        button.set_focus_on_click(False)
-        icon = Gio.ThemedIcon.new_with_default_fallbacks(
-            'window-close-symbolic')
-        image = Gtk.Image.new_from_gicon(icon, Gtk.IconSize.MENU)
-        image.set_tooltip_text(_("Close tab"))
-        button.add(image)
-        button.connect("clicked", onclose)
-
-        icon = Gtk.Image.new_from_icon_name(iconname, Gtk.IconSize.MENU)
-
-        label_box = Gtk.EventBox()
-        label_box.add_events(Gdk.EventMask.BUTTON_PRESS_MASK)
-        label_box.props.visible_window = False
-        label_box.connect("button-press-event", self.on_label_clicked)
-        label_box.add(label)
-
-        self.pack_start(icon, False, True, 0)
-        self.pack_start(label_box, True, True, 0)
-        self.pack_start(button, False, True, 0)
-        self.set_tooltip_text(text)
-        self.show_all()
-
-        self.__label = label
-        self.__onclose = onclose
-
-    def on_label_clicked(self, box, event):
+from meld.ui._gtktemplate import Template
+
+
+@Template(resource_path='/org/gnome/meld/ui/notebook-label.ui')
+class NotebookLabel(Gtk.EventBox):
+
+    __gtype_name__ = 'NotebookLabel'
+
+    icon = Template.Child()
+    label = Template.Child()
+
+    icon_name = GObject.Property(
+        type=str,
+        nick='Name of the icon to display',
+        default=None,
+    )
+
+    label_text = GObject.Property(
+        type=str,
+        nick='Text of this notebook label',
+        default='',
+    )
+
+    page = GObject.Property(
+        type=object,
+        nick='Notebook page for which this is the label',
+        default=None,
+    )
+
+    def __init__(self, **kwargs):
+        super().__init__(**kwargs)
+        self.init_template()
+
+        self.bind_property(
+            'icon-name', self.icon, 'icon-name',
+            GObject.BindingFlags.DEFAULT | GObject.BindingFlags.SYNC_CREATE,
+        )
+        self.bind_property(
+            'label-text', self.label, 'label',
+            GObject.BindingFlags.DEFAULT | GObject.BindingFlags.SYNC_CREATE,
+        )
+        self.bind_property(
+            'label-text', self, 'tooltip-text',
+            GObject.BindingFlags.DEFAULT | GObject.BindingFlags.SYNC_CREATE,
+        )
+
+    @Template.Callback()
+    def on_label_button_press_event(self, widget, event):
+        # Middle-click on the tab closes the tab.
         if event.type == Gdk.EventType.BUTTON_PRESS and event.button == 2:
-            self.__onclose(None)
-
-    def get_label_text(self):
-        return self.__label.get_text()
+            self.page.on_delete_event()
 
-    def set_label_text(self, text):
-        self.__label.set_text(text)
-        self.set_tooltip_text(text)
+    @Template.Callback()
+    def on_close_button_clicked(self, widget):
+        self.page.on_delete_event()


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