Refactor cursor.
authorRadek Brich <radek.brich@devl.cz>
Wed, 03 Sep 2014 19:17:04 +0200
changeset 112 ce2e67e7bbb8
parent 111 b055add74b18
child 113 6796adfdc7eb
Refactor cursor.
tuikit/core/application.py
tuikit/core/container.py
tuikit/core/widget.py
tuikit/core/window.py
tuikit/widgets/textbox.py
tuikit/widgets/textfield.py
--- a/tuikit/core/application.py	Wed Sep 03 19:14:43 2014 +0200
+++ b/tuikit/core/application.py	Wed Sep 03 19:17:04 2014 +0200
@@ -62,7 +62,7 @@
         screen = ProxyBuffer(self.driver)
         while not self._quit:
             self.window_manager.draw(screen)
-            self.driver.cursor = self.window_manager.cursor
+            self.driver.cursor = self.window_manager.get_cursor_if_visible()
             self.driver.flush()
 
             timeout = self.timer.nearest_timeout()
--- a/tuikit/core/container.py	Wed Sep 03 19:14:43 2014 +0200
+++ b/tuikit/core/container.py	Wed Sep 03 19:17:04 2014 +0200
@@ -53,11 +53,16 @@
     def cursor(self):
         if self.focus_widget:
             cursor = self.focus_widget.cursor
-            if cursor is not None:
-                return cursor.moved(*self.focus_widget.pos)
+            return cursor.moved(*self.focus_widget.pos)
         else:
-            if self._cursor is not None:
-                return Point(self._cursor)
+            return self._cursor
+
+    @property
+    def cursor_visible(self):
+        if self.focus_widget:
+            return self.focus_widget.cursor_visible
+        else:
+            return self._cursor_visible
 
     ## input events ##
 
--- a/tuikit/core/widget.py	Wed Sep 03 19:14:43 2014 +0200
+++ b/tuikit/core/widget.py	Wed Sep 03 19:17:04 2014 +0200
@@ -40,9 +40,9 @@
         self.sizemax = Size(None, None)
 
         #: Cursor is position where text input will occur.
-        #: It is displayed on screen if widget is active.
-        #: None means no cursor (hidden).
-        self._cursor = None
+        self._cursor = Point()
+        #: Cursor is displayed on screen only if the widget is focused.
+        self._cursor_visible = False
 
         #: Hidden widget does not affect layout.
         self.hidden = False
@@ -100,8 +100,11 @@
 
     @property
     def cursor(self):
-        if self._cursor is not None:
-            return Point(self._cursor)
+        return self._cursor
+
+    @property
+    def cursor_visible(self):
+        return self._cursor_visible
 
     ## events ##
 
--- a/tuikit/core/window.py	Wed Sep 03 19:14:43 2014 +0200
+++ b/tuikit/core/window.py	Wed Sep 03 19:17:04 2014 +0200
@@ -86,3 +86,6 @@
             node = node.focus_widget
         return node
 
+    def get_cursor_if_visible(self):
+        if self.cursor_visible:
+            return self.cursor
--- a/tuikit/widgets/textbox.py	Wed Sep 03 19:14:43 2014 +0200
+++ b/tuikit/widgets/textbox.py	Wed Sep 03 19:17:04 2014 +0200
@@ -4,11 +4,7 @@
 
 class TextBox(Widget):
 
-    """Multiline text view/edit widget.
-
-    Spot is used for text cursor position.
-
-    """
+    """Multiline text view/edit widget."""
 
     def __init__(self, text=''):
         Widget.__init__(self)
@@ -18,8 +14,8 @@
         self._lines = []
         self.text = text
 
-        # Cursor position is same as spot.
-        # This variable rememberes horizontal position
+        self._cursor_visible = True
+        # This variable rememberes horizontal cursor position
         # for the case when cursor moves to shorter line.
         self.cursor_column = 0
         # selection - line and column of selection start
@@ -40,25 +36,20 @@
 
     @property
     def cur_line(self):
-        return self._lines[self._spot.y]
+        return self._lines[self._cursor.y]
 
     @cur_line.setter
     def cur_line(self, value):
-        self._lines[self._spot.y] = value
-
-    def set_theme(self, theme):
-        Widget.set_theme(self, theme)
-        self.color = theme.normal
+        self._lines[self._cursor.y] = value
 
     def draw(self, buffer):
         exposed = self.exposed(buffer)
-        with buffer.attr(self.color):
+        with buffer.attr(self.theme.normal):
             buffer.fill()
             end_y = min(len(self._lines), exposed.y + exposed.h)
             for j in range(exposed.y, end_y):
                 line = self._lines[j]
                 buffer.puts(line, 0, j)
-            #self.cursor = (self._spot.x, self._spot.y)
 
     def keypress_event(self, ev):
         if ev.keyname and not ev.mods:
@@ -96,7 +87,7 @@
     def on_mousedown(self, ev):
         y = ev.wy
         x = min(ev.wx, len(self._lines[y]))
-        self._spot.update(x=x, y=y)
+        self._cursor.update(x=x, y=y)
         self.redraw()
 
     def on_mousewheel(self, ev):
@@ -109,110 +100,110 @@
         self.redraw()
 
     def move_left(self):
-        if self._spot.x > 0:
-            self._spot.x -= 1
+        if self._cursor.x > 0:
+            self._cursor.x -= 1
         else:
-            if self._spot.y > 0:
-                self._spot.y -= 1
-                self._spot.x = len(self.cur_line)
-        self.cursor_column = self._spot.x
+            if self._cursor.y > 0:
+                self._cursor.y -= 1
+                self._cursor.x = len(self.cur_line)
+        self.cursor_column = self._cursor.x
 
     def move_right(self):
-        if self._spot.x < len(self.cur_line):
-            self._spot.x += 1
+        if self._cursor.x < len(self.cur_line):
+            self._cursor.x += 1
         else:
-            if self._spot.y < len(self._lines) - 1:
-                self._spot.y += 1
-                self._spot.x = 0
-        self.cursor_column = self._spot.x
+            if self._cursor.y < len(self._lines) - 1:
+                self._cursor.y += 1
+                self._cursor.x = 0
+        self.cursor_column = self._cursor.x
 
     def move_home(self):
-        self._spot.x = 0
-        self.cursor_column = self._spot.x
+        self._cursor.x = 0
+        self.cursor_column = self._cursor.x
 
     def move_end(self):
-        self._spot.x = len(self.cur_line)
-        self.cursor_column = self._spot.x
+        self._cursor.x = len(self.cur_line)
+        self.cursor_column = self._cursor.x
 
     def move_up(self):
-        if self._spot.y > 0:
-            self._spot.y -= 1
-        self._update_spot_x()
+        if self._cursor.y > 0:
+            self._cursor.y -= 1
+        self._update_cursor_x()
 
     def move_down(self):
-        if self._spot.y < len(self._lines) - 1:
-            self._spot.y += 1
-        self._update_spot_x()
+        if self._cursor.y < len(self._lines) - 1:
+            self._cursor.y += 1
+        self._update_cursor_x()
 
     def move_pageup(self):
-        if self._spot.y >= self.view_height - 1:
+        if self._cursor.y >= self.view_height - 1:
             self.emit('scrollreq', - (self.view_height - 1))
-            self._spot.y -= self.view_height - 1
+            self._cursor.y -= self.view_height - 1
         else:
-            self._spot.y = 0
-        self._update_spot_x()
+            self._cursor.y = 0
+        self._update_cursor_x()
 
     def move_pagedown(self):
-        if len(self._lines) - self._spot.y > (self.view_height - 1):
+        if len(self._lines) - self._cursor.y > (self.view_height - 1):
             self.emit('scrollreq', (self.view_height - 1))
-            self._spot.y += self.view_height - 1
+            self._cursor.y += self.view_height - 1
         else:
-            self._spot.y = len(self._lines) - 1
-        self._update_spot_x()
+            self._cursor.y = len(self._lines) - 1
+        self._update_cursor_x()
 
     def move_top(self):
-        self._spot.y = 0
-        self._update_spot_x()
+        self._cursor.y = 0
+        self._update_cursor_x()
 
     def move_bottom(self):
-        self._spot.y = len(self._lines) - 1
-        self._update_spot_x()
+        self._cursor.y = len(self._lines) - 1
+        self._update_cursor_x()
 
     def add_char(self, c):
         ln = self.cur_line
-        sx = self._spot.x
+        sx = self._cursor.x
         self.cur_line = ln[:sx] + c + ln[sx:]
         self.cursor_column = sx
 
     def add_newline(self, move=False):
         ln = self.cur_line
-        sx = self._spot.x
+        sx = self._cursor.x
         self.cur_line = ln[sx:]
-        self._lines.insert(self._spot.y, ln[:sx])
-        self._default_size.update(h=len(self._lines))
+        self._lines.insert(self._cursor.y, ln[:sx])
+        self.sizereq.update(h=len(self._lines))
         if move:
             self.move_right()
 
     def add_line(self, text):
         ln = self.cur_line
-        sx = self._spot.x
+        sx = self._cursor.x
         self.cur_line = ln[sx:]
-        self._lines.insert(self._spot.y, ln[:sx] + text)
+        self._lines.insert(self._cursor.y, ln[:sx] + text)
         self.cursor_column = 0
-        self._spot.x = 0
-        self._spot.y += 1
-        w = max(self._default_size.w, len(ln[:sx] + text))
-        self._default_size.update(w=w, h=len(self._lines))
+        self._cursor.x = 0
+        self._cursor.y += 1
+        w = max(self.sizereq.w, len(ln[:sx] + text))
+        self.sizereq.update(w=w, h=len(self._lines))
 
     def backspace(self):
-        if self._spot.y > 0 or self._spot.x > 0:
+        if self._cursor.y > 0 or self._cursor.x > 0:
             self.move_left()
             self.del_char()
 
     def del_char(self):
         ln = self.cur_line
-        sx = self._spot.x
+        sx = self._cursor.x
         if sx == len(self.cur_line):
-            if self._spot.y + 1 < len(self._lines):
-                self.cur_line += self._lines[self._spot.y+1]
-                del self._lines[self._spot.y+1]
-                self._default_size.update(h=len(self._lines))
+            if self._cursor.y + 1 < len(self._lines):
+                self.cur_line += self._lines[self._cursor.y+1]
+                del self._lines[self._cursor.y+1]
+                self.sizereq.update(h=len(self._lines))
         else:
             self.cur_line = ln[:sx] + ln[sx+1:]
 
-    def _update_spot_x(self):
+    def _update_cursor_x(self):
         if self.cursor_column > len(self.cur_line):
-            self._spot.x = len(self.cur_line)
+            self._cursor.x = len(self.cur_line)
         else:
-            self._spot.x = self.cursor_column
+            self._cursor.x = self.cursor_column
 
--- a/tuikit/widgets/textfield.py	Wed Sep 03 19:14:43 2014 +0200
+++ b/tuikit/widgets/textfield.py	Wed Sep 03 19:17:04 2014 +0200
@@ -21,6 +21,8 @@
         self.curspos = len(value)      # position of cursor in value
         self.ofs = 0      # position of value beginning on screen
 
+        self._cursor_visible = True
+
     def resize(self, w, h):
         self.tw = self.width - 2
 
@@ -43,7 +45,7 @@
                 c = '>'
             buffer.putch(c, self.width-1, 0)
 
-            self._cursor = (1 + self.curspos - self.ofs, 0)
+            self._cursor.update(1 + self.curspos - self.ofs, 0)
 
     def keypress_event(self, ev):
         consumed = True