diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2011-06-26 00:41:16 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2011-06-26 00:41:16 +0000 |
commit | 698569f8428ca088f764d704034a1330517b98c0 (patch) | |
tree | bf45be6946ebbbee9cce5a5bcf838f4c952d87e6 /chalk/plugins/viewplugins/histogram_docker | |
parent | 2785103a6bd4de55bd26d79e34d0fdd4b329a73a (diff) | |
download | koffice-698569f8428ca088f764d704034a1330517b98c0.tar.gz koffice-698569f8428ca088f764d704034a1330517b98c0.zip |
Finish rebranding of Krita as Chalk
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/koffice@1238363 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'chalk/plugins/viewplugins/histogram_docker')
11 files changed, 850 insertions, 0 deletions
diff --git a/chalk/plugins/viewplugins/histogram_docker/Makefile.am b/chalk/plugins/viewplugins/histogram_docker/Makefile.am new file mode 100644 index 00000000..64341755 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/Makefile.am @@ -0,0 +1,22 @@ +kde_services_DATA = chalkhistogramdocker.desktop +chalkrcdir = $(kde_datadir)/chalkplugins +chalkrc_DATA = chalkhistogramdocker.rc + +INCLUDES = -I$(srcdir)/../../../sdk \ + -I$(srcdir)/../../../core \ + -I$(srcdir)/../../../chalkcolor/ \ + -I$(srcdir)/../../../ui \ + -I$/../../../ui \ + $(KOFFICE_INCLUDES) \ + $(all_includes) + +chalkhistogramdocker_la_SOURCES = histogramdocker.cc kis_imagerasteredcache.cc kis_cachedhistogram.cc kis_accumulating_producer.cc + +kde_module_LTLIBRARIES = chalkhistogramdocker.la +noinst_HEADERS = histogramdocker.h kis_imagerasteredcache.h kis_cachedhistogram.h kis_accumulating_producer.h + +chalkhistogramdocker_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) chalkblurfilter_la_LDFLAGS = $(all_libraries) -module $(KDE_PLUGIN) $(LIB_QT) -lkdecore -lkdeui -lkjs -lkdefx -lkio -lkparts -L../../../../chalk/chalkcolor/.libs -lchalkcolor -L../../../../chalk/core/.libs -lchalkimage \ + -L../../../../chalk/ui/.libs -lchalkui -L../../../../lib/kofficeui/.libs -lkofficeui +chalkhistogramdocker_la_LIBADD = ../../../libchalkcommon.la + +chalkhistogramdocker_la_METASOURCES = AUTO diff --git a/chalk/plugins/viewplugins/histogram_docker/chalkhistogramdocker.desktop b/chalk/plugins/viewplugins/histogram_docker/chalkhistogramdocker.desktop new file mode 100644 index 00000000..aba9ded8 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/chalkhistogramdocker.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=Chalk/ViewPlugin +Type=Service +X-KDE-Library=chalkhistogramdocker +X-Chalk-Version=2 diff --git a/chalk/plugins/viewplugins/histogram_docker/chalkhistogramdocker.rc b/chalk/plugins/viewplugins/histogram_docker/chalkhistogramdocker.rc new file mode 100644 index 00000000..2b6006b9 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/chalkhistogramdocker.rc @@ -0,0 +1,3 @@ +<!DOCTYPE kpartgui SYSTEM "kpartgui.dtd"> +<kpartgui library="chalkhistogramdocker" version="1"> +</kpartgui>
\ No newline at end of file diff --git a/chalk/plugins/viewplugins/histogram_docker/histogramdocker.cc b/chalk/plugins/viewplugins/histogram_docker/histogramdocker.cc new file mode 100644 index 00000000..df5de24a --- /dev/null +++ b/chalk/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 <tqtooltip.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<ChalkHistogramDocker> ChalkHistogramDockerFactory; +K_EXPORT_COMPONENT_FACTORY( chalkhistogramdocker, ChalkHistogramDockerFactory( "chalk" ) ) + +ChalkHistogramDocker::ChalkHistogramDocker(TQObject *tqparent, const char *name, const TQStringList&) + : KParts::Plugin(tqparent, name) +{ + + if ( tqparent->inherits("KisView") ) { + m_view = dynamic_cast<KisView*>(tqparent); + + setInstance(ChalkHistogramDockerFactory::instance()); + setXMLFile(locate("data","chalkplugins/chalkhistogramdocker.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); + TQToolTip::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, TQT_SIGNAL(rightClicked(const TQPoint&)), + this, TQT_SLOT(popupMenu(const TQPoint&))); + connect(m_cache, TQT_SIGNAL(cacheUpdated()), + new HistogramDockerUpdater(this, m_histogram, m_hview, m_producer), TQT_SLOT(updated())); + connect(&m_popup, TQT_SIGNAL(activated(int)), + this, TQT_SLOT(producerChanged(int))); + connect(img, TQT_SIGNAL(sigColorSpaceChanged(KisColorSpace*)), + this, TQT_SLOT(colorSpaceChanged(KisColorSpace*))); // No need to force updates here + + // Add it to the control palette + m_view->canvasSubject()->paletteManager()->addWidget( + m_hview, "histodocker", chalk::CONTROL_PALETTE); + } else { + m_cache = 0; + } +} + +ChalkHistogramDocker::~ChalkHistogramDocker() +{ + uint count = m_producers . count(); + for (uint i = 0; i < count; i++) { + delete m_producers . at(i); + } + + if (m_cache) + m_cache->deleteLater(); +} + +void ChalkHistogramDocker::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, TQT_SIGNAL(cacheUpdated()), + new HistogramDockerUpdater(this, m_histogram, m_hview, m_producer), TQT_SLOT(updated())); + } +} + +void ChalkHistogramDocker::popupMenu(const TQPoint& pos) +{ + m_popup.popup(pos, m_currentProducerPos); +} + +void ChalkHistogramDocker::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(TQObject* /*tqparent*/, KisHistogramSP h, KisHistogramView* v, + KisAccumulatingHistogramProducer* p) + : m_histogram(h), m_view(v), m_producer(p) +{ + connect(p, TQT_SIGNAL(completed()), this, TQT_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/chalk/plugins/viewplugins/histogram_docker/histogramdocker.h b/chalk/plugins/viewplugins/histogram_docker/histogramdocker.h new file mode 100644 index 00000000..ade0650f --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/histogramdocker.h @@ -0,0 +1,81 @@ +/* + * This file is part of Chalk + * + * 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 <tqobject.h> +#include <tqpopupmenu.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 ChalkHistogramDocker : public KParts::Plugin +{ +Q_OBJECT + TQ_OBJECT +public: + ChalkHistogramDocker(TQObject *tqparent, const char *name, const TQStringList &); + virtual ~ChalkHistogramDocker(); +private slots: + void producerChanged(int pos); + void popupMenu(const TQPoint & 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; + TQPopupMenu m_popup; + KisHistogramSP m_histogram; + uint m_currentProducerPos; +}; + +class KisGenericRGBHistogramProducerFactory; + +class HistogramDockerUpdater : public TQObject { +Q_OBJECT + TQ_OBJECT +public: + HistogramDockerUpdater(TQObject* tqparent, 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/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cc b/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cc new file mode 100644 index 00000000..217a36d9 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.cc @@ -0,0 +1,102 @@ +/* + * This file is part of Chalk + * + * 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 <tqthread.h> +#include <tqapplication.h> +#include <tqevent.h> + +#include "kis_accumulating_producer.h" + +static const int EmitCompletedType = TQEvent::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 TQThread { + 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; + TQValueVector<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 + TQApplication::postEvent(m_source, new TQCustomEvent(EmitCompletedType)); + } +} + +void KisAccumulatingHistogramProducer::customEvent(TQCustomEvent* e) { + if (e->type() == EmitCompletedType) { + emit completed(); + } +} + +#include "kis_accumulating_producer.moc" + diff --git a/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.h b/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.h new file mode 100644 index 00000000..d74a3ec5 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/kis_accumulating_producer.h @@ -0,0 +1,77 @@ +/* + * This file is part of Chalk + * + * 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 <tqobject.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 TQObject, public KisBasicHistogramProducer { +Q_OBJECT + TQ_OBJECT +public: + KisAccumulatingHistogramProducer(KisCachedHistogramObserver::Producers* source); + ~KisAccumulatingHistogramProducer(); + /// Does _nothing_, use addRegionsToBinAsync + virtual void addRegionToBin(TQ_UINT8 *, TQ_UINT8*, TQ_UINT32, KisColorSpace *) {} + virtual void addRegionsToBinAsync(); + virtual TQString 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 TQ_INT32 numberOfBins() { return m_source->at(0)->numberOfBins(); } + + virtual TQValueVector<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(TQCustomEvent* 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/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cc b/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cc new file mode 100644 index 00000000..1ad197f9 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.cc @@ -0,0 +1,37 @@ +/* + * This file is part of Chalk + * + * 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/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.h b/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.h new file mode 100644 index 00000000..084ff389 --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/kis_cachedhistogram.h @@ -0,0 +1,53 @@ +/* + * This file is part of Chalk + * + * 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 <tqvaluevector.h> +#include <kis_histogram_producer.h> + +#include "kis_imagerasteredcache.h" + +class KisCachedHistogramObserver : public KisImageRasteredCache::Observer { +public: + typedef TQValueVector<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/chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cc b/chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.cc new file mode 100644 index 00000000..19599cd9 --- /dev/null +++ b/chalk/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 <tqapplication.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, TQT_SIGNAL(sigImageUpdated(TQRect)), + this, TQT_SLOT(imageUpdated(TQRect))); + connect(img, TQT_SIGNAL(sigSizeChanged(TQ_INT32, TQ_INT32)), + this, TQT_SLOT(imageSizeChanged(TQ_INT32, TQ_INT32))); + connect(&m_timer, TQT_SIGNAL(timeout()), this, TQT_SLOT(timeOut())); +} + +KisImageRasteredCache::~KisImageRasteredCache() { + cleanUpElements(); +} + +void KisImageRasteredCache::imageUpdated(TQRect rc) { + + if (rc.isValid()) { + TQRect 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(TQ_INT32 w, TQ_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(TQRect(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()) { + TQTimer::singleShot(0, this, TQT_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/chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.h b/chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.h new file mode 100644 index 00000000..7df7df8f --- /dev/null +++ b/chalk/plugins/viewplugins/histogram_docker/kis_imagerasteredcache.h @@ -0,0 +1,81 @@ +/* + * 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 <tqobject.h> +#include <tqvaluevector.h> +#include <tqvaluelist.h> +#include <tqtimer.h> + +#include <kis_paint_device.h> + +class KisView; + +class KisImageRasteredCache : public TQObject { +Q_OBJECT + TQ_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(TQRect rc); + void imageSizeChanged(TQ_INT32 w, TQ_INT32 h); + void timeOut(); + +private: + class Element { + public: + Element(Observer* o) : observer(o), valid(true) {} + Observer* observer; + bool valid; + }; + typedef TQValueVector< TQValueVector<Element*> > Raster; + typedef TQValueList<Element*> Queue; + + void cleanUpElements(); + + Observer* m_observer; + Raster m_raster; + Queue m_queue; + TQTimer 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_ |