OLD | NEW |
(Empty) | |
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 #include "content/shell/renderer/test_runner/WebTestThemeEngineMac.h" |
| 6 |
| 7 #import <AppKit/NSAffineTransform.h> |
| 8 #import <AppKit/NSGraphicsContext.h> |
| 9 #import <AppKit/NSScroller.h> |
| 10 #import <AppKit/NSWindow.h> |
| 11 #include <Carbon/Carbon.h> |
| 12 #include "skia/ext/skia_utils_mac.h" |
| 13 #include "third_party/WebKit/public/platform/WebCanvas.h" |
| 14 #include "third_party/WebKit/public/platform/WebRect.h" |
| 15 |
| 16 using blink::WebCanvas; |
| 17 using blink::WebRect; |
| 18 using blink::WebThemeEngine; |
| 19 |
| 20 // We can't directly tell the NSScroller to draw itself as active or inactive, |
| 21 // instead we have to make it a child of an (in)active window. This class lets |
| 22 // us fake that parent window. |
| 23 @interface FakeActiveWindow : NSWindow { |
| 24 @private |
| 25 BOOL hasActiveControls; |
| 26 } |
| 27 + (NSWindow*)alwaysActiveWindow; |
| 28 + (NSWindow*)alwaysInactiveWindow; |
| 29 - (id)initWithActiveControls:(BOOL)_hasActiveControls; |
| 30 - (BOOL)_hasActiveControls; |
| 31 @end |
| 32 |
| 33 @implementation FakeActiveWindow |
| 34 |
| 35 static NSWindow* alwaysActiveWindow = nil; |
| 36 static NSWindow* alwaysInactiveWindow = nil; |
| 37 |
| 38 + (NSWindow*)alwaysActiveWindow |
| 39 { |
| 40 if (alwaysActiveWindow == nil) |
| 41 alwaysActiveWindow = [[self alloc] initWithActiveControls:YES]; |
| 42 return alwaysActiveWindow; |
| 43 } |
| 44 |
| 45 + (NSWindow*)alwaysInactiveWindow |
| 46 { |
| 47 if (alwaysInactiveWindow == nil) |
| 48 alwaysInactiveWindow = [[self alloc] initWithActiveControls:NO]; |
| 49 return alwaysInactiveWindow; |
| 50 } |
| 51 |
| 52 - (id)initWithActiveControls:(BOOL)_hasActiveControls |
| 53 { |
| 54 self = [super init]; |
| 55 hasActiveControls = _hasActiveControls; |
| 56 return self; |
| 57 } |
| 58 |
| 59 - (BOOL)_hasActiveControls |
| 60 { |
| 61 return hasActiveControls; |
| 62 } |
| 63 |
| 64 @end |
| 65 |
| 66 namespace WebTestRunner { |
| 67 |
| 68 namespace { |
| 69 |
| 70 ThemeTrackEnableState stateToHIEnableState(WebThemeEngine::State state) |
| 71 { |
| 72 switch (state) { |
| 73 case WebThemeEngine::StateDisabled: |
| 74 return kThemeTrackDisabled; |
| 75 case WebThemeEngine::StateInactive: |
| 76 return kThemeTrackInactive; |
| 77 default: |
| 78 return kThemeTrackActive; |
| 79 } |
| 80 } |
| 81 |
| 82 } |
| 83 |
| 84 void WebTestThemeEngineMac::paintScrollbarThumb( |
| 85 WebCanvas* canvas, |
| 86 WebThemeEngine::State state, |
| 87 WebThemeEngine::Size size, |
| 88 const WebRect& rect, |
| 89 const WebThemeEngine::ScrollbarInfo& scrollbarInfo) |
| 90 { |
| 91 // To match the Mac port, we still use HITheme for inner scrollbars. |
| 92 if (scrollbarInfo.parent == WebThemeEngine::ScrollbarParentRenderLayer) |
| 93 paintHIThemeScrollbarThumb(canvas, state, size, rect, scrollbarInfo); |
| 94 else |
| 95 paintNSScrollerScrollbarThumb(canvas, state, size, rect, scrollbarInfo); |
| 96 } |
| 97 |
| 98 // Duplicated from webkit/glue/webthemeengine_impl_mac.cc in the downstream |
| 99 // Chromium WebThemeEngine implementation. |
| 100 void WebTestThemeEngineMac::paintHIThemeScrollbarThumb( |
| 101 WebCanvas* canvas, |
| 102 WebThemeEngine::State state, |
| 103 WebThemeEngine::Size size, |
| 104 const WebRect& rect, |
| 105 const WebThemeEngine::ScrollbarInfo& scrollbarInfo) |
| 106 { |
| 107 HIThemeTrackDrawInfo trackInfo; |
| 108 trackInfo.version = 0; |
| 109 trackInfo.kind = size == WebThemeEngine::SizeRegular ? kThemeMediumScrollBar
: kThemeSmallScrollBar; |
| 110 trackInfo.bounds = CGRectMake(rect.x, rect.y, rect.width, rect.height); |
| 111 trackInfo.min = 0; |
| 112 trackInfo.max = scrollbarInfo.maxValue; |
| 113 trackInfo.value = scrollbarInfo.currentValue; |
| 114 trackInfo.trackInfo.scrollbar.viewsize = scrollbarInfo.visibleSize; |
| 115 trackInfo.attributes = 0; |
| 116 if (scrollbarInfo.orientation == WebThemeEngine::ScrollbarOrientationHorizon
tal) |
| 117 trackInfo.attributes |= kThemeTrackHorizontal; |
| 118 |
| 119 trackInfo.enableState = stateToHIEnableState(state); |
| 120 |
| 121 trackInfo.trackInfo.scrollbar.pressState = |
| 122 state == WebThemeEngine::StatePressed ? kThemeThumbPressed : 0; |
| 123 trackInfo.attributes |= (kThemeTrackShowThumb | kThemeTrackHideTrack); |
| 124 gfx::SkiaBitLocker bitLocker(canvas); |
| 125 CGContextRef cgContext = bitLocker.cgContext(); |
| 126 HIThemeDrawTrack(&trackInfo, 0, cgContext, kHIThemeOrientationNormal); |
| 127 } |
| 128 |
| 129 void WebTestThemeEngineMac::paintNSScrollerScrollbarThumb( |
| 130 WebCanvas* canvas, |
| 131 WebThemeEngine::State state, |
| 132 WebThemeEngine::Size size, |
| 133 const WebRect& rect, |
| 134 const WebThemeEngine::ScrollbarInfo& scrollbarInfo) |
| 135 { |
| 136 [NSGraphicsContext saveGraphicsState]; |
| 137 NSScroller* scroller = [[NSScroller alloc] initWithFrame:NSMakeRect(rect.x,
rect.y, rect.width, rect.height)]; |
| 138 [scroller setEnabled:state != WebThemeEngine::StateDisabled]; |
| 139 if (state == WebThemeEngine::StateInactive) |
| 140 [[[FakeActiveWindow alwaysInactiveWindow] contentView] addSubview:scroll
er]; |
| 141 else |
| 142 [[[FakeActiveWindow alwaysActiveWindow] contentView] addSubview:scroller
]; |
| 143 |
| 144 [scroller setControlSize:size == WebThemeEngine::SizeRegular ? NSRegularCont
rolSize : NSSmallControlSize]; |
| 145 |
| 146 double value = double(scrollbarInfo.currentValue) / double(scrollbarInfo.max
Value); |
| 147 [scroller setDoubleValue: value]; |
| 148 |
| 149 float knobProportion = float(scrollbarInfo.visibleSize) / float(scrollbarInf
o.totalSize); |
| 150 [scroller setKnobProportion: knobProportion]; |
| 151 |
| 152 gfx::SkiaBitLocker bitLocker(canvas); |
| 153 CGContextRef cgContext = bitLocker.cgContext(); |
| 154 NSGraphicsContext* nsGraphicsContext = [NSGraphicsContext graphicsContextWit
hGraphicsPort:cgContext flipped:YES]; |
| 155 [NSGraphicsContext setCurrentContext:nsGraphicsContext]; |
| 156 |
| 157 // Despite passing in frameRect() to the scroller, it always draws at (0, 0)
. |
| 158 // Force it to draw in the right location by translating the whole graphics |
| 159 // context. |
| 160 CGContextSaveGState(cgContext); |
| 161 NSAffineTransform *transform = [NSAffineTransform transform]; |
| 162 [transform translateXBy:rect.x yBy:rect.y]; |
| 163 [transform concat]; |
| 164 |
| 165 [scroller drawKnob]; |
| 166 CGContextRestoreGState(cgContext); |
| 167 |
| 168 [scroller release]; |
| 169 |
| 170 [NSGraphicsContext restoreGraphicsState]; |
| 171 } |
| 172 |
| 173 } |
OLD | NEW |