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/ui/kis_previewwidget.cc | |
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/ui/kis_previewwidget.cc')
-rw-r--r-- | chalk/ui/kis_previewwidget.cc | 409 |
1 files changed, 409 insertions, 0 deletions
diff --git a/chalk/ui/kis_previewwidget.cc b/chalk/ui/kis_previewwidget.cc new file mode 100644 index 00000000..c9c2a766 --- /dev/null +++ b/chalk/ui/kis_previewwidget.cc @@ -0,0 +1,409 @@ +/* + * kis_previewwidget.cc - part of Chalk + * + * Copyright (c) 2001 John Califf <[email protected]> + * Copyright (c) 2004 Bart Coppens <[email protected]> + * Copyright (c) 2005 Cyrille Berger <[email protected]> + * Copyright (c) 2007 Ben Schleimer <[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 <tqcheckbox.h> +#include <tqradiobutton.h> +#include <tqpainter.h> +#include <tqpoint.h> +#include <tqpushbutton.h> +#include <tqlayout.h> +#include <tqlabel.h> +#include <tqapplication.h> +#include <tqcolor.h> +#include <tqgroupbox.h> +#include <tqcursor.h> +#include <tqtimer.h> + +#include <kdebug.h> +#include <kiconloader.h> +#include <kpushbutton.h> + +#include <kis_cursor.h> +#include <kis_colorspace.h> +#include <kis_colorspace_factory_registry.h> +#include <kis_config.h> +#include <kis_filter_strategy.h> +#include <kis_global.h> +#include <kis_image.h> +#include <kis_layer.h> +#include <kis_paint_layer.h> +#include <kis_group_layer.h> +#include <kis_meta_registry.h> +#include <kis_painter.h> +#include <kis_profile.h> +#include <kis_types.h> +#include <kis_undo_adapter.h> +#include <kis_label_progress.h> +#include <kis_selection.h> +#include <kis_transform_worker.h> + +#include "kis_previewwidgetbase.h" +#include "kis_previewwidget.h" +#include "imageviewer.h" + +static const int ZOOM_PAUSE = 100; +static const int FILTER_PAUSE = 500; +static const double ZOOM_FACTOR = 1.1; + +KisPreviewWidget::KisPreviewWidget( TQWidget* tqparent, const char* name ) + : PreviewWidgetBase( tqparent, name ) + , m_autoupdate(true) + , m_previewIsDisplayed(true) + , m_scaledOriginal() + , m_dirtyOriginal(true) + , m_origDevice(new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getRGB8(), "temp")) + , m_scaledPreview() + , m_dirtyPreview(true) + , m_previewDevice(new KisPaintDevice(KisMetaRegistry::instance()->csRegistry()->getRGB8(), "temp")) + , m_scaledImage(NULL) + , m_filterZoom(1.0) + , m_zoom(-1.0) + , m_profile(NULL) + , m_progress( 0 ) + , m_zoomTimer(new TQTimer(this)) + , m_filterTimer(new TQTimer(this)) + , m_firstFilter(true) + , m_firstZoom(true) +{ + btnZoomIn->setIconSet(KGlobal::instance()->iconLoader()->loadIconSet( "viewmag+", KIcon::MainToolbar, 16 )); + connect(btnZoomIn, TQT_SIGNAL(clicked()), this, TQT_SLOT(zoomIn())); + btnZoomOut->setIconSet(KGlobal::instance()->iconLoader()->loadIconSet( "viewmag-", KIcon::MainToolbar, 16 )); + connect(btnZoomOut, TQT_SIGNAL(clicked()), this, TQT_SLOT(zoomOut())); + btnUpdate->setIconSet(KGlobal::instance()->iconLoader()->loadIconSet( "reload", KIcon::MainToolbar, 16 )); + connect(btnUpdate, TQT_SIGNAL(clicked()), this, TQT_SLOT(forceUpdate())); + + connect(radioBtnPreview, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(setPreviewDisplayed(bool))); + + connect(checkBoxAutoUpdate, TQT_SIGNAL(toggled(bool)), this, TQT_SLOT(slotSetAutoUpdate(bool))); + btnZoomOneToOne->setIconSet(KGlobal::instance()->iconLoader()->loadIconSet( "viewmag1", KIcon::MainToolbar, 16 )); + connect(btnZoomOneToOne, TQT_SIGNAL(clicked()), this, TQT_SLOT(zoomOneToOne())); + + m_progress = new KisLabelProgress(frmProgress); + m_progress->setMaximumHeight(fontMetrics().height() ); + TQVBoxLayout *vbox = new TQVBoxLayout( frmProgress ); + vbox->addWidget(m_progress); + m_progress->hide(); + + connect(m_zoomTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(updateZoom())); + connect(m_filterTimer, TQT_SIGNAL(timeout()), this, TQT_SLOT(runFilterHelper())); + +/* kToolBar1->insertLineSeparator(); + kToolBar1->insertButton("reload",2, true, i18n("Update")); + connect(kToolBar1->getButton(2),TQT_SIGNAL(clicked()),this,TQT_SLOT(forceUpdate())); + + kToolBar1->insertButton("",3, true, i18n("Auto Update")); + connect(kToolBar1->getButton(3),TQT_SIGNAL(clicked()),this,TQT_SLOT(toggleAutoUpdate())); + + kToolBar1->insertButton("",4, true, i18n("Switch")); + connect(kToolBar1->getButton(4),TQT_SIGNAL(clicked()),this,TQT_SLOT(toggleImageDisplayed()));*/ +// these currently don't yet work, reenable when they do work :) (TZ-12-2005) +// TODO reenable these +// kToolBar1->insertButton("",5, true, i18n("Popup Original and Preview")); +} + +KisPreviewWidget::~KisPreviewWidget() { } + +void KisPreviewWidget::forceUpdate() +{ + if(m_previewIsDisplayed) + { + m_groupBox->setTitle(m_origDevice->name()); + emit updated(); + } +} + +void KisPreviewWidget::slotSetDevice(KisPaintDeviceSP dev) +{ + Q_ASSERT( dev ); + + if (!dev) return; + + m_origDevice = dev; + m_previewDevice = dev; + m_filterZoom = 1.0; + + KisConfig cfg; + TQString monitorProfileName = cfg.monitorProfile(); + m_profile = KisMetaRegistry::instance()->csRegistry()->getProfileByName(monitorProfileName); + + TQRect r = dev->exactBounds(); + + m_groupBox->setTitle(i18n("Preview: ") + dev->name()); + m_previewIsDisplayed = true; + + m_zoom = -1.0; + zoomChanged(double(m_preview->width()) / double(r.width()) ); +} + +void KisPreviewWidget::updateZoom() +{ + TQApplication::setOverrideCursor(KisCursor::waitCursor()); + + if(m_previewIsDisplayed) + { + if(m_dirtyPreview) + { + TQSize r = m_previewDevice->extent().size(); + int w = r.width(), h = r.height(); + int sw = int(ceil(m_zoom * w / m_filterZoom)); + int sh = int(ceil(m_zoom * h / m_filterZoom)); + m_dirtyPreview = false; + m_scaledPreview = m_previewDevice->convertToTQImage(m_profile, 0, 0, w, h); + m_scaledPreview = m_scaledPreview.scale(sw,sh, TQ_ScaleMax); // Use scale instead of smoothScale for speed up + } + m_preview->setImage(m_scaledPreview); + } else + { + if(m_dirtyOriginal) + { + TQSize r = m_origDevice->extent().size(); + int w = r.width(), h = r.height(); + int sw = int(ceil(m_zoom * w)); + int sh = int(ceil(m_zoom * h)); + m_dirtyOriginal = false; + m_scaledOriginal = m_origDevice->convertToTQImage(m_profile, 0, 0, w, h); + m_scaledOriginal = m_scaledOriginal.scale(sw,sh, TQ_ScaleMax); // Use scale instead of smoothScale for speed up + } + m_preview->setImage(m_scaledOriginal); + } + + TQApplication::restoreOverrideCursor(); +} + +void KisPreviewWidget::slotSetAutoUpdate(bool set) { + m_autoupdate = set; +} + +void KisPreviewWidget::wheelEvent(TQWheelEvent * e) +{ + if (e->delta() > 0) { + zoomIn(); + } else { + zoomOut(); + } + e->accept(); +} + +void KisPreviewWidget::setPreviewDisplayed(bool v) +{ + if(v != m_previewIsDisplayed) + { + m_previewIsDisplayed = v; + if(m_previewIsDisplayed) { + m_groupBox->setTitle(i18n("Preview: ") + m_origDevice->name()); + } else { + m_groupBox->setTitle(i18n("Original: ") + m_origDevice->name()); + } + // Call directly without any pause because there is no scaling + updateZoom(); + } +} + +void KisPreviewWidget::needUpdate() +{ + if(m_previewIsDisplayed) + m_groupBox->setTitle(i18n("Preview (needs update)")); +} + +bool KisPreviewWidget::getAutoUpdate() const { + return m_autoupdate; +} + +void KisPreviewWidget::zoomChanged(const double zoom) +{ + // constrain the zoom + double tZoom = zoom; + if(zoom <= 1./8.) { tZoom = 1./8.; } + if(zoom > 8.) { tZoom = 8.; } + + if(tZoom != m_zoom) + { + m_zoom = tZoom; + m_dirtyOriginal = true; + m_dirtyPreview = true; + + if(m_firstZoom) { + m_firstZoom = false; + updateZoom(); + } else { + m_zoomTimer->start(ZOOM_PAUSE, true); + } + } +} + +void KisPreviewWidget::zoomIn() { + zoomChanged(m_zoom * ZOOM_FACTOR); +} + +void KisPreviewWidget::zoomOut() { + zoomChanged(m_zoom / ZOOM_FACTOR); +} + +void KisPreviewWidget::zoomOneToOne() { + zoomChanged(1.0); +} + +static inline void cropDevice(KisPaintDevice * device, const double & zoom) { + TQRect r = device->exactBounds(); + r.setX(int(zoom * r.x()) ); + r.setY(int(zoom * r.y()) ); + r.setWidth(int(zoom * r.width()) ); + r.setHeight(int(zoom * r.height()) ); + device->crop(r); +} + +class MyCropVisitor : public KisLayerVisitor { + const double m_zoom; + +public: + MyCropVisitor(const double & z) : m_zoom(z) { } + virtual ~MyCropVisitor() { } + + virtual bool visit(KisPaintLayer *layer) { + KisPaintDeviceSP device = layer->paintDevice(); + ::cropDevice(device.data(), m_zoom); + // Make sure we have a tight fit for the selection + if(device->hasSelection()) { + ::cropDevice(device->selection().data(), m_zoom); + } + + return true; + } + virtual bool visit(KisGroupLayer *layer) { + for(KisLayerSP l = layer->firstChild(); l; l = l->nextSibling()) { + l->accept(*this); + } + return true; + } + virtual bool visit(KisPartLayer *) { return true; } + virtual bool visit(KisAdjustmentLayer *) { return true; } +}; + +void KisPreviewWidget::runFilter(KisFilter * filter, KisFilterConfiguration * config) { + if(!filter) return; + if(!config) return; + + m_filter = filter; + m_config = config; + + if(m_firstFilter) { + m_firstFilter = false; + runFilterHelper(); + } else { + m_filterTimer->start(FILTER_PAUSE, true); + } +} + +/** + * XXX: Fix the situations which m_origDevice is NOT associated with a image. + * If it comes from a adjustment layer or projection or thumbnail. Currently, nothing happens + */ +void KisPreviewWidget::runFilterHelper() { + + m_filterZoom = m_zoom; + // Dont scale more then 1.0 so we don't waste time in preview widget for large scaling. + if(m_filterZoom > 1.0) { + m_filterZoom = 1.0; + } + + KisPaintDeviceSP scaledDevice; + KisHermiteFilterStrategy strategy; + + // Copy the image and scale + if (m_origDevice->image()) + { + m_scaledImage = new KisImage(*m_origDevice->image()); + if(!m_origDevice->tqparentLayer()) return; + TQString layerName = m_origDevice->tqparentLayer()->name(); + KisPaintLayerSP pl = ::tqqt_cast<KisPaintLayer*>(m_scaledImage->findLayer(layerName)); + if(!pl) return; + scaledDevice = pl->paintDevice(); + + KisSelectionSP select; + if(scaledDevice->hasSelection()) + { + select = new KisSelection(*scaledDevice->selection()); + scaledDevice->deselect(); + } + // Scale + m_scaledImage->setUndoAdapter(NULL); + m_scaledImage->scale(m_filterZoom, m_filterZoom, NULL, &strategy); + // Scale the selection + if(select) + { + KisPaintDeviceSP t = select.data(); + KisTransformWorker tw(t, m_filterZoom, m_filterZoom, + 0.0, 0.0, 0.0, 0, 0, NULL, &strategy); + tw.run(); + scaledDevice->setSelection(select); + select->setParentLayer(scaledDevice->tqparentLayer()); + } + + // Crop by the zoom value instead of cropping by rectangle. It gives better results + MyCropVisitor v(m_filterZoom); + m_scaledImage->rootLayer()->accept(v); + } else + { + scaledDevice = new KisPaintDevice(*m_origDevice); + KisSelectionSP select; + if(scaledDevice->hasSelection()) + { + select = new KisSelection(*scaledDevice->selection()); + scaledDevice->deselect(); + } + KisTransformWorker tw(scaledDevice, m_filterZoom, m_filterZoom, + 0.0, 0.0, 0.0, 0, 0, NULL, &strategy); + tw.run(); + // Scale the selection + if(select) + { + KisPaintDeviceSP t = select.data(); + KisTransformWorker tw(t, m_filterZoom, m_filterZoom, + 0.0, 0.0, 0.0, 0, 0, NULL, &strategy); + tw.run(); + scaledDevice->setSelection(select); + ::cropDevice(select.data(), m_filterZoom); + } + ::cropDevice(scaledDevice.data(), m_filterZoom); + } + + m_previewDevice = new KisPaintDevice(*scaledDevice); + + // Setup the progress display + m_filter->enableProgress(); + m_progress->setSubject(m_filter, true, true); + m_filter->setProgressDisplay(m_progress); + m_filter->process(scaledDevice, m_previewDevice, m_config, scaledDevice->exactBounds()); + m_filter->disableProgress(); + + m_dirtyPreview = true; + + if(m_firstZoom) { + m_firstZoom = false; + updateZoom(); + } else { + m_zoomTimer->start(ZOOM_PAUSE, true); + } +} + +#include "kis_previewwidget.moc" |