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/kobirdeyepanel.cpp | |
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/kobirdeyepanel.cpp')
-rw-r--r-- | chalk/ui/kobirdeyepanel.cpp | 619 |
1 files changed, 619 insertions, 0 deletions
diff --git a/chalk/ui/kobirdeyepanel.cpp b/chalk/ui/kobirdeyepanel.cpp new file mode 100644 index 00000000..0cd835b1 --- /dev/null +++ b/chalk/ui/kobirdeyepanel.cpp @@ -0,0 +1,619 @@ +/* + * This file is part of the KDE project + * + * Copyright (c) 2005 Boudewijn Rempt <boud@valdyas.org> + * + * 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 <tqpixmap.h> +#include <tqimage.h> +#include <tqlayout.h> +#include <tqpainter.h> +#include <tqframe.h> +#include <tqlabel.h> +#include <tqtoolbutton.h> +#include <tqslider.h> +#include <tqcursor.h> + +#include <kdebug.h> +#include <kglobalsettings.h> +#include <kaction.h> +#include <ktoolbar.h> +#include <knuminput.h> +#include <klocale.h> + +#include <KoDocument.h> + +#include "wdgbirdeye.h" +#include "kobirdeyepanel.h" +#include "kis_int_spinbox.h" + +KoCanvasAdapter::KoCanvasAdapter() {} +KoCanvasAdapter::~KoCanvasAdapter() {} + +KoZoomAdapter::KoZoomAdapter() {} +KoZoomAdapter::~KoZoomAdapter() {} + +KoThumbnailAdapter::KoThumbnailAdapter() {} +KoThumbnailAdapter::~KoThumbnailAdapter() {} + +KoBirdEyePanel::KoBirdEyePanel( KoZoomAdapter * zoomListener, + KoThumbnailAdapter * thumbnailProvider, + KoCanvasAdapter * canvas, + TQWidget * tqparent, + const char * name, + WFlags f) + : TQWidget(tqparent, name, f) + , m_zoomListener(zoomListener) + , m_thumbnailProvider(thumbnailProvider) + , m_canvas(canvas) + , m_dragging(false) +{ + TQHBoxLayout * l = new TQHBoxLayout(this); + m_page = new WdgBirdEye(this); + m_page->zoom->setRange((int) (TQMAX(1, 100 * zoomListener->getMinZoom())), (int) (100 * zoomListener->getMaxZoom())); + m_page->zoom->setValue(100); + m_page->zoom->setSuffix("%"); + + m_page->toolbar->setIconSize(16); + m_page->view->installEventFilter(this); + m_page->view->setBackgroundMode(TQt::NoBackground); + + m_zoomIn = new KAction( i18n("Zoom In"), "birdeye_zoom_plus", 0, TQT_TQOBJECT(this), TQT_SLOT(zoomPlus()), TQT_TQOBJECT(this), "zoomIn" ); + m_zoomOut = new KAction( i18n("Zoom Out"), "birdeye_zoom_minus", 0, TQT_TQOBJECT(this), TQT_SLOT(zoomMinus()), TQT_TQOBJECT(this), "zoomOut" ); + + l->addWidget(m_page); + + connect(m_page->zoom, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(zoomValueChanged(int))); + connect(m_page->bn100, TQT_SIGNAL(clicked()), TQT_SLOT(zoom100())); + connect(m_page->slZoom, TQT_SIGNAL(valueChanged(int)), TQT_SLOT(sliderChanged( int ))); +} + +KoBirdEyePanel::~KoBirdEyePanel() +{ + delete m_canvas; + delete m_thumbnailProvider; + delete m_zoomListener; +} + +void KoBirdEyePanel::setZoom(int zoom) +{ + m_page->zoom->blockSignals(true); + m_page->slZoom->blockSignals(true); + + m_page->zoom->setValue(zoom); + + if (zoom < 10) { + m_page->slZoom->setValue(0); + } + else if (zoom > 10 && zoom < 100) { + m_page->slZoom->setValue(zoom / 10); + } + else if (zoom >= 100 && zoom < 150) { + m_page->slZoom->setValue(10); + } + else if (zoom >= 150 && zoom < 250) { + m_page->slZoom->setValue(11); + } + else if (zoom >= 250 && zoom < 350) { + m_page->slZoom->setValue(12); + } + else if (zoom >= 350 && zoom < 450) { + m_page->slZoom->setValue(13); + } + else if (zoom >= 450 && zoom < 550) { + m_page->slZoom->setValue(14); + } + else if (zoom >= 550 && zoom < 650) { + m_page->slZoom->setValue(15); + } + else if (zoom >= 650 && zoom < 875) { + m_page->slZoom->setValue(16); + } + else if (zoom >= 875 && zoom < 1150) { + m_page->slZoom->setValue(17); + } + else if (zoom >= 1150 && zoom < 1450) { + m_page->slZoom->setValue(18); + } + else if (zoom >= 1450) { + m_page->slZoom->setValue(19); + } + + + m_page->zoom->blockSignals(false); + m_page->slZoom->blockSignals(false); + + +} + +void KoBirdEyePanel::zoomValueChanged(int zoom) +{ + KoPoint center; + center = m_canvas->visibleArea().center(); + m_zoomListener->zoomTo(center.x(), center.y(), zoom / 100.0); + setZoom(zoom); +} + +void KoBirdEyePanel::zoom100() +{ + zoomValueChanged( 100 ); +} + +void KoBirdEyePanel::sliderChanged( int v ) +{ + if (v < 10) { + zoomValueChanged((v + 1) * 10); + } + else { + switch(v) { + case 10: + zoomValueChanged(100); + break; + case 11: + zoomValueChanged(200); + break; + case 12: + zoomValueChanged(300); + case 13: + zoomValueChanged(400); + break; + case 14: + zoomValueChanged(500); + break; + case 15: + zoomValueChanged(600); + break; + case 16: + zoomValueChanged(750); + break; + case 17: + zoomValueChanged(1000); + break; + case 18: + zoomValueChanged(1300); + break; + case 19: + zoomValueChanged(1600); + break; + } + } +} + +void KoBirdEyePanel::cursorPosChanged(TQ_INT32 xpos, TQ_INT32 ypos) +{ + m_page->txtX->setText(TQString("%L1").tqarg(xpos, 5)); + m_page->txtY->setText(TQString("%L1").tqarg(ypos, 5)); +} + +void KoBirdEyePanel::setThumbnailProvider(KoThumbnailAdapter * thumbnailProvider) +{ + delete m_thumbnailProvider; + m_thumbnailProvider = thumbnailProvider; +} + +void KoBirdEyePanel::slotViewTransformationChanged() +{ + updateVisibleArea(); + renderView(); + m_page->view->update(); + setZoom(tqRound(m_canvas->zoomFactor() * 100)); +} + +void KoBirdEyePanel::slotUpdate(const TQRect & r) +{ + TQRect updateRect = r; + + if (m_thumbnailProvider->pixelSize() != m_documentSize) { + m_documentSize = m_thumbnailProvider->pixelSize(); + fitThumbnailToView(); + updateRect = TQRect(0, 0, m_documentSize.width(), m_documentSize.height()); + } + + updateRect &= TQRect(0, 0, m_documentSize.width(), m_documentSize.height()); + + if (!updateRect.isEmpty() && !m_documentSize.isEmpty()) { + + TQRect thumbnailRect = documentToThumbnail(KoRect::fromTQRect(updateRect)); + + if (!thumbnailRect.isEmpty()) { + + TQImage thumbnailImage = m_thumbnailProvider->image(thumbnailRect, m_thumbnail.size()); + + if (!thumbnailImage.isNull()) { + + Q_ASSERT(thumbnailImage.size() == thumbnailRect.size()); + + TQPainter painter(&m_thumbnail); + + painter.fillRect(thumbnailRect, tqcolorGroup().mid()); + painter.drawImage(thumbnailRect.x(), thumbnailRect.y(), thumbnailImage); + } + } + } + + renderView(); + m_page->view->update(); +} + +TQRect KoBirdEyePanel::documentToThumbnail(const KoRect& docRect) +{ + if (docRect.isEmpty() || m_documentSize.isEmpty() || m_thumbnail.isNull()) { + return TQRect(); + } + + TQ_INT32 thumbnailLeft = static_cast<TQ_INT32>((docRect.left() * m_thumbnail.width()) / m_documentSize.width()); + TQ_INT32 thumbnailRight = static_cast<TQ_INT32>(((docRect.right() + 1) * m_thumbnail.width()) / m_documentSize.width()); + TQ_INT32 thumbnailTop = static_cast<TQ_INT32>((docRect.top() * m_thumbnail.height()) / m_documentSize.height()); + TQ_INT32 thumbnailBottom = static_cast<TQ_INT32>(((docRect.bottom() + 1) * m_thumbnail.height()) / m_documentSize.height()); + + TQRect thumbnailRect(thumbnailLeft, thumbnailTop, thumbnailRight - thumbnailLeft + 1, thumbnailBottom - thumbnailTop + 1); + thumbnailRect &= m_thumbnail.rect(); + + return thumbnailRect; +} + +KoRect KoBirdEyePanel::thumbnailToDocument(const TQRect& thumbnailRect) +{ + if (thumbnailRect.isEmpty() || m_documentSize.isEmpty() || m_thumbnail.isNull()) { + return KoRect(); + } + + double docLeft = (static_cast<double>(thumbnailRect.left()) * m_documentSize.width()) / m_thumbnail.width(); + double docRight = (static_cast<double>(thumbnailRect.right() + 1) * m_documentSize.width()) / m_thumbnail.width(); + double docTop = (static_cast<double>(thumbnailRect.top()) * m_documentSize.height()) / m_thumbnail.height(); + double docBottom = (static_cast<double>(thumbnailRect.bottom() + 1) * m_documentSize.height()) / m_thumbnail.height(); + + KoRect docRect(docLeft, docTop, docRight - docLeft + 1, docBottom - docTop + 1); + docRect &= KoRect(0, 0, m_documentSize.width(), m_documentSize.height()); + + return docRect; +} + +TQPoint KoBirdEyePanel::viewToThumbnail(const TQPoint& viewPoint) +{ + int thumbnailX = (m_viewBuffer.width() - m_thumbnail.width()) / 2; + int thumbnailY = (m_viewBuffer.height() - m_thumbnail.height()) / 2; + + return TQPoint(viewPoint.x() - thumbnailX, viewPoint.y() - thumbnailY); +} + + +void KoBirdEyePanel::zoomMinus() +{ +} + +void KoBirdEyePanel::zoomPlus() +{ +} + +void KoBirdEyePanel::updateVisibleArea() +{ + m_visibleAreaInThumbnail = documentToThumbnail(m_canvas->visibleArea()); +} + + +bool KoBirdEyePanel::eventFilter(TQObject* o, TQEvent* ev) +{ + if (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(m_page->view) && ev->type() == TQEvent::Resize) { + resizeViewEvent(TQT_TQRESIZEEVENT(ev)->size()); + } + + if (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(m_page->view) && ev->type() == TQEvent::Paint) { + paintViewEvent(TQT_TQPAINTEVENT(ev)); + } + + if (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(m_page->view) && ev->type() == TQEvent::MouseMove) { + + TQMouseEvent* me = (TQMouseEvent*)ev; + TQPoint thumbnailPos = viewToThumbnail(me->pos()); + + if (m_dragging) { + handleMouseMoveAction(thumbnailPos); + } else { + handleMouseMove(thumbnailPos); + } + + return true; + } + + if (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(m_page->view) && ev->type() == TQEvent::MouseButtonPress) { + + TQMouseEvent* me = (TQMouseEvent*)ev; + TQPoint thumbnailPos = viewToThumbnail(me->pos()); + + if (me->button() == Qt::LeftButton) { + handleMousePress(thumbnailPos); + } + + return true; + } + + if (TQT_BASE_OBJECT(o) == TQT_BASE_OBJECT(m_page->view) && ev->type() == TQEvent::MouseButtonRelease) { + + TQMouseEvent* me = (TQMouseEvent*)ev; + + if (me->button() == Qt::LeftButton) { + m_dragging = false; + } + + return true; + } + + return m_page->eventFilter(o, ev); +} + +KoBirdEyePanel::enumDragHandle KoBirdEyePanel::dragHandleAt(TQPoint p) +{ + TQRect left = TQRect(m_visibleAreaInThumbnail.left()-1, m_visibleAreaInThumbnail.top()-1, 3, m_visibleAreaInThumbnail.height()+2); + TQRect right = TQRect(m_visibleAreaInThumbnail.right()-1, m_visibleAreaInThumbnail.top()-1, 3, m_visibleAreaInThumbnail.height()+2); + TQRect top = TQRect(m_visibleAreaInThumbnail.left()-1, m_visibleAreaInThumbnail.top()-1, m_visibleAreaInThumbnail.width()+2, 3); + TQRect bottom = TQRect(m_visibleAreaInThumbnail.left()-1, m_visibleAreaInThumbnail.bottom()-1, m_visibleAreaInThumbnail.width()+2, 3); + + if (left.tqcontains(p)) { + return DragHandleLeft; + } + + if (right.tqcontains(p)) { + return DragHandleRight; + } + + if (top.tqcontains(p)) { + return DragHandleTop; + } + + if (bottom.tqcontains(p)) { + return DragHandleBottom; + } + + if (m_visibleAreaInThumbnail.tqcontains(p)) { + return DragHandleCentre; + } + + return DragHandleNone; +} + +void KoBirdEyePanel::handleMouseMove(TQPoint p) +{ + TQCursor cursor; + + switch (dragHandleAt(p)) { + case DragHandleLeft: + case DragHandleRight: + cursor = TQt::sizeHorCursor; + break; + case DragHandleTop: + case DragHandleBottom: + cursor = TQt::sizeVerCursor; + break; + case DragHandleCentre: + cursor = TQt::sizeAllCursor; + break; + default: + case DragHandleNone: + if (TQT_TQRECT_OBJECT(m_thumbnail.rect()).tqcontains(p)) { + cursor = TQt::PointingHandCursor; + } else { + cursor = TQt::arrowCursor; + } + break; + } + + m_page->view->setCursor(cursor); +} + +void KoBirdEyePanel::handleMouseMoveAction(TQPoint p) +{ + if (m_dragging) { + + TQ_INT32 dx = p.x() - m_lastDragPos.x(); + TQ_INT32 dy = p.y() - m_lastDragPos.y(); + + m_lastDragPos = p; + + TQRect thumbnailRect = m_visibleAreaInThumbnail; + + switch (m_dragHandle) { + case DragHandleLeft: { + thumbnailRect.setLeft(thumbnailRect.left()+dx); + break; + } + case DragHandleRight: { + thumbnailRect.setRight(thumbnailRect.right()+dx); + break; + } + case DragHandleTop: { + thumbnailRect.setTop(thumbnailRect.top()+dy); + break; + } + case DragHandleBottom: { + thumbnailRect.setBottom(thumbnailRect.bottom()+dy); + break; + } + case DragHandleCentre: { + thumbnailRect.moveBy(dx, dy); + break; + } + default: + case DragHandleNone: + break; + } + + makeThumbnailRectVisible(thumbnailRect); + } +} + +void KoBirdEyePanel::handleMousePress(TQPoint p) +{ + if (!m_dragging) { + + enumDragHandle dragHandle = dragHandleAt(p); + + if (dragHandle == DragHandleNone) { + if (TQT_TQRECT_OBJECT(m_thumbnail.rect()).tqcontains(p)) { + + // Snap visible area centre to p and begin a centre drag. + + TQRect thumbnailRect = m_visibleAreaInThumbnail; + thumbnailRect.moveCenter(p); + makeThumbnailRectVisible(thumbnailRect); + + m_dragHandle = DragHandleCentre; + m_page->view->setCursor(TQt::sizeAllCursor); + m_dragging = true; + } + } else { + m_dragHandle = dragHandle; + m_dragging = true; + } + m_lastDragPos = p; + } +} + +void KoBirdEyePanel::makeThumbnailRectVisible(const TQRect& r) +{ + if (r.isEmpty()) { + return; + } + + TQRect thumbnailRect = r; + + if (thumbnailRect.left() < m_thumbnail.rect().left()) { + thumbnailRect.moveLeft(m_thumbnail.rect().left()); + } + if (thumbnailRect.right() > m_thumbnail.rect().right()) { + thumbnailRect.moveRight(m_thumbnail.rect().right()); + } + if (thumbnailRect.top() < m_thumbnail.rect().top()) { + thumbnailRect.moveTop(m_thumbnail.rect().top()); + } + if (thumbnailRect.bottom() > m_thumbnail.rect().bottom()) { + thumbnailRect.moveBottom(m_thumbnail.rect().bottom()); + } + + if (thumbnailRect.width() > m_thumbnail.rect().width()) { + thumbnailRect.setLeft(m_thumbnail.rect().left()); + thumbnailRect.setRight(m_thumbnail.rect().right()); + } + if (thumbnailRect.height() > m_thumbnail.rect().height()) { + thumbnailRect.setTop(m_thumbnail.rect().top()); + thumbnailRect.setBottom(m_thumbnail.rect().bottom()); + } + + double zoomFactor = m_canvas->zoomFactor(); + + if (thumbnailRect.size() == m_visibleAreaInThumbnail.size()) { + // No change to zoom + } else if (thumbnailRect.width() != m_visibleAreaInThumbnail.width()) { + + Q_ASSERT(thumbnailRect.height() == m_visibleAreaInThumbnail.height()); + + zoomFactor *= static_cast<double>(m_visibleAreaInThumbnail.width()) / thumbnailRect.width(); + } else { + + Q_ASSERT(thumbnailRect.width() == m_visibleAreaInThumbnail.width()); + + zoomFactor *= static_cast<double>(m_visibleAreaInThumbnail.height()) / thumbnailRect.height(); + } + + if (zoomFactor < m_zoomListener->getMinZoom()) { + zoomFactor = m_zoomListener->getMinZoom(); + } else if (zoomFactor > m_zoomListener->getMaxZoom()) { + zoomFactor = m_zoomListener->getMaxZoom(); + } + + KoRect docRect = thumbnailToDocument(thumbnailRect); + m_zoomListener->zoomTo(docRect.center().x(), docRect.center().y(), zoomFactor); +} + +void KoBirdEyePanel::resizeViewEvent(TQSize size) +{ + m_viewBuffer.resize(size); + fitThumbnailToView(); + slotUpdate(TQRect(0, 0, m_documentSize.width(), m_documentSize.height())); +} + +void KoBirdEyePanel::fitThumbnailToView() +{ + TQRect docRect = TQRect(0, 0, m_thumbnailProvider->pixelSize().width(), m_thumbnailProvider->pixelSize().height()); + TQ_INT32 thumbnailWidth; + TQ_INT32 thumbnailHeight; + + if (docRect.isEmpty()) { + thumbnailWidth = 0; + thumbnailHeight = 0; + } else { + const int thumbnailBorderPixels = 4; + + double xScale = double(m_page->view->contentsRect().width() - thumbnailBorderPixels) / docRect.width(); + double yScale = double(m_page->view->contentsRect().height() - thumbnailBorderPixels) / docRect.height(); + + if (xScale < yScale) { + thumbnailWidth = m_page->view->contentsRect().width() - thumbnailBorderPixels; + thumbnailHeight = TQ_INT32(ceil(docRect.height() * xScale)); + } else { + thumbnailWidth = TQ_INT32(ceil(docRect.width() * yScale)); + thumbnailHeight = m_page->view->contentsRect().height() - thumbnailBorderPixels; + } + } + + m_thumbnail.resize(thumbnailWidth, thumbnailHeight); + updateVisibleArea(); +} + +void KoBirdEyePanel::renderView() +{ + Q_ASSERT(!m_viewBuffer.isNull()); + + if (!m_viewBuffer.isNull()) { + + updateVisibleArea(); + + TQPainter painter(&m_viewBuffer); + + painter.fillRect(0, 0, m_viewBuffer.width(), m_viewBuffer.height(), tqcolorGroup().mid()); + + if (!m_thumbnail.isNull()) { + + int thumbnailX = (m_viewBuffer.width() - m_thumbnail.width()) / 2; + int thumbnailY = (m_viewBuffer.height() - m_thumbnail.height()) / 2; + + painter.drawPixmap(thumbnailX, thumbnailY, m_thumbnail); + + painter.setPen(TQt::red); + painter.drawRect(thumbnailX + m_visibleAreaInThumbnail.x() - 1, + thumbnailY + m_visibleAreaInThumbnail.y() - 1, + m_visibleAreaInThumbnail.width() + 2, + m_visibleAreaInThumbnail.height() + 2); + painter.setPen(TQt::red.light()); + painter.drawRect(thumbnailX + m_visibleAreaInThumbnail.x() - 2, + thumbnailY + m_visibleAreaInThumbnail.y() - 2, + m_visibleAreaInThumbnail.width() + 4, + m_visibleAreaInThumbnail.height() + 4); + } + } +} + +void KoBirdEyePanel::paintViewEvent(TQPaintEvent *e) +{ + Q_ASSERT(!m_viewBuffer.isNull()); + + if (!m_viewBuffer.isNull()) { + bitBlt(m_page->view, e->rect().x(), e->rect().y(), &m_viewBuffer, + e->rect().x(), e->rect().y(), e->rect().width(), e->rect().height()); + } +} + +#include "kobirdeyepanel.moc" |