Merge branch 'master' into gtk3

This commit is contained in:
Hombre 2015-08-20 23:46:29 +02:00
commit 5a9531b353
15 changed files with 618 additions and 228 deletions

View File

@ -11,7 +11,7 @@ set (RTENGINESOURCEFILES safegtk.cc colortemp.cc curves.cc flatcurves.cc diagona
dfmanager.cc ffmanager.cc rawimage.cc image8.cc image16.cc imagefloat.cc imagedata.cc imageio.cc improcfun.cc init.cc dcrop.cc dfmanager.cc ffmanager.cc rawimage.cc image8.cc image16.cc imagefloat.cc imagedata.cc imageio.cc improcfun.cc init.cc dcrop.cc
loadinitial.cc procparams.cc rawimagesource.cc demosaic_algos.cc shmap.cc simpleprocess.cc refreshmap.cc loadinitial.cc procparams.cc rawimagesource.cc demosaic_algos.cc shmap.cc simpleprocess.cc refreshmap.cc
fast_demo.cc amaze_demosaic_RT.cc CA_correct_RT.cc cfa_linedn_RT.cc green_equil_RT.cc hilite_recon.cc expo_before_b.cc fast_demo.cc amaze_demosaic_RT.cc CA_correct_RT.cc cfa_linedn_RT.cc green_equil_RT.cc hilite_recon.cc expo_before_b.cc
stdimagesource.cc myfile.cc iccjpeg.cc hlmultipliers.cc improccoordinator.cc editbuffer.cc stdimagesource.cc myfile.cc iccjpeg.cc hlmultipliers.cc improccoordinator.cc editbuffer.cc coord.cc
processingjob.cc rtthumbnail.cc utils.cc labimage.cc slicer.cc cieimage.cc processingjob.cc rtthumbnail.cc utils.cc labimage.cc slicer.cc cieimage.cc
iplab2rgb.cc ipsharpen.cc iptransform.cc ipresize.cc ipvibrance.cc iplab2rgb.cc ipsharpen.cc iptransform.cc ipresize.cc ipvibrance.cc
imagedimensions.cc jpeg_memsrc.cc jdatasrc.cc iimage.cc imagedimensions.cc jpeg_memsrc.cc jdatasrc.cc iimage.cc

39
rtengine/coord.cc Normal file
View File

@ -0,0 +1,39 @@
/*
* This file is part of RawTherapee.
*
* Copyright (c) 2004-2010 Gabor Horvath <hgabor@rawtherapee.com>
*
* RawTherapee is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* RawTherapee is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/
#include "coord.h"
namespace rtengine
{
void Coord::setFromPolar(PolarCoord polar)
{
while (polar.angle < 0.f) {
polar.angle += 360.f;
}
while (polar.angle > 360.f) {
polar.angle -= 360.f;
}
x = polar.radius * cos(polar.angle / 180.f * M_PI);
y = polar.radius * sin(polar.angle / 180.f * M_PI);
}
}

View File

@ -16,12 +16,17 @@
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with RawTherapee. If not, see <http://www.gnu.org/licenses/>. * along with RawTherapee. If not, see <http://www.gnu.org/licenses/>.
*/ */
#ifndef _COORD_H_ #ifndef __COORD__
#define _COORD_H_ #define __COORD__
#include "rt_math.h"
namespace rtengine
{
class PolarCoord; class PolarCoord;
// Do not confuse with rtengine::Coord2D, Coord is for the GUI // Do not confuse with rtengine::Coord2D, this one is for the GUI
class Coord class Coord
{ {
public: public:
@ -51,6 +56,16 @@ public:
return retval; return retval;
} }
bool operator== (const Coord& other) const
{
return other.x == x && other.y == y;
}
bool operator!= (const Coord& other) const
{
return other.x != x || other.y != y;
}
void operator+=(const Coord & rhs) void operator+=(const Coord & rhs)
{ {
x += rhs.x; x += rhs.x;
@ -91,6 +106,14 @@ public:
PolarCoord() : radius(1.), angle(0.) {} PolarCoord() : radius(1.), angle(0.) {}
PolarCoord(double radius, double angle) : radius(radius), angle(angle) {} PolarCoord(double radius, double angle) : radius(radius), angle(angle) {}
PolarCoord(Coord start, Coord end) : radius(1.), angle(0.)
{
setFromCartesian(start, end);
}
PolarCoord(Coord delta) : radius(1.), angle(0.)
{
setFromCartesian(delta);
}
void set (double radius, double angle) void set (double radius, double angle)
{ {
@ -134,6 +157,16 @@ public:
} }
} }
bool operator== (const PolarCoord& other) const
{
return other.radius == radius && other.angle == angle;
}
bool operator!= (const PolarCoord& other) const
{
return other.radius != radius || other.angle != angle;
}
void operator+=(const PolarCoord & rhs) void operator+=(const PolarCoord & rhs)
{ {
Coord thisCoord, rhsCoord; Coord thisCoord, rhsCoord;
@ -182,4 +215,7 @@ public:
}; };
}
#endif #endif

View File

@ -22,6 +22,7 @@
#include "../rtgui/edit.h" #include "../rtgui/edit.h"
#include "array2D.h" #include "array2D.h"
#include "iimage.h" #include "iimage.h"
#include "coord.h"
namespace rtengine namespace rtengine
{ {

View File

@ -24,6 +24,7 @@
#include <cstdio> #include <cstdio>
#include <cmath> #include <cmath>
#include "LUT.h" #include "LUT.h"
#include "coord.h"
class ParamsEdited; class ParamsEdited;
@ -1221,7 +1222,7 @@ public:
ResizeParams resize; ///< Resize parameters ResizeParams resize; ///< Resize parameters
ColorManagementParams icm; ///< profiles/color spaces used during the image processing ColorManagementParams icm; ///< profiles/color spaces used during the image processing
RAWParams raw; ///< RAW parameters before demosaicing RAWParams raw; ///< RAW parameters before demosaicing
WaveletParams wavelet; ///< wavelet wavelet parameters WaveletParams wavelet; ///< Wavelet parameters
DirPyrEqualizerParams dirpyrequalizer; ///< directional pyramid wavelet parameters DirPyrEqualizerParams dirpyrequalizer; ///< directional pyramid wavelet parameters
HSVEqualizerParams hsvequalizer; ///< hsv wavelet parameters HSVEqualizerParams hsvequalizer; ///< hsv wavelet parameters
FilmSimulationParams filmSimulation; ///< film simulation parameters FilmSimulationParams filmSimulation; ///< film simulation parameters

View File

@ -267,6 +267,8 @@ void CropWindow::flawnOver (bool isFlawnOver)
void CropWindow::buttonPress (int button, int type, int bstate, int x, int y) void CropWindow::buttonPress (int button, int type, int bstate, int x, int y)
{ {
bool needRedraw = true; // most common case ; not redrawing are exceptions
iarea->grabFocus (this); iarea->grabFocus (this);
if (button == 1 && type == GDK_2BUTTON_PRESS && onArea (CropImage, x, y) && (state == SNormal || state == SCropImgMove)) { if (button == 1 && type == GDK_2BUTTON_PRESS && onArea (CropImage, x, y) && (state == SNormal || state == SCropImgMove)) {
@ -355,33 +357,55 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y)
} else if (iarea->getToolMode () == TMHand) { } else if (iarea->getToolMode () == TMHand) {
EditSubscriber *editSubscriber = iarea->getCurrSubscriber(); EditSubscriber *editSubscriber = iarea->getCurrSubscriber();
if (button == 1 && editSubscriber && cropgl && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) && (editSubscriber->getEditingType() == ET_OBJECTS && iarea->object > -1) ) { if (editSubscriber && cropgl && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) && (editSubscriber->getEditingType() == ET_OBJECTS)) {
editSubscriber->button1Pressed(bstate); if (button == 1) {
state = SEditDrag; needRedraw = editSubscriber->button1Pressed(bstate);
press_x = x;
press_y = y; if (editSubscriber->isDragging()) {
action_x = 0; state = SEditDrag1;
action_y = 0; }
} else if (onArea (CropObserved, x, y)) { } else if (button == 2) {
state = SObservedMove; needRedraw = editSubscriber->button2Pressed(bstate);
press_x = x;
press_y = y; if (editSubscriber->isDragging()) {
action_x = 0; state = SEditDrag2;
action_y = 0; }
} else if (button == 1 && editSubscriber && cropgl && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) && (editSubscriber->getEditingType() == ET_PIPETTE && (bstate & GDK_CONTROL_MASK)) ) { } else if (button == 3) {
editSubscriber->button1Pressed(bstate); needRedraw = editSubscriber->button3Pressed(bstate);
state = SEditDrag;
press_x = x; if (editSubscriber->isDragging()) {
press_y = y; state = SEditDrag3;
action_x = 0; }
action_y = 0; }
} else if(zoomSteps[cropZoom].zoom > cropHandler.getFitZoom()) { // only allow move when image is only partial visible
state = SCropImgMove;
press_x = x; press_x = x;
press_y = y; press_y = y;
action_x = 0; action_x = 0;
action_y = 0; action_y = 0;
} }
if (state != SEditDrag1 && state != SEditDrag2 && state != SEditDrag3) {
if (onArea (CropObserved, x, y)) {
state = SObservedMove;
press_x = x;
press_y = y;
action_x = 0;
action_y = 0;
} else if (button == 1 && editSubscriber && cropgl && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) && (editSubscriber->getEditingType() == ET_PIPETTE && (bstate & GDK_CONTROL_MASK)) ) {
editSubscriber->button1Pressed(bstate);
state = SEditDrag1;
press_x = x;
press_y = y;
action_x = 0;
action_y = 0;
} else if(zoomSteps[cropZoom].zoom > cropHandler.getFitZoom()) { // only allow move when image is only partial visible
state = SCropImgMove;
press_x = x;
press_y = y;
action_x = 0;
action_y = 0;
}
}
} else if (onArea (CropObserved, x, y)) { } else if (onArea (CropObserved, x, y)) {
state = SObservedMove; state = SObservedMove;
press_x = x; press_x = x;
@ -424,7 +448,10 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y)
} }
} }
iarea->redraw (); if (needRedraw) {
iarea->redraw ();
}
updateCursor (x, y); updateCursor (x, y);
} }
@ -472,8 +499,14 @@ void CropWindow::buttonRelease (int button, int num, int bstate, int x, int y)
observedCropWin->remoteMoveReady (); observedCropWin->remoteMoveReady ();
state = SNormal; state = SNormal;
needRedraw = true; needRedraw = true;
} else if (state == SEditDrag) { } else if (state == SEditDrag1 || state == SEditDrag2 || state == SEditDrag3) {
editSubscriber->button1Released(); if (state == SEditDrag1) {
needRedraw = editSubscriber->button1Released();
} else if (state == SEditDrag2) {
needRedraw = editSubscriber->button2Released();
} else if (state == SEditDrag3) {
needRedraw = editSubscriber->button3Released();
}
if (editSubscriber) { if (editSubscriber) {
rtengine::Crop* crop = static_cast<rtengine::Crop*>(cropHandler.getCrop()); rtengine::Crop* crop = static_cast<rtengine::Crop*>(cropHandler.getCrop());
@ -488,7 +521,7 @@ void CropWindow::buttonRelease (int button, int num, int bstate, int x, int y)
Coord cropPos; Coord cropPos;
screenCoordToCropBuffer(x, y, cropPos.x, cropPos.y); screenCoordToCropBuffer(x, y, cropPos.x, cropPos.y);
if (editSubscriber->getEditingType() == ET_PIPETTE) { if (state == SEditDrag1 && editSubscriber->getEditingType() == ET_PIPETTE) {
iarea->object = onArea (CropImage, x, y) && !onArea (CropObserved, x, y) ? 1 : 0; iarea->object = onArea (CropImage, x, y) && !onArea (CropObserved, x, y) ? 1 : 0;
//iarea->object = cropgl && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) ? 1 : 0; //iarea->object = cropgl && cropgl->inImageArea(iarea->posImage.x, iarea->posImage.y) ? 1 : 0;
@ -506,9 +539,7 @@ void CropWindow::buttonRelease (int button, int num, int bstate, int x, int y)
} }
} }
if (editSubscriber->mouseOver(bstate)) { needRedraw |= editSubscriber->mouseOver(bstate);
iarea->redraw ();
}
} else { } else {
iarea->object = 0; iarea->object = 0;
} }
@ -518,7 +549,6 @@ void CropWindow::buttonRelease (int button, int num, int bstate, int x, int y)
iarea->deltaPrevImage.set(0, 0); iarea->deltaPrevImage.set(0, 0);
iarea->deltaPrevScreen.set(0, 0); iarea->deltaPrevScreen.set(0, 0);
state = SNormal; state = SNormal;
needRedraw = true;
} }
if (cropgl && (state == SCropSelecting || state == SResizeH1 || state == SResizeH2 || state == SResizeW1 || state == SResizeW2 || state == SResizeTL || state == SResizeTR || state == SResizeBL || state == SResizeBR || state == SCropMove)) { if (cropgl && (state == SCropSelecting || state == SResizeH1 || state == SResizeH2 || state == SResizeW1 || state == SResizeW2 || state == SResizeTL || state == SResizeTR || state == SResizeBL || state == SResizeBR || state == SCropMove)) {
@ -703,7 +733,7 @@ void CropWindow::pointerMoved (int bstate, int x, int y)
if (editSubscriber->mouseOver(bstate)) { if (editSubscriber->mouseOver(bstate)) {
iarea->redraw (); iarea->redraw ();
} }
} else if (state == SEditDrag) { } else if (state == SEditDrag1 || state == SEditDrag2 || state == SEditDrag3) {
Coord currPos; Coord currPos;
action_x = x; action_x = x;
action_y = y; action_y = y;
@ -721,8 +751,18 @@ void CropWindow::pointerMoved (int bstate, int x, int y)
iarea->deltaPrevScreen = currPos - oldPosScreen; iarea->deltaPrevScreen = currPos - oldPosScreen;
//printf(" action_ & xy (%d x %d) -> (%d x %d) = (%d x %d) + (%d x %d) / deltaPrev(%d x %d)\n", action_x, action_y, currPos.x, currPos.y, iarea->posScreen.x, iarea->posScreen.y, iarea->deltaScreen.x, iarea->deltaScreen.y, iarea->deltaPrevScreen.x, iarea->deltaPrevScreen.y); //printf(" action_ & xy (%d x %d) -> (%d x %d) = (%d x %d) + (%d x %d) / deltaPrev(%d x %d)\n", action_x, action_y, currPos.x, currPos.y, iarea->posScreen.x, iarea->posScreen.y, iarea->deltaScreen.x, iarea->deltaScreen.y, iarea->deltaPrevScreen.x, iarea->deltaPrevScreen.y);
if (editSubscriber->drag(bstate)) { if (state == SEditDrag1) {
iarea->redraw (); if (editSubscriber->drag1(bstate)) {
iarea->redraw ();
}
} else if (state == SEditDrag2) {
if (editSubscriber->drag2(bstate)) {
iarea->redraw ();
}
} else if (state == SEditDrag3) {
if (editSubscriber->drag3(bstate)) {
iarea->redraw ();
}
} }
} }
} }
@ -1485,7 +1525,6 @@ void CropWindow::expose (Cairo::RefPtr<Cairo::Context> cr)
if (editSubscriber && crop->bufferCreated()) { if (editSubscriber && crop->bufferCreated()) {
// clip the region
if (this != iarea->mainCropWindow) { if (this != iarea->mainCropWindow) {
cr->set_line_width (0.); cr->set_line_width (0.);
cr->rectangle (x + imgX, y + imgY, imgW, imgH); cr->rectangle (x + imgX, y + imgY, imgW, imgH);

View File

@ -422,7 +422,7 @@ bool CurveEditor::button1Released()
return true; return true;
} }
bool CurveEditor::drag(int modifierKey) bool CurveEditor::drag1(int modifierKey)
{ {
EditDataProvider* provider = getEditProvider(); EditDataProvider* provider = getEditProvider();
subGroup->pipetteDrag(provider, modifierKey); subGroup->pipetteDrag(provider, modifierKey);

View File

@ -35,9 +35,8 @@ class CurveEditorSubGroup;
*/ */
/* /** @brief This class is an interface between RT and the curve editor group
* This class is an interface between RT and the curve editor group ; it handles the methods * It handles the methods related to a specific curve. It is created by CurveEditorGroup::addCurve
* related to a specific curve. It is created by CurveEditorGroup::addCurve
*/ */
class CurveEditor : public EditSubscriber class CurveEditor : public EditSubscriber
{ {
@ -131,7 +130,7 @@ public:
bool mouseOver(int modifierKey); bool mouseOver(int modifierKey);
bool button1Pressed(int modifierKey); bool button1Pressed(int modifierKey);
bool button1Released(); bool button1Released();
bool drag(int modifierKey); bool drag1(int modifierKey);
CursorShape getCursor(int objectID); CursorShape getCursor(int objectID);

View File

@ -19,32 +19,21 @@
#include "edit.h" #include "edit.h"
#include "../rtengine/editbuffer.h" #include "../rtengine/editbuffer.h"
#include "rtimage.h"
void Coord::setFromPolar(PolarCoord polar)
{
while (polar.angle < 0.f) {
polar.angle += 360.f;
}
while (polar.angle > 360.f) {
polar.angle -= 360.f;
}
x = polar.radius * cos(polar.angle / 180.f * M_PI);
y = polar.radius * sin(polar.angle / 180.f * M_PI);
}
RGBColor Geometry::getInnerLineColor () RGBColor Geometry::getInnerLineColor ()
{ {
RGBColor color; RGBColor color;
if (flags & AUTO_COLOR) { if (flags & F_AUTO_COLOR) {
if (state == NORMAL) { if (state == NORMAL) {
color.setColor (1., 1., 1.); // White color.setColor (1., 1., 1.); // White
} else if (state == ACTIVE) {
color.setColor (1., 1., 0.); // Yellow
} else if (state == PRELIGHT) { } else if (state == PRELIGHT) {
color.setColor (1., 1., 0.); // Orange color.setColor (1., 100. / 255., 0.); // Orange
} else if (state == DRAGGED) { } else if (state == DRAGGED) {
color.setColor (1., 0., 0.); // Red color.setColor (1., 0., 0.); // Red
} }
} else { } else {
color = innerLineColor; color = innerLineColor;
@ -57,7 +46,7 @@ RGBColor Geometry::getOuterLineColor ()
{ {
RGBColor color; RGBColor color;
if (flags & AUTO_COLOR) { if (flags & F_AUTO_COLOR) {
/* /*
if (state == NORMAL) { color.setColor (0., 0., 0.); } // Black if (state == NORMAL) { color.setColor (0., 0., 0.); } // Black
else if (state == PRELIGHT) { color.setColor (0., 0., 0.); } // Black else if (state == PRELIGHT) { color.setColor (0., 0., 0.); } // Black
@ -73,10 +62,10 @@ RGBColor Geometry::getOuterLineColor ()
void Circle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) void Circle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
{ {
if (flags & ACTIVE) { if ((flags & F_VISIBLE) && state != INSENSITIVE) {
RGBColor color; RGBColor color;
if (flags & AUTO_COLOR) { if (flags & F_AUTO_COLOR) {
color = getOuterLineColor(); color = getOuterLineColor();
} else { } else {
color = outerLineColor; color = outerLineColor;
@ -85,7 +74,7 @@ void Circle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Edit
cr->set_source_rgb (color.getR(), color.getG(), color.getB()); cr->set_source_rgb (color.getR(), color.getG(), color.getB());
cr->set_line_width( getOuterLineWidth() ); cr->set_line_width( getOuterLineWidth() );
Coord center_ = center; rtengine::Coord center_ = center;
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToScreen(double(radius)) : double(radius); double radius_ = radiusInImageSpace ? coordSystem.scaleValueToScreen(double(radius)) : double(radius);
if (datum == IMAGE) { if (datum == IMAGE) {
@ -93,7 +82,7 @@ void Circle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Edit
} else if (datum == CLICKED_POINT) { } else if (datum == CLICKED_POINT) {
center_ += editBuffer->getDataProvider()->posScreen; center_ += editBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) { } else if (datum == CURSOR) {
center_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; center_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
} }
cr->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0., 2.*M_PI); cr->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0., 2.*M_PI);
@ -103,19 +92,22 @@ void Circle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Edit
void Circle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) void Circle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
{ {
if (flags & ACTIVE) { if (flags & F_VISIBLE) {
RGBColor color; if (state != INSENSITIVE) {
RGBColor color;
if (flags & AUTO_COLOR) { if (flags & F_AUTO_COLOR) {
color = getInnerLineColor(); color = getInnerLineColor();
} else { } else {
color = innerLineColor; color = innerLineColor;
}
cr->set_source_rgb(color.getR(), color.getG(), color.getB());
} }
cr->set_source_rgb (color.getR(), color.getG(), color.getB());
cr->set_line_width( innerLineWidth ); cr->set_line_width( innerLineWidth );
Coord center_ = center; rtengine::Coord center_ = center;
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToScreen(double(radius)) : double(radius); double radius_ = radiusInImageSpace ? coordSystem.scaleValueToScreen(double(radius)) : double(radius);
if (datum == IMAGE) { if (datum == IMAGE) {
@ -123,10 +115,10 @@ void Circle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Edit
} else if (datum == CLICKED_POINT) { } else if (datum == CLICKED_POINT) {
center_ += editBuffer->getDataProvider()->posScreen; center_ += editBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) { } else if (datum == CURSOR) {
center_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; center_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
} }
if (filled) { if (filled && state != INSENSITIVE) {
cr->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0., 2.*M_PI); cr->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0., 2.*M_PI);
if (innerLineWidth > 0.) { if (innerLineWidth > 0.) {
@ -137,16 +129,29 @@ void Circle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Edit
} }
} else if (innerLineWidth > 0.) { } else if (innerLineWidth > 0.) {
cr->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0., 2.*M_PI); cr->arc(center_.x + 0.5, center_.y + 0.5, radius_, 0., 2.*M_PI);
cr->stroke();
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();
}
} }
} }
} }
void Circle::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) void Circle::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
{ {
if (flags & ACTIVE) { if (flags & F_HOVERABLE) {
cr->set_line_width( getMouseOverLineWidth() ); cr->set_line_width( getMouseOverLineWidth() );
Coord center_ = center; rtengine::Coord center_ = center;
double radius_ = radiusInImageSpace ? coordSystem.scaleValueToScreen(double(radius)) : double(radius); double radius_ = radiusInImageSpace ? coordSystem.scaleValueToScreen(double(radius)) : double(radius);
if (datum == IMAGE) { if (datum == IMAGE) {
@ -154,7 +159,7 @@ void Circle::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<C
} else if (datum == CLICKED_POINT) { } else if (datum == CLICKED_POINT) {
center_ += editBuffer->getDataProvider()->posScreen; center_ += editBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) { } else if (datum == CURSOR) {
center_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; center_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
} }
// drawing the lower byte's value // drawing the lower byte's value
@ -195,10 +200,10 @@ void Circle::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<C
void Line::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) void Line::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
{ {
if (flags & ACTIVE) { if ((flags & F_VISIBLE) && state != INSENSITIVE) {
RGBColor color; RGBColor color;
if (flags & AUTO_COLOR) { if (flags & F_AUTO_COLOR) {
color = getOuterLineColor(); color = getOuterLineColor();
} else { } else {
color = outerLineColor; color = outerLineColor;
@ -207,8 +212,8 @@ void Line::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBu
cr->set_source_rgb (color.getR(), color.getG(), color.getB()); cr->set_source_rgb (color.getR(), color.getG(), color.getB());
cr->set_line_width( getOuterLineWidth() ); cr->set_line_width( getOuterLineWidth() );
Coord begin_ = begin; rtengine::Coord begin_ = begin;
Coord end_ = end; rtengine::Coord end_ = end;
if (datum == IMAGE) { if (datum == IMAGE) {
coordSystem.imageCoordToScreen(begin.x, begin.y, begin_.x, begin_.y); coordSystem.imageCoordToScreen(begin.x, begin.y, begin_.x, begin_.y);
@ -217,8 +222,8 @@ void Line::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBu
begin_ += editBuffer->getDataProvider()->posScreen; begin_ += editBuffer->getDataProvider()->posScreen;
end_ += editBuffer->getDataProvider()->posScreen; end_ += editBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) { } else if (datum == CURSOR) {
begin_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; begin_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
end_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; end_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
} }
cr->move_to(begin_.x + 0.5, begin_.y + 0.5); cr->move_to(begin_.x + 0.5, begin_.y + 0.5);
@ -229,20 +234,23 @@ void Line::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBu
void Line::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) void Line::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
{ {
if ((flags & ACTIVE) && innerLineWidth > 0.) { if ((flags & F_VISIBLE) && innerLineWidth > 0.) {
RGBColor color; if (state != INSENSITIVE) {
RGBColor color;
if (flags & AUTO_COLOR) { if (flags & F_AUTO_COLOR) {
color = getInnerLineColor(); color = getInnerLineColor();
} else { } else {
color = innerLineColor; color = innerLineColor;
}
cr->set_source_rgb (color.getR(), color.getG(), color.getB());
} }
cr->set_source_rgb (color.getR(), color.getG(), color.getB());
cr->set_line_width(innerLineWidth); cr->set_line_width(innerLineWidth);
Coord begin_ = begin; rtengine::Coord begin_ = begin;
Coord end_ = end; rtengine::Coord end_ = end;
if (datum == IMAGE) { if (datum == IMAGE) {
coordSystem.imageCoordToScreen(begin.x, begin.y, begin_.x, begin_.y); coordSystem.imageCoordToScreen(begin.x, begin.y, begin_.x, begin_.y);
@ -251,22 +259,37 @@ void Line::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBu
begin_ += editBuffer->getDataProvider()->posScreen; begin_ += editBuffer->getDataProvider()->posScreen;
end_ += editBuffer->getDataProvider()->posScreen; end_ += editBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) { } else if (datum == CURSOR) {
begin_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; begin_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
end_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; end_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
} }
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) {
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();
}
} }
} }
void Line::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) void Line::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr,
Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id,
rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
{ {
if (flags & ACTIVE) { if (flags & F_HOVERABLE) {
cr->set_line_width( getMouseOverLineWidth() ); cr->set_line_width( getMouseOverLineWidth() );
Coord begin_ = begin; rtengine::Coord begin_ = begin;
Coord end_ = end; rtengine::Coord end_ = end;
if (datum == IMAGE) { if (datum == IMAGE) {
coordSystem.imageCoordToCropBuffer(begin.x, begin.y, begin_.x, begin_.y); coordSystem.imageCoordToCropBuffer(begin.x, begin.y, begin_.x, begin_.y);
@ -275,8 +298,8 @@ void Line::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cai
begin_ += editBuffer->getDataProvider()->posScreen; begin_ += editBuffer->getDataProvider()->posScreen;
end_ += editBuffer->getDataProvider()->posScreen; end_ += editBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) { } else if (datum == CURSOR) {
begin_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; begin_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
end_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; end_ += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
} }
// drawing the lower byte's value // drawing the lower byte's value
@ -299,10 +322,10 @@ void Line::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cai
void Polyline::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) void Polyline::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
{ {
if ((flags & ACTIVE) && points.size() > 1) { if ((flags & F_VISIBLE) && state != INSENSITIVE && points.size() > 1) {
RGBColor color; RGBColor color;
if (flags & AUTO_COLOR) { if (flags & F_AUTO_COLOR) {
color = getOuterLineColor(); color = getOuterLineColor();
} else { } else {
color = outerLineColor; color = outerLineColor;
@ -311,7 +334,7 @@ void Polyline::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Ed
cr->set_source_rgb (color.getR(), color.getG(), color.getB()); cr->set_source_rgb (color.getR(), color.getG(), color.getB());
cr->set_line_width( getOuterLineWidth() ); cr->set_line_width( getOuterLineWidth() );
Coord currPos; rtengine::Coord currPos;
for (unsigned int i = 0; i < points.size(); ++i) { for (unsigned int i = 0; i < points.size(); ++i) {
currPos = points.at(i); currPos = points.at(i);
@ -321,7 +344,7 @@ void Polyline::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Ed
} else if (datum == CLICKED_POINT) { } else if (datum == CLICKED_POINT) {
currPos += editBuffer->getDataProvider()->posScreen; currPos += editBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) { } else if (datum == CURSOR) {
currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
} }
if (!i) { if (!i) {
@ -342,20 +365,23 @@ void Polyline::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Ed
void Polyline::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) void Polyline::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
{ {
if ((flags & ACTIVE) && points.size() > 1) { if ((flags & F_VISIBLE) && points.size() > 1) {
RGBColor color; if (state != INSENSITIVE) {
RGBColor color;
if (flags & AUTO_COLOR) { if (flags & F_AUTO_COLOR) {
color = getInnerLineColor(); color = getInnerLineColor();
} else { } else {
color = innerLineColor; color = innerLineColor;
}
cr->set_source_rgb (color.getR(), color.getG(), color.getB());
} }
cr->set_source_rgb (color.getR(), color.getG(), color.getB()); cr->set_line_width( innerLineWidth );
cr->set_line_width( getOuterLineWidth() );
if (filled) { if (filled && state != INSENSITIVE) {
Coord currPos; rtengine::Coord currPos;
for (unsigned int i = 0; i < points.size(); ++i) { for (unsigned int i = 0; i < points.size(); ++i) {
currPos = points.at(i); currPos = points.at(i);
@ -365,7 +391,7 @@ void Polyline::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Ed
} else if (datum == CLICKED_POINT) { } else if (datum == CLICKED_POINT) {
currPos += editBuffer->getDataProvider()->posScreen; currPos += editBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) { } else if (datum == CURSOR) {
currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
} }
if (!i) { if (!i) {
@ -382,17 +408,17 @@ void Polyline::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Ed
cr->fill(); cr->fill();
} }
} else if (innerLineWidth > 0.) { } else if (innerLineWidth > 0.) {
Coord currPos; rtengine::Coord currPos;
for (unsigned int i = 0; i < points.size(); ++i) { for (unsigned int i = 0; i < points.size(); ++i) {
currPos = points.at(i); currPos = points.at(i);
if (datum == IMAGE) { if (datum == IMAGE) {
coordSystem.imageCoordToScreen(points.at(i).x, points.at(i).y, currPos.x, currPos.y); coordSystem.imageCoordToScreen(points.at(i).x, points.at(i).y, currPos.x, currPos.y);
} else if (datum == CLICKED_POINT) { } else if (datum == CLICKED_POINT) {
currPos += editBuffer->getDataProvider()->posScreen; currPos += editBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) { } else if (datum == CURSOR) {
currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
} }
if (!i) { if (!i) {
@ -402,22 +428,34 @@ void Polyline::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::Ed
} }
} }
cr->stroke(); 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();
}
} }
} }
} }
void Polyline::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) void Polyline::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
{ {
if ((flags & ACTIVE) && points.size() > 1) { if ((flags & F_HOVERABLE) && points.size() > 1) {
Coord currPos; rtengine::Coord currPos;
// drawing the lower byte's value // drawing the lower byte's value
unsigned short a = (id + 1) & 0xFF; unsigned short a = (id + 1) & 0xFF;
cr->set_source_rgba (0., 0., 0., double(a) / 255.); cr->set_source_rgba (0., 0., 0., double(a) / 255.);
for (unsigned int i = 0; i < points.size(); ++i) { for (unsigned int i = 0; i < points.size(); ++i) {
cr->set_line_width( getOuterLineWidth() ); cr->set_line_width( getMouseOverLineWidth() );
currPos = points.at(i); currPos = points.at(i);
if (datum == IMAGE) { if (datum == IMAGE) {
@ -425,7 +463,7 @@ void Polyline::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr
} else if (datum == CLICKED_POINT) { } else if (datum == CLICKED_POINT) {
currPos += editBuffer->getDataProvider()->posScreen; currPos += editBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) { } else if (datum == CURSOR) {
currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
} }
if (!i) { if (!i) {
@ -452,7 +490,7 @@ void Polyline::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr
cr2->set_source_rgba (0., 0., 0., double(a) / 255.); cr2->set_source_rgba (0., 0., 0., double(a) / 255.);
for (unsigned int i = 0; i < points.size(); ++i) { for (unsigned int i = 0; i < points.size(); ++i) {
cr2->set_line_width( getOuterLineWidth() ); cr2->set_line_width( getMouseOverLineWidth() );
currPos = points.at(i); currPos = points.at(i);
if (datum == IMAGE) { if (datum == IMAGE) {
@ -460,7 +498,7 @@ void Polyline::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr
} else if (datum == CLICKED_POINT) { } else if (datum == CLICKED_POINT) {
currPos += editBuffer->getDataProvider()->posScreen; currPos += editBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) { } else if (datum == CURSOR) {
currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; currPos += editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
} }
if (!i) { if (!i) {
@ -496,24 +534,24 @@ void Rectangle::setXYXY(int left, int top, int right, int bottom)
bottomRight.set(right, bottom); bottomRight.set(right, bottom);
} }
void Rectangle::setXYWH(Coord topLeft, Coord widthHeight) void Rectangle::setXYWH(rtengine::Coord topLeft, rtengine::Coord widthHeight)
{ {
this->topLeft = topLeft; this->topLeft = topLeft;
this->bottomRight = topLeft + widthHeight; this->bottomRight = topLeft + widthHeight;
} }
void Rectangle::setXYXY(Coord topLeft, Coord bottomRight) void Rectangle::setXYXY(rtengine::Coord topLeft, rtengine::Coord bottomRight)
{ {
this->topLeft = topLeft; this->topLeft = topLeft;
this->bottomRight = bottomRight; this->bottomRight = bottomRight;
} }
void Rectangle::drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) void Rectangle::drawOuterGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
{ {
if ((flags & ACTIVE)) { if ((flags & F_VISIBLE) && state != INSENSITIVE) {
RGBColor color; RGBColor color;
if (flags & AUTO_COLOR) { if (flags & F_AUTO_COLOR) {
color = getOuterLineColor(); color = getOuterLineColor();
} else { } else {
color = outerLineColor; color = outerLineColor;
@ -522,14 +560,14 @@ void Rectangle::drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::
cr->set_source_rgb (color.getR(), color.getG(), color.getB()); cr->set_source_rgb (color.getR(), color.getG(), color.getB());
cr->set_line_width( getOuterLineWidth() ); cr->set_line_width( getOuterLineWidth() );
Coord tl, br; rtengine::Coord tl, br;
if (datum == IMAGE) { if (datum == IMAGE) {
coordSystem.imageCoordToScreen(topLeft.x, topLeft.y, tl.x, tl.y); coordSystem.imageCoordToScreen(topLeft.x, topLeft.y, tl.x, tl.y);
} else if (datum == CLICKED_POINT) { } else if (datum == CLICKED_POINT) {
tl = topLeft + editBuffer->getDataProvider()->posScreen; tl = topLeft + editBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) { } else if (datum == CURSOR) {
tl = topLeft + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; tl = topLeft + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
} }
if (datum == IMAGE) { if (datum == IMAGE) {
@ -537,7 +575,7 @@ void Rectangle::drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::
} else if (datum == CLICKED_POINT) { } else if (datum == CLICKED_POINT) {
br = bottomRight + editBuffer->getDataProvider()->posScreen; br = bottomRight + editBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) { } else if (datum == CURSOR) {
br = bottomRight + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; br = bottomRight + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
} }
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);
@ -551,28 +589,31 @@ void Rectangle::drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::
} }
} }
void Rectangle::drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) void Rectangle::drawInnerGeometry(Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
{ {
if (flags & ACTIVE) { if (flags & F_VISIBLE) {
RGBColor color; if (state != INSENSITIVE) {
RGBColor color;
if (flags & AUTO_COLOR) { if (flags & F_AUTO_COLOR) {
color = getInnerLineColor(); color = getInnerLineColor();
} else { } else {
color = innerLineColor; color = innerLineColor;
}
cr->set_source_rgb (color.getR(), color.getG(), color.getB());
} }
cr->set_source_rgb (color.getR(), color.getG(), color.getB());
cr->set_line_width( innerLineWidth ); cr->set_line_width( innerLineWidth );
Coord tl, br; rtengine::Coord tl, br;
if (datum == IMAGE) { if (datum == IMAGE) {
coordSystem.imageCoordToScreen(topLeft.x, topLeft.y, tl.x, tl.y); coordSystem.imageCoordToScreen(topLeft.x, topLeft.y, tl.x, tl.y);
} else if (datum == CLICKED_POINT) { } else if (datum == CLICKED_POINT) {
tl = topLeft + editBuffer->getDataProvider()->posScreen; tl = topLeft + editBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) { } else if (datum == CURSOR) {
tl = topLeft + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; tl = topLeft + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
} }
if (datum == IMAGE) { if (datum == IMAGE) {
@ -580,10 +621,10 @@ void Rectangle::drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::
} else if (datum == CLICKED_POINT) { } else if (datum == CLICKED_POINT) {
br = bottomRight + editBuffer->getDataProvider()->posScreen; br = bottomRight + editBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) { } else if (datum == CURSOR) {
br = bottomRight + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; br = bottomRight + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
} }
if (filled) { if (filled && state != INSENSITIVE) {
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.) {
@ -594,24 +635,37 @@ void Rectangle::drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::
} }
} 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);
cr->stroke();
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();
}
} }
} }
} }
void Rectangle::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem) void Rectangle::drawToMOChannel(Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem)
{ {
if (flags & ACTIVE) { if (flags & F_HOVERABLE) {
cr->set_line_width( getMouseOverLineWidth() ); cr->set_line_width( getMouseOverLineWidth() );
Coord tl, br; rtengine::Coord tl, br;
if (datum == IMAGE) { if (datum == IMAGE) {
coordSystem.imageCoordToCropBuffer(topLeft.x, topLeft.y, tl.x, tl.y); coordSystem.imageCoordToCropBuffer(topLeft.x, topLeft.y, tl.x, tl.y);
} else if (datum == CLICKED_POINT) { } else if (datum == CLICKED_POINT) {
tl = topLeft + editBuffer->getDataProvider()->posScreen; tl = topLeft + editBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) { } else if (datum == CURSOR) {
tl = topLeft + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; tl = topLeft + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
} }
if (datum == IMAGE) { if (datum == IMAGE) {
@ -619,7 +673,7 @@ void Rectangle::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPt
} else if (datum == CLICKED_POINT) { } else if (datum == CLICKED_POINT) {
br = bottomRight + editBuffer->getDataProvider()->posScreen; br = bottomRight + editBuffer->getDataProvider()->posScreen;
} else if (datum == CURSOR) { } else if (datum == CURSOR) {
br = bottomRight + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaPrevScreen; br = bottomRight + editBuffer->getDataProvider()->posScreen + editBuffer->getDataProvider()->deltaScreen;
} }
// drawing the lower byte's value // drawing the lower byte's value
@ -658,7 +712,7 @@ void Rectangle::drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPt
} }
} }
EditSubscriber::EditSubscriber (EditType editType) : ID(EUID_None), editingType(editType), bufferType(BT_SINGLEPLANE_FLOAT), provider(NULL) {} EditSubscriber::EditSubscriber (EditType editType) : ID(EUID_None), editingType(editType), bufferType(BT_SINGLEPLANE_FLOAT), provider(NULL), dragging(false) {}
void EditSubscriber::setEditProvider(EditDataProvider *provider) void EditSubscriber::setEditProvider(EditDataProvider *provider)
{ {
@ -717,6 +771,10 @@ BufferType EditSubscriber::getEditBufferType()
return bufferType; return bufferType;
} }
bool EditSubscriber::isDragging()
{
return dragging;
}
//-------------------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------------------

View File

@ -24,7 +24,9 @@
#include "editid.h" #include "editid.h"
#include "cursormanager.h" #include "cursormanager.h"
#include "../rtengine/rt_math.h" #include "../rtengine/rt_math.h"
#include "coord.h" #include "../rtengine/coord.h"
#include "guiutils.h"
#include "options.h"
class EditDataProvider; class EditDataProvider;
@ -39,30 +41,117 @@ class EditBuffer;
* Subscribers will be tools that need to create some graphics in the preview area, to let the user interact * Subscribers will be tools that need to create some graphics in the preview area, to let the user interact
* with it in a more user friendly way. * with it in a more user friendly way.
* *
* Do not confuse with a _local_ editing, which is another topic implemented in another class. The Edit feature * Subscribers will be tools that need to create some graphics in the preview area, to let the user interact
* with it in a more user friendly way.
*
* Do not confuse with _local_ editing, which is another topic implemented in another class. The Edit feature
* is also not supported in batch editing from the File Browser. * is also not supported in batch editing from the File Browser.
* *
* Each Edit tool must have a unique ID, that will identify them, and which let the ImProcCoordinator or other * Edit tool can be of 2 types: pipette editing and object editing.
* mechanism act as appropriated. They are all defined in rtgui/editid.h.
* *
* ## How does it works? * ## Pipette edition
* *
* When a tool is being constructed, unique IDs are affected to the EditSubscribers. Then the EditorPanel class * By using this class, a pipette mechanism can be handled on the preview.
* will ask all ToolPanel to register the 'after' preview ImageArea object as data provider. The Subscribers *
* have now to provide a toggle button to click on to start the Edit listening. When toggling on, the Subscriber * Each pipette Edit tool must have a unique ID, that will identify them, and which let the ImProcCoordinator
* or other mechanism act as appropriated. They are all defined in rtgui/editid.h. A buffer type has to be given
* too, to know which kind of buffer to allocate (see EditSubscriber::BufferType).
*
* Only the first mouse button can be used to manipulate the pipette on the Preview, that's why the developer has
* to implement at least the following 4 methods:
* - mouseOver
* - button1Pressed
* - drag1
* - button1Released
*
* Actually, only curves does use this class, and everything is handled for curve implementor (as much as possible).
* See the curve's class documentation to see how to implement the curve's pipette feature.
*
* ### Event handling
*
* The mouseOver method is called on each mouse movement, excepted when dragging a point. This method can then access
* the pipetteVal array values, which contain the mean of the pixel read in the buffer, or -1 of the cursor is outside
* of the image. In this case, EditDataProvider::object is also set to 0 (and 1 if over the image).
*
* When the user will click on the left mouse button while pressing the CTRL key, the button1Pressed will be called.
* Setting "dragging" to true (or false) is not required for the pipette type editing.
*
* The drag1 method will be called on all subsequent mouse move. The pipetteVal[3] array will already be filled with
* the mean of the read values under the cursor (actually a fixed square of 8px). If the BufferType is BT_SINGLEPLANE_FLOAT,
* only the first array value will be filled.
*
* Then the button1Released will be called to stop the dragging.
*
* ## Object edition
*
* By using this class, object can be drawn and manipulated on the preview.
*
* The developer has to handle the buttonPress, buttonRelease, drag and mouseOver method that he needs. There
* are buttonPress, buttonRelease and drag methods dedicated to each mouse button, for better flexibility
* (e.g.button2Press, button2Release, drag2 will handle event when mouse button 2 is used first). RT actually
* does not handle multiple mouse button event (e.g. button1 + button2), only one at a time. The first button pressed
* set the mechanism, all other combined button press are ignored.
*
* The developer also have to fill 2 display list with object of the Geometry subclass. Each geometrical shape
* _can_ be used in one or the other, or both list at a time.
*
* The first list (visibleGeometry) is used to be displayed on the preview. The developer will have to set their state
* manually (see Geometry::State), but the display shape, line width and color can be handled automatically, or with
* specific values. To be displayed, the F_VISIBLE flag has to be set through the setActive or setVisible methods.
*
* The second list (mouseOverGeometry) is used in a backbuffer, the color used to draw the shape being the id of the
* mouseOverGeometry. As an example, you could use a circle line to represent the line to the user, but use another
* Circle object, filled, to be used as mouseOver detection. The association between both shape (visible and mouseOver)
* is handled by the developer. To be displayed on this backbuffer, the F_HOVERABLE flag has to be set through the
* setActive or setHoverable methods.
*
*
* ### Event handling
*
* RT will draw in the back buffer all mouseOverGeometry set by the developer once the Edit button is pressed, and handle
* the events automatically.
*
* RT will call the mouseOver method on each mouse movement where no mouse button is pressed.
*
* On mouse button press over a mouseOverGeometry, it will call the button press method corresponding to the button
* (e.g. button1Pressed for mouse button 1), with the modifier key as parameter. Any other mouse button pressed at
* the same time will be ignored. It's up to the developer to decide whether it leads to a drag movement or not,
* by setting the "dragging" boolean to true.
*
* In this case, RT will then sent drag1 event (to stay with our button 1 pressed example) on each mouse movement. It's up
* to the developer of the tool to handle the dragging. The EditProvider class will help you in this by handling the actual
* position in various coordinate system and ways.
*
* When the user will release the mouse button, RT will call the button1Release event (in our example). The developer have
* then to set the "dragging" flag to false.
*
* Each of these methods have to returns a boolean value saying that the preview has to be refreshed or not (i.e. the displayed
* geometry).
*
* ## Other general internal implementation notes
*
* When a tool is being constructed, unique IDs are affected to the EditSubscribers of the Pipette type.
* Then the EditorPanel class will ask all ToolPanel to register the 'after' preview ImageArea object as data provider.
* The Subscribers have now to provide a toggle button to click on to start the Edit listening. When toggling on, the Subscriber
* register itself to the DataProvider, then an event is thrown through the standard ToolPanelListener::panelChanged * register itself to the DataProvider, then an event is thrown through the standard ToolPanelListener::panelChanged
* method to update the preview with new graphics to be displayed, and eventually buffers to create and populate. * method to update the preview with new graphics to be displayed. If a previous Edit button was active, it will be deactivated
* (the Edit buttons are mutually exclusive). For the Pipette type, a buffer will be created and has to be populated
* by the developer in rtengine's pipeline. The unique pipette ID will be used to know where to fill the buffer, as each pipette
* will need different data, corresponding to the state of the image right before the tool that needs pipette values. E.g for
* the HSV tool, the Hue and Saturation and Value curves are applied on the current state of the image. That's why the pipette
* of the H, S and V curve will share the same data of this "current state", otherwise the read value would be wrong.
* *
* When the Edit process stops, the Subscriber is removed from the DataProvider, so buffer can be freed up. * When the mouse button 1 is pressed while pressing the CTRL key, the button1Pressed method will be called.
*
* When the Edit process stops, the Subscriber is removed from the DataProvider, so buffers can be freed up.
* A new ToolPanelListener::panelChanged event is also thrown to update the preview again, without the tool's * A new ToolPanelListener::panelChanged event is also thrown to update the preview again, without the tool's
* graphical objects. The Edit button is also toggled off (by the user or programmatically). * graphical objects. The Edit button is also toggled off (by the user or programmatically).
* *
* It means that each Edit buttons toggled on will start an update of the preview which might or might not create * It means that each Edit buttons toggled on will start an update of the preview which might or might not create
* a new History entry, depending on the event. * a new History entry, depending on the ProcEvent used.
* *
*/ */
/** @brief Coordinate system where the widgets will be drawn /** @brief Coordinate system where the widgets will be drawn
* *
* The EditCoordSystem is used to define a screen and an image coordinate system. * The EditCoordSystem is used to define a screen and an image coordinate system.
@ -133,22 +222,69 @@ public:
} }
}; };
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.) {}
void setColor(double r, double g, double b, double a)
{
RGBColor::setColor(r, g, b);
this->a = 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;
}
};
/// @brief Displayable and MouseOver geometry base class
class Geometry class Geometry
{ {
public: public:
/// @brief Graphical state of the element
enum State { enum State {
NORMAL, NORMAL, /// Default state
PRELIGHT, ACTIVE, /// Focused state
DRAGGED PRELIGHT, /// Hovered state
DRAGGED, /// When being dragged
INSENSITIVE /// Displayed but insensitive
}; };
/// @brief Coordinate space and origin of the point
enum Datum { enum Datum {
IMAGE, IMAGE, /// Image coordinate system with image's top left corner as origin
CLICKED_POINT, CLICKED_POINT, /// Screen coordinate system with clicked point as origin
CURSOR CURSOR /// Screen coordinate system with actual cursor position as origin
}; };
enum Flags { enum Flags {
ACTIVE = 1 << 0, // true if the geometry is active and have to be drawn F_VISIBLE = 1 << 0, /// true if the geometry have to be drawn on the visible layer
AUTO_COLOR = 1 << 1, // true if the color depend on the state value, not the color field above 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
};
/// @brief Key point of the image's rectangle that is used to locate the icon copy to the target point:
enum DrivenPoint {
DP_CENTERCENTER,
DP_TOPLEFT,
DP_TOPCENTER,
DP_TOPRIGHT,
DP_CENTERRIGHT,
DP_BOTTOMRIGHT,
DP_BOTTOMCENTER,
DP_BOTTOMLEFT,
DP_CENTERLEFT
}; };
protected: protected:
@ -161,29 +297,29 @@ public:
Datum datum; Datum datum;
State state; // set by the Subscriber State state; // set by the Subscriber
Geometry () : innerLineColor(char(255), char(255), char(255)), outerLineColor(char(0), char(0), char(0)), flags(ACTIVE | AUTO_COLOR), innerLineWidth(1.f), datum(IMAGE), state(NORMAL) {} 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) {}
virtual ~Geometry() {} virtual ~Geometry() {}
void setInnerLineColor (double r, double g, double b) void setInnerLineColor (double r, double g, double b)
{ {
innerLineColor.setColor(r, g, b); innerLineColor.setColor(r, g, b);
flags &= ~AUTO_COLOR; flags &= ~F_AUTO_COLOR;
} }
void setInnerLineColor (char r, char g, char b) void setInnerLineColor (char r, char g, char b)
{ {
innerLineColor.setColor(r, g, b); innerLineColor.setColor(r, g, b);
flags &= ~AUTO_COLOR; flags &= ~F_AUTO_COLOR;
} }
RGBColor getInnerLineColor (); RGBColor getInnerLineColor ();
void setOuterLineColor (double r, double g, double b) void setOuterLineColor (double r, double g, double b)
{ {
outerLineColor.setColor(r, g, b); outerLineColor.setColor(r, g, b);
flags &= ~AUTO_COLOR; flags &= ~F_AUTO_COLOR;
} }
void setOuterLineColor (char r, char g, char b) void setOuterLineColor (char r, char g, char b)
{ {
outerLineColor.setColor(r, g, b); outerLineColor.setColor(r, g, b);
flags &= ~AUTO_COLOR; flags &= ~F_AUTO_COLOR;
} }
RGBColor getOuterLineColor (); RGBColor getOuterLineColor ();
double getOuterLineWidth () double getOuterLineWidth ()
@ -197,17 +333,43 @@ public:
void setAutoColor (bool aColor) void setAutoColor (bool aColor)
{ {
if (aColor) { if (aColor) {
flags |= AUTO_COLOR; flags |= F_AUTO_COLOR;
} else { } else {
flags &= ~AUTO_COLOR; 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;
}
}
// setActive will enable/disable the visible and hoverable flags in one shot!
void setActive (bool active) void setActive (bool active)
{ {
if (active) { if (active) {
flags |= ACTIVE; flags |= (F_VISIBLE | F_HOVERABLE);
} else { } else {
flags &= ~ACTIVE; flags &= ~(F_VISIBLE | F_HOVERABLE);
} }
} }
@ -219,13 +381,13 @@ public:
class Circle : public Geometry class Circle : public Geometry
{ {
public: public:
Coord center; rtengine::Coord center;
int radius; int radius;
bool filled; bool filled;
bool radiusInImageSpace; /// If true, the radius depend on the image scale; if false, it is a fixed 'screen' size 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 () : center(100, 100), radius(10), filled(false), radiusInImageSpace(false) {}
Circle (Coord &center, int radius, bool filled = false, bool radiusInImageSpace = false) : center(center), radius(radius), filled(filled), radiusInImageSpace(radiusInImageSpace) {} 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 (int centerX, int centerY, int radius, bool filled = false, bool radiusInImageSpace = false) : center(centerX, centerY), radius(radius), filled(filled), radiusInImageSpace(radiusInImageSpace) {}
void drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem); void drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem);
@ -236,11 +398,11 @@ public:
class Line : public Geometry class Line : public Geometry
{ {
public: public:
Coord begin; rtengine::Coord begin;
Coord end; rtengine::Coord end;
Line () : begin(10, 10), end(100, 100) {} Line () : begin(10, 10), end(100, 100) {}
Line (Coord &begin, Coord &end) : begin(begin), end(end) {} 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 (int beginX, int beginY, int endX, int endY) : begin(beginX, beginY), end(endX, endY) {}
void drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem); void drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem);
@ -251,7 +413,7 @@ public:
class Polyline : public Geometry class Polyline : public Geometry
{ {
public: public:
std::vector<Coord> points; std::vector<rtengine::Coord> points;
bool filled; bool filled;
Polyline() : filled(false) {} Polyline() : filled(false) {}
@ -264,16 +426,16 @@ public:
class Rectangle : public Geometry class Rectangle : public Geometry
{ {
public: public:
Coord topLeft; rtengine::Coord topLeft;
Coord bottomRight; rtengine::Coord bottomRight;
bool filled; bool filled;
Rectangle() : topLeft(0, 0), bottomRight(10, 10), filled(false) {} Rectangle() : topLeft(0, 0), bottomRight(10, 10), filled(false) {}
void setXYWH(int left, int top, int width, int height); void setXYWH(int left, int top, int width, int height);
void setXYXY(int left, int top, int right, int bottom); void setXYXY(int left, int top, int right, int bottom);
void setXYWH(Coord topLeft, Coord widthHeight); void setXYWH(rtengine::Coord topLeft, rtengine::Coord widthHeight);
void setXYXY(Coord topLeft, Coord bottomRight); void setXYXY(rtengine::Coord topLeft, rtengine::Coord bottomRight);
void drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem); void drawOuterGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem);
void drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem); void drawInnerGeometry (Cairo::RefPtr<Cairo::Context> &cr, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem);
void drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem); void drawToMOChannel (Cairo::RefPtr<Cairo::Context> &cr, Cairo::RefPtr<Cairo::Context> &cr2, unsigned short id, rtengine::EditBuffer *editBuffer, EditCoordSystem &coordSystem);
@ -292,8 +454,9 @@ private:
EditDataProvider *provider; EditDataProvider *provider;
protected: protected:
std::vector<Geometry*> visibleGeometry; std::vector<Geometry*> visibleGeometry; /// displayed geometry
std::vector<Geometry*> mouseOverGeometry; std::vector<Geometry*> mouseOverGeometry; /// mouseOver geometry, drawn in a hidden buffer
bool dragging; /// in object mode, set this to true in buttonPressed events to start dragging and ask for drag event (ignored in pipette mode)
public: public:
EditSubscriber (EditType editType); EditSubscriber (EditType editType);
@ -312,6 +475,7 @@ public:
EditUniqueID getEditID(); EditUniqueID getEditID();
EditType getEditingType(); EditType getEditingType();
BufferType getEditBufferType(); BufferType getEditBufferType();
bool isDragging(); /// Returns true if something is being dragged and drag events has to be sent (object mode only)
/** @brief Get the cursor to be displayed when above handles /** @brief Get the cursor to be displayed when above handles
@param objectID object currently "hovered" */ @param objectID object currently "hovered" */
@ -331,6 +495,7 @@ public:
} }
/** @brief Triggered when mouse button 1 is pressed, together with the CTRL modifier key if the subscriber is of type ET_PIPETTE /** @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 | ...) @param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...)
@return true if the preview has to be redrawn, false otherwise */ @return true if the preview has to be redrawn, false otherwise */
virtual bool button1Pressed(int modifierKey) virtual bool button1Pressed(int modifierKey)
@ -345,10 +510,58 @@ public:
return false; return false;
} }
/** @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;
}
/** @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;
}
/** @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;
}
/** @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;
}
/** @brief Triggered when the user is moving while holding down mouse button 1 /** @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 | ...) @param modifierKey Gtk's event modifier key (GDK_CONTROL_MASK | GDK_SHIFT_MASK | ...)
@return true if the preview has to be redrawn, false otherwise */ @return true if the preview has to be redrawn, false otherwise */
virtual bool drag(int modifierKey) virtual bool drag1(int modifierKey)
{
return false;
}
/** @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;
}
/** @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; return false;
} }
@ -381,12 +594,12 @@ public:
int object; /// ET_OBJECTS mode: Object detected under the cursor, 0 otherwise; ET_PIPETTE mode: 1 if above the image, 0 otherwise int object; /// ET_OBJECTS mode: Object detected under the cursor, 0 otherwise; ET_PIPETTE mode: 1 if above the image, 0 otherwise
float pipetteVal[3]; /// Current pipette values; if bufferType==BT_SINGLEPLANE_FLOAT, #2 & #3 will be set to 0 float pipetteVal[3]; /// Current pipette values; if bufferType==BT_SINGLEPLANE_FLOAT, #2 & #3 will be set to 0
Coord posScreen; /// Location of the mouse button press, in preview image space rtengine::Coord posScreen; /// Location of the mouse button press, in preview image space
Coord posImage; /// Location of the mouse button press, in the full image space rtengine::Coord posImage; /// Location of the mouse button press, in the full image space
Coord deltaScreen; /// Delta relative to posScreen rtengine::Coord deltaScreen; /// Delta relative to posScreen
Coord deltaImage; /// Delta relative to posImage rtengine::Coord deltaImage; /// Delta relative to posImage
Coord deltaPrevScreen; /// Delta relative to the previous mouse location, in preview image space rtengine::Coord deltaPrevScreen; /// Delta relative to the previous mouse location, in preview image space
Coord deltaPrevImage; /// Delta relative to the previous mouse location, in the full image space rtengine::Coord deltaPrevImage; /// Delta relative to the previous mouse location, in the full image space
EditDataProvider(); EditDataProvider();
virtual ~EditDataProvider() {} virtual ~EditDataProvider() {}

View File

@ -20,7 +20,7 @@
#define _EDITENUMS_ #define _EDITENUMS_
enum ImgEditState {SNormal, SCropMove, SHandMove, SResizeW1, SResizeW2, SResizeH1, SResizeH2, SResizeTL, SResizeTR, SResizeBL, SResizeBR, enum ImgEditState {SNormal, SCropMove, SHandMove, SResizeW1, SResizeW2, SResizeH1, SResizeH2, SResizeTL, SResizeTR, SResizeBL, SResizeBR,
SCropSelecting, SRotateSelecting, SCropWinMove, SCropFrameMove, SCropImgMove, SCropWinResize, SObservedMove, SEditDrag SCropSelecting, SRotateSelecting, SCropWinMove, SCropFrameMove, SCropImgMove, SCropWinResize, SObservedMove, SEditDrag1, SEditDrag2, SEditDrag3
}; };
enum CursorArea {CropWinButtons, CropToolBar, CropImage, CropBorder, CropTop, CropTopLeft, CropTopRight, CropBottom, CropBottomLeft, enum CursorArea {CropWinButtons, CropToolBar, CropImage, CropBorder, CropTop, CropTopLeft, CropTopRight, CropBottom, CropBottomLeft,
CropBottomRight, CropLeft, CropRight, CropInside, CropResize, CropObserved CropBottomRight, CropLeft, CropRight, CropInside, CropResize, CropObserved

View File

@ -146,7 +146,7 @@ void Gradient::updateGeometry(int centerX_, int centerY_, double feather_, doubl
dataProvider->getImageSize(imW, imH); dataProvider->getImageSize(imW, imH);
double decay = feather_ * sqrt(double(imW) * double(imW) + double(imH) * double(imH)) / 200.; double decay = feather_ * sqrt(double(imW) * double(imW) + double(imH) * double(imH)) / 200.;
Coord origin(imW / 2 + centerX_ * imW / 200.f, imH / 2 + centerY_ * imH / 200.f); rtengine::Coord origin(imW / 2 + centerX_ * imW / 200.f, imH / 2 + centerY_ * imH / 200.f);
Line *currLine; Line *currLine;
Circle *currCircle; Circle *currCircle;
@ -397,10 +397,11 @@ bool Gradient::mouseOver(int modifierKey)
bool Gradient::button1Pressed(int modifierKey) bool Gradient::button1Pressed(int modifierKey)
{ {
if (!(modifierKey & (GDK_CONTROL_MASK | GDK_CONTROL_MASK))) { EditDataProvider *provider = getEditProvider();
if (!(modifierKey & GDK_CONTROL_MASK)) {
// button press is valid (no modifier key) // button press is valid (no modifier key)
PolarCoord pCoord; PolarCoord pCoord;
EditDataProvider *provider = getEditProvider();
int imW, imH; int imW, imH;
provider->getImageSize(imW, imH); provider->getImageSize(imW, imH);
double halfSizeW = imW / 2.; double halfSizeW = imW / 2.;
@ -408,8 +409,8 @@ bool Gradient::button1Pressed(int modifierKey)
draggedCenter.set(int(halfSizeW + halfSizeW * (centerX->getValue() / 100.)), int(halfSizeH + halfSizeH * (centerY->getValue() / 100.))); draggedCenter.set(int(halfSizeW + halfSizeW * (centerX->getValue() / 100.)), int(halfSizeH + halfSizeH * (centerY->getValue() / 100.)));
// trick to get the correct angle (clockwise/counter-clockwise) // trick to get the correct angle (clockwise/counter-clockwise)
Coord p1 = draggedCenter; rtengine::Coord p1 = draggedCenter;
Coord p2 = provider->posImage; rtengine::Coord p2 = provider->posImage;
int p = p1.y; int p = p1.y;
p1.y = p2.y; p1.y = p2.y;
p2.y = p; p2.y = p;
@ -422,9 +423,9 @@ bool Gradient::button1Pressed(int modifierKey)
if (lastObject == 2 || lastObject == 3) { if (lastObject == 2 || lastObject == 3) {
// Dragging a line to change the angle // Dragging a line to change the angle
PolarCoord draggedPoint; PolarCoord draggedPoint;
Coord currPos; rtengine::Coord currPos;
currPos = provider->posImage; currPos = provider->posImage;
Coord centerPos = draggedCenter; rtengine::Coord centerPos = draggedCenter;
double diagonal = sqrt(double(imW) * double(imW) + double(imH) * double(imH)); double diagonal = sqrt(double(imW) * double(imW) + double(imH) * double(imH));
@ -444,6 +445,7 @@ bool Gradient::button1Pressed(int modifierKey)
draggedFeatherOffset -= (feather->getValue() / 200. * diagonal); draggedFeatherOffset -= (feather->getValue() / 200. * diagonal);
} }
EditSubscriber::dragging = true;
return false; return false;
} else { } else {
// this will let this class ignore further drag events // this will let this class ignore further drag events
@ -464,10 +466,11 @@ bool Gradient::button1Pressed(int modifierKey)
bool Gradient::button1Released() bool Gradient::button1Released()
{ {
draggedPointOldAngle = -1000.; draggedPointOldAngle = -1000.;
EditSubscriber::dragging = false;
return true; return true;
} }
bool Gradient::drag(int modifierKey) bool Gradient::drag1(int modifierKey)
{ {
// compute the polar coordinate of the mouse position // compute the polar coordinate of the mouse position
EditDataProvider *provider = getEditProvider(); EditDataProvider *provider = getEditProvider();
@ -480,9 +483,9 @@ bool Gradient::drag(int modifierKey)
// Dragging a line to change the angle // Dragging a line to change the angle
PolarCoord draggedPoint; PolarCoord draggedPoint;
Coord currPos; rtengine::Coord currPos;
currPos = provider->posImage + provider->deltaImage; currPos = provider->posImage + provider->deltaImage;
Coord centerPos = draggedCenter; rtengine::Coord centerPos = draggedCenter;
// trick to get the correct angle (clockwise/counter-clockwise) // trick to get the correct angle (clockwise/counter-clockwise)
int p = centerPos.y; int p = centerPos.y;
@ -523,9 +526,9 @@ bool Gradient::drag(int modifierKey)
} else if (lastObject == 2 || lastObject == 3) { } else if (lastObject == 2 || lastObject == 3) {
// Dragging the upper or lower feather bar // Dragging the upper or lower feather bar
PolarCoord draggedPoint; PolarCoord draggedPoint;
Coord currPos; rtengine::Coord currPos;
currPos = provider->posImage + provider->deltaImage; currPos = provider->posImage + provider->deltaImage;
Coord centerPos = draggedCenter; rtengine::Coord centerPos = draggedCenter;
double diagonal = sqrt(double(imW) * double(imW) + double(imH) * double(imH)); double diagonal = sqrt(double(imW) * double(imW) + double(imH) * double(imH));
@ -561,7 +564,7 @@ bool Gradient::drag(int modifierKey)
} }
} else if (lastObject == 4) { } else if (lastObject == 4) {
// Dragging the circle to change the center // Dragging the circle to change the center
Coord currPos; rtengine::Coord currPos;
draggedCenter += provider->deltaPrevImage; draggedCenter += provider->deltaPrevImage;
currPos = draggedCenter; currPos = draggedCenter;
currPos.clip(imW, imH); currPos.clip(imW, imH);

View File

@ -8,6 +8,7 @@
#include "adjuster.h" #include "adjuster.h"
#include "toolpanel.h" #include "toolpanel.h"
#include "edit.h" #include "edit.h"
#include "guiutils.h"
class Gradient : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public EditSubscriber class Gradient : public ToolParamBlock, public AdjusterListener, public FoldableToolPanel, public EditSubscriber
{ {
@ -26,7 +27,7 @@ protected:
double draggedPointOldAngle; double draggedPointOldAngle;
double draggedPointAdjusterAngle; double draggedPointAdjusterAngle;
double draggedFeatherOffset; double draggedFeatherOffset;
Coord draggedCenter; rtengine::Coord draggedCenter;
sigc::connection editConn; sigc::connection editConn;
void editToggled (); void editToggled ();
@ -55,7 +56,7 @@ public:
bool mouseOver(int modifierKey); bool mouseOver(int modifierKey);
bool button1Pressed(int modifierKey); bool button1Pressed(int modifierKey);
bool button1Released(); bool button1Released();
bool drag(int modifierKey); bool drag1(int modifierKey);
void switchOffEditMode (); void switchOffEditMode ();
}; };

View File

@ -115,10 +115,10 @@ bool Inspector::on_draw(const ::Cairo::RefPtr< Cairo::Context> &cr)
// this will eventually create/update the off-screen pixmap // this will eventually create/update the off-screen pixmap
// compute the displayed area // compute the displayed area
Coord availableSize; rtengine::Coord availableSize;
Coord topLeft; rtengine::Coord topLeft;
Coord displayedSize; rtengine::Coord displayedSize;
Coord dest(0, 0); rtengine::Coord dest(0, 0);
availableSize.x = win->get_width(); availableSize.x = win->get_width();
availableSize.y = win->get_height(); availableSize.y = win->get_height();
int imW = currImage->imgBuffer.getWidth(); int imW = currImage->imgBuffer.getWidth();

View File

@ -21,7 +21,7 @@
#include <gtkmm.h> #include <gtkmm.h>
#include "guiutils.h" #include "guiutils.h"
#include "coord.h" #include "../rtengine/coord.h"
class InspectorBuffer class InspectorBuffer
{ {
@ -42,7 +42,7 @@ class Inspector : public Gtk::DrawingArea
{ {
private: private:
Coord center; rtengine::Coord center;
std::vector<InspectorBuffer*> images; std::vector<InspectorBuffer*> images;
InspectorBuffer* currImage; InspectorBuffer* currImage;
double zoom; double zoom;