mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-07-11 22:03:01 -06:00
CtrlCore, CtrlLib: Cocoa dock menu support
git-svn-id: svn://ultimatepp.org/upp/trunk@12717 f0d560ea-af0d-0410-9eb7-867de7ffcac7
This commit is contained in:
parent
615ee3d8ca
commit
e8f9edd7ac
7 changed files with 83 additions and 8 deletions
|
|
@ -4,6 +4,22 @@
|
|||
|
||||
#ifdef PLATFORM_COCOA
|
||||
|
||||
@interface AppDelegate : NSObject<NSApplicationDelegate>
|
||||
{
|
||||
}
|
||||
@end
|
||||
|
||||
namespace Upp {
|
||||
NSMenu *Cocoa_DockMenu();
|
||||
};
|
||||
|
||||
@implementation AppDelegate
|
||||
- (NSMenu *)applicationDockMenu:(NSApplication *)sender
|
||||
{
|
||||
return Upp::Cocoa_DockMenu();
|
||||
}
|
||||
@end
|
||||
|
||||
namespace Upp {
|
||||
|
||||
int Ctrl::WndCaretTime;
|
||||
|
|
@ -48,6 +64,8 @@ void CocoInit(int argc, const char **argv, const char **envptr)
|
|||
[appMenuItem setSubmenu:appMenu];
|
||||
|
||||
[NSApp setMainMenu:menubar];
|
||||
|
||||
[NSApp setDelegate:[[AppDelegate alloc] init]];
|
||||
|
||||
NSFont *sysfont = [NSFont systemFontOfSize:0];
|
||||
Font::SetFace(0, ToString((CFStringRef)[sysfont familyName]), Font::TTF);
|
||||
|
|
|
|||
|
|
@ -27,6 +27,13 @@
|
|||
return active && ctrl && ctrl->IsEnabled() && dynamic_cast<Upp::TopWindow *>(~ctrl) && !ctrl->GetOwner();
|
||||
}
|
||||
|
||||
- (NSMenu *)applicationDockMenu:(NSApplication *)sender {
|
||||
NSMenu *menu = [[[NSMenu alloc] initWithTitle:@"DocTile Menu"] autorelease];
|
||||
NSMenuItem *item = [[[NSMenuItem alloc] initWithTitle:@"Hello" action:@selector(hello) keyEquivalent:@"k"] autorelease];
|
||||
[menu addItem:item];
|
||||
return menu;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
namespace Upp {
|
||||
|
|
@ -45,7 +52,7 @@ Ctrl *Ctrl::GetActiveCtrl()
|
|||
for(Ctrl *p : mmtopctrl)
|
||||
if(p && p->top && p->top->coco && p->top->coco->window.keyWindow)
|
||||
return p;
|
||||
return NULL;
|
||||
return lastActive;
|
||||
}
|
||||
|
||||
bool Ctrl::SetWndFocus()
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ private:
|
|||
static bool WndCaretVisible;
|
||||
static bool local_dnd_copy;
|
||||
static void AnimateCaret();
|
||||
static Ptr<Ctrl> lastActive;
|
||||
|
||||
friend void CocoInit(int argc, const char **argv, const char **envptr);
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,8 @@ static bool coco_mouse_right;
|
|||
static int coco_flags;
|
||||
static Upp::Ptr<Upp::Ctrl> coco_capture;
|
||||
|
||||
Upp::Ptr<Upp::Ctrl> Upp::Ctrl::lastActive;
|
||||
|
||||
namespace Upp {
|
||||
|
||||
extern id menubar;
|
||||
|
|
@ -113,6 +115,7 @@ struct MMImp {
|
|||
|
||||
static bool MouseDownEvent(CocoView *view, NSEvent *e, int button)
|
||||
{
|
||||
Upp::Ctrl::lastActive = view->ctrl;
|
||||
if(Ctrl::ignoremouseup) {
|
||||
Ctrl::KillRepeat();
|
||||
Ctrl::ignoreclick = false;
|
||||
|
|
@ -179,6 +182,7 @@ struct MMImp {
|
|||
static void BecomeKey(Upp::Ctrl *ctrl)
|
||||
{
|
||||
LLOG("Become key " << Upp::Name(ctrl));
|
||||
Upp::Ctrl::lastActive = ctrl;
|
||||
ctrl->ActivateWnd();
|
||||
auto tw = dynamic_cast<TopWindow *>(ctrl);
|
||||
if(tw && tw->placefocus) {
|
||||
|
|
|
|||
|
|
@ -8,14 +8,18 @@ protected:
|
|||
|
||||
virtual void MMClose() { WhenClose(); }
|
||||
|
||||
static TopWindow *GetMenuTopWindow();
|
||||
static void SyncMainMenu(bool force);
|
||||
|
||||
void *menubar = NULL;
|
||||
Event<Bar&> MainMenu;
|
||||
|
||||
public: // really private:
|
||||
static TopWindow *GetMenuTopWindow(bool dock);
|
||||
|
||||
public:
|
||||
virtual bool HotKey(dword key);
|
||||
|
||||
Event<Bar&> WhenDockMenu;
|
||||
|
||||
void SetMainMenu(Event<Bar&> menu);
|
||||
//$ };
|
||||
|
|
@ -3,6 +3,8 @@ brew install gdb
|
|||
|
||||
sooner:
|
||||
|
||||
- replace block dialog has wrong layout
|
||||
|
||||
- dropping DropList several times can lead to focus issue
|
||||
- cursor problem after local menu invocation (better, but still...)
|
||||
|
||||
|
|
|
|||
|
|
@ -25,6 +25,7 @@ namespace Upp {
|
|||
struct CocoMenuBar : public Bar {
|
||||
CocoMenu *cocomenu;
|
||||
int lock = 0;
|
||||
bool dockmenu = false;
|
||||
|
||||
struct Item : Bar::Item {
|
||||
NSMenuItem *nsitem;
|
||||
|
|
@ -85,14 +86,27 @@ struct CocoMenuBar : public Bar {
|
|||
|
||||
void Set(Event<Bar&> bar);
|
||||
|
||||
CocoMenuBar() {
|
||||
void Clear() {
|
||||
item.Clear();
|
||||
if(cocomenu) {
|
||||
[cocomenu release];
|
||||
cocomenu = NULL;
|
||||
}
|
||||
}
|
||||
void New() {
|
||||
Clear();
|
||||
cocomenu = [CocoMenu new];
|
||||
cocomenu.autoenablesItems = NO;
|
||||
cocomenu->ptr = this;
|
||||
cocomenu.delegate = cocomenu;
|
||||
}
|
||||
|
||||
CocoMenuBar() {
|
||||
cocomenu = NULL;
|
||||
New();
|
||||
}
|
||||
~CocoMenuBar() {
|
||||
[cocomenu release];
|
||||
Clear();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
@ -189,6 +203,8 @@ bool CocoMenuBar::IsEmpty() const
|
|||
|
||||
- (void)menuWillOpen:(NSMenu *)menu {
|
||||
CocoMenu *m = (CocoMenu *)menu;
|
||||
if(m && m->ptr && m->ptr->dockmenu)
|
||||
return;
|
||||
if(m && m->ptr && proc) {
|
||||
[m removeAllItems];
|
||||
proc(*m->ptr);
|
||||
|
|
@ -197,6 +213,8 @@ bool CocoMenuBar::IsEmpty() const
|
|||
|
||||
- (void)menuDidClose:(NSMenu *)menu {
|
||||
CocoMenu *m = (CocoMenu *)menu;
|
||||
if(m && m->ptr && m->ptr->dockmenu)
|
||||
return;
|
||||
[m removeAllItems];
|
||||
}
|
||||
|
||||
|
|
@ -234,15 +252,17 @@ bool TopWindow::HotKey(dword key)
|
|||
return Ctrl::HotKey(key);
|
||||
}
|
||||
|
||||
TopWindow *TopWindow::GetMenuTopWindow()
|
||||
TopWindow *TopWindow::GetMenuTopWindow(bool dock)
|
||||
{
|
||||
Ctrl *q = GetFocusCtrl();
|
||||
if(!q)
|
||||
q = GetActiveCtrl();
|
||||
if(!q)
|
||||
return NULL;
|
||||
q = q->GetTopCtrl();
|
||||
while(q) {
|
||||
TopWindow *w = dynamic_cast<TopWindow *>(q);
|
||||
if(w && w->menubar)
|
||||
if(w && (dock ? (bool)w->WhenDockMenu : (bool)w->menubar))
|
||||
return w;
|
||||
q = q->GetOwner();
|
||||
}
|
||||
|
|
@ -251,7 +271,7 @@ TopWindow *TopWindow::GetMenuTopWindow()
|
|||
|
||||
void TopWindow::SyncMainMenu(bool force)
|
||||
{
|
||||
TopWindow *w = GetMenuTopWindow();
|
||||
TopWindow *w = GetMenuTopWindow(false);
|
||||
static TopWindow *current;
|
||||
if(w != current || force) {
|
||||
current = w;
|
||||
|
|
@ -264,7 +284,7 @@ void TopWindow::SyncMainMenu(bool force)
|
|||
|
||||
void MenuBar::ExecuteHostBar(Ctrl *owner, Point p)
|
||||
{
|
||||
if(host_bar) {
|
||||
if(host_bar && owner) {
|
||||
CocoMenuBar& bar = *(CocoMenuBar *)~host_bar;
|
||||
|
||||
owner = owner->GetTopCtrl();
|
||||
|
|
@ -289,6 +309,25 @@ void MenuBar::CreateHostBar(One<Bar>& bar)
|
|||
host_bar.Create<CocoMenuBar>();
|
||||
}
|
||||
|
||||
NSMenu *Cocoa_DockMenu() {
|
||||
Upp::TopWindow *w = Upp::TopWindow::GetMenuTopWindow(true);
|
||||
|
||||
if(w && w->WhenDockMenu) {
|
||||
static Upp::CocoMenuBar bar;
|
||||
bar.dockmenu = true;
|
||||
bar.Clear();
|
||||
bar.cocomenu = [[[CocoMenu alloc] initWithTitle:@"DocTile Menu"] autorelease];
|
||||
bar.cocomenu.autoenablesItems = NO;
|
||||
bar.cocomenu->ptr = &bar;
|
||||
bar.cocomenu.delegate = bar.cocomenu;
|
||||
w->WhenDockMenu(bar);
|
||||
CocoMenu *m = bar.cocomenu;
|
||||
bar.cocomenu = NULL;
|
||||
return m;
|
||||
}
|
||||
return nil;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue