Menu development. New focus. Easier imports from tuikit package.
--- a/docs/focus.rst Wed Feb 16 23:51:30 2011 +0100
+++ b/docs/focus.rst Thu Feb 17 23:35:05 2011 +0100
@@ -1,14 +1,16 @@
Focus
=====
-Only one non-container widget can have focus at the time.
-All parent containers also have focus.
+Only one widget can have focus at the time.
+Top widget has link to currently focused widget in 'focuswidget'.
Events emitted on change: focus, unfocus
-mousedown - focus widget under mouse or its parent if canfocus() == false
+mousedown - focus widget under mouse
-tab - focus next child in container
+tab - focus next child in container (depends on canfocus())
shift-tab - previous child
hide() -> unfocus
+
+tab/shift-tab into / out off containers?
--- a/example.py Wed Feb 16 23:51:30 2011 +0100
+++ b/example.py Thu Feb 17 23:35:05 2011 +0100
@@ -4,17 +4,7 @@
import locale
locale.setlocale(locale.LC_ALL, '')
-import os
-
-from tuikit.application import Application
-from tuikit.editfield import EditField
-from tuikit.window import Window
-from tuikit.button import Button
-from tuikit.scrollbar import VScrollbar
-from tuikit.textedit import TextEdit
-from tuikit.menubar import MenuBar
-from tuikit.menu import Menu
-from tuikit.layout import VerticalLayout
+from tuikit import *
class MyApplication(Application):
@@ -25,34 +15,39 @@
menubar = MenuBar()
self.top.add(menubar)
- filemenu = Menu(['New', '-', 'Open', 'Save', '-', 'Quit'])
+ win = Window()
+ self.top.add(win)
+ win.x = 10
+ win.y = 5
+ win.allowlayout = False
+
+
+ filemenu = Menu([
+ ('New', None),
+ None,
+ ('Open', None),
+ ('Save', None),
+ None,
+ ('Quit', self.terminate),
+ ])
self.top.add(filemenu)
- filemenu.allowlayout = False
- filemenu.hidden = True
- editmenu = Menu(['Copy', 'Paste'])
+ editmenu = Menu([('Copy', None), ('Paste', None)])
+ helpmenu = Menu([('About', None)])
+
self.top.add(editmenu)
- editmenu.allowlayout = False
- editmenu.hidden = True
-
- helpmenu = Menu(['About'])
self.top.add(helpmenu)
- helpmenu.allowlayout = False
- helpmenu.hidden = True
menubar.setitems([
('File', filemenu),
('Edit', editmenu),
- ('Help', helpmenu)
+ ('Help', helpmenu),
])
vert = VerticalLayout()
self.top.layout(vert)
- #win = Window()
- #self.top.add(win)
-
#button = Button('click!')
#win.add(button)
#button.x = 10
--- a/tuikit/__init__.py Wed Feb 16 23:51:30 2011 +0100
+++ b/tuikit/__init__.py Thu Feb 17 23:35:05 2011 +0100
@@ -0,0 +1,15 @@
+# -*- coding: utf-8 -*-
+
+from tuikit.application import Application
+from tuikit.button import Button
+from tuikit.common import Rect
+from tuikit.container import Container
+from tuikit.editbox import EditBox
+from tuikit.editfield import EditField
+from tuikit.layout import VerticalLayout
+from tuikit.menu import Menu
+from tuikit.menubar import MenuBar
+from tuikit.scrollbar import VScrollbar
+from tuikit.textedit import TextEdit
+from tuikit.widget import Widget
+from tuikit.window import Window
--- a/tuikit/application.py Wed Feb 16 23:51:30 2011 +0100
+++ b/tuikit/application.py Thu Feb 17 23:35:05 2011 +0100
@@ -14,6 +14,8 @@
def __init__(self):
Container.__init__(self)
+ self.focuswidget = None
+
self.top = self
self.timeout = []
@@ -21,6 +23,11 @@
self.connect('draw', self.on_draw)
+ def keypress(self, keyname, char):
+ if self.focuswidget and self.focuswidget != self:
+ self.focuswidget.emit('keypress', keyname, char)
+ self.handle('keypress', keyname, char)
+
def on_draw(self, screen, x, y):
screen.erase()
@@ -87,7 +94,6 @@
self.screen = BackendCurses(screen)
self.top.width, self.top.height = self.screen.width, self.screen.height
self.top.emit('resize')
- self.top.setfocus()
while True:
self.top.draw(self.screen)
--- a/tuikit/container.py Wed Feb 16 23:51:30 2011 +0100
+++ b/tuikit/container.py Thu Feb 17 23:35:05 2011 +0100
@@ -8,7 +8,6 @@
Widget.__init__(self, width, height)
self.children = []
- self.focuschild = None
self.mousechild = None
self.borders = (0, 0, 0, 0) # left, top, right, bottom
@@ -34,34 +33,6 @@
child.settop(top)
- ### focus
-
-
- def canfocus(self):
- return True
-
-
- def setfocus(self):
- self.focus = True
- if self.focuschild is None and len(self.children) > 0:
- for child in self.children:
- if self.focuschild is None:
- if child.canfocus():
- self.focuschild = child
- child.setfocus()
- else:
- if child.focus:
- child.unfocus()
-
- def unfocus(self):
- self.focus = False
- for child in self.children:
- child.unfocus()
-
-
- ###
-
-
def draw(self, screen, x=0, y=0):
#if self._redraw:
#self.fill(screen, self.y, self.x, self.height, self.width)
@@ -80,14 +51,6 @@
#self._redraw = False
- def keypress(self, keyname, char):
- # always relay key event to some child
- if self.focus:
- self.handle('keypress', keyname, char)
- if self.focuschild:
- self.focuschild.keypress(keyname, char)
-
-
def mousedown(self, ev):
handled = False
for child in reversed(self.children):
@@ -98,6 +61,7 @@
handled = True
break
if not handled:
+ self.setfocus()
self.handle('mousedown', ev)
--- a/tuikit/menu.py Wed Feb 16 23:51:30 2011 +0100
+++ b/tuikit/menu.py Thu Feb 17 23:35:05 2011 +0100
@@ -6,14 +6,19 @@
class Menu(Widget):
def __init__(self, items=[]):
Widget.__init__(self)
- self.width = max([len(x) for x in items]) + 4
+ self.width = max([len(x[0]) for x in items if x is not None]) + 4
self.height = len(items) + 2
self.bg = 2
+ self.highlight = 3
self.items = items
+ self.selected = items[0]
self.connect('draw', self.on_draw)
self.connect('keypress', self.on_keypress)
+ self.connect('mousedown', self.on_mousedown)
+ self.connect('mousemove', self.on_mousemove)
+ self.connect('mouseup', self.on_mouseup)
def on_draw(self, screen, x, y):
@@ -21,14 +26,71 @@
screen.frame(x, y, self.width, self.height)
i = 1
for item in self.items:
- if item == '-':
+ if item is None:
screen.puts(x, y + i, screen.LTEE + screen.HLINE * (self.width - 2) + screen.RTEE)
else:
- screen.puts(x + 1, y + i, ' ' + item + ' ' * (self.width - 3 - len(item)))
+ if self.selected == item:
+ screen.pushcolor(self.highlight, screen.BOLD)
+ screen.puts(x + 1, y + i, ' ' + item[0] + ' ' * (self.width - 3 - len(item[0])))
+ screen.popcolor()
+ else:
+ screen.puts(x + 1, y + i, ' ' + item[0] + ' ' * (self.width - 3 - len(item[0])))
i += 1
screen.popcolor()
def on_keypress(self, keyname, char):
+ if keyname == 'up':
+ self.move_selected(-1)
+ if keyname == 'down':
+ self.move_selected(+1)
+ if keyname == 'enter':
+ self.run_selected()
self.redraw()
+
+ def on_mousedown(self, ev):
+ self.select_at_pos(ev.wy - 1)
+ self.run_selected()
+
+
+ def on_mousemove(self, ev):
+ self.select_at_pos(ev.wy - 1)
+
+
+ def on_mouseup(self, ev):
+ ok = self.select_at_pos(ev.wy - 1)
+ if ok:
+ self.run_selected()
+
+
+ def select_at_pos(self, pos):
+ if pos < 0:
+ return False
+ try:
+ item = self.items[pos]
+ except IndexError:
+ return False
+ if item is None:
+ return False
+ self.selected = item
+ self.redraw()
+ return True
+
+
+ def move_selected(self, offset):
+ if self.selected:
+ i = self.items.index(self.selected)
+ i += offset
+ item = self.items[i % len(self.items)]
+ if item is None:
+ i += offset
+ item = self.items[i % len(self.items)]
+ self.selected = item
+ self.redraw()
+
+
+ def run_selected(self):
+ if self.selected and self.selected[1] is not None:
+ self.selected[1]()
+
--- a/tuikit/menubar.py Wed Feb 16 23:51:30 2011 +0100
+++ b/tuikit/menubar.py Thu Feb 17 23:35:05 2011 +0100
@@ -1,6 +1,7 @@
# -*- coding: utf-8 -*-
from .widget import Widget
+import logging
class MenuBar(Widget):
@@ -16,11 +17,23 @@
self.connect('draw', self.on_draw)
self.connect('keypress', self.on_keypress)
self.connect('mousedown', self.on_mousedown)
+ self.connect('mousemove', self.on_mousemove)
+ self.connect('unfocus', self.on_unfocus)
def setitems(self, items):
self.items = items
+ i = 0
+ for item in self.items:
+ if isinstance(item[1], Widget):
+ item[1].x = i
+ item[1].y = self.y + 1
+ item[1].allowlayout = False
+ item[1].hidden = True
+ item[1].connect('focus', self.on_submenu_focus)
+ i += len(item[0]) + 4
+
def on_draw(self, screen, x, y):
screen.pushcolor(self.bg)
@@ -39,23 +52,60 @@
def on_keypress(self, keyname, char):
+ if keyname == 'left':
+ self.move_selected(-1)
+ elif keyname == 'right':
+ self.move_selected(+1)
+ else:
+ if self.selected:
+ if isinstance(self.selected[1], Widget):
+ self.selected[1].emit('keypress', keyname, char)
+
+
+ def move_selected(self, offset):
+ if self.selected:
+ i = self.items.index(self.selected)
+ item = self.items[(i + offset) % len(self.items)]
+ self.unselect()
+ self.select(item)
self.redraw()
def on_mousedown(self, ev):
i = 0
+ self.unselect()
+ for item in self.items:
+ w = len(item[0]) + 4
+ if ev.wx >= i and ev.wx < i + w:
+ self.select(item)
+ i += w
+
+
+ def on_mousemove(self, ev):
+ self.on_mousedown(ev)
+
+
+ def on_unfocus(self, newfocus):
+ #logging.getLogger('tuikit').debug('unfocus')
+ if self.selected and newfocus == self.selected[1]:
+ return
+ self.unselect()
+
+
+ def on_submenu_focus(self):
+ self.setfocus()
+
+
+ def select(self, item):
+ self.selected = item
+ if isinstance(item[1], Widget):
+ item[1].hidden = False
+ item[1].redraw()
+
+
+ def unselect(self):
if self.selected:
if isinstance(self.selected[1], Widget):
self.selected[1].hidden = True
self.selected = None
- for item in self.items:
- w = len(item[0]) + 4
- if ev.wx >= i and ev.wx < i + w:
- self.selected = item
- if isinstance(item[1], Widget):
- item[1].x = i
- item[1].y = self.y + 1
- item[1].hidden = False
- item[1].redraw()
- i += w
--- a/tuikit/widget.py Wed Feb 16 23:51:30 2011 +0100
+++ b/tuikit/widget.py Thu Feb 17 23:35:05 2011 +0100
@@ -16,17 +16,19 @@
self.allowlayout = True
# redraw request
self._redraw = True
- self.focus = False
self.hidden = False
# event handlers
self.event = {
'resize' : [],
'draw' : [],
+ 'focus' : [],
+ 'unfocus' : [],
'keypress' : [],
'mousedown' : [],
'mouseup' : [],
'mousemove' : [],
- 'mousewheel' : []}
+ 'mousewheel' : [],
+ }
def settop(self, top):
@@ -85,27 +87,42 @@
def setfocus(self):
- self.focus = True
+ if self.hasfocus():
+ return
+ if self.top.focuswidget:
+ self.top.focuswidget.unfocus(self)
+ self.top.focuswidget = self
+ self.emit('focus')
def unfocus(self):
- self.focus = False
+ if self.top.focuswidget != self:
+ return
+ self.top.focuswidget = None
+ self.emit('unfocus')
- def grabfocus(self):
- if not self.focus:
- self.parent.grabfocus(self) # grab focus for me
+ def hasfocus(self):
+ return self.top.focuswidget == self
+
+
+ def focus(self):
+ self.handle('focus')
+
+
+ def unfocus(self, newfocus=None):
+ self.handle('unfocus', newfocus)
###
def keypress(self, keyname, char):
- if self.focus:
- self.handle('keypress', keyname, char)
+ self.handle('keypress', keyname, char)
def mousedown(self, ev):
+ self.setfocus()
self.handle('mousedown', ev)
@@ -142,3 +159,4 @@
y,x = self.parent.screenyx()
return self.y + y, self.x + x
return self.y, self.x
+