1 |
|
# Orca |
2 |
|
# |
3 |
|
# Copyright 2006 Sun Microsystems Inc. |
4 |
|
# |
5 |
|
# This library is free software; you can redistribute it and/or |
6 |
|
# modify it under the terms of the GNU Library General Public |
7 |
|
# License as published by the Free Software Foundation; either |
8 |
|
# version 2 of the License, or (at your option) any later version. |
9 |
|
# |
10 |
|
# This library is distributed in the hope that it will be useful, |
11 |
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of |
12 |
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 |
|
# Library General Public License for more details. |
14 |
|
# |
15 |
|
# You should have received a copy of the GNU Library General Public |
16 |
|
# License along with this library; if not, write to the |
17 |
|
# Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 |
|
# Boston, MA 02111-1307, USA. |
19 |
|
|
20 |
|
"""Provides a graphical braille display at the top of the screen. |
21 |
1 |
This is mainly for debugging and for demonstrations.""" |
22 |
|
|
23 |
1 |
__id__ = "$Id: brlmon.py 2520 2007-07-06 19:51:57Z joanied $" |
24 |
1 |
__version__ = "$Revision: 2520 $" |
25 |
1 |
__date__ = "$Date: 2007-07-06 15:51:57 -0400 (Fri, 06 Jul 2007) $" |
26 |
1 |
__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc." |
27 |
1 |
__license__ = "LGPL" |
28 |
|
|
29 |
1 |
import gtk |
30 |
|
|
31 |
|
# Attribute/Selection mask strings: |
32 |
|
# |
33 |
1 |
DOT_7 = '\x40' # 01000000 |
34 |
1 |
DOT_8 = '\x80' # 10000000 |
35 |
1 |
DOTS_78 = '\xc0' # 11000000 |
36 |
|
|
37 |
|
# Markup strings: |
38 |
|
# |
39 |
1 |
NORMAL = " size='xx-large'" |
40 |
|
|
41 |
|
CURSOR_CELL_EMPTY = " background='black'" \ |
42 |
|
+ " weight='ultrabold'" \ |
43 |
1 |
+ " style='italic'" |
44 |
|
|
45 |
|
CURSOR_CELL = " background='white'" \ |
46 |
|
+ " weight='ultrabold'" \ |
47 |
1 |
+ " style='italic'" \ |
48 |
|
|
49 |
1 |
ATTRIBUTE_7 = " underline='low'" |
50 |
|
|
51 |
1 |
ATTRIBUTE_8 = " underline='error'" |
52 |
|
|
53 |
1 |
ATTRIBUTE_78 = " underline='double'" |
54 |
|
|
55 |
2 |
class BrlMon(gtk.Window): |
56 |
|
|
57 |
|
"""Displays a GUI braille monitor that mirrors what is being |
58 |
|
shown on the braille display. This currently needs a lot of |
59 |
|
work, but it is a start. TODO's include doing a better job of |
60 |
|
docking it at the top of the display (e.g., make all other |
61 |
|
windows move out from underneath it), doing better highlighting of |
62 |
|
the cursor cell, allowing the font to be set, and perhaps allowing |
63 |
1 |
clicks to simulate cursor routing keys.""" |
64 |
|
|
65 |
1 |
def __init__(self, numCells=32, cellWidth=25, cellHeight=50): |
66 |
|
"""Create a new BrlMon. |
67 |
|
|
68 |
|
Arguments: |
69 |
|
- numCells: how many braille cells to make |
70 |
|
- cellWidth: width of each cell in pixels |
71 |
|
- cellHeight: height of each cell in pixels |
72 |
|
""" |
73 |
|
|
74 |
0 |
gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL) |
75 |
0 |
self.set_title("Braille Monitor") |
76 |
0 |
self.set_default_size(cellWidth * numCells, cellHeight) |
77 |
0 |
hbox = gtk.HBox(True) |
78 |
0 |
self.add(hbox) |
79 |
0 |
self.cellFrames = [] |
80 |
0 |
self.cellLabels = [] |
81 |
0 |
for i in range(0, numCells): |
82 |
0 |
frame = gtk.Frame() |
83 |
0 |
frame.set_shadow_type(gtk.SHADOW_OUT) |
84 |
0 |
label = gtk.Label(" ") |
85 |
0 |
label.set_use_markup(True) |
86 |
0 |
frame.add(label) |
87 |
0 |
hbox.add(frame) |
88 |
0 |
self.cellFrames.append(frame) |
89 |
0 |
self.cellLabels.append(label) |
90 |
|
|
91 |
|
# This prevents it from getting focus. |
92 |
|
# |
93 |
0 |
self.set_property("accept-focus", False) |
94 |
0 |
self.connect_after("check-resize", self.onResize) |
95 |
|
|
96 |
1 |
def onResize(self, object): |
97 |
|
"""Tell the window to be a dock and set its struts, which I |
98 |
|
thinks means to attempt to glue it somewhere on the display. |
99 |
|
""" |
100 |
|
|
101 |
0 |
screen_width = gtk.gdk.screen_width() |
102 |
0 |
[window_width, window_height] = self.window.get_size() |
103 |
0 |
if window_width < screen_width: |
104 |
0 |
x = (screen_width - window_width) / 2 |
105 |
|
else: |
106 |
0 |
x = 0 |
107 |
|
|
108 |
0 |
self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DOCK) |
109 |
0 |
self.window.property_change( |
110 |
0 |
gtk.gdk.atom_intern("_NET_WM_STRUT_PARTIAL", False), |
111 |
0 |
gtk.gdk.atom_intern("CARDINAL", False), 32, |
112 |
0 |
gtk.gdk.PROP_MODE_REPLACE, |
113 |
0 |
[0, # LEFT |
114 |
0 |
0, # RIGHT |
115 |
0 |
window_height, # TOP |
116 |
0 |
0, # BOTTOM |
117 |
0 |
0, # LEFT_START |
118 |
0 |
0, # LEFT_END |
119 |
0 |
0, # RIGHT_START |
120 |
0 |
0, # RIGHT_END |
121 |
0 |
0, # TOP_START |
122 |
0 |
screen_width - 1, # TOP_END |
123 |
0 |
0, # BOTTOM_START |
124 |
0 |
0]) # BOTTOM_END |
125 |
|
|
126 |
0 |
self.move(x, 0) |
127 |
|
|
128 |
1 |
def writeText(self, cursorCell, string, mask=None): |
129 |
|
"""Display the given text and highlight the given |
130 |
|
cursor cell. A cursorCell of 0 means no cell has |
131 |
|
the cursor. |
132 |
|
|
133 |
|
Arguments: |
134 |
|
- cursorCell: 1-based index of cell with cursor |
135 |
|
- string: len must be <= num cells. |
136 |
|
""" |
137 |
|
|
138 |
|
# Fill out the cells from the string. |
139 |
|
# |
140 |
0 |
try: |
141 |
0 |
string = string.decode("UTF-8") |
142 |
0 |
except: |
143 |
0 |
string = "" |
144 |
|
|
145 |
0 |
for i in range(0, len(string)): |
146 |
|
|
147 |
|
# Handle special chars so they are not interpreted by pango. |
148 |
|
# |
149 |
0 |
if string[i] == "<": |
150 |
0 |
char = "<" |
151 |
0 |
elif string[i] == "&": |
152 |
0 |
char = "&" |
153 |
|
else: |
154 |
0 |
char = string[i] |
155 |
|
|
156 |
0 |
markup = NORMAL |
157 |
0 |
if i == (cursorCell - 1): |
158 |
0 |
if string[i] == " ": |
159 |
0 |
markup += CURSOR_CELL_EMPTY |
160 |
|
else: |
161 |
0 |
markup += CURSOR_CELL |
162 |
0 |
self.cellFrames[i].set_shadow_type( |
163 |
0 |
gtk.SHADOW_IN) |
164 |
|
else: |
165 |
0 |
self.cellFrames[i].set_shadow_type( |
166 |
0 |
gtk.SHADOW_OUT) |
167 |
|
|
168 |
0 |
if mask: |
169 |
0 |
if (mask[i] == DOTS_78): |
170 |
0 |
markup += ATTRIBUTE_78 |
171 |
0 |
elif (mask[i] == DOT_7): |
172 |
0 |
markup += ATTRIBUTE_7 |
173 |
0 |
elif (mask[i] == DOT_8): |
174 |
0 |
markup += ATTRIBUTE_8 |
175 |
|
|
176 |
0 |
self.cellLabels[i].set_markup( |
177 |
0 |
"<span" + markup + ">%s</span>" % char) |
178 |
|
|
179 |
|
# Pad the rest |
180 |
|
# |
181 |
0 |
for i in range(len(string), len(self.cellFrames)): |
182 |
0 |
self.cellLabels[i].set_text(" ") |
183 |
0 |
self.cellFrames[i].set_shadow_type( |
184 |
0 |
gtk.SHADOW_OUT) |