1643ca7872b450ea4efacab6188849e5aac2ba161Steve Block/* 2643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * Copyright (C) 2008 Apple Inc. All Rights Reserved. 3643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * Copyright (C) 2009 Google Inc. All Rights Reserved. 4643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * 5643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * Redistribution and use in source and binary forms, with or without 6643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * modification, are permitted provided that the following conditions 7643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * are met: 8643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * 1. Redistributions of source code must retain the above copyright 9643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * notice, this list of conditions and the following disclaimer. 10643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * 2. Redistributions in binary form must reproduce the above copyright 11643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * notice, this list of conditions and the following disclaimer in the 12643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * documentation and/or other materials provided with the distribution. 13643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * 14643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 15643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 18643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 24643ca7872b450ea4efacab6188849e5aac2ba161Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25643ca7872b450ea4efacab6188849e5aac2ba161Steve Block */ 26643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 27643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "config.h" 28643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "ScrollbarThemeChromiumMac.h" 29643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 30cad810f21b803229eb11403f9209855525a25d57Steve Block#include "FrameView.h" 31643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "ImageBuffer.h" 32ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch#include "PlatformBridge.h" 33643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "PlatformMouseEvent.h" 34643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include "ScrollView.h" 35643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include <Carbon/Carbon.h> 36643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include <wtf/StdLibExtras.h> 37643ca7872b450ea4efacab6188849e5aac2ba161Steve Block#include <wtf/UnusedParam.h> 38643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 39cad810f21b803229eb11403f9209855525a25d57Steve Block 40643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// FIXME: There are repainting problems due to Aqua scroll bar buttons' visual overflow. 41643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 42643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockusing namespace std; 43643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockusing namespace WebCore; 44643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 45643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// This file (and its associated .h file) is a clone of ScrollbarThemeMac.mm. 46643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// Because we want to draw tickmarks in the scrollbar, we must maintain a fork. 47643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// Please maintain this file by performing parallel changes to it. 48643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// 49643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// The only changes from ScrollbarThemeMac should be: 50643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// - The classname change from ScrollbarThemeMac to ScrollbarThemeChromiumMac. 51643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// - In paint() the code to paint the track, tickmarks, and thumb separately. 52cad810f21b803229eb11403f9209855525a25d57Steve Block// - In paint() the thumb is drawn via ChromeBridge/WebThemeEngine. 53643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// 54643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// For all other differences, if it was introduced in this file, then the 55643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// maintainer forgot to include it in the list; otherwise it is an update that 56643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// should have been applied to this file but was not. 57643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 58643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic HashSet<Scrollbar*>* gScrollbars; 59643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 60643ca7872b450ea4efacab6188849e5aac2ba161Steve Block@interface ScrollbarPrefsObserver : NSObject 61643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 62643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 63643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 64643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 65643ca7872b450ea4efacab6188849e5aac2ba161Steve Block+ (void)registerAsObserver; 66643ca7872b450ea4efacab6188849e5aac2ba161Steve Block+ (void)appearancePrefsChanged:(NSNotification*)theNotification; 67643ca7872b450ea4efacab6188849e5aac2ba161Steve Block+ (void)behaviorPrefsChanged:(NSNotification*)theNotification; 68643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 69643ca7872b450ea4efacab6188849e5aac2ba161Steve Block@end 70643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 71643ca7872b450ea4efacab6188849e5aac2ba161Steve Block@implementation ScrollbarPrefsObserver 72643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 73643ca7872b450ea4efacab6188849e5aac2ba161Steve Block+ (void)appearancePrefsChanged:(NSNotification*)unusedNotification 74643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 75643ca7872b450ea4efacab6188849e5aac2ba161Steve Block UNUSED_PARAM(unusedNotification); 76643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 77643ca7872b450ea4efacab6188849e5aac2ba161Steve Block static_cast<ScrollbarThemeChromiumMac*>(ScrollbarTheme::nativeTheme())->preferencesChanged(); 78643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!gScrollbars) 79643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return; 80643ca7872b450ea4efacab6188849e5aac2ba161Steve Block HashSet<Scrollbar*>::iterator end = gScrollbars->end(); 81643ca7872b450ea4efacab6188849e5aac2ba161Steve Block for (HashSet<Scrollbar*>::iterator it = gScrollbars->begin(); it != end; ++it) { 82643ca7872b450ea4efacab6188849e5aac2ba161Steve Block (*it)->styleChanged(); 83643ca7872b450ea4efacab6188849e5aac2ba161Steve Block (*it)->invalidate(); 84643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 85643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 86643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 87643ca7872b450ea4efacab6188849e5aac2ba161Steve Block+ (void)behaviorPrefsChanged:(NSNotification*)unusedNotification 88643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 89643ca7872b450ea4efacab6188849e5aac2ba161Steve Block UNUSED_PARAM(unusedNotification); 90643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 91643ca7872b450ea4efacab6188849e5aac2ba161Steve Block static_cast<ScrollbarThemeChromiumMac*>(ScrollbarTheme::nativeTheme())->preferencesChanged(); 92643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 93643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 94643ca7872b450ea4efacab6188849e5aac2ba161Steve Block+ (void)registerAsObserver 95643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 96643ca7872b450ea4efacab6188849e5aac2ba161Steve Block [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(appearancePrefsChanged:) name:@"AppleAquaScrollBarVariantChanged" object:nil suspensionBehavior:NSNotificationSuspensionBehaviorDeliverImmediately]; 97643ca7872b450ea4efacab6188849e5aac2ba161Steve Block [[NSDistributedNotificationCenter defaultCenter] addObserver:self selector:@selector(behaviorPrefsChanged:) name:@"AppleNoRedisplayAppearancePreferenceChanged" object:nil suspensionBehavior:NSNotificationSuspensionBehaviorCoalesce]; 98643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 99643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 100643ca7872b450ea4efacab6188849e5aac2ba161Steve Block@end 101643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 102643ca7872b450ea4efacab6188849e5aac2ba161Steve Blocknamespace WebCore { 103643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 104643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockScrollbarTheme* ScrollbarTheme::nativeTheme() 105643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 106643ca7872b450ea4efacab6188849e5aac2ba161Steve Block DEFINE_STATIC_LOCAL(ScrollbarThemeChromiumMac, theme, ()); 107643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return &theme; 108643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 109643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 110643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// FIXME: Get these numbers from CoreUI. 111643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic int cScrollbarThickness[] = { 15, 11 }; 112643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic int cRealButtonLength[] = { 28, 21 }; 113643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic int cButtonInset[] = { 14, 11 }; 114643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic int cButtonHitInset[] = { 3, 2 }; 115643ca7872b450ea4efacab6188849e5aac2ba161Steve Block// cRealButtonLength - cButtonInset 116643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic int cButtonLength[] = { 14, 10 }; 117643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic int cThumbMinLength[] = { 26, 20 }; 118643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 119643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic int cOuterButtonLength[] = { 16, 14 }; // The outer button in a double button pair is a bit bigger. 120643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic int cOuterButtonOverlap = 2; 121643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 122643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic float gInitialButtonDelay = 0.5f; 123643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic float gAutoscrollButtonDelay = 0.05f; 124643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic bool gJumpOnTrackClick = false; 125643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic ScrollbarButtonsPlacement gButtonPlacement = ScrollbarButtonsDoubleEnd; 126643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 127643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic void updateArrowPlacement() 128643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 129643ca7872b450ea4efacab6188849e5aac2ba161Steve Block NSString *buttonPlacement = [[NSUserDefaults standardUserDefaults] objectForKey:@"AppleScrollBarVariant"]; 130643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if ([buttonPlacement isEqualToString:@"Single"]) 131643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gButtonPlacement = ScrollbarButtonsSingle; 132643ca7872b450ea4efacab6188849e5aac2ba161Steve Block else if ([buttonPlacement isEqualToString:@"DoubleMin"]) 133643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gButtonPlacement = ScrollbarButtonsDoubleStart; 134643ca7872b450ea4efacab6188849e5aac2ba161Steve Block else if ([buttonPlacement isEqualToString:@"DoubleBoth"]) 135643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gButtonPlacement = ScrollbarButtonsDoubleBoth; 136643ca7872b450ea4efacab6188849e5aac2ba161Steve Block else 137643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gButtonPlacement = ScrollbarButtonsDoubleEnd; // The default is ScrollbarButtonsDoubleEnd. 138643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 139643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 140643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid ScrollbarThemeChromiumMac::registerScrollbar(Scrollbar* scrollbar) 141643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 142643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!gScrollbars) 143643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gScrollbars = new HashSet<Scrollbar*>; 144643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gScrollbars->add(scrollbar); 145643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 146643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 147643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid ScrollbarThemeChromiumMac::unregisterScrollbar(Scrollbar* scrollbar) 148643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 149643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gScrollbars->remove(scrollbar); 150643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (gScrollbars->isEmpty()) { 151643ca7872b450ea4efacab6188849e5aac2ba161Steve Block delete gScrollbars; 152643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gScrollbars = 0; 153643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 154643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 155643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 156643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockScrollbarThemeChromiumMac::ScrollbarThemeChromiumMac() 157643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 158643ca7872b450ea4efacab6188849e5aac2ba161Steve Block static bool initialized; 159643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!initialized) { 160643ca7872b450ea4efacab6188849e5aac2ba161Steve Block initialized = true; 161643ca7872b450ea4efacab6188849e5aac2ba161Steve Block [ScrollbarPrefsObserver registerAsObserver]; 162643ca7872b450ea4efacab6188849e5aac2ba161Steve Block preferencesChanged(); 163643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 164643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 165643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 166643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockScrollbarThemeChromiumMac::~ScrollbarThemeChromiumMac() 167643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 168643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 169643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 170643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockvoid ScrollbarThemeChromiumMac::preferencesChanged() 171643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 172643ca7872b450ea4efacab6188849e5aac2ba161Steve Block NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults]; 173643ca7872b450ea4efacab6188849e5aac2ba161Steve Block [defaults synchronize]; 174643ca7872b450ea4efacab6188849e5aac2ba161Steve Block updateArrowPlacement(); 175643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gInitialButtonDelay = [defaults floatForKey:@"NSScrollerButtonDelay"]; 176643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gAutoscrollButtonDelay = [defaults floatForKey:@"NSScrollerButtonPeriod"]; 177643ca7872b450ea4efacab6188849e5aac2ba161Steve Block gJumpOnTrackClick = [defaults boolForKey:@"AppleScrollerPagingBehavior"]; 178643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 179643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 180643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockint ScrollbarThemeChromiumMac::scrollbarThickness(ScrollbarControlSize controlSize) 181643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 182643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return cScrollbarThickness[controlSize]; 183643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 184643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 185643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockdouble ScrollbarThemeChromiumMac::initialAutoscrollTimerDelay() 186643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 187643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return gInitialButtonDelay; 188643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 189643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 190643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockdouble ScrollbarThemeChromiumMac::autoscrollTimerDelay() 191643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 192643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return gAutoscrollButtonDelay; 193643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 194643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 195643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockScrollbarButtonsPlacement ScrollbarThemeChromiumMac::buttonsPlacement() const 196643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 197643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return gButtonPlacement; 198643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 199643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 200643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockbool ScrollbarThemeChromiumMac::hasButtons(Scrollbar* scrollbar) 201643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 202643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return scrollbar->enabled() && (scrollbar->orientation() == HorizontalScrollbar ? 203643ca7872b450ea4efacab6188849e5aac2ba161Steve Block scrollbar->width() : 204643ca7872b450ea4efacab6188849e5aac2ba161Steve Block scrollbar->height()) >= 2 * (cRealButtonLength[scrollbar->controlSize()] - cButtonHitInset[scrollbar->controlSize()]); 205643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 206643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 207643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockbool ScrollbarThemeChromiumMac::hasThumb(Scrollbar* scrollbar) 208643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 209643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return scrollbar->enabled() && (scrollbar->orientation() == HorizontalScrollbar ? 210643ca7872b450ea4efacab6188849e5aac2ba161Steve Block scrollbar->width() : 211643ca7872b450ea4efacab6188849e5aac2ba161Steve Block scrollbar->height()) >= 2 * cButtonInset[scrollbar->controlSize()] + cThumbMinLength[scrollbar->controlSize()] + 1; 212643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 213643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 214643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic IntRect buttonRepaintRect(const IntRect& buttonRect, ScrollbarOrientation orientation, ScrollbarControlSize controlSize, bool start) 215643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 216643ca7872b450ea4efacab6188849e5aac2ba161Steve Block IntRect paintRect(buttonRect); 217643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (orientation == HorizontalScrollbar) { 218643ca7872b450ea4efacab6188849e5aac2ba161Steve Block paintRect.setWidth(cRealButtonLength[controlSize]); 219643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!start) 220643ca7872b450ea4efacab6188849e5aac2ba161Steve Block paintRect.setX(buttonRect.x() - (cRealButtonLength[controlSize] - buttonRect.width())); 221643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } else { 222643ca7872b450ea4efacab6188849e5aac2ba161Steve Block paintRect.setHeight(cRealButtonLength[controlSize]); 223643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!start) 224643ca7872b450ea4efacab6188849e5aac2ba161Steve Block paintRect.setY(buttonRect.y() - (cRealButtonLength[controlSize] - buttonRect.height())); 225643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 226643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 227643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return paintRect; 228643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 229643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 230643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockIntRect ScrollbarThemeChromiumMac::backButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool painting) 231643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 232643ca7872b450ea4efacab6188849e5aac2ba161Steve Block IntRect result; 233643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 234643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (part == BackButtonStartPart && (buttonsPlacement() == ScrollbarButtonsNone || buttonsPlacement() == ScrollbarButtonsDoubleEnd)) 235643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return result; 236643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 237643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (part == BackButtonEndPart && (buttonsPlacement() == ScrollbarButtonsNone || buttonsPlacement() == ScrollbarButtonsDoubleStart || buttonsPlacement() == ScrollbarButtonsSingle)) 238643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return result; 239643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 240643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int thickness = scrollbarThickness(scrollbar->controlSize()); 241643ca7872b450ea4efacab6188849e5aac2ba161Steve Block bool outerButton = part == BackButtonStartPart && (buttonsPlacement() == ScrollbarButtonsDoubleStart || buttonsPlacement() == ScrollbarButtonsDoubleBoth); 242643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (outerButton) { 243643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (scrollbar->orientation() == HorizontalScrollbar) 244643ca7872b450ea4efacab6188849e5aac2ba161Steve Block result = IntRect(scrollbar->x(), scrollbar->y(), cOuterButtonLength[scrollbar->controlSize()] + painting ? cOuterButtonOverlap : 0, thickness); 245643ca7872b450ea4efacab6188849e5aac2ba161Steve Block else 246643ca7872b450ea4efacab6188849e5aac2ba161Steve Block result = IntRect(scrollbar->x(), scrollbar->y(), thickness, cOuterButtonLength[scrollbar->controlSize()] + painting ? cOuterButtonOverlap : 0); 247643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return result; 248643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 249643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 250643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Our repaint rect is slightly larger, since we are a button that is adjacent to the track. 251643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (scrollbar->orientation() == HorizontalScrollbar) { 252643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int start = part == BackButtonStartPart ? scrollbar->x() : scrollbar->x() + scrollbar->width() - cOuterButtonLength[scrollbar->controlSize()] - cButtonLength[scrollbar->controlSize()]; 253643ca7872b450ea4efacab6188849e5aac2ba161Steve Block result = IntRect(start, scrollbar->y(), cButtonLength[scrollbar->controlSize()], thickness); 254643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } else { 255643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int start = part == BackButtonStartPart ? scrollbar->y() : scrollbar->y() + scrollbar->height() - cOuterButtonLength[scrollbar->controlSize()] - cButtonLength[scrollbar->controlSize()]; 256643ca7872b450ea4efacab6188849e5aac2ba161Steve Block result = IntRect(scrollbar->x(), start, thickness, cButtonLength[scrollbar->controlSize()]); 257643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 258643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 259643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (painting) 260643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return buttonRepaintRect(result, scrollbar->orientation(), scrollbar->controlSize(), part == BackButtonStartPart); 261643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return result; 262643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 263643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 264643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockIntRect ScrollbarThemeChromiumMac::forwardButtonRect(Scrollbar* scrollbar, ScrollbarPart part, bool painting) 265643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 266643ca7872b450ea4efacab6188849e5aac2ba161Steve Block IntRect result; 267643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 268643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (part == ForwardButtonEndPart && (buttonsPlacement() == ScrollbarButtonsNone || buttonsPlacement() == ScrollbarButtonsDoubleStart)) 269643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return result; 270643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 271643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (part == ForwardButtonStartPart && (buttonsPlacement() == ScrollbarButtonsNone || buttonsPlacement() == ScrollbarButtonsDoubleEnd || buttonsPlacement() == ScrollbarButtonsSingle)) 272643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return result; 273643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 274643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int thickness = scrollbarThickness(scrollbar->controlSize()); 275643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int outerButtonLength = cOuterButtonLength[scrollbar->controlSize()]; 276643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int buttonLength = cButtonLength[scrollbar->controlSize()]; 277643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 278643ca7872b450ea4efacab6188849e5aac2ba161Steve Block bool outerButton = part == ForwardButtonEndPart && (buttonsPlacement() == ScrollbarButtonsDoubleEnd || buttonsPlacement() == ScrollbarButtonsDoubleBoth); 279643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (outerButton) { 280643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (scrollbar->orientation() == HorizontalScrollbar) { 281643ca7872b450ea4efacab6188849e5aac2ba161Steve Block result = IntRect(scrollbar->x() + scrollbar->width() - outerButtonLength, scrollbar->y(), outerButtonLength, thickness); 282643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (painting) 283643ca7872b450ea4efacab6188849e5aac2ba161Steve Block result.inflateX(cOuterButtonOverlap); 284643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } else { 285643ca7872b450ea4efacab6188849e5aac2ba161Steve Block result = IntRect(scrollbar->x(), scrollbar->y() + scrollbar->height() - outerButtonLength, thickness, outerButtonLength); 286643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (painting) 287643ca7872b450ea4efacab6188849e5aac2ba161Steve Block result.inflateY(cOuterButtonOverlap); 288643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 289643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return result; 290643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 291643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 292643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (scrollbar->orientation() == HorizontalScrollbar) { 293643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int start = part == ForwardButtonEndPart ? scrollbar->x() + scrollbar->width() - buttonLength : scrollbar->x() + outerButtonLength; 294643ca7872b450ea4efacab6188849e5aac2ba161Steve Block result = IntRect(start, scrollbar->y(), buttonLength, thickness); 295643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } else { 296643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int start = part == ForwardButtonEndPart ? scrollbar->y() + scrollbar->height() - buttonLength : scrollbar->y() + outerButtonLength; 297643ca7872b450ea4efacab6188849e5aac2ba161Steve Block result = IntRect(scrollbar->x(), start, thickness, buttonLength); 298643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 299643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (painting) 300643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return buttonRepaintRect(result, scrollbar->orientation(), scrollbar->controlSize(), part == ForwardButtonStartPart); 301643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return result; 302643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 303643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 304643ca7872b450ea4efacab6188849e5aac2ba161Steve BlockIntRect ScrollbarThemeChromiumMac::trackRect(Scrollbar* scrollbar, bool painting) 305643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 306643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (painting || !hasButtons(scrollbar)) 307643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return scrollbar->frameRect(); 308643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 309643ca7872b450ea4efacab6188849e5aac2ba161Steve Block IntRect result; 310643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int thickness = scrollbarThickness(scrollbar->controlSize()); 311643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int startWidth = 0; 312643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int endWidth = 0; 313643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int outerButtonLength = cOuterButtonLength[scrollbar->controlSize()]; 314643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int buttonLength = cButtonLength[scrollbar->controlSize()]; 315643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int doubleButtonLength = outerButtonLength + buttonLength; 316643ca7872b450ea4efacab6188849e5aac2ba161Steve Block switch (buttonsPlacement()) { 317643ca7872b450ea4efacab6188849e5aac2ba161Steve Block case ScrollbarButtonsSingle: 318643ca7872b450ea4efacab6188849e5aac2ba161Steve Block startWidth = buttonLength; 319643ca7872b450ea4efacab6188849e5aac2ba161Steve Block endWidth = buttonLength; 320643ca7872b450ea4efacab6188849e5aac2ba161Steve Block break; 321643ca7872b450ea4efacab6188849e5aac2ba161Steve Block case ScrollbarButtonsDoubleStart: 322643ca7872b450ea4efacab6188849e5aac2ba161Steve Block startWidth = doubleButtonLength; 323643ca7872b450ea4efacab6188849e5aac2ba161Steve Block break; 324643ca7872b450ea4efacab6188849e5aac2ba161Steve Block case ScrollbarButtonsDoubleEnd: 325643ca7872b450ea4efacab6188849e5aac2ba161Steve Block endWidth = doubleButtonLength; 326643ca7872b450ea4efacab6188849e5aac2ba161Steve Block break; 327643ca7872b450ea4efacab6188849e5aac2ba161Steve Block case ScrollbarButtonsDoubleBoth: 328643ca7872b450ea4efacab6188849e5aac2ba161Steve Block startWidth = doubleButtonLength; 329643ca7872b450ea4efacab6188849e5aac2ba161Steve Block endWidth = doubleButtonLength; 330643ca7872b450ea4efacab6188849e5aac2ba161Steve Block break; 331643ca7872b450ea4efacab6188849e5aac2ba161Steve Block default: 332643ca7872b450ea4efacab6188849e5aac2ba161Steve Block break; 333643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 334643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 335643ca7872b450ea4efacab6188849e5aac2ba161Steve Block int totalWidth = startWidth + endWidth; 336643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (scrollbar->orientation() == HorizontalScrollbar) 337643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return IntRect(scrollbar->x() + startWidth, scrollbar->y(), scrollbar->width() - totalWidth, thickness); 338643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return IntRect(scrollbar->x(), scrollbar->y() + startWidth, thickness, scrollbar->height() - totalWidth); 339643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 340643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 341643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockint ScrollbarThemeChromiumMac::minimumThumbLength(Scrollbar* scrollbar) 342643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 343643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return cThumbMinLength[scrollbar->controlSize()]; 344643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 345643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 346643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockbool ScrollbarThemeChromiumMac::shouldCenterOnThumb(Scrollbar*, const PlatformMouseEvent& evt) 347643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 348643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (evt.button() != LeftButton) 349643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return false; 350643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (gJumpOnTrackClick) 351643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return !evt.altKey(); 352643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return evt.altKey(); 353643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 354643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 355643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockstatic int scrollbarPartToHIPressedState(ScrollbarPart part) 356643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 357643ca7872b450ea4efacab6188849e5aac2ba161Steve Block switch (part) { 358643ca7872b450ea4efacab6188849e5aac2ba161Steve Block case BackButtonStartPart: 359643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return kThemeTopOutsideArrowPressed; 360643ca7872b450ea4efacab6188849e5aac2ba161Steve Block case BackButtonEndPart: 361643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return kThemeTopOutsideArrowPressed; // This does not make much sense. For some reason the outside constant is required. 362643ca7872b450ea4efacab6188849e5aac2ba161Steve Block case ForwardButtonStartPart: 363643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return kThemeTopInsideArrowPressed; 364643ca7872b450ea4efacab6188849e5aac2ba161Steve Block case ForwardButtonEndPart: 365643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return kThemeBottomOutsideArrowPressed; 366643ca7872b450ea4efacab6188849e5aac2ba161Steve Block case ThumbPart: 367643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return kThemeThumbPressed; 368643ca7872b450ea4efacab6188849e5aac2ba161Steve Block default: 369643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return 0; 370643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 371643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 372643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 373ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdochstatic PlatformBridge::ThemePaintState scrollbarStateToThemeState(Scrollbar* scrollbar) { 374cad810f21b803229eb11403f9209855525a25d57Steve Block if (!scrollbar->enabled()) 375ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return PlatformBridge::StateDisabled; 376ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch if (!scrollbar->scrollableArea()->isActive()) 377ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return PlatformBridge::StateInactive; 378cad810f21b803229eb11403f9209855525a25d57Steve Block if (scrollbar->pressedPart() == ThumbPart) 379ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return PlatformBridge::StatePressed; 380cad810f21b803229eb11403f9209855525a25d57Steve Block 381ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch return PlatformBridge::StateActive; 382cad810f21b803229eb11403f9209855525a25d57Steve Block} 383cad810f21b803229eb11403f9209855525a25d57Steve Block 384643ca7872b450ea4efacab6188849e5aac2ba161Steve Blockbool ScrollbarThemeChromiumMac::paint(Scrollbar* scrollbar, GraphicsContext* context, const IntRect& damageRect) 385643ca7872b450ea4efacab6188849e5aac2ba161Steve Block{ 386643ca7872b450ea4efacab6188849e5aac2ba161Steve Block HIThemeTrackDrawInfo trackInfo; 387643ca7872b450ea4efacab6188849e5aac2ba161Steve Block trackInfo.version = 0; 388643ca7872b450ea4efacab6188849e5aac2ba161Steve Block trackInfo.kind = scrollbar->controlSize() == RegularScrollbar ? kThemeMediumScrollBar : kThemeSmallScrollBar; 389643ca7872b450ea4efacab6188849e5aac2ba161Steve Block trackInfo.bounds = scrollbar->frameRect(); 390643ca7872b450ea4efacab6188849e5aac2ba161Steve Block trackInfo.min = 0; 391643ca7872b450ea4efacab6188849e5aac2ba161Steve Block trackInfo.max = scrollbar->maximum(); 392643ca7872b450ea4efacab6188849e5aac2ba161Steve Block trackInfo.value = scrollbar->currentPos(); 393d0825bca7fe65beaee391d30da42e937db621564Steve Block trackInfo.trackInfo.scrollbar.viewsize = scrollbar->visibleSize(); 394643ca7872b450ea4efacab6188849e5aac2ba161Steve Block trackInfo.attributes = 0; 395643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (scrollbar->orientation() == HorizontalScrollbar) 396643ca7872b450ea4efacab6188849e5aac2ba161Steve Block trackInfo.attributes |= kThemeTrackHorizontal; 397643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 398643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!scrollbar->enabled()) 399643ca7872b450ea4efacab6188849e5aac2ba161Steve Block trackInfo.enableState = kThemeTrackDisabled; 400643ca7872b450ea4efacab6188849e5aac2ba161Steve Block else 401ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch trackInfo.enableState = scrollbar->scrollableArea()->isActive() ? kThemeTrackActive : kThemeTrackInactive; 402643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 403643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!hasButtons(scrollbar)) 404643ca7872b450ea4efacab6188849e5aac2ba161Steve Block trackInfo.enableState = kThemeTrackNothingToScroll; 405643ca7872b450ea4efacab6188849e5aac2ba161Steve Block trackInfo.trackInfo.scrollbar.pressState = scrollbarPartToHIPressedState(scrollbar->pressedPart()); 406643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 407643ca7872b450ea4efacab6188849e5aac2ba161Steve Block CGAffineTransform currentCTM = CGContextGetCTM(context->platformContext()); 408643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 409643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // The Aqua scrollbar is buggy when rotated and scaled. We will just draw into a bitmap if we detect a scale or rotation. 410643ca7872b450ea4efacab6188849e5aac2ba161Steve Block bool canDrawDirectly = currentCTM.a == 1.0f && currentCTM.b == 0.0f && currentCTM.c == 0.0f && (currentCTM.d == 1.0f || currentCTM.d == -1.0f); 411643ca7872b450ea4efacab6188849e5aac2ba161Steve Block GraphicsContext* drawingContext = context; 412643ca7872b450ea4efacab6188849e5aac2ba161Steve Block OwnPtr<ImageBuffer> imageBuffer; 413643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!canDrawDirectly) { 414643ca7872b450ea4efacab6188849e5aac2ba161Steve Block trackInfo.bounds = IntRect(IntPoint(), scrollbar->frameRect().size()); 415643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 416643ca7872b450ea4efacab6188849e5aac2ba161Steve Block IntRect bufferRect(scrollbar->frameRect()); 417643ca7872b450ea4efacab6188849e5aac2ba161Steve Block bufferRect.intersect(damageRect); 418643ca7872b450ea4efacab6188849e5aac2ba161Steve Block bufferRect.move(-scrollbar->frameRect().x(), -scrollbar->frameRect().y()); 419643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 420643ca7872b450ea4efacab6188849e5aac2ba161Steve Block imageBuffer = ImageBuffer::create(bufferRect.size()); 421643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!imageBuffer) 422643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return true; 423643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 424643ca7872b450ea4efacab6188849e5aac2ba161Steve Block drawingContext = imageBuffer->context(); 425643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 426643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 427643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Draw thumbless. 428643ca7872b450ea4efacab6188849e5aac2ba161Steve Block HIThemeDrawTrack(&trackInfo, 0, drawingContext->platformContext(), kHIThemeOrientationNormal); 429643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 430643ca7872b450ea4efacab6188849e5aac2ba161Steve Block Vector<IntRect> tickmarks; 431ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch scrollbar->scrollableArea()->getTickmarks(tickmarks); 432643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (scrollbar->orientation() == VerticalScrollbar && tickmarks.size()) { 433643ca7872b450ea4efacab6188849e5aac2ba161Steve Block drawingContext->save(); 434643ca7872b450ea4efacab6188849e5aac2ba161Steve Block drawingContext->setShouldAntialias(false); 435a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch drawingContext->setStrokeColor(Color(0xCC, 0xAA, 0x00, 0xFF), ColorSpaceDeviceRGB); 436a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch drawingContext->setFillColor(Color(0xFF, 0xDD, 0x00, 0xFF), ColorSpaceDeviceRGB); 437643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 438643ca7872b450ea4efacab6188849e5aac2ba161Steve Block IntRect thumbArea = trackRect(scrollbar, false); 439643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (!canDrawDirectly) { 440643ca7872b450ea4efacab6188849e5aac2ba161Steve Block thumbArea.setX(0); 441643ca7872b450ea4efacab6188849e5aac2ba161Steve Block thumbArea.setY(0); 442643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 443643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // The ends are rounded and the thumb doesn't go there. 444643ca7872b450ea4efacab6188849e5aac2ba161Steve Block thumbArea.inflateY(-thumbArea.width()); 445643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 446643ca7872b450ea4efacab6188849e5aac2ba161Steve Block for (Vector<IntRect>::const_iterator i = tickmarks.begin(); i != tickmarks.end(); ++i) { 447643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Calculate how far down (in %) the tick-mark should appear. 448643ca7872b450ea4efacab6188849e5aac2ba161Steve Block const float percent = static_cast<float>(i->y()) / scrollbar->totalSize(); 449643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (percent < 0.0 || percent > 1.0) 450643ca7872b450ea4efacab6188849e5aac2ba161Steve Block continue; 451643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 452643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Calculate how far down (in pixels) the tick-mark should appear. 4532fc2651226baac27029e38c9d6ef883fa32084dbSteve Block const int yPos = static_cast<int>((thumbArea.y() + (thumbArea.height() * percent))) & ~1; 454643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 455643ca7872b450ea4efacab6188849e5aac2ba161Steve Block // Paint. 456643ca7872b450ea4efacab6188849e5aac2ba161Steve Block const int indent = 2; 4572fc2651226baac27029e38c9d6ef883fa32084dbSteve Block FloatRect tickRect(thumbArea.x() + indent, yPos, thumbArea.width() - 2 * indent - 1, 2); 458643ca7872b450ea4efacab6188849e5aac2ba161Steve Block drawingContext->fillRect(tickRect); 459643ca7872b450ea4efacab6188849e5aac2ba161Steve Block drawingContext->strokeRect(tickRect, 1); 460643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 461643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 462643ca7872b450ea4efacab6188849e5aac2ba161Steve Block drawingContext->restore(); 463643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 464643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 465643ca7872b450ea4efacab6188849e5aac2ba161Steve Block if (hasThumb(scrollbar)) { 466ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch PlatformBridge::ThemePaintScrollbarInfo scrollbarInfo; 467ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch scrollbarInfo.orientation = scrollbar->orientation() == HorizontalScrollbar ? PlatformBridge::ScrollbarOrientationHorizontal : PlatformBridge::ScrollbarOrientationVertical; 468ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch scrollbarInfo.parent = scrollbar->parent() && scrollbar->parent()->isFrameView() && static_cast<FrameView*>(scrollbar->parent())->isScrollViewScrollbar(scrollbar) ? PlatformBridge::ScrollbarParentScrollView : PlatformBridge::ScrollbarParentRenderLayer; 469cad810f21b803229eb11403f9209855525a25d57Steve Block scrollbarInfo.maxValue = scrollbar->maximum(); 470cad810f21b803229eb11403f9209855525a25d57Steve Block scrollbarInfo.currentValue = scrollbar->currentPos(); 471cad810f21b803229eb11403f9209855525a25d57Steve Block scrollbarInfo.visibleSize = scrollbar->visibleSize(); 472cad810f21b803229eb11403f9209855525a25d57Steve Block scrollbarInfo.totalSize = scrollbar->totalSize(); 473cad810f21b803229eb11403f9209855525a25d57Steve Block 474ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch PlatformBridge::paintScrollbarThumb( 475cad810f21b803229eb11403f9209855525a25d57Steve Block drawingContext, 476cad810f21b803229eb11403f9209855525a25d57Steve Block scrollbarStateToThemeState(scrollbar), 477ab9e7a118cf1ea2e3a93dce683b2ded3e7291ddbBen Murdoch scrollbar->controlSize() == RegularScrollbar ? PlatformBridge::SizeRegular : PlatformBridge::SizeSmall, 478cad810f21b803229eb11403f9209855525a25d57Steve Block scrollbar->frameRect(), 479cad810f21b803229eb11403f9209855525a25d57Steve Block scrollbarInfo); 480643ca7872b450ea4efacab6188849e5aac2ba161Steve Block } 481643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 482f486d19d62f1bc33246748b14b14a9dfa617b57fIain Merrick if (!canDrawDirectly) 483a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch context->drawImageBuffer(imageBuffer.get(), ColorSpaceDeviceRGB, scrollbar->frameRect().location()); 484643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 485643ca7872b450ea4efacab6188849e5aac2ba161Steve Block return true; 486643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 487643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 488643ca7872b450ea4efacab6188849e5aac2ba161Steve Block} 489643ca7872b450ea4efacab6188849e5aac2ba161Steve Block 490