X-Git-Url: https://git.saurik.com/wxWidgets.git/blobdiff_plain/bbbbe360a81bab2ce9bc83aed4719765fd46d297..fc9ef629ac8733c4f0b844356782cca80ae09c4b:/src/gtk1/window.cpp diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index 4c95e23186..89b75f8a9d 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -9,7 +9,7 @@ #ifdef __GNUG__ -#pragma implementation "window.h" + #pragma implementation "window.h" #endif #include "wx/defs.h" @@ -21,10 +21,15 @@ #include "wx/utils.h" #include "wx/dialog.h" #include "wx/msgdlg.h" + #if wxUSE_DRAG_AND_DROP -#include "wx/dnd.h" + #include "wx/dnd.h" +#endif + +#if wxUSE_TOOLTIPS + #include "wx/tooltip.h" #endif -#include "wx/tooltip.h" + #include "wx/menu.h" #include "wx/statusbr.h" #include "wx/intl.h" @@ -242,6 +247,8 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e switch (gdk_event->keyval) { case GDK_BackSpace: key_code = WXK_BACK; break; + case GDK_ISO_Left_Tab: + case GDK_KP_Tab: case GDK_Tab: key_code = WXK_TAB; break; case GDK_Linefeed: key_code = WXK_RETURN; break; case GDK_Clear: key_code = WXK_CLEAR; break; @@ -266,7 +273,6 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e case GDK_Execute: key_code = WXK_EXECUTE; break; case GDK_Insert: key_code = WXK_INSERT; break; case GDK_Num_Lock: key_code = WXK_NUMLOCK; break; - case GDK_KP_Tab: key_code = WXK_TAB; break; case GDK_KP_Enter: key_code = WXK_RETURN; break; case GDK_KP_Home: key_code = WXK_HOME; break; case GDK_KP_Left: key_code = WXK_LEFT; break; @@ -347,16 +353,30 @@ static gint gtk_window_key_press_callback( GtkWidget *widget, GdkEventKey *gdk_e } // win is a control: tab can be propagated up - if ((!ret) && (gdk_event->keyval == GDK_Tab) && ((win->m_windowStyle & wxTE_PROCESS_TAB) == 0)) + if ( (!ret) && + ((gdk_event->keyval == GDK_Tab) || (gdk_event->keyval == GDK_ISO_Left_Tab)) && + ((win->m_windowStyle & wxTE_PROCESS_TAB) == 0)) { wxNavigationKeyEvent new_event; - new_event.SetDirection( !(gdk_event->state & GDK_SHIFT_MASK) ); - new_event.SetWindowChange( FALSE ); + /* GDK reports GDK_ISO_Left_Tab for SHIFT-TAB */ + new_event.SetDirection( (gdk_event->keyval == GDK_Tab) ); + /* CTRL-TAB changes the (parent) window, i.e. switch notebook page */ + new_event.SetWindowChange( (gdk_event->state & GDK_CONTROL_MASK) ); new_event.SetCurrentFocus( win ); ret = win->GetEventHandler()->ProcessEvent( new_event ); } + if ( (!ret) && + (gdk_event->keyval == GDK_Escape) ) + { + wxCommandEvent new_event(wxEVT_COMMAND_BUTTON_CLICKED,wxID_CANCEL); + new_event.SetEventObject( win ); + ret = win->GetEventHandler()->ProcessEvent( new_event ); + } + /* + Damn, I forgot why this didn't work, but it didn't work. + // win is a panel: up can be propagated to the panel if ((!ret) && (win->m_wxwindow) && (win->m_parent) && (win->m_parent->AcceptsFocus()) && (gdk_event->keyval == GDK_Up)) @@ -405,6 +425,8 @@ static gint gtk_window_key_release_callback( GtkWidget *widget, GdkEventKey *gdk switch (gdk_event->keyval) { case GDK_BackSpace: key_code = WXK_BACK; break; + case GDK_ISO_Left_Tab: + case GDK_KP_Tab: case GDK_Tab: key_code = WXK_TAB; break; case GDK_Linefeed: key_code = WXK_RETURN; break; case GDK_Clear: key_code = WXK_CLEAR; break; @@ -429,7 +451,6 @@ static gint gtk_window_key_release_callback( GtkWidget *widget, GdkEventKey *gdk case GDK_Execute: key_code = WXK_EXECUTE; break; case GDK_Insert: key_code = WXK_INSERT; break; case GDK_Num_Lock: key_code = WXK_NUMLOCK; break; - case GDK_KP_Tab: key_code = WXK_TAB; break; case GDK_KP_Enter: key_code = WXK_RETURN; break; case GDK_KP_Home: key_code = WXK_HOME; break; case GDK_KP_Left: key_code = WXK_LEFT; break; @@ -495,7 +516,7 @@ static gint gtk_window_key_release_callback( GtkWidget *widget, GdkEventKey *gdk if (ret) { - gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_press_event" ); + gtk_signal_emit_stop_by_name( GTK_OBJECT(widget), "key_release_event" ); } return ret; @@ -1060,6 +1081,7 @@ static void gtk_window_vscroll_callback( GtkWidget *WXUNUSED(widget), wxWindow * float diff = win->m_vAdjust->value - win->m_oldVerticalPos; if (fabs(diff) < 0.2) return; + win->m_oldVerticalPos = win->m_vAdjust->value; wxEventType command = wxEVT_NULL; @@ -1107,6 +1129,7 @@ static void gtk_window_hscroll_callback( GtkWidget *WXUNUSED(widget), wxWindow * float diff = win->m_hAdjust->value - win->m_oldHorizontalPos; if (fabs(diff) < 0.2) return; + win->m_oldHorizontalPos = win->m_hAdjust->value; wxEventType command = wxEVT_NULL; @@ -1288,8 +1311,10 @@ BEGIN_EVENT_TABLE(wxWindow, wxEvtHandler) EVT_KEY_DOWN(wxWindow::OnKeyDown) END_EVENT_TABLE() -wxWindow::wxWindow() +void wxWindow::Init() { + m_isWindow = TRUE; + m_widget = (GtkWidget *) NULL; m_wxwindow = (GtkWidget *) NULL; m_parent = (wxWindow *) NULL; @@ -1356,11 +1381,17 @@ wxWindow::wxWindow() #endif // wxUSE_TOOLTIPS } +wxWindow::wxWindow() +{ + Init(); +} + wxWindow::wxWindow( wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name ) { - m_insertCallback = wxInsertChildInWindow; + Init(); + Create( parent, id, pos, size, style, name ); } @@ -1368,9 +1399,7 @@ bool wxWindow::Create( wxWindow *parent, wxWindowID id, const wxPoint &pos, const wxSize &size, long style, const wxString &name ) { - m_isShown = FALSE; - m_isEnabled = TRUE; - m_needParent = TRUE; + wxASSERT_MSG( m_isWindow, "Init() must have been called before!" ); PreCreation( parent, id, pos, size, style, name ); @@ -1511,18 +1540,27 @@ wxWindow::~wxWindow() m_hasVMT = FALSE; #if wxUSE_DRAG_AND_DROP - wxDELETE(m_dropTarget); + if (m_dropTarget) + { + delete m_dropTarget; + m_dropTarget = (wxDropTarget*) NULL; + } #endif #if wxUSE_TOOLTIPS - wxDELETE(m_toolTip); + if (m_toolTip) + { + delete m_toolTip; + m_toolTip = (wxToolTip*) NULL; + } #endif // wxUSE_TOOLTIPS - if (m_parent) m_parent->RemoveChild( this ); if (m_widget) Show( FALSE ); DestroyChildren(); + if (m_parent) m_parent->RemoveChild( this ); + if (m_widgetStyle) gtk_style_unref( m_widgetStyle ); if (m_scrollGC) gdk_gc_unref( m_scrollGC ); @@ -1536,28 +1574,29 @@ wxWindow::~wxWindow() DeleteRelatedConstraints(); if (m_constraints) { - // This removes any dangling pointers to this window - // in other windows' constraintsInvolvedIn lists. + /* This removes any dangling pointers to this window + * in other windows' constraintsInvolvedIn lists. */ UnsetConstraints(m_constraints); delete m_constraints; m_constraints = (wxLayoutConstraints *) NULL; } + if (m_windowSizer) { delete m_windowSizer; m_windowSizer = (wxSizer *) NULL; } - // If this is a child of a sizer, remove self from parent + /* If this is a child of a sizer, remove self from parent */ if (m_sizerParent) m_sizerParent->RemoveChild((wxWindow *)this); - // Just in case the window has been Closed, but - // we're then deleting immediately: don't leave - // dangling pointers. + /* Just in case the window has been Closed, but + * we're then deleting immediately: don't leave + * dangling pointers. */ wxPendingDelete.DeleteObject(this); - // Just in case we've loaded a top-level window via - // wxWindow::LoadNativeDialog but we weren't a dialog - // class + /* Just in case we've loaded a top-level window via + * wxWindow::LoadNativeDialog but we weren't a dialog + * class */ wxTopLevelWindows.DeleteObject(this); if (m_windowValidator) delete m_windowValidator; @@ -1585,7 +1624,7 @@ void wxWindow::PreCreation( wxWindow *parent, wxWindowID id, m_x = (int)pos.x; m_y = (int)pos.y; - if (!m_needParent) // some reasonable defaults + if (!m_needParent) /* some reasonable defaults */ { if (m_x == -1) { @@ -1655,18 +1694,21 @@ void wxWindow::PreCreation( wxWindow *parent, wxWindowID id, void wxWindow::PostCreation() { + wxASSERT_MSG( (m_widget != NULL), "invalid window" ); + if (m_wxwindow) { - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", - GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this ); + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "expose_event", + GTK_SIGNAL_FUNC(gtk_window_expose_callback), (gpointer)this ); - gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw", - GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this ); + gtk_signal_connect( GTK_OBJECT(m_wxwindow), "draw", + GTK_SIGNAL_FUNC(gtk_window_draw_callback), (gpointer)this ); } ConnectWidget( GetConnectWidget() ); - if (m_widget && m_parent) gtk_widget_realize( m_widget ); + /* we force the creation of wxFrame and wxDialog in the respective code */ + if (m_parent) gtk_widget_realize( m_widget ); if (m_wxwindow) gtk_widget_realize( m_wxwindow ); @@ -1718,13 +1760,9 @@ bool wxWindow::Close( bool force ) event.SetEventObject(this); event.SetCanVeto(!force); - (void)GetEventHandler()->ProcessEvent(event); - - // when we're forced to close we do it anyhow, otherwise only if the - // application didn't forbid it (if the event wasn't processed, GetVeto() - // will return FALSE too) - if ( force || !event.GetVeto() ) - Destroy(); + /* return FALSE if window wasn't closed because the application vetoed the + * close event */ + return GetEventHandler()->ProcessEvent(event) && !event.GetVeto(); } bool wxWindow::Destroy() @@ -1771,17 +1809,17 @@ void wxWindow::AdjustForParentClientOrigin( int& x, int& y, int sizeFlags ) } } -void wxWindow::SetSize( int x, int y, int width, int height, int sizeFlags ) +void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags ) { wxASSERT_MSG( (m_widget != NULL), "invalid window" ); wxASSERT_MSG( (m_parent != NULL), "wxWindow::SetSize requires parent.\n" ); - if (m_resizing) return; // I don't like recursions + if (m_resizing) return; /* I don't like recursions */ m_resizing = TRUE; - if (m_parent->m_wxwindow == NULL) // i.e. wxNotebook + if (m_parent->m_wxwindow == NULL) /* i.e. wxNotebook */ { - // don't set the size for children of wxNotebook, just take the values. + /* don't set the size for children of wxNotebook, just take the values. */ m_x = x; m_y = y; m_width = width; @@ -1822,11 +1860,24 @@ void wxWindow::SetSize( int x, int y, int width, int height, int sizeFlags ) if ((m_maxWidth != -1) && (m_width > m_maxWidth)) m_width = m_maxWidth; if ((m_maxHeight != -1) && (m_height > m_maxHeight)) m_height = m_maxHeight; - wxPoint pt( m_parent->GetClientAreaOrigin() ); - gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x+pt.x, m_y+pt.y ); + if (GTK_WIDGET_HAS_DEFAULT(m_widget)) + { + /* the default button has a border around it */ + int border = 5; + + wxPoint pt( m_parent->GetClientAreaOrigin() ); + gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x+pt.x-border, m_y+pt.y-border ); - if ((old_width != m_width) || (old_height != m_height)) - gtk_widget_set_usize( m_widget, m_width, m_height ); + gtk_widget_set_usize( m_widget, m_width+2*border, m_height+2*border ); + } + else + { + wxPoint pt( m_parent->GetClientAreaOrigin() ); + gtk_myfixed_move( GTK_MYFIXED(m_parent->m_wxwindow), m_widget, m_x+pt.x, m_y+pt.y ); + + if ((old_width != m_width) || (old_height != m_height)) + gtk_widget_set_usize( m_widget, m_width, m_height ); + } } m_sizeSet = TRUE; @@ -1843,16 +1894,6 @@ void wxWindow::OnInternalIdle() UpdateWindowUI(); } -void wxWindow::SetSize( int width, int height ) -{ - SetSize( -1, -1, width, height, wxSIZE_USE_EXISTING ); -} - -void wxWindow::Move( int x, int y ) -{ - SetSize( x, y, -1, -1, wxSIZE_USE_EXISTING ); -} - void wxWindow::GetSize( int *width, int *height ) const { wxCHECK_RET( (m_widget != NULL), "invalid window" ); @@ -1861,7 +1902,7 @@ void wxWindow::GetSize( int *width, int *height ) const if (height) (*height) = m_height; } -void wxWindow::SetClientSize( int width, int height ) +void wxWindow::DoSetClientSize( int width, int height ) { wxCHECK_RET( (m_widget != NULL), "invalid window" ); @@ -2125,6 +2166,8 @@ bool wxWindow::Show( bool show ) { wxCHECK_MSG( (m_widget != NULL), FALSE, "invalid window" ); + if (show == m_isShown) return TRUE; + if (show) gtk_widget_show( m_widget ); else @@ -2418,12 +2461,11 @@ void wxWindow::Refresh( bool eraseBackground, const wxRect *rect ) { gdk_window_clear_area( m_wxwindow->window, rect->x, rect->y, - rect->width, - rect->height ); + rect->width, rect->height ); } else { - Clear(); + gdk_window_clear( m_wxwindow->window ); } } @@ -2478,7 +2520,10 @@ void wxWindow::Clear() { wxCHECK_RET( m_widget != NULL, "invalid window" ); - if (m_wxwindow && m_wxwindow->window) gdk_window_clear( m_wxwindow->window ); + if (m_wxwindow && m_wxwindow->window) + { + gdk_window_clear( m_wxwindow->window ); + } } #if wxUSE_TOOLTIPS @@ -2531,14 +2576,18 @@ void wxWindow::SetBackgroundColour( const wxColour &colour ) m_backgroundColour = colour; if (!m_backgroundColour.Ok()) return; - if (m_wxwindow) + if (m_wxwindow && m_wxwindow->window) { - GdkWindow *window = m_wxwindow->window; - m_backgroundColour.CalcPixel( gdk_window_get_colormap( window ) ); - gdk_window_set_background( window, m_backgroundColour.GetColor() ); + /* wxMSW doesn't clear the window here. I don't do that + either to provide compatibility. call Clear() to do + the job. */ + + m_backgroundColour.CalcPixel( gdk_window_get_colormap( m_wxwindow->window ) ); + gdk_window_set_background( m_wxwindow->window, m_backgroundColour.GetColor() ); } wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE ); + if (sysbg.Red() == colour.Red() && sysbg.Green() == colour.Green() && sysbg.Blue() == colour.Blue()) @@ -2731,6 +2780,8 @@ bool wxWindow::PopupMenu( wxMenu *menu, int x, int y ) SetInvokingWindow( menu, this ); + menu->UpdateUI(); + gs_pop_x = x; gs_pop_y = y; @@ -2786,7 +2837,9 @@ bool wxWindow::IsOwnGtkWindow( GdkWindow *window ) void wxWindow::SetFont( const wxFont &font ) { wxCHECK_RET( m_widget != NULL, "invalid window" ); - + + if (m_font == font) return; + if (((wxFont*)&font)->Ok()) m_font = font; else