Updating from skeleton
[gc-dialer] / src / util / qtpie.py
index a3de6aa..6b77d5d 100755 (executable)
@@ -3,20 +3,11 @@
 import math
 import logging
 
-from PyQt4 import QtGui
-from PyQt4 import QtCore
+import qt_compat
+QtCore = qt_compat.QtCore
+QtGui = qt_compat.import_module("QtGui")
 
-try:
-       from util import misc as misc_utils
-except ImportError:
-       class misc_utils(object):
-
-               @staticmethod
-               def log_exception(logger):
-
-                       def wrapper(func):
-                               return func
-                       return wrapper
+import misc as misc_utils
 
 
 _moduleLogger = logging.getLogger(__name__)
@@ -198,7 +189,10 @@ class PieArtist(object):
        SHAPE_SQUARE = "square"
        DEFAULT_SHAPE = SHAPE_SQUARE
 
-       def __init__(self, filing):
+       BACKGROUND_FILL = "fill"
+       BACKGROUND_NOFILL = "no fill"
+
+       def __init__(self, filing, background = BACKGROUND_FILL):
                self._filing = filing
 
                self._cachedOuterRadius = self._filing.outerRadius()
@@ -206,6 +200,7 @@ class PieArtist(object):
                canvasSize = self._cachedOuterRadius * 2 + 1
                self._canvas = QtGui.QPixmap(canvasSize, canvasSize)
                self._mask = None
+               self._backgroundState = background
                self.palette = None
 
        def pieSize(self):
@@ -253,37 +248,27 @@ class PieArtist(object):
                painter = QtGui.QPainter(self._canvas)
                painter.setRenderHint(QtGui.QPainter.Antialiasing, True)
 
-               adjustmentRect = self._canvas.rect().adjusted(0, 0, -1, -1)
+               self.paintPainter(selectionIndex, painter)
+
+               return self._canvas
+
+       def paintPainter(self, selectionIndex, painter):
+               adjustmentRect = painter.viewport().adjusted(0, 0, -1, -1)
 
                numChildren = len(self._filing)
                if numChildren == 0:
-                       if selectionIndex == PieFiling.SELECTION_CENTER and self._filing.center().isEnabled():
-                               painter.setBrush(self.palette.highlight())
-                       else:
-                               painter.setBrush(self.palette.window())
-                       painter.setPen(self.palette.mid().color())
-
-                       painter.drawRect(self._canvas.rect())
-                       self._paint_center_foreground(painter, selectionIndex)
+                       self._paint_center_background(painter, adjustmentRect, selectionIndex)
+                       self._paint_center_foreground(painter, adjustmentRect, selectionIndex)
                        return self._canvas
-               elif numChildren == 1:
-                       if selectionIndex == 0 and self._filing[0].isEnabled():
-                               painter.setBrush(self.palette.highlight())
-                       else:
-                               painter.setBrush(self.palette.window())
-
-                       painter.fillRect(self._canvas.rect(), painter.brush())
                else:
                        for i in xrange(len(self._filing)):
                                self._paint_slice_background(painter, adjustmentRect, i, selectionIndex)
 
                self._paint_center_background(painter, adjustmentRect, selectionIndex)
-               self._paint_center_foreground(painter, selectionIndex)
+               self._paint_center_foreground(painter, adjustmentRect, selectionIndex)
 
                for i in xrange(len(self._filing)):
-                       self._paint_slice_foreground(painter, i, selectionIndex)
-
-               return self._canvas
+                       self._paint_slice_foreground(painter, adjustmentRect, i, selectionIndex)
 
        def _generate_mask(self, mask):
                """
@@ -310,11 +295,16 @@ class PieArtist(object):
                else:
                        raise NotImplementedError(self.DEFAULT_SHAPE)
 
-               if i == selectionIndex and self._filing[i].isEnabled():
-                       painter.setBrush(self.palette.highlight())
+               if self._backgroundState == self.BACKGROUND_NOFILL:
+                       painter.setBrush(QtGui.QBrush(QtCore.Qt.transparent))
+                       painter.setPen(self.palette.highlight().color())
                else:
-                       painter.setBrush(self.palette.window())
-               painter.setPen(self.palette.mid().color())
+                       if i == selectionIndex and self._filing[i].isEnabled():
+                               painter.setBrush(self.palette.highlight())
+                               painter.setPen(self.palette.highlight().color())
+                       else:
+                               painter.setBrush(self.palette.window())
+                               painter.setPen(self.palette.window().color())
 
                a = self._filing._index_to_angle(i, True)
                b = self._filing._index_to_angle(i + 1, True)
@@ -328,7 +318,7 @@ class PieArtist(object):
                sizeInDeg = (size * 360 * 16) / _TWOPI
                painter.drawPie(adjustmentRect, int(startAngleInDeg), int(sizeInDeg))
 
-       def _paint_slice_foreground(self, painter, i, selectionIndex):
+       def _paint_slice_foreground(self, painter, adjustmentRect, i, selectionIndex):
                child = self._filing[i]
 
                a = self._filing._index_to_angle(i, True)
@@ -341,7 +331,7 @@ class PieArtist(object):
                sliceX = averageRadius * math.cos(middleAngle)
                sliceY = - averageRadius * math.sin(middleAngle)
 
-               piePos = self._canvas.rect().center()
+               piePos = adjustmentRect.center()
                pieX = piePos.x()
                pieY = piePos.y()
                self._paint_label(
@@ -398,41 +388,54 @@ class PieArtist(object):
                        painter.drawText(leftX, topY, text)
 
        def _paint_center_background(self, painter, adjustmentRect, selectionIndex):
-               dark = self.palette.mid().color()
-               light = self.palette.light().color()
-               if selectionIndex == PieFiling.SELECTION_CENTER and self._filing.center().isEnabled():
-                       background = self.palette.highlight().color()
-               else:
-                       background = self.palette.window().color()
-
-               innerRadius = self._cachedInnerRadius
-               adjustmentCenterPos = adjustmentRect.center()
-               innerRect = QtCore.QRect(
-                       adjustmentCenterPos.x() - innerRadius,
-                       adjustmentCenterPos.y() - innerRadius,
-                       innerRadius * 2 + 1,
-                       innerRadius * 2 + 1,
-               )
+               if self._backgroundState == self.BACKGROUND_NOFILL:
+                       return
+               if len(self._filing) == 0:
+                       if self._backgroundState == self.BACKGROUND_NOFILL:
+                               painter.setBrush(QtGui.QBrush(QtCore.Qt.transparent))
+                       else:
+                               if selectionIndex == PieFiling.SELECTION_CENTER and self._filing.center().isEnabled():
+                                       painter.setBrush(self.palette.highlight())
+                               else:
+                                       painter.setBrush(self.palette.window())
+                       painter.setPen(self.palette.mid().color())
 
-               painter.setPen(QtCore.Qt.NoPen)
-               painter.setBrush(background)
-               painter.drawPie(innerRect, 0, 360 * 16)
+                       painter.drawRect(adjustmentRect)
+               else:
+                       dark = self.palette.mid().color()
+                       light = self.palette.light().color()
+                       if self._backgroundState == self.BACKGROUND_NOFILL:
+                               background = QtGui.QBrush(QtCore.Qt.transparent)
+                       else:
+                               if selectionIndex == PieFiling.SELECTION_CENTER and self._filing.center().isEnabled():
+                                       background = self.palette.highlight().color()
+                               else:
+                                       background = self.palette.window().color()
+
+                       innerRadius = self._cachedInnerRadius
+                       adjustmentCenterPos = adjustmentRect.center()
+                       innerRect = QtCore.QRect(
+                               adjustmentCenterPos.x() - innerRadius,
+                               adjustmentCenterPos.y() - innerRadius,
+                               innerRadius * 2 + 1,
+                               innerRadius * 2 + 1,
+                       )
 
-               painter.setPen(QtGui.QPen(dark, 1))
-               painter.setBrush(QtCore.Qt.NoBrush)
-               painter.drawEllipse(innerRect)
+                       painter.setPen(QtCore.Qt.NoPen)
+                       painter.setBrush(background)
+                       painter.drawPie(innerRect, 0, 360 * 16)
 
-               if self.DEFAULT_SHAPE == self.SHAPE_SQUARE:
-                       pass
-               elif self.DEFAULT_SHAPE == self.SHAPE_CIRCLE:
-                       painter.setPen(QtGui.QPen(dark, 1))
-                       painter.setBrush(QtCore.Qt.NoBrush)
-                       painter.drawEllipse(adjustmentRect)
-               else:
-                       raise NotImplementedError(self.DEFAULT_SHAPE)
+                       if self.DEFAULT_SHAPE == self.SHAPE_SQUARE:
+                               pass
+                       elif self.DEFAULT_SHAPE == self.SHAPE_CIRCLE:
+                               painter.setPen(QtGui.QPen(dark, 1))
+                               painter.setBrush(QtCore.Qt.NoBrush)
+                               painter.drawEllipse(adjustmentRect)
+                       else:
+                               raise NotImplementedError(self.DEFAULT_SHAPE)
 
-       def _paint_center_foreground(self, painter, selectionIndex):
-               centerPos = self._canvas.rect().center()
+       def _paint_center_foreground(self, painter, adjustmentRect, selectionIndex):
+               centerPos = adjustmentRect.center()
                pieX = centerPos.x()
                pieY = centerPos.y()
 
@@ -478,9 +481,10 @@ class QPieDisplay(QtGui.QWidget):
        @misc_utils.log_exception(_moduleLogger)
        def paintEvent(self, paintEvent):
                canvas = self._artist.paint(self._selectionIndex)
+               offset = (self.size() - canvas.size()) / 2
 
                screen = QtGui.QPainter(self)
-               screen.drawPixmap(QtCore.QPoint(0, 0), canvas)
+               screen.drawPixmap(QtCore.QPoint(offset.width(), offset.height()), canvas)
 
                QtGui.QWidget.paintEvent(self, paintEvent)
 
@@ -493,11 +497,11 @@ class QPieDisplay(QtGui.QWidget):
 
 class QPieButton(QtGui.QWidget):
 
-       activated = QtCore.pyqtSignal(int)
-       highlighted = QtCore.pyqtSignal(int)
-       canceled = QtCore.pyqtSignal()
-       aboutToShow = QtCore.pyqtSignal()
-       aboutToHide = QtCore.pyqtSignal()
+       activated = qt_compat.Signal(int)
+       highlighted = qt_compat.Signal(int)
+       canceled = qt_compat.Signal()
+       aboutToShow = qt_compat.Signal()
+       aboutToHide = qt_compat.Signal()
 
        BUTTON_RADIUS = 24
        DELAY = 250
@@ -518,8 +522,9 @@ class QPieButton(QtGui.QWidget):
                        for slice in buttonSlices:
                                self._buttonFiling.insertItem(slice)
                self._buttonFiling.setOuterRadius(self.BUTTON_RADIUS)
-               self._buttonArtist = PieArtist(self._buttonFiling)
+               self._buttonArtist = PieArtist(self._buttonFiling, PieArtist.BACKGROUND_NOFILL)
                self._poppedUp = False
+               self._pressed = False
 
                self._delayPopupTimer = QtCore.QTimer()
                self._delayPopupTimer.setInterval(self.DELAY)
@@ -577,9 +582,6 @@ class QPieButton(QtGui.QWidget):
                self._buttonFiling.setInnerRadius(radius / 2)
                self._buttonArtist.show(self.palette())
 
-       def sizeHint(self):
-               return self._buttonArtist.pieSize()
-
        def minimumSizeHint(self):
                return self._buttonArtist.centerSize()
 
@@ -594,10 +596,11 @@ class QPieButton(QtGui.QWidget):
                self.highlighted.emit(self._selectionIndex)
 
                self._display.selectAt(self._selectionIndex)
+               self._pressed = True
+               self.update()
                self._popupLocation = mouseEvent.globalPos()
                self._delayPopupTimer.start()
 
-       @QtCore.pyqtSlot()
        @misc_utils.log_exception(_moduleLogger)
        def _on_delayed_popup(self):
                assert self._popupLocation is not None, "Widget location abuse"
@@ -645,6 +648,8 @@ class QPieButton(QtGui.QWidget):
                self._mousePosition = None
 
                self._activate_at(self._selectionIndex)
+               self._pressed = False
+               self.update()
                self._hide_child()
 
        @misc_utils.log_exception(_moduleLogger)
@@ -704,12 +709,18 @@ class QPieButton(QtGui.QWidget):
        def paintEvent(self, paintEvent):
                self.setButtonRadius(min(self.rect().width(), self.rect().height()) / 2 - 1)
                if self._poppedUp:
-                       canvas = self._buttonArtist.paint(PieFiling.SELECTION_CENTER)
+                       selectionIndex = PieFiling.SELECTION_CENTER
                else:
-                       canvas = self._buttonArtist.paint(PieFiling.SELECTION_NONE)
+                       selectionIndex = PieFiling.SELECTION_NONE
 
-               screen = QtGui.QPainter(self)
-               screen.drawPixmap(QtCore.QPoint(0, 0), canvas)
+               screen = QtGui.QStylePainter(self)
+               screen.setRenderHint(QtGui.QPainter.Antialiasing, True)
+               option = QtGui.QStyleOptionButton()
+               option.initFrom(self)
+               option.state = QtGui.QStyle.State_Sunken if self._pressed else QtGui.QStyle.State_Raised
+
+               screen.drawControl(QtGui.QStyle.CE_PushButton, option)
+               self._buttonArtist.paintPainter(selectionIndex, screen)
 
                QtGui.QWidget.paintEvent(self, paintEvent)
 
@@ -768,11 +779,11 @@ class QPieButton(QtGui.QWidget):
 
 class QPieMenu(QtGui.QWidget):
 
-       activated = QtCore.pyqtSignal(int)
-       highlighted = QtCore.pyqtSignal(int)
-       canceled = QtCore.pyqtSignal()
-       aboutToShow = QtCore.pyqtSignal()
-       aboutToHide = QtCore.pyqtSignal()
+       activated = qt_compat.Signal(int)
+       highlighted = qt_compat.Signal(int)
+       canceled = qt_compat.Signal()
+       aboutToShow = qt_compat.Signal()
+       aboutToHide = qt_compat.Signal()
 
        def __init__(self, parent = None):
                QtGui.QWidget.__init__(self, parent)