From f60a4fc4b11960da61c7c39e9db4c0165f5e7106 Mon Sep 17 00:00:00 2001 From: Hombre Date: Wed, 5 Oct 2016 01:13:20 +0200 Subject: [PATCH] Adding Picker size support and Displayed values support (RGB/HSV/LAB) --- rtgui/cropwindow.cc | 97 ++++++++++++++++++++++++++++++------ rtgui/cropwindow.h | 2 + rtgui/imagearea.cc | 12 +---- rtgui/lockablecolorpicker.cc | 45 ++++++++++++----- rtgui/lockablecolorpicker.h | 1 + rtgui/toolbar.cc | 4 ++ 6 files changed, 123 insertions(+), 38 deletions(-) diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index f5d8ede4a..df9cb9f86 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -273,6 +273,38 @@ void CropWindow::flawnOver (bool isFlawnOver) this->isFlawnOver = isFlawnOver; } +void CropWindow::scroll (int state, GdkScrollDirection direction, int x, int y) +{ + if ((state & GDK_CONTROL_MASK) && onArea(ColorPicker, x, y)) { + // resizing a color picker + if (direction == GDK_SCROLL_UP) { + hoveredPicker->incSize(); + rtengine::Coord imgPos; + screenCoordToImage(x, y, imgPos.x, imgPos.y); + updateHoveredPicker(imgPos); + iarea->redraw (); + }else if (direction == GDK_SCROLL_DOWN) { + hoveredPicker->decSize(); + rtengine::Coord imgPos; + screenCoordToImage(x, y, imgPos.x, imgPos.y); + updateHoveredPicker(imgPos); + iarea->redraw (); + } + } else { + // not over a color picker, we zoom in/out + int newCenterX = x; + int newCenterY = y; + + screenCoordToImage(newCenterX, newCenterY, newCenterX, newCenterY); + + if (direction == GDK_SCROLL_UP && !isMaxZoom()) { + zoomIn (true, newCenterX, newCenterY); + } else if (!isMinZoom()) { + zoomOut (true, newCenterX, newCenterY); + } + } +} + void CropWindow::buttonPress (int button, int type, int bstate, int x, int y) { @@ -282,7 +314,7 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y) iarea->grabFocus (this); if (button == 1) { - if (type == GDK_2BUTTON_PRESS && onArea (CropImage, x, y) && (state == SNormal || state == SCropImgMove)) { + if (type == GDK_2BUTTON_PRESS && onArea (CropImage, x, y) && !onArea (ColorPicker, x, y) && (state == SNormal || state == SCropImgMove)) { if (fitZoomEnabled) { if (fitZoom) { state = SNormal; @@ -318,23 +350,27 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y) if (onArea (CropImage, x, y)) { // events inside of the image domain if (iarea->getToolMode () == TMColorPicker) { if (hoveredPicker) { - // Color Picker drag starts - state = SDragPicker; + if ((bstate & GDK_CONTROL_MASK) && !(bstate & GDK_SHIFT_MASK)) { + hoveredPicker->decSize(); + rtengine::Coord imgPos; + screenCoordToImage(x, y, imgPos.x, imgPos.y); + updateHoveredPicker(imgPos); + needRedraw = true; + } else if (!(bstate & GDK_CONTROL_MASK) && (bstate & GDK_SHIFT_MASK)) { + hoveredPicker->rollDisplayedValues(); + needRedraw = true; + } else if (!(bstate & GDK_CONTROL_MASK) && !(bstate & GDK_SHIFT_MASK)) { + // Color Picker drag starts + state = SDragPicker; + } } else { // Add a new Color Picker - rtengine::Coord imgPos, cropPos; + rtengine::Coord imgPos; screenCoordToImage(x, y, imgPos.x, imgPos.y); 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); 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); - } + updateHoveredPicker(imgPos); state = SDragPicker; press_x = x; press_y = y; @@ -465,8 +501,18 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y) action_y = 0; } } else if (iarea->getToolMode () == TMColorPicker && hoveredPicker) { - // Color Picker drag starts - state = SDragPicker; + if ((bstate & GDK_CONTROL_MASK) && !(bstate & GDK_SHIFT_MASK)) { + hoveredPicker->decSize(); + rtengine::Coord imgPos; + screenCoordToImage(x, y, imgPos.x, imgPos.y); + updateHoveredPicker(imgPos); + needRedraw = true; + } else if (!(bstate & GDK_CONTROL_MASK) && (bstate & GDK_SHIFT_MASK)) { + hoveredPicker->rollDisplayedValues(); + } else if (!(bstate & GDK_CONTROL_MASK) && !(bstate & GDK_SHIFT_MASK)) { + // Color Picker drag starts + state = SDragPicker; + } } } } @@ -521,6 +567,12 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y) hoveredPicker = nullptr; state = SDeletePicker; needRedraw = true; + } else if ((bstate & GDK_CONTROL_MASK) && !(bstate & GDK_SHIFT_MASK)) { + hoveredPicker->incSize(); + rtengine::Coord imgPos; + screenCoordToImage(x, y, imgPos.x, imgPos.y); + updateHoveredPicker(imgPos); + needRedraw = true; } else if (!(bstate & GDK_CONTROL_MASK) && !(bstate & GDK_SHIFT_MASK)) { // Deleting the hovered picker for (std::vector::iterator i = colorPickers.begin(); i != colorPickers.end(); i++) { @@ -2018,6 +2070,23 @@ void CropWindow::redrawNeeded (LWButton* button) iarea->redraw (); } +void CropWindow::updateHoveredPicker (rtengine::Coord &imgPos) +{ + + if (!hoveredPicker) { + return; + } + + rtengine::Coord cropPos; + 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); + } +} void CropWindow::changeZoom (int zoom, bool notify, int centerx, int centery) { diff --git a/rtgui/cropwindow.h b/rtgui/cropwindow.h index 74cc318c4..089fcb8a4 100644 --- a/rtgui/cropwindow.h +++ b/rtgui/cropwindow.h @@ -104,6 +104,7 @@ class CropWindow : public LWButtonListener, public CropDisplayHandler, public Ed void drawUnscaledSpotRectangle (Cairo::RefPtr cr, int rectSize); void drawObservedFrame (Cairo::RefPtr cr, int rw = 0, int rh = 0); void changeZoom (int zoom, bool notify = true, int centerx = -1, int centery = -1); + void updateHoveredPicker (rtengine::Coord &imgPos); LockableColorPicker::Validity checkValidity (LockableColorPicker* picker, const rtengine::Coord &pos); @@ -166,6 +167,7 @@ public: bool isInside (int x, int y); + void scroll (int state, GdkScrollDirection direction, int x, int y); void buttonPress (int button, int num, int state, int x, int y); void buttonRelease (int button, int num, int state, int x, int y); void pointerMoved (int bstate, int x, int y); diff --git a/rtgui/imagearea.cc b/rtgui/imagearea.cc index f21cd1b94..c09051e4f 100644 --- a/rtgui/imagearea.cc +++ b/rtgui/imagearea.cc @@ -274,18 +274,8 @@ bool ImageArea::on_scroll_event (GdkEventScroll* event) { CropWindow* cw = getCropWindow (event->x, event->y); - if (cw) { - int newCenterX = (int)event->x; - int newCenterY = (int)event->y; - - cw->screenCoordToImage(newCenterX, newCenterY, newCenterX, newCenterY); - - if (event->direction == GDK_SCROLL_UP && !cw->isMaxZoom()) { - cw->zoomIn (true, newCenterX, newCenterY); - } else if (!cw->isMinZoom()) { - cw->zoomOut (true, newCenterX, newCenterY); - } + cw->scroll (event->state, event->direction, event->x, event->y); } return true; diff --git a/rtgui/lockablecolorpicker.cc b/rtgui/lockablecolorpicker.cc index 351787121..1d1da9b5c 100644 --- a/rtgui/lockablecolorpicker.cc +++ b/rtgui/lockablecolorpicker.cc @@ -38,12 +38,12 @@ LockableColorPicker::LockableColorPicker (int x, int y, Size size, const float R r(R), g(G), b(B), L(0.f), a(0.f), bb(0.f) { 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(r*65535.f, g*65535.f, b*65535.f, h_, s_, v_); h = (int)(h_*255.f); s = (int)(s_*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? + rtengine::Color::rgb2lab (*outputProfile, *workingProfile, r * 65535.f, g * 65535.f, b * 65535.f, L, a, bb, options.rtSettings.HistogramWorking); // TODO: Really sure this function works? } void LockableColorPicker::updateBackBuffer () @@ -66,21 +66,29 @@ void LockableColorPicker::updateBackBuffer () switch (displayedValues) { case ColorPickerType::RGB: - layout[0][0] = iArea->create_pango_layout(M("NAVIGATOR_R") + " "); + layout[0][0] = iArea->create_pango_layout(M("NAVIGATOR_R")); layout[0][1] = iArea->create_pango_layout(Glib::ustring::format(std::fixed, std::setprecision(0), (int)(r*255.f))); - layout[1][0] = iArea->create_pango_layout(M("NAVIGATOR_G") + " "); + layout[1][0] = iArea->create_pango_layout(M("NAVIGATOR_G")); layout[1][1] = iArea->create_pango_layout(Glib::ustring::format(std::fixed, std::setprecision(0), (int)(g*255.f))); - layout[2][0] = iArea->create_pango_layout(M("NAVIGATOR_B") + " "); + layout[2][0] = iArea->create_pango_layout(M("NAVIGATOR_B")); layout[2][1] = iArea->create_pango_layout(Glib::ustring::format(std::fixed, std::setprecision(0), (int)(b*255.f))); break; case ColorPickerType::HSV: - default: - layout[0][0] = iArea->create_pango_layout(M("NAVIGATOR_H") + " "); + layout[0][0] = iArea->create_pango_layout(M("NAVIGATOR_H")); layout[0][1] = iArea->create_pango_layout(Glib::ustring::format(std::fixed, std::setprecision(0), (int)(h*255.f))); - layout[1][0] = iArea->create_pango_layout(M("NAVIGATOR_S") + " "); + layout[1][0] = iArea->create_pango_layout(M("NAVIGATOR_S")); layout[1][1] = iArea->create_pango_layout(Glib::ustring::format(std::fixed, std::setprecision(0), (int)(s*255.f))); - layout[2][0] = iArea->create_pango_layout(M("NAVIGATOR_V") + " "); + layout[2][0] = iArea->create_pango_layout(M("NAVIGATOR_V")); layout[2][1] = iArea->create_pango_layout(Glib::ustring::format(std::fixed, std::setprecision(0), (int)(v*255.f))); + break; + case ColorPickerType::LAB: + default: + layout[0][0] = iArea->create_pango_layout(M("NAVIGATOR_LAB_L")); + layout[0][1] = iArea->create_pango_layout(Glib::ustring::format(std::fixed, std::setprecision(1), L)); + layout[1][0] = iArea->create_pango_layout(M("NAVIGATOR_LAB_A")); + layout[1][1] = iArea->create_pango_layout(Glib::ustring::format(std::fixed, std::setprecision(1), a)); + layout[2][0] = iArea->create_pango_layout(M("NAVIGATOR_LAB_B")); + layout[2][1] = iArea->create_pango_layout(Glib::ustring::format(std::fixed, std::setprecision(1), bb)); } int w00, w01, w10, w11, w20, w21, h00, h01, h10, h11, h20, h21; @@ -256,12 +264,12 @@ void LockableColorPicker::setPosition (const rtengine::Coord &newPos, const floa b = B; 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(r*65535.f, g*65535.f, b*65535.f, h_, s_, v_); h = (float)h_; s = (float)s_; v = (float)v_; - 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? + rtengine::Color::rgb2lab (*outputProfile, *workingProfile, r * 65535.f, g * 65535.f, b * 65535.f, L, a, bb, options.rtSettings.HistogramWorking); // TODO: Really sure this function works? if (validity != Validity::OUTSIDE) { setDirty(true); @@ -279,12 +287,12 @@ void LockableColorPicker::setRGB (const float R, const float G, const float B) b = B; 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(r*65535.f, g*65535.f, b*65535.f, h_, s_, v_); h = (float)h_; s = (float)s_; v = (float)v_; - 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? + rtengine::Color::rgb2lab (*outputProfile, *workingProfile, r * 65535.f, g * 65535.f, b * 65535.f, L, a, bb, options.rtSettings.HistogramWorking); // TODO: Really sure this function works? if (validity != Validity::OUTSIDE) { setDirty(true); @@ -340,6 +348,17 @@ LockableColorPicker::Size LockableColorPicker::getSize () return size; } +void LockableColorPicker::rollDisplayedValues () +{ + if (displayedValues < ColorPickerType::LAB) { + displayedValues = (ColorPickerType)((int)displayedValues + 1); + } else { + displayedValues = ColorPickerType::RGB; + } + setDirty(true); + +} + void LockableColorPicker::incSize () { if (size < Size::S30) { diff --git a/rtgui/lockablecolorpicker.h b/rtgui/lockablecolorpicker.h index 8be803081..c42f742c4 100644 --- a/rtgui/lockablecolorpicker.h +++ b/rtgui/lockablecolorpicker.h @@ -87,6 +87,7 @@ public: bool isOver (int x, int y); void setValidity (Validity isValid); void setSize (Size newSize); + void rollDisplayedValues (); void incSize (); void decSize (); }; diff --git a/rtgui/toolbar.cc b/rtgui/toolbar.cc index 10137c673..c3b1cae1d 100644 --- a/rtgui/toolbar.cc +++ b/rtgui/toolbar.cc @@ -1,3 +1,4 @@ + /* * This file is part of RawTherapee. * @@ -371,6 +372,9 @@ void ToolBar::colPicker_pressed (GdkEventButton* event) handTool->set_active (false); showColorPickers(true); current = TMColorPicker; + if (pickerListener) { + pickerListener->switchPickerVisibility (showColPickers); + } } else { // Disabling the picker tool, enabling the Hand tool and keeping the "visible pickers" mode handTool->set_active (true);