Update ctrl+alt window management functionality.

* Use double-headed resize arrows instead of single headed.
* Remove border highlighting, it is replaced by mouse cursor.
* Don't enter drag state if window is not movable.
* Make Ctrl+LMB resize window border like RMB.
* Define other 3 corners in default decorator and resize by them
  as well
* Update mouse cursor to show arrows when over borders and control
  is held.
* Set the move cursor on ctrl+alt if the window is movable.
* Set cursor to not allowed on ctrl+alt if window is not movable.
* Set the cursor to appropriate resize arrow on ctrl+alt+RMB.
* Set the cursor to not allowed on ctrl+alt+RMB if not resizable.
* Make window go to back when you right-click or ctrl+click
  on the tab. It doesn't lose focus though unlike BeOS R5.
This commit is contained in:
John Scipione 2013-01-16 19:58:25 -05:00
parent e5de7e2102
commit 3071859cc6
3 changed files with 382 additions and 207 deletions

View File

@ -218,7 +218,33 @@ DefaultDecorator::RegionAt(BPoint where, int32& tab) const
if (region != REGION_NONE)
return region;
// check the resize corner
// check the left top corner
BRect leftTopLeft(fLeftBorder.left, fLeftBorder.top,
fLeftBorder.right, fLeftBorder.top + kBorderResizeLength);
BRect leftTopTop(fTopBorder.left, fTopBorder.top,
fTopBorder.left + kBorderResizeLength, fTopBorder.bottom);
if (leftTopLeft.Contains(where) || leftTopTop.Contains(where))
return REGION_LEFT_TOP_CORNER;
// check the left bottom corner
BRect leftBottomLeft(fLeftBorder.left,
fLeftBorder.bottom - kBorderResizeLength,
fLeftBorder.right, fLeftBorder.bottom);
BRect leftBottomBottom(fBottomBorder.left,
fBottomBorder.top, fBottomBorder.left + kBorderResizeLength,
fBottomBorder.bottom);
if (leftBottomLeft.Contains(where) || leftBottomBottom.Contains(where))
return REGION_LEFT_BOTTOM_CORNER;
// check the right top corner
BRect rightTopRight(fRightBorder.left, fRightBorder.top,
fRightBorder.right, fRightBorder.top + kBorderResizeLength);
BRect rightTopTop(fTopBorder.right - kBorderResizeLength, fTopBorder.top,
fTopBorder.right, fTopBorder.bottom);
if (rightTopRight.Contains(where) || rightTopTop.Contains(where))
return REGION_RIGHT_TOP_CORNER;
// check the right bottom resize corner
if (fTopTab->look == B_DOCUMENT_WINDOW_LOOK && fResizeRect.Contains(where))
return REGION_RIGHT_BOTTOM_CORNER;

View File

@ -86,6 +86,31 @@ protected:
};
// #pragma mark - ManageWindowState Definition
struct DefaultWindowBehaviour::ManageWindowState : State {
ManageWindowState(DefaultWindowBehaviour& behavior,
BPoint where);
ManageWindowState(DefaultWindowBehaviour& behavior,
BPoint where, int8 horizontal, int8 vertical);
virtual void EnterState(State* previousState);
virtual void ExitState(State* nextState);
virtual bool MouseDown(BMessage* message, BPoint where,
bool& _unhandled);
virtual void MouseMoved(BMessage* message, BPoint where, bool isFake);
virtual void ModifiersChanged(BPoint where, int32 modifiers);
private:
void _UpdateResizeArrows(BPoint where);
private:
BPoint fLastMousePosition;
int8 fHorizontal;
int8 fVertical;
};
// #pragma mark - MouseTrackingState
@ -215,6 +240,14 @@ struct DefaultWindowBehaviour::DragState : MouseTrackingState {
{
}
virtual void EnterState(State* previousState)
{
}
virtual void ExitState(State* nextState)
{
}
virtual bool MouseDown(BMessage* message, BPoint where, bool& _unhandled)
{
// right-click while dragging shall bring the window to front
@ -230,6 +263,25 @@ struct DefaultWindowBehaviour::DragState : MouseTrackingState {
return MouseTrackingState::MouseDown(message, where, _unhandled);
}
virtual void MouseUp(BMessage* message, BPoint where)
{
if (fBehavior._IsWindowModifier(message->FindInt32("modifiers"))) {
// If the window modifiers are held return to the window
// management state.
fBehavior._NextState(new(std::nothrow) ManageWindowState(
fBehavior, where));
} else
fBehavior._NextState(NULL);
}
virtual void ModifiersChanged(BPoint where, int32 modifiers)
{
// Exit if user lifted window management modifiers
fBehavior.fLastModifiers = modifiers;
if (!fBehavior._IsWindowModifier(modifiers))
fBehavior._NextState(NULL);
}
virtual void MouseMovedAction(BPoint& delta, bigtime_t now)
{
if (!(fWindow->Flags() & B_NOT_MOVABLE)) {
@ -356,7 +408,8 @@ struct DefaultWindowBehaviour::ResizeBorderState : MouseTrackingState {
{
switch (region) {
case Decorator::REGION_TAB:
// TODO: Handle like the border it is attached to (top/left)?
fHorizontal = NONE;
fVertical = NONE;
break;
case Decorator::REGION_LEFT_BORDER:
fHorizontal = LEFT;
@ -403,21 +456,30 @@ struct DefaultWindowBehaviour::ResizeBorderState : MouseTrackingState {
virtual void EnterState(State* previousState)
{
if ((fWindow->Flags() & B_NOT_RESIZABLE) != 0)
fHorizontal = fVertical = NONE;
else {
if ((fWindow->Flags() & B_NOT_H_RESIZABLE) != 0)
fHorizontal = NONE;
if ((fWindow->Flags() & B_NOT_V_RESIZABLE) != 0)
fVertical = NONE;
}
fBehavior._SetResizeCursor(fHorizontal, fVertical);
}
virtual void ExitState(State* nextState)
{
fBehavior._ResetResizeCursor();
}
virtual void MouseUp(BMessage* message, BPoint where)
{
if (fBehavior._IsWindowModifier(message->FindInt32("modifiers"))) {
// If the window modifiers are still held return to window
// management state.
fBehavior._NextState(new(std::nothrow) ManageWindowState(
fBehavior, where, fHorizontal, fVertical));
} else
fBehavior._NextState(NULL);
}
virtual void ModifiersChanged(BPoint where, int32 modifiers)
{
// Exit if user lifted window management modifiers
fBehavior.fLastModifiers = modifiers;
if (!fBehavior._IsWindowModifier(modifiers))
fBehavior._NextState(NULL);
}
virtual void MouseMovedAction(BPoint& delta, bigtime_t now)
@ -580,100 +642,138 @@ protected:
// #pragma mark - ManageWindowState
struct DefaultWindowBehaviour::ManageWindowState : State {
ManageWindowState(DefaultWindowBehaviour& behavior, BPoint where)
:
State(behavior),
fLastMousePosition(where),
fHorizontal(NONE),
fVertical(NONE)
{
}
DefaultWindowBehaviour::ManageWindowState::ManageWindowState(
DefaultWindowBehaviour& behavior, BPoint where)
:
State(behavior),
fLastMousePosition(where),
fHorizontal(NONE),
fVertical(NONE)
{
}
virtual void EnterState(State* previousState)
{
_UpdateBorders(fLastMousePosition);
}
virtual void ExitState(State* nextState)
{
fBehavior._SetBorderHighlights(fHorizontal, fVertical, false);
}
DefaultWindowBehaviour::ManageWindowState::ManageWindowState(
DefaultWindowBehaviour& behavior, BPoint where, int8 horizontal,
int8 vertical)
:
State(behavior),
fLastMousePosition(where),
fHorizontal(horizontal),
fVertical(vertical)
{
}
virtual bool MouseDown(BMessage* message, BPoint where, bool& _unhandled)
{
// We're only interested, if the secondary mouse button was pressed.
// Othewise let the our caller handle the event.
int32 buttons = message->FindInt32("buttons");
if ((buttons & B_SECONDARY_MOUSE_BUTTON) == 0) {
_unhandled = true;
return true;
void
DefaultWindowBehaviour::ManageWindowState::EnterState(State* previousState)
{
// Update the mouse cursor
if ((fWindow->Flags() & B_NOT_MOVABLE) == 0)
fBehavior._SetMoveCursor();
else
fBehavior._SetNowAllowedCursor();
_UpdateResizeArrows(fLastMousePosition);
}
void
DefaultWindowBehaviour::ManageWindowState::ExitState(State* nextState)
{
}
bool
DefaultWindowBehaviour::ManageWindowState::MouseDown(BMessage* message,
BPoint where, bool& _unhandled)
{
int32 buttons = message->FindInt32("buttons");
if ((buttons & B_PRIMARY_MOUSE_BUTTON) != 0) {
if ((fWindow->Flags() & B_NOT_MOVABLE) == 0) {
fBehavior._SetMoveCursor();
fBehavior._NextState(new (std::nothrow) DragState(fBehavior,
where, false, false));
}
fBehavior._NextState(new (std::nothrow) ResizeBorderState(fBehavior,
where, fHorizontal, fVertical));
return true;
}
virtual void MouseMoved(BMessage* message, BPoint where, bool isFake)
{
// If the mouse is still over our window, update the borders. Otherwise
// leave the state.
if (fDesktop->WindowAt(where) == fWindow) {
fLastMousePosition = where;
_UpdateBorders(fLastMousePosition);
} else if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0) {
if ((fWindow->Flags() & B_NOT_RESIZABLE) == 0) {
fBehavior._NextState(new (std::nothrow) ResizeBorderState(
fBehavior, where, fHorizontal, fVertical));
} else
fBehavior._NextState(NULL);
fBehavior._SetNowAllowedCursor();
}
virtual void ModifiersChanged(BPoint where, int32 modifiers)
{
if (!fBehavior._IsWindowModifier(modifiers))
fBehavior._NextState(NULL);
return true;
}
void
DefaultWindowBehaviour::ManageWindowState::MouseMoved(BMessage* message,
BPoint where, bool isFake)
{
// Update the mouse cursor
if ((fDesktop->WindowAt(where)->Flags() & B_NOT_RESIZABLE) != 0
&& (message->FindInt32("buttons") & B_SECONDARY_MOUSE_BUTTON) != 0) {
fBehavior._SetNowAllowedCursor();
} else if ((fDesktop->WindowAt(where)->Flags() & B_NOT_MOVABLE) == 0)
fBehavior._SetMoveCursor();
else
fBehavior._SetNowAllowedCursor();
// If the cursor is still over our window, update the borders.
// Otherwise leave the state.
if (fDesktop->WindowAt(where) == fWindow) {
fLastMousePosition = where;
_UpdateResizeArrows(fLastMousePosition);
} else
fBehavior._NextState(NULL);
}
void
DefaultWindowBehaviour::ManageWindowState::ModifiersChanged(BPoint where,
int32 modifiers)
{
fBehavior.fLastModifiers = modifiers;
if (!fBehavior._IsWindowModifier(modifiers)) {
if ((fWindow->Flags() & B_NOT_RESIZABLE) == 0
&& fBehavior._IsControlModifier(modifiers)) {
fBehavior._SetBorderResizeCursor(where);
} else
fBehavior._ResetCursor();
fBehavior._NextState(NULL);
}
}
private:
void _UpdateBorders(BPoint where)
{
if ((fWindow->Flags() & B_NOT_RESIZABLE) != 0)
return;
// 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;
void
DefaultWindowBehaviour::ManageWindowState::_UpdateResizeArrows(BPoint where)
{
if ((fWindow->Flags() & B_NOT_RESIZABLE) != 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 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;
// compute the resize direction
int8 horizontal;
int8 vertical;
_ComputeResizeDirection(x, y, horizontal, vertical);
float x = (where.x - (frame.left + frame.right) / 2)
/ (frame.Width() + 1);
float y = (where.y - (frame.top + frame.bottom) / 2)
/ (frame.Height() + 1);
if ((fWindow->Flags() & B_NOT_H_RESIZABLE) != 0)
horizontal = NONE;
if ((fWindow->Flags() & B_NOT_V_RESIZABLE) != 0)
vertical = NONE;
// compute the resize direction
_ComputeResizeDirection(x, y, fHorizontal, fVertical);
// update the highlight, if necessary
if (horizontal != fHorizontal || vertical != fVertical) {
fBehavior._SetBorderHighlights(fHorizontal, fVertical, false);
fHorizontal = horizontal;
fVertical = vertical;
fBehavior._SetBorderHighlights(fHorizontal, fVertical, true);
}
}
private:
BPoint fLastMousePosition;
int8 fHorizontal;
int8 fVertical;
};
// set resize direction to NONE if not resizable
if ((fWindow->Flags() & B_NOT_H_RESIZABLE) != 0)
fHorizontal = NONE;
if ((fWindow->Flags() & B_NOT_V_RESIZABLE) != 0)
fVertical = NONE;
}
// #pragma mark - DefaultWindowBehaviour
@ -742,7 +842,34 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where,
// translate the region into an action
uint32 flags = fWindow->Flags();
if ((buttons & B_PRIMARY_MOUSE_BUTTON) != 0) {
if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0
|| _IsControlModifier(fLastModifiers)
&& (buttons & B_PRIMARY_MOUSE_BUTTON) != 0) {
// right mouse button or control + left mouse button
switch (hitRegion) {
case Decorator::REGION_TAB:
case Decorator::REGION_CLOSE_BUTTON:
case Decorator::REGION_ZOOM_BUTTON:
case Decorator::REGION_MINIMIZE_BUTTON:
// Right clicking on the window tab sends it behind
fDesktop->SendWindowBehind(fWindow);
break;
case Decorator::REGION_LEFT_BORDER:
case Decorator::REGION_RIGHT_BORDER:
case Decorator::REGION_TOP_BORDER:
case Decorator::REGION_BOTTOM_BORDER:
case Decorator::REGION_LEFT_TOP_CORNER:
case Decorator::REGION_LEFT_BOTTOM_CORNER:
case Decorator::REGION_RIGHT_TOP_CORNER:
case Decorator::REGION_RIGHT_BOTTOM_CORNER:
action = (flags & B_NOT_RESIZABLE) == 0
? ACTION_RESIZE_BORDER : ACTION_DRAG;
break;
default:
break;
}
} else if ((buttons & B_PRIMARY_MOUSE_BUTTON) != 0) {
// left mouse button
switch (hitRegion) {
case Decorator::REGION_TAB: {
@ -792,27 +919,6 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where,
? ACTION_RESIZE : ACTION_DRAG;
break;
default:
break;
}
} else if ((buttons & B_SECONDARY_MOUSE_BUTTON) != 0) {
// right mouse button
switch (hitRegion) {
case Decorator::REGION_TAB:
case Decorator::REGION_LEFT_BORDER:
case Decorator::REGION_RIGHT_BORDER:
case Decorator::REGION_TOP_BORDER:
case Decorator::REGION_BOTTOM_BORDER:
case Decorator::REGION_CLOSE_BUTTON:
case Decorator::REGION_ZOOM_BUTTON:
case Decorator::REGION_MINIMIZE_BUTTON:
case Decorator::REGION_LEFT_TOP_CORNER:
case Decorator::REGION_LEFT_BOTTOM_CORNER:
case Decorator::REGION_RIGHT_TOP_CORNER:
case Decorator::REGION_RIGHT_BOTTOM_CORNER:
action = ACTION_RESIZE_BORDER;
break;
default:
break;
}
@ -894,22 +1000,20 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where,
void
DefaultWindowBehaviour::MouseUp(BMessage* message, BPoint where)
{
if (fState != NULL)
fState->MouseUp(message, where);
}
void
DefaultWindowBehaviour::MouseMoved(BMessage* message, BPoint where, bool isFake)
DefaultWindowBehaviour::MouseMoved(BMessage* message, BPoint where,
bool isFake)
{
if (fState != NULL) {
fState->MouseMoved(message, where, isFake);
} else {
// If the window modifiers are hold, enter the window management state.
if (_IsWindowModifier(message->FindInt32("modifiers")))
if (_IsWindowModifier(message->FindInt32("modifiers"))) {
// Enter the window management state.
_NextState(new(std::nothrow) ManageWindowState(*this, where));
} else if ((fWindow->Flags() & B_NOT_RESIZABLE) == 0
&& _IsControlModifier(message->FindInt32("modifiers"))) {
_SetBorderResizeCursor(where);
} else
_ResetCursor();
}
// change focus in FFM mode
@ -924,6 +1028,14 @@ DefaultWindowBehaviour::MouseMoved(BMessage* message, BPoint where, bool isFake)
}
void
DefaultWindowBehaviour::MouseUp(BMessage* message, BPoint where)
{
if (fState != NULL)
fState->MouseUp(message, where);
}
void
DefaultWindowBehaviour::ModifiersChanged(int32 modifiers)
{
@ -934,9 +1046,14 @@ DefaultWindowBehaviour::ModifiersChanged(int32 modifiers)
if (fState != NULL) {
fState->ModifiersChanged(where, modifiers);
} else {
// If the window modifiers are hold, enter the window management state.
if (_IsWindowModifier(modifiers))
if (_IsWindowModifier(modifiers)) {
// Enter the window management state.
_NextState(new(std::nothrow) ManageWindowState(*this, where));
} else if ((fWindow->Flags() & B_NOT_RESIZABLE) == 0
&& _IsControlModifier(modifiers)) {
_SetBorderResizeCursor(where);
} else
_ResetCursor();
}
}
@ -954,7 +1071,16 @@ DefaultWindowBehaviour::_IsWindowModifier(int32 modifiers) const
{
return (fWindow->Flags() & B_NO_SERVER_SIDE_WINDOW_MODIFIERS) == 0
&& (modifiers & (B_COMMAND_KEY | B_CONTROL_KEY | B_OPTION_KEY
| B_SHIFT_KEY)) == (B_COMMAND_KEY | B_CONTROL_KEY);
| B_SHIFT_KEY)) == (B_COMMAND_KEY | B_CONTROL_KEY);
}
bool
DefaultWindowBehaviour::_IsControlModifier(int32 modifiers) const
{
return (fWindow->Flags() & B_NO_SERVER_SIDE_WINDOW_MODIFIERS) == 0
&& (modifiers & (B_COMMAND_KEY | B_CONTROL_KEY | B_OPTION_KEY
| B_SHIFT_KEY)) == B_CONTROL_KEY;
}
@ -973,72 +1099,6 @@ DefaultWindowBehaviour::_RegionFor(const BMessage* message, int32& tab) const
}
void
DefaultWindowBehaviour::_SetBorderHighlights(int8 horizontal, int8 vertical,
bool active)
{
if (Decorator* decorator = fWindow->Decorator()) {
uint8 highlight = active
? Decorator::HIGHLIGHT_RESIZE_BORDER
: Decorator::HIGHLIGHT_NONE;
// set the highlights for the borders
BRegion dirtyRegion;
switch (horizontal) {
case LEFT:
decorator->SetRegionHighlight(Decorator::REGION_LEFT_BORDER,
highlight, &dirtyRegion);
break;
case RIGHT:
decorator->SetRegionHighlight(
Decorator::REGION_RIGHT_BORDER, highlight,
&dirtyRegion);
break;
}
switch (vertical) {
case TOP:
decorator->SetRegionHighlight(Decorator::REGION_TOP_BORDER,
highlight, &dirtyRegion);
break;
case BOTTOM:
decorator->SetRegionHighlight(
Decorator::REGION_BOTTOM_BORDER, highlight,
&dirtyRegion);
break;
}
// set the highlights for the corners
if (horizontal != NONE && vertical != NONE) {
if (horizontal == LEFT) {
if (vertical == TOP) {
decorator->SetRegionHighlight(
Decorator::REGION_LEFT_TOP_CORNER, highlight,
&dirtyRegion);
} else {
decorator->SetRegionHighlight(
Decorator::REGION_LEFT_BOTTOM_CORNER, highlight,
&dirtyRegion);
}
} else {
if (vertical == TOP) {
decorator->SetRegionHighlight(
Decorator::REGION_RIGHT_TOP_CORNER, highlight,
&dirtyRegion);
} else {
decorator->SetRegionHighlight(
Decorator::REGION_RIGHT_BOTTOM_CORNER, highlight,
&dirtyRegion);
}
}
}
// invalidate the affected regions
fWindow->ProcessDirtyRegion(dirtyRegion);
}
}
ServerCursor*
DefaultWindowBehaviour::_ResizeCursorFor(int8 horizontal, int8 vertical)
{
@ -1047,29 +1107,45 @@ DefaultWindowBehaviour::_ResizeCursorFor(int8 horizontal, int8 vertical)
if (horizontal == LEFT) {
if (vertical == TOP)
cursorID = B_CURSOR_ID_RESIZE_NORTH_WEST;
cursorID = B_CURSOR_ID_RESIZE_NORTH_WEST_SOUTH_EAST;
else if (vertical == BOTTOM)
cursorID = B_CURSOR_ID_RESIZE_SOUTH_WEST;
cursorID = B_CURSOR_ID_RESIZE_NORTH_EAST_SOUTH_WEST;
else
cursorID = B_CURSOR_ID_RESIZE_WEST;
cursorID = B_CURSOR_ID_RESIZE_EAST_WEST;
} else if (horizontal == RIGHT) {
if (vertical == TOP)
cursorID = B_CURSOR_ID_RESIZE_NORTH_EAST;
cursorID = B_CURSOR_ID_RESIZE_NORTH_EAST_SOUTH_WEST;
else if (vertical == BOTTOM)
cursorID = B_CURSOR_ID_RESIZE_SOUTH_EAST;
cursorID = B_CURSOR_ID_RESIZE_NORTH_WEST_SOUTH_EAST;
else
cursorID = B_CURSOR_ID_RESIZE_EAST;
cursorID = B_CURSOR_ID_RESIZE_EAST_WEST;
} else {
if (vertical == TOP)
cursorID = B_CURSOR_ID_RESIZE_NORTH;
cursorID = B_CURSOR_ID_RESIZE_NORTH_SOUTH;
else if (vertical == BOTTOM)
cursorID = B_CURSOR_ID_RESIZE_SOUTH;
cursorID = B_CURSOR_ID_RESIZE_NORTH_SOUTH;
}
return fDesktop->GetCursorManager().GetCursor(cursorID);
}
void
DefaultWindowBehaviour::_SetMoveCursor()
{
fDesktop->SetManagementCursor(
fDesktop->GetCursorManager().GetCursor(B_CURSOR_ID_MOVE));
}
void
DefaultWindowBehaviour::_SetNowAllowedCursor()
{
fDesktop->SetManagementCursor(
fDesktop->GetCursorManager().GetCursor(B_CURSOR_ID_NOT_ALLOWED));
}
void
DefaultWindowBehaviour::_SetResizeCursor(int8 horizontal, int8 vertical)
{
@ -1078,7 +1154,76 @@ DefaultWindowBehaviour::_SetResizeCursor(int8 horizontal, int8 vertical)
void
DefaultWindowBehaviour::_ResetResizeCursor()
DefaultWindowBehaviour::_SetBorderResizeCursor(BPoint where)
{
Decorator* decorator = fWindow->Decorator();
if (!decorator->GetFootprint().Contains(where)) {
// not over window
_ResetCursor();
return;
}
Decorator::Region hitRegion = Decorator::REGION_NONE;
int32 tab = -1;
BMessage* message = new BMessage();
message->AddPoint("where", where);
hitRegion = _RegionFor(message, tab);
delete message;
int8 horizontal = NONE;
int8 vertical = NONE;
switch (hitRegion) {
case Decorator::REGION_TAB:
break;
case Decorator::REGION_LEFT_BORDER:
horizontal = LEFT;
break;
case Decorator::REGION_RIGHT_BORDER:
horizontal = RIGHT;
break;
case Decorator::REGION_TOP_BORDER:
vertical = TOP;
break;
case Decorator::REGION_BOTTOM_BORDER:
vertical = BOTTOM;
break;
case Decorator::REGION_CLOSE_BUTTON:
case Decorator::REGION_ZOOM_BUTTON:
case Decorator::REGION_MINIMIZE_BUTTON:
break;
case Decorator::REGION_LEFT_TOP_CORNER:
horizontal = LEFT;
vertical = TOP;
break;
case Decorator::REGION_LEFT_BOTTOM_CORNER:
horizontal = LEFT;
vertical = BOTTOM;
break;
case Decorator::REGION_RIGHT_TOP_CORNER:
horizontal = RIGHT;
vertical = TOP;
break;
case Decorator::REGION_RIGHT_BOTTOM_CORNER:
horizontal = RIGHT;
vertical = BOTTOM;
break;
default:
break;
}
if ((fWindow->Flags() & B_NOT_H_RESIZABLE) != 0)
horizontal = NONE;
if ((fWindow->Flags() & B_NOT_V_RESIZABLE) != 0)
vertical = NONE;
_SetResizeCursor(horizontal, vertical);
}
void
DefaultWindowBehaviour::_ResetCursor()
{
fDesktop->SetManagementCursor(NULL);
}

View File

@ -87,18 +87,22 @@ private:
friend struct ManageWindowState;
private:
bool _IsControlModifier(int32 modifiers) const;
bool _IsWindowModifier(int32 modifiers) const;
Decorator::Region _RegionFor(const BMessage* message,
int32& tab) const;
void _SetBorderHighlights(int8 horizontal,
int8 vertical, bool active);
ServerCursor* _ResizeCursorFor(int8 horizontal,
int8 vertical);
void _SetMoveCursor();
void _SetNowAllowedCursor();
void _SetResizeCursor(int8 horizontal,
int8 vertical);
void _ResetResizeCursor();
void _SetBorderResizeCursor(BPoint where);
void _ResetCursor();
void _UpdateResizeArrows(BPoint where);
static void _ComputeResizeDirection(float x, float y,
int8& _horizontal, int8& _vertical);