1. Henning Schröder
  2. ttgui

Commits

Henning Schröder  committed cf5ecfe

splitted module, more widgets

  • Participants
  • Parent commits b7885b4
  • Branches default

Comments (0)

Files changed (4)

File tcore.py

View file
+# -*- coding: utf-8 -*-
+from console import debug
+from collections import namedtuple
+
+
+class TSize(object):
+    __slots__ = ("width", "height")
+
+    
+    def __init__(self, width, height):
+        self.width = width
+        self.height = height
+
+        
+    def __cmp__(self, other):
+        return cmp((self.width, self.height), (other.width, other.height))
+
+
+
+class TPoint(object):
+    __slots__ = ("x", "y")
+    
+    def __init__(self, x, y):
+        self.x = x
+        self.y = y
+
+
+    def __cmp__(self, other):
+        return cmp((self.x, self.y), (other.x, other.y))
+
+
+        
+        
+class TRect(object):
+    __slots__ = ("_topLeft", "_size")
+
+
+    def __init__(self, point, size):
+        self._topLeft = point
+        self._size = size
+
+
+    @property
+    def size(self):
+        return self._size
+    
+    
+    @property
+    def topLeft(self):
+        return self._topLeft
+
+        
+    @property
+    def bottomLeft(self):
+        x, y = self.topLeft.x, self.topLeft.y
+        return TPoint(x + self.width, y + self.height)
+
+
+    @property
+    def width(self):
+        return self._size.width
+    
+    
+    @property
+    def height(self):
+        return self._size.height
+
+    
+    @property
+    def left(seft):
+        return self._topLeft.x
+
+    
+    @property
+    def top(self):
+        return self._topLeft.y
+
+
+    def inner(self, radius=1):
+        tl = self._topLeft
+        sz = self._size
+        return TRect(
+           TPoint(tl.x+radius, tl.y+radius), 
+           TSize(sz.width-1-radius, sz.height-1-radius))
+
+
+
+class TEvent(object):
+
+    
+    def __init__(self):
+        self.accepted = False
+        self.ignored = False
+
+
+    
+    def accept(self):
+        self.accepted = True
+    
+    
+    def ignore(self):
+        self.ignored = True
+
+
+
+
+class TEventLoop(object):
+    _instance = None
+
+    def __init__(self):
+        self.queue = []
+
+
+    @classmethod
+    def instance(cls):
+        if not cls._instance:
+            cls._instance = cls()
+        return cls._instance
+
+
+    def postEvent(self, obj, event):
+        self.queue.insert(0, (obj, event))
+
+
+    def processEvent(self):
+        if self.queue:
+            obj, event = self.queue.pop()
+            debug("processing event", event, "for", obj)
+            obj.event(event)
+            return True
+        return False
+
+
+
+class TObject(object):
+
+    
+    def __init__(self, parent=None):
+        self._children = set()
+        self._parent = parent
+        self._event_filters = set()
+        if parent:
+            parent._children.add(self)
+            
+            
+    def children(self):
+        return list(self._children)
+    
+    
+    def parent(self):
+        return self._parent
+    
+    
+    def dump_object_tree(self):
+        def dump(obj, level=0):
+            print " " * (level*2), obj
+            for child in obj.children():
+                dump(child, level+1)
+        dump(self)
+
+    
+    def installEventFilter(self, receiver_object):
+        self._event_filters.add(receiver_object)
+
+
+    def postEvent(self, event):
+        TEventLoop.instance().postEvent(self, event)
+
+
+    def event(self, event):
+        for receiver_object in self._event_filters:
+            if receiver_object.eventFilter(self, event):
+                return True
+        return False
+            
+    
+    def eventFilter(self, obj, event):
+        pass
+    
+
+

File test.py

View file
-from tobject import TApplication, TWidget, TLabel, TPoint, TSize
+from tgui import TApplication, TWidget, TLabel, TPoint, TSize, TPushButton
 
 
 app = TApplication()
 win.resize(TSize(60, 15))
 l = TLabel(win)
 l.setText("Hello, world")
+l.move(TPoint(2,2))
+b = TPushButton(win, "OK")
+b.move(TPoint(4,4))
 win.show()
 
 while app.event_loop.processEvent():

File tgui.py

View file
+# -*- coding: utf-8 -*-
+from console import Console, debug
+from tcore import TSize, TPoint, TRect, TEvent, TEventLoop, TObject
+
+
+class TKeyEvent(TEvent):
+    pass
+
+
+class TPaintEvent(TEvent):
+
+    def __init__(self, rect=None):
+        super(TPaintEvent, self).__init__()
+        self.rect = rect
+
+
+class TCloseEvent(TEvent):
+    pass
+
+
+class THideEvent(TEvent):
+    pass
+
+
+class TShowEvent(TEvent):
+    pass
+
+
+class TResizeEvent(TEvent):
+    
+    def __init__(self, size):
+        super(TResizeEvent, self).__init__()
+        self.size = size
+
+
+
+        
+class TPainter(object):
+
+
+    def __init__(self, obj=None):
+        self.stack = []
+        if obj:
+            self.stack.append(obj)
+        self.obj = obj
+        self.con = Console.instance
+
+
+    def begin(self, obj):
+        self.stack.append(obj)
+        self.obj = obj
+        
+
+    def end(self):
+        self.stack.pop()
+        if self.stack:
+            self.obj = self.stack[-1]
+        else:
+            self.obj = None
+            
+            
+    def drawRect(self, rect):
+        gpos = self.obj.mapToGlobal(TPoint(0, 0))
+        x1 = gpos.x + rect.topLeft.x
+        y1 = gpos.y + rect.topLeft.y
+        width = rect.size.width
+        height = rect.size.height
+        x2 = x1 + width - 1
+        y2 = y1 + height - 1
+        # topleft
+        self.con.text(x1, y1, "+")
+        # topright
+        self.con.text(x2, y1, "+")
+        # top line
+        self.con.text(x1 + 1, y1, "-" * (width-2))
+        # bottomleft
+        self.con.text(x1, y2, "+")
+        # bottomright
+        self.con.text(x2, y2, "+")
+        # bottom line
+        self.con.text(x1+1, y2, "-" * (width-2))
+        # side lines
+        for y in range(y1+1, y2):
+            self.con.text(x1, y, "|") # left
+            self.con.text(x2, y, "|") # right
+
+
+    
+    def drawLine(self, start_pos, end_pos):
+        x1, y1 = start_pos.x, start_pos.y
+        x2, y2 = end_pos.x, end_pos.y
+        if y1 == y1:
+            width = x2 - x1
+            self.con.text(x1, y1, "-" * width)
+        elif x1 == x2:
+            for y in range(y1, y2+1):
+                self.con.text(x1, y, "|")
+        else:
+            raise NotImplementedError("Only horizontal and vertial lines supported right now")
+
+        
+    def drawText(self, pos, text):
+        gpos = self.obj.mapToGlobal(pos)
+        self.con.text(gpos.x, gpos.y, text)
+        
+
+
+    def fillRect(self, rect, char):
+        gpos = self.obj.mapToGlobal(TPoint(0, 0))
+        x1 = gpos.x + rect.topLeft.x
+        y1 = gpos.y + rect.topLeft.y
+        width = rect.size.width
+        height = rect.size.height
+        x2 = x1 + width - 1
+        y2 = y1 + height - 1
+        for y in range(y1, y2):
+            self.con.text(x1, y, char*width)
+    
+
+
+
+class TApplication(TObject):
+
+    instance = None
+
+    
+    def __init__(self):
+        super(TApplication, self).__init__()
+        self.event_loop = TEventLoop.instance()
+        self._desktop = TDesktopWidget()
+        TApplication.instance = self
+
+        
+    def desktop(self):
+        return self._desktop
+
+
+    def postEvent(self, receiver_object, event):
+        self.event_loop.postEvent(receiver_object, event)
+    
+    
+    def sendEvent(self, receiver_object, event):
+        self.event_loop.sendEvent(receiver_object, event)
+
+    
+    def notify(self, receiver_object, event):
+        self.event_loop.notify(receiver_object, event)
+        
+        
+    def processEvent(self):
+        return self.event_loop.processEvent()
+    
+        
+    def run(self):
+        self._desktop.show()
+        while True:
+            self.processEvent()
+
+            
+            
+
+
+class TWidget(TObject):
+
+    
+    def __init__(self, parent=None):
+        super(TWidget, self).__init__(parent)
+        self._update_geom(TPoint(0,0), self.sizeHint(), silent=True)
+        self._visible = True
+        
+
+    def sizeHint(self):
+        return TSize(1,1)
+
+        
+    def window(self):
+        parent = self
+        parent_parent = parent.parent()
+        while parent_parent:
+            parent = parent_parent
+            parent_parent = parent.parent()
+        return parent
+
+    
+    def close(self):
+        pass
+    
+        
+    def show(self):
+        self.setVisible(True)
+        
+
+    def hide(self):
+        self.setVisible(False)
+
+        
+    def setVisible(self, flag):
+        self._visible = flag
+        self.postEvent(TPaintEvent())
+        if flag:
+            self.postEvent(TShowEvent())
+        else:    
+            self.postEvent(THideEvent())
+        for child in self.children():
+            child.setVisible(flag)
+
+
+    def _update_geom(self, pos, size, silent=False):
+        x1 = pos.x
+        y1 = pos.y
+        x2 = x1 + size.width
+        y2 = y1 + size.height
+        self._geom = (x1, y1, x2, y2)
+        if not silent:
+            self.postEvent(TResizeEvent(size))
+
+        
+    def size(self):
+        (x1, y1, x2, y2) = self._geom
+        width, height = x2 - y1, y2 - y1
+        return TSize(width, height)
+    
+    
+    def width(self):
+        return self.size().width
+    
+    
+    def height(self):
+        return self.size().height
+
+    
+    def left(seft):
+        return self.pos().x
+
+    
+    def top(self):
+        return self.pos().y
+    
+
+
+    def resize(self, size):
+        (x1, y1, x2, y2) = self._geom
+        width, height = size.width, size.height
+        self._update_geom(TPoint(x1, y1), TSize(width, height))
+
+        
+    def pos(self):
+        (x1, y1, x2, y2) = self._geom
+        return TPoint(x1, y1)
+
+
+    def move(self, pos):
+        self._update_geom(pos, self.size())
+
+
+    def geometry(self):
+        return TRect(self.pos(), self.size())
+
+    
+    def setGeometry(self, pos, size):
+        self._update_geom(pos, size)
+
+    
+    def mapToParent(self, pos):
+        parent = self.parent()
+        if not parent:
+            return TPoint(pos.x, pos.y)
+        else:
+            ppos = parent.pos()
+            return TPoint(ppos.x + pos.x, ppos.y + pos.y)
+
+
+    def mapToGlobal(self, pos):
+        obj = self
+        while obj:
+            pos = obj.mapToParent(pos)
+            obj = obj.parent()
+        return pos
+
+    
+    def event(self, event):
+        if super(TWidget, self).event(event):
+            return True
+        if isinstance(event, TPaintEvent):
+            return self.paintEvent(event)
+        elif isinstance(event, TKeyEvent):
+            return self.keyPressevent(event)
+
+            
+    def keyPressEvent(self, event):
+        pass
+
+
+    def paintEvent(self, event):
+        painter = TPainter(self)
+        if self.parent():
+            painter.fillRect(self.geometry(), " ")
+        else:
+            rect = self.geometry()
+            painter.drawRect(rect)
+            painter.fillRect(rect.inner(), " ")
+
+
+    def resizeEvent(self, event):
+        pass
+
+    
+    def update(self, rect=None):
+        self.postEvent(TPaintEvent(rect))
+    
+        
+    def repaint(self, rect=None):
+        event = TPaintEvent(rect)
+        self.paintEvent(event)
+
+
+        
+
+
+class TDesktopWidget(TWidget):
+
+
+    def __init__(self):
+        super(TDesktopWidget, self).__init__()
+        self._update_geom(TPoint(1, 1), TSize(78, 23))
+        self.console = Console()
+
+        
+    def paintEvent(self, event):
+        painter = TPainter(self)
+        painter.fillRect(self.geometry(), ".")
+
+
+
+        
+class AbstractTextWidgetMixin(object):
+
+    
+    def __init__(self, text=""):
+        self._text = text
+
+            
+    def sizeHint(self):
+        return TSize(min(70, len(self._text)), 1)
+
+
+    def setText(self, text):
+        self._text = text
+        self.resize(self.sizeHint())
+        self.update()
+
+
+    def text(self):
+        return self._text
+
+
+
+class TLabel(TWidget, AbstractTextWidgetMixin):
+
+    
+    def __init__(self, parent=None, text=""):
+        AbstractTextWidgetMixin.__init__(self, text)
+        TWidget.__init__(self, parent)
+
+    
+
+    def paintEvent(self, event):
+        painter = TPainter(self)
+        painter.drawText(self.pos(), self.text())
+
+
+
+        
+class TAbstractButton(TWidget, AbstractTextWidgetMixin):
+
+    
+    def __init__(self, parent=None, text="", checked=False):
+        AbstractTextWidgetMixin.__init__(self, text)
+        self._checked = checked
+        TWidget.__init__(self, parent)
+
+
+    def setChecked(self, flag):
+        self._checked = flag
+        self.update()
+        
+        
+    def isChecked(self):
+        return self._checked
+
+
+        
+        
+class TCheckBox(TAbstractButton):
+    
+    
+    def paintEvent(self, event):
+        painter = TPainter(self)
+        checked = self._checked and "x" or " "
+        painter.drawText(self.pos(), "[%s] %s" % (checked, self.text()))
+
+        
+
+class TRadioButton(TAbstractButton):
+    
+    
+    def paintEvent(self, event):
+        painter = TPainter(self)
+        checked = self._checked and "x" or " "
+        painter.drawText(self.pos(), "(%s) %s" % (checked, self.text()))
+
+
+
+        
+class TPushButton(TAbstractButton):
+    
+    
+    def paintEvent(self, event):
+        painter = TPainter(self)
+        painter.drawText(self.pos(), "< %s >" % self.text())
+

File tobject.py

-# -*- coding: utf-8 -*-
-from console import Console, debug
-
-
-class TEvent(object):
-    pass
-
-
-class TKeyEvent(TEvent):
-    pass
-
-
-class TPaintEvent(TEvent):
-
-    def __init__(self, rect=None):
-        super(TPaintEvent, self).__init__()
-        self.rect = rect
-
-
-class TCloseEvent(TEvent):
-    pass
-
-
-class THideEvent(TEvent):
-    pass
-
-
-class TShowEvent(TEvent):
-    pass
-
-
-class TResizeEvent(TEvent):
-    
-    def __init__(self, size):
-        super(TResizeEvent, self).__init__()
-        self.size = size
-
-
-class TEventLoop(object):
-    _instance = None
-
-    def __init__(self):
-        self.queue = []
-
-
-    @classmethod
-    def instance(cls):
-        if not cls._instance:
-            cls._instance = cls()
-        return cls._instance
-
-
-    def postEvent(self, obj, event):
-        self.queue.insert(0, (obj, event))
-
-
-    def processEvent(self):
-        if self.queue:
-            obj, event = self.queue.pop()
-            debug("processing event", event, "for", obj)
-            obj.event(event)
-            return True
-        return False
-
-
-
-class TObject(object):
-    
-    def __init__(self, parent=None):
-        self._children = set()
-        self._parent = parent
-        self._event_filters = set()
-        if parent:
-            parent._children.add(self)
-            
-            
-    def children(self):
-        return list(self._children)
-    
-    
-    def parent(self):
-        return self._parent
-    
-    
-    def installEventFilter(self, receiver_object):
-        self._event_filters.add(receiver_object)
-
-
-    def postEvent(self, event):
-        TEventLoop.instance().postEvent(self, event)
-
-
-    def event(self, event):
-        for receiver_object in self._event_filters:
-            if receiver_object.eventFilter(self, event):
-                return True
-        return False
-            
-    
-    def eventFilter(self, obj, event):
-        pass
-    
-
-    
-class TSize(object):
-    
-    def __init__(self, width, height):
-        self.width = width
-        self.height = height
-
-
-
-class TPoint(object):
-    
-    def __init__(self, x, y):
-        self.x = x
-        self.y = y
-
-
-        
-class TRect(object):
-    
-
-    def __init__(self, point, size):
-        self.topLeft = point
-        self.size = size
-
-
-
-
-
-class TApplication(TObject):
-
-    instance = None
-
-    
-    def __init__(self):
-        super(TApplication, self).__init__()
-        self.event_loop = TEventLoop.instance()
-        self._desktop = TDesktopWidget()
-        TApplication.instance = self
-
-        
-    def desktop(self):
-        return self._desktop
-
-
-    def postEvent(self, receiver_object, event):
-        self.event_loop.postEvent(receiver_object, event)
-    
-    
-    def sendEvent(self, receiver_object, event):
-        self.event_loop.sendEvent(receiver_object, event)
-
-    
-    def notify(self, receiver_object, event):
-        self.event_loop.notify(receiver_object, event)
-        
-        
-    def processEvent(self):
-        return self.event_loop.processEvent()
-    
-        
-    def run(self):
-        self._desktop.show()
-        while True:
-            self.processEvent()
-
-            
-            
-
-
-class TWidget(TObject):
-
-    
-    def __init__(self, parent=None):
-        super(TWidget, self).__init__(parent)
-        self._update_geom(TPoint(0,0), TSize(1,1))
-        self._visible = True
-        
-
-    def window(self):
-        parent = self
-        parent_parent = parent.parent()
-        while parent_parent:
-            parent = parent_parent
-            parent_parent = parent.parent()
-        return parent
-
-    
-    def close(self):
-        pass
-    
-        
-    def show(self):
-        self.setVisible(True)
-        
-
-    def hide(self):
-        self.setVisible(False)
-
-        
-    def setVisible(self, flag):
-        self._visible = flag
-        self.postEvent(TPaintEvent())
-        if flag:
-            self.postEvent(TShowEvent())
-        else:    
-            self.postEvent(THideEvent())
-        for child in self.children():
-            child.setVisible(flag)
-
-
-    def _update_geom(self, pos, size):
-        x1 = pos.x
-        y1 = pos.y
-        x2 = x1 + size.width
-        y2 = y1 + size.height
-        self._geom = (x1, y1, x2, y2)
-        self.postEvent(TResizeEvent(size))
-
-        
-    def size(self):
-        (x1, y1, x2, y2) = self._geom
-        width, height = x2 - y1, y2 - y1
-        return TSize(width, height)
-    
-
-    def resize(self, size):
-        (x1, y1, x2, y2) = self._geom
-        width, height = size.width, size.height
-        self._update_geom(TPoint(x1, y1), TSize(width, height))
-
-        
-    def pos(self):
-        (x1, y1, x2, y2) = self._geom
-        return TPoint(x1, y1)
-
-
-    def move(self, pos):
-        self._update_geom(pos, self.size())
-
-
-    def geometry(self):
-        return TRect(self.pos(), self.size())
-
-    
-    def setGeometry(self, pos, size):
-        self._update_geom(pos, size)
-
-    
-    def mapToParent(self, pos):
-        parent = self.parent()
-        if not parent:
-            return TPoint(pos.x, pos.y)
-        else:
-            ppos = parent.pos()
-            return TPoint(ppos.x + pos.x, ppos.y + pos.y)
-
-
-    def mapToGlobal(self, pos):
-        obj = self
-        while obj:
-            pos = obj.mapToParent(pos)
-            obj = obj.parent()
-        return pos
-
-    
-    def event(self, event):
-        if super(TWidget, self).event(event):
-            return True
-        if isinstance(event, TPaintEvent):
-            return self.paintEvent(event)
-        elif isinstance(event, TKeyEvent):
-            return self.keyPressevent(event)
-
-            
-    def keyPressEvent(self, event):
-        pass
-
-
-    def paintEvent(self, event):
-        painter = TPainter(self)
-        if self.parent():
-            painter.fillRect(self.geometry(), " ")
-        else:
-            rect = self.geometry()
-            painter.drawRect(rect)
-            pos = rect.topLeft
-            width, height = rect.size.width, rect.size.height
-            inner = TRect(TPoint(pos.x, pos.y), TSize(width-1, height-1))
-            painter.fillRect(inner, " ")
-
-    def resizeEvent(self, event):
-        pass
-
-    
-    def update(self, rect=None):
-        self.postEvent(TPaintEvent(rect))
-    
-        
-    def repaint(self, rect=None):
-        event = TPaintEvent(rect)
-        self.paintEvent(event)
-
-
-        
-class TPainter(object):
-
-
-    def __init__(self, obj=None):
-        self.stack = []
-        if obj:
-            self.stack.append(obj)
-        self.obj = obj
-        self.con = Console.instance
-
-
-    def begin(self, obj):
-        self.stack.append(obj)
-        self.obj = obj
-        
-
-    def end(self):
-        self.stack.pop()
-        if self.stack:
-            self.obj = self.stack[-1]
-        else:
-            self.obj = None
-            
-            
-    def drawRect(self, rect):
-        gpos = self.obj.mapToGlobal(TPoint(0, 0))
-        x1 = gpos.x + rect.topLeft.x
-        y1 = gpos.y + rect.topLeft.y
-        width = rect.size.width
-        height = rect.size.height
-        x2 = x1 + width - 1
-        y2 = y1 + height - 1
-        # topleft
-        self.con.text(x1, y1, "+")
-        # topright
-        self.con.text(x2, y1, "+")
-        # top line
-        self.con.text(x1 + 1, y1, "-" * (width-2))
-        # bottomleft
-        self.con.text(x1, y2, "+")
-        # bottomright
-        self.con.text(x2, y2, "+")
-        # bottom line
-        self.con.text(x1+1, y2, "-" * (width-2))
-        # side lines
-        for y in range(y1+1, y2):
-            self.con.text(x1, y, "|") # left
-            self.con.text(x2, y, "|") # right
-
-        
-    def drawText(self, pos, text):
-        gpos = self.obj.mapToGlobal(pos)
-        self.con.text(gpos.x, gpos.y, text)
-        
-
-
-    def fillRect(self, rect, char):
-        gpos = self.obj.mapToGlobal(TPoint(0, 0))
-        x1 = gpos.x + rect.topLeft.x
-        y1 = gpos.y + rect.topLeft.y
-        width = rect.size.width
-        height = rect.size.height
-        x2 = x1 + width - 1
-        y2 = y1 + height - 1
-        for y in range(y1, y2):
-            self.con.text(x1, y, char*width)
-    
-
-
-class TDesktopWidget(TWidget):
-
-
-    def __init__(self):
-        super(TDesktopWidget, self).__init__()
-        self._update_geom(TPoint(1, 1), TSize(78, 23))
-        self.console = Console()
-
-        
-    def paintEvent(self, event):
-        painter = TPainter(self)
-        painter.fillRect(self.geometry(), ".")
-
-        
-class TLabel(TWidget):
-
-
-    def __init__(self, parent=None, text=None):
-        super(TLabel, self).__init__(parent)
-        self.setText(text)
-        if text:
-            self.resize(TSize(min(70, len(text)), 1))
-
-        
-    def setText(self, text):
-        self._text = text
-        self.update()
-
-        
-    def text(self):
-        return self._text
-    
-
-    def paintEvent(self, event):
-        painter = TPainter(self)
-        painter.drawText(self.pos(), self.text())