diff --git a/rainbow/Framebuffer/Clip.cpp b/rainbow/Framebuffer/Clip.cpp index 5b81c425e..c22765b83 100644 --- a/rainbow/Framebuffer/Clip.cpp +++ b/rainbow/Framebuffer/Clip.cpp @@ -233,20 +233,6 @@ Vector GetFiles(PasteClip& clip) return f; } -bool PasteClip::IsAvailable(const char *fmt) const -{ - return IsClipboardAvailable(fmt); -} - -String PasteClip::Get(const char *fmt) const -{ - return ReadClipboard(fmt); -} - -void PasteClip::GuiPlatformConstruct() -{ -} - END_UPP_NAMESPACE #endif diff --git a/rainbow/Framebuffer/Ctrl.h b/rainbow/Framebuffer/Ctrl.h index b81ef334c..dbf7061ac 100644 --- a/rainbow/Framebuffer/Ctrl.h +++ b/rainbow/Framebuffer/Ctrl.h @@ -47,6 +47,7 @@ private: friend struct PaintProxy__; friend class TopWindowFrame; friend class SystemDraw; + friend struct DnDLoop; void SetOpen(bool b) { isopen = b; } @@ -74,6 +75,8 @@ public: void DragRectDraw(const Rect& rect1, const Rect& rect2, const Rect& clip, int n, Color color, int type, int animation); + static Ctrl *FindMouseTopCtrl(); + static bool FullWindowDrag; enum { DRAWDRAGRECT_SCREEN = 0x8000 }; diff --git a/rainbow/Framebuffer/DnD.cpp b/rainbow/Framebuffer/DnD.cpp index af619c255..c684f2974 100644 --- a/rainbow/Framebuffer/DnD.cpp +++ b/rainbow/Framebuffer/DnD.cpp @@ -16,14 +16,17 @@ Ctrl * Ctrl::GetDragAndDropSource() } struct DnDLoop : LocalLoop { - Image move, copy, reject; const VectorMap *data; - Ptr source; - int action; + Vector fmts; - void Sync(); + Image move, copy, reject; + Ptr target; + int action; + byte actions; + + void Sync(); String GetData(const String& f); - void Leave(); + void DnD(bool paste); virtual void LeftUp(Point, dword); virtual bool Key(dword, int); @@ -33,20 +36,67 @@ struct DnDLoop : LocalLoop { Ptr dndloop; -void DnDLoop::Leave() +bool PasteClip::IsAvailable(const char *fmt) const { - GuiLock __; + DDUMP(fmt); + GuiLock __; + return dnd ? dndloop && FindIndex(dndloop->fmts, fmt) >= 0 + : IsClipboardAvailable(fmt); +} + +String DnDLoop::GetData(const String& f) +{ + GuiLock __; + int i = data->Find(f); + String d; + if(i >= 0) + d = (*data)[i].Render(); + else + if(sDnDSource) + d = sDnDSource->GetDropData(f); + return d; +} + +String PasteClip::Get(const char *fmt) const +{ + return dnd ? dndloop ? dndloop->GetData(fmt) : String() : ReadClipboard(fmt); +} + +void PasteClip::GuiPlatformConstruct() +{ + dnd = false; +} + +void DnDLoop::DnD(bool paste) +{ + PasteClip d; + d.paste = paste; + d.accepted = false; + d.allowed = (byte)actions; + d.action = GetCtrl() ? DND_COPY : DND_MOVE; + d.dnd = true; + if(target) + target->DnD(GetMousePos() - target->GetScreenRect().TopLeft(), d); + action = d.IsAccepted() ? d.GetAction() : DND_NONE; } void DnDLoop::Sync() { - GuiLock __; + GuiLock __; + + Ptr t = FindMouseTopCtrl(); + if(t != target) + if(target) + target->DnDLeave(); + target = t; + DnD(false); } void DnDLoop::LeftUp(Point, dword) { GuiLock __; LLOG("DnDLoop::LeftUp"); + DnD(true); /* if(target) { LLOG("Sending XdndDrop to " << target); XEvent e = ClientMsg(target, XdndDrop); @@ -95,34 +145,21 @@ Image DnDLoop::CursorImage(Point, dword) return action == DND_MOVE ? move : action == DND_COPY ? copy : reject; } -String DnDLoop::GetData(const String& f) -{ - GuiLock __; - int i = data->Find(f); - String d; - if(i >= 0) - d = (*data)[i].Render(); - else - if(source) - d = source->GetDropData(f); - return d; -} - int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions, const VectorMap& data) { GuiLock __; DnDLoop d; - PNGEncoder().SaveFile("U://sample.png", sample); _DBG_ + d.actions = actions; d.reject = actions & DND_EXACTIMAGE ? CtrlCoreImg::DndNone() : MakeDragImage(CtrlCoreImg::DndNone(), sample); - PNGEncoder().SaveFile("U://reject.png", d.reject); _DBG_ if(actions & DND_COPY) d.copy = actions & DND_EXACTIMAGE ? sample : MakeDragImage(CtrlCoreImg::DndCopy(), sample); if(actions & DND_MOVE) d.move = actions & DND_EXACTIMAGE ? sample : MakeDragImage(CtrlCoreImg::DndMoveX11(), sample); d.SetMaster(*this); d.data = &data; - d.source = this; + d.action = DND_NONE; + d.fmts = Split(fmts, ';'); dndloop = &d; sDnDSource = this; d.Run(); diff --git a/rainbow/Framebuffer/Event.cpp b/rainbow/Framebuffer/Event.cpp index b4b156b27..75b37ca9b 100644 --- a/rainbow/Framebuffer/Event.cpp +++ b/rainbow/Framebuffer/Event.cpp @@ -32,6 +32,16 @@ void Ctrl::MouseEventFB(Ptr t, int event, Point p, int zdelta) t->PostInput(); } +Ctrl *Ctrl::FindMouseTopCtrl() +{ + for(int i = topctrl.GetCount() - 1; i >= 0; i--) { + Ctrl *t = topctrl[i]; + if(t->GetRect().Contains(fbmousepos)) + return t->IsEnabled() ? t : NULL; + } + return desktop->IsEnabled() ? desktop : NULL; +} + void Ctrl::DoMouseFB(int event, Point p, int zdelta) { fbmousepos = p; diff --git a/rainbow/Framebuffer/Framebuffer.h b/rainbow/Framebuffer/Framebuffer.h index 7563d752e..4372e4470 100644 --- a/rainbow/Framebuffer/Framebuffer.h +++ b/rainbow/Framebuffer/Framebuffer.h @@ -95,7 +95,9 @@ class TopWindowFrame; #define GUIPLATFORM_CTRL_DECLS_INCLUDE -#define GUIPLATFORM_PASTECLIP_DECLS +#define GUIPLATFORM_PASTECLIP_DECLS \ + bool dnd; \ + friend struct DnDLoop; \ #define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE diff --git a/rainbow/Framebuffer/Wnd.cpp b/rainbow/Framebuffer/Wnd.cpp index 1f9206fe2..afb024139 100644 --- a/rainbow/Framebuffer/Wnd.cpp +++ b/rainbow/Framebuffer/Wnd.cpp @@ -4,9 +4,9 @@ NAMESPACE_UPP -#define LLOG(x) //DLOG(x) -#define LDUMP(x) //DDUMP(x) -#define LDUMPC(x) //DDUMPC(x) +#define LLOG(x) DLOG(x) +#define LDUMP(x) DDUMP(x) +#define LDUMPC(x) DDUMPC(x) ImageBuffer Ctrl::framebuffer; Vector Ctrl::invalid; @@ -419,7 +419,7 @@ void Ctrl::EventLoop0(Ctrl *ctrl) ASSERT(IsMainThread()); ASSERT(LoopLevel == 0 || ctrl); LoopLevel++; - LLOG("Entering event loop at level " << LoopLevel << BeginIndent); + LLOG("Entering event loop at level " << LoopLevel << LOG_BEGIN); Ptr ploop; if(ctrl) { ploop = LoopCtrl; @@ -447,7 +447,7 @@ void Ctrl::EventLoop0(Ctrl *ctrl) if(ctrl) LoopCtrl = ploop; LoopLevel--; - LLOG(EndIndent << "Leaving event loop "); + LLOG(LOG_END << "Leaving event loop "); } void Ctrl::GuiSleep0(int ms)