Modified Preview Canvas

- Now the Preview can show free space around the image (the image's
corner will coincide with the center of the preview area)
- Editing objects can now be manipulated in this free space
- The editing mechanism has been split : it was completely handled in
rtengine before, now rtengine still handle the pipette's data provider,
but rtgui now handle the objects data provider.
- Bugfix: when using coarse rotate in the Editor panel, the Gradient
widgets are now correctly displayed
This commit is contained in:
Hombre
2016-01-29 22:09:56 +01:00
parent 8c3e6eab95
commit 4665b88788
22 changed files with 1413 additions and 848 deletions

View File

@@ -24,13 +24,16 @@
#include "cropwindow.h"
#include "../rtengine/dcrop.h"
#include "../rtengine/refreshmap.h"
#include "../rtengine/rt_math.h"
using namespace rtengine;
CropHandler::CropHandler ()
: zoom(10), ww(0), wh(0), cx(0), cy(0), cw(0), ch(0),
cropX(0), cropY(0), cropW(0), cropH(0), enabled(false),
cropimg(NULL), cropimgtrue(NULL), ipc(NULL), crop(NULL), listener(NULL), isLowUpdatePriority(false)
: zoom(10), ww(0), wh(0), imx(-1), imy(-1), imw(0), imh(0), cax(-1), cay(-1),
cx(0), cy(0), cw(0), ch(0), cropX(0), cropY(0), cropW(0), cropH(0), enabled(false),
cropimg(NULL), cropimgtrue(NULL), cropimg_width(0), cropimg_height(0),
initial(false), isLowUpdatePriority(false), ipc(NULL), crop(NULL),
displayHandler(NULL)
{
chi = new CropHandlerIdleHelper;
@@ -82,7 +85,7 @@ void CropHandler::newImage (StagedImageProcessor* ipc_, bool isDetailWindow)
}
EditDataProvider *editDataProvider = NULL;
CropWindow *cropWin = listener ? static_cast<CropWindow*>(listener) : NULL;
CropWindow *cropWin = displayHandler ? static_cast<CropWindow*>(displayHandler) : NULL;
if (cropWin) {
editDataProvider = cropWin->getImageArea();
@@ -126,16 +129,28 @@ double CropHandler::getFitZoom ()
void CropHandler::setZoom (int z, int centerx, int centery)
{
assert (ipc);
int x = cx + cw / 2;
int y = cy + ch / 2;
float oldScale = zoom >= 1000 ? float(zoom / 1000) : 1.f / float(zoom);
float newScale = z >= 1000 ? float(z / 1000) : 1.f / float(z);
if (centerx >= 0) {
x = centerx;
int oldcax = cax;
int oldcay = cay;
if (centerx == -1) {
cax = ipc->getFullWidth () / 2;
} else {
float distToAnchor = float(cax - centerx);
distToAnchor = distToAnchor / newScale * oldScale;
cax = centerx + int(distToAnchor);
}
if (centery >= 0) {
y = centery;
if (centery == -1) {
cay = ipc->getFullHeight () / 2;
} else {
float distToAnchor = float(cay - centery);
distToAnchor = distToAnchor / newScale * oldScale;
cay = centery + int(distToAnchor);
}
// maybe demosaic etc. if we cross the border to >100%
@@ -151,12 +166,18 @@ void CropHandler::setZoom (int z, int centerx, int centery)
ch = wh * zoom;
}
cx = x - cw / 2;
cy = y - ch / 2;
cx = cax - cw / 2;
cy = cay - ch / 2;
int oldCropX = cropX;
int oldCropY = cropY;
int oldCropW = cropW;
int oldCropH = cropH;
compDim ();
if (enabled) {
if (enabled && (oldcax != cax || oldcay != cay || oldCropX != cropX || oldCropY != cropY || oldCropW != cropW || oldCropH != cropH)) {
if (needsFullRefresh) {
ipc->startProcessing(M_HIGHQUAL);
} else {
@@ -194,11 +215,44 @@ void CropHandler::getWSize (int& w, int &h)
h = wh;
}
void CropHandler::setPosition (int x, int y, bool update_)
void CropHandler::getAnchorPosition (int& x, int& y)
{
x = cax;
y = cay;
}
cx = x;
cy = y;
void CropHandler::setAnchorPosition (int x, int y, bool update_)
{
cax = x;
cay = y;
compDim ();
if (enabled && update_) {
update ();
}
}
void CropHandler::moveAnchor (int deltaX, int deltaY, bool update_)
{
cax += deltaX;
cay += deltaY;
compDim ();
if (enabled && update_) {
update ();
}
}
void CropHandler::centerAnchor (bool update_)
{
assert (ipc);
// Computes the crop's size and position given the anchor's position and display size
cax = ipc->getFullWidth() / 2;
cay = ipc->getFullHeight() / 2;
compDim ();
@@ -280,11 +334,11 @@ int createpixbufs (void* data)
ch->cimg.unlock ();
if (ch->listener) {
ch->listener->cropImageUpdated ();
if (ch->displayHandler) {
ch->displayHandler->cropImageUpdated ();
if (ch->initial) {
ch->listener->initialImageArrived ();
ch->displayHandler->initialImageArrived ();
ch->initial = false;
}
}
@@ -365,7 +419,7 @@ bool CropHandler::getWindow (int& cwx, int& cwy, int& cww, int& cwh, int& cskip)
void CropHandler::update ()
{
if (crop) {
if (crop && enabled) {
// crop->setWindow (cropX, cropY, cropW, cropH, zoom>=1000 ? 1 : zoom); --> we use the "getWindow" hook instead of setting the size before
crop->setListener (this);
cropPixbuf.clear ();
@@ -428,41 +482,78 @@ void CropHandler::getFullImageSize (int& w, int& h)
void CropHandler::compDim ()
{
assert (ipc && displayHandler);
cropX = cx;
cropY = cy;
cropW = cw;
cropH = ch;
// Computes the crop's size and position given the anchor's position and display size
cutRectToImgBounds (cropX, cropY, cropW, cropH);
}
int fullW = ipc->getFullWidth();
int fullH = ipc->getFullHeight();
int imgX = -1, imgY = -1;
//int scaledFullW, scaledFullH;
int scaledCAX, scaledCAY;
int wwImgSpace;
int whImgSpace;
void CropHandler::cutRectToImgBounds (int& x, int& y, int& w, int& h)
{
cax = rtengine::LIM(cax, 0, fullW-1);
cay = rtengine::LIM(cay, 0, fullH-1);
if (ipc) {
if (w > ipc->getFullWidth()) {
w = ipc->getFullWidth();
}
if (h > ipc->getFullHeight()) {
h = ipc->getFullHeight();
}
if (x < 0) {
x = 0;
}
if (y < 0) {
y = 0;
}
if (x + w >= ipc->getFullWidth()) {
x = ipc->getFullWidth() - w;
}
if (y + h >= ipc->getFullHeight()) {
y = ipc->getFullHeight() - h;
}
if (zoom >= 1000) {
wwImgSpace = int(float(ww) / float(zoom/1000) + 0.5f);
whImgSpace = int(float(wh) / float(zoom/1000) + 0.5f);
//scaledFullW = fullW * (zoom/1000);
//scaledFullH = fullH * (zoom/1000);
scaledCAX = cax * (zoom/1000);
scaledCAY = cay * (zoom/1000);
} else {
wwImgSpace = int(float(ww) * float(zoom) + 0.5f);
whImgSpace = int(float(wh) * float(zoom) + 0.5f);
//scaledFullW = fullW / zoom;
//scaledFullH = fullH / zoom;
scaledCAX = cax / zoom;
scaledCAY = cay / zoom;
}
imgX = ww / 2 - scaledCAX;
if (imgX < 0) {
imgX = 0;
}
imgY = wh / 2 - scaledCAY;
if (imgY < 0) {
imgY = 0;
}
cropX = cax - (wwImgSpace/2);
cropY = cay - (whImgSpace/2);
cropW = wwImgSpace;
cropH = whImgSpace;
if (cropX + cropW > fullW) {
cropW = fullW - cropX;
}
if (cropY + cropH > fullH) {
cropH = fullH - cropY;
}
if (cropX < 0) {
cropW += cropX;
cropX = 0;
}
if (cropY < 0) {
cropH += cropY;
cropY = 0;
}
// Should be good already, but this will correct eventual rounding error
if (cropW > fullW) {
cropW = fullW;
}
if (cropH > fullH) {
cropH = fullH;
}
displayHandler->setDisplayPosition(imgX, imgY);
}

View File

@@ -24,14 +24,15 @@
#include "edit.h"
#include <gtkmm.h>
class CropHandlerListener
class CropDisplayHandler
{
public:
virtual ~CropHandlerListener() {}
virtual ~CropDisplayHandler() {}
virtual void cropImageUpdated () {}
virtual void cropWindowChanged () {}
virtual void initialImageArrived () {}
virtual void setDisplayPosition (int x, int y) {}
};
class CropHandler;
@@ -41,16 +42,22 @@ struct CropHandlerIdleHelper {
int pending;
};
/**
* This class handle the displayed part of the image, ask for the initial data and process it so it can display it.
* Its position on the preview is handled not set by this class but by the CropHandlerListener (i.e. CropWindow) with which it works closely.
*/
class CropHandler : public rtengine::DetailedCropListener, public rtengine::SizeListener
{
friend int createpixbufs (void* data);
protected:
int zoom;
int ww, wh; // size of the crop view on the screen
int cx, cy, cw, ch; // position and size of the requested crop
int cropX, cropY, cropW, cropH; // position and size of the crop corresponding to cropPixbuf
int zoom; // scale factor (e.g. 5 if 1:5 scale) ; if 1:1 scale and bigger, factor is multiplied by 1000 (i.e. 1000 for 1:1 scale, 2000 for 2:1, etc...)
int ww, wh; // size of the crop's canvas on the screen ; might be bigger than the displayed image, but not smaller
int imx, imy, imw, imh; // this is a copy of the cropwindow's parameters
int cax, cay; // clamped crop anchor's coordinate, i.e. point of the image that coincide to the center of the display area, expressed in image coordinates; cannot be outside the image's bounds; but if cax==cay==-1, designate the center of the image
int cx, cy, cw, ch; // position and size of the requested crop ; position expressed in image coordinates, so cx and cy might be negative and cw and ch higher than the image's 1:1 size
int cropX, cropY, cropW, cropH; // cropPixbuf's displayed area (position and size), i.e. coordinates in 1:1 scale, i.e. cx, cy, cw & ch trimmed to the image's bounds
bool enabled;
unsigned char* cropimg;
unsigned char* cropimgtrue;
@@ -61,7 +68,7 @@ protected:
rtengine::StagedImageProcessor* ipc;
rtengine::DetailedCrop* crop;
CropHandlerListener* listener;
CropDisplayHandler* displayHandler;
CropHandlerIdleHelper* chi;
void compDim ();
@@ -81,9 +88,9 @@ public:
CropHandler ();
~CropHandler ();
void setCropHandlerListener (CropHandlerListener* l)
void setDisplayHandler (CropDisplayHandler* l)
{
listener = l;
displayHandler = l;
}
void setEditSubscriber (EditSubscriber* newSubscriber);
@@ -93,7 +100,10 @@ public:
double getFitCropZoom();
void setWSize (int w, int h);
void getWSize (int& w, int &h);
void setPosition (int x, int y, bool update = true);
void getAnchorPosition (int& x, int& y);
void setAnchorPosition (int x, int y, bool update = true);
void moveAnchor (int deltaX, int deltaY, bool update = true);
void centerAnchor (bool update = true);
void getPosition (int& x, int& y);
void getSize (int& w, int& h);
void getFullImageSize (int& w, int& h);
@@ -112,8 +122,6 @@ public:
bool getWindow (int& cwx, int& cwy, int& cww, int& cwh, int& cskip);
// SizeListener interface
void sizeChanged (int w, int h, int ow, int oh);
void cutRectToImgBounds (int& x, int& y, int& w, int& h);
};
#endif

View File

@@ -64,10 +64,10 @@ ZoomStep zoomSteps[] = {
#define ZOOM11INDEX 13
CropWindow::CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_, bool isLowUpdatePriority_, bool isDetailWindow)
: onResizeArea(false), deleted(false), fitZoomEnabled(true), fitZoom(false), isLowUpdatePriority(isLowUpdatePriority_),
: ObjectMOBuffer(parent), onResizeArea(false), deleted(false), fitZoomEnabled(true), fitZoom(false), isLowUpdatePriority(isLowUpdatePriority_),
backColor(options.bgcolor), decorated(true), titleHeight(30),
sideBorderWidth(3), lowerBorderWidth(3), upperBorderWidth(1), sepWidth(2),
xpos(30), ypos(30), imgX(0), imgY(0), imgW(1), imgH(1), iarea(parent),
xpos(30), ypos(30), imgX(-1), imgY(-1), imgW(1), imgH(1), iarea(parent),
cropZoom(0), cropgl(NULL), pmlistener(NULL), observedCropWin(NULL), ipc(ipc_), isFlawnOver(false)
{
Glib::RefPtr<Pango::Context> context = parent->get_pango_context () ;
@@ -107,7 +107,7 @@ CropWindow::CropWindow (ImageArea* parent, rtengine::StagedImageProcessor* ipc_,
minWidth = bsw + iw + 2 * sideBorderWidth;
cropHandler.setCropHandlerListener (this);
cropHandler.setDisplayHandler(this);
cropHandler.newImage (ipc_, isDetailWindow);
state = SNormal;
@@ -158,36 +158,27 @@ void CropWindow::getCropPosition (int& x, int& y)
void CropWindow::getCropRectangle (int& x, int& y, int& w, int& h)
{
int cropX, cropY, cropW, cropH;
cropHandler.getPosition (cropX, cropY);
cropHandler.getSize (cropW, cropH);
if (state != SCropImgMove) {
x = cropX;
y = cropY;
} else {
x = cropX + action_x;
y = cropY + action_y;
}
if (state != SCropWinResize) {
w = cropW;
h = cropH;
} else {
w = imgAreaW;
h = imgAreaH;
}
cropHandler.cutRectToImgBounds (x, y, w, h);
cropHandler.getPosition (x, y);
cropHandler.getSize (w, h);
}
void CropWindow::setCropPosition (int x, int y, bool update)
{
cropHandler.setPosition (x, y, update);
cropHandler.setAnchorPosition (x, y, update);
for (std::list<CropWindowListener*>::iterator i = listeners.begin(); i != listeners.end(); i++) {
(*i)->cropPositionChanged (this);
for (auto listener : listeners) {
listener->cropPositionChanged (this);
}
}
void CropWindow::centerCrop (bool update)
{
cropHandler.centerAnchor (update);
for (auto listener : listeners) {
listener->cropPositionChanged (this);
}
}
@@ -240,6 +231,16 @@ void CropWindow::getCropSize (int& w, int& h)
h = imgAreaH;
}
void CropWindow::getCropAnchorPosition (int& x, int& y)
{
cropHandler.getAnchorPosition(x, y);
}
void CropWindow::setCropAnchorPosition (int& x, int& y)
{
cropHandler.setAnchorPosition(x, y);
}
bool CropWindow::isInside (int x, int y)
{
@@ -288,11 +289,6 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y)
state = SNormal;
}
//below code is no longer working/needed after adding buttons for each of the backColor values
/*else if (button==1 && type==GDK_2BUTTON_PRESS && onArea (CropBorder, x, y)) {
backColor = (backColor+1) % 3;
options.bgcolor = backColor;
}*/
else if (button == 1 && type == GDK_BUTTON_PRESS && state == SNormal && onArea (CropToolBar, x, y)) {
if (!decorated || !buttonSet.pressNotify (x, y)) {
state = SCropWinMove;
@@ -307,48 +303,48 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y)
action_y = y;
press_x = width;
press_y = height;
} else if (button == 1 && type == GDK_BUTTON_PRESS && state == SNormal && onArea (CropImage, x, y)) {
if (onArea (CropTopLeft, x, y)) {
} else if (type == GDK_BUTTON_PRESS && state == SNormal && onArea (CropImage, x, y)) {
if (button == 1 && onArea (CropTopLeft, x, y)) {
state = SResizeTL;
press_x = x;
action_x = cropHandler.cropParams.x;
press_y = y;
action_y = cropHandler.cropParams.y;
} else if (onArea (CropTopRight, x, y)) {
} else if (button == 1 && onArea (CropTopRight, x, y)) {
state = SResizeTR;
press_x = x;
action_x = cropHandler.cropParams.w;
press_y = y;
action_y = cropHandler.cropParams.y;
} else if (onArea (CropBottomLeft, x, y)) {
} else if (button == 1 && onArea (CropBottomLeft, x, y)) {
state = SResizeBL;
press_x = x;
action_x = cropHandler.cropParams.x;
press_y = y;
action_y = cropHandler.cropParams.h;
} else if (onArea (CropBottomRight, x, y)) {
} else if (button == 1 && onArea (CropBottomRight, x, y)) {
state = SResizeBR;
press_x = x;
action_x = cropHandler.cropParams.w;
press_y = y;
action_y = cropHandler.cropParams.h;
} else if (onArea (CropTop, x, y)) {
} else if (button == 1 && onArea (CropTop, x, y)) {
state = SResizeH1;
press_y = y;
action_y = cropHandler.cropParams.y;
} else if (onArea (CropBottom, x, y)) {
} else if (button == 1 && onArea (CropBottom, x, y)) {
state = SResizeH2;
press_y = y;
action_y = cropHandler.cropParams.h;
} else if (onArea (CropLeft, x, y)) {
} else if (button == 1 && onArea (CropLeft, x, y)) {
state = SResizeW1;
press_x = x;
action_x = cropHandler.cropParams.x;
} else if (onArea (CropRight, x, y)) {
} else if (button == 1 && onArea (CropRight, x, y)) {
state = SResizeW2;
press_x = x;
action_x = cropHandler.cropParams.w;
} else if ((bstate & GDK_SHIFT_MASK) && onArea (CropInside, x, y)) {
} else if (button == 1 && (bstate & GDK_SHIFT_MASK) && onArea (CropInside, x, y)) {
state = SCropMove;
press_x = x;
press_y = y;
@@ -357,7 +353,7 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y)
} else if (iarea->getToolMode () == TMHand) {
EditSubscriber *editSubscriber = iarea->getCurrSubscriber();
if (editSubscriber && cropgl && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) && (editSubscriber->getEditingType() == ET_OBJECTS)) {
if (editSubscriber && editSubscriber->getEditingType() == ET_OBJECTS) {
if (button == 1) {
needRedraw = editSubscriber->button1Pressed(bstate);
@@ -385,7 +381,7 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y)
}
if (state != SEditDrag1 && state != SEditDrag2 && state != SEditDrag3) {
if (onArea (CropObserved, x, y)) {
if (button == 1 && onArea (CropObserved, x, y)) {
state = SObservedMove;
press_x = x;
press_y = y;
@@ -398,7 +394,7 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y)
press_y = y;
action_x = 0;
action_y = 0;
} else if(zoomSteps[cropZoom].zoom > cropHandler.getFitZoom()) { // only allow move when image is only partial visible
} else if (button == 1) { // if(zoomSteps[cropZoom].zoom > cropHandler.getFitZoom()) { // only allow move when image is only partial visible
state = SCropImgMove;
press_x = x;
press_y = y;
@@ -406,22 +402,24 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y)
action_y = 0;
}
}
} else if (onArea (CropObserved, x, y)) {
} else if (button == 1 && onArea (CropObserved, x, y)) {
state = SObservedMove;
press_x = x;
press_y = y;
} else if (iarea->getToolMode () == TMStraighten) {
action_x = 0;
action_y = 0;
} else if (button == 1 && iarea->getToolMode () == TMStraighten) {
state = SRotateSelecting;
press_x = x;
press_y = y;
action_x = x;
action_y = y;
rot_deg = 0;
} else if (iarea->getToolMode () == TMSpotWB) {
} else if (button == 1 && iarea->getToolMode () == TMSpotWB) {
int spotx, spoty;
screenCoordToImage (x, y, spotx, spoty);
iarea->spotWBSelected (spotx, spoty);
} else if (iarea->getToolMode () == TMCropSelect && cropgl) {
} else if (button == 1 && iarea->getToolMode () == TMCropSelect && cropgl) {
state = SCropSelecting;
screenCoordToImage (x, y, press_x, press_y);
cropHandler.cropParams.enabled = true;
@@ -430,6 +428,36 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y)
cropHandler.cropParams.w = cropHandler.cropParams.h = 1;
cropgl->cropInit (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h);
}
} else if (type == GDK_BUTTON_PRESS && state == SNormal && iarea->getToolMode () == TMHand) {
// Any other case... i.e. we're assuming to be on the canvas, looking for editing objects
EditSubscriber *editSubscriber = iarea->getCurrSubscriber();
if (editSubscriber && editSubscriber->getEditingType() == ET_OBJECTS) {
if (button == 1) {
needRedraw = editSubscriber->button1Pressed(bstate);
if (editSubscriber->isDragging()) {
state = SEditDrag1;
}
} else if (button == 2) {
needRedraw = editSubscriber->button2Pressed(bstate);
if (editSubscriber->isDragging()) {
state = SEditDrag2;
}
} else if (button == 3) {
needRedraw = editSubscriber->button3Pressed(bstate);
if (editSubscriber->isDragging()) {
state = SEditDrag3;
}
}
press_x = x;
press_y = y;
action_x = 0;
action_y = 0;
}
}
if (button == 3) {
@@ -474,16 +502,14 @@ void CropWindow::buttonRelease (int button, int num, int bstate, int x, int y)
state = SNormal;
for (std::list<CropWindowListener*>::iterator i = listeners.begin(); i != listeners.end(); i++) {
(*i)->cropWindowSizeChanged (this);
for (auto listener : listeners) {
listener->cropWindowSizeChanged (this);
}
needRedraw = true;
} else if (state == SCropImgMove) {
int cropX, cropY;
cropHandler.getPosition (cropX, cropY);
cropHandler.setPosition (cropX + action_x, cropY + action_y);
cropHandler.getPosition (cropX, cropY);
cropHandler.update ();
state = SNormal;
for (std::list<CropWindowListener*>::iterator i = listeners.begin(); i != listeners.end(); i++) {
@@ -519,9 +545,9 @@ void CropWindow::buttonRelease (int button, int num, int bstate, int x, int y)
iarea->posScreen.set(x, y);
Coord cropPos;
screenCoordToCropBuffer(x, y, cropPos.x, cropPos.y);
if (state == SEditDrag1 && editSubscriber->getEditingType() == ET_PIPETTE) {
screenCoordToCropBuffer (x, y, cropPos.x, cropPos.y);
iarea->object = onArea (CropImage, x, y) && !onArea (CropObserved, x, y) ? 1 : 0;
//iarea->object = cropgl && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) ? 1 : 0;
@@ -532,8 +558,10 @@ void CropWindow::buttonRelease (int button, int num, int bstate, int x, int y)
iarea->pipetteVal[0] = iarea->pipetteVal[1] = iarea->pipetteVal[2] = -1.f;
}
} else if (editSubscriber->getEditingType() == ET_OBJECTS) {
screenCoordToCropCanvas (x, y, cropPos.x, cropPos.y);
if (onArea (CropImage, x, y)) {
iarea->object = crop->getObjectID(cropPos);
iarea->object = ObjectMOBuffer::getObjectID(cropPos);
} else {
iarea->object = -1;
}
@@ -588,8 +616,8 @@ void CropWindow::pointerMoved (int bstate, int x, int y)
} else if (state == SCropWinResize) {
setSize (press_x + x - action_x, press_y + y - action_y, true);
for (std::list<CropWindowListener*>::iterator i = listeners.begin(); i != listeners.end(); i++) {
(*i)->cropWindowSizeChanged (this);
for (auto listener : listeners) {
listener->cropWindowSizeChanged (this);
}
iarea->redraw ();
@@ -602,11 +630,19 @@ void CropWindow::pointerMoved (int bstate, int x, int y)
factor = 1.0;
}
action_x = (press_x - x) / zoomSteps[cropZoom].zoom * factor;
action_y = (press_y - y) / zoomSteps[cropZoom].zoom * factor;
int newAction_x = (press_x - x) / zoomSteps[cropZoom].zoom * factor;
int newAction_y = (press_y - y) / zoomSteps[cropZoom].zoom * factor;
for (std::list<CropWindowListener*>::iterator i = listeners.begin(); i != listeners.end(); i++) {
(*i)->cropPositionChanged (this);
int deltaX = newAction_x - action_x;
int deltaY = newAction_y - action_y;
action_x = newAction_x;
action_y = newAction_y;
cropHandler.moveAnchor(deltaX, deltaY, false);
for (auto listener : listeners) {
listener->cropPositionChanged (this);
}
iarea->redraw ();
@@ -695,7 +731,11 @@ void CropWindow::pointerMoved (int bstate, int x, int y)
iarea->redraw ();
} else if (state == SObservedMove) {
observedCropWin->remoteMove ((x - press_x) / zoomSteps[cropZoom].zoom, (y - press_y) / zoomSteps[cropZoom].zoom);
int new_action_x = x - press_x;
int new_action_y = y - press_y;
observedCropWin->remoteMove ((new_action_x - action_x) / zoomSteps[cropZoom].zoom, (new_action_y - action_y) / zoomSteps[cropZoom].zoom);
action_x = new_action_x;
action_y = new_action_y;
iarea->redraw ();
} else if (editSubscriber) {
rtengine::Crop* crop = static_cast<rtengine::Crop*>(cropHandler.getCrop());
@@ -710,9 +750,10 @@ void CropWindow::pointerMoved (int bstate, int x, int y)
iarea->posScreen.set(x, y);
Coord cropPos;
screenCoordToCropBuffer(x, y, cropPos.x, cropPos.y);
if (editSubscriber->getEditingType() == ET_PIPETTE) {
screenCoordToCropBuffer (x, y, cropPos.x, cropPos.y);
iarea->object = onArea (CropImage, x, y) && !onArea (CropObserved, x, y) ? 1 : 0;
//iarea->object = cropgl && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) ? 1 : 0;
@@ -723,11 +764,8 @@ void CropWindow::pointerMoved (int bstate, int x, int y)
iarea->pipetteVal[0] = iarea->pipetteVal[1] = iarea->pipetteVal[2] = -1.f;
}
} else if (editSubscriber->getEditingType() == ET_OBJECTS) {
if (onArea (CropImage, x, y)) {
iarea->object = crop->getObjectID(cropPos);
} else {
iarea->object = -1;
}
screenCoordToCropCanvas (x, y, cropPos.x, cropPos.y);
iarea->object = ObjectMOBuffer::getObjectID(cropPos);
}
if (editSubscriber->mouseOver(bstate)) {
@@ -850,7 +888,7 @@ bool CropWindow::onArea (CursorArea a, int x, int y)
return x > xpos && y > ypos && x < xpos + width - 1 && y < ypos + imgAreaY;
case CropImage:
return x >= xpos + imgX && y >= ypos + imgY && x < xpos + imgX + imgW && y < ypos + imgY + imgH;
return x >= xpos + imgX + imgAreaX && y >= ypos + imgY + imgAreaY && x < xpos + imgX + imgAreaX + imgW && y < ypos + imgY + imgAreaY + imgH;
case CropBorder:
return
@@ -985,10 +1023,10 @@ void CropWindow::updateCursor (int x, int y)
} else if (onArea (CropImage, x, y)) {
int objectID = -1;
if (editSubscriber) {
if (editSubscriber && editSubscriber->getEditingType() == ET_OBJECTS) {
Coord cropPos;
screenCoordToCropBuffer(iarea->posScreen.x, iarea->posScreen.y, cropPos.x, cropPos.y);
objectID = static_cast<rtengine::Crop*>(cropHandler.getCrop())->getObjectID(cropPos);
screenCoordToCropCanvas (iarea->posScreen.x, iarea->posScreen.y, cropPos.x, cropPos.y);
objectID = ObjectMOBuffer::getObjectID(cropPos);
}
if (objectID > -1) {
@@ -1007,7 +1045,19 @@ void CropWindow::updateCursor (int x, int y)
cursorManager.setCursor (iarea->get_window(), CSStraighten);
}
} else {
cursorManager.setCursor (iarea->get_window(), CSArrow);
int objectID = -1;
if (editSubscriber && editSubscriber->getEditingType() == ET_OBJECTS) {
Coord cropPos;
screenCoordToCropCanvas (iarea->posScreen.x, iarea->posScreen.y, cropPos.x, cropPos.y);
objectID = ObjectMOBuffer::getObjectID(cropPos);
}
if (objectID > -1) {
cursorManager.setCursor (iarea->get_window(), editSubscriber->getCursor(objectID));
} else {
cursorManager.setCursor (iarea->get_window(), CSArrow);
}
}
} else if (state == SCropSelecting) {
cursorManager.setCursor (iarea->get_window(), CSCropSelect);
@@ -1042,7 +1092,7 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
drawDecoration (cr);
}
int x = xpos, y = ypos, h = height, w = width;
int x = xpos, y = ypos;
// draw the background
backColor = iarea->previewModePanel->GetbackColor();
@@ -1069,15 +1119,10 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
int cropX, cropY;
cropHandler.getPosition (cropX, cropY);
if (state == SCropImgMove) {
cropX += action_x;
cropY += action_y;
}
Glib::RefPtr<Gdk::Pixbuf> rough = iarea->getPreviewHandler()->getRoughImage (cropX, cropY, imgAreaW, imgAreaH, zoomSteps[cropZoom].zoom);
if (rough) {
iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), rough, 0, 0, x + imgAreaX + (imgAreaW - rough->get_width()) / 2, y + imgAreaY + (imgAreaH - rough->get_height()) / 2, -1, -1, Gdk::RGB_DITHER_NORMAL, 0, 0);
iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), rough, 0, 0, x + imgAreaX + imgX, y + imgAreaY + imgY, rtengine::min (rough->get_width (), imgAreaW-imgX), rtengine::min (rough->get_height (), imgAreaH-imgY), Gdk::RGB_DITHER_NORMAL, 0, 0);
// if (cropHandler.cropParams.enabled)
// drawCrop (cr, x+imgX, y+imgY, imgW, imgH, cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams);
}
@@ -1089,8 +1134,6 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
if (cropHandler.cropPixbuf) {
imgW = cropHandler.cropPixbuf->get_width ();
imgH = cropHandler.cropPixbuf->get_height ();
imgX = imgAreaX + (imgAreaW - imgW) / 2;
imgY = imgAreaY + (imgAreaH - imgH) / 2;
exposeVersion++;
bool showcs = iarea->indClippedPanel->showClippedShadows();
@@ -1240,8 +1283,8 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
}
}
float sum_L2 = tmpLsum[i * bWidth + j];
float sumsq_L2 = tmpLsumSq[i * bWidth + j];
//float sum_L2 = tmpLsum[i * bWidth + j];
//float sumsq_L2 = tmpLsumSq[i * bWidth + j];
//*************
// averages
// Optimized formulas to avoid divisions
@@ -1484,16 +1527,15 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
}
}
//printf("zoomSteps[cropZoom].zoom=%d\n",zoomSteps[cropZoom].zoom);
iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), tmp, 0, 0, x + imgX, y + imgY, -1, -1, Gdk::RGB_DITHER_NONE, 0, 0);
iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), tmp, 0, 0, x + imgAreaX + imgX, y + imgAreaY + imgY, rtengine::min (tmp->get_width (), imgAreaW-imgX), rtengine::min (tmp->get_height (), imgAreaH-imgY), Gdk::RGB_DITHER_NORMAL, 0, 0);
} else {
iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), cropHandler.cropPixbuf, 0, 0, x + imgX, y + imgY, -1, -1, Gdk::RGB_DITHER_NONE, 0, 0);
iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), cropHandler.cropPixbuf, 0, 0, x + imgAreaX + imgX, y + imgAreaY + imgY, rtengine::min (cropHandler.cropPixbuf->get_width (), imgAreaW-imgX), rtengine::min (cropHandler.cropPixbuf->get_height (), imgAreaH-imgY), Gdk::RGB_DITHER_NORMAL, 0, 0);
}
if (cropHandler.cropParams.enabled) {
int cropX, cropY;
cropHandler.getPosition (cropX, cropY);
drawCrop (cr, x + imgX, y + imgY, imgW, imgH, cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams, (this == iarea->mainCropWindow), true, zoomSteps[cropZoom].zoom <= cropHandler.getFitZoom() );
drawCrop (cr, x + imgAreaX + imgX, y + imgAreaY + imgY, imgW, imgH, cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams, (this == iarea->mainCropWindow), true, zoomSteps[cropZoom].zoom <= cropHandler.getFitZoom() );
}
if (observedCropWin) {
@@ -1501,13 +1543,12 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
}
EditSubscriber *editSubscriber = iarea->getCurrSubscriber();
rtengine::Crop* crop = static_cast<rtengine::Crop*>(cropHandler.getCrop());
if (editSubscriber && crop->bufferCreated()) {
if (editSubscriber && bufferCreated()) {
if (this != iarea->mainCropWindow) {
cr->set_line_width (0.);
cr->rectangle (x + imgX, y + imgY, imgW, imgH);
cr->rectangle (x + imgAreaX, y + imgAreaY, imgAreaW, imgAreaH);
cr->clip();
}
@@ -1518,17 +1559,13 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
cr->set_line_join(Cairo::LINE_JOIN_ROUND);
// drawing outer lines
for (std::vector<Geometry*>::const_iterator i = visibleGeom.begin(); i != visibleGeom.end(); ++i) {
(*i)->drawOuterGeometry(cr, crop, *this);
for (auto geom : visibleGeom) {
geom->drawOuterGeometry(cr, this, *this);
}
// drawing inner lines
for (std::vector<Geometry*>::const_iterator i = visibleGeom.begin(); i != visibleGeom.end(); ++i) {
(*i)->drawInnerGeometry(cr, crop, *this);
}
if (this != iarea->mainCropWindow) {
cr->reset_clip();
for (auto geom : visibleGeom) {
geom->drawInnerGeometry(cr, this, *this);
}
// drawing to the "mouse over" channel
@@ -1536,8 +1573,8 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
const std::vector<Geometry*> mouseOverGeom = editSubscriber->getMouseOverGeometry();
if (mouseOverGeom.size()) {
//printf("ObjectMap (%d x %d)\n", crop->getObjectMap()->get_width(), crop->getObjectMap()->get_height());
Cairo::RefPtr<Cairo::Context> crMO = Cairo::Context::create(crop->getObjectMap());
//printf("ObjectMap (%d x %d)\n", ObjectMOBuffer::getObjectMap()->get_width(), ObjectMOBuffer::getObjectMap()->get_height());
Cairo::RefPtr<Cairo::Context> crMO = Cairo::Context::create(ObjectMOBuffer::getObjectMap());
crMO->set_antialias(Cairo::ANTIALIAS_NONE);
crMO->set_line_cap(Cairo::LINE_CAP_SQUARE);
crMO->set_line_join(Cairo::LINE_JOIN_ROUND);
@@ -1545,14 +1582,14 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
// clear the bitmap
crMO->set_source_rgba(0., 0., 0., 0.);
crMO->rectangle(0., 0., crop->getObjectMap()->get_width(), crop->getObjectMap()->get_height());
crMO->rectangle(0., 0., ObjectMOBuffer::getObjectMap()->get_width(), ObjectMOBuffer::getObjectMap()->get_height());
crMO->set_line_width(0.);
crMO->fill();
Cairo::RefPtr<Cairo::Context> crMO2;
if (crop->getObjectMode() > OM_255) {
crMO2 = Cairo::Context::create(crop->getObjectMap2());
if (ObjectMOBuffer::getObjectMode() > OM_255) {
crMO2 = Cairo::Context::create(ObjectMOBuffer::getObjectMap2());
crMO2->set_antialias(Cairo::ANTIALIAS_NONE);
crMO2->set_line_cap(Cairo::LINE_CAP_SQUARE);
crMO2->set_line_join(Cairo::LINE_JOIN_ROUND);
@@ -1560,28 +1597,29 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
// clear the bitmap
crMO2->set_source_rgba(0., 0., 0., 0.);
crMO2->rectangle(0., 0., crop->getObjectMap2()->get_width(), crop->getObjectMap2()->get_height());
crMO2->rectangle(0., 0., ObjectMOBuffer::getObjectMap2()->get_width(), ObjectMOBuffer::getObjectMap2()->get_height());
crMO2->set_line_width(0.);
crMO2->fill();
}
std::vector<Geometry*>::const_iterator i;
int a;
int a=0;
for (a = 0, i = mouseOverGeom.begin(); i != mouseOverGeom.end(); ++i, ++a) {
(*i)->drawToMOChannel(crMO, crMO2, a, crop, *this);
for (auto moGeom : mouseOverGeom) {
moGeom->drawToMOChannel(crMO, crMO2, a, this, *this);
++a;
}
// Debug code: save the "mouse over" image to a new file at each occurrence
#if 0
{
static unsigned int count = 0;
int w = crop->getObjectMap()->get_width();
int h = crop->getObjectMap()->get_height();
int w = ObjectMOBuffer::getObjectMap()->get_width();
int h = ObjectMOBuffer::getObjectMap()->get_height();
Glib::RefPtr<Gdk::Pixbuf> img = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, false, 8, w, h);
guint8 *dst = img->get_pixels();
unsigned char *src1 = crop->getObjectMap()->get_data();
unsigned char *src2 = crop->getObjectMode() > OM_255 ? crop->getObjectMap()->get_data() : NULL;
unsigned char *src1 = ObjectMOBuffer::getObjectMap()->get_data();
unsigned char *src2 = ObjectMOBuffer::getObjectMode() > OM_255 ? ObjectMOBuffer::getObjectMap()->get_data() : NULL;
memcpy(dst, src1, w * h);
for (int n = 0, n3 = 0; n < w * h;) {
@@ -1602,6 +1640,10 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
#endif
}
}
if (this != iarea->mainCropWindow) {
cr->reset_clip();
}
}
} else {
// cropHandler.cropPixbuf is null
@@ -1610,14 +1652,14 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
Glib::RefPtr<Gdk::Pixbuf> rough = iarea->getPreviewHandler()->getRoughImage (cropX, cropY, imgAreaW, imgAreaH, zoomSteps[cropZoom].zoom);
if (rough) {
iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), rough, 0, 0, x + imgAreaX + (imgAreaW - rough->get_width()) / 2, y + imgAreaY + (imgAreaH - rough->get_height()) / 2, -1, -1, Gdk::RGB_DITHER_NORMAL, 0, 0);
iarea->get_window()->draw_pixbuf (iarea->get_style()->get_base_gc(Gtk::STATE_NORMAL), rough, 0, 0, x + imgAreaX + imgX, y + imgAreaY + imgY, rtengine::min (rough->get_width (), imgAreaW-imgX), rtengine::min (rough->get_height (), imgAreaH-imgY), Gdk::RGB_DITHER_NORMAL, 0, 0);
if (cropHandler.cropParams.enabled) {
drawCrop (cr, x + imgAreaX + (imgAreaW - rough->get_width()) / 2, y + imgAreaY + (imgAreaH - rough->get_height()) / 2, rough->get_width(), rough->get_height(), cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams, (this == iarea->mainCropWindow), true, zoomSteps[cropZoom].zoom <= cropHandler.getFitZoom());
drawCrop (cr, x + imgAreaX + imgX, y + imgAreaY + imgY, rough->get_width(), rough->get_height(), cropX, cropY, zoomSteps[cropZoom].zoom, cropHandler.cropParams, (this == iarea->mainCropWindow), true, zoomSteps[cropZoom].zoom <= cropHandler.getFitZoom());
}
if (observedCropWin) {
drawObservedFrame (cr, rough->get_width(), rough->get_height());
drawObservedFrame (cr);
}
}
}
@@ -1641,24 +1683,10 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
// printf ("etime --> %d, %d\n", t2.etime (t1), t4.etime (t3));
}
// calculate the center of the zoomed in/out preview given a cursor position
void CropWindow::findCenter (int deltaZoom, int& x, int& y)
{
int cursorX, cursorY;
screenCoordToImage(x, y, cursorX, cursorY);
int cropX, cropY, cropW, cropH, skip;
cropHandler.getWindow (cropX, cropY, cropW, cropH, skip);
int currCenterX = cropX + cropW / 2;
int currCenterY = cropY + cropH / 2;
int deltaX = currCenterX - cursorX;
int deltaY = currCenterY - cursorY;
double factor = zoomSteps[cropZoom].zoom / zoomSteps[cropZoom + deltaZoom].zoom;
x = cursorX + (int)((double)(deltaX) * factor);
y = cursorY + (int)((double)(deltaY) * factor);
void CropWindow::setEditSubscriber (EditSubscriber* newSubscriber) {
// Delete, create, update all buffers based upon newSubscriber's type
ObjectMOBuffer::resize(imgAreaW, imgAreaH, newSubscriber);
cropHandler.setEditSubscriber(newSubscriber);
}
// zoom* is called from the zoomPanel or the scroll wheel in the preview area
@@ -1806,7 +1834,7 @@ double CropWindow::getZoomFitVal ()
}
void CropWindow::zoomFit (bool skipZoomIfUnchanged)
void CropWindow::zoomFit ()
{
double z = cropHandler.getFitZoom ();
@@ -1822,7 +1850,7 @@ void CropWindow::zoomFit (bool skipZoomIfUnchanged)
}
zoomVersion = exposeVersion;
changeZoom (cz, true, -1, -1, skipZoomIfUnchanged);
changeZoom (cz, true, -1, -1);
fitZoom = true;
}
@@ -1845,7 +1873,7 @@ void CropWindow::zoomFitCrop ()
int centerX, centerY;
centerX = cropHandler.cropParams.x + cropHandler.cropParams.w / 2;
centerY = cropHandler.cropParams.y + cropHandler.cropParams.h / 2;
changeZoom (cz, true, centerX, centerY, false);
changeZoom (cz, true, centerX, centerY);
fitZoom = false;
}
}
@@ -1874,7 +1902,7 @@ void CropWindow::redrawNeeded (LWButton* button)
iarea->redraw ();
}
void CropWindow::changeZoom (int zoom, bool notify, int centerx, int centery, bool skipZoomIfUnchanged)
void CropWindow::changeZoom (int zoom, bool notify, int centerx, int centery)
{
if (zoom < 0) {
@@ -1883,19 +1911,14 @@ void CropWindow::changeZoom (int zoom, bool notify, int centerx, int centery, b
zoom = MAXZOOMSTEPS;
}
if (cropZoom == zoom && skipZoomIfUnchanged) {
// We are already at the start/end of the zoom range, so we do nothing
return;
}
cropZoom = zoom;
cropLabel = zoomSteps[cropZoom].label;
cropHandler.setZoom (zoomSteps[cropZoom].czoom, centerx, centery);
if (notify)
for (std::list<CropWindowListener*>::iterator i = listeners.begin(); i != listeners.end(); i++) {
(*i)->cropZoomChanged (this);
for (auto listener : listeners) {
listener->cropZoomChanged (this);
}
iarea->redraw ();
@@ -1905,8 +1928,8 @@ void CropWindow::screenCoordToCropBuffer (int phyx, int phyy, int& cropx, int& c
{
rtengine::Crop* crop = static_cast<rtengine::Crop*>(cropHandler.getCrop());
cropx = phyx - xpos - imgX;
cropy = phyy - ypos - imgY;
cropx = phyx - xpos - imgX - imgAreaX;
cropy = phyy - ypos - imgY - imgAreaY;
if (zoomSteps[cropZoom].zoom > 1.) {
cropx = int(double(cropx) / zoomSteps[cropZoom].zoom);
@@ -1926,11 +1949,11 @@ void CropWindow::screenCoordToImage (int phyx, int phyy, int& imgx, int& imgy)
imgy = cropY + (phyy - ypos - imgY) / zoomSteps[cropZoom].zoom;
}
void CropWindow::screenCoordToPreview (int phyx, int phyy, int& prevx, int& prevy)
void CropWindow::screenCoordToCropCanvas (int phyx, int phyy, int& prevx, int& prevy)
{
prevx = phyx - xpos - imgX;
prevy = phyy - ypos - imgY;
prevx = phyx - xpos - imgAreaX;
prevy = phyy - ypos - imgAreaY;
}
void CropWindow::imageCoordToScreen (int imgx, int imgy, int& phyx, int& phyy)
@@ -1938,9 +1961,17 @@ void CropWindow::imageCoordToScreen (int imgx, int imgy, int& phyx, int& phyy)
int cropX, cropY;
cropHandler.getPosition (cropX, cropY);
phyx = (imgx - cropX) * zoomSteps[cropZoom].zoom + xpos + imgX;
phyy = (imgy - cropY) * zoomSteps[cropZoom].zoom + ypos + imgY;
// printf("imgx:%d / imgy:%d / cropX:%d / cropY:%d / xpos:%d / ypos:%d / imgX:%d / imgY:%d / leftBorder: %d / upperBorder:%d / phyx:%d / phyy:%d\n", imgx, imgy, cropX, cropY, xpos, ypos, imgX, imgY, crop->getLeftBorder(), crop->getUpperBorder(), phyx, phyy);
phyx = (imgx - cropX) * zoomSteps[cropZoom].zoom + xpos + imgX + imgAreaX;
phyy = (imgy - cropY) * zoomSteps[cropZoom].zoom + ypos + imgY + imgAreaY;
}
void CropWindow::imageCoordToCropCanvas (int imgx, int imgy, int& phyx, int& phyy)
{
int cropX, cropY;
cropHandler.getPosition (cropX, cropY);
phyx = (imgx - cropX) * zoomSteps[cropZoom].zoom + imgX;
phyy = (imgy - cropY) * zoomSteps[cropZoom].zoom + imgY;
}
void CropWindow::imageCoordToCropBuffer (int imgx, int imgy, int& phyx, int& phyy)
@@ -1950,7 +1981,6 @@ void CropWindow::imageCoordToCropBuffer (int imgx, int imgy, int& phyx, int& phy
cropHandler.getPosition (cropX, cropY);
phyx = (imgx - cropX) * zoomSteps[cropZoom].zoom + /*xpos + imgX +*/ crop->getLeftBorder();
phyy = (imgy - cropY) * zoomSteps[cropZoom].zoom + /*ypos + imgY +*/ crop->getUpperBorder();
//printf("imgx:%d / imgy:%d / cropX:%d / cropY:%d / xpos:%d / ypos:%d / imgX:%d / imgY:%d / leftBorder: %d / upperBorder:%d / phyx:%d / phyy:%d\n", imgx, imgy, cropX, cropY, xpos, ypos, imgX, imgY, crop->getLeftBorder(), crop->getUpperBorder(), phyx, phyy);
}
int CropWindow::scaleValueToImage (int value)
@@ -1968,17 +1998,17 @@ double CropWindow::scaleValueToImage (double value)
return value / zoomSteps[cropZoom].zoom;
}
int CropWindow::scaleValueToScreen (int value)
int CropWindow::scaleValueToCanvas (int value)
{
return int(double(value) * zoomSteps[cropZoom].zoom);
}
float CropWindow::scaleValueToScreen (float value)
float CropWindow::scaleValueToCanvas (float value)
{
return float(double(value) * zoomSteps[cropZoom].zoom);
}
double CropWindow::scaleValueToScreen (double value)
double CropWindow::scaleValueToCanvas (double value)
{
return value * zoomSteps[cropZoom].zoom;
}
@@ -2113,7 +2143,7 @@ void CropWindow::drawScaledSpotRectangle (Cairo::RefPtr<Cairo::Context> cr, int
int x2 = action_x / zoomSteps[cropZoom].zoom + rectSize;
cr->set_line_width (1.0);
cr->rectangle (xpos + imgX - 0.5, ypos + imgY - 0.5, imgW, imgH);
cr->rectangle (xpos + imgX + imgAreaX - 0.5, ypos + imgY + imgAreaY - 0.5, imgAreaW, imgAreaH);
cr->clip ();
cr->set_source_rgb (1.0, 1.0, 1.0);
@@ -2135,7 +2165,7 @@ void CropWindow::drawUnscaledSpotRectangle (Cairo::RefPtr<Cairo::Context> cr, in
int x2 = action_x + rectSize;
cr->set_line_width (1.0);
cr->rectangle (xpos + imgX - 0.5, ypos + imgY - 0.5, imgW, imgH);
cr->rectangle (xpos + imgX + imgAreaX - 0.5, ypos + imgY + imgAreaY - 0.5, imgAreaW, imgAreaH);
cr->clip ();
cr->set_source_rgb (1.0, 1.0, 1.0);
@@ -2151,22 +2181,22 @@ void CropWindow::drawUnscaledSpotRectangle (Cairo::RefPtr<Cairo::Context> cr, in
void CropWindow::getObservedFrameArea (int& x, int& y, int& w, int& h, int rw, int rh)
{
int cropX, cropY, cropW, cropH;
observedCropWin->getCropRectangle (cropX, cropY, cropW, cropH);
int myCropX, myCropY, myCropW, myCropH;
getCropRectangle (myCropX, myCropY, myCropW, myCropH);
int observedCropX, observedCropY, observedCropW, observedCropH;
observedCropWin->getCropRectangle (observedCropX, observedCropY, observedCropW, observedCropH);
int mainCropX, mainCropY, mainCropW, mainCropH;
getCropRectangle (mainCropX, mainCropY, mainCropW, mainCropH);
// translate it to screen coordinates
if (rw) {
x = xpos + imgAreaX + (imgAreaW - rw) / 2 + (cropX - myCropX) * zoomSteps[cropZoom].zoom;
y = ypos + imgAreaY + (imgAreaH - rh) / 2 + (cropY - myCropY) * zoomSteps[cropZoom].zoom;
if (rw) { // rw and rh are the rough image's dimension
x = xpos + imgAreaX + (imgAreaW - rw) / 2 + (observedCropX - mainCropX) * zoomSteps[cropZoom].zoom;
y = ypos + imgAreaY + (imgAreaH - rh) / 2 + (observedCropY - mainCropY) * zoomSteps[cropZoom].zoom;
} else {
x = xpos + imgX + (cropX - myCropX) * zoomSteps[cropZoom].zoom;
y = ypos + imgY + (cropY - myCropY) * zoomSteps[cropZoom].zoom;
x = xpos + imgX + (observedCropX - mainCropX) * zoomSteps[cropZoom].zoom;
y = ypos + imgY + (observedCropY - mainCropY) * zoomSteps[cropZoom].zoom;
}
w = cropW * zoomSteps[cropZoom].zoom;
h = cropH * zoomSteps[cropZoom].zoom;
w = observedCropW * zoomSteps[cropZoom].zoom;
h = observedCropH * zoomSteps[cropZoom].zoom;
}
void CropWindow::drawObservedFrame (Cairo::RefPtr<Cairo::Context> cr, int rw, int rh)
@@ -2206,35 +2236,35 @@ void CropWindow::cropWindowChanged ()
void CropWindow::initialImageArrived ()
{
for (std::list<CropWindowListener*>::iterator i = listeners.begin(); i != listeners.end(); i++) {
(*i)->initialImageArrived (this);
for (auto listener : listeners) {
listener->initialImageArrived (this);
}
}
void CropWindow::setDisplayPosition (int x, int y) {
imgX = x;
imgY = y;
}
void CropWindow::remoteMove (int deltaX, int deltaY)
{
state = SCropImgMove;
action_x = deltaX;
action_y = deltaY;
cropHandler.moveAnchor(deltaX, deltaY, false);
for (std::list<CropWindowListener*>::iterator i = listeners.begin(); i != listeners.end(); i++) {
(*i)->cropPositionChanged (this);
for (auto listener : listeners) {
listener->cropPositionChanged (this);
}
}
void CropWindow::remoteMoveReady ()
{
int cropX, cropY;
cropHandler.getPosition (cropX, cropY);
cropHandler.setPosition (cropX + action_x, cropY + action_y);
cropHandler.getPosition (cropX, cropY);
cropHandler.update ();
state = SNormal;
for (std::list<CropWindowListener*>::iterator i = listeners.begin(); i != listeners.end(); i++) {
(*i)->cropPositionChanged (this);
for (auto listener : listeners) {
listener->cropPositionChanged (this);
}
}

View File

@@ -28,6 +28,7 @@
#include <list>
#include "cropguilistener.h"
#include "pointermotionlistener.h"
#include "edit.h"
class CropWindow;
class CropWindowListener
@@ -42,12 +43,13 @@ public:
};
class ImageArea;
class CropWindow : public LWButtonListener, public CropHandlerListener, public EditCoordSystem
class CropWindow : public LWButtonListener, public CropDisplayHandler, public EditCoordSystem, public ObjectMOBuffer
{
// state management
ImgEditState state; // current state of user (see enum State)
int action_x, action_y, press_x, press_y;
ImgEditState state; // current state of user (see enum State)
int press_x, press_y; // position of the cursor in the GUI space on button press
int action_x, action_y; // parameter that will evolve during a pan or drag action
double rot_deg;
bool onResizeArea;
bool deleted;
@@ -85,7 +87,7 @@ class CropWindow : public LWButtonListener, public CropHandlerListener, public E
PointerMotionListener* pmhlistener;
std::list<CropWindowListener*> listeners;
CropWindow* observedCropWin;
CropWindow* observedCropWin; // Pointer to the currently active detail CropWindow
rtengine::StagedImageProcessor* ipc;
bool onArea (CursorArea a, int x, int y);
@@ -95,7 +97,9 @@ class CropWindow : public LWButtonListener, public CropHandlerListener, public E
void drawScaledSpotRectangle (Cairo::RefPtr<Cairo::Context> cr, int rectSize);
void drawUnscaledSpotRectangle (Cairo::RefPtr<Cairo::Context> cr, int rectSize);
void drawObservedFrame (Cairo::RefPtr<Cairo::Context> cr, int rw = 0, int rh = 0);
void changeZoom (int zoom, bool notify = true, int centerx = -1, int centery = -1, bool skipZoomIfUnchanged = true);
void changeZoom (int zoom, bool notify = true, int centerx = -1, int centery = -1);
// Used by the mainCropWindow only
void getObservedFrameArea (int& x, int& y, int& w, int& h, int rw = 0, int rh = 0);
public:
@@ -117,15 +121,16 @@ public:
void screenCoordToCropBuffer (int phyx, int phyy, int& cropx, int& cropy);
void screenCoordToImage (int phyx, int phyy, int& imgx, int& imgy);
void screenCoordToPreview (int phyx, int phyy, int& prevx, int& prevy);
void screenCoordToCropCanvas (int phyx, int phyy, int& prevx, int& prevy);
void imageCoordToCropCanvas (int imgx, int imgy, int& phyx, int& phyy);
void imageCoordToScreen (int imgx, int imgy, int& phyx, int& phyy);
void imageCoordToCropBuffer (int imgx, int imgy, int& phyx, int& phyy);
int scaleValueToImage (int value);
float scaleValueToImage (float value);
double scaleValueToImage (double value);
int scaleValueToScreen (int value);
float scaleValueToScreen (float value);
double scaleValueToScreen (double value);
int scaleValueToCanvas (int value);
float scaleValueToCanvas (float value);
double scaleValueToCanvas (double value);
double getZoomFitVal ();
void setPosition (int x, int y);
void getPosition (int& x, int& y);
@@ -140,14 +145,13 @@ public:
void zoomIn (bool toCursor = false, int cursorX = -1, int cursorY = -1);
void zoomOut (bool toCursor = false, int cursorX = -1, int cursorY = -1);
void zoom11 ();
void zoomFit (bool skipZoomIfUnchanged = true);
void zoomFit ();
void zoomFitCrop ();
double getZoom ();
bool isMinZoom ();
bool isMaxZoom ();
void setZoom (double zoom);
void findCenter (int deltaZoom, int& x, int& y);
bool isInside (int x, int y);
@@ -157,15 +161,20 @@ public:
void expose (Cairo::RefPtr<Cairo::Context> cr);
void setEditSubscriber (EditSubscriber* newSubscriber);
// interface lwbuttonlistener
void buttonPressed (LWButton* button, int actionCode, void* actionData);
void redrawNeeded (LWButton* button);
// crop handling
void getCropRectangle (int& x, int& y, int& w, int& h);
void getCropPosition (int& x, int& y);
void setCropPosition (int x, int y, bool update = true);
void getCropSize (int& w, int& h);
void getCropRectangle (int& x, int& y, int& w, int& h);
void getCropPosition (int& x, int& y);
void setCropPosition (int x, int y, bool update = true);
void centerCrop (bool update = true);
void getCropSize (int& w, int& h);
void getCropAnchorPosition (int& w, int& h);
void setCropAnchorPosition (int& w, int& h);
// listeners
void setCropGUIListener (CropGUIListener* cgl)
@@ -192,6 +201,7 @@ public:
void cropImageUpdated ();
void cropWindowChanged ();
void initialImageArrived ();
void setDisplayPosition (int x, int y);
void remoteMove (int deltaX, int deltaY);
void remoteMoveReady ();

View File

@@ -18,9 +18,119 @@
*/
#include "edit.h"
#include "../rtengine/editbuffer.h"
#include "rtimage.h"
ObjectMOBuffer::ObjectMOBuffer(EditDataProvider *dataProvider) : objectMap(NULL), objectMap2(NULL), objectMode(OM_255), dataProvider(dataProvider) {}
ObjectMOBuffer::~ObjectMOBuffer()
{
flush();
}
/* Upgrade or downgrade the objectModeType; we're assuming that objectMap has been allocated */
void ObjectMOBuffer::setObjectMode(ObjectMode newType)
{
switch (newType) {
case (OM_255):
if (objectMap2) {
objectMap2->unreference();
}
objectMode = OM_255;
break;
case (OM_65535):
if (!objectMap2) {
objectMap2 = Cairo::ImageSurface::create(Cairo::FORMAT_A8, objectMap->get_width(), objectMap->get_height());
}
objectMode = OM_65535;
break;
}
}
void ObjectMOBuffer::flush()
{
if (objectMap ) {
objectMap.clear();
}
if (objectMap2) {
objectMap2.clear();
}
}
EditSubscriber *ObjectMOBuffer::getEditSubscriber () {
if (dataProvider) {
return dataProvider->getCurrSubscriber();
} else {
return NULL;
}
}
// Resize buffers if they already exist
void ObjectMOBuffer::resize(int newWidth, int newHeight, EditSubscriber* newSubscriber)
{
if (newSubscriber) {
if (newSubscriber->getEditingType() == ET_OBJECTS) {
if (objectMap && (objectMap->get_width() != newWidth || objectMap->get_height() != newHeight)) {
objectMap.clear();
}
if (!objectMap && newWidth>0 && newHeight>0) {
objectMap = Cairo::ImageSurface::create(Cairo::FORMAT_A8, newWidth, newHeight);
}
if (objectMode == OM_65535) {
if (objectMap2) {
if (objectMap2->get_width() != newWidth || objectMap2->get_height() != newHeight) {
objectMap2.clear();
}
}
if (!objectMap2 && newWidth>0 && newHeight>0) {
objectMap2 = Cairo::ImageSurface::create(Cairo::FORMAT_A8, newWidth, newHeight);
}
} else if (objectMap2) {
// OM_255 -> deleting objectMap2, if any
objectMap2.clear();
}
} else {
flush();
}
} else {
flush();
}
}
int ObjectMOBuffer::getObjectID(const rtengine::Coord& location)
{
int id = 0;
if (objectMap && location.x > 0 && location.y > 0 && location.x < objectMap->get_width() && location.y < objectMap->get_height()) {
id = (unsigned short)(*( objectMap->get_data() + location.y * objectMap->get_stride() + location.x ));
if (objectMap2) {
id |= (unsigned short)(*( objectMap->get_data() + location.y * objectMap->get_stride() + location.x )) << 8;
}
}
return id - 1;
}
bool ObjectMOBuffer::bufferCreated()
{
EditSubscriber* subscriber;
if (dataProvider && (subscriber = dataProvider->getCurrSubscriber())) {
return subscriber->getEditingType() == ET_OBJECTS ? bool(objectMap) : false;
}
return false;
}
RGBColor Geometry::getInnerLineColor ()
{
RGBColor color;
@@ -60,7 +170,7 @@ RGBColor Geometry::getOuterLineColor ()
return color;
}
void Circle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
void Circle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
{
if ((flags & F_VISIBLE) && state != INSENSITIVE) {
RGBColor color;
@@ -75,14 +185,14 @@ void Circle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Edit
cr->set_line_width( getOuterLineWidth() );
rtengine::Coord center_ = center;
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToScreen(double(radius)) : double(radius);
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas(double(radius)) : double(radius);
if (datum == IMAGE) {
coordSystem.imageCoordToScreen(center.x, center.y, center_.x, center_.y);
coordSystem.imageCoordToScreen (center.x, center.y, center_.x, center_.y);
} else if (datum == CLICKED_POINT) {
center_ += editBuffer->getDataProvider()->posScreen;
center_ += objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
center_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
center_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
cr->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0., 2.*M_PI);
@@ -90,7 +200,7 @@ void Circle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Edit
}
}
void Circle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
void Circle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
{
if (flags & F_VISIBLE) {
if (state != INSENSITIVE) {
@@ -108,14 +218,14 @@ void Circle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Edit
cr->set_line_width( innerLineWidth );
rtengine::Coord center_ = center;
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToScreen(double(radius)) : double(radius);
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas(double(radius)) : double(radius);
if (datum == IMAGE) {
coordSystem.imageCoordToScreen(center.x, center.y, center_.x, center_.y);
coordSystem.imageCoordToScreen (center.x, center.y, center_.x, center_.y);
} else if (datum == CLICKED_POINT) {
center_ += editBuffer->getDataProvider()->posScreen;
center_ += objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
center_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
center_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
if (filled && state != INSENSITIVE) {
@@ -147,19 +257,19 @@ void Circle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Edit
}
}
void Circle::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
void Circle::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
{
if (flags & F_HOVERABLE) {
cr->set_line_width( getMouseOverLineWidth() );
rtengine::Coord center_ = center;
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToScreen(double(radius)) : double(radius);
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas(double(radius)) : double(radius);
if (datum == IMAGE) {
coordSystem.imageCoordToCropBuffer(center.x, center.y, center_.x, center_.y);
coordSystem.imageCoordToCropCanvas (center.x, center.y, center_.x, center_.y);
} else if (datum == CLICKED_POINT) {
center_ += editBuffer->getDataProvider()->posScreen;
center_ += objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
center_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
center_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
// drawing the lower byte's value
@@ -179,7 +289,7 @@ void Circle::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<C
}
// drawing the higher byte's value
if (editBuffer->getObjectMode() == OM_65535) {
if (objectBuffer->getObjectMode() == OM_65535) {
a = (id + 1) >> 8;
cr2->set_source_rgba (0., 0., 0., double(a) / 255.);
cr2->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0, 2.*M_PI);
@@ -198,7 +308,7 @@ void Circle::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<C
}
}
void Line::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
void Line::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
{
if ((flags & F_VISIBLE) && state != INSENSITIVE) {
RGBColor color;
@@ -216,14 +326,14 @@ void Line::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBu
rtengine::Coord end_ = end;
if (datum == IMAGE) {
coordSystem.imageCoordToScreen(begin.x, begin.y, begin_.x, begin_.y);
coordSystem.imageCoordToScreen(end.x, end.y, end_.x, end_.y);
coordSystem.imageCoordToScreen (begin.x, begin.y, begin_.x, begin_.y);
coordSystem.imageCoordToScreen (end.x, end.y, end_.x, end_.y);
} else if (datum == CLICKED_POINT) {
begin_ += editBuffer->getDataProvider()->posScreen;
end_ += editBuffer->getDataProvider()->posScreen;
begin_ += objectBuffer->getDataProvider()->posScreen;
end_ += objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
begin_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
end_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
begin_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
end_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
cr->move_to(begin_.x + 0.5, begin_.y + 0.5);
@@ -232,7 +342,7 @@ void Line::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBu
}
}
void Line::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
void Line::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
{
if ((flags & F_VISIBLE) && innerLineWidth > 0.) {
if (state != INSENSITIVE) {
@@ -253,14 +363,14 @@ void Line::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBu
rtengine::Coord end_ = end;
if (datum == IMAGE) {
coordSystem.imageCoordToScreen(begin.x, begin.y, begin_.x, begin_.y);
coordSystem.imageCoordToScreen(end.x, end.y, end_.x, end_.y);
coordSystem.imageCoordToScreen (begin.x, begin.y, begin_.x, begin_.y);
coordSystem.imageCoordToScreen (end.x, end.y, end_.x, end_.y);
} else if (datum == CLICKED_POINT) {
begin_ += editBuffer->getDataProvider()->posScreen;
end_ += editBuffer->getDataProvider()->posScreen;
begin_ += objectBuffer->getDataProvider()->posScreen;
end_ += objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
begin_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
end_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
begin_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
end_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
cr->move_to(begin_.x + 0.5, begin_.y + 0.5);
@@ -284,7 +394,7 @@ void Line::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBu
void Line::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr,
Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id,
rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
{
if (flags & F_HOVERABLE) {
cr->set_line_width( getMouseOverLineWidth() );
@@ -292,14 +402,14 @@ void Line::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr,
rtengine::Coord end_ = end;
if (datum == IMAGE) {
coordSystem.imageCoordToCropBuffer(begin.x, begin.y, begin_.x, begin_.y);
coordSystem.imageCoordToCropBuffer(end.x, end.y, end_.x, end_.y);
coordSystem.imageCoordToCropCanvas (begin.x, begin.y, begin_.x, begin_.y);
coordSystem.imageCoordToCropCanvas (end.x, end.y, end_.x, end_.y);
} else if (datum == CLICKED_POINT) {
begin_ += editBuffer->getDataProvider()->posScreen;
end_ += editBuffer->getDataProvider()->posScreen;
begin_ += objectBuffer->getDataProvider()->posScreen;
end_ += objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
begin_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
end_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
begin_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
end_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
// drawing the lower byte's value
@@ -310,7 +420,7 @@ void Line::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr,
cr->stroke();
// drawing the higher byte's value
if (editBuffer->getObjectMode() == OM_65535) {
if (objectBuffer->getObjectMode() == OM_65535) {
a = (id + 1) >> 8;
cr2->set_source_rgba (0., 0., 0., double(a) / 255.);
cr2->move_to(begin_.x + 0.5, begin_.y + 0.5);
@@ -320,7 +430,7 @@ void Line::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr,
}
}
void Polyline::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
void Polyline::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
{
if ((flags & F_VISIBLE) && state != INSENSITIVE && points.size() > 1) {
RGBColor color;
@@ -340,11 +450,11 @@ void Polyline::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Ed
currPos = points.at(i);
if (datum == IMAGE) {
coordSystem.imageCoordToScreen(points.at(i).x, points.at(i).y, currPos.x, currPos.y);
coordSystem.imageCoordToScreen (points.at(i).x, points.at(i).y, currPos.x, currPos.y);
} else if (datum == CLICKED_POINT) {
currPos += editBuffer->getDataProvider()->posScreen;
currPos += objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
currPos += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
if (!i) {
@@ -363,7 +473,7 @@ void Polyline::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Ed
}
}
void Polyline::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
void Polyline::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
{
if ((flags & F_VISIBLE) && points.size() > 1) {
if (state != INSENSITIVE) {
@@ -387,11 +497,11 @@ void Polyline::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Ed
currPos = points.at(i);
if (datum == IMAGE) {
coordSystem.imageCoordToScreen(points.at(i).x, points.at(i).y, currPos.x, currPos.y);
coordSystem.imageCoordToScreen (points.at(i).x, points.at(i).y, currPos.x, currPos.y);
} else if (datum == CLICKED_POINT) {
currPos += editBuffer->getDataProvider()->posScreen;
currPos += objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
currPos += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
if (!i) {
@@ -414,11 +524,11 @@ void Polyline::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Ed
currPos = points.at(i);
if (datum == IMAGE) {
coordSystem.imageCoordToScreen(points.at(i).x, points.at(i).y, currPos.x, currPos.y);
coordSystem.imageCoordToScreen (points.at(i).x, points.at(i).y, currPos.x, currPos.y);
} else if (datum == CLICKED_POINT) {
currPos += editBuffer->getDataProvider()->posScreen;
currPos += objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
currPos += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
if (!i) {
@@ -445,7 +555,7 @@ void Polyline::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Ed
}
}
void Polyline::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
void Polyline::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
{
if ((flags & F_HOVERABLE) && points.size() > 1) {
rtengine::Coord currPos;
@@ -459,11 +569,11 @@ void Polyline::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr
currPos = points.at(i);
if (datum == IMAGE) {
coordSystem.imageCoordToCropBuffer(points.at(i).x, points.at(i).y, currPos.x, currPos.y);
coordSystem.imageCoordToCropCanvas (points.at(i).x, points.at(i).y, currPos.x, currPos.y);
} else if (datum == CLICKED_POINT) {
currPos += editBuffer->getDataProvider()->posScreen;
currPos += objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
currPos += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
if (!i) {
@@ -485,7 +595,7 @@ void Polyline::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr
}
// drawing the higher byte's value
if (editBuffer->getObjectMode() == OM_65535) {
if (objectBuffer->getObjectMode() == OM_65535) {
a = (id + 1) >> 8;
cr2->set_source_rgba (0., 0., 0., double(a) / 255.);
@@ -494,11 +604,11 @@ void Polyline::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr
currPos = points.at(i);
if (datum == IMAGE) {
coordSystem.imageCoordToCropBuffer(points.at(i).x, points.at(i).y, currPos.x, currPos.y);
coordSystem.imageCoordToCropCanvas (points.at(i).x, points.at(i).y, currPos.x, currPos.y);
} else if (datum == CLICKED_POINT) {
currPos += editBuffer->getDataProvider()->posScreen;
currPos += objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
currPos += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
if (!i) {
@@ -546,7 +656,7 @@ void Rectangle::setXYXY(rtengine::Coord topLeft, rtengine::Coord bottomRight)
this->bottomRight = bottomRight;
}
void Rectangle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
void Rectangle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
{
if ((flags & F_VISIBLE) && state != INSENSITIVE) {
RGBColor color;
@@ -563,19 +673,19 @@ void Rectangle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::E
rtengine::Coord tl, br;
if (datum == IMAGE) {
coordSystem.imageCoordToScreen(topLeft.x, topLeft.y, tl.x, tl.y);
coordSystem.imageCoordToScreen (topLeft.x, topLeft.y, tl.x, tl.y);
} else if (datum == CLICKED_POINT) {
tl = topLeft + editBuffer->getDataProvider()->posScreen;
tl = topLeft + objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
tl = topLeft + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
tl = topLeft + objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
if (datum == IMAGE) {
coordSystem.imageCoordToScreen(bottomRight.x, bottomRight.y, br.x, br.y);
coordSystem.imageCoordToScreen (bottomRight.x, bottomRight.y, br.x, br.y);
} else if (datum == CLICKED_POINT) {
br = bottomRight + editBuffer->getDataProvider()->posScreen;
br = bottomRight + objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
br = bottomRight + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
br = bottomRight + objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
cr->rectangle(tl.x + 0.5, tl.y + 0.5, br.x - tl.x, br.y - tl.y);
@@ -589,7 +699,7 @@ void Rectangle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::E
}
}
void Rectangle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
void Rectangle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
{
if (flags & F_VISIBLE) {
if (state != INSENSITIVE) {
@@ -609,19 +719,19 @@ void Rectangle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::E
rtengine::Coord tl, br;
if (datum == IMAGE) {
coordSystem.imageCoordToScreen(topLeft.x, topLeft.y, tl.x, tl.y);
coordSystem.imageCoordToScreen (topLeft.x, topLeft.y, tl.x, tl.y);
} else if (datum == CLICKED_POINT) {
tl = topLeft + editBuffer->getDataProvider()->posScreen;
tl = topLeft + objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
tl = topLeft + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
tl = topLeft + objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
if (datum == IMAGE) {
coordSystem.imageCoordToScreen(bottomRight.x, bottomRight.y, br.x, br.y);
coordSystem.imageCoordToScreen (bottomRight.x, bottomRight.y, br.x, br.y);
} else if (datum == CLICKED_POINT) {
br = bottomRight + editBuffer->getDataProvider()->posScreen;
br = bottomRight + objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
br = bottomRight + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
br = bottomRight + objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
if (filled && state != INSENSITIVE) {
@@ -653,7 +763,7 @@ void Rectangle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::E
}
}
void Rectangle::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
void Rectangle::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
{
if (flags & F_HOVERABLE) {
cr->set_line_width( getMouseOverLineWidth() );
@@ -661,19 +771,19 @@ void Rectangle::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr
rtengine::Coord tl, br;
if (datum == IMAGE) {
coordSystem.imageCoordToCropBuffer(topLeft.x, topLeft.y, tl.x, tl.y);
coordSystem.imageCoordToCropCanvas (topLeft.x, topLeft.y, tl.x, tl.y);
} else if (datum == CLICKED_POINT) {
tl = topLeft + editBuffer->getDataProvider()->posScreen;
tl = topLeft + objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
tl = topLeft + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
tl = topLeft + objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
if (datum == IMAGE) {
coordSystem.imageCoordToCropBuffer(bottomRight.x, bottomRight.y, br.x, br.y);
coordSystem.imageCoordToCropCanvas (bottomRight.x, bottomRight.y, br.x, br.y);
} else if (datum == CLICKED_POINT) {
br = bottomRight + editBuffer->getDataProvider()->posScreen;
br = bottomRight + objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
br = bottomRight + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
br = bottomRight + objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
// drawing the lower byte's value
@@ -693,7 +803,7 @@ void Rectangle::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr
}
// drawing the higher byte's value
if (editBuffer->getObjectMode() == OM_65535) {
if (objectBuffer->getObjectMode() == OM_65535) {
a = (id + 1) >> 8;
cr2->set_source_rgba (0., 0., 0., double(a) / 255.);
cr->rectangle(tl.x + 0.5, tl.y + 0.5, br.x - tl.x, br.y - tl.y);
@@ -766,7 +876,7 @@ EditType EditSubscriber::getEditingType()
return editingType;
}
BufferType EditSubscriber::getEditBufferType()
BufferType EditSubscriber::getPipetteBufferType()
{
return bufferType;
}

View File

@@ -29,11 +29,7 @@
#include "options.h"
class EditDataProvider;
namespace rtengine
{
class EditBuffer;
}
class EditSubscriber;
/** @file
*
@@ -41,9 +37,6 @@ class EditBuffer;
* Subscribers will be tools that need to create some graphics in the preview area, to let the user interact
* with it in a more user friendly way.
*
* Subscribers will be tools that need to create some graphics in the preview area, to let the user interact
* with it in a more user friendly way.
*
* Do not confuse with _local_ editing, which is another topic implemented in another class. The Edit feature
* is also not supported in batch editing from the File Browser.
*
@@ -84,7 +77,7 @@ class EditBuffer;
*
* ## Object edition
*
* By using this class, object can be drawn and manipulated on the preview.
* By using this class, objects can be drawn and manipulated on the preview.
*
* The developer has to handle the buttonPress, buttonRelease, drag and mouseOver method that he needs. There
* are buttonPress, buttonRelease and drag methods dedicated to each mouse button, for better flexibility
@@ -92,7 +85,7 @@ class EditBuffer;
* does not handle multiple mouse button event (e.g. button1 + button2), only one at a time. The first button pressed
* set the mechanism, all other combined button press are ignored.
*
* The developer also have to fill 2 display list with object of the Geometry subclass. Each geometrical shape
* The developer also have to fill 2 display list with object of the Geometry subclass. Each geometric shape
* _can_ be used in one or the other, or both list at a time.
*
* The first list (visibleGeometry) is used to be displayed on the preview. The developer will have to set their state
@@ -152,6 +145,59 @@ class EditBuffer;
*
*/
class ObjectMOBuffer
{
private:
// Used to draw the objects where the color correspond to the object's ID, in order to find the correct object when hovering
Cairo::RefPtr<Cairo::ImageSurface> objectMap;
// If more than 254 objects has to be handled, objectMap2 contains the "upper part" of the 16 bit int value. objectMap2 will be NULL otherwise.
Cairo::RefPtr<Cairo::ImageSurface> objectMap2;
ObjectMode objectMode;
protected:
// To avoid duplicated information, we points to a EditDataProvider that contains the current EditSubscriber
// instead of pointing to the EditSubscriber directly
EditDataProvider* dataProvider;
void createBuffer(int width, int height);
void resize(int newWidth, int newHeight, EditSubscriber* newSubscriber);
void flush();
EditSubscriber *getEditSubscriber ();
public:
ObjectMOBuffer(EditDataProvider *dataProvider);
~ObjectMOBuffer();
EditDataProvider* getDataProvider()
{
return dataProvider;
}
void setObjectMode(ObjectMode newType);
ObjectMode getObjectMode()
{
return objectMode;
}
Cairo::RefPtr<Cairo::ImageSurface> &getObjectMap ()
{
return objectMap;
}
Cairo::RefPtr<Cairo::ImageSurface> &getObjectMap2()
{
return objectMap2;
}
// return true if the buffer has been allocated
bool bufferCreated();
int getObjectID(const rtengine::Coord& location);
};
/** @brief Coordinate system where the widgets will be drawn
*
* The EditCoordSystem is used to define a screen and an image coordinate system.
@@ -167,6 +213,8 @@ public:
virtual void screenCoordToImage (int phyx, int phyy, int& imgx, int& imgy) = 0;
/// Convert the image coords to the widget's DrawingArea (i.e. preview area) coords
virtual void imageCoordToScreen (int imgx, int imgy, int& phyx, int& phyy) = 0;
/// Convert the image coords to the crop's canvas coords
virtual void imageCoordToCropCanvas (int imgx, int imgy, int& phyx, int& phyy) = 0;
/// Convert the image coords to the edit buffer coords
virtual void imageCoordToCropBuffer (int imgx, int imgy, int& phyx, int& phyy) = 0;
/// Convert a size value from the preview's scale to the image's scale
@@ -176,11 +224,11 @@ public:
/// Convert a size value from the preview's scale to the image's scale
virtual double scaleValueToImage (double value) = 0;
/// Convert a size value from the image's scale to the preview's scale
virtual int scaleValueToScreen (int value) = 0;
virtual int scaleValueToCanvas (int value) = 0;
/// Convert a size value from the image's scale to the preview's scale
virtual float scaleValueToScreen (float value) = 0;
virtual float scaleValueToCanvas (float value) = 0;
/// Convert a size value from the image's scale to the preview's scale
virtual double scaleValueToScreen (double value) = 0;
virtual double scaleValueToCanvas (double value) = 0;
};
class RGBColor
@@ -373,9 +421,9 @@ public:
}
}
virtual void drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *parent, EditCoordSystem &coordSystem) = 0;
virtual void drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *parent, EditCoordSystem &coordSystem) = 0;
virtual void drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) = 0;
virtual void drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *parent, EditCoordSystem &coordSystem) = 0;
virtual void drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *parent, EditCoordSystem &coordSystem) = 0;
virtual void drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem) = 0;
};
class Circle : public Geometry
@@ -390,9 +438,9 @@ public:
Circle (rtengine::Coord &center, int radius, bool filled = false, bool radiusInImageSpace = false) : center(center), radius(radius), filled(filled), radiusInImageSpace(radiusInImageSpace) {}
Circle (int centerX, int centerY, int radius, bool filled = false, bool radiusInImageSpace = false) : center(centerX, centerY), radius(radius), filled(filled), radiusInImageSpace(radiusInImageSpace) {}
void drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem);
void drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem);
void drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem);
void drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem);
void drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem);
void drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem);
};
class Line : public Geometry
@@ -405,9 +453,9 @@ public:
Line (rtengine::Coord &begin, rtengine::Coord &end) : begin(begin), end(end) {}
Line (int beginX, int beginY, int endX, int endY) : begin(beginX, beginY), end(endX, endY) {}
void drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem);
void drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem);
void drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem);
void drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem);
void drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem);
void drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem);
};
class Polyline : public Geometry
@@ -418,9 +466,9 @@ public:
Polyline() : filled(false) {}
void drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem);
void drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem);
void drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem);
void drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem);
void drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem);
void drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem);
};
class Rectangle : public Geometry
@@ -436,9 +484,9 @@ public:
void setXYXY(int left, int top, int right, int bottom);
void setXYWH(rtengine::Coord topLeft, rtengine::Coord widthHeight);
void setXYXY(rtengine::Coord topLeft, rtengine::Coord bottomRight);
void drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem);
void drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem);
void drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem);
void drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem);
void drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem);
void drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem);
};
/// @brief Method for client tools needing Edit information
@@ -474,7 +522,7 @@ public:
virtual void switchOffEditMode (); /// Occurs when the user want to stop the editing mode
EditUniqueID getEditID();
EditType getEditingType();
BufferType getEditBufferType();
BufferType getPipetteBufferType();
bool isDragging(); /// Returns true if something is being dragged and drag events has to be sent (object mode only)
/** @brief Get the cursor to be displayed when above handles
@@ -487,7 +535,6 @@ public:
/** @brief Triggered when the mouse is moving over an object
This method is also triggered when the cursor is moving over the image in ET_PIPETTE mode
@param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...)
@param editBuffer buffer to get the pipette values and the from
@return true if the preview has to be redrawn, false otherwise */
virtual bool mouseOver(int modifierKey)
{

View File

@@ -136,88 +136,99 @@ void Gradient::read (const ProcParams* pp, const ParamsEdited* pedited)
enableListener ();
}
void Gradient::updateGeometry(int centerX_, int centerY_, double feather_, double degree_)
void Gradient::updateGeometry(const int centerX_, const int centerY_, const double feather_, const double degree_, const int fullWidth, const int fullHeight)
{
EditDataProvider* dataProvider = getEditProvider();
if (dataProvider) {
int imW, imH;
PolarCoord polCoord1, polCoord2;
dataProvider->getImageSize(imW, imH);
double decay = feather_ * sqrt(double(imW) * double(imW) + double(imH) * double(imH)) / 200.;
rtengine::Coord origin(imW / 2 + centerX_ * imW / 200.f, imH / 2 + centerY_ * imH / 200.f);
Line *currLine;
Circle *currCircle;
// update horizontal line
currLine = static_cast<Line*>(visibleGeometry.at(0));
polCoord1.set(1500.f, float(-degree_ + 180));
currLine->begin.setFromPolar(polCoord1);
currLine->begin += origin;
polCoord1.set(1500.f, float(-degree_ ));
currLine->end.setFromPolar (polCoord1);
currLine->end += origin;
currLine = static_cast<Line*>(mouseOverGeometry.at(0));
polCoord1.set(1500.f, float(-degree_ + 180));
currLine->begin.setFromPolar(polCoord1);
currLine->begin += origin;
polCoord1.set(1500.f, float(-degree_ ));
currLine->end.setFromPolar (polCoord1);
currLine->end += origin;
// update vertical line
currLine = static_cast<Line*>(visibleGeometry.at(1));
polCoord1.set( 700.f, float(-degree_ + 90 ));
currLine->begin.setFromPolar(polCoord1);
currLine->begin += origin;
polCoord1.set( 700.f, float(-degree_ + 270));
currLine->end.setFromPolar (polCoord1);
currLine->end += origin;
currLine = static_cast<Line*>(mouseOverGeometry.at(1));
polCoord1.set( 700.f, float(-degree_ + 90 ));
currLine->begin.setFromPolar(polCoord1);
currLine->begin += origin;
polCoord1.set( 700.f, float(-degree_ + 270));
currLine->end.setFromPolar (polCoord1);
currLine->end += origin;
// update upper feather line
currLine = static_cast<Line*>(visibleGeometry.at(2));
polCoord2.set(decay, float(-degree_ + 270));
polCoord1.set(350.f, float(-degree_ + 180));
currLine->begin.setFromPolar(polCoord1 + polCoord2);
currLine->begin += origin;
polCoord1.set(350.f, float(-degree_ ));
currLine->end.setFromPolar (polCoord1 + polCoord2);
currLine->end += origin;
currLine = static_cast<Line*>(mouseOverGeometry.at(2));
polCoord1.set(350.f, float(-degree_ + 180));
currLine->begin.setFromPolar(polCoord1 + polCoord2);
currLine->begin += origin;
polCoord1.set(350.f, float(-degree_ ));
currLine->end.setFromPolar (polCoord1 + polCoord2);
currLine->end += origin;
// update lower feather line
currLine = static_cast<Line*>(visibleGeometry.at(3));
polCoord2.set(decay, float(-degree_ + 90));
polCoord1.set(350.f, float(-degree_ + 180));
currLine->begin.setFromPolar(polCoord1 + polCoord2);
currLine->begin += origin;
polCoord1.set(350.f, float(-degree_ ));
currLine->end.setFromPolar (polCoord1 + polCoord2);
currLine->end += origin;
currLine = static_cast<Line*>(mouseOverGeometry.at(3));
polCoord1.set(350.f, float(-degree_ + 180));
currLine->begin.setFromPolar(polCoord1 + polCoord2);
currLine->begin += origin;
polCoord1.set(350.f, float(-degree_ ));
currLine->end.setFromPolar (polCoord1 + polCoord2);
currLine->end += origin;
// update circle's position
currCircle = static_cast<Circle*>(visibleGeometry.at(4));
currCircle->center = origin;
currCircle = static_cast<Circle*>(mouseOverGeometry.at(4));
currCircle->center = origin;
if (!dataProvider) {
return;
}
int imW, imH;
if (fullWidth != -1 && fullHeight != -1) {
imW = fullWidth;
imH = fullHeight;
} else {
dataProvider->getImageSize(imW, imH);
if (!imW || !imH) {
return;
}
}
PolarCoord polCoord1, polCoord2;
double decay = feather_ * sqrt(double(imW) * double(imW) + double(imH) * double(imH)) / 200.;
rtengine::Coord origin(imW / 2 + centerX_ * imW / 200.f, imH / 2 + centerY_ * imH / 200.f);
Line *currLine;
Circle *currCircle;
// update horizontal line
currLine = static_cast<Line*>(visibleGeometry.at(0));
polCoord1.set(1500.f, float(-degree_ + 180));
currLine->begin.setFromPolar(polCoord1);
currLine->begin += origin;
polCoord1.set(1500.f, float(-degree_ ));
currLine->end.setFromPolar (polCoord1);
currLine->end += origin;
currLine = static_cast<Line*>(mouseOverGeometry.at(0));
polCoord1.set(1500.f, float(-degree_ + 180));
currLine->begin.setFromPolar(polCoord1);
currLine->begin += origin;
polCoord1.set(1500.f, float(-degree_ ));
currLine->end.setFromPolar (polCoord1);
currLine->end += origin;
// update vertical line
currLine = static_cast<Line*>(visibleGeometry.at(1));
polCoord1.set( 700.f, float(-degree_ + 90 ));
currLine->begin.setFromPolar(polCoord1);
currLine->begin += origin;
polCoord1.set( 700.f, float(-degree_ + 270));
currLine->end.setFromPolar (polCoord1);
currLine->end += origin;
currLine = static_cast<Line*>(mouseOverGeometry.at(1));
polCoord1.set( 700.f, float(-degree_ + 90 ));
currLine->begin.setFromPolar(polCoord1);
currLine->begin += origin;
polCoord1.set( 700.f, float(-degree_ + 270));
currLine->end.setFromPolar (polCoord1);
currLine->end += origin;
// update upper feather line
currLine = static_cast<Line*>(visibleGeometry.at(2));
polCoord2.set(decay, float(-degree_ + 270));
polCoord1.set(350.f, float(-degree_ + 180));
currLine->begin.setFromPolar(polCoord1 + polCoord2);
currLine->begin += origin;
polCoord1.set(350.f, float(-degree_ ));
currLine->end.setFromPolar (polCoord1 + polCoord2);
currLine->end += origin;
currLine = static_cast<Line*>(mouseOverGeometry.at(2));
polCoord1.set(350.f, float(-degree_ + 180));
currLine->begin.setFromPolar(polCoord1 + polCoord2);
currLine->begin += origin;
polCoord1.set(350.f, float(-degree_ ));
currLine->end.setFromPolar (polCoord1 + polCoord2);
currLine->end += origin;
// update lower feather line
currLine = static_cast<Line*>(visibleGeometry.at(3));
polCoord2.set(decay, float(-degree_ + 90));
polCoord1.set(350.f, float(-degree_ + 180));
currLine->begin.setFromPolar(polCoord1 + polCoord2);
currLine->begin += origin;
polCoord1.set(350.f, float(-degree_ ));
currLine->end.setFromPolar (polCoord1 + polCoord2);
currLine->end += origin;
currLine = static_cast<Line*>(mouseOverGeometry.at(3));
polCoord1.set(350.f, float(-degree_ + 180));
currLine->begin.setFromPolar(polCoord1 + polCoord2);
currLine->begin += origin;
polCoord1.set(350.f, float(-degree_ ));
currLine->end.setFromPolar (polCoord1 + polCoord2);
currLine->end += origin;
// update circle's position
currCircle = static_cast<Circle*>(visibleGeometry.at(4));
currCircle->center = origin;
currCircle = static_cast<Circle*>(mouseOverGeometry.at(4));
currCircle->center = origin;
}
void Gradient::write (ProcParams* pp, ParamsEdited* pedited)
@@ -399,7 +410,7 @@ bool Gradient::button1Pressed(int modifierKey)
{
EditDataProvider *provider = getEditProvider();
if (!(modifierKey & GDK_CONTROL_MASK)) {
if (!(modifierKey & GDK_CONTROL_MASK) && lastObject > -1) {
// button press is valid (no modifier key)
PolarCoord pCoord;
int imW, imH;
@@ -447,20 +458,20 @@ bool Gradient::button1Pressed(int modifierKey)
EditSubscriber::dragging = true;
return false;
} else {
} else if (lastObject > -1) { // should theoretically always be true
// this will let this class ignore further drag events
if (lastObject > -1) { // should theoretically always be true
if (lastObject == 2 || lastObject == 3) {
EditSubscriber::visibleGeometry.at(2)->state = Geometry::NORMAL;
EditSubscriber::visibleGeometry.at(3)->state = Geometry::NORMAL;
} else {
EditSubscriber::visibleGeometry.at(lastObject)->state = Geometry::NORMAL;
}
if (lastObject == 2 || lastObject == 3) {
EditSubscriber::visibleGeometry.at(2)->state = Geometry::NORMAL;
EditSubscriber::visibleGeometry.at(3)->state = Geometry::NORMAL;
} else {
EditSubscriber::visibleGeometry.at(lastObject)->state = Geometry::NORMAL;
}
lastObject = -1;
return true;
}
return false;
}
bool Gradient::button1Released()

View File

@@ -42,12 +42,11 @@ public:
void setDefaults (const rtengine::procparams::ProcParams* defParams, const ParamsEdited* pedited = NULL);
void setBatchMode (bool batchMode);
void updateGeometry (int centerX_, int centerY_, double feather_, double degree_);
void adjusterChanged (Adjuster* a, double newval);
void enabledChanged ();
void setAdjusterBehavior (bool degreeadd, bool featheradd, bool strengthadd, bool centeradd);
void trimValues (rtengine::procparams::ProcParams* pp);
void updateGeometry (const int centerX_, const int centerY_, const double feather_, const double degree_, const int fullWidth=-1, const int fullHeight=-1);
void setEditProvider (EditDataProvider* provider);

View File

@@ -56,8 +56,8 @@ ImageArea::ImageArea (ImageAreaPanel* p) : parent(p), firstOpen(true)
ImageArea::~ImageArea ()
{
for (std::list<CropWindow*>::iterator i = cropWins.begin(); i != cropWins.end(); i++) {
delete *i;
for (auto cropWin : cropWins) {
delete cropWin;
}
cropWins.clear ();
@@ -110,10 +110,9 @@ void ImageArea::setImProcCoordinator (rtengine::StagedImageProcessor* ipc_)
{
if( !ipc_ ) {
focusGrabber = NULL;
std::list<CropWindow*>::iterator i = cropWins.begin();
for( ; i != cropWins.end(); i++ ) {
delete *i;
for (auto cropWin : cropWins) {
delete cropWin;
}
cropWins.clear();
@@ -170,10 +169,11 @@ CropWindow* ImageArea::getCropWindow (int x, int y)
CropWindow* cw = mainCropWindow;
for (std::list<CropWindow*>::iterator i = cropWins.begin(); i != cropWins.end(); i++)
if ((*i)->isInside (x, y)) {
return *i;
for (auto cropWin : cropWins) {
if (cropWin->isInside (x, y)) {
return cropWin;
}
}
return cw;
}
@@ -200,7 +200,6 @@ bool ImageArea::on_expose_event(GdkEventExpose* event)
Cairo::RefPtr<Cairo::Context> cr = get_window()->create_cairo_context();
if (mainCropWindow) {
//printf("MainCropWindow (%d x %d)\n", window->get_width(), window->get_height());
mainCropWindow->expose (cr);
}
@@ -275,11 +274,11 @@ bool ImageArea::on_scroll_event (GdkEventScroll* event)
int newCenterX = (int)event->x;
int newCenterY = (int)event->y;
cw->screenCoordToImage(newCenterX, newCenterY, newCenterX, newCenterY);
if (event->direction == GDK_SCROLL_UP && !cw->isMaxZoom()) {
cw->findCenter (1, newCenterX, newCenterY);
cw->zoomIn (true, newCenterX, newCenterY);
} else if (!cw->isMinZoom()) {
cw->findCenter (-1, newCenterX, newCenterY);
cw->zoomOut (true, newCenterX, newCenterY);
}
}
@@ -327,10 +326,10 @@ bool ImageArea::on_leave_notify_event (GdkEventCrossing* event)
void ImageArea::subscribe(EditSubscriber *subscriber)
{
mainCropWindow->cropHandler.setEditSubscriber(subscriber);
mainCropWindow->setEditSubscriber(subscriber);
for (std::list<CropWindow*>::iterator i = cropWins.begin(); i != cropWins.end(); i++) {
(*i)->cropHandler.setEditSubscriber(subscriber);
for (auto cropWin : cropWins) {
cropWin->setEditSubscriber(subscriber);
}
EditDataProvider::subscribe(subscriber);
@@ -339,7 +338,7 @@ void ImageArea::subscribe(EditSubscriber *subscriber)
listener->getToolBar()->startEditMode ();
}
if (subscriber->getEditingType() == ET_OBJECTS) {
if (subscriber && subscriber->getEditingType() == ET_OBJECTS) {
// In this case, no need to reprocess the image, so we redraw the image to display the geometry
queue_draw();
}
@@ -358,8 +357,8 @@ void ImageArea::unsubscribe()
// Ask the Crops to free-up edit mode buffers
mainCropWindow->cropHandler.setEditSubscriber(NULL);
for (std::list<CropWindow*>::iterator i = cropWins.begin(); i != cropWins.end(); i++) {
(*i)->cropHandler.setEditSubscriber(NULL);
for (auto cropWin : cropWins) {
cropWin->cropHandler.setEditSubscriber(NULL);
}
setToolHand();
@@ -473,12 +472,10 @@ void ImageArea::addCropWindow ()
y = cropheight * (N % maxRows);
cw->setPosition (x, y);
cw->setEditSubscriber (getCurrSubscriber());
cw->enable(); // start processing!
int x0, y0, w, h, wc, hc;
mainCropWindow->getCropRectangle(x0, y0, w, h );
cw->getCropSize(wc, hc);
cw->setCropPosition(x0 + w / 2 - wc / 2, y0 + h / 2 - hc / 2);
cw->centerCrop();
mainCropWindow->setObservedCropWin (cropWins.front());
if(cropWins.size() == 1) { // after first detail window we already have high quality
@@ -539,9 +536,8 @@ void ImageArea::getScrollImageSize (int& w, int& h)
{
if (mainCropWindow && ipc) {
double z = mainCropWindow->getZoom ();
w = ipc->getFullWidth() * z;
h = ipc->getFullHeight() * z;
w = ipc->getFullWidth();
h = ipc->getFullHeight();
} else {
w = h = 0;
}
@@ -551,10 +547,7 @@ void ImageArea::getScrollPosition (int& x, int& y)
{
if (mainCropWindow) {
int cropX, cropY;
mainCropWindow->getCropPosition (cropX, cropY);
x = cropX * mainCropWindow->getZoom ();
y = cropY * mainCropWindow->getZoom ();
mainCropWindow->getCropAnchorPosition (x, y);
} else {
x = y = 0;
}
@@ -565,7 +558,7 @@ void ImageArea::setScrollPosition (int x, int y)
if (mainCropWindow) {
mainCropWindow->delCropWindowListener (this);
mainCropWindow->setCropPosition (x / mainCropWindow->getZoom (), y / mainCropWindow->getZoom ());
mainCropWindow->setCropAnchorPosition (x, y);
mainCropWindow->addCropWindowListener (this);
}
}
@@ -618,19 +611,18 @@ void ImageArea::initialImageArrived (CropWindow* cw)
if (mainCropWindow) {
if(firstOpen || options.prevdemo != PD_Sidecar || (!options.rememberZoomAndPan) ) {
mainCropWindow->zoomFit (false);
mainCropWindow->zoomFit ();
firstOpen = false;
mainCropWindow->cropHandler.getFullImageSize(fullImageWidth, fullImageHeight);
} else {
int w, h;
mainCropWindow->cropHandler.getFullImageSize(w, h);
if(w == fullImageWidth && h == fullImageHeight) { // && mainCropWindow->getZoom() != mainCropWindow->getZoomFitVal()) {
int x, y;
mainCropWindow->getCropPosition(x, y);
mainCropWindow->setCropPosition(x, y, false);
if(w != fullImageWidth || h != fullImageHeight) {
printf("zoomFit !\n");
mainCropWindow->zoomFit ();
} else {
mainCropWindow->zoomFit (false);
printf("no-zoomFit\n");
}
fullImageWidth = w;
@@ -649,8 +641,8 @@ void ImageArea::setCropGUIListener (CropGUIListener* l)
cropgl = l;
for (std::list<CropWindow*>::iterator i = cropWins.begin(); i != cropWins.end(); i++) {
(*i)->setCropGUIListener (cropgl);
for (auto cropWin : cropWins) {
cropWin->setCropGUIListener (cropgl);
}
if (mainCropWindow) {
@@ -663,8 +655,8 @@ void ImageArea::setPointerMotionListener (PointerMotionListener* pml)
pmlistener = pml;
for (std::list<CropWindow*>::iterator i = cropWins.begin(); i != cropWins.end(); i++) {
(*i)->setPointerMotionListener (pml);
for (auto cropWin : cropWins) {
cropWin->setPointerMotionListener (pml);
}
if (mainCropWindow) {
@@ -677,8 +669,8 @@ void ImageArea::setPointerMotionHListener (PointerMotionListener* pml)
pmhlistener = pml;
for (std::list<CropWindow*>::iterator i = cropWins.begin(); i != cropWins.end(); i++) {
(*i)->setPointerMotionHListener (pml);
for (auto cropWin : cropWins) {
cropWin->setPointerMotionHListener (pml);
}
if (mainCropWindow) {

View File

@@ -84,9 +84,7 @@ void ImageAreaPanel::synchronize ()
after->imageArea->getScrollPosition (x, y);
if (imgw > 0 && imgh > 0) {
int bimgw, bimgh;
imageArea->getScrollImageSize (bimgw, bimgh);
imageArea->setScrollPosition (x * bimgw / imgw, y * bimgh / imgh);
imageArea->setScrollPosition (x, y);
imageArea->queue_draw ();
}
} else if (before && this == after) {
@@ -95,9 +93,7 @@ void ImageAreaPanel::synchronize ()
before->imageArea->getScrollPosition (x, y);
if (imgw > 0 && imgh > 0) {
int bimgw, bimgh;
imageArea->getScrollImageSize (bimgw, bimgh);
imageArea->setScrollPosition (x * bimgw / imgw, y * bimgh / imgh);
imageArea->setScrollPosition (x, y);
imageArea->queue_draw ();
}
}

View File

@@ -204,27 +204,19 @@ Glib::RefPtr<Gdk::Pixbuf> PreviewHandler::getRoughImage (int x, int y, int w, in
h = image->getHeight() * totalZoom;
}
int ix = x * zoom;
int iy = y * zoom;
x *= zoom;
y *= zoom;
if (ix < 0) {
ix = 0;
if ((x + w) / totalZoom > previewImg->get_width()) {
w = previewImg->get_width() * totalZoom - x;
}
if (iy < 0) {
iy = 0;
}
if ((ix + w) / totalZoom > previewImg->get_width()) {
ix = previewImg->get_width() * totalZoom - w;
}
if ((iy + h) / totalZoom > previewImg->get_height()) {
iy = previewImg->get_height() * totalZoom - h;
if ((y + h) / totalZoom > previewImg->get_height()) {
h = previewImg->get_height() * totalZoom - y;
}
resPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, w, h);
previewImg->scale (resPixbuf, 0, 0, w, h, -ix, -iy, totalZoom, totalZoom, Gdk::INTERP_NEAREST);
previewImg->scale (resPixbuf, 0, 0, w, h, -x, -y, totalZoom, totalZoom, Gdk::INTERP_NEAREST);
}
return resPixbuf;

View File

@@ -199,6 +199,8 @@ bool PreviewWindow::on_motion_notify_event (GdkEventMotion* event)
if (isMoving) {
mainCropWin->remoteMove ((event->x - press_x) / zoom, (event->y - press_y) / zoom);
press_x = event->x;
press_y = event->y;
} else if (inside && !moreInside) {
cursorManager.setCursor (get_window(), CSClosedHand);
} else {

View File

@@ -269,8 +269,8 @@ ToolPanelCoordinator::ToolPanelCoordinator () : ipc(NULL)
toolPanelNotebook->set_scrollable ();
toolPanelNotebook->show_all ();
for (size_t i = 0; i < toolPanels.size(); i++) {
toolPanels[i]->setListener (this);
for (auto toolPanel : toolPanels) {
toolPanel->setListener (this);
}
whitebalance->setWBProvider (this);
@@ -323,8 +323,8 @@ void ToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib::
ProcParams* params = ipc->beginUpdateParams ();
for (size_t i = 0; i < toolPanels.size(); i++) {
toolPanels[i]->write (params);
for (auto toolPanel : toolPanels) {
toolPanel->write (params);
}
// Compensate rotation on flip
@@ -336,6 +336,24 @@ void ToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib::
}
}
int tr = TR_NONE;
if (params->coarse.rotate == 90) {
tr = TR_R90;
} else if (params->coarse.rotate == 180) {
tr = TR_R180;
} else if (params->coarse.rotate == 270) {
tr = TR_R270;
}
// Update "on preview" geometry
if (event == rtengine::EvPhotoLoaded || event == rtengine::EvProfileChanged || event == rtengine::EvHistoryBrowsed || event == rtengine::EvCTRotate) {
// updating the "on preview" geometry
int fw, fh;
rtengine::ImageSource *ii = (rtengine::ImageSource*)ipc->getInitialImage();
ii->getFullSize (fw, fh, tr);
gradient->updateGeometry (params->gradient.centerX, params->gradient.centerY, params->gradient.feather, params->gradient.degree, fw, fh);
}
// some transformations make the crop change for convenience
if (event == rtengine::EvCTHFlip) {
crop->hFlipCrop ();
@@ -357,8 +375,8 @@ void ToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib::
hasChanged = true;
for (size_t i = 0; i < paramcListeners.size(); i++) {
paramcListeners[i]->procParamsChanged (params, event, descr);
for (auto paramcListener : paramcListeners) {
paramcListener->procParamsChanged (params, event, descr);
}
}
@@ -403,17 +421,12 @@ void ToolPanelCoordinator::profileChange (const PartialProfile *nparams, rtengi
delete mergedParams;
tr = TR_NONE;
if (params->coarse.rotate == 90) {
tr |= TR_R90;
}
if (params->coarse.rotate == 180) {
tr |= TR_R180;
}
if (params->coarse.rotate == 270) {
tr |= TR_R270;
tr = TR_R90;
} else if (params->coarse.rotate == 180) {
tr = TR_R180;
} else if (params->coarse.rotate == 270) {
tr = TR_R270;
}
// trimming overflowing cropped area
@@ -422,14 +435,19 @@ void ToolPanelCoordinator::profileChange (const PartialProfile *nparams, rtengi
crop->trim(params, fw, fh);
// updating the GUI with updated values
for (unsigned int i = 0; i < toolPanels.size(); i++) {
toolPanels[i]->read (params);
for (auto toolPanel : toolPanels) {
toolPanel->read (params);
if (event == rtengine::EvPhotoLoaded || event == rtengine::EvProfileChanged) {
toolPanels[i]->autoOpenCurve();
toolPanel->autoOpenCurve();
}
}
if (event == rtengine::EvPhotoLoaded || event == rtengine::EvProfileChanged || event == rtengine::EvHistoryBrowsed || event == rtengine::EvCTRotate) {
// updating the "on preview" geometry
gradient->updateGeometry (params->gradient.centerX, params->gradient.centerY, params->gradient.feather, params->gradient.degree, fw, fh);
}
// start the IPC processing
if (filterRawRefresh) {
ipc->endUpdateParams ( refreshmap[(int)event] & ALLNORAW );
@@ -439,8 +457,8 @@ void ToolPanelCoordinator::profileChange (const PartialProfile *nparams, rtengi
hasChanged = event != rtengine::EvProfileChangeNotification;
for (size_t i = 0; i < paramcListeners.size(); i++) {
paramcListeners[i]->procParamsChanged (params, event, descr);
for (auto paramcListener : paramcListeners) {
paramcListener->procParamsChanged (params, event, descr);
}
}
@@ -448,8 +466,8 @@ void ToolPanelCoordinator::setDefaults (ProcParams* defparams)
{
if (defparams)
for (size_t i = 0; i < toolPanels.size(); i++) {
toolPanels[i]->setDefaults (defparams);
for (auto toolPanel : toolPanels) {
toolPanel->setDefaults (defparams);
}
}
@@ -746,9 +764,9 @@ void ToolPanelCoordinator::updateCurveBackgroundHistogram (LUTu & histToneCurve,
void ToolPanelCoordinator::foldAllButOne (Gtk::Box* parent, FoldableToolPanel* openedSection)
{
for (size_t i = 0; i < toolPanels.size(); i++) {
if (toolPanels[i]->getParent() != NULL) {
ToolPanel* currentTP = toolPanels[i];
for (auto toolPanel : toolPanels) {
if (toolPanel->getParent() != NULL) {
ToolPanel* currentTP = toolPanel;
if (currentTP->getParent() == parent) {
// Section in the same tab, we unfold it if it's not the one that has been clicked