1231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block/* 2231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2008 Apple Inc. All Rights Reserved. 3231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Copyright (C) 2009 Google Inc. All Rights Reserved. 4231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 5231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * Redistribution and use in source and binary forms, with or without 6231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * modification, are permitted provided that the following conditions 7231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * are met: 8231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 1. Redistributions of source code must retain the above copyright 9231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * notice, this list of conditions and the following disclaimer. 10231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 2. Redistributions in binary form must reproduce the above copyright 11231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * notice, this list of conditions and the following disclaimer in the 12231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * documentation and/or other materials provided with the distribution. 13231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * 14231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY 15231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 17231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR 18231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 19231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 20231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 21231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 22231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 245e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block */ 26231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 27231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#import "config.h" 28231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#import "ThemeChromiumMac.h" 29231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 30231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#import "BlockExceptions.h" 31231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#import "GraphicsContext.h" 32231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#import "LocalCurrentGraphicsContext.h" 33231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#import "ScrollView.h" 34231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#import "WebCoreSystemInterface.h" 35967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch#import <Carbon/Carbon.h> 36231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block#include <wtf/StdLibExtras.h> 378a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block#import <objc/runtime.h> 38231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 39231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockusing namespace std; 40231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 41231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// This file (and its associated .h file) is a clone of ThemeMac.mm. 42231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// Because the original file is designed to run in-process inside a Cocoa view, 43231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// we must maintain a fork. Please maintain this file by performing parallel 44231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// changes to it. 45231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// 46231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// The only changes from ThemeMac should be: 47231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// - The classname change from ThemeMac to ThemeChromiumMac. 48231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// - The import of FlippedView() and its use as the parent view for cell 49231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// rendering. 50231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// - In updateStates() the code to update the cells' inactive state. 51231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// - In paintButton() the code to save/restore the window's default button cell. 528a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// - The Snow Leopard focus ring bug fix and its use around every call to 538a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// -[NSButtonCell drawWithFrame:inView:]. 54231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// 55231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// For all other differences, if it was introduced in this file, then the 56231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// maintainer forgot to include it in the list; otherwise it is an update that 57231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// should have been applied to this file but was not. 58231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 59231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// FIXME: Default buttons really should be more like push buttons and not like buttons. 60231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 618a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// --- START fix for Snow Leopard focus ring bug --- 628a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 638a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// There is a bug in the Cocoa focus ring drawing code. The code calls +[NSView 648a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// focusView] (to get the currently focused view) and then calls an NSRect- 658a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// returning method on that view to obtain a clipping rect. However, if there is 668a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// no focused view (as there won't be if the destination is a context), the rect 678a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// returned from the method invocation on nil is garbage. 688a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// 698a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// The garbage fortunately does not clip the focus ring on Leopard, but 708a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// unfortunately does so on Snow Leopard. Therefore, if a runtime test shows 718a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// that focus ring drawing fails, we swizzle NSView to ensure it returns a valid 728a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// view with a valid clipping rectangle. 738a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// 748a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// FIXME: After the referenced bug is fixed on all supported platforms, remove 758a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// this code. 768a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// 778a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// References: 788a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// <http://crbug.com/27493> 798a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// <rdar://problem/7604051> (<http://openradar.appspot.com/7604051>) 808a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 818a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block@interface TCMVisibleView : NSView 828a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 838a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block@end 848a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 858a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block@implementation TCMVisibleView 868a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 878a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block- (struct CGRect)_focusRingVisibleRect 888a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{ 898a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return CGRectZero; 908a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block} 918a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 928a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block- (id)_focusRingClipAncestor 938a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{ 948a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return self; 958a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block} 968a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 978a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block@end 988a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 998a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block@interface NSView (TCMInterposing) 1008a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block+ (NSView *)TCMInterposing_focusView; 1018a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block@end 1028a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1038a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blocknamespace FocusIndicationFix { 1048a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1058a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockbool currentOSHasSetFocusRingStyleInBitmapBug() 1068a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{ 1078a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block UInt32 pixel = 0; 1088a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block UInt32* pixelPlane = &pixel; 1098a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block UInt32** pixelPlanes = &pixelPlane; 1108a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block NSBitmapImageRep *bitmap = [[NSBitmapImageRep alloc] initWithBitmapDataPlanes:(UInt8**)pixelPlanes 1118a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block pixelsWide:1 1128a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block pixelsHigh:1 1138a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block bitsPerSample:8 1148a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block samplesPerPixel:4 1158a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block hasAlpha:YES 1168a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block isPlanar:NO 1178a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block colorSpaceName:NSCalibratedRGBColorSpace 1188a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block bitmapFormat:NSAlphaFirstBitmapFormat 1198a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block bytesPerRow:4 1208a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block bitsPerPixel:32]; 1218a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block [NSGraphicsContext saveGraphicsState]; 1228a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block [NSGraphicsContext setCurrentContext:[NSGraphicsContext graphicsContextWithBitmapImageRep:bitmap]]; 1238a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block NSSetFocusRingStyle(NSFocusRingOnly); 1248a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block NSRectFill(NSMakeRect(0, 0, 1, 1)); 1258a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block [NSGraphicsContext restoreGraphicsState]; 1268a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block [bitmap release]; 1278a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1288a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return !pixel; 1298a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block} 1308a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1318a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockbool swizzleFocusView() 1328a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{ 1338a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if (!currentOSHasSetFocusRingStyleInBitmapBug()) 1348a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return false; 1358a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1368a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block Class nsview = [NSView class]; 1378a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block Method m1 = class_getClassMethod(nsview, @selector(focusView)); 1388a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block Method m2 = class_getClassMethod(nsview, @selector(TCMInterposing_focusView)); 1398a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if (m1 && m2) { 1408a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block method_exchangeImplementations(m1, m2); 1418a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return true; 1428a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 1438a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1448a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return false; 1458a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block} 1468a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1478a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockstatic bool interpose = false; 1488a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1498a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// A class to restrict the amount of time spent messing with interposing. It 1508a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// only stacks one-deep. 1518a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockclass ScopedFixer { 1528a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Blockpublic: 1538a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block ScopedFixer() 1548a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block { 1558a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block static bool swizzled = swizzleFocusView(); 1568a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block interpose = swizzled; 1578a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 1588a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1598a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block ~ScopedFixer() 1608a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block { 1618a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block interpose = false; 1628a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 1638a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block}; 1648a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1658a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block} // namespace FocusIndicationFix 1668a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1678a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block@implementation NSView (TCMInterposing) 1688a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1698a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block+ (NSView *)TCMInterposing_focusView 1708a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block{ 1718a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block NSView *view = [self TCMInterposing_focusView]; // call original (was swizzled) 1728a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block if (!view && FocusIndicationFix::interpose) { 1738a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block static TCMVisibleView* fixedView = [[TCMVisibleView alloc] init]; 1748a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block view = fixedView; 1758a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 1768a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1778a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block return view; 1788a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block} 1798a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1808a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block@end 1818a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 1828a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block// --- END fix for Snow Leopard focus ring bug --- 1838a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block 184231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blocknamespace WebCore { 185231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 186231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// Pick up utility function from RenderThemeChromiumMac. 187231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockextern NSView* FlippedView(); 188231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 189231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockenum { 190231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block topMargin, 191231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block rightMargin, 192231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bottomMargin, 193231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block leftMargin 194231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block}; 195231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 196231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockTheme* platformTheme() 197231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 198231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block DEFINE_STATIC_LOCAL(ThemeChromiumMac, themeMac, ()); 199231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return &themeMac; 200231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 201231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 202231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// Helper functions used by a bunch of different control parts. 203231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 204231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic NSControlSize controlSizeForFont(const Font& font) 205231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 206231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block int fontSize = font.pixelSize(); 207231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (fontSize >= 16) 208231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return NSRegularControlSize; 209231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (fontSize >= 11) 210231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return NSSmallControlSize; 211231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return NSMiniControlSize; 212231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 213231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 214967717af5423377c967781471ee106e2bb4e11c8Ben Murdochstatic LengthSize sizeFromNSControlSize(NSControlSize nsControlSize, const LengthSize& zoomedSize, float zoomFactor, const IntSize* sizes) 215231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 216967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch IntSize controlSize = sizes[nsControlSize]; 217231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (zoomFactor != 1.0f) 218231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block controlSize = IntSize(controlSize.width() * zoomFactor, controlSize.height() * zoomFactor); 219231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block LengthSize result = zoomedSize; 220231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (zoomedSize.width().isIntrinsicOrAuto() && controlSize.width() > 0) 221231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block result.setWidth(Length(controlSize.width(), Fixed)); 222231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (zoomedSize.height().isIntrinsicOrAuto() && controlSize.height() > 0) 223231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block result.setHeight(Length(controlSize.height(), Fixed)); 224231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return result; 225231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 226231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 227967717af5423377c967781471ee106e2bb4e11c8Ben Murdochstatic LengthSize sizeFromFont(const Font& font, const LengthSize& zoomedSize, float zoomFactor, const IntSize* sizes) 228967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 229967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return sizeFromNSControlSize(controlSizeForFont(font), zoomedSize, zoomFactor, sizes); 230967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 231967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 232967717af5423377c967781471ee106e2bb4e11c8Ben Murdochstatic ControlSize controlSizeFromPixelSize(const IntSize* sizes, const IntSize& minZoomedSize, float zoomFactor) 233231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 234231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (minZoomedSize.width() >= static_cast<int>(sizes[NSRegularControlSize].width() * zoomFactor) && 235231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block minZoomedSize.height() >= static_cast<int>(sizes[NSRegularControlSize].height() * zoomFactor)) 236967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return NSRegularControlSize; 237967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (minZoomedSize.width() >= static_cast<int>(sizes[NSSmallControlSize].width() * zoomFactor) && 238967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch minZoomedSize.height() >= static_cast<int>(sizes[NSSmallControlSize].height() * zoomFactor)) 239967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return NSSmallControlSize; 240967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return NSMiniControlSize; 241967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 242967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 243967717af5423377c967781471ee106e2bb4e11c8Ben Murdochstatic void setControlSize(NSCell* cell, const IntSize* sizes, const IntSize& minZoomedSize, float zoomFactor) 244967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 245967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch ControlSize size = controlSizeFromPixelSize(sizes, minZoomedSize, zoomFactor); 246231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (size != [cell controlSize]) // Only update if we have to, since AppKit does work even if the size is the same. 247967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch [cell setControlSize:(NSControlSize)size]; 248231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 249231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 250231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic void updateStates(NSCell* cell, ControlStates states) 251231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 252231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Hover state is not supported by Aqua. 2535e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 254231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Pressed state 255231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool oldPressed = [cell isHighlighted]; 256231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool pressed = states & PressedState; 257231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (pressed != oldPressed) 258231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [cell setHighlighted:pressed]; 2595e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 260231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Enabled state 261231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool oldEnabled = [cell isEnabled]; 262231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool enabled = states & EnabledState; 263231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (enabled != oldEnabled) 264231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [cell setEnabled:enabled]; 2655e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 266231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Focused state 267231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool oldFocused = [cell showsFirstResponder]; 268231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool focused = states & FocusState; 269231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (focused != oldFocused) 270231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [cell setShowsFirstResponder:focused]; 271231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 272231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Checked and Indeterminate 273231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool oldIndeterminate = [cell state] == NSMixedState; 274231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool indeterminate = (states & IndeterminateState); 275231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool checked = states & CheckedState; 276231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool oldChecked = [cell state] == NSOnState; 277231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (oldIndeterminate != indeterminate || checked != oldChecked) 278231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [cell setState:indeterminate ? NSMixedState : (checked ? NSOnState : NSOffState)]; 2795e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 280231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Window Inactive state 281231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block NSControlTint oldTint = [cell controlTint]; 282231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block bool windowInactive = (states & WindowInactiveState); 28306ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen NSControlTint tint = windowInactive ? static_cast<NSControlTint>(NSClearControlTint) 28406ea8e899e48f1f2f396b70e63fae369f2f23232Kristian Monsen : [NSColor currentControlTint]; 285231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (tint != oldTint) 286231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [cell setControlTint:tint]; 287231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 288231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 289967717af5423377c967781471ee106e2bb4e11c8Ben Murdochstatic ThemeDrawState convertControlStatesToThemeDrawState(ThemeButtonKind kind, ControlStates states) 290967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 291967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (states & ReadOnlyState) 292967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return kThemeStateUnavailableInactive; 293967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (!(states & EnabledState)) 294967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return kThemeStateUnavailableInactive; 295967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 296967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch // Do not process PressedState if !EnabledState or ReadOnlyState. 297967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (states & PressedState) { 298967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (kind == kThemeIncDecButton || kind == kThemeIncDecButtonSmall || kind == kThemeIncDecButtonMini) 299967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return states & SpinUpState ? kThemeStatePressedUp : kThemeStatePressedDown; 300967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return kThemeStatePressed; 301967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 302967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return kThemeStateActive; 303967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 304967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 305231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic IntRect inflateRect(const IntRect& zoomedRect, const IntSize& zoomedSize, const int* margins, float zoomFactor) 306231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 307231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Only do the inflation if the available width/height are too small. Otherwise try to 308231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // fit the glow/check space into the available box's width/height. 309231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block int widthDelta = zoomedRect.width() - (zoomedSize.width() + margins[leftMargin] * zoomFactor + margins[rightMargin] * zoomFactor); 310231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block int heightDelta = zoomedRect.height() - (zoomedSize.height() + margins[topMargin] * zoomFactor + margins[bottomMargin] * zoomFactor); 311231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block IntRect result(zoomedRect); 312231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (widthDelta < 0) { 313231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block result.setX(result.x() - margins[leftMargin] * zoomFactor); 314231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block result.setWidth(result.width() - widthDelta); 315231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 316231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (heightDelta < 0) { 317231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block result.setY(result.y() - margins[topMargin] * zoomFactor); 318231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block result.setHeight(result.height() - heightDelta); 319231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 320231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return result; 321231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 322231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 323231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// Checkboxes 324231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 325231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic const IntSize* checkboxSizes() 326231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 327231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block static const IntSize sizes[3] = { IntSize(14, 14), IntSize(12, 12), IntSize(10, 10) }; 328231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return sizes; 329231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 330231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 331231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic const int* checkboxMargins(NSControlSize controlSize) 332231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 333231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block static const int margins[3][4] = 334231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block { 335231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block { 3, 4, 4, 2 }, 336231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block { 4, 3, 3, 3 }, 337231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block { 4, 3, 3, 3 }, 338231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block }; 339231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return margins[controlSize]; 340231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 341231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 342231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic LengthSize checkboxSize(const Font& font, const LengthSize& zoomedSize, float zoomFactor) 343231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 344231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // If the width and height are both specified, then we have nothing to do. 345231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto()) 346231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return zoomedSize; 347231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 348231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Use the font size to determine the intrinsic width of the control. 349231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return sizeFromFont(font, zoomedSize, zoomFactor, checkboxSizes()); 350231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 351231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 3525e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockstatic NSButtonCell *checkbox(ControlStates states, const IntRect& zoomedRect, float zoomFactor) 353231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 3545e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block static NSButtonCell *checkboxCell; 355231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!checkboxCell) { 356231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block checkboxCell = [[NSButtonCell alloc] init]; 357231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [checkboxCell setButtonType:NSSwitchButton]; 358231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [checkboxCell setTitle:nil]; 359231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [checkboxCell setAllowsMixedState:YES]; 360231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [checkboxCell setFocusRingType:NSFocusRingTypeExterior]; 361231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 3625e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 363231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Set the control size based off the rectangle we're painting into. 364231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block setControlSize(checkboxCell, checkboxSizes(), zoomedRect.size(), zoomFactor); 365231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 366231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Update the various states we respond to. 367231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block updateStates(checkboxCell, states); 3685e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 369231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return checkboxCell; 370231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 371231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 372231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// FIXME: Share more code with radio buttons. 373231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic void paintCheckbox(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) 374231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 375231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block BEGIN_BLOCK_OBJC_EXCEPTIONS 376231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 377231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Determine the width and height needed for the control and prepare the cell for painting. 3785e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block NSButtonCell *checkboxCell = checkbox(states, zoomedRect, zoomFactor); 379a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch LocalCurrentGraphicsContext localContext(context); 380231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 381231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context->save(); 382231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 383231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block NSControlSize controlSize = [checkboxCell controlSize]; 384231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block IntSize zoomedSize = checkboxSizes()[controlSize]; 385231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block zoomedSize.setWidth(zoomedSize.width() * zoomFactor); 386231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block zoomedSize.setHeight(zoomedSize.height() * zoomFactor); 387231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block IntRect inflatedRect = inflateRect(zoomedRect, zoomedSize, checkboxMargins(controlSize), zoomFactor); 3885e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 389231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (zoomFactor != 1.0f) { 390231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block inflatedRect.setWidth(inflatedRect.width() / zoomFactor); 391231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block inflatedRect.setHeight(inflatedRect.height() / zoomFactor); 392231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context->translate(inflatedRect.x(), inflatedRect.y()); 393231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context->scale(FloatSize(zoomFactor, zoomFactor)); 394231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context->translate(-inflatedRect.x(), -inflatedRect.y()); 395231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 3965e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 3978a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block { 3988a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block FocusIndicationFix::ScopedFixer fix; 3998a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block [checkboxCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()]; 4008a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 401231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [checkboxCell setControlView:nil]; 402231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 403231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context->restore(); 4045e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 405231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block END_BLOCK_OBJC_EXCEPTIONS 406231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 407231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 408231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// Radio Buttons 409231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 410231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic const IntSize* radioSizes() 411231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 412231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block static const IntSize sizes[3] = { IntSize(14, 15), IntSize(12, 13), IntSize(10, 10) }; 413231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return sizes; 414231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 415231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 416231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic const int* radioMargins(NSControlSize controlSize) 417231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 418231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block static const int margins[3][4] = 419231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block { 420231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block { 2, 2, 4, 2 }, 421231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block { 3, 2, 3, 2 }, 422231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block { 1, 0, 2, 0 }, 423231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block }; 424231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return margins[controlSize]; 425231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 426231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 427231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic LengthSize radioSize(const Font& font, const LengthSize& zoomedSize, float zoomFactor) 428231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 429231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // If the width and height are both specified, then we have nothing to do. 430231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto()) 431231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return zoomedSize; 432231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 433231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Use the font size to determine the intrinsic width of the control. 434231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return sizeFromFont(font, zoomedSize, zoomFactor, radioSizes()); 435231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 436231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 4375e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockstatic NSButtonCell *radio(ControlStates states, const IntRect& zoomedRect, float zoomFactor) 438231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 4395e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block static NSButtonCell *radioCell; 440231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!radioCell) { 441231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block radioCell = [[NSButtonCell alloc] init]; 442231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [radioCell setButtonType:NSRadioButton]; 443231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [radioCell setTitle:nil]; 444231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [radioCell setFocusRingType:NSFocusRingTypeExterior]; 445231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 4465e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 447231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Set the control size based off the rectangle we're painting into. 448231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block setControlSize(radioCell, radioSizes(), zoomedRect.size(), zoomFactor); 449231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 450231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Update the various states we respond to. 451231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block updateStates(radioCell, states); 4525e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 453231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return radioCell; 454231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 455231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 456231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic void paintRadio(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) 457231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 458231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Determine the width and height needed for the control and prepare the cell for painting. 4595e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block NSButtonCell *radioCell = radio(states, zoomedRect, zoomFactor); 460a94275402997c11dd2e778633dacf4b7e630a35dBen Murdoch LocalCurrentGraphicsContext localContext(context); 461231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 462231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context->save(); 463231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 464231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block NSControlSize controlSize = [radioCell controlSize]; 465231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block IntSize zoomedSize = radioSizes()[controlSize]; 466231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block zoomedSize.setWidth(zoomedSize.width() * zoomFactor); 467231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block zoomedSize.setHeight(zoomedSize.height() * zoomFactor); 468231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block IntRect inflatedRect = inflateRect(zoomedRect, zoomedSize, radioMargins(controlSize), zoomFactor); 4695e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 470231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (zoomFactor != 1.0f) { 471231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block inflatedRect.setWidth(inflatedRect.width() / zoomFactor); 472231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block inflatedRect.setHeight(inflatedRect.height() / zoomFactor); 473231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context->translate(inflatedRect.x(), inflatedRect.y()); 474231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context->scale(FloatSize(zoomFactor, zoomFactor)); 475231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context->translate(-inflatedRect.x(), -inflatedRect.y()); 476231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 4775e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 478231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block BEGIN_BLOCK_OBJC_EXCEPTIONS 4798a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block { 4808a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block FocusIndicationFix::ScopedFixer fix; 4818a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block [radioCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()]; 4828a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 483231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [radioCell setControlView:nil]; 484231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block END_BLOCK_OBJC_EXCEPTIONS 485231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 486231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context->restore(); 487231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 488231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 489231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// Buttons 490231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 491231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// Buttons really only constrain height. They respect width. 492231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic const IntSize* buttonSizes() 493231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 494231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block static const IntSize sizes[3] = { IntSize(0, 21), IntSize(0, 18), IntSize(0, 15) }; 495231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return sizes; 496231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 497231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 4985e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#if ENABLE(DATALIST) 4995e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockstatic const IntSize* listButtonSizes() 5005e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 5015e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block static const IntSize sizes[3] = { IntSize(21, 21), IntSize(19, 18), IntSize(17, 16) }; 5025e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return sizes; 5035e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 5045e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#endif 5055e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 506231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic const int* buttonMargins(NSControlSize controlSize) 507231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 508231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block static const int margins[3][4] = 509231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block { 510231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block { 4, 6, 7, 6 }, 511231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block { 4, 5, 6, 5 }, 512231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block { 0, 1, 1, 1 }, 513231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block }; 514231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return margins[controlSize]; 515231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 516231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 5175e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockstatic void setupButtonCell(NSButtonCell *&buttonCell, ControlPart part, ControlStates states, const IntRect& zoomedRect, float zoomFactor) 518231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 519231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (!buttonCell) { 520231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block buttonCell = [[NSButtonCell alloc] init]; 521231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [buttonCell setTitle:nil]; 522231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [buttonCell setButtonType:NSMomentaryPushInButton]; 5235e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block if (states & DefaultState) 5245e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block [buttonCell setKeyEquivalent:@"\r"]; 525231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 526231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 527231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Set the control size based off the rectangle we're painting into. 5285e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block const IntSize* sizes = buttonSizes(); 5295e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#if ENABLE(DATALIST) 5305e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block if (part == ListButtonPart) { 5315e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block [buttonCell setBezelStyle:NSRoundedDisclosureBezelStyle]; 5325e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block sizes = listButtonSizes(); 5335e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block } else 5345e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#endif 535231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (part == SquareButtonPart || zoomedRect.height() > buttonSizes()[NSRegularControlSize].height() * zoomFactor) { 536231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Use the square button 537231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if ([buttonCell bezelStyle] != NSShadowlessSquareBezelStyle) 538231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [buttonCell setBezelStyle:NSShadowlessSquareBezelStyle]; 539231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } else if ([buttonCell bezelStyle] != NSRoundedBezelStyle) 540231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [buttonCell setBezelStyle:NSRoundedBezelStyle]; 541231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 5425e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block setControlSize(buttonCell, sizes, zoomedRect.size(), zoomFactor); 543231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 544231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Update the various states we respond to. 545231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block updateStates(buttonCell, states); 5465e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block} 5475e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 5485e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Blockstatic NSButtonCell *button(ControlPart part, ControlStates states, const IntRect& zoomedRect, float zoomFactor) 5495e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block{ 5505e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block bool isDefault = states & DefaultState; 5515e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block static NSButtonCell *cells[2]; 5525e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block setupButtonCell(cells[isDefault], part, states, zoomedRect, zoomFactor); 5535e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return cells[isDefault]; 554231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 555231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 556231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockstatic void paintButton(ControlPart part, ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) 557231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 558231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block BEGIN_BLOCK_OBJC_EXCEPTIONS 5595e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block 560231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Determine the width and height needed for the control and prepare the cell for painting. 561231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block NSButtonCell *buttonCell = button(part, states, zoomedRect, zoomFactor); 562231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block LocalCurrentGraphicsContext localContext(context); 563231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 564231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block NSControlSize controlSize = [buttonCell controlSize]; 5655e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#if ENABLE(DATALIST) 5665e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block IntSize zoomedSize = (part == ListButtonPart ? listButtonSizes() : buttonSizes())[controlSize]; 5675e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#else 568231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block IntSize zoomedSize = buttonSizes()[controlSize]; 5695e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#endif 570231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever constrain width, so the zoomed width can just be honored. 571231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block zoomedSize.setHeight(zoomedSize.height() * zoomFactor); 572231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block IntRect inflatedRect = zoomedRect; 573231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if ([buttonCell bezelStyle] == NSRoundedBezelStyle) { 574231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Center the button within the available space. 575231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (inflatedRect.height() > zoomedSize.height()) { 576231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block inflatedRect.setY(inflatedRect.y() + (inflatedRect.height() - zoomedSize.height()) / 2); 577231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block inflatedRect.setHeight(zoomedSize.height()); 578231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 579231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 580231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Now inflate it to account for the shadow. 581231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block inflatedRect = inflateRect(inflatedRect, zoomedSize, buttonMargins(controlSize), zoomFactor); 582231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 583231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (zoomFactor != 1.0f) { 584231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block inflatedRect.setWidth(inflatedRect.width() / zoomFactor); 585231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block inflatedRect.setHeight(inflatedRect.height() / zoomFactor); 586231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context->translate(inflatedRect.x(), inflatedRect.y()); 587231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context->scale(FloatSize(zoomFactor, zoomFactor)); 588231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block context->translate(-inflatedRect.x(), -inflatedRect.y()); 589231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 5905e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block } 591231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 5928a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block { 5938a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block FocusIndicationFix::ScopedFixer fix; 5948a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block [buttonCell drawWithFrame:NSRect(inflatedRect) inView:FlippedView()]; 5958a0914b749bbe7da7768e07a7db5c6d4bb09472bSteve Block } 596231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block [buttonCell setControlView:nil]; 597231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 598231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block END_BLOCK_OBJC_EXCEPTIONS 599231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 600231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 601967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch// Stepper 602967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 603967717af5423377c967781471ee106e2bb4e11c8Ben Murdochstatic const IntSize* stepperSizes() 604967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 605967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch static const IntSize sizes[3] = { IntSize(19, 27), IntSize(15, 22), IntSize(13, 15) }; 606967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return sizes; 607967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 608967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 609967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch// We don't use controlSizeForFont() for steppers because the stepper height 610967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch// should be equal to or less than the corresponding text field height, 611967717af5423377c967781471ee106e2bb4e11c8Ben Murdochstatic NSControlSize stepperControlSizeForFont(const Font& font) 612967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 613967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch int fontSize = font.pixelSize(); 614967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (fontSize >= 18) 615967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return NSRegularControlSize; 616967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (fontSize >= 13) 617967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return NSSmallControlSize; 618967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return NSMiniControlSize; 619967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 620967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 621967717af5423377c967781471ee106e2bb4e11c8Ben Murdochstatic void paintStepper(ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView*) 622967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch{ 623967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch // We don't use NSStepperCell because there are no ways to draw an 624967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch // NSStepperCell with the up button highlighted. 625967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 626967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch HIThemeButtonDrawInfo drawInfo; 627967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch drawInfo.version = 0; 628967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch drawInfo.state = convertControlStatesToThemeDrawState(kThemeIncDecButton, states); 629967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch drawInfo.adornment = kThemeAdornmentDefault; 630967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch ControlSize controlSize = controlSizeFromPixelSize(stepperSizes(), zoomedRect.size(), zoomFactor); 631967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (controlSize == NSSmallControlSize) 632967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch drawInfo.kind = kThemeIncDecButtonSmall; 633967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch else if (controlSize == NSMiniControlSize) 634967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch drawInfo.kind = kThemeIncDecButtonMini; 635967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch else 636967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch drawInfo.kind = kThemeIncDecButton; 637967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 638967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch IntRect rect(zoomedRect); 639967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch context->save(); 640967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (zoomFactor != 1.0f) { 641967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch rect.setWidth(rect.width() / zoomFactor); 642967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch rect.setHeight(rect.height() / zoomFactor); 643967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch context->translate(rect.x(), rect.y()); 644967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch context->scale(FloatSize(zoomFactor, zoomFactor)); 645967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch context->translate(-rect.x(), -rect.y()); 646967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 647967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CGRect bounds(rect); 648967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch // Adjust 'bounds' so that HIThemeDrawButton(bounds,...) draws exactly on 'rect'. 649967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch CGRect backgroundBounds; 650967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch HIThemeGetButtonBackgroundBounds(&bounds, &drawInfo, &backgroundBounds); 651967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (bounds.origin.x != backgroundBounds.origin.x) 652967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch bounds.origin.x += bounds.origin.x - backgroundBounds.origin.x; 653967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (bounds.origin.y != backgroundBounds.origin.y) 654967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch bounds.origin.y += bounds.origin.y - backgroundBounds.origin.y; 655967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch HIThemeDrawButton(&bounds, &drawInfo, context->platformContext(), kHIThemeOrientationNormal, 0); 656967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch context->restore(); 657967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch} 658967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch 659231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block// Theme overrides 660231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 661231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockint ThemeChromiumMac::baselinePositionAdjustment(ControlPart part) const 662231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 663231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if (part == CheckboxPart || part == RadioPart) 664231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return -2; 665231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return Theme::baselinePositionAdjustment(part); 666231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 667231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 668231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockFontDescription ThemeChromiumMac::controlFont(ControlPart part, const Font& font, float zoomFactor) const 669231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 670231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block switch (part) { 671231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case PushButtonPart: { 672231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block FontDescription fontDescription; 673231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block fontDescription.setIsAbsoluteSize(true); 674231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block fontDescription.setGenericFamily(FontDescription::SerifFamily); 675231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 676231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block NSFont* nsFont = [NSFont systemFontOfSize:[NSFont systemFontSizeForControlSize:controlSizeForFont(font)]]; 677231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block fontDescription.firstFamily().setFamily([nsFont familyName]); 678231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block fontDescription.setComputedSize([nsFont pointSize] * zoomFactor); 679231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block fontDescription.setSpecifiedSize([nsFont pointSize] * zoomFactor); 680231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return fontDescription; 681231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 682231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block default: 683231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return Theme::controlFont(part, font, zoomFactor); 684231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 685231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 686231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 687231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockLengthSize ThemeChromiumMac::controlSize(ControlPart part, const Font& font, const LengthSize& zoomedSize, float zoomFactor) const 688231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 689231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block switch (part) { 690231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case CheckboxPart: 691231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return checkboxSize(font, zoomedSize, zoomFactor); 692231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case RadioPart: 693231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return radioSize(font, zoomedSize, zoomFactor); 694231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case PushButtonPart: 695231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Height is reset to auto so that specified heights can be ignored. 696231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return sizeFromFont(font, LengthSize(zoomedSize.width(), Length()), zoomFactor, buttonSizes()); 6975e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#if ENABLE(DATALIST) 6985e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block case ListButtonPart: 6995e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block return sizeFromFont(font, LengthSize(zoomedSize.width(), Length()), zoomFactor, listButtonSizes()); 7005e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block#endif 701967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch case InnerSpinButtonPart: 702967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch // We don't use inner spin buttons on Mac. 703967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return LengthSize(Length(Fixed), Length(Fixed)); 704967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch case OuterSpinButtonPart: 705967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch if (!zoomedSize.width().isIntrinsicOrAuto() && !zoomedSize.height().isIntrinsicOrAuto()) 706967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return zoomedSize; 707967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return sizeFromNSControlSize(stepperControlSizeForFont(font), zoomedSize, zoomFactor, stepperSizes()); 708231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block default: 709231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return zoomedSize; 710231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 711231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 712231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 713231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockLengthSize ThemeChromiumMac::minimumControlSize(ControlPart part, const Font& font, float zoomFactor) const 714231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 715231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block switch (part) { 716231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case SquareButtonPart: 717231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case DefaultButtonPart: 718231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case ButtonPart: 7195e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block case ListButtonPart: 720231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return LengthSize(Length(0, Fixed), Length(static_cast<int>(15 * zoomFactor), Fixed)); 721967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch case InnerSpinButtonPart: 722967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch // We don't use inner spin buttons on Mac. 723967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return LengthSize(Length(Fixed), Length(Fixed)); 724967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch case OuterSpinButtonPart: { 725967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch IntSize base = stepperSizes()[NSMiniControlSize]; 726967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch return LengthSize(Length(static_cast<int>(base.width() * zoomFactor), Fixed), 727967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch Length(static_cast<int>(base.height() * zoomFactor), Fixed)); 728967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 729231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block default: 730231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return Theme::minimumControlSize(part, font, zoomFactor); 731231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 732231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 733231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 734231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockLengthBox ThemeChromiumMac::controlBorder(ControlPart part, const Font& font, const LengthBox& zoomedBox, float zoomFactor) const 735231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 736231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block switch (part) { 737231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case SquareButtonPart: 738231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case DefaultButtonPart: 739231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case ButtonPart: 7405e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block case ListButtonPart: 741231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return LengthBox(0, zoomedBox.right().value(), 0, zoomedBox.left().value()); 742231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block default: 743231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return Theme::controlBorder(part, font, zoomedBox, zoomFactor); 744231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 745231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 746231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 747231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve BlockLengthBox ThemeChromiumMac::controlPadding(ControlPart part, const Font& font, const LengthBox& zoomedBox, float zoomFactor) const 748231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 749231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block switch (part) { 750231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case PushButtonPart: { 751231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // Just use 8px. AppKit wants to use 11px for mini buttons, but that padding is just too large 752231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // for real-world Web sites (creating a huge necessary minimum width for buttons whose space is 753231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // by definition constrained, since we select mini only for small cramped environments. 754231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // This also guarantees the HTML <button> will match our rendering by default, since we're using a consistent 755231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // padding. 756231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block const int padding = 8 * zoomFactor; 757231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return LengthBox(0, padding, 0, padding); 758231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 759231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block default: 760231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block return Theme::controlPadding(part, font, zoomedBox, zoomFactor); 761231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 762231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 763231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 764231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid ThemeChromiumMac::inflateControlPaintRect(ControlPart part, ControlStates states, IntRect& zoomedRect, float zoomFactor) const 765231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 766231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block BEGIN_BLOCK_OBJC_EXCEPTIONS 767231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block switch (part) { 768231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case CheckboxPart: { 769231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // We inflate the rect as needed to account for padding included in the cell to accommodate the checkbox 770231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // shadow" and the check. We don't consider this part of the bounds of the control in WebKit. 771231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block NSCell *cell = checkbox(states, zoomedRect, zoomFactor); 772231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block NSControlSize controlSize = [cell controlSize]; 773231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block IntSize zoomedSize = checkboxSizes()[controlSize]; 774231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block zoomedSize.setHeight(zoomedSize.height() * zoomFactor); 775231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block zoomedSize.setWidth(zoomedSize.width() * zoomFactor); 776231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block zoomedRect = inflateRect(zoomedRect, zoomedSize, checkboxMargins(controlSize), zoomFactor); 777231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block break; 778231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 779231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case RadioPart: { 780231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // We inflate the rect as needed to account for padding included in the cell to accommodate the radio button 781231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // shadow". We don't consider this part of the bounds of the control in WebKit. 782231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block NSCell *cell = radio(states, zoomedRect, zoomFactor); 783231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block NSControlSize controlSize = [cell controlSize]; 784231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block IntSize zoomedSize = radioSizes()[controlSize]; 785231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block zoomedSize.setHeight(zoomedSize.height() * zoomFactor); 786231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block zoomedSize.setWidth(zoomedSize.width() * zoomFactor); 787231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block zoomedRect = inflateRect(zoomedRect, zoomedSize, radioMargins(controlSize), zoomFactor); 788231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block break; 789231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 790231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case PushButtonPart: 791231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case DefaultButtonPart: 792231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case ButtonPart: { 793231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block NSButtonCell *cell = button(part, states, zoomedRect, zoomFactor); 794231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block NSControlSize controlSize = [cell controlSize]; 795231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 796231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block // We inflate the rect as needed to account for the Aqua button's shadow. 797231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block if ([cell bezelStyle] == NSRoundedBezelStyle) { 798231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block IntSize zoomedSize = buttonSizes()[controlSize]; 799231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block zoomedSize.setHeight(zoomedSize.height() * zoomFactor); 800231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block zoomedSize.setWidth(zoomedRect.width()); // Buttons don't ever constrain width, so the zoomed width can just be honored. 801231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block zoomedRect = inflateRect(zoomedRect, zoomedSize, buttonMargins(controlSize), zoomFactor); 802231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 803231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block break; 804231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 805967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch case OuterSpinButtonPart: { 806967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch static const int stepperMargin[4] = { 0, 0, 0, 0 }; 807967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch ControlSize controlSize = controlSizeFromPixelSize(stepperSizes(), zoomedRect.size(), zoomFactor); 808967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch IntSize zoomedSize = stepperSizes()[controlSize]; 809967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch zoomedSize.setHeight(zoomedSize.height() * zoomFactor); 810967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch zoomedSize.setWidth(zoomedSize.width() * zoomFactor); 811967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch zoomedRect = inflateRect(zoomedRect, zoomedSize, stepperMargin, zoomFactor); 812967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch break; 813967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch } 814231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block default: 815231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block break; 816231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 817231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block END_BLOCK_OBJC_EXCEPTIONS 818231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 819231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 820231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Blockvoid ThemeChromiumMac::paint(ControlPart part, ControlStates states, GraphicsContext* context, const IntRect& zoomedRect, float zoomFactor, ScrollView* scrollView) const 821231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block{ 822231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block switch (part) { 823231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case CheckboxPart: 824231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block paintCheckbox(states, context, zoomedRect, zoomFactor, scrollView); 825231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block break; 826231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case RadioPart: 827231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block paintRadio(states, context, zoomedRect, zoomFactor, scrollView); 828231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block break; 829231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case PushButtonPart: 830231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case DefaultButtonPart: 831231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case ButtonPart: 832231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block case SquareButtonPart: 8335e2bc6953fe6923165b8a5d7679939693a1d58d6Steve Block case ListButtonPart: 834231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block paintButton(part, states, context, zoomedRect, zoomFactor, scrollView); 835231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block break; 836967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch case OuterSpinButtonPart: 837967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch paintStepper(states, context, zoomedRect, zoomFactor, scrollView); 838967717af5423377c967781471ee106e2bb4e11c8Ben Murdoch break; 839231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block default: 840231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block break; 841231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block } 842231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 843231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block 844231d4e3152a9c27a73b6ac7badbe6be673aa3ddfSteve Block} 845