From 39cdae74a7fc098db3a59a3e9db03b6ad57ab991 Mon Sep 17 00:00:00 2001 From: Michael Lotz Date: Mon, 10 Apr 2006 21:22:05 +0000 Subject: [PATCH] First steps at getting drag & drop to work properly. Simple drag & drop (draging Tracker items) should work now. Not sure about the negotiated version (with mimetype exchange). Fixed left behind drag bitmaps. Some cleanup. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@17058 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- headers/private/app/MessagePrivate.h | 9 ++++ src/kits/interface/View.cpp | 22 ++++---- src/kits/interface/Window.cpp | 69 +++++++++++++------------ src/servers/app/EventDispatcher.cpp | 9 ++-- src/servers/app/EventDispatcher.h | 1 + src/servers/app/ServerWindow.cpp | 3 +- src/servers/app/drawing/HWInterface.cpp | 4 +- 7 files changed, 67 insertions(+), 50 deletions(-) diff --git a/headers/private/app/MessagePrivate.h b/headers/private/app/MessagePrivate.h index f28c663dda..263e435614 100644 --- a/headers/private/app/MessagePrivate.h +++ b/headers/private/app/MessagePrivate.h @@ -136,6 +136,15 @@ class BMessage::Private { return fMessage->fHeader->target == B_PREFERRED_TOKEN; } + void + SetWasDropped(bool wasDropped) + { + if (wasDropped) + fMessage->fHeader->flags |= MESSAGE_FLAG_WAS_DROPPED; + else + fMessage->fHeader->flags &= ~MESSAGE_FLAG_WAS_DROPPED; + } + status_t Clear() { diff --git a/src/kits/interface/View.cpp b/src/kits/interface/View.cpp index 5df5c74ad0..8f6646e1ef 100644 --- a/src/kits/interface/View.cpp +++ b/src/kits/interface/View.cpp @@ -1266,20 +1266,21 @@ BView::DragMessage(BMessage *message, BRect dragRect, BHandler *replyTo) message->AddInt32("buttons", buttons); } - BMessage::Private(message).SetReply(BMessenger(replyTo, replyTo->Looper())); + BMessage::Private privateMessage(message); + privateMessage.SetReply(BMessenger(replyTo, replyTo->Looper())); - int32 bufferSize = message->FlattenedSize(); + int32 bufferSize = privateMessage.NativeFlattenedSize(); char* buffer = new (nothrow) char[bufferSize]; if (buffer) { - message->Flatten(buffer, bufferSize); - + privateMessage.NativeFlatten(buffer, bufferSize); + fOwner->fLink->StartMessage(AS_LAYER_DRAG_RECT); fOwner->fLink->Attach(dragRect); fOwner->fLink->Attach(offset); fOwner->fLink->Attach(bufferSize); fOwner->fLink->Attach(buffer, bufferSize); fOwner->fLink->Flush(); - + delete [] buffer; } else { fprintf(stderr, "BView::DragMessage() - no memory to flatten drag message\n"); @@ -1323,13 +1324,14 @@ BView::DragMessage(BMessage *message, BBitmap *image, message->AddInt32("buttons", buttons); } - BMessage::Private(message).SetReply(BMessenger(replyTo, replyTo->Looper())); + BMessage::Private privateMessage(message); + privateMessage.SetReply(BMessenger(replyTo, replyTo->Looper())); - int32 bufferSize = message->FlattenedSize(); + int32 bufferSize = privateMessage.NativeFlattenedSize(); char* buffer = new (nothrow) char[bufferSize]; if (buffer) { - message->Flatten(buffer, bufferSize); - + privateMessage.NativeFlatten(buffer, bufferSize); + fOwner->fLink->StartMessage(AS_LAYER_DRAG_IMAGE); fOwner->fLink->Attach(image->_ServerToken()); fOwner->fLink->Attach((int32)dragMode); @@ -1342,7 +1344,7 @@ BView::DragMessage(BMessage *message, BBitmap *image, // before we can delete the bitmap int32 code; fOwner->fLink->FlushWithReply(code); - + delete [] buffer; } else { fprintf(stderr, "BView::DragMessage() - no memory to flatten drag message\n"); diff --git a/src/kits/interface/Window.cpp b/src/kits/interface/Window.cpp index d2586e21c5..9b635d4a62 100644 --- a/src/kits/interface/Window.cpp +++ b/src/kits/interface/Window.cpp @@ -897,57 +897,60 @@ FrameMoved(origin); case B_MOUSE_DOWN: { - BPoint where; - msg->FindPoint("be:view_where", &where); - - if (BView *view = dynamic_cast(target)) + if (BView *view = dynamic_cast(target)) { + BPoint where; + msg->FindPoint("be:view_where", &where); view->MouseDown(where); - else + } else target->MessageReceived(msg); + break; } case B_MOUSE_UP: { - BPoint where; - msg->FindPoint("be:view_where", &where); - - if (BView *view = dynamic_cast(target)) + if (BView *view = dynamic_cast(target)) { + BPoint where; + msg->FindPoint("be:view_where", &where); view->MouseUp(where); - else + } else target->MessageReceived(msg); + break; } case B_MOUSE_MOVED: { - BPoint where; - uint32 buttons; - uint32 transit; - msg->FindPoint("be:view_where", &where); - msg->FindInt32("buttons", (int32*)&buttons); - msg->FindInt32("be:transit", (int32*)&transit); -// bigtime_t when; -// if (msg->FindInt64("when", (int64*)&when) < B_OK) -// printf("BWindow B_MOUSE_MOVED no when\n"); -// else if (system_time() - when > 5000) { -// printf("BWindow B_MOUSE_MOVED lagging behind\n"); -// } - BMessage* dragMessage = NULL; - if (msg->HasMessage("be:drag_message")) { - dragMessage = new BMessage(); - if (msg->FindMessage("be:drag_message", dragMessage) != B_OK) { - delete dragMessage; - dragMessage = NULL; - } - } + if (BView *view = dynamic_cast(target)) { + BPoint where; + uint32 buttons; + uint32 transit; + msg->FindPoint("be:view_where", &where); + msg->FindInt32("buttons", (int32*)&buttons); + msg->FindInt32("be:transit", (int32*)&transit); + +#if 0 + bigtime_t when; + if (msg->FindInt64("when", (int64*)&when) < B_OK) + printf("BWindow B_MOUSE_MOVED no when\n"); + else if (system_time() - when > 5000) + printf("BWindow B_MOUSE_MOVED lagging behind\n"); +#endif + + BMessage* dragMessage = NULL; + if (msg->HasMessage("be:drag_message")) { + dragMessage = new BMessage(); + if (msg->FindMessage("be:drag_message", dragMessage) != B_OK) { + delete dragMessage; + dragMessage = NULL; + } + } - if (BView *view = dynamic_cast(target)) view->MouseMoved(where, transit, dragMessage); - else + delete dragMessage; + } else target->MessageReceived(msg); - delete dragMessage; break; } diff --git a/src/servers/app/EventDispatcher.cpp b/src/servers/app/EventDispatcher.cpp index a079155f6d..75ebb22dcf 100644 --- a/src/servers/app/EventDispatcher.cpp +++ b/src/servers/app/EventDispatcher.cpp @@ -15,6 +15,7 @@ #include "InputManager.h" #include "ServerBitmap.h" +#include #include #include @@ -524,10 +525,9 @@ EventDispatcher::SetDragMessage(BMessage& message, fHWInterface->SetDragBitmap(bitmap, offsetFromCursor); - BAutolock _(this); - fDragMessage = message; fDraggingMessage = true; + fDragOffset = offsetFromCursor; } @@ -630,12 +630,13 @@ EventDispatcher::_DeliverDragMessage() ETRACE(("EventDispatcher::_DeliverDragMessage()\n")); if (fDraggingMessage && fPreviousMouseTarget != NULL) { + BMessage::Private(fDragMessage).SetWasDropped(true); fDragMessage.RemoveName("_original_what"); fDragMessage.AddInt32("_original_what", fDragMessage.what); + fDragMessage.AddPoint("_drop_point_", fLastCursorPosition); + fDragMessage.AddPoint("_drop_offset_", fDragOffset); fDragMessage.what = _MESSAGE_DROPPED_; -// fDragMessage.AddBool("dropped", true); -//printf(" sending message to previous mouse target\n"); _SendMessage(fPreviousMouseTarget->Messenger(), &fDragMessage, 100.0); } diff --git a/src/servers/app/EventDispatcher.h b/src/servers/app/EventDispatcher.h index 0224dc090b..5bb3ed96e9 100644 --- a/src/servers/app/EventDispatcher.h +++ b/src/servers/app/EventDispatcher.h @@ -139,6 +139,7 @@ class EventDispatcher : public BLocker { BMessage fDragMessage; bool fDraggingMessage; + BPoint fDragOffset; ServerBitmap* fDragBitmap; // NOTE: unfortunately, the EventDispatcher // has to know what a ServerBitmap is... diff --git a/src/servers/app/ServerWindow.cpp b/src/servers/app/ServerWindow.cpp index 461696f383..0e55f83ef9 100644 --- a/src/servers/app/ServerWindow.cpp +++ b/src/servers/app/ServerWindow.cpp @@ -1782,8 +1782,7 @@ ServerWindow::_DispatchViewMessage(int32 code, if (link.Read(buffer, bufferSize) == B_OK && dragMessage.Unflatten(buffer) == B_OK) { fDesktop->EventDispatcher().SetDragMessage(dragMessage, - NULL, // should be dragRect - offset); + NULL /* should be dragRect */, offset); } delete[] buffer; } diff --git a/src/servers/app/drawing/HWInterface.cpp b/src/servers/app/drawing/HWInterface.cpp index 6264d5a271..55f2befe7e 100644 --- a/src/servers/app/drawing/HWInterface.cpp +++ b/src/servers/app/drawing/HWInterface.cpp @@ -637,7 +637,7 @@ HWInterface::_AdoptDragBitmap(const ServerBitmap* bitmap, const BPoint& offset) } _RestoreCursorArea(); - Invalidate(_CursorFrame()); + BRect cursorFrame = _CursorFrame(); if (fCursorAndDragBitmap && fCursorAndDragBitmap != fCursor) { delete fCursorAndDragBitmap; @@ -764,6 +764,8 @@ HWInterface::_AdoptDragBitmap(const ServerBitmap* bitmap, const BPoint& offset) fCursorAndDragBitmap = fCursor; } + Invalidate(cursorFrame); + // NOTE: the EventDispatcher does the reference counting stuff for us // TODO: You can not simply call Release() on a ServerBitmap like you // can for a ServerCursor... it could be changed, but there are linking