I instantiate GtkInfobars a lot in my GTK+ application in order to communicate with the user. There are various types of infobars, depending on the message. Basically, any infobar could be a combination of the 4 different infobar message types and 5 different icons (which are painted on the left side of the infobar).
Initially, I would call my custom infobar
function like this:
infobar("Message. Woo.", type=gtk.MESSAGE_INFO, icon=gtk.STOCK_DIALOG_WARNING, timeout=5)
After a while I decided I wanted to simplify all the creation calls... so I modified my infobar
function so that I could do this:
infobar("Message. Woo.", type=(1,3), timeout=3)
I feel like the second way is better and that it's worth the code obfuscation, but I suspect not everyone will agree with me.
def infobar(self, msg=None, type=(1,1), timeout=3, vbox=None):
"""Popup a new auto-hiding InfoBar."""
# List of possible infobar message types
msgtypes = [0,
gtk.MESSAGE_INFO, # 1
gtk.MESSAGE_QUESTION, # 2
gtk.MESSAGE_WARNING, # 3
gtk.MESSAGE_ERROR] # 4
# List of possible images to show in infobar
imgtypes = [gtk.STOCK_APPLY, # 0
gtk.STOCK_DIALOG_INFO, # 1
gtk.STOCK_DIALOG_QUESTION, # 2
gtk.STOCK_DIALOG_WARNING, # 3
gtk.STOCK_DIALOG_ERROR] # 4
ibar = gtk.InfoBar()
ibar.set_message_type (msgtypes[type[0]])
if vbox:
# If specific vbox requested: assume ibar for filemode, add cancel button
ibar.add_button (gtk.STOCK_CANCEL, gtk.RESPONSE_CANCEL)
ibar.connect ('response', self.cleanup_filemode)
else:
# If no specific vbox requested: do normal ibar at the top of message area
vbox = self.vbox_ibar
ibar.add_button (gtk.STOCK_OK, gtk.RESPONSE_OK)
ibar.connect ('response', lambda *args: ibar.destroy())
vbox.pack_end (ibar, False, False)
content = ibar.get_content_area()
img = gtk.Image()
img.set_from_stock (imgtypes[type[1]], gtk.ICON_SIZE_LARGE_TOOLBAR)
content.pack_start (img, False, False)
img.show ()
if msg:
# If msg was specified, show it, but change the default color
label = gtk.Label()
label.set_markup ("<span foreground='#2E2E2E'>{}</span>".format(msg))
content.pack_start (label, False, False)
label.show ()
# FIXME: Why doesn't Esc trigger this close signal?
ibar.connect ('close', lambda *args: ibar.destroy())
ibar.show()
if timeout:
glib.timeout_add_seconds(timeout, ibar.destroy)
return ibar