]> git.saurik.com Git - wxWidgets.git/blame - src/gtk/frame.cpp
VTK wrapper of vtkRenderWindow for wxPython. Tested on MSW so far.
[wxWidgets.git] / src / gtk / frame.cpp
CommitLineData
c801d85f
KB
1/////////////////////////////////////////////////////////////////////////////
2// Name: frame.cpp
3// Purpose:
4// Author: Robert Roebling
a81258be 5// Id: $Id$
01111366 6// Copyright: (c) 1998 Robert Roebling
19717c50 7// Licence: wxWindows licence
c801d85f
KB
8/////////////////////////////////////////////////////////////////////////////
9
7c0ea335
VZ
10// ============================================================================
11// declarations
12// ============================================================================
13
14// ----------------------------------------------------------------------------
15// headers
16// ----------------------------------------------------------------------------
17
c801d85f 18#ifdef __GNUG__
fe4e9e6c 19 #pragma implementation "frame.h"
c801d85f
KB
20#endif
21
22#include "wx/frame.h"
23#include "wx/dialog.h"
24#include "wx/control.h"
25#include "wx/app.h"
cf4219e7 26#include "wx/menu.h"
dcf924a3 27#if wxUSE_TOOLBAR
7c0ea335 28 #include "wx/toolbar.h"
dcf924a3
RR
29#endif
30#if wxUSE_STATUSBAR
7c0ea335 31 #include "wx/statusbr.h"
dcf924a3 32#endif
362c6693 33#include "wx/dcclient.h"
83624f79
RR
34
35#include "glib.h"
36#include "gdk/gdk.h"
37#include "gtk/gtk.h"
c801d85f 38#include "wx/gtk/win_gtk.h"
801aa178 39#include "gdk/gdkkeysyms.h"
cd25b18c 40#include "gdk/gdkx.h"
c801d85f 41
7c0ea335 42// ----------------------------------------------------------------------------
2f2aa628 43// constants
7c0ea335 44// ----------------------------------------------------------------------------
2f2aa628 45
907789a0 46const int wxMENU_HEIGHT = 27;
c67daf87 47const int wxSTATUS_HEIGHT = 25;
41ca191f 48const int wxPLACE_HOLDER = 0;
c801d85f 49
7c0ea335 50// ----------------------------------------------------------------------------
acfd422a 51// idle system
7c0ea335 52// ----------------------------------------------------------------------------
acfd422a
RR
53
54extern void wxapp_install_idle_handler();
55extern bool g_isIdle;
2d68e1b4 56extern int g_openDialogs;
acfd422a 57
7c0ea335
VZ
58// ----------------------------------------------------------------------------
59// event tables
60// ----------------------------------------------------------------------------
61
62IMPLEMENT_DYNAMIC_CLASS(wxFrame,wxWindow)
63
64// ----------------------------------------------------------------------------
2f2aa628 65// data
7c0ea335 66// ----------------------------------------------------------------------------
2f2aa628 67
c801d85f
KB
68extern wxList wxPendingDelete;
69
7c0ea335 70// ----------------------------------------------------------------------------
2e563988 71// debug
7c0ea335 72// ----------------------------------------------------------------------------
2e563988
RR
73
74#ifdef __WXDEBUG__
75
76extern void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window );
77
78#endif
79
7c0ea335
VZ
80// ============================================================================
81// implementation
82// ============================================================================
83
84// ----------------------------------------------------------------------------
85// GTK callbacks
86// ----------------------------------------------------------------------------
87
69ffe1d2
RR
88//-----------------------------------------------------------------------------
89// "focus" from m_window
90//-----------------------------------------------------------------------------
91
92static gint gtk_frame_focus_callback( GtkWidget *widget, GtkDirectionType WXUNUSED(d), wxWindow *WXUNUSED(win) )
93{
94 if (g_isIdle)
95 wxapp_install_idle_handler();
96
97 // This disables GTK's tab traversal
98 gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "focus" );
99 return TRUE;
100}
101
c801d85f 102//-----------------------------------------------------------------------------
2f2aa628 103// "size_allocate"
c801d85f 104//-----------------------------------------------------------------------------
c801d85f 105
2f2aa628 106static void gtk_frame_size_callback( GtkWidget *WXUNUSED(widget), GtkAllocation* alloc, wxFrame *win )
ed7a557b 107{
88ac883a 108 if (g_isIdle)
121a3581 109 wxapp_install_idle_handler();
acfd422a 110
54517652
RR
111 if (!win->m_hasVMT)
112 return;
8bbe427f 113
121a3581
RR
114 if ((win->m_width != alloc->width) || (win->m_height != alloc->height))
115 {
54517652
RR
116/*
117 wxPrintf( "OnSize from " );
118 if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
119 wxPrintf( win->GetClassInfo()->GetClassName() );
120 wxPrintf( " %d %d %d %d\n", (int)alloc->x,
121 (int)alloc->y,
122 (int)alloc->width,
123 (int)alloc->height );
124*/
7beba2fc 125
121a3581
RR
126 win->m_width = alloc->width;
127 win->m_height = alloc->height;
128 win->UpdateSize();
129 }
362c6693 130}
c801d85f
KB
131
132//-----------------------------------------------------------------------------
2f2aa628
RR
133// "delete_event"
134//-----------------------------------------------------------------------------
c801d85f 135
2f2aa628 136static gint gtk_frame_delete_callback( GtkWidget *WXUNUSED(widget), GdkEvent *WXUNUSED(event), wxFrame *win )
ed7a557b 137{
88ac883a 138 if (g_isIdle)
121a3581 139 wxapp_install_idle_handler();
ed7a557b 140
2d68e1b4
RR
141 if (g_openDialogs == 0)
142 win->Close();
c801d85f 143
fb1585ae 144 return TRUE;
362c6693 145}
c801d85f 146
16bcc879
RR
147//-----------------------------------------------------------------------------
148// "child_attached" of menu bar
149//-----------------------------------------------------------------------------
150
151static void gtk_menu_attached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win )
152{
a2053b27 153 if (!win->m_hasVMT) return;
88ac883a 154
16bcc879 155 win->m_menuBarDetached = FALSE;
f03fc89f 156 win->UpdateSize();
16bcc879
RR
157}
158
159//-----------------------------------------------------------------------------
160// "child_detached" of menu bar
161//-----------------------------------------------------------------------------
162
163static void gtk_menu_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win )
164{
a2053b27 165 if (!win->m_hasVMT) return;
88ac883a 166
16bcc879 167 win->m_menuBarDetached = TRUE;
f03fc89f 168 win->UpdateSize();
16bcc879
RR
169}
170
88ac883a 171#if wxUSE_TOOLBAR
16bcc879
RR
172//-----------------------------------------------------------------------------
173// "child_attached" of tool bar
174//-----------------------------------------------------------------------------
175
176static void gtk_toolbar_attached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win )
177{
a2053b27 178 if (!win->m_hasVMT) return;
88ac883a 179
16bcc879 180 win->m_toolBarDetached = FALSE;
88ac883a 181
f03fc89f 182 win->UpdateSize();
16bcc879
RR
183}
184
185//-----------------------------------------------------------------------------
186// "child_detached" of tool bar
187//-----------------------------------------------------------------------------
188
5e0201ea 189static void gtk_toolbar_detached_callback( GtkWidget *WXUNUSED(widget), GtkWidget *WXUNUSED(child), wxFrame *win )
16bcc879 190{
88ac883a 191 if (g_isIdle)
801aa178 192 wxapp_install_idle_handler();
acfd422a 193
a2053b27 194 if (!win->m_hasVMT) return;
88ac883a 195
16bcc879 196 win->m_toolBarDetached = TRUE;
f03fc89f 197 win->UpdateSize();
16bcc879 198}
88ac883a 199#endif // wxUSE_TOOLBAR
16bcc879 200
47908e25 201//-----------------------------------------------------------------------------
2f2aa628
RR
202// "configure_event"
203//-----------------------------------------------------------------------------
47908e25 204
7beba2fc 205static gint
2d68e1b4 206#if (GTK_MINOR_VERSION > 0)
c693edf3
RR
207gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *WXUNUSED(event), wxFrame *win )
208#else
209gtk_frame_configure_callback( GtkWidget *WXUNUSED(widget), GdkEventConfigure *event, wxFrame *win )
210#endif
47908e25 211{
7beba2fc 212 if (g_isIdle)
121a3581 213 wxapp_install_idle_handler();
acfd422a 214
7c0ea335 215 if (!win->m_hasVMT)
2d68e1b4 216 return FALSE;
7c0ea335 217
2d68e1b4 218#if (GTK_MINOR_VERSION > 0)
dfc3d7e0
RR
219 int x = 0;
220 int y = 0;
221 gdk_window_get_root_origin( win->m_widget->window, &x, &y );
dfc3d7e0
RR
222 win->m_x = x;
223 win->m_y = y;
c693edf3
RR
224#else
225 win->m_x = event->x;
226 win->m_y = event->y;
227#endif
8bbe427f 228
a2053b27 229 wxMoveEvent mevent( wxPoint(win->m_x,win->m_y), win->GetId() );
36b3b54a
RR
230 mevent.SetEventObject( win );
231 win->GetEventHandler()->ProcessEvent( mevent );
232
fb1585ae 233 return FALSE;
362c6693 234}
47908e25 235
2b07d713
RR
236//-----------------------------------------------------------------------------
237// "realize" from m_widget
238//-----------------------------------------------------------------------------
239
88ac883a 240/* we cannot MWM hints and icons before the widget has been realized,
2b07d713
RR
241 so we do this directly after realization */
242
88ac883a 243static gint
2e5c594e 244gtk_frame_realized_callback( GtkWidget *widget, wxFrame *win )
2b07d713 245{
88ac883a 246 if (g_isIdle)
121a3581 247 wxapp_install_idle_handler();
acfd422a 248
2e5c594e
RR
249 /* I haven't been able to set the position of
250 the dialog before it is shown, so I set the
251 position in "realize" */
8487f887 252 gtk_widget_set_uposition( widget, win->m_x, win->m_y );
2e5c594e 253
2b07d713
RR
254 /* all this is for Motif Window Manager "hints" and is supposed to be
255 recognized by other WM as well. not tested. */
051b55ad
KB
256 long decor = (long) GDK_DECOR_BORDER;
257 long func = (long) GDK_FUNC_MOVE;
88ac883a 258
f03fc89f
VZ
259 if ((win->GetWindowStyle() & wxCAPTION) != 0)
260 decor |= GDK_DECOR_TITLE;
261 if ((win->GetWindowStyle() & wxSYSTEM_MENU) != 0)
aa64626e
KB
262 {
263 decor |= GDK_DECOR_MENU;
264 func |= GDK_FUNC_CLOSE;
265 }
f03fc89f 266 if ((win->GetWindowStyle() & wxMINIMIZE_BOX) != 0)
15b24b14 267 {
f03fc89f
VZ
268 func |= GDK_FUNC_MINIMIZE;
269 decor |= GDK_DECOR_MINIMIZE;
15b24b14 270 }
f03fc89f 271 if ((win->GetWindowStyle() & wxMAXIMIZE_BOX) != 0)
15b24b14 272 {
f03fc89f
VZ
273 func |= GDK_FUNC_MAXIMIZE;
274 decor |= GDK_DECOR_MAXIMIZE;
15b24b14 275 }
f03fc89f 276 if ((win->GetWindowStyle() & wxRESIZE_BORDER) != 0)
aa64626e
KB
277 {
278 func |= GDK_FUNC_RESIZE;
279 decor |= GDK_DECOR_RESIZEH;
aa64626e
KB
280 }
281
a2053b27
RR
282 gdk_window_set_decorations( win->m_widget->window, (GdkWMDecoration)decor);
283 gdk_window_set_functions( win->m_widget->window, (GdkWMFunction)func);
88ac883a 284
2b07d713 285 /* GTK's shrinking/growing policy */
f03fc89f 286 if ((win->GetWindowStyle() & wxRESIZE_BORDER) == 0)
a2053b27 287 gtk_window_set_policy(GTK_WINDOW(win->m_widget), 0, 0, 1);
2b07d713 288 else
a2053b27 289 gtk_window_set_policy(GTK_WINDOW(win->m_widget), 1, 1, 1);
88ac883a 290
738f9e5a 291 /* set size hints */
8487f887 292 gint flag = 0; // GDK_HINT_POS;
738f9e5a
RR
293 if ((win->GetMinWidth() != -1) || (win->GetMinHeight() != -1)) flag |= GDK_HINT_MIN_SIZE;
294 if ((win->GetMaxWidth() != -1) || (win->GetMaxHeight() != -1)) flag |= GDK_HINT_MAX_SIZE;
295 if (flag)
296 {
7beba2fc
VZ
297 gdk_window_set_hints( win->m_widget->window,
298 win->m_x, win->m_y,
299 win->GetMinWidth(), win->GetMinHeight(),
300 win->GetMaxWidth(), win->GetMaxHeight(),
301 flag );
738f9e5a 302 }
7beba2fc 303
58dea4b0 304 /* reset the icon */
7c0ea335
VZ
305 wxIcon iconOld = win->GetIcon();
306 if ( iconOld != wxNullIcon )
58dea4b0 307 {
7c0ea335
VZ
308 wxIcon icon( iconOld );
309 win->SetIcon( wxNullIcon );
f03fc89f 310 win->SetIcon( icon );
58dea4b0 311 }
88ac883a 312
2e563988
RR
313 /* we set the focus to the child that accepts the focus. this
314 doesn't really have to be done in "realize" but why not? */
f03fc89f 315 wxWindowList::Node *node = win->GetChildren().GetFirst();
2e563988
RR
316 while (node)
317 {
f03fc89f
VZ
318 wxWindow *child = node->GetData();
319 if (child->AcceptsFocus())
320 {
321 child->SetFocus();
322 break;
323 }
88ac883a 324
f03fc89f 325 node = node->GetNext();
2e563988 326 }
88ac883a 327
227e5e99
RR
328 return FALSE;
329}
88ac883a 330
7c0ea335
VZ
331// ----------------------------------------------------------------------------
332// wxFrame itself
333// ----------------------------------------------------------------------------
334
f362b96d
RR
335//-----------------------------------------------------------------------------
336// InsertChild for wxFrame
337//-----------------------------------------------------------------------------
338
339/* Callback for wxFrame. This very strange beast has to be used because
340 * C++ has no virtual methods in a constructor. We have to emulate a
341 * virtual function here as wxWindows requires different ways to insert
342 * a child in container classes. */
343
6bc8a1c8 344static void wxInsertChildInFrame( wxFrame* parent, wxWindow* child )
f362b96d 345{
5fd11f09 346 wxASSERT( GTK_IS_WIDGET(child->m_widget) );
7beba2fc 347
6bc8a1c8 348 if (!parent->m_insertInClientArea)
f362b96d
RR
349 {
350 /* these are outside the client area */
f03fc89f 351 wxFrame* frame = (wxFrame*) parent;
da048e3d 352 gtk_pizza_put( GTK_PIZZA(frame->m_mainWidget),
a2053b27
RR
353 GTK_WIDGET(child->m_widget),
354 child->m_x,
355 child->m_y,
356 child->m_width,
357 child->m_height );
88ac883a
VZ
358
359#if wxUSE_TOOLBAR
f03fc89f
VZ
360 /* we connect to these events for recalculating the client area
361 space when the toolbar is floating */
362 if (wxIS_KIND_OF(child,wxToolBar))
363 {
364 wxToolBar *toolBar = (wxToolBar*) child;
365 if (toolBar->GetWindowStyle() & wxTB_DOCKABLE)
366 {
a2053b27 367 gtk_signal_connect( GTK_OBJECT(toolBar->m_widget), "child_attached",
41ca191f 368 GTK_SIGNAL_FUNC(gtk_toolbar_attached_callback), (gpointer)parent );
88ac883a 369
a2053b27 370 gtk_signal_connect( GTK_OBJECT(toolBar->m_widget), "child_detached",
41ca191f 371 GTK_SIGNAL_FUNC(gtk_toolbar_detached_callback), (gpointer)parent );
f03fc89f
VZ
372 }
373 }
88ac883a 374#endif // wxUSE_TOOLBAR
f362b96d
RR
375 }
376 else
377 {
378 /* these are inside the client area */
da048e3d 379 gtk_pizza_put( GTK_PIZZA(parent->m_wxwindow),
a2053b27
RR
380 GTK_WIDGET(child->m_widget),
381 child->m_x,
382 child->m_y,
383 child->m_width,
384 child->m_height );
f362b96d
RR
385 }
386
f362b96d 387 /* resize on OnInternalIdle */
f03fc89f 388 parent->UpdateSize();
f362b96d
RR
389}
390
7c0ea335
VZ
391// ----------------------------------------------------------------------------
392// wxFrame creation
393// ----------------------------------------------------------------------------
c801d85f 394
ddb6bc71 395void wxFrame::Init()
c801d85f 396{
fb1585ae 397 m_sizeSet = FALSE;
b2b3ccc5
RR
398 m_miniEdge = 0;
399 m_miniTitle = 0;
ab2b3dd4 400 m_mainWidget = (GtkWidget*) NULL;
16bcc879
RR
401 m_menuBarDetached = FALSE;
402 m_toolBarDetached = FALSE;
6bc8a1c8 403 m_insertInClientArea = TRUE;
54517652 404 m_isFrame = TRUE;
362c6693 405}
c801d85f 406
7c0ea335
VZ
407bool wxFrame::Create( wxWindow *parent,
408 wxWindowID id,
409 const wxString &title,
410 const wxPoint &pos,
411 const wxSize &size,
412 long style,
413 const wxString &name )
c801d85f 414{
a802c3a1 415 wxTopLevelWindows.Append( this );
8bbe427f 416
fb1585ae 417 m_needParent = FALSE;
ed7a557b 418
4dcaf11a
RR
419 if (!PreCreation( parent, pos, size ) ||
420 !CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
421 {
223d09f6 422 wxFAIL_MSG( wxT("wxFrame creation failed") );
7beba2fc 423 return FALSE;
4dcaf11a 424 }
c801d85f 425
fb1585ae 426 m_title = title;
88ac883a 427
6bc8a1c8 428 m_insertCallback = (wxInsertChildFunction) wxInsertChildInFrame;
ed7a557b 429
faecf4cb 430 GtkWindowType win_type = GTK_WINDOW_TOPLEVEL;
fb1585ae 431 if (style & wxSIMPLE_BORDER) win_type = GTK_WINDOW_POPUP;
8bbe427f 432
fb1585ae 433 m_widget = gtk_window_new( win_type );
88ac883a 434
de1c750f
RR
435 if (!name.IsEmpty())
436 gtk_window_set_wmclass( GTK_WINDOW(m_widget), name.mb_str(), name.mb_str() );
8bbe427f 437
2e563988 438#ifdef __WXDEBUG__
223d09f6 439 debug_focus_in( m_widget, wxT("wxFrame::m_widget"), name );
2e563988
RR
440#endif
441
ed9b9841 442 gtk_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
fb1585ae 443 GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
ed7a557b 444
fb1585ae
RR
445 gtk_signal_connect( GTK_OBJECT(m_widget), "delete_event",
446 GTK_SIGNAL_FUNC(gtk_frame_delete_callback), (gpointer)this );
ed7a557b 447
f362b96d 448 /* m_mainWidget holds the toolbar, the menubar and the client area */
da048e3d 449 m_mainWidget = gtk_pizza_new();
f362b96d
RR
450 gtk_widget_show( m_mainWidget );
451 GTK_WIDGET_UNSET_FLAGS( m_mainWidget, GTK_CAN_FOCUS );
452 gtk_container_add( GTK_CONTAINER(m_widget), m_mainWidget );
88ac883a 453
2e563988 454#ifdef __WXDEBUG__
223d09f6 455 debug_focus_in( m_mainWidget, wxT("wxFrame::m_mainWidget"), name );
2e563988
RR
456#endif
457
f362b96d 458 /* m_wxwindow only represents the client area without toolbar and menubar */
da048e3d 459 m_wxwindow = gtk_pizza_new();
fb1585ae 460 gtk_widget_show( m_wxwindow );
f362b96d 461 gtk_container_add( GTK_CONTAINER(m_mainWidget), m_wxwindow );
88ac883a 462
2e563988 463#ifdef __WXDEBUG__
223d09f6 464 debug_focus_in( m_wxwindow, wxT("wxFrame::m_wxwindow"), name );
2e563988
RR
465#endif
466
467 /* we donm't allow the frame to get the focus as otherwise
468 the frame will grabit at arbitrary fcous changes. */
469 GTK_WIDGET_UNSET_FLAGS( m_wxwindow, GTK_CAN_FOCUS );
ed7a557b 470
de8113d9
RR
471 if (m_parent) m_parent->AddChild( this );
472
54517652
RR
473 /* the user resized the frame by dragging etc. */
474 gtk_signal_connect( GTK_OBJECT(m_widget), "size_allocate",
475 GTK_SIGNAL_FUNC(gtk_frame_size_callback), (gpointer)this );
476
de8113d9
RR
477 PostCreation();
478
58dea4b0 479 /* we cannot set MWM hints and icons before the widget has
2b07d713
RR
480 been realized, so we do this directly after realization */
481 gtk_signal_connect( GTK_OBJECT(m_widget), "realize",
f03fc89f 482 GTK_SIGNAL_FUNC(gtk_frame_realized_callback), (gpointer) this );
88ac883a 483
ab2b3dd4 484 /* the only way to get the window size is to connect to this event */
fb1585ae
RR
485 gtk_signal_connect( GTK_OBJECT(m_widget), "configure_event",
486 GTK_SIGNAL_FUNC(gtk_frame_configure_callback), (gpointer)this );
8bbe427f 487
69ffe1d2
RR
488 /* disable native tab traversal */
489 gtk_signal_connect( GTK_OBJECT(m_widget), "focus",
490 GTK_SIGNAL_FUNC(gtk_frame_focus_callback), (gpointer)this );
491
fb1585ae 492 return TRUE;
362c6693 493}
c801d85f 494
19717c50 495wxFrame::~wxFrame()
c801d85f 496{
31c6b4fc 497 m_isBeingDeleted = TRUE;
88ac883a 498
7c0ea335 499 DeleteAllBars();
ed7a557b 500
fb1585ae 501 wxTopLevelWindows.DeleteObject( this );
2b854a32 502
0d2a2b60 503 if (wxTheApp->GetTopWindow() == this)
0d2a2b60 504 wxTheApp->SetTopWindow( (wxWindow*) NULL );
2b854a32 505
0d2a2b60 506 if (wxTopLevelWindows.Number() == 0)
0d2a2b60 507 wxTheApp->ExitMainLoop();
362c6693 508}
ed7a557b 509
7c0ea335
VZ
510// ----------------------------------------------------------------------------
511// overridden wxWindow methods
512// ----------------------------------------------------------------------------
513
debe6624 514bool wxFrame::Show( bool show )
c801d85f 515{
223d09f6 516 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
8bbe427f 517
35178437 518 if (show && !m_sizeSet)
fb1585ae 519 {
e27ce4e9
RR
520 /* by calling GtkOnSize here, we don't have to call
521 either after showing the frame, which would entail
f362b96d 522 much ugly flicker or from within the size_allocate
e27ce4e9 523 handler, because GTK 1.1.X forbids that. */
8bbe427f 524
35178437 525 GtkOnSize( m_x, m_y, m_width, m_height );
fb1585ae 526 }
8bbe427f 527
fb1585ae 528 return wxWindow::Show( show );
362c6693 529}
c801d85f 530
bfc6fde4 531void wxFrame::DoSetSize( int x, int y, int width, int height, int sizeFlags )
903f689b 532{
223d09f6 533 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
8bbe427f 534
ab2b3dd4 535 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
223d09f6 536 wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
88ac883a 537
ab2b3dd4 538 /* avoid recursions */
7c0ea335
VZ
539 if (m_resizing)
540 return;
fb1585ae
RR
541 m_resizing = TRUE;
542
543 int old_x = m_x;
544 int old_y = m_y;
7beba2fc 545
fb1585ae
RR
546 int old_width = m_width;
547 int old_height = m_height;
8bbe427f 548
85ad5eb5 549 if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0)
fb1585ae
RR
550 {
551 if (x != -1) m_x = x;
552 if (y != -1) m_y = y;
553 if (width != -1) m_width = width;
554 if (height != -1) m_height = height;
555 }
556 else
557 {
558 m_x = x;
559 m_y = y;
560 m_width = width;
561 m_height = height;
562 }
563
11e1c70d 564/*
fb1585ae
RR
565 if ((sizeFlags & wxSIZE_AUTO_WIDTH) == wxSIZE_AUTO_WIDTH)
566 {
567 if (width == -1) m_width = 80;
568 }
569
570 if ((sizeFlags & wxSIZE_AUTO_HEIGHT) == wxSIZE_AUTO_HEIGHT)
571 {
572 if (height == -1) m_height = 26;
573 }
11e1c70d 574*/
8bbe427f 575
fb1585ae
RR
576 if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
577 if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
0c77152e
RR
578 if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
579 if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
fb1585ae
RR
580
581 if ((m_x != -1) || (m_y != -1))
582 {
8bbe427f 583 if ((m_x != old_x) || (m_y != old_y))
0138c2de 584 {
8487f887 585 gtk_widget_set_uposition( m_widget, m_x, m_y );
0138c2de 586 }
fb1585ae 587 }
8bbe427f 588
fb1585ae
RR
589 if ((m_width != old_width) || (m_height != old_height))
590 {
ab2b3dd4 591 /* we set the size in GtkOnSize, i.e. mostly the actual resizing is
f03fc89f
VZ
592 done either directly before the frame is shown or in idle time
593 so that different calls to SetSize() don't lead to flicker. */
de8113d9 594 m_sizeSet = FALSE;
fb1585ae 595 }
8bbe427f 596
fb1585ae 597 m_resizing = FALSE;
903f689b
RR
598}
599
f9241296 600void wxFrame::DoGetClientSize( int *width, int *height ) const
c801d85f 601{
223d09f6 602 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
8bbe427f 603
f9241296 604 wxWindow::DoGetClientSize( width, height );
fb1585ae 605 if (height)
46dc76ba 606 {
41ca191f
RR
607 /* menu bar */
608 if (m_frameMenuBar)
f03fc89f 609 {
88ac883a 610 if (!m_menuBarDetached)
f03fc89f
VZ
611 (*height) -= wxMENU_HEIGHT;
612 else
613 (*height) -= wxPLACE_HOLDER;
614 }
88ac883a 615
dcf924a3 616#if wxUSE_STATUSBAR
f03fc89f 617 /* status bar */
fb1585ae 618 if (m_frameStatusBar) (*height) -= wxSTATUS_HEIGHT;
dcf924a3 619#endif
88ac883a 620
dcf924a3 621#if wxUSE_TOOLBAR
f03fc89f 622 /* tool bar */
fb1585ae
RR
623 if (m_frameToolBar)
624 {
f03fc89f
VZ
625 if (!m_toolBarDetached)
626 {
41ca191f
RR
627 int y = 0;
628 m_frameToolBar->GetSize( (int *) NULL, &y );
629 (*height) -= y;
f03fc89f
VZ
630 }
631 else
41ca191f 632 (*height) -= wxPLACE_HOLDER;
fb1585ae 633 }
dcf924a3 634#endif
88ac883a 635
f03fc89f 636 /* mini edge */
b2b3ccc5
RR
637 (*height) -= m_miniEdge*2 + m_miniTitle;
638 }
639 if (width)
640 {
641 (*width) -= m_miniEdge*2;
46dc76ba 642 }
362c6693 643}
c801d85f 644
bfc6fde4 645void wxFrame::DoSetClientSize( int width, int height )
b593568e 646{
223d09f6 647 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
8bbe427f 648
41ca191f
RR
649 /* menu bar */
650 if (m_frameMenuBar)
f03fc89f 651 {
88ac883a 652 if (!m_menuBarDetached)
f03fc89f
VZ
653 height += wxMENU_HEIGHT;
654 else
655 height += wxPLACE_HOLDER;
656 }
88ac883a 657
dcf924a3 658#if wxUSE_STATUSBAR
f03fc89f 659 /* status bar */
41ca191f 660 if (m_frameStatusBar) height += wxSTATUS_HEIGHT;
dcf924a3 661#endif
88ac883a 662
dcf924a3 663#if wxUSE_TOOLBAR
f03fc89f 664 /* tool bar */
41ca191f
RR
665 if (m_frameToolBar)
666 {
f03fc89f
VZ
667 if (!m_toolBarDetached)
668 {
41ca191f
RR
669 int y = 0;
670 m_frameToolBar->GetSize( (int *) NULL, &y );
671 height += y;
f03fc89f
VZ
672 }
673 else
41ca191f
RR
674 height += wxPLACE_HOLDER;
675 }
dcf924a3 676#endif
88ac883a 677
3017f78d 678 DoSetSize( -1, -1, width + m_miniEdge*2, height + m_miniEdge*2 + m_miniTitle, 0 );
362c6693 679}
b593568e 680
7c0ea335
VZ
681void wxFrame::GtkOnSize( int WXUNUSED(x), int WXUNUSED(y),
682 int width, int height )
c801d85f 683{
f5368809
RR
684 // due to a bug in gtk, x,y are always 0
685 // m_x = x;
686 // m_y = y;
687
ab2b3dd4 688 /* avoid recursions */
e52f60e6
RR
689 if (m_resizing) return;
690 m_resizing = TRUE;
8bbe427f 691
ab2b3dd4 692 /* this shouldn't happen: wxFrame, wxMDIParentFrame and wxMDIChildFrame have m_wxwindow */
223d09f6 693 wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
88ac883a 694
f5368809
RR
695 m_width = width;
696 m_height = height;
7beba2fc 697
ab2b3dd4 698 /* space occupied by m_frameToolBar and m_frameMenuBar */
88ac883a 699 int client_area_y_offset = 0;
8bbe427f 700
ab2b3dd4
RR
701 /* wxMDIChildFrame derives from wxFrame but it _is_ a wxWindow as it uses
702 wxWindow::Create to create it's GTK equivalent. m_mainWidget is only
703 set in wxFrame::Create so it is used to check what kind of frame we
704 have here. if m_mainWidget is NULL it is a wxMDIChildFrame and so we
705 skip the part which handles m_frameMenuBar, m_frameToolBar and (most
706 importantly) m_mainWidget */
88ac883a 707
ab2b3dd4 708 if (m_mainWidget)
f5368809 709 {
ab2b3dd4
RR
710 /* check if size is in legal range */
711 if ((m_minWidth != -1) && (m_width < m_minWidth)) m_width = m_minWidth;
712 if ((m_minHeight != -1) && (m_height < m_minHeight)) m_height = m_minHeight;
713 if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth;
714 if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight;
715
716 /* I revert back to wxGTK's original behaviour. m_mainWidget holds the
717 * menubar, the toolbar and the client area, which is represented by
718 * m_wxwindow.
719 * this hurts in the eye, but I don't want to call SetSize()
720 * because I don't want to call any non-native functions here. */
88ac883a 721
ab2b3dd4
RR
722 if (m_frameMenuBar)
723 {
724 int xx = m_miniEdge;
725 int yy = m_miniEdge + m_miniTitle;
726 int ww = m_width - 2*m_miniEdge;
41ca191f 727 int hh = wxMENU_HEIGHT;
f03fc89f 728 if (m_menuBarDetached) hh = wxPLACE_HOLDER;
121a3581
RR
729 m_frameMenuBar->m_x = xx;
730 m_frameMenuBar->m_y = yy;
731 m_frameMenuBar->m_width = ww;
732 m_frameMenuBar->m_height = hh;
da048e3d 733 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
88ac883a 734 m_frameMenuBar->m_widget,
f03fc89f
VZ
735 xx, yy, ww, hh );
736 client_area_y_offset += hh;
ab2b3dd4 737 }
88ac883a 738
dcf924a3 739#if wxUSE_TOOLBAR
11e1c70d 740 if ((m_frameToolBar) &&
7beba2fc 741 (m_frameToolBar->m_widget->parent == m_mainWidget))
ab2b3dd4
RR
742 {
743 int xx = m_miniEdge;
744 int yy = m_miniEdge + m_miniTitle;
41ca191f 745 if (m_frameMenuBar)
f03fc89f 746 {
88ac883a
VZ
747 if (!m_menuBarDetached)
748 yy += wxMENU_HEIGHT;
749 else
f03fc89f
VZ
750 yy += wxPLACE_HOLDER;
751 }
ab2b3dd4 752 int ww = m_width - 2*m_miniEdge;
a2053b27 753 int hh = m_frameToolBar->m_height;
7beba2fc 754 if (m_toolBarDetached) hh = wxPLACE_HOLDER;
121a3581
RR
755 m_frameToolBar->m_x = xx;
756 m_frameToolBar->m_y = yy;
11e1c70d
RR
757 /* m_frameToolBar->m_height = hh; don't change the toolbar's reported size
758 m_frameToolBar->m_width = ww; */
da048e3d 759 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
88ac883a 760 m_frameToolBar->m_widget,
f03fc89f
VZ
761 xx, yy, ww, hh );
762 client_area_y_offset += hh;
ab2b3dd4 763 }
dcf924a3 764#endif
88ac883a 765
32a95f9f 766 int client_x = m_miniEdge;
f03fc89f 767 int client_y = client_area_y_offset + m_miniEdge + m_miniTitle;
32a95f9f 768 int client_w = m_width - 2*m_miniEdge;
f03fc89f 769 int client_h = m_height - client_area_y_offset- 2*m_miniEdge - m_miniTitle;
da048e3d 770 gtk_pizza_set_size( GTK_PIZZA(m_mainWidget),
88ac883a 771 m_wxwindow,
f03fc89f 772 client_x, client_y, client_w, client_h );
32a95f9f
RR
773 }
774 else
775 {
776 /* if there is no m_mainWidget between m_widget and m_wxwindow there
f03fc89f 777 is no need to set the size or position of m_wxwindow. */
f5368809 778 }
88ac883a 779
dcf924a3 780#if wxUSE_STATUSBAR
f5368809
RR
781 if (m_frameStatusBar)
782 {
b2b3ccc5 783 int xx = 0 + m_miniEdge;
f362b96d 784 int yy = m_height - wxSTATUS_HEIGHT - m_miniEdge - client_area_y_offset;
ac57418f
RR
785 int ww = m_width - 2*m_miniEdge;
786 int hh = wxSTATUS_HEIGHT;
121a3581
RR
787 m_frameStatusBar->m_x = xx;
788 m_frameStatusBar->m_y = yy;
789 m_frameStatusBar->m_width = ww;
790 m_frameStatusBar->m_height = hh;
da048e3d 791 gtk_pizza_set_size( GTK_PIZZA(m_wxwindow),
7c0ea335
VZ
792 m_frameStatusBar->m_widget,
793 xx, yy, ww, hh );
f5368809 794 }
dcf924a3 795#endif
8bbe427f 796
de8113d9
RR
797 /* we actually set the size of a frame here and no-where else */
798 gtk_widget_set_usize( m_widget, m_width, m_height );
88ac883a 799
54517652 800 m_sizeSet = TRUE;
7beba2fc 801
54517652 802 // send size event to frame
43a18898
RR
803 wxSizeEvent event( wxSize(m_width,m_height), GetId() );
804 event.SetEventObject( this );
e52f60e6 805 GetEventHandler()->ProcessEvent( event );
8bbe427f 806
54517652 807 // send size event to status bar
5aa5e35a
RR
808 if (m_frameStatusBar)
809 {
a2053b27 810 wxSizeEvent event2( wxSize(m_frameStatusBar->m_width,m_frameStatusBar->m_height), m_frameStatusBar->GetId() );
5aa5e35a
RR
811 event2.SetEventObject( m_frameStatusBar );
812 m_frameStatusBar->GetEventHandler()->ProcessEvent( event2 );
813 }
884470b1 814
e52f60e6
RR
815 m_resizing = FALSE;
816}
817
ca26177c
RR
818void wxFrame::MakeModal( bool modal )
819{
820 if (modal)
ca26177c 821 gtk_grab_add( m_widget );
ca26177c 822 else
c25ccf85 823 gtk_grab_remove( m_widget );
ca26177c
RR
824}
825
9390a202 826void wxFrame::OnInternalIdle()
e52f60e6 827{
1b3667ab 828 if (!m_sizeSet && GTK_WIDGET_REALIZED(m_wxwindow))
54517652 829 {
e52f60e6 830 GtkOnSize( m_x, m_y, m_width, m_height );
7beba2fc
VZ
831
832 // we'll come back later
54517652
RR
833 if (g_isIdle)
834 wxapp_install_idle_handler();
7beba2fc 835 return;
54517652 836 }
88ac883a 837
082b2798 838 if (m_frameMenuBar) m_frameMenuBar->OnInternalIdle();
dcf924a3 839#if wxUSE_TOOLBAR
082b2798 840 if (m_frameToolBar) m_frameToolBar->OnInternalIdle();
dcf924a3
RR
841#endif
842#if wxUSE_STATUSBAR
082b2798 843 if (m_frameStatusBar) m_frameStatusBar->OnInternalIdle();
dcf924a3 844#endif
5e014a0c
RR
845
846 wxWindow::OnInternalIdle();
362c6693 847}
c801d85f 848
7c0ea335
VZ
849// ----------------------------------------------------------------------------
850// menu/tool/status bar stuff
851// ----------------------------------------------------------------------------
c801d85f 852
c801d85f
KB
853void wxFrame::SetMenuBar( wxMenuBar *menuBar )
854{
223d09f6
KB
855 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
856 wxASSERT_MSG( (m_wxwindow != NULL), wxT("invalid frame") );
8bbe427f 857
f5368809 858 m_frameMenuBar = menuBar;
8bbe427f 859
f5368809 860 if (m_frameMenuBar)
30dea054 861 {
5bd9e519 862 m_frameMenuBar->SetInvokingWindow( this );
8bbe427f 863
f03fc89f 864 if (m_frameMenuBar->GetParent() != this)
f5368809 865 {
f03fc89f 866 m_frameMenuBar->SetParent(this);
da048e3d 867 gtk_pizza_put( GTK_PIZZA(m_mainWidget),
88ac883a
VZ
868 m_frameMenuBar->m_widget,
869 m_frameMenuBar->m_x,
a2053b27
RR
870 m_frameMenuBar->m_y,
871 m_frameMenuBar->m_width,
872 m_frameMenuBar->m_height );
88ac883a 873
f03fc89f
VZ
874 if (menuBar->GetWindowStyle() & wxMB_DOCKABLE)
875 {
a2053b27 876 gtk_signal_connect( GTK_OBJECT(menuBar->m_widget), "child_attached",
16bcc879 877 GTK_SIGNAL_FUNC(gtk_menu_attached_callback), (gpointer)this );
88ac883a 878
a2053b27 879 gtk_signal_connect( GTK_OBJECT(menuBar->m_widget), "child_detached",
16bcc879 880 GTK_SIGNAL_FUNC(gtk_menu_detached_callback), (gpointer)this );
f03fc89f 881 }
7beba2fc
VZ
882
883 m_frameMenuBar->Show( TRUE );
f5368809 884 }
716b7364 885 }
8bbe427f 886
1e133b7d 887 /* resize window in OnInternalIdle */
5b077d48 888 m_sizeSet = FALSE;
362c6693 889}
c801d85f 890
88ac883a 891#if wxUSE_TOOLBAR
6bc8a1c8 892wxToolBar* wxFrame::CreateToolBar( long style, wxWindowID id, const wxString& name )
46dc76ba 893{
223d09f6 894 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
8bbe427f 895
6bc8a1c8 896 m_insertInClientArea = FALSE;
88ac883a 897
7c0ea335 898 m_frameToolBar = wxFrameBase::CreateToolBar( style, id, name );
8bbe427f 899
7c0ea335
VZ
900 if (m_frameToolBar)
901 GetChildren().DeleteObject( m_frameToolBar );
88ac883a 902
6bc8a1c8 903 m_insertInClientArea = TRUE;
8bbe427f 904
5b077d48 905 m_sizeSet = FALSE;
8bbe427f 906
f5368809 907 return m_frameToolBar;
362c6693 908}
46dc76ba 909
7beba2fc
VZ
910void wxFrame::SetToolBar(wxToolBar *toolbar)
911{
7c0ea335
VZ
912 wxFrameBase::SetToolBar(toolbar);
913
307f16e8
RR
914 if (m_frameToolBar)
915 {
916 /* insert into toolbar area if not already there */
3017f78d
RR
917 if ((m_frameToolBar->m_widget->parent) &&
918 (m_frameToolBar->m_widget->parent != m_mainWidget))
307f16e8 919 {
3017f78d 920 GetChildren().DeleteObject( m_frameToolBar );
7beba2fc
VZ
921
922 gtk_widget_reparent( m_frameToolBar->m_widget, m_mainWidget );
923 UpdateSize();
924 }
307f16e8
RR
925 }
926}
927
88ac883a 928#endif // wxUSE_TOOLBAR
46dc76ba 929
88ac883a 930#if wxUSE_STATUSBAR
8bbe427f 931
7c0ea335
VZ
932wxStatusBar* wxFrame::CreateStatusBar(int number,
933 long style,
934 wxWindowID id,
935 const wxString& name)
c801d85f 936{
223d09f6 937 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
8bbe427f 938
7c0ea335
VZ
939 // because it will change when toolbar is added
940 m_sizeSet = FALSE;
c801d85f 941
7c0ea335 942 return wxFrameBase::CreateStatusBar( number, style, id, name );
362c6693
RR
943}
944
88ac883a 945#endif // wxUSE_STATUSBAR
c801d85f 946
7c0ea335
VZ
947// ----------------------------------------------------------------------------
948// frame title/icon
949// ----------------------------------------------------------------------------
c801d85f 950
c801d85f
KB
951void wxFrame::SetTitle( const wxString &title )
952{
223d09f6 953 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
8bbe427f 954
f5368809 955 m_title = title;
ed9b9841 956 gtk_window_set_title( GTK_WINDOW(m_widget), title.mbc_str() );
362c6693 957}
c801d85f 958
d355d3fe
RR
959void wxFrame::SetIcon( const wxIcon &icon )
960{
223d09f6 961 wxASSERT_MSG( (m_widget != NULL), wxT("invalid frame") );
8bbe427f 962
7c0ea335 963 wxFrameBase::SetIcon(icon);
8bbe427f 964
7c0ea335
VZ
965 if ( !m_icon.Ok() )
966 return;
967
968 if (!m_widget->window)
969 return;
58dea4b0 970
f5368809
RR
971 wxMask *mask = icon.GetMask();
972 GdkBitmap *bm = (GdkBitmap *) NULL;
973 if (mask) bm = mask->GetBitmap();
8bbe427f 974
f5368809 975 gdk_window_set_icon( m_widget->window, (GdkWindow *) NULL, icon.GetPixmap(), bm );
d355d3fe 976}
b2b3ccc5 977
7c0ea335
VZ
978// ----------------------------------------------------------------------------
979// frame state: maximized/iconized/normal (TODO)
980// ----------------------------------------------------------------------------
981
7beba2fc 982void wxFrame::Maximize(bool WXUNUSED(maximize))
cd25b18c
RR
983{
984}
985
7c0ea335
VZ
986bool wxFrame::IsMaximized() const
987{
988 return FALSE;
989}
990
7beba2fc 991void wxFrame::Restore()
cd25b18c
RR
992{
993}
994
7beba2fc
VZ
995void wxFrame::Iconize( bool iconize )
996{
cd25b18c
RR
997 if (iconize)
998 {
999 XIconifyWindow( GDK_WINDOW_XDISPLAY( m_widget->window ),
7beba2fc
VZ
1000 GDK_WINDOW_XWINDOW( m_widget->window ),
1001 DefaultScreen( GDK_DISPLAY() ) );
cd25b18c
RR
1002 }
1003}
1004
7beba2fc
VZ
1005bool wxFrame::IsIconized() const
1006{
1007 return FALSE;
cd25b18c 1008}