Improve binary/image buttons

- show/hide clear/select button
- move open as primary icon of filename
- show download only when there is data to download

issue6719
review37641002
This commit is contained in:
C?dric Krier 2017-09-07 18:44:55 +02:00
parent 5fcdfe11ba
commit f9581df3b7
4 changed files with 83 additions and 58 deletions

View file

@ -1,3 +1,4 @@
* Re-position buttons on Binary/Image widget
* Improve treeview headers
* Update states of both toolbar and menu
* Improve toolbar order

View file

@ -6,8 +6,8 @@ import pango
gtk_version = getattr(gtk, 'get_major_version', lambda: 2)()
BUTTON_BORDER = 10
BUTTON_SPACING = 2
BUTTON_BORDER = 2
BUTTON_SPACING = 1
class CellRendererBinary(gtk.GenericCellRenderer):
@ -36,10 +36,6 @@ class CellRendererBinary(gtk.GenericCellRenderer):
self.editable = False
self.set_property('mode', gtk.CELL_RENDERER_MODE_EDITABLE)
self.use_filename = use_filename
if use_filename:
self.buttons = ('select', 'open', 'save', 'clear')
else:
self.buttons = ('select', 'save', 'clear')
self.clicking = ''
self.images = {}
widget = gtk.Button()
@ -57,6 +53,18 @@ class CellRendererBinary(gtk.GenericCellRenderer):
height = img_sensitive.get_height()
self.images[key] = (img_sensitive, img_insensitive, width, height)
@property
def buttons(self):
buttons = []
if self.size:
if self.use_filename:
buttons.append('open')
buttons.append('save')
buttons.append('clear')
else:
buttons.append('select')
return buttons
def do_set_property(self, pspec, value):
setattr(self, pspec.name, value)
@ -64,7 +72,8 @@ class CellRendererBinary(gtk.GenericCellRenderer):
return getattr(self, pspec.name)
def button_width(self):
return (sum(width for _, _, width, _ in self.images.itervalues())
return (sum(width for n, (_, _, width, _) in self.images.iteritems()
if n in self.buttons)
+ (2 * (BUTTON_BORDER + BUTTON_SPACING) * len(self.buttons))
- 2 * BUTTON_SPACING)
@ -84,8 +93,12 @@ class CellRendererBinary(gtk.GenericCellRenderer):
for index, button_name in enumerate(self.buttons):
_, _, pxbf_width, _ = self.images[button_name]
x_offset = (cell_area.width - button_width
+ (pxbf_width + (2 * BUTTON_BORDER) + BUTTON_SPACING) * index)
if index == 0 and button_name == 'open':
x_offset = 0
else:
x_offset = (cell_area.width - button_width
+ (pxbf_width + (2 * BUTTON_BORDER) + BUTTON_SPACING)
* index)
x_button = cell_area.x + x_offset
if x_button < event.x < (x_button + pxbf_width
+ (2 * BUTTON_BORDER)):
@ -150,9 +163,12 @@ class CellRendererBinary(gtk.GenericCellRenderer):
pixbuf = pxbf_insens
else:
pixbuf = pxbf_sens
x_offset = (cell_area.width - button_width
+ (pxbf_width + (2 * BUTTON_BORDER) + BUTTON_SPACING)
* index)
if index == 0 and button_name == 'open':
x_offset = 0
else:
x_offset = (cell_area.width - button_width
+ (pxbf_width + (2 * BUTTON_BORDER) + BUTTON_SPACING)
* index)
if x_offset < 0:
continue
widget.style.paint_box(window, state, shadow,
@ -185,13 +201,13 @@ class CellRendererBinary(gtk.GenericCellRenderer):
padding = context.get_padding(state)
layout = widget.create_pango_layout(self.size)
lwidth = (
min(w / 2, w - button_width) - padding.left - padding.right)
lwidth = w - button_width - padding.left - padding.right
if lwidth < 0:
lwidth = 0
layout.set_width(lwidth * pango.SCALE)
layout.set_ellipsize(pango.ELLIPSIZE_END)
layout.set_wrap(pango.WRAP_CHAR)
layout.set_alignment(pango.ALIGN_RIGHT)
if lwidth > 0:
lw, lh = layout.get_size() # Can not use get_pixel_extents
@ -199,6 +215,9 @@ class CellRendererBinary(gtk.GenericCellRenderer):
lh /= pango.SCALE
lx = x + padding.left
if self.buttons and self.buttons[0] == 'open':
pxbf_width = self.images['open'][2]
lx += pxbf_width + 2 * BUTTON_BORDER + BUTTON_SPACING
ly = y + padding.top + 0.5 * (
h - padding.top - padding.bottom - lh)
@ -218,9 +237,12 @@ class CellRendererBinary(gtk.GenericCellRenderer):
else:
pixbuf = pxbf_sens
x_offset = (w - button_width
+ (pxbf_width + (2 * BUTTON_BORDER) + BUTTON_SPACING)
* index)
if index == 0 and button_name == 'open':
x_offset = 0
else:
x_offset = (w - button_width
+ (pxbf_width + (2 * BUTTON_BORDER) + BUTTON_SPACING)
* index)
if x_offset < 0:
continue
bx = cell_area.x + x_offset

View file

@ -25,27 +25,6 @@ class BinaryMixin(Widget):
hbox = gtk.HBox(spacing=0)
tooltips = Tooltips()
self.but_select = gtk.Button()
img_select = gtk.Image()
img_select.set_from_stock('tryton-find', gtk.ICON_SIZE_SMALL_TOOLBAR)
self.but_select.set_image(img_select)
self.but_select.set_relief(gtk.RELIEF_NONE)
self.but_select.connect('clicked', self.select)
tooltips.set_tip(self.but_select, _('Select...'))
hbox.pack_start(self.but_select, expand=False, fill=False)
if self.filename:
self.but_open = gtk.Button()
img_open = gtk.Image()
img_open.set_from_stock('tryton-open', gtk.ICON_SIZE_SMALL_TOOLBAR)
self.but_open.set_image(img_open)
self.but_open.set_relief(gtk.RELIEF_NONE)
self.but_open.connect('clicked', self.open_)
tooltips.set_tip(self.but_open, _('Open...'))
hbox.pack_start(self.but_open, expand=False, fill=False)
else:
self.but_open = None
self.but_save_as = gtk.Button()
img_save_as = gtk.Image()
img_save_as.set_from_stock('tryton-save-as',
@ -56,6 +35,15 @@ class BinaryMixin(Widget):
tooltips.set_tip(self.but_save_as, _('Save As...'))
hbox.pack_start(self.but_save_as, expand=False, fill=False)
self.but_select = gtk.Button()
img_select = gtk.Image()
img_select.set_from_stock('tryton-find', gtk.ICON_SIZE_SMALL_TOOLBAR)
self.but_select.set_image(img_select)
self.but_select.set_relief(gtk.RELIEF_NONE)
self.but_select.connect('clicked', self.select)
tooltips.set_tip(self.but_select, _('Select...'))
hbox.pack_start(self.but_select, expand=False, fill=False)
self.but_clear = gtk.Button()
img_clear = gtk.Image()
img_clear.set_from_stock('tryton-clear', gtk.ICON_SIZE_SMALL_TOOLBAR)
@ -83,6 +71,16 @@ class BinaryMixin(Widget):
def preview(self):
return False
def update_buttons(self, value):
if value:
self.but_save_as.show()
self.but_select.hide()
self.but_clear.show()
else:
self.but_save_as.hide()
self.but_select.show()
self.but_clear.hide()
def select(self, widget=None):
if not self.field:
return
@ -152,6 +150,7 @@ class Binary(BinaryMixin, Widget):
self.wid_text.connect('focus-out-event',
lambda x, y: self._focus_out())
self.wid_text.connect_after('key_press_event', self.sig_key_press)
self.wid_text.connect('icon-press', self.sig_icon_press)
self.widget.pack_start(self.wid_text, expand=True, fill=True)
else:
self.wid_text = None
@ -162,12 +161,8 @@ class Binary(BinaryMixin, Widget):
self.widget.pack_start(self.toolbar(), expand=False, fill=False)
def _readonly_set(self, value):
if value:
self.but_select.hide()
self.but_clear.hide()
else:
self.but_select.show()
self.but_clear.show()
self.but_select.set_sensitive(not value)
self.but_clear.set_sensitive(not value)
if self.wid_text:
self.wid_text.set_editable(not value)
set_widget_style(self.wid_text, not value)
@ -189,28 +184,35 @@ class Binary(BinaryMixin, Widget):
return True
return False
def sig_icon_press(self, widget, icon_pos, event):
if icon_pos == gtk.ENTRY_ICON_PRIMARY:
self.open_()
def display(self, record, field):
super(Binary, self).display(record, field)
if not field:
if self.wid_text:
self.wid_text.set_text('')
self.wid_size.set_text('')
if self.but_open:
self.but_open.set_sensitive(False)
self.but_save_as.set_sensitive(False)
self.but_save_as.hide()
return False
if self.wid_text:
self.wid_text.set_text(self.filename_field.get(record) or '')
reset_position(self.wid_text)
if hasattr(field, 'get_size'):
size = field.get_size(record)
else:
size = len(field.get(record))
self.wid_size.set_text(common.humanize(size or 0))
reset_position(self.wid_size)
if self.but_open:
self.but_open.set_sensitive(bool(size))
self.but_save_as.set_sensitive(bool(size))
if self.wid_text:
self.wid_text.set_text(self.filename_field.get(record) or '')
reset_position(self.wid_text)
if size:
stock, tooltip = 'tryton-open', _("Open...")
else:
stock, tooltip = None, ''
pos = gtk.ENTRY_ICON_PRIMARY
self.wid_text.set_icon_from_stock(pos, stock)
self.wid_text.set_icon_tooltip_text(pos, tooltip)
self.update_buttons(bool(size))
return True
def set_value(self, record, field):

View file

@ -56,10 +56,8 @@ class Image(BinaryMixin, Widget):
def _readonly_set(self, value):
self._readonly = value
for button in [self.but_select, self.but_open, self.but_save_as,
self.but_clear]:
if button:
button.set_sensitive(not value)
self.but_select.set_sensitive(not value)
self.but_clear.set_sensitive(not value)
def clear(self, widget=None):
super(Image, self).clear(widget=widget)
@ -102,7 +100,9 @@ class Image(BinaryMixin, Widget):
value = self.field.get_data(self.record)
pixbuf = resize_pixbuf(data2pixbuf(value), self.width, self.height)
self.image.set_from_pixbuf(pixbuf)
return bool(value)
def display(self, record, field):
super(Image, self).display(record, field)
self.update_img()
value = self.update_img()
self.update_buttons(bool(value))