Name all the GLib timeout sources
[WebKit-https.git] / Source / WebCore / platform / gtk / ScrollbarThemeGtk3.cpp
1 /*
2  * Copyright (C) 2008 Apple 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
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27 #include "ScrollbarThemeGtk.h"
28
29 #ifndef GTK_API_VERSION_2
30
31 #include "PlatformContextCairo.h"
32 #include "PlatformMouseEvent.h"
33 #include "RenderThemeGtk.h"
34 #include "ScrollView.h"
35 #include "Scrollbar.h"
36 #include <gtk/gtk.h>
37
38 namespace WebCore {
39
40 static void gtkStyleChangedCallback(GtkWidget*, ScrollbarThemeGtk* scrollbarTheme)
41 {
42     scrollbarTheme->updateThemeProperties();
43 }
44
45 ScrollbarThemeGtk::ScrollbarThemeGtk()
46     : m_context(static_cast<RenderThemeGtk*>(RenderTheme::defaultTheme().get())->gtkScrollbarStyle())
47 {
48     updateThemeProperties();
49     g_signal_connect(m_context, "changed", G_CALLBACK(gtkStyleChangedCallback), this);
50 }
51
52 void ScrollbarThemeGtk::updateThemeProperties()
53 {
54     gtk_style_context_get_style(m_context,
55                                 "min-slider-length", &m_minThumbLength,
56                                 "slider-width", &m_thumbFatness,
57                                 "trough-border", &m_troughBorderWidth,
58                                 "stepper-size", &m_stepperSize,
59                                 "stepper-spacing", &m_stepperSpacing,
60                                 "trough-under-steppers", &m_troughUnderSteppers,
61                                 "has-backward-stepper", &m_hasBackButtonStartPart,
62                                 "has-forward-stepper", &m_hasForwardButtonEndPart,
63                                 "has-secondary-backward-stepper", &m_hasBackButtonEndPart,
64                                 "has-secondary-forward-stepper", &m_hasForwardButtonStartPart,
65                                 NULL);
66     updateScrollbarsFrameThickness();
67 }
68
69 static void applyScrollbarStyleContextClasses(GtkStyleContext* context, ScrollbarOrientation orientation)
70 {
71     gtk_style_context_add_class(context, GTK_STYLE_CLASS_SCROLLBAR);
72     gtk_style_context_add_class(context, orientation == VerticalScrollbar ?  GTK_STYLE_CLASS_VERTICAL : GTK_STYLE_CLASS_HORIZONTAL);
73 }
74
75 void ScrollbarThemeGtk::paintTrackBackground(GraphicsContext* context, ScrollbarThemeClient* scrollbar, const IntRect& rect)
76 {
77     // Paint the track background. If the trough-under-steppers property is true, this
78     // should be the full size of the scrollbar, but if is false, it should only be the
79     // track rect.
80     IntRect fullScrollbarRect(rect);
81     if (m_troughUnderSteppers)
82         fullScrollbarRect = IntRect(scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height());
83
84     gtk_style_context_save(m_context);
85
86     applyScrollbarStyleContextClasses(m_context, scrollbar->orientation());
87     gtk_style_context_add_class(m_context, GTK_STYLE_CLASS_TROUGH);
88
89     gtk_render_background(m_context, context->platformContext()->cr(),
90                           fullScrollbarRect.x(), fullScrollbarRect.y(), fullScrollbarRect.width(), fullScrollbarRect.height());
91     gtk_render_frame(m_context, context->platformContext()->cr(),
92                      fullScrollbarRect.x(), fullScrollbarRect.y(), fullScrollbarRect.width(), fullScrollbarRect.height());
93
94     gtk_style_context_restore(m_context);
95 }
96
97 void ScrollbarThemeGtk::paintScrollbarBackground(GraphicsContext* context, ScrollbarThemeClient* scrollbar)
98 {
99     gtk_style_context_save(m_context);
100
101     applyScrollbarStyleContextClasses(m_context, scrollbar->orientation());
102     gtk_style_context_add_class(m_context, "scrolled-window");
103     gtk_render_frame(m_context, context->platformContext()->cr(), scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height());
104
105     gtk_style_context_restore(m_context);
106 }
107
108 void ScrollbarThemeGtk::paintThumb(GraphicsContext* context, ScrollbarThemeClient* scrollbar, const IntRect& rect)
109 {
110     gtk_style_context_save(m_context);
111
112     ScrollbarOrientation orientation = scrollbar->orientation();
113     applyScrollbarStyleContextClasses(m_context, orientation);
114     gtk_style_context_add_class(m_context, GTK_STYLE_CLASS_SLIDER);
115
116     guint flags = 0;
117     if (scrollbar->pressedPart() == ThumbPart)
118         flags |= GTK_STATE_FLAG_ACTIVE;
119     if (scrollbar->hoveredPart() == ThumbPart)
120         flags |= GTK_STATE_FLAG_PRELIGHT;
121     gtk_style_context_set_state(m_context, static_cast<GtkStateFlags>(flags));
122
123     gtk_render_slider(m_context, context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height(),
124                       orientation == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL);
125
126     gtk_style_context_restore(m_context);
127 }
128
129 void ScrollbarThemeGtk::paintButton(GraphicsContext* context, ScrollbarThemeClient* scrollbar, const IntRect& rect, ScrollbarPart part)
130 {
131     gtk_style_context_save(m_context);
132
133     ScrollbarOrientation orientation = scrollbar->orientation();
134     applyScrollbarStyleContextClasses(m_context, orientation);
135
136     guint flags = 0;
137     if ((BackButtonStartPart == part && scrollbar->currentPos())
138         || (BackButtonEndPart == part && scrollbar->currentPos())
139         || (ForwardButtonEndPart == part && scrollbar->currentPos() != scrollbar->maximum())
140         || (ForwardButtonStartPart == part && scrollbar->currentPos() != scrollbar->maximum())) {
141         if (part == scrollbar->pressedPart())
142             flags |= GTK_STATE_FLAG_ACTIVE;
143         if (part == scrollbar->hoveredPart())
144             flags |= GTK_STATE_FLAG_PRELIGHT;
145     } else
146         flags |= GTK_STATE_FLAG_INSENSITIVE;
147     gtk_style_context_set_state(m_context, static_cast<GtkStateFlags>(flags));
148
149     gtk_style_context_add_class(m_context, GTK_STYLE_CLASS_BUTTON);
150     gtk_render_background(m_context, context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
151     gtk_render_frame(m_context, context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
152
153     gfloat arrowScaling;
154     gtk_style_context_get_style(m_context, "arrow-scaling", &arrowScaling, NULL);
155
156     double arrowSize = std::min(rect.width(), rect.height()) * arrowScaling;
157     FloatPoint arrowPoint(rect.x() + (rect.width() - arrowSize) / 2,
158                           rect.y() + (rect.height() - arrowSize) / 2);
159
160     if (flags & GTK_STATE_FLAG_ACTIVE) {
161         gint arrowDisplacementX, arrowDisplacementY;
162         gtk_style_context_get_style(m_context,
163                                     "arrow-displacement-x", &arrowDisplacementX,
164                                     "arrow-displacement-y", &arrowDisplacementY,
165                                     NULL);
166         arrowPoint.move(arrowDisplacementX, arrowDisplacementY);
167     }
168
169     gdouble angle;
170     if (orientation == VerticalScrollbar) {
171         angle = (part == ForwardButtonEndPart || part == ForwardButtonStartPart) ? G_PI : 0;
172     } else {
173         angle = (part == ForwardButtonEndPart || part == ForwardButtonStartPart) ? G_PI / 2 : 3 * (G_PI / 2);
174     }
175
176     gtk_render_arrow(m_context, context->platformContext()->cr(), angle, arrowPoint.x(), arrowPoint.y(), arrowSize);
177
178     gtk_style_context_restore(m_context);
179 }
180
181 } // namespace WebCore
182
183 #endif // !GTK_API_VERSION_2