#
#   Python GUI - Components - Gtk
#

import gtk
from Geometry import sub_pt
from GComponents import Component as GComponent

_gtk_widget_to_component = {}

#------------------------------------------------------------------------------

class Component(GComponent):

    def __init__(self, _gtk_outer, _gtk_inner = None, **kwds):
        self._position = (0, 0)
        self._size = _gtk_outer.size_request()
        self._gtk_outer_widget = _gtk_outer
        self._gtk_inner_widget = _gtk_inner or _gtk_outer
        _gtk_widget_to_component[_gtk_outer] = self
        GComponent.__init__(self, **kwds)
    
    def destroy(self):
        gtk_widget = self._gtk_outer_widget
        if gtk_widget in _gtk_widget_to_component:
            del _gtk_widget_to_component[gtk_widget]
        GComponent.destroy(self)
    
    #
    #		Properties
    #

    def set_width(self, v):
        w, h = self.size
        self.size = (v, h)

    def set_height(self, v):
        w, h = self.size
        self.size = (w, v)

    def get_position(self):
        return self._position

    def set_position(self, v):
        self._position = v
        widget = self._gtk_outer_widget
        parent = widget.get_parent()
        if parent:
            parent.move(widget, *v)
        
    def get_size(self):
        return self._size

    def set_size(self, new_size):
        w, h = new_size
        self._gtk_outer_widget.set_size_request(max(w, 1), max(h, 1))
        self._size = new_size
    
    def get_bounds(self):
        x, y = self._position
        w, h = self.size
        return (x, y, x + w, y + h)

    def set_bounds(self, (l, t, r, b)):
        self.position = (l, t)
        self.size = (r - l, b - t)

    def get_visible(self):
        return self._gtk_outer_widget.get_property('visible')
    
    def set_visible(self, v):
        self._gtk_outer_widget.set_property('visible', v)
    
    #
    #   Message dispatching
    #

    def become_target(self):
        self._gtk_inner_widget.grab_focus()

    def current_target(self):
        """Find the current target object within the Window containing
        this component. If the component is not contained in a Window,
        the result is undefined."""
        target = _gtk_find_component(self._gtk_outer_widget.get_focus())
        if not target:
            target = self.window
        return target

    def is_target(self):
        """Return true if this is the current target within the containing
        Window. If the component is not contained in a Window, the result
        is undefined."""
        return self == self.current_target()
    
    #
    #   Internal
    #
    
    def _gtk_connect(self, gtk_widget, signal, handler):
        gtk_widget.connect(signal, lambda widget, *args: handler(*args))

    def _gtk_connect_after(self, gtk_widget, signal, handler):
        gtk_widget.connect_after(signal, lambda widget, *args: handler(*args))

#------------------------------------------------------------------------------

def _gtk_find_component(gtk_widget):
    while gtk_widget:
        component = _gtk_widget_to_component.get(gtk_widget)
        if component:
            return component
        gtk_widget = gtk_widget.get_parent()
    return None
