Work in progress for the new input handling stuff...

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@14191 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Adi Oanca 2005-09-16 05:10:21 +00:00
parent a59bd8b8bc
commit 8b94d5ecdd
8 changed files with 262 additions and 20 deletions

View File

@ -1100,7 +1100,7 @@ Layer::ScrollBy(float x, float y)
void
Layer::MouseDown(const PointerEvent& evt)
{
if (Window()) {
if (Window() && !IsTopLayer()) {
BMessage msg;
msg.what = B_MOUSE_DOWN;
msg.AddInt64("when", evt.when);
@ -1116,7 +1116,7 @@ Layer::MouseDown(const PointerEvent& evt)
void
Layer::MouseUp(const PointerEvent& evt)
{
if (Window()) {
if (Window() && !IsTopLayer()) {
BMessage upmsg(B_MOUSE_UP);
upmsg.AddInt64("when",evt.when);
upmsg.AddPoint("where",evt.where);
@ -1129,7 +1129,7 @@ Layer::MouseUp(const PointerEvent& evt)
void
Layer::MouseMoved(const PointerEvent& evt, uint32 transit)
{
if (Window()) {
if (Window() && !IsTopLayer()) {
BMessage movemsg(B_MOUSE_MOVED);
movemsg.AddInt64("when", evt.when);
movemsg.AddPoint("where", evt.where);

View File

@ -199,9 +199,11 @@ class Layer {
ServerApp* App() const
{ return fServerWin? fServerWin->App(): NULL; }
inline WinBorder* Owner() const
{ return fOwner; }
virtual bool HasClient()
{ return true; }
// bool IsServerLayer() const;
uint32 EventMask() const
{ return fEventMask; }
@ -250,6 +252,9 @@ class Layer {
void CopyBits(BRect& src, BRect& dst,
int32 xOffset, int32 yOffset);
inline const BRegion& VisibleRegion() const { return fVisible; }
inline const BRegion& FullVisible() const { return fFullVisible; }
#ifdef NEW_CLIPPING
inline const BRegion& VisibleRegion() const { return fVisible2; }
inline const BRegion& FullVisible() const { return fFullVisible2; }

View File

@ -1033,9 +1033,6 @@ RootLayer::WinBorderAt(const BPoint& pt) const
void
RootLayer::_ProcessMouseMovedEvent(PointerEvent &evt)
{
// move cursor on screen
GetHWInterface()->MoveCursorTo(evt.where.x, evt.where.y);
Layer* target = LayerAt(evt.where);
if (target == NULL) {
CRITICAL("RootLayer::_ProcessMouseMovedEvent() 'target' can't be null.\n");
@ -1120,6 +1117,9 @@ RootLayer::MouseEventHandler(int32 code, BPrivate::PortLink& msg)
if (fLastMousePosition != evt.where) {
#ifdef NEW_INPUT_HANDLING
// move cursor on screen
GetHWInterface()->MoveCursorTo(evt.where.x, evt.where.y);
_ProcessMouseMovedEvent(evt);
#else
@ -1146,6 +1146,65 @@ RootLayer::MouseEventHandler(int32 code, BPrivate::PortLink& msg)
if (fLastLayerUnderMouse == this)
break;
#ifdef NEW_INPUT_HANDLING
WinBorder* winBorderUnderMouse = fLastLayerUnderMouse->Owner() ?
fLastLayerUnderMouse->fOwner :
(WinBorder*)fLastLayerUnderMouse;
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
// we are clicking a WinBorder
@ -1235,16 +1294,13 @@ RootLayer::MouseEventHandler(int32 code, BPrivate::PortLink& msg)
evt.where.ConstrainTo(fFrame);
#ifdef NEW_INPUT_HANDLING
ClearNotifyLayer();
#endif
if (fLastLayerUnderMouse == NULL) {
CRITICAL("RootLayer::MouseEventHandler(B_MOUSE_UP) fLastLayerUnderMouse is null!\n");
break;
}
if (fLastMousePosition != evt.where) {
#ifdef NEW_INPUT_HANDLING
// move cursor on screen
GetHWInterface()->MoveCursorTo(evt.where.x, evt.where.y);
_ProcessMouseMovedEvent(evt);
#else
// TODO: a B_MOUSE_MOVED message might have to be generated in order to
// correctly trigger entered/exited view transits.
fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_MOUSE_MOVED (%.1f, %.1f)!\n",
@ -1252,6 +1308,20 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
// update on screen mouse pos
GetHWInterface()->MoveCursorTo(evt.where.x, evt.where.y);
fLastMousePosition = evt.where;
#endif
}
#ifdef NEW_INPUT_HANDLING
ClearNotifyLayer();
if (fLastLayerUnderMouse == NULL) {
CRITICAL("RootLayer::MouseEventHandler(B_MOUSE_UP) fLastLayerUnderMouse is null!\n");
break;
}
fLastLayerUnderMouse->MouseUp(evt);
#else
if (fLastLayerUnderMouse == NULL) {
CRITICAL("RootLayer::MouseEventHandler(B_MOUSE_UP) fLastLayerUnderMouse is null!\n");
break;
}
// TODO: what if 'fNotifyLayer' is deleted in the mean time.
@ -1296,7 +1366,7 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
}
STRACE(("MOUSE UP: at (%f, %f)\n", evt.where.x, evt.where.y));
#endif
// TODO: This is a quick fix to avoid the endless loop with windows created
// with the B_ASYNCHRONOUS_CONTROLS flag, but please someone have a look into this.
fButtons = 0;
@ -1320,6 +1390,9 @@ fprintf(stderr, "mouse position changed in B_MOUSE_UP (%.1f, %.1f) from last B_M
evt.where.ConstrainTo(fFrame);
#ifdef NEW_INPUT_HANDLING
// move cursor on screen
GetHWInterface()->MoveCursorTo(evt.where.x, evt.where.y);
_ProcessMouseMovedEvent(evt);
#else
GetHWInterface()->MoveCursorTo(evt.where.x, evt.where.y);
@ -1871,10 +1944,10 @@ RootLayer::SetNotifyLayer(Layer *lay, uint32 mask, uint32 options)
Lock();
#if 0 // to be removed when the new "event" stuff is ready
#if NEW_INPUT_HANDLING // to be removed when the new "event" stuff is ready
fNotifyLayer = lay;
fSavedEventMask = lay->EventMask();
fSavedOptions = lay->EventOptions();
fSavedEventOptions = lay->EventOptions();
AddToInputNotificationLists(lay, mask, options);

View File

@ -142,7 +142,9 @@ public:
private:
friend class Desktop;
#ifdef NEW_INPUT_HANDLING
friend class WinBorder; // temporarily, I need invalidate_layer()
#endif
// these are meant for Desktop class only!
void AddWinBorder(WinBorder* winBorder);
void RemoveWinBorder(WinBorder* winBorder);

View File

@ -450,16 +450,134 @@ WinBorder::GetSizeLimits(float* minWidth, float* maxWidth,
void
WinBorder::MouseDown(const PointerEvent& event)
{
if (fDecorator) {
click_type action = _ActionFor(event);
// 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:
fIsDragging = true;
#ifdef NEW_INPUT_HANDLING
GetRootLayer()->SetNotifyLayer(this, B_POINTER_EVENTS, 0UL);
#endif
fLastMousePosition = event.where;
STRACE_CLICK(("===> DEC_DRAG\n"));
break;
case DEC_RESIZE:
fIsResizing = true;
fLastMousePosition = event.where;
STRACE_CLICK(("===> DEC_RESIZE\n"));
break;
case DEC_SLIDETAB:
fIsSlidingTab = true;
fLastMousePosition = event.where;
STRACE_CLICK(("===> DEC_SLIDETAB\n"));
break;
default:
break;
}
}
// TODO: set dirty regions!
#ifndef NEW_CLIPPING
GetRootLayer()->invalidate_layer(this, VisibleRegion());
#else
do_Invalidate(VisibleRegion());
#endif
}
void
WinBorder::MouseUp(const PointerEvent& event)
{
if (fDecorator) {
click_type action = _ActionFor(event);
if (fIsZooming) {
fIsZooming = false;
fDecorator->SetZoom(false);
if (action == DEC_ZOOM)
Window()->NotifyZoom();
return;
}
if (fIsClosing) {
fIsClosing = false;
fDecorator->SetClose(false);
if (action == DEC_CLOSE)
Window()->NotifyQuitRequested();
return;
}
if (fIsMinimizing) {
fIsMinimizing = false;
fDecorator->SetMinimize(false);
if (action == DEC_MINIMIZE)
Window()->NotifyMinimize(true);
return;
}
}
fIsDragging = false;
fIsResizing = false;
fIsSlidingTab = false;
// TODO: set dirty regions!
#ifndef NEW_CLIPPING
GetRootLayer()->invalidate_layer(this, VisibleRegion());
#else
do_Invalidate(VisibleRegion());
#endif
}
void
WinBorder::MouseMoved(const PointerEvent& event, uint32 transit)
{
if (fDecorator) {
if (fIsZooming) {
fDecorator->SetZoom(_ActionFor(event) == DEC_ZOOM);
} else if (fIsClosing) {
fDecorator->SetClose(_ActionFor(event) == DEC_CLOSE);
} else if (fIsMinimizing) {
fDecorator->SetMinimize(_ActionFor(event) == DEC_MINIMIZE);
}
}
if (fIsDragging) {
BPoint delta = event.where - fLastMousePosition;
#ifndef NEW_CLIPPING
MoveBy(delta.x, delta.y);
#else
do_MoveBy(delta.x, delta.y);
#endif
}
if (fIsResizing) {
BPoint delta = event.where - fLastMousePosition;
#ifndef NEW_CLIPPING
ResizeBy(delta.x, delta.y);
#else
do_ResizeBy(delta.x, delta.y);
#endif
}
if (fIsSlidingTab) {
// TODO: implement
}
fLastMousePosition = event.where;
}
#else
@ -745,6 +863,7 @@ WinBorder::QuietlySetFeel(int32 feel)
click_type
WinBorder::_ActionFor(const PointerEvent& event) const
{
#ifndef NEW_INPUT_HANDING
#ifndef NEW_CLIPPING
if (fTopLayer->fFullVisible.Contains(event.where))
return DEC_NONE;
@ -753,6 +872,7 @@ WinBorder::_ActionFor(const PointerEvent& event) const
if (fTopLayer->fFullVisible2.Contains(event.where))
return DEC_NONE;
else
#endif
#endif
if (fDecorator)
return fDecorator->Clicked(event.where, event.buttons, event.modifiers);

View File

@ -85,6 +85,8 @@ class WinBorder : public Layer {
virtual void MouseDown(const PointerEvent& evt);
virtual void MouseUp(const PointerEvent& evt);
virtual void MouseMoved(const PointerEvent& evt, uint32 transit);
click_type ActionFor(const PointerEvent& evt)
{ return _ActionFor(evt); }
#else
click_type MouseDown(const PointerEvent& evt);
void MouseMoved(const PointerEvent& evt);

View File

@ -219,7 +219,36 @@ Workspace::Active() const
//return fActiveItem ? fActiveItem->layerPtr: NULL;
}
void
Workspace::GetState(Workspace::State *state) const
{
state->Front = Front();
state->Focus = Focus();
ListData *cursor = fBottomItem;
while (cursor) {
if (!cursor->layerPtr->IsHidden())
state->WindowList.AddItem(cursor->layerPtr);
cursor = cursor->upperItem;
}
}
bool
Workspace::AttemptToSetFront(WinBorder *newFront)
{
return MoveToFront(newFront);
}
bool
Workspace::AttemptToSetFocus(WinBorder *newFocus)
{
return SetFocus(newFocus);
}
bool
Workspace::AttemptToMoveToBack(WinBorder *newBack)
{
return MoveToBack(newBack);
}
/*
\brief This method provides you the list of visible windows in this workspace.
\param list The list of visible WinBorders found in this workspace.

View File

@ -49,6 +49,13 @@ struct ListData
class Workspace {
public:
class State {
public:
State() : Front(NULL), Focus(NULL), WindowList(40) { }
WinBorder* Front;
WinBorder* Focus;
BList WindowList;
};
Workspace( const int32 ID,
const uint32 colorspace,
const RGBColor& BGColor);
@ -63,6 +70,10 @@ class Workspace {
WinBorder* Focus() const;
WinBorder* Front() const;
WinBorder* Active() const;
void GetState(Workspace::State *state) const;
bool AttemptToSetFront(WinBorder *newFront);
bool AttemptToSetFocus(WinBorder *newFocus);
bool AttemptToMoveToBack(WinBorder *newBack);
bool GetWinBorderList(void **list, int32 *itemCount ) const;