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:
parent
e5de7e2102
commit
3071859cc6
@ -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;
|
||||
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user