diff options
| author | Jon A. Cruz <jon@joncruz.org> | 2011-05-30 07:36:58 +0000 |
|---|---|---|
| committer | Jon A. Cruz <jon@joncruz.org> | 2011-05-30 07:36:58 +0000 |
| commit | 961baa0d3d2691ebeabc3f51fdab8d816b32c563 (patch) | |
| tree | 9711da6fad6af8f89bacfd85b337d857d65756dc /src | |
| parent | Voronoi extension by Vincent Nivoliers (Bug 783922) (diff) | |
| download | inkscape-961baa0d3d2691ebeabc3f51fdab8d816b32c563.tar.gz inkscape-961baa0d3d2691ebeabc3f51fdab8d816b32c563.zip | |
Queue swatch updates during periods of high UI usage, such as dragging gradient handles. Fixes bug #734981.
Fixed bugs:
- https://launchpad.net/bugs/734981
(bzr r10244)
Diffstat (limited to 'src')
| -rw-r--r-- | src/ui/dialog/swatches.cpp | 89 | ||||
| -rw-r--r-- | src/ui/dialog/swatches.h | 3 |
2 files changed, 89 insertions, 3 deletions
diff --git a/src/ui/dialog/swatches.cpp b/src/ui/dialog/swatches.cpp index b2b1b26da..935fe9806 100644 --- a/src/ui/dialog/swatches.cpp +++ b/src/ui/dialog/swatches.cpp @@ -23,6 +23,7 @@ #include <gtk/gtkmenuitem.h> #include <gtk/gtkseparatormenuitem.h> #include <glibmm/i18n.h> +#include <glibmm/main.h> #include <gdkmm/pixbuf.h> #include "color-item.h" @@ -63,8 +64,6 @@ namespace Dialogs { void _loadPaletteFile( gchar const *filename ); -class DocTrack; - std::vector<SwatchPage*> possible; static std::map<SPDocument*, SwatchPage*> docPalettes; static std::vector<DocTrack*> docTrackings; @@ -715,14 +714,31 @@ class DocTrack public: DocTrack(SPDocument *doc, sigc::connection &gradientRsrcChanged, sigc::connection &defsChanged, sigc::connection &defsModified) : doc(doc), + updatePending(false), + lastGradientUpdate(0.0), gradientRsrcChanged(gradientRsrcChanged), defsChanged(defsChanged), defsModified(defsModified) { + if ( !timer ) { + timer = new Glib::Timer(); + refreshTimer = Glib::signal_timeout().connect( sigc::ptr_fun(handleTimerCB), 33 ); + } + timerRefCount++; } ~DocTrack() { + timerRefCount--; + if ( timerRefCount <= 0 ) { + refreshTimer.disconnect(); + timerRefCount = 0; + if ( timer ) { + timer->stop(); + delete timer; + timer = 0; + } + } if (doc) { gradientRsrcChanged.disconnect(); defsChanged.disconnect(); @@ -730,7 +746,22 @@ public: } } + static bool handleTimerCB(); + + /** + * Checks if update should be queued or executed immediately. + * + * @return true if the update was queued and should not be immediately executed. + */ + static bool queueUpdateIfNeeded(SPDocument *doc); + + static Glib::Timer *timer; + static int timerRefCount; + static sigc::connection refreshTimer; + SPDocument *doc; + bool updatePending; + double lastGradientUpdate; sigc::connection gradientRsrcChanged; sigc::connection defsChanged; sigc::connection defsModified; @@ -740,6 +771,58 @@ private: DocTrack &operator=(DocTrack const &); // no assign }; +Glib::Timer *DocTrack::timer = 0; +int DocTrack::timerRefCount = 0; +sigc::connection DocTrack::refreshTimer; + +static const double DOC_UPDATE_THREASHOLD = 0.090; + +bool DocTrack::handleTimerCB() +{ + double now = timer->elapsed(); + + std::vector<DocTrack *> needCallback; + for (std::vector<DocTrack *>::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it) { + DocTrack *track = *it; + if ( track->updatePending && ( (now - track->lastGradientUpdate) >= DOC_UPDATE_THREASHOLD) ) { + needCallback.push_back(track); + } + } + + for (std::vector<DocTrack *>::iterator it = needCallback.begin(); it != needCallback.end(); ++it) { + DocTrack *track = *it; + if ( std::find(docTrackings.begin(), docTrackings.end(), track) != docTrackings.end() ) { // Just in case one gets deleted while we are looping + // Note: calling handleDefsModified will call queueUpdateIfNeeded and thus update the time and flag. + SwatchesPanel::handleDefsModified(track->doc); + } + } + + return true; +} + +bool DocTrack::queueUpdateIfNeeded( SPDocument *doc ) +{ + bool deferProcessing = false; + for (std::vector<DocTrack*>::iterator it = docTrackings.begin(); it != docTrackings.end(); ++it) { + DocTrack *track = *it; + if ( track->doc == doc ) { + double now = timer->elapsed(); + double elapsed = now - track->lastGradientUpdate; + + if ( elapsed < DOC_UPDATE_THREASHOLD ) { + deferProcessing = true; + track->updatePending = true; + } else { + track->lastGradientUpdate = now; + track->updatePending = false; + } + + break; + } + } + return deferProcessing; +} + void SwatchesPanel::_trackDocument( SwatchesPanel *panel, SPDocument *document ) { SPDocument *oldDoc = 0; @@ -897,7 +980,7 @@ void SwatchesPanel::handleGradientsChange(SPDocument *document) void SwatchesPanel::handleDefsModified(SPDocument *document) { SwatchPage *docPalette = (docPalettes.find(document) != docPalettes.end()) ? docPalettes[document] : 0; - if (docPalette) { + if (docPalette && !DocTrack::queueUpdateIfNeeded(document) ) { std::vector<ColorItem*> tmpColors; std::map<ColorItem*, guchar*> tmpPrevs; std::map<ColorItem*, SPGradient*> tmpGrads; diff --git a/src/ui/dialog/swatches.h b/src/ui/dialog/swatches.h index f9f3daf91..95d7acb00 100644 --- a/src/ui/dialog/swatches.h +++ b/src/ui/dialog/swatches.h @@ -23,6 +23,7 @@ namespace Dialogs { class ColorItem; class SwatchPage; +class DocTrack; /** * A panel that displays paint swatches. @@ -68,6 +69,8 @@ private: sigc::connection _documentConnection; sigc::connection _selChanged; + + friend class DocTrack; }; } //namespace Dialogs |
