From dc5b70a336cf6691ff714ccff54fc391669df27d Mon Sep 17 00:00:00 2001 From: cxl Date: Sat, 21 Jul 2018 17:14:40 +0000 Subject: [PATCH] CtrlCore: Developing Cocoa git-svn-id: svn://ultimatepp.org/upp/trunk@12088 f0d560ea-af0d-0410-9eb7-867de7ffcac7 --- uppsrc/CtrlCore/Coco.h | 2 + uppsrc/CtrlCore/CocoAfter.h | 24 ++---- uppsrc/CtrlCore/CocoApp.mm | 136 ++++++++++++++++++++++++++++++ uppsrc/CtrlCore/CocoCode.h | 133 +++++++++++++++++++++++++++++ uppsrc/CtrlCore/CocoCreate.mm | 26 ++++-- uppsrc/CtrlCore/CocoCtrl.h | 2 +- uppsrc/CtrlCore/CocoDraw.mm | 3 + uppsrc/CtrlCore/CocoKeys.h | 152 +++++++++++++++++----------------- uppsrc/CtrlCore/CocoProc.mm | 35 +++++++- uppsrc/CtrlCore/CocoWnd.cpp | 86 ------------------- uppsrc/CtrlCore/CtrlCore.h | 8 ++ uppsrc/CtrlCore/CtrlCore.upp | 2 + uppsrc/CtrlCore/CtrlKbd.cpp | 69 +++++++++++++-- uppsrc/CtrlCore/cocotodo.txt | 16 ++++ uppsrc/Draw/FontFc.cpp | 2 +- 15 files changed, 497 insertions(+), 199 deletions(-) create mode 100644 uppsrc/CtrlCore/CocoApp.mm create mode 100644 uppsrc/CtrlCore/CocoCode.h diff --git a/uppsrc/CtrlCore/Coco.h b/uppsrc/CtrlCore/Coco.h index 63a3ef50a..12a310249 100644 --- a/uppsrc/CtrlCore/Coco.h +++ b/uppsrc/CtrlCore/Coco.h @@ -134,6 +134,8 @@ void DrawDragRect(SystemDraw& w, const Rect& rect1, const Rect& rect2, const Rec #include #endif +#include "CocoCode.h" + #define GUIPLATFORM_KEYCODES_INCLUDE struct CocoTop; diff --git a/uppsrc/CtrlCore/CocoAfter.h b/uppsrc/CtrlCore/CocoAfter.h index 4f36409d6..6be76e347 100644 --- a/uppsrc/CtrlCore/CocoAfter.h +++ b/uppsrc/CtrlCore/CocoAfter.h @@ -7,33 +7,19 @@ public: Vector& coreCmdLine__(); Vector SplitCmdLine__(const char *cmd); -#ifdef PLATFORM_WIN32 - -#define GUI_APP_MAIN \ -void GuiMainFn_();\ -\ -int APIENTRY WinMain(HINSTANCE hInstance, HINSTANCE, LPSTR lpCmdLine, int nCmdShow) \ -{ \ - UPP::coreCmdLine__() = UPP::SplitCmdLine__(UPP::FromSystemCharset(lpCmdLine)); \ - UPP::AppInitEnvironment__(); \ - GuiMainFn_(); \ - UPP::Ctrl::CloseTopCtrls(); \ - return UPP::GetExitCode(); \ -} \ -\ -void GuiMainFn_() - -#endif +void CocoInit(int argc, const char **argv, const char **envptr); +void CocoExit(); #ifdef PLATFORM_POSIX #define GUI_APP_MAIN \ void GuiMainFn_(); \ \ int main(int argc, const char **argv, const char **envptr) { \ - UPP::AppInit__(argc, argv, envptr); \ + UPP::AppInit__(argc, (const char **)argv, envptr); \ + UPP::CocoInit(argc, argv, envptr); \ GuiMainFn_(); \ UPP::Ctrl::CloseTopCtrls(); \ - UPP::AppExit__(); \ + UPP::CocoExit(); \ return UPP::GetExitCode(); \ } \ \ diff --git a/uppsrc/CtrlCore/CocoApp.mm b/uppsrc/CtrlCore/CocoApp.mm new file mode 100644 index 000000000..788ab0d1e --- /dev/null +++ b/uppsrc/CtrlCore/CocoApp.mm @@ -0,0 +1,136 @@ +#include "CocoMM.h" + +#define LLOG(x) + +NSAutoreleasePool *main_coco_pool; + +void Upp::CocoInit(int argc, const char **argv, const char **envptr) +{ + main_coco_pool = [NSAutoreleasePool new]; + + [NSApplication sharedApplication]; + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + id menubar = [[NSMenu new] autorelease]; + id appMenuItem = [[NSMenuItem new] autorelease]; + [menubar addItem:appMenuItem]; + [NSApp setMainMenu:menubar]; + id appMenu = [[NSMenu new] autorelease]; + id appName = [[NSProcessInfo processInfo] processName]; + id quitTitle = [@"Quit " stringByAppendingString:appName]; + id quitMenuItem = [[[NSMenuItem alloc] initWithTitle:quitTitle + action:@selector(terminate:) keyEquivalent:@"q"] autorelease]; + [appMenu addItem:quitMenuItem]; + [appMenuItem setSubmenu:appMenu]; + [NSApp activateIgnoringOtherApps:YES]; +} + +void Upp::CocoExit() +{ + [main_coco_pool release]; +} + +bool Upp::Ctrl::IsWaitingEvent() +{ + Upp::AutoreleasePool __; + bool b = [NSApp nextEventMatchingMask:NSEventMaskAny + untilDate:[NSDate date] + inMode:NSDefaultRunLoopMode dequeue:NO]; + return b; +} + +bool Upp::Ctrl::ProcessEvent(bool *) +{ + ASSERT(IsMainThread()); + + Upp::AutoreleasePool __; + + ONCELOCK { + [NSApp finishLaunching]; + } + + NSEvent *event = [NSApp nextEventMatchingMask:NSEventMaskAny + untilDate:[NSDate distantFuture] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + + [NSApp sendEvent:event]; + [NSApp updateWindows]; + + return true; +} + +void SweepMkImageCache(); + +bool Upp::Ctrl::ProcessEvents(bool *quit) +{ + if(ProcessEvent(quit)) { + while(ProcessEvent(quit) && (!LoopCtrl || LoopCtrl->InLoop())); // LoopCtrl-MF 071008 + TimerProc(GetTickCount()); + SweepMkImageCache(); + return true; + } + SweepMkImageCache(); + TimerProc(GetTickCount()); + return false; +} + + +void Upp::Ctrl::EventLoop(Ctrl *ctrl) +{ + GuiLock __; + ASSERT(IsMainThread()); + ASSERT(LoopLevel == 0 || ctrl); + LoopLevel++; + LLOG("Entering event loop at level " << LoopLevel << BeginIndent); + Ptr ploop; + if(ctrl) { + ploop = LoopCtrl; + LoopCtrl = ctrl; + ctrl->inloop = true; + } + + bool quit = false; + ProcessEvents(&quit); + while(ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount()) + { +// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / GuiSleep"); + SyncCaret(); + GuiSleep(1000); +// if(EndSession()) break; +// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / ProcessEvents"); + ProcessEvents(&quit); +// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / after ProcessEvents"); + } + + if(ctrl) + LoopCtrl = ploop; + LoopLevel--; + LLOG(EndIndent << "Leaving event loop "); +} + +void Upp::Ctrl::GuiSleep(int ms) +{ + GuiLock __; + Sleep(ms); // TODO! +/* ASSERT(IsMainThread()); + ELOG("GuiSleep"); + if(EndSession()) + return; + ELOG("GuiSleep 2"); + int level = LeaveGMutexAll(); +#if !defined(flagDLL) && !defined(PLATFORM_WINCE) + if(!OverwatchThread) { + DWORD dummy; + OverwatchThread = CreateThread(NULL, 0x100000, Win32OverwatchThread, NULL, 0, &dummy); + ELOG("ExitLoopEventWait 1"); + ExitLoopEvent.Wait(); + } + HANDLE h[1]; + *h = ExitLoopEvent.GetHandle(); + ELOG("ExitLoopEventWait 2 " << (void *)*h); + MsgWaitForMultipleObjects(1, h, FALSE, ms, QS_ALLINPUT); +#else + MsgWaitForMultipleObjects(0, NULL, FALSE, ms, QS_ALLINPUT); +#endif + EnterGMutex(level);*/ +} diff --git a/uppsrc/CtrlCore/CocoCode.h b/uppsrc/CtrlCore/CocoCode.h new file mode 100644 index 000000000..2c67d42fe --- /dev/null +++ b/uppsrc/CtrlCore/CocoCode.h @@ -0,0 +1,133 @@ +/* + * Summary: + * Virtual keycodes + * + * Discussion: + * These constants are the virtual keycodes defined originally in + * Inside Mac Volume V, pg. V-191. They identify physical keys on a + * keyboard. Those constants with "ANSI" in the name are labeled + * according to the key position on an ANSI-standard US keyboard. + * For example, kVK_ANSI_A indicates the virtual keycode for the key + * with the letter 'A' in the US keyboard layout. Other keyboard + * layouts may have the 'A' key label on a different physical key; + * in this case, pressing 'A' will generate a different virtual + * keycode. + */ +enum { + kVK_ANSI_A = 0x00, + kVK_ANSI_S = 0x01, + kVK_ANSI_D = 0x02, + kVK_ANSI_F = 0x03, + kVK_ANSI_H = 0x04, + kVK_ANSI_G = 0x05, + kVK_ANSI_Z = 0x06, + kVK_ANSI_X = 0x07, + kVK_ANSI_C = 0x08, + kVK_ANSI_V = 0x09, + kVK_ANSI_B = 0x0B, + kVK_ANSI_Q = 0x0C, + kVK_ANSI_W = 0x0D, + kVK_ANSI_E = 0x0E, + kVK_ANSI_R = 0x0F, + kVK_ANSI_Y = 0x10, + kVK_ANSI_T = 0x11, + kVK_ANSI_1 = 0x12, + kVK_ANSI_2 = 0x13, + kVK_ANSI_3 = 0x14, + kVK_ANSI_4 = 0x15, + kVK_ANSI_6 = 0x16, + kVK_ANSI_5 = 0x17, + kVK_ANSI_Equal = 0x18, + kVK_ANSI_9 = 0x19, + kVK_ANSI_7 = 0x1A, + kVK_ANSI_Minus = 0x1B, + kVK_ANSI_8 = 0x1C, + kVK_ANSI_0 = 0x1D, + kVK_ANSI_RightBracket = 0x1E, + kVK_ANSI_O = 0x1F, + kVK_ANSI_U = 0x20, + kVK_ANSI_LeftBracket = 0x21, + kVK_ANSI_I = 0x22, + kVK_ANSI_P = 0x23, + kVK_ANSI_L = 0x25, + kVK_ANSI_J = 0x26, + kVK_ANSI_Quote = 0x27, + kVK_ANSI_K = 0x28, + kVK_ANSI_Semicolon = 0x29, + kVK_ANSI_Backslash = 0x2A, + kVK_ANSI_Comma = 0x2B, + kVK_ANSI_Slash = 0x2C, + kVK_ANSI_N = 0x2D, + kVK_ANSI_M = 0x2E, + kVK_ANSI_Period = 0x2F, + kVK_ANSI_Grave = 0x32, + kVK_ANSI_KeypadDecimal = 0x41, + kVK_ANSI_KeypadMultiply = 0x43, + kVK_ANSI_KeypadPlus = 0x45, + kVK_ANSI_KeypadClear = 0x47, + kVK_ANSI_KeypadDivide = 0x4B, + kVK_ANSI_KeypadEnter = 0x4C, + kVK_ANSI_KeypadMinus = 0x4E, + kVK_ANSI_KeypadEquals = 0x51, + kVK_ANSI_Keypad0 = 0x52, + kVK_ANSI_Keypad1 = 0x53, + kVK_ANSI_Keypad2 = 0x54, + kVK_ANSI_Keypad3 = 0x55, + kVK_ANSI_Keypad4 = 0x56, + kVK_ANSI_Keypad5 = 0x57, + kVK_ANSI_Keypad6 = 0x58, + kVK_ANSI_Keypad7 = 0x59, + kVK_ANSI_Keypad8 = 0x5B, + kVK_ANSI_Keypad9 = 0x5C +}; + +/* keycodes for keys that are independent of keyboard layout*/ +enum { + kVK_Return = 0x24, + kVK_Tab = 0x30, + kVK_Space = 0x31, + kVK_Delete = 0x33, + kVK_Escape = 0x35, + kVK_Command = 0x37, + kVK_Shift = 0x38, + kVK_CapsLock = 0x39, + kVK_Option = 0x3A, + kVK_Control = 0x3B, + kVK_RightShift = 0x3C, + kVK_RightOption = 0x3D, + kVK_RightControl = 0x3E, + kVK_Function = 0x3F, + kVK_F17 = 0x40, + kVK_VolumeUp = 0x48, + kVK_VolumeDown = 0x49, + kVK_Mute = 0x4A, + kVK_F18 = 0x4F, + kVK_F19 = 0x50, + kVK_F20 = 0x5A, + kVK_F5 = 0x60, + kVK_F6 = 0x61, + kVK_F7 = 0x62, + kVK_F3 = 0x63, + kVK_F8 = 0x64, + kVK_F9 = 0x65, + kVK_F11 = 0x67, + kVK_F13 = 0x69, + kVK_F16 = 0x6A, + kVK_F14 = 0x6B, + kVK_F10 = 0x6D, + kVK_F12 = 0x6F, + kVK_F15 = 0x71, + kVK_Help = 0x72, + kVK_Home = 0x73, + kVK_PageUp = 0x74, + kVK_ForwardDelete = 0x75, + kVK_F4 = 0x76, + kVK_End = 0x77, + kVK_F2 = 0x78, + kVK_PageDown = 0x79, + kVK_F1 = 0x7A, + kVK_LeftArrow = 0x7B, + kVK_RightArrow = 0x7C, + kVK_DownArrow = 0x7D, + kVK_UpArrow = 0x7E +}; diff --git a/uppsrc/CtrlCore/CocoCreate.mm b/uppsrc/CtrlCore/CocoCreate.mm index ab658f8d0..fe0550f67 100644 --- a/uppsrc/CtrlCore/CocoCreate.mm +++ b/uppsrc/CtrlCore/CocoCreate.mm @@ -4,20 +4,34 @@ #define LLOG(x) +@interface CocoWindow : NSWindow +{ +} +@end + +@implementation CocoWindow +- (BOOL)canBecomeKeyWindow { + return YES; +} +@end + void Upp::MMCtrl::SyncRect(CocoView *view) { NSWindow *win = [view window]; view->ctrl->SetWndRect(MakeRect([win contentRectForFrameRect: [win frame]])); } -void Upp::Ctrl::Create(const Upp::Rect& r, const char *title) +void Upp::Ctrl::Create(const Upp::Rect& r, const char *title, bool popup) { NSRect frame = NSMakeRect(r.left, r.top, r.GetWidth(), r.GetHeight()); - NSWindow *window = [[NSWindow alloc] initWithContentRect:frame - styleMask:NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask - | NSWindowStyleMaskResizable - backing:NSBackingStoreBuffered - defer:false]; + + Upp::dword style = popup ? NSWindowStyleMaskBorderless : + NSWindowStyleMaskTitled | NSWindowStyleMaskClosable + | NSWindowStyleMaskMiniaturizable + | NSWindowStyleMaskResizable; + + NSWindow *window = [[CocoWindow alloc] initWithContentRect:frame styleMask: style + backing:NSBackingStoreBuffered defer:false]; // TODO: Move title CFRef s = CFStringCreateWithCString(NULL, title, kCFStringEncodingUTF8); diff --git a/uppsrc/CtrlCore/CocoCtrl.h b/uppsrc/CtrlCore/CocoCtrl.h index de6cd68f8..bde79829d 100644 --- a/uppsrc/CtrlCore/CocoCtrl.h +++ b/uppsrc/CtrlCore/CocoCtrl.h @@ -7,7 +7,7 @@ private: public: // TODO: Temp only, remove! - void Create(const Upp::Rect& r, const char *title); + void Create(const Upp::Rect& r, const char *title, bool popup); static void EndSession() {} static bool IsEndSession() { return false; } diff --git a/uppsrc/CtrlCore/CocoDraw.mm b/uppsrc/CtrlCore/CocoDraw.mm index 0a052584d..0e785e929 100644 --- a/uppsrc/CtrlCore/CocoDraw.mm +++ b/uppsrc/CtrlCore/CocoDraw.mm @@ -6,6 +6,7 @@ namespace Upp { void SystemDraw::Init(void *cgContext, int cy) { + DDUMP(cgContext); handle = cgContext; top = cy; Push(); @@ -20,6 +21,7 @@ SystemDraw::SystemDraw(void *cgContext, int cy) SystemDraw::~SystemDraw() { + DLOG("~SystemDraw"); Pop(); } @@ -38,6 +40,7 @@ dword SystemDraw::GetInfo() const void SystemDraw::Push() { + DDUMP(cgHandle); CGContextSaveGState(cgHandle); offset.Add(GetOffset()); clip.Add(GetClip()); diff --git a/uppsrc/CtrlCore/CocoKeys.h b/uppsrc/CtrlCore/CocoKeys.h index d1fa2f84c..f4882cb44 100644 --- a/uppsrc/CtrlCore/CocoKeys.h +++ b/uppsrc/CtrlCore/CocoKeys.h @@ -1,41 +1,43 @@ K_BACK = 53000, K_BACKSPACE, -K_TAB, +K_TAB = 9, -K_SPACE, +K_SPACE = 32, -K_RETURN, -K_ENTER, +K_RETURN = 13, +K_ENTER = K_RETURN, K_SHIFT_KEY, K_CTRL_KEY, K_ALT_KEY, K_CAPSLOCK, -K_ESCAPE, -K_PRIOR, -K_PAGEUP, -K_NEXT, -K_PAGEDOWN, -K_END, -K_HOME, -K_LEFT, -K_UP, -K_RIGHT, -K_DOWN, -K_INSERT, -K_DELETE, -K_NUMPAD0, -K_NUMPAD1, -K_NUMPAD2, -K_NUMPAD3, -K_NUMPAD4, -K_NUMPAD5, -K_NUMPAD6, -K_NUMPAD7, -K_NUMPAD8, -K_NUMPAD9, +K_ESCAPE = kVK_Escape|K_DELTA, +K_PRIOR = kVK_PageUp|K_DELTA, +K_PAGEUP = kVK_PageUp|K_DELTA, +K_NEXT = kVK_PageDown|K_DELTA, +K_PAGEDOWN = kVK_PageDown|K_DELTA, +K_END = kVK_End|K_DELTA, +K_HOME = kVK_Home|K_DELTA, +K_LEFT = kVK_LeftArrow|K_DELTA, +K_UP = kVK_UpArrow|K_DELTA, +K_RIGHT = kVK_RightArrow|K_DELTA, +K_DOWN = kVK_DownArrow|K_DELTA, +K_INSERT = 0, // kVK_Insert|K_DELTA, // TODO +K_DELETE = kVK_Delete|K_DELTA, + +K_NUMPAD0 = kVK_ANSI_Keypad0|K_DELTA, +K_NUMPAD1 = kVK_ANSI_Keypad1|K_DELTA, +K_NUMPAD2 = kVK_ANSI_Keypad2|K_DELTA, +K_NUMPAD3 = kVK_ANSI_Keypad3|K_DELTA, +K_NUMPAD4 = kVK_ANSI_Keypad4|K_DELTA, +K_NUMPAD5 = kVK_ANSI_Keypad5|K_DELTA, +K_NUMPAD6 = kVK_ANSI_Keypad6|K_DELTA, +K_NUMPAD7 = kVK_ANSI_Keypad7|K_DELTA, +K_NUMPAD8 = kVK_ANSI_Keypad8|K_DELTA, +K_NUMPAD9 = kVK_ANSI_Keypad9|K_DELTA, + K_MULTIPLY, K_ADD, K_SEPARATOR, @@ -44,55 +46,55 @@ K_DECIMAL, K_DIVIDE, K_SCROLL, -K_F1, -K_F2, -K_F3, -K_F4, -K_F5, -K_F6, -K_F7, -K_F8, -K_F9, -K_F10, -K_F11, -K_F12, +K_F1 = kVK_F1|K_DELTA, +K_F2 = kVK_F2|K_DELTA, +K_F3 = kVK_F3|K_DELTA, +K_F4 = kVK_F4|K_DELTA, +K_F5 = kVK_F5|K_DELTA, +K_F6 = kVK_F6|K_DELTA, +K_F7 = kVK_F7|K_DELTA, +K_F8 = kVK_F8|K_DELTA, +K_F9 = kVK_F9|K_DELTA, +K_F10 = kVK_F10|K_DELTA, +K_F11 = kVK_F11|K_DELTA, +K_F12 = kVK_F12|K_DELTA, -K_A, -K_B, -K_C, -K_D, -K_E, -K_F, -K_G, -K_H, -K_I, -K_J, -K_K, -K_L, -K_M, -K_N, -K_O, -K_P, -K_Q, -K_R, -K_S, -K_T, -K_U, -K_V, -K_W, -K_X, -K_Y, -K_Z, -K_0, -K_1, -K_2, -K_3, -K_4, -K_5, -K_6, -K_7, -K_8, -K_9, +K_A = kVK_ANSI_A|K_DELTA, +K_B = kVK_ANSI_B|K_DELTA, +K_C = kVK_ANSI_C|K_DELTA, +K_D = kVK_ANSI_D|K_DELTA, +K_E = kVK_ANSI_E|K_DELTA, +K_F = kVK_ANSI_F|K_DELTA, +K_G = kVK_ANSI_G|K_DELTA, +K_H = kVK_ANSI_H|K_DELTA, +K_I = kVK_ANSI_I|K_DELTA, +K_J = kVK_ANSI_J|K_DELTA, +K_K = kVK_ANSI_K|K_DELTA, +K_L = kVK_ANSI_L|K_DELTA, +K_M = kVK_ANSI_M|K_DELTA, +K_N = kVK_ANSI_N|K_DELTA, +K_O = kVK_ANSI_O|K_DELTA, +K_P = kVK_ANSI_P|K_DELTA, +K_Q = kVK_ANSI_Q|K_DELTA, +K_R = kVK_ANSI_R|K_DELTA, +K_S = kVK_ANSI_S|K_DELTA, +K_T = kVK_ANSI_T|K_DELTA, +K_U = kVK_ANSI_U|K_DELTA, +K_V = kVK_ANSI_V|K_DELTA, +K_W = kVK_ANSI_W|K_DELTA, +K_X = kVK_ANSI_X|K_DELTA, +K_Y = kVK_ANSI_Y|K_DELTA, +K_Z = kVK_ANSI_Z|K_DELTA, +K_0 = kVK_ANSI_0|K_DELTA, +K_1 = kVK_ANSI_1|K_DELTA, +K_2 = kVK_ANSI_2|K_DELTA, +K_3 = kVK_ANSI_3|K_DELTA, +K_4 = kVK_ANSI_4|K_DELTA, +K_5 = kVK_ANSI_5|K_DELTA, +K_6 = kVK_ANSI_6|K_DELTA, +K_7 = kVK_ANSI_7|K_DELTA, +K_8 = kVK_ANSI_8|K_DELTA, +K_9 = kVK_ANSI_9|K_DELTA, K_CTRL_LBRACKET, K_CTRL_RBRACKET, diff --git a/uppsrc/CtrlCore/CocoProc.mm b/uppsrc/CtrlCore/CocoProc.mm index 1d76ab470..9e2beecab 100644 --- a/uppsrc/CtrlCore/CocoProc.mm +++ b/uppsrc/CtrlCore/CocoProc.mm @@ -13,7 +13,9 @@ namespace Upp { bool GetShift() { return coco_flags & NSEventModifierFlagShift; } bool GetCtrl() { return coco_flags & NSEventModifierFlagCommand; } bool GetAlt() { return coco_flags & NSEventModifierFlagControl; } +bool GetOption() { return coco_flags & NSEventModifierFlagOption; } bool GetCapsLock() { return coco_flags & NSEventModifierFlagCapsLock; } + /* NSEventModifierFlagOption NSEventModifierFlagNumericPad @@ -51,6 +53,31 @@ struct MMImp { ctrl->fullrefresh = false; ctrl->UpdateArea(w, r); } + + static void KeyEvent(Upp::Ctrl *ctrl, NSEvent *e, int up) { + Flags(e); + Upp::dword k = e.keyCode|K_DELTA|up; + if(GetCtrl()) + k |= K_CTRL; + if(GetShift()) + k |= K_SHIFT; + if(GetAlt()) + k |= K_ALT; + if(GetOption()) // TODO + k |= K_OPTION; + ctrl->DispatchKey(k, 1); + if(!up) { + WString x = ToWString((CFStringRef)(e.characters)); + for(wchar c : x) + if(c < 0xF700) + ctrl->DispatchKey(c, 1); + } + } + + static void GotFocus(Upp::Ctrl *ctrl) + { + ctrl->ActivateWnd(); + } }; }; @@ -69,12 +96,11 @@ struct MMImp { - (void)rightMouseUp:(NSEvent*)e { Upp::MMImp::MouseEvent(self, e, Upp::Ctrl::RIGHTUP); coco_mouse_right = false; } - (void)keyDown:(NSEvent *)e { -// ctrl->Text("keyDown flag: " + AsString(e.modifierFlags) + ", characters: " + -// ToString((CFStringRef)(e.characters)) + ", keycode: " + AsString(e.keyCode)); + Upp::MMImp::KeyEvent(ctrl, e, 0); } - (void)keyUp:(NSEvent *)e { -// ctrl->Text("keyUp "); + Upp::MMImp::KeyEvent(ctrl, e, Upp::K_KEYUP); } - (void)windowDidResize:(NSNotification *)notification { Upp::MMCtrl::SyncRect(self); } @@ -83,7 +109,8 @@ struct MMImp { - (void)windowDidBecomeKey:(NSNotification *)notification { - // THIS IS "GOT FOCUS" + DLOG("DidBecomeKey"); + Upp::MMImp::GotFocus(ctrl); } - (BOOL)acceptsFirstResponder { return YES; } diff --git a/uppsrc/CtrlCore/CocoWnd.cpp b/uppsrc/CtrlCore/CocoWnd.cpp index a540f8581..79f52e374 100644 --- a/uppsrc/CtrlCore/CocoWnd.cpp +++ b/uppsrc/CtrlCore/CocoWnd.cpp @@ -79,92 +79,6 @@ void Ctrl::UnregisterSystemHotKey(int id) }*/ } -bool Ctrl::IsWaitingEvent() -{ - return false; -} - -bool Ctrl::ProcessEvent(bool *quit) -{ - ASSERT(IsMainThread()); - return false; -} - -void SweepMkImageCache(); - -bool Ctrl::ProcessEvents(bool *quit) -{ -/* if(ProcessEvent(quit)) { - while(ProcessEvent(quit) && (!LoopCtrl || LoopCtrl->InLoop())); // LoopCtrl-MF 071008 - TimerProc(GetTickCount()); - SweepMkImageCache(); - return true; - } - SweepMkImageCache(); - TimerProc(GetTickCount());*/ - return false; -} - - -void Ctrl::EventLoop(Ctrl *ctrl) -{ - GuiLock __; -/* ASSERT(IsMainThread()); - ASSERT(LoopLevel == 0 || ctrl); - LoopLevel++; - LLOG("Entering event loop at level " << LoopLevel << BeginIndent); - Ptr ploop; - if(ctrl) { - ploop = LoopCtrl; - LoopCtrl = ctrl; - ctrl->inloop = true; - } - - bool quit = false; - ProcessEvents(&quit); - while(!EndSession() && !quit && ctrl ? ctrl->IsOpen() && ctrl->InLoop() : GetTopCtrls().GetCount()) - { -// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / GuiSleep"); - SyncCaret(); - GuiSleep(1000); - if(EndSession()) break; -// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / ProcessEvents"); - ProcessEvents(&quit); -// LLOG(GetSysTime() << " % " << (unsigned)msecs() % 10000 << ": EventLoop / after ProcessEvents"); - } - - if(ctrl) - LoopCtrl = ploop; - LoopLevel--; - LLOG(EndIndent << "Leaving event loop ");*/ -} - -void Ctrl::GuiSleep(int ms) -{ - GuiLock __; -/* ASSERT(IsMainThread()); - ELOG("GuiSleep"); - if(EndSession()) - return; - ELOG("GuiSleep 2"); - int level = LeaveGMutexAll(); -#if !defined(flagDLL) && !defined(PLATFORM_WINCE) - if(!OverwatchThread) { - DWORD dummy; - OverwatchThread = CreateThread(NULL, 0x100000, Win32OverwatchThread, NULL, 0, &dummy); - ELOG("ExitLoopEventWait 1"); - ExitLoopEvent.Wait(); - } - HANDLE h[1]; - *h = ExitLoopEvent.GetHandle(); - ELOG("ExitLoopEventWait 2 " << (void *)*h); - MsgWaitForMultipleObjects(1, h, FALSE, ms, QS_ALLINPUT); -#else - MsgWaitForMultipleObjects(0, NULL, FALSE, ms, QS_ALLINPUT); -#endif - EnterGMutex(level);*/ -} - Rect Ctrl::GetWndScreenRect() const { GuiLock __; diff --git a/uppsrc/CtrlCore/CtrlCore.h b/uppsrc/CtrlCore/CtrlCore.h index 7840b002f..2f8377be7 100644 --- a/uppsrc/CtrlCore/CtrlCore.h +++ b/uppsrc/CtrlCore/CtrlCore.h @@ -95,6 +95,10 @@ enum { K_MOUSETRIPLE = 0x2000000, K_SHIFT_CTRL = K_SHIFT|K_CTRL, + +#ifdef flagCOCOA + K_OPTION = 0x4000000, +#endif }; #include "MKeys.h" @@ -107,6 +111,10 @@ bool GetMouseLeft(); bool GetMouseRight(); bool GetMouseMiddle(); +#ifdef flagCOCOA +bool GetOption(); +#endif + enum { DELAY_MINIMAL = 0 }; diff --git a/uppsrc/CtrlCore/CtrlCore.upp b/uppsrc/CtrlCore/CtrlCore.upp index cd53f7b71..586241c38 100644 --- a/uppsrc/CtrlCore/CtrlCore.upp +++ b/uppsrc/CtrlCore/CtrlCore.upp @@ -123,6 +123,7 @@ file GtkApp.cpp, Cocoa readonly separator, Coco.h, + CocoCode.h, CocoAfter.h, CocoKeys.h, CocoMM.h, @@ -132,6 +133,7 @@ file CocoDrawText.mm, CocoImage.mm, CocoCtrl.h, + CocoApp.mm, CocoCreate.mm, CocoProc.mm, CocoCtrl.cpp, diff --git a/uppsrc/CtrlCore/CtrlKbd.cpp b/uppsrc/CtrlCore/CtrlKbd.cpp index 3c80447df..7aa608c3b 100644 --- a/uppsrc/CtrlCore/CtrlKbd.cpp +++ b/uppsrc/CtrlCore/CtrlKbd.cpp @@ -371,29 +371,81 @@ String GetKeyDesc(dword key) if(key == 0) return desc; + + DDUMPHEX(key); + DDUMPHEX(K_A); + DDUMPHEX(K_DELTA); + if(key & K_KEYUP) desc << t_("key\vUP "); if(key & K_CTRL) desc << t_("key\vCtrl+"); if(key & K_ALT) desc << t_("key\vAlt+"); if(key & K_SHIFT) desc << t_("key\vShift+"); - if(key & K_KEYUP) desc << t_("key\vUP "); +#ifdef flagCOCOA + if(key & K_OPTION) desc << t_("key\vOption+"); +#endif key &= ~(K_CTRL | K_ALT | K_SHIFT | K_KEYUP); +#ifdef flagCOCOA + key &= ~(K_OPTION); +#endif if(key < K_DELTA && key > 32 && key != K_DELETE) return desc + ToUtf8((wchar)key); if(key >= K_NUMPAD0 && key <= K_NUMPAD9) desc << "Num " << (char)(key - K_NUMPAD0 + '0'); - else if(key >= K_0 && key <= K_9) - desc << (char)('0' + key - K_0); - else if(key >= K_A && key <= K_Z) - desc << (char)('A' + key - K_A); - else if(key >= K_F1 && key <= K_F12) - desc << Format("F%d", (int)key - K_F1 + 1); else { static struct { dword key; const char *name; } nkey[] = { + { K_A, tt_("key\vA") }, + { K_B, tt_("key\vB") }, + { K_C, tt_("key\vC") }, + { K_D, tt_("key\vD") }, + { K_E, tt_("key\vE") }, + { K_F, tt_("key\vF") }, + { K_G, tt_("key\vG") }, + { K_H, tt_("key\vH") }, + { K_I, tt_("key\vI") }, + { K_J, tt_("key\vJ") }, + { K_K, tt_("key\vK") }, + { K_L, tt_("key\vL") }, + { K_M, tt_("key\vM") }, + { K_N, tt_("key\vN") }, + { K_O, tt_("key\vO") }, + { K_P, tt_("key\vP") }, + { K_Q, tt_("key\vQ") }, + { K_R, tt_("key\vR") }, + { K_S, tt_("key\vS") }, + { K_T, tt_("key\vT") }, + { K_U, tt_("key\vU") }, + { K_V, tt_("key\vV") }, + { K_W, tt_("key\vW") }, + { K_X, tt_("key\vX") }, + { K_Y, tt_("key\vY") }, + { K_Z, tt_("key\vZ") }, + { K_0, tt_("key\v0") }, + { K_1, tt_("key\v1") }, + { K_2, tt_("key\v2") }, + { K_3, tt_("key\v3") }, + { K_4, tt_("key\v4") }, + { K_5, tt_("key\v5") }, + { K_6, tt_("key\v6") }, + { K_7, tt_("key\v7") }, + { K_8, tt_("key\v8") }, + { K_9, tt_("key\v9") }, + { K_F1, tt_("key\vF1") }, + { K_F2, tt_("key\vF2") }, + { K_F3, tt_("key\vF3") }, + { K_F4, tt_("key\vF4") }, + { K_F5, tt_("key\vF5") }, + { K_F6, tt_("key\vF6") }, + { K_F7, tt_("key\vF7") }, + { K_F8, tt_("key\vF8") }, + { K_F9, tt_("key\vF9") }, + { K_F10, tt_("key\vF10") }, + { K_F11, tt_("key\vF11") }, + { K_F12, tt_("key\vF12") }, { K_TAB, tt_("key\vTab") }, { K_SPACE, tt_("key\vSpace") }, { K_RETURN, tt_("key\vEnter") }, { K_BACKSPACE, tt_("key\vBackspace") }, { K_CAPSLOCK, tt_("key\vCaps Lock") }, { K_ESCAPE, tt_("key\vEsc") }, @@ -411,6 +463,9 @@ String GetKeyDesc(dword key) }; for(int i = 0; nkey[i].key; i++) if(nkey[i].key == key) { + DDUMP(i); + DDUMP(nkey[i].name); + DDUMP(GetLngString(nkey[i].name)); desc << GetLngString(nkey[i].name); return desc; } diff --git a/uppsrc/CtrlCore/cocotodo.txt b/uppsrc/CtrlCore/cocotodo.txt index 18f5d9544..e88478390 100644 --- a/uppsrc/CtrlCore/cocotodo.txt +++ b/uppsrc/CtrlCore/cocotodo.txt @@ -10,3 +10,19 @@ - ignoreclick - event flags +- CachedSetColorKeepAlpha optimize out +- use NSView:needsToDrawRect: for IsPaintingOp +- implement missing Draw ops +- fix rotated text +- fix link options (joining link options missing space) +- set application icons +- fix resizing arrows +- implement cursor shape +- implement caret +- RenderCharacterSys + +- flagCOCOA + +done: + + diff --git a/uppsrc/Draw/FontFc.cpp b/uppsrc/Draw/FontFc.cpp index ba1bde389..3fd6f3125 100644 --- a/uppsrc/Draw/FontFc.cpp +++ b/uppsrc/Draw/FontFc.cpp @@ -3,7 +3,7 @@ #define LLOG(x) // LOG(x) #define LTIMING(x) // TIMING(x) -#ifndef CUSTOM_FONTSYS +#if !defined(CUSTOM_FONTSYS) && !defined(flagCOCOA) #ifdef PLATFORM_POSIX