From 27ac686726234ec6a6f5cc15e93ce534b069958f Mon Sep 17 00:00:00 2001 From: Walter Bender Date: Mon, 22 Oct 2012 18:32:43 +0000 Subject: add support for on-screen keyboard --- 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. ''' -- cgit v0.9.1