added scrolling support to wxWindow

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/branches/wxUNIVERSAL@8198 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Vadim Zeitlin
2000-08-27 17:00:42 +00:00
parent bd9218ba08
commit dac7332cc2
6 changed files with 319 additions and 210 deletions

View File

@@ -63,6 +63,7 @@ public:
// background pixmap support // background pixmap support
// ------------------------- // -------------------------
virtual void SetBackground(const wxBitmap& bitmap, virtual void SetBackground(const wxBitmap& bitmap,
int alignment = wxALIGN_CENTRE, int alignment = wxALIGN_CENTRE,
wxStretch stretch = wxSTRETCH_NOT); wxStretch stretch = wxSTRETCH_NOT);
@@ -74,11 +75,11 @@ public:
// instead of the native ones // instead of the native ones
// ------------------------------------------------------------------ // ------------------------------------------------------------------
virtual void SetScrollbar( int orient, virtual void SetScrollbar(int orient,
int pos, int pos,
int thumbVisible, int page,
int range, int range,
bool refresh = TRUE ); bool refresh = TRUE );
virtual void SetScrollPos( int orient, int pos, bool refresh = TRUE ); virtual void SetScrollPos( int orient, int pos, bool refresh = TRUE );
virtual int GetScrollPos( int orient ) const; virtual int GetScrollPos( int orient ) const;
virtual int GetScrollThumb( int orient ) const; virtual int GetScrollThumb( int orient ) const;
@@ -103,7 +104,14 @@ protected:
// common part of all ctors // common part of all ctors
void Init(); void Init();
// overridden base class virtuals
// we deal with the scrollbars in these functions
virtual void DoSetClientSize(int width, int height);
virtual void DoGetClientSize(int *width, int *height) const;
// event handlers // event handlers
void OnSize(wxSizeEvent& event);
void OnPaint(wxPaintEvent& event); void OnPaint(wxPaintEvent& event);
void OnErase(wxEraseEvent& event); void OnErase(wxEraseEvent& event);
@@ -120,6 +128,15 @@ protected:
// adjust the size of the window to take into account its borders // adjust the size of the window to take into account its borders
wxSize AdjustSize(const wxSize& size) const; wxSize AdjustSize(const wxSize& size) const;
// get the scrollbar (may be NULL) for the given orientation
wxScrollBar *GetScrollbar(int orient) const
{
return orient & wxVERTICAL ? m_scrollbarVert : m_scrollbarHorz;
}
// put the scrollbars along the edges of the window
void PositionScrollbars();
// background bitmap info // background bitmap info
wxBitmap m_bitmapBg; wxBitmap m_bitmapBg;
int m_alignBgBitmap; int m_alignBgBitmap;

View File

@@ -37,6 +37,7 @@
#include "wx/bmpbuttn.h" #include "wx/bmpbuttn.h"
#include "wx/button.h" #include "wx/button.h"
#include "wx/scrolbar.h" #include "wx/scrolbar.h"
#include "wx/scrolwin.h"
#include "wx/statbox.h" #include "wx/statbox.h"
#include "wx/stattext.h" #include "wx/stattext.h"
#endif #endif
@@ -236,11 +237,26 @@ MyUnivFrame::MyUnivFrame(const wxString& title)
new wxStaticBitmap(this, -1, wxBITMAP(tip), wxPoint(50, 350), new wxStaticBitmap(this, -1, wxBITMAP(tip), wxPoint(50, 350),
wxDefaultSize, wxSUNKEN_BORDER); wxDefaultSize, wxSUNKEN_BORDER);
#if 0
wxScrollBar *sb; wxScrollBar *sb;
sb = new wxScrollBar(this, -1, wxPoint(200, 300), wxSize(300, -1)); sb = new wxScrollBar(this, -1, wxPoint(200, 300), wxSize(300, -1));
sb->SetScrollbar(0, 10, 100, 10); sb->SetScrollbar(0, 10, 100, 10);
sb = new wxScrollBar(this, -1, wxPoint(200, 330), wxSize(-1, 150), wxSB_VERTICAL); sb = new wxScrollBar(this, -1, wxPoint(200, 330), wxSize(-1, 150), wxSB_VERTICAL);
sb->SetScrollbar(50, 50, 100, 10); sb->SetScrollbar(50, 50, 100, 10);
#elif 1
wxWindow *win = new wxWindow(this, -1,
wxPoint(200, 300),
wxSize(300, 150),
wxSUNKEN_BORDER);
win->SetScrollbar(wxHORIZONTAL, 0, 10, 30);
win->SetScrollbar(wxVERTICAL, 0, 5, 30);
#else
wxScrolledWindow *win = new wxScrolledWindow(this, -1,
wxPoint(200, 300),
wxSize(300, 150),
wxSUNKEN_BORDER);
win->SetScrollbars(10, 5, 30, 30, 15, 15);
#endif
new wxButton(this, -1, wxBITMAP(open), _T("&Open..."), wxPoint(10, 420)); new wxButton(this, -1, wxBITMAP(open), _T("&Open..."), wxPoint(10, 420));

View File

@@ -438,9 +438,9 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win )
gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindowGTK *win ) gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindowGTK *win )
{ {
if (gdk_event->count > 0) return FALSE; if (gdk_event->count > 0) return FALSE;
draw_frame( widget, win ); draw_frame( widget, win );
return TRUE; return TRUE;
} }
@@ -675,7 +675,7 @@ static int gtk_window_expose_callback( GtkWidget *widget,
if (g_isIdle) if (g_isIdle)
wxapp_install_idle_handler(); wxapp_install_idle_handler();
/* /*
if (win->GetName() == wxT("panel")) if (win->GetName() == wxT("panel"))
{ {
@@ -688,7 +688,7 @@ static int gtk_window_expose_callback( GtkWidget *widget,
(int)gdk_event->area.height ); (int)gdk_event->area.height );
} }
*/ */
win->GetUpdateRegion().Union( gdk_event->area.x, win->GetUpdateRegion().Union( gdk_event->area.x,
gdk_event->area.y, gdk_event->area.y,
gdk_event->area.width, gdk_event->area.width,
@@ -707,14 +707,14 @@ static int gtk_window_expose_callback( GtkWidget *widget,
win->GetUpdateRegion().Clear(); win->GetUpdateRegion().Clear();
} }
/* The following code will result in all window-less widgets /* The following code will result in all window-less widgets
being redrawn if the wxWindows class is given a chance to being redrawn if the wxWindows class is given a chance to
paint *anything* because it will then be allowed to paint paint *anything* because it will then be allowed to paint
over the window-less widgets */ over the window-less widgets */
GtkPizza *pizza = GTK_PIZZA (widget); GtkPizza *pizza = GTK_PIZZA (widget);
GList *children = pizza->children; GList *children = pizza->children;
while (children) while (children)
{ {
@@ -734,7 +734,7 @@ static int gtk_window_expose_callback( GtkWidget *widget,
gtk_widget_event (child->widget, (GdkEvent*) &child_event); gtk_widget_event (child->widget, (GdkEvent*) &child_event);
} }
} }
return TRUE; return TRUE;
} }
@@ -768,13 +768,15 @@ gint gtk_window_event_event_callback( GtkWidget *widget,
/* This callback is a complete replacement of the gtk_pizza_draw() function, /* This callback is a complete replacement of the gtk_pizza_draw() function,
which disabled. */ which disabled. */
static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindowGTK *win ) static void gtk_window_draw_callback( GtkWidget *widget,
GdkRectangle *rect,
wxWindow *win )
{ {
DEBUG_MAIN_THREAD DEBUG_MAIN_THREAD
if (g_isIdle) if (g_isIdle)
wxapp_install_idle_handler(); wxapp_install_idle_handler();
/* /*
if (win->GetName() == wxT("panel")) if (win->GetName() == wxT("panel"))
{ {
@@ -787,45 +789,46 @@ static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxW
(int)rect->height ); (int)rect->height );
} }
*/ */
GtkPizza *pizza = GTK_PIZZA (widget); GtkPizza *pizza = GTK_PIZZA (widget);
if (!(GTK_WIDGET_APP_PAINTABLE (widget)) && if (!(GTK_WIDGET_APP_PAINTABLE (widget)) &&
(pizza->clear_on_draw)) (pizza->clear_on_draw))
{
gdk_window_clear_area( pizza->bin_window,
rect->x, rect->y, rect->width, rect->height);
}
win->GetUpdateRegion().Union( rect->x, rect->y, rect->width, rect->height );
win->m_clipPaintRegion = TRUE;
wxClientDC dc(win);
wxEraseEvent eevent( win->GetId(), &dc );
eevent.SetEventObject( win );
win->GetEventHandler()->ProcessEvent(eevent);
wxPaintEvent event( win->GetId() );
event.SetEventObject( win );
win->GetEventHandler()->ProcessEvent( event );
win->GetUpdateRegion().Clear();
win->m_clipPaintRegion = FALSE;
GList *children = pizza->children;
while (children)
{
GtkPizzaChild *child = (GtkPizzaChild*) children->data;
children = children->next;
GdkRectangle child_area;
if (gtk_widget_intersect (child->widget, rect, &child_area))
{ {
gdk_window_clear_area( pizza->bin_window, gtk_widget_draw (child->widget, &child_area /* (GdkRectangle*) NULL*/ );
rect->x, rect->y, rect->width, rect->height);
}
win->GetUpdateRegion().Union( rect->x, rect->y, rect->width, rect->height );
win->m_clipPaintRegion = TRUE;
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();
win->m_clipPaintRegion = FALSE;
GList *children = pizza->children;
while (children)
{
GtkPizzaChild *child = (GtkPizzaChild*) children->data;
children = children->next;
GdkRectangle child_area;
if (gtk_widget_intersect (child->widget, rect, &child_area))
{
gtk_widget_draw (child->widget, &child_area /* (GdkRectangle*) NULL*/ );
}
} }
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -1915,7 +1918,7 @@ gtk_window_realized_callback( GtkWidget *WXUNUSED(m_widget), wxWindow *win )
wxWindowCreateEvent event( win ); wxWindowCreateEvent event( win );
event.SetEventObject( win ); event.SetEventObject( win );
win->GetEventHandler()->ProcessEvent( event ); win->GetEventHandler()->ProcessEvent( event );
return FALSE; return FALSE;
} }
@@ -2012,22 +2015,22 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget),
GdkIMStyle style; GdkIMStyle style;
GdkIMStyle supported_style = (GdkIMStyle) GdkIMStyle supported_style = (GdkIMStyle)
(GDK_IM_PREEDIT_NONE | (GDK_IM_PREEDIT_NONE |
GDK_IM_PREEDIT_NOTHING | GDK_IM_PREEDIT_NOTHING |
GDK_IM_PREEDIT_POSITION | GDK_IM_PREEDIT_POSITION |
GDK_IM_STATUS_NONE | GDK_IM_STATUS_NONE |
GDK_IM_STATUS_NOTHING); GDK_IM_STATUS_NOTHING);
if (widget->style && widget->style->font->type != GDK_FONT_FONTSET) if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
supported_style = (GdkIMStyle)(supported_style & ~GDK_IM_PREEDIT_POSITION); supported_style = (GdkIMStyle)(supported_style & ~GDK_IM_PREEDIT_POSITION);
attr->style = style = gdk_im_decide_style (supported_style); attr->style = style = gdk_im_decide_style (supported_style);
attr->client_window = widget->window; attr->client_window = widget->window;
if ((colormap = gtk_widget_get_colormap (widget)) != if ((colormap = gtk_widget_get_colormap (widget)) !=
gtk_widget_get_default_colormap ()) gtk_widget_get_default_colormap ())
{ {
attrmask |= GDK_IC_PREEDIT_COLORMAP; attrmask |= GDK_IC_PREEDIT_COLORMAP;
attr->preedit_colormap = colormap; attr->preedit_colormap = colormap;
} }
attrmask |= GDK_IC_PREEDIT_FOREGROUND; attrmask |= GDK_IC_PREEDIT_FOREGROUND;
@@ -2037,40 +2040,40 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget),
switch (style & GDK_IM_PREEDIT_MASK) switch (style & GDK_IM_PREEDIT_MASK)
{ {
case GDK_IM_PREEDIT_POSITION: case GDK_IM_PREEDIT_POSITION:
if (widget->style && widget->style->font->type != GDK_FONT_FONTSET) if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
{ {
g_warning ("over-the-spot style requires fontset"); g_warning ("over-the-spot style requires fontset");
break; break;
} }
gdk_window_get_size (widget->window, &width, &height); gdk_window_get_size (widget->window, &width, &height);
attrmask |= GDK_IC_PREEDIT_POSITION_REQ; attrmask |= GDK_IC_PREEDIT_POSITION_REQ;
attr->spot_location.x = 0; attr->spot_location.x = 0;
attr->spot_location.y = height; attr->spot_location.y = height;
attr->preedit_area.x = 0; attr->preedit_area.x = 0;
attr->preedit_area.y = 0; attr->preedit_area.y = 0;
attr->preedit_area.width = width; attr->preedit_area.width = width;
attr->preedit_area.height = height; attr->preedit_area.height = height;
attr->preedit_fontset = widget->style->font; attr->preedit_fontset = widget->style->font;
break; break;
} }
win->m_ic = gdk_ic_new (attr, (GdkICAttributesType)attrmask); win->m_ic = gdk_ic_new (attr, (GdkICAttributesType)attrmask);
if (win->m_ic == NULL) if (win->m_ic == NULL)
g_warning ("Can't create input context."); g_warning ("Can't create input context.");
else else
{ {
mask = gdk_window_get_events (widget->window); mask = gdk_window_get_events (widget->window);
mask = (GdkEventMask)(mask | gdk_ic_get_events (win->m_ic)); mask = (GdkEventMask)(mask | gdk_ic_get_events (win->m_ic));
gdk_window_set_events (widget->window, mask); gdk_window_set_events (widget->window, mask);
if (GTK_WIDGET_HAS_FOCUS(widget)) if (GTK_WIDGET_HAS_FOCUS(widget))
gdk_im_begin (win->m_ic, widget->window); gdk_im_begin (win->m_ic, widget->window);
} }
#endif #endif
return FALSE; return FALSE;
@@ -2166,7 +2169,7 @@ void wxWindowGTK::Init()
m_delayedForegroundColour = FALSE; m_delayedForegroundColour = FALSE;
m_delayedBackgroundColour = FALSE; m_delayedBackgroundColour = FALSE;
#ifdef HAVE_XIM #ifdef HAVE_XIM
m_ic = (GdkIC*) NULL; m_ic = (GdkIC*) NULL;
m_icattr = (GdkICAttr*) NULL; m_icattr = (GdkICAttr*) NULL;
@@ -2205,7 +2208,7 @@ bool wxWindowGTK::Create( wxWindow *parent,
} }
m_insertCallback = wxInsertChildInWindow; m_insertCallback = wxInsertChildInWindow;
m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL ); m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
@@ -2349,7 +2352,7 @@ wxWindowGTK::~wxWindowGTK()
// don't delete if it's a pixmap theme style // don't delete if it's a pixmap theme style
if (!m_widgetStyle->engine_data) if (!m_widgetStyle->engine_data)
gtk_style_unref( m_widgetStyle ); gtk_style_unref( m_widgetStyle );
#endif #endif
m_widgetStyle = (GtkStyle*) NULL; m_widgetStyle = (GtkStyle*) NULL;
} }
@@ -2407,7 +2410,7 @@ void wxWindowGTK::PostCreation()
if (!m_noExpose) if (!m_noExpose)
{ {
/* these get reported to wxWindows -> wxPaintEvent */ /* these get reported to wxWindows -> wxPaintEvent */
gtk_pizza_set_external( GTK_PIZZA(m_wxwindow), TRUE ); gtk_pizza_set_external( GTK_PIZZA(m_wxwindow), TRUE );
gtk_signal_connect( GTK_OBJECT(m_wxwindow), "event", gtk_signal_connect( GTK_OBJECT(m_wxwindow), "event",
@@ -2441,7 +2444,7 @@ void wxWindowGTK::PostCreation()
else else
{ {
// For dialogs and frames, we are interested mainly in // For dialogs and frames, we are interested mainly in
// m_widget's focus. // m_widget's focus.
gtk_signal_connect( GTK_OBJECT(m_widget), "focus_in_event", gtk_signal_connect( GTK_OBJECT(m_widget), "focus_in_event",
GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this ); GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
@@ -2522,7 +2525,7 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags
if (m_resizing) return; /* I don't like recursions */ if (m_resizing) return; /* I don't like recursions */
m_resizing = TRUE; 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. */
@@ -2583,7 +2586,7 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags
if (m_hasScrolling) if (m_hasScrolling)
{ {
/* Sometimes the client area changes size without the /* Sometimes the client area changes size without the
whole windows's size changing, but if the whole whole windows's size changing, but if the whole
windows's size doesn't change, no wxSizeEvent will windows's size doesn't change, no wxSizeEvent will
normally be sent. Here we add an extra test if normally be sent. Here we add an extra test if
@@ -3061,7 +3064,7 @@ bool wxWindowGTK::SetCursor( const wxCursor &cursor )
if (g_isIdle) if (g_isIdle)
wxapp_install_idle_handler(); wxapp_install_idle_handler();
if (cursor == wxNullCursor) if (cursor == wxNullCursor)
return wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ); return wxWindowBase::SetCursor( *wxSTANDARD_CURSOR );
else else
@@ -3341,7 +3344,7 @@ void wxWindowGTK::SetWidgetStyle()
style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor(); style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor();
style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor(); style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor();
} }
else else
{ {
// Try to restore the gtk default style. This is still a little // Try to restore the gtk default style. This is still a little
// oversimplified for what is probably really needed here for controls // oversimplified for what is probably really needed here for controls
@@ -3378,7 +3381,7 @@ void wxWindowGTK::SetWidgetStyle()
// oversimplified for what is probably really needed here for controls // oversimplified for what is probably really needed here for controls
// other than buttons, but is better than not being able to (re)set a // other than buttons, but is better than not being able to (re)set a
// control's background colour to default grey and means resetting a // control's background colour to default grey and means resetting a
// button to wxSYS_COLOUR_BTNFACE will restore its usual highlighting // button to wxSYS_COLOUR_BTNFACE will restore its usual highlighting
// behavior -- RL // behavior -- RL
GtkStyle *def = gtk_rc_get_style( m_widget ); GtkStyle *def = gtk_rc_get_style( m_widget );
@@ -3749,14 +3752,14 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
wxCHECK_RET( m_widget != NULL, wxT("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, wxT("window needs client area for scrolling") );
if ((dx == 0) && (dy == 0)) return; if ((dx == 0) && (dy == 0)) return;
m_clipPaintRegion = TRUE; m_clipPaintRegion = TRUE;
gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
m_clipPaintRegion = FALSE; m_clipPaintRegion = FALSE;
/* /*
if (m_children.GetCount() > 0) if (m_children.GetCount() > 0)
{ {
gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
@@ -3764,10 +3767,10 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
else else
{ {
GtkPizza *pizza = GTK_PIZZA(m_wxwindow); GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
pizza->xoffset -= dx; pizza->xoffset -= dx;
pizza->yoffset -= dy; pizza->yoffset -= dy;
GdkGC *m_scrollGC = gdk_gc_new( pizza->bin_window ); GdkGC *m_scrollGC = gdk_gc_new( pizza->bin_window );
gdk_gc_set_exposures( m_scrollGC, TRUE ); gdk_gc_set_exposures( m_scrollGC, TRUE );
@@ -3780,7 +3783,7 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
if ((h < 0) || (w < 0)) if ((h < 0) || (w < 0))
{ {
Refresh(); Refresh();
} }
else else
{ {
int s_x = 0; int s_x = 0;
@@ -3803,7 +3806,7 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
Refresh( TRUE, &rect ); Refresh( TRUE, &rect );
} }
gdk_gc_unref( m_scrollGC ); gdk_gc_unref( m_scrollGC );
} }
*/ */

View File

@@ -438,9 +438,9 @@ static void draw_frame( GtkWidget *widget, wxWindowGTK *win )
gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindowGTK *win ) gint gtk_window_own_expose_callback( GtkWidget *widget, GdkEventExpose *gdk_event, wxWindowGTK *win )
{ {
if (gdk_event->count > 0) return FALSE; if (gdk_event->count > 0) return FALSE;
draw_frame( widget, win ); draw_frame( widget, win );
return TRUE; return TRUE;
} }
@@ -675,7 +675,7 @@ static int gtk_window_expose_callback( GtkWidget *widget,
if (g_isIdle) if (g_isIdle)
wxapp_install_idle_handler(); wxapp_install_idle_handler();
/* /*
if (win->GetName() == wxT("panel")) if (win->GetName() == wxT("panel"))
{ {
@@ -688,7 +688,7 @@ static int gtk_window_expose_callback( GtkWidget *widget,
(int)gdk_event->area.height ); (int)gdk_event->area.height );
} }
*/ */
win->GetUpdateRegion().Union( gdk_event->area.x, win->GetUpdateRegion().Union( gdk_event->area.x,
gdk_event->area.y, gdk_event->area.y,
gdk_event->area.width, gdk_event->area.width,
@@ -707,14 +707,14 @@ static int gtk_window_expose_callback( GtkWidget *widget,
win->GetUpdateRegion().Clear(); win->GetUpdateRegion().Clear();
} }
/* The following code will result in all window-less widgets /* The following code will result in all window-less widgets
being redrawn if the wxWindows class is given a chance to being redrawn if the wxWindows class is given a chance to
paint *anything* because it will then be allowed to paint paint *anything* because it will then be allowed to paint
over the window-less widgets */ over the window-less widgets */
GtkPizza *pizza = GTK_PIZZA (widget); GtkPizza *pizza = GTK_PIZZA (widget);
GList *children = pizza->children; GList *children = pizza->children;
while (children) while (children)
{ {
@@ -734,7 +734,7 @@ static int gtk_window_expose_callback( GtkWidget *widget,
gtk_widget_event (child->widget, (GdkEvent*) &child_event); gtk_widget_event (child->widget, (GdkEvent*) &child_event);
} }
} }
return TRUE; return TRUE;
} }
@@ -768,13 +768,15 @@ gint gtk_window_event_event_callback( GtkWidget *widget,
/* This callback is a complete replacement of the gtk_pizza_draw() function, /* This callback is a complete replacement of the gtk_pizza_draw() function,
which disabled. */ which disabled. */
static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxWindowGTK *win ) static void gtk_window_draw_callback( GtkWidget *widget,
GdkRectangle *rect,
wxWindow *win )
{ {
DEBUG_MAIN_THREAD DEBUG_MAIN_THREAD
if (g_isIdle) if (g_isIdle)
wxapp_install_idle_handler(); wxapp_install_idle_handler();
/* /*
if (win->GetName() == wxT("panel")) if (win->GetName() == wxT("panel"))
{ {
@@ -787,45 +789,46 @@ static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxW
(int)rect->height ); (int)rect->height );
} }
*/ */
GtkPizza *pizza = GTK_PIZZA (widget); GtkPizza *pizza = GTK_PIZZA (widget);
if (!(GTK_WIDGET_APP_PAINTABLE (widget)) && if (!(GTK_WIDGET_APP_PAINTABLE (widget)) &&
(pizza->clear_on_draw)) (pizza->clear_on_draw))
{
gdk_window_clear_area( pizza->bin_window,
rect->x, rect->y, rect->width, rect->height);
}
win->GetUpdateRegion().Union( rect->x, rect->y, rect->width, rect->height );
win->m_clipPaintRegion = TRUE;
wxClientDC dc(win);
wxEraseEvent eevent( win->GetId(), &dc );
eevent.SetEventObject( win );
win->GetEventHandler()->ProcessEvent(eevent);
wxPaintEvent event( win->GetId() );
event.SetEventObject( win );
win->GetEventHandler()->ProcessEvent( event );
win->GetUpdateRegion().Clear();
win->m_clipPaintRegion = FALSE;
GList *children = pizza->children;
while (children)
{
GtkPizzaChild *child = (GtkPizzaChild*) children->data;
children = children->next;
GdkRectangle child_area;
if (gtk_widget_intersect (child->widget, rect, &child_area))
{ {
gdk_window_clear_area( pizza->bin_window, gtk_widget_draw (child->widget, &child_area /* (GdkRectangle*) NULL*/ );
rect->x, rect->y, rect->width, rect->height);
}
win->GetUpdateRegion().Union( rect->x, rect->y, rect->width, rect->height );
win->m_clipPaintRegion = TRUE;
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();
win->m_clipPaintRegion = FALSE;
GList *children = pizza->children;
while (children)
{
GtkPizzaChild *child = (GtkPizzaChild*) children->data;
children = children->next;
GdkRectangle child_area;
if (gtk_widget_intersect (child->widget, rect, &child_area))
{
gtk_widget_draw (child->widget, &child_area /* (GdkRectangle*) NULL*/ );
}
} }
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@@ -1915,7 +1918,7 @@ gtk_window_realized_callback( GtkWidget *WXUNUSED(m_widget), wxWindow *win )
wxWindowCreateEvent event( win ); wxWindowCreateEvent event( win );
event.SetEventObject( win ); event.SetEventObject( win );
win->GetEventHandler()->ProcessEvent( event ); win->GetEventHandler()->ProcessEvent( event );
return FALSE; return FALSE;
} }
@@ -2012,22 +2015,22 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget),
GdkIMStyle style; GdkIMStyle style;
GdkIMStyle supported_style = (GdkIMStyle) GdkIMStyle supported_style = (GdkIMStyle)
(GDK_IM_PREEDIT_NONE | (GDK_IM_PREEDIT_NONE |
GDK_IM_PREEDIT_NOTHING | GDK_IM_PREEDIT_NOTHING |
GDK_IM_PREEDIT_POSITION | GDK_IM_PREEDIT_POSITION |
GDK_IM_STATUS_NONE | GDK_IM_STATUS_NONE |
GDK_IM_STATUS_NOTHING); GDK_IM_STATUS_NOTHING);
if (widget->style && widget->style->font->type != GDK_FONT_FONTSET) if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
supported_style = (GdkIMStyle)(supported_style & ~GDK_IM_PREEDIT_POSITION); supported_style = (GdkIMStyle)(supported_style & ~GDK_IM_PREEDIT_POSITION);
attr->style = style = gdk_im_decide_style (supported_style); attr->style = style = gdk_im_decide_style (supported_style);
attr->client_window = widget->window; attr->client_window = widget->window;
if ((colormap = gtk_widget_get_colormap (widget)) != if ((colormap = gtk_widget_get_colormap (widget)) !=
gtk_widget_get_default_colormap ()) gtk_widget_get_default_colormap ())
{ {
attrmask |= GDK_IC_PREEDIT_COLORMAP; attrmask |= GDK_IC_PREEDIT_COLORMAP;
attr->preedit_colormap = colormap; attr->preedit_colormap = colormap;
} }
attrmask |= GDK_IC_PREEDIT_FOREGROUND; attrmask |= GDK_IC_PREEDIT_FOREGROUND;
@@ -2037,40 +2040,40 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget),
switch (style & GDK_IM_PREEDIT_MASK) switch (style & GDK_IM_PREEDIT_MASK)
{ {
case GDK_IM_PREEDIT_POSITION: case GDK_IM_PREEDIT_POSITION:
if (widget->style && widget->style->font->type != GDK_FONT_FONTSET) if (widget->style && widget->style->font->type != GDK_FONT_FONTSET)
{ {
g_warning ("over-the-spot style requires fontset"); g_warning ("over-the-spot style requires fontset");
break; break;
} }
gdk_window_get_size (widget->window, &width, &height); gdk_window_get_size (widget->window, &width, &height);
attrmask |= GDK_IC_PREEDIT_POSITION_REQ; attrmask |= GDK_IC_PREEDIT_POSITION_REQ;
attr->spot_location.x = 0; attr->spot_location.x = 0;
attr->spot_location.y = height; attr->spot_location.y = height;
attr->preedit_area.x = 0; attr->preedit_area.x = 0;
attr->preedit_area.y = 0; attr->preedit_area.y = 0;
attr->preedit_area.width = width; attr->preedit_area.width = width;
attr->preedit_area.height = height; attr->preedit_area.height = height;
attr->preedit_fontset = widget->style->font; attr->preedit_fontset = widget->style->font;
break; break;
} }
win->m_ic = gdk_ic_new (attr, (GdkICAttributesType)attrmask); win->m_ic = gdk_ic_new (attr, (GdkICAttributesType)attrmask);
if (win->m_ic == NULL) if (win->m_ic == NULL)
g_warning ("Can't create input context."); g_warning ("Can't create input context.");
else else
{ {
mask = gdk_window_get_events (widget->window); mask = gdk_window_get_events (widget->window);
mask = (GdkEventMask)(mask | gdk_ic_get_events (win->m_ic)); mask = (GdkEventMask)(mask | gdk_ic_get_events (win->m_ic));
gdk_window_set_events (widget->window, mask); gdk_window_set_events (widget->window, mask);
if (GTK_WIDGET_HAS_FOCUS(widget)) if (GTK_WIDGET_HAS_FOCUS(widget))
gdk_im_begin (win->m_ic, widget->window); gdk_im_begin (win->m_ic, widget->window);
} }
#endif #endif
return FALSE; return FALSE;
@@ -2166,7 +2169,7 @@ void wxWindowGTK::Init()
m_delayedForegroundColour = FALSE; m_delayedForegroundColour = FALSE;
m_delayedBackgroundColour = FALSE; m_delayedBackgroundColour = FALSE;
#ifdef HAVE_XIM #ifdef HAVE_XIM
m_ic = (GdkIC*) NULL; m_ic = (GdkIC*) NULL;
m_icattr = (GdkICAttr*) NULL; m_icattr = (GdkICAttr*) NULL;
@@ -2205,7 +2208,7 @@ bool wxWindowGTK::Create( wxWindow *parent,
} }
m_insertCallback = wxInsertChildInWindow; m_insertCallback = wxInsertChildInWindow;
m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL ); m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL );
GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS ); GTK_WIDGET_UNSET_FLAGS( m_widget, GTK_CAN_FOCUS );
@@ -2349,7 +2352,7 @@ wxWindowGTK::~wxWindowGTK()
// don't delete if it's a pixmap theme style // don't delete if it's a pixmap theme style
if (!m_widgetStyle->engine_data) if (!m_widgetStyle->engine_data)
gtk_style_unref( m_widgetStyle ); gtk_style_unref( m_widgetStyle );
#endif #endif
m_widgetStyle = (GtkStyle*) NULL; m_widgetStyle = (GtkStyle*) NULL;
} }
@@ -2407,7 +2410,7 @@ void wxWindowGTK::PostCreation()
if (!m_noExpose) if (!m_noExpose)
{ {
/* these get reported to wxWindows -> wxPaintEvent */ /* these get reported to wxWindows -> wxPaintEvent */
gtk_pizza_set_external( GTK_PIZZA(m_wxwindow), TRUE ); gtk_pizza_set_external( GTK_PIZZA(m_wxwindow), TRUE );
gtk_signal_connect( GTK_OBJECT(m_wxwindow), "event", gtk_signal_connect( GTK_OBJECT(m_wxwindow), "event",
@@ -2441,7 +2444,7 @@ void wxWindowGTK::PostCreation()
else else
{ {
// For dialogs and frames, we are interested mainly in // For dialogs and frames, we are interested mainly in
// m_widget's focus. // m_widget's focus.
gtk_signal_connect( GTK_OBJECT(m_widget), "focus_in_event", gtk_signal_connect( GTK_OBJECT(m_widget), "focus_in_event",
GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this ); GTK_SIGNAL_FUNC(gtk_window_focus_in_callback), (gpointer)this );
@@ -2522,7 +2525,7 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags
if (m_resizing) return; /* I don't like recursions */ if (m_resizing) return; /* I don't like recursions */
m_resizing = TRUE; 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. */
@@ -2583,7 +2586,7 @@ void wxWindowGTK::DoSetSize( int x, int y, int width, int height, int sizeFlags
if (m_hasScrolling) if (m_hasScrolling)
{ {
/* Sometimes the client area changes size without the /* Sometimes the client area changes size without the
whole windows's size changing, but if the whole whole windows's size changing, but if the whole
windows's size doesn't change, no wxSizeEvent will windows's size doesn't change, no wxSizeEvent will
normally be sent. Here we add an extra test if normally be sent. Here we add an extra test if
@@ -3061,7 +3064,7 @@ bool wxWindowGTK::SetCursor( const wxCursor &cursor )
if (g_isIdle) if (g_isIdle)
wxapp_install_idle_handler(); wxapp_install_idle_handler();
if (cursor == wxNullCursor) if (cursor == wxNullCursor)
return wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ); return wxWindowBase::SetCursor( *wxSTANDARD_CURSOR );
else else
@@ -3341,7 +3344,7 @@ void wxWindowGTK::SetWidgetStyle()
style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor(); style->fg[GTK_STATE_PRELIGHT] = *m_foregroundColour.GetColor();
style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor(); style->fg[GTK_STATE_ACTIVE] = *m_foregroundColour.GetColor();
} }
else else
{ {
// Try to restore the gtk default style. This is still a little // Try to restore the gtk default style. This is still a little
// oversimplified for what is probably really needed here for controls // oversimplified for what is probably really needed here for controls
@@ -3378,7 +3381,7 @@ void wxWindowGTK::SetWidgetStyle()
// oversimplified for what is probably really needed here for controls // oversimplified for what is probably really needed here for controls
// other than buttons, but is better than not being able to (re)set a // other than buttons, but is better than not being able to (re)set a
// control's background colour to default grey and means resetting a // control's background colour to default grey and means resetting a
// button to wxSYS_COLOUR_BTNFACE will restore its usual highlighting // button to wxSYS_COLOUR_BTNFACE will restore its usual highlighting
// behavior -- RL // behavior -- RL
GtkStyle *def = gtk_rc_get_style( m_widget ); GtkStyle *def = gtk_rc_get_style( m_widget );
@@ -3749,14 +3752,14 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
wxCHECK_RET( m_widget != NULL, wxT("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, wxT("window needs client area for scrolling") );
if ((dx == 0) && (dy == 0)) return; if ((dx == 0) && (dy == 0)) return;
m_clipPaintRegion = TRUE; m_clipPaintRegion = TRUE;
gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
m_clipPaintRegion = FALSE; m_clipPaintRegion = FALSE;
/* /*
if (m_children.GetCount() > 0) if (m_children.GetCount() > 0)
{ {
gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy );
@@ -3764,10 +3767,10 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
else else
{ {
GtkPizza *pizza = GTK_PIZZA(m_wxwindow); GtkPizza *pizza = GTK_PIZZA(m_wxwindow);
pizza->xoffset -= dx; pizza->xoffset -= dx;
pizza->yoffset -= dy; pizza->yoffset -= dy;
GdkGC *m_scrollGC = gdk_gc_new( pizza->bin_window ); GdkGC *m_scrollGC = gdk_gc_new( pizza->bin_window );
gdk_gc_set_exposures( m_scrollGC, TRUE ); gdk_gc_set_exposures( m_scrollGC, TRUE );
@@ -3780,7 +3783,7 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
if ((h < 0) || (w < 0)) if ((h < 0) || (w < 0))
{ {
Refresh(); Refresh();
} }
else else
{ {
int s_x = 0; int s_x = 0;
@@ -3803,7 +3806,7 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) )
Refresh( TRUE, &rect ); Refresh( TRUE, &rect );
} }
gdk_gc_unref( m_scrollGC ); gdk_gc_unref( m_scrollGC );
} }
*/ */

View File

@@ -77,12 +77,7 @@ bool wxScrollBar::Create(wxWindow *parent,
if ( !wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name) ) if ( !wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name) )
return FALSE; return FALSE;
if ( size.x == -1 || size.y == -1 ) SetBestSize(size);
{
wxSize sizeBest = DoGetBestSize();
SetSize(size.x == -1 ? sizeBest.x : size.x,
size.y == -1 ? sizeBest.y : size.y);
}
return TRUE; return TRUE;
} }

View File

@@ -33,6 +33,7 @@
#include "wx/window.h" #include "wx/window.h"
#include "wx/dcclient.h" #include "wx/dcclient.h"
#include "wx/event.h" #include "wx/event.h"
#include "wx/scrolbar.h"
#endif // WX_PRECOMP #endif // WX_PRECOMP
#include "wx/univ/renderer.h" #include "wx/univ/renderer.h"
@@ -49,6 +50,8 @@
IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase) IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase)
BEGIN_EVENT_TABLE(wxWindow, wxWindowBase) BEGIN_EVENT_TABLE(wxWindow, wxWindowBase)
EVT_SIZE(wxWindow::OnSize)
EVT_PAINT(wxWindow::OnPaint) EVT_PAINT(wxWindow::OnPaint)
EVT_ERASE_BACKGROUND(wxWindow::OnErase) EVT_ERASE_BACKGROUND(wxWindow::OnErase)
END_EVENT_TABLE() END_EVENT_TABLE()
@@ -197,6 +200,16 @@ int wxWindow::GetStateFlags() const
// size // size
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void wxWindow::OnSize(wxSizeEvent& event)
{
if ( m_scrollbarVert || m_scrollbarHorz )
{
PositionScrollbars();
}
event.Skip();
}
wxSize wxWindow::AdjustSize(const wxSize& size) const wxSize wxWindow::AdjustSize(const wxSize& size) const
{ {
wxSize sz = size; wxSize sz = size;
@@ -204,36 +217,98 @@ wxSize wxWindow::AdjustSize(const wxSize& size) const
return sz; return sz;
} }
void wxWindow::DoSetClientSize(int width, int height)
{
// take into account the scrollbars
if ( m_scrollbarVert )
width += m_scrollbarVert->GetSize().x;
if ( m_scrollbarHorz )
height += m_scrollbarHorz->GetSize().y;
wxWindowNative::DoSetClientSize(width, height);
}
void wxWindow::DoGetClientSize(int *width, int *height) const
{
wxWindowNative::DoGetClientSize(width, height);
if ( width && m_scrollbarVert )
*width -= m_scrollbarVert->GetSize().x;
if ( height && m_scrollbarHorz )
*height -= m_scrollbarHorz->GetSize().y;
}
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
// scrolling // scrolling: we implement it entirely ourselves except for ScrollWindow()
// function which is supposed to be (efficiently) implemented by the native
// window class
// ---------------------------------------------------------------------------- // ----------------------------------------------------------------------------
void wxWindow::PositionScrollbars()
{
wxCoord x, y;
DoGetSize(&x, &y);
int width = m_scrollbarVert ? m_scrollbarVert->GetSize().x : 0;
int height = m_scrollbarHorz ? m_scrollbarHorz->GetSize().y : 0;
if ( m_scrollbarVert )
m_scrollbarVert->SetSize(x - width, 0, width, y - height);
if ( m_scrollbarHorz )
m_scrollbarHorz->SetSize(0, y - height, x - width, height);
}
void wxWindow::SetScrollbar(int orient, void wxWindow::SetScrollbar(int orient,
int pos, int pos,
int thumb, int thumb,
int range, int range,
bool refresh) bool refresh)
{ {
return wxWindowNative::SetScrollbar(orient, pos, thumb, range, refresh); wxScrollBar *scrollbar = GetScrollbar(orient);
if ( !scrollbar )
{
// create it
scrollbar = new wxScrollBar(this, -1,
wxDefaultPosition, wxDefaultSize,
orient & wxVERTICAL ? wxSB_VERTICAL
: wxSB_HORIZONTAL);
if ( orient & wxVERTICAL )
m_scrollbarVert = scrollbar;
else
m_scrollbarHorz = scrollbar;
PositionScrollbars();
}
scrollbar->SetScrollbar(pos, thumb, range, thumb, refresh);
} }
void wxWindow::SetScrollPos(int orient, int pos, bool refresh) void wxWindow::SetScrollPos(int orient, int pos, bool refresh)
{ {
return wxWindowNative::SetScrollPos(orient, pos, refresh); wxScrollBar *scrollbar = GetScrollbar(orient);
wxCHECK_RET( scrollbar, _T("no scrollbar to set position for") );
scrollbar->SetThumbPosition(pos);
if ( refresh )
Refresh();
} }
int wxWindow::GetScrollPos(int orient) const int wxWindow::GetScrollPos(int orient) const
{ {
return wxWindowNative::GetScrollPos(orient); wxScrollBar *scrollbar = GetScrollbar(orient);
return scrollbar ? scrollbar->GetThumbPosition() : 0;
} }
int wxWindow::GetScrollThumb(int orient) const int wxWindow::GetScrollThumb(int orient) const
{ {
return wxWindowNative::GetScrollThumb(orient); wxScrollBar *scrollbar = GetScrollbar(orient);
return scrollbar ? scrollbar->GetThumbSize() : 0;
} }
int wxWindow::GetScrollRange(int orient) const int wxWindow::GetScrollRange(int orient) const
{ {
return wxWindowNative::GetScrollRange(orient); wxScrollBar *scrollbar = GetScrollbar(orient);
return scrollbar ? scrollbar->GetRange() : 0;
} }