summaryrefslogtreecommitdiffstats
path: root/Source/WebCore/platform/gtk/ScrollbarThemeGtk2.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'Source/WebCore/platform/gtk/ScrollbarThemeGtk2.cpp')
-rw-r--r--Source/WebCore/platform/gtk/ScrollbarThemeGtk2.cpp184
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