Spot removal : differentiating source/dest, betted cursor handling
+ some code cleanup from floessie (see issue #2239)
This commit is contained in:
parent
4b7e8b7705
commit
82e7caa635
@ -23,18 +23,6 @@
|
|||||||
#include "imagesource.h"
|
#include "imagesource.h"
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
|
|
||||||
// "ceil" rounding
|
|
||||||
template<typename T>
|
|
||||||
constexpr T skips(T a, T b)
|
|
||||||
{
|
|
||||||
return a / b + static_cast<bool>(a % b);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
namespace rtengine
|
namespace rtengine
|
||||||
{
|
{
|
||||||
|
|
||||||
@ -48,14 +36,12 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct Rectangle {
|
struct Rectangle {
|
||||||
public:
|
|
||||||
int x1;
|
int x1;
|
||||||
int y1;
|
int y1;
|
||||||
int x2;
|
int x2;
|
||||||
int y2;
|
int y2;
|
||||||
|
|
||||||
Rectangle() : x1(0), y1(0), x2(0), y2(0) {}
|
Rectangle() : Rectangle(0, 0, 0, 0) {}
|
||||||
Rectangle(const Rectangle &other) : x1(other.x1), y1(other.y1), x2(other.x2), y2(other.y2) {}
|
|
||||||
Rectangle(int X1, int Y1, int X2, int Y2) : x1(X1), y1(Y1), x2(X2), y2(Y2) {}
|
Rectangle(int X1, int Y1, int X2, int Y2) : x1(X1), y1(Y1), x2(X2), y2(Y2) {}
|
||||||
|
|
||||||
bool intersects(const Rectangle &other) const {
|
bool intersects(const Rectangle &other) const {
|
||||||
@ -65,21 +51,24 @@ public:
|
|||||||
|
|
||||||
bool getIntersection(const Rectangle &other, std::unique_ptr<Rectangle> &intersection) const {
|
bool getIntersection(const Rectangle &other, std::unique_ptr<Rectangle> &intersection) const {
|
||||||
if (intersects(other)) {
|
if (intersects(other)) {
|
||||||
if (!intersection) {
|
std::unique_ptr<Rectangle> intsec(
|
||||||
intersection.reset(new Rectangle());
|
new Rectangle(
|
||||||
}
|
rtengine::max(x1, other.x1),
|
||||||
intersection->x1 = rtengine::max(x1, other.x1);
|
rtengine::max(y1, other.y1),
|
||||||
intersection->x2 = rtengine::min(x2, other.x2);
|
rtengine::min(x2, other.x2),
|
||||||
intersection->y1 = rtengine::max(y1, other.y1);
|
rtengine::min(y2, other.y2)
|
||||||
intersection->y2 = rtengine::min(y2, other.y2);
|
)
|
||||||
|
);
|
||||||
|
|
||||||
if (intersection->x1 > intersection->x2 || intersection->y1 > intersection->y2) {
|
if (intsec->x1 > intsec->x2 || intsec->y1 > intsec->y2) {
|
||||||
intersection.release();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
intersection = std::move(intsec);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (intersection) {
|
if (intersection) {
|
||||||
|
// There's no intersection, we delete the Rectangle structure
|
||||||
intersection.release();
|
intersection.release();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
@ -101,15 +90,15 @@ public:
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle& operator/=(const int &v) {
|
Rectangle& operator/=(int v) {
|
||||||
if (v == 1) {
|
if (v == 1) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
int w = x2 - x1 + 1;
|
int w = x2 - x1 + 1;
|
||||||
int h = y2 - y1 + 1;
|
int h = y2 - y1 + 1;
|
||||||
w = w / v + (w % v > 0);
|
w = w / v + static_cast<bool>(w % v);
|
||||||
h = h / v + (h % v > 0);
|
h = h / v + static_cast<bool>(h % v);
|
||||||
x1 /= v;
|
x1 /= v;
|
||||||
y1 /= v;
|
y1 /= v;
|
||||||
x2 = x1 + w - 1;
|
x2 = x1 + w - 1;
|
||||||
@ -173,7 +162,7 @@ public:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
SpotBox& operator /=(const int& v) {
|
SpotBox& operator /=(int v) {
|
||||||
if (v == 1) {
|
if (v == 1) {
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -497,7 +497,7 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y)
|
|||||||
cropgl->cropInit (cropHandler.cropParams->x, cropHandler.cropParams->y, cropHandler.cropParams->w, cropHandler.cropParams->h);
|
cropgl->cropInit (cropHandler.cropParams->x, cropHandler.cropParams->y, cropHandler.cropParams->w, cropHandler.cropParams->h);
|
||||||
} else if (iarea->getToolMode () == TMHand) {
|
} else if (iarea->getToolMode () == TMHand) {
|
||||||
if (editSubscriber) {
|
if (editSubscriber) {
|
||||||
if ((cropgl && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) && editSubscriber->getEditingType() == ET_PIPETTE && (bstate & GDK_CONTROL_MASK))) {
|
if ((cropgl && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) && (editSubscriber->getEditingType() == ET_PIPETTE && (bstate & GDK_CONTROL_MASK))) || editSubscriber->getEditingType() == ET_OBJECTS) {
|
||||||
needRedraw = editSubscriber->button1Pressed(bstate);
|
needRedraw = editSubscriber->button1Pressed(bstate);
|
||||||
if (editSubscriber->isDragging()) {
|
if (editSubscriber->isDragging()) {
|
||||||
state = SEditDrag1;
|
state = SEditDrag1;
|
||||||
@ -1277,7 +1277,10 @@ void CropWindow::updateCursor (int x, int y)
|
|||||||
} else if (onArea (CropToolBar, x, y)) {
|
} else if (onArea (CropToolBar, x, y)) {
|
||||||
newType = CSMove;
|
newType = CSMove;
|
||||||
} else if (iarea->getObject() > -1 && editSubscriber && editSubscriber->getEditingType() == ET_OBJECTS) {
|
} else if (iarea->getObject() > -1 && editSubscriber && editSubscriber->getEditingType() == ET_OBJECTS) {
|
||||||
newType = editSubscriber->getCursor(iarea->getObject());
|
int cursorX;
|
||||||
|
int cursorY;
|
||||||
|
screenCoordToImage (x, y, cursorX, cursorY);
|
||||||
|
newType = editSubscriber->getCursor(iarea->getObject(), cursorX, cursorY);
|
||||||
} else if (onArea (CropResize, x, y)) {
|
} else if (onArea (CropResize, x, y)) {
|
||||||
newType = CSResizeDiagonal;
|
newType = CSResizeDiagonal;
|
||||||
} else if (tm == TMColorPicker && hoveredPicker) {
|
} else if (tm == TMColorPicker && hoveredPicker) {
|
||||||
@ -1304,7 +1307,10 @@ void CropWindow::updateCursor (int x, int y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (objectID > -1) {
|
if (objectID > -1) {
|
||||||
newType = editSubscriber->getCursor(objectID);
|
int cursorX;
|
||||||
|
int cursorY;
|
||||||
|
screenCoordToImage (x, y, cursorX, cursorY);
|
||||||
|
newType = editSubscriber->getCursor(objectID, cursorX, cursorY);
|
||||||
} else if (tm == TMHand) {
|
} else if (tm == TMHand) {
|
||||||
if (onArea (CropObserved, x, y)) {
|
if (onArea (CropObserved, x, y)) {
|
||||||
newType = CSMove;
|
newType = CSMove;
|
||||||
@ -1330,7 +1336,10 @@ void CropWindow::updateCursor (int x, int y)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (objectID > -1) {
|
if (objectID > -1) {
|
||||||
newType = editSubscriber->getCursor(objectID);
|
int cursorX;
|
||||||
|
int cursorY;
|
||||||
|
screenCoordToImage (x, y, cursorX, cursorY);
|
||||||
|
newType = editSubscriber->getCursor(objectID, cursorX, cursorY);
|
||||||
} else {
|
} else {
|
||||||
newType = CSArrow;
|
newType = CSArrow;
|
||||||
}
|
}
|
||||||
@ -1359,6 +1368,16 @@ void CropWindow::updateCursor (int x, int y)
|
|||||||
newType = CSResizeDiagonal;
|
newType = CSResizeDiagonal;
|
||||||
} else if (state == SDragPicker) {
|
} else if (state == SDragPicker) {
|
||||||
newType = CSMove2D;
|
newType = CSMove2D;
|
||||||
|
} else if (editSubscriber && editSubscriber->getEditingType() == ET_OBJECTS) {
|
||||||
|
int objectID = iarea->getObject();
|
||||||
|
if (objectID > -1) {
|
||||||
|
int cursorX;
|
||||||
|
int cursorY;
|
||||||
|
screenCoordToImage (x, y, cursorX, cursorY);
|
||||||
|
newType = editSubscriber->getCursor(objectID, cursorX, cursorY);
|
||||||
|
} else {
|
||||||
|
newType = CSArrow;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (newType != cursor_type) {
|
if (newType != cursor_type) {
|
||||||
|
@ -490,7 +490,7 @@ bool CurveEditor::drag1(int modifierKey)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
CursorShape CurveEditor::getCursor(int objectID) const
|
CursorShape CurveEditor::getCursor(int objectID, int xPos, int yPos) const
|
||||||
{
|
{
|
||||||
if (remoteDrag) {
|
if (remoteDrag) {
|
||||||
return CSResizeHeight;
|
return CSResizeHeight;
|
||||||
|
@ -133,7 +133,7 @@ public:
|
|||||||
bool button1Pressed(int modifierKey) override;
|
bool button1Pressed(int modifierKey) override;
|
||||||
bool button1Released() override;
|
bool button1Released() override;
|
||||||
bool drag1(int modifierKey) override;
|
bool drag1(int modifierKey) override;
|
||||||
CursorShape getCursor(int objectID) const override;
|
CursorShape getCursor(int objectID, int xPos, int yPos) const override;
|
||||||
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
@ -172,10 +172,10 @@ void EditDataProvider::setPipetteVal3(float newVal)
|
|||||||
pipetteVal3 = newVal;
|
pipetteVal3 = newVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
CursorShape EditDataProvider::getCursor(int objectID) const
|
CursorShape EditDataProvider::getCursor(int objectID, int xPos, int yPos) const
|
||||||
{
|
{
|
||||||
if (currSubscriber) {
|
if (currSubscriber) {
|
||||||
currSubscriber->getCursor(objectID);
|
currSubscriber->getCursor(objectID, xPos, yPos);
|
||||||
}
|
}
|
||||||
|
|
||||||
return CSHandOpen;
|
return CSHandOpen;
|
||||||
@ -186,12 +186,12 @@ EditSubscriber* EditDataProvider::getCurrSubscriber() const
|
|||||||
return currSubscriber;
|
return currSubscriber;
|
||||||
}
|
}
|
||||||
|
|
||||||
EditDataProvider* EditSubscriber::getEditProvider()
|
EditDataProvider* EditSubscriber::getEditProvider() const
|
||||||
{
|
{
|
||||||
return provider;
|
return provider;
|
||||||
}
|
}
|
||||||
|
|
||||||
CursorShape EditSubscriber::getCursor(int objectID) const
|
CursorShape EditSubscriber::getCursor(int objectID, int xPos, int yPos) const
|
||||||
{
|
{
|
||||||
return CSHandOpen;
|
return CSHandOpen;
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ public:
|
|||||||
virtual ~EditSubscriber () = default;
|
virtual ~EditSubscriber () = default;
|
||||||
|
|
||||||
void setEditProvider(EditDataProvider *provider);
|
void setEditProvider(EditDataProvider *provider);
|
||||||
EditDataProvider* getEditProvider ();
|
EditDataProvider* getEditProvider () const;
|
||||||
void setEditID(EditUniqueID ID, BufferType buffType);
|
void setEditID(EditUniqueID ID, BufferType buffType);
|
||||||
bool isCurrentSubscriber() const;
|
bool isCurrentSubscriber() const;
|
||||||
virtual void subscribe();
|
virtual void subscribe();
|
||||||
@ -70,8 +70,10 @@ public:
|
|||||||
bool isPicking() const; /// Returns true if something is being picked
|
bool isPicking() const; /// Returns true if something is being picked
|
||||||
|
|
||||||
/** @brief Get the cursor to be displayed when above handles
|
/** @brief Get the cursor to be displayed when above handles
|
||||||
@param objectID object currently "hovered" */
|
@param objectID object currently "hovered"
|
||||||
virtual CursorShape getCursor (int objectID) const;
|
@param xPos X cursor position in image space
|
||||||
|
@param yPos Y cursor position in image space */
|
||||||
|
virtual CursorShape getCursor (int objectID, int xPos, int yPos) const;
|
||||||
|
|
||||||
/** @brief Triggered when the mouse is moving over an object
|
/** @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
|
This method is also triggered when the cursor is moving over the image in ET_PIPETTE mode
|
||||||
@ -188,7 +190,7 @@ public:
|
|||||||
void setPipetteVal1(float newVal);
|
void setPipetteVal1(float newVal);
|
||||||
void setPipetteVal2(float newVal);
|
void setPipetteVal2(float newVal);
|
||||||
void setPipetteVal3(float newVal);
|
void setPipetteVal3(float newVal);
|
||||||
virtual CursorShape getCursor(int objectID) const;
|
virtual CursorShape getCursor(int objectID, int xPos, int yPos) const;
|
||||||
int getPipetteRectSize () const;
|
int getPipetteRectSize () const;
|
||||||
EditSubscriber* getCurrSubscriber() const;
|
EditSubscriber* getCurrSubscriber() const;
|
||||||
virtual void getImageSize (int &w, int&h) = 0;
|
virtual void getImageSize (int &w, int&h) = 0;
|
||||||
|
@ -20,7 +20,11 @@
|
|||||||
#include "editwidgets.h"
|
#include "editwidgets.h"
|
||||||
#include "editbuffer.h"
|
#include "editbuffer.h"
|
||||||
#include "editcallbacks.h"
|
#include "editcallbacks.h"
|
||||||
#include "../rtengine/rt_math.h"
|
|
||||||
|
const std::vector<double> Geometry::dash = {3., 1.5};
|
||||||
|
|
||||||
|
#define INNERGEOM_OPACITY 1.
|
||||||
|
#define OUTERGEOM_OPACITY 0.7
|
||||||
|
|
||||||
RGBColor Geometry::getInnerLineColor ()
|
RGBColor Geometry::getInnerLineColor ()
|
||||||
{
|
{
|
||||||
@ -65,7 +69,8 @@ RGBColor Geometry::getOuterLineColor ()
|
|||||||
|
|
||||||
void Circle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
|
void Circle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
|
||||||
{
|
{
|
||||||
if ((flags & F_VISIBLE) && state != INSENSITIVE) {
|
double lineWidth = getOuterLineWidth();
|
||||||
|
if ((flags & F_VISIBLE) && state != INSENSITIVE && lineWidth > 0. && innerLineWidth > 0.) {
|
||||||
RGBColor color;
|
RGBColor color;
|
||||||
|
|
||||||
if (flags & F_AUTO_COLOR) {
|
if (flags & F_AUTO_COLOR) {
|
||||||
@ -74,8 +79,9 @@ void Circle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer
|
|||||||
color = outerLineColor;
|
color = outerLineColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
cr->set_source_rgb (color.getR(), color.getG(), color.getB());
|
cr->set_source_rgba (color.getR(), color.getG(), color.getB(), OUTERGEOM_OPACITY * rtengine::min(innerLineWidth / 2.f, 1.f));
|
||||||
cr->set_line_width( getOuterLineWidth() );
|
cr->set_line_width (lineWidth);
|
||||||
|
cr->set_line_cap(Cairo::LINE_CAP_ROUND);
|
||||||
|
|
||||||
rtengine::Coord center_ = center;
|
rtengine::Coord center_ = center;
|
||||||
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas(double(radius)) : double(radius);
|
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas(double(radius)) : double(radius);
|
||||||
@ -105,10 +111,11 @@ void Circle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer
|
|||||||
color = innerLineColor;
|
color = innerLineColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
cr->set_source_rgb(color.getR(), color.getG(), color.getB());
|
cr->set_source_rgba (color.getR(), color.getG(), color.getB(), INNERGEOM_OPACITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
cr->set_line_width(innerLineWidth);
|
cr->set_line_width(innerLineWidth);
|
||||||
|
cr->set_line_cap(flags & F_DASHED ? Cairo::LINE_CAP_BUTT : Cairo::LINE_CAP_ROUND);
|
||||||
|
|
||||||
rtengine::Coord center_ = center;
|
rtengine::Coord center_ = center;
|
||||||
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas(double(radius)) : double(radius);
|
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas(double(radius)) : double(radius);
|
||||||
@ -121,9 +128,12 @@ void Circle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer
|
|||||||
center_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
|
center_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filled && state != INSENSITIVE) {
|
if (flags & F_DASHED) {
|
||||||
cr->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0., 2.*rtengine::RT_PI);
|
cr->set_dash(dash, 0.);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filled) {
|
||||||
|
cr->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0., 2.*rtengine::RT_PI);
|
||||||
if (innerLineWidth > 0.) {
|
if (innerLineWidth > 0.) {
|
||||||
cr->fill_preserve();
|
cr->fill_preserve();
|
||||||
cr->stroke();
|
cr->stroke();
|
||||||
@ -132,20 +142,11 @@ void Circle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer
|
|||||||
}
|
}
|
||||||
} else if (innerLineWidth > 0.) {
|
} else if (innerLineWidth > 0.) {
|
||||||
cr->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0., 2.*rtengine::RT_PI);
|
cr->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0., 2.*rtengine::RT_PI);
|
||||||
|
|
||||||
if (state == INSENSITIVE) {
|
|
||||||
std::valarray<double> ds(1);
|
|
||||||
ds[0] = 4;
|
|
||||||
cr->set_source_rgba(1.0, 1.0, 1.0, 0.618);
|
|
||||||
cr->stroke_preserve();
|
|
||||||
cr->set_source_rgba(0.0, 0.0, 0.0, 0.618);
|
|
||||||
cr->set_dash(ds, 0);
|
|
||||||
cr->stroke();
|
|
||||||
ds.resize(0);
|
|
||||||
cr->set_dash(ds, 0);
|
|
||||||
} else {
|
|
||||||
cr->stroke();
|
cr->stroke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & F_DASHED) {
|
||||||
|
cr->unset_dash();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -154,6 +155,7 @@ void Circle::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, unsigned short
|
|||||||
{
|
{
|
||||||
if (flags & F_HOVERABLE) {
|
if (flags & F_HOVERABLE) {
|
||||||
cr->set_line_width( getMouseOverLineWidth() );
|
cr->set_line_width( getMouseOverLineWidth() );
|
||||||
|
cr->set_line_cap(Cairo::LINE_CAP_ROUND);
|
||||||
rtengine::Coord center_ = center;
|
rtengine::Coord center_ = center;
|
||||||
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas(double(radius)) : double(radius);
|
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToCanvas(double(radius)) : double(radius);
|
||||||
|
|
||||||
@ -188,7 +190,8 @@ void Circle::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, unsigned short
|
|||||||
|
|
||||||
void Line::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
|
void Line::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
|
||||||
{
|
{
|
||||||
if ((flags & F_VISIBLE) && state != INSENSITIVE) {
|
double lineWidth = getOuterLineWidth();
|
||||||
|
if ((flags & F_VISIBLE) && state != INSENSITIVE && lineWidth > 0. && innerLineWidth > 0.) {
|
||||||
RGBColor color;
|
RGBColor color;
|
||||||
|
|
||||||
if (flags & F_AUTO_COLOR) {
|
if (flags & F_AUTO_COLOR) {
|
||||||
@ -197,8 +200,9 @@ void Line::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *
|
|||||||
color = outerLineColor;
|
color = outerLineColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
cr->set_source_rgb (color.getR(), color.getG(), color.getB());
|
cr->set_source_rgba (color.getR(), color.getG(), color.getB(), OUTERGEOM_OPACITY * rtengine::min(innerLineWidth / 2.f, 1.f));
|
||||||
cr->set_line_width( getOuterLineWidth() );
|
cr->set_line_width (lineWidth);
|
||||||
|
cr->set_line_cap(Cairo::LINE_CAP_ROUND);
|
||||||
|
|
||||||
rtengine::Coord begin_ = begin;
|
rtengine::Coord begin_ = begin;
|
||||||
rtengine::Coord end_ = end;
|
rtengine::Coord end_ = end;
|
||||||
@ -232,10 +236,11 @@ void Line::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *
|
|||||||
color = innerLineColor;
|
color = innerLineColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
cr->set_source_rgb (color.getR(), color.getG(), color.getB());
|
cr->set_source_rgba (color.getR(), color.getG(), color.getB(), INNERGEOM_OPACITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
cr->set_line_width(innerLineWidth);
|
cr->set_line_width(innerLineWidth);
|
||||||
|
cr->set_line_cap(flags & F_DASHED ? Cairo::LINE_CAP_BUTT : Cairo::LINE_CAP_ROUND);
|
||||||
|
|
||||||
rtengine::Coord begin_ = begin;
|
rtengine::Coord begin_ = begin;
|
||||||
rtengine::Coord end_ = end;
|
rtengine::Coord end_ = end;
|
||||||
@ -251,21 +256,16 @@ void Line::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *
|
|||||||
end_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
|
end_ += objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & F_DASHED) {
|
||||||
|
cr->set_dash(dash, 0.);
|
||||||
|
}
|
||||||
|
|
||||||
cr->move_to(begin_.x + 0.5, begin_.y + 0.5);
|
cr->move_to(begin_.x + 0.5, begin_.y + 0.5);
|
||||||
cr->line_to(end_.x + 0.5, end_.y + 0.5);
|
cr->line_to(end_.x + 0.5, end_.y + 0.5);
|
||||||
|
cr->stroke();
|
||||||
|
|
||||||
if (state == INSENSITIVE) {
|
if (flags & F_DASHED) {
|
||||||
std::valarray<double> ds(1);
|
cr->unset_dash();
|
||||||
ds[0] = 4;
|
|
||||||
cr->set_source_rgba(1.0, 1.0, 1.0, 0.618);
|
|
||||||
cr->stroke_preserve();
|
|
||||||
cr->set_source_rgba(0.0, 0.0, 0.0, 0.618);
|
|
||||||
cr->set_dash(ds, 0);
|
|
||||||
cr->stroke();
|
|
||||||
ds.resize(0);
|
|
||||||
cr->set_dash(ds, 0);
|
|
||||||
} else {
|
|
||||||
cr->stroke();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -274,6 +274,7 @@ void Line::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr, unsigned short id,
|
|||||||
{
|
{
|
||||||
if (flags & F_HOVERABLE) {
|
if (flags & F_HOVERABLE) {
|
||||||
cr->set_line_width( getMouseOverLineWidth() );
|
cr->set_line_width( getMouseOverLineWidth() );
|
||||||
|
cr->set_line_cap(Cairo::LINE_CAP_ROUND);
|
||||||
rtengine::Coord begin_ = begin;
|
rtengine::Coord begin_ = begin;
|
||||||
rtengine::Coord end_ = end;
|
rtengine::Coord end_ = end;
|
||||||
|
|
||||||
@ -302,7 +303,8 @@ void Line::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr, unsigned short id,
|
|||||||
|
|
||||||
void Polyline::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
|
void Polyline::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
|
||||||
{
|
{
|
||||||
if ((flags & F_VISIBLE) && state != INSENSITIVE && points.size() > 1) {
|
double lineWidth = getOuterLineWidth();
|
||||||
|
if ((flags & F_VISIBLE) && state != INSENSITIVE && points.size() > 1 && lineWidth > 0.) {
|
||||||
RGBColor color;
|
RGBColor color;
|
||||||
|
|
||||||
if (flags & F_AUTO_COLOR) {
|
if (flags & F_AUTO_COLOR) {
|
||||||
@ -311,8 +313,10 @@ void Polyline::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuff
|
|||||||
color = outerLineColor;
|
color = outerLineColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
cr->set_source_rgb (color.getR(), color.getG(), color.getB());
|
cr->set_source_rgba (color.getR(), color.getG(), color.getB(), OUTERGEOM_OPACITY * rtengine::min(innerLineWidth / 2.f, 1.f));
|
||||||
cr->set_line_width( getOuterLineWidth() );
|
cr->set_line_width (lineWidth);
|
||||||
|
cr->set_line_cap(Cairo::LINE_CAP_ROUND);
|
||||||
|
cr->set_line_join(Cairo::LINE_JOIN_ROUND);
|
||||||
|
|
||||||
rtengine::Coord currPos;
|
rtengine::Coord currPos;
|
||||||
|
|
||||||
@ -355,10 +359,16 @@ void Polyline::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuff
|
|||||||
color = innerLineColor;
|
color = innerLineColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
cr->set_source_rgb (color.getR(), color.getG(), color.getB());
|
cr->set_source_rgba (color.getR(), color.getG(), color.getB(), INNERGEOM_OPACITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
cr->set_line_width(innerLineWidth);
|
cr->set_line_width(innerLineWidth);
|
||||||
|
cr->set_line_cap(flags & F_DASHED ? Cairo::LINE_CAP_BUTT : Cairo::LINE_CAP_ROUND);
|
||||||
|
cr->set_line_join(Cairo::LINE_JOIN_ROUND);
|
||||||
|
|
||||||
|
if (flags & F_DASHED) {
|
||||||
|
cr->set_dash(dash, 0.);
|
||||||
|
}
|
||||||
|
|
||||||
if (filled && state != INSENSITIVE) {
|
if (filled && state != INSENSITIVE) {
|
||||||
rtengine::Coord currPos;
|
rtengine::Coord currPos;
|
||||||
@ -407,20 +417,11 @@ void Polyline::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuff
|
|||||||
cr->line_to(currPos.x + 0.5, currPos.y + 0.5);
|
cr->line_to(currPos.x + 0.5, currPos.y + 0.5);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state == INSENSITIVE) {
|
|
||||||
std::valarray<double> ds(1);
|
|
||||||
ds[0] = 4;
|
|
||||||
cr->set_source_rgba(1.0, 1.0, 1.0, 0.618);
|
|
||||||
cr->stroke_preserve();
|
|
||||||
cr->set_source_rgba(0.0, 0.0, 0.0, 0.618);
|
|
||||||
cr->set_dash(ds, 0);
|
|
||||||
cr->stroke();
|
|
||||||
ds.resize(0);
|
|
||||||
cr->set_dash(ds, 0);
|
|
||||||
} else {
|
|
||||||
cr->stroke();
|
cr->stroke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & F_DASHED) {
|
||||||
|
cr->unset_dash();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -437,8 +438,11 @@ void Polyline::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, unsigned shor
|
|||||||
cr->set_source_rgba (0., 0., 0., (id + 1) / 65535.);
|
cr->set_source_rgba (0., 0., 0., (id + 1) / 65535.);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned int i = 0; i < points.size(); ++i) {
|
|
||||||
cr->set_line_width( getMouseOverLineWidth() );
|
cr->set_line_width( getMouseOverLineWidth() );
|
||||||
|
cr->set_line_cap(Cairo::LINE_CAP_ROUND);
|
||||||
|
cr->set_line_join(Cairo::LINE_JOIN_ROUND);
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < points.size(); ++i) {
|
||||||
currPos = points.at(i);
|
currPos = points.at(i);
|
||||||
|
|
||||||
if (datum == IMAGE) {
|
if (datum == IMAGE) {
|
||||||
@ -495,7 +499,8 @@ void Rectangle::setXYXY(rtengine::Coord topLeft, rtengine::Coord bottomRight)
|
|||||||
|
|
||||||
void Rectangle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
|
void Rectangle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuffer *objectBuffer, EditCoordSystem &coordSystem)
|
||||||
{
|
{
|
||||||
if ((flags & F_VISIBLE) && state != INSENSITIVE) {
|
double lineWidth = getOuterLineWidth();
|
||||||
|
if ((flags & F_VISIBLE) && state != INSENSITIVE && lineWidth > 0. && innerLineWidth > 0.) {
|
||||||
RGBColor color;
|
RGBColor color;
|
||||||
|
|
||||||
if (flags & F_AUTO_COLOR) {
|
if (flags & F_AUTO_COLOR) {
|
||||||
@ -504,8 +509,9 @@ void Rectangle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuf
|
|||||||
color = outerLineColor;
|
color = outerLineColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
cr->set_source_rgb (color.getR(), color.getG(), color.getB());
|
cr->set_source_rgba (color.getR(), color.getG(), color.getB(), OUTERGEOM_OPACITY * rtengine::min(innerLineWidth / 2.f, 1.f));
|
||||||
cr->set_line_width( getOuterLineWidth() );
|
cr->set_line_width (lineWidth);
|
||||||
|
cr->set_line_join(Cairo::LINE_JOIN_BEVEL);
|
||||||
|
|
||||||
rtengine::Coord tl, br;
|
rtengine::Coord tl, br;
|
||||||
|
|
||||||
@ -548,10 +554,11 @@ void Rectangle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuf
|
|||||||
color = innerLineColor;
|
color = innerLineColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
cr->set_source_rgb (color.getR(), color.getG(), color.getB());
|
cr->set_source_rgba (color.getR(), color.getG(), color.getB(), INNERGEOM_OPACITY);
|
||||||
}
|
}
|
||||||
|
|
||||||
cr->set_line_width(innerLineWidth);
|
cr->set_line_width(innerLineWidth);
|
||||||
|
cr->set_line_join(Cairo::LINE_JOIN_BEVEL);
|
||||||
|
|
||||||
rtengine::Coord tl, br;
|
rtengine::Coord tl, br;
|
||||||
|
|
||||||
@ -571,7 +578,11 @@ void Rectangle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuf
|
|||||||
br = bottomRight + objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
|
br = bottomRight + objectBuffer->getDataProvider()->posScreen + objectBuffer->getDataProvider()->deltaScreen;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (filled && state != INSENSITIVE) {
|
if (flags & F_DASHED) {
|
||||||
|
cr->set_dash(dash, 0.);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filled) {
|
||||||
cr->rectangle(tl.x + 0.5, tl.y + 0.5, br.x - tl.x, br.y - tl.y);
|
cr->rectangle(tl.x + 0.5, tl.y + 0.5, br.x - tl.x, br.y - tl.y);
|
||||||
|
|
||||||
if (innerLineWidth > 0.) {
|
if (innerLineWidth > 0.) {
|
||||||
@ -582,20 +593,11 @@ void Rectangle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, ObjectMOBuf
|
|||||||
}
|
}
|
||||||
} else if (innerLineWidth > 0.) {
|
} else if (innerLineWidth > 0.) {
|
||||||
cr->rectangle(tl.x + 0.5, tl.y + 0.5, br.x - tl.x, br.y - tl.y);
|
cr->rectangle(tl.x + 0.5, tl.y + 0.5, br.x - tl.x, br.y - tl.y);
|
||||||
|
|
||||||
if (state == INSENSITIVE) {
|
|
||||||
std::valarray<double> ds(1);
|
|
||||||
ds[0] = 4;
|
|
||||||
cr->set_source_rgba(1.0, 1.0, 1.0, 0.618);
|
|
||||||
cr->stroke_preserve();
|
|
||||||
cr->set_source_rgba(0.0, 0.0, 0.0, 0.618);
|
|
||||||
cr->set_dash(ds, 0);
|
|
||||||
cr->stroke();
|
|
||||||
ds.resize(0);
|
|
||||||
cr->set_dash(ds, 0);
|
|
||||||
} else {
|
|
||||||
cr->stroke();
|
cr->stroke();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (flags & F_DASHED) {
|
||||||
|
cr->unset_dash();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -604,6 +606,7 @@ void Rectangle::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr, unsigned shor
|
|||||||
{
|
{
|
||||||
if (flags & F_HOVERABLE) {
|
if (flags & F_HOVERABLE) {
|
||||||
cr->set_line_width( getMouseOverLineWidth() );
|
cr->set_line_width( getMouseOverLineWidth() );
|
||||||
|
cr->set_line_join(Cairo::LINE_JOIN_ROUND);
|
||||||
|
|
||||||
rtengine::Coord tl, br;
|
rtengine::Coord tl, br;
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "editbuffer.h"
|
#include "editbuffer.h"
|
||||||
#include "editcoordsys.h"
|
#include "editcoordsys.h"
|
||||||
#include "../rtengine/coord.h"
|
#include "../rtengine/coord.h"
|
||||||
|
#include "../rtengine/rt_math.h"
|
||||||
|
|
||||||
class ObjectMOBuffer;
|
class ObjectMOBuffer;
|
||||||
|
|
||||||
@ -208,6 +209,8 @@ public:
|
|||||||
F_VISIBLE = 1 << 0, /// true if the geometry have to be drawn on the visible layer
|
F_VISIBLE = 1 << 0, /// true if the geometry have to be drawn on the visible layer
|
||||||
F_HOVERABLE = 1 << 1, /// true if the geometry have to be drawn on the "mouse over" layer
|
F_HOVERABLE = 1 << 1, /// true if the geometry have to be drawn on the "mouse over" layer
|
||||||
F_AUTO_COLOR = 1 << 2, /// true if the color depend on the state value, not the color field above
|
F_AUTO_COLOR = 1 << 2, /// true if the color depend on the state value, not the color field above
|
||||||
|
F_DASHED = 1 << 3, /// true if the geometry have to be drawn as a dash line
|
||||||
|
// (TODO: add a F_LARGE_DASH to have two different dash size ?)
|
||||||
};
|
};
|
||||||
|
|
||||||
/// @brief Key point of the image's rectangle that is used to locate the icon copy to the target point:
|
/// @brief Key point of the image's rectangle that is used to locate the icon copy to the target point:
|
||||||
@ -224,6 +227,7 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
static const std::vector<double> dash;
|
||||||
RGBColor innerLineColor;
|
RGBColor innerLineColor;
|
||||||
RGBColor outerLineColor;
|
RGBColor outerLineColor;
|
||||||
short flags;
|
short flags;
|
||||||
@ -249,6 +253,8 @@ public:
|
|||||||
void setVisible (bool visible);
|
void setVisible (bool visible);
|
||||||
bool isHoverable ();
|
bool isHoverable ();
|
||||||
void setHoverable (bool visible);
|
void setHoverable (bool visible);
|
||||||
|
bool isDashed ();
|
||||||
|
void setDashed (bool dashed);
|
||||||
|
|
||||||
|
|
||||||
// setActive will enable/disable the visible and hoverable flags in one shot!
|
// setActive will enable/disable the visible and hoverable flags in one shot!
|
||||||
@ -427,7 +433,7 @@ inline void Geometry::setOuterLineColor (char r, char g, char b) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
inline double Geometry::getMouseOverLineWidth () {
|
inline double Geometry::getMouseOverLineWidth () {
|
||||||
return getOuterLineWidth () + 2.;
|
return rtengine::max(double(innerLineWidth), 1.) + 2.;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline void Geometry::setAutoColor (bool aColor) {
|
inline void Geometry::setAutoColor (bool aColor) {
|
||||||
@ -462,6 +468,18 @@ inline void Geometry::setHoverable (bool hoverable) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline bool Geometry::isDashed () {
|
||||||
|
return flags & F_DASHED;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void Geometry::setDashed (bool dashed) {
|
||||||
|
if (dashed) {
|
||||||
|
flags |= F_DASHED;
|
||||||
|
} else {
|
||||||
|
flags &= ~F_DASHED;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
inline void Geometry::setActive (bool active) {
|
inline void Geometry::setActive (bool active) {
|
||||||
if (active) {
|
if (active) {
|
||||||
flags |= (F_VISIBLE | F_HOVERABLE);
|
flags |= (F_VISIBLE | F_HOVERABLE);
|
||||||
|
@ -225,7 +225,7 @@ void FilmNegative::setEditProvider(EditDataProvider* provider)
|
|||||||
EditSubscriber::setEditProvider(provider);
|
EditSubscriber::setEditProvider(provider);
|
||||||
}
|
}
|
||||||
|
|
||||||
CursorShape FilmNegative::getCursor(int objectID) const
|
CursorShape FilmNegative::getCursor(int objectID, int xPos, int yPos) const
|
||||||
{
|
{
|
||||||
return CSSpotWB;
|
return CSSpotWB;
|
||||||
}
|
}
|
||||||
|
@ -59,7 +59,7 @@ public:
|
|||||||
void setEditProvider(EditDataProvider* provider) override;
|
void setEditProvider(EditDataProvider* provider) override;
|
||||||
|
|
||||||
// EditSubscriber interface
|
// EditSubscriber interface
|
||||||
CursorShape getCursor(int objectID) const override;
|
CursorShape getCursor(int objectID, int xPos, int yPos) const override;
|
||||||
bool mouseOver(int modifierKey) override;
|
bool mouseOver(int modifierKey) override;
|
||||||
bool button1Pressed(int modifierKey) override;
|
bool button1Pressed(int modifierKey) override;
|
||||||
bool button1Released() override;
|
bool button1Released() override;
|
||||||
|
@ -327,7 +327,7 @@ void Gradient::editToggled ()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CursorShape Gradient::getCursor(int objectID) const
|
CursorShape Gradient::getCursor(int objectID, int xPos, int yPos) const
|
||||||
{
|
{
|
||||||
switch (objectID) {
|
switch (objectID) {
|
||||||
case (0):
|
case (0):
|
||||||
|
@ -51,7 +51,7 @@ public:
|
|||||||
void setEditProvider (EditDataProvider* provider) override;
|
void setEditProvider (EditDataProvider* provider) override;
|
||||||
|
|
||||||
// EditSubscriber interface
|
// EditSubscriber interface
|
||||||
CursorShape getCursor(int objectID) const override;
|
CursorShape getCursor(int objectID, int xPos, int yPos) const override;
|
||||||
bool mouseOver(int modifierKey) override;
|
bool mouseOver(int modifierKey) override;
|
||||||
bool button1Pressed(int modifierKey) override;
|
bool button1Pressed(int modifierKey) override;
|
||||||
bool button1Released() override;
|
bool button1Released() override;
|
||||||
|
@ -32,8 +32,14 @@ using namespace rtengine::procparams;
|
|||||||
#define STATIC_VISIBLE_OBJ_NBR 6
|
#define STATIC_VISIBLE_OBJ_NBR 6
|
||||||
#define STATIC_MO_OBJ_NBR 6
|
#define STATIC_MO_OBJ_NBR 6
|
||||||
|
|
||||||
Spot::Spot() : FoldableToolPanel (this, "spot", M ("TP_SPOT_LABEL"), true, true), EditSubscriber (ET_OBJECTS), lastObject (-1), activeSpot (-1),
|
Spot::Spot() :
|
||||||
sourceIcon ("spot-normal.png", "spot-active.png", "spot-active.png", "spot-prelight.png", "", Geometry::DP_CENTERCENTER), editedCheckBox (nullptr)
|
FoldableToolPanel(this, "spot", M ("TP_SPOT_LABEL"), true, true),
|
||||||
|
EditSubscriber(ET_OBJECTS),
|
||||||
|
draggedSide(DraggedSide::NONE),
|
||||||
|
lastObject(-1),
|
||||||
|
activeSpot(-1),
|
||||||
|
sourceIcon("spot-normal.png", "spot-active.png", "spot-prelight.png", "", "", Geometry::DP_CENTERCENTER),
|
||||||
|
editedCheckBox(nullptr)
|
||||||
{
|
{
|
||||||
countLabel = Gtk::manage (new Gtk::Label (Glib::ustring::compose (M ("TP_SPOT_COUNTLABEL"), 0)));
|
countLabel = Gtk::manage (new Gtk::Label (Glib::ustring::compose (M ("TP_SPOT_COUNTLABEL"), 0)));
|
||||||
|
|
||||||
@ -61,6 +67,7 @@ Spot::Spot() : FoldableToolPanel (this, "spot", M ("TP_SPOT_LABEL"), true, true)
|
|||||||
sourceCircle.datum = Geometry::IMAGE;
|
sourceCircle.datum = Geometry::IMAGE;
|
||||||
sourceCircle.setActive (false);
|
sourceCircle.setActive (false);
|
||||||
sourceCircle.radiusInImageSpace = true;
|
sourceCircle.radiusInImageSpace = true;
|
||||||
|
sourceCircle.setDashed(true);
|
||||||
sourceMODisc.datum = Geometry::IMAGE;
|
sourceMODisc.datum = Geometry::IMAGE;
|
||||||
sourceMODisc.setActive (false);
|
sourceMODisc.setActive (false);
|
||||||
sourceMODisc.radiusInImageSpace = true;
|
sourceMODisc.radiusInImageSpace = true;
|
||||||
@ -77,9 +84,12 @@ Spot::Spot() : FoldableToolPanel (this, "spot", M ("TP_SPOT_LABEL"), true, true)
|
|||||||
sourceFeatherCircle.datum = Geometry::IMAGE;
|
sourceFeatherCircle.datum = Geometry::IMAGE;
|
||||||
sourceFeatherCircle.setActive (false);
|
sourceFeatherCircle.setActive (false);
|
||||||
sourceFeatherCircle.radiusInImageSpace = true;
|
sourceFeatherCircle.radiusInImageSpace = true;
|
||||||
|
sourceFeatherCircle.setDashed(true);
|
||||||
|
sourceFeatherCircle.innerLineWidth = 0.7;
|
||||||
targetFeatherCircle.datum = Geometry::IMAGE;
|
targetFeatherCircle.datum = Geometry::IMAGE;
|
||||||
targetFeatherCircle.setActive (false);
|
targetFeatherCircle.setActive (false);
|
||||||
targetFeatherCircle.radiusInImageSpace = true;
|
targetFeatherCircle.radiusInImageSpace = true;
|
||||||
|
targetFeatherCircle.innerLineWidth = 0.7;
|
||||||
link.datum = Geometry::IMAGE;
|
link.datum = Geometry::IMAGE;
|
||||||
link.setActive (false);
|
link.setActive (false);
|
||||||
|
|
||||||
@ -241,6 +251,10 @@ Geometry* Spot::getVisibleGeometryFromMO (int MOID)
|
|||||||
return &sourceIcon;
|
return &sourceIcon;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (MOID > STATIC_MO_OBJ_NBR) {
|
||||||
|
return EditSubscriber::visibleGeometry.at(MOID - STATIC_MO_OBJ_NBR);
|
||||||
|
}
|
||||||
|
|
||||||
return EditSubscriber::mouseOverGeometry.at (MOID);
|
return EditSubscriber::mouseOverGeometry.at (MOID);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,10 +273,12 @@ void Spot::createGeometry ()
|
|||||||
delete EditSubscriber::visibleGeometry.at (i);
|
delete EditSubscriber::visibleGeometry.at (i);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t i = 0, j = 0;
|
// mouse over geometry starts with the static geometry, then the spot's icon geometry
|
||||||
EditSubscriber::mouseOverGeometry.resize (STATIC_MO_OBJ_NBR + nbrEntry);
|
EditSubscriber::mouseOverGeometry.resize (STATIC_MO_OBJ_NBR + nbrEntry);
|
||||||
|
// visible geometry starts with the spot's icon geometry, then the static geometry
|
||||||
EditSubscriber::visibleGeometry.resize (nbrEntry + STATIC_VISIBLE_OBJ_NBR);
|
EditSubscriber::visibleGeometry.resize (nbrEntry + STATIC_VISIBLE_OBJ_NBR);
|
||||||
|
|
||||||
|
size_t i = 0, j = 0;
|
||||||
EditSubscriber::mouseOverGeometry.at (i++) = &targetMODisc; // STATIC_MO_OBJ_NBR + 0
|
EditSubscriber::mouseOverGeometry.at (i++) = &targetMODisc; // STATIC_MO_OBJ_NBR + 0
|
||||||
EditSubscriber::mouseOverGeometry.at (i++) = &sourceMODisc; // STATIC_MO_OBJ_NBR + 1
|
EditSubscriber::mouseOverGeometry.at (i++) = &sourceMODisc; // STATIC_MO_OBJ_NBR + 1
|
||||||
EditSubscriber::mouseOverGeometry.at (i++) = &targetCircle; // STATIC_MO_OBJ_NBR + 2
|
EditSubscriber::mouseOverGeometry.at (i++) = &targetCircle; // STATIC_MO_OBJ_NBR + 2
|
||||||
@ -351,6 +367,10 @@ void Spot::updateGeometry()
|
|||||||
} else {
|
} else {
|
||||||
link.setActive (false);
|
link.setActive (false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
sourceCircle.setVisible(draggedSide != DraggedSide::SOURCE);
|
||||||
|
targetCircle.setVisible(draggedSide != DraggedSide::TARGET);
|
||||||
|
link.setVisible(draggedSide == DraggedSide::NONE);
|
||||||
} else {
|
} else {
|
||||||
targetCircle.setActive (false);
|
targetCircle.setActive (false);
|
||||||
targetMODisc.setActive (false);
|
targetMODisc.setActive (false);
|
||||||
@ -432,10 +452,37 @@ void Spot::deleteSelectedEntry()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO
|
CursorShape Spot::getCursor (int objectID, int xPos, int yPos) const
|
||||||
CursorShape Spot::getCursor (int objectID) const
|
|
||||||
{
|
{
|
||||||
return CSHandOpen;
|
const EditDataProvider* editProvider = getEditProvider();
|
||||||
|
if (editProvider) {
|
||||||
|
if (draggedSide != DraggedSide::NONE) {
|
||||||
|
return CSEmpty;
|
||||||
|
}
|
||||||
|
|
||||||
|
int object = editProvider->getObject();
|
||||||
|
if (object == 0 || object == 1) {
|
||||||
|
return CSMove2D;
|
||||||
|
}
|
||||||
|
if (object >= 2 || object <= 5) {
|
||||||
|
Coord delta(Coord(xPos, yPos) - ((object == 3 || object == 5) ? spots.at(activeSpot).sourcePos : spots.at(activeSpot).targetPos));
|
||||||
|
PolarCoord polarPos(delta);
|
||||||
|
if (polarPos.angle < 0.) {
|
||||||
|
polarPos.angle += 180.;
|
||||||
|
}
|
||||||
|
if (polarPos.angle < 22.5 || polarPos.angle >= 157.5) {
|
||||||
|
return CSMove1DH;
|
||||||
|
}
|
||||||
|
if (polarPos.angle < 67.5) {
|
||||||
|
return CSResizeBottomRight;
|
||||||
|
}
|
||||||
|
if (polarPos.angle < 112.5) {
|
||||||
|
return CSMove1DV;
|
||||||
|
}
|
||||||
|
return CSResizeBottomLeft;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return CSCrosshair;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Spot::mouseOver (int modifierKey)
|
bool Spot::mouseOver (int modifierKey)
|
||||||
@ -494,10 +541,12 @@ bool Spot::button1Pressed (int modifierKey)
|
|||||||
|
|
||||||
if (editProvider) {
|
if (editProvider) {
|
||||||
if (lastObject == -1 && (modifierKey & GDK_CONTROL_MASK)) {
|
if (lastObject == -1 && (modifierKey & GDK_CONTROL_MASK)) {
|
||||||
|
draggedSide = DraggedSide::SOURCE;
|
||||||
addNewEntry();
|
addNewEntry();
|
||||||
EditSubscriber::action = EditSubscriber::Action::DRAGGING;
|
EditSubscriber::action = EditSubscriber::Action::DRAGGING;
|
||||||
return true;
|
return true;
|
||||||
} else if (lastObject > -1) {
|
} else if (lastObject > -1) {
|
||||||
|
draggedSide = lastObject == 0 ? DraggedSide::TARGET : lastObject == 1 ? DraggedSide::SOURCE : DraggedSide::NONE;
|
||||||
getVisibleGeometryFromMO (lastObject)->state = Geometry::DRAGGED;
|
getVisibleGeometryFromMO (lastObject)->state = Geometry::DRAGGED;
|
||||||
EditSubscriber::action = EditSubscriber::Action::DRAGGING;
|
EditSubscriber::action = EditSubscriber::Action::DRAGGING;
|
||||||
return true;
|
return true;
|
||||||
@ -519,6 +568,7 @@ bool Spot::button1Released()
|
|||||||
|
|
||||||
loGeom->state = Geometry::PRELIGHT;
|
loGeom->state = Geometry::PRELIGHT;
|
||||||
EditSubscriber::action = EditSubscriber::Action::NONE;
|
EditSubscriber::action = EditSubscriber::Action::NONE;
|
||||||
|
draggedSide = DraggedSide::NONE;
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -552,6 +602,7 @@ bool Spot::button3Pressed (int modifierKey)
|
|||||||
lastObject = 1; // sourceMODisc
|
lastObject = 1; // sourceMODisc
|
||||||
sourceIcon.state = Geometry::DRAGGED;
|
sourceIcon.state = Geometry::DRAGGED;
|
||||||
EditSubscriber::action = EditSubscriber::Action::DRAGGING;
|
EditSubscriber::action = EditSubscriber::Action::DRAGGING;
|
||||||
|
draggedSide = DraggedSide::SOURCE;
|
||||||
return true;
|
return true;
|
||||||
} else if (! (modifierKey & (GDK_SHIFT_MASK | GDK_SHIFT_MASK))) {
|
} else if (! (modifierKey & (GDK_SHIFT_MASK | GDK_SHIFT_MASK))) {
|
||||||
EditSubscriber::action = EditSubscriber::Action::PICKING;
|
EditSubscriber::action = EditSubscriber::Action::PICKING;
|
||||||
@ -571,6 +622,7 @@ bool Spot::button3Released()
|
|||||||
|
|
||||||
lastObject = -1;
|
lastObject = -1;
|
||||||
sourceIcon.state = Geometry::ACTIVE;
|
sourceIcon.state = Geometry::ACTIVE;
|
||||||
|
draggedSide = DraggedSide::NONE;
|
||||||
updateGeometry();
|
updateGeometry();
|
||||||
EditSubscriber::action = EditSubscriber::Action::NONE;
|
EditSubscriber::action = EditSubscriber::Action::NONE;
|
||||||
return true;
|
return true;
|
||||||
|
@ -57,6 +57,13 @@ class Spot : public ToolParamBlock, public FoldableToolPanel, public rtengine::T
|
|||||||
{
|
{
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
enum class DraggedSide {
|
||||||
|
NONE,
|
||||||
|
SOURCE,
|
||||||
|
TARGET
|
||||||
|
};
|
||||||
|
|
||||||
|
DraggedSide draggedSide; // tells which of source or target is being dragged
|
||||||
int lastObject; // current object that is hovered
|
int lastObject; // current object that is hovered
|
||||||
int activeSpot; // currently active spot, being edited
|
int activeSpot; // currently active spot, being edited
|
||||||
std::vector<rtengine::procparams::SpotEntry> spots; // list of edited spots
|
std::vector<rtengine::procparams::SpotEntry> spots; // list of edited spots
|
||||||
@ -103,7 +110,7 @@ public:
|
|||||||
void setBatchMode (bool batchMode) override;
|
void setBatchMode (bool batchMode) override;
|
||||||
|
|
||||||
// EditSubscriber interface
|
// EditSubscriber interface
|
||||||
CursorShape getCursor (int objectID) const override;
|
CursorShape getCursor (int objectID, int xPos, int yPos) const override;
|
||||||
bool mouseOver (int modifierKey) override;
|
bool mouseOver (int modifierKey) override;
|
||||||
bool button1Pressed (int modifierKey) override;
|
bool button1Pressed (int modifierKey) override;
|
||||||
bool button1Released () override;
|
bool button1Released () override;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user