Added implementation of MDI using top level windows

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@24546 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
David Elliott
2003-11-13 16:03:08 +00:00
parent 3905012063
commit f99422e9e9
2 changed files with 498 additions and 0 deletions

335
src/cocoa/mdi.mm Normal file
View File

@@ -0,0 +1,335 @@
/////////////////////////////////////////////////////////////////////////////
// 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;
}