Menu, Window and other improvements.
authorRadek Brich <radek.brich@devl.cz>
Tue, 15 Mar 2011 17:27:09 +0100
changeset 2 684cdc352562
parent 1 69318aba22bf
child 3 33ec838dc021
Menu, Window and other improvements.
docs/button.rst
docs/container.rst
docs/index.rst
docs/redraw.rst
docs/widget.rst
docs/window.rst
editor.py
example.py
tuikit/backend_curses.py
tuikit/button.py
tuikit/container.py
tuikit/menu.py
tuikit/menubar.py
tuikit/widget.py
tuikit/window.py
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/button.rst	Tue Mar 15 17:27:09 2011 +0100
@@ -0,0 +1,2 @@
+Button
+======
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/container.rst	Tue Mar 15 17:27:09 2011 +0100
@@ -0,0 +1,7 @@
+Container
+=========
+
+.. toctree::
+   :maxdepth: 2
+
+   window
--- a/docs/index.rst	Thu Feb 17 23:35:05 2011 +0100
+++ b/docs/index.rst	Tue Mar 15 17:27:09 2011 +0100
@@ -1,22 +1,13 @@
-.. Tuikit documentation master file, created by
-   sphinx-quickstart on Wed Feb  2 23:35:28 2011.
-   You can adapt this file completely to your liking, but it should at least
-   contain the root `toctree` directive.
-
-Welcome to Tuikit's documentation!
-==================================
+Tuikit documentation
+====================
 
 Contents:
 
 .. toctree::
-   :maxdepth: 2
+   :maxdepth: 3
 
+   widget
+   focus
    redraw
 
-Indices and tables
-==================
 
-* :ref:`genindex`
-* :ref:`modindex`
-* :ref:`search`
-
--- a/docs/redraw.rst	Thu Feb 17 23:35:05 2011 +0100
+++ b/docs/redraw.rst	Tue Mar 15 17:27:09 2011 +0100
@@ -0,0 +1,2 @@
+Redraw
+======
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/widget.rst	Tue Mar 15 17:27:09 2011 +0100
@@ -0,0 +1,57 @@
+Widget
+======
+
+.. toctree::
+   :maxdepth: 2
+
+   container
+   button
+
+Class attributes
+----------------
+
+.. attribute:: Widget.parent
+
+.. attribute:: Widget.top
+
+.. attribute:: Widget.x
+
+.. attribute:: Widget.y
+
+.. attribute:: Widget.width
+
+.. attribute:: Widget.height
+
+.. attribute:: Widget.hidden
+
+.. attribute:: Widget.allowlayout
+
+
+Event management
+----------------
+
+.. classmethod:: Widget.newevent(event)
+
+   Create new event with empty handler list.
+
+
+.. classmethod:: Widget.connect(event, handler)
+
+   Add handler to handler list of the event.
+
+
+.. classmethod:: Widget.disconnect(event, handler=None)
+
+   Remove handler from event's handler list. If no handler is given, remove all handlers.
+
+
+.. classmethod:: Widget.handle(event, ...)
+
+   Call all handlers from event's handler list.
+   This is used when user defined handlers are to be called.
+
+
+.. classmethod:: Widget.emit(event, ...)
+
+   Emit event.
+   This is used by original event source when the event is detected.
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/docs/window.rst	Tue Mar 15 17:27:09 2011 +0100
@@ -0,0 +1,2 @@
+Window
+======
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/editor.py	Tue Mar 15 17:27:09 2011 +0100
@@ -0,0 +1,64 @@
+#!/usr/bin/env python3
+# -*- coding: utf-8 -*-
+
+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
+
+
+class MyApplication(Application):
+    def __init__(self):
+        Application.__init__(self)
+        self.top.connect('keypress', self.globalkeypress)
+
+        #edit = EditField(50, 'DlouhyTest12')
+        #self.top.add(edit)
+
+
+        t = open('tuikit/widget.py').read()
+        textedit = TextEdit(100, 40, t)
+        self.top.add(textedit)
+        textedit.x = 2
+        self.textedit = textedit
+
+        #win = Window()
+        #self.top.add(win)
+
+        #button = Button('click!')
+        #win.add(button)
+        #button.x = 10
+        #button.y = 7
+
+        #button.connect('click', self.buttonclick)
+        #self.button = button
+
+        #subwin = Window(8,8)
+        #win.add(subwin)
+
+
+    def buttonclick(self):
+        self.button.label = 'YES'
+
+
+    def globalkeypress(self, keyname, char):
+        if keyname == 'escape':
+            self.terminate()
+        if keyname == 'f1':
+            self.textedit.settext('%s' % self.top.focuschild)
+            self.textedit.redraw()
+            
+
+
+if __name__ == '__main__':
+    os.environ['ESCDELAY'] = '25' # do not wait 1 second after pressing Escape key
+    app = MyApplication()
+    app.start()
+
--- a/example.py	Thu Feb 17 23:35:05 2011 +0100
+++ b/example.py	Tue Mar 15 17:27:09 2011 +0100
@@ -15,11 +15,15 @@
         menubar = MenuBar()
         self.top.add(menubar)
 
-        win = Window()
-        self.top.add(win)
-        win.x = 10
-        win.y = 5
-        win.allowlayout = False
+        helpwin = Window()
+        self.top.add(helpwin)
+        helpwin.x = 10
+        helpwin.y = 5
+        helpwin.allowlayout = False
+        helpwin.hidden = True
+        helpwin.title = 'About'
+        #helpwin.closebutton = False
+        #helpwin.resizable = False
 
 
         filemenu = Menu([
@@ -33,7 +37,7 @@
         self.top.add(filemenu)
 
         editmenu = Menu([('Copy', None), ('Paste', None)])
-        helpmenu = Menu([('About', None)])
+        helpmenu = Menu([('About', helpwin)])
 
         self.top.add(editmenu)
         self.top.add(helpmenu)
--- a/tuikit/backend_curses.py	Thu Feb 17 23:35:05 2011 +0100
+++ b/tuikit/backend_curses.py	Tue Mar 15 17:27:09 2011 +0100
@@ -84,6 +84,8 @@
         curses.init_pair(1, curses.COLOR_WHITE, curses.COLOR_BLACK)
         curses.init_pair(2, curses.COLOR_BLACK, curses.COLOR_CYAN)
         curses.init_pair(3, curses.COLOR_WHITE, curses.COLOR_CYAN)
+        curses.init_pair(4, curses.COLOR_WHITE, curses.COLOR_BLUE)
+        curses.init_pair(5, curses.COLOR_CYAN, curses.COLOR_BLUE)
 
         self.BOLD = curses.A_BOLD
         self.BLINK = curses.A_BLINK
@@ -162,6 +164,10 @@
     ## attributes ##
 
     def pushcolor(self, col, attr=0):
+        if type(col) is tuple:
+            col, attr = col
+        if attr == 'bold':
+            attr = self.BOLD
         self.screen.attrset(curses.color_pair(col) | attr)
         self.colorstack.append((col, attr))
 
--- a/tuikit/button.py	Thu Feb 17 23:35:05 2011 +0100
+++ b/tuikit/button.py	Tue Mar 15 17:27:09 2011 +0100
@@ -12,6 +12,11 @@
 
         self.label = label
         self.bg = 1
+        self.bghi = 2
+        self.highlight = False
+
+        self.lbracket = '<'
+        self.rbracket = '>'
 
         self.connect('draw', self.on_draw)
         self.connect('mousedown', self.on_mousedown)
@@ -22,26 +27,32 @@
 
     def on_draw(self, screen, x, y):
         l = (self.width - len(self.label)) // 2
-        screen.pushcolor(self.bg)
-        screen.putch(x, y, '<')
+        screen.pushcolor(self.getcolor())
+        screen.putch(x, y, self.lbracket)
         for i in range(x+1, x+l):
             screen.putch(i, y, ' ')
         screen.puts(x + l, y, self.label)
         for i in range(x+l+len(self.label), x+self.width-1):
             screen.putch(i, y, ' ')
-        screen.putch(x + self.width - 1, y, '>')
+        screen.putch(x + self.width - 1, y, self.rbracket)
         screen.popcolor()
 
 
     def on_mousedown(self, ev):
-        self.bg = 2
+        self.highlight = True
         self.redraw()
 
 
     def on_mouseup(self, ev):
-        self.bg = 1
+        self.highlight = False
         self.redraw()
 
         if self.enclose(ev.px, ev.py):
             self.handle('click')
 
+
+    def getcolor(self):
+        if self.highlight:
+            return self.bghi
+        return self.bg
+
--- a/tuikit/container.py	Thu Feb 17 23:35:05 2011 +0100
+++ b/tuikit/container.py	Tue Mar 15 17:27:09 2011 +0100
@@ -34,6 +34,8 @@
 
 
     def draw(self, screen, x=0, y=0):
+        if self.hidden:
+            return
         #if self._redraw:
             #self.fill(screen, self.y, self.x, self.height, self.width)
         self.handle('draw', screen, x, y)
--- a/tuikit/menu.py	Thu Feb 17 23:35:05 2011 +0100
+++ b/tuikit/menu.py	Tue Mar 15 17:27:09 2011 +0100
@@ -13,6 +13,7 @@
         self.highlight = 3
         self.items = items
         self.selected = items[0]
+        self.menubar = None
 
         self.connect('draw', self.on_draw)
         self.connect('keypress', self.on_keypress)
@@ -51,7 +52,6 @@
 
     def on_mousedown(self, ev):
         self.select_at_pos(ev.wy - 1)
-        self.run_selected()
 
 
     def on_mousemove(self, ev):
@@ -92,5 +92,10 @@
 
     def run_selected(self):
         if self.selected and self.selected[1] is not None:
-            self.selected[1]()
+            if isinstance(self.selected[1], Widget):
+                self.selected[1].show()
+                self.selected[1].setfocus()
+            else:
+                self.menubar.unfocus()
+                self.selected[1]()
 
--- a/tuikit/menubar.py	Thu Feb 17 23:35:05 2011 +0100
+++ b/tuikit/menubar.py	Tue Mar 15 17:27:09 2011 +0100
@@ -32,6 +32,7 @@
                 item[1].allowlayout = False
                 item[1].hidden = True
                 item[1].connect('focus', self.on_submenu_focus)
+                item[1].menubar = self
             i += len(item[0]) + 4
 
 
--- a/tuikit/widget.py	Thu Feb 17 23:35:05 2011 +0100
+++ b/tuikit/widget.py	Tue Mar 15 17:27:09 2011 +0100
@@ -35,6 +35,9 @@
         self.top = top
 
 
+    ### event management
+
+
     def newevent(self, event):
         self.event[event] = []
 
@@ -62,6 +65,9 @@
         getattr(self, event)(*args, **kwargs)
 
 
+    ###
+
+
     def resize(self):
         self.handle('resize')
 
@@ -160,3 +166,13 @@
             return self.y + y, self.x + x
         return self.y, self.x
 
+
+    def hide(self):
+        self.hidden = True
+        self.redraw()
+
+
+    def show(self):
+        self.hidden = False
+        self.redraw()
+
--- a/tuikit/window.py	Thu Feb 17 23:35:05 2011 +0100
+++ b/tuikit/window.py	Tue Mar 15 17:27:09 2011 +0100
@@ -1,6 +1,7 @@
 # -*- coding: utf-8 -*-
 
 from .container import Container
+from .button import Button
 
 
 class Window(Container):
@@ -11,42 +12,80 @@
         self.connect('mousedown', self.on_mousedown)
         self.connect('mouseup', self.on_mouseup)
         self.connect('mousemove', self.on_mousemove)
+        self.connect('resize', self.on_resize)
 
-        self.title = ' '
+        self.title = ''
+        self._closebutton = True
+        self.resizable = True
+        self.movable = True
+
+        self.resizing = False
+        self.moving = False
+
+        self.closebtn = Button('x')
+        self.closebtn.x = self.width - 5
+        self.closebtn.width = 3
+        self.closebtn.connect('click', self.on_closebtn)
+        self.closebtn.bg = (4, 'bold')
+        self.closebtn.bghi = (5, 'bold')
+        self.add(self.closebtn)
+
+
+    @property
+    def closebutton(self):
+        return self._closebutton
+
+    @closebutton.setter
+    def closebutton(self, value):
+        self._closebutton = value
+        self.closebtn.hidden = not value
 
 
     def on_draw(self, screen, x, y):
+        screen.pushcolor(4)
         screen.frame(x, y, self.width, self.height)
+
+        if self.resizable:
+            if self.resizing:
+                screen.pushcolor(5, 'bold')
+            else:
+                screen.pushcolor(4, 'bold')
+            screen.puts(x + self.width - 2, y + self.height - 1, '─┘') # '━┛'
+            screen.popcolor()
+
+        if self.title:
+            screen.puts(x + (self.width - len(self.title))//2, y, self.title)
+
         screen.fill(x+1, y+1, self.width-2, self.height-2)
-    #    screen.addstr(self.title)
+        screen.popcolor()
 
 
     def on_mousedown(self, ev):
         self.dragstart = (ev.wx, ev.wy)
-        if ev.wx >= self.width - 1 and ev.wy >= self.height - 1:
+        if self.resizable and ev.wx >= self.width - 1 and ev.wy >= self.height - 1:
             self.resizing = True
-        else:
-            self.resizing = False
+        elif self.movable:
+            self.moving = True
         self.origsize = (self.width, self.height)
-        #self.title += '%dP%d ' % (x,y)
+
         self.redraw(True)
 
 
     def on_mouseup(self, ev):
-        #self.title += '%dR%d ' % (x,y)
-
         if self.resizing:
             self.width = self.origsize[0] + ev.wx - self.dragstart[0]
             self.height = self.origsize[1] + ev.wy - self.dragstart[1]
-        else:
+            self.resizing = False
+            self.emit('resize')
+        elif self.moving:
             self.x = ev.px - self.dragstart[0]
             self.y = ev.py - self.dragstart[1]
+            self.moving = False
 
         self.redraw(True)
 
 
     def on_mousemove(self, ev):
-     #   self.title += '%dM%d ' % (x,y)
         if ev.px == self.x + self.dragstart[0] \
         and ev.py == self.y + self.dragstart[1]:
             return
@@ -57,9 +96,19 @@
         if self.resizing:
             self.width = self.origsize[0] + ev.wx - self.dragstart[0]
             self.height = self.origsize[1] + ev.wy - self.dragstart[1]
-        else:
+            self.emit('resize')
+        elif self.moving:
             self.x = ev.px - self.dragstart[0]
             self.y = ev.py - self.dragstart[1]
 
         self.redraw(True)
 
+
+    def on_resize(self):
+        self.closebtn.x = self.width - 5
+
+
+    def on_closebtn(self):
+        self.hide()
+
+