X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/0d57be459406c2830f6abc9d99ae99166c6d133b..bf6d45ebf663a0f31021893d2369a95d96198c8f:/src/motif/mdi.cpp diff --git a/src/motif/mdi.cpp b/src/motif/mdi.cpp index 75a528cedb..fe31aa958a 100644 --- a/src/motif/mdi.cpp +++ b/src/motif/mdi.cpp @@ -1,22 +1,33 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: mdi.cpp +// Name: src/motif/mdi.cpp // Purpose: MDI classes // Author: Julian Smart // Modified by: // Created: 17/09/98 // RCS-ID: $Id$ // Copyright: (c) Julian Smart -// Licence: wxWindows licence +// Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "mdi.h" +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" + +#ifdef __VMS +#define XtDisplay XTDISPLAY +#define XtWindow XTWINDOW #endif #include "wx/mdi.h" -#include "wx/menu.h" -#include "wx/settings.h" +#ifndef WX_PRECOMP + #include "wx/menu.h" + #include "wx/icon.h" + #include "wx/settings.h" +#endif + +#ifdef __VMS__ +#pragma message disable nosimpint +#endif #include #include #include @@ -27,188 +38,36 @@ #include #include #include - -#include "mdi/lib/XsMDICanvas.h" -#include "mdi/lib/XsMotifWindow.h" +#ifdef __VMS__ +#pragma message enable nosimpint +#endif #include "wx/motif/private.h" extern wxList wxModelessWindows; // Implemented in frame.cpp -extern void wxFrameFocusProc(Widget workArea, XtPointer clientData, - XmAnyCallbackStruct *cbs); +extern void wxFrameFocusProc(Widget workArea, XtPointer clientData, + XmAnyCallbackStruct *cbs); + +#define wxID_NOTEBOOK_CLIENT_AREA wxID_HIGHEST + 100 -#if !USE_SHARED_LIBRARY IMPLEMENT_DYNAMIC_CLASS(wxMDIParentFrame, wxFrame) IMPLEMENT_DYNAMIC_CLASS(wxMDIChildFrame, wxFrame) -IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxWindow) +IMPLEMENT_DYNAMIC_CLASS(wxMDIClientWindow, wxNotebook) BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame) - EVT_SIZE(wxMDIParentFrame::OnSize) - EVT_ACTIVATE(wxMDIParentFrame::OnActivate) - EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged) + EVT_SIZE(wxMDIParentFrame::OnSize) + EVT_ACTIVATE(wxMDIParentFrame::OnActivate) + EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged) + EVT_MENU_HIGHLIGHT_ALL(wxMDIParentFrame::OnMenuHighlight) END_EVENT_TABLE() -BEGIN_EVENT_TABLE(wxMDIClientWindow, wxWindow) - EVT_SCROLL(wxMDIClientWindow::OnScroll) +BEGIN_EVENT_TABLE(wxMDIClientWindow, wxNotebook) + EVT_SCROLL(wxMDIClientWindow::OnScroll) + EVT_NOTEBOOK_PAGE_CHANGED(wxID_NOTEBOOK_CLIENT_AREA, wxMDIClientWindow::OnPageChanged) END_EVENT_TABLE() -#endif - - /* -static void _doNothingCallback (Widget, XtPointer, XtPointer) -{ -} -*/ - -// wxXsMDIWindow represents the MDI child frame, as far as the MDI -// package is concerned. -// TODO: override raise, so we can tell which is the 'active' -// (raised) window. We can also use it to send wxActivateEvents, -// and switching menubars when we make the child frame menubar -// appear on the parent frame. - -// Note: see XsMotifWindow.C, _XsMotifMenu::_processItem for -// where user menu selections are processed. -// When Close is selected, _win->close() is called. - -class wxXsMDIWindow: public XsMotifWindow -{ -public: - wxMDIChildFrame* m_childFrame; - - wxXsMDIWindow(const char* name, wxMDIChildFrame* frame): XsMotifWindow(name) - { - m_childFrame = frame; - } - virtual void setSize(Dimension w, Dimension h) - { - XsMotifWindow::setSize(w, h); - - // Generate wxSizeEvent here, I think. Maybe also restore, maximize - // Probably don't need to generate size event here since work area - // is used (???) - wxSizeEvent event(wxSize(w, h), m_childFrame->GetId()); - event.SetEventObject(m_childFrame); - m_childFrame->ProcessEvent(event); - } - virtual void close() - { - XsMotifWindow::close(); - m_childFrame->Close(); - } - virtual void raise() - { - XsMotifWindow::raise(); - m_childFrame->OnRaise(); - } - virtual void lower() - { - XsMotifWindow::lower(); - m_childFrame->OnLower(); - } - virtual void _buildClientArea(Widget parent) - { - m_childFrame->BuildClientArea((WXWidget) parent); - - // Code from MDI sample -#if 0 - assert (parent != 0); - - Widget pulldown; - Widget cascade; - Widget button; - -// Create a main window with some dummy menus - - Widget mainW = XtVaCreateWidget ("mainWin", xmMainWindowWidgetClass, parent, - XmNtopAttachment, XmATTACH_FORM, XmNbottomAttachment, XmATTACH_FORM, - XmNleftAttachment, XmATTACH_FORM, XmNrightAttachment, XmATTACH_FORM, - NULL); - -// Create a menubar - - Widget menuBar = XmCreateMenuBar (mainW, "menuBar", NULL, 0); - -// Create the "file" menu - - pulldown = XmCreatePulldownMenu (menuBar, "pulldown", NULL, 0); - cascade = XtVaCreateManagedWidget ("fileMenu", xmCascadeButtonGadgetClass, - menuBar, XmNsubMenuId, pulldown, NULL); - - button = XtVaCreateManagedWidget ("openMenuItem", xmPushButtonGadgetClass, - pulldown, NULL); - XtAddCallback (button, XmNactivateCallback, _doNothingCallback, (XtPointer)this); - - button = XtVaCreateManagedWidget ("newMenuItem", xmPushButtonGadgetClass, - pulldown, NULL); - // XtAddCallback (button, XmNactivateCallback, _newWindowCallback, (XtPointer)this); - -// Create the "edit" menu - - pulldown = XmCreatePulldownMenu (menuBar, "pulldown", NULL, 0); - cascade = XtVaCreateManagedWidget ("editMenu", xmCascadeButtonGadgetClass, - menuBar, XmNsubMenuId, pulldown, NULL); - - button = XtVaCreateManagedWidget ("cutMenuItem", xmPushButtonGadgetClass, - pulldown, NULL); - XtAddCallback (button, XmNactivateCallback, _doNothingCallback, (XtPointer)this); - - button = XtVaCreateManagedWidget ("copyMenuItem", xmPushButtonGadgetClass, - pulldown, NULL); - XtAddCallback (button, XmNactivateCallback, _doNothingCallback, (XtPointer)this); - - button = XtVaCreateManagedWidget ("pasteMenuItem", xmPushButtonGadgetClass, - pulldown, NULL); - XtAddCallback (button, XmNactivateCallback, _doNothingCallback, (XtPointer)this); - -// Create the help menu - - pulldown = XmCreatePulldownMenu (menuBar, "pulldown", NULL, 0); - cascade = XtVaCreateManagedWidget ("helpMenu", xmCascadeButtonGadgetClass, - menuBar, XmNsubMenuId, pulldown, NULL); - - button = XtVaCreateManagedWidget ("aboutMenuItem", xmPushButtonGadgetClass, - pulldown, NULL); - XtAddCallback (button, XmNactivateCallback, _doNothingCallback, (XtPointer)this); - - XtVaSetValues (menuBar, XmNmenuHelpWidget, cascade, NULL); - -// Manage the menubar - - XtManageChild (menuBar); - -// Create the work area - - const int nargs = 8; - Arg args[nargs]; - int n; - - n = 0; - XtSetArg (args[n], XmNscrollingPolicy, XmAUTOMATIC); n++; - XtSetArg (args[n], XmNhighlightThickness, (Dimension)0); n++; - XtSetArg (args[n], XmNeditMode, XmMULTI_LINE_EDIT); n++; - XtSetArg (args[n], XmNeditable, True); n++; - XtSetArg (args[n], XmNwordWrap, False); n++; - XtSetArg (args[n], XmNcursorPositionVisible, True); n++; - XtSetArg (args[n], XmNverifyBell, True); n++; - - assert (n <= nargs); - - Widget scrolledText = XmCreateScrolledText (mainW, "scrolledText", args, n); - XtManageChild (scrolledText); - -// Set the main window area - - XtVaSetValues (mainW, XmNmenuBar, menuBar, XmNworkWindow, - XtParent (scrolledText), NULL); - - XtManageChild (mainW); -#endif - } - void Show() { show(); } -}; // Parent frame @@ -216,18 +75,20 @@ wxMDIParentFrame::wxMDIParentFrame() { m_clientWindow = (wxMDIClientWindow*) NULL; m_activeChild = (wxMDIChildFrame*) NULL; + m_activeMenuBar = (wxMenuBar*) NULL; } bool wxMDIParentFrame::Create(wxWindow *parent, - wxWindowID id, - const wxString& title, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) + wxWindowID id, + const wxString& title, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) { m_clientWindow = (wxMDIClientWindow*) NULL; m_activeChild = (wxMDIChildFrame*) NULL; + m_activeMenuBar = (wxMenuBar*) NULL; bool success = wxFrame::Create(parent, id, title, pos, size, style, name); if (success) @@ -237,36 +98,42 @@ bool wxMDIParentFrame::Create(wxWindow *parent, // (we're in the constructor). How to resolve? m_clientWindow = OnCreateClient(); - // Uses own style for client style - m_clientWindow->CreateClient(this, GetWindowStyleFlag()); - return TRUE; + + // Uses own style for client style + m_clientWindow->CreateClient(this, GetWindowStyleFlag()); + + int w, h; + GetClientSize(& w, & h); + m_clientWindow->SetSize(0, 0, w, h); + return true; } else - return FALSE; + return false; } wxMDIParentFrame::~wxMDIParentFrame() { + // Make sure we delete the client window last of all + RemoveChild(m_clientWindow); + DestroyChildren(); - delete m_clientWindow; -} -// Get size *available for subwindows* i.e. excluding menu bar. -void wxMDIParentFrame::GetClientSize(int *x, int *y) const -{ - wxFrame::GetClientSize(x, y); + delete m_clientWindow; + m_clientWindow = NULL; } void wxMDIParentFrame::SetMenuBar(wxMenuBar *menu_bar) { - wxFrame::SetMenuBar(menu_bar); + m_frameMenuBar = menu_bar; + + SetChildMenuBar((wxMDIChildFrame*) NULL); } -void wxMDIParentFrame::OnSize(wxSizeEvent& event) +void wxMDIParentFrame::OnSize(wxSizeEvent& WXUNUSED(event)) { #if wxUSE_CONSTRAINTS if (GetAutoLayout()) - Layout(); + Layout(); #endif int x = 0; int y = 0; @@ -277,9 +144,14 @@ void wxMDIParentFrame::OnSize(wxSizeEvent& event) GetClientWindow()->SetSize(x, y, width, height); } -void wxMDIParentFrame::OnActivate(wxActivateEvent& event) +void wxMDIParentFrame::DoGetClientSize(int *width, int *height) const +{ + wxFrame::DoGetClientSize(width, height); +} + +void wxMDIParentFrame::OnActivate(wxActivateEvent& WXUNUSED(event)) { - // Do nothing + // Do nothing } // Returns the active MDI child window @@ -292,7 +164,101 @@ wxMDIChildFrame *wxMDIParentFrame::GetActiveChild() const // just return a new class) wxMDIClientWindow *wxMDIParentFrame::OnCreateClient() { - return new wxMDIClientWindow ; + return new wxMDIClientWindow ; +} + +// Set the child's menu into the parent frame +void wxMDIParentFrame::SetChildMenuBar(wxMDIChildFrame* child) +{ + wxMenuBar* oldMenuBar = m_activeMenuBar; + + if (child == (wxMDIChildFrame*) NULL) // No child: use parent frame + { + if (GetMenuBar() && (GetMenuBar() != m_activeMenuBar)) + { + // if (m_activeMenuBar) + // m_activeMenuBar->DestroyMenuBar(); + + m_activeMenuBar = GetMenuBar(); + m_activeMenuBar->CreateMenuBar(this); + /* + if (oldMenuBar && XtIsManaged((Widget) oldMenuBar->GetMainWidget())) + XtUnmanageChild((Widget) oldMenuBar->GetMainWidget()); + */ + if (oldMenuBar && oldMenuBar->GetMainWidget()) + XtUnmapWidget((Widget) oldMenuBar->GetMainWidget()); + + } + } + else if (child->GetMenuBar() == (wxMenuBar*) NULL) // No child menu bar: use parent frame + { + if (GetMenuBar() && (GetMenuBar() != m_activeMenuBar)) + { + // if (m_activeMenuBar) + // m_activeMenuBar->DestroyMenuBar(); + m_activeMenuBar = GetMenuBar(); + m_activeMenuBar->CreateMenuBar(this); + /* + if (oldMenuBar && XtIsManaged((Widget) oldMenuBar->GetMainWidget())) + XtUnmanageChild((Widget) oldMenuBar->GetMainWidget()); + */ + if (oldMenuBar && oldMenuBar->GetMainWidget()) + XtUnmapWidget((Widget) oldMenuBar->GetMainWidget()); + } + } + else // The child has a menubar + { + if (child->GetMenuBar() != m_activeMenuBar) + { + // if (m_activeMenuBar) + // m_activeMenuBar->DestroyMenuBar(); + + m_activeMenuBar = child->GetMenuBar(); + m_activeMenuBar->CreateMenuBar(this); + /* + if (oldMenuBar && XtIsManaged((Widget) oldMenuBar->GetMainWidget())) + XtUnmanageChild((Widget) oldMenuBar->GetMainWidget()); + */ + if (oldMenuBar && oldMenuBar->GetMainWidget()) + XtUnmapWidget((Widget) oldMenuBar->GetMainWidget()); + } + } +} + +// Redirect events to active child first +bool wxMDIParentFrame::ProcessEvent(wxEvent& event) +{ + // Stops the same event being processed repeatedly + static wxEventType inEvent = wxEVT_NULL; + if (inEvent == event.GetEventType()) + return false; + + inEvent = event.GetEventType(); + + bool res = false; + if (m_activeChild && event.IsKindOf(CLASSINFO(wxCommandEvent))) + { + res = m_activeChild->GetEventHandler()->ProcessEvent(event); + } + + if (!res) + res = GetEventHandler()->wxEvtHandler::ProcessEvent(event); + + inEvent = wxEVT_NULL; + + return res; +} + +void wxMDIParentFrame::DoSetSize(int x, int y, + int width, int height, + int sizeFlags) +{ + wxWindow::DoSetSize(x, y, width, height, sizeFlags); +} + +void wxMDIParentFrame::DoSetClientSize(int width, int height) +{ + wxWindow::DoSetClientSize(width, height); } // Responds to colour changes, and passes event on to children. @@ -310,7 +276,7 @@ void wxMDIParentFrame::Cascade() // TODO } -void wxMDIParentFrame::Tile() +void wxMDIParentFrame::Tile(wxOrientation WXUNUSED(orient)) { // TODO } @@ -330,201 +296,159 @@ void wxMDIParentFrame::ActivatePrevious() // TODO } +// Default menu selection behaviour - display a help string +void wxMDIParentFrame::OnMenuHighlight(wxMenuEvent& event) +{ + if (GetStatusBar()) + { + if (event.GetMenuId() == -1) + SetStatusText(wxEmptyString); + else + { + wxMenuBar *menuBar = (wxMenuBar*) NULL; + if (GetActiveChild()) + menuBar = GetActiveChild()->GetMenuBar(); + else + menuBar = GetMenuBar(); + if (menuBar) + { + wxString helpString(menuBar->GetHelpString(event.GetMenuId())); + if (!helpString.empty()) + SetStatusText(helpString); + } + } + } +} + // Child frame wxMDIChildFrame::wxMDIChildFrame() { + m_mdiParentFrame = (wxMDIParentFrame*) NULL; } bool wxMDIChildFrame::Create(wxMDIParentFrame *parent, - wxWindowID id, - const wxString& title, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) + wxWindowID id, + const wxString& title, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) { SetName(name); + SetWindowStyleFlag(style); if ( id > -1 ) m_windowId = id; else m_windowId = (int)NewControlId(); - if (parent) parent->AddChild(this); + wxMDIClientWindow* clientWindow = parent->GetClientWindow(); + + wxCHECK_MSG( clientWindow, false, "Missing MDI client window." ); - int x = pos.x; int y = pos.y; - int width = size.x; int height = size.y; + clientWindow->AddChild(this); + + SetMDIParentFrame(parent); + PreCreation(); + + int width = size.x; + int height = size.y; if (width == -1) width = 200; // TODO: give reasonable default if (height == -1) height = 200; // TODO: give reasonable default - wxMDIClientWindow* clientWindow = parent->GetClientWindow(); - if (!clientWindow) - return FALSE; - // We're deactivating the old child wxMDIChildFrame* oldActiveChild = parent->GetActiveChild(); if (oldActiveChild) { - wxActivateEvent event(wxEVT_ACTIVATE, FALSE, oldActiveChild->GetId()); + wxActivateEvent event(wxEVT_ACTIVATE, false, oldActiveChild->GetId()); event.SetEventObject( oldActiveChild ); oldActiveChild->GetEventHandler()->ProcessEvent(event); } - m_mdiWindow = new wxXsMDIWindow("mdiChildWindow", this); - clientWindow->GetMDICanvas()->add(m_mdiWindow); - // This is the currently active child parent->SetActiveChild((wxMDIChildFrame*) this); - m_mdiWindow->Show(); - -#if 0 - m_mainWidget = (WXWidget) (Widget) (*m_mdiWindow); - - m_frameWidget = (WXWidget) XtVaCreateManagedWidget("main_window", - xmMainWindowWidgetClass, (Widget) m_mainWidget, - XmNresizePolicy, XmRESIZE_NONE, - NULL); - - m_workArea = (WXWidget) XtVaCreateWidget("form", - xmFormWidgetClass, (Widget) m_frameWidget, - XmNresizePolicy, XmRESIZE_NONE, - NULL); - - m_clientArea = (WXWidget) XtVaCreateWidget("client", - xmBulletinBoardWidgetClass, (Widget) m_workArea, - XmNmarginWidth, 0, - XmNmarginHeight, 0, - XmNrightAttachment, XmATTACH_FORM, - XmNleftAttachment, XmATTACH_FORM, - XmNtopAttachment, XmATTACH_FORM, - XmNbottomAttachment, XmATTACH_FORM, -// XmNresizePolicy, XmRESIZE_ANY, - NULL); - - XtVaSetValues((Widget) m_frameWidget, - XmNworkWindow, (Widget) m_workArea, - NULL); - - XtManageChild((Widget) m_clientArea); - XtManageChild((Widget) m_workArea); - - wxASSERT_MSG ((wxWidgetHashTable->Get((long)m_workArea) == (wxObject*) NULL), "Widget table clash in frame.cpp") ; - - wxAddWindowToTable((Widget) m_workArea, this); - - XtTranslations ptr ; - - XtOverrideTranslations((Widget) m_workArea, - ptr = XtParseTranslationTable(": resize()")); - - XtFree((char *)ptr); - - XtAddCallback((Widget) m_workArea, XmNfocusCallback, - (XtCallbackProc)wxFrameFocusProc, (XtPointer)this); - - if (x > -1) - XtVaSetValues((Widget) m_mainWidget, XmNx, x, NULL); - if (y > -1) - XtVaSetValues((Widget) m_mainWidget, XmNy, y, NULL); - if (width > -1) - XtVaSetValues((Widget) m_mainWidget, XmNwidth, width, NULL); - if (height > -1) - XtVaSetValues((Widget) m_mainWidget, XmNheight, height, NULL); -#endif + // This time we'll try a bog-standard bulletin board for + // the 'frame'. A main window doesn't seem to work. - SetTitle(title); + m_mainWidget = (WXWidget) XtVaCreateWidget("client", + xmBulletinBoardWidgetClass, (Widget) clientWindow->GetTopWidget(), + XmNmarginWidth, 0, + XmNmarginHeight, 0, + /* + XmNrightAttachment, XmATTACH_FORM, + XmNleftAttachment, XmATTACH_FORM, + XmNtopAttachment, XmATTACH_FORM, + XmNbottomAttachment, XmATTACH_FORM, + */ + XmNresizePolicy, XmRESIZE_NONE, + NULL); - PreResize(); + XtAddEventHandler((Widget) m_mainWidget, ExposureMask,False, + wxUniversalRepaintProc, (XtPointer) this); - m_mdiWindow->setSize(width, height); + PostCreation(); + AttachWidget (parent, m_mainWidget, (WXWidget) NULL, pos.x, pos.y, size.x, size.y); - wxModelessWindows.Append(this); - return TRUE; -} + XtManageChild((Widget) m_mainWidget); -void wxMDIChildFrame::BuildClientArea(WXWidget parent) -{ - m_mainWidget = parent; - - m_frameWidget = (WXWidget) XtVaCreateManagedWidget("main_window", - xmMainWindowWidgetClass, (Widget) m_mainWidget, - XmNresizePolicy, XmRESIZE_NONE, - XmNtopAttachment, XmATTACH_FORM, - XmNbottomAttachment, XmATTACH_FORM, - XmNleftAttachment, XmATTACH_FORM, - XmNrightAttachment, XmATTACH_FORM, - NULL); - - m_workArea = (WXWidget) XtVaCreateWidget("form", - xmFormWidgetClass, (Widget) m_frameWidget, - XmNresizePolicy, XmRESIZE_NONE, - NULL); - - m_clientArea = (WXWidget) XtVaCreateWidget("client", - xmBulletinBoardWidgetClass, (Widget) m_workArea, - XmNmarginWidth, 0, - XmNmarginHeight, 0, - XmNrightAttachment, XmATTACH_FORM, - XmNleftAttachment, XmATTACH_FORM, - XmNtopAttachment, XmATTACH_FORM, - XmNbottomAttachment, XmATTACH_FORM, -// XmNresizePolicy, XmRESIZE_ANY, - NULL); - - XtVaSetValues((Widget) m_frameWidget, - XmNworkWindow, (Widget) m_workArea, - NULL); - - XtManageChild((Widget) m_clientArea); - XtManageChild((Widget) m_workArea); - - wxASSERT_MSG ((wxWidgetHashTable->Get((long)m_workArea) == (wxObject*) NULL), "Widget table clash in frame.cpp") ; - - wxAddWindowToTable((Widget) m_workArea, this); - - XtTranslations ptr ; - - XtOverrideTranslations((Widget) m_workArea, - ptr = XtParseTranslationTable(": resize()")); - - XtFree((char *)ptr); - - XtAddCallback((Widget) m_workArea, XmNfocusCallback, - (XtCallbackProc)wxFrameFocusProc, (XtPointer)this); + SetTitle(title); - /* - int x = pos.x; int y = pos.y; - int width = size.x; int height = size.y; + clientWindow->AddPage(this, title, true); + clientWindow->Refresh(); - if (x > -1) - XtVaSetValues((Widget) m_mainWidget, XmNx, x, NULL); - if (y > -1) - XtVaSetValues((Widget) m_mainWidget, XmNy, y, NULL); - if (width > -1) - XtVaSetValues((Widget) m_mainWidget, XmNwidth, width, NULL); - if (height > -1) - XtVaSetValues((Widget) m_mainWidget, XmNheight, height, NULL); - */ + // Positions the toolbar and status bar -- but we don't have any. + // PreResize(); - XtManageChild((Widget) m_frameWidget); + wxModelessWindows.Append(this); + return true; } wxMDIChildFrame::~wxMDIChildFrame() { - wxMDIParentFrame* parentFrame = (wxMDIParentFrame*) GetParent() ; - if (parentFrame->GetActiveChild() == this) - parentFrame->SetActiveChild((wxMDIChildFrame*) NULL); + if (m_mainWidget) + XtRemoveEventHandler((Widget) m_mainWidget, ExposureMask,False, + wxUniversalRepaintProc, (XtPointer) this); - wxMDIClientWindow* clientWindow = parentFrame->GetClientWindow(); - clientWindow->GetMDICanvas()->remove(m_mdiWindow); - m_mainWidget = (WXWidget) 0; + if (GetMDIParentFrame()) + { + wxMDIParentFrame* parentFrame = GetMDIParentFrame(); + + if (parentFrame->GetActiveChild() == this) + parentFrame->SetActiveChild((wxMDIChildFrame*) NULL); + wxMDIClientWindow* clientWindow = parentFrame->GetClientWindow(); + + // Remove page if still there + { + int i = clientWindow->FindPage(this); + + if (i != -1) + { + clientWindow->RemovePage(i); + clientWindow->Refresh(); + } + } + + // Set the selection to the first remaining page + if (clientWindow->GetPageCount() > 0) + { + wxMDIChildFrame* child = (wxMDIChildFrame*) clientWindow->GetPage(0); + parentFrame->SetActiveChild(child); + parentFrame->SetChildMenuBar(child); + } + else + { + parentFrame->SetActiveChild((wxMDIChildFrame*) NULL); + parentFrame->SetChildMenuBar((wxMDIChildFrame*) NULL); + } + } } +#if 0 // Implementation: intercept and act upon raise and lower commands. void wxMDIChildFrame::OnRaise() { @@ -534,12 +458,12 @@ void wxMDIChildFrame::OnRaise() if (oldActiveChild) { - wxActivateEvent event(wxEVT_ACTIVATE, FALSE, oldActiveChild->GetId()); + wxActivateEvent event(wxEVT_ACTIVATE, false, oldActiveChild->GetId()); event.SetEventObject( oldActiveChild ); oldActiveChild->GetEventHandler()->ProcessEvent(event); } - wxActivateEvent event(wxEVT_ACTIVATE, TRUE, this->GetId()); + wxActivateEvent event(wxEVT_ACTIVATE, true, this->GetId()); event.SetEventObject( this ); this->GetEventHandler()->ProcessEvent(event); } @@ -551,7 +475,7 @@ void wxMDIChildFrame::OnLower() if (oldActiveChild == this) { - wxActivateEvent event(wxEVT_ACTIVATE, FALSE, oldActiveChild->GetId()); + wxActivateEvent event(wxEVT_ACTIVATE, false, oldActiveChild->GetId()); event.SetEventObject( oldActiveChild ); oldActiveChild->GetEventHandler()->ProcessEvent(event); } @@ -559,157 +483,238 @@ void wxMDIChildFrame::OnLower() // so make the active child NULL. parentFrame->SetActiveChild((wxMDIChildFrame*) NULL); } +#endif // Set the client size (i.e. leave the calculation of borders etc. -// to wxWindows) -void wxMDIChildFrame::SetClientSize(int width, int height) +// to wxWidgets) +void wxMDIChildFrame::DoSetClientSize(int width, int height) { - wxFrame::SetClientSize(width, height); + wxWindow::DoSetClientSize(width, height); } -void wxMDIChildFrame::GetClientSize(int* width, int* height) const +void wxMDIChildFrame::DoGetClientSize(int* width, int* height) const { - wxFrame::GetClientSize(width, height); + wxWindow::DoGetSize(width, height); } -void wxMDIChildFrame::SetSize(int x, int y, int width, int height, int sizeFlags) +void wxMDIChildFrame::DoSetSize(int x, int y, int width, int height, int sizeFlags) { - wxWindow::SetSize(x, y, width, height, sizeFlags); + wxWindow::DoSetSize(x, y, width, height, sizeFlags); } -void wxMDIChildFrame::GetSize(int* width, int* height) const +void wxMDIChildFrame::DoGetSize(int* width, int* height) const { - wxWindow::GetSize(width, height); + wxWindow::DoGetSize(width, height); } -void wxMDIChildFrame::GetPosition(int *x, int *y) const +void wxMDIChildFrame::DoGetPosition(int *x, int *y) const { - wxWindow::GetPosition(x, y); + wxWindow::DoGetPosition(x, y); } bool wxMDIChildFrame::Show(bool show) { - m_visibleStatus = show; /* show-&-hide fix */ - return TRUE; + SetVisibleStatus( show ); + return wxWindow::Show(show); } -void wxMDIChildFrame::SetMenuBar(wxMenuBar *menu_bar) +void wxMDIChildFrame::SetMenuBar(wxMenuBar *menuBar) { - // TODO - // Currently, the menu appears on the child frame. - // It should eventually be recreated on the main frame - // whenever the child is activated. - wxFrame::SetMenuBar(menu_bar); + // Don't create the underlying menubar yet; need to recreate + // it every time the child is activated. + m_frameMenuBar = menuBar; + + // We make the assumption that if you're setting the menubar, + // this is the currently active child. + GetMDIParentFrame()->SetChildMenuBar(this); } // Set icon void wxMDIChildFrame::SetIcon(const wxIcon& icon) { - m_icon = icon; - if (m_icon.Ok()) + m_icons = wxIconBundle( icon ); + + if (icon.Ok()) { - /* TODO: doesn't work yet (crashes in XCopyArea) - Pixmap pixmap = (Pixmap) m_icon.GetPixmap(); - m_mdiWindow->setPixmap(pixmap); - */ + // Not appropriate since there are no icons in + // a tabbed window } } +void wxMDIChildFrame::SetIcons(const wxIconBundle& icons) +{ + m_icons = icons; +} + void wxMDIChildFrame::SetTitle(const wxString& title) { - m_title = title; - m_mdiWindow->setTitle(title); - m_mdiWindow->setIconName(title); + wxTopLevelWindow::SetTitle( title ); + wxMDIClientWindow* clientWindow = GetMDIParentFrame()->GetClientWindow(); + + // Remove page if still there + { + int i = clientWindow->FindPage(this); + + if (i != -1) + clientWindow->SetPageText(i, title); + } } // MDI operations void wxMDIChildFrame::Maximize() { - m_mdiWindow->maximize(); + // TODO } -void wxMDIChildFrame::Iconize(bool iconize) +void wxMDIChildFrame::Iconize(bool WXUNUSED(iconize)) { - if (iconize) - m_mdiWindow->minimize(); - else - m_mdiWindow->restore(); + // TODO } bool wxMDIChildFrame::IsIconized() const { - return m_mdiWindow->minimized(); + return false; +} + +// Is it maximized? Always maximized under Motif, using the +// tabbed MDI implementation. +bool wxMDIChildFrame::IsMaximized(void) const +{ + return true; } void wxMDIChildFrame::Restore() { - m_mdiWindow->restore(); + // TODO } void wxMDIChildFrame::Activate() { - m_mdiWindow->raise(); + // TODO +} + +void wxMDIChildFrame::CaptureMouse() +{ + wxWindow::CaptureMouse(); +} + +void wxMDIChildFrame::ReleaseMouse() +{ + wxWindow::ReleaseMouse(); +} + +void wxMDIChildFrame::Raise() +{ + wxWindow::Raise(); +} + +void wxMDIChildFrame::Lower(void) +{ + wxWindow::Raise(); +} + +void wxMDIChildFrame::DoSetSizeHints(int WXUNUSED(minW), int WXUNUSED(minH), int WXUNUSED(maxW), int WXUNUSED(maxH), int WXUNUSED(incW), int WXUNUSED(incH)) +{ } // Client window wxMDIClientWindow::wxMDIClientWindow() { - m_mdiCanvas = NULL; - m_topWidget = (WXWidget) 0; } wxMDIClientWindow::~wxMDIClientWindow() { + // By the time this destructor is called, the child frames will have been + // deleted and removed from the notebook/client window. DestroyChildren(); - delete m_mdiCanvas; m_mainWidget = (WXWidget) 0; - m_topWidget = (WXWidget) 0; } bool wxMDIClientWindow::CreateClient(wxMDIParentFrame *parent, long style) { - m_windowParent = parent; - m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE); - m_mdiCanvas = new XsMDICanvas("mdiClientWindow", (Widget) parent->GetClientWidget()); - m_mainWidget = (WXWidget) m_mdiCanvas->GetDrawingArea(); - // m_topWidget = (WXWidget) m_mdiCanvas->GetBase(); - m_topWidget = (WXWidget) (Widget) (*m_mdiCanvas); + SetWindowStyleFlag(style); + + bool success = wxNotebook::Create(parent, wxID_NOTEBOOK_CLIENT_AREA, wxPoint(0, 0), wxSize(100, 100), 0); + if (success) + { + return true; + } + else + return false; +} - m_mdiCanvas->show(); +int wxMDIClientWindow::FindPage(const wxNotebookPage* page) +{ + for (int i = GetPageCount() - 1; i >= 0; --i) + { + if (GetPage(i) == page) + return i; + } - return TRUE; + return -1; } -void wxMDIClientWindow::SetSize(int x, int y, int width, int height, int sizeFlags) +void wxMDIClientWindow::DoSetSize(int x, int y, int width, int height, int sizeFlags) { - wxWindow::SetSize(x, y, width, height, sizeFlags); + wxWindow::DoSetSize(x, y, width, height, sizeFlags); } -void wxMDIClientWindow::SetClientSize(int width, int height) +void wxMDIClientWindow::DoSetClientSize(int width, int height) { - wxWindow::SetClientSize(width, height); + wxWindow::DoSetClientSize(width, height); } -void wxMDIClientWindow::GetClientSize(int *width, int *height) const +void wxMDIClientWindow::DoGetClientSize(int *width, int *height) const { - wxWindow::GetClientSize(width, height); + wxWindow::DoGetClientSize(width, height); } -void wxMDIClientWindow::GetSize(int *width, int *height) const +void wxMDIClientWindow::DoGetSize(int *width, int *height) const { - wxWindow::GetSize(width, height); + wxWindow::DoGetSize(width, height); } -void wxMDIClientWindow::GetPosition(int *x, int *y) const +void wxMDIClientWindow::DoGetPosition(int *x, int *y) const { - wxWindow::GetPosition(x, y); + wxWindow::DoGetPosition(x, y); } -// Explicitly call default scroll behaviour void wxMDIClientWindow::OnScroll(wxScrollEvent& event) { - Default(); // Default processing + // Default(); // Default processing: OBSOLETE FUNCTION + event.Skip(); } +void wxMDIClientWindow::OnPageChanged(wxNotebookEvent& event) +{ + // Notify child that it has been activated + if (event.GetOldSelection() != -1) + { + wxMDIChildFrame* oldChild = (wxMDIChildFrame*) GetPage(event.GetOldSelection()); + if (oldChild) + { + wxActivateEvent event(wxEVT_ACTIVATE, false, oldChild->GetId()); + event.SetEventObject( oldChild ); + oldChild->GetEventHandler()->ProcessEvent(event); + } + } + if (event.GetSelection() != -1) + { + wxMDIChildFrame* activeChild = (wxMDIChildFrame*) GetPage(event.GetSelection()); + if (activeChild) + { + wxActivateEvent event(wxEVT_ACTIVATE, true, activeChild->GetId()); + event.SetEventObject( activeChild ); + activeChild->GetEventHandler()->ProcessEvent(event); + + if (activeChild->GetMDIParentFrame()) + { + activeChild->GetMDIParentFrame()->SetActiveChild(activeChild); + activeChild->GetMDIParentFrame()->SetChildMenuBar(activeChild); + } + } + } + event.Skip(); +}