X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/50414e24a7aa082f2569666421d3ee1ea581a3cd..60435227b10297510316a88f67758fb6b6d93c10:/src/motif/frame.cpp diff --git a/src/motif/frame.cpp b/src/motif/frame.cpp index 516b5a6765..be67bd55c9 100644 --- a/src/motif/frame.cpp +++ b/src/motif/frame.cpp @@ -1,39 +1,52 @@ ///////////////////////////////////////////////////////////////////////////// -// Name: frame.cpp +// Name: src/motif/frame.cpp // Purpose: wxFrame // Author: Julian Smart // Modified by: // Created: 17/09/98 -// RCS-ID: $Id$ // Copyright: (c) Julian Smart // Licence: wxWindows licence ///////////////////////////////////////////////////////////////////////////// -#ifdef __GNUG__ -#pragma implementation "frame.h" -#endif +// ============================================================================ +// declarations +// ============================================================================ + +// ---------------------------------------------------------------------------- +// headers +// ---------------------------------------------------------------------------- + +// For compilers that support precompilation, includes "wx.h". +#include "wx/wxprec.h" #include "wx/frame.h" -#include "wx/statusbr.h" -#include "wx/toolbar.h" -#include "wx/menuitem.h" -#include "wx/menu.h" -#include "wx/dcclient.h" -#include "wx/dialog.h" -#include "wx/settings.h" -#include "wx/app.h" -#include "wx/utils.h" + +#ifndef WX_PRECOMP + #include "wx/log.h" + #include "wx/app.h" + #include "wx/utils.h" + #include "wx/menu.h" + #include "wx/icon.h" + #include "wx/settings.h" + #include "wx/toolbar.h" + #include "wx/statusbr.h" +#endif + +#ifdef __VMS__ + #pragma message disable nosimpint +#endif #if defined(__ultrix) || defined(__sgi) -#include + #include #endif #include #include +#include #if XmVersion >= 1002 -#include + #include #else -#include + #include #endif #include #include @@ -45,542 +58,420 @@ #include #include #if XmVersion > 1000 -#include + #include +#endif + +#ifdef __VMS__ + #pragma message enable nosimpint #endif #include "wx/motif/private.h" +#include "wx/unix/utilsx11.h" -void wxCloseFrameCallback(Widget, XtPointer, XmAnyCallbackStruct *cbs); -static void wxFrameFocusProc(Widget workArea, XtPointer clientData, - XmAnyCallbackStruct *cbs); -static void wxFrameMapProc(Widget frameShell, XtPointer clientData, - XCrossingEvent * event); +// ---------------------------------------------------------------------------- +// private functions +// ---------------------------------------------------------------------------- + +static void wxFrameMapProc(Widget frameShell, XtPointer clientData, + XCrossingEvent* event); + +// ---------------------------------------------------------------------------- +// globals +// ---------------------------------------------------------------------------- extern wxList wxModelessWindows; -extern wxList wxPendingDelete; - -// TODO: this should be tidied so that any frame can be the -// top frame -static bool wxTopLevelUsed = FALSE; - -#if !USE_SHARED_LIBRARY -BEGIN_EVENT_TABLE(wxFrame, wxWindow) - EVT_SIZE(wxFrame::OnSize) - EVT_ACTIVATE(wxFrame::OnActivate) - EVT_MENU_HIGHLIGHT_ALL(wxFrame::OnMenuHighlight) - EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged) - EVT_IDLE(wxFrame::OnIdle) - EVT_CLOSE(wxFrame::OnCloseWindow) + +// ---------------------------------------------------------------------------- +// wxWin macros +// ---------------------------------------------------------------------------- + +BEGIN_EVENT_TABLE(wxFrame, wxFrameBase) + EVT_ACTIVATE(wxFrame::OnActivate) + EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged) END_EVENT_TABLE() -IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow) -#endif +// ============================================================================ +// implementation +// ============================================================================ -#if USE_NATIVE_STATUSBAR -bool wxFrame::m_useNativeStatusBar = TRUE; -#else -bool wxFrame::m_useNativeStatusBar = FALSE; -#endif +// ---------------------------------------------------------------------------- +// frame construction +// ---------------------------------------------------------------------------- -wxFrame::wxFrame() +void wxFrame::Init() { - m_frameToolBar = NULL ; - m_frameMenuBar = NULL; - m_frameStatusBar = NULL; - - m_windowParent = NULL; - m_iconized = FALSE; + m_iconized = false; //// Motif-specific m_frameShell = (WXWidget) NULL; - m_frameWidget = (WXWidget) NULL;; - m_workArea = (WXWidget) NULL;; - m_clientArea = (WXWidget) NULL;; - m_visibleStatus = TRUE; - m_title = ""; + m_mainWidget = (WXWidget) NULL; + m_workArea = (WXWidget) NULL; + m_clientArea = (WXWidget) NULL; } bool wxFrame::Create(wxWindow *parent, - wxWindowID id, - const wxString& title, - const wxPoint& pos, - const wxSize& size, - long style, - const wxString& name) -{ - if (!parent) - wxTopLevelWindows.Append(this); - - SetName(name); - - m_windowStyle = style; - m_frameMenuBar = NULL; - m_frameToolBar = NULL ; - m_frameStatusBar = NULL; - - //// Motif-specific - m_frameShell = (WXWidget) NULL; - m_frameWidget = (WXWidget) NULL;; - m_workArea = (WXWidget) NULL;; - m_clientArea = (WXWidget) NULL;; - m_visibleStatus = TRUE; - m_title = ""; - - SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE)); - - if ( id > -1 ) - m_windowId = id; - else - m_windowId = (int)NewControlId(); - - if (parent) parent->AddChild(this); - - wxModelessWindows.Append(this); - - int x = pos.x; int y = pos.y; - int width = size.x; int height = size.y; - - if (wxTopLevelUsed) - // Change suggested by Matthew Flatt - m_frameShell = (WXWidget) XtAppCreateShell(name, wxTheApp->GetClassName(), topLevelShellWidgetClass, (Display*) wxGetDisplay(), NULL, 0); - else - { - m_frameShell = wxTheApp->GetTopLevelWidget(); - wxTopLevelUsed = TRUE; - } - - XtVaSetValues((Widget) m_frameShell, - // Allows menu to resize - XmNallowShellResize, True, - XmNdeleteResponse, XmDO_NOTHING, - XmNmappedWhenManaged, False, - XmNiconic, (style & wxICONIZE) ? TRUE : FALSE, - NULL); - - if (!title.IsNull()) - XtVaSetValues((Widget) m_frameShell, - XmNtitle, (const char*) title, - NULL); + wxWindowID id, + const wxString& title, + const wxPoint& pos, + const wxSize& size, + long style, + const wxString& name) +{ + if( !wxTopLevelWindow::Create( parent, id, title, pos, size, style, + name ) ) + return false; + + int x = pos.x, y = pos.y; + int width = size.x, height = size.y; + + // Set reasonable values for position and size if defaults have been + // requested + // + // MB TODO: something better than these arbitrary values ? + // VZ should use X resources for this... + if ( width == -1 ) + width = 400; + if ( height == -1 ) + height = 400; + + int displayW, displayH; + wxDisplaySize( &displayW, &displayH ); + + if ( x == -1 ) + { + x = (displayW - width) / 2; + if (x < 10) x = 10; + } + if ( y == -1 ) + { + y = (displayH - height) / 2; + if (y < 10) y = 10; + } - m_frameWidget = (WXWidget) XtVaCreateManagedWidget("main_window", - xmMainWindowWidgetClass, (Widget) m_frameShell, - 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); - - /* Part of show-&-hide fix */ - XtAddEventHandler((Widget) m_frameShell, StructureNotifyMask, - False, (XtEventHandler)wxFrameMapProc, - (XtPointer)m_workArea); - - if (x > -1) - XtVaSetValues((Widget) m_frameShell, XmNx, x, NULL); - if (y > -1) - XtVaSetValues((Widget) m_frameShell, XmNy, y, NULL); - if (width > -1) - XtVaSetValues((Widget) m_frameShell, XmNwidth, width, NULL); - if (height > -1) - XtVaSetValues((Widget) m_frameShell, XmNheight, height, NULL); - - m_mainWidget = m_frameWidget; - - // This patch comes from Torsten Liermann lier@lier1.muc.de - if (XmIsMotifWMRunning( (Widget) wxTheApp->GetTopLevelWidget())) - { - int decor = 0 ; - if (style & wxRESIZE_BORDER) - decor |= MWM_DECOR_RESIZEH ; - if (style & wxSYSTEM_MENU) - decor |= MWM_DECOR_MENU; - if ((style & wxCAPTION) || - (style & wxTINY_CAPTION_HORIZ) || - (style & wxTINY_CAPTION_VERT)) - decor |= MWM_DECOR_TITLE; - if (style & wxTHICK_FRAME) - decor |= MWM_DECOR_BORDER; - if (style & wxTHICK_FRAME) - decor |= MWM_DECOR_BORDER; - if (style & wxMINIMIZE_BOX) - decor |= MWM_DECOR_MINIMIZE; - if (style & wxMAXIMIZE_BOX) - decor |= MWM_DECOR_MAXIMIZE; - XtVaSetValues((Widget) m_frameShell,XmNmwmDecorations,decor,NULL) ; - } - // This allows non-Motif window managers to support at least the - // no-decorations case. - else - { - if (style == 0) - XtVaSetValues((Widget) m_frameShell,XmNoverrideRedirect,TRUE,NULL); - } - XtRealizeWidget((Widget) m_frameShell); - - // Intercept CLOSE messages from the window manager - Atom WM_DELETE_WINDOW = XmInternAtom(XtDisplay((Widget) m_frameShell), "WM_DELETE_WINDOW", False); -#if (XmREVISION > 1 || XmVERSION > 1) - XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (XtCallbackProc) wxCloseFrameCallback, (XtPointer)this); -#else -#if XmREVISION == 1 - XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (XtCallbackProc) wxCloseFrameCallback, (caddr_t)this); -#else - XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (void (*)())wxCloseFrameCallback, (caddr_t)this); -#endif -#endif + SetTitle( title ); + + wxLogTrace(wxTRACE_Messages, + "Created frame (0x%p) with work area 0x%p and client " + "area 0x%p", m_mainWidget, m_workArea, m_clientArea); + + XtAddEventHandler((Widget) m_clientArea, ExposureMask,False, + wxUniversalRepaintProc, (XtPointer) this); - PreResize(); + if (x > -1) + XtVaSetValues((Widget) m_frameShell, XmNx, x, NULL); + if (y > -1) + XtVaSetValues((Widget) m_frameShell, XmNy, y, NULL); + if (width > -1) + XtVaSetValues((Widget) m_frameShell, XmNwidth, width, NULL); + if (height > -1) + XtVaSetValues((Widget) m_frameShell, XmNheight, height, NULL); - wxSizeEvent sizeEvent(wxSize(width, height), GetId()); - sizeEvent.SetEventObject(this); + PostCreation(); + PreResize(); + + wxSize newSize(width, height); + wxSizeEvent sizeEvent(newSize, GetId()); + sizeEvent.SetEventObject(this); - GetEventHandler()->ProcessEvent(sizeEvent); + HandleWindowEvent(sizeEvent); - return TRUE; + return true; } -wxFrame::~wxFrame() +bool wxFrame::XmDoCreateTLW(wxWindow* WXUNUSED(parent), + wxWindowID WXUNUSED(id), + const wxString& WXUNUSED(title), + const wxPoint& WXUNUSED(pos), + const wxSize& WXUNUSED(size), + long style, + const wxString& name) { - if (GetMainWidget()) - Show(FALSE); - - if (m_frameMenuBar) - { -// Hack to stop core dump on Ultrix, OSF, for some strange reason. -#if MOTIF_MENUBAR_DELETE_FIX - GetMenuBar()->SetMainWidget((WXWidget) NULL); -#endif - delete m_frameMenuBar; - m_frameMenuBar = NULL; - } - - wxTopLevelWindows.DeleteObject(this); - wxModelessWindows.DeleteObject(this); + Widget frameShell; - if (m_frameStatusBar) - delete m_frameStatusBar; + frameShell = XtCreatePopupShell( name, topLevelShellWidgetClass, + (Widget)wxTheApp->GetTopLevelWidget(), + NULL, 0 ); - DestroyChildren(); + XtVaSetValues(frameShell, + // Allows menu to resize + XmNallowShellResize, True, + XmNdeleteResponse, XmDO_NOTHING, + XmNmappedWhenManaged, False, + XmNiconic, (style & wxICONIZE) ? True : False, + NULL); -/* - int i; - for (i = 0; i < wxMAX_STATUS; i++) - if (statusTextWidget[i]) - XtDestroyWidget (statusTextWidget[i]); + m_frameShell = (WXWidget)frameShell; - if (statusLineForm) - XtDestroyWidget (statusLineForm); + m_mainWidget = (WXWidget) XtVaCreateManagedWidget("main_window", + xmMainWindowWidgetClass, frameShell, + XmNresizePolicy, XmRESIZE_NONE, + NULL); - if (statusLineWidget) - XtDestroyWidget (statusLineWidget); - */ + m_workArea = (WXWidget) XtVaCreateWidget("form", + xmFormWidgetClass, (Widget) m_mainWidget, + XmNresizePolicy, XmRESIZE_NONE, + NULL); - wxDeleteWindowFromTable((Widget) m_workArea); + 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, + NULL); - XtDestroyWidget ((Widget) m_workArea); - XtDestroyWidget ((Widget) m_frameWidget); + XtVaSetValues((Widget) m_mainWidget, + XmNworkWindow, (Widget) m_workArea, + NULL); - wxDeleteWindowFromTable((Widget) m_frameWidget); + XtManageChild((Widget) m_clientArea); + XtManageChild((Widget) m_workArea); - XtDestroyWidget ((Widget) m_frameShell); + XtTranslations ptr = XtParseTranslationTable( ": resize()" ); + XtOverrideTranslations( (Widget) m_workArea, ptr ); + XtFree( (char *)ptr ); - SetMainWidget((WXWidget) NULL); + /* Part of show-&-hide fix */ + XtAddEventHandler( frameShell, StructureNotifyMask, + False, (XtEventHandler)wxFrameMapProc, + (XtPointer)this ); -/* Check if it's the last top-level window */ + XtRealizeWidget(frameShell); - if (wxTheApp && (wxTopLevelWindows.Number() == 0)) - { - wxTheApp->SetTopWindow(NULL); + wxAddWindowToTable( (Widget)m_workArea, this); + wxAddWindowToTable( (Widget)m_clientArea, this); - if (wxTheApp->GetExitOnFrameDelete()) - { - // TODO signal to the app that we're going to close - wxTheApp->ExitMainLoop(); - } - } + wxModelessWindows.Append( this ); + return true; } -// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc. -void wxFrame::GetClientSize(int *x, int *y) const +wxFrame::~wxFrame() { - Dimension xx, yy; - XtVaGetValues((Widget) m_workArea, XmNwidth, &xx, XmNheight, &yy, NULL); - - /* TODO - if (status_line_exists) - { - Dimension ys; - XtVaGetValues(statusLineWidget, XmNheight, &ys, NULL); - yy -= ys; - } - */ - - if (GetMenuBar() != (wxMenuBar*) NULL) - { - // it seems that if a frame holds a panel, the menu bar size - // gets automatically taken care of --- grano@cs.helsinki.fi 4.4.95 - bool hasSubPanel = FALSE; - for(wxNode* node = GetChildren()->First(); node; node = node->Next()) - { - wxWindow *win = (wxWindow *)node->Data(); - hasSubPanel = (win->IsKindOf(CLASSINFO(wxPanel)) && !win->IsKindOf(CLASSINFO(wxDialog))); + SendDestroyEvent(); - if (hasSubPanel) - break; + if (m_clientArea) + { + XtRemoveEventHandler((Widget) m_clientArea, ExposureMask, False, + wxUniversalRepaintProc, (XtPointer) this); } - if (! hasSubPanel) { - Dimension ys; - XtVaGetValues((Widget) GetMenuBarWidget(), XmNheight, &ys, NULL); - yy -= ys; + + if (GetMainWidget()) + Show(false); + + if (m_frameMenuBar) + { + m_frameMenuBar->DestroyMenuBar(); + wxDELETE(m_frameMenuBar); } - } - *x = xx; *y = yy; -} + wxDELETE(m_frameStatusBar); -// Set the client size (i.e. leave the calculation of borders etc. -// to wxWindows) -void wxFrame::SetClientSize(int width, int height) -{ - // Calculate how large the new main window should be - // by finding the difference between the client area and the - // main window area, and adding on to the new client area - if (width > -1) - XtVaSetValues((Widget) m_workArea, XmNwidth, width, NULL); - - if (height > -1) - { - /* TODO - if (status_line_exists) + PreDestroy(); + + Widget frameShell = (Widget)GetShellWidget(); + + if( frameShell ) + XtRemoveEventHandler( frameShell, StructureNotifyMask, + False, (XtEventHandler)wxFrameMapProc, + (XtPointer)this ); + + if( m_clientArea ) { - Dimension ys; - XtVaGetValues(statusLineWidget, XmNheight, &ys, NULL); - height += ys; + wxDeleteWindowFromTable( (Widget)m_clientArea ); + XtDestroyWidget( (Widget)m_clientArea ); } - */ - XtVaSetValues((Widget) m_workArea, XmNheight, height, NULL); - } - PreResize(); - wxSizeEvent sizeEvent(wxSize(width, height), GetId()); - sizeEvent.SetEventObject(this); + if( m_workArea ) + { + XtVaSetValues( (Widget)m_mainWidget, + XmNworkWindow, (Widget)NULL, + NULL ); - GetEventHandler()->ProcessEvent(sizeEvent); + wxDeleteWindowFromTable( (Widget)m_workArea ); + XtDestroyWidget( (Widget)m_workArea ); + } -} + if( m_mainWidget ) + XtDestroyWidget( (Widget)m_mainWidget ); -void wxFrame::GetSize(int *width, int *height) const -{ - Dimension xx, yy; - XtVaGetValues((Widget) m_frameShell, XmNwidth, &xx, XmNheight, &yy, NULL); - *width = xx; *height = yy; + if( frameShell ) + XtDestroyWidget( frameShell ); } -void wxFrame::GetPosition(int *x, int *y) const +// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc. +void wxFrame::DoGetClientSize(int *x, int *y) const { - Window parent_window = XtWindow((Widget) m_frameShell), - next_parent = XtWindow((Widget) m_frameShell), - root = RootWindowOfScreen(XtScreen((Widget) m_frameShell)); - - // search for the parent that is child of ROOT, because the WM may - // reparent twice and notify only the next parent (like FVWM) - while (next_parent != root) { - Window *theChildren; unsigned int n; - parent_window = next_parent; - XQueryTree(XtDisplay((Widget) m_frameShell), parent_window, &root, - &next_parent, &theChildren, &n); - XFree(theChildren); // not needed + Dimension xx, yy; + XtVaGetValues((Widget) m_workArea, XmNwidth, &xx, XmNheight, &yy, NULL); + + if (m_frameStatusBar) + { + int sbw, sbh; + m_frameStatusBar->GetSize(& sbw, & sbh); + yy = (Dimension)(yy - sbh); } - int xx, yy; unsigned int dummy; - XGetGeometry(XtDisplay((Widget) m_frameShell), parent_window, &root, - &xx, &yy, &dummy, &dummy, &dummy, &dummy); - if (x) *x = xx; - if (y) *y = yy; +#if wxUSE_TOOLBAR + if (m_frameToolBar) + { + int tbw, tbh; + m_frameToolBar->GetSize(& tbw, & tbh); + if (m_frameToolBar->GetWindowStyleFlag() & wxTB_VERTICAL) + xx = (Dimension)(xx - tbw); + else + yy = (Dimension)(yy - tbh); + } +#endif // wxUSE_TOOLBAR + +//CE found a call here with NULL y pointer + if (x) + *x = xx; + if (y) + *y = yy; } -void wxFrame::SetSize(int x, int y, int width, int height, int sizeFlags) +// Set the client size (i.e. leave the calculation of borders etc. +// to wxWidgets) +void wxFrame::DoSetClientSize(int width, int height) { - if (x > -1) - XtVaSetValues((Widget) m_frameShell, XmNx, x, NULL); - if (y > -1) - XtVaSetValues((Widget) m_frameShell, XmNy, y, NULL); - if (width > -1) - XtVaSetValues((Widget) m_frameWidget, XmNwidth, width, NULL); - if (height > -1) - XtVaSetValues((Widget) m_frameWidget, XmNheight, height, NULL); - - if (!(height == -1 && width == -1)) - { + // Calculate how large the new main window should be + // by finding the difference between the client area and the + // main window area, and adding on to the new client area + if (width > -1) + XtVaSetValues((Widget) m_workArea, XmNwidth, width, NULL); + + if (height > -1) + { + if (m_frameStatusBar) + { + int sbw, sbh; + m_frameStatusBar->GetSize(& sbw, & sbh); + height += sbh; + } +#if wxUSE_TOOLBAR + if (m_frameToolBar) + { + int tbw, tbh; + m_frameToolBar->GetSize(& tbw, & tbh); + if (m_frameToolBar->GetWindowStyleFlag() & wxTB_VERTICAL) + width += tbw; + else + height += tbh; + } +#endif // wxUSE_TOOLBAR + + XtVaSetValues((Widget) m_workArea, XmNheight, height, NULL); + } PreResize(); - wxSizeEvent sizeEvent(wxSize(width, height), GetId()); + + wxSize newSize(width, height); + wxSizeEvent sizeEvent(newSize, GetId()); sizeEvent.SetEventObject(this); - GetEventHandler()->ProcessEvent(sizeEvent); - } -} + HandleWindowEvent(sizeEvent); -bool wxFrame::Show(bool show) -{ - m_visibleStatus = show; /* show-&-hide fix */ - - m_isShown = show; - if (show) { - XtMapWidget((Widget) m_frameShell); - XRaiseWindow(XtDisplay((Widget) m_frameShell), XtWindow((Widget) m_frameShell)); - } else { - XtUnmapWidget((Widget) m_frameShell); -// XmUpdateDisplay(wxTheApp->topLevel); // Experimental: may be responsible for crashes - } - return TRUE; } -void wxFrame::Iconize(bool iconize) +void wxFrame::DoGetSize(int *width, int *height) const { - if (!iconize) - Show(TRUE); + if (!m_frameShell) + { + *width = -1; *height = -1; + return; + } - XtVaSetValues((Widget) m_frameShell, XmNiconic, (Boolean)iconize, NULL); + Dimension xx, yy; + XtVaGetValues((Widget) m_frameShell, XmNwidth, &xx, XmNheight, &yy, NULL); + *width = xx; *height = yy; } -// Equivalent to maximize/restore in Windows -void wxFrame::Maximize(bool maximize) +void wxFrame::DoSetSize(int x, int y, int width, int height, int WXUNUSED(sizeFlags)) { - Show(TRUE); + if (x > -1) + XtVaSetValues((Widget) m_frameShell, XmNx, x, NULL); + if (y > -1) + XtVaSetValues((Widget) m_frameShell, XmNy, y, NULL); + if (width > -1) + XtVaSetValues((Widget) m_mainWidget, XmNwidth, width, NULL); + if (height > -1) + XtVaSetValues((Widget) m_mainWidget, XmNheight, height, NULL); - if (maximize) - XtVaSetValues((Widget) m_frameShell, XmNiconic, FALSE, NULL); + if (!(height == -1 && width == -1)) + { + PreResize(); + } } -bool wxFrame::IsIconized() const +bool wxFrame::Show( bool show ) { - Boolean iconic; - XtVaGetValues((Widget) m_frameShell, XmNiconic, &iconic, NULL); - return iconic; -} + if( !wxWindowBase::Show( show ) ) + return false; -void wxFrame::SetTitle(const wxString& title) -{ - if (title == m_title) - return; - - m_title = title; - - if (!title.IsNull()) - XtVaSetValues((Widget) m_frameShell, - XmNtitle, (const char*) title, - XmNiconName, (const char*) title, - NULL); -} + m_isShown = show; -void wxFrame::SetIcon(const wxIcon& icon) -{ - m_icon = icon; + Widget shell = (Widget)GetShellWidget(); + if (!shell) + return wxWindow::Show(show); - // TODO - /* - if (!icon.Ok() || !icon.GetPixmap()) - return; + SetVisibleStatus(show); + if (show) + { + XtPopup(shell, XtGrabNone); + } + else + { + XtPopdown(shell); + } - XtVaSetValues((Widget) m_frameShell, XtNiconPixmap, icon->.GetPixmap(), NULL); - */ + return true; } -wxStatusBar *wxFrame::OnCreateStatusBar(int number, long style, wxWindowID id, - const wxString& name) +void wxFrame::SetTitle(const wxString& title) { - wxStatusBar *statusBar = NULL; - - statusBar = new wxStatusBar(this, id, wxPoint(0, 0), wxSize(100, 20), - style, name); - - // Set the height according to the font and the border size - wxClientDC dc(statusBar); - dc.SetFont(* statusBar->GetFont()); - - long x, y; - dc.GetTextExtent("X", &x, &y); - - int height = (int)( (y * 1.1) + 2* statusBar->GetBorderY()); + wxString oldTitle = GetTitle(); + if( title == oldTitle ) + return; - statusBar->SetSize(-1, -1, 100, height); + wxTopLevelWindow::SetTitle( title ); - statusBar->SetFieldsCount(number); - return statusBar; + if( !title.empty() ) + XtVaSetValues( (Widget)m_frameShell, + XmNtitle, (const char*)title.mb_str(), + XmNiconName, (const char*)title.mb_str(), + NULL ); } -wxStatusBar* wxFrame::CreateStatusBar(int number, long style, wxWindowID id, - const wxString& name) +void wxFrame::DoSetIcon(const wxIcon& icon) { - // Calling CreateStatusBar twice is an error. - wxCHECK_MSG( m_frameStatusBar == NULL, FALSE, - "recreating status bar in wxFrame" ); - - m_frameStatusBar = OnCreateStatusBar(number, style, id, - name); - if ( m_frameStatusBar ) - { - PositionStatusBar(); - return m_frameStatusBar; - } - else - return NULL; -} + if (!m_frameShell) + return; -void wxFrame::SetStatusText(const wxString& text, int number) -{ - wxCHECK_RET( m_frameStatusBar != NULL, "no statusbar to set text for" ); + if (!icon.IsOk() || !icon.GetDrawable()) + return; - m_frameStatusBar->SetStatusText(text, number); + XtVaSetValues((Widget) m_frameShell, + XtNiconPixmap, icon.GetDrawable(), + NULL); } -void wxFrame::SetStatusWidths(int n, const int widths_field[]) +void wxFrame::SetIcons(const wxIconBundle& icons) { - wxCHECK_RET( m_frameStatusBar != NULL, "no statusbar to set widths for" ); + wxFrameBase::SetIcons( icons ); + + if (!m_frameShell) + return; - m_frameStatusBar->SetStatusWidths(n, widths_field); - PositionStatusBar(); + DoSetIcon( m_icons.GetIcon( -1 ) ); + wxSetIconsX11(GetXDisplay(), + (WXWindow) XtWindow( (Widget) m_frameShell ), icons); } void wxFrame::PositionStatusBar() { if (!m_frameStatusBar) - return; + return; int w, h; GetClientSize(&w, &h); @@ -589,15 +480,15 @@ void wxFrame::PositionStatusBar() // Since we wish the status bar to be directly under the client area, // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS. - m_frameStatusBar->SetSize(0-sh, h, w, sh); + m_frameStatusBar->SetSize(0, h, w, sh); } WXWidget wxFrame::GetMenuBarWidget() const { - if (GetMenuBar()) - return GetMenuBar()->GetMainWidget(); - else - return (WXWidget) NULL; + if (GetMenuBar()) + return GetMenuBar()->GetMainWidget(); + else + return (WXWidget) NULL; } void wxFrame::SetMenuBar(wxMenuBar *menuBar) @@ -609,428 +500,159 @@ 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; - - Widget menuBarW = XmCreateMenuBar ((Widget) m_frameWidget, "MenuBar", NULL, 0); - m_frameMenuBar->SetMainWidget( (WXWidget) menuBarW); + // wxASSERT_MSG( (m_frameMenuBar == NULL), "Cannot set the menubar more than once"); - 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); -} - -void wxFrame::Fit() -{ - // Work out max. size - wxNode *node = GetChildren()->First(); - int max_width = 0; - int max_height = 0; - while (node) - { - // Find a child that's a subwindow, but not a dialog box. - wxWindow *win = (wxWindow *)node->Data(); - - if (!win->IsKindOf(CLASSINFO(wxFrame)) && - !win->IsKindOf(CLASSINFO(wxDialog))) - { - int width, height; - int x, y; - win->GetSize(&width, &height); - win->GetPosition(&x, &y); - - if ((x + width) > max_width) - max_width = x + width; - if ((y + height) > max_height) - max_height = y + height; - } - node = node->Next(); - } - SetClientSize(max_width, max_height); + m_frameMenuBar = menuBar; + m_frameMenuBar->CreateMenuBar(this); } // Responds to colour changes, and passes event on to children. void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event) { - SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE)); + SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE)); Refresh(); if ( m_frameStatusBar ) { wxSysColourChangedEvent event2; event2.SetEventObject( m_frameStatusBar ); - m_frameStatusBar->ProcessEvent(event2); + m_frameStatusBar->HandleWindowEvent(event2); } // Propagate the event to the non-top-level children wxWindow::OnSysColourChanged(event); } -// Default resizing behaviour - if only ONE subwindow, -// resize to client rectangle size -void wxFrame::OnSize(wxSizeEvent& event) -{ - // if we're using constraints - do use them - #if USE_CONSTRAINTS - if ( GetAutoLayout() ) { - Layout(); - return; - } - #endif - - // do we have _exactly_ one child? - wxWindow *child = NULL; - for ( wxNode *node = GetChildren()->First(); node; node = node->Next() ) - { - wxWindow *win = (wxWindow *)node->Data(); - if ( !win->IsKindOf(CLASSINFO(wxFrame)) && - !win->IsKindOf(CLASSINFO(wxDialog)) && - (win != GetStatusBar()) && - (win != GetToolBar()) ) - { - if ( child ) - return; // it's our second subwindow - nothing to do - child = win; - } - } - - if ( child ) { - // we have exactly one child - set it's size to fill the whole frame - int clientW, clientH; - GetClientSize(&clientW, &clientH); - - int x = 0; - int y = 0; - - child->SetSize(x, y, clientW, clientH); - } -} - // Default activation behaviour - set the focus for the first child // subwindow found. void wxFrame::OnActivate(wxActivateEvent& event) { - for(wxNode *node = GetChildren()->First(); node; node = node->Next()) - { - // Find a child that's a subwindow, but not a dialog box. - wxWindow *child = (wxWindow *)node->Data(); - if (!child->IsKindOf(CLASSINFO(wxFrame)) && - !child->IsKindOf(CLASSINFO(wxDialog))) - { -#if WXDEBUG > 1 - wxDebugMsg("wxFrame::OnActivate: about to set the child's focus.\n"); -#endif - child->SetFocus(); - return; - } - } -} - -// The default implementation for the close window event - calls -// OnClose for backward compatibility. - -void wxFrame::OnCloseWindow(wxCloseEvent& event) -{ - // Compatibility - if ( GetEventHandler()->OnClose() || event.GetForce()) - { - this->Destroy(); - } -} - -bool wxFrame::OnClose() -{ - return TRUE; -} - -// Destroy the window (delayed, if a managed window) -bool wxFrame::Destroy() -{ - if (!wxPendingDelete.Member(this)) - wxPendingDelete.Append(this); - return TRUE; -} - -// Default menu selection behaviour - display a help string -void wxFrame::OnMenuHighlight(wxMenuEvent& event) -{ - if (GetStatusBar()) - { - if (event.GetMenuId() == -1) - SetStatusText(""); - else - { - wxMenuBar *menuBar = GetMenuBar(); - if (menuBar) - { - wxString helpString(menuBar->GetHelpString(event.GetMenuId())); - if (helpString != "") - SetStatusText(helpString); - } - } - } -} - -wxMenuBar *wxFrame::GetMenuBar() const -{ - return m_frameMenuBar; -} - -void wxFrame::Centre(int direction) -{ - int display_width, display_height, width, height, x, y; - wxDisplaySize(&display_width, &display_height); - - GetSize(&width, &height); - GetPosition(&x, &y); - - if (direction & wxHORIZONTAL) - x = (int)((display_width - width)/2); - if (direction & wxVERTICAL) - y = (int)((display_height - height)/2); - - SetSize(x, y, width, height); -} - -// Call this to simulate a menu command -void wxFrame::Command(int id) -{ - ProcessCommand(id); -} - -void wxFrame::ProcessCommand(int id) -{ - wxCommandEvent commandEvent(wxEVENT_TYPE_MENU_COMMAND, id); - commandEvent.SetInt( id ); - commandEvent.SetEventObject( this ); - - wxMenuBar *bar = GetMenuBar() ; - if (!bar) - return; - -/* TODO: check the menu item if required - wxMenuItem *item = bar->FindItemForId(id) ; - if (item && item->IsCheckable()) - { - bar->Check(id,!bar->Checked(id)) ; - } -*/ - - GetEventHandler()->ProcessEvent(commandEvent); -} + if (!event.GetActive()) + return; -// Checks if there is a toolbar, and returns the first free client position -wxPoint wxFrame::GetClientAreaOrigin() const -{ - wxPoint pt(0, 0); - if (GetToolBar()) + for(wxWindowList::compatibility_iterator node = GetChildren().GetFirst(); node; + node = node->GetNext()) { - int w, h; - GetToolBar()->GetSize(& w, & h); - - if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL) - { - pt.x += w; - } - else + // Find a child that's a subwindow, but not a dialog box. + wxWindow *child = node->GetData(); + if (!child->IsTopLevel()) { - pt.y += h; + child->SetFocus(); + return; } } - return pt; } -wxToolBar* wxFrame::CreateToolBar(long style, wxWindowID id, const wxString& name) -{ - wxCHECK_MSG( m_frameToolBar == NULL, FALSE, - "recreating toolbar in wxFrame" ); +#if wxUSE_TOOLBAR - wxToolBar* toolBar = OnCreateToolBar(style, id, name); - if (toolBar) +wxToolBar* wxFrame::CreateToolBar(long style, + wxWindowID id, + const wxString& name) +{ + if ( wxFrameBase::CreateToolBar(style, id, name) ) { - SetToolBar(toolBar); PositionToolBar(); - return toolBar; - } - else - { - return NULL; } + + return m_frameToolBar; } -wxToolBar* wxFrame::OnCreateToolBar(long style, wxWindowID id, const wxString& name) +void wxFrame::SetToolBar(wxToolBar *toolbar) { - return new wxToolBar(this, id, wxDefaultPosition, wxDefaultSize, style, name); + wxFrameBase::SetToolBar(toolbar); + SendSizeEvent(); } void wxFrame::PositionToolBar() { - int cw, ch; - - // TODO: we actually need to use the low-level client size, before - // the toolbar/status bar were added. - // So DEFINITELY replace the line below with something appropriate. - - GetClientSize(& cw, &ch); - - if ( GetStatusBar() ) + wxToolBar* tb = GetToolBar(); + if (tb) { - int statusX, statusY; - GetStatusBar()->GetClientSize(&statusX, &statusY); - ch -= statusY; - } + int cw, ch; + GetClientSize(& cw, &ch); - if (GetToolBar()) - { int tw, th; - GetToolBar()->GetSize(& tw, & th); + tb->GetSize(& tw, & th); - if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL) + if (tb->GetWindowStyleFlag() & wxTB_VERTICAL) { // Use the 'real' position. wxSIZE_NO_ADJUSTMENTS // means, pretend we don't have toolbar/status bar, so we // have the original client size. - GetToolBar()->SetSize(0, 0, tw, ch, wxSIZE_NO_ADJUSTMENTS); + th = ch + th; } else { // Use the 'real' position - GetToolBar()->SetSize(0, 0, cw, th, wxSIZE_NO_ADJUSTMENTS); + tw = cw; } + + tb->SetSize(0, 0, -1, -1, wxSIZE_NO_ADJUSTMENTS); } } +#endif // wxUSE_TOOLBAR -void wxFrame::CaptureMouse() +//// Motif-specific +bool wxFrame::PreResize() { - if (m_winCaptured) - return; - - if (GetMainWidget()) - XtAddGrab((Widget) m_frameShell, TRUE, FALSE); - m_winCaptured = TRUE; +#if wxUSE_TOOLBAR + PositionToolBar(); +#endif // wxUSE_TOOLBAR + +#if wxUSE_STATUSBAR + PositionStatusBar(); +#endif // wxUSE_STATUSBAR + + return true; } -void wxFrame::ReleaseMouse() +WXWidget wxFrame::GetClientWidget() const { - if (!m_winCaptured) - return; - - if (GetMainWidget()) - XtRemoveGrab((Widget) m_frameShell); - m_winCaptured = FALSE; + return m_clientArea; } -void wxFrame::Raise(void) +void wxFrame::ChangeFont(bool WXUNUSED(keepOriginalSize)) { - Window parent_window = XtWindow((Widget) m_frameShell), - next_parent = XtWindow((Widget) m_frameShell), - root = RootWindowOfScreen(XtScreen((Widget) m_frameShell)); - // search for the parent that is child of ROOT, because the WM may - // reparent twice and notify only the next parent (like FVWM) - while (next_parent != root) { - Window *theChildren; unsigned int n; - parent_window = next_parent; - XQueryTree(XtDisplay((Widget) m_frameShell), parent_window, &root, - &next_parent, &theChildren, &n); - XFree(theChildren); // not needed - } - XRaiseWindow(XtDisplay((Widget) m_frameShell), parent_window); + // TODO } -void wxFrame::Lower(void) +void wxFrame::ChangeBackgroundColour() { - Window parent_window = XtWindow((Widget) m_frameShell), - next_parent = XtWindow((Widget) m_frameShell), - root = RootWindowOfScreen(XtScreen((Widget) m_frameShell)); - // search for the parent that is child of ROOT, because the WM may - // reparent twice and notify only the next parent (like FVWM) - while (next_parent != root) { - Window *theChildren; unsigned int n; - parent_window = next_parent; - XQueryTree(XtDisplay((Widget) m_frameShell), parent_window, &root, - &next_parent, &theChildren, &n); - XFree(theChildren); // not needed - } - XLowerWindow(XtDisplay((Widget) m_frameShell), parent_window); + if (GetClientWidget()) + wxDoChangeBackgroundColour(GetClientWidget(), m_backgroundColour); } -void wxFrame::SetToolBar(wxToolBar *toolbar) -{ m_frameToolBar = toolbar; } - -wxToolBar *wxFrame::GetToolBar() const -{ return m_frameToolBar; } - -static void wxFrameFocusProc(Widget workArea, XtPointer clientData, - XmAnyCallbackStruct *cbs) +void wxFrame::ChangeForegroundColour() { - wxFrame *frame = (wxFrame *)clientData; - - // wxDebugMsg("focus proc from frame %ld\n",(long)frame); - // TODO - // frame->GetEventHandler()->OnSetFocus(); + if (GetClientWidget()) + wxDoChangeForegroundColour(GetClientWidget(), m_foregroundColour); } /* MATTEW: Used to insure that hide-&-show within an event cycle works */ -static void wxFrameMapProc(Widget frameShell, XtPointer clientData, - XCrossingEvent * event) +static void wxFrameMapProc( Widget frameShell, XtPointer clientData, + XCrossingEvent* event ) { - wxFrame *frame = (wxFrame *)wxWidgetHashTable->Get((long)clientData); + wxFrame *tli = (wxFrame*)clientData; - if (frame) { XEvent *e = (XEvent *)event; - if (e->xany.type == MapNotify) + if( e->xany.type == MapNotify ) { - // Iconize fix - XtVaSetValues(frameShell, XmNiconic, (Boolean)False, NULL); - if (!frame->GetVisibleStatus()) - { - /* We really wanted this to be hidden! */ - XtUnmapWidget((Widget) frame->GetShellWidget()); - } + // Iconize fix + XtVaSetValues( frameShell, XmNiconic, (Boolean)False, NULL ); + if( !tli->GetVisibleStatus() ) + { + /* We really wanted this to be hidden! */ + XtUnmapWidget( frameShell ); + } } - else if (e->xany.type == UnmapNotify) - // Iconize fix - XtVaSetValues(frameShell, XmNiconic, (Boolean)True, NULL); - } -} - -//// Motif-specific -bool wxFrame::PreResize() -{ - PositionStatusBar(); - return TRUE; -} - -WXWidget wxFrame::GetClientWidget() const -{ - return m_clientArea; -} - -void wxCloseFrameCallback(Widget widget, XtPointer client_data, XmAnyCallbackStruct *cbs) -{ - wxFrame *frame = (wxFrame *)client_data; - - wxCloseEvent closeEvent(wxEVT_CLOSE_WINDOW, frame->GetId()); - closeEvent.SetEventObject(frame); - - // May delete the frame (with delayed deletion) - frame->GetEventHandler()->ProcessEvent(closeEvent); + else if( e->xany.type == UnmapNotify ) + // Iconize fix + XtVaSetValues( frameShell, XmNiconic, (Boolean)True, NULL ); }