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:
parent
a59bd8b8bc
commit
8b94d5ecdd
@ -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);
|
||||
|
@ -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; }
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user