summaryrefslogtreecommitdiffstats
path: root/kimagemapeditor/imagemap.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kimagemapeditor/imagemap.cpp')
-rw-r--r--kimagemapeditor/imagemap.cpp395
1 files changed, 395 insertions, 0 deletions
diff --git a/kimagemapeditor/imagemap.cpp b/kimagemapeditor/imagemap.cpp
new file mode 100644
index 00000000..665ef000
--- /dev/null
+++ b/kimagemapeditor/imagemap.cpp
@@ -0,0 +1,395 @@
+/***************************************************************************
+ imagemap.cpp - description
+ -------------------
+ begin : Wed Apr 4 2001
+ copyright : (C) 2001 by Jan Schäfer
+ email : j_schaef@informatik.uni-kl.de
+ ***************************************************************************/
+
+/***************************************************************************
+ * *
+ * 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. *
+ * *
+ ***************************************************************************/
+
+#include "imagemap.h"
+#include "kimagemapeditor.h"
+#include "qpainter.h"
+#include "kdebug.h"
+#include <qbitmap.h>
+
+int round(double d) {
+ if ( (d-((int) d)) < 0.5 )
+ return (int) d;
+ else
+ return ((int) d)+1;
+}
+
+ImageMap::ImageMap(QWidget *parent,KImageMapEditor* _imageMapEditor)
+ : QScrollView(parent)
+{
+ imageMapEditor=_imageMapEditor;
+// setPicture(QImage());
+ currentAction=None;
+ currentArea=0L;
+ eraseOldArea=false;
+ oldArea=0L;
+ _zoom=1;
+ viewport()->setMouseTracking(true);
+
+
+}
+
+ImageMap::~ImageMap(){
+}
+
+void ImageMap::setPicture(const QImage &_image) {
+ image=_image;
+ zoomedImage.convertFromImage(image);
+ setZoom(_zoom);
+}
+
+void ImageMap::setZoom(double z) {
+ _zoom=z;
+ imageRect.setHeight(image.height()*_zoom);
+ imageRect.setWidth(image.width()*_zoom);
+ zoomedImage=QPixmap(imageRect.width(),imageRect.height());
+ QPainter p(&zoomedImage);
+ p.scale(z,z);
+ QPixmap pix;
+ pix.convertFromImage(image);
+ // if the picture has transparent areas,
+ // fill them with Gimp like background
+ if (pix.mask()) {
+ QPixmap backPix(32,32);
+ QPainter p2(&backPix);
+ p2.fillRect(0,0,32,32,QColor(156,149,156));
+ p2.fillRect(0,16,16,16,QColor(98,105,98));
+ p2.fillRect(16,0,16,16,QColor(98,105,98));
+ p2.flush();
+ p.setPen(QPen());
+ p.fillRect(imageRect.left(),imageRect.top(),imageRect.width(),imageRect.height(),QBrush(QColor("black"),backPix));
+ }
+ p.drawPixmap(imageRect.left(),imageRect.top(),pix);
+ p.flush();
+ resizeContents(visibleWidth()>imageRect.width() ? visibleWidth() : imageRect.width(),
+ visibleHeight()>imageRect.height() ? visibleHeight() : imageRect.height());
+ repaintContents(0,0,contentsWidth(),contentsHeight(),true);
+}
+
+QPoint ImageMap::translateFromZoom(const QPoint & p) const {
+ return QPoint(p.x()/_zoom,p.y()/_zoom);
+}
+
+QPoint ImageMap::translateToZoom(const QPoint & p) const {
+ return QPoint(round(p.x()*_zoom),round(p.y()*_zoom));
+}
+
+QRect ImageMap::translateToZoom(const QRect & r) const {
+ return QRect(round(r.x()*_zoom),round(r.y()*_zoom),
+ round(r.width()*_zoom),round(r.height()*_zoom));
+}
+
+void ImageMap::contentsMouseDoubleClickEvent(QMouseEvent* e) {
+ QPoint point=e->pos();
+ point-=imageRect.topLeft();
+ point=translateFromZoom(point);
+ if ( currentAction==None &&
+ (currentArea=imageMapEditor->onArea(point)))
+ imageMapEditor->showTagEditor(currentArea);
+
+}
+
+void ImageMap::contentsMousePressEvent(QMouseEvent* e) {
+ drawStart=e->pos();
+ // Check if it's on picture if not
+ // move it to the picture's border
+ if (!imageRect.contains(drawStart)) {
+ if (drawStart.x()>imageRect.right())
+ drawStart.setX(imageRect.right());
+ if (drawStart.x()<imageRect.left())
+ drawStart.setX(imageRect.left());
+ if (drawStart.y()>imageRect.bottom())
+ drawStart.setY(imageRect.bottom());
+ if (drawStart.y()<imageRect.top())
+ drawStart.setY(imageRect.top());
+ }
+
+ // Translate it to picture coordinates
+ drawStart-=imageRect.topLeft();
+ drawStart=translateFromZoom(drawStart);
+ if (currentArea)
+ oldArea=new Area(*currentArea);
+
+ if ( currentAction==None ) {
+ if (e->button()==RightButton) {
+ currentArea=imageMapEditor->onArea(drawStart);
+ imageMapEditor->select(currentArea);
+ imageMapEditor->slotShowPopupMenu(e->globalPos());
+ } else
+ if ((currentArea=imageMapEditor->selected()) &&
+ (currentSelectionPoint=currentArea->onSelectionPoint(drawStart)))
+ {
+ currentAction=MoveSelectionPoint;
+ } else
+ if ((currentArea=imageMapEditor->onArea(drawStart))) {
+ currentAction=MoveArea;
+ imageMapEditor->select(currentArea);
+ } else
+ if (imageMapEditor->currentShapeType()!=Area::None) {
+ currentArea=new Area(imageMapEditor->currentShapeType());
+ currentArea->setRect(QRect(drawStart,drawStart));
+ currentArea->setSelected(false);
+ if (imageMapEditor->selected())
+ imageMapEditor->selected()->setSelected(false);
+ switch (currentArea->type()) {
+ case Area::Rectangle : currentAction=DrawRectangle; break;
+ case Area::Circle : currentAction=DrawCircle; break;
+ case Area::Polygon :
+ currentAction=DrawPolygon;
+ currentArea->addCoord(drawStart);
+ currentSelectionPoint=currentArea->selectionPoints()->last();
+
+ break;
+ default: break;
+ }
+ }
+ // Clicked with the arrow at an areafree position
+ else {
+ currentArea=0L;
+ imageMapEditor->deselectAll();
+ }
+ } else
+ if ( currentAction==DrawPolygon) {
+
+ }
+
+ QRect r;
+ if (oldArea)
+ r=oldArea->selectionRect();
+ if (currentArea) {
+ r= r | currentArea->selectionRect();
+ repaintContents(translateToZoom(r),false);
+ }
+
+}
+
+void ImageMap::contentsMouseReleaseEvent(QMouseEvent *e) {
+ drawEnd=e->pos();
+
+ // Check if it's on picture if not
+ // move it to the picture's border
+ if (!imageRect.contains(drawEnd)) {
+ if (drawEnd.x()>imageRect.right())
+ drawEnd.setX(imageRect.right());
+ if (drawEnd.x()<imageRect.left())
+ drawEnd.setX(imageRect.left());
+ if (drawEnd.y()>imageRect.bottom())
+ drawEnd.setY(imageRect.bottom());
+ if (drawEnd.y()<imageRect.top())
+ drawEnd.setY(imageRect.top());
+ }
+ // Translate it to picture coordinates
+ drawEnd-=imageRect.topLeft();
+ drawEnd=translateFromZoom(drawEnd);
+
+ if (currentAction==DrawCircle || currentAction==DrawRectangle) {
+ imageMapEditor->addArea(currentArea);
+ imageMapEditor->select(currentArea);
+ //imageMapEditor->slotAreaChanged(currentArea);
+ currentAction=None;
+ } else
+ if (currentAction==DrawPolygon) {
+ // If the number of Polygonpoints is more than 2
+ // and clicked on the first PolygonPoint or
+ // the right Button was pressed the Polygon is finished
+ if ((currentArea->selectionPoints()->count()>2)
+ && (currentArea->selectionPoints()->first()->contains(drawEnd)
+ || (e->button()==RightButton)))
+ {
+ currentArea->setFinished(true);
+ imageMapEditor->addArea(currentArea);
+ currentAction=None;
+ } else
+ {
+ currentArea->addCoord(drawEnd);
+ currentSelectionPoint=currentArea->selectionPoints()->last();
+ }
+
+// currentArea->addCoord(drawEnd);
+// currentSelectionPoint=currentArea->selectionPoints()->last();
+ } else
+ if (currentAction==MoveArea || currentAction==MoveSelectionPoint) {
+ imageMapEditor->slotAreaChanged(currentArea);
+ currentAction=None;
+ }
+ else {
+ currentAction=None;
+ }
+ imageMapEditor->slotChangeStatusCoords(drawEnd.x(),drawEnd.y());
+ imageMapEditor->slotUpdateSelectionCoords();
+
+ if (currentArea)
+ repaintArea(*currentArea);
+// repaintContents(0,0,contentsWidth(),contentsHeight(),false);
+}
+
+
+void ImageMap::contentsMouseMoveEvent(QMouseEvent *e) {
+ drawCurrent=e->pos();
+
+ // If outside the image
+ // set it to the border
+ if (!imageRect.contains(drawCurrent)) {
+ if (drawCurrent.x()>imageRect.right())
+ drawCurrent.setX(imageRect.right());
+ if (drawCurrent.x()<imageRect.left())
+ drawCurrent.setX(imageRect.left());
+ if (drawCurrent.y()>imageRect.bottom())
+ drawCurrent.setY(imageRect.bottom());
+ if (drawCurrent.y()<imageRect.top())
+ drawCurrent.setY(imageRect.top());
+ }
+
+ // Translate to image coordinates
+ drawCurrent-=imageRect.topLeft();
+ drawCurrent=translateFromZoom(drawCurrent);
+
+ if (currentAction==DrawRectangle) {
+ // To avoid flicker, only repaint the minimum rect
+ QRect oldRect=translateToZoom(currentArea->rect());
+ currentArea->setRect(QRect(drawStart,drawCurrent).normalize());
+ QRect newRect=translateToZoom(currentArea->rect());
+ QRect r=oldRect | newRect;
+ repaintContents(r,false);
+ imageMapEditor->slotUpdateSelectionCoords(currentArea->rect());
+ } else
+ if (currentAction==DrawCircle) {
+ QRect oldRect=translateToZoom(currentArea->rect());
+ currentArea->setRect(QRect(drawStart,drawCurrent).normalize());
+ QRect newRect=translateToZoom(currentArea->rect());
+ QRect r=oldRect | newRect;
+ repaintContents(r,false);
+ imageMapEditor->slotUpdateSelectionCoords(currentArea->rect());
+ } else
+ if ( currentAction==DrawPolygon ) {
+ QRect oldRect=translateToZoom(currentArea->rect());
+ currentArea->moveSelectionPoint(currentSelectionPoint,drawCurrent);
+ QRect newRect=translateToZoom(currentArea->rect());
+ QRect r=oldRect | newRect;
+ repaintContents(r,false);
+ imageMapEditor->slotUpdateSelectionCoords(currentArea->rect());
+ } else
+ if ( currentAction==MoveArea ) {
+ QRect oldRect=translateToZoom(currentArea->selectionRect());
+ currentArea->moveBy((drawCurrent-drawStart).x(),(drawCurrent-drawStart).y());
+ QRect newRect=translateToZoom(currentArea->selectionRect());
+ QRect r=oldRect | newRect;
+ repaintContents(r,false);
+ drawStart=drawCurrent;
+ imageMapEditor->slotUpdateSelectionCoords();
+ } else
+ if ( currentAction==MoveSelectionPoint ) {
+ QRect oldRect=translateToZoom(currentArea->selectionRect());
+ currentArea->moveSelectionPoint(currentSelectionPoint,drawCurrent);
+ QRect newRect=translateToZoom(currentArea->selectionRect());
+ QRect r=oldRect | newRect;
+ repaintContents(r,false);
+ imageMapEditor->slotUpdateSelectionCoords();
+ }
+ imageMapEditor->slotChangeStatusCoords(drawCurrent.x(),drawCurrent.y());
+}
+
+void ImageMap::resizeEvent(QResizeEvent* e) {
+ QScrollView::resizeEvent(e);
+ int width=(int) (image.width()*_zoom);
+ int height=(int) (image.height()*_zoom);
+ if (visibleWidth()>width)
+ width=visibleWidth();
+ if (visibleHeight()>height)
+ height=visibleHeight();
+
+ resizeContents(width,height);
+
+ imageRect.setLeft(0);
+ imageRect.setTop(0);
+ imageRect.setHeight(image.height()*_zoom);
+ imageRect.setWidth(image.width()*_zoom);
+
+}
+
+void ImageMap::repaintArea(const Area & a) {
+ repaintContents(translateToZoom(a.selectionRect()),false);
+}
+
+void ImageMap::drawContents(QPainter* p,int clipx,int clipy,int clipw,int cliph) {
+// kdDebug() << "drawing\n" << endl;
+// p.scale(rect.width()*2,rect.height()*2);
+// if (e->rect()!=rect()) {
+// p.setClipping(true);
+// p.setClipRect(e->rect());
+// } else
+/* if (currentAction==DrawRectangle) {
+ p->setClipping(true);
+ QRect r(currentArea->rect());
+ r.moveBy(imageRect.left()-5,imageRect.top()-5);
+ r.setSize(r.size()+QSize(10,10));
+ p->setClipRegion(r);
+ }
+*/
+
+ QRect updateRect(clipx,clipy,clipw,cliph);
+ QPixmap doubleBuffer(updateRect.size()); // Pixmap for double-buffering
+ QPainter p2(&doubleBuffer);
+ p2.drawPixmap(0,0,zoomedImage,clipx,clipy,clipw,cliph);
+ p2.translate(-updateRect.x(), -updateRect.y());
+ p2.scale(_zoom,_zoom);
+
+ AreaList *list=imageMapEditor->areaList();
+ for (Area* s=list->first();s != 0L; s=list->next())
+ s->draw(p2);
+
+ // Draw the current drawing Area
+ if (currentAction != MoveArea &&
+ currentAction != MoveSelectionPoint &&
+ currentAction != None)
+ {
+ currentArea->draw(p2);
+ }
+
+ p2.end();
+
+ // Copy the double buffer into the widget
+ p->drawPixmap(clipx,clipy,doubleBuffer);
+ // Erase background without flicker
+ QRegion region(contentsX(),contentsY(),visibleWidth(),visibleHeight());
+ region=region.subtract(QRegion(imageRect));
+ for (int i=0;i<region.rects().count();i++) {
+ p->eraseRect(region.rects()[i]);
+ }
+
+
+ // Draw our picture
+// p->drawPixmap(imageRect.left(),imageRect.top(),zoomedImage);
+//
+//
+// p->scale(_zoom,_zoom);
+// p->translate(imageRect.left(),imageRect.top());
+//
+// AreaList *list=imageMapEditor->areaList();
+// for (Area* s=list->first();s != 0L; s=list->next())
+// s->draw(*p);
+//
+// // Draw the current drawing Area
+// if (currentAction != MoveArea &&
+// currentAction != MoveSelectionPoint &&
+// currentAction != None)
+// {
+// currentArea->draw(*p);
+// }
+
+
+}