Rework layouts: Layout is now normal Container which places its children upon resize event.
Drop TopWindow, top is now any subclass of Container.
Add floater concept: floaters are widgets drawn over normal widgets, not clipped by parent.
Add HScrollbar and Scrollbar abstract base class.
# -*- coding: utf-8 -*-
from tuikit.widget import Widget
from tuikit.events import Event
class Button(Widget):
'''Clickable button.'''
def __init__(self, label=''):
'''Create button with given label, size according to label.'''
Widget.__init__(self)
#: Button label.
self._label = ''
#: Text or graphics to be added before label
self.prefix = '['
#: Text or graphics to be added after label
self.suffix = ']'
#: How should label be aligned if button has excess space - center | left | right
self.align = 'center'
#: Padding between prefix/suffix and label
self.padding = 1
self.allow_focus = True
self.bg = 'button'
self.bghi = 'button-active'
self.highlight = False
self.add_events('click', Event)
self.label = label
@property
def label(self):
"""Button label."""
return self._label
@label.setter
def label(self, value):
self._label = value
w = len(value) + len(self.prefix) + len(self.suffix) + 2 * self.padding
self._default_size.update(w, 1)
def on_draw(self, ev):
pad = self.width - len(self.label) - len(self.prefix) - len(self.suffix)
lpad, rpad = self._divide_padding(pad)
ev.driver.pushcolor(self.getcolor())
# prefix
ev.driver.puts(ev.x, ev.y, self.prefix)
pos = len(self.prefix)
# left pad
ev.driver.puts(ev.x + pos, ev.y, ' ' * lpad)
pos += lpad
# label
ev.driver.puts(ev.x + pos, ev.y, self.label)
pos += len(self.label)
# right pad
ev.driver.puts(ev.x + pos, ev.y, ' ' * rpad)
pos += rpad
# suffix
ev.driver.puts(ev.x + pos, ev.y, self.suffix)
ev.driver.popcolor()
def on_mousedown(self, ev):
self.highlight = True
self.redraw()
def on_mouseup(self, ev):
self.highlight = False
self.redraw()
if self.enclose(ev.px, ev.py):
self.emit('click')
def on_keypress(self, ev):
if ev.keyname == 'enter':
self.emit('click')
def getcolor(self):
if self.highlight or self.has_focus():
return self.bghi
return self.bg
def _divide_padding(self, pad):
# default is 'left'
lpad, rpad = 0, pad
if self.align == 'center':
lpad = pad // 2
rpad = pad - lpad
elif self.align == 'right':
lpad, rpad = pad, 0
return lpad, rpad