Changeset 11411:f1d5470c8031 in orange


Ignore:
Timestamp:
03/18/13 11:52:35 (13 months ago)
Author:
Ales Erjavec <ales.erjavec@…>
Branch:
default
Message:

Added ping and shadow animations for node items.

Location:
Orange/OrangeCanvas
Files:
7 edited

Legend:

Unmodified
Added
Removed
  • Orange/OrangeCanvas/application/canvasmain.py

    r11399 r11411  
    16641664        self.scheme_widget.setChannelNamesVisible(show_channel_names) 
    16651665 
     1666        node_animations = settings.value("enable-node-animations", 
     1667                                         defaultValue=False, 
     1668                                         type=bool) 
     1669        self.scheme_widget.setNodeAnimationEnabled(node_animations) 
    16661670        settings.endGroup() 
    16671671 
  • Orange/OrangeCanvas/application/settings.py

    r11320 r11411  
    234234        tab.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed) 
    235235 
     236        nodes = QWidget(self, objectName="nodes") 
     237        nodes.setLayout(QVBoxLayout()) 
     238        nodes.layout().setContentsMargins(0, 0, 0, 0) 
     239 
     240        cb_anim = QCheckBox( 
     241            self.tr("Enable node animations"), 
     242            objectName="enable-node-animations", 
     243            toolTip=self.tr("Enable shadow and ping animations for node " 
     244                            "items in the scheme.") 
     245        ) 
     246        self.bind(cb_anim, "checked", "schemeedit/enable-node-animations") 
     247        nodes.layout().addWidget(cb_anim) 
     248 
     249        form.addRow(self.tr("Nodes"), nodes) 
     250 
    236251        links = QWidget(self, objectName="links") 
    237252        links.setLayout(QVBoxLayout()) 
  • Orange/OrangeCanvas/canvas/items/nodeitem.py

    r11369 r11411  
    77 
    88from PyQt4.QtGui import ( 
    9     QGraphicsItem, QGraphicsPathItem, QGraphicsObject, 
    10     QGraphicsTextItem, QGraphicsDropShadowEffect, QGraphicsView, 
     9    QGraphicsItem, QGraphicsObject, QGraphicsTextItem, 
     10    QGraphicsDropShadowEffect, QGraphicsView, 
    1111    QPen, QBrush, QColor, QPalette, QIcon, QStyle, QPainter, 
    1212    QPainterPath, QPainterPathStroker, QApplication 
    1313) 
    1414 
    15 from PyQt4.QtCore import Qt, QPointF, QRectF, QSize, QTimer 
     15from PyQt4.QtCore import Qt, QPointF, QRectF, QSize, QTimer, QPropertyAnimation 
    1616from PyQt4.QtCore import pyqtSignal as Signal 
    1717from PyQt4.QtCore import pyqtProperty as Property 
     
    5656 
    5757 
     58def animation_restart(animation): 
     59    if animation.state() == QPropertyAnimation.Running: 
     60        animation.pause() 
     61    animation.start() 
     62 
     63 
    5864SHADOW_COLOR = "#9CACB4" 
    5965FOCUS_OUTLINE_COLOR = "#609ED7" 
    6066 
    6167 
    62 class NodeBodyItem(QGraphicsPathItem): 
     68class NodeBodyItem(GraphicsPathObject): 
    6369    """ 
    6470    The central part (body) of the `NodeItem`. 
    6571    """ 
    6672    def __init__(self, parent=None): 
    67         QGraphicsPathItem.__init__(self, parent) 
     73        GraphicsPathObject.__init__(self, parent) 
    6874        assert(isinstance(parent, NodeItem)) 
    6975 
    7076        self.__processingState = 0 
    7177        self.__progress = -1 
     78        self.__animationEnabled = False 
    7279        self.__isSelected = False 
    7380        self.__hasFocus = False 
     
    8592 
    8693        self.shadow = QGraphicsDropShadowEffect( 
    87             blurRadius=10, 
     94            blurRadius=3, 
    8895            color=QColor(SHADOW_COLOR), 
    8996            offset=QPointF(0, 0), 
     
    9198 
    9299        self.setGraphicsEffect(self.shadow) 
    93         self.shadow.setEnabled(False) 
     100        self.shadow.setEnabled(True) 
     101 
     102        self.__blurAnimation = QPropertyAnimation(self.shadow, "blurRadius", 
     103                                                  self) 
     104        self.__blurAnimation.setDuration(100) 
     105        self.__blurAnimation.finished.connect(self.__on_finished) 
     106 
     107        self.__pingAnimation = QPropertyAnimation(self, "scale", self) 
     108        self.__pingAnimation.setDuration(250) 
     109        self.__pingAnimation.setKeyValues([(0.0, 1.0), (0.5, 1.1), (1.0, 1.0)]) 
    94110 
    95111    # TODO: The body item should allow the setting of arbitrary painter 
     
    113129        self.__updateBrush() 
    114130 
     131    def setAnimationEnabled(self, enabled): 
     132        """ 
     133        Set the node animation enabled. 
     134        """ 
     135        if self.__animationEnabled != enabled: 
     136            self.__animationEnabled = enabled 
     137 
    115138    def setProcessingState(self, state): 
    116139        """ 
    117140        Set the processing state of the node. 
    118141        """ 
    119         self.__processingState = state 
    120         self.update() 
     142        if self.__processingState != state: 
     143            self.__processingState = state 
     144            if not state and self.__animationEnabled: 
     145                self.ping() 
    121146 
    122147    def setProgress(self, progress): 
     
    128153        self.__progress = progress 
    129154        self.update() 
     155 
     156    def ping(self): 
     157        """ 
     158        Trigger a 'ping' animation. 
     159        """ 
     160        animation_restart(self.__pingAnimation) 
    130161 
    131162    def hoverEnterEvent(self, event): 
    132163        self.__hover = True 
    133164        self.__updateShadowState() 
    134         return QGraphicsPathItem.hoverEnterEvent(self, event) 
     165        return GraphicsPathObject.hoverEnterEvent(self, event) 
    135166 
    136167    def hoverLeaveEvent(self, event): 
    137168        self.__hover = False 
    138169        self.__updateShadowState() 
    139         return QGraphicsPathItem.hoverLeaveEvent(self, event) 
     170        return GraphicsPathObject.hoverLeaveEvent(self, event) 
    140171 
    141172    def paint(self, painter, option, widget): 
     
    147178            # Prevent the default bounding rect selection indicator. 
    148179            option.state = option.state ^ QStyle.State_Selected 
    149         QGraphicsPathItem.paint(self, painter, option, widget) 
     180        GraphicsPathObject.paint(self, painter, option, widget) 
    150181 
    151182        if self.__progress >= 0: 
     
    169200            self.setPen(QPen(Qt.NoPen)) 
    170201 
     202        radius = 3 
    171203        enabled = False 
     204 
    172205        if self.__isSelected: 
    173             self.shadow.setBlurRadius(7) 
    174206            enabled = True 
    175         elif self.__hover: 
    176             self.shadow.setBlurRadius(17) 
     207            radius = 7 
     208 
     209        if self.__hover: 
     210            radius = 17 
    177211            enabled = True 
    178         self.shadow.setEnabled(enabled) 
     212 
     213        if enabled and not self.shadow.isEnabled(): 
     214            self.shadow.setEnabled(enabled) 
     215 
     216        if self.__animationEnabled: 
     217            if self.__blurAnimation.state() == QPropertyAnimation.Running: 
     218                self.__blurAnimation.pause() 
     219 
     220            self.__blurAnimation.setStartValue(self.shadow.blurRadius()) 
     221            self.__blurAnimation.setEndValue(radius) 
     222            self.__blurAnimation.start() 
     223        else: 
     224            self.shadow.setBlurRadius(radius) 
    179225 
    180226    def __updateBrush(self): 
     
    215261        self.__hasFocus = focus 
    216262        self.__updateShadowState() 
     263 
     264    def __on_finished(self): 
     265        if self.shadow.blurRadius() == 0: 
     266            self.shadow.setEnabled(False) 
    217267 
    218268 
     
    692742 
    693743        self.__anchorLayout = None 
     744        self.__animationEnabled = False 
    694745 
    695746        self.setZValue(self.Z_VALUE) 
     
    727778        self.shapeItem = NodeBodyItem(self) 
    728779        self.shapeItem.setShapeRect(shape_rect) 
     780        self.shapeItem.setAnimationEnabled(self.__animationEnabled) 
    729781 
    730782        # Rect for widget's 'ears'. 
     
    855907        return self.captionTextItem.font() 
    856908 
     909    def setAnimationEnabled(self, enabled): 
     910        """ 
     911        Set the node animation enabled state. 
     912        """ 
     913        if self.__animationEnabled != enabled: 
     914            self.__animationEnabled = enabled 
     915            self.shapeItem.setAnimationEnabled(enabled) 
     916 
     917    def animationEnabled(self): 
     918        """ 
     919        Are node animations enabled. 
     920        """ 
     921        return self.__animationEnabled 
     922 
    857923    def setProcessingState(self, state): 
    858924        """ 
     
    867933                # Clear the progress meter. 
    868934                self.setProgress(-1) 
     935                if self.__animationEnabled: 
     936                    self.shapeItem.ping() 
    869937 
    870938    def processingState(self): 
  • Orange/OrangeCanvas/canvas/scene.py

    r11369 r11411  
    100100 
    101101        self.__channel_names_visible = True 
     102        self.__node_animation_enabled = True 
    102103 
    103104        self.user_interaction_handler = None 
     
    217218        return self.__channel_names_visible 
    218219 
     220    def set_node_animation_enabled(self, enabled): 
     221        if self.__node_animation_enabled != enabled: 
     222            self.__node_animation_enabled = enabled 
     223 
     224            for node in self.__node_items: 
     225                node.setAnimationEnabled(enabled) 
     226 
    219227    def add_node_item(self, item): 
    220228        """Add a :class:`NodeItem` instance to the scene. 
     
    301309            item.setWidgetCategory(category_desc) 
    302310 
     311        item.setAnimationEnabled(self.__node_animation_enabled) 
    303312        return item 
    304313 
  • Orange/OrangeCanvas/config.py

    r11388 r11411  
    7979     ("schemeedit/show-link-state", bool, True, 
    8080      "Show link state hints."), 
     81 
     82     ("schemeedit/enable-node-animations", bool, True, 
     83      "Enable node animations."), 
    8184 
    8285     ("schemeedit/freeze-on-load", bool, False, 
  • Orange/OrangeCanvas/document/schemeedit.py

    r11390 r11411  
    116116        self.__emptyClickButtons = 0 
    117117        self.__channelNamesVisible = True 
     118        self.__nodeAnimationEnabled = True 
    118119        self.__possibleSelectionHandler = None 
    119120        self.__possibleMouseItemsMove = False 
     
    344345        scene = CanvasScene() 
    345346        scene.set_channel_names_visible(self.__channelNamesVisible) 
     347        scene.set_node_animation_enabled(self.__nodeAnimationEnabled) 
    346348        scene.setFont(self.font()) 
    347349 
     
    469471        """ 
    470472        return self.__channelNamesVisible 
     473 
     474    def setNodeAnimationEnabled(self, enabled): 
     475        """ 
     476        Set the node item animation enabled state. 
     477        """ 
     478        if self.__nodeAnimationEnabled != enabled: 
     479            self.__nodeAnimationEnabled = enabled 
     480            self.__scene.set_node_animation_enabled(enabled) 
     481 
     482    def nodeAnimationEnabled(self): 
     483        """ 
     484        Return the node item animation enabled state. 
     485        """ 
     486        return self.__nodeAnimationEnabled 
    471487 
    472488    def undoStack(self): 
     
    545561            self.__view.setScene(self.__scene) 
    546562            self.__scene.set_channel_names_visible(self.__channelNamesVisible) 
     563            self.__scene.set_node_animation_enabled( 
     564                self.__nodeAnimationEnabled 
     565            ) 
     566 
    547567            self.__scene.setFont(self.font()) 
    548568 
  • Orange/OrangeCanvas/scheme/widgetsscheme.py

    r11391 r11411  
    5050        self.node_for_widget = {} 
    5151        self.signal_manager = WidgetsSignalManager(self) 
     52        self.signal_manager.processingStarted[SchemeNode].connect( 
     53            self.__on_processing_started 
     54        ) 
     55        self.signal_manager.processingFinished[SchemeNode].connect( 
     56            self.__on_processing_finished 
     57        ) 
    5258 
    5359    def add_node(self, node): 
     
    6470        # widget_for_node, etc. to be up to date. 
    6571        widget = self.create_widget_instance(node) 
    66  
    6772        Scheme.add_node(self, node) 
    6873 
     
    199204            QCoreApplication.sendEvent(self, event) 
    200205 
     206    def __on_processing_started(self, node): 
     207        node.set_processing_state(1) 
     208 
     209    def __on_processing_finished(self, node): 
     210        node.set_processing_state(0) 
     211 
    201212 
    202213class WidgetsSignalManager(SignalManager): 
Note: See TracChangeset for help on using the changeset viewer.