Implemented Humdinger's resizing method, activated on Cmd-Ctrl-middle-click.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39656 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -668,53 +668,10 @@ private:
|
||||
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;
|
||||
|
||||
int8 horizontal = NONE;
|
||||
int8 vertical = NONE;
|
||||
switch (int(angle / M_PI_4)) {
|
||||
case 0:
|
||||
horizontal = RIGHT;
|
||||
break;
|
||||
case 1:
|
||||
horizontal = RIGHT;
|
||||
vertical = BOTTOM;
|
||||
break;
|
||||
case 2:
|
||||
vertical = BOTTOM;
|
||||
break;
|
||||
case 3:
|
||||
horizontal = LEFT;
|
||||
vertical = BOTTOM;
|
||||
break;
|
||||
case 4:
|
||||
horizontal = LEFT;
|
||||
break;
|
||||
case 5:
|
||||
horizontal = LEFT;
|
||||
vertical = TOP;
|
||||
break;
|
||||
case 6:
|
||||
vertical = TOP;
|
||||
break;
|
||||
case 7:
|
||||
default:
|
||||
horizontal = RIGHT;
|
||||
vertical = TOP;
|
||||
break;
|
||||
}
|
||||
// compute the resize direction
|
||||
int8 horizontal;
|
||||
int8 vertical;
|
||||
_ComputeResizeDirection(x, y, horizontal, vertical);
|
||||
|
||||
// update the highlight, if necessary
|
||||
if (horizontal != fHorizontal || vertical != fVertical) {
|
||||
@@ -732,6 +689,68 @@ private:
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - State
|
||||
|
||||
|
||||
struct DefaultWindowBehaviour::HumdingerResizeState : State {
|
||||
HumdingerResizeState(DefaultWindowBehaviour& behavior, BPoint where)
|
||||
:
|
||||
State(behavior),
|
||||
fInitialMousePosition(where),
|
||||
fJitterPhase(true)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void EnterState(State* previousState)
|
||||
{
|
||||
fDesktop->SetManagementCursor(
|
||||
fDesktop->GetCursorManager().GetCursor(B_CURSOR_ID_MOVE));
|
||||
}
|
||||
|
||||
virtual void ExitState(State* nextState)
|
||||
{
|
||||
fBehavior._ResetResizeCursor();
|
||||
}
|
||||
|
||||
virtual void MouseUp(BMessage* message, BPoint where)
|
||||
{
|
||||
// Leave the state, when the middle mouse button has been released.
|
||||
int32 buttons = message->FindInt32("buttons");
|
||||
if ((buttons & B_TERTIARY_MOUSE_BUTTON) == 0)
|
||||
fBehavior._NextState(NULL);
|
||||
}
|
||||
|
||||
virtual void MouseMoved(BMessage* message, BPoint where, bool isFake)
|
||||
{
|
||||
// ignore the initial movement
|
||||
float dx = where.x - fInitialMousePosition.x;
|
||||
float dy = where.y - fInitialMousePosition.y;
|
||||
if (dx * dx + dy * dy < (fJitterPhase ? 16 : 64))
|
||||
return;
|
||||
|
||||
// Enter the next phase, if we're still in the first one.
|
||||
if (fJitterPhase) {
|
||||
fInitialMousePosition = where;
|
||||
fJitterPhase = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// The mouse has moved far enough for us to take a guess in which
|
||||
// direction.
|
||||
int8 horizontal;
|
||||
int8 vertical;
|
||||
_ComputeResizeDirection(dx, dy, horizontal, vertical);
|
||||
|
||||
fBehavior._NextState(new (std::nothrow) ResizeBorderState(fBehavior,
|
||||
where, horizontal, vertical));
|
||||
}
|
||||
|
||||
private:
|
||||
BPoint fInitialMousePosition;
|
||||
bool fJitterPhase;
|
||||
};
|
||||
|
||||
|
||||
// #pragma mark - DefaultWindowBehaviour
|
||||
|
||||
|
||||
@@ -870,6 +889,11 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where,
|
||||
default:
|
||||
break;
|
||||
}
|
||||
} else if ((buttons & B_TERTIARY_MOUSE_BUTTON) != 0) {
|
||||
// Middle-click anywhere on the window shall initiate
|
||||
// humdinger-resize mode.
|
||||
if (windowModifier && hitRegion != Decorator::REGION_NONE)
|
||||
action = ACTION_HUMDINGER_RESIZE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -939,6 +963,11 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where,
|
||||
STRACE_CLICK(("===> ACTION_RESIZE_BORDER\n"));
|
||||
break;
|
||||
|
||||
case ACTION_HUMDINGER_RESIZE:
|
||||
_NextState(new (std::nothrow) HumdingerResizeState(*this, where));
|
||||
STRACE_CLICK(("===> ACTION_HUMDINGER_RESIZE\n"));
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -1096,30 +1125,6 @@ DefaultWindowBehaviour::_SetBorderHighlights(int8 horizontal, int8 vertical,
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DefaultWindowBehaviour::_NextState(State* state)
|
||||
{
|
||||
// exit the old state
|
||||
if (fState != NULL)
|
||||
fState->ExitState(state);
|
||||
|
||||
// set and enter the new state
|
||||
State* oldState = fState;
|
||||
fState = state;
|
||||
|
||||
if (fState != NULL) {
|
||||
fState->EnterState(oldState);
|
||||
fDesktop->SetMouseEventWindow(fWindow);
|
||||
} else if (oldState != NULL) {
|
||||
// no state anymore -- reset the mouse event window, if it's still us
|
||||
if (fDesktop->MouseEventWindow() == fWindow)
|
||||
fDesktop->SetMouseEventWindow(NULL);
|
||||
}
|
||||
|
||||
delete oldState;
|
||||
}
|
||||
|
||||
|
||||
ServerCursor*
|
||||
DefaultWindowBehaviour::_ResizeCursorFor(int8 horizontal, int8 vertical)
|
||||
{
|
||||
@@ -1163,3 +1168,82 @@ DefaultWindowBehaviour::_ResetResizeCursor()
|
||||
{
|
||||
fDesktop->SetManagementCursor(NULL);
|
||||
}
|
||||
|
||||
|
||||
/*static*/ void
|
||||
DefaultWindowBehaviour::_ComputeResizeDirection(float x, float y,
|
||||
int8& _horizontal, int8& _vertical)
|
||||
{
|
||||
_horizontal = NONE;
|
||||
_vertical = NONE;
|
||||
|
||||
// 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:
|
||||
_horizontal = RIGHT;
|
||||
break;
|
||||
case 1:
|
||||
_horizontal = RIGHT;
|
||||
_vertical = BOTTOM;
|
||||
break;
|
||||
case 2:
|
||||
_vertical = BOTTOM;
|
||||
break;
|
||||
case 3:
|
||||
_horizontal = LEFT;
|
||||
_vertical = BOTTOM;
|
||||
break;
|
||||
case 4:
|
||||
_horizontal = LEFT;
|
||||
break;
|
||||
case 5:
|
||||
_horizontal = LEFT;
|
||||
_vertical = TOP;
|
||||
break;
|
||||
case 6:
|
||||
_vertical = TOP;
|
||||
break;
|
||||
case 7:
|
||||
default:
|
||||
_horizontal = RIGHT;
|
||||
_vertical = TOP;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
DefaultWindowBehaviour::_NextState(State* state)
|
||||
{
|
||||
// exit the old state
|
||||
if (fState != NULL)
|
||||
fState->ExitState(state);
|
||||
|
||||
// set and enter the new state
|
||||
State* oldState = fState;
|
||||
fState = state;
|
||||
|
||||
if (fState != NULL) {
|
||||
fState->EnterState(oldState);
|
||||
fDesktop->SetMouseEventWindow(fWindow);
|
||||
} else if (oldState != NULL) {
|
||||
// no state anymore -- reset the mouse event window, if it's still us
|
||||
if (fDesktop->MouseEventWindow() == fWindow)
|
||||
fDesktop->SetMouseEventWindow(NULL);
|
||||
}
|
||||
|
||||
delete oldState;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,8 @@ private:
|
||||
ACTION_DRAG,
|
||||
ACTION_SLIDE_TAB,
|
||||
ACTION_RESIZE,
|
||||
ACTION_RESIZE_BORDER
|
||||
ACTION_RESIZE_BORDER,
|
||||
ACTION_HUMDINGER_RESIZE
|
||||
};
|
||||
|
||||
enum {
|
||||
@@ -71,6 +72,7 @@ private:
|
||||
struct ResizeBorderState;
|
||||
struct DecoratorButtonState;
|
||||
struct ManageWindowState;
|
||||
struct HumdingerResizeState;
|
||||
|
||||
// to keep gcc 2 happy
|
||||
friend struct State;
|
||||
@@ -81,6 +83,7 @@ private:
|
||||
friend struct ResizeBorderState;
|
||||
friend struct DecoratorButtonState;
|
||||
friend struct ManageWindowState;
|
||||
friend struct HumdingerResizeState;
|
||||
|
||||
private:
|
||||
bool _IsWindowModifier(int32 modifiers) const;
|
||||
@@ -94,6 +97,8 @@ private:
|
||||
void _SetResizeCursor(int8 horizontal,
|
||||
int8 vertical);
|
||||
void _ResetResizeCursor();
|
||||
static void _ComputeResizeDirection(float x, float y,
|
||||
int8& _horizontal, int8& _vertical);
|
||||
|
||||
void _NextState(State* state);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user