2009-12-07 Evan Martin <evan@chromium.org>
authoreric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 8 Dec 2009 02:54:52 +0000 (02:54 +0000)
committereric@webkit.org <eric@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 8 Dec 2009 02:54:52 +0000 (02:54 +0000)
        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-07  Evan Martin  <evan@chromium.org>

        Reviewed by Eric Seidel.

        Chromium: theme scrollbars to match GTK theme.
        Add API to set the colors.

        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>.

        * public/WebView.h:
        * src/WebViewImpl.cpp:
        (WebKit::WebViewImpl::setScrollbarColors):
        * src/WebViewImpl.h:

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@51827 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/platform/chromium/ScrollbarThemeChromiumLinux.cpp
WebCore/rendering/RenderThemeChromiumLinux.cpp
WebCore/rendering/RenderThemeChromiumLinux.h
WebKit/chromium/ChangeLog
WebKit/chromium/public/WebView.h
WebKit/chromium/src/WebViewImpl.cpp
WebKit/chromium/src/WebViewImpl.h

index bc87b4e2253ec294f89548cf4f1d142ae170d9f8..9660980667ffe8098f302f3e6c9bdf19827babd4 100644 (file)
@@ -1,3 +1,29 @@
+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.
index 64f58c4e6e284b2e95db03ea0f7c1a4966c21cf2..3a1a6521eb9521806ae441a89fe3daf2824cd6af 100644 (file)
@@ -33,6 +33,8 @@
 
 #include "PlatformContextSkia.h"
 #include "PlatformMouseEvent.h"
+#include "RenderTheme.h"
+#include "RenderThemeChromiumLinux.h"
 #include "Scrollbar.h"
 #include "TransformationMatrix.h"
 
@@ -73,6 +75,60 @@ static void drawBox(SkCanvas* canvas, const IntRect& rect, const SkPaint& paint)
     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);
@@ -89,10 +145,16 @@ void ScrollbarThemeChromiumLinux::paintTrackPiece(GraphicsContext* gc, 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);
 }
 
@@ -109,11 +171,14 @@ void ScrollbarThemeChromiumLinux::paintThumb(GraphicsContext* gc, Scrollbar* scr
     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)
@@ -123,10 +188,7 @@ void ScrollbarThemeChromiumLinux::paintThumb(GraphicsContext* gc, Scrollbar* scr
 
     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());
@@ -135,11 +197,12 @@ void ScrollbarThemeChromiumLinux::paintThumb(GraphicsContext* gc, Scrollbar* scr
 
     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) {
index 9048ce38e2bcc185f23a7c3934938234e81c379a..2cdea7ae07613e5952ce724fc800e40719cad68e 100644 (file)
 
 namespace WebCore {
 
+unsigned RenderThemeChromiumLinux::m_thumbInactiveColor = 0;
+unsigned RenderThemeChromiumLinux::m_thumbActiveColor = 0;
+unsigned RenderThemeChromiumLinux::m_trackColor = 0;
+
 PassRefPtr<RenderTheme> RenderThemeChromiumLinux::create()
 {
     return adoptRef(new RenderThemeChromiumLinux());
@@ -122,4 +126,12 @@ double RenderThemeChromiumLinux::caretBlinkIntervalInternal() const
     return m_caretBlinkInterval;
 }
 
+void RenderThemeChromiumLinux::setScrollbarColors(
+    SkColor inactiveColor, SkColor activeColor, SkColor trackColor)
+{
+    m_thumbInactiveColor = inactiveColor;
+    m_thumbActiveColor = activeColor;
+    m_trackColor = trackColor;
+}
+
 } // namespace WebCore
index e137ad598efe07f57920613813a6c2a6793769a9..8736b0d08bdcafc632f8856058887ec49a17caad 100644 (file)
@@ -54,6 +54,13 @@ namespace WebCore {
         void setCaretBlinkInterval(double interval);
         virtual double caretBlinkIntervalInternal() const;
 
+        static void setScrollbarColors(unsigned inactive_color,
+                                       unsigned active_color,
+                                       unsigned track_color);
+        static unsigned thumbInactiveColor() { return m_thumbInactiveColor; }
+        static unsigned thumbActiveColor() { return m_thumbActiveColor; }
+        static unsigned trackColor() { return m_trackColor; }
+
     private:
         RenderThemeChromiumLinux();
         virtual ~RenderThemeChromiumLinux();
@@ -62,6 +69,10 @@ namespace WebCore {
         virtual bool supportsControlTints() const;
 
         double m_caretBlinkInterval;
+
+        static unsigned m_thumbInactiveColor;
+        static unsigned m_thumbActiveColor;
+        static unsigned m_trackColor;
     };
 
 } // namespace WebCore
index 58b78eeca89a3afd9fc96108158cf560c5e075f6..e03947d4ba68e7ec9e101f2960ffca1a3b75cff0 100644 (file)
@@ -1,3 +1,21 @@
+2009-12-07  Evan Martin  <evan@chromium.org>
+
+        Reviewed by Eric Seidel.
+
+        Chromium: theme scrollbars to match GTK theme.
+        Add API to set the colors.
+
+        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>.
+
+        * public/WebView.h:
+        * src/WebViewImpl.cpp:
+        (WebKit::WebViewImpl::setScrollbarColors):
+        * src/WebViewImpl.h:
+
 2009-12-07  Finnur Thorarinsson  <finnur.webkit@gmail.com>
 
         Reviewed by Darin Fisher.
index 6f6ffff2b6ad3c423341f9d60a92fb104f5f0121..d239ef1962aff219ddbc23361f990e1f76aff40a 100644 (file)
@@ -245,6 +245,10 @@ public:
     // their links.
     WEBKIT_API static void resetVisitedLinkState();
 
+    // Scrollbar colors ----------------------------------------------------
+    virtual void setScrollbarColors(unsigned inactiveColor,
+                                    unsigned activeColor,
+                                    unsigned trackColor) = 0;
 
 protected:
     ~WebView() {}
index 1f89ffe6ebcce15a1e14625afda80da946492d0d..dc87101fe8f9415f9fb4b62524bd07133addbc17 100644 (file)
@@ -97,6 +97,9 @@
 #include "KeyboardCodesWin.h"
 #include "RenderThemeChromiumWin.h"
 #else
+#if PLATFORM(LINUX)
+#include "RenderThemeChromiumLinux.h"
+#endif
 #include "KeyboardCodesPosix.h"
 #include "RenderTheme.h"
 #endif
@@ -1621,6 +1624,16 @@ bool WebViewImpl::isActive() const
     return (page() && page()->focusController()) ? page()->focusController()->isActive() : false;
 }
 
+void WebViewImpl::setScrollbarColors(unsigned inactiveColor,
+                                     unsigned activeColor,
+                                     unsigned trackColor) {
+#if PLATFORM(LINUX)
+    RenderThemeChromiumLinux::setScrollbarColors(inactiveColor,
+                                                 activeColor,
+                                                 trackColor);
+#endif
+}
+
 void WebViewImpl::didCommitLoad(bool* isNewNavigation)
 {
     if (isNewNavigation)
index fe209c7b1dcc6857ef3702e78d0d14cbacc557d7..3bec50d15979d3273d34d5e519de6c8cc11d84ca 100644 (file)
@@ -154,6 +154,9 @@ public:
         const WebVector<WebString>& suggestions,
         int defaultSuggestionIndex);
     virtual void hideAutofillPopup();
+    virtual void setScrollbarColors(unsigned inactiveColor,
+                                    unsigned activeColor,
+                                    unsigned trackColor);
 
     // WebViewImpl