OLD | NEW |
1 /* | 1 /* |
2 * Copyright (c) 2008, 2009, Google Inc. All rights reserved. | 2 * Copyright (c) 2008, 2009, Google Inc. All rights reserved. |
3 * | 3 * |
4 * Redistribution and use in source and binary forms, with or without | 4 * Redistribution and use in source and binary forms, with or without |
5 * modification, are permitted provided that the following conditions are | 5 * modification, are permitted provided that the following conditions are |
6 * met: | 6 * met: |
7 * | 7 * |
8 * * Redistributions of source code must retain the above copyright | 8 * * Redistributions of source code must retain the above copyright |
9 * notice, this list of conditions and the following disclaimer. | 9 * notice, this list of conditions and the following disclaimer. |
10 * * Redistributions in binary form must reproduce the above | 10 * * Redistributions in binary form must reproduce the above |
(...skipping 15 matching lines...) Expand all Loading... |
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
29 */ | 29 */ |
30 | 30 |
31 #include "config.h" | 31 #include "config.h" |
32 #include "ScrollbarThemeChromiumLinux.h" | 32 #include "ScrollbarThemeChromiumLinux.h" |
33 | 33 |
34 #include "PlatformContextSkia.h" | 34 #include "PlatformContextSkia.h" |
35 #include "PlatformMouseEvent.h" | 35 #include "PlatformMouseEvent.h" |
| 36 #include "RenderTheme.h" |
| 37 #include "RenderThemeChromiumLinux.h" |
36 #include "Scrollbar.h" | 38 #include "Scrollbar.h" |
37 #include "TransformationMatrix.h" | 39 #include "TransformationMatrix.h" |
38 | 40 |
39 namespace WebCore { | 41 namespace WebCore { |
40 | 42 |
41 ScrollbarTheme* ScrollbarTheme::nativeTheme() | 43 ScrollbarTheme* ScrollbarTheme::nativeTheme() |
42 { | 44 { |
43 static ScrollbarThemeChromiumLinux theme; | 45 static ScrollbarThemeChromiumLinux theme; |
44 return &theme; | 46 return &theme; |
45 } | 47 } |
(...skipping 20 matching lines...) Expand all Loading... |
66 static void drawBox(SkCanvas* canvas, const IntRect& rect, const SkPaint& paint) | 68 static void drawBox(SkCanvas* canvas, const IntRect& rect, const SkPaint& paint) |
67 { | 69 { |
68 const int right = rect.x() + rect.width() - 1; | 70 const int right = rect.x() + rect.width() - 1; |
69 const int bottom = rect.y() + rect.height() - 1; | 71 const int bottom = rect.y() + rect.height() - 1; |
70 drawHorizLine(canvas, rect.x(), right, rect.y(), paint); | 72 drawHorizLine(canvas, rect.x(), right, rect.y(), paint); |
71 drawVertLine(canvas, right, rect.y(), bottom, paint); | 73 drawVertLine(canvas, right, rect.y(), bottom, paint); |
72 drawHorizLine(canvas, rect.x(), right, bottom, paint); | 74 drawHorizLine(canvas, rect.x(), right, bottom, paint); |
73 drawVertLine(canvas, rect.x(), rect.y(), bottom, paint); | 75 drawVertLine(canvas, rect.x(), rect.y(), bottom, paint); |
74 } | 76 } |
75 | 77 |
| 78 static SkColor saturateAndBrighten(SkScalar* hsv, |
| 79 SkScalar saturateAmount, |
| 80 SkScalar brightenAmount) |
| 81 { |
| 82 SkScalar color[3]; |
| 83 color[0] = hsv[0]; |
| 84 |
| 85 color[1] = hsv[1] + saturateAmount; |
| 86 if (color[1] > 1.0) |
| 87 color[1] = 1.0; |
| 88 else if (color[1] < 0.0) |
| 89 color[1] = 0.0; |
| 90 |
| 91 color[2] = hsv[2] + brightenAmount; |
| 92 if (color[2] > 1.0) |
| 93 color[2] = 1.0; |
| 94 else if (color[2] < 0.0) |
| 95 color[2] = 0.0; |
| 96 |
| 97 return SkHSVToColor(color); |
| 98 } |
| 99 |
| 100 static SkColor outlineColor(SkScalar* hsv1, SkScalar* hsv2) { |
| 101 // GTK Theme engines have way too much control over the layout of the |
| 102 // scrollbar. We might be able to more closely approximate its look-and-feel, |
| 103 // if we sent whole images instead of just colors from the browser to the |
| 104 // renderer. But even then, some themes would just break. |
| 105 // |
| 106 // So, instead, we don't even try to 100% replicate the look of the native |
| 107 // scrollbar. We render our own version, but we make sure to pick colors that |
| 108 // blend in nicely with the system GTK theme. In most cases, we can just |
| 109 // sample a couple of pixels from the system scrollbar and use those colors |
| 110 // to draw our scrollbar. |
| 111 // |
| 112 // This works fine for the track color and the overall thumb color. But it |
| 113 // fails spectacularly for the outline color used around the thumb piece. |
| 114 // Not all themes have a clearly defined outline. For some of them it is |
| 115 // partially transparent, and for others the thickness is very unpredictable. |
| 116 // |
| 117 // So, instead of trying to approximate the system theme, we instead try to |
| 118 // compute a reasonable looking choice based on the known color of the track |
| 119 // and the thumb piece. This is difficult when trying to deal both with high- |
| 120 // and low-contrast themes, and both with positive and inverted themes. |
| 121 // |
| 122 // The following code has been tested to look OK with all of the default GTK |
| 123 // themes. |
| 124 SkScalar min_diff = (hsv1[1] + hsv2[1])*1.2; |
| 125 if (min_diff < 0.2) |
| 126 min_diff = 0.2; |
| 127 else if (min_diff > 0.5) |
| 128 min_diff = 0.5; |
| 129 |
| 130 SkScalar diff = fabs(hsv1[2] - hsv2[2])/2; |
| 131 if (diff < min_diff) |
| 132 diff = min_diff; |
| 133 else if (diff > 0.5) |
| 134 diff = 0.5; |
| 135 |
| 136 if (hsv1[2] + hsv2[2] > 1.0) |
| 137 diff = -diff; |
| 138 |
| 139 return saturateAndBrighten(hsv2, -0.2, diff); |
| 140 } |
| 141 |
76 IntRect ScrollbarThemeChromium::trackRect(Scrollbar* scrollbar, bool) | 142 IntRect ScrollbarThemeChromium::trackRect(Scrollbar* scrollbar, bool) |
77 { | 143 { |
78 IntSize bs = buttonSize(scrollbar); | 144 IntSize bs = buttonSize(scrollbar); |
79 int thickness = scrollbarThickness(scrollbar->controlSize()); | 145 int thickness = scrollbarThickness(scrollbar->controlSize()); |
80 if (scrollbar->orientation() == HorizontalScrollbar) | 146 if (scrollbar->orientation() == HorizontalScrollbar) |
81 return IntRect(scrollbar->x() + bs.width(), scrollbar->y(), scrollbar->w
idth(), thickness); | 147 return IntRect(scrollbar->x() + bs.width(), scrollbar->y(), scrollbar->w
idth(), thickness); |
82 return IntRect(scrollbar->x(), scrollbar->y() + bs.height(), thickness, scro
llbar->height()); | 148 return IntRect(scrollbar->x(), scrollbar->y() + bs.height(), thickness, scro
llbar->height()); |
83 } | 149 } |
84 | 150 |
85 void ScrollbarThemeChromiumLinux::paintTrackPiece(GraphicsContext* gc, Scrollbar
* scrollbar, const IntRect& rect, ScrollbarPart partType) | 151 void ScrollbarThemeChromiumLinux::paintTrackPiece(GraphicsContext* gc, Scrollbar
* scrollbar, const IntRect& rect, ScrollbarPart partType) |
86 { | 152 { |
87 SkCanvas* const canvas = gc->platformContext()->canvas(); | 153 SkCanvas* const canvas = gc->platformContext()->canvas(); |
88 SkPaint paint; | 154 SkPaint paint; |
89 SkIRect skrect; | 155 SkIRect skrect; |
90 | 156 |
91 skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.heig
ht()); | 157 skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), rect.y() + rect.heig
ht()); |
92 paint.setARGB(0xff, 0xe3, 0xdd, 0xd8); | 158 SkScalar track_hsv[3]; |
| 159 SkColorToHSV(RenderThemeChromiumLinux::trackColor(), track_hsv); |
| 160 paint.setColor(saturateAndBrighten(track_hsv, 0, 0)); |
93 canvas->drawIRect(skrect, paint); | 161 canvas->drawIRect(skrect, paint); |
94 | 162 |
95 paint.setARGB(0xff, 0xc5, 0xba, 0xb0); | 163 SkScalar thumb_hsv[3]; |
| 164 SkColorToHSV(RenderThemeChromiumLinux::thumbInactiveColor(), |
| 165 thumb_hsv); |
| 166 |
| 167 paint.setColor(outlineColor(track_hsv, thumb_hsv)); |
96 drawBox(canvas, rect, paint); | 168 drawBox(canvas, rect, paint); |
97 } | 169 } |
98 | 170 |
99 void ScrollbarThemeChromiumLinux::paintButton(GraphicsContext* gc, Scrollbar* sc
rollbar, const IntRect& rect, ScrollbarPart part) | 171 void ScrollbarThemeChromiumLinux::paintButton(GraphicsContext* gc, Scrollbar* sc
rollbar, const IntRect& rect, ScrollbarPart part) |
100 { | 172 { |
101 // We don't use buttons | 173 // We don't use buttons |
102 } | 174 } |
103 | 175 |
104 void ScrollbarThemeChromiumLinux::paintThumb(GraphicsContext* gc, Scrollbar* scr
ollbar, const IntRect& rect) | 176 void ScrollbarThemeChromiumLinux::paintThumb(GraphicsContext* gc, Scrollbar* scr
ollbar, const IntRect& rect) |
105 { | 177 { |
106 const bool hovered = scrollbar->hoveredPart() == ThumbPart; | 178 const bool hovered = scrollbar->hoveredPart() == ThumbPart; |
107 const int midx = rect.x() + rect.width() / 2; | 179 const int midx = rect.x() + rect.width() / 2; |
108 const int midy = rect.y() + rect.height() / 2; | 180 const int midy = rect.y() + rect.height() / 2; |
109 const bool vertical = scrollbar->orientation() == VerticalScrollbar; | 181 const bool vertical = scrollbar->orientation() == VerticalScrollbar; |
110 SkCanvas* const canvas = gc->platformContext()->canvas(); | 182 SkCanvas* const canvas = gc->platformContext()->canvas(); |
111 | 183 |
| 184 SkScalar thumb[3]; |
| 185 SkColorToHSV(hovered |
| 186 ? RenderThemeChromiumLinux::thumbActiveColor() |
| 187 : RenderThemeChromiumLinux::thumbInactiveColor(), |
| 188 thumb); |
| 189 |
112 SkPaint paint; | 190 SkPaint paint; |
113 if (hovered) | 191 paint.setColor(saturateAndBrighten(thumb, 0, 0.02)); |
114 paint.setARGB(0xff, 0xff, 0xff, 0xff); | |
115 else | |
116 paint.setARGB(0xff, 0xf4, 0xf2, 0xef); | |
117 | 192 |
118 SkIRect skrect; | 193 SkIRect skrect; |
119 if (vertical) | 194 if (vertical) |
120 skrect.set(rect.x(), rect.y(), midx + 1, rect.y() + rect.height()); | 195 skrect.set(rect.x(), rect.y(), midx + 1, rect.y() + rect.height()); |
121 else | 196 else |
122 skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), midy + 1); | 197 skrect.set(rect.x(), rect.y(), rect.x() + rect.width(), midy + 1); |
123 | 198 |
124 canvas->drawIRect(skrect, paint); | 199 canvas->drawIRect(skrect, paint); |
125 | 200 |
126 if (hovered) | 201 paint.setColor(saturateAndBrighten(thumb, 0, -0.02)); |
127 paint.setARGB(0xff, 0xf4, 0xf2, 0xef); | |
128 else | |
129 paint.setARGB(0xff, 0xea, 0xe5, 0xe0); | |
130 | 202 |
131 if (vertical) | 203 if (vertical) |
132 skrect.set(midx + 1, rect.y(), rect.x() + rect.width(), rect.y() + rect.
height()); | 204 skrect.set(midx + 1, rect.y(), rect.x() + rect.width(), rect.y() + rect.
height()); |
133 else | 205 else |
134 skrect.set(rect.x(), midy + 1, rect.x() + rect.width(), rect.y() + rect.
height()); | 206 skrect.set(rect.x(), midy + 1, rect.x() + rect.width(), rect.y() + rect.
height()); |
135 | 207 |
136 canvas->drawIRect(skrect, paint); | 208 canvas->drawIRect(skrect, paint); |
137 | 209 |
138 paint.setARGB(0xff, 0x9d, 0x96, 0x8e); | 210 SkScalar track[3]; |
| 211 SkColorToHSV(RenderThemeChromiumLinux::trackColor(), track); |
| 212 paint.setColor(outlineColor(track, thumb)); |
139 drawBox(canvas, rect, paint); | 213 drawBox(canvas, rect, paint); |
140 | 214 |
141 if (rect.height() > 10 && rect.width() > 10) { | 215 if (rect.height() > 10 && rect.width() > 10) { |
142 paint.setARGB(0xff, 0x9d, 0x96, 0x8e); | |
143 const int grippyHalfWidth = 2; | 216 const int grippyHalfWidth = 2; |
144 const int interGrippyOffset = 3; | 217 const int interGrippyOffset = 3; |
145 if (vertical) { | 218 if (vertical) { |
146 drawHorizLine(canvas, midx - grippyHalfWidth, midx + grippyHalfWidth
, midy - interGrippyOffset, paint); | 219 drawHorizLine(canvas, midx - grippyHalfWidth, midx + grippyHalfWidth
, midy - interGrippyOffset, paint); |
147 drawHorizLine(canvas, midx - grippyHalfWidth, midx + grippyHalfWidth
, midy, paint); | 220 drawHorizLine(canvas, midx - grippyHalfWidth, midx + grippyHalfWidth
, midy, paint); |
148 drawHorizLine(canvas, midx - grippyHalfWidth, midx + grippyHalfWidth
, midy + interGrippyOffset, paint); | 221 drawHorizLine(canvas, midx - grippyHalfWidth, midx + grippyHalfWidth
, midy + interGrippyOffset, paint); |
149 } else { | 222 } else { |
150 drawVertLine(canvas, midx - interGrippyOffset, midy - grippyHalfWidt
h, midy + grippyHalfWidth, paint); | 223 drawVertLine(canvas, midx - interGrippyOffset, midy - grippyHalfWidt
h, midy + grippyHalfWidth, paint); |
151 drawVertLine(canvas, midx, midy - grippyHalfWidt
h, midy + grippyHalfWidth, paint); | 224 drawVertLine(canvas, midx, midy - grippyHalfWidt
h, midy + grippyHalfWidth, paint); |
152 drawVertLine(canvas, midx + interGrippyOffset, midy - grippyHalfWidt
h, midy + grippyHalfWidth, paint); | 225 drawVertLine(canvas, midx + interGrippyOffset, midy - grippyHalfWidt
h, midy + grippyHalfWidth, paint); |
(...skipping 12 matching lines...) Expand all Loading... |
165 return IntSize(0, 0); | 238 return IntSize(0, 0); |
166 } | 239 } |
167 | 240 |
168 int ScrollbarThemeChromiumLinux::minimumThumbLength(Scrollbar* scrollbar) | 241 int ScrollbarThemeChromiumLinux::minimumThumbLength(Scrollbar* scrollbar) |
169 { | 242 { |
170 // This matches Firefox on Linux. | 243 // This matches Firefox on Linux. |
171 return 2 * scrollbarThickness(scrollbar->controlSize()); | 244 return 2 * scrollbarThickness(scrollbar->controlSize()); |
172 } | 245 } |
173 | 246 |
174 } // namespace WebCore | 247 } // namespace WebCore |
OLD | NEW |