diff --git a/include/wx/univ/window.h b/include/wx/univ/window.h index 2a58645d7d..913146cd89 100644 --- a/include/wx/univ/window.h +++ b/include/wx/univ/window.h @@ -63,6 +63,7 @@ public: // background pixmap support // ------------------------- + virtual void SetBackground(const wxBitmap& bitmap, int alignment = wxALIGN_CENTRE, wxStretch stretch = wxSTRETCH_NOT); @@ -74,11 +75,11 @@ public: // instead of the native ones // ------------------------------------------------------------------ - virtual void SetScrollbar( int orient, - int pos, - int thumbVisible, - int range, - bool refresh = TRUE ); + virtual void SetScrollbar(int orient, + int pos, + int page, + int range, + bool refresh = TRUE ); virtual void SetScrollPos( int orient, int pos, bool refresh = TRUE ); virtual int GetScrollPos( int orient ) const; virtual int GetScrollThumb( int orient ) const; @@ -103,7 +104,14 @@ protected: // common part of all ctors 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 + void OnSize(wxSizeEvent& event); void OnPaint(wxPaintEvent& event); void OnErase(wxEraseEvent& event); @@ -120,6 +128,15 @@ protected: // adjust the size of the window to take into account its borders 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 wxBitmap m_bitmapBg; int m_alignBgBitmap; diff --git a/samples/univ/univ.cpp b/samples/univ/univ.cpp index 0b6de10279..11732d24f3 100644 --- a/samples/univ/univ.cpp +++ b/samples/univ/univ.cpp @@ -37,6 +37,7 @@ #include "wx/bmpbuttn.h" #include "wx/button.h" #include "wx/scrolbar.h" + #include "wx/scrolwin.h" #include "wx/statbox.h" #include "wx/stattext.h" #endif @@ -236,11 +237,26 @@ MyUnivFrame::MyUnivFrame(const wxString& title) new wxStaticBitmap(this, -1, wxBITMAP(tip), wxPoint(50, 350), wxDefaultSize, wxSUNKEN_BORDER); +#if 0 wxScrollBar *sb; sb = new wxScrollBar(this, -1, wxPoint(200, 300), wxSize(300, -1)); sb->SetScrollbar(0, 10, 100, 10); sb = new wxScrollBar(this, -1, wxPoint(200, 330), wxSize(-1, 150), wxSB_VERTICAL); 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)); diff --git a/src/gtk/window.cpp b/src/gtk/window.cpp index 9d475f43d9..1c52f515d3 100644 --- a/src/gtk/window.cpp +++ b/src/gtk/window.cpp @@ -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 ) { if (gdk_event->count > 0) return FALSE; - + draw_frame( widget, win ); - + return TRUE; } @@ -675,7 +675,7 @@ static int gtk_window_expose_callback( GtkWidget *widget, if (g_isIdle) wxapp_install_idle_handler(); - + /* if (win->GetName() == wxT("panel")) { @@ -688,7 +688,7 @@ static int gtk_window_expose_callback( GtkWidget *widget, (int)gdk_event->area.height ); } */ - + win->GetUpdateRegion().Union( gdk_event->area.x, gdk_event->area.y, gdk_event->area.width, @@ -707,14 +707,14 @@ static int gtk_window_expose_callback( GtkWidget *widget, win->GetUpdateRegion().Clear(); } - + /* The following code will result in all window-less widgets being redrawn if the wxWindows class is given a chance to paint *anything* because it will then be allowed to paint over the window-less widgets */ - + GtkPizza *pizza = GTK_PIZZA (widget); - + GList *children = pizza->children; while (children) { @@ -734,7 +734,7 @@ static int gtk_window_expose_callback( GtkWidget *widget, gtk_widget_event (child->widget, (GdkEvent*) &child_event); } } - + 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, 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 if (g_isIdle) wxapp_install_idle_handler(); - + /* if (win->GetName() == wxT("panel")) { @@ -787,45 +789,46 @@ static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxW (int)rect->height ); } */ - + GtkPizza *pizza = GTK_PIZZA (widget); - - if (!(GTK_WIDGET_APP_PAINTABLE (widget)) && - (pizza->clear_on_draw)) + + if (!(GTK_WIDGET_APP_PAINTABLE (widget)) && + (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, - 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*/ ); - } + 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 ); event.SetEventObject( win ); win->GetEventHandler()->ProcessEvent( event ); - + return FALSE; } @@ -2012,22 +2015,22 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget), GdkIMStyle style; GdkIMStyle supported_style = (GdkIMStyle) (GDK_IM_PREEDIT_NONE | - GDK_IM_PREEDIT_NOTHING | - GDK_IM_PREEDIT_POSITION | - GDK_IM_STATUS_NONE | - GDK_IM_STATUS_NOTHING); + GDK_IM_PREEDIT_NOTHING | + GDK_IM_PREEDIT_POSITION | + GDK_IM_STATUS_NONE | + GDK_IM_STATUS_NOTHING); 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->client_window = widget->window; if ((colormap = gtk_widget_get_colormap (widget)) != - gtk_widget_get_default_colormap ()) + gtk_widget_get_default_colormap ()) { - attrmask |= GDK_IC_PREEDIT_COLORMAP; - attr->preedit_colormap = colormap; + attrmask |= GDK_IC_PREEDIT_COLORMAP; + attr->preedit_colormap = colormap; } attrmask |= GDK_IC_PREEDIT_FOREGROUND; @@ -2037,40 +2040,40 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget), switch (style & GDK_IM_PREEDIT_MASK) { - case GDK_IM_PREEDIT_POSITION: - if (widget->style && widget->style->font->type != GDK_FONT_FONTSET) - { - g_warning ("over-the-spot style requires fontset"); - break; - } + case GDK_IM_PREEDIT_POSITION: + if (widget->style && widget->style->font->type != GDK_FONT_FONTSET) + { + g_warning ("over-the-spot style requires fontset"); + break; + } - gdk_window_get_size (widget->window, &width, &height); + gdk_window_get_size (widget->window, &width, &height); - attrmask |= GDK_IC_PREEDIT_POSITION_REQ; - attr->spot_location.x = 0; - attr->spot_location.y = height; - attr->preedit_area.x = 0; - attr->preedit_area.y = 0; - attr->preedit_area.width = width; - attr->preedit_area.height = height; - attr->preedit_fontset = widget->style->font; + attrmask |= GDK_IC_PREEDIT_POSITION_REQ; + attr->spot_location.x = 0; + attr->spot_location.y = height; + attr->preedit_area.x = 0; + attr->preedit_area.y = 0; + attr->preedit_area.width = width; + attr->preedit_area.height = height; + attr->preedit_fontset = widget->style->font; - break; + break; } win->m_ic = gdk_ic_new (attr, (GdkICAttributesType)attrmask); if (win->m_ic == NULL) - g_warning ("Can't create input context."); + g_warning ("Can't create input context."); else - { - mask = gdk_window_get_events (widget->window); - mask = (GdkEventMask)(mask | gdk_ic_get_events (win->m_ic)); - gdk_window_set_events (widget->window, mask); + { + mask = gdk_window_get_events (widget->window); + mask = (GdkEventMask)(mask | gdk_ic_get_events (win->m_ic)); + gdk_window_set_events (widget->window, mask); - if (GTK_WIDGET_HAS_FOCUS(widget)) - gdk_im_begin (win->m_ic, widget->window); - } + if (GTK_WIDGET_HAS_FOCUS(widget)) + gdk_im_begin (win->m_ic, widget->window); + } #endif return FALSE; @@ -2166,7 +2169,7 @@ void wxWindowGTK::Init() m_delayedForegroundColour = FALSE; m_delayedBackgroundColour = FALSE; - + #ifdef HAVE_XIM m_ic = (GdkIC*) NULL; m_icattr = (GdkICAttr*) NULL; @@ -2205,7 +2208,7 @@ bool wxWindowGTK::Create( wxWindow *parent, } m_insertCallback = wxInsertChildInWindow; - + m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL ); 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 if (!m_widgetStyle->engine_data) gtk_style_unref( m_widgetStyle ); -#endif +#endif m_widgetStyle = (GtkStyle*) NULL; } @@ -2407,7 +2410,7 @@ void wxWindowGTK::PostCreation() if (!m_noExpose) { /* these get reported to wxWindows -> wxPaintEvent */ - + gtk_pizza_set_external( GTK_PIZZA(m_wxwindow), TRUE ); gtk_signal_connect( GTK_OBJECT(m_wxwindow), "event", @@ -2441,7 +2444,7 @@ void wxWindowGTK::PostCreation() else { // 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_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 */ m_resizing = TRUE; - + if (m_parent->m_wxwindow == NULL) /* i.e. wxNotebook */ { /* 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) { - /* 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 windows's size doesn't change, no wxSizeEvent will normally be sent. Here we add an extra test if @@ -3061,7 +3064,7 @@ bool wxWindowGTK::SetCursor( const wxCursor &cursor ) if (g_isIdle) wxapp_install_idle_handler(); - + if (cursor == wxNullCursor) return wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ); else @@ -3341,7 +3344,7 @@ void wxWindowGTK::SetWidgetStyle() style->fg[GTK_STATE_PRELIGHT] = *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 // 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 // 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 - // button to wxSYS_COLOUR_BTNFACE will restore its usual highlighting + // button to wxSYS_COLOUR_BTNFACE will restore its usual highlighting // behavior -- RL 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_wxwindow != NULL, wxT("window needs client area for scrolling") ); - + if ((dx == 0) && (dy == 0)) return; m_clipPaintRegion = TRUE; gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); m_clipPaintRegion = FALSE; - -/* + +/* if (m_children.GetCount() > 0) { 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 { GtkPizza *pizza = GTK_PIZZA(m_wxwindow); - + pizza->xoffset -= dx; pizza->yoffset -= dy; - + GdkGC *m_scrollGC = gdk_gc_new( pizza->bin_window ); 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)) { Refresh(); - } + } else { int s_x = 0; @@ -3803,7 +3806,7 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) Refresh( TRUE, &rect ); } - + gdk_gc_unref( m_scrollGC ); } */ diff --git a/src/gtk1/window.cpp b/src/gtk1/window.cpp index 9d475f43d9..1c52f515d3 100644 --- a/src/gtk1/window.cpp +++ b/src/gtk1/window.cpp @@ -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 ) { if (gdk_event->count > 0) return FALSE; - + draw_frame( widget, win ); - + return TRUE; } @@ -675,7 +675,7 @@ static int gtk_window_expose_callback( GtkWidget *widget, if (g_isIdle) wxapp_install_idle_handler(); - + /* if (win->GetName() == wxT("panel")) { @@ -688,7 +688,7 @@ static int gtk_window_expose_callback( GtkWidget *widget, (int)gdk_event->area.height ); } */ - + win->GetUpdateRegion().Union( gdk_event->area.x, gdk_event->area.y, gdk_event->area.width, @@ -707,14 +707,14 @@ static int gtk_window_expose_callback( GtkWidget *widget, win->GetUpdateRegion().Clear(); } - + /* The following code will result in all window-less widgets being redrawn if the wxWindows class is given a chance to paint *anything* because it will then be allowed to paint over the window-less widgets */ - + GtkPizza *pizza = GTK_PIZZA (widget); - + GList *children = pizza->children; while (children) { @@ -734,7 +734,7 @@ static int gtk_window_expose_callback( GtkWidget *widget, gtk_widget_event (child->widget, (GdkEvent*) &child_event); } } - + 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, 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 if (g_isIdle) wxapp_install_idle_handler(); - + /* if (win->GetName() == wxT("panel")) { @@ -787,45 +789,46 @@ static void gtk_window_draw_callback( GtkWidget *widget, GdkRectangle *rect, wxW (int)rect->height ); } */ - + GtkPizza *pizza = GTK_PIZZA (widget); - - if (!(GTK_WIDGET_APP_PAINTABLE (widget)) && - (pizza->clear_on_draw)) + + if (!(GTK_WIDGET_APP_PAINTABLE (widget)) && + (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, - 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*/ ); - } + 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 ); event.SetEventObject( win ); win->GetEventHandler()->ProcessEvent( event ); - + return FALSE; } @@ -2012,22 +2015,22 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget), GdkIMStyle style; GdkIMStyle supported_style = (GdkIMStyle) (GDK_IM_PREEDIT_NONE | - GDK_IM_PREEDIT_NOTHING | - GDK_IM_PREEDIT_POSITION | - GDK_IM_STATUS_NONE | - GDK_IM_STATUS_NOTHING); + GDK_IM_PREEDIT_NOTHING | + GDK_IM_PREEDIT_POSITION | + GDK_IM_STATUS_NONE | + GDK_IM_STATUS_NOTHING); 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->client_window = widget->window; if ((colormap = gtk_widget_get_colormap (widget)) != - gtk_widget_get_default_colormap ()) + gtk_widget_get_default_colormap ()) { - attrmask |= GDK_IC_PREEDIT_COLORMAP; - attr->preedit_colormap = colormap; + attrmask |= GDK_IC_PREEDIT_COLORMAP; + attr->preedit_colormap = colormap; } attrmask |= GDK_IC_PREEDIT_FOREGROUND; @@ -2037,40 +2040,40 @@ gtk_wxwindow_realized_callback( GtkWidget * WXUNUSED_UNLESS_XIM(widget), switch (style & GDK_IM_PREEDIT_MASK) { - case GDK_IM_PREEDIT_POSITION: - if (widget->style && widget->style->font->type != GDK_FONT_FONTSET) - { - g_warning ("over-the-spot style requires fontset"); - break; - } + case GDK_IM_PREEDIT_POSITION: + if (widget->style && widget->style->font->type != GDK_FONT_FONTSET) + { + g_warning ("over-the-spot style requires fontset"); + break; + } - gdk_window_get_size (widget->window, &width, &height); + gdk_window_get_size (widget->window, &width, &height); - attrmask |= GDK_IC_PREEDIT_POSITION_REQ; - attr->spot_location.x = 0; - attr->spot_location.y = height; - attr->preedit_area.x = 0; - attr->preedit_area.y = 0; - attr->preedit_area.width = width; - attr->preedit_area.height = height; - attr->preedit_fontset = widget->style->font; + attrmask |= GDK_IC_PREEDIT_POSITION_REQ; + attr->spot_location.x = 0; + attr->spot_location.y = height; + attr->preedit_area.x = 0; + attr->preedit_area.y = 0; + attr->preedit_area.width = width; + attr->preedit_area.height = height; + attr->preedit_fontset = widget->style->font; - break; + break; } win->m_ic = gdk_ic_new (attr, (GdkICAttributesType)attrmask); if (win->m_ic == NULL) - g_warning ("Can't create input context."); + g_warning ("Can't create input context."); else - { - mask = gdk_window_get_events (widget->window); - mask = (GdkEventMask)(mask | gdk_ic_get_events (win->m_ic)); - gdk_window_set_events (widget->window, mask); + { + mask = gdk_window_get_events (widget->window); + mask = (GdkEventMask)(mask | gdk_ic_get_events (win->m_ic)); + gdk_window_set_events (widget->window, mask); - if (GTK_WIDGET_HAS_FOCUS(widget)) - gdk_im_begin (win->m_ic, widget->window); - } + if (GTK_WIDGET_HAS_FOCUS(widget)) + gdk_im_begin (win->m_ic, widget->window); + } #endif return FALSE; @@ -2166,7 +2169,7 @@ void wxWindowGTK::Init() m_delayedForegroundColour = FALSE; m_delayedBackgroundColour = FALSE; - + #ifdef HAVE_XIM m_ic = (GdkIC*) NULL; m_icattr = (GdkICAttr*) NULL; @@ -2205,7 +2208,7 @@ bool wxWindowGTK::Create( wxWindow *parent, } m_insertCallback = wxInsertChildInWindow; - + m_widget = gtk_scrolled_window_new( (GtkAdjustment *) NULL, (GtkAdjustment *) NULL ); 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 if (!m_widgetStyle->engine_data) gtk_style_unref( m_widgetStyle ); -#endif +#endif m_widgetStyle = (GtkStyle*) NULL; } @@ -2407,7 +2410,7 @@ void wxWindowGTK::PostCreation() if (!m_noExpose) { /* these get reported to wxWindows -> wxPaintEvent */ - + gtk_pizza_set_external( GTK_PIZZA(m_wxwindow), TRUE ); gtk_signal_connect( GTK_OBJECT(m_wxwindow), "event", @@ -2441,7 +2444,7 @@ void wxWindowGTK::PostCreation() else { // 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_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 */ m_resizing = TRUE; - + if (m_parent->m_wxwindow == NULL) /* i.e. wxNotebook */ { /* 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) { - /* 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 windows's size doesn't change, no wxSizeEvent will normally be sent. Here we add an extra test if @@ -3061,7 +3064,7 @@ bool wxWindowGTK::SetCursor( const wxCursor &cursor ) if (g_isIdle) wxapp_install_idle_handler(); - + if (cursor == wxNullCursor) return wxWindowBase::SetCursor( *wxSTANDARD_CURSOR ); else @@ -3341,7 +3344,7 @@ void wxWindowGTK::SetWidgetStyle() style->fg[GTK_STATE_PRELIGHT] = *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 // 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 // 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 - // button to wxSYS_COLOUR_BTNFACE will restore its usual highlighting + // button to wxSYS_COLOUR_BTNFACE will restore its usual highlighting // behavior -- RL 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_wxwindow != NULL, wxT("window needs client area for scrolling") ); - + if ((dx == 0) && (dy == 0)) return; m_clipPaintRegion = TRUE; gtk_pizza_scroll( GTK_PIZZA(m_wxwindow), -dx, -dy ); m_clipPaintRegion = FALSE; - -/* + +/* if (m_children.GetCount() > 0) { 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 { GtkPizza *pizza = GTK_PIZZA(m_wxwindow); - + pizza->xoffset -= dx; pizza->yoffset -= dy; - + GdkGC *m_scrollGC = gdk_gc_new( pizza->bin_window ); 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)) { Refresh(); - } + } else { int s_x = 0; @@ -3803,7 +3806,7 @@ void wxWindowGTK::ScrollWindow( int dx, int dy, const wxRect* WXUNUSED(rect) ) Refresh( TRUE, &rect ); } - + gdk_gc_unref( m_scrollGC ); } */ diff --git a/src/univ/scrolbar.cpp b/src/univ/scrolbar.cpp index c202027b14..caffa661a4 100644 --- a/src/univ/scrolbar.cpp +++ b/src/univ/scrolbar.cpp @@ -77,12 +77,7 @@ bool wxScrollBar::Create(wxWindow *parent, if ( !wxControl::Create(parent, id, pos, size, style, wxDefaultValidator, name) ) return FALSE; - if ( size.x == -1 || size.y == -1 ) - { - wxSize sizeBest = DoGetBestSize(); - SetSize(size.x == -1 ? sizeBest.x : size.x, - size.y == -1 ? sizeBest.y : size.y); - } + SetBestSize(size); return TRUE; } diff --git a/src/univ/winuniv.cpp b/src/univ/winuniv.cpp index 545be5e032..1b02b0e86a 100644 --- a/src/univ/winuniv.cpp +++ b/src/univ/winuniv.cpp @@ -33,6 +33,7 @@ #include "wx/window.h" #include "wx/dcclient.h" #include "wx/event.h" + #include "wx/scrolbar.h" #endif // WX_PRECOMP #include "wx/univ/renderer.h" @@ -49,6 +50,8 @@ IMPLEMENT_DYNAMIC_CLASS(wxWindow, wxWindowBase) BEGIN_EVENT_TABLE(wxWindow, wxWindowBase) + EVT_SIZE(wxWindow::OnSize) + EVT_PAINT(wxWindow::OnPaint) EVT_ERASE_BACKGROUND(wxWindow::OnErase) END_EVENT_TABLE() @@ -197,6 +200,16 @@ int wxWindow::GetStateFlags() const // size // ---------------------------------------------------------------------------- +void wxWindow::OnSize(wxSizeEvent& event) +{ + if ( m_scrollbarVert || m_scrollbarHorz ) + { + PositionScrollbars(); + } + + event.Skip(); +} + wxSize wxWindow::AdjustSize(const wxSize& size) const { wxSize sz = size; @@ -204,36 +217,98 @@ wxSize wxWindow::AdjustSize(const wxSize& size) const 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, int pos, int thumb, int range, 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) { - 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 { - return wxWindowNative::GetScrollPos(orient); + wxScrollBar *scrollbar = GetScrollbar(orient); + return scrollbar ? scrollbar->GetThumbPosition() : 0; } 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 { - return wxWindowNative::GetScrollRange(orient); + wxScrollBar *scrollbar = GetScrollbar(orient); + return scrollbar ? scrollbar->GetRange() : 0; } -