Exemplo n.º 1
0
 def place(self, rect, containing_view):
     """Place this widget on a view.  """
     if self.viewport is None:
         if self.CREATES_VIEW:
             self.viewport = Viewport(self.view, rect)
             containing_view.addSubview_(self.view)
             wrappermap.add(self.view, self)
         else:
             self.viewport = BorrowedViewport(containing_view, rect)
         self.viewport_created()
     else:
         if not self.viewport.at_position(rect):
             self.viewport.reposition(rect)
             self.viewport_repositioned()
     self.emit('size-allocated', rect.size.width, rect.size.height)
Exemplo n.º 2
0
class Widget(signals.SignalEmitter):
    """Base class for Cocoa widgets.
    
    attributes:

    CREATES_VIEW -- Does the widget create a view for itself?  If this is True
    the widget must have an attribute named view, which is the view that the
    widget uses.

    placement -- What portion of view the widget occupies.
    """

    CREATES_VIEW = True 

    def __init__(self):
        threadcheck.confirm_ui_thread()
        signals.SignalEmitter.__init__(self)
        self.create_signal('key-press')
        self.create_signal('focus-out')
        self.create_signal('place-in-scroller')
        self.create_signal('size-request-changed', okay_to_nest=True)
        self.create_signal('size-allocated', okay_to_nest=True)
        self.viewport = None
        self.parent_is_scroller = False
        self.manual_size_request = None
        self.cached_size_request = None
        self._disabled = False

    def set_can_focus(self, allow):
        assert isinstance(self.view, NSControl)
        self.view.setRefusesFirstResponder_(not allow)

    def set_size_request(self, width, height):
        self.manual_size_request = (width, height)
        self.invalidate_size_request()

    def get_size_request(self):
        if self.manual_size_request:
            width, height = self.manual_size_request
            if width == -1:
                width = self.get_natural_size_request()[0]
            if height == -1:
                height = self.get_natural_size_request()[1]
            return width, height
        return self.get_natural_size_request()

    def get_natural_size_request(self):
        if self.cached_size_request:
            return self.cached_size_request
        else:
            self.cached_size_request = self.calc_size_request()
            return self.cached_size_request

    def invalidate_size_request(self):
        """Recalculate the size request for this widget."""
        old_size_request = self.get_size_request()
        self.cached_size_request = None
        self.emit('size-request-changed', old_size_request)

    def calc_size_request(self):
        """Return the minimum size needed to display this widget.
        Must be Implemented by subclasses.  
        """
        raise NotImplementedError()

    def _debug_size_request(self, nesting_level=0):
        """Debug size request calculations.

        This method recursively prints out the size request for each widget.
        """
        request = self.calc_size_request()
        width = int(request[0])
        height = int(request[1])
        indent = '    ' * nesting_level
        me = str(self.__class__).split('.')[-1]
        print '%s%s: %sx%s' % (indent, me, width, height)

    def place(self, rect, containing_view):
        """Place this widget on a view.  """
        if self.viewport is None:
            if self.CREATES_VIEW:
                self.viewport = Viewport(self.view, rect)
                containing_view.addSubview_(self.view)
                wrappermap.add(self.view, self)
            else:
                self.viewport = BorrowedViewport(containing_view, rect)
            self.viewport_created()
        else:
            if not self.viewport.at_position(rect):
                self.viewport.reposition(rect)
                self.viewport_repositioned()
        self.emit('size-allocated', rect.size.width, rect.size.height)

    def remove_viewport(self):
        if self.viewport is not None:
            self.viewport.remove()
            self.viewport = None
            if self.CREATES_VIEW:
                wrappermap.remove(self.view)

    def viewport_created(self):
        """Called after we first create a viewport.  Subclasses can override
        this method if they want to handle this event.
        """

    def viewport_repositioned(self):
        """Called when we reposition our viewport.  Subclasses can override
        this method if they want to handle this event.
        """

    def viewport_scrolled(self):
        """Called by the Scroller widget on it's child widget when it is
        scrolled.
        """

    def get_width(self):
        return int(self.viewport.get_width())
    width = property(get_width)

    def get_height(self):
        return int(self.viewport.get_height())
    height = property(get_height)

    def get_window(self):
        if not self.viewport.view:
            return None
        return wrappermap.wrapper(self.viewport.view.window())

    def queue_redraw(self):
        if self.viewport:
            self.viewport.queue_redraw()

    def redraw_now(self):
        if self.viewport:
            self.viewport.redraw_now()

    def relative_position(self, other_widget):
        """Get the position of another widget, relative to this widget."""
        basePoint = self.viewport.view.convertPoint_fromView_(
                other_widget.viewport.area().origin,
                other_widget.viewport.view)
        return (basePoint.x - self.viewport.area().origin.x,
                basePoint.y - self.viewport.area().origin.y)

    def make_color(self, (red, green, blue)):
        return NSColor.colorWithDeviceRed_green_blue_alpha_(red, green, blue, 
                1.0)
Exemplo n.º 3
0
Arquivo: base.py Projeto: cool-RR/Miro
class Widget(signals.SignalEmitter):
    """Base class for Cocoa widgets.
    
    attributes:

    CREATES_VIEW -- Does the widget create a view for itself?  If this is True
    the widget must have an attribute named view, which is the view that the
    widget uses.

    placement -- What portion of view the widget occupies.
    """

    CREATES_VIEW = True 

    def __init__(self):
        signals.SignalEmitter.__init__(self, 'size-request-changed',
                'size-allocated', 'key-press')
        self.viewport = None
        self.parent_is_scroller = False
        self.manual_size_request = None
        self.cached_size_request = None
        self._disabled = False

    def set_size_request(self, width, height):
        self.manual_size_request = (width, height)
        self.invalidate_size_request()

    def get_size_request(self):
        if self.manual_size_request:
            width, height = self.manual_size_request
            if width == -1:
                width = self.get_natural_size_request()[0]
            if height == -1:
                height = self.get_natural_size_request()[1]
            return width, height
        return self.get_natural_size_request()

    def get_natural_size_request(self):
        if self.cached_size_request:
            return self.cached_size_request
        else:
            self.cached_size_request = self.calc_size_request()
            return self.cached_size_request

    def invalidate_size_request(self):
        if hasattr(self, 'view') and self.view is not None:
            scroll_view = self.view.enclosingScrollView()
            if scroll_view is not None:
                scrolled_view = scroll_view.contentView()
                current_scroll_position = scrolled_view.bounds().origin
                self.do_invalidate_size_request()
                scrolled_view.scrollPoint_(current_scroll_position)
            else:
                self.do_invalidate_size_request()
        else:
            self.do_invalidate_size_request()

    def do_invalidate_size_request(self):
        """Recalculate the size request for this widget."""
        old_size_request = self.cached_size_request
        self.cached_size_request = None
        self.emit('size-request-changed', old_size_request)

    def calc_size_request(self):
        """Return the minimum size needed to display this widget.
        Must be Implemented by subclasses.  
        """
        raise NotImplementedError()

    def place(self, rect, containing_view):
        """Place this widget on a view.  """
        if self.viewport is None:
            if self.CREATES_VIEW:
                self.viewport = Viewport(self.view, rect)
                containing_view.addSubview_(self.view)
                wrappermap.add(self.view, self)
            else:
                self.viewport = BorrowedViewport(containing_view, rect)
            self.viewport_created()
        else:
            if not self.viewport.at_position(rect):
                self.viewport.reposition(rect)
                self.viewport_repositioned()
        self.emit('size-allocated', rect.size.width, rect.size.height)

    def remove_viewport(self):
        if self.viewport is not None:
            self.viewport.remove()
            self.viewport = None
            if self.CREATES_VIEW:
                wrappermap.remove(self.view)

    def create_view(self, rect):
        """Implemented by subclasses with CREATES_VIEW set.  It must return a
        NSView with a frame size equal to rect.
        """
        raise NotImplementedError("%s has CREATES_VIEW set, but doesn't implement create_view" % self.__class__)

    def viewport_created(self):
        """Called after we first create a viewport.  Subclasses can override
        this method if they want to handle this event.
        """

    def viewport_repositioned(self):
        """Called when we reposition our viewport.  Subclasses can override
        this method if they want to handle this event.
        """

    def viewport_scrolled(self):
        """Called by the Scroller widget on it's child widget when it is
        scrolled.
        """

    def get_width(self):
        return int(self.viewport.get_width())
    width = property(get_width)

    def get_height(self):
        return int(self.viewport.get_height())
    height = property(get_height)

    def get_window(self):
        if not self.viewport.view:
            return None
        return wrappermap.wrapper(self.viewport.view.window())

    def queue_redraw(self):
        if self.viewport:
            self.viewport.queue_redraw()

    def redraw_now(self):
        if self.viewport:
            self.viewport.redraw_now()

    def relative_position(self, other_widget):
        """Get the position of another widget, relative to this widget."""
        basePoint = self.viewport.view.convertPoint_fromView_(
                other_widget.viewport.area().origin,
                other_widget.viewport.view)
        return (basePoint.x - self.viewport.area().origin.x,
                basePoint.y - self.viewport.area().origin.y)

    def make_color(self, (red, green, blue)):
        return NSColor.colorWithDeviceRed_green_blue_alpha_(red, green, blue, 
                1.0)