void ScrollbarThemeWin::paintThumb(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& rect) { checkAndInitScrollbarTheme(); int state; if (!scrollbar.enabled()) state = TS_DISABLED; else if (scrollbar.pressedPart() == ThumbPart) state = TS_ACTIVE; // Thumb always stays active once pressed. else if (scrollbar.hoveredPart() == ThumbPart) state = TS_HOVER; else state = TS_NORMAL; bool alphaBlend = false; if (scrollbarTheme) alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, scrollbar.orientation() == HorizontalScrollbar ? SP_THUMBHOR : SP_THUMBVERT, state); LocalWindowsContext windowsContext(context, rect, alphaBlend); RECT themeRect(rect); if (scrollbarTheme) { DrawThemeBackground(scrollbarTheme, windowsContext.hdc(), scrollbar.orientation() == HorizontalScrollbar ? SP_THUMBHOR : SP_THUMBVERT, state, &themeRect, 0); paintGripper(scrollbar, windowsContext.hdc(), gripperRect(scrollbarThickness(), rect)); } else ::DrawEdge(windowsContext.hdc(), &themeRect, EDGE_RAISED, BF_RECT | BF_MIDDLE); if (!alphaBlend && !context.isInTransparencyLayer()) DIBPixelData::setRGBABitmapAlpha(windowsContext.hdc(), rect, 255); }
void ScrollbarThemeWin::paintButton(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& rect, ScrollbarPart part) { checkAndInitScrollbarTheme(); bool start = (part == BackButtonStartPart); int xpState = 0; int classicState = 0; if (scrollbar.orientation() == HorizontalScrollbar) xpState = start ? TS_LEFT_BUTTON : TS_RIGHT_BUTTON; else xpState = start ? TS_UP_BUTTON : TS_DOWN_BUTTON; classicState = xpState / 4; if (!scrollbar.enabled()) { xpState += TS_DISABLED; classicState |= DFCS_INACTIVE; } else if ((scrollbar.hoveredPart() == BackButtonStartPart && start) || (scrollbar.hoveredPart() == ForwardButtonEndPart && !start)) { if (scrollbar.pressedPart() == scrollbar.hoveredPart()) { xpState += TS_ACTIVE; classicState |= DFCS_PUSHED; classicState |= DFCS_FLAT; } else xpState += TS_HOVER; } else { if (scrollbar.hoveredPart() == NoPart || !runningVista) xpState += TS_NORMAL; else { if (scrollbar.orientation() == HorizontalScrollbar) xpState = start ? TS_LEFT_BUTTON_HOVER : TS_RIGHT_BUTTON_HOVER; else xpState = start ? TS_UP_BUTTON_HOVER : TS_DOWN_BUTTON_HOVER; } } bool alphaBlend = false; if (scrollbarTheme) alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, SP_BUTTON, xpState); LocalWindowsContext windowsContext(context, rect, alphaBlend); RECT themeRect(rect); if (scrollbarTheme) DrawThemeBackground(scrollbarTheme, windowsContext.hdc(), SP_BUTTON, xpState, &themeRect, 0); else ::DrawFrameControl(windowsContext.hdc(), &themeRect, DFC_SCROLL, classicState); if (!alphaBlend && !context.isInTransparencyLayer()) DIBPixelData::setRGBABitmapAlpha(windowsContext.hdc(), rect, 255); }
void ScrollbarThemeAura::paintTrackPiece(GraphicsContext& gc, const Scrollbar& scrollbar, const IntRect& rect, ScrollbarPart partType) { DisplayItem::Type displayItemType = trackPiecePartToDisplayItemType(partType); if (DrawingRecorder::useCachedDrawingIfPossible(gc, scrollbar, displayItemType)) return; DrawingRecorder recorder(gc, scrollbar, displayItemType, rect); WebThemeEngine::State state = scrollbar.hoveredPart() == partType ? WebThemeEngine::StateHover : WebThemeEngine::StateNormal; if (useMockTheme() && !scrollbar.enabled()) state = WebThemeEngine::StateDisabled; IntRect alignRect = trackRect(scrollbar, false); WebThemeEngine::ExtraParams extraParams; extraParams.scrollbarTrack.isBack = (partType == BackTrackPart); extraParams.scrollbarTrack.trackX = alignRect.x(); extraParams.scrollbarTrack.trackY = alignRect.y(); extraParams.scrollbarTrack.trackWidth = alignRect.width(); extraParams.scrollbarTrack.trackHeight = alignRect.height(); Platform::current()->themeEngine()->paint( gc.canvas(), scrollbar.orientation() == HorizontalScrollbar ? WebThemeEngine::PartScrollbarHorizontalTrack : WebThemeEngine::PartScrollbarVerticalTrack, state, WebRect(rect), &extraParams); }
IntRect ScrollbarThemeSafari::forwardButtonRect(Scrollbar& scrollbar, ScrollbarPart part, bool painting) { IntRect result; // Windows just has single arrows. if (part == ForwardButtonStartPart) return result; int thickness = scrollbarThickness(scrollbar.controlSize()); if (scrollbar.orientation() == HorizontalScrollbar) result = IntRect(scrollbar.x() + scrollbar.width() - cButtonLength[scrollbar.controlSize()], scrollbar.y(), cButtonLength[scrollbar.controlSize()], thickness); else result = IntRect(scrollbar.x(), scrollbar.y() + scrollbar.height() - cButtonLength[scrollbar.controlSize()], thickness, cButtonLength[scrollbar.controlSize()]); if (painting) return buttonRepaintRect(result, scrollbar.orientation(), scrollbar.controlSize(), false); return result; }
IntRect ScrollbarThemeSafari::backButtonRect(Scrollbar& scrollbar, ScrollbarPart part, bool painting) { IntRect result; // Windows just has single arrows. if (part == BackButtonEndPart) return result; int thickness = scrollbarThickness(scrollbar.controlSize()); if (scrollbar.orientation() == HorizontalScrollbar) result = IntRect(scrollbar.x(), scrollbar.y(), cButtonLength[scrollbar.controlSize()], thickness); else result = IntRect(scrollbar.x(), scrollbar.y(), thickness, cButtonLength[scrollbar.controlSize()]); if (painting) return buttonRepaintRect(result, scrollbar.orientation(), scrollbar.controlSize(), true); return result; }
// GTK+ must scroll horizontally if the mouse pointer is on top of the // horizontal scrollbar while scrolling with the wheel; we need to // add the deltas and ticks here so that this behavior is consistent // for styled scrollbars. bool EventHandler::shouldTurnVerticalTicksIntoHorizontal(const HitTestResult& result, const PlatformWheelEvent& event) const { FrameView* view = m_frame.view(); Scrollbar* scrollbar = view ? view->scrollbarAtPoint(event.position()) : nullptr; if (!scrollbar) scrollbar = result.scrollbar(); return scrollbar && scrollbar->orientation() == HorizontalScrollbar; }
void ScrollbarThemeSafari::paintButton(GraphicsContext& graphicsContext, Scrollbar& scrollbar, const IntRect& buttonRect, ScrollbarPart part) { if (!SafariThemeLibrary()) return; NSControlSize size = scrollbar.controlSize() == SmallScrollbar ? NSSmallControlSize : NSRegularControlSize; ThemeControlState state = 0; if (scrollbar.isScrollableAreaActive()) state |= ActiveState; if (hasButtons(scrollbar)) state |= EnabledState; if (scrollbar.pressedPart() == part) state |= PressedState; if (part == BackButtonStartPart) paintThemePart(scrollbar.orientation() == VerticalScrollbar ? ScrollUpArrowPart : ScrollLeftArrowPart, graphicsContext.platformContext(), buttonRect, size, state); else if (part == ForwardButtonEndPart) paintThemePart(scrollbar.orientation() == VerticalScrollbar ? ScrollDownArrowPart : ScrollRightArrowPart, graphicsContext.platformContext(), buttonRect, size, state); }
IntRect ScrollbarThemeSafari::trackRect(Scrollbar& scrollbar, bool painting) { if (painting || !hasButtons(scrollbar)) return scrollbar.frameRect(); IntRect result; int thickness = scrollbarThickness(scrollbar.controlSize()); if (scrollbar.orientation() == HorizontalScrollbar) return IntRect(scrollbar.x() + cButtonLength[scrollbar.controlSize()], scrollbar.y(), scrollbar.width() - 2 * cButtonLength[scrollbar.controlSize()], thickness); return IntRect(scrollbar.x(), scrollbar.y() + cButtonLength[scrollbar.controlSize()], thickness, scrollbar.height() - 2 * cButtonLength[scrollbar.controlSize()]); }
void ScrollbarThemeWin::paintTrackPiece(GraphicsContext& context, Scrollbar& scrollbar, const IntRect& rect, ScrollbarPart partType) { checkAndInitScrollbarTheme(); bool start = partType == BackTrackPart; int part; if (scrollbar.orientation() == HorizontalScrollbar) part = start ? SP_TRACKSTARTHOR : SP_TRACKENDHOR; else part = start ? SP_TRACKSTARTVERT : SP_TRACKENDVERT; int state; if (!scrollbar.enabled()) state = TS_DISABLED; else if ((scrollbar.hoveredPart() == BackTrackPart && start) || (scrollbar.hoveredPart() == ForwardTrackPart && !start)) state = (scrollbar.pressedPart() == scrollbar.hoveredPart() ? TS_ACTIVE : TS_HOVER); else state = TS_NORMAL; bool alphaBlend = false; if (scrollbarTheme) alphaBlend = IsThemeBackgroundPartiallyTransparent(scrollbarTheme, part, state); LocalWindowsContext windowsContext(context, rect, alphaBlend); RECT themeRect(rect); if (scrollbarTheme) DrawThemeBackground(scrollbarTheme, windowsContext.hdc(), part, state, &themeRect, 0); else { DWORD color3DFace = ::GetSysColor(COLOR_3DFACE); DWORD colorScrollbar = ::GetSysColor(COLOR_SCROLLBAR); DWORD colorWindow = ::GetSysColor(COLOR_WINDOW); HDC hdc = windowsContext.hdc(); if ((color3DFace != colorScrollbar) && (colorWindow != colorScrollbar)) ::FillRect(hdc, &themeRect, HBRUSH(COLOR_SCROLLBAR+1)); else { static WORD patternBits[8] = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 }; auto patternBitmap = adoptGDIObject(::CreateBitmap(8, 8, 1, 1, patternBits)); auto brush = adoptGDIObject(::CreatePatternBrush(patternBitmap.get())); SaveDC(hdc); ::SetTextColor(hdc, ::GetSysColor(COLOR_3DHILIGHT)); ::SetBkColor(hdc, ::GetSysColor(COLOR_3DFACE)); ::SetBrushOrgEx(hdc, rect.x(), rect.y(), NULL); ::SelectObject(hdc, brush.get()); ::FillRect(hdc, &themeRect, brush.get()); ::RestoreDC(hdc, -1); } } if (!alphaBlend && !context.isInTransparencyLayer()) DIBPixelData::setRGBABitmapAlpha(windowsContext.hdc(), rect, 255); }
void ScrollbarThemeSafari::paintTrackBackground(GraphicsContext& graphicsContext, Scrollbar& scrollbar, const IntRect& trackRect) { if (!SafariThemeLibrary()) return; NSControlSize size = scrollbar.controlSize() == SmallScrollbar ? NSSmallControlSize : NSRegularControlSize; ThemeControlState state = 0; if (scrollbar.isScrollableAreaActive()) state |= ActiveState; if (hasButtons(scrollbar)) state |= EnabledState; paintThemePart(scrollbar.orientation() == VerticalScrollbar ? VScrollTrackPart : HScrollTrackPart, graphicsContext.platformContext(), trackRect, size, state); }
IntRect ScrollbarThemeWin::trackRect(Scrollbar& scrollbar, bool) { int thickness = scrollbarThickness(); if (scrollbar.orientation() == HorizontalScrollbar) { if (scrollbar.width() < 2 * thickness) return IntRect(); return IntRect(scrollbar.x() + thickness, scrollbar.y(), scrollbar.width() - 2 * thickness, thickness); } if (scrollbar.height() < 2 * thickness) return IntRect(); return IntRect(scrollbar.x(), scrollbar.y() + thickness, thickness, scrollbar.height() - 2 * thickness); }
void GtkAdjustmentWatcher::adjustmentValueChanged(GtkAdjustment* adjustment) { FrameView* frameView = core(m_webView)->mainFrame()->view(); Scrollbar* scrollbar = (adjustment == m_horizontalAdjustment.get()) ? frameView->horizontalScrollbar() : frameView->verticalScrollbar(); if (!scrollbar) return; int newValue = static_cast<int>(gtk_adjustment_get_value(adjustment)); if (newValue != scrollbar->value()) { m_handlingGtkAdjustmentChange = true; frameView->scrollToOffsetWithoutAnimation(scrollbar->orientation(), newValue); m_handlingGtkAdjustmentChange = false; } }
bool ScrollbarThemeWin::shouldSnapBackToDragOrigin(Scrollbar& scrollbar, const PlatformMouseEvent& evt) { // Find the rect within which we shouldn't snap, by expanding the track rect // in both dimensions. IntRect rect = trackRect(scrollbar); const bool horz = scrollbar.orientation() == HorizontalScrollbar; const int thickness = scrollbarThickness(scrollbar.controlSize()); rect.inflateX((horz ? kOffEndMultiplier : kOffSideMultiplier) * thickness); rect.inflateY((horz ? kOffSideMultiplier : kOffEndMultiplier) * thickness); // Convert the event to local coordinates. IntPoint mousePosition = scrollbar.convertFromContainingWindow(evt.position()); mousePosition.move(scrollbar.x(), scrollbar.y()); // We should snap iff the event is outside our calculated rect. return !rect.contains(mousePosition); }
static void paintGripper(Scrollbar& scrollbar, HDC hdc, const IntRect& rect) { if (!scrollbarTheme) return; // Classic look has no gripper. int state; if (!scrollbar.enabled()) state = TS_DISABLED; else if (scrollbar.pressedPart() == ThumbPart) state = TS_ACTIVE; // Thumb always stays active once pressed. else if (scrollbar.hoveredPart() == ThumbPart) state = TS_HOVER; else state = TS_NORMAL; RECT themeRect(rect); DrawThemeBackground(scrollbarTheme, hdc, scrollbar.orientation() == HorizontalScrollbar ? SP_GRIPPERHOR : SP_GRIPPERVERT, state, &themeRect, 0); }
IntRect ScrollbarThemeWin::backButtonRect(Scrollbar& scrollbar, ScrollbarPart part, bool) { // Windows just has single arrows. if (part == BackButtonEndPart) return IntRect(); // 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. int thickness = scrollbarThickness(); if (scrollbar.orientation() == HorizontalScrollbar) return IntRect(scrollbar.x(), scrollbar.y(), scrollbar.width() < 2 * thickness ? scrollbar.width() / 2 : thickness, thickness); return IntRect(scrollbar.x(), scrollbar.y(), thickness, scrollbar.height() < 2 * thickness ? scrollbar.height() / 2 : thickness); }
void ScrollbarThemeAura::paintThumb(GraphicsContext& gc, const Scrollbar& scrollbar, const IntRect& rect) { if (DrawingRecorder::useCachedDrawingIfPossible(gc, scrollbar, DisplayItem::kScrollbarThumb)) return; DrawingRecorder recorder(gc, scrollbar, DisplayItem::kScrollbarThumb, rect); WebThemeEngine::State state; WebCanvas* canvas = gc.canvas(); if (scrollbar.pressedPart() == ThumbPart) state = WebThemeEngine::StatePressed; else if (scrollbar.hoveredPart() == ThumbPart) state = WebThemeEngine::StateHover; else state = WebThemeEngine::StateNormal; Platform::current()->themeEngine()->paint( canvas, scrollbar.orientation() == HorizontalScrollbar ? WebThemeEngine::PartScrollbarHorizontalThumb : WebThemeEngine::PartScrollbarVerticalThumb, state, WebRect(rect), nullptr); }
void ScrollbarThemeGtk::updateThemeProperties() { MozGtkScrollbarMetrics metrics; moz_gtk_get_scrollbar_metrics(&metrics); m_thumbFatness = metrics.slider_width; m_troughBorderWidth = metrics.trough_border; m_stepperSize = metrics.stepper_size; m_stepperSpacing = metrics.stepper_spacing; m_minThumbLength = metrics.min_slider_size; m_troughUnderSteppers = metrics.trough_under_steppers; m_hasForwardButtonStartPart = metrics.has_secondary_forward_stepper; m_hasBackButtonEndPart = metrics.has_secondary_backward_stepper; if (!gScrollbars) return; // Update the thickness of every interior frame scrollbar widget. The // platform-independent scrollbar them code isn't yet smart enough to get // this information when it paints. HashSet<Scrollbar*>::iterator end = gScrollbars->end(); for (HashSet<Scrollbar*>::iterator it = gScrollbars->begin(); it != end; ++it) { Scrollbar* scrollbar = (*it); // Top-level scrollbar i.e. scrollbars who have a parent ScrollView // with no parent are native, and thus do not need to be resized. if (!scrollbar->parent() || !scrollbar->parent()->parent()) return; int thickness = scrollbarThickness(scrollbar->controlSize()); if (scrollbar->orientation() == HorizontalScrollbar) scrollbar->setFrameRect(IntRect(0, scrollbar->parent()->height() - thickness, scrollbar->width(), thickness)); else scrollbar->setFrameRect(IntRect(scrollbar->parent()->width() - thickness, 0, thickness, scrollbar->height())); } }
bool ScrollbarThemeSafari::hasButtons(Scrollbar& scrollbar) { return scrollbar.enabled() && (scrollbar.orientation() == HorizontalScrollbar ? scrollbar.width() : scrollbar.height()) >= 2 * (cRealButtonLength[scrollbar.controlSize()] - cButtonHitInset[scrollbar.controlSize()]); }
bool ScrollbarThemeSafari::hasThumb(Scrollbar& scrollbar) { return scrollbar.enabled() && (scrollbar.orientation() == HorizontalScrollbar ? scrollbar.width() : scrollbar.height()) >= 2 * cButtonInset[scrollbar.controlSize()] + cThumbMinLength[scrollbar.controlSize()] + 1; }