diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-01-20 01:29:50 +0000 |
commit | 8362bf63dea22bbf6736609b0f49c152f975eb63 (patch) | |
tree | 0eea3928e39e50fae91d4e68b21b1e6cbae25604 /krita/plugins/viewplugins/histogram_docker | |
download | koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.tar.gz koffice-8362bf63dea22bbf6736609b0f49c152f975eb63.zip |
Added old abandoned KDE3 version of koffice
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1077364 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'krita/plugins/viewplugins/histogram_docker')
11 files changed, 845 insertions, 0 deletions
diff --git a/krita/plugins/viewplugins/histogram_docker/Makefile.am b/krita/plugins/viewplugins/histogram_docker/Makefile.am new file mode 100644 index 00000000..6d116358 --- /dev/null +++ b/krita/plugins/viewplugins/histogram_docker/Makefile.am @@ -0,0 +1,21 @@ +kde_services_DATA = kritahistogramdocker.desktop +kritarcdir = $(kde_datadir)/kritaplugins +kritarc_DATA = kritahistogramdocker.rc + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../kritacolor/ \ + -I$(srcdir)/../../../ui \ + -I$/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +kritahistogramdocker_la_SOURCES = histogramdocker.cc kis_imagerasteredcache.cc kis_cachedhistogram.cc kis_accumulating_producer.cc + +kde_module_LTLIBRARIES = kritahistogramdocker.la +noinst_HEADERS = histogramdocker.h kis_imagerasteredcache.h kis_cachedhistogram.h kis_accumulating_producer.h + +kritahistogramdocker_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) +kritahistogramdocker_la_LIBADD = ../../../libkritacommon.la + +kritahistogramdocker_la_METASOURCES = AUTO diff --git a/krita/plugins/viewplugins/histogram_docker/histogramdocker.cc b/krita/plugins/viewplugins/histogram_docker/histogramdocker.cc new file mode 100644 index 00000000..93d77bfb --- /dev/null +++ b/krita/plugins/viewplugins/histogram_docker/histogramdocker.cc @@ -0,0 +1,192 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Bart Coppens <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +#include <qtooltip.h> + +#include <klocale.h> +#include <kiconloader.h> +#include <kinstance.h> +#include <kmessagebox.h> +#include <kstandarddirs.h> +#include <ktempfile.h> +#include <kdebug.h> +#include <kgenericfactory.h> + +#include <kopalettemanager.h> + +#include "kis_meta_registry.h" +#include <kis_doc.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_view.h> + +#include <kis_basic_histogram_producers.h> +#include <kis_colorspace_factory_registry.h> + +#include "histogramdocker.h" +#include "kis_imagerasteredcache.h" +#include "kis_accumulating_producer.h" + +typedef KGenericFactory<KritaHistogramDocker> KritaHistogramDockerFactory; +K_EXPORT_COMPONENT_FACTORY( kritahistogramdocker, KritaHistogramDockerFactory( "krita" ) ) + +KritaHistogramDocker::KritaHistogramDocker(QObject *parent, const char *name, const QStringList&) + : KParts::Plugin(parent, name) +{ + + if ( parent->inherits("KisView") ) { + m_view = dynamic_cast<KisView*>(parent); + + setInstance(KritaHistogramDockerFactory::instance()); + setXMLFile(locate("data","kritaplugins/kritahistogramdocker.rc"), true); + + KisImageSP img = m_view->canvasSubject()->currentImg(); + if (!img) { + m_cache = 0; + return; + } + + m_hview = 0; // producerChanged wants to setCurrentChannels, prevent that here + m_cache = 0; // we try to delete it in producerChanged + colorSpaceChanged(img->colorSpace()); // calls producerChanged(0) + + + m_hview = new KisHistogramView(m_view); + QToolTip::add(m_hview, i18n("Right-click to select histogram type")); + m_hview->setHistogram(m_histogram); + m_hview->setColor(true); + m_hview->setCurrentChannels(m_producer, m_producer->channels()); + m_hview->setFixedSize(256, 100); // XXX if not it keeps expanding + m_hview->setCaption(i18n("Histogram")); + + + connect(m_hview, SIGNAL(rightClicked(const QPoint&)), + this, SLOT(popupMenu(const QPoint&))); + connect(m_cache, SIGNAL(cacheUpdated()), + new HistogramDockerUpdater(this, m_histogram, m_hview, m_producer), SLOT(updated())); + connect(&m_popup, SIGNAL(activated(int)), + this, SLOT(producerChanged(int))); + connect(img, SIGNAL(sigColorSpaceChanged(KisColorSpace*)), + this, SLOT(colorSpaceChanged(KisColorSpace*))); // No need to force updates here + + // Add it to the control palette + m_view->canvasSubject()->paletteManager()->addWidget( + m_hview, "histodocker", krita::CONTROL_PALETTE); + } else { + m_cache = 0; + } +} + +KritaHistogramDocker::~KritaHistogramDocker() +{ + uint count = m_producers . count(); + for (uint i = 0; i < count; i++) { + delete m_producers . at(i); + } + + if (m_cache) + m_cache->deleteLater(); +} + +void KritaHistogramDocker::producerChanged(int pos) +{ + if (m_cache) + m_cache->deleteLater(); + m_cache = 0; + + if (m_currentProducerPos < m_popup.count()) + m_popup.setItemChecked(m_currentProducerPos, false); + m_currentProducerPos = pos; + m_popup.setItemChecked(m_currentProducerPos, true); + + uint count = m_producers . count(); + for (uint i = 0; i < count; i++) { + delete m_producers . at(i); + } + m_producers.clear(); + + KisIDList keys = KisHistogramProducerFactoryRegistry::instance() -> + listKeysCompatibleWith(m_cs); + + m_factory = KisHistogramProducerFactoryRegistry::instance()->get(*(keys.at(pos))); + + KisCachedHistogramObserver observer(&m_producers, m_factory, 0, 0, 0, 0, false); + + // We can reference observer because it will be only used as a factory to create new + // instances + m_cache = new KisImageRasteredCache(m_view, &observer); + + m_producer = new KisAccumulatingHistogramProducer(&m_producers); + + // use dummy layer as a source; we are not going to actually use or need it + // All of these are SP, no need to delete them afterwards + m_histogram = new KisHistogram( new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getAlpha8(), "dummy histogram"), m_producer, LOGARITHMIC); + + if (m_hview) { + m_hview->setHistogram(m_histogram); + m_hview->setColor(true); + m_hview->setCurrentChannels(m_producer, m_producer->channels()); + + connect(m_cache, SIGNAL(cacheUpdated()), + new HistogramDockerUpdater(this, m_histogram, m_hview, m_producer), SLOT(updated())); + } +} + +void KritaHistogramDocker::popupMenu(const QPoint& pos) +{ + m_popup.popup(pos, m_currentProducerPos); +} + +void KritaHistogramDocker::colorSpaceChanged(KisColorSpace* cs) +{ + m_cs = cs; + + KisIDList keys = KisHistogramProducerFactoryRegistry::instance() -> + listKeysCompatibleWith(m_cs); + + m_popup.clear(); + m_currentProducerPos = 0; + + for (uint i = 0; i < keys.count(); i++) { + KisID id(*(keys.at(i))); + m_popup . insertItem(id.name(), static_cast<int>(i)); + } + + producerChanged(0); +} + +HistogramDockerUpdater::HistogramDockerUpdater(QObject* /*parent*/, KisHistogramSP h, KisHistogramView* v, + KisAccumulatingHistogramProducer* p) + : m_histogram(h), m_view(v), m_producer(p) +{ + connect(p, SIGNAL(completed()), this, SLOT(completed())); +} + +void HistogramDockerUpdater::updated() { + // We don't [!] do m_histogram->updateHistogram();, because that will try to compute + // the histogram synchronously, while we want it asynchronously. + m_producer->addRegionsToBinAsync(); +} + +void HistogramDockerUpdater::completed() { + m_histogram->computeHistogram(); + m_view->updateHistogram(); +} + +#include "histogramdocker.moc" diff --git a/krita/plugins/viewplugins/histogram_docker/histogramdocker.h b/krita/plugins/viewplugins/histogram_docker/histogramdocker.h new file mode 100644 index 00000000..5cc57e18 --- /dev/null +++ b/krita/plugins/viewplugins/histogram_docker/histogramdocker.h @@ -0,0 +1,79 @@ +/* + * This file is part of Krita + * + * Copyright (c) 2005 Bart Coppens <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _HISTOGRAMDOCKER_H_ +#define _HISTOGRAMDOCKER_H_ + +#include <qobject.h> +#include <qpopupmenu.h> + +#include <kparts/plugin.h> +#include <kis_histogram_view.h> +#include <kis_histogram.h> + +#include "kis_cachedhistogram.h" + +class KisAccumulatingHistogramProducer; +class KisColorSpace; +class KisHistogramView; +class KisView; +class KisColorSpace; + +class KritaHistogramDocker : public KParts::Plugin +{ +Q_OBJECT +public: + KritaHistogramDocker(QObject *parent, const char *name, const QStringList &); + virtual ~KritaHistogramDocker(); +private slots: + void producerChanged(int pos); + void popupMenu(const QPoint & pos); + void colorSpaceChanged(KisColorSpace* cs); +private: + KisHistogramProducerFactory* m_factory; + KisCachedHistogramObserver::Producers m_producers; + KisAccumulatingHistogramProducer* m_producer; + KisColorSpace* m_cs; + KisView* m_view; + KisHistogramView* m_hview; + KisImageRasteredCache* m_cache; + QPopupMenu m_popup; + KisHistogramSP m_histogram; + uint m_currentProducerPos; +}; + +class KisGenericRGBHistogramProducerFactory; + +class HistogramDockerUpdater : public QObject { +Q_OBJECT +public: + HistogramDockerUpdater(QObject* parent, KisHistogramSP h, KisHistogramView* v, + KisAccumulatingHistogramProducer* p); +public slots: + void updated(); +private slots: + void completed(); +private: + KisHistogramSP m_histogram; + KisHistogramView* m_view; + KisAccumulatingHistogramProducer* m_producer; +}; + +#endif //_HISTOGRAMDOCKER_H_ diff --git a/krita/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cc b/krita/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cc new file mode 100644 index 00000000..f899f2af --- /dev/null +++ b/krita/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cc @@ -0,0 +1,102 @@ +/* + * This file is part of Krita + * + * Copyright (c) 2005 Bart Coppens <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <qthread.h> +#include <qapplication.h> +#include <qevent.h> + +#include "kis_accumulating_producer.h" + +static const int EmitCompletedType = QEvent::User + 1; + +/** + * The threaded producer definition in c++ file because this is really an internal affair. + * Note that since we _know_ that we'll only have a single instance of it running, at most, + * we don't care too much about locking and synchronization + **/ +class KisAccumulatingHistogramProducer::ThreadedProducer : public QThread { + KisAccumulatingHistogramProducer* m_source; + bool m_stop; +protected: + virtual void run(); +public: + ThreadedProducer(KisAccumulatingHistogramProducer* source) + : m_source(source), m_stop(false) {} + void cancel() { m_stop = true; } +}; + +KisAccumulatingHistogramProducer::KisAccumulatingHistogramProducer(KisCachedHistogramObserver::Producers* source) + : KisBasicHistogramProducer( + KisID("ACCHISTO", ""), + source->at(0)->channels().count(), + source->at(0)->numberOfBins(), + 0), + m_source(source) +{ + m_thread = new ThreadedProducer(this); +} + +KisAccumulatingHistogramProducer::~KisAccumulatingHistogramProducer() { + m_thread->cancel(); + m_thread->wait(); + delete m_thread; +} + +void KisAccumulatingHistogramProducer::addRegionsToBinAsync() { + m_thread->cancel(); + m_thread->wait(); + clear(); + m_thread->start(); +} + +void KisAccumulatingHistogramProducer::ThreadedProducer::run() { + m_stop = false; + + uint count = m_source->m_source->count(); // Talk about bad naming schemes... + KisCachedHistogramObserver::Producers* source = m_source->m_source; + QValueVector<vBins>& bins = m_source->m_bins; + int channels = m_source->m_channels; + int nrOfBins = m_source->m_nrOfBins; + + for (uint i = 0; i < count && !m_stop; i++) { + KisHistogramProducer* p = source->at(i); + m_source->m_count += p->count(); + + for (int j = 0; j < channels && !m_stop; j++) { + for (int k = 0; k < nrOfBins; k++) { + bins.at(j).at(k) += p->getBinAt(j, k); + } + } + } + + if (!m_stop) { + // This function is thread-safe; and it takes ownership of the event + QApplication::postEvent(m_source, new QCustomEvent(EmitCompletedType)); + } +} + +void KisAccumulatingHistogramProducer::customEvent(QCustomEvent* e) { + if (e->type() == EmitCompletedType) { + emit completed(); + } +} + +#include "kis_accumulating_producer.moc" + diff --git a/krita/plugins/viewplugins/histogram_docker/kis_accumulating_producer.h b/krita/plugins/viewplugins/histogram_docker/kis_accumulating_producer.h new file mode 100644 index 00000000..4ef9f02a --- /dev/null +++ b/krita/plugins/viewplugins/histogram_docker/kis_accumulating_producer.h @@ -0,0 +1,76 @@ +/* + * This file is part of Krita + * + * Copyright (c) 2005 Bart Coppens <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_ACCUMULATING_PRODUCER_H_ +#define _KIS_ACCUMULATING_PRODUCER_H_ + +#include <qobject.h> + +#include <kis_basic_histogram_producers.h> +#include "kis_cachedhistogram.h" + +/** + * Kept very minimalistic because all options would require much reiterating which we don't want. + * This class is multithreading! Don't expect it to contain the right data after an + * addRegionsToBinAsync call, but await it's completed() signal. Also beware! This function + * _does_ clear() before addRegionsToBinAsync! (hence not conforming to the regular semantics + * of HistogramProducers if you'd take addRegionsToBinAsync = addRegionToBin, but since that is + * already violated with the asynchronousity of it that is not really an issue anymore, I think) + **/ +class KisAccumulatingHistogramProducer : public QObject, public KisBasicHistogramProducer { +Q_OBJECT +public: + KisAccumulatingHistogramProducer(KisCachedHistogramObserver::Producers* source); + ~KisAccumulatingHistogramProducer(); + /// Does _nothing_, use addRegionsToBinAsync + virtual void addRegionToBin(Q_UINT8 *, Q_UINT8*, Q_UINT32, KisColorSpace *) {} + virtual void addRegionsToBinAsync(); + virtual QString positionToString(double pos) const + { return m_source->at(0)->positionToString(pos); } + + virtual void setView(double, double) {} // No view support + virtual double maximalZoom() const { return 1.0; } + + virtual Q_INT32 numberOfBins() { return m_source->at(0)->numberOfBins(); } + + virtual QValueVector<KisChannelInfo *> channels() { return m_source->at(0)->channels(); } + + /// Call this when the 'source' list has changed colorspace + virtual void changedSourceProducer() { + m_count = m_source->at(0)->channels().count(); + m_external.clear(); + makeExternalToInternal(); + } + +signals: + void completed(); + +protected: + virtual void customEvent(QCustomEvent* e); + /// source already converts external to internal + virtual int externalToInternal(int ext) { return ext; } + KisCachedHistogramObserver::Producers* m_source; + + class ThreadedProducer; + friend class ThreadedProducer; + ThreadedProducer* m_thread; +}; + +#endif // _KIS_ACCUMULATING_PRODUCER_H_ diff --git a/krita/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cc b/krita/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cc new file mode 100644 index 00000000..2b0c9b85 --- /dev/null +++ b/krita/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cc @@ -0,0 +1,37 @@ +/* + * This file is part of Krita + * + * Copyright (c) 2005 Bart Coppens <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <kis_paint_device.h> +#include <kis_iterators_pixel.h> + +#include "kis_cachedhistogram.h" + +void KisCachedHistogramObserver::regionUpdated(KisPaintDeviceSP dev) { + m_producer->clear(); + KisRectIteratorPixel srcIt = dev->createRectIterator(m_x, m_y, m_w, m_h, false); + int i; + while ( !srcIt.isDone() ) { + i = srcIt.nConseqPixels(); + m_producer->addRegionToBin(srcIt.rawData(), srcIt.selectionMask(), i, dev->colorSpace()); + srcIt += i; + if (i == 0) + ++srcIt; + } +} diff --git a/krita/plugins/viewplugins/histogram_docker/kis_cachedhistogram.h b/krita/plugins/viewplugins/histogram_docker/kis_cachedhistogram.h new file mode 100644 index 00000000..dfe7a05e --- /dev/null +++ b/krita/plugins/viewplugins/histogram_docker/kis_cachedhistogram.h @@ -0,0 +1,53 @@ +/* + * This file is part of Krita + * + * Copyright (c) 2005 Bart Coppens <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _CACHED_HISTOGRAM_H_ +#define _CACHED_HISTOGRAM_H_ + +#include <qvaluevector.h> +#include <kis_histogram_producer.h> + +#include "kis_imagerasteredcache.h" + +class KisCachedHistogramObserver : public KisImageRasteredCache::Observer { +public: + typedef QValueVector<KisHistogramProducer*> Producers; + KisCachedHistogramObserver(Producers* p, KisHistogramProducerFactory* f, + int x, int y, int w, int h, bool add = true) + : m_producers(p), m_factory(f), m_x(x), m_y(y), m_w(w), m_h(h) + { + m_producer = m_factory->generate(); + if (add) + m_producers->append(m_producer); + } + virtual ~KisCachedHistogramObserver() {} + + virtual Observer* createNew(int x, int y, int w, int h) + { return new KisCachedHistogramObserver(m_producers, m_factory, x, y, w, h); } + + virtual void regionUpdated(KisPaintDeviceSP dev); +private: + Producers* m_producers; + KisHistogramProducerFactory* m_factory; + KisHistogramProducerSP m_producer; + int m_x, m_y, m_w, m_h; +}; + +#endif // _CACHED_HISTOGRAM_H_ diff --git a/krita/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cc b/krita/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cc new file mode 100644 index 00000000..2c6562df --- /dev/null +++ b/krita/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cc @@ -0,0 +1,162 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Bart Coppens <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#include <cmath> + +#include <qapplication.h> + +#include <kdebug.h> + +#include <kis_doc.h> +#include <kis_global.h> +#include <kis_types.h> +#include <kis_view.h> + +#include "kis_imagerasteredcache.h" + +KisImageRasteredCache::KisImageRasteredCache(KisView* view, Observer* o) + : m_observer(o->createNew(0, 0, 0, 0)), m_view(view) +{ + m_busy = false; + m_imageProjection = 0; + m_rasterSize = 64*4; + m_timeOutMSec = 1000; + + KisImageSP img = view->canvasSubject()->currentImg(); + + if (!img) { + return; + } + + imageSizeChanged(img->width(), img->height()); + + connect(img, SIGNAL(sigImageUpdated(QRect)), + this, SLOT(imageUpdated(QRect))); + connect(img, SIGNAL(sigSizeChanged(Q_INT32, Q_INT32)), + this, SLOT(imageSizeChanged(Q_INT32, Q_INT32))); + connect(&m_timer, SIGNAL(timeout()), this, SLOT(timeOut())); +} + +KisImageRasteredCache::~KisImageRasteredCache() { + cleanUpElements(); +} + +void KisImageRasteredCache::imageUpdated(QRect rc) { + + if (rc.isValid()) { + QRect r(0, 0, m_width * m_rasterSize, m_height * m_rasterSize); + r &= rc; + + uint x = static_cast<int>(r.x() / m_rasterSize); + uint y = static_cast<int>(r.y() / m_rasterSize); + uint x2 = static_cast<int>(ceil(float(r.x() + r.width()) / float(m_rasterSize))); + uint y2 = static_cast<int>(ceil(float(r.y() + r.height()) / float(m_rasterSize))); + + if (!m_raster.empty()) { + for ( ; x < x2; x++) { + for (uint i = y; i < y2; i++) { + if (x < m_raster.size()) { + if (i < m_raster.at(x).size()) { + Element* e = m_raster.at(x).at(i); + if (e && e->valid) { + e->valid = false; + m_queue.push_back(e); + } + } + } + } + } + } + } + + if (!m_busy) { + // If the timer is already started, this resets it. That way, we update always + // m_timeOutMSec milliseconds after the lastly monitored activity + m_timer.start(m_timeOutMSec, true); // true->singleshot + } +} + +void KisImageRasteredCache::imageSizeChanged(Q_INT32 w, Q_INT32 h) { + + KisImageSP image = m_view->canvasSubject()->currentImg(); + + cleanUpElements(); + m_busy = false; + + m_width = static_cast<int>(ceil(float(w) / float(m_rasterSize))); + m_height = static_cast<int>(ceil(float(h) / float(m_rasterSize))); + + m_raster.resize(m_width); + + int rasterX = 0; + + for (int i = 0; i < m_width * m_rasterSize; i += m_rasterSize) { + int rasterY = 0; + + m_raster.at(rasterX).resize(m_height + 1); + + for (int j = 0; j < m_height * m_rasterSize; j += m_rasterSize) { + Element* e = new Element(m_observer->createNew(i, j, m_rasterSize, m_rasterSize)); + m_raster.at(rasterX).at(rasterY) = e; + rasterY++; + } + rasterX++; + } + + imageUpdated(QRect(0,0, image->width(), image->height())); +} + +void KisImageRasteredCache::timeOut() { + m_busy = true; + KisImageSP img = m_view->canvasSubject()->currentImg(); + + // Temporary cache: while we are busy, we won't get the mergeImage time and again. + if (!m_imageProjection) + m_imageProjection = img->mergedImage(); + + // Pick one element of the cache, and update it + if (!m_queue.isEmpty()) { + m_queue.front()->observer->regionUpdated(m_imageProjection); + m_queue.front()->valid = true; + m_queue.pop_front(); + } + + // If there are still elements, we need to be called again (this emulates processEvents) + if (!m_queue.isEmpty()) { + QTimer::singleShot(0, this, SLOT(timeOut())); + } else { + emit cacheUpdated(); + m_imageProjection = 0; + m_busy = false; + } +} + +void KisImageRasteredCache::cleanUpElements() { + for (uint i = 0; i < m_raster.count(); i++) { + for (uint j = 0; j < m_raster.at(i).count(); j++) { + delete m_raster.at(i).at(j); + } + m_raster.at(i).clear(); + } + m_raster.clear(); + m_queue.clear(); +} + +#include "kis_imagerasteredcache.moc" diff --git a/krita/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.h b/krita/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.h new file mode 100644 index 00000000..6335eadb --- /dev/null +++ b/krita/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.h @@ -0,0 +1,80 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Bart Coppens <[email protected]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ + +#ifndef _KIS_IMAGE_RASTERED_CACHE_H_ +#define _KIS_IMAGE_RASTERED_CACHE_H_ + +#include <qobject.h> +#include <qvaluevector.h> +#include <qvaluelist.h> +#include <qtimer.h> + +#include <kis_paint_device.h> + +class KisView; + +class KisImageRasteredCache : public QObject { +Q_OBJECT + +public: + class Observer { + public: + virtual Observer* createNew(int x, int y, int w, int h) = 0; + virtual void regionUpdated(KisPaintDeviceSP dev) = 0; + virtual ~Observer() {} + }; + + KisImageRasteredCache(KisView* view, Observer* o); + virtual ~KisImageRasteredCache(); + +signals: + void cacheUpdated(); + +private slots: + void imageUpdated(QRect rc); + void imageSizeChanged(Q_INT32 w, Q_INT32 h); + void timeOut(); + +private: + class Element { + public: + Element(Observer* o) : observer(o), valid(true) {} + Observer* observer; + bool valid; + }; + typedef QValueVector< QValueVector<Element*> > Raster; + typedef QValueList<Element*> Queue; + + void cleanUpElements(); + + Observer* m_observer; + Raster m_raster; + Queue m_queue; + QTimer m_timer; + int m_timeOutMSec; + int m_rasterSize; + int m_width, m_height; + KisView * m_view; + bool m_busy; + + KisPaintDeviceSP m_imageProjection; +}; + +#endif // _KIS_IMAGE_RASTERED_CACHE_H_ diff --git a/krita/plugins/viewplugins/histogram_docker/kritahistogramdocker.desktop b/krita/plugins/viewplugins/histogram_docker/kritahistogramdocker.desktop new file mode 100644 index 00000000..1603058d --- /dev/null +++ b/krita/plugins/viewplugins/histogram_docker/kritahistogramdocker.desktop @@ -0,0 +1,40 @@ +[Desktop Entry] +Name=Histogram Docker +Name[ca]=Amarrador de l'histograma +Name[cy]=Bachydd Histogram +Name[da]=Histogramdokning +Name[de]=Histogramm-Docker +Name[el]=Προσάρτηση ιστογράμματος +Name[eo]=Histogramdokilo +Name[es]=Anclaje del histograma +Name[et]=Histogrammi dokk +Name[fa]=پیونددهندۀ سابقهنما +Name[fr]=Ancrage d'histogramme +Name[fy]=Histogramkomponint +Name[gl]=Acoplador de Histogramas +Name[hu]=Hisztogramdokkoló +Name[is]=Súluritsspjald +Name[it]=Aggancia-istogrammi +Name[ja]=ヒストグラムドッカー +Name[km]=កន្លែងចតអ៊ីស្តូក្រាម +Name[nb]=Histogramdokker +Name[nds]=Histogramm-Docker +Name[ne]=हिस्टोग्राम डकर +Name[nl]=Histogramcomponent +Name[pl]=Doker histogramu +Name[pt]=Acoplador de Histogramas +Name[pt_BR]=Acoplador de Histogramas +Name[ru]=Панель гистограммы +Name[sk]=Histogram +Name[sl]=Histogram +Name[sr]=Сидраш хистограма +Name[sr@Latn]=Sidraš histograma +Name[sv]=Histogramdockning +Name[uk]=Швартувальник гістограм +Name[uz]=Gistogramma paneli +Name[uz@cyrillic]=Гистограмма панели +Name[zh_TW]=直方圖停駐點 +ServiceTypes=Krita/ViewPlugin +Type=Service +X-KDE-Library=kritahistogramdocker +X-Krita-Version=2 diff --git a/krita/plugins/viewplugins/histogram_docker/kritahistogramdocker.rc b/krita/plugins/viewplugins/histogram_docker/kritahistogramdocker.rc new file mode 100644 index 00000000..525fd65b --- /dev/null +++ b/krita/plugins/viewplugins/histogram_docker/kritahistogramdocker.rc @@ -0,0 +1,3 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="kritahistogramdocker" version="1"> +</kpartgui>
\ No newline at end of file |