text: /*
   * Copyright (C) 2008 Apple Inc. All Rights Reserved.
   *
   * Redistribution and use in source and binary forms, with or without
   * modification, are permitted provided that the following conditions
   * are met:
   * 1. Redistributions of source code must retain the above copyright
   *    notice, this list of conditions and the following disclaimer.
   * 2. Redistributions in binary form must reproduce the above copyright
   *    notice, this list of conditions and the following disclaimer in the
   *    documentation and/or other materials provided with the distribution.
   *
   * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
   * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
   * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
   * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
   * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
   * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
   * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
   * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
   */
  
  #include "config.h"
  #include "ScrollbarThemeWx.h"
  
  #include "HostWindow.h"
  #include "NotImplemented.h"
  #include "PlatformMouseEvent.h"
  #include "Scrollbar.h"
  #include "ScrollbarClient.h"
  #include "scrollbar_render.h"
  #include "ScrollbarThemeComposite.h"
  #include "ScrollView.h"
  
  #include <wx/defs.h>
  #include <wx/dcgraph.h>
  #include <wx/settings.h>
  
  const int cMacButtonOverlap = 4;
  
  namespace WebCore {
  
  ScrollbarTheme* ScrollbarTheme::nativeTheme()
  {
      static ScrollbarThemeWx theme;
      return &theme;
  }
  
  ScrollbarThemeWx::~ScrollbarThemeWx()
  {
  }
  
  int ScrollbarThemeWx::scrollbarThickness(ScrollbarControlSize size)
  {
      int thickness = wxSystemSettings::GetMetric(wxSYS_VSCROLL_X);
      
      // fallback for when a platform doesn't define this metric
      if (thickness <= 0)
          thickness = 20;
      
      return thickness;
  }
  
  bool ScrollbarThemeWx::hasThumb(Scrollbar* scrollbar)
  {
      // This method is just called as a paint-time optimization to see if
      // painting the thumb can be skipped.  We don't have to be exact here.
      return thumbLength(scrollbar) > 0;
  }
  
  int ScrollbarThemeWx::minimumThumbLength(Scrollbar* scrollbar)
  {
      return 20;
  }
  
  IntSize ScrollbarThemeWx::buttonSize(Scrollbar*) 
  {
  #ifdef __WXMAC__
      return IntSize(20,20);
  #else
      return IntSize(16,16);
  #endif
  }
  
  void ScrollbarThemeWx::splitTrack(Scrollbar* scrollbar, const IntRect& unconstrainedTrackRect, IntRect& beforeThumbRect, IntRect& thumbRect, IntRect& afterThumbRect)
  {
      ScrollbarThemeComposite::splitTrack(scrollbar, unconstrainedTrackRect, beforeThumbRect, thumbRect, afterThumbRect);
  #ifdef __WXMAC__
      // on Mac, there are a few pixels drawn above the actual track and so adjust
      // the hit testing rects accordingly
      int trackStart = 10; 
      if (scrollbar->orientation() == HorizontalScrollbar) {
          thumbRect.setX(thumbRect.x() + trackStart);
          afterThumbRect.setX(afterThumbRect.x() - trackStart);
      } else {
          thumbRect.setY(thumbRect.y() + trackStart);
          afterThumbRect.setY(afterThumbRect.y() - trackStart);
      }
  #endif
  }
  
  IntRect ScrollbarThemeWx::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
  {
      // FIXME: Handling this case is needed when there are two sets of arrow buttons
      // on Mac, one at the top and one at the bottom.
      if (part == BackButtonEndPart)
          return IntRect();
  
      IntSize size = buttonSize(scrollbar);
      int x = scrollbar->x();
      int y = scrollbar->y();
      
  #if __WXMAC__
      if (scrollbar->orientation() == HorizontalScrollbar)
          x += scrollbar->width() - (size.width() * 2) + cMacButtonOverlap;
      else
          y += scrollbar->height() - (size.height() * 2) + cMacButtonOverlap;
  #endif
      
      return IntRect(x, y, size.width(), size.height());
  }
  
  IntRect ScrollbarThemeWx::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool)
  {
      // FIXME: Handling this case is needed when there are two sets of arrow buttons
      // on Mac, one at the top and one at the bottom.
      if (part == ForwardButtonStartPart)
          return IntRect();
  
      IntSize size = buttonSize(scrollbar);
      int x, y;
      if (scrollbar->orientation() == HorizontalScrollbar) {
  #ifdef __WXMAC__
          size.setWidth(size.width() + cMacButtonOverlap);
  #endif
          x = scrollbar->x() + scrollbar->width() - size.width();
          y = scrollbar->y();
      } else {
          x = scrollbar->x();
  #ifdef __WXMAC__
          size.setHeight(size.height() + cMacButtonOverlap);
  #endif
          y = scrollbar->y() + scrollbar->height() - size.height();
      }
      return IntRect(x, y, size.width(), size.height());
  }
  
  IntRect ScrollbarThemeWx::trackRect(Scrollbar* scrollbar, bool)
  {
      IntSize bs = buttonSize(scrollbar);
      int trackStart = 0;
      if (scrollbar->orientation() == HorizontalScrollbar)
          trackStart = bs.width();
      else
          trackStart = bs.height();
          
  #if __WXMAC__
      trackStart = 0;
  #endif
      
      int thickness = scrollbarThickness(scrollbar->controlSize());
      if (scrollbar->orientation() == HorizontalScrollbar) {
          if (scrollbar->width() < 2 * thickness)
              return IntRect();
          return IntRect(scrollbar->x() + trackStart, scrollbar->y(), scrollbar->width() - 2 * bs.width(), thickness);
      }
      if (scrollbar->height() < 2 * thickness)
          return IntRect();
      return IntRect(scrollbar->x(), scrollbar->y() + trackStart, thickness, scrollbar->height() - 2 * bs.height());
  }
  
  void ScrollbarThemeWx::paintScrollCorner(ScrollView* view, GraphicsContext* context, const IntRect& cornerRect)
  {
      // ScrollbarThemeComposite::paintScrollCorner incorrectly assumes that the
      // ScrollView is a FrameView (see FramelessScrollView), so we cannot let
      // that code run.  For FrameView's this is correct since we don't do custom
      // scrollbar corner rendering, which ScrollbarThemeComposite supports.
      ScrollbarTheme::paintScrollCorner(view, context, cornerRect);
  }
  
  bool ScrollbarThemeWx::paint(Scrollbar* scrollbar, GraphicsContext* context, const IntRect& rect)
  {
      wxOrientation orientation = (scrollbar->orientation() == HorizontalScrollbar) ? wxHORIZONTAL : wxVERTICAL;
      int flags = 0;
      if (scrollbar->client()->isActive())
          flags |= wxCONTROL_FOCUSED;
      
      if (!scrollbar->enabled())
          flags |= wxCONTROL_DISABLED;
      
      wxDC* dc = static_cast<wxDC*>(context->platformContext());
      
      context->save();
      ScrollView* root = scrollbar->root();
      ASSERT(root);
      if (!root)
          return false;
      
      wxWindow* webview = root->hostWindow()->platformPageClient(); 
      
      wxRenderer_DrawScrollbar(webview, *dc, scrollbar->frameRect(), orientation, scrollbar->currentPos(), static_cast<wxScrollbarPart>(scrollbar->pressedPart()),    
                       static_cast<wxScrollbarPart>(scrollbar->hoveredPart()), scrollbar->maximum(), scrollbar->pageStep(), flags);
  
      context->restore();
      return true;
  }
  
  }
  
  