[polari] mainWindow: Use template



commit 2d6ccc7c8314e19b0cb8f673dbec355ee7b36b6f
Author: Florian Müllner <fmuellner gnome org>
Date:   Sat Feb 6 16:42:39 2016 +0100

    mainWindow: Use template
    
    As part of our move to consistently use inheritance, the few remaining
    classes that still use GtkBuilder directly need to be migrated to
    templates.

 data/resources/main-window.ui |   47 +++++++------
 src/application.js            |   14 ++--
 src/mainWindow.js             |  154 +++++++++++++++++++++++------------------
 3 files changed, 120 insertions(+), 95 deletions(-)
---
diff --git a/data/resources/main-window.ui b/data/resources/main-window.ui
index 48f4cd7..4489643 100644
--- a/data/resources/main-window.ui
+++ b/data/resources/main-window.ui
@@ -12,16 +12,16 @@
       </item>
     </section>
   </menu>
-  <object class="Gjs_UserListPopover" id="user_list_popover">
+  <object class="Gjs_UserListPopover" id="userListPopover">
     <property name="position">bottom</property>
     <property name="border-width">6</property>
     <property name="width-request">250</property>
-    <property name="relative-to">show_user_list_button</property>
+    <property name="relative-to">showUserListButton</property>
     <style>
       <class name="polari-user-list"/>
     </style>
   </object>
-  <object class="GtkApplicationWindow" id="main_window">
+  <template class="Gjs_MainWindow">
     <property name="title" translatable="yes">Polari</property>
     <property name="icon-name">polari</property>
     <property name="show-menubar">false</property>
@@ -29,7 +29,7 @@
       <object class="GtkBox">
         <property name="visible">True</property>
         <child>
-          <object class="GtkHeaderBar" id="titlebar_left">
+          <object class="GtkHeaderBar" id="titlebarLeft">
             <property name="visible">True</property>
             <property name="hexpand">False</property>
             <property name="show-close-button">True</property>
@@ -37,7 +37,7 @@
               <class name="polari-titlebar-left"/>
             </style>
             <child>
-              <object class="GtkMenuButton" id="join_menu_button">
+              <object class="GtkMenuButton" id="joinMenuButton">
                 <property name="visible">True</property>
                 <property name="halign">end</property>
                 <property name="valign">center</property>
@@ -67,7 +67,7 @@
               </packing>
             </child>
             <child>
-              <object class="GtkLabel" id="titlebar_separator">
+              <object class="GtkLabel">
                 <property name="visible">True</property>
                 <style>
                   <class name="polari-titlebar-separator"/>
@@ -80,7 +80,7 @@
           </object>
         </child>
         <child>
-          <object class="GtkHeaderBar" id="titlebar_right">
+          <object class="GtkHeaderBar" id="titlebarRight">
             <property name="visible">True</property>
             <property name="hexpand">True</property>
             <property name="show-close-button">True</property>
@@ -94,31 +94,37 @@
                  We replicate this by using a stack which will only ever show
                  its first child, but still consider the second one's size -->
             <child type="title">
-              <object class="GtkStack" id="stack1">
+              <object class="GtkStack">
                 <property name="visible">True</property>
                 <property name="margin-start">24</property>
                 <property name="margin-end">24</property>
                 <child>
-                  <object class="GtkBox" id="box5">
+                  <object class="GtkBox">
                     <property name="visible">True</property>
                     <property name="orientation">vertical</property>
                     <property name="valign">center</property>
                     <child>
-                      <object class="GtkLabel" id="title_label">
+                      <object class="GtkLabel">
                         <property name="visible">True</property>
                         <property name="single-line-mode">True</property>
                         <property name="ellipsize">end</property>
+                        <property name="label" bind-source="Gjs_MainWindow"
+                                  bind-property="title" bind-flags="sync-create"/>
                         <style>
                           <class name="title"/>
                         </style>
                       </object>
                     </child>
                     <child>
-                      <object class="GtkLabel" id="subtitle_label">
-                        <property name="visible">True</property>
+                      <object class="GtkLabel">
+                        <property name="visible" bind-source="Gjs_MainWindow"
+                                  bind-property="subtitle-visible"
+                                  bind-flags="sync-create"/>
                         <property name="single-line-mode">True</property>
                         <property name="ellipsize">end</property>
                         <property name="use-markup">True</property>
+                        <property name="label" bind-source="Gjs_MainWindow"
+                                  bind-property="subtitle" bind-flags="sync-create"/>
                         <style>
                           <class name="subtitle"/>
                           <class name="dim-label"/>
@@ -158,7 +164,7 @@
               </object>
             </child>
             <child>
-              <object class="GtkToggleButton" id="show_user_list_button">
+              <object class="GtkToggleButton" id="showUserListButton">
                 <property name="visible">True</property>
                 <property name="focus-on-click">False</property>
                 <property name="action-name">app.user-list</property>
@@ -179,12 +185,12 @@
       <object class="GtkBox">
         <property name="visible">True</property>
         <child>
-          <object class="GtkRevealer" id="room_list_revealer">
+          <object class="GtkRevealer" id="roomListRevealer">
             <property name="visible">True</property>
             <property name="hexpand">False</property>
             <property name="transition-type">slide-right</property>
             <child>
-              <object class="Gjs_FixedSizeFrame" id="room_sidebar">
+              <object class="Gjs_FixedSizeFrame" id="roomSidebar">
                 <property name="visible">True</property>
                 <property name="hexpand">False</property>
                 <property name="width">200</property>
@@ -218,7 +224,7 @@
             <property name="visible">True</property>
             <property name="vexpand">True</property>
             <child>
-              <object class="Gjs_RoomStack" id="room_stack">
+              <object class="Gjs_RoomStack" id="roomStack">
                 <property name="visible">True</property>
                 <property name="homogeneous">True</property>
                 <property name="transition-type">crossfade</property>
@@ -228,12 +234,11 @@
         </child>
       </object>
     </child>
-  </object>
-  <object class="GtkSizeGroup" id="left_side_size_group">
-      <property name="mode">horizontal</property>
+  </template>
+  <object class="GtkSizeGroup">
       <widgets>
-        <widget name="titlebar_left"/>
-        <widget name="room_sidebar"/>
+        <widget name="titlebarLeft"/>
+        <widget name="roomSidebar"/>
       </widgets>
   </object>
 </interface>
diff --git a/src/application.js b/src/application.js
index 0b0e929..c2e476d 100644
--- a/src/application.js
+++ b/src/application.js
@@ -135,18 +135,18 @@ const Application = new Lang.Class({
 
     vfunc_activate: function() {
         if (!this._window) {
-            this._window = new MainWindow.MainWindow(this);
-            this._window.window.connect('destroy', Lang.bind(this,
+            this._window = new MainWindow.MainWindow({ application: this });
+            this._window.connect('destroy', Lang.bind(this,
                 function() {
                     for (let id in this._pendingRequests)
                         this._pendingRequests[id].cancellable.cancel();
                     this.emitJS('prepare-shutdown');
             }));
-            this._window.window.show_all();
+            this._window.show_all();
 
             this._chatroomManager.lateInit();
         }
-        this._window.window.present();
+        this._window.present();
     },
 
     _updateAccountAction: function(action) {
@@ -445,7 +445,7 @@ const Application = new Lang.Class({
         let factory = Tp.AccountManager.dup().get_factory();
         let account = factory.ensure_account(accountPath, []);
         let dialog = new Connections.ConnectionDetailsDialog(account);
-        dialog.transient_for = this._window.window;
+        dialog.transient_for = this._window;
         dialog.connect('response', Lang.bind(this,
             function(w, response) {
                 w.destroy();
@@ -488,7 +488,7 @@ const Application = new Lang.Class({
             website_label: _("Learn more about Polari"),
             website: 'https://wiki.gnome.org/Apps/Polari',
 
-            transient_for: this._window.window,
+            transient_for: this._window,
             modal: true
         };
 
@@ -501,7 +501,7 @@ const Application = new Lang.Class({
     },
 
     _onQuit: function() {
-        this._window.window.destroy();
+        this._window.destroy();
     }
 });
 Utils.addJSSignalMethods(Application.prototype);
diff --git a/src/mainWindow.js b/src/mainWindow.js
index 64c619e..1149757 100644
--- a/src/mainWindow.js
+++ b/src/mainWindow.js
@@ -92,8 +92,36 @@ const FixedSizeFrame = new Lang.Class({
 
 const MainWindow = new Lang.Class({
     Name: 'MainWindow',
+    Extends: Gtk.ApplicationWindow,
+    Template: 'resource:///org/gnome/Polari/ui/main-window.ui',
+    InternalChildren: ['titlebarRight',
+                       'titlebarLeft',
+                       'joinMenuButton',
+                       'showUserListButton',
+                       'userListPopover',
+                       'roomListRevealer',
+                       'overlay',
+                       'roomStack'],
+    Properties: {
+        subtitle: GObject.ParamSpec.string('subtitle',
+                                           'subtitle',
+                                           'subtitle',
+                                           GObject.ParamFlags.READABLE,
+                                           null),
+        'subtitle-visible': GObject.ParamSpec.boolean('subtitle-visible',
+                                                      'subtitle-visible',
+                                                      'subtitle-visible',
+                                                      GObject.ParamFlags.READABLE,
+                                                      false)
+    },
+
+    _init: function(params) {
+        this._subtitle = '';
+
+        this.parent(params);
+
+        this._addApplicationStyle();
 
-    _init: function(app) {
         this._rooms = {};
         this._entries = {};
 
@@ -109,27 +137,32 @@ const MainWindow = new Lang.Class({
         this._isMaximized = false;
         this._isFullscreen = false;
 
-        this._createWidget(app);
+        let app = this.application;
+        this._overlay.add_overlay(app.notificationQueue);
+        this._overlay.add_overlay(app.commandOutputQueue);
 
-        let provider = new Gtk.CssProvider();
-        let uri = 'resource:///org/gnome/Polari/css/application.css';
-        let file = Gio.File.new_for_uri(uri);
-        try {
-            provider.load_from_file(Gio.File.new_for_uri(uri));
-        } catch(e) {
-            logError(e, "Failed to add application style");
-        }
-        Gtk.StyleContext.add_provider_for_screen(
-            this.window.get_screen(),
-            provider,
-            Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
-        );
+        // command output notifications should not pop up over
+        // the input area, but appear to emerge from it, so
+        // set up an appropriate margin
+        this._roomStack.bind_property('entry-area-height',
+                                      app.commandOutputQueue, 'margin-bottom',
+                                      GObject.BindingFlags.SYNC_CREATE);
+
+        // Make sure user-list button is at least as wide as icon buttons
+        this._joinMenuButton.connect('size-allocate', Lang.bind(this,
+            function(w, rect) {
+                let width = rect.width;
+                Mainloop.idle_add(Lang.bind(this, function() {
+                    this._showUserListButton.width_request = width;
+                    return GLib.SOURCE_REMOVE;
+                }));
+            }));
 
         this._accountsMonitor = AccountsMonitor.getDefault();
         this._accountsMonitor.connect('accounts-changed', Lang.bind(this,
             function(am) {
                 let accounts = am.dupAccounts();
-                this._revealer.reveal_child = accounts.some(function(a) {
+                this._roomListRevealer.reveal_child = accounts.some(function(a) {
                     return a.enabled;
                 });
             }));
@@ -158,21 +191,29 @@ const MainWindow = new Lang.Class({
                                   Lang.bind(this, this._updateDecorations));
         this._updateDecorations();
 
-        this.window.connect('window-state-event',
+        this.connect('window-state-event',
                             Lang.bind(this, this._onWindowStateEvent));
-        this.window.connect('size-allocate',
+        this.connect('size-allocate',
                             Lang.bind(this, this._onSizeAllocate));
-        this.window.connect('delete-event',
+        this.connect('delete-event',
                             Lang.bind(this, this._onDelete));
 
         let size = this._settings.get_value('window-size').deep_unpack();
         if (size.length == 2)
-            this.window.set_default_size.apply(this.window, size);
+            this.set_default_size.apply(this, size);
 
         if (this._settings.get_boolean('window-maximized'))
-            this.window.maximize();
+            this.maximize();
+
+        this.show_all();
+    },
 
-        this.window.show_all();
+    get subtitle() {
+        return this._subtitle;
+    },
+
+    get subtitle_visible() {
+        return this._subtitle.length > 0;
     },
 
     _onWindowStateEvent: function(widget, event) {
@@ -184,7 +225,7 @@ const MainWindow = new Lang.Class({
 
     _onSizeAllocate: function(widget, allocation) {
         if (!this._isFullscreen && !this._isMaximized)
-            this._currentSize = this.window.get_size(this);
+            this._currentSize = this.get_size(this);
     },
 
     _onDelete: function(widget, event) {
@@ -237,54 +278,29 @@ const MainWindow = new Lang.Class({
                                Lang.bind(this, this._updateUserListLabel));
     },
 
-    _createWidget: function(app) {
-        let builder = new Gtk.Builder();
-        builder.add_from_resource('/org/gnome/Polari/ui/main-window.ui');
-
-        this.window = builder.get_object('main_window');
-        this.window.application = app;
-
-        let overlay = builder.get_object('overlay');
-        overlay.add_overlay(app.notificationQueue);
-        overlay.add_overlay(app.commandOutputQueue);
-
-        this._titlebarRight = builder.get_object('titlebar_right');
-        this._titlebarLeft = builder.get_object('titlebar_left');
-
-        this._titleLabel = builder.get_object('title_label');
-        this._subtitleLabel = builder.get_object('subtitle_label');
-
-        this._joinMenuButton = builder.get_object('join_menu_button');
-        this._showUserListButton = builder.get_object('show_user_list_button');
-        this._userListPopover = builder.get_object('user_list_popover');
-        this._revealer = builder.get_object('room_list_revealer');
-
-        // command output notifications should not pop up over
-        // the input area, but appear to emerge from it, so
-        // set up an appropriate margin
-        let roomStack = builder.get_object('room_stack');
-        roomStack.bind_property('entry-area-height',
-                                app.commandOutputQueue, 'margin-bottom',
-                                GObject.BindingFlags.SYNC_CREATE);
-
-        // Make sure user-list button is at least as wide as icon buttons
-        this._joinMenuButton.connect('size-allocate', Lang.bind(this,
-            function(w, rect) {
-                let width = rect.width;
-                Mainloop.idle_add(Lang.bind(this, function() {
-                    this._showUserListButton.width_request = width;
-                    return GLib.SOURCE_REMOVE;
-                }));
-            }));
+    _addApplicationStyle: function() {
+        let provider = new Gtk.CssProvider();
+        let uri = 'resource:///org/gnome/Polari/css/application.css';
+        let file = Gio.File.new_for_uri(uri);
+        try {
+            provider.load_from_file(Gio.File.new_for_uri(uri));
+        } catch(e) {
+            logError(e, "Failed to add application style");
+        }
+        Gtk.StyleContext.add_provider_for_screen(
+            this.get_screen(),
+            provider,
+            Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
+        );
     },
 
     showJoinRoomDialog: function() {
-        let dialog = new JoinDialog.JoinDialog({ transient_for: this.window });
+        let dialog = new JoinDialog.JoinDialog({ transient_for: this });
         dialog.show();
     },
 
     showMessageUserDialog: function() {
-        let dialog = new MessageDialog.MessageDialog({ transient_for: this.window });
+        let dialog = new MessageDialog.MessageDialog({ transient_for: this });
         dialog.show();
     },
 
@@ -317,9 +333,13 @@ const MainWindow = new Lang.Class({
             }
             subtitle += GLib.markup_escape_text(this._room.topic.substr(pos), -1);
         }
-        this._subtitleLabel.label = subtitle;
-        this._subtitleLabel.visible = subtitle.length > 0;
 
-        this._titleLabel.label = this._room ? this._room.display_name : null;
+        if (this._subtitle != subtitle) {
+            this._subtitle = subtitle;
+            this.notify('subtitle');
+            this.notify('subtitle-visible');
+        }
+
+        this.title = this._room ? this._room.display_name : null;
     }
 });


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