CtrlCore: Cocoa Drag&Drop

git-svn-id: svn://ultimatepp.org/upp/trunk@12315 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
cxl 2018-09-27 13:58:15 +00:00
parent fe46fbf49a
commit e53a81a71d
11 changed files with 209 additions and 110 deletions

View file

@ -32,11 +32,11 @@ void AssertFailed(const char *file, int line, const char *cond);
void InstallPanicMessageBox(void (*mb)(const char *title, const char *text));
void PanicMessageBox(const char *title, const char *text);
#define VERIFY(x) ((x) ? (void)0 : UPP::AssertFailed(__FILE__, __LINE__, #x))
#define VERIFY(x) ((x) ? (void)0 : ::Upp::AssertFailed(__FILE__, __LINE__, #x))
#ifdef _DEBUG
#define ASSERT_(x, msg) ((x) ? (void)0 : UPP::AssertFailed(__FILE__, __LINE__, msg))
#define ASSERT_(x, msg) ((x) ? (void)0 : ::Upp ::AssertFailed(__FILE__, __LINE__, msg))
#define ASSERT(x) ASSERT_(x, #x)
#else

View file

@ -276,8 +276,8 @@ public:
typedef std::atomic<bool> OnceFlag;
#define ONCELOCK_(o_b_) \
for(static UPP::Mutex o_ss_; !o_b_.load(std::memory_order_acquire);) \
for(UPP::Mutex::Lock o_ss_lock__(o_ss_); !o_b_.load(std::memory_order_acquire); o_b_.store(true, std::memory_order_release))
for(static ::Upp::Mutex o_ss_; !o_b_.load(std::memory_order_acquire);) \
for(::Upp::Mutex::Lock o_ss_lock__(o_ss_); !o_b_.load(std::memory_order_acquire); o_b_.store(true, std::memory_order_release))
#define ONCELOCK \
for(static OnceFlag o_b_; !o_b_.load(std::memory_order_acquire);) ONCELOCK_(o_b_)

View file

@ -163,7 +163,9 @@ struct MMImp;
#define GUIPLATFORM_CTRL_DECLS_INCLUDE <CtrlCore/CocoCtrl.h>
#define GUIPLATFORM_PASTECLIP_DECLS
#define GUIPLATFORM_PASTECLIP_DECLS \
void *nspasteboard; \
friend struct MMImp;
#define GUIPLATFORM_TOPWINDOW_DECLS_INCLUDE <CtrlCore/CocoTop.h>

View file

@ -1,11 +1,13 @@
#include "CocoMM.h"
#ifdef PLATFORM_COCOA
#define LLOG(x) // DLOG(x)
int Upp::Ctrl::WndCaretTime;
bool Upp::Ctrl::WndCaretVisible;
#ifdef PLATFORM_COCOA
namespace Upp {
int Ctrl::WndCaretTime;
bool Ctrl::WndCaretVisible;
static NSAutoreleasePool *main_coco_pool;
static NSEvent *current_event;
@ -31,7 +33,7 @@ static void ReleaseCurrentEvent()
void SyncPopupFocus(NSWindow *win)
{
Upp::Ctrl *q = Upp::Ctrl::GetFocusCtrl();
Ctrl *q = Ctrl::GetFocusCtrl();
if(q) {
q = q->GetTopCtrl();
if(q->IsPopUp() && q->GetNSWindow() != win) {
@ -41,11 +43,9 @@ void SyncPopupFocus(NSWindow *win)
}
}
namespace Upp {
extern const char *sClipFmtsRTF;
};
extern const char *sClipFmtsRTF;
void Upp::CocoInit(int argc, const char **argv, const char **envptr)
void CocoInit(int argc, const char **argv, const char **envptr)
{
Ctrl::GlobalBackBuffer();
main_coco_pool = [NSAutoreleasePool new];
@ -66,7 +66,7 @@ void Upp::CocoInit(int argc, const char **argv, const char **envptr)
[NSApp activateIgnoringOtherApps:YES];
NSFont *sysfont = [NSFont systemFontOfSize:0];
Font::SetFace(0, Upp::ToString((CFStringRef)[sysfont familyName]), Font::TTF);
Font::SetFace(0, ToString((CFStringRef)[sysfont familyName]), Font::TTF);
Ctrl::SetUHDEnabled(true);
@ -90,39 +90,39 @@ void Upp::CocoInit(int argc, const char **argv, const char **envptr)
return e;
}];
Upp::sClipFmtsRTF = "rtf";
sClipFmtsRTF = "rtf";
Upp::Ctrl::Csizeinit();
Ctrl::Csizeinit();
}
void Upp::CocoExit()
void CocoExit()
{
ReleaseCurrentEvent();
[main_coco_pool release];
}
int Upp::Ctrl::GetKbdDelay()
int Ctrl::GetKbdDelay()
{
GuiLock __;
return int(1000 * NSEvent.keyRepeatDelay);
}
int Upp::Ctrl::GetKbdSpeed()
int Ctrl::GetKbdSpeed()
{
GuiLock __;
return int(1000 * NSEvent.keyRepeatInterval);
}
bool Upp::Ctrl::IsWaitingEvent()
bool Ctrl::IsWaitingEvent()
{
return GetNextEvent(nil);
}
bool Upp::Ctrl::ProcessEvent(bool *)
bool Ctrl::ProcessEvent(bool *)
{
ASSERT(IsMainThread());
Upp::AutoreleasePool __;
AutoreleasePool __;
ONCELOCK {
[NSApp finishLaunching];
@ -144,7 +144,7 @@ bool Upp::Ctrl::ProcessEvent(bool *)
void SweepMkImageCache();
bool Upp::Ctrl::ProcessEvents(bool *quit)
bool Ctrl::ProcessEvents(bool *quit)
{
if(ProcessEvent(quit)) {
while(ProcessEvent(quit) && (!LoopCtrl || LoopCtrl->InLoop()));
@ -160,7 +160,7 @@ bool Upp::Ctrl::ProcessEvents(bool *quit)
}
void Upp::Ctrl::EventLoop(Ctrl *ctrl)
void Ctrl::EventLoop(Ctrl *ctrl)
{
GuiLock __;
ASSERT(IsMainThread());
@ -196,7 +196,7 @@ void Upp::Ctrl::EventLoop(Ctrl *ctrl)
static std::atomic<bool> sGuiSleep;
void Upp::Ctrl::GuiSleep(int ms)
void Ctrl::GuiSleep(int ms)
{
ASSERT(IsMainThread());
sGuiSleep = true;
@ -204,20 +204,24 @@ void Upp::Ctrl::GuiSleep(int ms)
sGuiSleep = false;
}
namespace Upp {
void WakeUpGuiThread(void)
{
if(sGuiSleep) {
sGuiSleep = false;
[NSApp postEvent:[NSEvent otherEventWithType:NSEventTypeApplicationDefined
location:NSMakePoint(0, 0) modifierFlags:0 timestamp:0.0
windowNumber:0 context:nil subtype: 0 data1:0 data2:0]
atStart:YES];
location:NSMakePoint(0, 0)
modifierFlags:0
timestamp:0.0
windowNumber:0
context:nil
subtype:0
data1:0
data2:0]
atStart:YES];
}
}
};
void Upp::Ctrl::AnimateCaret()
void Ctrl::AnimateCaret()
{
GuiLock __;
int v = !(((GetTickCount() - WndCaretTime) / 500) & 1);
@ -227,7 +231,7 @@ void Upp::Ctrl::AnimateCaret()
}
}
void Upp::Ctrl::PaintCaret(SystemDraw& w)
void Ctrl::PaintCaret(SystemDraw& w)
{
GuiLock __;
LLOG("PaintCaret " << Name() << ", caretCtrl: " << caretCtrl << ", WndCaretVisible: " << WndCaretVisible);
@ -235,7 +239,7 @@ void Upp::Ctrl::PaintCaret(SystemDraw& w)
w.DrawRect(caretx, carety, caretcx, caretcy, InvertColor);
}
void Upp::Ctrl::SetCaret(int x, int y, int cx, int cy)
void Ctrl::SetCaret(int x, int y, int cx, int cy)
{
GuiLock __;
LLOG("SetCaret " << Name());
@ -252,64 +256,64 @@ void Upp::Ctrl::SetCaret(int x, int y, int cx, int cy)
}
}
void Upp::Ctrl::SyncCaret() {
void Ctrl::SyncCaret() {
GuiLock __;
// LLOG("SyncCaret");
if(focusCtrl != caretCtrl) {
LLOG("SyncCaret DO " << Upp::Name(caretCtrl) << " -> " << Upp::Name(focusCtrl));
LLOG("SyncCaret DO " << Name(caretCtrl) << " -> " << Name(focusCtrl));
RefreshCaret();
caretCtrl = focusCtrl;
RefreshCaret();
}
}
Upp::Rect Upp::Ctrl::GetWorkArea() const
Rect Ctrl::GetWorkArea() const
{
return GetPrimaryWorkArea();
}
void Upp::Ctrl::GetWorkArea(Array<Rect>& rc)
void Ctrl::GetWorkArea(Array<Rect>& rc)
{
GuiLock __;
rc.Add(GetPrimaryWorkArea());
}
Upp::Rect Upp::Ctrl::GetVirtualWorkArea()
Rect Ctrl::GetVirtualWorkArea()
{
return GetPrimaryWorkArea();
}
Upp::Rect Upp::Ctrl::GetVirtualScreenArea()
Rect Ctrl::GetVirtualScreenArea()
{
return GetPrimaryWorkArea();
}
Upp::Rect MakeScreenRect(NSScreen *screen, CGRect r)
Rect MakeScreenRect(NSScreen *screen, CGRect r)
{
r.origin.y = [screen frame].size.height - r.origin.y - r.size.height;
return MakeRect(r);
}
Upp::Rect Upp::Ctrl::GetPrimaryWorkArea()
Rect Ctrl::GetPrimaryWorkArea()
{
for (NSScreen *screen in [NSScreen screens])
return DPI(1) * MakeScreenRect(screen, [screen visibleFrame]);
return Rect(0, 0, 1024, 768);
}
Upp::Rect Upp::Ctrl::GetPrimaryScreenArea()
Rect Ctrl::GetPrimaryScreenArea()
{
for (NSScreen *screen in [NSScreen screens])
return DPI(1) * MakeScreenRect(screen, [screen frame]);
return Rect(0, 0, 1024, 768);
}
bool Upp::Ctrl::IsCompositedGui()
bool Ctrl::IsCompositedGui()
{
return true;
}
Upp::Rect Upp::Ctrl::GetDefaultWindowRect()
Rect Ctrl::GetDefaultWindowRect()
{
GuiLock __;
Rect r = GetPrimaryWorkArea();
@ -324,29 +328,29 @@ Upp::Rect Upp::Ctrl::GetDefaultWindowRect()
return RectC(r.left + pos + 20, r.top + pos + 20, cx, cy);
}
void Upp::Ctrl::GuiPlatformGetTopRect(Rect& r) const
void Ctrl::GuiPlatformGetTopRect(Rect& r) const
{
}
void Upp::MMCtrl::SyncRect(CocoView *view)
void MMCtrl::SyncRect(CocoView *view)
{
NSWindow *win = [view window];
view->ctrl->SetWndRect(DPI(1) *
MakeScreenRect([win screen], [win contentRectForFrameRect: [win frame]]));
}
void Upp::AppendClipboardText(const String& s)
void AppendClipboardText(const String& s)
{
CFRef<CFStringRef> cs = CFStringCreateWithCString(NULL, (const char *)~s.ToString(), kCFStringEncodingUTF8);
[[NSPasteboard generalPasteboard] setString:(NSString *)~cs forType:NSPasteboardTypeString];
}
void Upp::AppendClipboardUnicodeText(const WString& s)
void AppendClipboardUnicodeText(const WString& s)
{
AppendClipboardText(s.ToString());
}
Upp::ViewDraw::ViewDraw(Ctrl *ctrl)
ViewDraw::ViewDraw(Ctrl *ctrl)
{
EnterGuiMutex();
ASSERT(ctrl->top->coco);
@ -361,11 +365,13 @@ Upp::ViewDraw::ViewDraw(Ctrl *ctrl)
Clipoff(Rect(r.TopLeft() - tr.TopLeft(), r.GetSize()));
}
Upp::ViewDraw::~ViewDraw()
ViewDraw::~ViewDraw()
{
End();
CGContextFlush(cgHandle);
LeaveGuiMutex();
}
};
#endif

View file

@ -93,6 +93,14 @@ void ClearClipboard()
ClearClipboard(false);
}
NSMutableSet *PasteboardTypes(const Vector<String>& fmt)
{
NSMutableSet *types = [[[NSMutableSet alloc] init] autorelease];
for(auto id : fmt)
[types addObject:PasteboardType(id)];
return types;
}
void AppendClipboard(bool dnd, const char *format, const Value& value, String (*render)(const Value& data))
{
GuiLock __;
@ -102,17 +110,31 @@ void AppendClipboard(bool dnd, const char *format, const Value& value, String (*
for(String fmt : Split(format, ';'))
data.GetAdd(fmt) = ClipData(value, render);
NSAutoreleasePool *pool;
pool = [[NSAutoreleasePool alloc] init];
AutoreleasePool ___;
NSMutableSet *types = [[NSMutableSet alloc] init];
for(auto id : data.GetKeys())
[types addObject:PasteboardType(id)];
[Pasteboard(dnd) declareTypes:[PasteboardTypes(data.GetKeys()) allObjects]
owner:ClipboardOwner(dnd)];
}
[Pasteboard(dnd) declareTypes:[types allObjects] owner:ClipboardOwner(dnd)];
Index<String> drop_formats;
[types release];
[pool release];
void Ctrl::RegisterCocoaDropFormats()
{
AutoreleasePool ___;
NSView *nsview = (NSView *)GetNSView();
[nsview registerForDraggedTypes:[PasteboardTypes(drop_formats.GetKeys()) allObjects]];
}
void RegisterDropFormats(const char *formats)
{
for(String fmt : Split(formats, ';'))
drop_formats.FindAdd(fmt);
for(Ctrl *q : Ctrl::GetTopCtrls())
q->RegisterCocoaDropFormats();
}
INITBLOCK {
RegisterDropFormats("text;png;image;rtf;files;url");
}
void AppendClipboard(const char *format, const Value& value, String (*render)(const Value& data))
@ -132,35 +154,45 @@ void AppendClipboard(const char *format, const byte *data, int length)
AppendClipboard(format, String(data, length));
}
bool IsFormatAvailable(NSPasteboard *pasteboard, const char *fmt)
{
return [pasteboard availableTypeFromArray:[NSArray arrayWithObjects:PasteboardType(fmt), nil]];
}
String ReadFormat(NSPasteboard *pasteboard, const char *fmt)
{
NSData *data = [pasteboard dataForType:PasteboardType(fmt)];
return String((const char *)[data bytes], [data length]);
}
bool PasteClip::IsAvailable(const char *fmt) const
{
return IsClipboardAvailable(fmt);
return nspasteboard ? IsFormatAvailable((NSPasteboard *)nspasteboard, fmt)
: IsClipboardAvailable(fmt);
}
String PasteClip::Get(const char *fmt) const
{
return ReadClipboard(fmt);
return nspasteboard ? ReadFormat((NSPasteboard *)nspasteboard, fmt)
: ReadClipboard(fmt);
}
void PasteClip::GuiPlatformConstruct()
{
nspasteboard = NULL;
}
bool IsClipboardAvailable(const char *id)
bool IsClipboardAvailable(const char *fmt)
{
return [[NSPasteboard generalPasteboard]
availableTypeFromArray:[NSArray arrayWithObjects:PasteboardType(id), nil]];
return IsFormatAvailable([NSPasteboard generalPasteboard], fmt);
}
String ReadClipboard(const char *fmt_)
String ReadClipboard(const char *fmt)
{
String fmt = fmt_;
if(fmt == "text")
return ToString([[NSPasteboard generalPasteboard] stringForType:NSPasteboardTypeString]);
NSData *data = [[NSPasteboard generalPasteboard] dataForType:PasteboardType(fmt)];
return String((const char *)[data bytes], [data length]);
return ReadFormat([NSPasteboard generalPasteboard], fmt);
}
bool IsClipboardAvailableText()
{
return IsClipboardAvailable("text");

View file

@ -15,7 +15,7 @@
@implementation CocoWindow
- (void)becomeKeyWindow {
[super becomeKeyWindow];
[super becomeKeyWindow];
}
- (BOOL)canBecomeKeyWindow {
@ -29,15 +29,17 @@
@end
static Upp::Vector<Upp::Ptr<Upp::Ctrl>> mmtopctrl; // should work without Ptr, but let us be defensive....
namespace Upp {
Upp::Ctrl *Upp::Ctrl::GetOwner()
static Vector<Ptr<Ctrl>> mmtopctrl; // should work without Ptr, but let us be defensive....
Ctrl *Ctrl::GetOwner()
{
GuiLock __;
return top && top->coco ? top->coco->owner : NULL;
}
Upp::Ctrl *Upp::Ctrl::GetActiveCtrl()
Ctrl *Ctrl::GetActiveCtrl()
{
GuiLock __;
for(Ctrl *p : mmtopctrl)
@ -46,7 +48,7 @@ Upp::Ctrl *Upp::Ctrl::GetActiveCtrl()
return NULL;
}
bool Upp::Ctrl::SetWndFocus()
bool Ctrl::SetWndFocus()
{
GuiLock __;
if(top && top->coco) {
@ -59,44 +61,44 @@ bool Upp::Ctrl::SetWndFocus()
return true;
}
bool Upp::Ctrl::HasWndFocus() const
bool Ctrl::HasWndFocus() const
{
GuiLock __;
return GetActiveCtrl() == this;
}
void Upp::Ctrl::SetWndForeground()
void Ctrl::SetWndForeground()
{
GuiLock __;
SetWndFocus();
}
bool Upp::Ctrl::IsWndForeground() const
bool Ctrl::IsWndForeground() const
{
GuiLock __;
return HasWndFocus();
}
NSRect DesktopRect(const Upp::Rect& r)
NSRect DesktopRect(const Rect& r)
{
double scalei = 1.0 / Upp::DPI(1);
double scalei = 1.0 / DPI(1);
return NSMakeRect(scalei * r.left,
scalei * (Upp::Ctrl::GetPrimaryScreenArea().GetHeight() - r.top - r.GetHeight()),
scalei * (Ctrl::GetPrimaryScreenArea().GetHeight() - r.top - r.GetHeight()),
scalei * r.GetWidth(), scalei * r.GetHeight());
}
void *Upp::Ctrl::GetNSWindow() const
void *Ctrl::GetNSWindow() const
{
return top && top->coco ? top->coco->window : NULL;
}
void *Upp::Ctrl::GetNSView() const
void *Ctrl::GetNSView() const
{
return top && top->coco ? top->coco->view : NULL;
}
void Upp::Ctrl::Create(Ctrl *owner, dword style, bool active)
void Ctrl::Create(Ctrl *owner, dword style, bool active)
{
if(owner)
owner = owner->GetTopCtrl();
@ -128,9 +130,11 @@ void Upp::Ctrl::Create(Ctrl *owner, dword style, bool active)
MMCtrl::SyncRect(view);
isopen = true;
mmtopctrl.Add(this);
RegisterCocoaDropFormats();
}
void Upp::Ctrl::WndDestroy()
void Ctrl::WndDestroy()
{
LLOG("WndDestroy " << Name());
if(!top)
@ -148,7 +152,7 @@ void Upp::Ctrl::WndDestroy()
owner->SetWndFocus();
}
Upp::Vector<Upp::Ctrl *> Upp::Ctrl::GetTopCtrls()
Vector<Ctrl *> Ctrl::GetTopCtrls()
{
Vector<Ctrl *> h;
for(Ctrl *p : mmtopctrl)
@ -156,7 +160,7 @@ Upp::Vector<Upp::Ctrl *> Upp::Ctrl::GetTopCtrls()
return h;
}
void Upp::Ctrl::WndInvalidateRect(const Rect& r)
void Ctrl::WndInvalidateRect(const Rect& r)
{
GuiLock __;
LLOG("Invalidate Rect " << r);
@ -164,19 +168,19 @@ void Upp::Ctrl::WndInvalidateRect(const Rect& r)
[top->coco->view setNeedsDisplayInRect:(NSRect)CGRectDPI(r)];
}
void Upp::Ctrl::WndScrollView(const Rect& r, int dx, int dy)
void Ctrl::WndScrollView(const Rect& r, int dx, int dy)
{
GuiLock __;
LLOG("Scroll View " << r);
WndInvalidateRect(r);
}
bool Upp::Ctrl::IsWndOpen() const {
bool Ctrl::IsWndOpen() const {
GuiLock __;
return top;
}
void Upp::Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost)
void Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow, bool topmost)
{
Create(owner ? owner->GetTopCtrl() : GetActiveCtrl(), NSWindowStyleMaskBorderless, 0);
popup = true;
@ -202,9 +206,9 @@ void Upp::Ctrl::PopUp(Ctrl *owner, bool savebits, bool activate, bool dropshadow
#endif
}
Upp::dword Upp::TopWindow::GetMMStyle() const
dword TopWindow::GetMMStyle() const
{
Upp::dword style = NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskResizable;
dword style = NSWindowStyleMaskTitled|NSWindowStyleMaskClosable|NSWindowStyleMaskResizable;
if(minimizebox)
style |= NSWindowStyleMaskMiniaturizable;
// if(maximizebox)
@ -212,7 +216,7 @@ Upp::dword Upp::TopWindow::GetMMStyle() const
return style;
}
void Upp::TopWindow::Open(Ctrl *owner)
void TopWindow::Open(Ctrl *owner)
{
GuiLock __;
SetupRect(owner);
@ -233,17 +237,17 @@ void Upp::TopWindow::Open(Ctrl *owner)
// top->placefocus = true;
}
void Upp::TopWindow::Open()
void TopWindow::Open()
{
Open(GetActiveCtrl());
}
void Upp::TopWindow::OpenMain()
void TopWindow::OpenMain()
{
Open(NULL);
}
void Upp::TopWindow::SyncTitle()
void TopWindow::SyncTitle()
{
GuiLock __;
if(top) {
@ -253,7 +257,7 @@ void Upp::TopWindow::SyncTitle()
}
}
void Upp::TopWindow::SyncCaption()
void TopWindow::SyncCaption()
{
GuiLock __;
if(top) {
@ -264,33 +268,33 @@ void Upp::TopWindow::SyncCaption()
}
}
CGSize MMFrameSize(Upp::Size sz, Upp::dword style)
CGSize MMFrameSize(Size sz, dword style)
{
double scale = 1.0 / Upp::DPI(1);
double scale = 1.0 / DPI(1);
return [NSWindow frameRectForContentRect:
(NSRect)CGRectMake(100, 100, scale * sz.cx, scale * sz.cy) styleMask:style].size;
}
void Upp::TopWindow::SyncSizeHints()
void TopWindow::SyncSizeHints()
{
GuiLock __;
if(top) {
NSWindow *window = top->coco->window;
Upp::dword style = GetMMStyle();
dword style = GetMMStyle();
Size sz = GetRect().GetSize();
[window setMinSize:MMFrameSize(sizeable ? GetMinSize() : sz, style)];
[window setMaxSize:MMFrameSize(sizeable ? GetMaxSize() : sz, style)];
}
}
Upp::Rect Upp::Ctrl::GetWndScreenRect() const
Rect Ctrl::GetWndScreenRect() const
{ // THIS IS NOT NEEDED
GuiLock __;
Rect r = GetRect();
return r;
}
void Upp::Ctrl::WndSetPos(const Upp::Rect& rect)
void Ctrl::WndSetPos(const Rect& rect)
{
GuiLock __;
if(top)
@ -299,7 +303,7 @@ void Upp::Ctrl::WndSetPos(const Upp::Rect& rect)
display:YES];
}
void Upp::TopWindow::SerializePlacement(Stream& s, bool reminimize)
void TopWindow::SerializePlacement(Stream& s, bool reminimize)
{
GuiLock __;
int version = 0;
@ -310,7 +314,7 @@ void Upp::TopWindow::SerializePlacement(Stream& s, bool reminimize)
SetRect(rect);
}
void Upp::TopWindow::Maximize(bool effect)
void TopWindow::Maximize(bool effect)
{
state = MAXIMIZED;
if(top && top->coco && top->coco->window && !top->coco->window.zoomed) {
@ -321,7 +325,7 @@ void Upp::TopWindow::Maximize(bool effect)
}
}
void Upp::TopWindow::Minimize(bool effect)
void TopWindow::Minimize(bool effect)
{
state = MINIMIZED;
if(top && top->coco && top->coco->window && !top->coco->window.miniaturized) {
@ -332,7 +336,7 @@ void Upp::TopWindow::Minimize(bool effect)
}
}
void Upp::TopWindow::Overlap(bool effect)
void TopWindow::Overlap(bool effect)
{
state = OVERLAPPED;
if(top && top->coco && top->coco->window && top->coco->window.zoomed)
@ -341,5 +345,6 @@ void Upp::TopWindow::Overlap(bool effect)
[top->coco->window deminiaturize:top->coco->window];
}
}
#endif

View file

@ -24,4 +24,6 @@ public:
void *GetNSWindow() const;
void *GetNSView() const;
void RegisterCocoaDropFormats();
//$ };

View file

@ -13,6 +13,7 @@ static int coco_flags;
static Upp::Ptr<Upp::Ctrl> coco_capture;
namespace Upp {
bool GetShift() { return coco_flags & NSEventModifierFlagShift; }
bool GetCtrl() { return coco_flags & NSEventModifierFlagCommand; }
bool GetAlt() { return coco_flags & NSEventModifierFlagControl; }
@ -182,6 +183,27 @@ struct MMImp {
{
ctrl->MMClose();
}
static int DnD(Upp::Ctrl *ctrl, id<NSDraggingInfo> info, bool paste = false)
{
NSView *nsview = (NSView *)ctrl->GetNSView();
PasteClip clip;
clip.nspasteboard = info.draggingPasteboard;
clip.paste = paste;
clip.accepted = false;
clip.allowed = DND_MOVE|DND_COPY; // TODO: Use draggingSourceOperationMask
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
return clip.IsAccepted() ? clip.GetAction() == DND_MOVE ? NSDragOperationMove
: NSDragOperationCopy
: NSDragOperationNone;
}
static void DnDLeave(Ctrl *ctrl)
{
ctrl->DnDLeave();
}
};
};
@ -280,6 +302,31 @@ struct MMImp {
return ctrl->IsEnabled();
}
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender
{
return Upp::MMImp::DnD(ctrl, sender);
}
- (NSDragOperation)draggingUpdated:(id <NSDraggingInfo>)sender
{
return Upp::MMImp::DnD(ctrl, sender);
}
- (void)draggingEnded:(id <NSDraggingInfo>)sender
{
return Upp::MMImp::DnDLeave(ctrl);
}
- (void)draggingExited:(id <NSDraggingInfo>)sender
{
return Upp::MMImp::DnDLeave(ctrl);
}
- (BOOL)performDragOperation:(id <NSDraggingInfo>)sender
{
return Upp::MMImp::DnD(ctrl, sender, true);
}
@end
#endif

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

@ -310,7 +310,7 @@ void GuiPlatformAdjustDragImage(ImageBuffer& b);
Image MakeDragImage(const Image& arrow, Image sample);
const char *ClipFmtsText();
bool AcceptText(PasteClip& clip);
bool AcceptText (PasteClip& clip);
String GetString(PasteClip& clip);
WString GetWString(PasteClip& clip);
String GetTextClip(const String& text, const String& fmt);
@ -1218,6 +1218,8 @@ public:
static PasteClip& Selection();
void SetSelectionSource(const char *fmts);
static void RegisterDropFormats(const char *fmts); // MacOS requires drop formats to be registered
int DoDragAndDrop(const char *fmts, const Image& sample, dword actions,
const VectorMap<String, ClipData>& data);

View file

@ -1,5 +1,6 @@
sooner:
- fix modifier keys (read before each event)
- UHD problem with tabbar
- UHD problem with Prompt text size ([g ?)
- initial focus in uword
@ -7,7 +8,7 @@ sooner:
- fix package organiser link options (joining link options missing space)
- perhaps better UTI names
- CH improve spinbuttons
- Delete CocoClip.mm -> crash
- Delete CocoDnD.cpp -> crash
* cursor trouble osscilation
* after mouse up, cursor changes to arrow
@ -31,6 +32,8 @@ later:
- ch improve button matching to viewedge in droplist / UHD
- ch focus
- improve dnd protocol - allow macstyle images and offsets
- filesel icons
- Warning: Terminal '/usr/bin/xterm' not found, executing in background.