95d0f78b810ccce41149d54df7fc92a82d4a809d
[WebKit-https.git] / WebCore / platform / chromium / ScrollbarThemeChromiumLinux.cpp
1 /*
2  * Copyright (c) 2008, 2009, Google Inc. All rights reserved.
3  * 
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  * 
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  * 
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
29  */
30
31 #include "config.h"
32 #include "ScrollbarThemeChromium.h"
33
34 #include "NotImplemented.h"
35 #include "PlatformContextSkia.h"
36 #include "PlatformMouseEvent.h"
37 #include "Scrollbar.h"
38 #include "TransformationMatrix.h"
39
40 #include "gtkdrawing.h"
41 #include <gtk/gtk.h>
42 #include "skia/ext/GdkSkia.h"
43
44 namespace WebCore {
45
46 int ScrollbarThemeChromium::scrollbarThickness(ScrollbarControlSize controlSize)
47 {
48     static int size = 0;
49     if (!size) {
50         MozGtkScrollbarMetrics metrics;
51         moz_gtk_get_scrollbar_metrics(&metrics);
52         size = metrics.slider_width;
53     }
54     return size;
55 }
56
57 bool ScrollbarThemeChromium::invalidateOnMouseEnterExit()
58 {
59     notImplemented();
60     return false;
61 }
62
63 // Given an uninitialised widget state object, set the members such that it's
64 // sane for drawing scrollbars
65 static void initMozState(GtkWidgetState* mozState)
66 {
67     mozState->active = true;
68     mozState->focused = false;
69     mozState->inHover = false;
70     mozState->disabled = false;
71     mozState->isDefault = false;
72     mozState->canDefault = false;
73     mozState->depressed = false;
74     mozState->curpos = 0;
75     mozState->maxpos = 0;
76 }
77
78 // Paint a GTK widget
79 //   gc: context to draw onto
80 //   rect: the area of the widget
81 //   widget_type: the type of widget to draw
82 //   flags: widget dependent flags (e.g. direction of scrollbar arrows etc)
83 //
84 // See paintMozWiget in RenderThemeGtk.cpp for an explanation of the clipping.
85 static void paintScrollbarWidget(GraphicsContext* gc, const IntRect& rect,
86                                  GtkThemeWidgetType widget_type, gint flags)
87 {
88     PlatformContextSkia* pcs = gc->platformContext();
89
90     GdkRectangle gdkRect = { rect.x(), rect.y(), rect.width(), rect.height() };
91
92     const SkIRect clip_region = pcs->canvas()->getTotalClip().getBounds();
93     TransformationMatrix ctm = gc->getCTM().inverse();
94     IntPoint pos = ctm.mapPoint(
95         IntPoint(SkScalarRound(clip_region.fLeft), SkScalarRound(clip_region.fTop)));
96     GdkRectangle gdkClipRect;
97     gdkClipRect.x = pos.x();
98     gdkClipRect.y = pos.y();
99     gdkClipRect.width = clip_region.width();
100     gdkClipRect.height = clip_region.height();
101
102     gdk_rectangle_intersect(&gdkRect, &gdkClipRect, &gdkClipRect);
103
104     GtkWidgetState mozState;
105     initMozState(&mozState);
106
107     moz_gtk_widget_paint(widget_type, pcs->gdk_skia(), &gdkRect, &gdkClipRect,
108                          &mozState, flags, GTK_TEXT_DIR_LTR);
109 }
110
111 void ScrollbarThemeChromium::paintTrackPiece(GraphicsContext* gc, Scrollbar* scrollbar,
112                                              const IntRect& rect, ScrollbarPart partType)
113 {
114     const bool horz = scrollbar->orientation() == HorizontalScrollbar;
115     const GtkThemeWidgetType track_type =
116         horz ? MOZ_GTK_SCROLLBAR_TRACK_HORIZONTAL : MOZ_GTK_SCROLLBAR_TRACK_VERTICAL;
117     paintScrollbarWidget(gc, rect, track_type, 0);
118 }
119
120 void ScrollbarThemeChromium::paintButton(GraphicsContext* gc, Scrollbar* scrollbar,
121                                     const IntRect& rect, ScrollbarPart part)
122 {
123     // FIXME: It appears the either we're upsetting GTK by forcing WebKit sizes
124     // on it, or the buttons expect the track to be drawn under them.  Either
125     // way, we end up with unpainted pixels which are upsetting the pixel
126     // tests. Thus we paint green under the buttons to, at least, make the
127     // pixel output the same between debug and opt builds.
128     SkPaint paint;
129     paint.setARGB(255, 0, 255, 128);
130     SkRect skrect;
131     skrect.set(rect.x(), rect.y(), rect.x() + rect.width() - 1, rect.y() + rect.height() - 1);
132     gc->platformContext()->canvas()->drawRect(skrect, paint);
133
134     const bool horz = scrollbar->orientation() == HorizontalScrollbar;
135     gint flags = horz ? 0 : MOZ_GTK_STEPPER_VERTICAL;
136     flags |= ForwardButtonEndPart == part ? MOZ_GTK_STEPPER_DOWN : 0;
137     paintScrollbarWidget(gc, rect, MOZ_GTK_SCROLLBAR_BUTTON, flags);
138 }
139
140 void ScrollbarThemeChromium::paintThumb(GraphicsContext* gc, Scrollbar* scrollbar, const IntRect& rect)
141 {
142     const bool horz = scrollbar->orientation() == HorizontalScrollbar;
143     const GtkThemeWidgetType thumb_type =
144         horz ? MOZ_GTK_SCROLLBAR_THUMB_HORIZONTAL : MOZ_GTK_SCROLLBAR_THUMB_VERTICAL;
145     paintScrollbarWidget(gc, rect, thumb_type, 0);
146 }
147
148 } // namespace WebCore