summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorJon A. Cruz <jon@joncruz.org>2011-05-30 07:36:58 +0000
committerJon A. Cruz <jon@joncruz.org>2011-05-30 07:36:58 +0000
commit961baa0d3d2691ebeabc3f51fdab8d816b32c563 (patch)
tree9711da6fad6af8f89bacfd85b337d857d65756dc /src
parentVoronoi extension by Vincent Nivoliers (Bug 783922) (diff)
downloadinkscape-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.cpp89
-rw-r--r--src/ui/dialog/swatches.h3
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