Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWalter Bender <walter.bender@gmail.com>2012-10-22 18:32:43 (GMT)
committer Walter Bender <walter.bender@gmail.com>2012-10-22 18:32:43 (GMT)
commit27ac686726234ec6a6f5cc15e93ce534b069958f (patch)
tree657fc0af8ee12e4afcd3a552b95bc6c8b307e669
parent516c2ce16eae08a8cbe2b353037d9625545a57df (diff)
add support for on-screen keyboard
-rw-r--r--PortfolioActivity.py215
1 files changed, 70 insertions, 145 deletions
diff --git a/PortfolioActivity.py b/PortfolioActivity.py
index 220849c..a7a2430 100644
--- a/PortfolioActivity.py
+++ b/PortfolioActivity.py
@@ -101,29 +101,6 @@ MIDDLE = 2
BOTTOM = 1
HIDE = 0
-DEAD_KEYS = ['grave', 'acute', 'circumflex', 'tilde', 'diaeresis', 'abovering']
-DEAD_DICTS = [{'A': 192, 'E': 200, 'I': 204, 'O': 210, 'U': 217, 'a': 224,
- 'e': 232, 'i': 236, 'o': 242, 'u': 249},
- {'A': 193, 'E': 201, 'I': 205, 'O': 211, 'U': 218, 'a': 225,
- 'e': 233, 'i': 237, 'o': 243, 'u': 250},
- {'A': 194, 'E': 202, 'I': 206, 'O': 212, 'U': 219, 'a': 226,
- 'e': 234, 'i': 238, 'o': 244, 'u': 251},
- {'A': 195, 'O': 211, 'N': 209, 'U': 360, 'a': 227, 'o': 245,
- 'n': 241, 'u': 361},
- {'A': 196, 'E': 203, 'I': 207, 'O': 211, 'U': 218, 'a': 228,
- 'e': 235, 'i': 239, 'o': 245, 'u': 252},
- {'A': 197, 'a': 229}]
-NOISE_KEYS = ['Shift_L', 'Shift_R', 'Control_L', 'Caps_Lock', 'Pause',
- 'Alt_L', 'Alt_R', 'KP_Enter', 'ISO_Level3_Shift', 'KP_Divide',
- 'Escape', 'Return', 'KP_Page_Up', 'Up', 'Down', 'Menu',
- 'Left', 'Right', 'KP_Home', 'KP_End', 'KP_Up', 'Super_L',
- 'KP_Down', 'KP_Left', 'KP_Right', 'KP_Page_Down', 'Scroll_Lock',
- 'Page_Down', 'Page_Up']
-WHITE_SPACE = ['space', 'Tab']
-
-CURSOR = '█'
-NEWLINE = '\n'
-
class Slide():
''' A container for a slide '''
@@ -209,16 +186,32 @@ class PortfolioActivity(activity.Activity):
self._setup_presence_service()
+ def _fixed_resize_cb(self, widget=None, rect=None):
+ ''' If a toolbar opens or closes, we need to resize the vbox
+ holding out scrolling window. '''
+ self.vbox.set_size_request(rect.width, rect.height)
+
def _setup_canvas(self):
''' Create a canvas '''
+ self.fixed = Gtk.Fixed()
+ self.fixed.connect('size-allocate', self._fixed_resize_cb)
+ self.fixed.show()
+ self.set_canvas(self.fixed)
+
+ self.vbox = Gtk.VBox(False, 0)
+ self.vbox.set_size_request(
+ Gdk.Screen.width(), Gdk.Screen.height() - style.GRID_CELL_SIZE)
+ self.fixed.put(self.vbox, 0, 0)
+ self.vbox.show()
+
self._canvas = Gtk.DrawingArea()
self._canvas.set_size_request(int(Gdk.Screen.width()),
int(Gdk.Screen.height()))
self._canvas.show()
- self.set_canvas(self._canvas)
self.show_all()
+ self.vbox.pack_end(self._canvas, True, True, 0)
+ self.vbox.show()
- #self._canvas.set_flags(Gtk.CAN_FOCUS)
self._canvas.add_events(Gdk.EventMask.BUTTON_PRESS_MASK)
self._canvas.add_events(Gdk.EventMask.POINTER_MOTION_MASK)
self._canvas.add_events(Gdk.EventMask.BUTTON_RELEASE_MASK)
@@ -229,7 +222,7 @@ class PortfolioActivity(activity.Activity):
self._canvas.connect('button-release-event', self._button_release_cb)
self._canvas.connect('motion-notify-event', self._mouse_move_cb)
self._canvas.connect('key-press-event', self._keypress_cb)
- self._canvas.connect('configure-event', self._configure_cb)
+ # self._canvas.connect('configure-event', self._configure_cb)
self._canvas.grab_focus()
@@ -653,7 +646,6 @@ class PortfolioActivity(activity.Activity):
self._title.hide()
self._preview.hide()
self._description.hide()
- self.invalt(0, 0, self._width, self._height)
# Reset drag settings
self._press = None
@@ -834,7 +826,7 @@ class PortfolioActivity(activity.Activity):
# Create the cairo context
cr = self.canvas.props.window.cairo_create()
- # Restrict Cairo to the drawd area; avoid extra work
+ # Restrict Cairo to the drawn area; avoid extra work
cr.rectangle(allocation.x, allocation.y,
allocation.width, allocation.height)
cr.clip()
@@ -856,11 +848,11 @@ class PortfolioActivity(activity.Activity):
''' Hide the sugar3 toolbars. '''
self.fullscreen()
- def invalt(self, x, y, w, h):
- ''' Mark a region for refresh '''
- rect = Gdk.Rectangle()
- rect.x, rect.y, rect.width, rect.height = x, y, w, h
- self._canvas.props.window.invalidate_rect(rect, False)
+ def _text_focus_out_cb(self, widget=None, event=None):
+ bounds = self.text_entry.get_buffer().get_bounds()
+ s = self.text_entry.get_buffer().get_text(bounds[0], bounds[1], True)
+ self._selected_spr.set_label(s)
+ self._saved_string = self._selected_spr.labels[0]
def _button_press_cb(self, win, event):
''' The mouse button was pressed. Is it on a thumbnail sprite? '''
@@ -885,17 +877,40 @@ class PortfolioActivity(activity.Activity):
self._saved_string = spr.labels[0]
if spr.type == 'description':
if self.initiating is not None and not self.initiating:
- label = '%s\n[%s] %s' % (self._selected_spr.labels[0],
- profile.get_nick_name(), CURSOR)
+ label = '%s\n[%s] ' % (self._selected_spr.labels[0],
+ profile.get_nick_name())
else:
- label = '%s%s' % (self._selected_spr.labels[0], CURSOR)
+ label = self._selected_spr.labels[0]
self._selected_spr.set_label(label)
elif spr.type == 'title':
if self.initiating is None or self.initiating:
- label = '%s%s' % (self._selected_spr.labels[0], CURSOR)
+ label = self._selected_spr.labels[0]
self._selected_spr.set_label(label)
else:
self._selected_spr = None
+ if not hasattr(self, 'text_entry'):
+ self.text_entry = Gtk.TextView()
+ self.text_entry.set_justification(Gtk.Justification.CENTER)
+ self.text_entry.set_pixels_above_lines(4)
+ '''
+ NOTE: Use override_background_color in GTK3 port to set
+ transparent background.
+ '''
+ self.text_entry.override_background_color()
+ self.text_buffer = Gtk.TextBuffer()
+ self.fixed.put(self.text_entry, 0, 0)
+ self.text_entry.show()
+ self.text_buffer.set_text(self._saved_string)
+ self.text_entry.set_buffer(self.text_buffer)
+ w = spr.label_safe_width()
+ h = spr.label_safe_height()
+ self.text_entry.set_size_request(w, h)
+ bx, by = spr.get_xy()
+ mx, my = spr.label_left_top()
+ self.fixed.move(self.text_entry, bx + mx, by + my * 2)
+ self.fixed.show()
+ self.text_entry.connect('focus-out-event', self._text_focus_out_cb)
+ self.text_entry.grab_focus()
else:
self._unselect()
@@ -1185,8 +1200,6 @@ class PortfolioActivity(activity.Activity):
if alt_mask:
if keyname == 'q':
exit()
- elif self._selected_spr is not None:
- self.process_alphanumeric_input(keyname, keyunicode)
elif not self._thumbnail_mode:
if keyname == 'Home':
self._first_cb()
@@ -1198,114 +1211,26 @@ class PortfolioActivity(activity.Activity):
self._last_cb()
return True
- def process_alphanumeric_input(self, keyname, keyunicode):
- ''' Make sure alphanumeric input is properly parsed. '''
- if len(self._selected_spr.labels[0]) > 0:
- c = self._selected_spr.labels[0].count(CURSOR)
- if c == 0:
- oldleft = self._selected_spr.labels[0]
- oldright = ''
- elif len(self._selected_spr.labels[0]) == 1:
- oldleft = ''
- oldright = ''
- elif CURSOR in self._selected_spr.labels[0]:
- oldleft, oldright = \
- self._selected_spr.labels[0].split(CURSOR)
- else: # Where did our cursor go?
- oldleft = self._selected_spr.labels[0]
- oldright = ''
- else:
- oldleft = ''
- oldright = ''
- newleft = oldleft
- if keyname in ['Shift_L', 'Shift_R', 'Control_L', 'Caps_Lock', \
- 'Alt_L', 'Alt_R', 'KP_Enter', 'ISO_Level3_Shift']:
- keyname = ''
- keyunicode = 0
- # Hack until I sort out input and unicode and dead keys,
- if keyname[0:5] == 'dead_':
- self._dead_key = keyname
- keyname = ''
- keyunicode = 0
- if keyname == 'space':
- keyunicode = 32
- elif keyname == 'Tab':
- keyunicode = 9
- if keyname == 'BackSpace':
- if len(oldleft) > 1:
- newleft = oldleft[:len(oldleft) - 1]
- else:
- newleft = ''
- if keyname == 'Delete':
- if len(oldright) > 0:
- oldright = oldright[1:]
- elif keyname == 'Home':
- oldright = oldleft + oldright
- newleft = ''
- elif keyname == 'Left':
- if len(oldleft) > 0:
- oldright = oldleft[len(oldleft) - 1:] + oldright
- newleft = oldleft[:len(oldleft) - 1]
- elif keyname == 'Right':
- if len(oldright) > 0:
- newleft = oldleft + oldright[0]
- oldright = oldright[1:]
- elif keyname == 'End':
- newleft = oldleft + oldright
- oldright = ''
- elif keyname == 'Return':
- newleft = oldleft + NEWLINE
- elif keyname == 'Down':
- if NEWLINE in oldright:
- parts = oldright.split(NEWLINE)
- newleft = oldleft + string.join(parts[0:2], NEWLINE)
- oldright = NEWLINE + string.join(parts[2:], NEWLINE)
- elif keyname == 'Up':
- if NEWLINE in oldleft:
- parts = oldleft.split(NEWLINE)
- newleft = string.join(parts[0:-1], NEWLINE)
- oldright = NEWLINE + parts[-1] + oldright
- elif keyname == 'Escape': # Restore previous state
- self._selected_spr.set_label(self._saved_string)
- self._unselect()
- return
- else:
- if self._dead_key is not '':
- keyunicode = \
- DEAD_DICTS[DEAD_KEYS.index(self._dead_key[5:])][keyname]
- self._dead_key = ''
- if keyunicode > 0:
- if unichr(keyunicode) != '\x00':
- newleft = oldleft + unichr(keyunicode)
- else:
- newleft = oldleft
- elif keyunicode == -1: # clipboard text
- if keyname == NEWLINE:
- newleft = oldleft + NEWLINE
- else:
- newleft = oldleft + keyname
- self._selected_spr.set_label('%s%s%s' % (newleft, CURSOR, oldright))
-
def _unselect(self):
+ if hasattr(self, 'text_entry'):
+ self.text_entry.hide()
+
if self._selected_spr is not None:
- if CURSOR in self._selected_spr.labels[0]:
- parts = self._selected_spr.labels[0].split(CURSOR)
- self._selected_spr.set_label(string.join(parts))
- slide = self._slides[self.i]
- if self._selected_spr.type == 'title':
- slide.title = self._selected_spr.labels[0]
- if self.initiating is not None and self.initiating:
- self._send_event('t:%s' % (self._data_dumper(
- [slide.uid, slide.title])))
- else:
- slide.description = self._selected_spr.labels[0]
- if self.initiating is not None:
- self._send_event('d:%s' % (self._data_dumper(
- [slide.uid, slide.description])))
- _logger.debug('marking %d as dirty' % (self.i))
- slide.dirty = True
- self._selected_spr = None
- self._saved_string = ''
+ slide = self._slides[self.i]
+ if self._selected_spr.type == 'title':
+ slide.title = self._selected_spr.labels[0]
+ if self.initiating is not None and self.initiating:
+ self._send_event('t:%s' % (self._data_dumper(
+ [slide.uid, slide.title])))
+ else:
+ slide.description = self._selected_spr.labels[0]
+ if self.initiating is not None:
+ self._send_event('d:%s' % (self._data_dumper(
+ [slide.uid, slide.description])))
+ _logger.debug('marking %d as dirty' % (self.i))
+ slide.dirty = True
+ self._selected_spr = None
+ self._saved_string = ''
def _restore_cursor(self):
''' No longer waiting, so restore standard cursor. '''