diff --git a/widget/src/gtk/gtkdrawing.c b/widget/src/gtk/gtkdrawing.c index c510c5220ea4..746fda78bd10 100644 --- a/widget/src/gtk/gtkdrawing.c +++ b/widget/src/gtk/gtkdrawing.c @@ -47,6 +47,7 @@ extern GtkWidget* gButtonWidget; extern GtkWidget* gCheckboxWidget; +extern GtkWidget* gScrollbarWidget; GtkStateType ConvertGtkState(GtkWidgetState* aState) @@ -185,7 +186,35 @@ moz_gtk_scrollbar_button_paint(GdkWindow* window, GtkStyle* style, GtkShadowType shadow_type = (state->active) ? GTK_SHADOW_IN : GTK_SHADOW_OUT; moz_gtk_button_paint(window, style, arrowRect, clipRect, state); - gtk_draw_arrow(style, window, state_type, shadow_type, arrowType, TRUE, - arrowRect->x, arrowRect->y, arrowRect->width, arrowRect->height); + gtk_paint_arrow(style, window, state_type, shadow_type, clipRect, + gScrollbarWidget, (arrowType < 2) ? "vscrollbar" : "hscrollbar", + arrowType, TRUE, + arrowRect->x, arrowRect->y, arrowRect->width, arrowRect->height); +} + +void +moz_gtk_scrollbar_trough_paint(GdkWindow* window, GtkStyle* style, + GdkRectangle* troughRect, GdkRectangle* clipRect, + GtkWidgetState* state) +{ + gtk_paint_box(style, window, GTK_STATE_ACTIVE, GTK_SHADOW_IN, + clipRect, gScrollbarWidget, "trough", troughRect->x, + troughRect->y, troughRect->width, troughRect->height); + + if (state->focused) + gtk_paint_focus(style, window, clipRect, gScrollbarWidget, "trough", + troughRect->x, troughRect->y, troughRect->width, + troughRect->height); +} + +void +moz_gtk_scrollbar_thumb_paint(GdkWindow* window, GtkStyle* style, + GdkRectangle* thumbRect, GdkRectangle* clipRect, + GtkWidgetState* state) +{ + GtkStateType state_type = state->inHover ? GTK_STATE_PRELIGHT : GTK_STATE_NORMAL; + gtk_paint_box(style, window, state_type, GTK_SHADOW_OUT, clipRect, + gScrollbarWidget, "slider", thumbRect->x, thumbRect->y, + thumbRect->width, thumbRect->height); } diff --git a/widget/src/gtk/gtkdrawing.h b/widget/src/gtk/gtkdrawing.h index a1702022ddbf..2cc34464ee98 100644 --- a/widget/src/gtk/gtkdrawing.h +++ b/widget/src/gtk/gtkdrawing.h @@ -77,4 +77,13 @@ moz_gtk_scrollbar_button_paint(GdkWindow* window, GtkStyle* style, GdkRectangle* arrowRect, GdkRectangle* clipRect, GtkWidgetState* state, GtkArrowType type); +void +moz_gtk_scrollbar_trough_paint(GdkWindow* window, GtkStyle* style, + GdkRectangle* troughRect, GdkRectangle* clipRect, + GtkWidgetState* state); + +void +moz_gtk_scrollbar_thumb_paint(GdkWindow* window, GtkStyle* style, + GdkRectangle* thumbRect, GdkRectangle* clipRect, + GtkWidgetState* state); #endif diff --git a/widget/src/gtk/nsNativeThemeGTK.cpp b/widget/src/gtk/nsNativeThemeGTK.cpp index 24dc456b145d..c7ccebe0beb4 100644 --- a/widget/src/gtk/nsNativeThemeGTK.cpp +++ b/widget/src/gtk/nsNativeThemeGTK.cpp @@ -71,6 +71,9 @@ nsNativeThemeGTK::nsNativeThemeGTK() } nsNativeThemeGTK::~nsNativeThemeGTK() { + // This will destroy all of our widgets + if (mProtoWindow) + gtk_widget_destroy(mProtoWindow); } static void GetPrimaryPresShell(nsIFrame* aFrame, nsIPresShell** aResult) @@ -273,10 +276,43 @@ nsNativeThemeGTK::DrawWidgetBackground(nsIRenderingContext* aContext, GtkArrowType arrowType = GtkArrowType(aWidgetType - NS_THEME_SCROLLBAR_BUTTON_UP); + printf("paint scrollbar button, rect=(%d,%d,%d,%d), clip=(%d,%d,%d,%d)\n", + gdk_rect.x, gdk_rect.y, gdk_rect.width, gdk_rect.height, + gdk_clip.x, gdk_clip.y, gdk_clip.width, gdk_clip.height); moz_gtk_scrollbar_button_paint(window, gScrollbarWidget->style, &gdk_rect, &gdk_clip, &buttonState, arrowType); } break; + + case NS_THEME_SCROLLBAR_TRACK_VERTICAL: + case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL: + { + EnsureScrollbarWidget(); + + GtkWidgetState troughState; + GetGtkWidgetState(aFrame, &troughState); + + moz_gtk_scrollbar_trough_paint(window, gScrollbarWidget->style, + &gdk_rect, &gdk_clip, &troughState); + } + break; + + case NS_THEME_SCROLLBAR_THUMB_VERTICAL: + case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: + { + EnsureScrollbarWidget(); + + GtkWidgetState thumbState; + GetGtkWidgetState(aFrame, &thumbState); + + printf("paint thumb, rect=(%d,%d,%d,%d), clip=(%d,%d,%d,%d)\n", + gdk_rect.x, gdk_rect.y, gdk_rect.width, gdk_rect.height, + gdk_clip.x, gdk_clip.y, gdk_clip.width, gdk_clip.height); + moz_gtk_scrollbar_thumb_paint(window, gScrollbarWidget->style, + &gdk_rect, &gdk_clip, &thumbState); + } + break; + } return NS_OK; @@ -292,12 +328,54 @@ nsNativeThemeGTK::GetWidgetBorder(nsIDeviceContext* aContext, return NS_OK; } +#define RANGE_CLASS(w) GTK_RANGE_CLASS(GTK_OBJECT(w)->klass) + NS_IMETHODIMP nsNativeThemeGTK::GetMinimumWidgetSize(nsIRenderingContext* aContext, nsIFrame* aFrame, PRUint8 aWidgetType, nsSize* aResult) { aResult->width = aResult->height = 0; + + switch (aWidgetType) { + case NS_THEME_SCROLLBAR_BUTTON_UP: + case NS_THEME_SCROLLBAR_BUTTON_DOWN: + { + EnsureScrollbarWidget(); + + gint slider_width, trough_border, stepper_size; // xxx stepper_spacing? + + slider_width = gtk_style_get_prop_experimental(gScrollbarWidget->style, + "GtkRange::slider_width", + RANGE_CLASS(gScrollbarWidget)->slider_width); + trough_border = gtk_style_get_prop_experimental(gScrollbarWidget->style, + "GtkRange::trough_border", + gScrollbarWidget->style->klass->xthickness); + stepper_size = gtk_style_get_prop_experimental(gScrollbarWidget->style, + "GtkRange::stepper_size", + RANGE_CLASS(gScrollbarWidget)->stepper_size); + aResult->width = slider_width + 2 * trough_border; + aResult->height = stepper_size; + printf("scrollbar button min size: (%d,%d)\n", aResult->width, + aResult->height); + } + break; + case NS_THEME_SCROLLBAR_THUMB_VERTICAL: + { + EnsureScrollbarWidget(); + gint slider_width; + + slider_width = gtk_style_get_prop_experimental(gScrollbarWidget->style, + "GtkRange::slider_width", + RANGE_CLASS(gScrollbarWidget)->slider_width); + aResult->width = slider_width + 2; + aResult->height = RANGE_CLASS(gScrollbarWidget)->min_slider_size; + printf("scrollbar thumb min size: (%d,%d)\n", aResult->width, + aResult->height); + } + break; + } + return NS_OK; } @@ -356,6 +434,11 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsIPresContext* aPresContext, case NS_THEME_SCROLLBAR_BUTTON_DOWN: case NS_THEME_SCROLLBAR_BUTTON_LEFT: case NS_THEME_SCROLLBAR_BUTTON_RIGHT: + case NS_THEME_SCROLLBAR_TRACK_VERTICAL: + case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL: + case NS_THEME_SCROLLBAR_THUMB_VERTICAL: + case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: + case NS_THEME_SCROLLBAR: return PR_TRUE; } diff --git a/widget/src/gtk2/gtkdrawing.h b/widget/src/gtk2/gtkdrawing.h index a1702022ddbf..2cc34464ee98 100644 --- a/widget/src/gtk2/gtkdrawing.h +++ b/widget/src/gtk2/gtkdrawing.h @@ -77,4 +77,13 @@ moz_gtk_scrollbar_button_paint(GdkWindow* window, GtkStyle* style, GdkRectangle* arrowRect, GdkRectangle* clipRect, GtkWidgetState* state, GtkArrowType type); +void +moz_gtk_scrollbar_trough_paint(GdkWindow* window, GtkStyle* style, + GdkRectangle* troughRect, GdkRectangle* clipRect, + GtkWidgetState* state); + +void +moz_gtk_scrollbar_thumb_paint(GdkWindow* window, GtkStyle* style, + GdkRectangle* thumbRect, GdkRectangle* clipRect, + GtkWidgetState* state); #endif diff --git a/widget/src/gtk2/nsNativeThemeGTK.cpp b/widget/src/gtk2/nsNativeThemeGTK.cpp index 24dc456b145d..c7ccebe0beb4 100644 --- a/widget/src/gtk2/nsNativeThemeGTK.cpp +++ b/widget/src/gtk2/nsNativeThemeGTK.cpp @@ -71,6 +71,9 @@ nsNativeThemeGTK::nsNativeThemeGTK() } nsNativeThemeGTK::~nsNativeThemeGTK() { + // This will destroy all of our widgets + if (mProtoWindow) + gtk_widget_destroy(mProtoWindow); } static void GetPrimaryPresShell(nsIFrame* aFrame, nsIPresShell** aResult) @@ -273,10 +276,43 @@ nsNativeThemeGTK::DrawWidgetBackground(nsIRenderingContext* aContext, GtkArrowType arrowType = GtkArrowType(aWidgetType - NS_THEME_SCROLLBAR_BUTTON_UP); + printf("paint scrollbar button, rect=(%d,%d,%d,%d), clip=(%d,%d,%d,%d)\n", + gdk_rect.x, gdk_rect.y, gdk_rect.width, gdk_rect.height, + gdk_clip.x, gdk_clip.y, gdk_clip.width, gdk_clip.height); moz_gtk_scrollbar_button_paint(window, gScrollbarWidget->style, &gdk_rect, &gdk_clip, &buttonState, arrowType); } break; + + case NS_THEME_SCROLLBAR_TRACK_VERTICAL: + case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL: + { + EnsureScrollbarWidget(); + + GtkWidgetState troughState; + GetGtkWidgetState(aFrame, &troughState); + + moz_gtk_scrollbar_trough_paint(window, gScrollbarWidget->style, + &gdk_rect, &gdk_clip, &troughState); + } + break; + + case NS_THEME_SCROLLBAR_THUMB_VERTICAL: + case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: + { + EnsureScrollbarWidget(); + + GtkWidgetState thumbState; + GetGtkWidgetState(aFrame, &thumbState); + + printf("paint thumb, rect=(%d,%d,%d,%d), clip=(%d,%d,%d,%d)\n", + gdk_rect.x, gdk_rect.y, gdk_rect.width, gdk_rect.height, + gdk_clip.x, gdk_clip.y, gdk_clip.width, gdk_clip.height); + moz_gtk_scrollbar_thumb_paint(window, gScrollbarWidget->style, + &gdk_rect, &gdk_clip, &thumbState); + } + break; + } return NS_OK; @@ -292,12 +328,54 @@ nsNativeThemeGTK::GetWidgetBorder(nsIDeviceContext* aContext, return NS_OK; } +#define RANGE_CLASS(w) GTK_RANGE_CLASS(GTK_OBJECT(w)->klass) + NS_IMETHODIMP nsNativeThemeGTK::GetMinimumWidgetSize(nsIRenderingContext* aContext, nsIFrame* aFrame, PRUint8 aWidgetType, nsSize* aResult) { aResult->width = aResult->height = 0; + + switch (aWidgetType) { + case NS_THEME_SCROLLBAR_BUTTON_UP: + case NS_THEME_SCROLLBAR_BUTTON_DOWN: + { + EnsureScrollbarWidget(); + + gint slider_width, trough_border, stepper_size; // xxx stepper_spacing? + + slider_width = gtk_style_get_prop_experimental(gScrollbarWidget->style, + "GtkRange::slider_width", + RANGE_CLASS(gScrollbarWidget)->slider_width); + trough_border = gtk_style_get_prop_experimental(gScrollbarWidget->style, + "GtkRange::trough_border", + gScrollbarWidget->style->klass->xthickness); + stepper_size = gtk_style_get_prop_experimental(gScrollbarWidget->style, + "GtkRange::stepper_size", + RANGE_CLASS(gScrollbarWidget)->stepper_size); + aResult->width = slider_width + 2 * trough_border; + aResult->height = stepper_size; + printf("scrollbar button min size: (%d,%d)\n", aResult->width, + aResult->height); + } + break; + case NS_THEME_SCROLLBAR_THUMB_VERTICAL: + { + EnsureScrollbarWidget(); + gint slider_width; + + slider_width = gtk_style_get_prop_experimental(gScrollbarWidget->style, + "GtkRange::slider_width", + RANGE_CLASS(gScrollbarWidget)->slider_width); + aResult->width = slider_width + 2; + aResult->height = RANGE_CLASS(gScrollbarWidget)->min_slider_size; + printf("scrollbar thumb min size: (%d,%d)\n", aResult->width, + aResult->height); + } + break; + } + return NS_OK; } @@ -356,6 +434,11 @@ nsNativeThemeGTK::ThemeSupportsWidget(nsIPresContext* aPresContext, case NS_THEME_SCROLLBAR_BUTTON_DOWN: case NS_THEME_SCROLLBAR_BUTTON_LEFT: case NS_THEME_SCROLLBAR_BUTTON_RIGHT: + case NS_THEME_SCROLLBAR_TRACK_VERTICAL: + case NS_THEME_SCROLLBAR_TRACK_HORIZONTAL: + case NS_THEME_SCROLLBAR_THUMB_VERTICAL: + case NS_THEME_SCROLLBAR_THUMB_HORIZONTAL: + case NS_THEME_SCROLLBAR: return PR_TRUE; }