1 /////////////////////////////////////////////////////////////////////////////
2 // Name: src/motif/frame.cpp
4 // Author: Julian Smart
7 // Copyright: (c) Julian Smart
8 // Licence: wxWindows licence
9 /////////////////////////////////////////////////////////////////////////////
11 // ============================================================================
13 // ============================================================================
15 // ----------------------------------------------------------------------------
17 // ----------------------------------------------------------------------------
19 // For compilers that support precompilation, includes "wx.h".
20 #include "wx/wxprec.h"
30 #include "wx/settings.h"
31 #include "wx/toolbar.h"
32 #include "wx/statusbr.h"
36 #pragma message disable nosimpint
39 #if defined(__ultrix) || defined(__sgi)
44 #include <X11/Shell.h>
51 #include <Xm/MwmUtil.h>
52 #include <Xm/BulletinB.h>
55 #include <Xm/RowColumn.h>
57 #include <Xm/AtomMgr.h>
58 #include <Xm/LabelG.h>
61 #include <Xm/Protocols.h>
65 #pragma message enable nosimpint
68 #include "wx/motif/private.h"
69 #include "wx/unix/utilsx11.h"
71 // ----------------------------------------------------------------------------
73 // ----------------------------------------------------------------------------
75 static void wxFrameMapProc(Widget frameShell
, XtPointer clientData
,
76 XCrossingEvent
* event
);
78 // ----------------------------------------------------------------------------
80 // ----------------------------------------------------------------------------
82 extern wxList wxModelessWindows
;
84 // ----------------------------------------------------------------------------
86 // ----------------------------------------------------------------------------
88 BEGIN_EVENT_TABLE(wxFrame
, wxFrameBase
)
89 EVT_ACTIVATE(wxFrame::OnActivate
)
90 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged
)
93 // ============================================================================
95 // ============================================================================
97 // ----------------------------------------------------------------------------
99 // ----------------------------------------------------------------------------
106 m_frameShell
= (WXWidget
) NULL
;
107 m_mainWidget
= (WXWidget
) NULL
;
108 m_workArea
= (WXWidget
) NULL
;
109 m_clientArea
= (WXWidget
) NULL
;
112 bool wxFrame::Create(wxWindow
*parent
,
114 const wxString
& title
,
118 const wxString
& name
)
120 if( !wxTopLevelWindow::Create( parent
, id
, title
, pos
, size
, style
,
124 int x
= pos
.x
, y
= pos
.y
;
125 int width
= size
.x
, height
= size
.y
;
127 // Set reasonable values for position and size if defaults have been
130 // MB TODO: something better than these arbitrary values ?
131 // VZ should use X resources for this...
137 int displayW
, displayH
;
138 wxDisplaySize( &displayW
, &displayH
);
142 x
= (displayW
- width
) / 2;
147 y
= (displayH
- height
) / 2;
153 wxLogTrace(wxTRACE_Messages
,
154 "Created frame (0x%p) with work area 0x%p and client "
155 "area 0x%p", m_mainWidget
, m_workArea
, m_clientArea
);
157 XtAddEventHandler((Widget
) m_clientArea
, ExposureMask
,False
,
158 wxUniversalRepaintProc
, (XtPointer
) this);
161 XtVaSetValues((Widget
) m_frameShell
, XmNx
, x
, NULL
);
163 XtVaSetValues((Widget
) m_frameShell
, XmNy
, y
, NULL
);
165 XtVaSetValues((Widget
) m_frameShell
, XmNwidth
, width
, NULL
);
167 XtVaSetValues((Widget
) m_frameShell
, XmNheight
, height
, NULL
);
172 wxSize
newSize(width
, height
);
173 wxSizeEvent
sizeEvent(newSize
, GetId());
174 sizeEvent
.SetEventObject(this);
176 HandleWindowEvent(sizeEvent
);
181 bool wxFrame::XmDoCreateTLW(wxWindow
* WXUNUSED(parent
),
182 wxWindowID
WXUNUSED(id
),
183 const wxString
& WXUNUSED(title
),
184 const wxPoint
& WXUNUSED(pos
),
185 const wxSize
& WXUNUSED(size
),
187 const wxString
& name
)
191 frameShell
= XtCreatePopupShell( name
, topLevelShellWidgetClass
,
192 (Widget
)wxTheApp
->GetTopLevelWidget(),
195 XtVaSetValues(frameShell
,
196 // Allows menu to resize
197 XmNallowShellResize
, True
,
198 XmNdeleteResponse
, XmDO_NOTHING
,
199 XmNmappedWhenManaged
, False
,
200 XmNiconic
, (style
& wxICONIZE
) ? True
: False
,
203 m_frameShell
= (WXWidget
)frameShell
;
205 m_mainWidget
= (WXWidget
) XtVaCreateManagedWidget("main_window",
206 xmMainWindowWidgetClass
, frameShell
,
207 XmNresizePolicy
, XmRESIZE_NONE
,
210 m_workArea
= (WXWidget
) XtVaCreateWidget("form",
211 xmFormWidgetClass
, (Widget
) m_mainWidget
,
212 XmNresizePolicy
, XmRESIZE_NONE
,
215 m_clientArea
= (WXWidget
) XtVaCreateWidget("client",
216 xmBulletinBoardWidgetClass
, (Widget
) m_workArea
,
219 XmNrightAttachment
, XmATTACH_FORM
,
220 XmNleftAttachment
, XmATTACH_FORM
,
221 XmNtopAttachment
, XmATTACH_FORM
,
222 XmNbottomAttachment
, XmATTACH_FORM
,
225 XtVaSetValues((Widget
) m_mainWidget
,
226 XmNworkWindow
, (Widget
) m_workArea
,
229 XtManageChild((Widget
) m_clientArea
);
230 XtManageChild((Widget
) m_workArea
);
232 XtTranslations ptr
= XtParseTranslationTable( "<Configure>: resize()" );
233 XtOverrideTranslations( (Widget
) m_workArea
, ptr
);
234 XtFree( (char *)ptr
);
236 /* Part of show-&-hide fix */
237 XtAddEventHandler( frameShell
, StructureNotifyMask
,
238 False
, (XtEventHandler
)wxFrameMapProc
,
241 XtRealizeWidget(frameShell
);
243 wxAddWindowToTable( (Widget
)m_workArea
, this);
244 wxAddWindowToTable( (Widget
)m_clientArea
, this);
246 wxModelessWindows
.Append( this );
257 XtRemoveEventHandler((Widget
) m_clientArea
, ExposureMask
, False
,
258 wxUniversalRepaintProc
, (XtPointer
) this);
266 m_frameMenuBar
->DestroyMenuBar();
267 wxDELETE(m_frameMenuBar
);
270 wxDELETE(m_frameStatusBar
);
274 Widget frameShell
= (Widget
)GetShellWidget();
277 XtRemoveEventHandler( frameShell
, StructureNotifyMask
,
278 False
, (XtEventHandler
)wxFrameMapProc
,
283 wxDeleteWindowFromTable( (Widget
)m_clientArea
);
284 XtDestroyWidget( (Widget
)m_clientArea
);
289 XtVaSetValues( (Widget
)m_mainWidget
,
290 XmNworkWindow
, (Widget
)NULL
,
293 wxDeleteWindowFromTable( (Widget
)m_workArea
);
294 XtDestroyWidget( (Widget
)m_workArea
);
298 XtDestroyWidget( (Widget
)m_mainWidget
);
301 XtDestroyWidget( frameShell
);
304 // Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
305 void wxFrame::DoGetClientSize(int *x
, int *y
) const
308 XtVaGetValues((Widget
) m_workArea
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
310 if (m_frameStatusBar
)
313 m_frameStatusBar
->GetSize(& sbw
, & sbh
);
314 yy
= (Dimension
)(yy
- sbh
);
320 m_frameToolBar
->GetSize(& tbw
, & tbh
);
321 if (m_frameToolBar
->GetWindowStyleFlag() & wxTB_VERTICAL
)
322 xx
= (Dimension
)(xx
- tbw
);
324 yy
= (Dimension
)(yy
- tbh
);
326 #endif // wxUSE_TOOLBAR
328 //CE found a call here with NULL y pointer
335 // Set the client size (i.e. leave the calculation of borders etc.
337 void wxFrame::DoSetClientSize(int width
, int height
)
339 // Calculate how large the new main window should be
340 // by finding the difference between the client area and the
341 // main window area, and adding on to the new client area
343 XtVaSetValues((Widget
) m_workArea
, XmNwidth
, width
, NULL
);
347 if (m_frameStatusBar
)
350 m_frameStatusBar
->GetSize(& sbw
, & sbh
);
357 m_frameToolBar
->GetSize(& tbw
, & tbh
);
358 if (m_frameToolBar
->GetWindowStyleFlag() & wxTB_VERTICAL
)
363 #endif // wxUSE_TOOLBAR
365 XtVaSetValues((Widget
) m_workArea
, XmNheight
, height
, NULL
);
369 wxSize
newSize(width
, height
);
370 wxSizeEvent
sizeEvent(newSize
, GetId());
371 sizeEvent
.SetEventObject(this);
373 HandleWindowEvent(sizeEvent
);
377 void wxFrame::DoGetSize(int *width
, int *height
) const
381 *width
= -1; *height
= -1;
386 XtVaGetValues((Widget
) m_frameShell
, XmNwidth
, &xx
, XmNheight
, &yy
, NULL
);
387 *width
= xx
; *height
= yy
;
390 void wxFrame::DoSetSize(int x
, int y
, int width
, int height
, int WXUNUSED(sizeFlags
))
393 XtVaSetValues((Widget
) m_frameShell
, XmNx
, x
, NULL
);
395 XtVaSetValues((Widget
) m_frameShell
, XmNy
, y
, NULL
);
397 XtVaSetValues((Widget
) m_mainWidget
, XmNwidth
, width
, NULL
);
399 XtVaSetValues((Widget
) m_mainWidget
, XmNheight
, height
, NULL
);
401 if (!(height
== -1 && width
== -1))
407 bool wxFrame::Show( bool show
)
409 if( !wxWindowBase::Show( show
) )
414 Widget shell
= (Widget
)GetShellWidget();
416 return wxWindow::Show(show
);
418 SetVisibleStatus(show
);
421 XtPopup(shell
, XtGrabNone
);
431 void wxFrame::SetTitle(const wxString
& title
)
433 wxString oldTitle
= GetTitle();
434 if( title
== oldTitle
)
437 wxTopLevelWindow::SetTitle( title
);
440 XtVaSetValues( (Widget
)m_frameShell
,
441 XmNtitle
, (const char*)title
.mb_str(),
442 XmNiconName
, (const char*)title
.mb_str(),
446 void wxFrame::DoSetIcon(const wxIcon
& icon
)
451 if (!icon
.IsOk() || !icon
.GetDrawable())
454 XtVaSetValues((Widget
) m_frameShell
,
455 XtNiconPixmap
, icon
.GetDrawable(),
459 void wxFrame::SetIcons(const wxIconBundle
& icons
)
461 wxFrameBase::SetIcons( icons
);
466 DoSetIcon( m_icons
.GetIcon( -1 ) );
467 wxSetIconsX11(GetXDisplay(),
468 (WXWindow
) XtWindow( (Widget
) m_frameShell
), icons
);
471 void wxFrame::PositionStatusBar()
473 if (!m_frameStatusBar
)
477 GetClientSize(&w
, &h
);
479 m_frameStatusBar
->GetSize(&sw
, &sh
);
481 // Since we wish the status bar to be directly under the client area,
482 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
483 m_frameStatusBar
->SetSize(0, h
, w
, sh
);
486 WXWidget
wxFrame::GetMenuBarWidget() const
489 return GetMenuBar()->GetMainWidget();
491 return (WXWidget
) NULL
;
494 void wxFrame::SetMenuBar(wxMenuBar
*menuBar
)
498 m_frameMenuBar
= NULL
;
502 // Currently can't set it twice
503 // wxASSERT_MSG( (m_frameMenuBar == NULL), "Cannot set the menubar more than once");
507 m_frameMenuBar
->DestroyMenuBar();
508 delete m_frameMenuBar
;
511 m_frameMenuBar
= menuBar
;
512 m_frameMenuBar
->CreateMenuBar(this);
515 // Responds to colour changes, and passes event on to children.
516 void wxFrame::OnSysColourChanged(wxSysColourChangedEvent
& event
)
518 SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_APPWORKSPACE
));
521 if ( m_frameStatusBar
)
523 wxSysColourChangedEvent event2
;
524 event2
.SetEventObject( m_frameStatusBar
);
525 m_frameStatusBar
->HandleWindowEvent(event2
);
528 // Propagate the event to the non-top-level children
529 wxWindow::OnSysColourChanged(event
);
532 // Default activation behaviour - set the focus for the first child
534 void wxFrame::OnActivate(wxActivateEvent
& event
)
536 if (!event
.GetActive())
539 for(wxWindowList::compatibility_iterator node
= GetChildren().GetFirst(); node
;
540 node
= node
->GetNext())
542 // Find a child that's a subwindow, but not a dialog box.
543 wxWindow
*child
= node
->GetData();
544 if (!child
->IsTopLevel())
554 wxToolBar
* wxFrame::CreateToolBar(long style
,
556 const wxString
& name
)
558 if ( wxFrameBase::CreateToolBar(style
, id
, name
) )
563 return m_frameToolBar
;
566 void wxFrame::SetToolBar(wxToolBar
*toolbar
)
568 wxFrameBase::SetToolBar(toolbar
);
572 void wxFrame::PositionToolBar()
574 wxToolBar
* tb
= GetToolBar();
578 GetClientSize(& cw
, &ch
);
581 tb
->GetSize(& tw
, & th
);
583 if (tb
->GetWindowStyleFlag() & wxTB_VERTICAL
)
585 // Use the 'real' position. wxSIZE_NO_ADJUSTMENTS
586 // means, pretend we don't have toolbar/status bar, so we
587 // have the original client size.
592 // Use the 'real' position
596 tb
->SetSize(0, 0, -1, -1, wxSIZE_NO_ADJUSTMENTS
);
599 #endif // wxUSE_TOOLBAR
602 bool wxFrame::PreResize()
606 #endif // wxUSE_TOOLBAR
610 #endif // wxUSE_STATUSBAR
615 WXWidget
wxFrame::GetClientWidget() const
620 void wxFrame::ChangeFont(bool WXUNUSED(keepOriginalSize
))
625 void wxFrame::ChangeBackgroundColour()
627 if (GetClientWidget())
628 wxDoChangeBackgroundColour(GetClientWidget(), m_backgroundColour
);
631 void wxFrame::ChangeForegroundColour()
633 if (GetClientWidget())
634 wxDoChangeForegroundColour(GetClientWidget(), m_foregroundColour
);
637 /* MATTEW: Used to insure that hide-&-show within an event cycle works */
638 static void wxFrameMapProc( Widget frameShell
, XtPointer clientData
,
639 XCrossingEvent
* event
)
641 wxFrame
*tli
= (wxFrame
*)clientData
;
643 XEvent
*e
= (XEvent
*)event
;
645 if( e
->xany
.type
== MapNotify
)
648 XtVaSetValues( frameShell
, XmNiconic
, (Boolean
)False
, NULL
);
649 if( !tli
->GetVisibleStatus() )
651 /* We really wanted this to be hidden! */
652 XtUnmapWidget( frameShell
);
655 else if( e
->xany
.type
== UnmapNotify
)
657 XtVaSetValues( frameShell
, XmNiconic
, (Boolean
)True
, NULL
);