From 5f121396151106b2af811d44f7759736a25fca35 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Sun, 26 Apr 2015 08:14:54 +0530 Subject: [PATCH] Animate the main toolbar when a device is connected/disconnected Useful to indicate that the toolbar contents have changed --- src/calibre/gui2/bars.py | 53 +++++++++++++++++++++++++++++++++++--- src/calibre/gui2/device.py | 4 +-- 2 files changed, 52 insertions(+), 5 deletions(-) diff --git a/src/calibre/gui2/bars.py b/src/calibre/gui2/bars.py index 6b0c13e54e..31895562f7 100644 --- a/src/calibre/gui2/bars.py +++ b/src/calibre/gui2/bars.py @@ -9,11 +9,55 @@ __docformat__ = 'restructuredtext en' import sip from PyQt5.Qt import ( - Qt, QAction, QMenu, QObject, QToolBar, QToolButton, QSize, pyqtSignal, QTimer) + Qt, QAction, QMenu, QObject, QToolBar, QToolButton, QSize, pyqtSignal, + QTimer, QPropertyAnimation, QEasingCurve, pyqtProperty, QPainter, QWidget) from calibre.constants import isosx from calibre.gui2.throbber import create_donate_widget -from calibre.gui2 import gprefs, native_menubar_defaults +from calibre.gui2 import gprefs, native_menubar_defaults, config + +class RevealBar(QWidget): # {{{ + + def __init__(self, parent): + QWidget.__init__(self, parent) + self.setVisible(False) + self._animated_size = 1.0 + self.animation = QPropertyAnimation(self, 'animated_size', self) + self.animation.setEasingCurve(QEasingCurve.Linear) + self.animation.setDuration(1000), self.animation.setStartValue(0.0), self.animation.setEndValue(1.0) + self.animation.valueChanged.connect(self.animation_value_changed) + self.animation.finished.connect(self.animation_done) + + @pyqtProperty(float) + def animated_size(self): + return self._animated_size + + @animated_size.setter + def animated_size(self, val): + self._animated_size = val + + def animation_value_changed(self, *args): + self.update() + + def animation_done(self): + self.setVisible(False) + self.update() + + def start(self, bar): + self.setGeometry(bar.geometry()) + self.setVisible(True) + self.animation.start() + + def paintEvent(self, ev): + if self._animated_size < 1.0: + rect = self.rect() + painter = QPainter(self) + pal = self.palette() + col = pal.color(pal.Button) + rect.setLeft(rect.left() + (rect.width() * self._animated_size)) + painter.setClipRect(rect) + painter.fillRect(self.rect(), col) +# }}} class ToolBar(QToolBar): # {{{ @@ -435,6 +479,7 @@ class BarsManager(QObject): range(3)] self.main_bars = tuple(bars[:2]) self.child_bars = tuple(bars[2:]) + self.reveal_bar = RevealBar(parent) self.menu_bar = MenuBar(self.location_manager, self.parent()) is_native_menubar = self.menu_bar.is_native_menubar @@ -470,7 +515,7 @@ class BarsManager(QObject): for bar, actions in zip(self.bars, self.bar_actions[:3]): bar.init_bar(actions) - def update_bars(self): + def update_bars(self, reveal_bar=False): ''' This shows the correct main toolbar and rebuilds the menubar based on whether a device is connected or not. Note that the toolbars are @@ -486,6 +531,8 @@ class BarsManager(QObject): bar.update_lm_actions() if main_bar.added_actions: main_bar.setVisible(True) + if reveal_bar and not config['disable_animations']: + self.reveal_bar.start(main_bar) if child_bar.added_actions: child_bar.setVisible(True) diff --git a/src/calibre/gui2/device.py b/src/calibre/gui2/device.py index d0066aa1a7..9a02fcfbba 100644 --- a/src/calibre/gui2/device.py +++ b/src/calibre/gui2/device.py @@ -1078,7 +1078,7 @@ class DeviceMixin(object): # {{{ if self.current_view() != self.library_view: self.book_details.reset_info() self.location_manager.update_devices() - self.bars_manager.update_bars() + self.bars_manager.update_bars(reveal_bar=True) self.library_view.set_device_connected(self.device_connected) # Empty any device view information self.memory_view.set_database([]) @@ -1096,7 +1096,7 @@ class DeviceMixin(object): # {{{ info, cp, fs = job.result self.location_manager.update_devices(cp, fs, self.device_manager.device.icon) - self.bars_manager.update_bars() + self.bars_manager.update_bars(reveal_bar=True) self.status_bar.device_connected(info[0]) db = self.current_db self.device_manager.set_library_information(None, os.path.basename(db.library_path),