Update drivers: Rename setcolor to defcolor, add real setcolor which ignores color stack.
Application: Add overridable startup() method.
Fix Widget draw clipping.
# -*- coding: utf-8 -*-
from tuikit.container import Container
from tuikit.button import Button
from tuikit.layout import AnchorLayout
from tuikit.common import Borders
import logging
class Window(AnchorLayout):
'''Window widget.
It represents part of screen with border, close button and contents.
Window can be moved, resized or closed by user.'''
def __init__(self, inner_layout=AnchorLayout):
'''Create window of requested size.'''
AnchorLayout.__init__(self)
self.sizemin.update(8, 3)
#: Window title.
self.title = ''
#: Allow user to resize window.
self.resizable = True
self._resizing = False
#: Allow user to move window.
self.movable = True
self._moving = False
self.closebtn = Button('x')
self.closebtn.sizereq.w = 3
self.closebtn.add_handler('click', self.on_closebtn_click)
self.closebtn.bg = 'controls'
self.closebtn.bghi = 'controls-active'
Container.add(self, self.closebtn, halign='right', margin=Borders(r=1))
self._closebutton = True
self.colorprefix = 'window:'
self._inner = inner_layout()
Container.add(self, self._inner, halign='fill', valign='fill', margin=Borders(1,1,1,1))
def add(self, widget, **kwargs):
self._inner.add(widget, **kwargs)
@property
def closebutton(self):
'''Show/hide close button.'''
return self._closebutton
@closebutton.setter
def closebutton(self, value):
self._closebutton = value
self.closebtn.hidden = not value
def on_draw(self, ev):
ev.driver.pushcolor('normal')
ev.driver.frame(ev.x, ev.y, self.width, self.height)
if self.resizable:
if self._resizing:
ev.driver.pushcolor('controls-active')
else:
ev.driver.pushcolor('controls')
ev.driver.puts(ev.x + self.width - 2, ev.y + self.height - 1, '─┘') # '━┛'
ev.driver.popcolor()
if self.title:
title = ' ' + self.title + ' '
left = max(1, (self.width - len(title))//2)
right = self.width - len(title) - left
maxlen = self.width - 5
if left > 1 and right < 4:
# move space from left to right to make space for close button
left -= 1
if len(title) > maxlen:
title = title[:maxlen]
title = title[:-1] + ' '
ev.driver.puts(ev.x + left, ev.y, title)
ev.driver.fill(ev.x+1, ev.y+1, self.width-2, self.height-2)
ev.driver.popcolor()
def after_mousedown(self, ev):
self.dragstart = (ev.wx, ev.wy)
if self.resizable and ev.wx >= self.width - 1 and ev.wy >= self.height - 1:
self._resizing = True
elif self.movable:
self._moving = True
self.origsize = (self.width, self.height)
self.redraw(True)
def after_mouseup(self, ev):
if self._resizing:
self.resize(self.origsize[0] + ev.wx - self.dragstart[0],
self.origsize[1] + ev.wy - self.dragstart[1])
self._resizing = False
elif self._moving:
self.move(ev.px - self.dragstart[0],
ev.py - self.dragstart[1])
self._moving = False
self.redraw(True)
def after_mousemove(self, ev):
if ev.px == self.x + self.dragstart[0] \
and ev.py == self.y + self.dragstart[1]:
return
#if x > self.parent.width-self.width:
# return
if self._resizing:
self.resize(self.origsize[0] + ev.wx - self.dragstart[0],
self.origsize[1] + ev.wy - self.dragstart[1])
elif self._moving:
self.move(ev.px - self.dragstart[0],
ev.py - self.dragstart[1])
self.redraw(True)
def on_closebtn_click(self, ev):
self.hide()