Skip to contentSkip to conversation

Hob tweaks

PATCH Applied Joshua Lock 3 participants 16 messages Mar 20, 2012

lore
Share & tools
lore
#0 lore raw

cover Hob tweaks

Here's a series of patches to polish the Hob GUI: some minor tweaks to remove redundant calls and API, a couple of HIG related tweaks to buttons, a change to the persistenttooltip to try and match the close position of the window manager (i.e. running under Unity on Ubuntu the close button on the persistent tooltip will appear on the left) and finally a change to the layer dialogue implementation so that it more closely matches the interaction design (this is still pending some designer feedback on visuals and whether to remove some labels but they can easily be implemented as iterative patches on top of these).

Cheers,

Joshua

The following changes since commit 5a1e62a8cdd4f0253b0dc59046b3b4c3186af461:

bitbake/fetch2: Fix typo which broke use of tarballs (2012-03-16 23:44:08 +0000)

are available in the git repository at:
git://github.com/incandescant/bitbake josh/hob
https://github.com/incandescant/bitbake/tree/josh/hob
git://git.yoctoproject.org/poky-contrib josh/hob
http://git.yoctoproject.org/cgit/cgit.cgi/poky-contrib/log/?h=josh/hob

Joshua Lock (6):
ui/crumbs/hig: use close rather than OK for dismis button ui/crumbs: remove unused return value from append_toolbar_button ui/crumbs/hobpage: no need to force a Toolbar button type ui/crumbs/persistenttooltip: try to reflect WM close button position ui/crumbs/builder: remove OK/Cancel buttons on Layer dialog. Use
Close.
ui/crumbs/hig: make the layer selection dialogue more closely match
design

 lib/bb/ui/crumbs/builder.py                |    3 +-
 lib/bb/ui/crumbs/hig.py                    |   98 +++++++++++++++++++++-------
 lib/bb/ui/crumbs/hobpages.py               |    6 +-
 lib/bb/ui/crumbs/imageconfigurationpage.py |    6 +-
 lib/bb/ui/crumbs/imagedetailspage.py       |    2 +-
 lib/bb/ui/crumbs/persistenttooltip.py      |   24 +++++++-
 6 files changed, 105 insertions(+), 34 deletions(-)
Signature · 1 line
1.7.7.6
#1 lore raw

PATCH 1/6 ui/crumbs/hig: use close rather than OK for dismis button

Dialogue buttons should have descriptive names

---
 lib/bb/ui/crumbs/hig.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
lib/bb/ui/crumbs/hig.py +1 -1
index 67cc94e..849d7c9 100644
@@ -838,7 +838,7 @@ class LayerSelectionDialog (CrumbsDialog):
                 layer_store.append([path])
                 return
             dialog = CrumbsMessageDialog(parent, lbl)
-            dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
+            dialog.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_OK)
             response = dialog.run()
             dialog.destroy()
 
Signature · 1 line
1.7.7.6
Acked-by on v1 1/6
#2 lore raw

Re: [PATCH 1/6] ui/crumbs/hig: use close rather than OK for dismis button

Quoted 3 lines · Joshua Lock

Dialogue buttons should have descriptive names

Quoted 17 lines
---
 lib/bb/ui/crumbs/hig.py |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)
lib/bb/ui/crumbs/hig.py +1 -1
index 67cc94e..849d7c9 100644
@@ -838,7 +838,7 @@ class LayerSelectionDialog (CrumbsDialog):
                 layer_store.append([path])
                 return
             dialog = CrumbsMessageDialog(parent, lbl)
-            dialog.add_button(gtk.STOCK_OK, gtk.RESPONSE_OK)
+            dialog.add_button(gtk.STOCK_CLOSE, gtk.RESPONSE_OK)
             response = dialog.run()
             dialog.destroy()
 
#3 lore raw

PATCH 2/6 ui/crumbs: remove unused return value from append_toolbar_button

In reply to Joshua Lock

No caller of the method uses the returned toolbar variable

---
 lib/bb/ui/crumbs/hobpages.py               |    2 +-
 lib/bb/ui/crumbs/imageconfigurationpage.py |    6 +++---
 lib/bb/ui/crumbs/imagedetailspage.py       |    2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)
lib/bb/ui/crumbs/hobpages.py +1 -1
index bd4b292..8137c0d 100755
@@ -84,4 +84,4 @@ class HobPage (gtk.VBox):
         button = toolbar.append_element(gtk.TOOLBAR_CHILD_RADIOBUTTON, None,
                      buttonname, tip_text, "Private text", icon,
                      cb, None)
-        return toolbar, button
+        return button
lib/bb/ui/crumbs/imageconfigurationpage.py +3 -3
index c8f7a56..b0c5daa 100644
@@ -45,19 +45,19 @@ class ImageConfigurationPage (HobPage):
         self.toolbar.set_orientation(gtk.ORIENTATION_HORIZONTAL)
         self.toolbar.set_style(gtk.TOOLBAR_BOTH)
 
-        _, template_button = self.append_toolbar_button(self.toolbar,
+        template_button = self.append_toolbar_button(self.toolbar,
             "Template",
             hic.ICON_TEMPLATES_DISPLAY_FILE,
             hic.ICON_TEMPLATES_HOVER_FILE,
             "Load a hob building template saved before",
             self.template_button_clicked_cb)
-        _, my_images_button = self.append_toolbar_button(self.toolbar,
+        my_images_button = self.append_toolbar_button(self.toolbar,
             "My images",
             hic.ICON_IMAGES_DISPLAY_FILE,
             hic.ICON_IMAGES_HOVER_FILE,
             "Open images built out previously for running or deployment",
             self.my_images_button_clicked_cb)
-        _, settings_button = self.append_toolbar_button(self.toolbar,
+        settings_button = self.append_toolbar_button(self.toolbar,
             "Settings",
             hic.ICON_SETTINGS_DISPLAY_FILE,
             hic.ICON_SETTINGS_HOVER_FILE,
lib/bb/ui/crumbs/imagedetailspage.py +1 -1
index c063d74..0159d15 100755
@@ -122,7 +122,7 @@ class ImageDetailsPage (HobPage):
         self.toolbar.set_orientation(gtk.ORIENTATION_HORIZONTAL)
         self.toolbar.set_style(gtk.TOOLBAR_BOTH)
 
-        _, my_images_button = self.append_toolbar_button(self.toolbar,
+        my_images_button = self.append_toolbar_button(self.toolbar,
             "My images",
             hic.ICON_IMAGES_DISPLAY_FILE,
             hic.ICON_IMAGES_HOVER_FILE,
Signature · 1 line
1.7.7.6
Acked-by on v1 2/6
#4 lore raw

Re: [PATCH 2/6] ui/crumbs: remove unused return value from append_toolbar_button

Quoted 3 lines · Joshua Lock

No caller of the method uses the returned toolbar variable

Quoted 56 lines
---
 lib/bb/ui/crumbs/hobpages.py               |    2 +-
 lib/bb/ui/crumbs/imageconfigurationpage.py |    6 +++---
 lib/bb/ui/crumbs/imagedetailspage.py       |    2 +-
 3 files changed, 5 insertions(+), 5 deletions(-)
lib/bb/ui/crumbs/hobpages.py +1 -1
index bd4b292..8137c0d 100755
@@ -84,4 +84,4 @@ class HobPage (gtk.VBox):
         button = toolbar.append_element(gtk.TOOLBAR_CHILD_RADIOBUTTON, None,
                      buttonname, tip_text, "Private text", icon,
                      cb, None)
-        return toolbar, button
+        return button
lib/bb/ui/crumbs/imageconfigurationpage.py +3 -3
index c8f7a56..b0c5daa 100644
@@ -45,19 +45,19 @@ class ImageConfigurationPage (HobPage):
         self.toolbar.set_orientation(gtk.ORIENTATION_HORIZONTAL)
         self.toolbar.set_style(gtk.TOOLBAR_BOTH)
 
-        _, template_button = self.append_toolbar_button(self.toolbar,
+        template_button = self.append_toolbar_button(self.toolbar,
             "Template",
             hic.ICON_TEMPLATES_DISPLAY_FILE,
             hic.ICON_TEMPLATES_HOVER_FILE,
             "Load a hob building template saved before",
             self.template_button_clicked_cb)
-        _, my_images_button = self.append_toolbar_button(self.toolbar,
+        my_images_button = self.append_toolbar_button(self.toolbar,
             "My images",
             hic.ICON_IMAGES_DISPLAY_FILE,
             hic.ICON_IMAGES_HOVER_FILE,
             "Open images built out previously for running or deployment",
             self.my_images_button_clicked_cb)
-        _, settings_button = self.append_toolbar_button(self.toolbar,
+        settings_button = self.append_toolbar_button(self.toolbar,
             "Settings",
             hic.ICON_SETTINGS_DISPLAY_FILE,
             hic.ICON_SETTINGS_HOVER_FILE,
lib/bb/ui/crumbs/imagedetailspage.py +1 -1
index c063d74..0159d15 100755
@@ -122,7 +122,7 @@ class ImageDetailsPage (HobPage):
         self.toolbar.set_orientation(gtk.ORIENTATION_HORIZONTAL)
         self.toolbar.set_style(gtk.TOOLBAR_BOTH)
 
-        _, my_images_button = self.append_toolbar_button(self.toolbar,
+        my_images_button = self.append_toolbar_button(self.toolbar,
             "My images",
             hic.ICON_IMAGES_DISPLAY_FILE,
             hic.ICON_IMAGES_HOVER_FILE,
#5 lore raw

PATCH 3/6 ui/crumbs/hobpage: no need to force a Toolbar button type

In reply to Joshua Lock

This uses a more concise API that will be more flexible whent he Toolbar style is updated to match the visual design.

---
 lib/bb/ui/crumbs/hobpages.py |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)
lib/bb/ui/crumbs/hobpages.py +1 -3
index 8137c0d..baf250b 100755
@@ -81,7 +81,5 @@ class HobPage (gtk.VBox):
         pix_buffer = gtk.gdk.pixbuf_new_from_file(icon_display)
         icon.set_from_pixbuf(pix_buffer)
         tip_text = tip
-        button = toolbar.append_element(gtk.TOOLBAR_CHILD_RADIOBUTTON, None,
-                     buttonname, tip_text, "Private text", icon,
-                     cb, None)
+        button = toolbar.append_item(buttonname, tip, None, icon, cb)
         return button
Signature · 1 line
1.7.7.6
Acked-by on v1 3/6
#6 lore raw

Re: [PATCH 3/6] ui/crumbs/hobpage: no need to force a Toolbar button type

Quoted 3 lines · Joshua Lock

This uses a more concise API that will be more flexible whent he Toolbar style is updated to match the visual design.

Quoted 18 lines
---
 lib/bb/ui/crumbs/hobpages.py |    4 +---
 1 files changed, 1 insertions(+), 3 deletions(-)
lib/bb/ui/crumbs/hobpages.py +1 -3
index 8137c0d..baf250b 100755
@@ -81,7 +81,5 @@ class HobPage (gtk.VBox):
         pix_buffer = gtk.gdk.pixbuf_new_from_file(icon_display)
         icon.set_from_pixbuf(pix_buffer)
         tip_text = tip
-        button = toolbar.append_element(gtk.TOOLBAR_CHILD_RADIOBUTTON, None,
-                     buttonname, tip_text, "Private text", icon,
-                     cb, None)
+        button = toolbar.append_item(buttonname, tip, None, icon, cb)
         return button
#7 lore raw

PATCH 4/6 ui/crumbs/persistenttooltip: try to reflect WM close button position

In reply to Joshua Lock

When the user is running a desktop where the close button is on the left we try to detect that and position the tooltip close button appropriately. Where we can't easily determine this we default to placing the close button on the right.

Tested on Ubuntu/Unity and Fedora/Gnome Shell.

---
 lib/bb/ui/crumbs/persistenttooltip.py |   24 +++++++++++++++++++++++-
 1 files changed, 23 insertions(+), 1 deletions(-)
lib/bb/ui/crumbs/persistenttooltip.py +23 -1
index 0167363..bae697e 100644
@@ -20,6 +20,10 @@
 
 import gobject
 import gtk
+try:
+    import gconf
+except:
+    pass
 
 class PersistentTooltip(gtk.Window):
 	"""
@@ -34,6 +38,21 @@ class PersistentTooltip(gtk.Window):
 	def __init__(self, markup):
 		gtk.Window.__init__(self, gtk.WINDOW_POPUP)
 
+		# The placement of the close button on the tip should reflect how the
+		# window manager of the users system places close buttons. Try to read
+		# the metacity gconf key to determine whether the close button is on the
+		# left or the right.
+		# In the case that we can't determine the users configuration we default
+		# to close buttons being on the right.
+		__button_right = True
+		try:
+		    client = gconf.client_get_default()
+		    order = client.get_string("/apps/metacity/general/button_layout")
+		    if order and order.endswith(":"):
+		        __button_right = False
+		except NameError:
+			pass
+
 		# We need to ensure we're only shown once
 		self.shown = False
 
@@ -65,7 +84,10 @@ class PersistentTooltip(gtk.Window):
 		self.button.set_can_default(True)
 		self.button.grab_focus()
 		self.button.show()
-		hbox.pack_end(self.button, False, False, 0)
+		if __button_right:
+		    hbox.pack_end(self.button, False, False, 0)
+		else:
+		    hbox.pack_start(self.button, False, False, 0)
 
 		self.set_default(self.button)
 
Signature · 1 line
1.7.7.6
Acked-by on v1 4/6
#8 lore raw

Re: [PATCH 4/6] ui/crumbs/persistenttooltip: try to reflect WM close button position

Quoted 8 lines · Joshua Lock

When the user is running a desktop where the close button is on the left we try to detect that and position the tooltip close button appropriately. Where we can't easily determine this we default to placing the close button on the right.

Tested on Ubuntu/Unity and Fedora/Gnome Shell.

Quoted 53 lines
---
 lib/bb/ui/crumbs/persistenttooltip.py |   24 +++++++++++++++++++++++-
 1 files changed, 23 insertions(+), 1 deletions(-)
lib/bb/ui/crumbs/persistenttooltip.py +23 -1
index 0167363..bae697e 100644
@@ -20,6 +20,10 @@
 
 import gobject
 import gtk
+try:
+    import gconf
+except:
+    pass
 
 class PersistentTooltip(gtk.Window):
 	"""
@@ -34,6 +38,21 @@ class PersistentTooltip(gtk.Window):
 	def __init__(self, markup):
 		gtk.Window.__init__(self, gtk.WINDOW_POPUP)
 
+		# The placement of the close button on the tip should reflect how the
+		# window manager of the users system places close buttons. Try to read
+		# the metacity gconf key to determine whether the close button is on the
+		# left or the right.
+		# In the case that we can't determine the users configuration we default
+		# to close buttons being on the right.
+		__button_right = True
+		try:
+		    client = gconf.client_get_default()
+		    order = client.get_string("/apps/metacity/general/button_layout")
+		    if order and order.endswith(":"):
+		        __button_right = False
+		except NameError:
+			pass
+
 		# We need to ensure we're only shown once
 		self.shown = False
 
@@ -65,7 +84,10 @@ class PersistentTooltip(gtk.Window):
 		self.button.set_can_default(True)
 		self.button.grab_focus()
 		self.button.show()
-		hbox.pack_end(self.button, False, False, 0)
+		if __button_right:
+		    hbox.pack_end(self.button, False, False, 0)
+		else:
+		    hbox.pack_start(self.button, False, False, 0)
 
 		self.set_default(self.button)
 
#9 lore raw

PATCH 5/6 ui/crumbs/builder: remove OK/Cancel buttons on Layer dialog. Use Close.

In reply to Joshua Lock
---
 lib/bb/ui/crumbs/builder.py |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)
lib/bb/ui/crumbs/builder.py +1 -2
index 1d255ac..9e85e72 100755
@@ -668,8 +668,7 @@ class Builder(gtk.Window):
                      flags = gtk.DIALOG_MODAL
                          | gtk.DIALOG_DESTROY_WITH_PARENT
                          | gtk.DIALOG_NO_SEPARATOR,
-                     buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_NO,
-                                gtk.STOCK_OK, gtk.RESPONSE_YES))
+                     buttons = (gtk.STOCK_CLOSE, gtk.RESPONSE_YES))
         response = dialog.run()
         if response == gtk.RESPONSE_YES:
             self.configuration.layers = dialog.layers
Signature · 1 line
1.7.7.6
#10 lore raw

Re: [PATCH 5/6] ui/crumbs/builder: remove OK/Cancel buttons on Layer dialog. Use Close.

Quoted 10 lines · Joshua Lock
---
 lib/bb/ui/crumbs/builder.py |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)
lib/bb/ui/crumbs/builder.py +0 -0
index 1d255ac..9e85e72 100755

lib/bb/ui/crumbs/builder.py class Builder(gtk.Window): · line 671

Quoted 6 lines
lib/bb/ui/crumbs/builder.py +1 -2
@@ -668,8 +668,7 @@ class Builder(gtk.Window):
                      flags = gtk.DIALOG_MODAL
                          | gtk.DIALOG_DESTROY_WITH_PARENT
                          | gtk.DIALOG_NO_SEPARATOR,
-                     buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_NO,
-                                gtk.STOCK_OK, gtk.RESPONSE_YES))
+                     buttons = (gtk.STOCK_CLOSE, gtk.RESPONSE_YES))

If users did some trial operations, for example deleted some layers, is it better that we provide a "cancel" button for users to ignore their changes?

Need comments from Belen and Giulia.

Thanks,
Dongxiao

Quoted 3 lines
lib/bb/ui/crumbs/builder.py +0 -0
         response = dialog.run()
         if response == gtk.RESPONSE_YES:
             self.configuration.layers = dialog.layers
#11 lore raw

Re: [PATCH 5/6] ui/crumbs/builder: remove OK/Cancel buttons on Layer dialog. Use Close.

Quoted 22 lines · Dongxiao
Quoted 10 lines · Joshua Lock
---
  lib/bb/ui/crumbs/builder.py |    3 +--
  1 files changed, 1 insertions(+), 2 deletions(-)
lib/bb/ui/crumbs/builder.py +0 -0
index 1d255ac..9e85e72 100755

lib/bb/ui/crumbs/builder.py class Builder(gtk.Window): · line 671

Quoted 6 lines
lib/bb/ui/crumbs/builder.py +1 -2
@@ -668,8 +668,7 @@ class Builder(gtk.Window):
                       flags = gtk.DIALOG_MODAL
                           | gtk.DIALOG_DESTROY_WITH_PARENT
                           | gtk.DIALOG_NO_SEPARATOR,
-                     buttons = (gtk.STOCK_CANCEL, gtk.RESPONSE_NO,
-                                gtk.STOCK_OK, gtk.RESPONSE_YES))
+                     buttons = (gtk.STOCK_CLOSE, gtk.RESPONSE_YES))

If users did some trial operations, for example deleted some layers, is it better that we provide a "cancel" button for users to ignore their changes?

Quoted 1 line

Need comments from Belen and Giulia.

Fair point, I'll wait for input from the design team for this one.

Cheers,
Joshua

Signature · 3 lines
Joshua '贾詡' Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#12 lore raw

PATCH 6/6 ui/crumbs/hig: make the layer selection dialogue more closely match design

In reply to Joshua Lock

The layer dialogue design includes in-line remove/delete widgets next to the layer path in the tree view for all layers other than the meta layer as well as an in-line notice that the meta layer cannot be removed.

This is achieved in this patch through the use of custom cell_data_func's for the treeview to render the meta layer differently and a custom CellRenderer implementation, CellRendererPixbufActivatable, which renders a pixbuf and emits a clicked signal when the user clicks on it.

---
 lib/bb/ui/crumbs/hig.py |   96 ++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 74 insertions(+), 22 deletions(-)
lib/bb/ui/crumbs/hig.py +74 -22
index 849d7c9..5b0cfc9 100644
@@ -789,6 +789,26 @@ class DeployImageDialog (CrumbsDialog):
         os.close(f_from)
         os.close(f_to)
         self.progress_bar.hide()
+
+class CellRendererPixbufActivatable(gtk.CellRendererPixbuf):
+    """
+    A custom CellRenderer implementation which is activatable
+    so that we can handle user clicks
+    """
+    __gsignals__    = { 'clicked' : (gobject.SIGNAL_RUN_LAST,
+                                     gobject.TYPE_NONE,
+                                     (gobject.TYPE_STRING,)), }
+
+    def __init__(self):
+        gtk.CellRendererPixbuf.__init__(self)
+        self.set_property('mode', gtk.CELL_RENDERER_MODE_ACTIVATABLE)
+
+    """
+    Respond to a user click on a cell
+    """
+    def do_activate(self, even, widget, path, background_area, cell_area, flags):
+        self.emit('clicked', path)
+
 #
 # LayerSelectionDialog
 #
@@ -855,13 +875,13 @@ class LayerSelectionDialog (CrumbsDialog):
         layer_tv.set_rules_hint(True)
         layer_tv.set_headers_visible(False)
         tree_selection = layer_tv.get_selection()
-        tree_selection.set_mode(gtk.SELECTION_SINGLE)
+        tree_selection.set_mode(gtk.SELECTION_NONE)
 
         col0= gtk.TreeViewColumn('Path')
         cell0 = gtk.CellRendererText()
         cell0.set_padding(5,2)
         col0.pack_start(cell0, True)
-        col0.set_attributes(cell0, text=0)
+        col0.set_cell_data_func(cell0, self.draw_layer_path_cb)
         layer_tv.append_column(col0)
 
         scroll = gtk.ScrolledWindow()
@@ -897,18 +917,19 @@ class LayerSelectionDialog (CrumbsDialog):
             for layer in layers:
                 layer_store.set(layer_store.append(), 0, layer)
 
-            image = gtk.Image()
-            image.set_from_stock(gtk.STOCK_ADD,gtk.ICON_SIZE_MENU)
+            col1 = gtk.TreeViewColumn('Enabled')
+            layer_tv.append_column(col1)
+
+            cell1 = CellRendererPixbufActivatable()
+            cell1.connect("clicked", self.del_cell_clicked_cb, layer_store)
+            col1.pack_start(cell1, True)
+            col1.set_cell_data_func(cell1, self.draw_delete_button_cb, layer_tv)
+
             add_button = gtk.Button()
-            add_button.set_image(image)
+            add_button.set_label("_Add layer")
+            add_button.set_use_underline(True)
             add_button.connect("clicked", self.layer_widget_add_clicked_cb, layer_store, window)
-            table_layer.attach(add_button, 0, 5, 1, 2, gtk.EXPAND | gtk.FILL, 0, 0, 6)
-            image = gtk.Image()
-            image.set_from_stock(gtk.STOCK_REMOVE,gtk.ICON_SIZE_MENU)
-            del_button = gtk.Button()
-            del_button.set_image(image)
-            del_button.connect("clicked", self.layer_widget_del_clicked_cb, tree_selection, layer_store)
-            table_layer.attach(del_button, 5, 10, 1, 2, gtk.EXPAND | gtk.FILL, 0, 0, 6)
+            table_layer.attach(add_button, 0, 10, 1, 2, gtk.EXPAND | gtk.FILL, 0, 0, 6)
         layer_tv.set_model(layer_store)
 
         hbox.show_all()
@@ -936,24 +957,16 @@ class LayerSelectionDialog (CrumbsDialog):
         hbox_top = gtk.HBox()
         self.vbox.pack_start(hbox_top, expand=False, fill=False)
 
-        if self.split_model:
-            label = self.gen_label_widget("<b>Select Layers:</b>\n(Available layers under '${COREBASE}/layers/' directory)")
-        else:
-            label = self.gen_label_widget("<b>Select Layers:</b>")
+        label = self.gen_label_widget("<b>Select Layers:</b>")
         hbox_top.pack_start(label, expand=False, fill=False)
-
         tooltip = "Layer is a collection of bb files and conf files"
         info = HobInfoButton(tooltip, self)
         hbox_top.pack_end(info, expand=False, fill=False)
 
         layer_widget, self.layer_store = self.gen_layer_widget(self.split_model, self.layers, self.all_layers, self, None)
-        layer_widget.set_size_request(-1, 180)
+        layer_widget.set_size_request(450, 250)
         self.vbox.pack_start(layer_widget, expand=True, fill=True)
 
-        label = self.gen_label_widget("<b>Note:</b> '<i>meta</i>' is the Core layer for Yocto images please do not remove it.")
-        label.show()
-        self.vbox.pack_end(label, expand=False, fill=False)
-
         self.show_all()
 
     def response_cb(self, dialog, response_id):
@@ -972,6 +985,45 @@ class LayerSelectionDialog (CrumbsDialog):
         self.layers_changed = (self.layers != layers)
         self.layers = layers
 
+    """
+    A custom cell_data_func to draw a delete 'button' in the TreeView for layers
+    other than the meta layer. The deletion of which is prevented so that the
+    user can't shoot themselves in the foot too badly.
+    """
+    def draw_delete_button_cb(self, col, cell, model, it, tv):
+        path =  model.get_value(it, 0)
+        # Trailing slashes are uncommon in bblayers.conf but confuse os.path.basename
+        path.rstrip('/')
+        name = os.path.basename(path)
+        if name == "meta":
+            cell.set_sensitive(False)
+            cell.set_property('pixbuf', None)
+            cell.set_property('mode', gtk.CELL_RENDERER_MODE_INERT)
+        else:
+            pix = tv.render_icon(gtk.STOCK_DELETE, gtk.ICON_SIZE_DND, None)
+            cell.set_property('pixbuf', pix)
+            cell.set_sensitive(True)
+            cell.set_property('mode', gtk.CELL_RENDERER_MODE_ACTIVATABLE)
+
+        return True
+
+    """
+    A custom cell_data_func to write an extra message into the layer path cell
+    for the meta layer. We should inform the user that they can't remove it for
+    their own safety.
+    """
+    def draw_layer_path_cb(self, col, cell, model, it):
+        path = model.get_value(it, 0)
+        name = os.path.basename(path)
+        if name == "meta":
+            cell.set_property('markup', "<b>Core layer, it cannot be removed</b>\n%s" % path)
+        else:
+            cell.set_property('text', path)
+
+    def del_cell_clicked_cb(self, cell, path, model):
+        it = model.get_iter_from_string(path)
+        model.remove(it)
+
 class ImageSelectionDialog (CrumbsDialog):
 
     __columns__ = [{
Signature · 1 line
1.7.7.6
#13 lore raw

Re: [PATCH 6/6] ui/crumbs/hig: make the layer selection dialogue more closely match design

Quoted 128 lines · Joshua Lock

The layer dialogue design includes in-line remove/delete widgets next to the layer path in the tree view for all layers other than the meta layer as well as an in-line notice that the meta layer cannot be removed.

This is achieved in this patch through the use of custom cell_data_func's for the treeview to render the meta layer differently and a custom CellRenderer implementation, CellRendererPixbufActivatable, which renders a pixbuf and emits a clicked signal when the user clicks on it.

---
 lib/bb/ui/crumbs/hig.py |   96 ++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 74 insertions(+), 22 deletions(-)
lib/bb/ui/crumbs/hig.py +41 -22
index 849d7c9..5b0cfc9 100644
@@ -789,6 +789,26 @@ class DeployImageDialog (CrumbsDialog):
         os.close(f_from)
         os.close(f_to)
         self.progress_bar.hide()
+
+class CellRendererPixbufActivatable(gtk.CellRendererPixbuf):
+    """
+    A custom CellRenderer implementation which is activatable
+    so that we can handle user clicks
+    """
+    __gsignals__    = { 'clicked' : (gobject.SIGNAL_RUN_LAST,
+                                     gobject.TYPE_NONE,
+                                     (gobject.TYPE_STRING,)), }
+
+    def __init__(self):
+        gtk.CellRendererPixbuf.__init__(self)
+        self.set_property('mode', gtk.CELL_RENDERER_MODE_ACTIVATABLE)
+
+    """
+    Respond to a user click on a cell
+    """
+    def do_activate(self, even, widget, path, background_area, cell_area, flags):
+        self.emit('clicked', path)
+
 #
 # LayerSelectionDialog
 #
@@ -855,13 +875,13 @@ class LayerSelectionDialog (CrumbsDialog):
         layer_tv.set_rules_hint(True)
         layer_tv.set_headers_visible(False)
         tree_selection = layer_tv.get_selection()
-        tree_selection.set_mode(gtk.SELECTION_SINGLE)
+        tree_selection.set_mode(gtk.SELECTION_NONE)
 
         col0= gtk.TreeViewColumn('Path')
         cell0 = gtk.CellRendererText()
         cell0.set_padding(5,2)
         col0.pack_start(cell0, True)
-        col0.set_attributes(cell0, text=0)
+        col0.set_cell_data_func(cell0, self.draw_layer_path_cb)
         layer_tv.append_column(col0)
 
         scroll = gtk.ScrolledWindow()
@@ -897,18 +917,19 @@ class LayerSelectionDialog (CrumbsDialog):
             for layer in layers:
                 layer_store.set(layer_store.append(), 0, layer)
 
-            image = gtk.Image()
-            image.set_from_stock(gtk.STOCK_ADD,gtk.ICON_SIZE_MENU)
+            col1 = gtk.TreeViewColumn('Enabled')
+            layer_tv.append_column(col1)
+
+            cell1 = CellRendererPixbufActivatable()
+            cell1.connect("clicked", self.del_cell_clicked_cb, layer_store)
+            col1.pack_start(cell1, True)
+            col1.set_cell_data_func(cell1, self.draw_delete_button_cb, layer_tv)
+
             add_button = gtk.Button()
-            add_button.set_image(image)
+            add_button.set_label("_Add layer")
+            add_button.set_use_underline(True)
             add_button.connect("clicked", self.layer_widget_add_clicked_cb, layer_store, window)
-            table_layer.attach(add_button, 0, 5, 1, 2, gtk.EXPAND | gtk.FILL, 0, 0, 6)
-            image = gtk.Image()
-            image.set_from_stock(gtk.STOCK_REMOVE,gtk.ICON_SIZE_MENU)
-            del_button = gtk.Button()
-            del_button.set_image(image)
-            del_button.connect("clicked", self.layer_widget_del_clicked_cb, tree_selection, layer_store)
-            table_layer.attach(del_button, 5, 10, 1, 2, gtk.EXPAND | gtk.FILL, 0, 0, 6)
+            table_layer.attach(add_button, 0, 10, 1, 2, gtk.EXPAND | gtk.FILL, 0, 0, 6)
         layer_tv.set_model(layer_store)
 
         hbox.show_all()
@@ -936,24 +957,16 @@ class LayerSelectionDialog (CrumbsDialog):
         hbox_top = gtk.HBox()
         self.vbox.pack_start(hbox_top, expand=False, fill=False)
 
-        if self.split_model:
-            label = self.gen_label_widget("<b>Select Layers:</b>\n(Available layers under '${COREBASE}/layers/' directory)")
-        else:
-            label = self.gen_label_widget("<b>Select Layers:</b>")
+        label = self.gen_label_widget("<b>Select Layers:</b>")
         hbox_top.pack_start(label, expand=False, fill=False)
-
         tooltip = "Layer is a collection of bb files and conf files"
         info = HobInfoButton(tooltip, self)
         hbox_top.pack_end(info, expand=False, fill=False)
 
         layer_widget, self.layer_store = self.gen_layer_widget(self.split_model, self.layers, self.all_layers, self, None)
-        layer_widget.set_size_request(-1, 180)
+        layer_widget.set_size_request(450, 250)
         self.vbox.pack_start(layer_widget, expand=True, fill=True)
 
-        label = self.gen_label_widget("<b>Note:</b> '<i>meta</i>' is the Core layer for Yocto images please do not remove it.")
-        label.show()
-        self.vbox.pack_end(label, expand=False, fill=False)
-
         self.show_all()
 
     def response_cb(self, dialog, response_id):
@@ -972,6 +985,45 @@ class LayerSelectionDialog (CrumbsDialog):
         self.layers_changed = (self.layers != layers)
         self.layers = layers
 
+    """
+    A custom cell_data_func to draw a delete 'button' in the TreeView for layers
+    other than the meta layer. The deletion of which is prevented so that the
+    user can't shoot themselves in the foot too badly.
+    """
+    def draw_delete_button_cb(self, col, cell, model, it, tv):

lib/bb/ui/crumbs/hig.py class LayerSelectionDialog (CrumbsDialog): · line 1003

Quoted 10 lines
lib/bb/ui/crumbs/hig.py +10 -0
+        path =  model.get_value(it, 0)
+        # Trailing slashes are uncommon in bblayers.conf but confuse os.path.basename
+        path.rstrip('/')
+        name = os.path.basename(path)
+        if name == "meta":
+            cell.set_sensitive(False)
+            cell.set_property('pixbuf', None)
+            cell.set_property('mode', gtk.CELL_RENDERER_MODE_INERT)
+        else:
+            pix = tv.render_icon(gtk.STOCK_DELETE, gtk.ICON_SIZE_DND, None)

Could Belen and Giulia provide an designed icon for this delete button? Since the default gtk.STOCK_DELETE may appear different from OS distributions.

Besides, I think it is better if this button can have the effect of hover/un-hover, because from first eye on the button, users may not know it is click-able.

Thanks,
Dongxiao

Quoted 26 lines
lib/bb/ui/crumbs/hig.py +23 -0
+            cell.set_property('pixbuf', pix)
+            cell.set_sensitive(True)
+            cell.set_property('mode', gtk.CELL_RENDERER_MODE_ACTIVATABLE)
+
+        return True
+
+    """
+    A custom cell_data_func to write an extra message into the layer path cell
+    for the meta layer. We should inform the user that they can't remove it for
+    their own safety.
+    """
+    def draw_layer_path_cb(self, col, cell, model, it):
+        path = model.get_value(it, 0)
+        name = os.path.basename(path)
+        if name == "meta":
+            cell.set_property('markup', "<b>Core layer, it cannot be removed</b>\n%s" % path)
+        else:
+            cell.set_property('text', path)
+
+    def del_cell_clicked_cb(self, cell, path, model):
+        it = model.get_iter_from_string(path)
+        model.remove(it)
+
 class ImageSelectionDialog (CrumbsDialog):
 
     __columns__ = [{
#14 lore raw

Re: [PATCH 6/6] ui/crumbs/hig: make the layer selection dialogue more closely match design

Quoted 135 lines · Dongxiao
Quoted 134 lines · Joshua Lock

The layer dialogue design includes in-line remove/delete widgets next to the layer path in the tree view for all layers other than the meta layer as well as an in-line notice that the meta layer cannot be removed.

This is achieved in this patch through the use of custom cell_data_func's for the treeview to render the meta layer differently and a custom CellRenderer implementation, CellRendererPixbufActivatable, which renders a pixbuf and emits a clicked signal when the user clicks on it.

---
  lib/bb/ui/crumbs/hig.py |   96 ++++++++++++++++++++++++++++++++++++-----------
  1 files changed, 74 insertions(+), 22 deletions(-)
lib/bb/ui/crumbs/hig.py +47 -22
index 849d7c9..5b0cfc9 100644
@@ -789,6 +789,26 @@ class DeployImageDialog (CrumbsDialog):
          os.close(f_from)
          os.close(f_to)
          self.progress_bar.hide()
+
+class CellRendererPixbufActivatable(gtk.CellRendererPixbuf):
+    """
+    A custom CellRenderer implementation which is activatable
+    so that we can handle user clicks
+    """
+    __gsignals__    = { 'clicked' : (gobject.SIGNAL_RUN_LAST,
+                                     gobject.TYPE_NONE,
+                                     (gobject.TYPE_STRING,)), }
+
+    def __init__(self):
+        gtk.CellRendererPixbuf.__init__(self)
+        self.set_property('mode', gtk.CELL_RENDERER_MODE_ACTIVATABLE)
+
+    """
+    Respond to a user click on a cell
+    """
+    def do_activate(self, even, widget, path, background_area, cell_area, flags):
+        self.emit('clicked', path)
+
  #
  # LayerSelectionDialog
  #
@@ -855,13 +875,13 @@ class LayerSelectionDialog (CrumbsDialog):
          layer_tv.set_rules_hint(True)
          layer_tv.set_headers_visible(False)
          tree_selection = layer_tv.get_selection()
-        tree_selection.set_mode(gtk.SELECTION_SINGLE)
+        tree_selection.set_mode(gtk.SELECTION_NONE)
 
          col0= gtk.TreeViewColumn('Path')
          cell0 = gtk.CellRendererText()
          cell0.set_padding(5,2)
          col0.pack_start(cell0, True)
-        col0.set_attributes(cell0, text=0)
+        col0.set_cell_data_func(cell0, self.draw_layer_path_cb)
          layer_tv.append_column(col0)
 
          scroll = gtk.ScrolledWindow()
@@ -897,18 +917,19 @@ class LayerSelectionDialog (CrumbsDialog):
              for layer in layers:
                  layer_store.set(layer_store.append(), 0, layer)
 
-            image = gtk.Image()
-            image.set_from_stock(gtk.STOCK_ADD,gtk.ICON_SIZE_MENU)
+            col1 = gtk.TreeViewColumn('Enabled')
+            layer_tv.append_column(col1)
+
+            cell1 = CellRendererPixbufActivatable()
+            cell1.connect("clicked", self.del_cell_clicked_cb, layer_store)
+            col1.pack_start(cell1, True)
+            col1.set_cell_data_func(cell1, self.draw_delete_button_cb, layer_tv)
+
              add_button = gtk.Button()
-            add_button.set_image(image)
+            add_button.set_label("_Add layer")
+            add_button.set_use_underline(True)
              add_button.connect("clicked", self.layer_widget_add_clicked_cb, layer_store, window)
-            table_layer.attach(add_button, 0, 5, 1, 2, gtk.EXPAND | gtk.FILL, 0, 0, 6)
-            image = gtk.Image()
-            image.set_from_stock(gtk.STOCK_REMOVE,gtk.ICON_SIZE_MENU)
-            del_button = gtk.Button()
-            del_button.set_image(image)
-            del_button.connect("clicked", self.layer_widget_del_clicked_cb, tree_selection, layer_store)
-            table_layer.attach(del_button, 5, 10, 1, 2, gtk.EXPAND | gtk.FILL, 0, 0, 6)
+            table_layer.attach(add_button, 0, 10, 1, 2, gtk.EXPAND | gtk.FILL, 0, 0, 6)
          layer_tv.set_model(layer_store)
 
          hbox.show_all()
@@ -936,24 +957,16 @@ class LayerSelectionDialog (CrumbsDialog):
          hbox_top = gtk.HBox()
          self.vbox.pack_start(hbox_top, expand=False, fill=False)
 
-        if self.split_model:
-            label = self.gen_label_widget("<b>Select Layers:</b>\n(Available layers under '${COREBASE}/layers/' directory)")
-        else:
-            label = self.gen_label_widget("<b>Select Layers:</b>")
+        label = self.gen_label_widget("<b>Select Layers:</b>")
          hbox_top.pack_start(label, expand=False, fill=False)
-
          tooltip = "Layer is a collection of bb files and conf files"
          info = HobInfoButton(tooltip, self)
          hbox_top.pack_end(info, expand=False, fill=False)
 
          layer_widget, self.layer_store = self.gen_layer_widget(self.split_model, self.layers, self.all_layers, self, None)
-        layer_widget.set_size_request(-1, 180)
+        layer_widget.set_size_request(450, 250)
          self.vbox.pack_start(layer_widget, expand=True, fill=True)
 
-        label = self.gen_label_widget("<b>Note:</b>  '<i>meta</i>' is the Core layer for Yocto images please do not remove it.")
-        label.show()
-        self.vbox.pack_end(label, expand=False, fill=False)
-
          self.show_all()
 
      def response_cb(self, dialog, response_id):
@@ -972,6 +985,45 @@ class LayerSelectionDialog (CrumbsDialog):
          self.layers_changed = (self.layers != layers)
          self.layers = layers
 
+    """
+    A custom cell_data_func to draw a delete 'button' in the TreeView for layers
+    other than the meta layer. The deletion of which is prevented so that the
+    user can't shoot themselves in the foot too badly.
+    """
+    def draw_delete_button_cb(self, col, cell, model, it, tv):
+        path =  model.get_value(it, 0)
+        # Trailing slashes are uncommon in bblayers.conf but confuse os.path.basename
+        path.rstrip('/')
+        name = os.path.basename(path)
+        if name == "meta":
+            cell.set_sensitive(False)
Quoted 8 lines

lib/bb/ui/crumbs/hig.py class LayerSelectionDialog (CrumbsDialog): · line 1003

Quoted 4 lines
lib/bb/ui/crumbs/hig.py +4 -0
+            cell.set_property('pixbuf', None)
+            cell.set_property('mode', gtk.CELL_RENDERER_MODE_INERT)
+        else:
+            pix = tv.render_icon(gtk.STOCK_DELETE, gtk.ICON_SIZE_DND, None)

Could Belen and Giulia provide an designed icon for this delete button? Since the default gtk.STOCK_DELETE may appear different from OS distributions.

I agree. I asked about this and a couple of other issues on the bug report:
https://bugzilla.yoctoproject.org/show_bug.cgi?id=2083

Quoted 3 lines

Besides, I think it is better if this button can have the effect of hover/un-hover, because from first eye on the button, users may not know it is click-able.

That's a good call. I'll look at implementing that.

Thanks for the feedback,

Joshua

Signature · 3 lines
Joshua '贾詡' Lock
        Yocto Project "Johannes factotum"
        Intel Open Source Technology Centre
#15 lore raw
In reply to Joshua Lock
Quoted 23 lines · Joshua Lock

Here's a series of patches to polish the Hob GUI: some minor tweaks to remove redundant calls and API, a couple of HIG related tweaks to buttons, a change to the persistenttooltip to try and match the close position of the window manager (i.e. running under Unity on Ubuntu the close button on the persistent tooltip will appear on the left) and finally a change to the layer dialogue implementation so that it more closely matches the interaction design (this is still pending some designer feedback on visuals and whether to remove some labels but they can easily be implemented as iterative patches on top of these).

Cheers,

Joshua

The following changes since commit 5a1e62a8cdd4f0253b0dc59046b3b4c3186af461:

bitbake/fetch2: Fix typo which broke use of tarballs (2012-03-16 23:44:08 +0000)

are available in the git repository at:
git://github.com/incandescant/bitbake josh/hob
https://github.com/incandescant/bitbake/tree/josh/hob
git://git.yoctoproject.org/poky-contrib josh/hob
http://git.yoctoproject.org/cgit/cgit.cgi/poky-contrib/log/?h=josh/hob

Quoted 9 lines

Joshua Lock (6):
ui/crumbs/hig: use close rather than OK for dismis button ui/crumbs: remove unused return value from append_toolbar_button ui/crumbs/hobpage: no need to force a Toolbar button type ui/crumbs/persistenttooltip: try to reflect WM close button position ui/crumbs/builder: remove OK/Cancel buttons on Layer dialog. Use
Close.
ui/crumbs/hig: make the layer selection dialogue more closely match
design

I've merged the first four, the last two seemed to be being discussed...

Cheers,

Richard