+2009-12-07 Evan Martin <evan@chromium.org>
+
+ Reviewed by Eric Seidel.
+
+ Chromium: theme scrollbars to match GTK theme.
+ Add functions to RenderThemeChromiumLinux to change the scrollbar
+ color.
+
+ Since the change is to the Chromium WebKit API layer, testing will
+ be in Chromium's test shell.
+ http://bugs.webkit.org/show_bug.cgi?id=32048
+
+ Patch from Markus Gutschke <markus@chromium.org>.
+
+ * platform/chromium/ScrollbarThemeChromiumLinux.cpp:
+ (WebCore::saturateAndBrighten):
+ (WebCore::outlineColor):
+ (WebCore::ScrollbarThemeChromiumLinux::paintTrackPiece):
+ (WebCore::ScrollbarThemeChromiumLinux::paintThumb):
+ * rendering/RenderThemeChromiumLinux.cpp:
+ (WebCore::RenderThemeChromiumLinux::setScrollbarColors):
+ * rendering/RenderThemeChromiumLinux.h:
+ (WebCore::RenderThemeChromiumLinux::thumbInactiveColor):
+ (WebCore::RenderThemeChromiumLinux::thumbActiveColor):
+ (WebCore::RenderThemeChromiumLinux::trackColor):
+
2009-12-08 Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk>
Reviewed by Xan Lopez.
#include "PlatformContextSkia.h"
#include "PlatformMouseEvent.h"
+#include "RenderTheme.h"
+#include "RenderThemeChromiumLinux.h"
#include "Scrollbar.h"
#include "TransformationMatrix.h"
drawVertLine(canvas, rect.x(), rect.y(), bottom, paint);
}
+static SkScalar clamp(SkScalar value, SkScalar min, SkScalar max)
+{
+ return std::min(std::max(value, min), max);
+}
+
+static SkColor saturateAndBrighten(SkScalar* hsv,
+ SkScalar saturateAmount,
+ SkScalar brightenAmount)
+{
+ SkScalar color[3];
+ color[0] = hsv[0];
+ color[1] = clamp(hsv[1] + saturateAmount, 0.0, 1.0);
+ color[2] = clamp(hsv[2] + brightenAmount, 0.0, 1.0);
+ return SkHSVToColor(color);
+}
+
+static SkColor outlineColor(SkScalar* hsv1, SkScalar* hsv2)
+{
+ // GTK Theme engines have way too much control over the layout of
+ // the scrollbar. We might be able to more closely approximate its
+ // look-and-feel, if we sent whole images instead of just colors
+ // from the browser to the renderer. But even then, some themes
+ // would just break.
+ //
+ // So, instead, we don't even try to 100% replicate the look of
+ // the native scrollbar. We render our own version, but we make
+ // sure to pick colors that blend in nicely with the system GTK
+ // theme. In most cases, we can just sample a couple of pixels
+ // from the system scrollbar and use those colors to draw our
+ // scrollbar.
+ //
+ // This works fine for the track color and the overall thumb
+ // color. But it fails spectacularly for the outline color used
+ // around the thumb piece. Not all themes have a clearly defined
+ // outline. For some of them it is partially transparent, and for
+ // others the thickness is very unpredictable.
+ //
+ // So, instead of trying to approximate the system theme, we
+ // instead try to compute a reasonable looking choice based on the
+ // known color of the track and the thumb piece. This is difficult
+ // when trying to deal both with high- and low-contrast themes,
+ // and both with positive and inverted themes.
+ //
+ // The following code has been tested to look OK with all of the
+ // default GTK themes.
+ SkScalar minDiff = clamp((hsv1[1] + hsv2[1]) * 1.2, 0.2, 0.5);
+ SkScalar diff = clamp(fabs(hsv1[2] - hsv2[2]) / 2, minDiff, 0.5);
+
+ if (hsv1[2] + hsv2[2] > 1.0)
+ diff = -diff;
+
+ return saturateAndBrighten(hsv2, -0.2, diff);
+}
+
IntRect ScrollbarThemeChromium::trackRect(Scrollbar* scrollbar, bool)
{
IntSize bs = buttonSize(scrollbar);
SkIRect skrect;
skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.height());
- paint.setARGB(0xff, 0xe3, 0xdd, 0xd8);
+ SkScalar track_hsv[3];
+ SkColorToHSV(RenderThemeChromiumLinux::trackColor(), track_hsv);
+ paint.setColor(saturateAndBrighten(track_hsv, 0, 0));
canvas->drawIRect(skrect, paint);
- paint.setARGB(0xff, 0xc5, 0xba, 0xb0);
+ SkScalar thumb_hsv[3];
+ SkColorToHSV(RenderThemeChromiumLinux::thumbInactiveColor(),
+ thumb_hsv);
+
+ paint.setColor(outlineColor(track_hsv, thumb_hsv));
drawBox(canvas, rect, paint);
}
const bool vertical = scrollbar->orientation() == VerticalScrollbar;
SkCanvas* const canvas = gc->platformContext()->canvas();
+ SkScalar thumb[3];
+ SkColorToHSV(hovered
+ ? RenderThemeChromiumLinux::thumbActiveColor()
+ : RenderThemeChromiumLinux::thumbInactiveColor(),
+ thumb);
+
SkPaint paint;
- if (hovered)
- paint.setARGB(0xff, 0xff, 0xff, 0xff);
- else
- paint.setARGB(0xff, 0xf4, 0xf2, 0xef);
+ paint.setColor(saturateAndBrighten(thumb, 0, 0.02));
SkIRect skrect;
if (vertical)
canvas->drawIRect(skrect, paint);
- if (hovered)
- paint.setARGB(0xff, 0xf4, 0xf2, 0xef);
- else
- paint.setARGB(0xff, 0xea, 0xe5, 0xe0);
+ paint.setColor(saturateAndBrighten(thumb, 0, -0.02));
if (vertical)
skrect.set(midx + 1, rect.y(), rect.x() + rect.width(), rect.y() + rect.height());
canvas->drawIRect(skrect, paint);
- paint.setARGB(0xff, 0x9d, 0x96, 0x8e);
+ SkScalar track[3];
+ SkColorToHSV(RenderThemeChromiumLinux::trackColor(), track);
+ paint.setColor(outlineColor(track, thumb));
drawBox(canvas, rect, paint);
if (rect.height() > 10 && rect.width() > 10) {
- paint.setARGB(0xff, 0x9d, 0x96, 0x8e);
const int grippyHalfWidth = 2;
const int interGrippyOffset = 3;
if (vertical) {