Commit 706493aa authored by Marc Pegon's avatar Marc Pegon

Corrected a small bug in transform worker with shearing.

Added constraints to the transformations :
- Hold shift while rotating by steps of 15°
- Hold shift while scaling to keep aspect ratio
- Hold shift while moving selection to move along X or Y "global" axis only. Hold shift+ctrl to move along X or Y "object" axis only.
- Hold shift while moving rotation center to move it along X or Y "local" axis only. Hold shift+ctrl to move it along X or Y "global" axis only.

Did some work on the ui of the transform tool :
- added small buttons to set rotation Center to th four corners/ middle of sides / center.
- added spinboxes to show/modify current arguments of the transformation, with an aspect button for scale factors to keep aspect ratio

Changed the general behaviour of the tool : Now QImages are used to display the temporary transformed selected pixels (drawn with some alpha to show that it's temporary),
with an "Apply" button to apply eventually the transformation to the selected pixels, and "Reset" button to cancel the current transformation (preview goes back to original
selection). Original selected pixels are kept the same and still drawn until the transformation has been applied, but to show that it is being modified, I darken it using a
 black QImage with alpha. Please tell me if you find it unclear or have a better idea (personally i think it's just fine).

In the process, undo/redo actions have been broken, but I restored it then.
Now we have 2 different commands : basic transform (which changes the preview only),  and apply transform (which changes the paintDevice).

Please report any bug/anormal behaviour you may encounter with undo/redo or the transform tool itself.


svn path=/trunk/koffice/; revision=1145719
parent bbbed91b
......@@ -447,12 +447,13 @@ bool KisTransformWorker::run()
qint32 xtranslate = m_xtranslate;
qint32 ytranslate = m_ytranslate;
m_progressTotalSteps = (r.width() + r.height() * m_xshear);
m_progressTotalSteps += r.height() + m_progressTotalSteps * m_yshear;
m_lastProgressReport = 0;
m_progressTotalSteps = 0;
//apply shear X and Y
if (xshear != 0 || yshear != 0) {
m_progressTotalSteps = (r.width() + r.height() * m_xshear);
m_progressTotalSteps += r.height() + m_progressTotalSteps * m_yshear;
transformPass <KisHLineIteratorPixel>(srcdev.data(), srcdev.data(), xscale, yscale * m_xshear, - int((r.top() + (double)r.height() / 2) * yscale * m_xshear), m_filter, m_fixBorderAlpha);
transformPass <KisVLineIteratorPixel>(srcdev.data(), srcdev.data(), yscale, m_yshear, - int((r.left() + (double)r.width() / 2) * xscale * m_yshear), m_filter, m_fixBorderAlpha);
yscale = 1.;
......@@ -477,18 +478,18 @@ bool KisTransformWorker::run()
tmp = xscale;
xscale = yscale;
yscale = tmp;
m_progressTotalSteps = r.width() * r.height();
m_progressTotalSteps += r.width() * r.height();
break;
case 2:
rotation -= M_PI;
m_progressTotalSteps = r.width() * r.height();
m_progressTotalSteps += r.width() * r.height();
break;
case 3:
rotation -= -M_PI / 2 + 2 * M_PI;
tmp = xscale;
xscale = yscale;
yscale = tmp;
m_progressTotalSteps = r.width() * r.height();
m_progressTotalSteps += r.width() * r.height();
break;
}
......
......@@ -28,6 +28,7 @@
#include <QPoint>
#include <QPointF>
#include <QVector3D>
#include <QButtonGroup>
#include <KoInteractionTool.h>
#include <KoToolFactoryBase.h>
......@@ -41,6 +42,8 @@
#include "ui_wdg_tool_transform.h"
#include "tool_transform_args.h"
#define PERSPECTIVE_DISABLED
class KoID;
class KisFilterStrategy;
......@@ -74,9 +77,15 @@ public:
virtual void mouseMoveEvent(KoPointerEvent *e);
virtual void mouseReleaseEvent(KoPointerEvent *e);
void paint(QPainter& gc, const KoViewConverter &converter);
//recalc the outline & current QImages
void recalcOutline();
//update the boundrect of the current transformed pixels
void updateCanvas();
void updateCurrentOutline();
//recalcs the outline and update the corresponding areas of the canvas (union of the outline boundrect before & after recalc)
void updateOutlineChanged();
//sets the value of the spinboxes to current args
void refreshSpinBoxes();
void setButtonBoxDisabled(bool disabled);
public:
......@@ -86,10 +95,43 @@ public:
public slots:
virtual void activate(ToolActivation toolActivation, const QSet<KoShape*> &shapes);
virtual void deactivate();
void setRotCenter(int id);
void setScaleX(double scaleX);
void setScaleY(double scaleY);
void setShearX(double shearX);
void setShearY(double shearY);
void setAX(double aX);
void setAY(double aY);
void setAZ(double aZ);
void setTranslateX(double translateX);
void setTranslateY(double translateY);
void buttonBoxClicked(QAbstractButton *button);
void keepAspectRatioChanged(bool keep);
void editingFinished();
private:
void transform();
void transform(); //only commits the current transformation to the undo stack
void applyTransform(); //applies the current transformation to the original paint device
#ifdef PERSPECTIVE_DISABLED
QVector3D rotX(double x, double y, double z) {
return QVector3D(x, y, z);
}
QVector3D invrotX(double x, double y, double z) {
return QVector3D(x, y, z);
}
QVector3D rotY(double x, double y, double z) {
return QVector3D(x, y, z);
}
QVector3D invrotY(double x, double y, double z) {
return QVector3D(x, y, z);
}
QPointF perspective(double x, double y, double z) {
Q_UNUSED(z);
return QPointF(x, y);
}
#else
QVector3D rotX(double x, double y, double z) {
return QVector3D(x, m_cosaX * y - m_sinaX * z, m_cosaX * z + m_sinaX * y);
}
......@@ -102,6 +144,13 @@ private:
QVector3D invrotY(double x, double y, double z) {
return QVector3D(m_cosaY * x + m_sinaY * z, y, - m_sinaY * x + m_cosaY * z);
}
QPointF perspective(double x, double y, double z) {
QVector3D t(x, y, z - m_viewerZ);
return QPointF(- t.x() * m_viewerZ / t.z(), - t.y() * m_viewerZ / t.z());
}
#endif
QVector3D rotZ(double x, double y, double z) {
return QVector3D(m_cosaZ*x - m_sinaZ*y, m_sinaZ*x + m_cosaZ*y, z);
}
......@@ -124,13 +173,43 @@ private:
QVector3D invscale(double x, double y, double z) {
return QVector3D(x / m_currentArgs.scaleX(), y / m_currentArgs.scaleY(), z);
}
QVector3D transformVector(double x, double y, double z) {
QVector3D t = scale(x, y ,z);
t = shear(t.x(), t.y(), t.z());
t = rotZ(t.x(), t.y(), t.z());
t = rotY(t.x(), t.y(), t.z());
t = rotX(t.x(), t.y(), t.z());
return t;
}
QVector3D invTransformVector(double x, double y, double z) {
QVector3D t = invrotX(x, y, z);
t = invrotY(t.x(), t.y(), t.z());
t = invrotZ(t.x(), t.y(), t.z());
t = invshear(t.x(), t.y(), t.z());
t = invscale(t.x(), t.y(), t.z());
return t;
}
QVector3D transformVector(QVector3D v) {
return transformVector(v.x(), v.y(), v.z());
}
QVector3D invTransformVector(QVector3D v) {
return invTransformVector(v.x(), v.y(), v.z());
}
int det(const QPointF & v, const QPointF & w);
double distsq(const QPointF & v, const QPointF & w); //square of the euclidian distance
int octant(double x, double y); //the octant of the director given by vector (x,y)
//sets the cursor according the mouse position (doesn't take shearing into account yet)
void setFunctionalCursor();
//just sets default values for current args, temporary values..
void initTransform();
//saves the original selection, paintDevice, Images previous. set transformation to default using initTransform
void initHandles();
//stores m_currentArgs into args
void storeArgs(ToolTransformArgs &args);
//sets m_currentArgs to args
void restoreArgs(ToolTransformArgs args);
private slots:
......@@ -143,7 +222,7 @@ private:
BOTTOMSHEAR, RIGHTSHEAR, TOPSHEAR, LEFTSHEAR,
MOVECENTER
};
QPointF m_handleDir[8];
QPointF m_handleDir[9];
QCursor m_sizeCursors[8]; //cursors for the 8 directions
function m_function; //current transformation function
......@@ -168,20 +247,36 @@ private:
QPoint m_previousBottomRight; //in image coords
//center used for rotation (calculated from rotationCenterOffset (in currentArgs))
QPointF m_rotationCenter;
QPointF m_clickRotationCenter; //the rotation center at click
QVector3D m_rotationCenter;
QVector3D m_clickRotationCenter; //the rotation center at click
QPointF m_rotationCenterProj;
bool m_selecting; // true <=> selection has been clicked
bool m_actuallyMoveWhileSelected; // true <=> selection has been moved while clicked
//informations on the current selection
QPointF m_topLeft; //in image coords
QPointF m_topRight; //in image coords
QPointF m_bottomLeft; //in image coords
QPointF m_bottomRight; //in image coords
QVector3D m_topLeft; //in image coords
QVector3D m_topRight; //in image coords
QVector3D m_bottomLeft; //in image coords
QVector3D m_bottomRight; //in image coords
QVector3D m_middleLeft;
QVector3D m_middleRight;
QVector3D m_middleTop;
QVector3D m_middleBottom;
QPointF m_topLeftProj; //perspective projection of m_topLeft
QPointF m_topRightProj;
QPointF m_bottomLeftProj;
QPointF m_bottomRightProj;
QPointF m_middleLeftProj;
QPointF m_middleRightProj;
QPointF m_middleTopProj;
QPointF m_middleBottomProj;
double m_viewerZ; //used for perspective projection
//current scale factors
//wOutModifier don't take shift modifier into account
//wOutModifiers don't take shift modifier into account
double m_scaleX_wOutModifier;
double m_scaleY_wOutModifier;
......@@ -196,6 +291,16 @@ private:
double m_sinaY;
double m_clickangle; //angle made at click, from the rotationCenter
bool m_boxValueChanged; //true if a boxValue has been changed directly by the user (not by click + move mouse)
bool m_hasBeenTransformed;
QImage *m_origImg; //image of the pixels in selection bound rect
QTransform m_transform; //transformation from the origImg
QImage m_currImg; //origImg transformed using m_transform
QImage *m_origSelectionImg; //the original selection with white used as alpha channel
QImage m_scaledOrigSelectionImg; //the original selection to be drawn, scaled to the view
QSizeF m_refSize; //used in paint() to check if the view has changed (need to update m_currSelectionImg);
KisFilterStrategy *m_filter;
WdgToolTransform *m_optWidget;
......@@ -205,6 +310,8 @@ private:
KisSelectionSP m_origSelection; //contains the original selection
//KisShapeSelection *m_previousShapeSelection;
KoCanvasBase *m_canvas;
QButtonGroup *m_rotCenterButtons;
};
class KisToolTransformFactory : public KoToolFactoryBase
......
......@@ -22,8 +22,8 @@
ToolTransformArgs::ToolTransformArgs()
{
m_translate = QPointF(0,0);
m_rotationCenterOffset = QPointF(0,0);
m_translate = QPointF(0, 0);
m_rotationCenterOffset = QPointF(0, 0);
m_aX = 0;
m_aY = 0;
m_aZ = 0;
......
......@@ -41,6 +41,7 @@ public:
double scaleY();
double shearX();
double shearY();
void setTranslate(QPointF translate);
void setRotationCenterOffset(QPointF rotationCenterOffset);
void setAX(double aX);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment