]> git.saurik.com Git - wxWidgets.git/blame - src/motif/frame.cpp
2 warnings from Solaris build log fixed
[wxWidgets.git] / src / motif / frame.cpp
CommitLineData
4bb6408c 1/////////////////////////////////////////////////////////////////////////////
1c4f8f8d 2// Name: motif/frame.cpp
4bb6408c
JS
3// Purpose: wxFrame
4// Author: Julian Smart
5// Modified by:
6// Created: 17/09/98
7// RCS-ID: $Id$
8// Copyright: (c) Julian Smart
9// Licence: wxWindows licence
10/////////////////////////////////////////////////////////////////////////////
11
1c4f8f8d
VZ
12// ============================================================================
13// declarations
14// ============================================================================
15
16// ----------------------------------------------------------------------------
17// headers
18// ----------------------------------------------------------------------------
19
4bb6408c 20#ifdef __GNUG__
1c4f8f8d 21 #pragma implementation "frame.h"
4bb6408c
JS
22#endif
23
24#include "wx/frame.h"
25#include "wx/statusbr.h"
26#include "wx/toolbar.h"
27#include "wx/menuitem.h"
28#include "wx/menu.h"
29#include "wx/dcclient.h"
30#include "wx/dialog.h"
31#include "wx/settings.h"
32#include "wx/app.h"
33#include "wx/utils.h"
34
338dd992 35#ifdef __VMS__
1c4f8f8d 36 #pragma message disable nosimpint
338dd992 37#endif
1c4f8f8d 38
4bb6408c 39#if defined(__ultrix) || defined(__sgi)
1c4f8f8d 40 #include <Xm/Frame.h>
4bb6408c
JS
41#endif
42
43#include <Xm/Xm.h>
44#include <X11/Shell.h>
45#if XmVersion >= 1002
1c4f8f8d 46 #include <Xm/XmAll.h>
4bb6408c 47#else
1c4f8f8d 48 #include <Xm/Frame.h>
4bb6408c
JS
49#endif
50#include <Xm/MwmUtil.h>
51#include <Xm/BulletinB.h>
52#include <Xm/Form.h>
53#include <Xm/MainW.h>
54#include <Xm/RowColumn.h>
55#include <Xm/Label.h>
56#include <Xm/AtomMgr.h>
57#include <Xm/LabelG.h>
58#include <Xm/Frame.h>
59#if XmVersion > 1000
1c4f8f8d 60 #include <Xm/Protocols.h>
4bb6408c 61#endif
1c4f8f8d 62
338dd992 63#ifdef __VMS__
1c4f8f8d 64 #pragma message enable nosimpint
338dd992 65#endif
4bb6408c
JS
66
67#include "wx/motif/private.h"
68
1c4f8f8d
VZ
69// ----------------------------------------------------------------------------
70// private functions
71// ----------------------------------------------------------------------------
72
73static void wxCloseFrameCallback(Widget, XtPointer, XmAnyCallbackStruct *cbs);
74static void wxFrameFocusProc(Widget workArea, XtPointer clientData,
75 XmAnyCallbackStruct *cbs);
dfe1eee3 76static void wxFrameMapProc(Widget frameShell, XtPointer clientData,
2d120f83 77 XCrossingEvent * event);
4bb6408c 78
1c4f8f8d
VZ
79// ----------------------------------------------------------------------------
80// globals
81// ----------------------------------------------------------------------------
82
4bb6408c
JS
83extern wxList wxModelessWindows;
84extern wxList wxPendingDelete;
85
86// TODO: this should be tidied so that any frame can be the
87// top frame
88static bool wxTopLevelUsed = FALSE;
89
1c4f8f8d
VZ
90// ----------------------------------------------------------------------------
91// wxWin macros
92// ----------------------------------------------------------------------------
93
1c4f8f8d
VZ
94BEGIN_EVENT_TABLE(wxFrame, wxFrameBase)
95 EVT_ACTIVATE(wxFrame::OnActivate)
96 EVT_SYS_COLOUR_CHANGED(wxFrame::OnSysColourChanged)
4bb6408c
JS
97END_EVENT_TABLE()
98
c0854a08 99IMPLEMENT_DYNAMIC_CLASS(wxFrame, wxWindow)
4bb6408c 100
1c4f8f8d
VZ
101// ============================================================================
102// implementation
103// ============================================================================
1ccbb61a 104
1c4f8f8d
VZ
105// ----------------------------------------------------------------------------
106// frame construction
107// ----------------------------------------------------------------------------
dfe1eee3 108
1c4f8f8d
VZ
109void wxFrame::Init()
110{
4bb6408c 111 m_iconized = FALSE;
dfe1eee3 112
4bb6408c
JS
113 //// Motif-specific
114 m_frameShell = (WXWidget) NULL;
115 m_frameWidget = (WXWidget) NULL;;
116 m_workArea = (WXWidget) NULL;;
117 m_clientArea = (WXWidget) NULL;;
118 m_visibleStatus = TRUE;
4bb6408c
JS
119}
120
121bool wxFrame::Create(wxWindow *parent,
2d120f83
JS
122 wxWindowID id,
123 const wxString& title,
124 const wxPoint& pos,
125 const wxSize& size,
126 long style,
127 const wxString& name)
4bb6408c 128{
1c4f8f8d
VZ
129 if ( parent )
130 AddChild(this);
131 else
2d120f83 132 wxTopLevelWindows.Append(this);
dfe1eee3 133
1c4f8f8d
VZ
134 wxModelessWindows.Append(this);
135
2d120f83 136 SetName(name);
dfe1eee3 137
2d120f83 138 m_windowStyle = style;
dfe1eee3 139
2d120f83
JS
140 m_backgroundColour = wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE);
141 m_foregroundColour = *wxBLACK;
da175b2c 142 m_font = wxSystemSettings::GetSystemFont(wxSYS_DEFAULT_GUI_FONT);
dfe1eee3 143
2d120f83
JS
144 if ( id > -1 )
145 m_windowId = id;
146 else
147 m_windowId = (int)NewControlId();
dfe1eee3 148
447a039f
MB
149 int x = pos.x, y = pos.y;
150 int width = size.x, height = size.y;
da8bed9b
VZ
151
152 // Set reasonable values for position and size if defaults have been
153 // requested
447a039f 154 //
da8bed9b
VZ
155 // MB TODO: something better than these arbitrary values ?
156 // VZ should use X resources for this...
157 if ( width == -1 )
158 width = 400;
159 if ( height == -1 )
160 height = 400;
447a039f
MB
161
162 int displayW, displayH;
163 wxDisplaySize( &displayW, &displayH );
164
165 if ( x == -1 )
166 {
167 x = (displayW - width) / 2;
168 if (x < 10) x = 10;
169 }
170 if ( y == -1 )
171 {
172 y = (displayH - height) / 2;
da8bed9b 173 if (y < 10) y = 10;
447a039f 174 }
da8bed9b 175
1c4f8f8d 176 // VZ: what does this do??
2d120f83 177 if (wxTopLevelUsed)
31528cd3 178 {
2d120f83 179 // Change suggested by Matthew Flatt
31528cd3
VZ
180 m_frameShell = (WXWidget)XtAppCreateShell
181 (
182 name,
183 wxTheApp->GetClassName(),
184 topLevelShellWidgetClass,
185 (Display*) wxGetDisplay(),
186 NULL,
187 0
188 );
189 }
2d120f83
JS
190 else
191 {
192 m_frameShell = wxTheApp->GetTopLevelWidget();
193 wxTopLevelUsed = TRUE;
194 }
dfe1eee3
VZ
195
196 XtVaSetValues((Widget) m_frameShell,
2d120f83
JS
197 // Allows menu to resize
198 XmNallowShellResize, True,
199 XmNdeleteResponse, XmDO_NOTHING,
200 XmNmappedWhenManaged, False,
201 XmNiconic, (style & wxICONIZE) ? TRUE : FALSE,
202 NULL);
dfe1eee3 203
1c4f8f8d 204 if (!title.IsEmpty())
dfe1eee3 205 XtVaSetValues((Widget) m_frameShell,
1c4f8f8d 206 XmNtitle, title.c_str(),
2d120f83 207 NULL);
dfe1eee3 208
2d120f83
JS
209 m_frameWidget = (WXWidget) XtVaCreateManagedWidget("main_window",
210 xmMainWindowWidgetClass, (Widget) m_frameShell,
211 XmNresizePolicy, XmRESIZE_NONE,
212 NULL);
dfe1eee3 213
2d120f83
JS
214 m_workArea = (WXWidget) XtVaCreateWidget("form",
215 xmFormWidgetClass, (Widget) m_frameWidget,
216 XmNresizePolicy, XmRESIZE_NONE,
217 NULL);
dfe1eee3 218
2d120f83
JS
219 m_clientArea = (WXWidget) XtVaCreateWidget("client",
220 xmBulletinBoardWidgetClass, (Widget) m_workArea,
221 XmNmarginWidth, 0,
222 XmNmarginHeight, 0,
223 XmNrightAttachment, XmATTACH_FORM,
224 XmNleftAttachment, XmATTACH_FORM,
225 XmNtopAttachment, XmATTACH_FORM,
226 XmNbottomAttachment, XmATTACH_FORM,
227 // XmNresizePolicy, XmRESIZE_ANY,
228 NULL);
0492c5a0 229
1c4f8f8d
VZ
230 wxLogTrace(wxTRACE_Messages,
231 "Created frame (0x%08x) with work area 0x%08x and client "
31528cd3
VZ
232 "area 0x%08x", m_frameWidget, m_workArea, m_clientArea);
233
2e35f56f
JS
234 XtAddEventHandler((Widget) m_clientArea, ExposureMask,FALSE,
235 wxUniversalRepaintProc, (XtPointer) this);
dfe1eee3 236
2d120f83
JS
237 XtVaSetValues((Widget) m_frameWidget,
238 XmNworkWindow, (Widget) m_workArea,
239 NULL);
dfe1eee3 240
2d120f83
JS
241 XtManageChild((Widget) m_clientArea);
242 XtManageChild((Widget) m_workArea);
dfe1eee3 243
2d120f83 244 wxAddWindowToTable((Widget) m_workArea, this);
dfe1eee3 245
1c4f8f8d 246 XtTranslations ptr;
dfe1eee3 247
2d120f83
JS
248 XtOverrideTranslations((Widget) m_workArea,
249 ptr = XtParseTranslationTable("<Configure>: resize()"));
dfe1eee3 250
2d120f83 251 XtFree((char *)ptr);
dfe1eee3
VZ
252
253 XtAddCallback((Widget) m_workArea, XmNfocusCallback,
2d120f83 254 (XtCallbackProc)wxFrameFocusProc, (XtPointer)this);
dfe1eee3 255
2d120f83
JS
256 /* Part of show-&-hide fix */
257 XtAddEventHandler((Widget) m_frameShell, StructureNotifyMask,
258 False, (XtEventHandler)wxFrameMapProc,
259 (XtPointer)m_workArea);
dfe1eee3 260
2d120f83
JS
261 if (x > -1)
262 XtVaSetValues((Widget) m_frameShell, XmNx, x, NULL);
263 if (y > -1)
264 XtVaSetValues((Widget) m_frameShell, XmNy, y, NULL);
265 if (width > -1)
266 XtVaSetValues((Widget) m_frameShell, XmNwidth, width, NULL);
267 if (height > -1)
268 XtVaSetValues((Widget) m_frameShell, XmNheight, height, NULL);
dfe1eee3 269
2d120f83 270 m_mainWidget = m_frameWidget;
dfe1eee3 271
2d120f83 272 ChangeFont(FALSE);
dfe1eee3 273
2d120f83
JS
274 // This patch comes from Torsten Liermann lier@lier1.muc.de
275 if (XmIsMotifWMRunning( (Widget) m_frameShell ))
276 {
1c4f8f8d 277 int decor = 0;
2d120f83 278 if (style & wxRESIZE_BORDER)
1c4f8f8d 279 decor |= MWM_DECOR_RESIZEH;
2d120f83
JS
280 if (style & wxSYSTEM_MENU)
281 decor |= MWM_DECOR_MENU;
282 if ((style & wxCAPTION) ||
283 (style & wxTINY_CAPTION_HORIZ) ||
284 (style & wxTINY_CAPTION_VERT))
285 decor |= MWM_DECOR_TITLE;
286 if (style & wxTHICK_FRAME)
287 decor |= MWM_DECOR_BORDER;
288 if (style & wxTHICK_FRAME)
289 decor |= MWM_DECOR_BORDER;
290 if (style & wxMINIMIZE_BOX)
291 decor |= MWM_DECOR_MINIMIZE;
292 if (style & wxMAXIMIZE_BOX)
293 decor |= MWM_DECOR_MAXIMIZE;
1c4f8f8d 294 XtVaSetValues((Widget) m_frameShell,XmNmwmDecorations,decor,NULL);
2d120f83
JS
295 }
296 // This allows non-Motif window managers to support at least the
297 // no-decorations case.
298 else
299 {
300 if (style == 0)
301 XtVaSetValues((Widget) m_frameShell,XmNoverrideRedirect,TRUE,NULL);
302 }
303 XtRealizeWidget((Widget) m_frameShell);
dfe1eee3 304
2d120f83
JS
305 // Intercept CLOSE messages from the window manager
306 Atom WM_DELETE_WINDOW = XmInternAtom(XtDisplay((Widget) m_frameShell), "WM_DELETE_WINDOW", False);
4bb6408c 307#if (XmREVISION > 1 || XmVERSION > 1)
2d120f83 308 XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (XtCallbackProc) wxCloseFrameCallback, (XtPointer)this);
4bb6408c
JS
309#else
310#if XmREVISION == 1
2d120f83 311 XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (XtCallbackProc) wxCloseFrameCallback, (caddr_t)this);
4bb6408c 312#else
2d120f83 313 XmAddWMProtocolCallback((Widget) m_frameShell, WM_DELETE_WINDOW, (void (*)())wxCloseFrameCallback, (caddr_t)this);
4bb6408c
JS
314#endif
315#endif
dfe1eee3 316
2d120f83 317 ChangeBackgroundColour();
dfe1eee3 318
2d120f83 319 PreResize();
dfe1eee3 320
2d120f83
JS
321 wxSizeEvent sizeEvent(wxSize(width, height), GetId());
322 sizeEvent.SetEventObject(this);
dfe1eee3 323
2d120f83 324 GetEventHandler()->ProcessEvent(sizeEvent);
dfe1eee3 325
2d120f83 326 return TRUE;
4bb6408c
JS
327}
328
329wxFrame::~wxFrame()
330{
3ab377bd 331 m_isBeingDeleted = TRUE;
da8bed9b 332
2e35f56f
JS
333 if (m_clientArea)
334 XtRemoveEventHandler((Widget) m_clientArea, ExposureMask, FALSE,
335 wxUniversalRepaintProc, (XtPointer) this);
336
2d120f83
JS
337 if (GetMainWidget())
338 Show(FALSE);
0492c5a0 339
2d120f83
JS
340 if (m_frameMenuBar)
341 {
342 m_frameMenuBar->DestroyMenuBar();
dfe1eee3 343
2d120f83 344 // Hack to stop core dump on Ultrix, OSF, for some strange reason.
4bb6408c 345#if MOTIF_MENUBAR_DELETE_FIX
2d120f83 346 GetMenuBar()->SetMainWidget((WXWidget) NULL);
4bb6408c 347#endif
2d120f83
JS
348 delete m_frameMenuBar;
349 m_frameMenuBar = NULL;
350 }
dfe1eee3 351
2d120f83
JS
352 wxTopLevelWindows.DeleteObject(this);
353 wxModelessWindows.DeleteObject(this);
dfe1eee3 354
2d120f83 355 if (m_frameStatusBar)
1c4f8f8d 356 {
2d120f83 357 delete m_frameStatusBar;
1c4f8f8d
VZ
358 m_frameStatusBar = NULL;
359 }
dfe1eee3 360
2d120f83 361 DestroyChildren();
dfe1eee3 362
2d120f83 363 if (m_workArea)
4bb6408c 364 {
2d120f83 365 wxDeleteWindowFromTable((Widget) m_workArea);
dfe1eee3 366
2d120f83 367 XtDestroyWidget ((Widget) m_workArea);
4bb6408c 368 }
dfe1eee3 369
2d120f83
JS
370 if (m_frameWidget)
371 {
372 wxDeleteWindowFromTable((Widget) m_frameWidget);
373 XtDestroyWidget ((Widget) m_frameWidget);
374 }
dfe1eee3 375
2d120f83
JS
376 if (m_frameShell)
377 XtDestroyWidget ((Widget) m_frameShell);
dfe1eee3 378
2d120f83 379 SetMainWidget((WXWidget) NULL);
dfe1eee3 380
2d120f83 381 /* Check if it's the last top-level window */
dfe1eee3 382
2d120f83
JS
383 if (wxTheApp && (wxTopLevelWindows.Number() == 0))
384 {
385 wxTheApp->SetTopWindow(NULL);
dfe1eee3 386
2d120f83
JS
387 if (wxTheApp->GetExitOnFrameDelete())
388 {
389 // Signal to the app that we're going to close
390 wxTheApp->ExitMainLoop();
391 }
392 }
4bb6408c
JS
393}
394
395// Get size *available for subwindows* i.e. excluding menu bar, toolbar etc.
449f38b5 396void wxFrame::DoGetClientSize(int *x, int *y) const
4bb6408c 397{
2d120f83
JS
398 Dimension xx, yy;
399 XtVaGetValues((Widget) m_workArea, XmNwidth, &xx, XmNheight, &yy, NULL);
dfe1eee3 400
2d120f83
JS
401 if (m_frameStatusBar)
402 {
403 int sbw, sbh;
404 m_frameStatusBar->GetSize(& sbw, & sbh);
405 yy -= sbh;
406 }
1ccbb61a 407#if wxUSE_TOOLBAR
2d120f83
JS
408 if (m_frameToolBar)
409 {
410 int tbw, tbh;
411 m_frameToolBar->GetSize(& tbw, & tbh);
412 if (m_frameToolBar->GetWindowStyleFlag() & wxTB_VERTICAL)
413 xx -= tbw;
414 else
415 yy -= tbh;
416 }
1ccbb61a 417#endif // wxUSE_TOOLBAR
2d120f83
JS
418 /*
419 if (GetMenuBar() != (wxMenuBar*) NULL)
420 {
4bb6408c
JS
421 // it seems that if a frame holds a panel, the menu bar size
422 // gets automatically taken care of --- grano@cs.helsinki.fi 4.4.95
423 bool hasSubPanel = FALSE;
c0ed460c 424 for(wxNode* node = GetChildren().First(); node; node = node->Next())
4bb6408c 425 {
2d120f83
JS
426 wxWindow *win = (wxWindow *)node->Data();
427 hasSubPanel = (win->IsKindOf(CLASSINFO(wxPanel)) && !win->IsKindOf(CLASSINFO(wxDialog)));
dfe1eee3 428
4bb6408c 429 if (hasSubPanel)
2d120f83
JS
430 break;
431 }
432 if (! hasSubPanel) {
4bb6408c
JS
433 Dimension ys;
434 XtVaGetValues((Widget) GetMenuBarWidget(), XmNheight, &ys, NULL);
435 yy -= ys;
2d120f83
JS
436 }
437 }
438 */
dfe1eee3 439
2d120f83 440 *x = xx; *y = yy;
4bb6408c
JS
441}
442
443// Set the client size (i.e. leave the calculation of borders etc.
444// to wxWindows)
bfc6fde4 445void wxFrame::DoSetClientSize(int width, int height)
4bb6408c 446{
2d120f83
JS
447 // Calculate how large the new main window should be
448 // by finding the difference between the client area and the
449 // main window area, and adding on to the new client area
450 if (width > -1)
451 XtVaSetValues((Widget) m_workArea, XmNwidth, width, NULL);
dfe1eee3 452
2d120f83 453 if (height > -1)
a4294b78 454 {
2d120f83
JS
455 if (m_frameStatusBar)
456 {
457 int sbw, sbh;
458 m_frameStatusBar->GetSize(& sbw, & sbh);
459 height += sbh;
460 }
1ccbb61a 461#if wxUSE_TOOLBAR
2d120f83
JS
462 if (m_frameToolBar)
463 {
464 int tbw, tbh;
465 m_frameToolBar->GetSize(& tbw, & tbh);
466 if (m_frameToolBar->GetWindowStyleFlag() & wxTB_VERTICAL)
467 width += tbw;
468 else
469 height += tbh;
470 }
1ccbb61a 471#endif // wxUSE_TOOLBAR
dfe1eee3 472
2d120f83 473 XtVaSetValues((Widget) m_workArea, XmNheight, height, NULL);
a4294b78 474 }
2d120f83 475 PreResize();
dfe1eee3 476
2d120f83
JS
477 wxSizeEvent sizeEvent(wxSize(width, height), GetId());
478 sizeEvent.SetEventObject(this);
dfe1eee3 479
2d120f83 480 GetEventHandler()->ProcessEvent(sizeEvent);
dfe1eee3 481
4bb6408c
JS
482}
483
449f38b5 484void wxFrame::DoGetSize(int *width, int *height) const
4bb6408c 485{
2d120f83
JS
486 Dimension xx, yy;
487 XtVaGetValues((Widget) m_frameShell, XmNwidth, &xx, XmNheight, &yy, NULL);
488 *width = xx; *height = yy;
4bb6408c
JS
489}
490
449f38b5 491void wxFrame::DoGetPosition(int *x, int *y) const
4bb6408c
JS
492{
493 Window parent_window = XtWindow((Widget) m_frameShell),
2d120f83
JS
494 next_parent = XtWindow((Widget) m_frameShell),
495 root = RootWindowOfScreen(XtScreen((Widget) m_frameShell));
dfe1eee3 496
4bb6408c
JS
497 // search for the parent that is child of ROOT, because the WM may
498 // reparent twice and notify only the next parent (like FVWM)
499 while (next_parent != root) {
2d120f83
JS
500 Window *theChildren; unsigned int n;
501 parent_window = next_parent;
502 XQueryTree(XtDisplay((Widget) m_frameShell), parent_window, &root,
503 &next_parent, &theChildren, &n);
504 XFree(theChildren); // not needed
4bb6408c
JS
505 }
506 int xx, yy; unsigned int dummy;
507 XGetGeometry(XtDisplay((Widget) m_frameShell), parent_window, &root,
2d120f83 508 &xx, &yy, &dummy, &dummy, &dummy, &dummy);
4bb6408c
JS
509 if (x) *x = xx;
510 if (y) *y = yy;
511}
512
af111fc3 513void wxFrame::DoSetSize(int x, int y, int width, int height, int WXUNUSED(sizeFlags))
4bb6408c 514{
2d120f83
JS
515 if (x > -1)
516 XtVaSetValues((Widget) m_frameShell, XmNx, x, NULL);
517 if (y > -1)
518 XtVaSetValues((Widget) m_frameShell, XmNy, y, NULL);
519 if (width > -1)
520 XtVaSetValues((Widget) m_frameWidget, XmNwidth, width, NULL);
521 if (height > -1)
522 XtVaSetValues((Widget) m_frameWidget, XmNheight, height, NULL);
dfe1eee3 523
2d120f83
JS
524 if (!(height == -1 && width == -1))
525 {
526 PreResize();
dfe1eee3 527
2d120f83
JS
528 wxSizeEvent sizeEvent(wxSize(width, height), GetId());
529 sizeEvent.SetEventObject(this);
dfe1eee3 530
2d120f83
JS
531 GetEventHandler()->ProcessEvent(sizeEvent);
532 }
4bb6408c
JS
533}
534
535bool wxFrame::Show(bool show)
536{
2d120f83
JS
537 if (!m_frameShell)
538 return wxWindow::Show(show);
dfe1eee3 539
2d120f83 540 m_visibleStatus = show; /* show-&-hide fix */
dfe1eee3 541
2d120f83
JS
542 m_isShown = show;
543 if (show) {
544 XtMapWidget((Widget) m_frameShell);
545 XRaiseWindow(XtDisplay((Widget) m_frameShell), XtWindow((Widget) m_frameShell));
546 } else {
547 XtUnmapWidget((Widget) m_frameShell);
548 // XmUpdateDisplay(wxTheApp->topLevel); // Experimental: may be responsible for crashes
549 }
550 return TRUE;
4bb6408c
JS
551}
552
553void wxFrame::Iconize(bool iconize)
554{
2d120f83
JS
555 if (!iconize)
556 Show(TRUE);
dfe1eee3 557
2d120f83
JS
558 if (m_frameShell)
559 XtVaSetValues((Widget) m_frameShell, XmNiconic, (Boolean)iconize, NULL);
4bb6408c
JS
560}
561
1c4f8f8d
VZ
562void wxFrame::Restore()
563{
564 if ( m_frameShell )
565 XtVaSetValues((Widget) m_frameShell, XmNiconic, FALSE, NULL);
566}
567
4bb6408c
JS
568void wxFrame::Maximize(bool maximize)
569{
2d120f83 570 Show(TRUE);
dfe1eee3 571
1c4f8f8d
VZ
572 if ( maximize )
573 Restore();
4bb6408c
JS
574}
575
576bool wxFrame::IsIconized() const
577{
2d120f83
JS
578 if (!m_frameShell)
579 return FALSE;
dfe1eee3 580
2d120f83
JS
581 Boolean iconic;
582 XtVaGetValues((Widget) m_frameShell, XmNiconic, &iconic, NULL);
583 return iconic;
4bb6408c
JS
584}
585
6f63ec3f 586// Is it maximized?
1c4f8f8d 587bool wxFrame::IsMaximized() const
6f63ec3f
JS
588{
589 // No maximizing in Motif (?)
590 return FALSE;
591}
592
4bb6408c
JS
593void wxFrame::SetTitle(const wxString& title)
594{
2d120f83
JS
595 if (title == m_title)
596 return;
dfe1eee3 597
2d120f83 598 m_title = title;
dfe1eee3 599
2d120f83 600 if (!title.IsNull())
dfe1eee3 601 XtVaSetValues((Widget) m_frameShell,
1c4f8f8d
VZ
602 XmNtitle, title.c_str(),
603 XmNiconName, title.c_str(),
2d120f83 604 NULL);
4bb6408c
JS
605}
606
607void wxFrame::SetIcon(const wxIcon& icon)
608{
2d120f83 609 m_icon = icon;
dfe1eee3 610
2d120f83
JS
611 if (!m_frameShell)
612 return;
dfe1eee3 613
2d120f83
JS
614 if (!icon.Ok() || !icon.GetPixmap())
615 return;
dfe1eee3 616
2d120f83 617 XtVaSetValues((Widget) m_frameShell, XtNiconPixmap, icon.GetPixmap(), NULL);
4bb6408c
JS
618}
619
4bb6408c
JS
620void wxFrame::PositionStatusBar()
621{
50414e24 622 if (!m_frameStatusBar)
2d120f83 623 return;
dfe1eee3 624
4bb6408c
JS
625 int w, h;
626 GetClientSize(&w, &h);
627 int sw, sh;
628 m_frameStatusBar->GetSize(&sw, &sh);
dfe1eee3 629
4bb6408c
JS
630 // Since we wish the status bar to be directly under the client area,
631 // we use the adjusted sizes without using wxSIZE_NO_ADJUSTMENTS.
89c7e962 632 m_frameStatusBar->SetSize(0, h, w, sh);
4bb6408c
JS
633}
634
635WXWidget wxFrame::GetMenuBarWidget() const
636{
2d120f83
JS
637 if (GetMenuBar())
638 return GetMenuBar()->GetMainWidget();
639 else
640 return (WXWidget) NULL;
4bb6408c
JS
641}
642
643void wxFrame::SetMenuBar(wxMenuBar *menuBar)
644{
645 if (!menuBar)
646 {
647 m_frameMenuBar = NULL;
648 return;
649 }
dfe1eee3 650
4bb6408c 651 // Currently can't set it twice
2d120f83 652 // wxASSERT_MSG( (m_frameMenuBar == (wxMenuBar*) NULL), "Cannot set the menubar more than once");
dfe1eee3 653
621793f4 654 if (m_frameMenuBar)
4bb6408c 655 {
621793f4
JS
656 m_frameMenuBar->DestroyMenuBar();
657 delete m_frameMenuBar;
4bb6408c 658 }
dfe1eee3 659
621793f4
JS
660 m_frameMenuBar = menuBar;
661 m_frameMenuBar->CreateMenuBar(this);
4bb6408c
JS
662}
663
4bb6408c
JS
664// Responds to colour changes, and passes event on to children.
665void wxFrame::OnSysColourChanged(wxSysColourChangedEvent& event)
666{
667 SetBackgroundColour(wxSystemSettings::GetSystemColour(wxSYS_COLOUR_APPWORKSPACE));
668 Refresh();
dfe1eee3 669
4bb6408c
JS
670 if ( m_frameStatusBar )
671 {
672 wxSysColourChangedEvent event2;
673 event2.SetEventObject( m_frameStatusBar );
674 m_frameStatusBar->ProcessEvent(event2);
675 }
dfe1eee3 676
4bb6408c
JS
677 // Propagate the event to the non-top-level children
678 wxWindow::OnSysColourChanged(event);
679}
680
4bb6408c
JS
681// Default activation behaviour - set the focus for the first child
682// subwindow found.
683void wxFrame::OnActivate(wxActivateEvent& event)
684{
af111fc3
JS
685 if (!event.GetActive())
686 return;
687
2d120f83 688 for(wxNode *node = GetChildren().First(); node; node = node->Next())
4bb6408c 689 {
2d120f83
JS
690 // Find a child that's a subwindow, but not a dialog box.
691 wxWindow *child = (wxWindow *)node->Data();
692 if (!child->IsKindOf(CLASSINFO(wxFrame)) &&
693 !child->IsKindOf(CLASSINFO(wxDialog)))
694 {
695 child->SetFocus();
696 return;
697 }
4bb6408c 698 }
4bb6408c
JS
699}
700
1ccbb61a 701#if wxUSE_TOOLBAR
dfe1eee3 702
1c4f8f8d
VZ
703wxToolBar* wxFrame::CreateToolBar(long style,
704 wxWindowID id,
705 const wxString& name)
4bb6408c 706{
1c4f8f8d 707 if ( wxFrameBase::CreateToolBar(style, id, name) )
4bb6408c 708 {
4bb6408c 709 PositionToolBar();
4bb6408c 710 }
4bb6408c 711
1ccbb61a
VZ
712 return m_frameToolBar;
713}
714
4bb6408c
JS
715void wxFrame::PositionToolBar()
716{
4bb6408c
JS
717 if (GetToolBar())
718 {
1c4f8f8d
VZ
719 int cw, ch;
720 GetClientSize(& cw, &ch);
721
4bb6408c
JS
722 int tw, th;
723 GetToolBar()->GetSize(& tw, & th);
dfe1eee3 724
4bb6408c
JS
725 if (GetToolBar()->GetWindowStyleFlag() & wxTB_VERTICAL)
726 {
727 // Use the 'real' position. wxSIZE_NO_ADJUSTMENTS
728 // means, pretend we don't have toolbar/status bar, so we
729 // have the original client size.
a4294b78 730 GetToolBar()->SetSize(0, 0, tw, ch + th, wxSIZE_NO_ADJUSTMENTS);
4bb6408c
JS
731 }
732 else
733 {
734 // Use the 'real' position
735 GetToolBar()->SetSize(0, 0, cw, th, wxSIZE_NO_ADJUSTMENTS);
736 }
737 }
738}
1ccbb61a 739#endif // wxUSE_TOOLBAR
4bb6408c 740
1c4f8f8d 741void wxFrame::Raise()
4bb6408c
JS
742{
743 Window parent_window = XtWindow((Widget) m_frameShell),
2d120f83
JS
744 next_parent = XtWindow((Widget) m_frameShell),
745 root = RootWindowOfScreen(XtScreen((Widget) m_frameShell));
4bb6408c
JS
746 // search for the parent that is child of ROOT, because the WM may
747 // reparent twice and notify only the next parent (like FVWM)
748 while (next_parent != root) {
2d120f83
JS
749 Window *theChildren; unsigned int n;
750 parent_window = next_parent;
751 XQueryTree(XtDisplay((Widget) m_frameShell), parent_window, &root,
752 &next_parent, &theChildren, &n);
753 XFree(theChildren); // not needed
4bb6408c
JS
754 }
755 XRaiseWindow(XtDisplay((Widget) m_frameShell), parent_window);
756}
757
1c4f8f8d 758void wxFrame::Lower()
4bb6408c
JS
759{
760 Window parent_window = XtWindow((Widget) m_frameShell),
2d120f83
JS
761 next_parent = XtWindow((Widget) m_frameShell),
762 root = RootWindowOfScreen(XtScreen((Widget) m_frameShell));
4bb6408c
JS
763 // search for the parent that is child of ROOT, because the WM may
764 // reparent twice and notify only the next parent (like FVWM)
765 while (next_parent != root) {
2d120f83
JS
766 Window *theChildren; unsigned int n;
767 parent_window = next_parent;
768 XQueryTree(XtDisplay((Widget) m_frameShell), parent_window, &root,
769 &next_parent, &theChildren, &n);
770 XFree(theChildren); // not needed
4bb6408c
JS
771 }
772 XLowerWindow(XtDisplay((Widget) m_frameShell), parent_window);
773}
774
af111fc3
JS
775void wxFrameFocusProc(Widget WXUNUSED(workArea), XtPointer WXUNUSED(clientData),
776 XmAnyCallbackStruct *WXUNUSED(cbs))
4bb6408c 777{
2d120f83
JS
778 // wxDebugMsg("focus proc from frame %ld\n",(long)frame);
779 // TODO
dfe1eee3
VZ
780 // wxFrame *frame = (wxFrame *)clientData;
781 // frame->GetEventHandler()->OnSetFocus();
4bb6408c
JS
782}
783
784/* MATTEW: Used to insure that hide-&-show within an event cycle works */
dfe1eee3 785static void wxFrameMapProc(Widget frameShell, XtPointer clientData,
2d120f83 786 XCrossingEvent * event)
4bb6408c 787{
dfe1eee3
VZ
788 wxFrame *frame = (wxFrame *)wxGetWindowFromTable((Widget)clientData);
789
2d120f83
JS
790 if (frame) {
791 XEvent *e = (XEvent *)event;
dfe1eee3 792
2d120f83
JS
793 if (e->xany.type == MapNotify)
794 {
795 // Iconize fix
796 XtVaSetValues(frameShell, XmNiconic, (Boolean)False, NULL);
797 if (!frame->GetVisibleStatus())
798 {
799 /* We really wanted this to be hidden! */
800 XtUnmapWidget((Widget) frame->GetShellWidget());
801 }
802 }
803 else if (e->xany.type == UnmapNotify)
804 // Iconize fix
805 XtVaSetValues(frameShell, XmNiconic, (Boolean)True, NULL);
4bb6408c 806 }
4bb6408c
JS
807}
808
809//// Motif-specific
810bool wxFrame::PreResize()
811{
1ccbb61a 812#if wxUSE_TOOLBAR
2d120f83 813 PositionToolBar();
1ccbb61a 814#endif // wxUSE_TOOLBAR
1c4f8f8d
VZ
815
816#if wxUSE_STATUSBAR
2d120f83 817 PositionStatusBar();
1c4f8f8d
VZ
818#endif // wxUSE_STATUSBAR
819
2d120f83 820 return TRUE;
4bb6408c
JS
821}
822
50414e24
JS
823WXWidget wxFrame::GetClientWidget() const
824{
2d120f83 825 return m_clientArea;
50414e24
JS
826}
827
af111fc3 828void wxFrame::ChangeFont(bool WXUNUSED(keepOriginalSize))
0d57be45
JS
829{
830 // TODO
831}
832
833void wxFrame::ChangeBackgroundColour()
834{
621793f4
JS
835 if (GetClientWidget())
836 DoChangeBackgroundColour(GetClientWidget(), m_backgroundColour);
0d57be45
JS
837}
838
839void wxFrame::ChangeForegroundColour()
840{
621793f4
JS
841 if (GetClientWidget())
842 DoChangeForegroundColour(GetClientWidget(), m_foregroundColour);
0d57be45
JS
843}
844
af111fc3 845void wxCloseFrameCallback(Widget WXUNUSED(widget), XtPointer client_data, XmAnyCallbackStruct *WXUNUSED(cbs))
4bb6408c 846{
2d120f83 847 wxFrame *frame = (wxFrame *)client_data;
dfe1eee3 848
2d120f83
JS
849 wxCloseEvent closeEvent(wxEVT_CLOSE_WINDOW, frame->GetId());
850 closeEvent.SetEventObject(frame);
dfe1eee3 851
2d120f83
JS
852 // May delete the frame (with delayed deletion)
853 frame->GetEventHandler()->ProcessEvent(closeEvent);
4bb6408c 854}
0d57be45 855