Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(112)

Side by Side Diff: ui/gtk/languagebar.py

Issue 5517048: Merge the devel branch (Closed) Base URL: git@github.com:phuang/ibus.git@devel
Patch Set: Rebase on HEAD Created 13 years ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 # vim:set et sts=4 sw=4:
2 #
3 # ibus - The Input Bus
4 #
5 # Copyright(c) 2007-2010 Peng Huang <shawn.p.huang@gmail.com>
6 # Copyright(c) 2007-2010 Red Hat, Inc.
7 #
8 # This library is free software; you can redistribute it and/or
9 # modify it under the terms of the GNU Lesser General Public
10 # License as published by the Free Software Foundation; either
11 # version 2 of the License, or(at your option) any later version.
12 #
13 # This library is distributed in the hope that it will be useful,
14 # but WITHOUT ANY WARRANTY; without even the implied warranty of
15 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 # GNU Lesser General Public License for more details.
17 #
18 # You should have received a copy of the GNU Lesser General Public
19 # License along with this program; if not, write to the
20 # Free Software Foundation, Inc., 59 Temple Place, Suite 330,
21 # Boston, MA 02111-1307 USA
22
23 import gtk
24 import gtk.gdk as gdk
25 import gobject
26 import ibus
27 import icon
28 from handle import Handle
29 from menu import menu_position,\
30 ImageMenuItem,\
31 Menu,\
32 CheckMenuItem,\
33 RadioMenuItem,\
34 SeparatorMenuItem
35 from engineabout import EngineAbout
36 from toolitem import ToolButton,\
37 ToggleToolButton, \
38 SeparatorToolItem, \
39 MenuToolButton
40
41 from i18n import _, N_
42
43 ICON_SIZE = gtk.ICON_SIZE_MENU
44
45 class LanguageBar(gtk.Toolbar):
46 __gtype_name__ = "IBusLanguagePanel"
47 __gsignals__ = {
48 "property-activate" : (
49 gobject.SIGNAL_RUN_FIRST,
50 gobject.TYPE_NONE,
51 (gobject.TYPE_STRING, gobject.TYPE_INT)),
52 "get-im-menu" : (
53 gobject.SIGNAL_RUN_LAST,
54 gobject.TYPE_PYOBJECT,
55 ()),
56 "show-engine-about" : (
57 gobject.SIGNAL_RUN_LAST,
58 gobject.TYPE_PYOBJECT,
59 ()),
60 "position-changed" : (
61 gobject.SIGNAL_RUN_LAST,
62 gobject.TYPE_NONE,
63 (gobject.TYPE_INT, gobject.TYPE_INT)),
64 }
65
66 def __init__ (self):
67 super(LanguageBar, self).__init__()
68 self.__show = 0
69 self.__enabled = False
70 self.__has_focus = False
71 self.__show_im_name = False
72 self.__im_name = None
73 self.__props = None
74 self.__selected_menu_item = None
75 self.set_style(gtk.TOOLBAR_BOTH_HORIZ)
76 self.set_show_arrow(False)
77 self.set_property("icon-size", ICON_SIZE)
78 self.__create_ui()
79
80 self.__properties = []
81 self.__toplevel = gtk.Window(gtk.WINDOW_POPUP)
82 self.__toplevel.connect("size-allocate", self.__toplevel_size_allocate_c b)
83 self.__toplevel.add(self)
84 self.__screen = gdk.screen_get_default()
85 self.__screen.connect("size-changed", self.__screen_size_changed_cb)
86
87 self.set_position(-1, -1)
88
89 def __create_ui(self):
90 # create move handle
91 self.__handle = gtk.ToolItem()
92 handle = Handle()
93 self.__handle.add(handle)
94 self.insert(self.__handle, -1)
95 handle.connect("move-end", self.__handle_move_end_cb)
96
97 # create input methods menu
98 # prop = ibus.Property(key = "", type = ibus.PROP_TYPE_TOGGLE, icon = "i bus", tooltip = _("Switch input method"))
99 self.__im_menu = gtk.ToggleToolButton()
100 self.__im_menu.set_homogeneous(False)
101 self.__im_menu.connect("toggled", self.__im_menu_toggled_cb)
102 self.insert(self.__im_menu, -1)
103
104 self.__about_button = gtk.ToolButton(gtk.STOCK_ABOUT)
105 self.__about_button.set_no_show_all(True)
106 self.__about_button.set_tooltip_text(_("About the input method"))
107 self.__about_button.connect("clicked", self.__about_button_clicked_cb)
108 self.insert(self.__about_button, -1)
109
110 def __screen_size_changed_cb(self, screen):
111 self.set_position(*self.__position)
112
113 def __im_menu_toggled_cb(self, widget):
114 if self.__im_menu.get_active():
115 menu = self.emit("get-im-menu")
116 menu.connect("deactivate", self.__im_menu_deactivate_cb)
117 menu.popup(None, None,
118 menu_position,
119 0,
120 gtk.get_current_event_time(),
121 widget)
122
123 def __about_button_clicked_cb(self, widget):
124 if self.__enabled:
125 self.emit("show-engine-about")
126
127 def __im_menu_deactivate_cb(self, menu):
128 self.__im_menu.set_active(False)
129
130 def __handle_move_end_cb(self, handle):
131 x, y = self.__toplevel.get_position()
132 w, h = self.__toplevel.get_size()
133 self.__position = x + w, y + h
134 self.emit("position-changed", *self.__position)
135
136 def __toplevel_size_allocate_cb(self, toplevel, allocation):
137 x, y = self.__position
138 w, h = self.__screen.get_width(), self.__screen.get_height()
139 if x >= w - 80 or True:
140 self.__toplevel.move(x - allocation.width, y - allocation.height)
141
142 def __remove_properties(self):
143 # reset all properties
144 map(lambda i: i.destroy(), self.__properties)
145 self.__properties = []
146
147 def __set_opacity(self, opacity):
148 if self.__toplevel.window == None:
149 self.__toplevel.realize()
150 self.__toplevel.window.set_opacity(opacity)
151
152 def __replace_property(self, old_prop, new_prop):
153 old_prop.label = new_prop.label
154 old_prop.icon= new_prop.icon
155 old_prop.tooltip = new_prop.tooltip
156 old_prop.sensitive = new_prop.sensitive
157 old_prop.visible = new_prop.visible
158 old_prop.state = new_prop.state
159 old_prop.sub_props = new_prop.sub_props
160
161 def __label_select_cb(self, widget, data):
162 self.__selected_menu_item = widget
163
164 def __label_deselect_cb(self, widget, data):
165 self.__selected_menu_item = None
166
167 def __label_expose_cb(self, widget, event):
168 x = widget.allocation.x
169 y = widget.allocation.y
170 label = widget._prop.label.get_text()
171 if self.__selected_menu_item != widget:
172 gc = widget.style.fg_gc[gtk.STATE_NORMAL]
173 else:
174 gc = widget.style.bg_gc[gtk.STATE_NORMAL]
175 layout = widget.create_pango_layout(label)
176 widget.window.draw_layout(gc, x + 5, y + 2, layout)
177
178 def __set_item_icon(self, item, prop):
179 item.set_property("always-show-image", True)
180 if prop.icon:
181 size = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU)
182 item.set_image(icon.IconWidget(prop.icon, size[0]))
183 elif prop.label and prop.label.get_text() != "":
184 item.set_label("")
185 item.connect_after("expose-event", self.__label_expose_cb)
186 item.connect("select", self.__label_select_cb, None)
187 item.connect("deselect", self.__label_deselect_cb, None)
188 else:
189 size = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU)
190 item.set_image(icon.IconWidget("ibus", size[0]))
191
192 def do_show(self):
193 gtk.Toolbar.do_show(self)
194
195 def do_size_request(self, requisition):
196 gtk.Toolbar.do_size_request(self, requisition)
197 self.__toplevel.resize(1, 1)
198
199 def set_im_icon(self, icon_name):
200 widget = icon.IconWidget(icon_name, 18)
201 self.__im_menu.set_icon_widget(widget)
202
203 def set_show_im_name(self, show):
204 self.__show_im_name = show
205 self.set_im_name(self.__im_name)
206 self.__im_menu.set_is_important(show)
207
208 def set_im_name(self, text):
209 self.__im_name = text
210 if text:
211 self.__im_menu.set_tooltip_text(text)
212 self.__im_menu.set_label(text)
213 else:
214 self.__im_menu.set_tooltip_text(_("Switch input method"))
215 self.__im_menu.set_label("")
216
217 def reset(self):
218 self.__remove_properties()
219
220 def set_enabled(self, enabled):
221 self.__enabled = enabled
222 if self.__enabled:
223 self.__about_button.show()
224 self.__set_opacity(1.0)
225 if self.__has_focus:
226 if self.__show in (1, 2):
227 self.show_all()
228 else:
229 self.__about_button.hide()
230 self.__set_opacity(0.5)
231 if self.__show in (1, 0):
232 self.hide_all()
233
234 def is_enabled(self):
235 return self.__enabled
236
237 def set_show(self, show):
238 if show not in (0, 1, 2):
239 show = 0
240 self.__show = show
241 if self.__has_focus:
242 self.focus_in()
243 else:
244 self.focus_out()
245
246 def set_position(self, x, y):
247 w, h = self.__screen.get_width(), self.__screen.get_height()
248 if x < 0 or y < 0:
249 x = w - 20
250 y = h - 40
251 if x > w:
252 x = w - 20
253 if y > h:
254 y = h - 40
255
256 self.__position = x, y
257 w, h = self.__toplevel.get_size()
258 self.__toplevel.move(self.__position[0] - w, self.__position[1] - h)
259
260 def get_show(self):
261 return self.__show
262
263 def register_properties(self, props):
264 self.__props = props
265 if self.__show == 0:
266 return
267 # refresh items on labguage bar
268 self.__remove_properties()
269 # create new properties
270 for i, prop in enumerate(props):
271 if prop.type == ibus.PROP_TYPE_NORMAL:
272 item = ToolButton(prop = prop)
273 elif prop.type == ibus.PROP_TYPE_TOGGLE:
274 item = ToggleToolButton(prop = prop)
275 elif prop.type == ibus.PROP_TYPE_MENU:
276 item = MenuToolButton(prop = prop)
277 elif prop.type == ibus.PROP_TYPE_SEPARATOR:
278 item = SeparatorToolItem()
279 else:
280 raise IBusException("Unknown property type = %d" % prop.type)
281
282 item.connect("property-activate",
283 lambda w, n, s: self.emit("property-activate", n, s))
284
285 item.set_sensitive(prop.sensitive)
286
287 item.set_no_show_all(True)
288
289 if prop.visible:
290 item.show()
291 else:
292 item.hide()
293
294 self.__properties.append(item)
295 self.insert(item, i + 2)
296
297 def update_property(self, prop):
298 if self.__show == 0 and self.__props:
299 list = self.__props.get_properties()
300 for i, p in enumerate(list):
301 if p.key == prop.key and p.type == prop.type:
302 self.__replace_property(p, prop)
303 break
304 map(lambda x: x.update_property(prop), self.__properties)
305
306 def show_all(self):
307 self.__toplevel.show_all()
308 self.__toplevel.window.raise_()
309 gtk.Toolbar.show_all(self)
310
311 def hide_all(self):
312 try:
313 self.__toplevel.window.lower()
314 self.__toplevel.window.hide_all()
315 except:
316 pass
317 x, y = self.__toplevel.get_position()
318 self.__toplevel.hide_all()
319 gtk.Toolbar.hide_all(self)
320
321 # save bar position
322 self.__toplevel.move(x, y)
323
324 def focus_in(self):
325 self.__has_focus = True
326 self.__im_menu.set_sensitive(True)
327 if (self.__show == 1 and self.__enabled) or self.__show == 2:
328 self.show_all()
329 else:
330 self.hide_all()
331
332 def focus_out(self):
333 self.__has_focus = False
334 self.__im_menu.set_sensitive(False)
335 if self.__show == 2:
336 self.show_all()
337 else:
338 self.hide_all()
339
340 def create_im_menu(self, menu):
341 if not self.__enabled:
342 return
343 if self.__show != 0:
344 return
345 if not menu:
346 assert False
347 props = self.__props
348 if not props:
349 return
350
351 self.__remove_properties()
352 item = SeparatorMenuItem()
353 item.show()
354 self.__properties.append(item)
355 menu.insert(item, 0)
356
357 about_label = _("About") + " - " + self.__im_name
358 prop = ibus.Property(key=u"about",
359 label=unicode(about_label),
360 icon=unicode(gtk.STOCK_ABOUT),
361 tooltip=unicode(_("About the Input Method")))
362 item = ImageMenuItem(prop = prop)
363 item.set_property("always-show-image", True)
364 item.set_no_show_all(True)
365 item.show()
366 self.__properties.append(item)
367 menu.insert(item, 0)
368 item.connect("property-activate",
369 lambda w, n, s: self.emit("show-engine-about"))
370
371 list = props.get_properties()
372 list.reverse()
373 radio_group = None
374
375 for i, prop in enumerate(list):
376 if prop.type == ibus.PROP_TYPE_NORMAL:
377 item = ImageMenuItem(prop = prop)
378 self.__set_item_icon(item, prop)
379 elif prop.type == ibus.PROP_TYPE_TOGGLE:
380 item = CheckMenuItem(prop = prop)
381 elif prop.type == ibus.PROP_TYPE_RADIO:
382 item = RadioMenuItem(radio_group, prop = prop)
383 radio_group = item
384 elif prop.type == ibus.PROP_TYPE_SEPARATOR:
385 item = SeparatorMenuItem()
386 radio_group = None
387 elif prop.type == ibus.PROP_TYPE_MENU:
388 item = ImageMenuItem(prop = prop)
389 self.__set_item_icon(item, prop)
390 submenu = Menu(prop)
391 item.set_submenu(submenu)
392 submenu.connect("property-activate",
393 lambda w, n, s: self.emit("property-activate", n , s))
394 else:
395 raise IBusException("Unknown property type = %d" % prop.type)
396
397 item.set_sensitive(prop.sensitive)
398
399 item.set_no_show_all(True)
400
401 if prop.visible:
402 item.show()
403 else:
404 item.hide()
405
406 self.__properties.append(item)
407 menu.insert(item, 0)
408
409 item.connect("property-activate",
410 lambda w, n, s: self.emit("property-activate", n, s))
411
OLDNEW
« src/tests/ibus-bus.c ('K') | « ui/gtk/icon.py ('k') | ui/gtk/main.py » ('j') | no next file with comments »

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b