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)
|
float y = (where.y - (frame.top + frame.bottom) / 2)
|
||||||
/ (frame.Height() + 1);
|
/ (frame.Height() + 1);
|
||||||
|
|
||||||
// compute the angle
|
// compute the resize direction
|
||||||
if (x == 0 && y == 0)
|
int8 horizontal;
|
||||||
return;
|
int8 vertical;
|
||||||
|
_ComputeResizeDirection(x, y, horizontal, vertical);
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the highlight, if necessary
|
// update the highlight, if necessary
|
||||||
if (horizontal != fHorizontal || vertical != fVertical) {
|
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
|
// #pragma mark - DefaultWindowBehaviour
|
||||||
|
|
||||||
|
|
||||||
@@ -870,6 +889,11 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where,
|
|||||||
default:
|
default:
|
||||||
break;
|
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"));
|
STRACE_CLICK(("===> ACTION_RESIZE_BORDER\n"));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case ACTION_HUMDINGER_RESIZE:
|
||||||
|
_NextState(new (std::nothrow) HumdingerResizeState(*this, where));
|
||||||
|
STRACE_CLICK(("===> ACTION_HUMDINGER_RESIZE\n"));
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
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*
|
ServerCursor*
|
||||||
DefaultWindowBehaviour::_ResizeCursorFor(int8 horizontal, int8 vertical)
|
DefaultWindowBehaviour::_ResizeCursorFor(int8 horizontal, int8 vertical)
|
||||||
{
|
{
|
||||||
@@ -1163,3 +1168,82 @@ DefaultWindowBehaviour::_ResetResizeCursor()
|
|||||||
{
|
{
|
||||||
fDesktop->SetManagementCursor(NULL);
|
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_DRAG,
|
||||||
ACTION_SLIDE_TAB,
|
ACTION_SLIDE_TAB,
|
||||||
ACTION_RESIZE,
|
ACTION_RESIZE,
|
||||||
ACTION_RESIZE_BORDER
|
ACTION_RESIZE_BORDER,
|
||||||
|
ACTION_HUMDINGER_RESIZE
|
||||||
};
|
};
|
||||||
|
|
||||||
enum {
|
enum {
|
||||||
@@ -71,6 +72,7 @@ private:
|
|||||||
struct ResizeBorderState;
|
struct ResizeBorderState;
|
||||||
struct DecoratorButtonState;
|
struct DecoratorButtonState;
|
||||||
struct ManageWindowState;
|
struct ManageWindowState;
|
||||||
|
struct HumdingerResizeState;
|
||||||
|
|
||||||
// to keep gcc 2 happy
|
// to keep gcc 2 happy
|
||||||
friend struct State;
|
friend struct State;
|
||||||
@@ -81,6 +83,7 @@ private:
|
|||||||
friend struct ResizeBorderState;
|
friend struct ResizeBorderState;
|
||||||
friend struct DecoratorButtonState;
|
friend struct DecoratorButtonState;
|
||||||
friend struct ManageWindowState;
|
friend struct ManageWindowState;
|
||||||
|
friend struct HumdingerResizeState;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool _IsWindowModifier(int32 modifiers) const;
|
bool _IsWindowModifier(int32 modifiers) const;
|
||||||
@@ -94,6 +97,8 @@ private:
|
|||||||
void _SetResizeCursor(int8 horizontal,
|
void _SetResizeCursor(int8 horizontal,
|
||||||
int8 vertical);
|
int8 vertical);
|
||||||
void _ResetResizeCursor();
|
void _ResetResizeCursor();
|
||||||
|
static void _ComputeResizeDirection(float x, float y,
|
||||||
|
int8& _horizontal, int8& _vertical);
|
||||||
|
|
||||||
void _NextState(State* state);
|
void _NextState(State* state);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user