diff options
Diffstat (limited to 'Source/WebCore/platform/gtk/ScrollbarThemeGtk2.cpp')
-rw-r--r-- | Source/WebCore/platform/gtk/ScrollbarThemeGtk2.cpp | 184 |
1 files changed, 123 insertions, 61 deletions
diff --git a/Source/WebCore/platform/gtk/ScrollbarThemeGtk2.cpp b/Source/WebCore/platform/gtk/ScrollbarThemeGtk2.cpp index 79295c1..1ab8850 100644 --- a/Source/WebCore/platform/gtk/ScrollbarThemeGtk2.cpp +++ b/Source/WebCore/platform/gtk/ScrollbarThemeGtk2.cpp @@ -28,12 +28,12 @@ #ifdef GTK_API_VERSION_2 +#include "GtkVersioning.h" #include "PlatformMouseEvent.h" #include "RenderThemeGtk.h" #include "ScrollView.h" #include "Scrollbar.h" #include "WidgetRenderingContext.h" -#include "gtkdrawing.h" #include <gtk/gtk.h> namespace WebCore { @@ -46,107 +46,169 @@ static void gtkStyleSetCallback(GtkWidget* widget, GtkStyle* previous, Scrollbar ScrollbarThemeGtk::ScrollbarThemeGtk() { updateThemeProperties(); - g_signal_connect(static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->gtkScrollbar(), + g_signal_connect(static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->gtkHScrollbar(), "style-set", G_CALLBACK(gtkStyleSetCallback), this); } void ScrollbarThemeGtk::updateThemeProperties() { - MozGtkScrollbarMetrics metrics; - moz_gtk_get_scrollbar_metrics(&metrics); - - m_thumbFatness = metrics.slider_width; - m_troughBorderWidth = metrics.trough_border; - m_stepperSize = metrics.stepper_size; - m_stepperSpacing = metrics.stepper_spacing; - m_minThumbLength = metrics.min_slider_size; - m_troughUnderSteppers = metrics.trough_under_steppers; - m_hasForwardButtonStartPart = metrics.has_secondary_forward_stepper; - m_hasBackButtonEndPart = metrics.has_secondary_backward_stepper; - + GtkWidget* scrollbar = static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->gtkHScrollbar(); + gtk_widget_style_get(scrollbar, + "slider_width", &m_thumbFatness, + "trough_border", &m_troughBorderWidth, + "stepper-size", &m_stepperSize, + "trough-under-steppers", &m_troughUnderSteppers, + "has-secondary-forward-stepper", &m_hasForwardButtonStartPart, + "has-secondary-backward-stepper", &m_hasBackButtonEndPart, NULL); + m_minThumbLength = gtk_range_get_min_slider_size(GTK_RANGE(scrollbar)); updateScrollbarsFrameThickness(); } -void ScrollbarThemeGtk::paintTrackBackground(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect) +static GtkWidget* getWidgetForScrollbar(Scrollbar* scrollbar) { - GtkWidgetState state; - state.focused = FALSE; - state.isDefault = FALSE; - state.canDefault = FALSE; - state.disabled = FALSE; - state.active = FALSE; - state.inHover = FALSE; + RenderThemeGtk* theme = static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get()); + return scrollbar->orientation() == VerticalScrollbar ? theme->gtkVScrollbar() : theme->gtkHScrollbar(); +} +void ScrollbarThemeGtk::paintTrackBackground(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect) +{ // Paint the track background. If the trough-under-steppers property is true, this // should be the full size of the scrollbar, but if is false, it should only be the // track rect. - IntRect fullScrollbarRect = rect; + IntRect fullScrollbarRect(rect); if (m_troughUnderSteppers) fullScrollbarRect = IntRect(scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height()); - GtkThemeWidgetType type = scrollbar->orientation() == VerticalScrollbar ? MOZ_GTK_SCROLLBAR_TRACK_VERTICAL : MOZ_GTK_SCROLLBAR_TRACK_HORIZONTAL; WidgetRenderingContext widgetContext(context, fullScrollbarRect); - widgetContext.paintMozillaWidget(type, &state, 0); + IntRect paintRect(IntPoint(), fullScrollbarRect.size()); + widgetContext.gtkPaintBox(paintRect, getWidgetForScrollbar(scrollbar), + GTK_STATE_ACTIVE, GTK_SHADOW_IN, "trough"); } void ScrollbarThemeGtk::paintScrollbarBackground(GraphicsContext* context, Scrollbar* scrollbar) { - // This is unused by the moz_gtk_scrollecd_window_paint. - GtkWidgetState state; IntRect fullScrollbarRect = IntRect(scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height()); + WidgetRenderingContext widgetContext(context, fullScrollbarRect); - widgetContext.paintMozillaWidget(MOZ_GTK_SCROLLED_WINDOW, &state, 0); + widgetContext.gtkPaintBox(fullScrollbarRect, getWidgetForScrollbar(scrollbar), + GTK_STATE_NORMAL, GTK_SHADOW_IN, "scrolled_window"); } void ScrollbarThemeGtk::paintThumb(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect) { - GtkWidgetState state; - state.focused = FALSE; - state.isDefault = FALSE; - state.canDefault = FALSE; - state.disabled = FALSE; - state.active = scrollbar->pressedPart() == ThumbPart; - state.inHover = scrollbar->hoveredPart() == ThumbPart; - state.maxpos = scrollbar->maximum(); - state.curpos = scrollbar->currentPos(); - - GtkThemeWidgetType type = scrollbar->orientation() == VerticalScrollbar ? MOZ_GTK_SCROLLBAR_THUMB_VERTICAL : MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL; + GtkWidget* widget = getWidgetForScrollbar(scrollbar); + gboolean activateSlider; + gtk_widget_style_get(widget, "activate-slider", &activateSlider, NULL); + + GtkStateType stateType = GTK_STATE_NORMAL; + GtkShadowType shadowType = GTK_SHADOW_OUT; + if (activateSlider && scrollbar->pressedPart() == ThumbPart) { + stateType = GTK_STATE_ACTIVE; + shadowType = GTK_SHADOW_IN; + } else if (scrollbar->pressedPart() == ThumbPart || scrollbar->hoveredPart() == ThumbPart) + stateType = GTK_STATE_PRELIGHT; + + // The adjustment controls the rendering of the scrollbar thumb. If it's not set + // properly the theme may not draw the thumb borders properly. + GtkAdjustment* adjustment = gtk_range_get_adjustment(GTK_RANGE(widget)); + gtk_adjustment_set_value(adjustment, scrollbar->currentPos()); + gtk_adjustment_set_lower(adjustment, 0); + gtk_adjustment_set_upper(adjustment, scrollbar->maximum()); + + GtkOrientation orientation = GTK_ORIENTATION_HORIZONTAL; + if (scrollbar->orientation() == VerticalScrollbar) { + gtk_adjustment_set_page_size(adjustment, rect.height()); + orientation = GTK_ORIENTATION_VERTICAL; + } else + gtk_adjustment_set_page_size(adjustment, rect.width()); + WidgetRenderingContext widgetContext(context, rect); - widgetContext.paintMozillaWidget(type, &state, 0); + IntRect sliderRect(IntPoint(), rect.size()); + widgetContext.gtkPaintSlider(sliderRect, widget, stateType, shadowType, "slider", orientation); } void ScrollbarThemeGtk::paintButton(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart part) { - int flags = 0; - if (scrollbar->orientation() == VerticalScrollbar) - flags |= MOZ_GTK_STEPPER_VERTICAL; - - if (part == ForwardButtonEndPart) - flags |= (MOZ_GTK_STEPPER_DOWN | MOZ_GTK_STEPPER_BOTTOM); - if (part == ForwardButtonStartPart) - flags |= MOZ_GTK_STEPPER_DOWN; - - GtkWidgetState state; - state.focused = TRUE; - state.isDefault = TRUE; - state.canDefault = TRUE; - state.depressed = FALSE; + // The buttons will be disabled if the thumb is as the appropriate extreme. + GtkShadowType shadowType = GTK_SHADOW_OUT; + GtkStateType stateType = GTK_STATE_INSENSITIVE; + bool pressed = (part == scrollbar->pressedPart()); if ((BackButtonStartPart == part && scrollbar->currentPos()) || (BackButtonEndPart == part && scrollbar->currentPos()) || (ForwardButtonEndPart == part && scrollbar->currentPos() != scrollbar->maximum()) || (ForwardButtonStartPart == part && scrollbar->currentPos() != scrollbar->maximum())) { - state.disabled = FALSE; - state.active = part == scrollbar->pressedPart(); - state.inHover = part == scrollbar->hoveredPart(); + stateType = GTK_STATE_NORMAL; + if (pressed) { + stateType = GTK_STATE_ACTIVE; + shadowType = GTK_SHADOW_IN; + } else if (part == scrollbar->hoveredPart()) + stateType = GTK_STATE_PRELIGHT; + } + + // Themes determine how to draw the button (which button to draw) based on the allocation + // of the widget. Where the target rect is in relation to the total widget allocation + // determines the button. + ScrollbarOrientation orientation = scrollbar->orientation(); + int buttonSize = (orientation == VerticalScrollbar) ? rect.height() : rect.width(); + int totalAllocation = buttonSize * 5; // One space for each button and one extra. + int buttonOffset = 0; + if (ForwardButtonStartPart == part) + buttonOffset = buttonSize; + else if (BackButtonEndPart == part) + buttonOffset = 3 * buttonSize; + else if (ForwardButtonEndPart == part) + buttonOffset = 4 * buttonSize; + + // Now we want the allocation to be relative to the origin of the painted rect. + GtkWidget* widget = getWidgetForScrollbar(scrollbar); + GtkAllocation allocation; + gtk_widget_get_allocation(widget, &allocation); + allocation.x = allocation.y = 0; + allocation.width = rect.width(); + allocation.height = rect.height(); + + if (orientation == VerticalScrollbar) { + allocation.height = totalAllocation; + allocation.y -= buttonOffset; } else { - state.disabled = TRUE; - state.active = FALSE; - state.inHover = FALSE; + allocation.width = totalAllocation; + allocation.x -= buttonOffset; } + gtk_widget_set_allocation(widget, &allocation); + const char* detail = orientation == VerticalScrollbar ? "vscrollbar" : "hscrollbar"; WidgetRenderingContext widgetContext(context, rect); - widgetContext.paintMozillaWidget(MOZ_GTK_SCROLLBAR_BUTTON, &state, flags); + + IntRect buttonRect(IntPoint(), rect.size()); + widgetContext.gtkPaintBox(buttonRect, widget, stateType, shadowType, detail); + + float arrowScaling; + gtk_widget_style_get(widget, "arrow-scaling", &arrowScaling, NULL); + IntSize arrowSize = rect.size(); + arrowSize.scale(arrowScaling); + IntRect arrowRect(IntPoint(buttonRect.x() + (buttonRect.width() - arrowSize.width()) / 2, + buttonRect.y() + (buttonRect.height() - arrowSize.height()) / 2), + arrowSize); + if (pressed) { + int arrowDisplacementX, arrowDisplacementY; + gtk_widget_style_get(widget, + "arrow-displacement-x", &arrowDisplacementX, + "arrow-displacement-y", &arrowDisplacementY, + NULL); + arrowRect.move(arrowDisplacementX, arrowDisplacementY); + } + + GtkArrowType arrowType = GTK_ARROW_DOWN; + if (orientation == VerticalScrollbar) { + if (part == BackButtonEndPart || part == BackButtonStartPart) + arrowType = GTK_ARROW_UP; + } else if (orientation == HorizontalScrollbar) { + arrowType = GTK_ARROW_RIGHT; + if (part == BackButtonEndPart || part == BackButtonStartPart) + arrowType = GTK_ARROW_LEFT; + } + widgetContext.gtkPaintArrow(arrowRect, widget, stateType, shadowType, arrowType, detail); } } // namespace WebCore |