source: orange/Orange/OrangeCanvas/gui/toolbar.py @ 11425:c202b2d41718

Revision 11425:c202b2d41718, 3.4 KB checked in by Ales Erjavec <ales.erjavec@…>, 13 months ago (diff)

Fixed some sphinx warnings.

RevLine 
[11100]1"""
[11366]2A custom toolbar with linear uniform size layout.
[11100]3
4"""
5from __future__ import division
6
7import logging
8
[11179]9from PyQt4.QtGui import QToolBar
[11100]10
[11179]11from PyQt4.QtCore import Qt, QSize, QEvent
[11100]12
13log = logging.getLogger(__name__)
14
15
16class DynamicResizeToolBar(QToolBar):
[11366]17    """
18    A :class:`QToolBar` subclass that dynamically resizes its tool buttons
[11100]19    to fit available space (this is done by setting fixed size on the
20    button instances).
21
[11425]22    .. note:: the class does not support :class:`QWidgetAction` items,
23              separators, etc.
[11100]24
25    """
26
27    def __init__(self, parent=None, *args, **kwargs):
28        QToolBar.__init__(self, *args, **kwargs)
29
30    def resizeEvent(self, event):
31        QToolBar.resizeEvent(self, event)
32        size = event.size()
33        self.__layout(size)
34
35    def actionEvent(self, event):
36        QToolBar.actionEvent(self, event)
37        if event.type() == QEvent.ActionAdded or \
38                event.type() == QEvent.ActionRemoved:
39            self.__layout(self.size())
40
41    def sizeHint(self):
42        hint = QToolBar.sizeHint(self)
43        width, height = hint.width(), hint.height()
44        dx1, dy1, dw1, dh1 = self.getContentsMargins()
45        dx2, dy2, dw2, dh2 = self.layout().getContentsMargins()
46        dx, dy = dx1 + dx2, dy1 + dy2
47        dw, dh = dw1 + dw2, dh1 + dh2
48
49        count = len(self.actions())
50        spacing = self.layout().spacing()
51        space_spacing = max(count - 1, 0) * spacing
52
53        if self.orientation() == Qt.Horizontal:
54            width = int(height * 1.618) * count + space_spacing + dw + dx
55        else:
56            height = int(width * 1.618) * count + space_spacing + dh + dy
57        return QSize(width, height)
58
59    def __layout(self, size):
[11425]60        """
61        Layout the buttons to fit inside size.
[11100]62        """
63        mygeom = self.geometry()
64        mygeom.setSize(size)
65
66        # Adjust for margins (both the widgets and the layouts.
67        dx, dy, dw, dh = self.getContentsMargins()
68        mygeom.adjust(dx, dy, -dw, -dh)
69
70        dx, dy, dw, dh = self.layout().getContentsMargins()
71        mygeom.adjust(dx, dy, -dw, -dh)
72
73        actions = self.actions()
74        widgets = map(self.widgetForAction, actions)
75
76        orientation = self.orientation()
77        if orientation == Qt.Horizontal:
78            widgets = sorted(widgets, key=lambda w: w.pos().x())
79        else:
80            widgets = sorted(widgets, key=lambda w: w.pos().y())
81
82        spacing = self.layout().spacing()
83        uniform_layout_helper(widgets, mygeom, orientation,
84                              spacing=spacing)
85
86
87def uniform_layout_helper(items, contents_rect, expanding, spacing):
[11425]88    """
89    Set fixed sizes on 'items' so they can be laid out in `contents_rect`
90    and fill the whole space. The items are laid out in
91    `expanding_direction` (:class:`Qt.Orientation`) with `spacing`
92    (:class:`int`)
[11100]93
94    """
95    if len(items) == 0:
96        return
97
98    spacing_space = (len(items) - 1) * spacing
99
100    if expanding == Qt.Horizontal:
101        space = contents_rect.width() - spacing_space
[11137]102        setter = lambda w, s: w.setFixedWidth(max(s, 0))
[11100]103    else:
104        space = contents_rect.height() - spacing_space
[11137]105        setter = lambda w, s: w.setFixedHeight(max(s, 0))
[11100]106
107    base_size = space / len(items)
108    remainder = space % len(items)
109
110    for i, item in enumerate(items):
111        item_size = base_size + (1 if i < remainder else 0)
112        setter(item, item_size)
Note: See TracBrowser for help on using the repository browser.