From feed87d046c598a9d483600b4b1653b0ba0aed01 Mon Sep 17 00:00:00 2001 From: Alberto Griggio Date: Thu, 16 Mar 2017 14:33:26 +0100 Subject: [PATCH] adding more zoom levels to the image editor --- rtgui/crophandler.cc | 43 +++++++++++---------- rtgui/cropwindow.cc | 91 ++++++++++++++++++++++---------------------- rtgui/cropwindow.h | 13 +++++++ 3 files changed, 82 insertions(+), 65 deletions(-) diff --git a/rtgui/crophandler.cc b/rtgui/crophandler.cc index 42c6eb756..28be67705 100644 --- a/rtgui/crophandler.cc +++ b/rtgui/crophandler.cc @@ -30,7 +30,7 @@ using namespace rtengine; CropHandler::CropHandler () - : zoom(10), ww(0), wh(0), imx(-1), imy(-1), imw(0), imh(0), cax(-1), cay(-1), + : zoom(100), ww(0), wh(0), imx(-1), imy(-1), imw(0), imh(0), cax(-1), cay(-1), cx(0), cy(0), cw(0), ch(0), cropX(0), cropY(0), cropW(0), cropH(0), enabled(false), cropimg(nullptr), cropimgtrue(nullptr), cropimg_width(0), cropimg_height(0), cix(0), ciy(0), ciw(0), cih(0), cis(1), @@ -145,8 +145,8 @@ void CropHandler::setZoom (int z, int centerx, int centery) assert (ipc); int oldZoom = zoom; - float oldScale = zoom >= 1000 ? float(zoom / 1000) : 1.f / float(zoom); - float newScale = z >= 1000 ? float(z / 1000) : 1.f / float(z); + float oldScale = zoom >= 1000 ? float(zoom / 1000) : 10.f / float(zoom); + float newScale = z >= 1000 ? float(z / 1000) : 10.f / float(z); int oldcax = cax; int oldcay = cay; @@ -176,8 +176,8 @@ void CropHandler::setZoom (int z, int centerx, int centery) cw = ww * 1000 / zoom; ch = wh * 1000 / zoom; } else { - cw = ww * zoom; - ch = wh * zoom; + cw = ww * zoom / 10; + ch = wh * zoom / 10; } cx = cax - cw / 2; @@ -206,7 +206,7 @@ float CropHandler::getZoomFactor () if (zoom >= 1000) { return zoom / 1000; } else { - return 1.f / (float)zoom; + return 10.f / (float)zoom; } } @@ -221,8 +221,8 @@ void CropHandler::setWSize (int w, int h) cw = ww * 1000 / zoom; ch = wh * 1000 / zoom; } else { - cw = ww * zoom; - ch = wh * zoom; + cw = ww * zoom/10; + ch = wh * zoom/10; } compDim (); @@ -320,7 +320,7 @@ void CropHandler::setDetailedCrop (IImage8* im, IImage8* imtrue, rtengine::procp cropimgtrue = nullptr; - if (ax == cropX && ay == cropY && aw == cropW && ah == cropH && askip == (zoom >= 1000 ? 1 : zoom)) { + if (ax == cropX && ay == cropY && aw == cropW && ah == cropH && askip == (zoom >= 1000 ? 1 : zoom/10)) { cropimg_width = im->getWidth (); cropimg_height = im->getHeight (); cropimg = new unsigned char [3 * cropimg_width * cropimg_height]; @@ -362,11 +362,14 @@ void CropHandler::setDetailedCrop (IImage8* im, IImage8* imtrue, rtengine::procp } if (ch->cropimg) { - if (ch->cix == ch->cropX && ch->ciy == ch->cropY && ch->ciw == ch->cropW && ch->cih == ch->cropH && ch->cis == (ch->zoom >= 1000 ? 1 : ch->zoom)) { + if (ch->cix == ch->cropX && ch->ciy == ch->cropY && ch->ciw == ch->cropW && ch->cih == ch->cropH && ch->cis == (ch->zoom >= 1000 ? 1 : ch->zoom/10)) { // calculate final image size - int czoom = ch->zoom < 1000 ? 1000 : ch->zoom; - int imw = ch->cropimg_width * czoom / 1000; - int imh = ch->cropimg_height * czoom / 1000; + //int czoom = ch->zoom < 1000 ? 1000 : ch->zoom; + float czoom = ch->zoom >= 1000 ? + ch->zoom / 1000.f : + float((ch->zoom/10) * 10) / float(ch->zoom); + int imw = ch->cropimg_width * czoom;// / 1000; + int imh = ch->cropimg_height * czoom;// / 1000; if (imw > ch->ww) { imw = ch->ww; @@ -378,12 +381,12 @@ void CropHandler::setDetailedCrop (IImage8* im, IImage8* imtrue, rtengine::procp Glib::RefPtr tmpPixbuf = Gdk::Pixbuf::create_from_data (ch->cropimg, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, 2 * ch->cropimg_height, 3 * ch->cropimg_width); ch->cropPixbuf = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh); - tmpPixbuf->scale (ch->cropPixbuf, 0, 0, imw, imh, 0, 0, czoom / 1000.0, czoom / 1000.0, Gdk::INTERP_NEAREST); + tmpPixbuf->scale (ch->cropPixbuf, 0, 0, imw, imh, 0, 0, czoom /* / 1000.0*/, czoom /* / 1000.0*/, Gdk::INTERP_NEAREST); tmpPixbuf.clear (); Glib::RefPtr tmpPixbuftrue = Gdk::Pixbuf::create_from_data (ch->cropimgtrue, Gdk::COLORSPACE_RGB, false, 8, ch->cropimg_width, 2 * ch->cropimg_height, 3 * ch->cropimg_width); ch->cropPixbuftrue = Gdk::Pixbuf::create (Gdk::COLORSPACE_RGB, false, 8, imw, imh); - tmpPixbuftrue->scale (ch->cropPixbuftrue, 0, 0, imw, imh, 0, 0, czoom / 1000.0, czoom / 1000.0, Gdk::INTERP_NEAREST); + tmpPixbuftrue->scale (ch->cropPixbuftrue, 0, 0, imw, imh, 0, 0, czoom /* / 1000.0*/, czoom /* / 1000.0*/, Gdk::INTERP_NEAREST); tmpPixbuftrue.clear (); } @@ -432,7 +435,7 @@ bool CropHandler::getWindow (int& cwx, int& cwy, int& cww, int& cwh, int& cskip) cwh = 32; } - cskip = zoom >= 1000 ? 1 : zoom; + cskip = zoom >= 1000 ? 1 : zoom/10; return true; } @@ -615,12 +618,12 @@ void CropHandler::compDim () scaledCAX = cax * (zoom/1000); scaledCAY = cay * (zoom/1000); } else { - wwImgSpace = int(float(ww) * float(zoom) + 0.5f); - whImgSpace = int(float(wh) * float(zoom) + 0.5f); + wwImgSpace = int(float(ww) * (float(zoom)/10.f) + 0.5f); + whImgSpace = int(float(wh) * (float(zoom)/10.f) + 0.5f); //scaledFullW = fullW / zoom; //scaledFullH = fullH / zoom; - scaledCAX = cax / zoom; - scaledCAY = cay / zoom; + scaledCAX = int(float(cax) / (float(zoom)/10.f)); + scaledCAY = int(float(cay) / (float(zoom)/10.f)); } imgX = ww / 2 - scaledCAX; diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index 46c956436..0dbece639 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -34,38 +34,6 @@ using namespace rtengine; -struct ZoomStep { - Glib::ustring label; - double zoom; - int czoom; -}; - -ZoomStep zoomSteps[] = { - {" 1%", 0.01, 100}, - {" 2%", 0.02, 50}, - {" 5%", 0.05, 20}, - {"6.7%", 1.0 / 15.0, 15}, - {" 8%", 1.0 / 12.0, 12}, - {" 10%", 0.1, 10}, - {"12.5%", 0.125, 8}, - {" 14%", 1.0 / 7.0, 7}, - {"16.6%", 1.0 / 6.0, 6}, - {" 20%", 0.2, 5}, - {" 25%", 0.25, 4}, - {" 33%", 1.0 / 3.0, 3}, - {" 50%", 0.5, 2}, - {"100%", 1.0, 1000}, - {"200%", 2.0, 2000}, - {"300%", 3.0, 3000}, - {"400%", 4.0, 4000}, - {"500%", 5.0, 5000}, - {"600%", 6.0, 6000}, - {"700%", 7.0, 7000}, - {"800%", 8.0, 8000} -}; -#define MAXZOOMSTEPS 20 -#define ZOOM11INDEX 13 - CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDetailWindow) : ObjectMOBuffer(parent), state(SNormal), press_x(0), press_y(0), action_x(0), action_y(0), pickedObject(-1), pickModifierKey(0), rot_deg(0), onResizeArea(false), deleted(false), fitZoomEnabled(true), fitZoom(false), isLowUpdatePriority(isLowUpdatePriority_), hoveredPicker(nullptr), cropLabel(Glib::ustring("100%")), @@ -74,6 +42,8 @@ CropWindow::CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDet imgX(-1), imgY(-1), imgW(1), imgH(1), iarea(parent), cropZoom(0), zoomVersion(0), exposeVersion(0), cropgl(nullptr), pmlistener(nullptr), pmhlistener(nullptr), observedCropWin(nullptr) { + initZoomSteps(); + Glib::RefPtr context = parent->get_pango_context () ; Pango::FontDescription fontd = context->get_font_description (); fontd.set_weight (Pango::WEIGHT_BOLD); @@ -120,6 +90,37 @@ CropWindow::~CropWindow () } } + +void CropWindow::initZoomSteps() +{ + zoomSteps.push_back(ZoomStep(" 1%", 0.01, 999)); + zoomSteps.push_back(ZoomStep(" 2%", 0.02, 500)); + zoomSteps.push_back(ZoomStep(" 5%", 0.05, 200)); + zoomSteps.push_back(ZoomStep(" 6%", 1.0/15.0, 150)); + zoomSteps.push_back(ZoomStep(" 8%", 1.0/12.0, 120)); + char lbl[64]; + for (int s = 100; s >= 50; s -= 5) { + float z = 10./float(s); + sprintf(lbl, "% 2d%%", int(z * 100)); + zoomSteps.push_back(ZoomStep(lbl, z, s)); + } + for (int s = 45; s >= 27; s -= 3) { + float z = 10./float(s); + sprintf(lbl, "% 2d%%", int(z * 100)); + zoomSteps.push_back(ZoomStep(lbl, z, s)); + } + for (int s = 25; s >= 11; --s) { + float z = 10./float(s); + sprintf(lbl, "% 2d%%", int(z * 100)); + zoomSteps.push_back(ZoomStep(lbl, z, s)); + } + zoom11index = zoomSteps.size(); + for (int s = 1; s <= 8; ++s) { + sprintf(lbl, "%d00", s); + zoomSteps.push_back(ZoomStep(lbl, s, s * 1000)); + } +} + void CropWindow::enable() { cropHandler.setEnabled (true); @@ -316,7 +317,7 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y) state = SNormal; zoomVersion = exposeVersion; screenCoordToImage (x, y, action_x, action_y); - changeZoom (ZOOM11INDEX, true, action_x, action_y); + changeZoom (zoom11index, true, action_x, action_y); fitZoom = false; } else { zoomFit (); @@ -1967,7 +1968,7 @@ void CropWindow::zoom11 () zoomVersion = exposeVersion; } - changeZoom (ZOOM11INDEX, true, x, y); + changeZoom (zoom11index, true, x, y); fitZoom = false; } @@ -1984,17 +1985,17 @@ bool CropWindow::isMinZoom () bool CropWindow::isMaxZoom () { - return cropZoom >= MAXZOOMSTEPS; + return cropZoom >= int(zoomSteps.size())-1; } void CropWindow::setZoom (double zoom) { - int cz = MAXZOOMSTEPS; + int cz = int(zoomSteps.size())-1; if (zoom < zoomSteps[0].zoom) { cz = 0; } else - for (int i = 0; i < MAXZOOMSTEPS; i++) + for (int i = 0; i < int(zoomSteps.size())-1; i++) if (zoomSteps[i].zoom <= zoom && zoomSteps[i + 1].zoom > zoom) { cz = i; break; @@ -2006,12 +2007,12 @@ void CropWindow::setZoom (double zoom) double CropWindow::getZoomFitVal () { double z = cropHandler.getFitZoom (); - int cz = MAXZOOMSTEPS; + int cz = int(zoomSteps.size())-1; if (z < zoomSteps[0].zoom) { cz = 0; } else - for (int i = 0; i < MAXZOOMSTEPS; i++) + for (int i = 0; i < int(zoomSteps.size())-1; i++) if (zoomSteps[i].zoom <= z && zoomSteps[i + 1].zoom > z) { cz = i; break; @@ -2025,12 +2026,12 @@ void CropWindow::zoomFit () { double z = cropHandler.getFitZoom (); - int cz = MAXZOOMSTEPS; + int cz = int(zoomSteps.size())-1; if (z < zoomSteps[0].zoom) { cz = 0; } else - for (int i = 0; i < MAXZOOMSTEPS; i++) + for (int i = 0; i < int(zoomSteps.size())-1; i++) if (zoomSteps[i].zoom <= z && zoomSteps[i + 1].zoom > z) { cz = i; break; @@ -2045,12 +2046,12 @@ void CropWindow::zoomFitCrop () { if(cropHandler.cropParams.enabled) { double z = cropHandler.getFitCropZoom (); - int cz = MAXZOOMSTEPS; + int cz = int(zoomSteps.size())-1; if (z < zoomSteps[0].zoom) { cz = 0; } else - for (int i = 0; i < MAXZOOMSTEPS; i++) + for (int i = 0; i < int(zoomSteps.size())-1; i++) if (zoomSteps[i].zoom <= z && zoomSteps[i + 1].zoom > z) { cz = i; break; @@ -2125,8 +2126,8 @@ void CropWindow::changeZoom (int zoom, bool notify, int centerx, int centery) if (zoom < 0) { zoom = 0; - } else if (zoom > MAXZOOMSTEPS) { - zoom = MAXZOOMSTEPS; + } else if (zoom > int(zoomSteps.size())-1) { + zoom = int(zoomSteps.size())-1; } cropZoom = zoom; diff --git a/rtgui/cropwindow.h b/rtgui/cropwindow.h index 52418e750..935928b88 100644 --- a/rtgui/cropwindow.h +++ b/rtgui/cropwindow.h @@ -114,6 +114,19 @@ class CropWindow : public LWButtonListener, public CropDisplayHandler, public Ed // Used by the mainCropWindow only void getObservedFrameArea (int& x, int& y, int& w, int& h, int rw = 0, int rh = 0); + struct ZoomStep { + Glib::ustring label; + double zoom; + int czoom; + + explicit ZoomStep(const Glib::ustring &l="", double z=0.0, int cz=0): + label(l), zoom(z), czoom(cz) {} + }; + std::vector zoomSteps; + size_t zoom11index; + + void initZoomSteps(); + public: CropHandler cropHandler; CropWindow (ImageArea* parent, bool isLowUpdatePriority_, bool isDetailWindow);