--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: wx/cocoa/mdi.h
+// Purpose: wxMDIParentFrame, wxMDIChildFrame, wxMDIClientWindow
+// Author: David Elliott
+// Modified by:
+// Created: 2003/09/08
+// RCS-ID: $Id$
+// Copyright: (c) 2003 David Elliott
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#ifndef __WX_COCOA_MDI_H__
+#define __WX_COCOA_MDI_H__
+
+#include "wx/frame.h"
+
+DECLARE_WXCOCOA_OBJC_CLASS(wxMDIParentFrameObserver);
+
+class WXDLLEXPORT wxMDIChildFrame;
+class WXDLLEXPORT wxMDIClientWindow;
+
+WX_DECLARE_LIST(wxMDIChildFrame, wxCocoaMDIChildFrameList);
+
+// ========================================================================
+// wxMDIParentFrame
+// ========================================================================
+class WXDLLEXPORT wxMDIParentFrame: public wxFrame
+{
+ friend class WXDLLEXPORT wxMDIChildFrame;
+ DECLARE_EVENT_TABLE()
+ DECLARE_DYNAMIC_CLASS(wxMDIParentFrame)
+// ------------------------------------------------------------------------
+// initialization
+// ------------------------------------------------------------------------
+public:
+ wxMDIParentFrame() { Init(); }
+ wxMDIParentFrame(wxWindow *parent,
+ wxWindowID winid,
+ const wxString& title,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxDEFAULT_FRAME_STYLE,
+ const wxString& name = wxFrameNameStr)
+ {
+ Init();
+ Create(parent, winid, title, pos, size, style, name);
+ }
+
+ virtual ~wxMDIParentFrame();
+
+ bool Create(wxWindow *parent,
+ wxWindowID winid,
+ const wxString& title,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxDEFAULT_FRAME_STYLE,
+ const wxString& name = wxFrameNameStr);
+protected:
+ void Init();
+// ------------------------------------------------------------------------
+// Cocoa specifics
+// ------------------------------------------------------------------------
+public:
+ void WindowDidBecomeMain(NSNotification *notification);
+protected:
+ virtual void CocoaDelegate_windowDidBecomeKey(void);
+ virtual void CocoaDelegate_windowDidResignKey(void);
+ virtual bool Cocoa_canBecomeMainWindow(bool &canBecome);
+ virtual wxMenuBar* GetAppMenuBar(wxCocoaNSWindow *win);
+
+ void AddMDIChild(wxMDIChildFrame *child);
+ void RemoveMDIChild(wxMDIChildFrame *child);
+
+ wxMDIParentFrameObserver *m_observer;
+// ------------------------------------------------------------------------
+// Implementation
+// ------------------------------------------------------------------------
+public:
+ wxMDIChildFrame *GetActiveChild() const;
+ void SetActiveChild(wxMDIChildFrame *child);
+
+ wxMDIClientWindow *GetClientWindow() const;
+ virtual wxMDIClientWindow *OnCreateClient();
+
+ virtual void Cascade() {}
+ virtual void Tile() {}
+ virtual void ArrangeIcons() {}
+ virtual void ActivateNext();
+ virtual void ActivatePrevious();
+protected:
+ wxMDIClientWindow *m_clientWindow;
+ wxMDIChildFrame *m_currentChild;
+ wxCocoaMDIChildFrameList m_mdiChildren;
+};
+
+// ========================================================================
+// wxMDIChildFrame
+// ========================================================================
+class WXDLLEXPORT wxMDIChildFrame: public wxFrame
+{
+ friend class WXDLLEXPORT wxMDIParentFrame;
+ DECLARE_EVENT_TABLE()
+ DECLARE_DYNAMIC_CLASS(wxMDIChildFrame)
+// ------------------------------------------------------------------------
+// initialization
+// ------------------------------------------------------------------------
+public:
+ wxMDIChildFrame() { Init(); }
+ wxMDIChildFrame(wxMDIParentFrame *parent,
+ wxWindowID winid,
+ const wxString& title,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxDEFAULT_FRAME_STYLE,
+ const wxString& name = wxFrameNameStr)
+ {
+ Init();
+ Create(parent, winid, title, pos, size, style, name);
+ }
+
+ virtual ~wxMDIChildFrame();
+
+ bool Create(wxMDIParentFrame *parent,
+ wxWindowID winid,
+ const wxString& title,
+ const wxPoint& pos = wxDefaultPosition,
+ const wxSize& size = wxDefaultSize,
+ long style = wxDEFAULT_FRAME_STYLE,
+ const wxString& name = wxFrameNameStr);
+protected:
+ void Init();
+// ------------------------------------------------------------------------
+// Cocoa specifics
+// ------------------------------------------------------------------------
+public:
+protected:
+ virtual void CocoaDelegate_windowDidBecomeKey(void);
+ virtual void CocoaDelegate_windowDidBecomeMain(void);
+ virtual void CocoaDelegate_windowDidResignKey(void);
+// ------------------------------------------------------------------------
+// Implementation
+// ------------------------------------------------------------------------
+public:
+ virtual void Activate();
+ virtual bool Destroy();
+protected:
+ wxMDIParentFrame *m_mdiParent;
+};
+
+// ========================================================================
+// wxMDIClientWindow
+// ========================================================================
+class wxMDIClientWindow: public wxWindow
+{
+ DECLARE_DYNAMIC_CLASS(wxMDIClientWindow)
+public:
+ wxMDIClientWindow();
+ wxMDIClientWindow( wxMDIParentFrame *parent, long style = 0 );
+ ~wxMDIClientWindow();
+ virtual bool CreateClient( wxMDIParentFrame *parent, long style = 0 );
+};
+
+#endif // __WX_COCOA_MDI_H__
--- /dev/null
+/////////////////////////////////////////////////////////////////////////////
+// Name: cocoa/mdi.mm
+// Purpose: wxMDIParentFrame, wxMDIChildFrame, wxMDIClientWindow
+// Author: David Elliott
+// Modified by:
+// Created: 2003/09/08
+// RCS-ID: $Id$
+// Copyright: (c) 2003 David Elliott
+// Licence: wxWindows licence
+/////////////////////////////////////////////////////////////////////////////
+
+#include "wx/wxprec.h"
+#ifndef WX_PRECOMP
+ #include "wx/log.h"
+ #include "wx/mdi.h"
+#endif // WX_PRECOMP
+
+// #include "wx/cocoa/autorelease.h"
+#include "wx/cocoa/mbarman.h"
+
+#import <AppKit/NSWindow.h>
+#import <Foundation/NSNotification.h>
+// #import <AppKit/NSApplication.h>
+// #import <AppKit/NSView.h>
+
+#include <wx/listimpl.cpp>
+WX_DEFINE_LIST(wxCocoaMDIChildFrameList);
+
+WX_DECLARE_HASH_MAP(int, wxMDIChildFrame*, wxIntegerHash, wxIntegerEqual, wxIntMDIChildFrameHashMap);
+
+// ============================================================================
+// wxMDIParentFrameObserver
+// ============================================================================
+@interface wxMDIParentFrameObserver : NSObject
+{
+ wxMDIParentFrame *m_mdiParent;
+}
+
+- (id)init;
+- (id)initWithWxMDIParentFrame: (wxMDIParentFrame *)mdiParent;
+- (void)windowDidBecomeMain: (NSNotification *)notification;
+@end // interface wxMDIParentFrameObserver : NSObject
+
+@implementation wxMDIParentFrameObserver : NSObject
+- (id)init
+{
+ wxFAIL_MSG("[wxMDIParentFrameObserver -init] should never be called!");
+ m_mdiParent = NULL;
+ return self;
+}
+
+- (id)initWithWxMDIParentFrame: (wxMDIParentFrame *)mdiParent
+{
+ wxASSERT(mdiParent);
+ m_mdiParent = mdiParent;
+ return [super init];
+}
+
+- (void)windowDidBecomeMain: (NSNotification *)notification
+{
+ wxASSERT(m_mdiParent);
+ m_mdiParent->WindowDidBecomeMain(notification);
+}
+
+@end // implementation wxMDIParentFrameObserver : NSObject
+
+// ========================================================================
+// wxMDIParentFrame
+// ========================================================================
+IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame,wxFrame)
+BEGIN_EVENT_TABLE(wxMDIParentFrame,wxFrame)
+END_EVENT_TABLE()
+
+void wxMDIParentFrame::Init()
+{
+ m_clientWindow = NULL;
+ m_currentChild = NULL;
+ m_observer = [[wxMDIParentFrameObserver alloc]
+ initWithWxMDIParentFrame:this];
+ [[NSNotificationCenter defaultCenter] addObserver:m_observer
+ selector:@selector(windowDidBecomeMain:)
+ name:NSWindowDidBecomeMainNotification object:nil];
+}
+
+bool wxMDIParentFrame::Create(wxWindow *parent,
+ wxWindowID winid, const wxString& title,
+ const wxPoint& pos, const wxSize& size,
+ long style, const wxString& name)
+{
+ bool success = wxFrame::Create(parent,winid,title,pos,size,style,name);
+ if(success)
+ OnCreateClient();
+ return success;
+}
+
+wxMDIParentFrame::~wxMDIParentFrame()
+{
+ for(wxCocoaMDIChildFrameList::compatibility_iterator node =
+ m_mdiChildren.GetFirst(); node; node = m_mdiChildren.GetFirst())
+ {
+ wxMDIChildFrame *child = node->GetData();
+ // Delete it NOW
+ delete child;
+ wxASSERT_MSG(!m_mdiChildren.Find(child),
+ wxT("MDI child didn't remove itself using RemoveMDIChild()"));
+ }
+ [m_observer release];
+}
+
+void wxMDIParentFrame::AddMDIChild(wxMDIChildFrame *child)
+{
+ m_mdiChildren.Append(child);
+}
+
+void wxMDIParentFrame::RemoveMDIChild(wxMDIChildFrame *child)
+{
+ m_mdiChildren.DeleteObject(child);
+ if(child==m_currentChild)
+ SetActiveChild(NULL);
+}
+
+wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const
+{
+ return m_currentChild;
+}
+
+void wxMDIParentFrame::SetActiveChild(wxMDIChildFrame *child)
+{
+ m_currentChild = child;
+ wxMenuBarManager::GetInstance()->UpdateMenuBar();
+}
+
+wxMDIClientWindow *wxMDIParentFrame::GetClientWindow() const
+{
+ return m_clientWindow;
+}
+
+wxMDIClientWindow *wxMDIParentFrame::OnCreateClient()
+{
+ m_clientWindow = new wxMDIClientWindow( this );
+ return m_clientWindow;
+}
+
+void wxMDIParentFrame::ActivateNext()
+{
+}
+
+void wxMDIParentFrame::ActivatePrevious()
+{
+}
+
+wxMenuBar *wxMDIParentFrame::GetAppMenuBar(wxCocoaNSWindow *win)
+{
+ if(m_currentChild && (win==this))
+ return m_currentChild->GetAppMenuBar(win);
+ return wxFrame::GetAppMenuBar(win);
+}
+
+void wxMDIParentFrame::CocoaDelegate_windowDidBecomeKey(void)
+{
+ wxLogDebug("wxMDIParentFrame=%p::CocoaDelegate_windowDidBecomeKey",this);
+ if(sm_cocoaDeactivateWindow && sm_cocoaDeactivateWindow==m_currentChild)
+ {
+ sm_cocoaDeactivateWindow = NULL;
+ }
+ #if 0
+ else if(sm_cocoaDeactivateWindow == this)
+ {
+ sm_cocoaDeactivateWindow = NULL;
+ }
+ #endif
+ else
+ {
+ if(m_currentChild)
+ {
+ NSWindow *nswin = m_currentChild->GetNSWindow();
+ if(![nswin isMainWindow])
+ [nswin makeMainWindow];
+ }
+ wxFrame::CocoaDelegate_windowDidBecomeKey();
+ }
+}
+
+void wxMDIParentFrame::CocoaDelegate_windowDidResignKey(void)
+{
+ wxLogDebug("wxMDIParentFrame=%p::CocoaDelegate_windowDidResignKey",this);
+ if(m_closed)
+ wxFrame::CocoaDelegate_windowDidResignKey();
+ else
+ sm_cocoaDeactivateWindow = this;
+}
+
+// We should not become the main window as we aren't a document window
+// MDI "Children" should be the main window
+bool wxMDIParentFrame::Cocoa_canBecomeMainWindow(bool &canBecome)
+{
+ canBecome = m_mdiChildren.IsEmpty(); return true;
+}
+
+void wxMDIParentFrame::WindowDidBecomeMain(NSNotification *notification)
+{
+ // If we aren't the key window, we don't care
+ if(![m_cocoaNSWindow isKeyWindow])
+ return;
+ wxCocoaNSWindow *win = wxCocoaNSWindow::GetFromCocoa([notification object]);
+ // If we are key and becoming main, that's great
+ if(win==this)
+ return;
+ // If one of our children is becoming main, also great
+ for(wxCocoaMDIChildFrameList::compatibility_iterator node =
+ m_mdiChildren.GetFirst(); node; node = node->GetNext())
+ {
+ wxMDIChildFrame *child = node->GetData();
+ if(win==child)
+ return;
+ }
+ // Some other window is becoming main, but we are key
+ // Make the new main window the key window
+ [[notification object] makeKeyWindow];
+ if(!m_currentChild)
+ {
+ wxIntMDIChildFrameHashMap hashmap;
+ for(wxCocoaMDIChildFrameList::compatibility_iterator node =
+ m_mdiChildren.GetFirst(); node; node = node->GetNext())
+ {
+ wxMDIChildFrame *child = node->GetData();
+ hashmap.insert(wxIntMDIChildFrameHashMap::value_type([child->m_cocoaNSWindow windowNumber],child));
+ }
+ if(!hashmap.empty())
+ {
+ int windowCount = 0;
+ NSCountWindows(&windowCount);
+ wxASSERT(windowCount>0);
+ int *windowList = new int[windowCount];
+ NSWindowList(windowCount, windowList);
+ wxIntMDIChildFrameHashMap::iterator iter = hashmap.end();
+ for(int i=0; i<windowCount && iter == hashmap.end(); i++)
+ iter=hashmap.find(windowList[i]);
+ if(iter != hashmap.end())
+ m_currentChild = iter->second;
+ }
+ }
+}
+
+// ========================================================================
+// wxMDIChildFrame
+// ========================================================================
+IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame,wxFrame)
+BEGIN_EVENT_TABLE(wxMDIChildFrame,wxFrame)
+END_EVENT_TABLE()
+
+void wxMDIChildFrame::Init()
+{
+ m_mdiParent = NULL;
+}
+
+bool wxMDIChildFrame::Create(wxMDIParentFrame *parent,
+ wxWindowID winid, const wxString& title,
+ const wxPoint& pos, const wxSize& size,
+ long style, const wxString& name)
+{
+ bool success = wxFrame::Create(parent,winid,title,pos,size,style,name);
+ if(success)
+ {
+ m_mdiParent = parent;
+ parent->AddMDIChild(this);
+ }
+ return success;
+}
+
+wxMDIChildFrame::~wxMDIChildFrame()
+{
+ // Just in case Destroy() wasn't called
+ m_mdiParent->RemoveMDIChild(this);
+}
+
+void wxMDIChildFrame::Activate()
+{
+}
+
+void wxMDIChildFrame::CocoaDelegate_windowDidBecomeKey(void)
+{
+ wxLogDebug("wxMDIChildFrame=%p::CocoaDelegate_windowDidBecomeKey",this);
+ if(sm_cocoaDeactivateWindow && sm_cocoaDeactivateWindow==m_mdiParent)
+ {
+ sm_cocoaDeactivateWindow = NULL;
+ if(m_mdiParent->GetActiveChild() != this)
+ sm_cocoaDeactivateWindow = m_mdiParent->GetActiveChild();
+ }
+ m_mdiParent->SetActiveChild(this);
+ wxFrame::CocoaDelegate_windowDidBecomeKey();
+}
+
+void wxMDIChildFrame::CocoaDelegate_windowDidBecomeMain(void)
+{
+ m_mdiParent->SetActiveChild(this);
+ wxFrame::CocoaDelegate_windowDidBecomeMain();
+}
+
+void wxMDIChildFrame::CocoaDelegate_windowDidResignKey(void)
+{
+ wxLogDebug("wxMDIChildFrame=%p::CocoaDelegate_windowDidResignKey",this);
+ sm_cocoaDeactivateWindow = this;
+}
+
+bool wxMDIChildFrame::Destroy()
+{
+ // It's good to do this here before we are really closed
+ m_mdiParent->RemoveMDIChild(this);
+ return wxFrame::Destroy();
+}
+
+// ========================================================================
+// wxMDIClientWindow
+// ========================================================================
+IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow,wxWindow)
+
+wxMDIClientWindow::wxMDIClientWindow()
+{
+}
+
+wxMDIClientWindow::wxMDIClientWindow(wxMDIParentFrame *parent, long style)
+: wxWindow(parent, -1)
+{
+}
+
+wxMDIClientWindow::~wxMDIClientWindow()
+{
+}
+
+bool wxMDIClientWindow::CreateClient( wxMDIParentFrame *parent, long style)
+{
+ return false;
+}
+