From 621793f45e003588e32f7a6ca10cd238f7c96fe6 Mon Sep 17 00:00:00 2001 From: Julian Smart Date: Tue, 24 Nov 1998 21:55:10 +0000 Subject: [PATCH] 2nd attempt at MDI in wxMotif, using wxNotebook this time (still some probs). git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@1034 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775 --- docs/latex/wx/notebook.tex | 8 +- include/wx/gdicmn.h | 5 +- include/wx/generic/tabg.h | 3 + include/wx/motif/frame.h | 1 + include/wx/motif/mdi.h | 62 +++-- include/wx/motif/menu.h | 6 + include/wx/motif/notebook.h | 9 +- include/wx/msw/notebook.h | 2 + include/wx/msw/radiobut.h | 1 + include/wx/stubs/notebook.h | 2 + src/generic/tabg.cpp | 43 ++- src/motif/data.cpp | 1 + src/motif/frame.cpp | 50 ++-- src/motif/makefile.unx | 15 +- src/motif/mdi.cpp | 532 +++++++++++++++++------------------- src/motif/menu.cpp | 69 +++++ src/motif/notebook.cpp | 197 +++++++------ src/motif/window.cpp | 11 +- src/msw/notebook.cpp | 12 + src/msw/radiobut.cpp | 12 + src/stubs/notebook.cpp | 10 + 21 files changed, 620 insertions(+), 431 deletions(-) diff --git a/docs/latex/wx/notebook.tex b/docs/latex/wx/notebook.tex index 1817f10652..726da6a80a 100644 --- a/docs/latex/wx/notebook.tex +++ b/docs/latex/wx/notebook.tex @@ -120,7 +120,7 @@ Deletes all pages. \func{bool}{DeletePage}{\param{int}{ page}} -Deletes the specified page. +Deletes the specified page, and the associated window. \membersection{wxNotebook::GetImageList}\label{wxnotebookgetimagelist} @@ -211,6 +211,12 @@ An event handler function, called when the page selection is changed. \helpref{wxNotebookEvent}{wxnotebookevent} +\membersection{wxNotebook::RemovePage}\label{wxnotebookremovepage} + +\func{bool}{RemovePage}{\param{int}{ page}} + +Deletes the specified page, without deleting the associated window. + \membersection{wxNotebook::SetImageList}\label{wxnotebooksetimagelist} \func{void}{SetImageList}{\param{wxImageList*}{ imageList}} diff --git a/include/wx/gdicmn.h b/include/wx/gdicmn.h index 2f2570797a..fe995f30a5 100644 --- a/include/wx/gdicmn.h +++ b/include/wx/gdicmn.h @@ -331,9 +331,12 @@ extern void WXDLLEXPORT wxSetCursor(const wxCursor& cursor); // Load from a resource # define wxICON(X) wxIcon("" #X "") -#elif defined(__WXGTK__) || defined(__WXMOTIF__) +#elif defined(__WXGTK__) // Initialize from an included XPM # define wxICON(X) wxIcon( (const char**) X##_xpm ) +#elif defined(__WXMOTIF__) +// Initialize from an included XPM +# define wxICON(X) wxIcon( X##_xpm ) #else // This will usually mean something on any platform diff --git a/include/wx/generic/tabg.h b/include/wx/generic/tabg.h index e937b156b1..3b246de2d5 100644 --- a/include/wx/generic/tabg.h +++ b/include/wx/generic/tabg.h @@ -114,6 +114,9 @@ public: // Automatically positions tabs wxTabControl *AddTab(int id, const wxString& label, wxTabControl *existingTab = (wxTabControl *) NULL); + + // Remove the tab without deleting the window + bool RemoveTab(int id); void ClearTabs(bool deleteTabs = TRUE); diff --git a/include/wx/motif/frame.h b/include/wx/motif/frame.h index 8c5da8f12f..0614b627ba 100644 --- a/include/wx/motif/frame.h +++ b/include/wx/motif/frame.h @@ -155,6 +155,7 @@ public: inline WXWidget GetWorkAreaWidget() const { return m_workArea; } inline WXWidget GetClientAreaWidget() const { return m_clientArea; } inline WXWidget GetTopWidget() const { return m_frameShell; } + inline WXWidget GetMainWindowWidget() const { return m_frameWidget; } // The widget that can have children on it WXWidget GetClientWidget() const; diff --git a/include/wx/motif/mdi.h b/include/wx/motif/mdi.h index b843dc4e60..73138a679a 100644 --- a/include/wx/motif/mdi.h +++ b/include/wx/motif/mdi.h @@ -16,7 +16,16 @@ #pragma interface "mdi.h" #endif +/* +New MDI scheme using tabs. We can use a wxNotebook to implement the client +window. wxMDIChildFrame can be implemented as an XmMainWindow widget +as before, and is a child of the notebook _and_ of the parent frame... +but wxMDIChildFrame::GetParent should return the parent frame. + +*/ + #include "wx/frame.h" +#include "wx/notebook.h" WXDLLEXPORT_DATA(extern const char*) wxFrameNameStr; WXDLLEXPORT_DATA(extern const char*) wxStatusLineNameStr; @@ -24,11 +33,6 @@ WXDLLEXPORT_DATA(extern const char*) wxStatusLineNameStr; class WXDLLEXPORT wxMDIClientWindow; class WXDLLEXPORT wxMDIChildFrame; -#if wxUSE_MDI_WIDGETS -class XsMDICanvas; -class wxXsMDIWindow; -#endif - class WXDLLEXPORT wxMDIParentFrame: public wxFrame { DECLARE_DYNAMIC_CLASS(wxMDIParentFrame) @@ -87,12 +91,24 @@ public: virtual void ActivatePrevious(); // Implementation + + // Set the active child inline void SetActiveChild(wxMDIChildFrame* child) { m_activeChild = child; } + // Set the child's menubar into the parent frame + void SetChildMenuBar(wxMDIChildFrame* frame); + + inline wxMenuBar* GetActiveMenuBar() const { return m_activeMenuBar; } + + // Redirect events to active child first + virtual bool ProcessEvent(wxEvent& event); + + protected: wxMDIClientWindow* m_clientWindow; wxMDIChildFrame* m_activeChild; + wxMenuBar* m_activeMenuBar; DECLARE_EVENT_TABLE() }; @@ -136,6 +152,13 @@ public: // Set icon virtual void SetIcon(const wxIcon& icon); + // Override wxFrame operations + void CaptureMouse(); + void ReleaseMouse(); + void Raise(); + void Lower(void); + void SetSizeHints(int minW = -1, int minH = -1, int maxW = -1, int maxH = -1, int incW = -1, int incH = -1); + // MDI operations virtual void Maximize(); inline void Minimize() { Iconize(TRUE); }; @@ -145,16 +168,21 @@ public: virtual bool IsIconized() const ; bool Show(bool show); - void BuildClientArea(WXWidget parent); + + inline WXWidget GetMainWidget() const { return m_mainWidget; }; inline WXWidget GetTopWidget() const { return m_mainWidget; }; -#if wxUSE_MDI_WIDGETS - inline wxXsMDIWindow *GetMDIWindow() const { return m_mdiWindow; }; -#endif + inline WXWidget GetClientWidget() const { return m_mainWidget; }; + +/* virtual void OnRaise(); virtual void OnLower(); +*/ + + inline void SetMDIParentFrame(wxMDIParentFrame* parentFrame) { m_mdiParentFrame = parentFrame; } + inline wxMDIParentFrame* GetMDIParentFrame() const { return m_mdiParentFrame; } protected: - wxXsMDIWindow* m_mdiWindow ; + wxMDIParentFrame* m_mdiParentFrame; }; /* The client window is a child of the parent MDI frame, and itself @@ -164,7 +192,7 @@ protected: * of the children. Phew! So the children are sort of 'adopted'... */ -class WXDLLEXPORT wxMDIClientWindow: public wxWindow +class WXDLLEXPORT wxMDIClientWindow: public wxNotebook { DECLARE_DYNAMIC_CLASS(wxMDIClientWindow) public: @@ -184,25 +212,17 @@ class WXDLLEXPORT wxMDIClientWindow: public wxWindow void GetSize(int *width, int *height) const ; void GetPosition(int *x, int *y) const ; - // Note: this is virtual, to allow overridden behaviour. virtual bool CreateClient(wxMDIParentFrame *parent, long style = wxVSCROLL | wxHSCROLL); // Explicitly call default scroll behaviour void OnScroll(wxScrollEvent& event); -#if wxUSE_MDI_WIDGETS - inline XsMDICanvas* GetMDICanvas() const { return m_mdiCanvas; } - WXWidget GetTopWidget() const { return m_topWidget; } -#endif + // Implementation + void OnPageChanged(wxNotebookEvent& event); protected: -#if wxUSE_MDI_WIDGETS - XsMDICanvas* m_mdiCanvas; - WXWidget m_topWidget; -#endif - DECLARE_EVENT_TABLE() }; diff --git a/include/wx/motif/menu.h b/include/wx/motif/menu.h index e0b40fc05b..f9ebc22090 100644 --- a/include/wx/motif/menu.h +++ b/include/wx/motif/menu.h @@ -188,6 +188,12 @@ class WXDLLEXPORT wxMenuBar: public wxEvtHandler inline WXWidget GetMainWidget() const { return m_mainWidget; } inline void SetMainWidget(WXWidget widget) { m_mainWidget = widget; } + // Create menubar + bool CreateMenuBar(wxFrame* frame); + + // Destroy menubar, but keep data structures intact so we can recreate it. + bool DestroyMenuBar(); + public: wxEvtHandler * m_eventHandler; int m_menuCount; diff --git a/include/wx/motif/notebook.h b/include/wx/motif/notebook.h index 734d17fc05..0615edef40 100644 --- a/include/wx/motif/notebook.h +++ b/include/wx/motif/notebook.h @@ -109,6 +109,9 @@ public: // get number of pages in the dialog int GetPageCount() const; + // Find the position of the wxNotebookPage, -1 if not found. + int FindPagePosition(wxNotebookPage* page) const; + // set the currently selected page, return the index of the previously // selected one (or -1 on error) // NB: this function will _not_ generate wxEVT_NOTEBOOK_PAGE_xxx events @@ -148,8 +151,12 @@ public: // operations // ---------- - // remove one page from the notebook + // remove one page from the notebook, and delete the page. bool DeletePage(int nPage); + bool DeletePage(wxNotebookPage* page); + // remove one page from the notebook, without deleting the page. + bool RemovePage(int nPage); + bool RemovePage(wxNotebookPage* page); // remove all pages bool DeleteAllPages(); // adds a new page to the notebook (it will be deleted ny the notebook, diff --git a/include/wx/msw/notebook.h b/include/wx/msw/notebook.h index bebae78055..b75bc7f228 100644 --- a/include/wx/msw/notebook.h +++ b/include/wx/msw/notebook.h @@ -143,6 +143,8 @@ public: // ---------- // remove one page from the notebook bool DeletePage(int nPage); + // remove one page from the notebook, without deleting + bool RemovePage(int nPage); // remove all pages bool DeleteAllPages(); // adds a new page to the notebook (it will be deleted ny the notebook, diff --git a/include/wx/msw/radiobut.h b/include/wx/msw/radiobut.h index a2514e7574..1a546cee83 100644 --- a/include/wx/msw/radiobut.h +++ b/include/wx/msw/radiobut.h @@ -47,6 +47,7 @@ class WXDLLEXPORT wxRadioButton: public wxControl virtual void SetValue(bool val); virtual bool GetValue(void) const ; + bool MSWCommand(WXUINT param, WXWORD id); void Command(wxCommandEvent& event); virtual WXHBRUSH OnCtlColor(WXHDC pDC, WXHWND pWnd, WXUINT nCtlColor, WXUINT message, WXWPARAM wParam, WXLPARAM lParam); diff --git a/include/wx/stubs/notebook.h b/include/wx/stubs/notebook.h index 9b0794f359..83f8c1ce4e 100644 --- a/include/wx/stubs/notebook.h +++ b/include/wx/stubs/notebook.h @@ -132,6 +132,8 @@ public: // ---------- // remove one page from the notebook bool DeletePage(int nPage); + // remove one page from the notebook, without deleting + bool RemovePage(int nPage); // remove all pages bool DeleteAllPages(); // adds a new page to the notebook (it will be deleted ny the notebook, diff --git a/src/generic/tabg.cpp b/src/generic/tabg.cpp index fe7590fd50..cc6a601bc5 100644 --- a/src/generic/tabg.cpp +++ b/src/generic/tabg.cpp @@ -597,6 +597,35 @@ wxTabControl *wxTabView::AddTab(int id, const wxString& label, wxTabControl *exi return tabControl; } + +// Remove the tab without deleting the window +bool wxTabView::RemoveTab(int id) +{ + wxNode *layerNode = m_layers.First(); + while (layerNode) + { + wxTabLayer *layer = (wxTabLayer *)layerNode->Data(); + wxNode *tabNode = layer->First(); + while (tabNode) + { + wxTabControl *tab = (wxTabControl *)tabNode->Data(); + if (tab->GetId() == id) + { + if (id == m_tabSelection) + m_tabSelection = -1; + delete tab; + delete tabNode; + + // The layout has changed + Layout(); + return TRUE; + } + tabNode = tabNode->Next(); + } + layerNode = layerNode->Next(); + } + return FALSE; +} // Returns the total height of the tabs component -- this may be several // times the height of a tab, if there are several tab layers (rows). @@ -968,20 +997,26 @@ void wxTabView::SetTabSelection(int sel, bool activateTool) { int oldSel = m_tabSelection; wxTabControl *control = FindTabControlForId(sel); + wxTabControl *oldControl = FindTabControlForId(m_tabSelection); if (!OnTabPreActivate(sel, oldSel)) return; if (control) - control->SetSelected((sel != 0)); // TODO ?? - else + control->SetSelected((sel != -1)); // TODO ?? + else if (sel != -1) { - wxMessageBox(_("Could not find tab for id"), _("Error"), wxOK); + wxFAIL_MSG(_("Could not find tab for id")); return; } + + if (oldControl) + oldControl->SetSelected(FALSE); m_tabSelection = sel; - MoveSelectionTab(control); + + if (control) + MoveSelectionTab(control); if (activateTool) OnTabActivate(sel, oldSel); diff --git a/src/motif/data.cpp b/src/motif/data.cpp index e65f345b87..94cbc7eaf9 100644 --- a/src/motif/data.cpp +++ b/src/motif/data.cpp @@ -14,6 +14,7 @@ #endif #include "wx/wx.h" +#include "wx/postscrp.h" #define _MAXPATHLEN 500 diff --git a/src/motif/frame.cpp b/src/motif/frame.cpp index d7fe6aefac..f0b7089297 100644 --- a/src/motif/frame.cpp +++ b/src/motif/frame.cpp @@ -287,6 +287,8 @@ wxFrame::~wxFrame() if (m_frameMenuBar) { + m_frameMenuBar->DestroyMenuBar(); + // Hack to stop core dump on Ultrix, OSF, for some strange reason. #if MOTIF_MENUBAR_DELETE_FIX GetMenuBar()->SetMainWidget((WXWidget) NULL); @@ -486,6 +488,9 @@ void wxFrame::SetSize(int x, int y, int width, int height, int sizeFlags) bool wxFrame::Show(bool show) { + if (!m_frameShell) + return wxWindow::Show(show); + m_visibleStatus = show; /* show-&-hide fix */ m_isShown = show; @@ -504,7 +509,8 @@ void wxFrame::Iconize(bool iconize) if (!iconize) Show(TRUE); - XtVaSetValues((Widget) m_frameShell, XmNiconic, (Boolean)iconize, NULL); + if (m_frameShell) + XtVaSetValues((Widget) m_frameShell, XmNiconic, (Boolean)iconize, NULL); } // Equivalent to maximize/restore in Windows @@ -512,12 +518,15 @@ void wxFrame::Maximize(bool maximize) { Show(TRUE); - if (maximize) + if (maximize && m_frameShell) XtVaSetValues((Widget) m_frameShell, XmNiconic, FALSE, NULL); } bool wxFrame::IsIconized() const { + if (!m_frameShell) + return FALSE; + Boolean iconic; XtVaGetValues((Widget) m_frameShell, XmNiconic, &iconic, NULL); return iconic; @@ -541,6 +550,9 @@ void wxFrame::SetIcon(const wxIcon& icon) { m_icon = icon; + if (!m_frameShell) + return; + // TODO /* if (!icon.Ok() || !icon.GetPixmap()) @@ -638,32 +650,16 @@ void wxFrame::SetMenuBar(wxMenuBar *menuBar) } // Currently can't set it twice - wxASSERT_MSG( (m_frameMenuBar == (wxMenuBar*) NULL), "Cannot set the menubar more than once"); - - m_frameMenuBar = menuBar; +// wxASSERT_MSG( (m_frameMenuBar == (wxMenuBar*) NULL), "Cannot set the menubar more than once"); - Widget menuBarW = XmCreateMenuBar ((Widget) m_frameWidget, "MenuBar", NULL, 0); - m_frameMenuBar->SetMainWidget( (WXWidget) menuBarW); - - int i; - for (i = 0; i < menuBar->GetMenuCount(); i++) + if (m_frameMenuBar) { - wxMenu *menu = menuBar->GetMenu(i); - wxString title(menuBar->m_titles[i]); - menu->SetButtonWidget(menu->CreateMenu (menuBar, menuBarW, menu, title, TRUE)); - - /* - * COMMENT THIS OUT IF YOU DON'T LIKE A RIGHT-JUSTIFIED HELP MENU - */ - wxStripMenuCodes ((char*) (const char*) title, wxBuffer); - - if (strcmp (wxBuffer, "Help") == 0) - XtVaSetValues ((Widget) menuBarW, XmNmenuHelpWidget, (Widget) menu->GetButtonWidget(), NULL); + m_frameMenuBar->DestroyMenuBar(); + delete m_frameMenuBar; } - XtRealizeWidget ((Widget) menuBarW); - XtManageChild ((Widget) menuBarW); - menuBar->SetMenuBarFrame(this); + m_frameMenuBar = menuBar; + m_frameMenuBar->CreateMenuBar(this); } void wxFrame::Fit() @@ -1071,12 +1067,14 @@ void wxFrame::ChangeFont(bool keepOriginalSize) void wxFrame::ChangeBackgroundColour() { - // TODO + if (GetClientWidget()) + DoChangeBackgroundColour(GetClientWidget(), m_backgroundColour); } void wxFrame::ChangeForegroundColour() { - // TODO + if (GetClientWidget()) + DoChangeForegroundColour(GetClientWidget(), m_foregroundColour); } void wxCloseFrameCallback(Widget widget, XtPointer client_data, XmAnyCallbackStruct *cbs) diff --git a/src/motif/makefile.unx b/src/motif/makefile.unx index a05e8a1282..fcaa095e9e 100644 --- a/src/motif/makefile.unx +++ b/src/motif/makefile.unx @@ -179,13 +179,14 @@ EXTRA_C_SRC=\ xmcombo/xmcombo.c # $(ZLIB_SRC) EXTRA_CPP_SRC=\ - mdi/lib/XsComponent.C\ - mdi/lib/XsMDICanvas.C\ - mdi/lib/XsMDIWindow.C\ - mdi/lib/XsMotifWindow.C\ - mdi/lib/XsMoveOutline.C\ - mdi/lib/XsOutline.C\ - mdi/lib/XsResizeOutline.C + +# mdi/lib/XsComponent.C\ +# mdi/lib/XsMDICanvas.C\ +# mdi/lib/XsMDIWindow.C\ +# mdi/lib/XsMotifWindow.C\ +# mdi/lib/XsMoveOutline.C\ +# mdi/lib/XsOutline.C\ +# mdi/lib/XsResizeOutline.C all: $(WXLIB) diff --git a/src/motif/mdi.cpp b/src/motif/mdi.cpp index 75a528cedb..902714acc2 100644 --- a/src/motif/mdi.cpp +++ b/src/motif/mdi.cpp @@ -28,9 +28,6 @@ #include #include -#include "mdi/lib/XsMDICanvas.h" -#include "mdi/lib/XsMotifWindow.h" - #include "wx/motif/private.h" extern wxList wxModelessWindows; @@ -39,10 +36,12 @@ extern wxList wxModelessWindows; 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) @@ -50,172 +49,20 @@ BEGIN_EVENT_TABLE(wxMDIParentFrame, wxFrame) EVT_SYS_COLOUR_CHANGED(wxMDIParentFrame::OnSysColourChanged) END_EVENT_TABLE() -BEGIN_EVENT_TABLE(wxMDIClientWindow, wxWindow) +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 wxMDIParentFrame::wxMDIParentFrame() { m_clientWindow = (wxMDIClientWindow*) NULL; m_activeChild = (wxMDIChildFrame*) NULL; + m_activeMenuBar = (wxMenuBar*) NULL; } bool wxMDIParentFrame::Create(wxWindow *parent, @@ -228,6 +75,7 @@ bool wxMDIParentFrame::Create(wxWindow *parent, { 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,8 +85,13 @@ 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()); + + // 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 @@ -247,8 +100,13 @@ bool wxMDIParentFrame::Create(wxWindow *parent, wxMDIParentFrame::~wxMDIParentFrame() { + // Make sure we delete the client window last of all + RemoveChild(m_clientWindow); + DestroyChildren(); + delete m_clientWindow; + m_clientWindow = NULL; } // Get size *available for subwindows* i.e. excluding menu bar. @@ -259,7 +117,9 @@ void wxMDIParentFrame::GetClientSize(int *x, int *y) const void wxMDIParentFrame::SetMenuBar(wxMenuBar *menu_bar) { - wxFrame::SetMenuBar(menu_bar); + m_frameMenuBar = menu_bar; + + SetChildMenuBar((wxMDIChildFrame*) NULL); } void wxMDIParentFrame::OnSize(wxSizeEvent& event) @@ -295,6 +155,88 @@ wxMDIClientWindow *wxMDIParentFrame::OnCreateClient() 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; +} + // Responds to colour changes, and passes event on to children. void wxMDIParentFrame::OnSysColourChanged(wxSysColourChangedEvent& event) { @@ -334,6 +276,7 @@ void wxMDIParentFrame::ActivatePrevious() wxMDIChildFrame::wxMDIChildFrame() { + m_mdiParentFrame = (wxMDIParentFrame*) NULL; } bool wxMDIChildFrame::Create(wxMDIParentFrame *parent, @@ -346,12 +289,22 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent, { SetName(name); + m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE); + m_foregroundColour = *wxBLACK; + m_windowFont = wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT); + if ( id > -1 ) m_windowId = id; else m_windowId = (int)NewControlId(); - if (parent) parent->AddChild(this); + wxMDIClientWindow* clientWindow = parent->GetClientWindow(); + + wxASSERT_MSG( (clientWindow != (wxWindow*) NULL), "Missing MDI client window."); + + if (clientWindow) clientWindow->AddChild(this); + + SetMDIParentFrame(parent); int x = pos.x; int y = pos.y; int width = size.x; int height = size.y; @@ -360,10 +313,6 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent, 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) @@ -373,92 +322,43 @@ bool wxMDIChildFrame::Create(wxMDIParentFrame *parent, 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); + // This time we'll try a bog-standard bulletin board for + // the 'frame'. A main window doesn't seem to work. - m_workArea = (WXWidget) XtVaCreateWidget("form", - xmFormWidgetClass, (Widget) m_frameWidget, - XmNresizePolicy, XmRESIZE_NONE, - NULL); - - m_clientArea = (WXWidget) XtVaCreateWidget("client", - xmBulletinBoardWidgetClass, (Widget) m_workArea, + 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_ANY, + */ + XmNresizePolicy, XmRESIZE_NONE, NULL); + + SetCanAddEventHandler(TRUE); + AttachWidget (parent, m_mainWidget, (WXWidget) NULL, pos.x, pos.y, size.x, size.y); - 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 + ChangeBackgroundColour(); - SetTitle(title); - - PreResize(); - - m_mdiWindow->setSize(width, height); - - wxModelessWindows.Append(this); - return TRUE; -} - -void wxMDIChildFrame::BuildClientArea(WXWidget parent) -{ - m_mainWidget = parent; + // Old stuff +#if 0 m_frameWidget = (WXWidget) XtVaCreateManagedWidget("main_window", - xmMainWindowWidgetClass, (Widget) m_mainWidget, + xmMainWindowWidgetClass, (Widget) clientWindow->GetTopWidget(), XmNresizePolicy, XmRESIZE_NONE, - XmNtopAttachment, XmATTACH_FORM, - XmNbottomAttachment, XmATTACH_FORM, - XmNleftAttachment, XmATTACH_FORM, - XmNrightAttachment, XmATTACH_FORM, NULL); + // TODO: make sure this doesn't cause problems. + // I think ~wxFrame will do the right thing since it deletes m_frameWidget, + // then sets the main widget to NULL. + m_mainWidget = m_frameWidget; + m_workArea = (WXWidget) XtVaCreateWidget("form", xmFormWidgetClass, (Widget) m_frameWidget, XmNresizePolicy, XmRESIZE_NONE, @@ -496,9 +396,7 @@ void wxMDIChildFrame::BuildClientArea(WXWidget parent) XtAddCallback((Widget) m_workArea, XmNfocusCallback, (XtCallbackProc)wxFrameFocusProc, (XtPointer)this); - /* - int x = pos.x; int y = pos.y; - int width = size.x; int height = size.y; + XtManageChild((Widget) m_mainWidget); if (x > -1) XtVaSetValues((Widget) m_mainWidget, XmNx, x, NULL); @@ -508,23 +406,54 @@ void wxMDIChildFrame::BuildClientArea(WXWidget parent) XtVaSetValues((Widget) m_mainWidget, XmNwidth, width, NULL); if (height > -1) XtVaSetValues((Widget) m_mainWidget, XmNheight, height, NULL); - */ - XtManageChild((Widget) m_frameWidget); +#endif + + XtManageChild((Widget) m_mainWidget); + + SetTitle(title); + + clientWindow->AddPage(this, title, TRUE); + clientWindow->Refresh(); + + // Positions the toolbar and status bar -- but we don't have any. + // PreResize(); + + wxModelessWindows.Append(this); + return TRUE; } wxMDIChildFrame::~wxMDIChildFrame() { - wxMDIParentFrame* parentFrame = (wxMDIParentFrame*) GetParent() ; - if (parentFrame->GetActiveChild() == this) - parentFrame->SetActiveChild((wxMDIChildFrame*) NULL); - - 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 + if (clientWindow->RemovePage(this)) + 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() { @@ -559,22 +488,23 @@ 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) { - wxFrame::SetClientSize(width, height); + wxWindow::SetClientSize(width, height); } void wxMDIChildFrame::GetClientSize(int* width, int* height) const { - wxFrame::GetClientSize(width, height); + wxWindow::GetSize(width, height); } void wxMDIChildFrame::SetSize(int x, int y, int width, int height, int sizeFlags) { - wxWindow::SetSize(x, y, width, height, sizeFlags); + wxWindow::SetSize(x, y, width, height, sizeFlags); } void wxMDIChildFrame::GetSize(int* width, int* height) const @@ -590,16 +520,18 @@ void wxMDIChildFrame::GetPosition(int *x, int *y) const bool wxMDIChildFrame::Show(bool show) { m_visibleStatus = show; /* show-&-hide fix */ - return TRUE; + 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 @@ -618,68 +550,80 @@ void wxMDIChildFrame::SetIcon(const wxIcon& icon) void wxMDIChildFrame::SetTitle(const wxString& title) { m_title = title; - m_mdiWindow->setTitle(title); - m_mdiWindow->setIconName(title); + // TODO: set parent frame title } // MDI operations void wxMDIChildFrame::Maximize() { - m_mdiWindow->maximize(); + // TODO } void wxMDIChildFrame::Iconize(bool iconize) { - if (iconize) - m_mdiWindow->minimize(); - else - m_mdiWindow->restore(); + // TODO } bool wxMDIChildFrame::IsIconized() const { - return m_mdiWindow->minimized(); + return FALSE; } 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::SetSizeHints(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); - - m_mdiCanvas->show(); + // m_windowParent = parent; + // m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE); - return TRUE; + return wxNotebook::Create(parent, wxID_NOTEBOOK_CLIENT_AREA, wxPoint(0, 0), wxSize(100, 100), 0); } void wxMDIClientWindow::SetSize(int x, int y, int width, int height, int sizeFlags) @@ -713,3 +657,31 @@ void wxMDIClientWindow::OnScroll(wxScrollEvent& event) Default(); // Default processing } +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); + } + } + 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(); +} diff --git a/src/motif/menu.cpp b/src/motif/menu.cpp index d10b977174..91df050e49 100644 --- a/src/motif/menu.cpp +++ b/src/motif/menu.cpp @@ -455,6 +455,7 @@ wxMenuBar::wxMenuBar() m_menus = NULL; m_titles = NULL; m_menuBarFrame = NULL; + m_mainWidget = (WXWidget) NULL; } wxMenuBar::wxMenuBar(int n, wxMenu *menus[], const wxString titles[]) @@ -747,6 +748,74 @@ wxString wxMenuBar::GetHelpString (int id) const return wxString(""); } +// Create menubar +bool wxMenuBar::CreateMenuBar(wxFrame* parent) +{ + if (m_mainWidget) + { + XtVaSetValues((Widget) parent->GetMainWindowWidget(), XmNmenuBar, (Widget) m_mainWidget, NULL); + /* + if (!XtIsManaged((Widget) m_mainWidget)) + XtManageChild((Widget) m_mainWidget); + */ + XtMapWidget((Widget) m_mainWidget); + return TRUE; + } + + Widget menuBarW = XmCreateMenuBar ((Widget) parent->GetMainWindowWidget(), "MenuBar", NULL, 0); + m_mainWidget = (WXWidget) menuBarW; + + int i; + for (i = 0; i < GetMenuCount(); i++) + { + wxMenu *menu = GetMenu(i); + wxString title(m_titles[i]); + menu->SetButtonWidget(menu->CreateMenu (this, menuBarW, menu, title, TRUE)); + + /* + * COMMENT THIS OUT IF YOU DON'T LIKE A RIGHT-JUSTIFIED HELP MENU + */ + wxStripMenuCodes ((char*) (const char*) title, wxBuffer); + + if (strcmp (wxBuffer, "Help") == 0) + XtVaSetValues ((Widget) menuBarW, XmNmenuHelpWidget, (Widget) menu->GetButtonWidget(), NULL); + } + + XtVaSetValues((Widget) parent->GetMainWindowWidget(), XmNmenuBar, (Widget) m_mainWidget, NULL); + XtRealizeWidget ((Widget) menuBarW); + XtManageChild ((Widget) menuBarW); + SetMenuBarFrame(parent); + + return TRUE; +} + +// Destroy menubar, but keep data structures intact so we can recreate it. +bool wxMenuBar::DestroyMenuBar() +{ + if (!m_mainWidget) + { + SetMenuBarFrame((wxFrame*) NULL); + return FALSE; + } + + XtUnmanageChild ((Widget) m_mainWidget); + XtUnrealizeWidget ((Widget) m_mainWidget); + + int i; + for (i = 0; i < GetMenuCount(); i++) + { + wxMenu *menu = GetMenu(i); + menu->DestroyMenu(TRUE); + + } + XtDestroyWidget((Widget) m_mainWidget); + m_mainWidget = (WXWidget) 0; + + SetMenuBarFrame((wxFrame*) NULL); + + return TRUE; +} + //// Motif-specific extern wxApp *wxTheApp; diff --git a/src/motif/notebook.cpp b/src/motif/notebook.cpp index ba296eb4d0..fd0e099d65 100644 --- a/src/motif/notebook.cpp +++ b/src/motif/notebook.cpp @@ -138,7 +138,10 @@ int wxNotebook::SetSelection(int nPage) wxASSERT( IS_VALID_PAGE(nPage) ); - ChangePage(m_nSelection, nPage); + wxNotebookPage* pPage = GetPage(nPage); + + m_tabView->SetTabSelection((int) (long) pPage); + // ChangePage(m_nSelection, nPage); // TODO return 0; @@ -196,22 +199,96 @@ void wxNotebook::SetImageList(wxImageList* imageList) // wxNotebook operations // ---------------------------------------------------------------------------- -// remove one page from the notebook +// remove one page from the notebook and delete it bool wxNotebook::DeletePage(int nPage) { - wxFAIL_MSG("Sorry, DeletePage not implemented for Motif wxNotebook because wxTabView doesn't support it."); - return FALSE; - -/* wxCHECK( IS_VALID_PAGE(nPage), FALSE ); - // TODO: delete native widget page + if (m_nSelection != -1) + { + m_aPages[m_nSelection]->Show(FALSE); + m_aPages[m_nSelection]->Lower(); + } + + wxNotebookPage* pPage = GetPage(nPage); + m_tabView->RemoveTab((int) (long) pPage); delete m_aPages[nPage]; m_aPages.Remove(nPage); + if (m_aPages.GetCount() == 0) + { + m_nSelection = -1; + m_tabView->SetTabSelection(-1, FALSE); + } + else if (m_nSelection > 0) + { + m_nSelection = -1; + m_tabView->SetTabSelection((int) (long) GetPage(0), FALSE); + ChangePage(-1, 0); + } + return TRUE; -*/ +} + +bool wxNotebook::DeletePage(wxNotebookPage* page) +{ + int pagePos = FindPagePosition(page); + if (pagePos > -1) + return DeletePage(pagePos); + else + return FALSE; +} + +// remove one page from the notebook +bool wxNotebook::RemovePage(int nPage) +{ + wxCHECK( IS_VALID_PAGE(nPage), FALSE ); + + if (m_nSelection != -1) + { + m_aPages[m_nSelection]->Show(FALSE); + m_aPages[m_nSelection]->Lower(); + } + + wxNotebookPage* pPage = GetPage(nPage); + m_tabView->RemoveTab((int) (long) pPage); + + m_aPages.Remove(nPage); + + if (m_aPages.GetCount() == 0) + { + m_nSelection = -1; + m_tabView->SetTabSelection(-1, FALSE); + } + else if (m_nSelection > 0) + { + m_nSelection = -1; + m_tabView->SetTabSelection((int) (long) GetPage(0), FALSE); + ChangePage(-1, 0); + } + + return TRUE; +} + +bool wxNotebook::RemovePage(wxNotebookPage* page) +{ + int pagePos = FindPagePosition(page); + if (pagePos > -1) + return RemovePage(pagePos); + else + return FALSE; +} + +// Find the position of the wxNotebookPage, -1 if not found. +int wxNotebook::FindPagePosition(wxNotebookPage* page) const +{ + int nPageCount = GetPageCount(); + int nPage; + for ( nPage = 0; nPage < nPageCount; nPage++ ) + if (m_aPages[nPage] == page) + return nPage; + return -1; } // remove all pages @@ -248,23 +325,23 @@ bool wxNotebook::InsertPage(int nPage, wxASSERT( pPage != NULL ); wxCHECK( IS_VALID_PAGE(nPage) || nPage == GetPageCount(), FALSE ); - m_tabView->AddTab(nPage, strText); - pPage->Show(FALSE); - -/* - if (bSelect) - m_tabView->SetTabSelection(nPage, TRUE); -*/ + m_tabView->AddTab((int) (long) pPage, strText); + if (!bSelect) + pPage->Show(FALSE); // save the pointer to the page m_aPages.Insert(pPage, nPage); - // some page must be selected: either this one or the first one if there is + if (bSelect) + { + // This will cause ChangePage to be called, via OnSelPage + m_tabView->SetTabSelection((int) (long) pPage, TRUE); + } + + // some page must be selected: either this one or the first one if there is // still no selection - if ( bSelect ) - m_nSelection = nPage; - else if ( m_nSelection == -1 ) - m_nSelection = 0; + if ( m_nSelection == -1 ) + ChangePage(-1, 0); return TRUE; } @@ -311,12 +388,13 @@ void wxNotebook::OnSize(wxSizeEvent& event) m_tabView->SetViewRect(rect); m_tabView->Layout(); - + /* // emulate page change (it's esp. important to do it first time because // otherwise our page would stay invisible) int nSel = m_nSelection; m_nSelection = -1; SetSelection(nSel); + */ // fit the notebook page to the tab control's display area @@ -493,76 +571,19 @@ void wxNotebookTabView::OnTabActivate(int activateId, int deactivateId) return; wxNotebookEvent event(wxEVT_COMMAND_NOTEBOOK_PAGE_CHANGED, m_notebook->GetId()); - event.SetEventObject(m_notebook); - event.SetSelection(activateId); - event.SetOldSelection(deactivateId); - m_notebook->GetEventHandler()->ProcessEvent(event); - - /* - wxWindow *oldWindow = ((deactivateId == -1) ? 0 : m_notebook->GetPage(deactivateId)); - wxWindow *newWindow = m_notebook->GetPage(activateId); - - if (oldWindow) - { - oldWindow->Show(FALSE); - oldWindow->Lower(); - } - if (newWindow) - { - newWindow->Show(TRUE); - newWindow->Raise(); - int cw, ch; - m_notebook->GetClientSize(& cw, & ch); - - int tabHeight = GetTotalTabHeight(); - wxRect rect; - rect.x = 4; - rect.y = tabHeight + 4; - rect.width = cw - 8; - rect.height = ch - 4 - rect.y ; - - newWindow->SetSize(rect.x + 2, rect.y + 2, rect.width - 2, rect.height - 2); - newWindow->Refresh(); - } + // Translate from wxTabView's ids (which aren't position-dependent) + // to wxNotebook's (which are). + wxNotebookPage* pActive = (wxNotebookPage*) activateId; + wxNotebookPage* pDeactive = (wxNotebookPage*) deactivateId; - // TODO: only refresh the tab area. - m_notebook->Refresh(); -*/ -} + int activatePos = m_notebook->FindPagePosition(pActive); + int deactivatePos = m_notebook->FindPagePosition(pDeactive); -#if 0 -void wxNotebookTabView::AddTabWindow(int id, wxWindow *window) -{ - m_tabWindows.Append((long)id, window); - window->Show(FALSE); -} - -wxWindow *wxNotebookTabView::GetTabWindow(int id) const -{ - wxNode *node = m_tabWindows.Find((long)id); - if (!node) - return (wxWindow *) NULL; - return (wxWindow *)node->Data(); -} - -void wxNotebookTabView::ClearWindows(bool deleteWindows) -{ - if (deleteWindows) - m_tabWindows.DeleteContents(TRUE); - m_tabWindows.Clear(); - m_tabWindows.DeleteContents(FALSE); + event.SetEventObject(m_notebook); + event.SetSelection(activatePos); + event.SetOldSelection(deactivatePos); + m_notebook->GetEventHandler()->ProcessEvent(event); } -void wxNotebookTabView::ShowWindowForTab(int id) -{ - wxWindow *newWindow = GetTabWindow(id); - if (newWindow == m_currentWindow) - return; - if (m_currentWindow) - m_currentWindow->Show(FALSE); - newWindow->Show(TRUE); - newWindow->Refresh(); -} -#endif diff --git a/src/motif/window.cpp b/src/motif/window.cpp index 618603b721..568974519d 100644 --- a/src/motif/window.cpp +++ b/src/motif/window.cpp @@ -746,7 +746,11 @@ bool wxWindow::Show(bool show) } else { - XtMapWidget((Widget) GetTopWidget()); + WXWidget topWidget = GetTopWidget(); + if (GetTopWidget()) + XtMapWidget((Widget) GetTopWidget()); + else if (GetMainWidget()) + XtMapWidget((Widget) GetMainWidget()); } } else @@ -759,7 +763,10 @@ bool wxWindow::Show(bool show) } else { - XtUnmapWidget((Widget) GetTopWidget()); + if (GetTopWidget()) + XtUnmapWidget((Widget) GetTopWidget()); + else if (GetMainWidget()) + XtUnmapWidget((Widget) GetMainWidget()); } } diff --git a/src/msw/notebook.cpp b/src/msw/notebook.cpp index 788da296c5..e58af84b52 100644 --- a/src/msw/notebook.cpp +++ b/src/msw/notebook.cpp @@ -278,6 +278,18 @@ bool wxNotebook::DeletePage(int nPage) return TRUE; } +// remove one page from the notebook, without deleting +bool wxNotebook::RemovePage(int nPage) +{ + wxCHECK_MSG( IS_VALID_PAGE(nPage), FALSE, "notebook page out of range" ); + + TabCtrl_DeleteItem(m_hwnd, nPage); + + m_aPages.Remove(nPage); + + return TRUE; +} + // remove all pages bool wxNotebook::DeleteAllPages() { diff --git a/src/msw/radiobut.cpp b/src/msw/radiobut.cpp index 32cf7fe87e..8a222716d2 100644 --- a/src/msw/radiobut.cpp +++ b/src/msw/radiobut.cpp @@ -33,6 +33,18 @@ IMPLEMENT_DYNAMIC_CLASS(wxRadioButton, wxControl) // IMPLEMENT_DYNAMIC_CLASS(wxBitmapRadioButton, wxRadioButton) #endif +bool wxRadioButton::MSWCommand(WXUINT param, WXWORD id) +{ + if (param == BN_CLICKED) + { + wxCommandEvent event(wxEVT_COMMAND_RADIOBUTTON_SELECTED, m_windowId); + event.SetEventObject( this ); + ProcessCommand(event); + return TRUE; + } + else return FALSE; +} + bool wxRadioButton::Create(wxWindow *parent, wxWindowID id, const wxString& label, const wxPoint& pos, diff --git a/src/stubs/notebook.cpp b/src/stubs/notebook.cpp index 233bc5639b..312dd0f3d3 100644 --- a/src/stubs/notebook.cpp +++ b/src/stubs/notebook.cpp @@ -202,6 +202,16 @@ bool wxNotebook::DeletePage(int nPage) return TRUE; } +// remove one page from the notebook, without deleting the window +bool wxNotebook::RemovePage(int nPage) +{ + wxCHECK( IS_VALID_PAGE(nPage), FALSE ); + + m_aPages.Remove(nPage); + + return TRUE; +} + // remove all pages bool wxNotebook::DeleteAllPages() { -- 2.45.2