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 1529 2006-10-05 16:31:04Z wwalker $" |
24 |
1 |
__version__ = "$Revision: 1529 $" |
25 |
1 |
__date__ = "$Date: 2006-10-05 09:31:04 -0700 (Thu, 05 Oct 2006) $" |
26 |
1 |
__copyright__ = "Copyright (c) 2005-2006 Sun Microsystems Inc." |
27 |
1 |
__license__ = "LGPL" |
28 |
|
|
29 |
1 |
import gtk |
30 |
|
|
31 |
2 |
class BrlMon(gtk.Window): |
32 |
|
|
33 |
|
"""Displays a GUI braille monitor that mirrors what is being |
34 |
|
shown on the braille display. This currently needs a lot of |
35 |
|
work, but it is a start. TODO's include doing a better job of |
36 |
|
docking it at the top of the display (e.g., make all other |
37 |
|
windows move out from underneath it), doing better highlighting of |
38 |
|
the cursor cell, allowing the font to be set, and perhaps allowing |
39 |
|
clicks to simulate cursor routing keys.""" |
40 |
|
|
41 |
1 |
def __init__(self, numCells=32, cellWidth=25, cellHeight=50): |
42 |
|
"""Create a new BrlMon. |
43 |
|
|
44 |
|
Arguments: |
45 |
|
- numCells: how many braille cells to make |
46 |
|
- cellWidth: width of each cell in pixels |
47 |
|
- cellHeight: height of each cell in pixels |
48 |
|
""" |
49 |
|
|
50 |
0 |
gtk.Window.__init__(self, gtk.WINDOW_TOPLEVEL) |
51 |
0 |
self.set_title("Braille Monitor") |
52 |
0 |
self.set_default_size(cellWidth * numCells, cellHeight) |
53 |
0 |
hbox = gtk.HBox(True) |
54 |
0 |
self.add(hbox) |
55 |
0 |
self.cellFrames = [] |
56 |
0 |
self.cellLabels = [] |
57 |
0 |
for i in range(0, numCells): |
58 |
0 |
frame = gtk.Frame() |
59 |
0 |
frame.set_shadow_type(gtk.SHADOW_OUT) |
60 |
0 |
label = gtk.Label(" ") |
61 |
0 |
label.set_use_markup(True) |
62 |
0 |
frame.add(label) |
63 |
0 |
hbox.add(frame) |
64 |
0 |
self.cellFrames.append(frame) |
65 |
0 |
self.cellLabels.append(label) |
66 |
|
|
67 |
|
# This prevents it from getting focus. |
68 |
|
# |
69 |
0 |
self.set_property("accept-focus", False) |
70 |
0 |
self.connect_after("check-resize", self.onResize) |
71 |
|
|
72 |
1 |
def onResize(self, object): |
73 |
|
"""Tell the window to be a dock and set its struts, which I |
74 |
|
thinks means to attempt to glue it somewhere on the display. |
75 |
|
""" |
76 |
|
|
77 |
0 |
screen_width = gtk.gdk.screen_width() |
78 |
0 |
[window_width, window_height] = self.window.get_size() |
79 |
0 |
if window_width < screen_width: |
80 |
0 |
x = (screen_width - window_width) / 2 |
81 |
|
else: |
82 |
0 |
x = 0 |
83 |
|
|
84 |
0 |
self.window.set_type_hint(gtk.gdk.WINDOW_TYPE_HINT_DOCK) |
85 |
0 |
self.window.property_change( |
86 |
|
gtk.gdk.atom_intern("_NET_WM_STRUT_PARTIAL", False), |
87 |
0 |
gtk.gdk.atom_intern("CARDINAL", False), 32, |
88 |
0 |
gtk.gdk.PROP_MODE_REPLACE, |
89 |
0 |
[0, # LEFT |
90 |
|
0, # RIGHT |
91 |
|
window_height, # TOP |
92 |
|
0, # BOTTOM |
93 |
|
0, # LEFT_START |
94 |
|
0, # LEFT_END |
95 |
|
0, # RIGHT_START |
96 |
|
0, # RIGHT_END |
97 |
|
0, # TOP_START |
98 |
|
screen_width - 1, # TOP_END |
99 |
|
0, # BOTTOM_START |
100 |
|
0]) # BOTTOM_END |
101 |
|
|
102 |
0 |
self.move(x, 0) |
103 |
|
|
104 |
1 |
def writeText(self, cursorCell, string): |
105 |
|
"""Display the given text and highlight the given |
106 |
|
cursor cell. A cursorCell of 0 means no cell has |
107 |
|
the cursor. |
108 |
|
|
109 |
|
Arguments: |
110 |
|
- cursorCell: 1-based index of cell with cursor |
111 |
|
- string: len must be <= num cells. |
112 |
|
""" |
113 |
|
|
114 |
|
# Fill out the cells from the string. |
115 |
|
# |
116 |
0 |
try: |
117 |
0 |
string = string.decode("UTF-8") |
118 |
0 |
except: |
119 |
0 |
string = "" |
120 |
|
|
121 |
0 |
for i in range(0, len(string)): |
122 |
|
|
123 |
|
# Handle special chars so they are not interpreted by pango. |
124 |
|
# |
125 |
0 |
if string[i] == "<": |
126 |
0 |
char = "<" |
127 |
0 |
elif string[i] == "&": |
128 |
0 |
char = "&" |
129 |
|
else: |
130 |
0 |
char = string[i] |
131 |
|
|
132 |
0 |
if i == (cursorCell - 1): |
133 |
0 |
if string[i] == " ": |
134 |
0 |
self.cellLabels[i].set_markup( |
135 |
|
"<span"\ |
136 |
|
+ " background='black'" \ |
137 |
|
+ " weight='ultrabold'" \ |
138 |
|
+ " style='italic'"\ |
139 |
|
+ " size='xx-large'"\ |
140 |
|
+ ">%s</span>" \ |
141 |
|
% char) |
142 |
|
else: |
143 |
0 |
self.cellLabels[i].set_markup( |
144 |
|
"<span"\ |
145 |
|
+ " background='white'" \ |
146 |
|
+ " weight='ultrabold'" \ |
147 |
|
+ " style='italic'"\ |
148 |
|
+ " size='xx-large'"\ |
149 |
|
+ ">%s</span>" \ |
150 |
|
% char) |
151 |
0 |
self.cellFrames[i].set_shadow_type( |
152 |
|
gtk.SHADOW_IN) |
153 |
|
else: |
154 |
0 |
self.cellLabels[i].set_markup( |
155 |
|
"<span size='xx-large'>%s</span>" % char) |
156 |
0 |
self.cellFrames[i].set_shadow_type( |
157 |
|
gtk.SHADOW_OUT) |
158 |
|
|
159 |
|
# Pad the rest |
160 |
|
# |
161 |
0 |
for i in range(len(string), len(self.cellFrames)): |
162 |
0 |
self.cellLabels[i].set_text(" ") |
163 |
0 |
self.cellFrames[i].set_shadow_type( |
164 |
|
gtk.SHADOW_OUT) |