Skip to contentSkip to conversation

Hob GUI tweaks

PATCH In review Joshua Lock 3 participants 12 messages Mar 21, 2012 – Mar 22, 2012

lore
Share & tools
lore
#0 lore raw

cover Hob GUI tweaks

All,

Here are some tweaks to the Hob GUI.

Firstly I include a tweaked version of my recent LayerSelectionDialog patch, this includes Dongxiao's suggestion to use a prelight on the clickable pixbuf in the TreeView. Sadly on Ubuntu this isn't hugely noticable as the remove icon is largely whitespace.
We should be able to replace the stock icon with a custom one soon.

The second patch adds a clear button to the search entry in HobNoteBook, per a suggestion I made whilst reviewing that code.

The remaining three patches are for the PersistentTooltip widget:
1) Tweak borders so that the button is aligned with the tooltip edge but the label remains inside padding.
2) Fix colours on darker Gtk+ themes, such as those used in Ubuntu Unity.
3) Fix whitespace to match the rest of BitBake (I had accidentally used tabs rather than 4 spaces per indent).

Cheers,
Joshua

The following changes since commit b7b7c768761d205bc5a60922ff709c9c184d4158:

utils: Add split_version function for splitting a version into its components (2012-03-20 14:37:16 +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 (5):
ui/crumbs/hig: make the layer selection dialogue more closely match
design
ui/crumbs/hobwidget: add clear icon to search entries in HobNotebook ui/crumbs/persistenttooltip: tweak borders ui/crumbs/persistenttooltip: fix colours on darker themes ui/crumbs/persistenttooltip: fix whitespace

 lib/bb/ui/crumbs/hig.py               |   97 ++++++++++---
 lib/bb/ui/crumbs/hobwidget.py         |   19 ++-
 lib/bb/ui/crumbs/persistenttooltip.py |  244 ++++++++++++++++++---------------
 3 files changed, 221 insertions(+), 139 deletions(-)
Signature · 1 line
1.7.7.6
#1 lore raw

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

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 |   97 ++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 75 insertions(+), 22 deletions(-)
lib/bb/ui/crumbs/hig.py +75 -22
index 849d7c9..2964752 100644
@@ -789,6 +789,27 @@ 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)
+        self.set_property('follow-state', True)
+
+    """
+    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 +876,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 +918,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 +958,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 +986,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
#5 lore raw

PATCH 2/5 ui/crumbs/hobwidget: add clear icon to search entries in HobNotebook

In reply to Joshua Lock

It's a common pattern on Gtk+ desktops to be able to clear a search/filter entry using an icon in that entry.

---
 lib/bb/ui/crumbs/hobwidget.py |   19 ++++++++++++++-----
 1 files changed, 14 insertions(+), 5 deletions(-)
lib/bb/ui/crumbs/hobwidget.py +14 -5
index 4b0a0cf..db52c47 100644
@@ -622,6 +622,8 @@ class HobNotebook(gtk.VBox):
         self.search.set_style(style)
         self.search.set_text(name)
         self.search.set_editable(False)
+        self.search.set_icon_from_stock(gtk.ENTRY_ICON_SECONDARY, gtk.STOCK_CLEAR)
+        self.search.connect("icon-release", self.set_search_entry_clear_cb)
         self.search.show()
         self.align = gtk.Alignment(xalign=1.0, yalign=0.7)
         self.align.add(self.search)
@@ -682,9 +684,16 @@ class HobNotebook(gtk.VBox):
         style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.BLACK, False, False)
         search.set_style(style)
 
-    def set_search_entry_reset_cb(self, search, event):
-        style = search.get_style()
+    def reset_entry(self, entry):
+        style = entry.get_style()
         style.text[gtk.STATE_NORMAL] = self.get_colormap().alloc_color(HobColors.GRAY, False, False)
-        search.set_style(style)
-        search.set_text(self.search_name)
-        search.set_editable(False)
+        entry.set_style(style)
+        entry.set_text(self.search_name)
+        entry.set_editable(False)
+
+    def set_search_entry_reset_cb(self, search, event):
+        self.reset_entry(search)
+
+    def set_search_entry_clear_cb(self, search, icon_pos, event):
+        self.reset_entry(search)
+
Signature · 1 line
1.7.7.6
#6 lore raw

PATCH 3/5 ui/crumbs/persistenttooltip: tweak borders

In reply to Joshua Lock

Change the layout and borders so that the close button is flush with the edge of the tooltip window yet leave the contents with a small border such that text isn't flush with the window edge.

---
 lib/bb/ui/crumbs/persistenttooltip.py |    8 ++++++--
 1 files changed, 6 insertions(+), 2 deletions(-)
lib/bb/ui/crumbs/persistenttooltip.py +6 -2
index bae697e..e9cc380 100644
@@ -64,7 +64,7 @@ class PersistentTooltip(gtk.Window):
 		# We must be modal to ensure we grab focus when presented from a gtk.Dialog
 		self.set_modal(True)
 
-		self.set_border_width(6)
+		self.set_border_width(0)
 		self.set_position(gtk.WIN_POS_MOUSE)
 		self.set_opacity(0.95)
 
@@ -91,10 +91,14 @@ class PersistentTooltip(gtk.Window):
 
 		self.set_default(self.button)
 
+		hbox = gtk.HBox(True, 6)
+		hbox.set_border_width(6)
+		hbox.show()
+		vbox.pack_end(hbox, True, True, 6)
 		self.label = gtk.Label()
 		self.label.set_markup(markup)
 		self.label.show()
-		vbox.pack_end(self.label, True, True, 6)
+		hbox.pack_end(self.label, True, True, 6)
 
 		self.connect("key-press-event", self._catch_esc_cb)
 
Signature · 1 line
1.7.7.6
#7 lore raw

PATCH 4/5 ui/crumbs/persistenttooltip: fix colours on darker themes

In reply to Joshua Lock

Darker gtk+ themes, such as the one used in Ubuntu Unity, revealed that the PersistentTooltip styling wasn't setting the label colour correctly.

Set the label foreground colour to the tooltip_fg_colour value as read from gtk-color-scheme property of the system settings.

---
 lib/bb/ui/crumbs/persistenttooltip.py |   26 +++++++++++++++++++++-----
 1 files changed, 21 insertions(+), 5 deletions(-)
lib/bb/ui/crumbs/persistenttooltip.py +21 -5
index e9cc380..d065ab2 100644
@@ -38,6 +38,11 @@ class PersistentTooltip(gtk.Window):
 	def __init__(self, markup):
 		gtk.Window.__init__(self, gtk.WINDOW_POPUP)
 
+		# Inherit the system theme for a tooltip
+		style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
+						'gtk-tooltip', 'gtk-tooltip', gobject.TYPE_NONE)
+		self.set_style(style)
+
 		# 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
@@ -96,17 +101,28 @@ class PersistentTooltip(gtk.Window):
 		hbox.show()
 		vbox.pack_end(hbox, True, True, 6)
 		self.label = gtk.Label()
+		# We want to match the colours of the normal tooltips, as dictated by
+		# the users gtk+-2.0 theme, wherever possible - on some systems this
+		# requires explicitly setting a fg_color for the label which matches the
+		# tooltip_fg_color
+		settings = gtk.settings_get_default()
+		colours = settings.get_property('gtk-color-scheme').split('\n')
+		# remove any empty lines, there's likely to be a trailing one after
+		# calling split on a dictionary-like string
+		colours = filter(None, colours)
+		for col in colours:
+			item, val = col.split(': ')
+			if item == 'tooltip_fg_color':
+				style = self.label.get_style()
+				style.fg[gtk.STATE_NORMAL] = gtk.gdk.color_parse(val)
+				self.label.set_style(style)
+				break # we only care for the tooltip_fg_color
 		self.label.set_markup(markup)
 		self.label.show()
 		hbox.pack_end(self.label, True, True, 6)
 
 		self.connect("key-press-event", self._catch_esc_cb)
 
-		# Inherit the system theme for a tooltip
-		style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
-			'gtk-tooltip', 'gtk-tooltip', gobject.TYPE_NONE)
-		self.set_style(style)
-
 		self.add(vbox)
 
 	"""
Signature · 1 line
1.7.7.6
#8 lore raw

PATCH 5/5 ui/crumbs/persistenttooltip: fix whitespace

In reply to Joshua Lock

We use 4 spaces, not a tab, in BitBake

---
 lib/bb/ui/crumbs/persistenttooltip.py |  264 ++++++++++++++++----------------
 1 files changed, 132 insertions(+), 132 deletions(-)
lib/bb/ui/crumbs/persistenttooltip.py +132 -132
index d065ab2..8ba0043 100644
@@ -26,135 +26,135 @@ except:
     pass
 
 class PersistentTooltip(gtk.Window):
-	"""
-	A tooltip which persists once shown until the user dismisses it with the Esc
-	key or by clicking the close button.
-
-	# FIXME: the PersistentTooltip should be disabled when the user clicks anywhere off
-	# it. We can't do this with focus-out-event becuase modal ensures we have focus?
-
-	markup: some Pango text markup to display in the tooltip
-	"""
-	def __init__(self, markup):
-		gtk.Window.__init__(self, gtk.WINDOW_POPUP)
-
-		# Inherit the system theme for a tooltip
-		style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
-						'gtk-tooltip', 'gtk-tooltip', gobject.TYPE_NONE)
-		self.set_style(style)
-
-		# 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
-
-		# We don't want any WM decorations
-		self.set_decorated(False)
-		# We don't want to show in the taskbar or window switcher
-		self.set_skip_pager_hint(True)
-		self.set_skip_taskbar_hint(True)
-		# We must be modal to ensure we grab focus when presented from a gtk.Dialog
-		self.set_modal(True)
-
-		self.set_border_width(0)
-		self.set_position(gtk.WIN_POS_MOUSE)
-		self.set_opacity(0.95)
-
-		# Draw our label and close buttons
-		hbox = gtk.HBox(False, 0)
-		hbox.show()
-		vbox = gtk.VBox(False, 0)
-		vbox.show()
-		vbox.pack_start(hbox, True, True, 0)
-
-		img = gtk.Image()
-		img.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_BUTTON)
-
-		self.button = gtk.Button()
-		self.button.set_image(img)
-		self.button.connect("clicked", self._dismiss_cb)
-		self.button.set_can_default(True)
-		self.button.grab_focus()
-		self.button.show()
-		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)
-
-		hbox = gtk.HBox(True, 6)
-		hbox.set_border_width(6)
-		hbox.show()
-		vbox.pack_end(hbox, True, True, 6)
-		self.label = gtk.Label()
-		# We want to match the colours of the normal tooltips, as dictated by
-		# the users gtk+-2.0 theme, wherever possible - on some systems this
-		# requires explicitly setting a fg_color for the label which matches the
-		# tooltip_fg_color
-		settings = gtk.settings_get_default()
-		colours = settings.get_property('gtk-color-scheme').split('\n')
-		# remove any empty lines, there's likely to be a trailing one after
-		# calling split on a dictionary-like string
-		colours = filter(None, colours)
-		for col in colours:
-			item, val = col.split(': ')
-			if item == 'tooltip_fg_color':
-				style = self.label.get_style()
-				style.fg[gtk.STATE_NORMAL] = gtk.gdk.color_parse(val)
-				self.label.set_style(style)
-				break # we only care for the tooltip_fg_color
-		self.label.set_markup(markup)
-		self.label.show()
-		hbox.pack_end(self.label, True, True, 6)
-
-		self.connect("key-press-event", self._catch_esc_cb)
-
-		self.add(vbox)
-
-	"""
-	Callback when the PersistentTooltip's close button is clicked.
-	Hides the PersistentTooltip.
-	"""
-	def _dismiss_cb(self, button):
-		self.hide()
-		return True
-
-	"""
-	Callback when the Esc key is detected. Hides the PersistentTooltip.
-	"""
-	def _catch_esc_cb(self, widget, event):
-		keyname = gtk.gdk.keyval_name(event.keyval)
-		if keyname == "Escape":
-			self.hide()
-		return True
-
-	"""
-	Called to present the PersistentTooltip.
-	Overrides the superclasses show() method to include state tracking.
-	"""
-	def show(self):
-		if not self.shown:
-			self.shown = True
-			gtk.Window.show(self)
-
-	"""
-	Called to hide the PersistentTooltip.
-	Overrides the superclasses hide() method to include state tracking.
-	"""
-	def hide(self):
-		self.shown = False
-		gtk.Window.hide(self)
+    """
+    A tooltip which persists once shown until the user dismisses it with the Esc
+    key or by clicking the close button.
+
+    # FIXME: the PersistentTooltip should be disabled when the user clicks anywhere off
+    # it. We can't do this with focus-out-event becuase modal ensures we have focus?
+
+    markup: some Pango text markup to display in the tooltip
+    """
+    def __init__(self, markup):
+        gtk.Window.__init__(self, gtk.WINDOW_POPUP)
+
+        # Inherit the system theme for a tooltip
+        style = gtk.rc_get_style_by_paths(gtk.settings_get_default(),
+                        'gtk-tooltip', 'gtk-tooltip', gobject.TYPE_NONE)
+        self.set_style(style)
+
+        # 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
+
+        # We don't want any WM decorations
+        self.set_decorated(False)
+        # We don't want to show in the taskbar or window switcher
+        self.set_skip_pager_hint(True)
+        self.set_skip_taskbar_hint(True)
+        # We must be modal to ensure we grab focus when presented from a gtk.Dialog
+        self.set_modal(True)
+
+        self.set_border_width(0)
+        self.set_position(gtk.WIN_POS_MOUSE)
+        self.set_opacity(0.95)
+
+        # Draw our label and close buttons
+        hbox = gtk.HBox(False, 0)
+        hbox.show()
+        vbox = gtk.VBox(False, 0)
+        vbox.show()
+        vbox.pack_start(hbox, True, True, 0)
+
+        img = gtk.Image()
+        img.set_from_stock(gtk.STOCK_CLOSE, gtk.ICON_SIZE_BUTTON)
+
+        self.button = gtk.Button()
+        self.button.set_image(img)
+        self.button.connect("clicked", self._dismiss_cb)
+        self.button.set_can_default(True)
+        self.button.grab_focus()
+        self.button.show()
+        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)
+
+        hbox = gtk.HBox(True, 6)
+        hbox.set_border_width(6)
+        hbox.show()
+        vbox.pack_end(hbox, True, True, 6)
+        self.label = gtk.Label()
+        # We want to match the colours of the normal tooltips, as dictated by
+        # the users gtk+-2.0 theme, wherever possible - on some systems this
+        # requires explicitly setting a fg_color for the label which matches the
+        # tooltip_fg_color
+        settings = gtk.settings_get_default()
+        colours = settings.get_property('gtk-color-scheme').split('\n')
+        # remove any empty lines, there's likely to be a trailing one after
+        # calling split on a dictionary-like string
+        colours = filter(None, colours)
+        for col in colours:
+            item, val = col.split(': ')
+            if item == 'tooltip_fg_color':
+                style = self.label.get_style()
+                style.fg[gtk.STATE_NORMAL] = gtk.gdk.color_parse(val)
+                self.label.set_style(style)
+                break # we only care for the tooltip_fg_color
+        self.label.set_markup(markup)
+        self.label.show()
+        hbox.pack_end(self.label, True, True, 6)
+
+        self.connect("key-press-event", self._catch_esc_cb)
+
+        self.add(vbox)
+
+    """
+    Callback when the PersistentTooltip's close button is clicked.
+    Hides the PersistentTooltip.
+    """
+    def _dismiss_cb(self, button):
+        self.hide()
+        return True
+
+    """
+    Callback when the Esc key is detected. Hides the PersistentTooltip.
+    """
+    def _catch_esc_cb(self, widget, event):
+        keyname = gtk.gdk.keyval_name(event.keyval)
+        if keyname == "Escape":
+            self.hide()
+        return True
+
+    """
+    Called to present the PersistentTooltip.
+    Overrides the superclasses show() method to include state tracking.
+    """
+    def show(self):
+        if not self.shown:
+            self.shown = True
+            gtk.Window.show(self)
+
+    """
+    Called to hide the PersistentTooltip.
+    Overrides the superclasses hide() method to include state tracking.
+    """
+    def hide(self):
+        self.shown = False
+        gtk.Window.hide(self)
Signature · 1 line
1.7.7.6
#9 lore raw

Re: [PATCH 5/5] ui/crumbs/persistenttooltip: fix whitespace

Joshua Lock wrote on 2012-03-21:

Quoted 3 lines

We use 4 spaces, not a tab, in BitBake

What's wrong with persistenttooltip.py?

--
Shane

#10 lore raw

Re: [PATCH 5/5] ui/crumbs/persistenttooltip: fix whitespace

Quoted 7 lines · Shane

Joshua Lock wrote on 2012-03-21:

Quoted 3 lines

We use 4 spaces, not a tab, in BitBake

What's wrong with persistenttooltip.py?

Nothing that we aren't already tracking in Bugzilla - this change just sets the indentation to match the rest of BitBake.

Cheers,
Joshua

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

All,

Here are some tweaks to the Hob GUI.

Firstly I include a tweaked version of my recent LayerSelectionDialog patch, this includes Dongxiao's suggestion to use a prelight on the clickable pixbuf in the TreeView. Sadly on Ubuntu this isn't hugely noticable as the remove icon is largely whitespace.
We should be able to replace the stock icon with a custom one soon.

I've received an asset to use for the remove icon so will send an updated pull request later today.

Please disregard this series.

Thanks,
Joshua

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

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

In reply to Joshua Lock
Quoted 3 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.

Hi Josh,

One thing just came to my mind is that, the meta-hob layer also could not be removed since Hob GUI will use that.

Thanks,
Dongxiao

Quoted 162 lines

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 |   97 ++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 75 insertions(+), 22 deletions(-)
lib/bb/ui/crumbs/hig.py +75 -22
index 849d7c9..2964752 100644
@@ -789,6 +789,27 @@ 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)
+        self.set_property('follow-state', True)
+
+    """
+    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 +876,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 +918,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 +958,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 +986,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__ = [{
#3 lore raw

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

Quoted 9 lines · Dongxiao
Quoted 3 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.

Hi Josh,

One thing just came to my mind is that, the meta-hob layer also could not be removed since Hob GUI will use that.

Will Hob not work without the Hob layer? If that's the case I guess we should disable removal of that also.

Cheers,
Joshua

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

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

Quoted 6 lines · Joshua Lock
Quoted 5 lines · Dongxiao
Quoted 3 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.

Quoted 7 lines
Quoted 4 lines

Hi Josh,

One thing just came to my mind is that, the meta-hob layer also could not be removed since Hob GUI will use that.

Will Hob not work without the Hob layer? If that's the case I guess we should disable removal of that also.

No, it won't work without meta-hob, it is a fundamental of building any image. We need to disable the removal of that.

Thanks,
Dongxiao

Quoted 3 lines

Cheers,
Joshua