Home | History | Annotate | Download | only in wx
      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 "ScrollbarThemeWx.h"
     28 
     29 #include "HostWindow.h"
     30 #include "NotImplemented.h"
     31 #include "PlatformMouseEvent.h"
     32 #include "Scrollbar.h"
     33 #include "ScrollbarClient.h"
     34 #include "scrollbar_render.h"
     35 #include "ScrollbarThemeComposite.h"
     36 #include "ScrollView.h"
     37 
     38 #include <wx/defs.h>
     39 #include <wx/dcgraph.h>
     40 #include <wx/settings.h>
     41 
     42 const int cMacButtonOverlap = 4;
     43 
     44 namespace WebCore {
     45 
     46 ScrollbarTheme* ScrollbarTheme::nativeTheme()
     47 {
     48     static ScrollbarThemeWx theme;
     49     return &theme;
     50 }
     51 
     52 ScrollbarThemeWx::~ScrollbarThemeWx()
     53 {
     54 }
     55 
     56 int ScrollbarThemeWx::scrollbarThickness(ScrollbarControlSize size)
     57 {
     58     int thickness = wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
     59 
     60     // fallback for when a platform doesn't define this metric
     61     if (thickness <= 0)
     62         thickness = 20;
     63 
     64     return thickness;
     65 }
     66 
     67 bool ScrollbarThemeWx::hasThumb(Scrollbar* scrollbar)
     68 {
     69     // This method is just called as a paint-time optimization to see if
     70     // painting the thumb can be skipped.  We don't have to be exact here.
     71     return thumbLength(scrollbar) > 0;
     72 }
     73 
     74 int ScrollbarThemeWx::minimumThumbLength(Scrollbar* scrollbar)
     75 {
     76     return 20;
     77 }
     78 
     79 IntSize ScrollbarThemeWx::buttonSize(Scrollbar*)
     80 {
     81 #ifdef __WXMAC__
     82     return IntSize(20,20);
     83 #else
     84     return IntSize(16,16);
     85 #endif
     86 }
     87 
     88 void ScrollbarThemeWx::splitTrack(Scrollbar* scrollbar, const IntRect& unconstrainedTrackRect, IntRect& beforeThumbRect, IntRect& thumbRect, IntRect& afterThumbRect)
     89 {
     90     ScrollbarThemeComposite::splitTrack(scrollbar, unconstrainedTrackRect, beforeThumbRect, thumbRect, afterThumbRect);
     91 #ifdef __WXMAC__
     92     // on Mac, there are a few pixels drawn above the actual track and so adjust
     93     // the hit testing rects accordingly
     94     int trackStart = 10;
     95     if (scrollbar->orientation() == HorizontalScrollbar) {
     96         thumbRect.setX(thumbRect.x() + trackStart);
     97         afterThumbRect.setX(afterThumbRect.x() - trackStart);
     98     } else {
     99         thumbRect.setY(thumbRect.y() + trackStart);
    100         afterThumbRect.setY(afterThumbRect.y() - trackStart);
    101     }
    102 #endif
    103 }
    104 
    105 IntRect ScrollbarThemeWx::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
    106 {
    107     // FIXME: Handling this case is needed when there are two sets of arrow buttons
    108     // on Mac, one at the top and one at the bottom.
    109     if (part == BackButtonEndPart)
    110         return IntRect();
    111 
    112     IntSize size = buttonSize(scrollbar);
    113     int x = scrollbar->x();
    114     int y = scrollbar->y();
    115 
    116 #if __WXMAC__
    117     if (scrollbar->orientation() == HorizontalScrollbar)
    118         x += scrollbar->width() - (size.width() * 2) + cMacButtonOverlap;
    119     else
    120         y += scrollbar->height() - (size.height() * 2) + cMacButtonOverlap;
    121 #endif
    122 
    123     return IntRect(x, y, size.width(), size.height());
    124 }
    125 
    126 IntRect ScrollbarThemeWx::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
    127 {
    128     // FIXME: Handling this case is needed when there are two sets of arrow buttons
    129     // on Mac, one at the top and one at the bottom.
    130     if (part == ForwardButtonStartPart)
    131         return IntRect();
    132 
    133     IntSize size = buttonSize(scrollbar);
    134     int x, y;
    135     if (scrollbar->orientation() == HorizontalScrollbar) {
    136 #ifdef __WXMAC__
    137         size.setWidth(size.width() + cMacButtonOverlap);
    138 #endif
    139         x = scrollbar->x() + scrollbar->width() - size.width();
    140         y = scrollbar->y();
    141     } else {
    142         x = scrollbar->x();
    143 #ifdef __WXMAC__
    144         size.setHeight(size.height() + cMacButtonOverlap);
    145 #endif
    146         y = scrollbar->y() + scrollbar->height() - size.height();
    147     }
    148     return IntRect(x, y, size.width(), size.height());
    149 }
    150 
    151 IntRect ScrollbarThemeWx::trackRect(Scrollbar* scrollbar, bool)
    152 {
    153     IntSize bs = buttonSize(scrollbar);
    154     int trackStart = 0;
    155     if (scrollbar->orientation() == HorizontalScrollbar)
    156         trackStart = bs.width();
    157     else
    158         trackStart = bs.height();
    159 
    160 #if __WXMAC__
    161     trackStart = 0;
    162 #endif
    163 
    164     int thickness = scrollbarThickness(scrollbar->controlSize());
    165     if (scrollbar->orientation() == HorizontalScrollbar) {
    166         if (scrollbar->width() < 2 * thickness)
    167             return IntRect();
    168         return IntRect(scrollbar->x() + trackStart, scrollbar->y(), scrollbar->width() - 2 * bs.width(), thickness);
    169     }
    170     if (scrollbar->height() < 2 * thickness)
    171         return IntRect();
    172     return IntRect(scrollbar->x(), scrollbar->y() + trackStart, thickness, scrollbar->height() - 2 * bs.height());
    173 }
    174 
    175 void ScrollbarThemeWx::paintScrollCorner(ScrollView* view, GraphicsContext* context, const IntRect& cornerRect)
    176 {
    177     // ScrollbarThemeComposite::paintScrollCorner incorrectly assumes that the
    178     // ScrollView is a FrameView (see FramelessScrollView), so we cannot let
    179     // that code run.  For FrameView's this is correct since we don't do custom
    180     // scrollbar corner rendering, which ScrollbarThemeComposite supports.
    181     ScrollbarTheme::paintScrollCorner(view, context, cornerRect);
    182 }
    183 
    184 bool ScrollbarThemeWx::paint(Scrollbar* scrollbar, GraphicsContext* context, const IntRect& rect)
    185 {
    186     wxOrientation orientation = (scrollbar->orientation() == HorizontalScrollbar) ? wxHORIZONTAL : wxVERTICAL;
    187     int flags = 0;
    188     if (scrollbar->client()->isActive())
    189         flags |= wxCONTROL_FOCUSED;
    190 
    191     if (!scrollbar->enabled())
    192         flags |= wxCONTROL_DISABLED;
    193 
    194     wxDC* dc = static_cast<wxDC*>(context->platformContext());
    195 
    196     context->save();
    197     ScrollView* root = scrollbar->root();
    198     ASSERT(root);
    199     if (!root)
    200         return false;
    201 
    202     wxWindow* webview = root->hostWindow()->platformPageClient();
    203 
    204     wxRenderer_DrawScrollbar(webview, *dc, scrollbar->frameRect(), orientation, scrollbar->currentPos(), static_cast<wxScrollbarPart>(scrollbar->pressedPart()),
    205                      static_cast<wxScrollbarPart>(scrollbar->hoveredPart()), scrollbar->maximum(), scrollbar->pageStep(), flags);
    206 
    207     context->restore();
    208     return true;
    209 }
    210 
    211 }
    212 
    213