From a72a8811ec7bc34a8de03353b3539c652bcc2cf9 Mon Sep 17 00:00:00 2001 From: torger Date: Thu, 7 Nov 2013 08:11:51 +0100 Subject: [PATCH] Issue 2025: crop box can now be grabbed in the corners --- rtgui/crop.cc | 300 +++++++++++++++++++++----------------- rtgui/crop.h | 7 +- rtgui/cropguilistener.h | 4 + rtgui/cropwindow.cc | 117 ++++++++++++++- rtgui/cursormanager.cc | 12 ++ rtgui/cursormanager.h | 6 +- rtgui/editenums.h | 4 +- rtgui/filebrowserentry.cc | 118 ++++++++++++++- 8 files changed, 427 insertions(+), 141 deletions(-) diff --git a/rtgui/crop.cc b/rtgui/crop.cc index 6f37a1f2e..f7f5530c1 100644 --- a/rtgui/crop.cc +++ b/rtgui/crop.cc @@ -741,158 +741,194 @@ void Crop::cropMoved (int &X, int &Y, int &W, int &H) { void Crop::cropWidth1Resized (int &X, int &Y, int &W, int &H) { - if (W<0) - W = 0; - if (H<0) - H = 0; - - if (X<0) { - W += X; - X = 0; - } - if (fixr->get_active()) { - double r = getRatio(); - int W2max = min(maxw, (int)round(r*maxh)); - if (W>W2max) { - X += W - W2max; - W = W2max; + int oldXR = nx + nw; + if (W < 0) W = 0; + if (W > oldXR) W = oldXR; + if (fixr->get_active()) { + double r = getRatio(); + H = (int)round(W / r); + if (H > maxh) { + H = maxh; + W = H * r; + } + ny = ny - (H - nh) / 2.0; + if (ny < 0) ny = 0; + if (ny + H > maxh) ny = maxh - H; } - int oldH = H; - H = (int)round(W / r); - Y = Y - (H - oldH) / 2; - if (X + W > maxw) - X = maxw - W; - if (Y + H > maxh) - Y = maxh - H; - else if (Y < 0) - Y = 0; - } + X = oldXR - W; + Y = ny; + nx = X; + nw = W; + nh = H; - nx = X; - ny = Y; - nw = W; - nh = H; - - g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); -// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); } void Crop::cropWidth2Resized (int &X, int &Y, int &W, int &H) { -// X = x->get_value (); -// Y = y->get_value (); - X = nx; - Y = ny; + if (W < 0) W = 0; + if (W > maxw - nx) W = maxw - nx; + if (fixr->get_active()) { + double r = getRatio(); + H = (int)round(W / r); + if (H > maxh) { + H = maxh; + W = H * r; + } + ny = ny - (H - nh) / 2.0; + if (ny < 0) ny = 0; + if (ny + H > maxh) ny = maxh - H; + } + X = nx; + Y = ny; + nw = W; + nh = H; - if (W<0) - W = 0; - if (H<0) - H = 0; - - if (W>maxw-X) - W = maxw-X; - - if (fixr->get_active()) { - double r = getRatio(); - int W2max = min(maxw, (int)round(r*maxh)); - if (W>W2max) - W = W2max; - int oldH = H; - H = (int)round(W / r); - Y = Y - (H - oldH) / 2; - if (X + W > maxw) - X = maxw - W; - if (Y + H > maxh) - Y = maxh - H; - else if (Y < 0) - Y = 0; - } - - nx = X; - ny = Y; - nw = W; - nh = H; - - g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); -// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); } void Crop::cropHeight1Resized (int &X, int &Y, int &W, int &H) { - if (W<0) - W = 0; - if (H<0) - H = 0; - - if (Y<0) { - H += Y; - Y = 0; - } - - if (fixr->get_active()) { - double r = getRatio(); - int H2max = min(maxh, (int)round(maxw / r)); - if (H>H2max) { - Y += H - H2max; - H = H2max; + int oldYB = ny + nh; + if (H < 0) H = 0; + if (H > oldYB) H = oldYB; + if (fixr->get_active()) { + double r = getRatio(); + W = (int)round(H * r); + if (W > maxw) { + W = maxw; + H = W / r; + } + nx = nx - (W - nw) / 2.0; + if (nx < 0) nx = 0; + if (nx + W > maxw) nx = maxw - W; } - int oldW = W; - W = (int)round(H * r); - X = X - (W - oldW) / 2; - if (X + W > maxw) - X = maxw - W; - else if (X < 0) - X = 0; - if (Y + H > maxh) - Y = maxh - H; - } + X = nx; + Y = oldYB - H; + ny = Y; + nw = W; + nh = H; - nx = X; - ny = Y; - nw = W; - nh = H; - - g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); -// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); } void Crop::cropHeight2Resized (int &X, int &Y, int &W, int &H) { -// X = x->get_value (); -// Y = y->get_value (); - X = nx; - Y = ny; + if (H < 0) H = 0; + if (H > maxh - ny) H = maxh - ny; + if (fixr->get_active()) { + double r = getRatio(); + W = (int)round(H * r); + if (W > maxw) { + W = maxw; + H = W / r; + } + nx = nx - (W - nw) / 2.0; // nx must be floating point to avoid drifting + if (nx < 0) nx = 0; + if (nx + W > maxw) nx = maxw - W; + } + X = nx; + Y = ny; + nw = W; + nh = H; - if (W<0) - W = 0; - if (H<0) - H = 0; - int H1max = maxh-Y; - if (H>H1max) - H = H1max; - if (fixr->get_active()) { - double r = getRatio (); - int H2max = min(maxh, (int)round (maxw / r)); - if (H>H2max) - H = H2max; - int oldW = W; - W = (int)round(H * r); - X = X - (W - oldW) / 2; - if (X + W > maxw) - X = maxw - W; - else if (X < 0) - X = 0; - if (Y + H > maxh) - Y = maxh - H; - } + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); +} - nx = X; - ny = Y; - nw = W; - nh = H; +void Crop::cropTopLeftResized (int &X, int &Y, int &W, int &H) { - g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); -// Glib::signal_idle().connect (sigc::mem_fun(*this, &Crop::refreshSpins)); + int oldXR = nx + nw; // right side + int oldYB = ny + nh; // bottom side + if (W < 0) W = 0; + if (H < 0) H = 0; + if (W > oldXR) W = oldXR; + if (H > oldYB) H = oldYB; + if (fixr->get_active()) { + double r = getRatio(); + W = (int)round(H * r); + if (W > oldXR) { + W = oldXR; + H = (int)round(W / r); + } + } + X = oldXR - W; + Y = oldYB - H; + nx = X; + ny = Y; + nw = W; + nh = H; + + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); +} + +void Crop::cropTopRightResized (int &X, int &Y, int &W, int &H) { + + int oldYB = ny + nh; + if (W < 0) W = 0; + if (H < 0) H = 0; + if (W > maxw - nx) W = maxw - nx; + if (H > oldYB) H = oldYB; + if (fixr->get_active()) { + double r = getRatio(); + W = (int)round(H * r); + if (W > maxw - nx) { + W = maxw - nx; + H = (int)round(W / r); + } + } + X = nx; + Y = oldYB - H; + ny = Y; + nw = W; + nh = H; + + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); +} + +void Crop::cropBottomLeftResized (int &X, int &Y, int &W, int &H) { + + int oldXR = nx + nw; + if (W < 0) W = 0; + if (H < 0) H = 0; + if (W > oldXR) W = oldXR; + if (H > maxh - ny) H = maxh - ny; + if (fixr->get_active()) { + double r = getRatio(); + W = (int)round(H * r); + if (W > oldXR) { + W = oldXR; + H = (int)round(W / r); + } + } + X = oldXR - W; + Y = ny; + nx = X; + nw = W; + nh = H; + + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); +} + +void Crop::cropBottomRightResized (int &X, int &Y, int &W, int &H) { + + if (W < 0) W = 0; + if (H < 0) H = 0; + if (W > maxw - nx) W = maxw - nx; + if (H > maxh - ny) H = maxh - ny; + if (fixr->get_active()) { + double r = getRatio(); + W = (int)round(H * r); + if (W > maxw - nx) { + W = maxw - nx; + H = (int)round(W / r); + } + } + X = nx; + Y = ny; + nw = W; + nh = H; + + g_idle_add (refreshSpinsUI, new RefreshSpinHelper (this, false)); } void Crop::cropInit (int &x, int &y, int &w, int &h) { diff --git a/rtgui/crop.h b/rtgui/crop.h index 49a4909bd..6e7ef5310 100644 --- a/rtgui/crop.h +++ b/rtgui/crop.h @@ -59,7 +59,8 @@ class Crop : public Gtk::VBox, public CropGUIListener, public FoldableToolPanel, Gtk::VBox* ppibox; Gtk::VBox* sizebox; int maxw, maxh; - int nx, ny, nw, nh; + double nx, ny; + int nw, nh; int lastRotationDeg; sigc::connection xconn, yconn, wconn, hconn, econn, fconn, rconn, oconn, gconn; bool wDirty, hDirty, xDirty, yDirty, lastEnabled, lastFixRatio; @@ -96,6 +97,10 @@ class Crop : public Gtk::VBox, public CropGUIListener, public FoldableToolPanel, 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 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 c06113c36..dc0a803bc 100644 --- a/rtgui/cropguilistener.h +++ b/rtgui/cropguilistener.h @@ -27,6 +27,10 @@ class CropGUIListener { 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 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 75023c67e..6cd4cc842 100644 --- a/rtgui/cropwindow.cc +++ b/rtgui/cropwindow.cc @@ -266,7 +266,35 @@ void CropWindow::buttonPress (int button, int type, int bstate, int x, int y) { press_y = height; } else if (button==1 && type==GDK_BUTTON_PRESS && state==SNormal && onArea (CropImage, x, y)) { - if (onArea (CropTop, x, y)) { + if (onArea (CropTopLeft, x, y)) { + state = SResizeTL; + press_x = x; + action_x = cropHandler.cropParams.x; + press_y = y; + action_y = cropHandler.cropParams.y; + } + else if (onArea (CropTopRight, x, y)) { + state = SResizeTR; + press_x = x; + action_x = cropHandler.cropParams.w; + press_y = y; + action_y = cropHandler.cropParams.y; + } + else if (onArea (CropBottomLeft, x, y)) { + state = SResizeBL; + press_x = x; + action_x = cropHandler.cropParams.x; + press_y = y; + action_y = cropHandler.cropParams.h; + } + else if (onArea (CropBottomRight, x, y)) { + state = SResizeBR; + press_x = x; + action_x = cropHandler.cropParams.w; + press_y = y; + action_y = cropHandler.cropParams.h; + } + else if (onArea (CropTop, x, y)) { state = SResizeH1; press_y = y; action_y = cropHandler.cropParams.y; @@ -364,7 +392,8 @@ void CropWindow::buttonRelease (int button, int num, int bstate, int x, int y) { observedCropWin->remoteMoveReady (); state = SNormal; } - if (cropgl && (state==SCropSelecting || state==SResizeH1 || state==SResizeH2 || state==SResizeW1 || state==SResizeW2 || state==SCropMove)) { + if (cropgl && (state==SCropSelecting || state==SResizeH1 || state==SResizeH2 || state==SResizeW1 || state==SResizeW2 || state==SResizeTL || state==SResizeTR || state==SResizeBL || state==SResizeBR || state==SCropMove)) + { cropgl->cropManipReady (); iarea->setToolHand (); } @@ -438,6 +467,38 @@ void CropWindow::pointerMoved (int x, int y) { cropgl->cropWidth2Resized (cropHandler.cropParams.x, cropHandler.cropParams.y, cropHandler.cropParams.w, cropHandler.cropParams.h); iarea->redraw (); } + else if (state==SResizeTL && cropgl) { + int ox = cropHandler.cropParams.x; + cropHandler.cropParams.x = action_x + (x-press_x) / zoomSteps[cropZoom].zoom; + cropHandler.cropParams.w += ox - cropHandler.cropParams.x; + 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); + 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); + 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); + 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); + iarea->redraw (); + } else if (state==SCropMove && cropgl) { cropHandler.cropParams.x = action_x + (x-press_x) / zoomSteps[cropZoom].zoom; cropHandler.cropParams.y = action_y + (y-press_y) / zoomSteps[cropZoom].zoom; @@ -537,6 +598,42 @@ bool CropWindow::onArea (CursorArea a, int x, int y) { return (x>=xpos+imgAreaX && y>=ypos+imgAreaY && x=xpos+imgX && y>=ypos+imgY && x=cropHandler.cropParams.y-CROPRESIZEBORDER && + y1<=cropHandler.cropParams.y+CROPRESIZEBORDER && + y>=ypos+imgY && + x1>=cropHandler.cropParams.x-CROPRESIZEBORDER && + x1<=cropHandler.cropParams.x+CROPRESIZEBORDER && + x>=xpos+imgX; + case CropTopRight: + translateCoord (x, y, x1, y1); + return cropHandler.cropParams.enabled && + y1>=cropHandler.cropParams.y-CROPRESIZEBORDER && + y1<=cropHandler.cropParams.y+CROPRESIZEBORDER && + y>=ypos+imgY && + x1>=cropHandler.cropParams.x+cropHandler.cropParams.w-1-CROPRESIZEBORDER && + x1<=cropHandler.cropParams.x+cropHandler.cropParams.w-1+CROPRESIZEBORDER && + x=cropHandler.cropParams.y+cropHandler.cropParams.h-1-CROPRESIZEBORDER && + y1<=cropHandler.cropParams.y+cropHandler.cropParams.h-1+CROPRESIZEBORDER && + y=cropHandler.cropParams.x-CROPRESIZEBORDER && + x1<=cropHandler.cropParams.x+CROPRESIZEBORDER && + x>=xpos+imgX; + case CropBottomRight: + translateCoord (x, y, x1, y1); + return cropHandler.cropParams.enabled && + y1>=cropHandler.cropParams.y+cropHandler.cropParams.h-1-CROPRESIZEBORDER && + y1<=cropHandler.cropParams.y+cropHandler.cropParams.h-1+CROPRESIZEBORDER && + y=cropHandler.cropParams.x+cropHandler.cropParams.w-1-CROPRESIZEBORDER && + x1<=cropHandler.cropParams.x+cropHandler.cropParams.w-1+CROPRESIZEBORDER && + xget_window(), CSMove); else if (onArea (CropResize, x, y)) cursorManager.setCursor (iarea->get_window(), CSResizeDiagonal); + else if (tm==TMHand && (onArea (CropTopLeft, x, y))) + cursorManager.setCursor (iarea->get_window(), CSResizeTopLeft); + else if (tm==TMHand && (onArea (CropTopRight, x, y))) + cursorManager.setCursor (iarea->get_window(), CSResizeTopRight); + else if (tm==TMHand && (onArea (CropBottomLeft, x, y))) + cursorManager.setCursor (iarea->get_window(), CSResizeBottomLeft); + else if (tm==TMHand && (onArea (CropBottomRight, x, y))) + cursorManager.setCursor (iarea->get_window(), CSResizeBottomRight); else if (tm==TMHand && (onArea (CropTop, x, y) || onArea (CropBottom, x, y))) cursorManager.setCursor (iarea->get_window(), CSResizeHeight); else if (tm==TMHand && (onArea (CropLeft, x, y) || onArea (CropRight, x, y))) @@ -632,6 +737,14 @@ void CropWindow::updateCursor (int x, int y) { cursorManager.setCursor (iarea->get_window(), CSResizeWidth); else if (state==SResizeH1 || state==SResizeH2) cursorManager.setCursor (iarea->get_window(), CSResizeHeight); + else if (state==SResizeTL) + cursorManager.setCursor (iarea->get_window(), CSResizeTopLeft); + else if (state==SResizeTR) + cursorManager.setCursor (iarea->get_window(), CSResizeTopRight); + else if (state==SResizeBL) + cursorManager.setCursor (iarea->get_window(), CSResizeBottomLeft); + else if (state==SResizeBR) + cursorManager.setCursor (iarea->get_window(), CSResizeBottomRight); else if (state==SCropWinResize) cursorManager.setCursor (iarea->get_window(), CSResizeDiagonal); } diff --git a/rtgui/cursormanager.cc b/rtgui/cursormanager.cc index 6315bc84c..99bdb6701 100644 --- a/rtgui/cursormanager.cc +++ b/rtgui/cursormanager.cc @@ -28,6 +28,10 @@ void CursorManager::init (Glib::RefPtr mainWin) { cResizeWidth = new Gdk::Cursor (Gdk::SB_H_DOUBLE_ARROW); cResizeHeight = new Gdk::Cursor (Gdk::SB_V_DOUBLE_ARROW); cResizeDiag = new Gdk::Cursor (Gdk::BOTTOM_RIGHT_CORNER); + cResizeTopLeft = new Gdk::Cursor (Gdk::TOP_LEFT_CORNER); + cResizeTopRight = new Gdk::Cursor (Gdk::TOP_RIGHT_CORNER); + cResizeBottomLeft = new Gdk::Cursor (Gdk::BOTTOM_LEFT_CORNER); + cResizeBottomRight = new Gdk::Cursor (Gdk::BOTTOM_RIGHT_CORNER); cCropMove = new Gdk::Cursor (Gdk::FLEUR); cCropMoving = new Gdk::Cursor (Gdk::HAND2); cCropSelection = new Gdk::Cursor (Gdk::CROSSHAIR); @@ -67,6 +71,14 @@ void CursorManager::setCursor (Glib::RefPtr window, CursorShape sha window->set_cursor (*cResizeHeight); else if (shape==CSResizeDiagonal) window->set_cursor (*cResizeDiag); + else if (shape==CSResizeTopLeft) + window->set_cursor (*cResizeTopLeft); + else if (shape==CSResizeTopRight) + window->set_cursor (*cResizeTopRight); + else if (shape==CSResizeBottomLeft) + window->set_cursor (*cResizeBottomLeft); + else if (shape==CSResizeBottomRight) + window->set_cursor (*cResizeBottomRight); else if (shape==CSSpotWB) window->set_cursor (*cWB); else if (shape==CSCropSelect) diff --git a/rtgui/cursormanager.h b/rtgui/cursormanager.h index 3f2f853f1..4c0d1f446 100644 --- a/rtgui/cursormanager.h +++ b/rtgui/cursormanager.h @@ -21,7 +21,7 @@ #include -enum CursorShape {CSArrow, CSOpenHand, CSClosedHand, CSMove, CSMoveLeft, CSMoveRight, CSResizeWidth, CSResizeHeight, CSResizeDiagonal, CSSpotWB, CSCropSelect, CSStraighten, CSPlus, CSWait, CSEmpty}; +enum CursorShape {CSArrow, CSOpenHand, CSClosedHand, CSMove, CSMoveLeft, CSMoveRight, CSResizeWidth, CSResizeHeight, CSResizeDiagonal, CSResizeTopLeft, CSResizeTopRight, CSResizeBottomLeft, CSResizeBottomRight, CSSpotWB, CSCropSelect, CSStraighten, CSPlus, CSWait, CSEmpty}; class CursorManager { @@ -29,6 +29,10 @@ class CursorManager { Gdk::Cursor* cResizeWidth; Gdk::Cursor* cResizeHeight; Gdk::Cursor* cResizeDiag; + Gdk::Cursor* cResizeTopLeft; + Gdk::Cursor* cResizeTopRight; + Gdk::Cursor* cResizeBottomLeft; + Gdk::Cursor* cResizeBottomRight; Gdk::Cursor* cCropMove; Gdk::Cursor* cCropMoving; Gdk::Cursor* cLeftTanMove; diff --git a/rtgui/editenums.h b/rtgui/editenums.h index bfccf3e65..22631b10f 100644 --- a/rtgui/editenums.h +++ b/rtgui/editenums.h @@ -19,7 +19,7 @@ #ifndef _EDITENUMS_ #define _EDITENUMS_ -enum ImgEditState {SNormal, SCropMove, SHandMove, SResizeW1, SResizeW2, SResizeH1, SResizeH2, SCropSelecting, SRotateSelecting, SCropWinMove, SCropFrameMove, SCropImgMove, SCropWinResize, SObservedMove}; -enum CursorArea {CropWinButtons, CropToolBar, CropImage, CropBorder, CropTop, CropBottom, CropLeft, CropRight, CropInside, CropResize, CropObserved}; +enum ImgEditState {SNormal, SCropMove, SHandMove, SResizeW1, SResizeW2, SResizeH1, SResizeH2, SResizeTL, SResizeTR, SResizeBL, SResizeBR, SCropSelecting, SRotateSelecting, SCropWinMove, SCropFrameMove, SCropImgMove, SCropWinResize, SObservedMove}; +enum CursorArea {CropWinButtons, CropToolBar, CropImage, CropBorder, CropTop, CropTopLeft, CropTopRight, CropBottom, CropBottomLeft, CropBottomRight, CropLeft, CropRight, CropInside, CropResize, CropObserved}; #endif diff --git a/rtgui/filebrowserentry.cc b/rtgui/filebrowserentry.cc index 557c452aa..772bba732 100644 --- a/rtgui/filebrowserentry.cc +++ b/rtgui/filebrowserentry.cc @@ -121,7 +121,7 @@ std::vector > FileBrowserEntry::getIconsOnImageArea () void FileBrowserEntry::customBackBufferUpdate (Cairo::RefPtr c) { - if (state==SCropSelecting || state==SResizeH1 || state==SResizeH2 || state==SResizeW1 || state==SResizeW2 || state==SCropMove) + if (state==SCropSelecting || state==SResizeH1 || state==SResizeH2 || state==SResizeW1 || state==SResizeW2 || state==SResizeTL || state==SResizeTR || state==SResizeBL || state==SResizeBR || state==SCropMove) drawCrop (c, prex, prey, prew, preh, 0, 0, scale, cropParams); else { rtengine::procparams::CropParams cparams = thumbnail->getProcParams().crop; @@ -292,6 +292,42 @@ bool FileBrowserEntry::motionNotify (int x, int y) { updateBackBuffer (); parent->redrawNeeded (this); } + else if (state==SResizeTL && cropgl) { + int ox = cropParams.x; + cropParams.x = action_x + (x-press_x) / scale; + cropParams.w += ox - cropParams.x; + 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); + updateBackBuffer (); + parent->redrawNeeded (this); + } + else if (state==SResizeTR && cropgl) { + cropParams.w = action_x + (x-press_x) / scale; + 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); + updateBackBuffer (); + parent->redrawNeeded (this); + } + else if (state==SResizeBL && cropgl) { + int ox = cropParams.x; + 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); + 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); + updateBackBuffer (); + parent->redrawNeeded (this); + } else if (state==SCropMove && cropgl) { cropParams.x = action_x + (x-press_x) / scale; cropParams.y = action_y + (y-press_y) / scale; @@ -338,7 +374,43 @@ bool FileBrowserEntry::pressNotify (int button, int type, int bstate, int x, i int iy = y - starty - ofsY; if (!b && selected && inside (x,y)) { if (button==1 && type==GDK_BUTTON_PRESS && state==SNormal) { - if (onArea (CropTop, ix, iy)) { + if (onArea (CropTopLeft, ix, iy)) { + state = SResizeTL; + press_x = x; + action_x = cropParams.x; + press_y = y; + action_y = cropParams.y; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if (onArea (CropTopRight, ix, iy)) { + state = SResizeTR; + press_x = x; + action_x = cropParams.w; + press_y = y; + action_y = cropParams.y; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if (onArea (CropBottomLeft, ix, iy)) { + state = SResizeBL; + press_x = x; + action_x = cropParams.x; + press_y = y; + action_y = cropParams.h; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if (onArea (CropBottomRight, ix, iy)) { + state = SResizeBR; + press_x = x; + action_x = cropParams.w; + press_y = y; + action_y = cropParams.h; + cropgl = iatlistener->startCropEditing (thumbnail); + b = true; + } + else if (onArea (CropTop, ix, iy)) { state = SResizeH1; press_y = y; action_y = cropParams.y; @@ -418,7 +490,7 @@ bool FileBrowserEntry::releaseNotify (int button, int type, int bstate, int x, i iatlistener->rotateSelectionReady (rot_deg, thumbnail); if (iatlistener->getToolBar()) iatlistener->getToolBar()->setTool (TMHand); } - else if (cropgl && (state==SCropSelecting || state==SResizeH1 || state==SResizeH2 || state==SResizeW1 || state==SResizeW2 || state==SCropMove)) { + else if (cropgl && (state==SCropSelecting || state==SResizeH1 || state==SResizeH2 || state==SResizeW1 || state==SResizeW2 || state==SResizeTL || state==SResizeTR || state==SResizeBL || state==SResizeBR || state==SCropMove)) { cropgl->cropManipReady (); cropgl = NULL; iatlistener->cropSelectionReady (); @@ -444,6 +516,30 @@ bool FileBrowserEntry::onArea (CursorArea a, int x, int y) { switch (a) { case CropImage: return x>=prex && x=prey && y=cropParams.y-cropResizeBorder && + y1<=cropParams.y+cropResizeBorder && + x1>=cropParams.x-cropResizeBorder && + x1<=cropParams.x+cropResizeBorder; + case CropTopRight: + return cropParams.enabled && + y1>=cropParams.y-cropResizeBorder && + y1<=cropParams.y+cropResizeBorder && + x1>=cropParams.x+cropParams.w-1-cropResizeBorder && + x1<=cropParams.x+cropParams.w-1+cropResizeBorder; + case CropBottomLeft: + return cropParams.enabled && + y1>=cropParams.y+cropParams.h-1-cropResizeBorder && + y1<=cropParams.y+cropParams.h-1+cropResizeBorder && + x1>=cropParams.x-cropResizeBorder && + x1<=cropParams.x+cropResizeBorder; + case CropBottomRight: + return cropParams.enabled && + y1>=cropParams.y+cropParams.h-1-cropResizeBorder && + y1<=cropParams.y+cropParams.h-1+cropResizeBorder && + x1>=cropParams.x+cropParams.w-1-cropResizeBorder && + x1<=cropParams.x+cropParams.w-1+cropResizeBorder; case CropTop: return cropParams.enabled && x1>cropParams.x+cropResizeBorder && @@ -497,6 +593,14 @@ void FileBrowserEntry::updateCursor (int x, int y) { cursorManager.setCursor (w, CSResizeHeight); else if (tm==TMHand && (onArea (CropLeft, x, y) || onArea (CropRight, x, y))) cursorManager.setCursor (w, CSResizeWidth); + else if (tm==TMHand && (onArea (CropTopLeft, x, y))) + cursorManager.setCursor (w, CSResizeTopLeft); + else if (tm==TMHand && (onArea (CropTopRight, x, y))) + cursorManager.setCursor (w, CSResizeTopRight); + else if (tm==TMHand && (onArea (CropBottomLeft, x, y))) + cursorManager.setCursor (w, CSResizeBottomLeft); + else if (tm==TMHand && (onArea (CropBottomRight, x, y))) + cursorManager.setCursor (w, CSResizeBottomRight); else if (onArea (CropImage, x, y)) { if (tm==TMHand) cursorManager.setCursor (w, CSArrow); @@ -520,6 +624,14 @@ void FileBrowserEntry::updateCursor (int x, int y) { cursorManager.setCursor (w, CSResizeWidth); else if (state==SResizeH1 || state==SResizeH2) cursorManager.setCursor (w, CSResizeHeight); + else if (state==SResizeTL) + cursorManager.setCursor (w, CSResizeTopLeft); + else if (state==SResizeTR) + cursorManager.setCursor (w, CSResizeTopRight); + else if (state==SResizeBL) + cursorManager.setCursor (w, CSResizeBottomLeft); + else if (state==SResizeBR) + cursorManager.setCursor (w, CSResizeBottomRight); } void FileBrowserEntry::draw () {