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-24 23:53:08 -05:00
parent e5de7e2102
commit 3071859cc6
3 changed files with 382 additions and 207 deletions
+27 -1
View File
@@ -218,7 +218,33 @@ DefaultDecorator::RegionAt(BPoint where, int32& tab) const
if (region != REGION_NONE) if (region != REGION_NONE)
return region; 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)) if (fTopTab->look == B_DOCUMENT_WINDOW_LOOK && fResizeRect.Contains(where))
return REGION_RIGHT_BOTTOM_CORNER; return REGION_RIGHT_BOTTOM_CORNER;
@@ -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 // #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) virtual bool MouseDown(BMessage* message, BPoint where, bool& _unhandled)
{ {
// right-click while dragging shall bring the window to front // right-click while dragging shall bring the window to front
@@ -230,6 +263,25 @@ struct DefaultWindowBehaviour::DragState : MouseTrackingState {
return MouseTrackingState::MouseDown(message, where, _unhandled); 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) virtual void MouseMovedAction(BPoint& delta, bigtime_t now)
{ {
if (!(fWindow->Flags() & B_NOT_MOVABLE)) { if (!(fWindow->Flags() & B_NOT_MOVABLE)) {
@@ -356,7 +408,8 @@ struct DefaultWindowBehaviour::ResizeBorderState : MouseTrackingState {
{ {
switch (region) { switch (region) {
case Decorator::REGION_TAB: case Decorator::REGION_TAB:
// TODO: Handle like the border it is attached to (top/left)? fHorizontal = NONE;
fVertical = NONE;
break; break;
case Decorator::REGION_LEFT_BORDER: case Decorator::REGION_LEFT_BORDER:
fHorizontal = LEFT; fHorizontal = LEFT;
@@ -403,21 +456,30 @@ struct DefaultWindowBehaviour::ResizeBorderState : MouseTrackingState {
virtual void EnterState(State* previousState) 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); fBehavior._SetResizeCursor(fHorizontal, fVertical);
} }
virtual void ExitState(State* nextState) 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) virtual void MouseMovedAction(BPoint& delta, bigtime_t now)
@@ -580,61 +642,114 @@ protected:
// #pragma mark - ManageWindowState // #pragma mark - ManageWindowState
struct DefaultWindowBehaviour::ManageWindowState : State { DefaultWindowBehaviour::ManageWindowState::ManageWindowState(
ManageWindowState(DefaultWindowBehaviour& behavior, BPoint where) DefaultWindowBehaviour& behavior, BPoint where)
: :
State(behavior), State(behavior),
fLastMousePosition(where), fLastMousePosition(where),
fHorizontal(NONE), fHorizontal(NONE),
fVertical(NONE) fVertical(NONE)
{ {
} }
virtual void EnterState(State* previousState)
{
_UpdateBorders(fLastMousePosition);
}
virtual void ExitState(State* nextState) DefaultWindowBehaviour::ManageWindowState::ManageWindowState(
{ DefaultWindowBehaviour& behavior, BPoint where, int8 horizontal,
fBehavior._SetBorderHighlights(fHorizontal, fVertical, false); int8 vertical)
} :
State(behavior),
fLastMousePosition(where),
fHorizontal(horizontal),
fVertical(vertical)
{
}
virtual bool MouseDown(BMessage* message, BPoint where, bool& _unhandled)
{ void
// We're only interested, if the secondary mouse button was pressed. DefaultWindowBehaviour::ManageWindowState::EnterState(State* previousState)
// Othewise let the our caller handle the event. {
// 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"); int32 buttons = message->FindInt32("buttons");
if ((buttons & B_SECONDARY_MOUSE_BUTTON) == 0) { if ((buttons & B_PRIMARY_MOUSE_BUTTON) != 0) {
_unhandled = true; if ((fWindow->Flags() & B_NOT_MOVABLE) == 0) {
return true; fBehavior._SetMoveCursor();
fBehavior._NextState(new (std::nothrow) DragState(fBehavior,
where, false, false));
}
} 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._SetNowAllowedCursor();
} }
fBehavior._NextState(new (std::nothrow) ResizeBorderState(fBehavior,
where, fHorizontal, fVertical));
return true; return true;
} }
virtual void MouseMoved(BMessage* message, BPoint where, bool isFake)
{ void
// If the mouse is still over our window, update the borders. Otherwise DefaultWindowBehaviour::ManageWindowState::MouseMoved(BMessage* message,
// leave the state. 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) { if (fDesktop->WindowAt(where) == fWindow) {
fLastMousePosition = where; fLastMousePosition = where;
_UpdateBorders(fLastMousePosition); _UpdateResizeArrows(fLastMousePosition);
} else } else
fBehavior._NextState(NULL); 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();
virtual void ModifiersChanged(BPoint where, int32 modifiers)
{
if (!fBehavior._IsWindowModifier(modifiers))
fBehavior._NextState(NULL); fBehavior._NextState(NULL);
} }
}
private:
void _UpdateBorders(BPoint where) void
{ DefaultWindowBehaviour::ManageWindowState::_UpdateResizeArrows(BPoint where)
{
if ((fWindow->Flags() & B_NOT_RESIZABLE) != 0) if ((fWindow->Flags() & B_NOT_RESIZABLE) != 0)
return; return;
@@ -651,29 +766,14 @@ private:
/ (frame.Height() + 1); / (frame.Height() + 1);
// compute the resize direction // compute the resize direction
int8 horizontal; _ComputeResizeDirection(x, y, fHorizontal, fVertical);
int8 vertical;
_ComputeResizeDirection(x, y, horizontal, vertical);
// set resize direction to NONE if not resizable
if ((fWindow->Flags() & B_NOT_H_RESIZABLE) != 0) if ((fWindow->Flags() & B_NOT_H_RESIZABLE) != 0)
horizontal = NONE; fHorizontal = NONE;
if ((fWindow->Flags() & B_NOT_V_RESIZABLE) != 0) if ((fWindow->Flags() & B_NOT_V_RESIZABLE) != 0)
vertical = NONE; fVertical = NONE;
}
// 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;
};
// #pragma mark - DefaultWindowBehaviour // #pragma mark - DefaultWindowBehaviour
@@ -742,7 +842,34 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where,
// translate the region into an action // translate the region into an action
uint32 flags = fWindow->Flags(); 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 // left mouse button
switch (hitRegion) { switch (hitRegion) {
case Decorator::REGION_TAB: { case Decorator::REGION_TAB: {
@@ -792,27 +919,6 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where,
? ACTION_RESIZE : ACTION_DRAG; ? ACTION_RESIZE : ACTION_DRAG;
break; 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: default:
break; break;
} }
@@ -894,22 +1000,20 @@ DefaultWindowBehaviour::MouseDown(BMessage* message, BPoint where,
void void
DefaultWindowBehaviour::MouseUp(BMessage* message, BPoint where) DefaultWindowBehaviour::MouseMoved(BMessage* message, BPoint where,
{ bool isFake)
if (fState != NULL)
fState->MouseUp(message, where);
}
void
DefaultWindowBehaviour::MouseMoved(BMessage* message, BPoint where, bool isFake)
{ {
if (fState != NULL) { if (fState != NULL) {
fState->MouseMoved(message, where, isFake); fState->MouseMoved(message, where, isFake);
} else { } 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)); _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 // 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 void
DefaultWindowBehaviour::ModifiersChanged(int32 modifiers) DefaultWindowBehaviour::ModifiersChanged(int32 modifiers)
{ {
@@ -934,9 +1046,14 @@ DefaultWindowBehaviour::ModifiersChanged(int32 modifiers)
if (fState != NULL) { if (fState != NULL) {
fState->ModifiersChanged(where, modifiers); fState->ModifiersChanged(where, modifiers);
} else { } 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)); _NextState(new(std::nothrow) ManageWindowState(*this, where));
} else if ((fWindow->Flags() & B_NOT_RESIZABLE) == 0
&& _IsControlModifier(modifiers)) {
_SetBorderResizeCursor(where);
} else
_ResetCursor();
} }
} }
@@ -958,6 +1075,15 @@ DefaultWindowBehaviour::_IsWindowModifier(int32 modifiers) const
} }
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;
}
Decorator::Region Decorator::Region
DefaultWindowBehaviour::_RegionFor(const BMessage* message, int32& tab) const DefaultWindowBehaviour::_RegionFor(const BMessage* message, int32& tab) const
{ {
@@ -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* ServerCursor*
DefaultWindowBehaviour::_ResizeCursorFor(int8 horizontal, int8 vertical) DefaultWindowBehaviour::_ResizeCursorFor(int8 horizontal, int8 vertical)
{ {
@@ -1047,29 +1107,45 @@ DefaultWindowBehaviour::_ResizeCursorFor(int8 horizontal, int8 vertical)
if (horizontal == LEFT) { if (horizontal == LEFT) {
if (vertical == TOP) if (vertical == TOP)
cursorID = B_CURSOR_ID_RESIZE_NORTH_WEST; cursorID = B_CURSOR_ID_RESIZE_NORTH_WEST_SOUTH_EAST;
else if (vertical == BOTTOM) else if (vertical == BOTTOM)
cursorID = B_CURSOR_ID_RESIZE_SOUTH_WEST; cursorID = B_CURSOR_ID_RESIZE_NORTH_EAST_SOUTH_WEST;
else else
cursorID = B_CURSOR_ID_RESIZE_WEST; cursorID = B_CURSOR_ID_RESIZE_EAST_WEST;
} else if (horizontal == RIGHT) { } else if (horizontal == RIGHT) {
if (vertical == TOP) if (vertical == TOP)
cursorID = B_CURSOR_ID_RESIZE_NORTH_EAST; cursorID = B_CURSOR_ID_RESIZE_NORTH_EAST_SOUTH_WEST;
else if (vertical == BOTTOM) else if (vertical == BOTTOM)
cursorID = B_CURSOR_ID_RESIZE_SOUTH_EAST; cursorID = B_CURSOR_ID_RESIZE_NORTH_WEST_SOUTH_EAST;
else else
cursorID = B_CURSOR_ID_RESIZE_EAST; cursorID = B_CURSOR_ID_RESIZE_EAST_WEST;
} else { } else {
if (vertical == TOP) if (vertical == TOP)
cursorID = B_CURSOR_ID_RESIZE_NORTH; cursorID = B_CURSOR_ID_RESIZE_NORTH_SOUTH;
else if (vertical == BOTTOM) else if (vertical == BOTTOM)
cursorID = B_CURSOR_ID_RESIZE_SOUTH; cursorID = B_CURSOR_ID_RESIZE_NORTH_SOUTH;
} }
return fDesktop->GetCursorManager().GetCursor(cursorID); 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 void
DefaultWindowBehaviour::_SetResizeCursor(int8 horizontal, int8 vertical) DefaultWindowBehaviour::_SetResizeCursor(int8 horizontal, int8 vertical)
{ {
@@ -1078,7 +1154,76 @@ DefaultWindowBehaviour::_SetResizeCursor(int8 horizontal, int8 vertical)
void 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); fDesktop->SetManagementCursor(NULL);
} }
@@ -87,18 +87,22 @@ private:
friend struct ManageWindowState; friend struct ManageWindowState;
private: private:
bool _IsControlModifier(int32 modifiers) const;
bool _IsWindowModifier(int32 modifiers) const; bool _IsWindowModifier(int32 modifiers) const;
Decorator::Region _RegionFor(const BMessage* message, Decorator::Region _RegionFor(const BMessage* message,
int32& tab) const; int32& tab) const;
void _SetBorderHighlights(int8 horizontal,
int8 vertical, bool active);
ServerCursor* _ResizeCursorFor(int8 horizontal, ServerCursor* _ResizeCursorFor(int8 horizontal,
int8 vertical); int8 vertical);
void _SetMoveCursor();
void _SetNowAllowedCursor();
void _SetResizeCursor(int8 horizontal, void _SetResizeCursor(int8 horizontal,
int8 vertical); int8 vertical);
void _ResetResizeCursor(); void _SetBorderResizeCursor(BPoint where);
void _ResetCursor();
void _UpdateResizeArrows(BPoint where);
static void _ComputeResizeDirection(float x, float y, static void _ComputeResizeDirection(float x, float y,
int8& _horizontal, int8& _vertical); int8& _horizontal, int8& _vertical);