some more information about what the wxWindow, which is the base class
for all other window classes, does seems required as well.
+ I)
+
What does wxWindow do? It contains the common interface for the following
jobs of its descendants:
5) A multitude of helper or extra methods for special purposes, such as
Drag'n'Drop, managing validators etc.
+ 6) Display a border (sunken, raised, simple or none).
+
Normally one might expect, that one wxWindows window would always correspond
to one GTK widget. Under GTK, there is no such allround widget that has all
the functionality. Moreover, the GTK defines a client area as a different
If the m_wxwindow field is set, then all input to this widget is inter-
cepted and sent to the wxWindows class. If not, all input to the widget
that gets pointed to by m_widget gets intercepted and sent to the class.
+
+ II)
+
+ The design of scrolling in wxWindows is markedly different from that offered
+ by the GTK itself and therefore we cannot simply take it as it is. In GTK,
+ clicking on a scrollbar belonging to scrolled window will inevitably move
+ the window. In wxWindows, the scrollbar will only emit an event, send this
+ to (normally) a wxScrolledWindow and that class will call ScrollWindow()
+ which actually move the window and its subchildren. Note that GtkMyFixed
+ memorizes how much it has been scrolled but that wxWindows forgets this
+ so that the two coordinates systems have to be kept in synch. This is done
+ in various places using the myfixed->xoffset and myfixed->yoffset values.
+
+ III)
+
+ Singularily the most broken code in GTK is the code that is supposes to
+ inform subwindows (child windows) about new positions. Very often, duplicate
+ events are sent without changes in size or position, equally often no
+ events are sent at all (All this is due to a bug in the GtkContainer code
+ which got fixed in GTK 1.2.6). For that reason, wxGTK completely ignores
+ GTK's own system and it simply waits for size events for toplevel windows
+ and then iterates down the respective size events to all window. This has
+ the disadvantage, that windows might get size events before the GTK widget
+ actually has the reported size. This doesn't normally pose any problem, but
+ the OpenGl drawing routines rely in correct behaviour. Therefore, I have
+ added the m_nativeSizeEvents flag, which is true only for the OpenGL canvas,
+ i.e. the wxGLCanvas will emit a size event, when (and not before) the X11
+ window that is used for OpenGl output really has that size (as reported by
+ GTK).
+
+ IV)
+
+ If someone at some point of time feels the immense desire to have a look at,
+ change or attempt to optimse the Refresh() logic, this person will need an
+ intimate understanding of what a "draw" and what an "expose" events are and
+ what there are used for, in particular when used in connection with GTK's
+ own windowless widgets. Beware.
+
+ V)
+
+ Cursors, too, have been a constant source of pleasure. The main difficulty
+ is that a GdkWindow inherits a cursor if the programmer sets a new cursor
+ for the parent. To prevent this from doing too much harm, I use idle time
+ to set the cursor over and over again, starting from the toplevel windows
+ and ending with the youngest generation (speaking of parent and child windows).
+ Also don't forget that cursors (like much else) are connected to GdkWindows,
+ not GtkWidgets and that the "window" field of a GtkWidget might very well
+ point to the GdkWindow of the parent widget (-> "window less widget") and
+ that the two obviously have very different meanings.
*/
wxLog::AddTraceMask("focus");
s_done = TRUE;
}
- wxLogTrace(_T("FOCUS NOW AT: %s"), name);
+ wxLogTrace(wxT("FOCUS NOW AT: %s"), name);
*/
return FALSE;
void debug_focus_in( GtkWidget* widget, const wxChar* name, const wxChar *window )
{
wxString tmp = name;
- tmp += _T(" FROM ");
+ tmp += wxT(" FROM ");
tmp += window;
wxChar *s = new wxChar[tmp.Length()+1];
extern void wxapp_install_idle_handler();
extern bool g_isIdle;
+//-----------------------------------------------------------------------------
+// local code (see below)
+//-----------------------------------------------------------------------------
+
+#if (GTK_MINOR_VERSION > 0)
+
+static void draw_frame( GtkWidget *widget, wxWindow *win )
+{
+ if (!win->m_hasVMT)
+ return;
+
+ int dw = 0;
+ int dh = 0;
+
+ if (win->HasScrolling())
+ {
+ GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(widget);
+ GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget)->klass );
+
+/*
+ GtkWidget *hscrollbar = scroll_window->hscrollbar;
+ GtkWidget *vscrollbar = scroll_window->vscrollbar;
+
+ we use this instead: range.slider_width = 11 + 2*2pts edge
+*/
+
+ if (scroll_window->vscrollbar_visible)
+ {
+ dw += 15; /* dw += vscrollbar->allocation.width; */
+ dw += scroll_class->scrollbar_spacing;
+ }
+
+ if (scroll_window->hscrollbar_visible)
+ {
+ dh += 15; /* dh += hscrollbar->allocation.height; */
+ dh += scroll_class->scrollbar_spacing;
+ }
+ }
+
+ int dx = 0;
+ int dy = 0;
+ if (GTK_WIDGET_NO_WINDOW (widget))
+ {
+ dx += widget->allocation.x;
+ dy += widget->allocation.y;
+ }
+
+ if (win->HasFlag(wxRAISED_BORDER))
+ {
+ gtk_draw_shadow( widget->style,
+ widget->window,
+ GTK_STATE_NORMAL,
+ GTK_SHADOW_OUT,
+ dx, dy,
+ win->m_width-dw, win->m_height-dh );
+ return;
+ }
+
+ if (win->HasFlag(wxSUNKEN_BORDER))
+ {
+ gtk_draw_shadow( widget->style,
+ widget->window,
+ GTK_STATE_NORMAL,
+ GTK_SHADOW_IN,
+ dx, dy,
+ win->m_width-dw, win->m_height-dh );
+ return;
+ }
+
+ if (win->HasFlag(wxSIMPLE_BORDER))
+ {
+ GdkGC *gc;
+ gc = gdk_gc_new( widget->window );
+ gdk_gc_set_foreground( gc, &widget->style->black );
+ gdk_draw_rectangle( widget->window, gc, FALSE,
+ dx, dy,
+ win->m_width-dw-1, win->m_height-dh-1 );
+ gdk_gc_unref( gc );
+ return;
+ }
+}
+
+//-----------------------------------------------------------------------------
+// "expose_event" of m_widget
+//-----------------------------------------------------------------------------
+
+static void gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
+{
+ if (gdk_event->count > 0) return;
+ draw_frame( widget, win );
+}
+
+//-----------------------------------------------------------------------------
+// "draw" of m_widget
+//-----------------------------------------------------------------------------
+
+static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNUSED(rect), wxWindow *win )
+{
+ draw_frame( widget, win );
+}
+
+#endif // GTK_MINOR_VERSION > 0
+
//-----------------------------------------------------------------------------
// key event conversion routines
//-----------------------------------------------------------------------------
return (key_code);
}
-//-----------------------------------------------------------------------------
-// local code (see below)
-//-----------------------------------------------------------------------------
-
-#if (GTK_MINOR_VERSION > 0)
-
-static void draw_frame( GtkWidget *widget, wxWindow *win )
-{
- if (!win->m_hasVMT)
- return;
-
- int dw = 0;
- int dh = 0;
-
- if (win->HasScrolling())
- {
- GtkScrolledWindow *scroll_window = GTK_SCROLLED_WINDOW(widget);
- GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(widget)->klass );
-
-/*
- GtkWidget *hscrollbar = scroll_window->hscrollbar;
- GtkWidget *vscrollbar = scroll_window->vscrollbar;
-
- we use this instead: range.slider_width = 11 + 2*2pts edge
-*/
-
- if (scroll_window->vscrollbar_visible)
- {
- dw += 15; /* dw += vscrollbar->allocation.width; */
- dw += scroll_class->scrollbar_spacing;
- }
-
- if (scroll_window->hscrollbar_visible)
- {
- dh += 15; /* dh += hscrollbar->allocation.height; */
- dh += scroll_class->scrollbar_spacing;
- }
- }
-
- int dx = 0;
- int dy = 0;
- if (GTK_WIDGET_NO_WINDOW (widget))
- {
- dx += widget->allocation.x;
- dy += widget->allocation.y;
- }
-
- if (win->HasFlag(wxRAISED_BORDER))
- {
- gtk_draw_shadow( widget->style,
- widget->window,
- GTK_STATE_NORMAL,
- GTK_SHADOW_OUT,
- dx, dy,
- win->m_width-dw, win->m_height-dh );
- return;
- }
-
- if (win->HasFlag(wxSUNKEN_BORDER))
- {
- gtk_draw_shadow( widget->style,
- widget->window,
- GTK_STATE_NORMAL,
- GTK_SHADOW_IN,
- dx, dy,
- win->m_width-dw, win->m_height-dh );
- return;
- }
-
- if (win->HasFlag(wxSIMPLE_BORDER))
- {
- GdkGC *gc = gdk_gc_new( widget->window );
- gdk_gc_set_foreground( gc, &widget->style->black );
- gdk_draw_rectangle( widget->window, gc, FALSE,
- dx, dy,
- win->m_width-dw-1, win->m_height-dh-1 );
- gdk_gc_unref( gc );
- return;
- }
-}
-
-//-----------------------------------------------------------------------------
-// "expose_event" of m_widget
-//-----------------------------------------------------------------------------
-
-static void gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindow *win )
-{
- if (gdk_event->count > 0) return;
- draw_frame( widget, win );
-}
-
-//-----------------------------------------------------------------------------
-// "draw" of m_wxwindow
-//-----------------------------------------------------------------------------
-
-static void gtk_window_own_draw_callback( GtkWidget *widget, GdkRectangle *WXUNUSED(rect), wxWindow *win )
-{
- draw_frame( widget, win );
-}
-
-#endif // GTK_MINOR_VERSION > 0
-
//-----------------------------------------------------------------------------
// "expose_event" of m_wxwindow
//-----------------------------------------------------------------------------
if (!win->m_hasVMT)
return;
- if (gdk_event->window != win->m_wxwindow->window)
- return;
-
win->GetUpdateRegion().Union( gdk_event->area.x,
gdk_event->area.y,
gdk_event->area.width,
if (gdk_event->count > 0)
return;
- wxPaintEvent event( win->GetId() );
- event.SetEventObject( win );
- win->GetEventHandler()->ProcessEvent( event );
-
/*
wxPrintf( "OnExpose from " );
if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
(int)gdk_event->area.height );
*/
+ wxEraseEvent eevent( win->GetId() );
+ eevent.SetEventObject( win );
+ win->GetEventHandler()->ProcessEvent(eevent);
+
+ wxPaintEvent event( win->GetId() );
+ event.SetEventObject( win );
+ win->GetEventHandler()->ProcessEvent( event );
+
win->GetUpdateRegion().Clear();
}
// "draw" of m_wxwindow
//-----------------------------------------------------------------------------
-static void gtk_window_draw_callback( GtkWidget *WXUNUSED(widget), GdkRectangle *rect, wxWindow *win )
+static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindow *win )
{
if (g_isIdle)
wxapp_install_idle_handler();
win->GetUpdateRegion().Union( rect->x, rect->y,
rect->width, rect->height );
- wxPaintEvent event( win->GetId() );
- event.SetEventObject( win );
-
/*
wxPrintf( "OnDraw from " );
if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
(int)rect->width,
(int)rect->height );
*/
-
+
+ wxEraseEvent eevent( win->GetId() );
+ eevent.SetEventObject( win );
+ win->GetEventHandler()->ProcessEvent(eevent);
+
+ wxPaintEvent event( win->GetId() );
+ event.SetEventObject( win );
win->GetEventHandler()->ProcessEvent( event );
win->GetUpdateRegion().Clear();
wxapp_install_idle_handler();
/*
- wxPrintf( _T("1) OnButtonPress from ") );
+ wxPrintf( wxT("1) OnButtonPress from ") );
if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
wxPrintf( win->GetClassInfo()->GetClassName() );
- wxPrintf( _T(".\n") );
+ wxPrintf( wxT(".\n") );
*/
if (!win->m_hasVMT) return FALSE;
if (g_blockEventsOnDrag) return TRUE;
gtk_widget_grab_focus (win->m_wxwindow);
/*
- wxPrintf( _T("GrabFocus from ") );
+ wxPrintf( wxT("GrabFocus from ") );
if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
wxPrintf( win->GetClassInfo()->GetClassName() );
- wxPrintf( _T(".\n") );
+ wxPrintf( wxT(".\n") );
*/
}
}
/*
- wxPrintf( _T("2) OnButtonPress from ") );
+ wxPrintf( wxT("2) OnButtonPress from ") );
if (win->GetClassInfo() && win->GetClassInfo()->GetClassName())
wxPrintf( win->GetClassInfo()->GetClassName() );
- wxPrintf( _T(".\n") );
+ wxPrintf( wxT(".\n") );
*/
wxEventType event_type = wxEVT_LEFT_DOWN;
if (gdk_event->is_hint)
{
- int x = 0;
- int y = 0;
- GdkModifierType state;
- gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
- gdk_event->x = x;
- gdk_event->y = y;
- gdk_event->state = state;
+ int x = 0;
+ int y = 0;
+ GdkModifierType state;
+ gdk_window_get_pointer(gdk_event->window, &x, &y, &state);
+ gdk_event->x = x;
+ gdk_event->y = y;
}
/*
// "button_release_event" from scrollbar
//-----------------------------------------------------------------------------
-static gint gtk_scrollbar_button_release_callback( GtkRange *widget,
+static gint gtk_scrollbar_button_release_callback( GtkRange *WXUNUSED(widget),
GdkEventButton *WXUNUSED(gdk_event),
wxWindow *win )
{
static void wxInsertChildInWindow( wxWindow* parent, wxWindow* child )
{
+ /* the window might have been scrolled already, do we
+ have to adapt the position */
+ GtkMyFixed *myfixed = GTK_MYFIXED(parent->m_wxwindow);
+ child->m_x += myfixed->xoffset;
+ child->m_y += myfixed->yoffset;
+
gtk_myfixed_put( GTK_MYFIXED(parent->m_wxwindow),
GTK_WIDGET(child->m_widget),
child->m_x,
m_hasVMT = FALSE;
m_needParent = TRUE;
m_isBeingDeleted = FALSE;
-
+
+ m_noExpose = FALSE;
+ m_nativeSizeEvent = FALSE;
+
m_hasScrolling = FALSE;
m_isScrolling = FALSE;
m_oldVerticalPos = 0.0;
m_resizing = FALSE;
- m_scrollGC = (GdkGC*) NULL;
m_widgetStyle = (GtkStyle*) NULL;
m_insertCallback = (wxInsertChildFunction) NULL;
m_isStaticBox = FALSE;
m_isRadioButton = FALSE;
+ m_isFrame = FALSE;
m_acceptsFocus = FALSE;
m_cursor = *wxSTANDARD_CURSOR;
if (!PreCreation( parent, pos, size ) ||
!CreateBase( parent, id, pos, size, style, wxDefaultValidator, name ))
{
- wxFAIL_MSG( _T("wxWindow creation failed") );
+ wxFAIL_MSG( wxT("wxWindow creation failed") );
return FALSE;
}
GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
#ifdef __WXDEBUG__
- debug_focus_in( m_widget, _T("wxWindow::m_widget"), name );
+ debug_focus_in( m_widget, wxT("wxWindow::m_widget"), name );
#endif
GtkScrolledWindow *scrolledWindow = GTK_SCROLLED_WINDOW(m_widget);
#ifdef __WXDEBUG__
- debug_focus_in( scrolledWindow->hscrollbar, _T("wxWindow::hsrcollbar"), name );
- debug_focus_in( scrolledWindow->vscrollbar, _T("wxWindow::vsrcollbar"), name );
+ debug_focus_in( scrolledWindow->hscrollbar, wxT("wxWindow::hsrcollbar"), name );
+ debug_focus_in( scrolledWindow->vscrollbar, wxT("wxWindow::vsrcollbar"), name );
#endif
GtkScrolledWindowClass *scroll_class = GTK_SCROLLED_WINDOW_CLASS( GTK_OBJECT(m_widget)->klass );
m_wxwindow = gtk_myfixed_new();
#ifdef __WXDEBUG__
- debug_focus_in( m_wxwindow, _T("wxWindow::m_wxwindow"), name );
+ debug_focus_in( m_wxwindow, wxT("wxWindow::m_wxwindow"), name );
#endif
gtk_container_add( GTK_CONTAINER(m_widget), m_wxwindow );
m_widgetStyle = (GtkStyle*) NULL;
}
- if (m_scrollGC)
- {
- gdk_gc_unref( m_scrollGC );
- m_scrollGC = (GdkGC*) NULL;
- }
-
if (m_wxwindow)
{
gtk_widget_destroy( m_wxwindow );
bool wxWindow::PreCreation( wxWindow *parent, const wxPoint &pos, const wxSize &size )
{
- wxCHECK_MSG( !m_needParent || parent, FALSE, _T("Need complete parent.") );
+ wxCHECK_MSG( !m_needParent || parent, FALSE, wxT("Need complete parent.") );
/* this turns -1 into 20 so that a minimal window is
visible even although -1,-1 has been given as the
void wxWindow::PostCreation()
{
- wxASSERT_MSG( (m_widget != NULL), _T("invalid window") );
+ wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
if (m_wxwindow)
{
- /* these get reported to wxWindows -> wxPaintEvent */
- 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 );
+ if (!m_noExpose)
+ {
+ /* these get reported to wxWindows -> wxPaintEvent */
+ 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 );
+ }
+
#if (GTK_MINOR_VERSION > 0)
- /* these are called when the "sunken", "raised" or "simple" borders are drawn */
+ /* these are called when the "sunken" or "raised" borders are drawn */
gtk_signal_connect( GTK_OBJECT(m_widget), "expose_event",
GTK_SIGNAL_FUNC(gtk_window_own_expose_callback), (gpointer)this );
bool wxWindow::Destroy()
{
- wxASSERT_MSG( (m_widget != NULL), _T("invalid window") );
+ wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
m_hasVMT = FALSE;
void wxWindow::DoSetSize( int x, int y, int width, int height, int sizeFlags )
{
- wxASSERT_MSG( (m_widget != NULL), _T("invalid window") );
- wxASSERT_MSG( (m_parent != NULL), _T("wxWindow::SetSize requires parent.\n") );
+ wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
+ wxASSERT_MSG( (m_parent != NULL), wxT("wxWindow::SetSize requires parent.\n") );
if (m_resizing) return; /* I don't like recursions */
m_resizing = TRUE;
}
else
{
+ GtkMyFixed *myfixed = GTK_MYFIXED(m_parent->m_wxwindow);
+
if ((sizeFlags & wxSIZE_ALLOW_MINUS_ONE) == 0)
{
- if (x != -1) m_x = x;
- if (y != -1) m_y = y;
+ if (x != -1) m_x = x + myfixed->xoffset;
+ if (y != -1) m_y = y + myfixed->yoffset;
if (width != -1) m_width = width;
if (height != -1) m_height = height;
}
else
{
- m_x = x;
- m_y = y;
+ m_x = x + myfixed->xoffset;
+ m_y = y + myfixed->yoffset;
m_width = width;
m_height = height;
}
bottom_border = 5;
}
- /* this is the result of hours of debugging: the following code
- means that if we have a m_wxwindow and we set the size of
- m_widget, m_widget (which is a GtkScrolledWindow) does NOT
- automatically propagate its size down to its m_wxwindow,
- which is its client area. therefore, we have to tell the
- client area directly that it has to resize itself.
- this will lead to that m_widget (GtkScrolledWindow) will
- calculate how much size it needs for scrollbars etc and
- it will then call XXX_size_allocate of its child, which
- is m_wxwindow. m_wxwindow in turn will do the same with its
- children and so on. problems can arise if this happens
- before all the children have been realized as some widgets
- stupidy need to be realized during XXX_size_allocate (e.g.
- GtkNotebook) and they will segv if called otherwise. this
- emergency is tested in gtk_myfixed_size_allocate. Normally
- this shouldn't be needed and only gtk_widget_queue_resize()
- should be enough to provoke a resize at the next appropriate
- moment, but this seems to fail, e.g. when a wxNotebook contains
- a wxSplitterWindow: the splitter window's children won't
- show up properly resized then. */
-
gtk_myfixed_set_size( GTK_MYFIXED(m_parent->m_wxwindow),
m_widget,
m_x-border,
m_width+2*border,
m_height+border+bottom_border );
}
+
+/*
+ wxPrintf( "OnSize sent from " );
+ if (GetClassInfo() && GetClassInfo()->GetClassName())
+ wxPrintf( GetClassInfo()->GetClassName() );
+ wxPrintf( " %d %d %d %d\n", (int)m_x, (int)m_y, (int)m_width, (int)m_height );
+*/
- m_sizeSet = TRUE;
-
- wxSizeEvent event( wxSize(m_width,m_height), GetId() );
- event.SetEventObject( this );
- GetEventHandler()->ProcessEvent( event );
+ if (!m_nativeSizeEvent)
+ {
+ wxSizeEvent event( wxSize(m_width,m_height), GetId() );
+ event.SetEventObject( this );
+ GetEventHandler()->ProcessEvent( event );
+ }
m_resizing = FALSE;
}
wxCursor cursor = m_cursor;
if (g_globalCursor.Ok()) cursor = g_globalCursor;
- if (cursor.Ok() && m_currentGdkCursor != cursor)
+ if (cursor.Ok())
{
- m_currentGdkCursor = cursor;
+ /* I now set the cursor the anew in every OnInternalIdle call
+ as setting the cursor in a parent window also effects the
+ windows above so that checking for the current cursor is
+ not possible. */
if (m_wxwindow)
{
- GdkWindow *window = m_wxwindow->window;
+ GdkWindow *window = GTK_MYFIXED(m_wxwindow)->bin_window;
if (window)
gdk_window_set_cursor( window, cursor.GetCursor() );
void wxWindow::DoGetSize( int *width, int *height ) const
{
- wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+ wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
if (width) (*width) = m_width;
if (height) (*height) = m_height;
void wxWindow::DoSetClientSize( int width, int height )
{
- wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+ wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
if (!m_wxwindow)
{
void wxWindow::DoGetClientSize( int *width, int *height ) const
{
- wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+ wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
if (!m_wxwindow)
{
void wxWindow::DoGetPosition( int *x, int *y ) const
{
- wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+ wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
+
+ int dx = 0;
+ int dy = 0;
+ if (m_parent && m_parent->m_wxwindow)
+ {
+ GtkMyFixed *myfixed = GTK_MYFIXED(m_parent->m_wxwindow);
+ dx = myfixed->xoffset;
+ dy = myfixed->yoffset;
+ }
- if (x) (*x) = m_x;
- if (y) (*y) = m_y;
+ if (x) (*x) = m_x - dx;
+ if (y) (*y) = m_y - dy;
}
void wxWindow::DoClientToScreen( int *x, int *y ) const
{
- wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+ wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
if (!m_widget->window) return;
GdkWindow *source = (GdkWindow *) NULL;
if (m_wxwindow)
- source = m_wxwindow->window;
+ source = GTK_MYFIXED(m_wxwindow)->bin_window;
else
source = m_widget->window;
void wxWindow::DoScreenToClient( int *x, int *y ) const
{
- wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+ wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
if (!m_widget->window) return;
GdkWindow *source = (GdkWindow *) NULL;
if (m_wxwindow)
- source = m_wxwindow->window;
+ source = GTK_MYFIXED(m_wxwindow)->bin_window;
else
source = m_widget->window;
bool wxWindow::Show( bool show )
{
- wxCHECK_MSG( (m_widget != NULL), FALSE, _T("invalid window") );
+ wxCHECK_MSG( (m_widget != NULL), FALSE, wxT("invalid window") );
if (!wxWindowBase::Show(show))
{
bool wxWindow::Enable( bool enable )
{
- wxCHECK_MSG( (m_widget != NULL), FALSE, _T("invalid window") );
+ wxCHECK_MSG( (m_widget != NULL), FALSE, wxT("invalid window") );
if (!wxWindowBase::Enable(enable))
{
int wxWindow::GetCharHeight() const
{
- wxCHECK_MSG( (m_widget != NULL), 12, _T("invalid window") );
+ wxCHECK_MSG( (m_widget != NULL), 12, wxT("invalid window") );
- wxCHECK_MSG( m_font.Ok(), 12, _T("invalid font") );
+ wxCHECK_MSG( m_font.Ok(), 12, wxT("invalid font") );
GdkFont *font = m_font.GetInternalFont( 1.0 );
int wxWindow::GetCharWidth() const
{
- wxCHECK_MSG( (m_widget != NULL), 8, _T("invalid window") );
+ wxCHECK_MSG( (m_widget != NULL), 8, wxT("invalid window") );
- wxCHECK_MSG( m_font.Ok(), 8, _T("invalid font") );
+ wxCHECK_MSG( m_font.Ok(), 8, wxT("invalid font") );
GdkFont *font = m_font.GetInternalFont( 1.0 );
wxFont fontToUse = m_font;
if (theFont) fontToUse = *theFont;
- wxCHECK_RET( fontToUse.Ok(), _T("invalid font") );
+ wxCHECK_RET( fontToUse.Ok(), wxT("invalid font") );
GdkFont *font = fontToUse.GetInternalFont( 1.0 );
if (x) (*x) = gdk_string_width( font, string.mbc_str() );
void wxWindow::SetFocus()
{
- wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+ wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
GtkWidget *connect_widget = GetConnectWidget();
if (connect_widget)
bool wxWindow::Reparent( wxWindowBase *newParentBase )
{
- wxCHECK_MSG( (m_widget != NULL), FALSE, _T("invalid window") );
+ wxCHECK_MSG( (m_widget != NULL), FALSE, wxT("invalid window") );
wxWindow *oldParent = m_parent,
*newParent = (wxWindow *)newParentBase;
+ wxASSERT( GTK_IS_WIDGET(m_widget) );
+
if ( !wxWindowBase::Reparent(newParent) )
return FALSE;
+ wxASSERT( GTK_IS_WIDGET(m_widget) );
+
+ /* prevent GTK from deleting the widget arbitrarily */
+ gtk_widget_ref( m_widget );
+
if (oldParent)
{
gtk_container_remove( GTK_CONTAINER(oldParent->m_wxwindow), m_widget );
}
+ wxASSERT( GTK_IS_WIDGET(m_widget) );
+
if (newParent)
{
/* insert GTK representation */
(*(newParent->m_insertCallback))(newParent, this);
}
+ /* reverse: prevent GTK from deleting the widget arbitrarily */
+ gtk_widget_unref( m_widget );
+
return TRUE;
}
void wxWindow::DoAddChild(wxWindow *child)
{
- wxASSERT_MSG( (m_widget != NULL), _T("invalid window") );
+ wxASSERT_MSG( (m_widget != NULL), wxT("invalid window") );
- wxASSERT_MSG( (child != NULL), _T("invalid child window") );
+ wxASSERT_MSG( (child != NULL), wxT("invalid child window") );
- wxASSERT_MSG( (m_insertCallback != NULL), _T("invalid child insertion function") );
+ wxASSERT_MSG( (m_insertCallback != NULL), wxT("invalid child insertion function") );
/* add to list */
AddChild( child );
void wxWindow::Raise()
{
- wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+ wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
if (!m_widget->window) return;
void wxWindow::Lower()
{
- wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+ wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
if (!m_widget->window) return;
bool wxWindow::SetCursor( const wxCursor &cursor )
{
- wxCHECK_MSG( (m_widget != NULL), FALSE, _T("invalid window") );
+ wxCHECK_MSG( (m_widget != NULL), FALSE, wxT("invalid window") );
return wxWindowBase::SetCursor( cursor );
}
void wxWindow::WarpPointer( int x, int y )
{
- wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+ wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
- GtkWidget *connect_widget = GetConnectWidget();
- if (connect_widget->window)
- {
- /* we provide this function ourselves as it is
- missing in GDK */
- gdk_window_warp_pointer( connect_widget->window, x, y );
- }
+ /* we provide this function ourselves as it is
+ missing in GDK (top of this file) */
+
+ GdkWindow *window = (GdkWindow*) NULL;
+ if (m_wxwindow)
+ window = GTK_MYFIXED(m_wxwindow)->bin_window;
+ else
+ window = GetConnectWidget()->window;
+
+ if (window)
+ gdk_window_warp_pointer( window, x, y );
}
void wxWindow::Refresh( bool eraseBackground, const wxRect *rect )
{
- wxCHECK_RET( (m_widget != NULL), _T("invalid window") );
+ wxCHECK_RET( (m_widget != NULL), wxT("invalid window") );
if (!m_widget->window) return;
{
if (rect)
{
- gdk_window_clear_area( m_wxwindow->window,
+ gdk_window_clear_area( GTK_MYFIXED(m_wxwindow)->bin_window,
rect->x, rect->y,
rect->width, rect->height );
}
else
{
- gdk_window_clear( m_wxwindow->window );
+ gdk_window_clear( GTK_MYFIXED(m_wxwindow)->bin_window );
}
}
+ /* there is no GTK equivalent of "draw only, don't clear" so we
+ invent our own in the GtkMyFixed widget */
+
if (!rect)
{
if (m_wxwindow)
{
- /* call the callback directly for preventing GTK from
- clearing the bakground */
- int w = 0;
- int h = 0;
- GetClientSize( &w, &h );
- GdkRectangle gdk_rect;
- gdk_rect.x = 0;
- gdk_rect.y = 0;
- gdk_rect.width = w;
- gdk_rect.height = h;
- gtk_window_draw_callback( m_wxwindow, &gdk_rect, this );
+ GtkMyFixed *myfixed = GTK_MYFIXED(m_wxwindow);
+ gboolean old_clear = myfixed->clear_on_draw;
+ gtk_my_fixed_set_clear( myfixed, FALSE );
+
+ gtk_widget_draw( m_wxwindow, (GdkRectangle*) NULL );
+
+ gtk_my_fixed_set_clear( myfixed, old_clear );
}
else
- {
gtk_widget_draw( m_widget, (GdkRectangle*) NULL );
- }
}
else
{
if (m_wxwindow)
{
- /* call the callback directly for preventing GTK from
- clearing the bakground */
- gtk_window_draw_callback( m_wxwindow, &gdk_rect, this );
+ GtkMyFixed *myfixed = GTK_MYFIXED(m_wxwindow);
+ gboolean old_clear = myfixed->clear_on_draw;
+ gtk_my_fixed_set_clear( myfixed, FALSE );
+
+ gtk_widget_draw( m_wxwindow, &gdk_rect );
+
+ gtk_my_fixed_set_clear( myfixed, old_clear );
}
else
- {
gtk_widget_draw( m_widget, &gdk_rect );
- }
}
}
void wxWindow::Clear()
{
- wxCHECK_RET( m_widget != NULL, _T("invalid window") );
+ wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
if (!m_widget->window) return;
bool wxWindow::SetBackgroundColour( const wxColour &colour )
{
- wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid window") );
+ wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") );
if (!wxWindowBase::SetBackgroundColour(colour))
{
if (!m_delayedBackgroundColour) return FALSE;
}
- GtkWidget *connect_widget = GetConnectWidget();
- if (!connect_widget->window)
+ GdkWindow *window = (GdkWindow*) NULL;
+ if (m_wxwindow)
+ window = GTK_MYFIXED(m_wxwindow)->bin_window;
+ else
+ window = GetConnectWidget()->window;
+
+ if (!window)
{
// indicate that a new style has been set
// but it couldn't get applied as the
return TRUE;
}
- if (m_wxwindow && m_wxwindow->window)
+ if (m_wxwindow)
{
/* 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() );
+ m_backgroundColour.CalcPixel( gdk_window_get_colormap( window ) );
+ gdk_window_set_background( window, m_backgroundColour.GetColor() );
}
wxColour sysbg = wxSystemSettings::GetSystemColour( wxSYS_COLOUR_BTNFACE );
bool wxWindow::SetForegroundColour( const wxColour &colour )
{
- wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid window") );
+ wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") );
if (!wxWindowBase::SetForegroundColour(colour))
{
if (!m_delayedForegroundColour) return FALSE;
}
- GtkWidget *connect_widget = GetConnectWidget();
- if (!connect_widget->window)
+ GdkWindow *window = (GdkWindow*) NULL;
+ if (m_wxwindow)
+ window = GTK_MYFIXED(m_wxwindow)->bin_window;
+ else
+ window = GetConnectWidget()->window;
+
+ if (!window)
{
// indicate that a new style has been set
// but it couldn't get applied as the
bool wxWindow::DoPopupMenu( wxMenu *menu, int x, int y )
{
- wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid window") );
+ wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") );
- wxCHECK_MSG( menu != NULL, FALSE, _T("invalid popup-menu") );
+ wxCHECK_MSG( menu != NULL, FALSE, wxT("invalid popup-menu") );
SetInvokingWindow( menu, this );
(GtkMenuPositionFunc) pop_pos_callback,
(gpointer) this, // client data
0, // button used to activate it
- 0 //gs_timeLastClick // the time of activation
+ gs_timeLastClick // the time of activation
);
while (is_waiting)
void wxWindow::SetDropTarget( wxDropTarget *dropTarget )
{
- wxCHECK_RET( m_widget != NULL, _T("invalid window") );
+ wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
GtkWidget *dnd_widget = GetConnectWidget();
bool wxWindow::IsOwnGtkWindow( GdkWindow *window )
{
- if (m_wxwindow) return (window == m_wxwindow->window);
+ if (m_wxwindow)
+ return (window == GTK_MYFIXED(m_wxwindow)->bin_window);
+
return (window == m_widget->window);
}
bool wxWindow::SetFont( const wxFont &font )
{
- wxCHECK_MSG( m_widget != NULL, FALSE, _T("invalid window") );
+ wxCHECK_MSG( m_widget != NULL, FALSE, wxT("invalid window") );
if (!wxWindowBase::SetFont(font))
{
if (!m_delayedFont) return FALSE;
}
- GtkWidget *connect_widget = GetConnectWidget();
- if (!connect_widget->window)
+ GdkWindow *window = (GdkWindow*) NULL;
+ if (m_wxwindow)
+ window = GTK_MYFIXED(m_wxwindow)->bin_window;
+ else
+ window = GetConnectWidget()->window;
+
+ if (!window)
{
// indicate that a new style has been set
// but it couldn't get applied as the
void wxWindow::CaptureMouse()
{
- wxCHECK_RET( m_widget != NULL, _T("invalid window") );
+ wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
- wxCHECK_RET( g_captureWindow == NULL, _T("CaptureMouse called twice") );
+ wxCHECK_RET( g_captureWindow == NULL, wxT("CaptureMouse called twice") );
- GtkWidget *connect_widget = GetConnectWidget();
- if (!connect_widget->window) return;
+ GdkWindow *window = (GdkWindow*) NULL;
+ if (m_wxwindow)
+ window = GTK_MYFIXED(m_wxwindow)->bin_window;
+ else
+ window = GetConnectWidget()->window;
+
+ if (!window) return;
- gdk_pointer_grab( connect_widget->window, FALSE,
+ gdk_pointer_grab( window, FALSE,
(GdkEventMask)
(GDK_BUTTON_PRESS_MASK |
GDK_BUTTON_RELEASE_MASK |
+ GDK_POINTER_MOTION_HINT_MASK |
GDK_POINTER_MOTION_MASK),
(GdkWindow *) NULL,
m_cursor.GetCursor(),
void wxWindow::ReleaseMouse()
{
- wxCHECK_RET( m_widget != NULL, _T("invalid window") );
+ wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
- wxCHECK_RET( g_captureWindow, _T("ReleaseMouse called twice") );
+ wxCHECK_RET( g_captureWindow, wxT("ReleaseMouse called twice") );
- GtkWidget *connect_widget = GetConnectWidget();
- if (!connect_widget->window) return;
+ GdkWindow *window = (GdkWindow*) NULL;
+ if (m_wxwindow)
+ window = GTK_MYFIXED(m_wxwindow)->bin_window;
+ else
+ window = GetConnectWidget()->window;
+
+ if (!window) return;
gdk_pointer_ungrab ( GDK_CURRENT_TIME );
g_captureWindow = (wxWindow*) NULL;
void wxWindow::SetScrollbar( int orient, int pos, int thumbVisible,
int range, bool refresh )
{
- wxCHECK_RET( m_widget != NULL, _T("invalid window") );
+ wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
- wxCHECK_RET( m_wxwindow != NULL, _T("window needs client area for scrolling") );
+ wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") );
m_hasScrolling = TRUE;
void wxWindow::SetScrollPos( int orient, int pos, bool WXUNUSED(refresh) )
{
- wxCHECK_RET( m_widget != NULL, _T("invalid window") );
+ wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
- wxCHECK_RET( m_wxwindow != NULL, _T("window needs client area for scrolling") );
+ wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") );
if (orient == wxHORIZONTAL)
{
int wxWindow::GetScrollThumb( int orient ) const
{
- wxCHECK_MSG( m_widget != NULL, 0, _T("invalid window") );
+ wxCHECK_MSG( m_widget != NULL, 0, wxT("invalid window") );
- wxCHECK_MSG( m_wxwindow != NULL, 0, _T("window needs client area for scrolling") );
+ wxCHECK_MSG( m_wxwindow != NULL, 0, wxT("window needs client area for scrolling") );
if (orient == wxHORIZONTAL)
return (int)(m_hAdjust->page_size+0.5);
int wxWindow::GetScrollPos( int orient ) const
{
- wxCHECK_MSG( m_widget != NULL, 0, _T("invalid window") );
+ wxCHECK_MSG( m_widget != NULL, 0, wxT("invalid window") );
- wxCHECK_MSG( m_wxwindow != NULL, 0, _T("window needs client area for scrolling") );
+ wxCHECK_MSG( m_wxwindow != NULL, 0, wxT("window needs client area for scrolling") );
if (orient == wxHORIZONTAL)
return (int)(m_hAdjust->value+0.5);
int wxWindow::GetScrollRange( int orient ) const
{
- wxCHECK_MSG( m_widget != NULL, 0, _T("invalid window") );
+ wxCHECK_MSG( m_widget != NULL, 0, wxT("invalid window") );
- wxCHECK_MSG( m_wxwindow != NULL, 0, _T("window needs client area for scrolling") );
+ wxCHECK_MSG( m_wxwindow != NULL, 0, wxT("window needs client area for scrolling") );
if (orient == wxHORIZONTAL)
return (int)(m_hAdjust->upper+0.5);
void wxWindow::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
{
- wxCHECK_RET( m_widget != NULL, _T("invalid window") );
+ wxCHECK_RET( m_widget != NULL, wxT("invalid window") );
+
+ wxCHECK_RET( m_wxwindow != NULL, wxT("window needs client area for scrolling") );
- wxCHECK_RET( m_wxwindow != NULL, _T("window needs client area for scrolling") );
+ gtk_myfixed_scroll( GTK_MYFIXED(m_wxwindow), -dx, -dy );
+/*
if (!m_scrollGC)
{
m_scrollGC = gdk_gc_new( m_wxwindow->window );
Refresh( TRUE, &rect );
}
+*/
}
void wxWindow::SetScrolling(bool scroll)