# HG changeset patch # User Radek Brich # Date 1358639359 -3600 # Node ID 03f591f5fe5cd1642eb8e7453ce2dc1aa1c23599 # Parent 2a0e04091898e418e79e60e84f2462575a3f763f Drop Container.offset, add special layout for that - OffsetLayout. Add Widget.bring_up(): moves child to end of children list. diff -r 2a0e04091898 -r 03f591f5fe5c demo_menu.py --- a/demo_menu.py Sat Jan 19 13:05:21 2013 +0100 +++ b/demo_menu.py Sun Jan 20 00:49:19 2013 +0100 @@ -44,6 +44,8 @@ menubtn = MenuButton('MenuButton', menu) self.top.add(menubtn, halign='center', valign='center') + helpwin.bring_up() + def on_top_keypress(self, ev): if ev.keyname == 'escape': self.terminate() diff -r 2a0e04091898 -r 03f591f5fe5c demo_tableview.py --- a/demo_tableview.py Sat Jan 19 13:05:21 2013 +0100 +++ b/demo_tableview.py Sun Jan 20 00:49:19 2013 +0100 @@ -5,7 +5,6 @@ locale.setlocale(locale.LC_ALL, '') from tuikit import Application -from tuikit.layout import VerticalLayout from tuikit.tableview import TableView, TableModel @@ -27,9 +26,7 @@ for x in range(10): view.addcolumn(title='head'+str(x)) - self.top.add(view, expand=True, fill=True) - - self.top.layout = VerticalLayout() + self.top.add(view, halign='fill', valign='fill') def on_top_keypress(self, ev): if ev.keyname == 'escape': diff -r 2a0e04091898 -r 03f591f5fe5c demo_treeview.py --- a/demo_treeview.py Sat Jan 19 13:05:21 2013 +0100 +++ b/demo_treeview.py Sun Jan 20 00:49:19 2013 +0100 @@ -4,12 +4,12 @@ import locale locale.setlocale(locale.LC_ALL, '') -from tuikit import Application, TreeView, TreeModel, ScrollView, VerticalLayout +from tuikit import Application, TreeView, TreeModel, ScrollView class MyApplication(Application): def __init__(self): - Application.__init__(self, top_layout=VerticalLayout) + Application.__init__(self) self.top.add_handler('keypress', self.on_top_keypress) model = TreeModel() @@ -27,7 +27,7 @@ scroll = ScrollView() scroll.add(view) - self.top.add(scroll, expand=True, fill=True) + self.top.add(scroll, halign='fill', valign='fill') def on_top_keypress(self, ev): if ev.keyname == 'escape': diff -r 2a0e04091898 -r 03f591f5fe5c tuikit/common.py --- a/tuikit/common.py Sat Jan 19 13:05:21 2013 +0100 +++ b/tuikit/common.py Sun Jan 20 00:49:19 2013 +0100 @@ -34,13 +34,32 @@ return type(name, (Select,), {'_options': args}) -class Coords: +class Coords(Emitter): '''2D coordinates.''' def __init__(self, x=0, y=0): - self.x = x - self.y = y + self._x = x + self._y = y + self.add_events('change', Event) + + @property + def x(self): + return self._x + + @x.setter + def x(self, value): + self._x = value + self.emit('change') + + @property + def y(self): + return self._y + + @y.setter + def y(self, value): + self._y = value + self.emit('change') def __getitem__(self, key): try: @@ -60,6 +79,7 @@ return 'Coords(x={0.x},y={0.y})'.format(self) def update(self, x=None, y=None): + old_x, old_y = self._x, self._y if isinstance(x, Coords) and y is None: self.x, self.y = x else: @@ -71,6 +91,8 @@ self.y = y elif y is not None: raise ValueError('Coords.update(): second parameter must be int') + if self._x != old_x or self._y != old_y: + self.emit('change') class Size(Emitter): diff -r 2a0e04091898 -r 03f591f5fe5c tuikit/container.py --- a/tuikit/container.py Sat Jan 19 13:05:21 2013 +0100 +++ b/tuikit/container.py Sun Jan 20 00:49:19 2013 +0100 @@ -17,9 +17,6 @@ self.children = [] self._hint_class = {} - #: Offset for child widgets - self.offset = Coords() - self.focuschild = None self.mousechild = None @@ -61,6 +58,11 @@ for hint_name, hint_class in zip(hints[::2], hints[1::2]): self._hint_class[hint_name] = hint_class + def bring_up_child(self, child): + if child in self.children: + self.children.remove(child) + self.children.append(child) + @property def layout(self): return self._layout @@ -100,7 +102,10 @@ event - in that case, True stops event propagation. """ - idx_current = self.children.index(self.focuschild) + if self.focuschild is None: + idx_current = 0 + else: + idx_current = self.children.index(self.focuschild) idx_new = idx_current cycled = False while True: @@ -150,8 +155,8 @@ for child in [ch for ch in self.children if not ch.floater]: child.draw(driver, - x + self.offset.x + child.x, - y + self.offset.y + child.y) + x + child.x, + y + child.y) driver.clipstack.pop() @@ -168,13 +173,13 @@ # draw our floaters for child in [ch for ch in self.children if ch.floater]: child.draw(driver, - x + self.offset.x + child.x, - y + self.offset.y + child.y) + x + child.x, + y + child.y) # delve into child containers, draw their floaters for child in [ch for ch in self.children if not ch.floater and isinstance(ch, Container)]: child.draw_floaters(driver, - x + self.offset.x + child.x, - y + self.offset.y + child.y) + x + child.x, + y + child.y) def on_resize(self, ev): for child in self.children: @@ -221,7 +226,7 @@ if self.floaters_mouse_event(ev): return True for child in reversed([ch for ch in self.children if not ch.floater]): - if child.enclose(ev.wx - self.offset.x, ev.wy - self.offset.y): + if child.enclose(ev.wx, ev.wy): child_ev = ev.make_child_event(self, child) child.emit(ev.event_name, child_ev) if ev.event_name == 'mousedown': @@ -241,7 +246,7 @@ return True # test our floaters for child in reversed([ch for ch in self.children if ch.floater]): - if child.enclose(ev.wx - self.offset.x, ev.wy - self.offset.y): + if child.enclose(ev.wx, ev.wy): child_ev = ev.make_child_event(self, child) child.emit(ev.event_name, child_ev) if ev.event_name == 'mousedown': diff -r 2a0e04091898 -r 03f591f5fe5c tuikit/layout.py --- a/tuikit/layout.py Sat Jan 19 13:05:21 2013 +0100 +++ b/tuikit/layout.py Sun Jan 20 00:49:19 2013 +0100 @@ -186,6 +186,36 @@ self._resize(ax1, ax2) +class OffsetLayout(Layout): + + """Offsets widget position, useful for scrollable area.""" + + def __init__(self): + Layout.__init__(self) + self._offset = Coords() + self._offset.add_handler('change', lambda ev: self._update_children_position()) + self.register_hints('position', Coords) + + @property + def offset(self): + """Offset of child widgets.""" + return self._offset + + def on_resize(self, ev): + for child in self._get_children(): + w, h = child.sizereq + child._size.update(w=w, h=h) + + def move_child(self, child, x, y): + child.hints('position').update(x, y) + + def _update_children_position(self): + ox, oy = self._offset + for child in self.children: + x, y = child.hints['position'] + child._pos.update(x=x+ox, y=y+oy) + + class GridLayout(Layout): def __init__(self, numcols=2): Layout.__init__(self) diff -r 2a0e04091898 -r 03f591f5fe5c tuikit/menubar.py --- a/tuikit/menubar.py Sat Jan 19 13:05:21 2013 +0100 +++ b/tuikit/menubar.py Sun Jan 20 00:49:19 2013 +0100 @@ -22,6 +22,12 @@ widget.move(0, 1) widget.hide() + def on_keypress(self, ev): + if ev.keyname == 'escape': + if not self.menu.hidden: + self.menu.hide() + return True + def on_click(self, ev): self.menu.show() @@ -76,7 +82,4 @@ return res elif ev.keyname == 'down': return self.focuschild.show_menu() - elif menu_visible and ev.keyname == 'escape': - self.focuschild.menu.hide() - return True diff -r 2a0e04091898 -r 03f591f5fe5c tuikit/scrollview.py --- a/tuikit/scrollview.py Sat Jan 19 13:05:21 2013 +0100 +++ b/tuikit/scrollview.py Sun Jan 20 00:49:19 2013 +0100 @@ -1,10 +1,11 @@ # -*- coding: utf-8 -*- -from tuikit.container import Container +from tuikit.layout import AnchorLayout, OffsetLayout from tuikit.scrollbar import VScrollbar +from tuikit.common import Borders -class ScrollView(Container): +class ScrollView(AnchorLayout): """Scrolling view Shows scrollbars when needed. @@ -13,50 +14,47 @@ """ def __init__(self): - Container.__init__(self) + AnchorLayout.__init__(self) self._default_size.update(20, 20) + self.inner = OffsetLayout() + AnchorLayout.add(self, self.inner, halign='fill', valign='fill', margin=Borders(r=1)) + self.vscroll = VScrollbar() self.vscroll.add_handler('change', self._on_vscroll_change) - self.vscroll.evade_layout = 2 - self.add(self.vscroll) + AnchorLayout.add(self, self.vscroll, halign='right', valign='fill') def add(self, widget, **kwargs): - Container.add(self, widget, **kwargs) - if widget != self.vscroll: - widget.add_handler('sizereq', self._on_child_sizereq) - widget.add_handler('spotmove', self._on_child_spotmove) + self.inner.add(widget, **kwargs) + widget.add_handler('sizereq', self._on_child_sizereq) + widget.add_handler('spotmove', self._on_child_spotmove) def on_resize(self, ev): - self.vscroll.move(x = self.size.w - 1) - self.vscroll.resize(h = self.height) self._update_vscroll_max() def _on_vscroll_change(self, ev): - self.offset.y = - self.vscroll.pos + self.inner.offset.y = - self.vscroll.scroll_pos def _on_child_sizereq(self, ev): self._update_vscroll_max() def _on_child_spotmove(self, ev): child = ev.originator - spot = child.y + child.spot.y - if spot < self.vscroll.pos: - self.vscroll.pos = spot - if spot > (self.size.h - 1) + self.vscroll.pos: - self.vscroll.pos = spot - (self.size.h - 1) + spot = child.y - self.inner.offset.y + child.spot.y + if spot < self.vscroll.scroll_pos: + self.vscroll.scroll_pos = spot + if spot > (self.height - 1) + self.vscroll.scroll_pos: + self.vscroll.scroll_pos = spot - (self.height - 1) def _update_vscroll_max(self): max_height = 0 - for child in self.children: - if child == self.vscroll: - continue - child_height = child.x + child.sizereq.h + for child in self.inner.children: + child_height = child.y - self.inner.offset.y + child.sizereq.h if child_height > max_height: max_height = child_height - if max_height < self.size.h: + if max_height < self.height: self.vscroll.hide() else: - self.vscroll.max = max_height - self.size.h + self.vscroll.scroll_max = max_height - self.height self.vscroll.show() diff -r 2a0e04091898 -r 03f591f5fe5c tuikit/tableview.py --- a/tuikit/tableview.py Sat Jan 19 13:05:21 2013 +0100 +++ b/tuikit/tableview.py Sun Jan 20 00:49:19 2013 +0100 @@ -64,8 +64,9 @@ class TableView(Widget): - def __init__(self, model=None, width=20, height=20): - Widget.__init__(self, width, height) + def __init__(self, model=None): + Widget.__init__(self) + self._default_size.update(20, 20) self.allow_focus = True @@ -79,8 +80,8 @@ self.headsize = 1 self.offset = Coords() + #: Active cell (cursor) self.acell = Coords() - '''Active cell (cursor).''' self.add_events( 'scroll', Event, @@ -106,7 +107,7 @@ self.columns.append(col) def compute_column_sizes(self): - total_space = self.size.w - self.spacing * len(self.columns) + total_space = self.width - self.spacing * len(self.columns) no_expand_cols = [col for col in self.columns if not col.expand] no_expand_size = sum([col.sizereq for col in no_expand_cols]) expand_cols = [col for col in self.columns if col.expand] @@ -161,7 +162,7 @@ def on_draw(self, ev): ev.driver.pushcolor('normal') self.rowcount = self.model.getcount() - numrows = min(self.rowcount - self.offset.y, self.size.h - self.headsize) + numrows = min(self.rowcount - self.offset.y, self.height - self.headsize) rows = self.model.getrows(self.offset.y, self.offset.y + numrows) self.compute_column_sizes() self.draw_head(ev.driver, ev.x, ev.y) diff -r 2a0e04091898 -r 03f591f5fe5c tuikit/widget.py --- a/tuikit/widget.py Sat Jan 19 13:05:21 2013 +0100 +++ b/tuikit/widget.py Sun Jan 20 00:49:19 2013 +0100 @@ -89,7 +89,7 @@ def y(self): return self._pos.y - def move(self, x, y): + def move(self, x=None, y=None): if self.floater: self._pos.update(x, y) if self.parent: @@ -263,6 +263,10 @@ self.hidden = False self.redraw() + def bring_up(self): + if self.parent: + self.parent.bring_up_child(self) + ## timeout ##