• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
gtkStyleChangedCallback(GtkWidget *,ScrollbarThemeGtk * scrollbarTheme)40 static void gtkStyleChangedCallback(GtkWidget*, ScrollbarThemeGtk* scrollbarTheme)
41 {
42     scrollbarTheme->updateThemeProperties();
43 }
44 
ScrollbarThemeGtk()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 
updateThemeProperties()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-secondary-backward-stepper", &m_hasBackButtonEndPart,
62                                 "has-secondary-forward-stepper", &m_hasForwardButtonStartPart,
63                                 NULL);
64     updateScrollbarsFrameThickness();
65 }
66 
paintTrackBackground(GraphicsContext * context,Scrollbar * scrollbar,const IntRect & rect)67 void ScrollbarThemeGtk::paintTrackBackground(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect)
68 {
69     // Paint the track background. If the trough-under-steppers property is true, this
70     // should be the full size of the scrollbar, but if is false, it should only be the
71     // track rect.
72     IntRect fullScrollbarRect(rect);
73     if (m_troughUnderSteppers)
74         fullScrollbarRect = IntRect(scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height());
75 
76     gtk_style_context_save(m_context);
77 
78     gtk_style_context_add_class(m_context, GTK_STYLE_CLASS_SCROLLBAR);
79     gtk_style_context_add_class(m_context, GTK_STYLE_CLASS_TROUGH);
80 
81     gtk_render_background(m_context, context->platformContext()->cr(),
82                           fullScrollbarRect.x(), fullScrollbarRect.y(), fullScrollbarRect.width(), fullScrollbarRect.height());
83     gtk_render_frame(m_context, context->platformContext()->cr(),
84                      fullScrollbarRect.x(), fullScrollbarRect.y(), fullScrollbarRect.width(), fullScrollbarRect.height());
85 
86     gtk_style_context_restore(m_context);
87 }
88 
paintScrollbarBackground(GraphicsContext * context,Scrollbar * scrollbar)89 void ScrollbarThemeGtk::paintScrollbarBackground(GraphicsContext* context, Scrollbar* scrollbar)
90 {
91     gtk_style_context_save(m_context);
92 
93     gtk_style_context_add_class(m_context, GTK_STYLE_CLASS_SCROLLBAR);
94     gtk_style_context_add_class(m_context, "scrolled-window");
95     gtk_render_frame(m_context, context->platformContext()->cr(), scrollbar->x(), scrollbar->y(), scrollbar->width(), scrollbar->height());
96 
97     gtk_style_context_restore(m_context);
98 }
99 
paintThumb(GraphicsContext * context,Scrollbar * scrollbar,const IntRect & rect)100 void ScrollbarThemeGtk::paintThumb(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect)
101 {
102     gtk_style_context_save(m_context);
103 
104     gtk_style_context_add_class(m_context, GTK_STYLE_CLASS_SCROLLBAR);
105     gtk_style_context_add_class(m_context, GTK_STYLE_CLASS_SLIDER);
106 
107     guint flags = 0;
108     if (scrollbar->pressedPart() == ThumbPart)
109         flags |= GTK_STATE_FLAG_ACTIVE;
110     if (scrollbar->hoveredPart() == ThumbPart)
111         flags |= GTK_STATE_FLAG_PRELIGHT;
112     gtk_style_context_set_state(m_context, static_cast<GtkStateFlags>(flags));
113 
114     gtk_render_slider(m_context, context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height(),
115                       scrollbar->orientation() == VerticalScrollbar ? GTK_ORIENTATION_VERTICAL : GTK_ORIENTATION_HORIZONTAL);
116 
117     gtk_style_context_restore(m_context);
118 }
119 
paintButton(GraphicsContext * context,Scrollbar * scrollbar,const IntRect & rect,ScrollbarPart part)120 void ScrollbarThemeGtk::paintButton(GraphicsContext* context, Scrollbar* scrollbar, const IntRect& rect, ScrollbarPart part)
121 {
122     gtk_style_context_save(m_context);
123 
124     gtk_style_context_add_class(m_context, GTK_STYLE_CLASS_SCROLLBAR);
125 
126     guint flags = 0;
127     if ((BackButtonStartPart == part && scrollbar->currentPos())
128         || (BackButtonEndPart == part && scrollbar->currentPos())
129         || (ForwardButtonEndPart == part && scrollbar->currentPos() != scrollbar->maximum())
130         || (ForwardButtonStartPart == part && scrollbar->currentPos() != scrollbar->maximum())) {
131         if (part == scrollbar->pressedPart())
132             flags |= GTK_STATE_FLAG_ACTIVE;
133         if (part == scrollbar->hoveredPart())
134             flags |= GTK_STATE_FLAG_PRELIGHT;
135     } else
136         flags |= GTK_STATE_FLAG_INSENSITIVE;
137     gtk_style_context_set_state(m_context, static_cast<GtkStateFlags>(flags));
138 
139     gtk_style_context_add_class(m_context, GTK_STYLE_CLASS_BUTTON);
140     gtk_render_background(m_context, context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
141     gtk_render_frame(m_context, context->platformContext()->cr(), rect.x(), rect.y(), rect.width(), rect.height());
142 
143     gfloat arrowScaling;
144     gtk_style_context_get_style(m_context, "arrow-scaling", &arrowScaling, NULL);
145 
146     double arrowSize = std::min(rect.width(), rect.height()) * arrowScaling;
147     FloatPoint arrowPoint(rect.x() + (rect.width() - arrowSize) / 2,
148                           rect.y() + (rect.height() - arrowSize) / 2);
149 
150     if (flags & GTK_STATE_FLAG_ACTIVE) {
151         gint arrowDisplacementX, arrowDisplacementY;
152         gtk_style_context_get_style(m_context,
153                                     "arrow-displacement-x", &arrowDisplacementX,
154                                     "arrow-displacement-y", &arrowDisplacementY,
155                                     NULL);
156         arrowPoint.move(arrowDisplacementX, arrowDisplacementY);
157     }
158 
159     gdouble angle;
160     if (scrollbar->orientation() == VerticalScrollbar) {
161         angle = (part == ForwardButtonEndPart || part == ForwardButtonStartPart) ? G_PI : 0;
162     } else {
163         angle = (part == ForwardButtonEndPart || part == ForwardButtonStartPart) ? G_PI / 2 : 3 * (G_PI / 2);
164     }
165 
166     gtk_render_arrow(m_context, context->platformContext()->cr(), angle, arrowPoint.x(), arrowPoint.y(), arrowSize);
167 
168     gtk_style_context_restore(m_context);
169 }
170 
171 } // namespace WebCore
172 
173 #endif // !GTK_API_VERSION_2
174