Updated code taking into account Adam's comments + bugfix

This commit is contained in:
Hombre
2016-02-13 17:54:47 +01:00
parent 4665b88788
commit de7c6d773a
13 changed files with 539 additions and 571 deletions

View File

@@ -187,23 +187,23 @@ public:
{
radius *= scale;
}
PolarCoord operator+(PolarCoord & rhs)
PolarCoord operator+ (const PolarCoord& rhs) const
{
PolarCoord result;
Coord thisCoord, rhsCoord;
thisCoord.setFromPolar(*this);
rhsCoord.setFromPolar(rhs);
thisCoord += rhsCoord;
PolarCoord result;
result.setFromCartesian(thisCoord);
return result;
}
PolarCoord operator-(PolarCoord & rhs)
PolarCoord operator- (const PolarCoord& rhs) const
{
PolarCoord result;
Coord thisCoord, rhsCoord;
thisCoord.setFromPolar(*this);
rhsCoord.setFromPolar(rhs);
thisCoord -= rhsCoord;
PolarCoord result;
result.setFromCartesian(thisCoord);
return result;
}

View File

@@ -1151,11 +1151,9 @@ bool Crop::setCropSizes (int rcx, int rcy, int rcw, int rch, int skip, bool inte
}
EditType editType = ET_PIPETTE;
EditDataProvider *editProvider = PipetteBuffer::getDataProvider();
if (editProvider) {
EditSubscriber *editSubscriber = editProvider->getCurrSubscriber();
if (editSubscriber) {
editType = editSubscriber->getEditingType();
if (const auto editProvider = PipetteBuffer::getDataProvider ()) {
if (const auto editSubscriber = editProvider->getCurrSubscriber ()) {
editType = editSubscriber->getEditingType ();
}
}
@@ -1241,12 +1239,7 @@ bool Crop::setCropSizes (int rcx, int rcy, int rcw, int rch, int skip, bool inte
trafx = orx;
trafy = ory;
if (settings->verbose) {
if (changed) {
printf("new crop size: cropx=%d, cropy=%d, cropw=%d, croph=%d / rqcropx=%d, rqcropy=%d, rqcropw=%d, rqcroph=%d / leftBorder=%d, upperBorder=%d\n",
cropx, cropy, cropw, croph, rqcropx, rqcropy, rqcropw, rqcroph, leftBorder, upperBorder);
}
printf ("setsizes ends\n");
}

View File

@@ -92,7 +92,7 @@ public:
return cropImageListener;
}
void update (int todo);
void setWindow (int cropX, int cropY, int cropW, int cropH, int canvasX, int canvasY, int canvasW, int canvasH, int skip)
void setWindow (int cropX, int cropY, int cropW, int cropH, int skip)
{
setCropSizes (cropX, cropY, cropW, cropH, skip, false);
}

View File

@@ -80,7 +80,8 @@ inline const _Tp& max(const _Tp& a, const _Tp& b, const _Tp& c, const _Tp& d)
}
template<typename _Tp>
inline const _Tp intp(const _Tp a, const _Tp b, const _Tp c) {
inline const _Tp intp(const _Tp a, const _Tp b, const _Tp c)
{
// calculate a * b + (1 - a) * c
// following is valid:
// intp(a, b+x, c+x) = intp(a, b, c) + x
@@ -88,5 +89,23 @@ inline const _Tp intp(const _Tp a, const _Tp b, const _Tp c) {
return a * (b-c) + c;
}
template<typename T>
T norm1(const T& x, const T& y)
{
return std::abs(x) + std::abs(y);
}
template<typename T>
T norm2(const T& x, const T& y)
{
return std::sqrt(x * x + y * y);
}
template< typename T >
T norminf(const T& x, const T& y)
{
return std::max(std::abs(x), std::abs(y));
}
}
#endif

View File

@@ -211,6 +211,7 @@ void CropWindow::setSize (int w, int h, bool norefresh)
}
if (!norefresh) {
ObjectMOBuffer::resize(imgAreaW, imgAreaH);
cropHandler.setWSize (imgAreaW, imgAreaH);
}
@@ -1543,8 +1544,7 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
}
EditSubscriber *editSubscriber = iarea->getCurrSubscriber();
if (editSubscriber && bufferCreated()) {
if (editSubscriber && editSubscriber->getEditingType() == ET_OBJECTS && bufferCreated()) {
if (this != iarea->mainCropWindow) {
cr->set_line_width (0.);
@@ -1569,75 +1569,31 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
}
// drawing to the "mouse over" channel
if (editSubscriber->getEditingType() == ET_OBJECTS) {
const std::vector<Geometry*> mouseOverGeom = editSubscriber->getMouseOverGeometry();
const auto mouseOverGeom = editSubscriber->getMouseOverGeometry();
if (mouseOverGeom.size()) {
if (mouseOverGeom.size() > 65534) {
// once it has been switched to OM_65535, it won't return back to OM_255
// to avoid constant memory allocations in some particular situation.
// It will return to OM_255 on a new editing session
setObjectMode(OM_65535);
}
if (mouseOverGeom.size()) {
//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);
crMO->set_operator(Cairo::OPERATOR_SOURCE);
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);
crMO->set_operator(Cairo::OPERATOR_SOURCE);
// clear the bitmap
crMO->set_source_rgba(0., 0., 0., 0.);
crMO->rectangle(0., 0., ObjectMOBuffer::getObjectMap()->get_width(), ObjectMOBuffer::getObjectMap()->get_height());
crMO->set_line_width(0.);
crMO->fill();
// clear the bitmap
crMO->set_source_rgba(0., 0., 0., 0.);
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 (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);
crMO2->set_operator(Cairo::OPERATOR_SOURCE);
// clear the bitmap
crMO2->set_source_rgba(0., 0., 0., 0.);
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=0;
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 = 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 = 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;) {
dst[n3++] = src1[n];
if (src2) {
dst[n3++] = src2[n];
} else {
dst[n3++] = 0;
}
dst[n3++] = 0;
++n;
}
img->save(Glib::ustring::compose("mouseOverImage-%1.png", count++), "png");
}
#endif
int a=0;
for (auto moGeom : mouseOverGeom) {
moGeom->drawToMOChannel(crMO, a, this, *this);
++a;
}
}
if (this != iarea->mainCropWindow) {
@@ -1685,7 +1641,11 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
void CropWindow::setEditSubscriber (EditSubscriber* newSubscriber) {
// Delete, create, update all buffers based upon newSubscriber's type
ObjectMOBuffer::resize(imgAreaW, imgAreaH, newSubscriber);
if (newSubscriber) {
ObjectMOBuffer::resize (imgAreaW, imgAreaH);
} else {
ObjectMOBuffer::flush ();
}
cropHandler.setEditSubscriber(newSubscriber);
}

View File

@@ -20,7 +20,7 @@
#include "edit.h"
#include "rtimage.h"
ObjectMOBuffer::ObjectMOBuffer(EditDataProvider *dataProvider) : objectMap(NULL), objectMap2(NULL), objectMode(OM_255), dataProvider(dataProvider) {}
ObjectMOBuffer::ObjectMOBuffer(EditDataProvider *dataProvider) : objectMap(NULL), objectMode(OM_255), dataProvider(dataProvider) {}
ObjectMOBuffer::~ObjectMOBuffer()
{
@@ -28,26 +28,34 @@ ObjectMOBuffer::~ObjectMOBuffer()
}
/* Upgrade or downgrade the objectModeType; we're assuming that objectMap has been allocated */
/* Upgrade or downgrade the objectModeType */
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;
if (!objectMap) {
objectMode = newType;
return;
}
int w = objectMap->get_width ();
int h = objectMap->get_height ();
if (w && h) {
switch (newType) {
case (OM_255):
if (objectMode==OM_65535) {
objectMap->unreference();
objectMap = Cairo::ImageSurface::create(Cairo::FORMAT_A8, w, h);
}
break;
case (OM_65535):
if (objectMode==OM_255) {
objectMap->unreference();
objectMap = Cairo::ImageSurface::create(Cairo::FORMAT_RGB16_565, w, h);
}
break;
}
}
objectMode = newType;
}
void ObjectMOBuffer::flush()
@@ -55,10 +63,6 @@ void ObjectMOBuffer::flush()
if (objectMap ) {
objectMap.clear();
}
if (objectMap2) {
objectMap2.clear();
}
}
EditSubscriber *ObjectMOBuffer::getEditSubscriber () {
@@ -71,32 +75,22 @@ EditSubscriber *ObjectMOBuffer::getEditSubscriber () {
// Resize buffers if they already exist
void ObjectMOBuffer::resize(int newWidth, int newHeight, EditSubscriber* newSubscriber)
void ObjectMOBuffer::resize(int newWidth, int newHeight)
{
if (newSubscriber) {
if (newSubscriber->getEditingType() == ET_OBJECTS) {
if (!dataProvider) {
return;
}
if (const auto currSubscriber = dataProvider->getCurrSubscriber ()) {
if (currSubscriber->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);
objectMap = Cairo::ImageSurface::create(objectMode==OM_255?Cairo::FORMAT_A8:Cairo::FORMAT_RGB16_565, 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();
}
@@ -109,12 +103,14 @@ 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 (!objectMap || location.x < 0 || location.y < 0 || location.x >= objectMap->get_width() || location.y >= objectMap->get_height()) {
return -1;
}
if (objectMap2) {
id |= (unsigned short)(*( objectMap->get_data() + location.y * objectMap->get_stride() + location.x )) << 8;
}
if (objectMode == OM_255) {
id = (unsigned char)(*( objectMap->get_data() + location.y * objectMap->get_stride() + location.x ));
} else {
id = (unsigned short)(*( objectMap->get_data() + location.y * objectMap->get_stride() + location.x ));
}
return id - 1;
@@ -257,7 +253,7 @@ void Circle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer
}
}
void Circle::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
void Circle::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
{
if (flags & F_HOVERABLE) {
cr->set_line_width( getMouseOverLineWidth() );
@@ -272,9 +268,12 @@ void Circle::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<C
center_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
// drawing the lower byte's value
unsigned short a = (id + 1) & 0xFF;
cr->set_source_rgba (0., 0., 0., double(a) / 255.);
// setting the color to the objet's ID
if (objectBuffer->getObjectMode() == OM_255) {
cr->set_source_rgba (0., 0., 0., ((id + 1) & 0xFF) / 255.);
} else {
cr->set_source_rgba (0., 0., 0., (id + 1) / 65535.);
}
cr->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0, 2.*M_PI);
if (filled) {
@@ -287,24 +286,6 @@ void Circle::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<C
} else {
cr->stroke();
}
// drawing the higher byte's value
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);
if (filled) {
if (innerLineWidth > 0.) {
cr2->fill_preserve();
cr2->stroke();
} else {
cr2->fill();
}
} else {
cr2->stroke();
}
}
}
}
@@ -392,9 +373,7 @@ void Line::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *
}
}
void Line::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr,
Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id,
ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
void Line::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
{
if (flags & F_HOVERABLE) {
cr->set_line_width( getMouseOverLineWidth() );
@@ -412,21 +391,15 @@ void Line::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr,
end_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
// drawing the lower byte's value
unsigned short a = (id + 1) & 0xFF;
cr->set_source_rgba (0., 0., 0., double(a) / 255.);
// setting the color to the objet's ID
if (objectBuffer->getObjectMode() == OM_255) {
cr->set_source_rgba (0., 0., 0., ((id + 1) & 0xFF) / 255.);
} else {
cr->set_source_rgba (0., 0., 0., (id + 1) / 65535.);
}
cr->move_to(begin_.x + 0.5, begin_.y + 0.5);
cr->line_to(end_.x + 0.5, end_.y + 0.5);
cr->stroke();
// drawing the higher byte's value
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);
cr2->line_to(end_.x + 0.5, end_.y + 0.5);
cr2->stroke();
}
}
}
@@ -555,14 +528,17 @@ void Polyline::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuff
}
}
void Polyline::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
void Polyline::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
{
if ((flags & F_HOVERABLE) && points.size() > 1) {
rtengine::Coord currPos;
// drawing the lower byte's value
unsigned short a = (id + 1) & 0xFF;
cr->set_source_rgba (0., 0., 0., double(a) / 255.);
// setting the color to the objet's ID
if (objectBuffer->getObjectMode() == OM_255) {
cr->set_source_rgba (0., 0., 0., ((id + 1) & 0xFF) / 255.);
} else {
cr->set_source_rgba (0., 0., 0., (id + 1) / 65535.);
}
for (unsigned int i = 0; i < points.size(); ++i) {
cr->set_line_width( getMouseOverLineWidth() );
@@ -593,42 +569,6 @@ void Polyline::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr
} else {
cr->stroke();
}
// drawing the higher byte's value
if (objectBuffer->getObjectMode() == OM_65535) {
a = (id + 1) >> 8;
cr2->set_source_rgba (0., 0., 0., double(a) / 255.);
for (unsigned int i = 0; i < points.size(); ++i) {
cr2->set_line_width( getMouseOverLineWidth() );
currPos = points.at(i);
if (datum == IMAGE) {
coordSystem.imageCoordToCropCanvas (points.at(i).x, points.at(i).y, currPos.x, currPos.y);
} else if (datum == CLICKED_POINT) {
currPos += objectBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) {
currPos += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
if (!i) {
cr2->move_to(currPos.x + 0.5, currPos.y + 0.5);
} else {
cr2->line_to(currPos.x + 0.5, currPos.y + 0.5);
}
}
if (filled) {
if (innerLineWidth > 0.) {
cr2->fill_preserve();
cr2->stroke();
} else {
cr2->fill();
}
} else {
cr2->stroke();
}
}
}
}
@@ -763,7 +703,7 @@ void Rectangle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuf
}
}
void Rectangle::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
void Rectangle::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr, unsigned short id, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
{
if (flags & F_HOVERABLE) {
cr->set_line_width( getMouseOverLineWidth() );
@@ -786,9 +726,12 @@ void Rectangle::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr
br = bottomRight + objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
}
// drawing the lower byte's value
unsigned short a = (id + 1) & 0xFF;
cr->set_source_rgba (0., 0., 0., double(a) / 255.);
// setting the color to the objet's ID
if (objectBuffer->getObjectMode() == OM_255) {
cr->set_source_rgba (0., 0., 0., ((id + 1) & 0xFF) / 255.);
} else {
cr->set_source_rgba (0., 0., 0., (id + 1) / 65535.);
}
cr->rectangle(tl.x + 0.5, tl.y + 0.5, br.x - tl.x, br.y - tl.y);
if (filled) {
@@ -801,24 +744,6 @@ void Rectangle::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr
} else {
cr->stroke();
}
// drawing the higher byte's value
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);
if (filled) {
if (innerLineWidth > 0.) {
cr2->fill_preserve();
cr2->stroke();
} else {
cr2->fill();
}
} else {
cr2->stroke();
}
}
}
}

View File

@@ -153,8 +153,6 @@ 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:
@@ -164,32 +162,19 @@ protected:
EditDataProvider* dataProvider;
void createBuffer(int width, int height);
void resize(int newWidth, int newHeight, EditSubscriber* newSubscriber);
void resize(int newWidth, int newHeight);
void flush();
EditSubscriber *getEditSubscriber ();
public:
ObjectMOBuffer(EditDataProvider *dataProvider);
explicit ObjectMOBuffer (EditDataProvider *dataProvider);
~ObjectMOBuffer();
EditDataProvider* getDataProvider()
{
return dataProvider;
}
void setObjectMode(ObjectMode newType);
ObjectMode getObjectMode()
{
return objectMode;
}
EditDataProvider* getDataProvider ();
void setObjectMode (ObjectMode newType);
ObjectMode getObjectMode ();
Cairo::RefPtr<Cairo::ImageSurface> &getObjectMap ()
{
return objectMap;
}
Cairo::RefPtr<Cairo::ImageSurface> &getObjectMap2()
{
return objectMap2;
}
Cairo::RefPtr<Cairo::ImageSurface>& getObjectMap ();
// return true if the buffer has been allocated
bool bufferCreated();
@@ -238,36 +223,16 @@ class RGBColor
double b;
public:
RGBColor () : r(0.), g(0.), b(0.) {}
explicit RGBColor (double r, double g, double b) : r(r), g(g), b(b) {}
explicit RGBColor (char r, char g, char b) : r(double(r) / 255.), g(double(g) / 255.), b(double(b) / 255.) {}
RGBColor ();
explicit RGBColor (double r, double g, double b);
explicit RGBColor (char r, char g, char b);
void setColor(double r, double g, double b)
{
this->r = r;
this->g = g;
this->b = b;
}
void setColor (double r, double g, double b);
void setColor (char r, char g, char b);
void setColor(char r, char g, char b)
{
this->r = double(r) / 255.;
this->g = double(g) / 255.;
this->b = double(b) / 255.;
}
double getR()
{
return r;
}
double getG()
{
return g;
}
double getB()
{
return b;
}
double getR ();
double getG ();
double getB ();
};
class RGBAColor : public RGBColor
@@ -275,26 +240,14 @@ class RGBAColor : public RGBColor
double a;
public:
RGBAColor () : RGBColor(0., 0., 0.), a(0.) {}
explicit RGBAColor (double r, double g, double b, double a) : RGBColor(r, g, b), a(a) {}
explicit RGBAColor (char r, char g, char b, char a) : RGBColor(r, g, b), a(double(a) / 255.) {}
RGBAColor ();
explicit RGBAColor (double r, double g, double b, double a);
explicit RGBAColor (char r, char g, char b, char a);
void setColor(double r, double g, double b, double a)
{
RGBColor::setColor(r, g, b);
this->a = a;
}
void setColor (double r, double g, double b, double a);
void setColor (char r, char g, char b, char a);
void setColor(char r, char g, char b, char a)
{
RGBColor::setColor(r, g, b);
this->a = double(a) / 255.;
}
double getA()
{
return a;
}
double getA ();
};
/// @brief Displayable and MouseOver geometry base class
@@ -345,85 +298,29 @@ public:
Datum datum;
State state; // set by the Subscriber
Geometry () : innerLineColor(char(255), char(255), char(255)), outerLineColor(char(0), char(0), char(0)), flags(F_VISIBLE | F_HOVERABLE | F_AUTO_COLOR), innerLineWidth(1.5f), datum(IMAGE), state(NORMAL) {}
Geometry ();
virtual ~Geometry() {}
void setInnerLineColor (double r, double g, double b)
{
innerLineColor.setColor(r, g, b);
flags &= ~F_AUTO_COLOR;
}
void setInnerLineColor (char r, char g, char b)
{
innerLineColor.setColor(r, g, b);
flags &= ~F_AUTO_COLOR;
}
RGBColor getInnerLineColor ();
void setOuterLineColor (double r, double g, double b)
{
outerLineColor.setColor(r, g, b);
flags &= ~F_AUTO_COLOR;
}
void setOuterLineColor (char r, char g, char b)
{
outerLineColor.setColor(r, g, b);
flags &= ~F_AUTO_COLOR;
}
RGBColor getOuterLineColor ();
double getOuterLineWidth ()
{
return double(innerLineWidth) + 2.;
}
double getMouseOverLineWidth ()
{
return getOuterLineWidth() + 2.;
}
void setAutoColor (bool aColor)
{
if (aColor) {
flags |= F_AUTO_COLOR;
} else {
flags &= ~F_AUTO_COLOR;
}
}
bool isVisible ()
{
return flags & F_VISIBLE;
}
void setVisible (bool visible)
{
if (visible) {
flags |= F_VISIBLE;
} else {
flags &= ~F_VISIBLE;
}
}
bool isHoverable ()
{
return flags & F_HOVERABLE;
}
void setHoverable (bool visible)
{
if (visible) {
flags |= F_HOVERABLE;
} else {
flags &= ~F_HOVERABLE;
}
}
void setInnerLineColor (double r, double g, double b);
void setInnerLineColor (char r, char g, char b);
RGBColor getInnerLineColor ();
void setOuterLineColor (double r, double g, double b);
void setOuterLineColor (char r, char g, char b);
RGBColor getOuterLineColor ();
double getOuterLineWidth ();
double getMouseOverLineWidth ();
void setAutoColor (bool aColor);
bool isVisible ();
void setVisible (bool visible);
bool isHoverable ();
void setHoverable (bool visible);
// setActive will enable/disable the visible and hoverable flags in one shot!
void setActive (bool active)
{
if (active) {
flags |= (F_VISIBLE | F_HOVERABLE);
} else {
flags &= ~(F_VISIBLE | F_HOVERABLE);
}
}
void setActive (bool active);
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;
virtual void drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem) = 0;
};
class Circle : public Geometry
@@ -434,13 +331,13 @@ public:
bool filled;
bool radiusInImageSpace; /// If true, the radius depend on the image scale; if false, it is a fixed 'screen' size
Circle () : center(100, 100), radius(10), filled(false), radiusInImageSpace(false) {}
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) {}
Circle ();
Circle (rtengine::Coord& center, int radius, bool filled = false, bool radiusInImageSpace = false);
Circle (int centerX, int centerY, int radius, bool filled = false, bool radiusInImageSpace = false);
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);
void drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem);
};
class Line : public Geometry
@@ -449,13 +346,13 @@ public:
rtengine::Coord begin;
rtengine::Coord end;
Line () : begin(10, 10), end(100, 100) {}
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) {}
Line ();
Line (rtengine::Coord& begin, rtengine::Coord& end);
Line (int beginX, int beginY, int endX, int endY);
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);
void drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem);
};
class Polyline : public Geometry
@@ -464,11 +361,11 @@ public:
std::vector<rtengine::Coord> points;
bool filled;
Polyline() : filled(false) {}
Polyline ();
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);
void drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem);
};
class Rectangle : public Geometry
@@ -478,7 +375,7 @@ public:
rtengine::Coord bottomRight;
bool filled;
Rectangle() : topLeft(0, 0), bottomRight(10, 10), filled(false) {}
Rectangle ();
void setXYWH(int left, int top, int width, int height);
void setXYXY(int left, int top, int right, int bottom);
@@ -486,7 +383,7 @@ public:
void setXYXY(rtengine::Coord topLeft, rtengine::Coord bottomRight);
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);
void drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, unsigned short id, ObjectMOBuffer *pipetteBuffer, EditCoordSystem &coordSystem);
};
/// @brief Method for client tools needing Edit information
@@ -511,10 +408,7 @@ public:
virtual ~EditSubscriber () {}
void setEditProvider(EditDataProvider *provider);
EditDataProvider* getEditProvider()
{
return provider;
}
EditDataProvider* getEditProvider ();
void setEditID(EditUniqueID ID, BufferType buffType);
bool isCurrentSubscriber();
virtual void subscribe();
@@ -527,103 +421,64 @@ public:
/** @brief Get the cursor to be displayed when above handles
@param objectID object currently "hovered" */
virtual CursorShape getCursor(int objectID)
{
return CSOpenHand;
}
virtual CursorShape getCursor (int objectID);
/** @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 | ...)
@return true if the preview has to be redrawn, false otherwise */
virtual bool mouseOver(int modifierKey)
{
return false;
}
virtual bool mouseOver (int modifierKey);
/** @brief Triggered when mouse button 1 is pressed, together with the CTRL modifier key if the subscriber is of type ET_PIPETTE
Once the key is pressed, RT will enter in drag1 mode on subsequent mouse movements
@param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...)
@return true if the preview has to be redrawn, false otherwise */
virtual bool button1Pressed(int modifierKey)
{
return false;
}
virtual bool button1Pressed (int modifierKey);
/** @brief Triggered when mouse button 1 is released
@return true if the preview has to be redrawn, false otherwise */
virtual bool button1Released()
{
return false;
}
virtual bool button1Released ();
/** @brief Triggered when mouse button 2 is pressed (middle button)
Once the key is pressed, RT will enter in drag2 mode on subsequent mouse movements
@param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...)
@return true if the preview has to be redrawn, false otherwise */
virtual bool button2Pressed(int modifierKey)
{
return false;
}
virtual bool button2Pressed (int modifierKey);
/** @brief Triggered when mouse button 2 is released (middle button)
@return true if the preview has to be redrawn, false otherwise */
virtual bool button2Released()
{
return false;
}
virtual bool button2Released ();
/** @brief Triggered when mouse button 3 is pressed (right button)
Once the key is pressed, RT will enter in drag3 mode on subsequent mouse movements
@param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...)
@return true if the preview has to be redrawn, false otherwise */
virtual bool button3Pressed(int modifierKey)
{
return false;
}
virtual bool button3Pressed (int modifierKey);
/** @brief Triggered when mouse button 3 is released (right button)
@return true if the preview has to be redrawn, false otherwise */
virtual bool button3Released()
{
return false;
}
virtual bool button3Released ();
/** @brief Triggered when the user is moving while holding down mouse button 1
@param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...)
@return true if the preview has to be redrawn, false otherwise */
virtual bool drag1(int modifierKey)
{
return false;
}
virtual bool drag1 (int modifierKey);
/** @brief Triggered when the user is moving while holding down mouse button 2
@param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...)
@return true if the preview has to be redrawn, false otherwise */
virtual bool drag2(int modifierKey)
{
return false;
}
virtual bool drag2 (int modifierKey);
/** @brief Triggered when the user is moving while holding down mouse button 3
@param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...)
@return true if the preview has to be redrawn, false otherwise */
virtual bool drag3(int modifierKey)
{
return false;
}
virtual bool drag3 (int modifierKey);
/** @brief Get the geometry to be shown to the user */
const std::vector<Geometry*> & getVisibleGeometry()
{
return visibleGeometry;
}
const std::vector<Geometry*>& getVisibleGeometry ();
/** @brief Get the geometry to be drawn in the "mouse over" channel, hidden from the user */
const std::vector<Geometry*> & getMouseOverGeometry()
{
return mouseOverGeometry;
}
const std::vector<Geometry*>& getMouseOverGeometry ();
};
/** @brief Class to handle the furniture of data to the subscribers.
@@ -655,12 +510,255 @@ public:
virtual void unsubscribe(); /// Occurs when the subscriber has been switched off first
virtual void switchOffEditMode (); /// Occurs when the user want to stop the editing mode
virtual CursorShape getCursor(int objectID);
int getPipetteRectSize()
{
return 8; // TODO: make a GUI
}
int getPipetteRectSize ();
EditSubscriber* getCurrSubscriber();
virtual void getImageSize (int &w, int&h) = 0;
};
inline EditDataProvider* ObjectMOBuffer::getDataProvider () {
return dataProvider;
}
inline ObjectMode ObjectMOBuffer::getObjectMode () {
return objectMode;
}
inline Cairo::RefPtr<Cairo::ImageSurface>& ObjectMOBuffer::getObjectMap () {
return objectMap;
}
inline void RGBColor::setColor (double r, double g, double b) {
this->r = r;
this->g = g;
this->b = b;
}
inline void RGBColor::setColor (char r, char g, char b) {
this->r = double (r) / 255.;
this->g = double (g) / 255.;
this->b = double (b) / 255.;
}
inline double RGBColor::getR () {
return r;
}
inline double RGBColor::getG () {
return g;
}
inline double RGBColor::getB () {
return b;
}
inline void RGBAColor::setColor (double r, double g, double b, double a) {
RGBColor::setColor (r, g, b);
this->a = a;
}
inline void RGBAColor::setColor (char r, char g, char b, char a) {
RGBColor::setColor (r, g, b);
this->a = double (a) / 255.;
}
inline double RGBAColor::getA () {
return a;
}
inline void Geometry::setInnerLineColor (double r, double g, double b) {
innerLineColor.setColor (r, g, b);
flags &= ~F_AUTO_COLOR;
}
inline void Geometry::setInnerLineColor (char r, char g, char b) {
innerLineColor.setColor (r, g, b);
flags &= ~F_AUTO_COLOR;
}
inline void Geometry::setOuterLineColor (double r, double g, double b) {
outerLineColor.setColor (r, g, b);
flags &= ~F_AUTO_COLOR;
}
inline double Geometry::getOuterLineWidth () {
return double (innerLineWidth) + 2.;
}
inline void Geometry::setOuterLineColor (char r, char g, char b) {
outerLineColor.setColor (r, g, b);
flags &= ~F_AUTO_COLOR;
}
inline double Geometry::getMouseOverLineWidth () {
return getOuterLineWidth () + 2.;
}
inline void Geometry::setAutoColor (bool aColor) {
if (aColor) {
flags |= F_AUTO_COLOR;
} else {
flags &= ~F_AUTO_COLOR;
}
}
inline bool Geometry::isVisible () {
return flags & F_VISIBLE;
}
inline void Geometry::setVisible (bool visible) {
if (visible) {
flags |= F_VISIBLE;
} else {
flags &= ~F_VISIBLE;
}
}
inline bool Geometry::isHoverable () {
return flags & F_HOVERABLE;
}
inline void Geometry::setHoverable (bool visible) {
if (visible) {
flags |= F_HOVERABLE;
} else {
flags &= ~F_HOVERABLE;
}
}
inline void Geometry::setActive (bool active) {
if (active) {
flags |= (F_VISIBLE | F_HOVERABLE);
} else {
flags &= ~(F_VISIBLE | F_HOVERABLE);
}
}
inline EditDataProvider* EditSubscriber::getEditProvider () {
return provider;
}
inline CursorShape EditSubscriber::getCursor (int objectID) {
return CSOpenHand;
}
inline bool EditSubscriber::mouseOver (int modifierKey) {
return false;
}
inline bool EditSubscriber::button1Pressed (int modifierKey) {
return false;
}
inline bool EditSubscriber::button1Released () {
return false;
}
inline bool EditSubscriber::button2Pressed (int modifierKey) {
return false;
}
inline bool EditSubscriber::button2Released () {
return false;
}
inline bool EditSubscriber::button3Pressed (int modifierKey) {
return false;
}
inline bool EditSubscriber::button3Released () {
return false;
}
inline bool EditSubscriber::drag1 (int modifierKey) {
return false;
}
inline bool EditSubscriber::drag2 (int modifierKey) {
return false;
}
inline bool EditSubscriber::drag3 (int modifierKey) {
return false;
}
inline const std::vector<Geometry*>& EditSubscriber::getVisibleGeometry () {
return visibleGeometry;
}
inline const std::vector<Geometry*>& EditSubscriber::getMouseOverGeometry () {
return mouseOverGeometry;
}
inline int EditDataProvider::getPipetteRectSize () {
return 8; // TODO: make a GUI
}
inline Geometry::Geometry () :
innerLineColor (char (255), char (255), char (255)), outerLineColor (
char (0), char (0), char (0)), flags (
F_VISIBLE | F_HOVERABLE | F_AUTO_COLOR), innerLineWidth (1.5f), datum (
IMAGE), state (NORMAL) {
}
inline Circle::Circle () :
center (100, 100), radius (10), filled (false), radiusInImageSpace (
false) {
}
inline Rectangle::Rectangle () :
topLeft (0, 0), bottomRight (10, 10), filled (false) {
}
inline Polyline::Polyline () :
filled (false) {
}
inline Line::Line () :
begin (10, 10), end (100, 100) {
}
inline RGBAColor::RGBAColor () :
RGBColor (0., 0., 0.), a (0.) {
}
inline RGBColor::RGBColor () :
r (0.), g (0.), b (0.) {
}
inline RGBColor::RGBColor (double r, double g, double b) :
r (r), g (g), b (b) {
}
inline RGBColor::RGBColor (char r, char g, char b) :
r (double (r) / 255.), g (double (g) / 255.), b (double (b) / 255.) {
}
inline RGBAColor::RGBAColor (double r, double g, double b, double a) :
RGBColor (r, g, b), a (a) {
}
inline RGBAColor::RGBAColor (char r, char g, char b, char a) :
RGBColor (r, g, b), a (double (a) / 255.) {
}
inline Circle::Circle (rtengine::Coord& center, int radius, bool filled,
bool radiusInImageSpace) :
center (center), radius (radius), filled (filled), radiusInImageSpace (
radiusInImageSpace) {
}
inline Circle::Circle (int centerX, int centerY, int radius, bool filled,
bool radiusInImageSpace) :
center (centerX, centerY), radius (radius), filled (filled), radiusInImageSpace (
radiusInImageSpace) {
}
inline Line::Line (rtengine::Coord& begin, rtengine::Coord& end) :
begin (begin), end (end) {
}
inline Line::Line (int beginX, int beginY, int endX, int endY) :
begin (beginX, beginY), end (endX, endY) {
}
#endif

View File

@@ -136,7 +136,7 @@ void Gradient::read (const ProcParams* pp, const ParamsEdited* pedited)
enableListener ();
}
void Gradient::updateGeometry(const int centerX_, const int centerY_, const double feather_, const double degree_, const int fullWidth, const int fullHeight)
void Gradient::updateGeometry(const int centerX, const int centerY, const double feather, const double degree, const int fullWidth, const int fullHeight)
{
EditDataProvider* dataProvider = getEditProvider();
@@ -144,7 +144,8 @@ void Gradient::updateGeometry(const int centerX_, const int centerY_, const doub
return;
}
int imW, imH;
int imW=0;
int imH=0;
if (fullWidth != -1 && fullHeight != -1) {
imW = fullWidth;
imH = fullHeight;
@@ -156,79 +157,56 @@ void Gradient::updateGeometry(const int centerX_, const int centerY_, const doub
}
PolarCoord polCoord1, polCoord2;
double decay = feather_ * sqrt(double(imW) * double(imW) + double(imH) * double(imH)) / 200.;
double decay = feather * rtengine::norm2<double>(imW, imH) / 200.;
rtengine::Coord origin(imW / 2 + centerX_ * imW / 200.f, imH / 2 + centerY_ * imH / 200.f);
rtengine::Coord origin(imW / 2 + centerX * imW / 200, imH / 2 + centerY * imH / 200);
Line *currLine;
Circle *currCircle;
const auto updateLine = [&](Geometry* geometry, const float radius, const float begin, const float end)
{
const auto line = static_cast<Line*>(geometry);
line->begin.setFromPolar(PolarCoord(radius, -degree + begin));
line->begin += origin;
line->end.setFromPolar(PolarCoord(radius, -degree + end));
line->end += origin;
};
const auto updateLineWithDecay = [&](Geometry* geometry, const float radius, const float offSetAngle)
{
const auto line = static_cast<Line*>(geometry);
line->begin.setFromPolar(PolarCoord(radius, -degree + 180.) + PolarCoord(decay, -degree + offSetAngle));
line->begin += origin;
line->end.setFromPolar(PolarCoord(radius, -degree) + PolarCoord(decay, -degree + offSetAngle));
line->end += origin;
};
const auto updateCircle = [&](Geometry* geometry)
{
const auto circle = static_cast<Circle*>(geometry);
circle->center = origin;
};
// 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;
updateLine (visibleGeometry.at(0), 1500., 0., 180.);
updateLine (mouseOverGeometry.at(0), 1500., 0., 180.);
// 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;
updateLine (visibleGeometry.at(1), 700., 90., 270.);
updateLine (mouseOverGeometry.at(1), 700., 90., 270.);
// 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;
updateLineWithDecay (visibleGeometry.at(2), 350., 270.);
updateLineWithDecay (mouseOverGeometry.at(2), 350., 270.);
// 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;
updateLineWithDecay (visibleGeometry.at(3), 350., 90.);
updateLineWithDecay (mouseOverGeometry.at(3), 350., 90.);
// update circle's position
currCircle = static_cast<Circle*>(visibleGeometry.at(4));
currCircle->center = origin;
currCircle = static_cast<Circle*>(mouseOverGeometry.at(4));
currCircle->center = origin;
updateCircle (visibleGeometry.at(4));
updateCircle (mouseOverGeometry.at(4));
}
void Gradient::write (ProcParams* pp, ParamsEdited* pedited)
@@ -408,9 +386,13 @@ bool Gradient::mouseOver(int modifierKey)
bool Gradient::button1Pressed(int modifierKey)
{
if (lastObject < 0) {
return false;
}
EditDataProvider *provider = getEditProvider();
if (!(modifierKey & GDK_CONTROL_MASK) && lastObject > -1) {
if (!(modifierKey & GDK_CONTROL_MASK)) {
// button press is valid (no modifier key)
PolarCoord pCoord;
int imW, imH;
@@ -458,7 +440,7 @@ bool Gradient::button1Pressed(int modifierKey)
EditSubscriber::dragging = true;
return false;
} else if (lastObject > -1) { // should theoretically always be true
} else { // should theoretically always be true
// this will let this class ignore further drag events
if (lastObject == 2 || lastObject == 3) {
EditSubscriber::visibleGeometry.at(2)->state = Geometry::NORMAL;

View File

@@ -46,7 +46,7 @@ public:
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 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

@@ -96,10 +96,10 @@ void ImageArea::on_resized (Gtk::Allocation& req)
mainCropWindow->setPointerMotionListener (pmlistener);
mainCropWindow->setPointerMotionHListener (pmhlistener);
mainCropWindow->setPosition (0, 0);
mainCropWindow->setSize (get_width(), get_height(), false); // this execute the refresh itself
mainCropWindow->setSize (get_width(), get_height()); // this execute the refresh itself
mainCropWindow->enable(); // start processing !
} else {
mainCropWindow->setSize (get_width(), get_height());
mainCropWindow->setSize (get_width(), get_height()); // this execute the refresh itself
}
parent->syncBeforeAfterViews();
@@ -326,14 +326,13 @@ bool ImageArea::on_leave_notify_event (GdkEventCrossing* event)
void ImageArea::subscribe(EditSubscriber *subscriber)
{
mainCropWindow->setEditSubscriber(subscriber);
EditDataProvider::subscribe(subscriber);
mainCropWindow->setEditSubscriber(subscriber);
for (auto cropWin : cropWins) {
cropWin->setEditSubscriber(subscriber);
}
EditDataProvider::subscribe(subscriber);
if (listener && listener->getToolBar()) {
listener->getToolBar()->startEditMode ();
}
@@ -354,11 +353,11 @@ void ImageArea::unsubscribe()
}
EditDataProvider::unsubscribe();
// Ask the Crops to free-up edit mode buffers
mainCropWindow->cropHandler.setEditSubscriber(NULL);
// Ask the Crops to free-up edit mode buffers
mainCropWindow->setEditSubscriber(NULL);
for (auto cropWin : cropWins) {
cropWin->cropHandler.setEditSubscriber(NULL);
cropWin->setEditSubscriber(NULL);
}
setToolHand();
@@ -619,10 +618,7 @@ void ImageArea::initialImageArrived (CropWindow* cw)
mainCropWindow->cropHandler.getFullImageSize(w, h);
if(w != fullImageWidth || h != fullImageHeight) {
printf("zoomFit !\n");
mainCropWindow->zoomFit ();
} else {
printf("no-zoomFit\n");
}
fullImageWidth = w;

View File

@@ -207,13 +207,8 @@ Glib::RefPtr<Gdk::Pixbuf> PreviewHandler::getRoughImage (int x, int y, int w, in
x *= zoom;
y *= zoom;
if ((x + w) / totalZoom > previewImg->get_width()) {
w = previewImg->get_width() * totalZoom - x;
}
if ((y + h) / totalZoom > previewImg->get_height()) {
h = previewImg->get_height() * totalZoom - y;
}
w = rtengine::LIM<int>(w, 0, int(previewImg->get_width() * totalZoom) - x);
h = rtengine::LIM<int>(h, 0, int(previewImg->get_height() * totalZoom) - y);
resPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, w, h);
previewImg->scale (resPixbuf, 0, 0, w, h, -x, -y, totalZoom, totalZoom, Gdk::INTERP_NEAREST);

View File

@@ -100,48 +100,50 @@ void PreviewWindow::on_resized (Gtk::Allocation& req)
bool PreviewWindow::on_expose_event (GdkEventExpose* event)
{
if (backBuffer) {
Glib::RefPtr<Gdk::Window> window = get_window();
if (!backBuffer) {
return true;
}
int bufferW, bufferH;
backBuffer->get_size (bufferW, bufferH);
Glib::RefPtr<Gdk::Window> window = get_window();
if (!mainCropWin && imageArea) {
mainCropWin = imageArea->getMainCropWindow ();
int bufferW, bufferH;
backBuffer->get_size (bufferW, bufferH);
if (mainCropWin) {
mainCropWin->addCropWindowListener (this);
}
if (!mainCropWin && imageArea) {
mainCropWin = imageArea->getMainCropWindow ();
if (mainCropWin) {
mainCropWin->addCropWindowListener (this);
}
}
if ((get_width() != bufferW && get_height() != bufferH) || needsUpdate) {
needsUpdate = false;
updatePreviewImage ();
}
if ((get_width() != bufferW && get_height() != bufferH) || needsUpdate) {
needsUpdate = false;
updatePreviewImage ();
}
window->draw_drawable (get_style()->get_base_gc(Gtk::STATE_NORMAL), backBuffer, 0, 0, 0, 0, -1, -1);
window->draw_drawable (get_style()->get_base_gc(Gtk::STATE_NORMAL), backBuffer, 0, 0, 0, 0, -1, -1);
if (mainCropWin && zoom > 0.0) {
if(mainCropWin->getZoom() > mainCropWin->cropHandler.getFitZoom()) {
Cairo::RefPtr<Cairo::Context> cr = get_window()->create_cairo_context();
int x, y, w, h;
getObservedFrameArea (x, y, w, h);
double rectX = x + 0.5;
double rectY = y + 0.5;
double rectW = std::min(w, (int)(imgW - (x - imgX) - 1));
double rectH = std::min(h, (int)(imgH - (y - imgY) - 1));
if (mainCropWin && zoom > 0.0) {
Cairo::RefPtr<Cairo::Context> cr = get_window()->create_cairo_context();
int x, y, w, h;
getObservedFrameArea (x, y, w, h);
if (x>imgX || y>imgY || w < imgW || h < imgH) {
double rectX = x + 0.5;
double rectY = y + 0.5;
double rectW = std::min(w, (int)(imgW - (x - imgX) - 1));
double rectH = std::min(h, (int)(imgH - (y - imgY) - 1));
// draw a black "shadow" line
cr->set_source_rgba (0.0, 0.0, 0.0, 0.65);
cr->set_line_width (1);
cr->rectangle (rectX + 1., rectY + 1, rectW, rectH);
cr->stroke ();
// draw a black "shadow" line
cr->set_source_rgba (0.0, 0.0, 0.0, 0.65);
cr->set_line_width (1);
cr->rectangle (rectX + 1., rectY + 1, rectW, rectH);
cr->stroke ();
// draw a "frame" line. Color of frame line can be set in preferences
cr->set_source_rgba(options.navGuideBrush[0], options.navGuideBrush[1], options.navGuideBrush[2], options.navGuideBrush[3]); //( 1.0, 1.0, 1.0, 1.0);
cr->rectangle (rectX, rectY, rectW, rectH);
cr->stroke ();
}
// draw a "frame" line. Color of frame line can be set in preferences
cr->set_source_rgba(options.navGuideBrush[0], options.navGuideBrush[1], options.navGuideBrush[2], options.navGuideBrush[3]); //( 1.0, 1.0, 1.0, 1.0);
cr->rectangle (rectX, rectY, rectW, rectH);
cr->stroke ();
}
}
@@ -191,9 +193,9 @@ bool PreviewWindow::on_motion_notify_event (GdkEventMotion* event)
return true;
}
if(mainCropWin->getZoom() > mainCropWin->cropHandler.getFitZoom()) {
int x, y, w, h;
getObservedFrameArea (x, y, w, h);
int x, y, w, h;
getObservedFrameArea (x, y, w, h);
if (x>imgX || y>imgY || w < imgW || h < imgH) {
bool inside = event->x > x - 6 && event->x < x + w - 1 + 6 && event->y > y - 6 && event->y < y + h - 1 + 6;
bool moreInside = event->x > x + 6 && event->x < x + w - 1 - 6 && event->y > y + 6 && event->y < y + h - 1 - 6;
@@ -207,7 +209,7 @@ bool PreviewWindow::on_motion_notify_event (GdkEventMotion* event)
cursorManager.setCursor (get_window(), CSArrow);
}
}
return true;
}
@@ -218,9 +220,9 @@ bool PreviewWindow::on_button_press_event (GdkEventButton* event)
return true;
}
if(mainCropWin->getZoom() > mainCropWin->cropHandler.getFitZoom()) {
int x, y, w, h;
getObservedFrameArea (x, y, w, h);
int x, y, w, h;
getObservedFrameArea (x, y, w, h);
if (x>imgX || y>imgY || w < imgW || h < imgH) {
bool inside = event->x > x - 6 && event->x < x + w - 1 + 6 && event->y > y - 6 && event->y < y + h - 1 + 6;
bool moreInside = event->x > x + 6 && event->x < x + w - 1 - 6 && event->y > y + 6 && event->y < y + h - 1 - 6;

View File

@@ -349,8 +349,7 @@ void ToolPanelCoordinator::panelChanged (rtengine::ProcEvent event, const Glib::
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);
ipc->getInitialImage()->getImageSource()->getFullSize (fw, fh, tr);
gradient->updateGeometry (params->gradient.centerX, params->gradient.centerY, params->gradient.feather, params->gradient.degree, fw, fh);
}
@@ -430,8 +429,7 @@ void ToolPanelCoordinator::profileChange (const PartialProfile *nparams, rtengi
}
// trimming overflowing cropped area
rtengine::ImageSource *ii = (rtengine::ImageSource*)ipc->getInitialImage();
ii->getFullSize (fw, fh, tr);
ipc->getInitialImage()->getImageSource()->getFullSize (fw, fh, tr);
crop->trim(params, fw, fh);
// updating the GUI with updated values