-
Notifications
You must be signed in to change notification settings - Fork 18
Expand file tree
/
Copy pathredrawrequests.go
More file actions
141 lines (122 loc) · 3.96 KB
/
Copy pathredrawrequests.go
File metadata and controls
141 lines (122 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
// SPDX-License-Identifier: Apache-2.0
// SPDX-FileCopyrightText: 2025 The Guigui Authors
package guigui
import (
"fmt"
"image"
"iter"
"log/slog"
"math/bits"
)
type redrawRequests struct {
region image.Rectangle
}
func (r *redrawRequests) reset() {
r.region = image.Rectangle{}
}
func (r *redrawRequests) empty() bool {
return r.region.Empty()
}
func (r *redrawRequests) union(region image.Rectangle) image.Rectangle {
return r.region.Union(region)
}
type requestRedrawReason int
const (
// These reasons require only a redraw, not a rebuild.
requestRedrawReasonExplicitRequest requestRedrawReason = iota
requestRedrawReasonStateKeyChangedForDraw
requestRedrawReasonTreeChanged
// The remaining reasons require a rebuild in addition to a redraw.
requestRedrawReasonStateKeyChangedForBuild
requestRedrawReasonWidgetFocus
requestRedrawReasonAppFocus
requestRedrawReasonScreenSize
requestRedrawReasonScreenDeviceScale
requestRedrawReasonAppScale
requestRedrawReasonColorMode
requestRedrawReasonLocale
)
func (r requestRedrawReason) String() string {
switch r {
case requestRedrawReasonExplicitRequest:
return "explicit request"
case requestRedrawReasonStateKeyChangedForDraw:
return "state key changed for draw"
case requestRedrawReasonTreeChanged:
return "tree changed"
case requestRedrawReasonStateKeyChangedForBuild:
return "state key changed for build"
case requestRedrawReasonWidgetFocus:
return "widget focus"
case requestRedrawReasonAppFocus:
return "app focus"
case requestRedrawReasonScreenSize:
return "screen size"
case requestRedrawReasonScreenDeviceScale:
return "screen device scale"
case requestRedrawReasonAppScale:
return "app scale"
case requestRedrawReasonColorMode:
return "color mode"
case requestRedrawReasonLocale:
return "locale"
default:
return "unknown"
}
}
// requestRedrawReasons is a set of requestRedrawReason values, one bit per reason.
// The zero value is the empty set, meaning no redraw is pending.
type requestRedrawReasons uint32
// redrawReasonsOf returns a set containing the single given reason.
func redrawReasonsOf(reason requestRedrawReason) requestRedrawReasons {
var r requestRedrawReasons
r.add(reason)
return r
}
func (r requestRedrawReasons) empty() bool {
return r == 0
}
func (r requestRedrawReasons) has(reason requestRedrawReason) bool {
return r&(1<<reason) != 0
}
// triggersRebuild reports whether the set contains any reason that forces a tree rebuild,
// i.e. any reason other than a redraw-only one.
func (r requestRedrawReasons) triggersRebuild() bool {
const redrawOnly = 1<<requestRedrawReasonExplicitRequest |
1<<requestRedrawReasonStateKeyChangedForDraw |
1<<requestRedrawReasonTreeChanged
return r&^redrawOnly != 0
}
// all returns an iterator over the reasons in the set, in ascending reason order.
func (r requestRedrawReasons) all() iter.Seq[requestRedrawReason] {
return func(yield func(requestRedrawReason) bool) {
for rs := r; rs != 0; rs &= rs - 1 {
reason := requestRedrawReason(bits.TrailingZeros32(uint32(rs)))
if !yield(reason) {
return
}
}
}
}
func (r *requestRedrawReasons) add(reason requestRedrawReason) {
*r |= 1 << reason
}
func (r *requestRedrawReasons) clear() {
*r = 0
}
func (r *redrawRequests) add(region image.Rectangle, reasons requestRedrawReasons, widget Widget) {
r.region = r.region.Union(region)
if !theDebugMode.showRenderingRegions {
return
}
for reason := range reasons.all() {
switch reason {
case requestRedrawReasonExplicitRequest:
slog.Info("request redrawing", "reason", reason.String(), "requester", fmt.Sprintf("%T", widget), "at", widget.widgetState().redrawRequestedAt, "region", region)
case requestRedrawReasonStateKeyChangedForDraw, requestRedrawReasonTreeChanged, requestRedrawReasonStateKeyChangedForBuild:
slog.Info("request redrawing", "reason", reason.String(), "requester", fmt.Sprintf("%T", widget), "region", region)
default:
slog.Info("request redrawing", "reason", reason.String(), "region", region)
}
}
}