Solving most if not all bugs left

Still some features to add, but this commit should make this tool fully
usable.
This commit is contained in:
Hombre 2016-10-02 17:23:09 +02:00
parent 4506247985
commit aca00389d9
12 changed files with 444 additions and 306 deletions

View File

@ -361,6 +361,153 @@ void Color::cleanup ()
} }
} }
void Color::rgb2lab (Glib::ustring profile, Glib::ustring profileW, int r, int g, int b, float &LAB_l, float &LAB_a, float &LAB_b, bool workingSpace)
{
double xyz_rgb[3][3];
const double ep = 216.0 / 24389.0;
const double ka = 24389.0 / 27.0;
double var_R = r / 65535.0;
double var_G = g / 65535.0;
double var_B = b / 65535.0;
Glib::ustring profileCalc;
profileCalc = "sRGB"; //default
if (workingSpace) {
profileCalc = profileW; //display working
}
else {// if you want display = output space
if (profile == "RT_sRGB" || profile == "RT_sRGB_gBT709" || profile == "RT_sRGB_g10") {
profileCalc = "sRGB";
}
if (profile == "ProPhoto" || profile == "RT_Large_gBT709" || profile == "RT_Large_g10" || profile == "RT_Large_gsRGB") {
profileCalc = "ProPhoto";
}
if (profile == "AdobeRGB1998" || profile == "RT_Medium_gsRGB") {
profileCalc = "Adobe RGB";
}
if (profile == "WideGamutRGB") {
profileCalc = "WideGamut";
}
}
if (workingSpace) {//display working
if (profileW == "sRGB") { //apply sRGB inverse gamma
if ( var_R > 0.04045 ) {
var_R = pow ( ( ( var_R + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve);
} else {
var_R = var_R / 12.92;
}
if ( var_G > 0.04045 ) {
var_G = pow ( ( ( var_G + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve);
} else {
var_G = var_G / 12.92;
}
if ( var_B > 0.04045 ) {
var_B = pow ( ( ( var_B + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve);
} else {
var_B = var_B / 12.92;
}
} else if (profileW == "ProPhoto") { // apply inverse gamma 1.8
var_R = pow ( var_R, 1.8);
var_G = pow ( var_G, 1.8);
var_B = pow ( var_B, 1.8);
} else { // apply inverse gamma 2.2
var_R = pow ( var_R, 2.2);
var_G = pow ( var_G, 2.2);
var_B = pow ( var_B, 2.2);
}
} else { //display outout profile
if (profile == "RT_sRGB" || profile == "RT_Large_gsRGB" || profile == "RT_Medium_gsRGB") { //apply sRGB inverse gamma
if ( var_R > 0.04045 ) {
var_R = pow ( ( ( var_R + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve);
} else {
var_R = var_R / 12.92;
}
if ( var_G > 0.04045 ) {
var_G = pow ( ( ( var_G + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve);
} else {
var_G = var_G / 12.92;
}
if ( var_B > 0.04045 ) {
var_B = pow ( ( ( var_B + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve);
} else {
var_B = var_B / 12.92;
}
}
else if (profile == "RT_sRGB_gBT709" || profile == "RT_Large_gBT709") { //
if ( var_R > 0.0795 ) {
var_R = pow ( ( ( var_R + 0.0954 ) / 1.0954 ), 2.2);
} else {
var_R = var_R / 4.5;
}
if ( var_G > 0.0795 ) {
var_G = pow ( ( ( var_G + 0.0954 ) / 1.0954 ), 2.2);
} else {
var_G = var_G / 4.5;
}
if ( var_B > 0.0795 ) {
var_B = pow ( ( ( var_B + 0.0954 ) / 1.0954 ), 2.2);
} else {
var_B = var_B / 4.5;
}
} else if (profile == "ProPhoto") { // apply inverse gamma 1.8
var_R = pow ( var_R, 1.8);
var_G = pow ( var_G, 1.8);
var_B = pow ( var_B, 1.8);
} else if (profile == "RT_sRGB_g10" || profile == "RT_Large_g10") { // apply inverse gamma 1.8
var_R = pow ( var_R, 1.);
var_G = pow ( var_G, 1.);
var_B = pow ( var_B, 1.);
}
else {// apply inverse gamma 2.2
var_R = pow ( var_R, 2.2);
var_G = pow ( var_G, 2.2);
var_B = pow ( var_B, 2.2);
}
}
// TMatrix wprof = rtengine::ICCStore::getInstance()->workingSpaceMatrix (profileW);
TMatrix wprof = rtengine::ICCStore::getInstance()->workingSpaceMatrix (profileCalc);
for (int m = 0; m < 3; m++)
for (int n = 0; n < 3; n++) {
xyz_rgb[m][n] = wprof[m][n];
}
double varxx, varyy, varzz;
double var_X = ( xyz_rgb[0][0] * var_R + xyz_rgb[0][1] * var_G + xyz_rgb[0][2] * var_B ) / Color::D50x;
double var_Y = ( xyz_rgb[1][0] * var_R + xyz_rgb[1][1] * var_G + xyz_rgb[1][2] * var_B ) ;
double var_Z = ( xyz_rgb[2][0] * var_R + xyz_rgb[2][1] * var_G + xyz_rgb[2][2] * var_B ) / Color::D50z;
varxx = var_X > ep ? cbrt(var_X) : ( ka * var_X + 16.0) / 116.0 ;
varyy = var_Y > ep ? cbrt(var_Y) : ( ka * var_Y + 16.0) / 116.0 ;
varzz = var_Z > ep ? cbrt(var_Z) : ( ka * var_Z + 16.0) / 116.0 ;
LAB_l = ( 116 * varyy ) - 16;
LAB_a = 500 * ( varxx - varyy );
LAB_b = 200 * ( varyy - varzz );
}
void Color::rgb2hsl(float r, float g, float b, float &h, float &s, float &l) void Color::rgb2hsl(float r, float g, float b, float &h, float &s, float &l)
{ {

View File

@ -175,6 +175,22 @@ public:
} }
/**
* @brief Convert red/green/blue to L*a*b
* @brief Convert red/green/blue to hue/saturation/luminance
* @param profile output profile name
* @param profileW working profile name
* @param r red channel [0 ; 65535]
* @param g green channel [0 ; 65535]
* @param b blue channel [0 ; 65535]
* @param L Lab L channel [0 ; 1] (return value)
* @param a Lab a channel [0 ; 1] (return value)
* @param b Lab b channel [0; 1] (return value)
* @param workingSpace true: compute the Lab value using the Working color space ; false: use the Output color space
*/
static void rgb2lab (Glib::ustring profile, Glib::ustring profileW, int r, int g, int b, float &LAB_l, float &LAB_a, float &LAB_b, bool workingSpace);
/** /**
* @brief Convert red/green/blue to hue/saturation/luminance * @brief Convert red/green/blue to hue/saturation/luminance
* @param r red channel [0 ; 65535] * @param r red channel [0 ; 65535]

View File

@ -475,12 +475,12 @@ bool CropHandler::getEnabled ()
return enabled; return enabled;
} }
void CropHandler::colorPick (rtengine::Coord pickerPos, float &r, float &g, float &b, LockableColorPicker::PickerSize size) void CropHandler::colorPick (rtengine::Coord pickerPos, float &r, float &g, float &b, LockableColorPicker::Size size)
{ {
int xSize = (int)size; int xSize = (int)size;
int ySize = (int)size; int ySize = (int)size;
int pixbufW = cropPixbuf->get_width(); int pixbufW = cropPixbuftrue->get_width();
rtengine::Coord topLeftPos(pickerPos.x - xSize/2, pickerPos.y - ySize/2); rtengine::Coord topLeftPos(pickerPos.x - xSize/2, pickerPos.y - ySize/2);
if (topLeftPos.x > pixbufW || topLeftPos.y > pixbufW || topLeftPos.x + xSize < 0 || topLeftPos.y + ySize < 0) { if (topLeftPos.x > pixbufW || topLeftPos.y > pixbufW || topLeftPos.x + xSize < 0 || topLeftPos.y + ySize < 0) {
@ -510,9 +510,9 @@ void CropHandler::colorPick (rtengine::Coord pickerPos, float &r, float &g, floa
// Accumulating the data // Accumulating the data
std::uint32_t r2=0, g2=0, b2=0; std::uint32_t r2=0, g2=0, b2=0;
std::uint32_t count = 0; std::uint32_t count = 0;
const guint8* data = cropPixbuf->get_pixels(); const guint8* data = cropPixbuftrue->get_pixels();
for (int j = topLeftPos.y ; j < topLeftPos.y + ySize ; ++j) { for (int j = topLeftPos.y ; j < topLeftPos.y + ySize ; ++j) {
const guint8* data2 = data + cropPixbuf->get_rowstride()*j; const guint8* data2 = data + cropPixbuftrue->get_rowstride()*j;
for (int i = topLeftPos.x ; i < topLeftPos.x + xSize ; ++i) { for (int i = topLeftPos.x ; i < topLeftPos.x + xSize ; ++i) {
const guint8* data3 = data2 + i*3; const guint8* data3 = data2 + i*3;
rtengine::Coord currPos(i, j); rtengine::Coord currPos(i, j);

View File

@ -113,7 +113,7 @@ public:
void setEnabled (bool e); void setEnabled (bool e);
bool getEnabled (); bool getEnabled ();
void colorPick (rtengine::Coord pickerPos, float &r, float &g, float &b, LockableColorPicker::PickerSize size); void colorPick (rtengine::Coord pickerPos, float &r, float &g, float &b, LockableColorPicker::Size size);
rtengine::DetailedCrop* getCrop() rtengine::DetailedCrop* getCrop()
{ {

View File

@ -322,11 +322,19 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y)
state = SDragPicker; state = SDragPicker;
} else { } else {
// Add a new Color Picker // Add a new Color Picker
int x2, y2; rtengine::Coord imgPos, cropPos;
screenCoordToImage(x, y, x2, y2); screenCoordToImage(x, y, imgPos.x, imgPos.y);
LockableColorPicker *newPicker = new LockableColorPicker(x2, y2, LockableColorPicker::PickerSize::S15, 0., 0., 0., this); LockableColorPicker *newPicker = new LockableColorPicker(imgPos.x, imgPos.y, LockableColorPicker::Size::S15, 0., 0., 0., this, &cropHandler.colorParams.output, &cropHandler.colorParams.working);
colorPickers.push_back(newPicker); colorPickers.push_back(newPicker);
hoveredPicker = newPicker; hoveredPicker = newPicker;
imageCoordToCropImage(imgPos.x, imgPos.y, cropPos.x, cropPos.y);
float r=0.f, g=0.f, b=0.f;
LockableColorPicker::Validity validity = checkValidity (hoveredPicker, cropPos);
hoveredPicker->setValidity (validity);
if (validity == LockableColorPicker::Validity::INSIDE) {
cropHandler.colorPick(cropPos, r, g, b, hoveredPicker->getSize());
hoveredPicker->setRGB (r, g, b);
}
state = SDragPicker; state = SDragPicker;
press_x = x; press_x = x;
press_y = y; press_y = y;
@ -854,9 +862,9 @@ void CropWindow::pointerMoved (int bstate, int x, int y)
} }
imageCoordToCropImage(imgPos.x, imgPos.y, cropPos.x, cropPos.y); imageCoordToCropImage(imgPos.x, imgPos.y, cropPos.x, cropPos.y);
float r=0.f, g=0.f, b=0.f; float r=0.f, g=0.f, b=0.f;
bool isValid = isHoveredPickerFullyInside (cropPos); LockableColorPicker::Validity validity = checkValidity (hoveredPicker, cropPos);
hoveredPicker->setValidity (isValid); hoveredPicker->setValidity (validity);
if (isValid) { if (validity == LockableColorPicker::Validity::INSIDE) {
cropHandler.colorPick(cropPos, r, g, b, hoveredPicker->getSize()); cropHandler.colorPick(cropPos, r, g, b, hoveredPicker->getSize());
} }
hoveredPicker->setPosition (imgPos, r, g, b); hoveredPicker->setPosition (imgPos, r, g, b);
@ -2032,23 +2040,41 @@ void CropWindow::changeZoom (int zoom, bool notify, int centerx, int centery)
iarea->redraw (); iarea->redraw ();
} }
bool CropWindow::isHoveredPickerFullyInside (const rtengine::Coord &pos) LockableColorPicker::Validity CropWindow::checkValidity (LockableColorPicker* picker, const rtengine::Coord &pos)
{ {
return true; if (!cropHandler.cropPixbuftrue) {
if (!cropHandler.cropPixbuf) { return LockableColorPicker::Validity::OUTSIDE;
return false;
} }
rtengine::Coord cropPos; rtengine::Coord cropTopLeft, cropBottomRight, cropSize;
int skip;
cropHandler.getWindow(cropTopLeft.x, cropTopLeft.y, cropSize.x, cropSize.y, skip);
cropBottomRight = cropTopLeft + cropSize;
rtengine::Coord pickerPos, cropPickerPos; rtengine::Coord pickerPos, cropPickerPos;
hoveredPicker->getImagePosition(pickerPos); picker->getImagePosition(pickerPos);
rtengine::Coord minPos(0, 0); rtengine::Coord minPos(0, 0);
rtengine::Coord maxPos(cropHandler.cropPixbuf->get_width(), cropHandler.cropPixbuf->get_height()); rtengine::Coord maxPos(cropHandler.cropPixbuftrue->get_width(), cropHandler.cropPixbuftrue->get_height());
rtengine::Coord halfPickerSize((int)hoveredPicker->getSize()/2, (int)hoveredPicker->getSize()/2); rtengine::Coord halfPickerSize((int)picker->getSize()/2, (int)picker->getSize()/2);
imageCoordToCropImage (pickerPos.x, pickerPos.y, cropPickerPos.x, cropPickerPos.y); imageCoordToCropImage (pickerPos.x, pickerPos.y, cropPickerPos.x, cropPickerPos.y);
imageCoordToCropImage (cropTopLeft.x, cropTopLeft.y, minPos.x, minPos.y);
imageCoordToCropImage (cropBottomRight.x, cropBottomRight.y, maxPos.x, maxPos.y);
rtengine::Coord pickerMinPos = cropPickerPos - halfPickerSize; rtengine::Coord pickerMinPos = cropPickerPos - halfPickerSize;
rtengine::Coord pickerMaxPos = cropPickerPos + halfPickerSize; rtengine::Coord pickerMaxPos = cropPickerPos + halfPickerSize;
return pickerMinPos >= minPos && pickerMaxPos <= maxPos; if (pickerMaxPos.x < minPos.x || pickerMaxPos.y < minPos.y || pickerMinPos.x > maxPos.x || pickerMinPos.y > maxPos.y) {
return LockableColorPicker::Validity::OUTSIDE;
} else if (pickerMinPos >= minPos && pickerMaxPos < maxPos) {
return LockableColorPicker::Validity::INSIDE;
} else {
return LockableColorPicker::Validity::CROSSING;
}
}
void CropWindow::deleteColorPickers ()
{
for (auto colorPicker : colorPickers) {
delete colorPicker;
}
colorPickers.clear();
} }
void CropWindow::screenCoordToCropBuffer (int phyx, int phyy, int& cropx, int& cropy) void CropWindow::screenCoordToCropBuffer (int phyx, int phyy, int& cropx, int& cropy)
@ -2360,6 +2386,7 @@ void CropWindow::cropImageUpdated ()
colorPicker->getImagePosition(imgPos); colorPicker->getImagePosition(imgPos);
imageCoordToCropImage(imgPos.x, imgPos.y, cropPos.x, cropPos.y); imageCoordToCropImage(imgPos.x, imgPos.y, cropPos.x, cropPos.y);
float r=0.f, g=0.f, b=0.f; float r=0.f, g=0.f, b=0.f;
colorPicker->setValidity (checkValidity (colorPicker, cropPos));
cropHandler.colorPick(cropPos, r, g, b, colorPicker->getSize()); cropHandler.colorPick(cropPos, r, g, b, colorPicker->getSize());
colorPicker->setRGB (r, g, b); colorPicker->setRGB (r, g, b);
} }

View File

@ -105,7 +105,7 @@ class CropWindow : public LWButtonListener, public CropDisplayHandler, public Ed
void drawObservedFrame (Cairo::RefPtr<Cairo::Context> cr, int rw = 0, int rh = 0); void drawObservedFrame (Cairo::RefPtr<Cairo::Context> cr, int rw = 0, int rh = 0);
void changeZoom (int zoom, bool notify = true, int centerx = -1, int centery = -1); void changeZoom (int zoom, bool notify = true, int centerx = -1, int centery = -1);
bool isHoveredPickerFullyInside(const rtengine::Coord &pos); LockableColorPicker::Validity checkValidity (LockableColorPicker* picker, const rtengine::Coord &pos);
// Used by the mainCropWindow only // Used by the mainCropWindow only
void getObservedFrameArea (int& x, int& y, int& w, int& h, int rw = 0, int rh = 0); void getObservedFrameArea (int& x, int& y, int& w, int& h, int rw = 0, int rh = 0);
@ -127,6 +127,7 @@ public:
{ {
observedCropWin = cw; observedCropWin = cw;
} }
void deleteColorPickers ();
void screenCoordToCropBuffer (int phyx, int phyy, int& cropx, int& cropy); void screenCoordToCropBuffer (int phyx, int phyy, int& cropx, int& cropy);
void screenCoordToImage (int phyx, int phyy, int& imgx, int& imgy); void screenCoordToImage (int phyx, int phyy, int& imgx, int& imgy);

View File

@ -117,6 +117,7 @@ void ImageArea::setImProcCoordinator (rtengine::StagedImageProcessor* ipc_)
cropWins.clear(); cropWins.clear();
mainCropWindow->deleteColorPickers ();
mainCropWindow->setObservedCropWin (NULL); mainCropWindow->setObservedCropWin (NULL);
} }

View File

@ -26,21 +26,24 @@
extern Options options; extern Options options;
LockableColorPicker::LockableColorPicker (CropWindow* cropWindow) LockableColorPicker::LockableColorPicker (CropWindow* cropWindow, Glib::ustring *oProfile, Glib::ustring *wProfile)
: cropWindow(cropWindow), displayedValues(ColorPickerType::RGB), position(0, 0), size(PickerSize::S20), : cropWindow(cropWindow), displayedValues(ColorPickerType::RGB), position(0, 0), size(Size::S20),
isValid(false), r(0.f), g(0.f), b(0.f), h(0.f), s(0.f), v(0.f) outputProfile(oProfile), workingProfile(wProfile), validity(Validity::OUTSIDE),
{ r(0.f), g(0.f), b(0.f), h(0.f), s(0.f), v(0.f), L(0.f), a(0.f), bb(0.f)
} {}
LockableColorPicker::LockableColorPicker (int x, int y, PickerSize size, const float R, const float G, const float B, CropWindow* cropWindow) LockableColorPicker::LockableColorPicker (int x, int y, Size size, const float R, const float G, const float B, CropWindow* cropWindow, Glib::ustring *oProfile, Glib::ustring *wProfile)
: cropWindow(cropWindow), displayedValues(ColorPickerType::RGB), position(x, y), size(size), : cropWindow(cropWindow), displayedValues(ColorPickerType::RGB), position(x, y), size(size),
isValid(false), r(R), g(G), b(B) outputProfile(oProfile), workingProfile(wProfile), validity(Validity::OUTSIDE),
r(R), g(G), b(B), L(0.f), a(0.f), bb(0.f)
{ {
float h_, s_, v_; float h_, s_, v_;
rtengine::Color::rgb2hsv((float)r*65535.f, (float)g*65535.f, (float)b*65535.f, h_, s_, v_); rtengine::Color::rgb2hsv((float)r*65535.f, (float)g*65535.f, (float)b*65535.f, h_, s_, v_);
h = (int)(h_*255.f); h = (int)(h_*255.f);
s = (int)(s_*255.f); s = (int)(s_*255.f);
v = (int)(v_*255.f); v = (int)(v_*255.f);
rtengine::Color::rgb2lab (*outputProfile, *workingProfile, r * 0xffff / 0xff, g * 0xffff / 0xff, b * 0xffff / 0xff, L, a, bb, options.rtSettings.HistogramWorking); // TODO: Really sure this function works?
} }
void LockableColorPicker::updateBackBuffer () void LockableColorPicker::updateBackBuffer ()
@ -48,20 +51,17 @@ void LockableColorPicker::updateBackBuffer ()
int newW, newH; int newW, newH;
// -------------------- setting some key constants --------------------- // -------------------- setting some key constants ---------------------
const float circlePadding = 3.f; const float circlePadding = 3.f; // keep this value odd
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
if (isValid) { if (validity == Validity::INSIDE) {
Gtk::DrawingArea *iArea = cropWindow->getImageArea(); Gtk::DrawingArea *iArea = cropWindow->getImageArea();
Cairo::RefPtr<Cairo::Context> bbcr = BackBuffer::getContext();
Glib::RefPtr<Pango::Context> pangoContext = iArea->get_pango_context (); Glib::RefPtr<Pango::Context> pangoContext = iArea->get_pango_context ();
Pango::FontDescription fontd(options.colorPickerFont); Pango::FontDescription fontd(options.colorPickerFont);
fontd.set_weight(Pango::WEIGHT_NORMAL);
pangoContext->set_font_description (fontd); pangoContext->set_font_description (fontd);
// for drawing text
bbcr->set_line_width (0.);
Glib::RefPtr<Pango::Layout> layout[3][2]; Glib::RefPtr<Pango::Layout> layout[3][2];
switch (displayedValues) { switch (displayedValues) {
@ -97,10 +97,10 @@ void LockableColorPicker::updateBackBuffer ()
int maxHRow2 = rtengine::max(h20, h21); int maxHRow2 = rtengine::max(h20, h21);
// -------------------- setting some key constants --------------------- // -------------------- setting some key constants ---------------------
const int textPadding = 2; const int textPadding = 3;
const int textWidth = maxWCol0 + maxWCol1 + textPadding; const int textWidth = maxWCol0 + maxWCol1 + textPadding;
const int textHeight = maxHRow0 + maxHRow1 + maxHRow2 + 2*textPadding; const int textHeight = maxHRow0 + maxHRow1 + maxHRow2 + 2*textPadding;
const double opacity = 0.75; const double opacity = 0.62;
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
newW = rtengine::max<int>((int)size + 2 * circlePadding, textWidth + 2 * textPadding); newW = rtengine::max<int>((int)size + 2 * circlePadding, textWidth + 2 * textPadding);
@ -108,29 +108,44 @@ void LockableColorPicker::updateBackBuffer ()
setDrawRectangle(Cairo::FORMAT_ARGB32, 0, 0, newW, newH, true); setDrawRectangle(Cairo::FORMAT_ARGB32, 0, 0, newW, newH, true);
float center = (float)size/2.f + circlePadding; Cairo::RefPtr<Cairo::Context> bbcr = BackBuffer::getContext();
// cleaning the back buffer
bbcr->set_source_rgba (0., 0., 0., 0.);
bbcr->set_operator (Cairo::OPERATOR_CLEAR);
bbcr->paint ();
bbcr->set_operator (Cairo::OPERATOR_OVER);
// for drawing text
bbcr->set_antialias (Cairo::ANTIALIAS_SUBPIXEL);
bbcr->set_line_width (0.);
float center = (float)size / 2.f + circlePadding;
// black background of the whole color picker // black background of the whole color picker
bbcr->set_line_width (0.); bbcr->set_line_width (0.);
bbcr->arc_negative (center, center, center, 0.f, (float)M_PI);
bbcr->line_to (0, 2.f * center + textHeight + 2*textPadding);
bbcr->line_to (textWidth + 2*textPadding, 2.f * center + textHeight + 2*textPadding);
bbcr->line_to (textWidth + 2*textPadding, 2.f * center);
bbcr->line_to (2.f * center, 2.f * center);
bbcr->close_path();
bbcr->set_source_rgba (0., 0., 0., opacity); bbcr->set_source_rgba (0., 0., 0., opacity);
bbcr->arc_negative (center, center, center, 0., (double)M_PI);
bbcr->line_to (0, 2. * center + textHeight);
bbcr->arc_negative (2. * textPadding, 2. * center + textHeight, 2. * textPadding, (double)M_PI, (double)M_PI / 2.);
bbcr->line_to (textWidth, 2. * center + textHeight + 2. * textPadding);
bbcr->arc_negative (textWidth, 2. * center + textHeight, 2. * textPadding, (double)M_PI / 2., 0.);
bbcr->line_to (textWidth + 2. * textPadding, 2. * center + 2. * textPadding);
bbcr->arc_negative (textWidth, 2. * center + 2. * textPadding, 2. * textPadding, 0., (double)M_PI * 1.5);
bbcr->line_to (2. * center, 2. * center);
bbcr->close_path();
bbcr->set_line_join (Cairo::LINE_JOIN_BEVEL); bbcr->set_line_join (Cairo::LINE_JOIN_BEVEL);
bbcr->set_line_cap (Cairo::LINE_CAP_SQUARE); bbcr->set_line_cap (Cairo::LINE_CAP_SQUARE);
bbcr->fill (); bbcr->fill ();
// light grey circle around the color mark // light grey circle around the color mark
bbcr->arc (center, center, center - circlePadding / 2.f - 0.5f, 0.f, 2.f * (float)M_PI); bbcr->arc (center, center, center - circlePadding / 2., 0., 2. * (double)M_PI);
bbcr->set_source_rgb (0.7, 0.7, 0.7); bbcr->set_source_rgb (0.75, 0.75, 0.75);
bbcr->set_line_width (circlePadding-2.f); bbcr->set_line_width (circlePadding - 2.);
bbcr->stroke (); bbcr->stroke ();
// spot disc with picked color // spot disc with picked color
bbcr->arc (center, center, center - circlePadding - 0.5f, 0.f, 2.f * (float)M_PI); bbcr->arc (center, center, center - circlePadding, 0., 2. * (double)M_PI);
bbcr->set_source_rgb (r, g, b); // <- set the picker color here bbcr->set_source_rgb (r, g, b); // <- set the picker color here
bbcr->set_line_width (0.); bbcr->set_line_width (0.);
bbcr->fill(); bbcr->fill();
@ -141,7 +156,7 @@ void LockableColorPicker::updateBackBuffer ()
bbcr->set_line_cap (Cairo::LINE_CAP_ROUND); bbcr->set_line_cap (Cairo::LINE_CAP_ROUND);
bbcr->set_source_rgb (1., 1., 1.); bbcr->set_source_rgb (1., 1., 1.);
double txtOffsetX = textPadding; double txtOffsetX = textPadding;
double txtOffsetY = (double)size + 2.f * circlePadding + textPadding; double txtOffsetY = (double)size + 2. * circlePadding + textPadding;
switch (iArea->get_direction()) { switch (iArea->get_direction()) {
case Gtk::TEXT_DIR_RTL: case Gtk::TEXT_DIR_RTL:
bbcr->move_to (txtOffsetX , txtOffsetY); bbcr->move_to (txtOffsetX , txtOffsetY);
@ -190,31 +205,37 @@ void LockableColorPicker::updateBackBuffer ()
anchorOffset.set (center, center); anchorOffset.set (center, center);
} else { setDirty (false);
} else if (validity == Validity::CROSSING) {
newH = newW = (int)size + 2 * circlePadding; newH = newW = (int)size + 2 * circlePadding;
setDrawRectangle(Cairo::FORMAT_ARGB32, 0, 0, newW, newH, true); setDrawRectangle(Cairo::FORMAT_ARGB32, 0, 0, newW, newH, true);
Cairo::RefPtr<Cairo::Context> bbcr = BackBuffer::getContext(); Cairo::RefPtr<Cairo::Context> bbcr = BackBuffer::getContext();
bbcr->set_antialias(Cairo::ANTIALIAS_SUBPIXEL);
float center = (float)size/2.f + circlePadding; float center = (float)size / 2.f + circlePadding;
bbcr->arc (center, center, center - circlePadding/2.f, 0.f, 2.f * (float)M_PI); bbcr->arc (center, center, center - circlePadding / 2., 0., 2. * (double)M_PI);
bbcr->set_source_rgb (0., 0., 0.); bbcr->set_source_rgb (0., 0., 0.);
bbcr->set_line_width(circlePadding); bbcr->set_line_width(circlePadding);
bbcr->stroke_preserve(); bbcr->stroke_preserve();
bbcr->set_source_rgb (1., 1., 1.); bbcr->set_source_rgb (1., 1., 1.);
bbcr->set_line_width(circlePadding-2.f); bbcr->set_line_width(circlePadding - 2.);
bbcr->stroke (); bbcr->stroke ();
anchorOffset.set (center, center); anchorOffset.set (center, center);
setDirty (false);
} }
setDirty (false);
} }
void LockableColorPicker::draw (Cairo::RefPtr<Cairo::Context> &cr) void LockableColorPicker::draw (Cairo::RefPtr<Cairo::Context> &cr)
{ {
if (validity == Validity::OUTSIDE) {
return;
}
if (isDirty()) { if (isDirty()) {
updateBackBuffer(); updateBackBuffer();
} }
@ -240,7 +261,9 @@ void LockableColorPicker::setPosition (const rtengine::Coord &newPos, const floa
s = (float)s_; s = (float)s_;
v = (float)v_; v = (float)v_;
if (isValid) { rtengine::Color::rgb2lab (*outputProfile, *workingProfile, r * 0xffff / 0xff, g * 0xffff / 0xff, b * 0xffff / 0xff, L, a, bb, options.rtSettings.HistogramWorking); // TODO: Really sure this function works?
if (validity != Validity::OUTSIDE) {
setDirty(true); setDirty(true);
} }
} }
@ -261,7 +284,9 @@ void LockableColorPicker::setRGB (const float R, const float G, const float B)
s = (float)s_; s = (float)s_;
v = (float)v_; v = (float)v_;
if (isValid) { rtengine::Color::rgb2lab (*outputProfile, *workingProfile, r * 0xffff / 0xff, g * 0xffff / 0xff, b * 0xffff / 0xff, L, a, bb, options.rtSettings.HistogramWorking); // TODO: Really sure this function works?
if (validity != Validity::OUTSIDE) {
setDirty(true); setDirty(true);
} }
} }
@ -293,15 +318,15 @@ bool LockableColorPicker::isOver (int x, int y)
return mousePos >= tl && mousePos <= br; return mousePos >= tl && mousePos <= br;
} }
void LockableColorPicker::setValidity (bool isValid) void LockableColorPicker::setValidity (Validity validity)
{ {
if (this->isValid != isValid) { if (this->validity != validity) {
setDirty(true); setDirty(true);
} }
this->isValid = isValid; this->validity = validity;
} }
void LockableColorPicker::setSize (PickerSize newSize) void LockableColorPicker::setSize (Size newSize)
{ {
if (size != newSize) if (size != newSize)
{ {
@ -310,23 +335,23 @@ void LockableColorPicker::setSize (PickerSize newSize)
} }
} }
LockableColorPicker::PickerSize LockableColorPicker::getSize () LockableColorPicker::Size LockableColorPicker::getSize ()
{ {
return size; return size;
} }
void LockableColorPicker::incSize () void LockableColorPicker::incSize ()
{ {
if (size < PickerSize::S30) { if (size < Size::S30) {
size = (PickerSize)((int)size + 5); size = (Size)((int)size + 5);
setDirty(true); setDirty(true);
} }
} }
void LockableColorPicker::decSize () void LockableColorPicker::decSize ()
{ {
if (size > PickerSize::S5) { if (size > Size::S5) {
size = (PickerSize)((int)size - 5); size = (Size)((int)size - 5);
setDirty(true); setDirty(true);
} }
} }

View File

@ -38,7 +38,7 @@ public:
class LockableColorPicker : BackBuffer class LockableColorPicker : BackBuffer
{ {
public: public:
enum class PickerSize { enum class Size {
S5=5, S5=5,
S10=10, S10=10,
S15=15, S15=15,
@ -46,26 +46,35 @@ public:
S25=25, S25=25,
S30=30 S30=30
}; };
enum class Validity {
INSIDE,
CROSSING,
OUTSIDE
};
private: private:
enum class ColorPickerType { enum class ColorPickerType {
RGB, RGB,
HSV HSV,
LAB
}; };
CropWindow* cropWindow; // the color picker is displayed in a single cropWindow, the one that the user has clicked in CropWindow* cropWindow; // the color picker is displayed in a single cropWindow, the one that the user has clicked in
ColorPickerType displayedValues; ColorPickerType displayedValues;
rtengine::Coord position; // Coordinate in image space rtengine::Coord position; // Coordinate in image space
rtengine::Coord anchorOffset; rtengine::Coord anchorOffset;
PickerSize size; Size size;
bool isValid; Glib::ustring *outputProfile;
Glib::ustring *workingProfile;
Validity validity;
float r, g, b; // red green blue in [0;1] range float r, g, b; // red green blue in [0;1] range
float h, s, v; // hue saturation value in [0;1] range float h, s, v; // hue saturation value in [0;1] range
float L, a, bb; // L*a*b value in [0;1] range
void updateBackBuffer (); void updateBackBuffer ();
public: public:
LockableColorPicker (CropWindow* cropWindow); LockableColorPicker (CropWindow* cropWindow, Glib::ustring *oProfile, Glib::ustring *wProfile);
LockableColorPicker (int x, int y, PickerSize size, const float R, const float G, const float B, CropWindow* cropWindow); LockableColorPicker (int x, int y, Size size, const float R, const float G, const float B, CropWindow* cropWindow, Glib::ustring *oProfile, Glib::ustring *wProfile);
void draw (Cairo::RefPtr<Cairo::Context> &cr); void draw (Cairo::RefPtr<Cairo::Context> &cr);
@ -74,10 +83,10 @@ public:
void setRGB (const float R, const float G, const float B); void setRGB (const float R, const float G, const float B);
void getImagePosition (rtengine::Coord &imgPos); void getImagePosition (rtengine::Coord &imgPos);
void getScreenPosition (rtengine::Coord &screenPos); void getScreenPosition (rtengine::Coord &screenPos);
PickerSize getSize (); Size getSize ();
bool isOver (int x, int y); bool isOver (int x, int y);
void setValidity (bool isValid); void setValidity (Validity isValid);
void setSize (PickerSize newSize); void setSize (Size newSize);
void incSize (); void incSize ();
void decSize (); void decSize ();
}; };

View File

@ -266,7 +266,7 @@ void Navigator::pointerMoved (bool validPos, Glib::ustring profile, Glib::ustrin
float LAB_a, LAB_b, LAB_l; float LAB_a, LAB_b, LAB_l;
//rgb2lab (r, g, b, LAB_l, LAB_a, LAB_b); //rgb2lab (r, g, b, LAB_l, LAB_a, LAB_b);
rgb2lab (profile, profileW, r, g, b, LAB_l, LAB_a, LAB_b); // TODO: Really sure this function works? Color::rgb2lab (profile, profileW, r * 0xffff / 0xff, g * 0xffff / 0xff, b * 0xffff / 0xff, LAB_l, LAB_a, LAB_b, options.rtSettings.HistogramWorking); // TODO: Really sure this function works?
LAB_A->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), LAB_a)); LAB_A->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), LAB_a));
LAB_B->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), LAB_b)); LAB_B->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), LAB_b));
LAB_L->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), LAB_l)); LAB_L->set_text (Glib::ustring::format(std::fixed, std::setprecision(1), LAB_l));
@ -328,150 +328,3 @@ void Navigator::cycleUnitsHSV (GdkEventButton *event) {
break; break;
} }
} }
void Navigator::rgb2lab (Glib::ustring profile, Glib::ustring profileW, int r, int g, int b, float &LAB_l, float &LAB_a, float &LAB_b)
{
double xyz_rgb[3][3];
const double ep = 216.0 / 24389.0;
const double ka = 24389.0 / 27.0;
double var_R = r / 255.0;
double var_G = g / 255.0;
double var_B = b / 255.0;
Glib::ustring profileCalc;
profileCalc = "sRGB"; //default
if(options.rtSettings.HistogramWorking) {
profileCalc = profileW; //display working
}
else {// if you want display = output space
if (profile == "RT_sRGB" || profile == "RT_sRGB_gBT709" || profile == "RT_sRGB_g10") {
profileCalc = "sRGB";
}
if (profile == "ProPhoto" || profile == "RT_Large_gBT709" || profile == "RT_Large_g10" || profile == "RT_Large_gsRGB") {
profileCalc = "ProPhoto";
}
if (profile == "AdobeRGB1998" || profile == "RT_Medium_gsRGB") {
profileCalc = "Adobe RGB";
}
if (profile == "WideGamutRGB") {
profileCalc = "WideGamut";
}
}
if(options.rtSettings.HistogramWorking) {//display working
if (profileW == "sRGB") { //apply sRGB inverse gamma
if ( var_R > 0.04045 ) {
var_R = pow ( ( ( var_R + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve);
} else {
var_R = var_R / 12.92;
}
if ( var_G > 0.04045 ) {
var_G = pow ( ( ( var_G + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve);
} else {
var_G = var_G / 12.92;
}
if ( var_B > 0.04045 ) {
var_B = pow ( ( ( var_B + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve);
} else {
var_B = var_B / 12.92;
}
} else if (profileW == "ProPhoto") { // apply inverse gamma 1.8
var_R = pow ( var_R, 1.8);
var_G = pow ( var_G, 1.8);
var_B = pow ( var_B, 1.8);
} else { // apply inverse gamma 2.2
var_R = pow ( var_R, 2.2);
var_G = pow ( var_G, 2.2);
var_B = pow ( var_B, 2.2);
}
} else { //display outout profile
if (profile == "RT_sRGB" || profile == "RT_Large_gsRGB" || profile == "RT_Medium_gsRGB") { //apply sRGB inverse gamma
if ( var_R > 0.04045 ) {
var_R = pow ( ( ( var_R + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve);
} else {
var_R = var_R / 12.92;
}
if ( var_G > 0.04045 ) {
var_G = pow ( ( ( var_G + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve);
} else {
var_G = var_G / 12.92;
}
if ( var_B > 0.04045 ) {
var_B = pow ( ( ( var_B + 0.055 ) / 1.055 ), rtengine::Color::sRGBGammaCurve);
} else {
var_B = var_B / 12.92;
}
}
else if (profile == "RT_sRGB_gBT709" || profile == "RT_Large_gBT709") { //
if ( var_R > 0.0795 ) {
var_R = pow ( ( ( var_R + 0.0954 ) / 1.0954 ), 2.2);
} else {
var_R = var_R / 4.5;
}
if ( var_G > 0.0795 ) {
var_G = pow ( ( ( var_G + 0.0954 ) / 1.0954 ), 2.2);
} else {
var_G = var_G / 4.5;
}
if ( var_B > 0.0795 ) {
var_B = pow ( ( ( var_B + 0.0954 ) / 1.0954 ), 2.2);
} else {
var_B = var_B / 4.5;
}
} else if (profile == "ProPhoto") { // apply inverse gamma 1.8
var_R = pow ( var_R, 1.8);
var_G = pow ( var_G, 1.8);
var_B = pow ( var_B, 1.8);
} else if (profile == "RT_sRGB_g10" || profile == "RT_Large_g10") { // apply inverse gamma 1.8
var_R = pow ( var_R, 1.);
var_G = pow ( var_G, 1.);
var_B = pow ( var_B, 1.);
}
else {// apply inverse gamma 2.2
var_R = pow ( var_R, 2.2);
var_G = pow ( var_G, 2.2);
var_B = pow ( var_B, 2.2);
}
}
// TMatrix wprof = rtengine::ICCStore::getInstance()->workingSpaceMatrix (profileW);
TMatrix wprof = rtengine::ICCStore::getInstance()->workingSpaceMatrix (profileCalc);
for (int m = 0; m < 3; m++)
for (int n = 0; n < 3; n++) {
xyz_rgb[m][n] = wprof[m][n];
}
double varxx, varyy, varzz;
double var_X = ( xyz_rgb[0][0] * var_R + xyz_rgb[0][1] * var_G + xyz_rgb[0][2] * var_B ) / Color::D50x;
double var_Y = ( xyz_rgb[1][0] * var_R + xyz_rgb[1][1] * var_G + xyz_rgb[1][2] * var_B ) ;
double var_Z = ( xyz_rgb[2][0] * var_R + xyz_rgb[2][1] * var_G + xyz_rgb[2][2] * var_B ) / Color::D50z;
varxx = var_X > ep ? cbrt(var_X) : ( ka * var_X + 16.0) / 116.0 ;
varyy = var_Y > ep ? cbrt(var_Y) : ( ka * var_Y + 16.0) / 116.0 ;
varzz = var_Z > ep ? cbrt(var_Z) : ( ka * var_Z + 16.0) / 116.0 ;
LAB_l = ( 116 * varyy ) - 16;
LAB_a = 500 * ( varxx - varyy );
LAB_b = 200 * ( varyy - varzz );
}

View File

@ -46,8 +46,6 @@ protected:
Gtk::Label *lH, *lS, *lV; Gtk::Label *lH, *lS, *lV;
Gtk::Label *lLAB_A, *lLAB_B, *lLAB_L; Gtk::Label *lLAB_A, *lLAB_B, *lLAB_L;
void rgb2lab (Glib::ustring profile, Glib::ustring profileW, int r, int g, int b, float &LAB_l, float &LAB_a, float &LAB_b);
void setInvalid (int fullWidth = -1, int fullHeight = -1); void setInvalid (int fullWidth = -1, int fullHeight = -1);
public: public:

View File

@ -109,17 +109,18 @@ ToolBar::~ToolBar ()
void ToolBar::setTool (ToolMode tool) void ToolBar::setTool (ToolMode tool)
{ {
handConn.block (true); bool handWasBlocked = handConn.block (true);
cropConn.block (true); bool cropWasBlocked = cropConn.block (true);
bool wbWasBlocked = true, cpWasBlocked = true;
if (wbTool) { if (wbTool) {
wbConn.block (true); wbWasBlocked = wbConn.block (true);
} }
if (colPickerTool) { if (colPickerTool) {
cpConn.block (true); cpWasBlocked = cpConn.block (true);
} }
straConn.block (true); bool straWasBlocked = straConn.block (true);
bool stopEdit = tool == TMHand && handTool->get_active() && editingMode; bool stopEdit = tool == TMHand && handTool->get_active() && editingMode;
@ -154,17 +155,17 @@ void ToolBar::setTool (ToolMode tool)
current = tool; current = tool;
handConn.block (false); if (!handWasBlocked) handConn.block (false);
cropConn.block (false); if (!cropWasBlocked) cropConn.block (false);
if (wbTool) { if (wbTool) {
wbConn.block (false); if (!wbWasBlocked) wbConn.block (false);
} }
if (colPickerTool) { if (colPickerTool) {
cpConn.block (false); if (!cpWasBlocked) cpConn.block (false);
} }
straConn.block (false); if (!straWasBlocked) straConn.block (false);
if (stopEdit) { if (stopEdit) {
stopEditMode(); stopEditMode();
@ -178,7 +179,44 @@ void ToolBar::setTool (ToolMode tool)
void ToolBar::startEditMode() void ToolBar::startEditMode()
{ {
if (!editingMode) { if (!editingMode) {
handTool->set_active(true); // will call hand_pressed, with editingMode=false bool handWasBlocked = handConn.block (true);
bool cropWasBlocked = cropConn.block (true);
bool wbWasBlocked = true, cpWasBlocked = true;
if (colPickerTool) {
cpWasBlocked = cpConn.block (true);
}
if (wbTool) {
wbWasBlocked = wbConn.block (true);
}
bool straWasBlocked = straConn.block (true);
if (current != TMHand) {
if (colPickerTool) {
colPickerTool->set_active(false);
}
if (wbTool) {
wbTool->set_active (false);
}
cropTool->set_active (false);
straTool->set_active (false);
current = TMHand;
}
handTool->set_active (true);
if (!handWasBlocked) handConn.block (false);
if (!cropWasBlocked) cropConn.block (false);
if (colPickerTool) {
if (!cpWasBlocked) cpConn.block (false);
}
if (wbTool) {
if (!wbWasBlocked) wbConn.block (false);
}
if (!straWasBlocked) straConn.block (false);
editingMode = true; editingMode = true;
handTool->set_image(*editinghandimg); handTool->set_image(*editinghandimg);
} }
@ -195,13 +233,6 @@ void ToolBar::stopEditMode()
{ {
if (editingMode) { if (editingMode) {
editingMode = false; editingMode = false;
/* WARNING: Should we toggle the Hand button on?
* This method can be called while another tool is active, e.g. if the user toggle off
* the Subscriber's Edit button. For now, we keep that other tool active. If one want to
* switch to the Hand tool, uncommenting the following line should suffice (not tested).
*
* handTool->set_active(true);
*/
handTool->set_image(*handimg); handTool->set_image(*handimg);
} }
} }
@ -209,18 +240,25 @@ void ToolBar::stopEditMode()
void ToolBar::hand_pressed () void ToolBar::hand_pressed ()
{ {
handConn.block (true); bool handWasBlocked = handConn.block (true);
cropConn.block (true); bool cropWasBlocked = cropConn.block (true);
bool wbWasBlocked = true, cpWasBlocked = true;
if (colPickerTool) { if (colPickerTool) {
cpConn.block (true); cpWasBlocked = cpConn.block (true);
} }
if (wbTool) { if (wbTool) {
wbConn.block (true); wbWasBlocked = wbConn.block (true);
} }
straConn.block (true); bool straWasBlocked = straConn.block (true);
if (editingMode) {
stopEditMode();
if (listener) {
listener->editModeSwitchedOff ();
}
}
if (current != TMHand) { if (current != TMHand) {
if (colPickerTool) { if (colPickerTool) {
colPickerTool->set_active(false); colPickerTool->set_active(false);
@ -232,27 +270,19 @@ void ToolBar::hand_pressed ()
cropTool->set_active (false); cropTool->set_active (false);
straTool->set_active (false); straTool->set_active (false);
current = TMHand; current = TMHand;
} else {
if (editingMode) {
stopEditMode();
}
if (listener) {
listener->editModeSwitchedOff ();
}
} }
handTool->set_active (true); handTool->set_active (true);
handConn.block (false); if (!handWasBlocked) handConn.block (false);
cropConn.block (false); if (!cropWasBlocked) cropConn.block (false);
if (colPickerTool) { if (colPickerTool) {
cpConn.block (false); if (!cpWasBlocked) cpConn.block (false);
} }
if (wbTool) { if (wbTool) {
wbConn.block (false); if (!wbWasBlocked) wbConn.block (false);
} }
straConn.block (false); if (!straWasBlocked) straConn.block (false);
if (listener) { if (listener) {
listener->toolSelected (TMHand); listener->toolSelected (TMHand);
@ -262,18 +292,25 @@ void ToolBar::hand_pressed ()
void ToolBar::wb_pressed () void ToolBar::wb_pressed ()
{ {
handConn.block (true); bool handWasBlocked = handConn.block (true);
cropConn.block (true); bool cropWasBlocked = cropConn.block (true);
bool wbWasBlocked = true, cpWasBlocked = true;
if (colPickerTool) { if (colPickerTool) {
cpConn.block (true); cpWasBlocked = cpConn.block (true);
} }
if (wbTool) { if (wbTool) {
wbConn.block (true); wbWasBlocked = wbConn.block (true);
} }
straConn.block (true); bool straWasBlocked = straConn.block (true);
if (current != TMSpotWB) { if (current != TMSpotWB) {
if (editingMode) {
stopEditMode();
if (listener) {
listener->editModeSwitchedOff ();
}
}
handTool->set_active (false); handTool->set_active (false);
cropTool->set_active (false); cropTool->set_active (false);
straTool->set_active (false); straTool->set_active (false);
@ -287,16 +324,16 @@ void ToolBar::wb_pressed ()
wbTool->set_active (true); wbTool->set_active (true);
} }
handConn.block (false); if (!handWasBlocked) handConn.block (false);
cropConn.block (false); if (!cropWasBlocked) cropConn.block (false);
if (colPickerTool) { if (colPickerTool) {
cpConn.block (false); if (!cpWasBlocked) cpConn.block (false);
} }
if (wbTool) { if (wbTool) {
wbConn.block (false); if (!wbWasBlocked) wbConn.block (false);
} }
straConn.block (false); if (!straWasBlocked) straConn.block (false);
if (listener) { if (listener) {
listener->toolSelected (TMSpotWB); listener->toolSelected (TMSpotWB);
@ -307,14 +344,15 @@ void ToolBar::colPicker_pressed (GdkEventButton* event)
{ {
if (event->button == 1) { if (event->button == 1) {
handConn.block (true); bool handWasBlocked = handConn.block (true);
cropConn.block (true); bool cropWasBlocked = cropConn.block (true);
cpConn.block (true); bool wbWasBlocked = true;
bool cpWasBlocked = cpConn.block (true);
if (wbTool) { if (wbTool) {
wbConn.block (true); wbWasBlocked = wbConn.block (true);
} }
straConn.block (true); bool straWasBlocked = straConn.block (true);
cropTool->set_active (false); cropTool->set_active (false);
if (wbTool) { if (wbTool) {
@ -324,21 +362,27 @@ void ToolBar::colPicker_pressed (GdkEventButton* event)
if (current != TMColorPicker) { if (current != TMColorPicker) {
// Disabling all other tools, enabling the Picker tool and entering the "visible pickers" mode // Disabling all other tools, enabling the Picker tool and entering the "visible pickers" mode
if (editingMode) {
stopEditMode();
if (listener) {
listener->editModeSwitchedOff ();
}
}
handTool->set_active (false); handTool->set_active (false);
showColorPickers(true); showColorPickers(true);
current = TMColorPicker; current = TMColorPicker;
} else { } else {
// Disabling the picker tool, enabling the Hand tool and keeping the "visible pickers" mode // Disabling the picker tool, enabling the Hand tool and keeping the "visible pickers" mode
handTool->set_active (true); handTool->set_active (true);
colPickerTool->set_active (false); //colPickerTool->set_active (false); Done by the standard event handler
current = TMHand; current = TMHand;
} }
handConn.block (false); if (!handWasBlocked) handConn.block (false);
cropConn.block (false); if (!cropWasBlocked) cropConn.block (false);
cpConn.block (false); if (!cpWasBlocked) cpConn.block (false);
wbConn.block (false); if (!wbWasBlocked) wbConn.block (false);
straConn.block (false); if (!straWasBlocked) straConn.block (false);
if (listener) { if (listener) {
listener->toolSelected (current); listener->toolSelected (current);
@ -346,14 +390,14 @@ void ToolBar::colPicker_pressed (GdkEventButton* event)
} else if (event->button == 3) { } else if (event->button == 3) {
if (current == TMColorPicker) { if (current == TMColorPicker) {
// Disabling the Picker tool and entering into the "invisible pickers" mode // Disabling the Picker tool and entering into the "invisible pickers" mode
cpConn.block (true); bool cpWasBlocked = cpConn.block (true);
handConn.block (true); bool handWasBlocked = handConn.block (true);
handTool->set_active (true); handTool->set_active (true);
colPickerTool->set_active (false); colPickerTool->set_active (false);
current = TMHand; current = TMHand;
showColorPickers(false); showColorPickers(false);
cpConn.block (false); if (!cpWasBlocked) cpConn.block (false);
handConn.block (false); if (!handWasBlocked) handConn.block (false);
} else { } else {
// The Picker tool is already disabled, entering into the "invisible pickers" mode // The Picker tool is already disabled, entering into the "invisible pickers" mode
switchColorPickersVisibility(); switchColorPickersVisibility();
@ -386,17 +430,26 @@ void ToolBar::switchColorPickersVisibility()
void ToolBar::crop_pressed () void ToolBar::crop_pressed ()
{ {
handConn.block (true); bool handWasBlocked = handConn.block (true);
cropConn.block (true); bool cropWasBlocked = cropConn.block (true);
bool wbWasBlocked = true, cpWasBlocked = true;
if (colPickerTool) {
cpConn.block(true); cpConn.block(true);
if (wbTool) {
wbConn.block (true);
} }
straConn.block (true); if (wbTool) {
wbWasBlocked = wbConn.block (true);
}
bool straWasBlocked = straConn.block (true);
if (current != TMCropSelect) { if (current != TMCropSelect) {
if (editingMode) {
stopEditMode();
if (listener) {
listener->editModeSwitchedOff ();
}
}
handTool->set_active (false); handTool->set_active (false);
if (colPickerTool) { if (colPickerTool) {
colPickerTool->set_active(false); colPickerTool->set_active(false);
@ -410,11 +463,12 @@ void ToolBar::crop_pressed ()
} }
cropTool->set_active (true); cropTool->set_active (true);
handConn.block (false); cropTool->grab_focus ();
cropConn.block (false); if (!handWasBlocked) handConn.block (false);
cpConn.block(false); if (!cropWasBlocked) cropConn.block (false);
wbConn.block (false); if (!cpWasBlocked) cpConn.block(false);
straConn.block (false); if (!wbWasBlocked) wbConn.block (false);
if (!straWasBlocked) straConn.block (false);
if (listener) { if (listener) {
listener->toolSelected (TMCropSelect); listener->toolSelected (TMCropSelect);
@ -424,19 +478,26 @@ void ToolBar::crop_pressed ()
void ToolBar::stra_pressed () void ToolBar::stra_pressed ()
{ {
handConn.block (true); bool handWasBlocked = handConn.block (true);
cropConn.block (true); bool cropWasBlocked = cropConn.block (true);
bool wbWasBlocked = true, cpWasBlocked = true;
if (colPickerTool) { if (colPickerTool) {
cpConn.block (true); cpWasBlocked = cpConn.block (true);
} }
if (wbTool) { if (wbTool) {
wbConn.block (true); wbWasBlocked = wbConn.block (true);
} }
straConn.block (true); bool straWasBlocked = straConn.block (true);
if (current != TMStraighten) { if (current != TMStraighten) {
if (editingMode) {
stopEditMode();
if (listener) {
listener->editModeSwitchedOff ();
}
}
handTool->set_active (false); handTool->set_active (false);
if (colPickerTool) { if (colPickerTool) {
colPickerTool->set_active(false); colPickerTool->set_active(false);
@ -450,15 +511,15 @@ void ToolBar::stra_pressed ()
} }
straTool->set_active (true); straTool->set_active (true);
handConn.block (false); if (!handWasBlocked) handConn.block (false);
cropConn.block (false); if (!cropWasBlocked) cropConn.block (false);
cpConn.block (false); if (!cpWasBlocked) cpConn.block (false);
if (wbTool) { if (wbTool) {
wbConn.block (false); if (!wbWasBlocked) wbConn.block (false);
} }
straConn.block (false); if (!straWasBlocked) straConn.block (false);
if (listener) { if (listener) {
listener->toolSelected (TMStraighten); listener->toolSelected (TMStraighten);