Bug 1705532 use async/await instead of callbacks r=annyG
[gecko.git] / widget / ScrollbarDrawingWin11.cpp
blob61116ff97e61570de8143dc3a558676af0bb4329
1 /* -*- Mode: C++; tab-width: 40; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #include "ScrollbarDrawingWin11.h"
8 #include "mozilla/gfx/Helpers.h"
9 #include "mozilla/Maybe.h"
10 #include "mozilla/StaticPrefs_widget.h"
11 #include "nsLayoutUtils.h"
12 #include "nsNativeBasicTheme.h"
13 #include "nsNativeTheme.h"
15 namespace mozilla::widget {
17 static LayoutDeviceIntCoord CSSToScrollbarDeviceSize(
18 CSSCoord aCoord, nsPresContext* aPresContext) {
19 return (aCoord * ScrollbarDrawing::GetDPIRatioForScrollbarPart(aPresContext))
20 .Rounded();
23 LayoutDeviceIntSize ScrollbarDrawingWin11::GetMinimumWidgetSize(
24 nsPresContext* aPresContext, StyleAppearance aAppearance,
25 nsIFrame* aFrame) {
26 MOZ_ASSERT(nsNativeTheme::IsWidgetScrollbarPart(aAppearance));
28 switch (aAppearance) {
29 case StyleAppearance::ScrollbarbuttonUp:
30 case StyleAppearance::ScrollbarbuttonDown:
31 return LayoutDeviceIntSize{GetVerticalScrollbarWidth(),
32 CSSToScrollbarDeviceSize(14, aPresContext)};
33 case StyleAppearance::ScrollbarbuttonLeft:
34 case StyleAppearance::ScrollbarbuttonRight:
35 return LayoutDeviceIntSize{CSSToScrollbarDeviceSize(14, aPresContext),
36 GetHorizontalScrollbarHeight()};
37 default:
38 return ScrollbarDrawingWin::GetMinimumWidgetSize(aPresContext,
39 aAppearance, aFrame);
43 sRGBColor ScrollbarDrawingWin11::ComputeScrollbarTrackColor(
44 nsIFrame* aFrame, const ComputedStyle& aStyle,
45 const EventStates& aDocumentState, const Colors& aColors) {
46 if (aColors.HighContrast()) {
47 return ScrollbarDrawingWin::ComputeScrollbarTrackColor(
48 aFrame, aStyle, aDocumentState, aColors);
50 if (ShouldUseDarkScrollbar(aFrame, aStyle)) {
51 return sRGBColor::FromU8(23, 23, 23, 255);
53 const nsStyleUI* ui = aStyle.StyleUI();
54 if (ui->mScrollbarColor.IsColors()) {
55 return sRGBColor::FromABGR(
56 ui->mScrollbarColor.AsColors().track.CalcColor(aStyle));
58 return sRGBColor::FromU8(240, 240, 240, 255);
61 sRGBColor ScrollbarDrawingWin11::ComputeScrollbarThumbColor(
62 nsIFrame* aFrame, const ComputedStyle& aStyle,
63 const EventStates& aElementState, const EventStates& aDocumentState,
64 const Colors& aColors) {
65 if (aColors.HighContrast()) {
66 return ScrollbarDrawingWin::ComputeScrollbarThumbColor(
67 aFrame, aStyle, aElementState, aDocumentState, aColors);
69 if (ShouldUseDarkScrollbar(aFrame, aStyle)) {
70 return sRGBColor::FromU8(149, 149, 149, 255);
72 const nsStyleUI* ui = aStyle.StyleUI();
73 if (ui->mScrollbarColor.IsColors()) {
74 return sRGBColor::FromABGR(ThemeColors::AdjustUnthemedScrollbarThumbColor(
75 ui->mScrollbarColor.AsColors().thumb.CalcColor(aStyle), aElementState));
77 return sRGBColor::FromU8(133, 133, 133, 255);
80 std::pair<sRGBColor, sRGBColor>
81 ScrollbarDrawingWin11::ComputeScrollbarButtonColors(
82 nsIFrame* aFrame, StyleAppearance aAppearance, const ComputedStyle& aStyle,
83 const EventStates& aElementState, const EventStates& aDocumentState,
84 const Colors& aColors) {
85 if (aColors.HighContrast()) {
86 return ScrollbarDrawingWin::ComputeScrollbarButtonColors(
87 aFrame, aAppearance, aStyle, aElementState, aDocumentState, aColors);
90 auto buttonColor =
91 ComputeScrollbarTrackColor(aFrame, aStyle, aDocumentState, aColors);
92 sRGBColor arrowColor = ComputeScrollbarThumbColor(
93 aFrame, aStyle, aElementState, aDocumentState, aColors);
95 if (aElementState.HasAtLeastOneOfStates(NS_EVENT_STATE_HOVER |
96 NS_EVENT_STATE_ACTIVE)) {
97 if (ShouldUseDarkScrollbar(aFrame, aStyle)) {
98 arrowColor = sRGBColor::FromU8(205, 205, 205, 255);
99 } else {
100 arrowColor = sRGBColor::FromU8(102, 102, 102, 255);
103 return {buttonColor, arrowColor};
106 bool ScrollbarDrawingWin11::PaintScrollbarButton(
107 DrawTarget& aDrawTarget, StyleAppearance aAppearance,
108 const LayoutDeviceRect& aRect, nsIFrame* aFrame,
109 const ComputedStyle& aStyle, const EventStates& aElementState,
110 const EventStates& aDocumentState, const Colors& aColors) {
111 if (!ScrollbarDrawing::IsParentScrollbarHoveredOrActive(aFrame)) {
112 return true;
115 auto [buttonColor, arrowColor] = ComputeScrollbarButtonColors(
116 aFrame, aAppearance, aStyle, aElementState, aDocumentState, aColors);
117 aDrawTarget.FillRect(aRect.ToUnknownRect(),
118 ColorPattern(ToDeviceColor(buttonColor)));
120 // Start with Up arrow.
121 float arrowPolygonX[] = {-5.5f, 3.5f, 3.5f, -0.5f, -1.5f, -5.5f, -5.5f};
122 float arrowPolygonXActive[] = {-5.0f, 3.0f, 3.0f, -0.75f,
123 -1.25f, -5.0f, -5.0f};
124 float arrowPolygonXHover[] = {-6.0f, 4.0f, 4.0f, -0.25f,
125 -1.75f, -6.0f, -6.0f};
126 float arrowPolygonY[] = {2.5f, 2.5f, 1.0f, -4.0f, -4.0f, 1.0f, 2.5f};
127 float arrowPolygonYActive[] = {2.0f, 2.0f, 0.5f, -3.5f, -3.5f, 0.5f, 2.0f};
128 float arrowPolygonYHover[] = {3.0f, 3.0f, 1.5f, -4.5f, -4.5f, 1.5f, 3.0f};
129 float* arrowX = arrowPolygonX;
130 float* arrowY = arrowPolygonY;
131 const float offset = aFrame->GetWritingMode().IsPhysicalLTR() ? 1.5f : -1.5f;
132 const float kPolygonSize = 17;
133 const int32_t arrowNumPoints = ArrayLength(arrowPolygonX);
135 if (aElementState.HasState(NS_EVENT_STATE_ACTIVE)) {
136 arrowX = arrowPolygonXActive;
137 arrowY = arrowPolygonYActive;
138 } else if (aElementState.HasState(NS_EVENT_STATE_HOVER)) {
139 arrowX = arrowPolygonXHover;
140 arrowY = arrowPolygonYHover;
143 switch (aAppearance) {
144 case StyleAppearance::ScrollbarbuttonDown:
145 for (int32_t i = 0; i < arrowNumPoints; i++) {
146 arrowY[i] *= -1;
148 [[fallthrough]];
149 case StyleAppearance::ScrollbarbuttonUp:
150 for (int32_t i = 0; i < arrowNumPoints; i++) {
151 arrowX[i] += offset;
153 break;
154 case StyleAppearance::ScrollbarbuttonRight:
155 for (int32_t i = 0; i < arrowNumPoints; i++) {
156 arrowX[i] *= -1;
158 [[fallthrough]];
159 case StyleAppearance::ScrollbarbuttonLeft:
160 std::swap(arrowX, arrowY);
161 break;
162 default:
163 return false;
166 ThemeDrawing::PaintArrow(aDrawTarget, aRect, arrowX, arrowY, kPolygonSize,
167 arrowNumPoints, arrowColor);
168 return true;
171 template <typename PaintBackendData>
172 bool ScrollbarDrawingWin11::DoPaintScrollbarThumb(
173 PaintBackendData& aPaintData, const LayoutDeviceRect& aRect,
174 bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
175 const EventStates& aElementState, const EventStates& aDocumentState,
176 const Colors& aColors, const DPIRatio& aDpiRatio) {
177 sRGBColor thumbColor = ComputeScrollbarThumbColor(
178 aFrame, aStyle, aElementState, aDocumentState, aColors);
180 LayoutDeviceRect thumbRect(aRect);
182 if (ScrollbarDrawing::IsParentScrollbarHoveredOrActive(aFrame)) {
183 if (aHorizontal) {
184 thumbRect.height = 6 * aDpiRatio.scale;
185 thumbRect.y += 5 * aDpiRatio.scale;
186 } else {
187 thumbRect.width = 6 * aDpiRatio.scale;
188 if (aFrame->GetWritingMode().IsPhysicalLTR()) {
189 thumbRect.x += 6 * aDpiRatio.scale;
190 } else {
191 thumbRect.x += 5 * aDpiRatio.scale;
194 LayoutDeviceCoord radius =
195 (aHorizontal ? thumbRect.height : thumbRect.width) / 2.0f;
197 MOZ_ASSERT(aRect.Contains(thumbRect));
199 ThemeDrawing::PaintRoundedRectWithRadius(aPaintData, thumbRect, thumbColor,
200 sRGBColor(), 0, radius / aDpiRatio,
201 aDpiRatio);
202 return true;
205 if (aHorizontal) {
206 thumbRect.height = 2 * aDpiRatio.scale;
207 thumbRect.y += 7 * aDpiRatio.scale;
208 } else {
209 thumbRect.width = 2 * aDpiRatio.scale;
210 if (aFrame->GetWritingMode().IsPhysicalLTR()) {
211 thumbRect.x += 8 * aDpiRatio.scale;
212 } else {
213 thumbRect.x += 7 * aDpiRatio.scale;
216 ThemeDrawing::FillRect(aPaintData, thumbRect, thumbColor);
217 return true;
220 bool ScrollbarDrawingWin11::PaintScrollbarThumb(
221 DrawTarget& aDrawTarget, const LayoutDeviceRect& aRect, bool aHorizontal,
222 nsIFrame* aFrame, const ComputedStyle& aStyle,
223 const EventStates& aElementState, const EventStates& aDocumentState,
224 const Colors& aColors, const DPIRatio& aDpiRatio) {
225 return DoPaintScrollbarThumb(aDrawTarget, aRect, aHorizontal, aFrame, aStyle,
226 aElementState, aDocumentState, aColors,
227 aDpiRatio);
230 bool ScrollbarDrawingWin11::PaintScrollbarThumb(
231 WebRenderBackendData& aWrData, const LayoutDeviceRect& aRect,
232 bool aHorizontal, nsIFrame* aFrame, const ComputedStyle& aStyle,
233 const EventStates& aElementState, const EventStates& aDocumentState,
234 const Colors& aColors, const DPIRatio& aDpiRatio) {
235 return DoPaintScrollbarThumb(aWrData, aRect, aHorizontal, aFrame, aStyle,
236 aElementState, aDocumentState, aColors,
237 aDpiRatio);
240 } // namespace mozilla::widget