[polari/wip/fmuellner/room-list: 10/12] WIP: Use TreeView



commit 2dad3860119ca5f8a6179f67a14e5e1a4ff9501a
Author: Florian Müllner <fmuellner gnome org>
Date:   Mon Nov 28 19:03:52 2016 +0100

    WIP: Use TreeView

 data/resources/application.css |    4 +
 src/serverRoomManager.js       |  124 +++++++++++++++++++++++++++++++--------
 2 files changed, 102 insertions(+), 26 deletions(-)
---
diff --git a/data/resources/application.css b/data/resources/application.css
index cbdb332..ab94219 100644
--- a/data/resources/application.css
+++ b/data/resources/application.css
@@ -92,6 +92,10 @@
     background-color: mix(@theme_unfocused_selected_bg_color, @theme_unfocused_selected_fg_color, 0.1);
 }
 
+treeview.polari-server-room-list {
+    padding: 6px 12px;
+}
+
 .irc-feedback {
     color: @theme_fg_color;
     background-color: @theme_bg_color;
diff --git a/src/serverRoomManager.js b/src/serverRoomManager.js
index 236b94c..8dbb1a8 100644
--- a/src/serverRoomManager.js
+++ b/src/serverRoomManager.js
@@ -93,6 +93,15 @@ const _ServerRoomManager = new Lang.Class({
 });
 Signals.addSignalMethods(_ServerRoomManager.prototype);
 
+
+const RoomListColumn = {
+    CHECKED:   0,
+    NAME:      1,
+    COUNT:     2,
+
+    SENSITIVE: 3,
+};
+
 const ServerRoomList = new Lang.Class({
     Name: 'ServerRoomList',
     Extends: Gtk.ScrolledWindow,
@@ -118,18 +127,61 @@ const ServerRoomList = new Lang.Class({
             this.setAccount(null);
         });
 
-        this._list = new Gtk.ListBox({ visible: true });
-        this._list.set_header_func(Lang.bind(this, this._updateHeader));
-        this._list.connect('row-activated',
-                               Lang.bind(this, this._onRowActivated));
+        let store = new Gtk.ListStore();
+        store.set_column_types([GObject.TYPE_BOOLEAN,
+                                GObject.TYPE_STRING,
+                                GObject.TYPE_STRING,
+                                GObject.TYPE_BOOLEAN]);
+
+        this._list = new Gtk.TreeView({ model: store,
+                                        activate_on_single_click: true,
+                                        enable_grid_lines: Gtk.TreeViewGridLines.HORIZONTAL,
+                                        headers_visible: false,
+                                        visible: true });
+        this._list.get_style_context().add_class('polari-server-room-list');
+        this._list.connect('row-activated', (view, path, column) => {
+            this._toggleChecked(path);
+        });
         this.add(this._list);
 
+        let renderer;
+
+        let column = new Gtk.TreeViewColumn();
+        this._list.append_column(column);
+
+        renderer = new Gtk.CellRendererToggle();
+        renderer.connect('toggled', (cell, pathStr) => {
+            this._toggleChecked(Gtk.TreePath.new_from_string(pathString));
+        });
+
+        column.pack_start(renderer, false);
+        column.add_attribute(renderer, 'active', RoomListColumn.CHECKED);
+        column.add_attribute(renderer, 'sensitive', RoomListColumn.SENSITIVE);
+
+        renderer = new Gtk.CellRendererText();
+
+        column.pack_start(renderer, true);
+        column.add_attribute(renderer, 'text', RoomListColumn.NAME);
+        column.add_attribute(renderer, 'sensitive', RoomListColumn.SENSITIVE);
+
+        renderer = new Gtk.CellRendererText();
+
+        column.pack_start(renderer, false);
+        column.add_attribute(renderer, 'text', RoomListColumn.COUNT);
+        column.add_attribute(renderer, 'sensitive', RoomListColumn.SENSITIVE);
+
         this._manager = getDefault();
         this._manager.connect('loaded', Lang.bind(this, this._onLoaded));
     },
 
     get can_join() {
-        return this._list.get_children().some(r => r.sensitive && r.checked);
+        let canJoin = false;
+        this._list.model.foreach((model, path, iter) => {
+            canJoin = model.get_value(iter, RoomListColumn.SENSITIVE) &&
+                      model.get_value(iter, RoomListColumn.CHECKED);
+            return canJoin;
+        });
+        return canJoin;
     },
 
     get loading() {
@@ -137,13 +189,16 @@ const ServerRoomList = new Lang.Class({
                this._manager.isLoading(this._account);
     },
 
-    _onRowActivated: function(list, row) {
-        row.activate();
-    },
-
     get selectedRooms() {
-        let selectedRows = this._list.get_children().filter(r => r.checked);
-        return selectedRows.map(r => r.info.get_name());
+        let rooms = [];
+        let [valid, iter] = this._list.model.get_iter_first();
+        for (; valid; valid = this._list.model.iter_next(iter)) {
+            if (!this._list.model.get_value(iter, RoomListColumn.SENSITIVE) ||
+                !this._list.model.get_value(iter, RoomListColumn.CHECKED))
+                continue;
+            rooms.push(this._list.model.get_value(iter, RoomListColumn.NAME));
+        }
+        return rooms;
     },
 
     setAccount: function(account) {
@@ -154,18 +209,11 @@ const ServerRoomList = new Lang.Class({
         this._onLoaded(this._manager, account);
     },
 
-    _updateHeader: function(row, before) {
-        if (!before)
-            row.set_header(null);
-        else if (!row.get_header())
-            row.set_header(new Gtk.Separator());
-    },
-
     _onLoaded: function(mgr, account) {
         if (account != this._account)
             return;
 
-        this._list.foreach(function(w) { w.destroy(); });
+        this._list.model.clear();
 
         if (this._timeoutId)
             Mainloop.source_remove(this._timeoutId);
@@ -182,11 +230,29 @@ const ServerRoomList = new Lang.Class({
 
         this.notify('loading');
 
+        let roomManager = RoomManager.getDefault();
+
         this._timeoutId = Mainloop.timeout_add(500, () => {
             this._pendingInfos.splice(0, 50).forEach(roomInfo => {
-                let row = new ServerRoomRow({ info: roomInfo });
-                row.connect('notify::checked', () => { this.notify('can-join'); });
-                this._list.add(row);
+                let store = this._list.model;
+
+                let name = roomInfo.get_name();
+                if (name[0] == '#')
+                    name = name.substr(1, name.length);
+
+                let room = roomManager.lookupRoomByName(roomInfo.get_name());
+                let sensitive = room == null;
+                let checked = !sensitive;
+                let count = '%d'.format(roomInfo.get_members_count(null));
+
+                store.insert_with_valuesv(-1,
+                                          [RoomListColumn.CHECKED,
+                                           RoomListColumn.NAME,
+                                           RoomListColumn.COUNT,
+                                           RoomListColumn.SENSITIVE],
+                                          [checked, name, count, sensitive]);
+
+                //row.connect('notify::checked', () => { this.notify('can-join'); });
             });
             if (this._pendingInfos.length)
                 return GLib.SOURCE_CONTINUE;
@@ -195,6 +261,16 @@ const ServerRoomList = new Lang.Class({
             this.notify('loading');
             return GLib.SOURCE_REMOVE;
         });
+    },
+
+    _toggleChecked: function(path) {
+        let [valid, iter] = this._list.model.get_iter(path);
+        if (!this._list.model.get_value(iter, RoomListColumn.SENSITIVE))
+            return;
+        let checked = this._list.model.get_value(iter, RoomListColumn.CHECKED);
+        this._list.model.set_value(iter, RoomListColumn.CHECKED, !checked);
+
+        this.notify('can-join');
     }
 });
 
@@ -253,9 +329,5 @@ const ServerRoomRow = new Lang.Class({
 
     get checked() {
         return this._checkbox.active;
-    },
-
-    vfunc_activate: function() {
-        this._checkbox.activate();
     }
 });


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