Home | History | Annotate | Download | only in gtk
      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-secondary-backward-stepper", &m_hasBackButtonEndPart,
     62                                 "has-secondary-forward-stepper", &m_hasForwardButtonStartPart,
     63                                 NULL);
     64     updateScrollbarsFrameThickness();
     65 }
     66 
     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 
     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 
    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 
    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