File: viewport_toolbar.py

package info (click to toggle)
python-enable 4.3.0-2
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 7,280 kB
  • ctags: 13,899
  • sloc: cpp: 48,447; python: 28,502; ansic: 9,004; makefile: 315; sh: 44
file content (107 lines) | stat: -rw-r--r-- 3,611 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107

from __future__ import with_statement

# Library imports

# Enthought Library imports
from enable.api import AbstractOverlay, Container, ColorTrait
from enable.font_metrics_provider import font_metrics_provider
from traits.api import Enum, Bool, Float, Int, Type, List

# Local imports
from toolbar_buttons import Button

class ViewportToolbar(Container, AbstractOverlay):
    """
    ViewportToolbar is a toolbar that is attached to the top of a viewport on
    the block canvas.
    """

    button_spacing = Int(5)

    button_vposition = Int(6)

    always_on = Bool(True)

    toolbar_height = Float(30.0)

    order = Enum("left-to-right", "right-to-left")

    buttons = List(Type(Button))

    # Override default values for inherited traits
    auto_size = False

    bgcolor = ColorTrait((0.5, 0.5, 0.5, 0.25))

    def __init__(self, component=None, *args, **kw):
        # self.component should be a CanvasViewport
        self.component = component
        for buttontype in self.buttons:
            self.add_button(buttontype())
        super(ViewportToolbar, self).__init__(*args, **kw)

    def _do_layout(self, component=None):
        if component is None:
            component = self.component

        if component is not None:
            self.x = component.x
            # FIXME: Adding 2 to the self.y because there is a tiny gap
            # at the top of the toolbar where components from the block
            # canvas show through.
            self.y = component.y2 - self.toolbar_height + 2
            self.height = self.toolbar_height
            self.width = component.width

        metrics = font_metrics_provider()
        if self.order == "right-to-left":
            last_button_position = self.width - self.button_spacing
            for b in self.components:
                x, y, w, h = metrics.get_text_extent(b.label)
                b.width = w + 2*b.label_padding
                b.x = last_button_position - b.width
                b.y = self.button_vposition
                last_button_position -= b.width + self.button_spacing*2
        else:
            last_button_position = 0
            for b in self.components:
                x, y, w, h = metrics.get_text_extent(b.label)
                b.width = w + 2*b.label_padding
                b.x = self.button_spacing + last_button_position
                b.y = self.button_vposition
                last_button_position += b.width + self.button_spacing*2

    def overlay(self, other_component, gc, view_bounds=None, mode="normal"):
        c = other_component
        self.do_layout(component=c)
        with gc:
            gc.clip_to_rect(c.x, c.y, c.width, c.height)
            Container._draw(self, gc, view_bounds)
        return

    def add_button(self, button):
        self.add(button)
        button.toolbar_overlay = self
        self._layout_needed = True
        return


class HoverToolbar(ViewportToolbar):

    # This is sort of a hack to make the container handle events like a plain
    # container.  We also want this overlay to be "opaque", so that events
    # inside it don't continue propagating.
    def _dispatch_stateful_event(self, event, suffix):
        Container._dispatch_stateful_event(self, event, suffix)
        if not event.handled:
            if self.is_in(event.x, event.y):
                event.handled = True
        return

    def _container_handle_mouse_event(self, event, suffix):
        if not self.is_in(event.x, event.y) and self.component.auto_hide:
            self.component.remove_toolbar()
            self.component.request_redraw()
        return