Logo Search packages:      
Sourcecode: ibus version File versions

menu.py

# vim:set et sts=4 sw=4:
#
# ibus - The Input Bus
#
# Copyright (c) 2007-2008 Huang Peng <shawn.p.huang@gmail.com>
#
# This library is free software; you can redistribute it and/or
# modify it under the terms of the GNU Lesser General Public
# License as published by the Free Software Foundation; either
# version 2 of the License, or (at your option) any later version.
#
# This library is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Lesser General Public License for more details.
#
# You should have received a copy of the GNU Lesser General Public
# License along with this program; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330,
# Boston, MA  02111-1307  USA

import gtk
import gobject
import ibus
import icon
from propitem import PropItem

class Menu (gtk.Menu, PropItem):
    __gsignals__ = {
    "property-activate" : (
        gobject.SIGNAL_RUN_FIRST,
        gobject.TYPE_NONE,
        (gobject.TYPE_STRING, gobject.TYPE_INT)),
    }

    def __init__ (self, prop):
        gtk.Menu.__init__ (self)
        PropItem.__init__ (self, prop)

        self.set_take_focus (False)
        self.__create_items (self._prop.sub_props)
        self.show_all ()
        self.set_sensitive (prop.sensitive)

    def __create_items (self, props):
        radio_group = None

        for prop in props:
            if prop.type == ibus.PROP_TYPE_NORMAL:
                item = gtk.ImageMenuItem (prop)
            elif prop.type == ibus.PROP_TYPE_TOGGLE:
                item = CheckMenuItem (prop)
            elif prop.type == ibus.PROP_TYPE_RADIO:
                item = RadioMenuItem (radio_group, prop)
                radio_group = item
            elif prop.type == ibus.PROP_TYPE_SEPARATOR:
                item = SeparatorMenuItem ()
                radio_group = None
            elif prop.type == ibus.PROP_TYPE_MENU:
                item = gtk.ImageMenuItem (prop)
                item.set_submenu (Menu (prop))
            else:
                assert Fasle

            item.set_sensitive (prop.sensitive)
            if prop.visible:
                item.set_no_show_all (False)
                item.show ()
            else:
                item.set_no_show_all (True)
                item.hide ()

            item.connect ("property-activate", lambda w,n,s: self.emit ("property-activate", n, s))

            self.append (item)
            self._sub_items.append (item)

    def popup (self, button, active_time, widget):
        gtk.Menu.popup (self, None, None, menu_position,
                            button, active_time, widget)

    def _property_clicked (self, item, prop):
        pass


class ImageMenuItem (gtk.ImageMenuItem, PropItem):
    __gsignals__ = {
    "property-activate" : (
        gobject.SIGNAL_RUN_FIRST,
        gobject.TYPE_NONE,
        (gobject.TYPE_STRING, gobject.TYPE_INT)),
    }

    def __init__ (self, prop):
        gtk.ImageMenuItem.__init__ (self, label = prop.label)
        PropItem.__init__ (self, prop)

        if self._prop.icon:
            size = gtk.icon_size_lookup(gtk.ICON_SIZE_MENU)
            self.set_image (icon.IconWidget(prop.icon, size[0]))

        if self._prop.visible:
            self.set_no_show_all (False)
            self.show_all ()
        else:
            self.set_no_show_all (True)
            self.hide_all ()

    def do_activate (self):
        self.emit ("property-activate", self._prop.name, self._prop.state)

    def property_changed (self):
        self.set_sensitive (self._prop.sensitive)
        if self._prop.visible:
            self.set_no_show_all (False)
            self.show_all ()
        else:
            self.set_no_show_all (True)
            self.hide_all ()


class CheckMenuItem (gtk.CheckMenuItem, PropItem):
    __gsignals__ = {
    "property-activate" : (
        gobject.SIGNAL_RUN_FIRST,
        gobject.TYPE_NONE,
        (gobject.TYPE_STRING, gobject.TYPE_INT)),
    }

    def __init__ (self, prop):
        gtk.CheckMenuItem.__init__ (self, label = prop.label)
        PropItem.__init__ (self, prop)

        self.set_active (self._prop._state == ibus.PROP_STATE_CHECKED)

        if prop.visible:
            self.set_no_show_all (False)
            self.show_all ()
        else:
            self.set_no_show_all (True)
            self.hide_all ()

    def do_toggled (self):
        if self.get_active ():
            self._prop.state = ibus.PROP_STATE_CHECKED
        else:
            self._prop.state = ibus.PROP_STATE_UNCHECKED
        self.emit ("property-activate", self._prop.name, self._prop.state)

    def property_changed (self):
        self.set_active (self._prop.state == ibus.PROP_STATE_CHECKED)
        self.set_sensitive (self._prop.sensitive)
        if self._prop.visible:
            self.set_no_show_all (False)
            self.show_all ()
        else:
            self.set_no_show_all (True)
            self.hide_all ()


class RadioMenuItem (gtk.RadioMenuItem, PropItem):
    __gsignals__ = {
    "property-activate" : (
        gobject.SIGNAL_RUN_FIRST,
        gobject.TYPE_NONE,
        (gobject.TYPE_STRING, gobject.TYPE_INT)),
    }

    def __init__ (self, group, prop):
        gtk.RadioMenuItem.__init__ (self, group, label = prop.label)
        PropItem.__init__ (self, prop)

        self.set_active (self._prop.state == ibus.PROP_STATE_CHECKED)

        if prop.visible:
            self.set_no_show_all (False)
            self.show_all ()
        else:
            self.set_no_show_all (True)
            self.hide_all ()

    def property_changed (self):
        self.set_active (self._prop.state == ibus.PROP_STATE_CHECKED)
        self.set_sensitive (self._prop.sensitive)
        if self._prop.visible:
            self.set_no_show_all (False)
            self.show_all ()
        else:
            self.set_no_show_all (True)
            self.hide_all ()

    def do_toggled (self):
        if self.get_active ():
            self._prop.state = ibus.PROP_STATE_CHECKED
        else:
            self._prop.state = ibus.PROP_STATE_UNCHECKED
        self.emit ("property-activate", self._prop.name, self._prop.state)

class SeparatorMenuItem (gtk.SeparatorMenuItem, PropItem):
    __gsignals__ = {
    "property-activate" : (
        gobject.SIGNAL_RUN_FIRST,
        gobject.TYPE_NONE,
        (gobject.TYPE_STRING, gobject.TYPE_INT)),
    }


gobject.type_register (Menu, "IBusMenu")
gobject.type_register (ImageMenuItem, "IBusImageMenuItem")
gobject.type_register (CheckMenuItem, "IBusCheckMenuItem")
gobject.type_register (RadioMenuItem, "IBusRadioMenuItem")
gobject.type_register (SeparatorMenuItem, "IBusSeparatorMenuItem")

def menu_position (menu, button):
    screen = button.get_screen ()
    monitor = screen.get_monitor_at_window (button.window)
    monitor_allocation = screen.get_monitor_geometry (monitor)

    x, y = button.window.get_origin ()
    x += button.allocation.x
    y += button.allocation.y

    menu_width, menu_height = menu.size_request ()

    if x + menu_width >= monitor_allocation.width:
        x -= menu_width - button.allocation.width
    elif x - menu_width <= 0:
        pass
    else:
        if x <= monitor_allocation.width * 3 / 4:
            pass
        else:
            x -= menu_width - button.allocation.width

    if y + button.allocation.height + menu_height >= monitor_allocation.height:
        y -= menu_height
    elif y - menu_height <= 0:
        y += button.allocation.height
    else:
        if y <= monitor_allocation.height * 3 / 4:
            y += button.allocation.height
        else:
            y -= menu_height

    return (x, y, False)


Generated by  Doxygen 1.6.0   Back to index