diff --git a/rtgui/crop.cc b/rtgui/crop.cc index 83efb6a37..a2a0e36ed 100644 --- a/rtgui/crop.cc +++ b/rtgui/crop.cc @@ -836,7 +836,7 @@ void Crop::cropMoved (int &X, int &Y, int &W, int &H) // Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); } -void Crop::cropWidth1Resized (int &X, int &Y, int &W, int &H) +void Crop::cropWidth1Resized (int &X, int &Y, int &W, int &H, float custom_ratio) { int oldXR = nx + nw; @@ -849,8 +849,8 @@ void Crop::cropWidth1Resized (int &X, int &Y, int &W, int &H) W = oldXR; } - if (fixr->get_active()) { - double r = getRatio(); + if (fixr->get_active() || custom_ratio > 0) { + double r = custom_ratio > 0 ? custom_ratio : getRatio(); H = (int)round(W / r); int Hmax = min(ny + nh, maxh - ny); @@ -879,7 +879,7 @@ void Crop::cropWidth1Resized (int &X, int &Y, int &W, int &H) idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false)); } -void Crop::cropWidth2Resized (int &X, int &Y, int &W, int &H) +void Crop::cropWidth2Resized (int &X, int &Y, int &W, int &H, float custom_ratio) { if (W < 0) { @@ -890,8 +890,8 @@ void Crop::cropWidth2Resized (int &X, int &Y, int &W, int &H) W = maxw - nx; } - if (fixr->get_active()) { - double r = getRatio(); + if (fixr->get_active() || custom_ratio > 0) { + double r = custom_ratio > 0 ? custom_ratio : getRatio(); H = (int)round(W / r); int Hmax = min(ny + nh, maxh - ny); @@ -919,7 +919,7 @@ void Crop::cropWidth2Resized (int &X, int &Y, int &W, int &H) idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false)); } -void Crop::cropHeight1Resized (int &X, int &Y, int &W, int &H) +void Crop::cropHeight1Resized (int &X, int &Y, int &W, int &H, float custom_ratio) { int oldYB = ny + nh; @@ -932,8 +932,8 @@ void Crop::cropHeight1Resized (int &X, int &Y, int &W, int &H) H = oldYB; } - if (fixr->get_active()) { - double r = getRatio(); + if (fixr->get_active() || custom_ratio > 0) { + double r = custom_ratio > 0 ? custom_ratio : getRatio(); W = (int)round(H * r); int Wmax = min(nx + nw, maxw - nx); @@ -962,7 +962,7 @@ void Crop::cropHeight1Resized (int &X, int &Y, int &W, int &H) idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false)); } -void Crop::cropHeight2Resized (int &X, int &Y, int &W, int &H) +void Crop::cropHeight2Resized (int &X, int &Y, int &W, int &H, float custom_ratio) { if (H < 0) { @@ -973,8 +973,8 @@ void Crop::cropHeight2Resized (int &X, int &Y, int &W, int &H) H = maxh - ny; } - if (fixr->get_active()) { - double r = getRatio(); + if (fixr->get_active() || custom_ratio > 0) { + double r = custom_ratio > 0 ? custom_ratio : getRatio(); W = (int)round(H * r); int Wmax = min(nx + nw, maxw - nx); @@ -1002,7 +1002,7 @@ void Crop::cropHeight2Resized (int &X, int &Y, int &W, int &H) idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false)); } -void Crop::cropTopLeftResized (int &X, int &Y, int &W, int &H) +void Crop::cropTopLeftResized (int &X, int &Y, int &W, int &H, float custom_ratio) { int oldXR = nx + nw; // right side @@ -1024,8 +1024,8 @@ void Crop::cropTopLeftResized (int &X, int &Y, int &W, int &H) H = oldYB; } - if (fixr->get_active()) { - double r = getRatio(); + if (fixr->get_active() || custom_ratio > 0) { + double r = custom_ratio > 0 ? custom_ratio : getRatio(); W = (int)round(H * r); if (W > oldXR) { @@ -1044,7 +1044,7 @@ void Crop::cropTopLeftResized (int &X, int &Y, int &W, int &H) idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false)); } -void Crop::cropTopRightResized (int &X, int &Y, int &W, int &H) +void Crop::cropTopRightResized (int &X, int &Y, int &W, int &H, float custom_ratio) { int oldYB = ny + nh; @@ -1065,8 +1065,8 @@ void Crop::cropTopRightResized (int &X, int &Y, int &W, int &H) H = oldYB; } - if (fixr->get_active()) { - double r = getRatio(); + if (fixr->get_active() || custom_ratio > 0) { + double r = custom_ratio > 0 ? custom_ratio : getRatio(); W = (int)round(H * r); if (W > maxw - nx) { @@ -1084,7 +1084,7 @@ void Crop::cropTopRightResized (int &X, int &Y, int &W, int &H) idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false)); } -void Crop::cropBottomLeftResized (int &X, int &Y, int &W, int &H) +void Crop::cropBottomLeftResized (int &X, int &Y, int &W, int &H, float custom_ratio) { int oldXR = nx + nw; @@ -1105,8 +1105,8 @@ void Crop::cropBottomLeftResized (int &X, int &Y, int &W, int &H) H = maxh - ny; } - if (fixr->get_active()) { - double r = getRatio(); + if (fixr->get_active() || custom_ratio > 0) { + double r = custom_ratio > 0 ? custom_ratio : getRatio(); W = (int)round(H * r); if (W > oldXR) { @@ -1124,7 +1124,7 @@ void Crop::cropBottomLeftResized (int &X, int &Y, int &W, int &H) idle_register.add(refreshSpinsUI, new RefreshSpinHelper(this, false)); } -void Crop::cropBottomRightResized (int &X, int &Y, int &W, int &H) +void Crop::cropBottomRightResized (int &X, int &Y, int &W, int &H, float custom_ratio) { if (W < 0) { @@ -1143,8 +1143,8 @@ void Crop::cropBottomRightResized (int &X, int &Y, int &W, int &H) H = maxh - ny; } - if (fixr->get_active()) { - double r = getRatio(); + if (fixr->get_active() || custom_ratio > 0) { + double r = custom_ratio > 0 ? custom_ratio : getRatio(); W = (int)round(H * r); if (W > maxw - nx) { diff --git a/rtgui/crop.h b/rtgui/crop.h index e0bad8b36..4c2d7a209 100644 --- a/rtgui/crop.h +++ b/rtgui/crop.h @@ -69,14 +69,14 @@ public: void writeOptions (); void cropMoved (int &x, int &y, int &w, int &h); - void cropWidth1Resized (int &x, int &y, int &w, int &h); - void cropWidth2Resized (int &x, int &y, int &w, int &h); - void cropHeight1Resized (int &x, int &y, int &w, int &h); - void cropHeight2Resized (int &x, int &y, int &w, int &h); - void cropTopLeftResized (int &x, int &y, int &w, int &h); - void cropTopRightResized (int &x, int &y, int &w, int &h); - void cropBottomLeftResized (int &x, int &y, int &w, int &h); - void cropBottomRightResized (int &x, int &y, int &w, int &h); + void cropWidth1Resized (int &x, int &y, int &w, int &h, float custom_ratio=0.f); + void cropWidth2Resized (int &x, int &y, int &w, int &h, float custom_ratio=0.f); + void cropHeight1Resized (int &x, int &y, int &w, int &h, float custom_ratio=0.f); + void cropHeight2Resized (int &x, int &y, int &w, int &h, float custom_ratio=0.f); + void cropTopLeftResized (int &x, int &y, int &w, int &h, float custom_ratio=0.f); + void cropTopRightResized (int &x, int &y, int &w, int &h, float custom_ratio=0.f); + void cropBottomLeftResized (int &x, int &y, int &w, int &h, float custom_ratio=0.f); + void cropBottomRightResized (int &x, int &y, int &w, int &h, float custom_ratio=0.f); void cropInit (int &x, int &y, int &w, int &h); void cropResized (int &x, int &y, int& x2, int& y2); void cropManipReady (); diff --git a/rtgui/cropguilistener.h b/rtgui/cropguilistener.h index 5124ece5f..239e9d002 100644 --- a/rtgui/cropguilistener.h +++ b/rtgui/cropguilistener.h @@ -25,14 +25,14 @@ class CropGUIListener public: virtual ~CropGUIListener() {} virtual void cropMoved (int &x, int &y, int &w, int &h) = 0; - virtual void cropWidth1Resized (int &x, int &y, int &w, int &h) = 0; - virtual void cropWidth2Resized (int &x, int &y, int &w, int &h) = 0; - virtual void cropHeight1Resized (int &x, int &y, int &w, int &h) = 0; - virtual void cropHeight2Resized (int &x, int &y, int &w, int &h) = 0; - virtual void cropTopLeftResized (int &x, int &y, int &w, int &h) = 0; - virtual void cropTopRightResized (int &x, int &y, int &w, int &h) = 0; - virtual void cropBottomLeftResized (int &x, int &y, int &w, int &h) = 0; - virtual void cropBottomRightResized (int &x, int &y, int &w, int &h) = 0; + virtual void cropWidth1Resized (int &x, int &y, int &w, int &h, float custom_ratio=0.f) = 0; + virtual void cropWidth2Resized (int &x, int &y, int &w, int &h, float custom_ratio=0.f) = 0; + virtual void cropHeight1Resized (int &x, int &y, int &w, int &h, float custom_ratio=0.f) = 0; + virtual void cropHeight2Resized (int &x, int &y, int &w, int &h, float custom_ratio=0.f) = 0; + virtual void cropTopLeftResized (int &x, int &y, int &w, int &h, float custom_ratio=0.f) = 0; + virtual void cropTopRightResized (int &x, int &y, int &w, int &h, float custom_ratio=0.f) = 0; + virtual void cropBottomLeftResized (int &x, int &y, int &w, int &h, float custom_ratio=0.f) = 0; + virtual void cropBottomRightResized (int &x, int &y, int &w, int &h, float custom_ratio=0.f) = 0; virtual void cropInit (int &x, int &y, int &w, int &h) = 0; virtual void cropResized (int &x, int &y, int& x2, int& y2) = 0; virtual void cropManipReady () = 0; diff --git a/rtgui/cropwindow.cc b/rtgui/cropwindow.cc index 4af132cea..5dde256f6 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -759,6 +759,8 @@ void CropWindow::pointerMoved (int bstate, int x, int y) EditSubscriber *editSubscriber = iarea->getCurrSubscriber(); + float cur_crop_ratio = (bstate & GDK_SHIFT_MASK) && cropHandler.cropParams.w > 0 && cropHandler.cropParams.h > 0 ? float(cropHandler.cropParams.w) / float(cropHandler.cropParams.h) : 0.0; + if (state == SCropWinMove) { setPosition (press_x + x - action_x, press_y + y - action_y); iarea->redraw (); @@ -807,21 +809,21 @@ void CropWindow::pointerMoved (int bstate, int x, int y) int oy = cropHandler.cropParams.y; cropHandler.cropParams.y = action_y + (y - press_y) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.h += oy - cropHandler.cropParams.y; - cropgl->cropHeight1Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + cropgl->cropHeight1Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, cur_crop_ratio); iarea->redraw (); } else if (state == SResizeH2 && cropgl) { cropHandler.cropParams.h = action_y + (y - press_y) / zoomSteps[cropZoom].zoom; - cropgl->cropHeight2Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + cropgl->cropHeight2Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, cur_crop_ratio); iarea->redraw (); } else if (state == SResizeW1 && cropgl) { int ox = cropHandler.cropParams.x; cropHandler.cropParams.x = action_x + (x - press_x) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.w += ox - cropHandler.cropParams.x; - cropgl->cropWidth1Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + cropgl->cropWidth1Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, cur_crop_ratio); iarea->redraw (); } else if (state == SResizeW2 && cropgl) { cropHandler.cropParams.w = action_x + (x - press_x) / zoomSteps[cropZoom].zoom; - cropgl->cropWidth2Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + cropgl->cropWidth2Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, cur_crop_ratio); iarea->redraw (); } else if (state == SResizeTL && cropgl) { int ox = cropHandler.cropParams.x; @@ -830,26 +832,26 @@ void CropWindow::pointerMoved (int bstate, int x, int y) int oy = cropHandler.cropParams.y; cropHandler.cropParams.y = action_y + (y - press_y) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.h += oy - cropHandler.cropParams.y; - cropgl->cropTopLeftResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + cropgl->cropTopLeftResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, cur_crop_ratio); iarea->redraw (); } else if (state == SResizeTR && cropgl) { cropHandler.cropParams.w = action_x + (x - press_x) / zoomSteps[cropZoom].zoom; int oy = cropHandler.cropParams.y; cropHandler.cropParams.y = action_y + (y - press_y) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.h += oy - cropHandler.cropParams.y; - cropgl->cropTopRightResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + cropgl->cropTopRightResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, cur_crop_ratio); iarea->redraw (); } else if (state == SResizeBL && cropgl) { int ox = cropHandler.cropParams.x; cropHandler.cropParams.x = action_x + (x - press_x) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.w += ox - cropHandler.cropParams.x; cropHandler.cropParams.h = action_y + (y - press_y) / zoomSteps[cropZoom].zoom; - cropgl->cropBottomLeftResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + cropgl->cropBottomLeftResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, cur_crop_ratio); iarea->redraw (); } else if (state == SResizeBR && cropgl) { cropHandler.cropParams.w = action_x + (x - press_x) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.h = action_y + (y - press_y) / zoomSteps[cropZoom].zoom; - cropgl->cropBottomRightResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); + cropgl->cropBottomRightResized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h, cur_crop_ratio); iarea->redraw (); } else if (state == SCropMove && cropgl) { cropHandler.cropParams.x = action_x + (x - press_x) / zoomSteps[cropZoom].zoom; diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index b5d6ef2d5..ceab1c1d3 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -38,7 +38,7 @@ Glib::RefPtr FileBrowserEntry::recentlySavedIcon; Glib::RefPtr FileBrowserEntry::enqueuedIcon; FileBrowserEntry::FileBrowserEntry (Thumbnail* thm, const Glib::ustring& fname) - : ThumbBrowserEntryBase (fname), wasInside(false), iatlistener(nullptr), cropgl(nullptr), state(SNormal) + : ThumbBrowserEntryBase (fname), wasInside(false), iatlistener(nullptr), cropgl(nullptr), state(SNormal), crop_custom_ratio(0.f) { thumbnail = thm; @@ -322,24 +322,24 @@ bool FileBrowserEntry::motionNotify (int x, int y) int oy = cropParams.y; cropParams.y = action_y + (y - press_y) / scale; cropParams.h += oy - cropParams.y; - cropgl->cropHeight1Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + cropgl->cropHeight1Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h, crop_custom_ratio); updateBackBuffer (); parent->redrawNeeded (this); } else if (state == SResizeH2 && cropgl) { cropParams.h = action_y + (y - press_y) / scale; - cropgl->cropHeight2Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + cropgl->cropHeight2Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h, crop_custom_ratio); updateBackBuffer (); parent->redrawNeeded (this); } else if (state == SResizeW1 && cropgl) { int ox = cropParams.x; cropParams.x = action_x + (x - press_x) / scale; cropParams.w += ox - cropParams.x; - cropgl->cropWidth1Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + cropgl->cropWidth1Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h, crop_custom_ratio); updateBackBuffer (); parent->redrawNeeded (this); } else if (state == SResizeW2 && cropgl) { cropParams.w = action_x + (x - press_x) / scale; - cropgl->cropWidth2Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + cropgl->cropWidth2Resized (cropParams.x, cropParams.y, cropParams.w, cropParams.h, crop_custom_ratio); updateBackBuffer (); parent->redrawNeeded (this); } else if (state == SResizeTL && cropgl) { @@ -349,7 +349,7 @@ bool FileBrowserEntry::motionNotify (int x, int y) int oy = cropParams.y; cropParams.y = action_y + (y - press_y) / scale; cropParams.h += oy - cropParams.y; - cropgl->cropTopLeftResized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + cropgl->cropTopLeftResized (cropParams.x, cropParams.y, cropParams.w, cropParams.h, crop_custom_ratio); updateBackBuffer (); parent->redrawNeeded (this); } else if (state == SResizeTR && cropgl) { @@ -357,7 +357,7 @@ bool FileBrowserEntry::motionNotify (int x, int y) int oy = cropParams.y; cropParams.y = action_y + (y - press_y) / scale; cropParams.h += oy - cropParams.y; - cropgl->cropTopRightResized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + cropgl->cropTopRightResized (cropParams.x, cropParams.y, cropParams.w, cropParams.h, crop_custom_ratio); updateBackBuffer (); parent->redrawNeeded (this); } else if (state == SResizeBL && cropgl) { @@ -365,13 +365,13 @@ bool FileBrowserEntry::motionNotify (int x, int y) cropParams.x = action_x + (x - press_x) / scale; cropParams.w += ox - cropParams.x; cropParams.h = action_y + (y - press_y) / scale; - cropgl->cropBottomLeftResized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + cropgl->cropBottomLeftResized (cropParams.x, cropParams.y, cropParams.w, cropParams.h, crop_custom_ratio); updateBackBuffer (); parent->redrawNeeded (this); } else if (state == SResizeBR && cropgl) { cropParams.w = action_x + (x - press_x) / scale; cropParams.h = action_y + (y - press_y) / scale; - cropgl->cropBottomRightResized (cropParams.x, cropParams.y, cropParams.w, cropParams.h); + cropgl->cropBottomRightResized (cropParams.x, cropParams.y, cropParams.w, cropParams.h, crop_custom_ratio); updateBackBuffer (); parent->redrawNeeded (this); } else if (state == SCropMove && cropgl) { @@ -425,8 +425,13 @@ bool FileBrowserEntry::pressNotify (int button, int type, int bstate, int x, i return b; } + crop_custom_ratio = 0.f; + if (!b && selected && inside (x, y)) { if (button == 1 && type == GDK_BUTTON_PRESS && state == SNormal) { + if ((bstate & GDK_SHIFT_MASK) && cropParams.w > 0 && cropParams.h > 0) { + crop_custom_ratio = float(cropParams.w) / float(cropParams.h); + } if (onArea (CropTopLeft, ix, iy)) { state = SResizeTL; press_x = x; diff --git a/rtgui/filebrowserentry.h b/rtgui/filebrowserentry.h index cbbe2c595..4c3d519ab 100644 --- a/rtgui/filebrowserentry.h +++ b/rtgui/filebrowserentry.h @@ -56,6 +56,7 @@ class FileBrowserEntry : public ThumbBrowserEntryBase, FileBrowserEntryIdleHelper* feih; ImgEditState state; + float crop_custom_ratio; IdleRegister idle_register;