Added new state ResizeBorderState, activated by right click on the decorator
or Cmd-Ctrl-right-click anywhere. Introduces the following behavioral changes: * The send-to-back effect is triggered on mouse-up now. It expires after a short time of holding the button or moving the mouse, just like the activation effect on left-click in FFM mode. * Depending on where the mouse was pressed, moving it will move the closest border or corner with it, thus resizing the window. The algorithm choosing the border/corner needs refinement. Currently the window is divided into 8 equally sized sectors corresponding to the borders/corners. Work in progress... git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39615 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
0fd5329656
commit
7cf8907453
@ -15,6 +15,8 @@
|
||||
|
||||
#include "DefaultWindowBehaviour.h"
|
||||
|
||||
#include <math.h>
|
||||
|
||||
#include <WindowPrivate.h>
|
||||
|
||||
#include "Desktop.h"
|
||||
@ -92,9 +94,11 @@ protected:
|
||||
|
||||
struct DefaultWindowBehaviour::MouseTrackingState : State {
|
||||
MouseTrackingState(DefaultWindowBehaviour& behavior, BPoint where,
|
||||
bool windowActionOnMouseUp, bool minimizeCheckOnMouseUp)
|
||||
bool windowActionOnMouseUp, bool minimizeCheckOnMouseUp,
|
||||
int32 mouseButton = B_PRIMARY_MOUSE_BUTTON)
|
||||
:
|
||||
State(behavior),
|
||||
fMouseButton(mouseButton),
|
||||
fWindowActionOnMouseUp(windowActionOnMouseUp),
|
||||
fMinimizeCheckOnMouseUp(minimizeCheckOnMouseUp),
|
||||
fLastMousePosition(where),
|
||||
@ -105,9 +109,9 @@ struct DefaultWindowBehaviour::MouseTrackingState : State {
|
||||
|
||||
virtual void MouseUp(BMessage* message, BPoint where)
|
||||
{
|
||||
// ignore, if it's not the primary mouse button
|
||||
// ignore, if it's not our mouse button
|
||||
int32 buttons = message->FindInt32("buttons");
|
||||
if ((buttons & B_PRIMARY_MOUSE_BUTTON) != 0)
|
||||
if ((buttons & fMouseButton) != 0)
|
||||
return;
|
||||
|
||||
if (fMinimizeCheckOnMouseUp) {
|
||||
@ -196,6 +200,7 @@ struct DefaultWindowBehaviour::MouseTrackingState : State {
|
||||
}
|
||||
|
||||
protected:
|
||||
int32 fMouseButton;
|
||||
bool fWindowActionOnMouseUp : 1;
|
||||
bool fMinimizeCheckOnMouseUp : 1;
|
||||
|
||||
@ -374,6 +379,134 @@ struct DefaultWindowBehaviour::SlideTabState : MouseTrackingState {
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - ResizeBorderState
|
||||
|
||||
|
||||
struct DefaultWindowBehaviour::ResizeBorderState : MouseTrackingState {
|
||||
ResizeBorderState(DefaultWindowBehaviour& behavior, BPoint where)
|
||||
:
|
||||
MouseTrackingState(behavior, where, true, false,
|
||||
B_SECONDARY_MOUSE_BUTTON),
|
||||
fHorizontal(NONE),
|
||||
fVertical(NONE)
|
||||
{
|
||||
// Compute the window center relative location of where. We divide by
|
||||
// the width respective the height, so we compensate for the window's
|
||||
// aspect ratio.
|
||||
BRect frame(fWindow->Frame());
|
||||
if (frame.Width() + 1 == 0 || frame.Height() + 1 == 0)
|
||||
return;
|
||||
|
||||
float x = (where.x - (frame.left + frame.right) / 2)
|
||||
/ (frame.Width() + 1);
|
||||
float y = (where.y - (frame.top + frame.bottom) / 2)
|
||||
/ (frame.Height() + 1);
|
||||
|
||||
// compute the angle
|
||||
if (x == 0 && y == 0)
|
||||
return;
|
||||
|
||||
float angle = atan2f(y, x);
|
||||
|
||||
// rotate by 22.5 degree to align our sectors with 45 degree multiples
|
||||
angle += M_PI / 8;
|
||||
|
||||
// add 180 degree to the negative values, so we get a nice 0 to 360
|
||||
// degree range
|
||||
if (angle < 0)
|
||||
angle += M_PI * 2;
|
||||
|
||||
switch (int(angle / M_PI_4)) {
|
||||
case 0:
|
||||
fHorizontal = RIGHT;
|
||||
break;
|
||||
case 1:
|
||||
fHorizontal = RIGHT;
|
||||
fVertical = BOTTOM;
|
||||
break;
|
||||
case 2:
|
||||
fVertical = BOTTOM;
|
||||
break;
|
||||
case 3:
|
||||
fHorizontal = LEFT;
|
||||
fVertical = BOTTOM;
|
||||
break;
|
||||
case 4:
|
||||
fHorizontal = LEFT;
|
||||
break;
|
||||
case 5:
|
||||
fHorizontal = LEFT;
|
||||
fVertical = TOP;
|
||||
break;
|
||||
case 6:
|
||||
fVertical = TOP;
|
||||
break;
|
||||
case 7:
|
||||
default:
|
||||
fHorizontal = RIGHT;
|
||||
fVertical = TOP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
virtual void MouseMovedAction(BPoint& delta, bigtime_t now)
|
||||
{
|
||||
if ((fWindow->Flags() & B_NOT_RESIZABLE) != 0) {
|
||||
delta = BPoint(0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((fWindow->Flags() & B_NOT_H_RESIZABLE) != 0 || fHorizontal == NONE)
|
||||
delta.x = 0;
|
||||
if ((fWindow->Flags() & B_NOT_V_RESIZABLE) != 0 || fVertical == NONE)
|
||||
delta.y = 0;
|
||||
|
||||
if (delta.x == 0 && delta.y == 0)
|
||||
return;
|
||||
|
||||
// Resize first -- due to the window size limits this is not unlikely
|
||||
// to turn out differently from what we request.
|
||||
BPoint oldRightBottom = fWindow->Frame().RightBottom();
|
||||
|
||||
fDesktop->ResizeWindowBy(fWindow, delta.x * fHorizontal,
|
||||
delta.y * fVertical);
|
||||
|
||||
// constrain delta to true change in size
|
||||
delta = fWindow->Frame().RightBottom() - oldRightBottom;
|
||||
delta.x *= fHorizontal;
|
||||
delta.y *= fVertical;
|
||||
|
||||
// see, if we have to move, too
|
||||
float moveX = fHorizontal == LEFT ? delta.x : 0;
|
||||
float moveY = fVertical == TOP ? delta.y : 0;
|
||||
|
||||
if (moveX != 0 || moveY != 0)
|
||||
fDesktop->MoveWindowBy(fWindow, moveX, moveY);
|
||||
}
|
||||
|
||||
virtual void MouseUpWindowAction()
|
||||
{
|
||||
fDesktop->SendWindowBehind(fWindow);
|
||||
}
|
||||
|
||||
private:
|
||||
enum {
|
||||
// 1 for the "natural" resize border, -1 for the opposite,
|
||||
// so multiplying the movement delta by that value results in the size
|
||||
// change.
|
||||
LEFT = -1,
|
||||
TOP = -1,
|
||||
NONE = 0,
|
||||
RIGHT = 1,
|
||||
BOTTOM = 1
|
||||
};
|
||||
|
||||
private:
|
||||
int8 fHorizontal;
|
||||
int8 fVertical;
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - DecoratorButtonState
|
||||
|
||||
|
||||
@ -692,7 +825,7 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where)
|
||||
break;
|
||||
|
||||
case ACTION_RESIZE_BORDER:
|
||||
fDesktop->SendWindowBehind(fWindow);
|
||||
_NextState(new (std::nothrow) ResizeBorderState(*this, where));
|
||||
STRACE_CLICK(("===> ACTION_RESIZE_BORDER\n"));
|
||||
break;
|
||||
|
||||
|
@ -65,6 +65,7 @@ private:
|
||||
struct DragState;
|
||||
struct ResizeState;
|
||||
struct SlideTabState;
|
||||
struct ResizeBorderState;
|
||||
struct DecoratorButtonState;
|
||||
|
||||
// to keep gcc 2 happy
|
||||
@ -73,6 +74,7 @@ private:
|
||||
friend struct DragState;
|
||||
friend struct ResizeState;
|
||||
friend struct SlideTabState;
|
||||
friend struct ResizeBorderState;
|
||||
friend struct DecoratorButtonState;
|
||||
|
||||
private:
|
||||
|
Loading…
Reference in New Issue
Block a user