CtrlCore: Cocoa Drag&Drop fixes

git-svn-id: svn://ultimatepp.org/upp/trunk@12326 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2018-10-01 09:51:25 +00:00
parent 3ea64f31f3
commit df85cae278
7 changed files with 73 additions and 51 deletions

View file

@ -341,17 +341,6 @@ void MMCtrl::SyncRect(CocoView *view)
MakeScreenRect([win screen], [win contentRectForFrameRect: [win frame]]));
}
void AppendClipboardText(const String& s)
{
CFRef<CFStringRef> cs = CFStringCreateWithCString(NULL, (const char *)~s.ToString(), kCFStringEncodingUTF8);
[[NSPasteboard generalPasteboard] setString:(NSString *)~cs forType:NSPasteboardTypeString];
}
void AppendClipboardUnicodeText(const WString& s)
{
AppendClipboardText(s.ToString());
}
ViewDraw::ViewDraw(Ctrl *ctrl)
{
EnterGuiMutex();

View file

@ -210,6 +210,19 @@ WString ReadClipboardUnicodeText()
return ReadClipboardText().ToWString();
}
void AppendClipboardText(const String& s)
{
AppendClipboard("text", s);
// TODO Remove:
// CFRef<CFStringRef> cs = CFStringCreateWithCString(NULL, (const char *)~s.ToString(), kCFStringEncodingUTF8);
// [[NSPasteboard generalPasteboard] setString:(NSString *)~cs forType:NSPasteboardTypeString];
}
void AppendClipboardUnicodeText(const WString& s)
{
AppendClipboardText(s.ToString());
}
const char *ClipFmtsText()
{
return "text";
@ -379,7 +392,7 @@ Ctrl * Ctrl::GetDragAndDropSource()
}
- (void)draggedImage:(NSImage *)anImage endedAt:(NSPoint)aPoint operation:(NSDragOperation)operation
{ // TODO: Looks like between apps, it is always move (?!)
{
result = operation;
}
@ -387,6 +400,8 @@ Ctrl * Ctrl::GetDragAndDropSource()
namespace Upp {
bool Ctrl::local_dnd_copy;
int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions,
const VectorMap<String, ClipData>& data)
{
@ -423,14 +438,19 @@ int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions,
src->actions |= NSDragOperationCopy;
if(actions & DND_MOVE)
src->actions |= NSDragOperationMove;
NSPoint p = [sCurrentMouseEvent__ locationInWindow];
p.y -= size.height;
local_dnd_copy = false; // macos does not have ability to change action in performDragOperation
[nswindow dragImage:nsimg
at:[sCurrentMouseEvent__ locationInWindow]
offset:NSMakeSize(0, 0)
event:sCurrentMouseEvent__
pasteboard:Pasteboard(true)
source:src
slideBack:YES];
at:p
offset:NSMakeSize(0, 0)
event:sCurrentMouseEvent__
pasteboard:Pasteboard(true)
source:src
slideBack:YES];
ClipboardOwner(true)->source = NULL;
@ -438,6 +458,9 @@ int Ctrl::DoDragAndDrop(const char *fmts, const Image& sample, dword actions,
CGImageRelease(cgimg);
if(local_dnd_copy) // action was local and changed to copy in DragAndDrop
return DND_COPY;
return decode(src->result, NSDragOperationCopy, DND_COPY,
NSDragOperationMove, DND_MOVE,
DND_NONE);

View file

@ -9,6 +9,7 @@ private:
static int WndCaretTime;
static bool WndCaretVisible;
static bool local_dnd_copy;
static void AnimateCaret();
friend void CocoInit(int argc, const char **argv, const char **envptr);

View file

@ -169,6 +169,9 @@ NSCursor *GetNSCursor(int kind)
void Ctrl::SetMouseCursor(const Image& img)
{
if(GetDragAndDropSource())
return;
int64 h = img.GetAuxData();
if(h) {
[GetNSCursor(h) set];
@ -205,7 +208,7 @@ void ImageDraw::Init(int cx, int cy)
{
ib.Create(cx, cy);
static CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); // TODO: This is probably wrong...
static CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
SystemDraw::Init(CGBitmapContextCreateWithData(~ib, cx, cy, 8, cx * sizeof(RGBA),
colorSpace, kCGImageAlphaPremultipliedFirst,

View file

@ -61,6 +61,32 @@ bool Ctrl::ReleaseWndCapture()
}
struct MMImp {
static bool KeyFlags(Upp::Ctrl *ctrl, NSEvent *e) {
bool alt = GetAlt();
bool ctl = GetCtrl();
bool sht = GetShift();
bool opt = GetOption();
Flags(e);
if(!ctrl->IsEnabled())
return false;
if(alt != GetAlt())
ctrl->DispatchKey(K_ALT_KEY|(alt * K_KEYUP), 1);
if(ctl != GetCtrl())
ctrl->DispatchKey(K_CTRL_KEY|(ctl * K_KEYUP), 1);
if(sht != GetShift())
ctrl->DispatchKey(K_SHIFT_KEY|(sht * K_KEYUP), 1);
if(opt != GetOption())
ctrl->DispatchKey(K_OPTION_KEY|(opt * K_KEYUP), 1);
return true;
}
static void Flags(NSEvent *e)
{
coco_flags = [e modifierFlags];
}
static bool MouseEvent(CocoView *view, NSEvent *e, int event, double zd = 0)
{
sCurrentMouseEvent__ = e;
@ -72,6 +98,7 @@ struct MMImp {
Rect r = view->ctrl->GetRect();
Upp::Point p(DPI(np.x), DPI(np.y));
coco_mouse_pos = p + r.TopLeft();
Flags(e);
if(view->ctrl->IsEnabled() && (view->ctrl->HasWndCapture() || r.Contains(coco_mouse_pos)))
view->ctrl->DispatchMouse(event, p, 120 * sgn(zd));
sCurrentMouseEvent__ = NULL;
@ -100,11 +127,6 @@ struct MMImp {
return b;
}
static void Flags(NSEvent *e)
{
coco_flags = [e modifierFlags];
}
static void Paint(Upp::Ctrl *ctrl, Upp::SystemDraw& w, const Rect& r)
{
ctrl->fullrefresh = false;
@ -142,27 +164,6 @@ struct MMImp {
return true;
}
static bool KeyFlags(Upp::Ctrl *ctrl, NSEvent *e) {
bool alt = GetAlt();
bool ctl = GetCtrl();
bool sht = GetShift();
bool opt = GetOption();
Flags(e);
if(!ctrl->IsEnabled())
return false;
if(alt != GetAlt())
ctrl->DispatchKey(K_ALT_KEY|(alt * K_KEYUP), 1);
if(ctl != GetCtrl())
ctrl->DispatchKey(K_CTRL_KEY|(ctl * K_KEYUP), 1);
if(sht != GetShift())
ctrl->DispatchKey(K_SHIFT_KEY|(sht * K_KEYUP), 1);
if(opt != GetOption())
ctrl->DispatchKey(K_OPTION_KEY|(opt * K_KEYUP), 1);
return true;
}
static void BecomeKey(Upp::Ctrl *ctrl)
{
LLOG("Become key " << Upp::Name(ctrl));
@ -192,9 +193,12 @@ struct MMImp {
clip.paste = paste;
clip.accepted = false;
clip.allowed = DND_MOVE|DND_COPY; // TODO: Use draggingSourceOperationMask
clip.action = info.draggingSourceOperationMask & NSDragOperationMove ? DND_MOVE
: DND_COPY;
NSPoint np = [nsview convertPoint:[info draggingLocation] fromView:nil];
ctrl->DnD(Upp::Point(DPI(np.x), DPI(np.y)) + ctrl->GetScreenView().TopLeft(), clip);
// TODO: Resolve allowed actions
ctrl->DnD(Upp::Point(DPI(np.x), DPI(np.y)) + ctrl->GetScreenRect().TopLeft(), clip);
if(paste && clip.IsAccepted() && clip.GetAction() == DND_COPY)
Ctrl::local_dnd_copy = true;
return clip.IsAccepted() ? clip.GetAction() == DND_MOVE ? NSDragOperationMove
: NSDragOperationCopy
: NSDragOperationNone;
@ -279,6 +283,7 @@ struct MMImp {
}
- (void)cursorUpdate:(NSEvent *)event {
Upp::MMImp::Flags(event);
Upp::MMImp::DoCursorShape();
}
@ -323,17 +328,17 @@ struct MMImp {
- (void)draggingEnded:(id <NSDraggingInfo>)sender
{
return Upp::MMImp::DnDLeave(ctrl);
Upp::MMImp::DnDLeave(ctrl);
}
- (void)draggingExited:(id <NSDraggingInfo>)sender
{
return Upp::MMImp::DnDLeave(ctrl);
Upp::MMImp::DnDLeave(ctrl);
}
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
return Upp::MMImp::DnD(ctrl, sender, true);
return Upp::MMImp::DnD(ctrl, sender, true) != NSDragOperationNone;
}
@end

View file

@ -215,7 +215,7 @@ void Ctrl::DnDRepeat()
UPP::KillTimeCallback(&dndpos);
}
void Ctrl::DnD(Point p, PasteClip& clip)
void Ctrl::DnD(Point p, PasteClip& clip)
{
GuiLock __;
UPP::KillTimeCallback(&dndpos);

View file

@ -2,6 +2,7 @@ sooner:
- fix modifier keys (read before each event)
- Ctrl key gets stuck
- initial focus in uword
- icondes - rightclick on image in the list, then move mouse over color ramp - weird focus issue happens