more work on the input handling. I let Layer/WinBorder handle the MouseDown/Moved/Up instead of doing this in RootLayer::MouseEventHandler(). I did this because I felt it's more clean and in the near future RootLayer may have other children than WinBorders, for example simple Layers representing tooltips/bubbles/etc.
git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14198 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
c5233d297e
commit
1b65556d66
@ -404,9 +404,20 @@ Layer::FindLayer(const int32 token)
|
|||||||
\return The layer containing the point or NULL if no layer found
|
\return The layer containing the point or NULL if no layer found
|
||||||
*/
|
*/
|
||||||
Layer*
|
Layer*
|
||||||
Layer::LayerAt(const BPoint &pt)
|
Layer::LayerAt(const BPoint &pt, bool recursive)
|
||||||
{
|
{
|
||||||
//printf("%p:%s:LayerAt(x = %g, y = %g)\n", this, Name(), pt.x, pt.y);
|
//printf("%p:%s:LayerAt(x = %g, y = %g)\n", this, Name(), pt.x, pt.y);
|
||||||
|
if (!recursive) {
|
||||||
|
if (VisibleRegion().Contains(pt))
|
||||||
|
return this;
|
||||||
|
|
||||||
|
for (Layer* child = LastChild(); child; child = PreviousChild())
|
||||||
|
if (child->FullVisible().Contains(pt))
|
||||||
|
return child;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NEW_CLIPPING
|
#ifndef NEW_CLIPPING
|
||||||
if (fVisible.Contains(pt))
|
if (fVisible.Contains(pt))
|
||||||
return this;
|
return this;
|
||||||
|
@ -108,7 +108,7 @@ class Layer {
|
|||||||
|
|
||||||
uint32 CountChildren() const;
|
uint32 CountChildren() const;
|
||||||
Layer* FindLayer(const int32 token);
|
Layer* FindLayer(const int32 token);
|
||||||
Layer* LayerAt(const BPoint &pt);
|
Layer* LayerAt(const BPoint &pt, bool recursive = true);
|
||||||
|
|
||||||
virtual Layer* FirstChild() const;
|
virtual Layer* FirstChild() const;
|
||||||
virtual Layer* NextChild() const;
|
virtual Layer* NextChild() const;
|
||||||
|
@ -1145,67 +1145,11 @@ RootLayer::MouseEventHandler(int32 code, BPrivate::PortLink& msg)
|
|||||||
|
|
||||||
if (fLastLayerUnderMouse == this)
|
if (fLastLayerUnderMouse == this)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#ifdef NEW_INPUT_HANDLING
|
#ifdef NEW_INPUT_HANDLING
|
||||||
WinBorder* winBorderUnderMouse = fLastLayerUnderMouse->Owner() ?
|
// get the pointer for one of the first RootLayer's descendants
|
||||||
fLastLayerUnderMouse->fOwner :
|
Layer *primaryTarget = LayerAt(evt.where, false);
|
||||||
(WinBorder*)fLastLayerUnderMouse;
|
primaryTarget->MouseDown(evt);
|
||||||
|
|
||||||
DesktopSettings ds(gDesktop);
|
|
||||||
Workspace::State oldState, newState;
|
|
||||||
click_type action = winBorderUnderMouse->ActionFor(evt);
|
|
||||||
|
|
||||||
ActiveWorkspace()->GetState(&oldState);
|
|
||||||
if (action == DEC_MOVETOBACK) {
|
|
||||||
ActiveWorkspace()->AttemptToMoveToBack(winBorderUnderMouse);
|
|
||||||
}
|
|
||||||
// in FFM, only bring in front if clicking on WinBorder's(decorator's) area
|
|
||||||
else if (dynamic_cast<WinBorder*>(fLastLayerUnderMouse) || ds.MouseMode() == B_NORMAL_MOUSE) {
|
|
||||||
ActiveWorkspace()->AttemptToSetFront(winBorderUnderMouse);
|
|
||||||
}
|
|
||||||
ActiveWorkspace()->AttemptToSetFocus(winBorderUnderMouse);
|
|
||||||
ActiveWorkspace()->GetState(&newState);
|
|
||||||
|
|
||||||
// send window activation messages
|
|
||||||
|
|
||||||
// NOTE !!! ATM we're sending B_WINDOW_ACTIVATED to front windows only!
|
|
||||||
// This means floating windows do not have their BWindow::WindowActivated()
|
|
||||||
// hook function called.
|
|
||||||
if (oldState.Front != newState.Front) {
|
|
||||||
if (oldState.Front && oldState.Front->Window()) {
|
|
||||||
BMessage msg(B_WINDOW_ACTIVATED);
|
|
||||||
msg.AddBool("active", false);
|
|
||||||
oldState.Front->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
|
|
||||||
}
|
|
||||||
if (newState.Front && newState.Front->Window()) {
|
|
||||||
BMessage msg(B_WINDOW_ACTIVATED);
|
|
||||||
msg.AddBool("active", true);
|
|
||||||
newState.Front->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// calculate the region that must be invalidated/redrawn
|
|
||||||
|
|
||||||
// first, if the focus window changed, make sure the decorators reflect this state.
|
|
||||||
BRegion dirtyRegion;
|
|
||||||
if (oldState.Focus != newState.Focus) {
|
|
||||||
dirtyRegion.Include(&oldState.Focus->VisibleRegion());
|
|
||||||
dirtyRegion.Include(&newState.Focus->VisibleRegion());
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef NEW_CLIPPING
|
|
||||||
invalidate_layer(this, dirtyRegion);
|
|
||||||
#else
|
|
||||||
do_Invalidate(dirtyRegion);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifndef NEW_CLIPPING
|
|
||||||
invalidate_layer(this, fFull);
|
|
||||||
#else
|
|
||||||
do_Invalidate(Bounds());
|
|
||||||
#endif
|
|
||||||
// TODO: DO NOT ALWAYS SEND THE FIRST MOUSE DOWN!!!
|
|
||||||
// TODO: if B_WILL_ACCEPT_FIRST_CLICK, DO NOT ACTIVATE THE CLICKED WINDOW!!!
|
|
||||||
fLastLayerUnderMouse->MouseDown(evt);
|
|
||||||
#else
|
#else
|
||||||
// we are clicking a WinBorder
|
// we are clicking a WinBorder
|
||||||
|
|
||||||
@ -2241,7 +2185,7 @@ RootLayer::draw_window_tab(WinBorder *exFocus)
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifndef NEW_CLIPPING
|
#ifndef NEW_CLIPPING
|
||||||
inline void
|
void
|
||||||
RootLayer::empty_visible_regions(Layer *layer)
|
RootLayer::empty_visible_regions(Layer *layer)
|
||||||
{
|
{
|
||||||
// TODO: optimize by avoiding recursion?
|
// TODO: optimize by avoiding recursion?
|
||||||
@ -2257,7 +2201,7 @@ RootLayer::empty_visible_regions(Layer *layer)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
inline void
|
void
|
||||||
RootLayer::winborder_activation(WinBorder* exActive)
|
RootLayer::winborder_activation(WinBorder* exActive)
|
||||||
{
|
{
|
||||||
// ToDo: not sure if this is correct - do floating windows get WindowActivated() events?
|
// ToDo: not sure if this is correct - do floating windows get WindowActivated() events?
|
||||||
@ -2274,7 +2218,7 @@ RootLayer::winborder_activation(WinBorder* exActive)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
inline void
|
void
|
||||||
RootLayer::show_final_scene(WinBorder *exFocus, WinBorder *exActive)
|
RootLayer::show_final_scene(WinBorder *exFocus, WinBorder *exActive)
|
||||||
{
|
{
|
||||||
if (fHaveWinBorderList || get_workspace_windows()) {
|
if (fHaveWinBorderList || get_workspace_windows()) {
|
||||||
|
@ -218,7 +218,7 @@ fInUpdateRegion.OffsetBy(x, y);
|
|||||||
// ...and here we get really hacky...
|
// ...and here we get really hacky...
|
||||||
fTopLayer->fFrame.OffsetTo(0.0, 0.0);
|
fTopLayer->fFrame.OffsetTo(0.0, 0.0);
|
||||||
} else {
|
} else {
|
||||||
move_layer(x, y);
|
Layer::move_layer(x, y);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (Window()) {
|
if (Window()) {
|
||||||
@ -448,62 +448,145 @@ WinBorder::GetSizeLimits(float* minWidth, float* maxWidth,
|
|||||||
#ifdef NEW_INPUT_HANDLING
|
#ifdef NEW_INPUT_HANDLING
|
||||||
|
|
||||||
void
|
void
|
||||||
WinBorder::MouseDown(const PointerEvent& event)
|
WinBorder::MouseDown(const PointerEvent& evt)
|
||||||
{
|
{
|
||||||
if (fDecorator) {
|
DesktopSettings desktopSettings(gDesktop);
|
||||||
click_type action = _ActionFor(event);
|
Workspace::State oldState, newState;
|
||||||
// find out where user clicked in Decorator
|
|
||||||
switch(action) {
|
|
||||||
case DEC_CLOSE:
|
|
||||||
fIsClosing = true;
|
|
||||||
fDecorator->SetClose(true);
|
|
||||||
STRACE_CLICK(("===> DEC_CLOSE\n"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DEC_ZOOM:
|
|
||||||
fIsZooming = true;
|
|
||||||
fDecorator->SetZoom(true);
|
|
||||||
STRACE_CLICK(("===> DEC_ZOOM\n"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DEC_MINIMIZE:
|
|
||||||
fIsMinimizing = true;
|
|
||||||
fDecorator->SetMinimize(true);
|
|
||||||
STRACE_CLICK(("===> DEC_MINIMIZE\n"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DEC_DRAG:
|
GetRootLayer()->ActiveWorkspace()->GetState(&oldState);
|
||||||
fIsDragging = true;
|
|
||||||
#ifdef NEW_INPUT_HANDLING
|
// not in FFM mode?
|
||||||
GetRootLayer()->SetNotifyLayer(this, B_POINTER_EVENTS, 0UL);
|
if (desktopSettings.MouseMode() == B_NORMAL_MOUSE) {
|
||||||
|
// default action is to drag the WinBorder
|
||||||
|
click_type action = DEC_DRAG;
|
||||||
|
Layer *target = LayerAt(evt.where);
|
||||||
|
// clicking a simple Layer.
|
||||||
|
if (target != this) {
|
||||||
|
if (GetRootLayer()->ActiveWorkspace()->Active() == this) {
|
||||||
|
target->MouseDown(evt);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (WindowFlags() & B_WILL_ACCEPT_FIRST_CLICK)
|
||||||
|
target->MouseDown(evt);
|
||||||
|
else
|
||||||
|
goto activateWindow;
|
||||||
|
}
|
||||||
|
// TODO: send mouse down to event registered BViews!!!
|
||||||
|
}
|
||||||
|
// clicking WinBorder visible area
|
||||||
|
else {
|
||||||
|
winBorderAreaHandle:
|
||||||
|
|
||||||
|
if (fDecorator)
|
||||||
|
action = _ActionFor(evt);
|
||||||
|
|
||||||
|
// set decorator internals
|
||||||
|
switch(action) {
|
||||||
|
case DEC_CLOSE:
|
||||||
|
fIsClosing = true;
|
||||||
|
fDecorator->SetClose(true);
|
||||||
|
STRACE_CLICK(("===> DEC_CLOSE\n"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEC_ZOOM:
|
||||||
|
fIsZooming = true;
|
||||||
|
fDecorator->SetZoom(true);
|
||||||
|
STRACE_CLICK(("===> DEC_ZOOM\n"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEC_MINIMIZE:
|
||||||
|
fIsMinimizing = true;
|
||||||
|
fDecorator->SetMinimize(true);
|
||||||
|
STRACE_CLICK(("===> DEC_MINIMIZE\n"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEC_DRAG:
|
||||||
|
fIsDragging = true;
|
||||||
|
fLastMousePosition = evt.where;
|
||||||
|
STRACE_CLICK(("===> DEC_DRAG\n"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEC_RESIZE:
|
||||||
|
fIsResizing = true;
|
||||||
|
fLastMousePosition = evt.where;
|
||||||
|
STRACE_CLICK(("===> DEC_RESIZE\n"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DEC_SLIDETAB:
|
||||||
|
fIsSlidingTab = true;
|
||||||
|
fLastMousePosition = evt.where;
|
||||||
|
STRACE_CLICK(("===> DEC_SLIDETAB\n"));
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// based on what the Decorator returned, properly place this window.
|
||||||
|
if (action == DEC_MOVETOBACK) {
|
||||||
|
GetRootLayer()->ActiveWorkspace()->MoveToBack(this);
|
||||||
|
}
|
||||||
|
else if (action == DEC_DRAG) {
|
||||||
|
GetRootLayer()->SetNotifyLayer(this, B_POINTER_EVENTS, 0UL);
|
||||||
|
activateWindow:
|
||||||
|
GetRootLayer()->ActiveWorkspace()->AttemptToActivate(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
GetRootLayer()->ActiveWorkspace()->GetState(&newState);
|
||||||
|
//--------------------------
|
||||||
|
// BOOKMARK!
|
||||||
|
// send window activation messages
|
||||||
|
|
||||||
|
// NOTE !!! ATM we're sending B_WINDOW_ACTIVATED to front windows only!
|
||||||
|
// This means floating windows do not have their BWindow::WindowActivated()
|
||||||
|
// hook function called.
|
||||||
|
if (oldState.Front != newState.Front) {
|
||||||
|
if (oldState.Front && oldState.Front->Window()) {
|
||||||
|
BMessage msg(B_WINDOW_ACTIVATED);
|
||||||
|
msg.AddBool("active", false);
|
||||||
|
oldState.Front->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
|
||||||
|
}
|
||||||
|
if (newState.Front && newState.Front->Window()) {
|
||||||
|
BMessage msg(B_WINDOW_ACTIVATED);
|
||||||
|
msg.AddBool("active", true);
|
||||||
|
newState.Front->Window()->SendMessageToClient(&msg, B_NULL_TOKEN, false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// calculate the region that must be invalidated/redrawn
|
||||||
|
|
||||||
|
// first, if the focus window changed, make sure the decorators reflect this state.
|
||||||
|
BRegion dirtyRegion;
|
||||||
|
if (oldState.Focus != newState.Focus) {
|
||||||
|
dirtyRegion.Include(&oldState.Focus->VisibleRegion());
|
||||||
|
dirtyRegion.Include(&newState.Focus->VisibleRegion());
|
||||||
|
#ifndef NEW_CLIPPING
|
||||||
|
GetRootLayer()->fRedrawReg.Include(&dirtyRegion);
|
||||||
|
#else
|
||||||
|
// TODO: code for new clipping engine!
|
||||||
#endif
|
#endif
|
||||||
fLastMousePosition = event.where;
|
}
|
||||||
STRACE_CLICK(("===> DEC_DRAG\n"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DEC_RESIZE:
|
#ifndef NEW_CLIPPING
|
||||||
fIsResizing = true;
|
GetRootLayer()->invalidate_layer(this, fFull);
|
||||||
fLastMousePosition = event.where;
|
#else
|
||||||
STRACE_CLICK(("===> DEC_RESIZE\n"));
|
GetRootLayer()->do_Invalidate(Bounds());
|
||||||
break;
|
#endif
|
||||||
|
|
||||||
case DEC_SLIDETAB:
|
|
||||||
fIsSlidingTab = true;
|
|
||||||
fLastMousePosition = event.where;
|
|
||||||
STRACE_CLICK(("===> DEC_SLIDETAB\n"));
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
// TODO: FINISH ABOVE.
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// in FFM mode
|
||||||
// TODO: set dirty regions!
|
else {
|
||||||
#ifndef NEW_CLIPPING
|
Layer *target = LayerAt(evt.where);
|
||||||
GetRootLayer()->invalidate_layer(this, VisibleRegion());
|
// clicking a simple Layer; forward event.
|
||||||
#else
|
if (target != this)
|
||||||
do_Invalidate(VisibleRegion());
|
target->MouseDown(evt);
|
||||||
#endif
|
// clicking inside our visible area.
|
||||||
|
else
|
||||||
|
goto winBorderAreaHandle;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -214,9 +214,16 @@ Workspace::Front() const
|
|||||||
WinBorder *
|
WinBorder *
|
||||||
Workspace::Active() const
|
Workspace::Active() const
|
||||||
{
|
{
|
||||||
// ToDo: for now!
|
// in case of a normal or modal window
|
||||||
return Focus();
|
if (fFrontItem && fFrontItem == fFocusItem)
|
||||||
//return fActiveItem ? fActiveItem->layerPtr: NULL;
|
return fFrontItem->layerPtr;
|
||||||
|
|
||||||
|
// a floating window is considered active if it has focus.
|
||||||
|
if (fFocusItem && (fFocusItem->layerPtr->Level() == B_FLOATING_APP ||
|
||||||
|
fFocusItem->layerPtr->Level() == B_FLOATING_ALL))
|
||||||
|
return fFocusItem->layerPtr;
|
||||||
|
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -249,6 +256,14 @@ Workspace::AttemptToMoveToBack(WinBorder *newBack)
|
|||||||
{
|
{
|
||||||
return MoveToBack(newBack);
|
return MoveToBack(newBack);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
Workspace::AttemptToActivate(WinBorder *toActivate)
|
||||||
|
{
|
||||||
|
MoveToFront(toActivate);
|
||||||
|
SetFocus(toActivate);
|
||||||
|
return Active() == toActivate;
|
||||||
|
}
|
||||||
/*
|
/*
|
||||||
\brief This method provides you the list of visible windows in this workspace.
|
\brief This method provides you the list of visible windows in this workspace.
|
||||||
\param list The list of visible WinBorders found in this workspace.
|
\param list The list of visible WinBorders found in this workspace.
|
||||||
|
@ -74,6 +74,7 @@ class Workspace {
|
|||||||
bool AttemptToSetFront(WinBorder *newFront);
|
bool AttemptToSetFront(WinBorder *newFront);
|
||||||
bool AttemptToSetFocus(WinBorder *newFocus);
|
bool AttemptToSetFocus(WinBorder *newFocus);
|
||||||
bool AttemptToMoveToBack(WinBorder *newBack);
|
bool AttemptToMoveToBack(WinBorder *newBack);
|
||||||
|
bool AttemptToActivate(WinBorder *toActivate);
|
||||||
|
|
||||||
bool GetWinBorderList(void **list, int32 *itemCount ) const;
|
bool GetWinBorderList(void **list, int32 *itemCount ) const;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user