[orca/introspection] Braille Monitor improvements:
- From: Joanmarie Diggs <joanied src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [orca/introspection] Braille Monitor improvements:
- Date: Tue, 23 Aug 2011 15:12:39 +0000 (UTC)
commit 26761a0e257b97286c0553010ba4a9048960fa58
Author: Joanmarie Diggs <joanmarie diggs gmail com>
Date: Tue Aug 23 11:07:45 2011 -0400
Braille Monitor improvements:
* Complete introspection
* Use the new GtkGrid to replace the deprecated HBox
* General code cleanup
* Display dots 7 and dots 8 as dots 7 and dots 8 rather than use
some semi-arbitrarily=chosen pango underline types
* Make the cells clickable so that sighted developers without
refreshable braille displays can simulate/test/work on cursor
routing. (I'll do panning and other traditional display features
post-introspection completion.)
src/orca/brlmon.py | 250 +++++++++++++++++++++++++++++++++-------------------
1 files changed, 160 insertions(+), 90 deletions(-)
---
diff --git a/src/orca/brlmon.py b/src/orca/brlmon.py
index ca621ee..3a15fae 100644
--- a/src/orca/brlmon.py
+++ b/src/orca/brlmon.py
@@ -1,6 +1,8 @@
+# -*- coding: utf-8 -*-
# Orca
#
# Copyright 2006-2008 Sun Microsystems Inc.
+# Copyright 2011 The Orca Team.
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
@@ -17,84 +19,189 @@
# Free Software Foundation, Inc., Franklin Street, Fifth Floor,
# Boston MA 02110-1301 USA.
-"""Provides a graphical braille display at the top of the screen.
-This is mainly for debugging and for demonstrations."""
+"""Provides a graphical braille display, mainly for development tasks."""
__id__ = "$Id$"
__version__ = "$Revision$"
__date__ = "$Date$"
-__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc."
+__copyright__ = "Copyright (c) 2005-2008 Sun Microsystems Inc." \
+ "Copyright (c) 2011 The Orca Team."
__license__ = "LGPL"
+import brlapi
from gi.repository import Gtk
+import orca_state
+from input_event import BrailleEvent
+
# Attribute/Selection mask strings:
#
DOT_7 = '\x40' # 01000000
DOT_8 = '\x80' # 10000000
DOTS_78 = '\xc0' # 11000000
-
-# Markup strings:
-#
-NORMAL = " size='xx-large'"
-CURSOR_CELL_EMPTY = " background='black'" \
- + " weight='ultrabold'" \
- + " style='italic'"
+class BrlDot(Gtk.Alignment):
+ """A single braille dot."""
-CURSOR_CELL = " background='white'" \
- + " weight='ultrabold'" \
- + " style='italic'" \
+ MARKUP_NORMAL = '<tt><small>%s</small></tt>'
+ SYMBOL_LOWERED = u'\u25CB' # 'â'
+ SYMBOL_RAISED = u'\u25CF' # 'â'
-ATTRIBUTE_7 = " underline='low'"
+ def __init__(self, dotNumber, isRaised=False):
+ """Create a new BrlDot.
-ATTRIBUTE_8 = " underline='error'"
+ Arguments:
+ - dotNumber: an integer reflecting the location of the dot within
+ an 8-dot braille cell, using traditional braille dot values.
+ """
-ATTRIBUTE_78 = " underline='double'"
+ Gtk.Alignment.__init__(self)
+ if dotNumber in [1, 2, 3, 7]:
+ self.set(1.0, 0.5, 0.0, 0.0)
+ self.set_padding(0, 0, 3, 0)
+ else:
+ self.set(0.0, 0.5, 0.0, 0.0)
+ self.set_padding(0, 0, 0, 3)
-class BrlMon(Gtk.Window):
+ self.label = Gtk.Label()
+ self.add(self.label)
+ if isRaised:
+ self.raiseDot()
+ else:
+ self.lowerDot()
+
+ def raiseDot(self):
+ self.set(0.5, 0.5, 0, 0)
+ self.label.set_markup(self.MARKUP_NORMAL % self.SYMBOL_RAISED)
+
+ def lowerDot(self):
+ self.set(0.5, 0.5, 0, 0)
+ self.label.set_markup(self.MARKUP_NORMAL % self.SYMBOL_LOWERED)
+
+class BrlCell(Gtk.Grid):
+ """A single graphical braille cell with cursor routing capability."""
+
+ MARKUP_NORMAL = '<tt><big>%s</big></tt>'
+ MARKUP_CURSOR_CELL = '<b><u>%s</u></b>'
+
+ def __init__(self, position):
+ """Create a new BrlCell.
+
+ Arguments:
+ - position: The location of the cell with respect to the monitor.
+ """
+
+ Gtk.Grid.__init__(self)
+ self._position = position
+
+ # For now, we display the char in print, like we always have. Use
+ # (merge) dots 1-6 for this purpose. Also make the button a means
+ # by which developers can work on cursor routing.
+ self._displayedChar = Gtk.Button()
+ self._displayedChar.set_size_request(30, 40)
+ self._displayedChar.add(Gtk.Label())
+ self.attach(self._displayedChar, 0, 0, 2, 3)
+ self._displayedChar.connect("clicked", self._onCellClicked)
+
+ # Create a more braille-like representation for dots 7-8 so that we
+ # do not have to remember/guess what pango underline type goes with
+ # what dot(s).
+ self.dot7 = BrlDot(7)
+ self.dot8 = BrlDot(8)
+ self.attach(self.dot7, 0, 3, 1, 1)
+ self.attach(self.dot8, 1, 3, 1, 1)
+
+ def _onCellClicked(self, widget):
+ """Callback for the 'clicked' signal on the push button. Synthesizes
+ a fake brlapi command to route the cursor to the current cell, similar
+ to what occurs when a user presses the cursor routing key on his/her
+ hardware braille display."""
+
+ if not orca_state.activeScript:
+ return
+
+ fakeKeyPress = {}
+ fakeKeyPress['command'] = brlapi.KEY_CMD_ROUTE
+ fakeKeyPress['argument'] = self._position
+ event = BrailleEvent(fakeKeyPress)
+ orca_state.activeScript.processRoutingKey(event)
+
+ def clear(self):
+ """Clears the braille cell."""
+
+ try:
+ label, = self._displayedChar.get_children()
+ except ValueError:
+ return
+
+ label.set_markup("")
+ self.dot7.lowerDot()
+ self.dot8.lowerDot()
- """Displays a GUI braille monitor that mirrors what is being
- shown on the braille display. This currently needs a lot of
- work, but it is a start. TODO's include doing a better job of
- docking it at the top of the display (e.g., make all other
- windows move out from underneath it), doing better highlighting of
- the cursor cell, allowing the font to be set, and perhaps allowing
- clicks to simulate cursor routing keys."""
+ def display(self, char, mask=None, isCursorCell=False):
+ """Displays the specified character in the cell.
- def __init__(self, numCells=32, cellWidth=25, cellHeight=50):
+ Arguments:
+ - char: The character to display in the cell.
+ - isCursorCell: If True, the cursor/caret is at this cell and this
+ should be indicated visually.
+ """
+
+ if char == '&':
+ char = '&'
+ elif char == '<':
+ char = '<'
+ elif char == '\t':
+ char = '$t'
+
+ markup = self.MARKUP_NORMAL
+ if isCursorCell:
+ markup = markup % self.MARKUP_CURSOR_CELL
+ label, = self._displayedChar.get_children()
+ label.set_markup(markup % char)
+
+ if mask in [DOT_7, DOTS_78]:
+ self.dot7.raiseDot()
+ if mask in [DOT_8, DOTS_78]:
+ self.dot8.raiseDot()
+
+class BrlMon(Gtk.Window):
+ """Displays a GUI braille monitor that mirrors what would be displayed
+ by Orca on a connected, configured, and enabled braille display. Cursor
+ routing functionality is emulated by each cell being a push button.
+ Panning and other functionality found on hardware braille displays will
+ be added."""
+
+ def __init__(self, numCells=32):
"""Create a new BrlMon.
Arguments:
- numCells: how many braille cells to make
- - cellWidth: width of each cell in pixels
- - cellHeight: height of each cell in pixels
"""
Gtk.Window.__init__(self)
self.set_title("Braille Monitor")
- self.set_size_request(cellWidth * numCells, cellHeight)
- hbox = Gtk.HBox(homogeneous=True)
- self.add(hbox)
- self.cellFrames = []
- self.cellLabels = []
- i = 0
- while (i < numCells):
- frame = Gtk.Frame()
- frame.set_shadow_type(Gtk.ShadowType.OUT)
- label = Gtk.Label(label=" ")
- label.set_use_markup(True)
- frame.add(label)
- hbox.add(frame)
- self.cellFrames.append(frame)
- self.cellLabels.append(label)
- i += 1
- self.set_property("accept-focus", False)
+ grid = Gtk.Grid()
+ self.add(grid)
+
+ self.cells = []
+ for i in range(numCells):
+ cell = BrlCell(i)
+ grid.attach(cell, i, 0, 1, 1)
+ self.cells.append(cell)
+
self.set_resizable(False)
+ self.set_property("accept-focus", False)
self.set_skip_taskbar_hint(True)
self.set_skip_pager_hint(True)
+ def clear(self):
+ """Clears the braille monitor display."""
+
+ for cell in self.cells:
+ cell.clear()
+
def writeText(self, cursorCell, string, mask=None):
"""Display the given text and highlight the given
cursor cell. A cursorCell of 0 means no cell has
@@ -105,55 +212,18 @@ class BrlMon(Gtk.Window):
- string: len must be <= num cells.
"""
- # Fill out the cells from the string.
- #
+ self.clear()
+
try:
string = string.decode("UTF-8")
except:
string = ""
- for i in range(0, len(string)):
-
- # Handle special chars so they are not interpreted by Pango.
- #
- if string[i] == "<":
- char = "<"
- elif string[i] == "&":
- char = "&"
- elif string[i] == "\t":
- char = "$t"
- else:
- char = string[i]
-
- markup = NORMAL
- if i == (cursorCell - 1):
- if string[i] == " ":
- markup += CURSOR_CELL_EMPTY
- else:
- markup += CURSOR_CELL
- self.cellFrames[i].set_shadow_type(
- Gtk.ShadowType.IN)
- else:
- self.cellFrames[i].set_shadow_type(
- Gtk.ShadowType.OUT)
-
+ length = min(len(string), len(self.cells))
+ for i in range(length):
+ isCursorCell = i == cursorCell - 1
try:
- if mask:
- if (mask[i] == DOTS_78):
- markup += ATTRIBUTE_78
- elif (mask[i] == DOT_7):
- markup += ATTRIBUTE_7
- elif (mask[i] == DOT_8):
- markup += ATTRIBUTE_8
- except:
- pass
-
- self.cellLabels[i].set_markup(
- "<span" + markup + ">%s</span>" % char)
-
- # Pad the rest
- #
- for i in range(len(string), len(self.cellFrames)):
- self.cellLabels[i].set_text(" ")
- self.cellFrames[i].set_shadow_type(
- Gtk.ShadowType.OUT)
+ cellMask = mask[i]
+ except IndexError:
+ cellMask = None
+ self.cells[i].display(string[i], cellMask, isCursorCell)
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]