diff options
Diffstat (limited to 'chalk/plugins/viewplugins/histogram_docker/histogramdocker.cc')
-rw-r--r-- | chalk/plugins/viewplugins/histogram_docker/histogramdocker.cc | 192 |
1 files changed, 192 insertions, 0 deletions
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 <kde@bartcoppens.be> + * + * 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" |