1/* 2 * Copyright (C) 2013 Google Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google Inc. nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31#include "config.h" 32#include "platform/scroll/ScrollbarThemeMacOverlayAPI.h" 33 34#include "platform/graphics/GraphicsContext.h" 35#include "platform/graphics/GraphicsContextStateSaver.h" 36#include "platform/mac/LocalCurrentGraphicsContext.h" 37#include "platform/mac/NSScrollerImpDetails.h" 38#include "platform/scroll/ScrollbarThemeClient.h" 39 40namespace WebCore { 41 42typedef HashMap<ScrollbarThemeClient*, RetainPtr<ScrollbarPainter> > ScrollbarPainterMap; 43 44static ScrollbarPainterMap* scrollbarPainterMap() 45{ 46 static ScrollbarPainterMap* map = new ScrollbarPainterMap; 47 return map; 48} 49 50static bool supportsExpandedScrollbars() 51{ 52 // FIXME: This is temporary until all platforms that support ScrollbarPainter support this part of the API. 53 static bool globalSupportsExpandedScrollbars = [NSClassFromString(@"NSScrollerImp") instancesRespondToSelector:@selector(setExpanded:)]; 54 return globalSupportsExpandedScrollbars; 55} 56 57void ScrollbarThemeMacOverlayAPI::registerScrollbar(ScrollbarThemeClient* scrollbar) 58{ 59 ScrollbarThemeMacCommon::registerScrollbar(scrollbar); 60 61 bool isHorizontal = scrollbar->orientation() == HorizontalScrollbar; 62 ScrollbarPainter scrollbarPainter = [NSClassFromString(@"NSScrollerImp") scrollerImpWithStyle:recommendedScrollerStyle() controlSize:(NSControlSize)scrollbar->controlSize() horizontal:isHorizontal replacingScrollerImp:nil]; 63 scrollbarPainterMap()->add(scrollbar, scrollbarPainter); 64 updateEnabledState(scrollbar); 65 updateScrollbarOverlayStyle(scrollbar); 66} 67 68void ScrollbarThemeMacOverlayAPI::unregisterScrollbar(ScrollbarThemeClient* scrollbar) 69{ 70 scrollbarPainterMap()->remove(scrollbar); 71 72 ScrollbarThemeMacCommon::unregisterScrollbar(scrollbar); 73} 74 75void ScrollbarThemeMacOverlayAPI::setNewPainterForScrollbar(ScrollbarThemeClient* scrollbar, ScrollbarPainter newPainter) 76{ 77 scrollbarPainterMap()->set(scrollbar, newPainter); 78 updateEnabledState(scrollbar); 79 updateScrollbarOverlayStyle(scrollbar); 80} 81 82ScrollbarPainter ScrollbarThemeMacOverlayAPI::painterForScrollbar(ScrollbarThemeClient* scrollbar) 83{ 84 return scrollbarPainterMap()->get(scrollbar).get(); 85} 86 87void ScrollbarThemeMacOverlayAPI::paintTrackBackground(GraphicsContext* context, ScrollbarThemeClient* scrollbar, const IntRect& rect) { 88 ASSERT(isOverlayAPIAvailable()); 89 90 GraphicsContextStateSaver stateSaver(*context); 91 context->translate(rect.x(), rect.y()); 92 LocalCurrentGraphicsContext localContext(context); 93 94 CGRect frameRect = scrollbar->frameRect(); 95 ScrollbarPainter scrollbarPainter = painterForScrollbar(scrollbar); 96 [scrollbarPainter setEnabled:scrollbar->enabled()]; 97 [scrollbarPainter setBoundsSize: NSSizeFromCGSize(frameRect.size)]; 98 99 NSRect trackRect = NSMakeRect(0, 0, frameRect.size.width, frameRect.size.height); 100 [scrollbarPainter drawKnobSlotInRect:trackRect highlight:NO]; 101} 102 103void ScrollbarThemeMacOverlayAPI::paintThumb(GraphicsContext* context, ScrollbarThemeClient* scrollbar, const IntRect& rect) { 104 ASSERT(isOverlayAPIAvailable()); 105 106 GraphicsContextStateSaver stateSaver(*context); 107 context->translate(rect.x(), rect.y()); 108 LocalCurrentGraphicsContext localContext(context); 109 110 ScrollbarPainter scrollbarPainter = painterForScrollbar(scrollbar); 111 [scrollbarPainter setEnabled:scrollbar->enabled()]; 112 [scrollbarPainter setBoundsSize:NSSizeFromCGSize(rect.size())]; 113 [scrollbarPainter setDoubleValue:0]; 114 [scrollbarPainter setKnobProportion:1]; 115 if (scrollbar->enabled()) 116 [scrollbarPainter drawKnob]; 117 118 // If this state is not set, then moving the cursor over the scrollbar area will only cause the 119 // scrollbar to engorge when moved over the top of the scrollbar area. 120 [scrollbarPainter setBoundsSize: NSSizeFromCGSize(scrollbar->frameRect().size())]; 121} 122 123int ScrollbarThemeMacOverlayAPI::scrollbarThickness(ScrollbarControlSize controlSize) 124{ 125 ScrollbarPainter scrollbarPainter = [NSClassFromString(@"NSScrollerImp") scrollerImpWithStyle:recommendedScrollerStyle() controlSize:controlSize horizontal:NO replacingScrollerImp:nil]; 126 if (supportsExpandedScrollbars()) 127 [scrollbarPainter setExpanded:YES]; 128 return [scrollbarPainter trackBoxWidth]; 129} 130 131bool ScrollbarThemeMacOverlayAPI::usesOverlayScrollbars() const 132{ 133 return recommendedScrollerStyle() == NSScrollerStyleOverlay; 134} 135 136void ScrollbarThemeMacOverlayAPI::updateScrollbarOverlayStyle(ScrollbarThemeClient* scrollbar) 137{ 138 ScrollbarPainter painter = painterForScrollbar(scrollbar); 139 switch (scrollbar->scrollbarOverlayStyle()) { 140 case ScrollbarOverlayStyleDefault: 141 [painter setKnobStyle:NSScrollerKnobStyleDefault]; 142 break; 143 case ScrollbarOverlayStyleDark: 144 [painter setKnobStyle:NSScrollerKnobStyleDark]; 145 break; 146 case ScrollbarOverlayStyleLight: 147 [painter setKnobStyle:NSScrollerKnobStyleLight]; 148 break; 149 } 150} 151 152ScrollbarButtonsPlacement ScrollbarThemeMacOverlayAPI::buttonsPlacement() const 153{ 154 return ScrollbarButtonsNone; 155} 156 157bool ScrollbarThemeMacOverlayAPI::hasThumb(ScrollbarThemeClient* scrollbar) 158{ 159 ScrollbarPainter painter = painterForScrollbar(scrollbar); 160 int minLengthForThumb = [painter knobMinLength] + [painter trackOverlapEndInset] + [painter knobOverlapEndInset] 161 + 2 * ([painter trackEndInset] + [painter knobEndInset]); 162 return scrollbar->enabled() && (scrollbar->orientation() == HorizontalScrollbar ? 163 scrollbar->width() : 164 scrollbar->height()) >= minLengthForThumb; 165} 166 167IntRect ScrollbarThemeMacOverlayAPI::backButtonRect(ScrollbarThemeClient* scrollbar, ScrollbarPart part, bool painting) 168{ 169 ASSERT(buttonsPlacement() == ScrollbarButtonsNone); 170 return IntRect(); 171} 172 173IntRect ScrollbarThemeMacOverlayAPI::forwardButtonRect(ScrollbarThemeClient* scrollbar, ScrollbarPart part, bool painting) 174{ 175 ASSERT(buttonsPlacement() == ScrollbarButtonsNone); 176 return IntRect(); 177} 178 179IntRect ScrollbarThemeMacOverlayAPI::trackRect(ScrollbarThemeClient* scrollbar, bool painting) 180{ 181 ASSERT(!hasButtons(scrollbar)); 182 return scrollbar->frameRect(); 183} 184 185int ScrollbarThemeMacOverlayAPI::minimumThumbLength(ScrollbarThemeClient* scrollbar) 186{ 187 return [painterForScrollbar(scrollbar) knobMinLength]; 188} 189 190void ScrollbarThemeMacOverlayAPI::updateEnabledState(ScrollbarThemeClient* scrollbar) 191{ 192 [painterForScrollbar(scrollbar) setEnabled:scrollbar->enabled()]; 193} 194 195} // namespace WebCore 196