| /* |
| * Copyright (C) 2007 Apple Inc. All rights reserved. |
| * |
| * Redistribution and use in source and binary forms, with or without |
| * modification, are permitted provided that the following conditions |
| * are met: |
| * 1. Redistributions of source code must retain the above copyright |
| * notice, this list of conditions and the following disclaimer. |
| * 2. Redistributions in binary form must reproduce the above copyright |
| * notice, this list of conditions and the following disclaimer in the |
| * documentation and/or other materials provided with the distribution. |
| * |
| * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
| * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
| * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
| * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
| * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
| * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
| * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
| * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
| * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| */ |
| |
| #include "config.h" |
| |
| #ifdef USE_SAFARI_THEME |
| |
| #include "PlatformScrollBar.h" |
| |
| #include "EventHandler.h" |
| #include "FrameView.h" |
| #include "Frame.h" |
| #include "GraphicsContext.h" |
| #include "IntRect.h" |
| #include "PlatformMouseEvent.h" |
| #include "SoftLinking.h" |
| |
| #include <CoreGraphics/CoreGraphics.h> |
| #include <SafariTheme/SafariTheme.h> |
| |
| // FIXME: There are repainting problems due to Aqua scroll bar buttons' visual overflow. |
| |
| using namespace std; |
| |
| namespace WebCore { |
| |
| using namespace SafariTheme; |
| |
| // FIXME: We should get these numbers from SafariTheme |
| static int cHorizontalWidth[] = { 15, 11 }; |
| static int cHorizontalHeight[] = { 15, 11 }; |
| static int cVerticalWidth[] = { 15, 11 }; |
| static int cVerticalHeight[] = { 15, 11 }; |
| static int cRealButtonLength[] = { 28, 21 }; |
| static int cButtonInset[] = { 14, 11 }; |
| static int cButtonHitInset[] = { 3, 2 }; |
| // cRealButtonLength - cButtonInset |
| static int cButtonLength[] = { 14, 10 }; |
| static int cThumbWidth[] = { 15, 11 }; |
| static int cThumbHeight[] = { 15, 11 }; |
| static int cThumbMinLength[] = { 26, 20 }; |
| |
| #if !defined(NDEBUG) && defined(USE_DEBUG_SAFARI_THEME) |
| SOFT_LINK_DEBUG_LIBRARY(SafariTheme) |
| #else |
| SOFT_LINK_LIBRARY(SafariTheme) |
| #endif |
| |
| SOFT_LINK(SafariTheme, paintThemePart, void, __stdcall, (ThemePart part, CGContextRef context, const CGRect& rect, NSControlSize size, ThemeControlState state), (part, context, rect, size, state)) |
| |
| const double cInitialTimerDelay = 0.25; |
| const double cNormalTimerDelay = 0.05; |
| |
| PlatformScrollbar::PlatformScrollbar(ScrollbarClient* client, ScrollbarOrientation orientation, ScrollbarControlSize size) |
| : Scrollbar(client, orientation, size), m_hoveredPart(NoPart), m_pressedPart(NoPart), m_pressedPos(0), |
| m_scrollTimer(this, &PlatformScrollbar::autoscrollTimerFired), |
| m_overlapsResizer(false) |
| { |
| // Obtain the correct scrollbar sizes from the system. |
| if (!cHorizontalWidth) { |
| // FIXME: Get metics from SafariTheme |
| } |
| |
| if (orientation == VerticalScrollbar) |
| setFrameGeometry(IntRect(0, 0, cVerticalWidth[controlSize()], cVerticalHeight[controlSize()])); |
| else |
| setFrameGeometry(IntRect(0, 0, cHorizontalWidth[controlSize()], cHorizontalHeight[controlSize()])); |
| } |
| |
| PlatformScrollbar::~PlatformScrollbar() |
| { |
| stopTimerIfNeeded(); |
| } |
| |
| void PlatformScrollbar::updateThumbPosition() |
| { |
| invalidateTrack(); |
| } |
| |
| void PlatformScrollbar::updateThumbProportion() |
| { |
| invalidateTrack(); |
| } |
| |
| static IntRect trackRepaintRect(const IntRect& trackRect, ScrollbarOrientation orientation, ScrollbarControlSize controlSize) |
| { |
| IntRect paintRect(trackRect); |
| if (orientation == HorizontalScrollbar) |
| paintRect.inflateX(cButtonLength[controlSize]); |
| else |
| paintRect.inflateY(cButtonLength[controlSize]); |
| |
| return paintRect; |
| } |
| |
| static IntRect buttonRepaintRect(const IntRect& buttonRect, ScrollbarOrientation orientation, ScrollbarControlSize controlSize, bool start) |
| { |
| IntRect paintRect(buttonRect); |
| if (orientation == HorizontalScrollbar) { |
| paintRect.setWidth(cRealButtonLength[controlSize]); |
| if (!start) |
| paintRect.setX(buttonRect.x() - (cRealButtonLength[controlSize] - buttonRect.width())); |
| } else { |
| paintRect.setHeight(cRealButtonLength[controlSize]); |
| if (!start) |
| paintRect.setY(buttonRect.y() - (cRealButtonLength[controlSize] - buttonRect.height())); |
| } |
| |
| return paintRect; |
| } |
| |
| void PlatformScrollbar::invalidateTrack() |
| { |
| IntRect rect = trackRepaintRect(trackRect(), m_orientation, controlSize()); |
| rect.move(-x(), -y()); |
| invalidateRect(rect); |
| } |
| |
| void PlatformScrollbar::invalidatePart(ScrollbarPart part) |
| { |
| if (part == NoPart) |
| return; |
| |
| IntRect result; |
| switch (part) { |
| case BackButtonPart: |
| result = buttonRepaintRect(backButtonRect(), m_orientation, controlSize(), true); |
| break; |
| case ForwardButtonPart: |
| result = buttonRepaintRect(forwardButtonRect(), m_orientation, controlSize(), false); |
| break; |
| default: { |
| IntRect beforeThumbRect, thumbRect, afterThumbRect; |
| splitTrack(trackRect(), beforeThumbRect, thumbRect, afterThumbRect); |
| if (part == BackTrackPart) |
| result = beforeThumbRect; |
| else if (part == ForwardTrackPart) |
| result = afterThumbRect; |
| else |
| result = thumbRect; |
| } |
| } |
| result.move(-x(), -y()); |
| invalidateRect(result); |
| } |
| |
| int PlatformScrollbar::width() const |
| { |
| return Widget::width(); |
| } |
| |
| int PlatformScrollbar::height() const |
| { |
| return Widget::height(); |
| } |
| |
| void PlatformScrollbar::setRect(const IntRect& rect) |
| { |
| // Get our window resizer rect and see if we overlap. Adjust to avoid the overlap |
| // if necessary. |
| IntRect adjustedRect(rect); |
| if (parent() && parent()->isFrameView()) { |
| bool overlapsResizer = false; |
| FrameView* view = static_cast<FrameView*>(parent()); |
| IntRect resizerRect = view->windowResizerRect(); |
| resizerRect.setLocation(view->convertFromContainingWindow(resizerRect.location())); |
| if (rect.intersects(resizerRect)) { |
| if (orientation() == HorizontalScrollbar) { |
| int overlap = rect.right() - resizerRect.x(); |
| if (overlap > 0 && resizerRect.right() >= rect.right()) { |
| adjustedRect.setWidth(rect.width() - overlap); |
| overlapsResizer = true; |
| } |
| } else { |
| int overlap = rect.bottom() - resizerRect.y(); |
| if (overlap > 0 && resizerRect.bottom() >= rect.bottom()) { |
| adjustedRect.setHeight(rect.height() - overlap); |
| overlapsResizer = true; |
| } |
| } |
| } |
| |
| if (overlapsResizer != m_overlapsResizer) { |
| m_overlapsResizer = overlapsResizer; |
| view->adjustOverlappingScrollbarCount(m_overlapsResizer ? 1 : -1); |
| } |
| } |
| |
| setFrameGeometry(adjustedRect); |
| } |
| |
| void PlatformScrollbar::setParent(ScrollView* parentView) |
| { |
| if (!parentView && m_overlapsResizer && parent() && parent()->isFrameView()) |
| static_cast<FrameView*>(parent())->adjustOverlappingScrollbarCount(-1); |
| Widget::setParent(parentView); |
| } |
| |
| void PlatformScrollbar::setEnabled(bool enabled) |
| { |
| if (enabled != isEnabled()) { |
| Widget::setEnabled(enabled); |
| invalidate(); |
| } |
| } |
| |
| void PlatformScrollbar::paint(GraphicsContext* graphicsContext, const IntRect& damageRect) |
| { |
| if (graphicsContext->updatingControlTints()) { |
| invalidate(); |
| return; |
| } |
| |
| if (graphicsContext->paintingDisabled()) |
| return; |
| |
| // Don't paint anything if the scrollbar doesn't intersect the damage rect. |
| if (!frameGeometry().intersects(damageRect)) |
| return; |
| |
| IntRect track = trackRect(); |
| paintTrack(graphicsContext, track, true, damageRect); |
| |
| if (hasButtons()) { |
| paintButton(graphicsContext, backButtonRect(), true, damageRect); |
| paintButton(graphicsContext, forwardButtonRect(), false, damageRect); |
| } |
| |
| if (hasThumb() && damageRect.intersects(track)) { |
| IntRect startTrackRect, thumbRect, endTrackRect; |
| splitTrack(track, startTrackRect, thumbRect, endTrackRect); |
| paintThumb(graphicsContext, thumbRect, damageRect); |
| } |
| } |
| |
| bool PlatformScrollbar::hasButtons() const |
| { |
| return isEnabled() && (m_orientation == HorizontalScrollbar ? width() : height()) >= 2 * (cRealButtonLength[controlSize()] - cButtonHitInset[controlSize()]); |
| } |
| |
| bool PlatformScrollbar::hasThumb() const |
| { |
| return isEnabled() && (m_orientation == HorizontalScrollbar ? width() : height()) >= 2 * cButtonInset[controlSize()] + cThumbMinLength[controlSize()] + 1; |
| } |
| |
| IntRect PlatformScrollbar::backButtonRect() const |
| { |
| // Our desired rect is essentially 17x17. |
| |
| // Our actual rect will shrink to half the available space when |
| // we have < 34 pixels left. This allows the scrollbar |
| // to scale down and function even at tiny sizes. |
| if (m_orientation == HorizontalScrollbar) |
| return IntRect(x(), y(), cButtonLength[controlSize()], cHorizontalHeight[controlSize()]); |
| return IntRect(x(), y(), cVerticalWidth[controlSize()], cButtonLength[controlSize()]); |
| } |
| |
| IntRect PlatformScrollbar::forwardButtonRect() const |
| { |
| // Our desired rect is essentially 17x17. |
| |
| // Our actual rect will shrink to half the available space when |
| // we have < 34 pixels left. This allows the scrollbar |
| // to scale down and function even at tiny sizes. |
| |
| if (m_orientation == HorizontalScrollbar) |
| return IntRect(x() + width() - cButtonLength[controlSize()], y(), cButtonLength[controlSize()], cHorizontalHeight[controlSize()]); |
| return IntRect(x(), y() + height() - cButtonLength[controlSize()], cVerticalWidth[controlSize()], cButtonLength[controlSize()]); |
| } |
| |
| IntRect PlatformScrollbar::trackRect() const |
| { |
| if (m_orientation == HorizontalScrollbar) { |
| if (!hasButtons()) |
| return IntRect(x(), y(), width(), cHorizontalHeight[controlSize()]); |
| return IntRect(x() + cButtonLength[controlSize()], y(), width() - 2 * cButtonLength[controlSize()], cHorizontalHeight[controlSize()]); |
| } |
| |
| if (!hasButtons()) |
| return IntRect(x(), y(), cVerticalWidth[controlSize()], height()); |
| return IntRect(x(), y() + cButtonLength[controlSize()], cVerticalWidth[controlSize()], height() - 2 * cButtonLength[controlSize()]); |
| } |
| |
| IntRect PlatformScrollbar::thumbRect() const |
| { |
| IntRect beforeThumbRect, thumbRect, afterThumbRect; |
| splitTrack(trackRect(), beforeThumbRect, thumbRect, afterThumbRect); |
| return thumbRect; |
| } |
| |
| void PlatformScrollbar::splitTrack(const IntRect& trackRect, IntRect& beforeThumbRect, IntRect& thumbRect, IntRect& afterThumbRect) const |
| { |
| // This function won't even get called unless we're big enough to have some combination of these three rects where at least |
| // one of them is non-empty. |
| int thumbPos = thumbPosition(); |
| if (m_orientation == HorizontalScrollbar) { |
| thumbRect = IntRect(trackRect.x() + thumbPos, trackRect.y() + (trackRect.height() - cThumbHeight[controlSize()]) / 2, thumbLength(), cThumbHeight[controlSize()]); |
| beforeThumbRect = IntRect(trackRect.x(), trackRect.y(), thumbPos, trackRect.height()); |
| afterThumbRect = IntRect(thumbRect.x() + thumbRect.width(), trackRect.y(), trackRect.right() - thumbRect.right(), trackRect.height()); |
| } else { |
| thumbRect = IntRect(trackRect.x() + (trackRect.width() - cThumbWidth[controlSize()]) / 2, trackRect.y() + thumbPos, cThumbWidth[controlSize()], thumbLength()); |
| beforeThumbRect = IntRect(trackRect.x(), trackRect.y(), trackRect.width(), thumbPos); |
| afterThumbRect = IntRect(trackRect.x(), thumbRect.y() + thumbRect.height(), trackRect.width(), trackRect.bottom() - thumbRect.bottom()); |
| } |
| } |
| |
| int PlatformScrollbar::thumbPosition() const |
| { |
| if (isEnabled()) |
| return (float)m_currentPos * (trackLength() - thumbLength()) / (m_totalSize - m_visibleSize); |
| return 0; |
| } |
| |
| int PlatformScrollbar::thumbLength() const |
| { |
| if (!isEnabled()) |
| return 0; |
| |
| float proportion = (float)(m_visibleSize) / m_totalSize; |
| int trackLen = trackLength(); |
| int length = proportion * trackLen; |
| int minLength = cThumbMinLength[controlSize()]; |
| length = max(length, minLength); |
| if (length > trackLen) |
| length = 0; // Once the thumb is below the track length, it just goes away (to make more room for the track). |
| return length; |
| } |
| |
| int PlatformScrollbar::trackLength() const |
| { |
| return (m_orientation == HorizontalScrollbar) ? trackRect().width() : trackRect().height(); |
| } |
| |
| void PlatformScrollbar::paintButton(GraphicsContext* context, const IntRect& rect, bool start, const IntRect& damageRect) const |
| { |
| if (!SafariThemeLibrary()) |
| return; |
| |
| IntRect paintRect = buttonRepaintRect(rect, m_orientation, controlSize(), start); |
| |
| if (!damageRect.intersects(paintRect)) |
| return; |
| |
| ThemePart part; |
| ThemeControlState state = 0; |
| if (m_client->isActive()) |
| state |= ActiveState; |
| if (m_orientation == HorizontalScrollbar) |
| part = start ? ScrollLeftArrowPart : ScrollRightArrowPart; |
| else |
| part = start ? ScrollUpArrowPart : ScrollDownArrowPart; |
| |
| if (isEnabled()) |
| state |= EnabledState; |
| if ((m_pressedPart == BackButtonPart && start) |
| || (m_pressedPart == ForwardButtonPart && !start)) |
| state |= PressedState; |
| |
| paintThemePart(part, context->platformContext(), paintRect, controlSize() == SmallScrollbar ? NSSmallControlSize : NSRegularControlSize, state); |
| } |
| |
| void PlatformScrollbar::paintTrack(GraphicsContext* context, const IntRect& rect, bool start, const IntRect& damageRect) const |
| { |
| if (!SafariThemeLibrary()) |
| return; |
| |
| IntRect paintRect = hasButtons() ? trackRepaintRect(rect, m_orientation, controlSize()) : rect; |
| |
| if (!damageRect.intersects(paintRect)) |
| return; |
| |
| ThemePart part = m_orientation == HorizontalScrollbar ? HScrollTrackPart : VScrollTrackPart; |
| ThemeControlState state = 0; |
| if (m_client->isActive()) |
| state |= ActiveState; |
| if (hasButtons()) |
| state |= EnabledState; |
| |
| paintThemePart(part, context->platformContext(), paintRect, controlSize() == SmallScrollbar ? NSSmallControlSize : NSRegularControlSize, state); |
| } |
| |
| void PlatformScrollbar::paintThumb(GraphicsContext* context, const IntRect& rect, const IntRect& damageRect) const |
| { |
| if (!SafariThemeLibrary()) |
| return; |
| |
| if (!damageRect.intersects(rect)) |
| return; |
| |
| ThemePart part = m_orientation == HorizontalScrollbar ? HScrollThumbPart : VScrollThumbPart; |
| ThemeControlState state = 0; |
| if (m_client->isActive()) |
| state |= ActiveState; |
| if (isEnabled()) |
| state |= EnabledState; |
| |
| paintThemePart(part, context->platformContext(), rect, controlSize() == SmallScrollbar ? NSSmallControlSize : NSRegularControlSize, state); |
| } |
| |
| ScrollbarPart PlatformScrollbar::hitTest(const PlatformMouseEvent& evt) |
| { |
| if (!isEnabled()) |
| return NoPart; |
| |
| IntPoint mousePosition = convertFromContainingWindow(evt.pos()); |
| mousePosition.move(x(), y()); |
| |
| if (hasButtons()) { |
| if (backButtonRect().contains(mousePosition)) |
| return BackButtonPart; |
| |
| if (forwardButtonRect().contains(mousePosition)) |
| return ForwardButtonPart; |
| } |
| |
| if (!hasThumb()) |
| return NoPart; |
| |
| IntRect track = trackRect(); |
| if (track.contains(mousePosition)) { |
| IntRect beforeThumbRect, thumbRect, afterThumbRect; |
| splitTrack(track, beforeThumbRect, thumbRect, afterThumbRect); |
| if (beforeThumbRect.contains(mousePosition)) |
| return BackTrackPart; |
| if (thumbRect.contains(mousePosition)) |
| return ThumbPart; |
| return ForwardTrackPart; |
| } |
| return NoPart; |
| } |
| |
| bool PlatformScrollbar::handleMouseMoveEvent(const PlatformMouseEvent& evt) |
| { |
| if (m_pressedPart == ThumbPart) { |
| // Drag the thumb. |
| int thumbPos = thumbPosition(); |
| int thumbLen = thumbLength(); |
| int trackLen = trackLength(); |
| int maxPos = trackLen - thumbLen; |
| int delta = 0; |
| if (m_orientation == HorizontalScrollbar) |
| delta = convertFromContainingWindow(evt.pos()).x() - m_pressedPos; |
| else |
| delta = convertFromContainingWindow(evt.pos()).y() - m_pressedPos; |
| |
| if (delta > 0) |
| // The mouse moved down/right. |
| delta = min(maxPos - thumbPos, delta); |
| else if (delta < 0) |
| // The mouse moved up/left. |
| delta = max(-thumbPos, delta); |
| |
| if (delta != 0) { |
| setValue((float)(thumbPos + delta) * (m_totalSize - m_visibleSize) / (trackLen - thumbLen)); |
| m_pressedPos += thumbPosition() - thumbPos; |
| } |
| |
| return true; |
| } |
| |
| if (m_pressedPart != NoPart) |
| m_pressedPos = (m_orientation == HorizontalScrollbar ? convertFromContainingWindow(evt.pos()).x() : convertFromContainingWindow(evt.pos()).y()); |
| |
| ScrollbarPart part = hitTest(evt); |
| if (part != m_hoveredPart) { |
| if (m_pressedPart != NoPart) { |
| if (part == m_pressedPart) { |
| // The mouse is moving back over the pressed part. We |
| // need to start up the timer action again. |
| startTimerIfNeeded(cNormalTimerDelay); |
| invalidatePart(m_pressedPart); |
| } else if (m_hoveredPart == m_pressedPart) { |
| // The mouse is leaving the pressed part. Kill our timer |
| // if needed. |
| stopTimerIfNeeded(); |
| invalidatePart(m_pressedPart); |
| } |
| } else { |
| invalidatePart(part); |
| invalidatePart(m_hoveredPart); |
| } |
| m_hoveredPart = part; |
| } |
| |
| return true; |
| } |
| |
| bool PlatformScrollbar::handleMouseOutEvent(const PlatformMouseEvent& evt) |
| { |
| invalidatePart(m_hoveredPart); |
| m_hoveredPart = NoPart; |
| |
| return true; |
| } |
| |
| bool PlatformScrollbar::handleMousePressEvent(const PlatformMouseEvent& evt) |
| { |
| m_pressedPart = hitTest(evt); |
| m_pressedPos = (m_orientation == HorizontalScrollbar ? convertFromContainingWindow(evt.pos()).x() : convertFromContainingWindow(evt.pos()).y()); |
| invalidatePart(m_pressedPart); |
| autoscrollPressedPart(cInitialTimerDelay); |
| return true; |
| } |
| |
| bool PlatformScrollbar::handleMouseReleaseEvent(const PlatformMouseEvent& evt) |
| { |
| invalidatePart(m_pressedPart); |
| m_pressedPart = NoPart; |
| m_pressedPos = 0; |
| stopTimerIfNeeded(); |
| |
| if (parent() && parent()->isFrameView()) |
| static_cast<FrameView*>(parent())->frame()->eventHandler()->setMousePressed(false); |
| |
| return true; |
| } |
| |
| void PlatformScrollbar::startTimerIfNeeded(double delay) |
| { |
| // Don't do anything for the thumb. |
| if (m_pressedPart == ThumbPart) |
| return; |
| |
| // Handle the track. We halt track scrolling once the thumb is level |
| // with us. |
| if ((m_pressedPart == BackTrackPart || m_pressedPart == ForwardTrackPart) && thumbUnderMouse()) { |
| invalidatePart(m_pressedPart); |
| m_hoveredPart = ThumbPart; |
| return; |
| } |
| |
| // We can't scroll if we've hit the beginning or end. |
| ScrollDirection dir = pressedPartScrollDirection(); |
| if (dir == ScrollUp || dir == ScrollLeft) { |
| if (m_currentPos == 0) |
| return; |
| } else { |
| if (m_currentPos == m_totalSize - m_visibleSize) |
| return; |
| } |
| |
| m_scrollTimer.startOneShot(delay); |
| } |
| |
| void PlatformScrollbar::stopTimerIfNeeded() |
| { |
| if (m_scrollTimer.isActive()) |
| m_scrollTimer.stop(); |
| } |
| |
| void PlatformScrollbar::autoscrollPressedPart(double delay) |
| { |
| // Don't do anything for the thumb or if nothing was pressed. |
| if (m_pressedPart == ThumbPart || m_pressedPart == NoPart) |
| return; |
| |
| // Handle the track. |
| if ((m_pressedPart == BackTrackPart || m_pressedPart == ForwardTrackPart) && thumbUnderMouse()) { |
| invalidatePart(m_pressedPart); |
| m_hoveredPart = ThumbPart; |
| return; |
| } |
| |
| // Handle the arrows and track. |
| if (scroll(pressedPartScrollDirection(), pressedPartScrollGranularity())) |
| startTimerIfNeeded(delay); |
| } |
| |
| void PlatformScrollbar::autoscrollTimerFired(Timer<PlatformScrollbar>*) |
| { |
| autoscrollPressedPart(cNormalTimerDelay); |
| } |
| |
| ScrollDirection PlatformScrollbar::pressedPartScrollDirection() |
| { |
| if (m_orientation == HorizontalScrollbar) { |
| if (m_pressedPart == BackButtonPart || m_pressedPart == BackTrackPart) |
| return ScrollLeft; |
| return ScrollRight; |
| } else { |
| if (m_pressedPart == BackButtonPart || m_pressedPart == BackTrackPart) |
| return ScrollUp; |
| return ScrollDown; |
| } |
| } |
| |
| ScrollGranularity PlatformScrollbar::pressedPartScrollGranularity() |
| { |
| if (m_pressedPart == BackButtonPart || m_pressedPart == ForwardButtonPart) |
| return ScrollByLine; |
| return ScrollByPage; |
| } |
| |
| bool PlatformScrollbar::thumbUnderMouse() |
| { |
| // Construct a rect. |
| IntRect thumb = thumbRect(); |
| thumb.move(-x(), -y()); |
| int begin = (m_orientation == HorizontalScrollbar) ? thumb.x() : thumb.y(); |
| int end = (m_orientation == HorizontalScrollbar) ? thumb.right() : thumb.bottom(); |
| return (begin <= m_pressedPos && m_pressedPos < end); |
| } |
| |
| int PlatformScrollbar::horizontalScrollbarHeight(ScrollbarControlSize controlSize) |
| { |
| return cHorizontalWidth[controlSize]; |
| } |
| |
| int PlatformScrollbar::verticalScrollbarWidth(ScrollbarControlSize controlSize) |
| { |
| return cVerticalHeight[controlSize]; |
| } |
| |
| IntRect PlatformScrollbar::windowClipRect() const |
| { |
| IntRect clipRect(0, 0, width(), height()); |
| clipRect = convertToContainingWindow(clipRect); |
| if (m_client) |
| clipRect.intersect(m_client->windowClipRect()); |
| return clipRect; |
| } |
| |
| void PlatformScrollbar::paintGripper(HDC hdc, const IntRect& rect) const |
| { |
| } |
| |
| IntRect PlatformScrollbar::gripperRect(const IntRect& thumbRect) const |
| { |
| return IntRect(); |
| } |
| |
| void PlatformScrollbar::themeChanged() |
| { |
| } |
| |
| } |
| |
| #endif // defined(USE_SAFARI_THEME) |