mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
CtrlCore: Cocoa Drag&Drop
git-svn-id: svn://ultimatepp.org/upp/trunk@12315 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
fe46fbf49a
commit
e53a81a71d
11 changed files with 209 additions and 110 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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_)
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -24,4 +24,6 @@ public:
|
|||
|
||||
void *GetNSWindow() const;
|
||||
void *GetNSView() const;
|
||||
|
||||
void RegisterCocoaDropFormats();
|
||||
//$ };
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue