Hob tweaks
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
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
@@ -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
PATCH 2/6 ui/crumbs: remove unused return value from append_toolbar_button
In reply to Joshua LockNo 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
@@ -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
@@ -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
@@ -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
PATCH 3/6 ui/crumbs/hobpage: no need to force a Toolbar button type
In reply to Joshua LockThis 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
@@ -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
PATCH 4/6 ui/crumbs/persistenttooltip: try to reflect WM close button position
In reply to Joshua LockWhen 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
@@ -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
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
@@ -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
PATCH 6/6 ui/crumbs/hig: make the layer selection dialogue more closely match design
In reply to Joshua LockThe 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
@@ -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
Re: [PATCH 2/6] ui/crumbs: remove unused return value from append_toolbar_button
In reply to Joshua LockQuoted 3 lines · Joshua Lock
No caller of the method uses the returned toolbar variable
Signed-off-by Joshua Lock <[email protected]>
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@@ -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 buttonlib/bb/ui/crumbs/imageconfigurationpage.py +3
-3@@ -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@@ -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,
Re: [PATCH 1/6] ui/crumbs/hig: use close rather than OK for dismis button
In reply to Joshua LockQuoted 3 lines · Joshua Lock
Dialogue buttons should have descriptive names
Signed-off-by Joshua Lock <[email protected]>
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@@ -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()
Re: [PATCH 3/6] ui/crumbs/hobpage: no need to force a Toolbar button type
In reply to Joshua LockQuoted 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
Signed-off-by Joshua Lock <[email protected]>--- lib/bb/ui/crumbs/hobpages.py | 4 +--- 1 files changed, 1 insertions(+), 3 deletions(-)lib/bb/ui/crumbs/hobpages.py +1
-3@@ -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
Re: [PATCH 4/6] ui/crumbs/persistenttooltip: try to reflect WM close button position
In reply to Joshua LockQuoted 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.
Signed-off-by Joshua Lock <[email protected]>
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@@ -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)
Re: [PATCH 5/6] ui/crumbs/builder: remove OK/Cancel buttons on Layer dialog. Use Close.
In reply to Joshua LockQuoted 10 lines · Joshua Lock
Signed-off-by Joshua Lock <[email protected]>--- lib/bb/ui/crumbs/builder.py | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)lib/bb/ui/crumbs/builder.py +0
-0
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
-0response = dialog.run() if response == gtk.RESPONSE_YES: self.configuration.layers = dialog.layers
Re: [PATCH 6/6] ui/crumbs/hig: make the layer selection dialogue more closely match design
In reply to Joshua LockQuoted 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.
Signed-off-by Joshua Lock <[email protected]>--- lib/bb/ui/crumbs/hig.py | 96 ++++++++++++++++++++++++++++++++++++----------- 1 files changed, 74 insertions(+), 22 deletions(-)lib/bb/ui/crumbs/hig.py +41
-22@@ -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__ = [{
Richard Purdie
AppliedQuoted 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/bitbakejosh/hob
https://github.com/incandescant/bitbake/tree/josh/hob
git://git.yoctoproject.org/poky-contribjosh/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 fromappend_toolbar_buttonui/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
Re: [PATCH 6/6] ui/crumbs/hig: make the layer selection dialogue more closely match design
In reply to Xu, DongxiaoQuoted 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.
Signed-off-by Joshua Lock<[email protected]>--- lib/bb/ui/crumbs/hig.py | 96 ++++++++++++++++++++++++++++++++++++----------- 1 files changed, 74 insertions(+), 22 deletions(-)lib/bb/ui/crumbs/hig.py +47
-22@@ -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 CentreRe: [PATCH 5/6] ui/crumbs/builder: remove OK/Cancel buttons on Layer dialog. Use Close.
In reply to Xu, DongxiaoQuoted 22 lines · Dongxiao
Quoted 10 lines · Joshua Lock
Signed-off-by Joshua Lock<[email protected]>--- lib/bb/ui/crumbs/builder.py | 3 +-- 1 files changed, 1 insertions(+), 2 deletions(-)lib/bb/ui/crumbs/builder.py +0
-0lib/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