Home | History | Annotate | Download | only in win
      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 "ScrollbarThemeSafari.h"
     28 
     29 #if USE(SAFARI_THEME)
     30 
     31 #include "GraphicsContext.h"
     32 #include "IntRect.h"
     33 #include "Page.h"
     34 #include "PlatformMouseEvent.h"
     35 #include "Scrollbar.h"
     36 #include "ScrollbarClient.h"
     37 #include "ScrollbarThemeWin.h"
     38 #include "Settings.h"
     39 #include "SoftLinking.h"
     40 
     41 #include <CoreGraphics/CoreGraphics.h>
     42 
     43 // If you have an empty placeholder SafariThemeConstants.h, then include SafariTheme.h
     44 // This is a workaround until a version of WebKitSupportLibrary is released with an updated SafariThemeConstants.h
     45 #include <SafariTheme/SafariThemeConstants.h>
     46 #ifndef SafariThemeConstants_h
     47 #include <SafariTheme/SafariTheme.h>
     48 #endif
     49 
     50 // FIXME: There are repainting problems due to Aqua scroll bar buttons' visual overflow.
     51 
     52 using namespace std;
     53 
     54 namespace WebCore {
     55 
     56 using namespace SafariTheme;
     57 
     58 ScrollbarTheme* ScrollbarTheme::nativeTheme()
     59 {
     60     static ScrollbarThemeSafari safariTheme;
     61     static ScrollbarThemeWin windowsTheme;
     62     if (Settings::shouldPaintNativeControls())
     63         return &windowsTheme;
     64     return &safariTheme;
     65 }
     66 
     67 // FIXME: Get these numbers from CoreUI.
     68 static int cScrollbarThickness[] = { 15, 11 };
     69 static int cRealButtonLength[] = { 28, 21 };
     70 static int cButtonInset[] = { 14, 11 };
     71 static int cButtonHitInset[] = { 3, 2 };
     72 // cRealButtonLength - cButtonInset
     73 static int cButtonLength[] = { 14, 10 };
     74 static int cThumbMinLength[] = { 26, 20 };
     75 
     76 #ifdef DEBUG_ALL
     77 SOFT_LINK_DEBUG_LIBRARY(SafariTheme)
     78 #else
     79 SOFT_LINK_LIBRARY(SafariTheme)
     80 #endif
     81 
     82 SOFT_LINK(SafariTheme, paintThemePart, void, __stdcall,
     83             (ThemePart part, CGContextRef context, const CGRect& rect, NSControlSize size, ThemeControlState state),
     84             (part, context, rect, size, state))
     85 
     86 static ScrollbarControlState scrollbarControlStateFromThemeState(ThemeControlState state)
     87 {
     88     ScrollbarControlState s = 0;
     89     if (state & ActiveState)
     90         s |= ActiveScrollbarState;
     91     if (state & EnabledState)
     92         s |= EnabledScrollbarState;
     93     if (state & PressedState)
     94         s |= PressedScrollbarState;
     95     return s;
     96 }
     97 
     98 ScrollbarThemeSafari::~ScrollbarThemeSafari()
     99 {
    100 }
    101 
    102 int ScrollbarThemeSafari::scrollbarThickness(ScrollbarControlSize controlSize)
    103 {
    104     return cScrollbarThickness[controlSize];
    105 }
    106 
    107 bool ScrollbarThemeSafari::hasButtons(Scrollbar* scrollbar)
    108 {
    109     return scrollbar->enabled() && (scrollbar->orientation() == HorizontalScrollbar ?
    110              scrollbar->width() :
    111              scrollbar->height()) >= 2 * (cRealButtonLength[scrollbar->controlSize()] - cButtonHitInset[scrollbar->controlSize()]);
    112 }
    113 
    114 bool ScrollbarThemeSafari::hasThumb(Scrollbar* scrollbar)
    115 {
    116     return scrollbar->enabled() && (scrollbar->orientation() == HorizontalScrollbar ?
    117              scrollbar->width() :
    118              scrollbar->height()) >= 2 * cButtonInset[scrollbar->controlSize()] + cThumbMinLength[scrollbar->controlSize()] + 1;
    119 }
    120 
    121 static IntRect buttonRepaintRect(const IntRect& buttonRect, ScrollbarOrientation orientation, ScrollbarControlSize controlSize, bool start)
    122 {
    123     IntRect paintRect(buttonRect);
    124     if (orientation == HorizontalScrollbar) {
    125         paintRect.setWidth(cRealButtonLength[controlSize]);
    126         if (!start)
    127             paintRect.setX(buttonRect.x() - (cRealButtonLength[controlSize] - buttonRect.width()));
    128     } else {
    129         paintRect.setHeight(cRealButtonLength[controlSize]);
    130         if (!start)
    131             paintRect.setY(buttonRect.y() - (cRealButtonLength[controlSize] - buttonRect.height()));
    132     }
    133 
    134     return paintRect;
    135 }
    136 
    137 IntRect ScrollbarThemeSafari::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool painting)
    138 {
    139     IntRect result;
    140 
    141     // Windows just has single arrows.
    142     if (part == BackButtonEndPart)
    143         return result;
    144 
    145     int thickness = scrollbarThickness(scrollbar->controlSize());
    146     if (scrollbar->orientation() == HorizontalScrollbar)
    147         result = IntRect(scrollbar->x(), scrollbar->y(), cButtonLength[scrollbar->controlSize()], thickness);
    148     else
    149         result = IntRect(scrollbar->x(), scrollbar->y(), thickness, cButtonLength[scrollbar->controlSize()]);
    150     if (painting)
    151         return buttonRepaintRect(result, scrollbar->orientation(), scrollbar->controlSize(), true);
    152     return result;
    153 }
    154 
    155 IntRect ScrollbarThemeSafari::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool painting)
    156 {
    157     IntRect result;
    158 
    159     // Windows just has single arrows.
    160     if (part == ForwardButtonStartPart)
    161         return result;
    162 
    163     int thickness = scrollbarThickness(scrollbar->controlSize());
    164     if (scrollbar->orientation() == HorizontalScrollbar)
    165         result = IntRect(scrollbar->x() + scrollbar->width() - cButtonLength[scrollbar->controlSize()], scrollbar->y(), cButtonLength[scrollbar->controlSize()], thickness);
    166     else
    167         result = IntRect(scrollbar->x(), scrollbar->y() + scrollbar->height() - cButtonLength[scrollbar->controlSize()], thickness, cButtonLength[scrollbar->controlSize()]);
    168     if (painting)
    169         return buttonRepaintRect(result, scrollbar->orientation(), scrollbar->controlSize(), false);
    170     return result;
    171 }
    172 
    173 static IntRect trackRepaintRect(const IntRect& trackRect, ScrollbarOrientation orientation, ScrollbarControlSize controlSize)
    174 {
    175     IntRect paintRect(trackRect);
    176     if (orientation == HorizontalScrollbar)
    177         paintRect.inflateX(cButtonLength[controlSize]);
    178     else
    179         paintRect.inflateY(cButtonLength[controlSize]);
    180 
    181     return paintRect;
    182 }
    183 
    184 IntRect ScrollbarThemeSafari::trackRect(Scrollbar* scrollbar, bool painting)
    185 {
    186     if (painting || !hasButtons(scrollbar))
    187         return scrollbar->frameRect();
    188 
    189     IntRect result;
    190     int thickness = scrollbarThickness(scrollbar->controlSize());
    191     if (scrollbar->orientation() == HorizontalScrollbar)
    192         return IntRect(scrollbar->x() + cButtonLength[scrollbar->controlSize()], scrollbar->y(), scrollbar->width() - 2 * cButtonLength[scrollbar->controlSize()], thickness);
    193     return IntRect(scrollbar->x(), scrollbar->y() + cButtonLength[scrollbar->controlSize()], thickness, scrollbar->height() - 2 * cButtonLength[scrollbar->controlSize()]);
    194 }
    195 
    196 int ScrollbarThemeSafari::minimumThumbLength(Scrollbar* scrollbar)
    197 {
    198     return cThumbMinLength[scrollbar->controlSize()];
    199 }
    200 
    201 bool ScrollbarThemeSafari::shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent& evt)
    202 {
    203     return evt.shiftKey() && evt.button() == LeftButton;
    204 }
    205 
    206 void ScrollbarThemeSafari::paintTrackBackground(GraphicsContext* graphicsContext, Scrollbar* scrollbar, const IntRect& trackRect)
    207 {
    208     if (!SafariThemeLibrary())
    209         return;
    210     NSControlSize size = scrollbar->controlSize() == SmallScrollbar ? NSSmallControlSize : NSRegularControlSize;
    211     ThemeControlState state = 0;
    212     if (scrollbar->client()->isActive())
    213         state |= ActiveState;
    214     if (hasButtons(scrollbar))
    215         state |= EnabledState;
    216     paintThemePart(scrollbar->orientation() == VerticalScrollbar ? VScrollTrackPart : HScrollTrackPart, graphicsContext->platformContext(), trackRect, size, state);
    217 }
    218 
    219 void ScrollbarThemeSafari::paintButton(GraphicsContext* graphicsContext, Scrollbar* scrollbar, const IntRect& buttonRect, ScrollbarPart part)
    220 {
    221     if (!SafariThemeLibrary())
    222         return;
    223     NSControlSize size = scrollbar->controlSize() == SmallScrollbar ? NSSmallControlSize : NSRegularControlSize;
    224     ThemeControlState state = 0;
    225     if (scrollbar->client()->isActive())
    226         state |= ActiveState;
    227     if (hasButtons(scrollbar))
    228         state |= EnabledState;
    229     if (scrollbar->pressedPart() == part)
    230         state |= PressedState;
    231     if (part == BackButtonStartPart)
    232         paintThemePart(scrollbar->orientation() == VerticalScrollbar ? ScrollUpArrowPart : ScrollLeftArrowPart, graphicsContext->platformContext(),
    233                        buttonRect, size, state);
    234     else if (part == ForwardButtonEndPart)
    235         paintThemePart(scrollbar->orientation() == VerticalScrollbar ? ScrollDownArrowPart : ScrollRightArrowPart, graphicsContext->platformContext(),
    236                        buttonRect, size, state);
    237 }
    238 
    239 void ScrollbarThemeSafari::paintThumb(GraphicsContext* graphicsContext, Scrollbar* scrollbar, const IntRect& thumbRect)
    240 {
    241     if (!SafariThemeLibrary())
    242         return;
    243     NSControlSize size = scrollbar->controlSize() == SmallScrollbar ? NSSmallControlSize : NSRegularControlSize;
    244     ThemeControlState state = 0;
    245     if (scrollbar->client()->isActive())
    246         state |= ActiveState;
    247     if (hasThumb(scrollbar))
    248         state |= EnabledState;
    249     if (scrollbar->pressedPart() == ThumbPart)
    250         state |= PressedState;
    251     paintThemePart(scrollbar->orientation() == VerticalScrollbar ? VScrollThumbPart : HScrollThumbPart, graphicsContext->platformContext(),
    252                    thumbRect, size, state);
    253 }
    254 
    255 }
    256 
    257 #endif
    258