@@ -3,7 +3,6 @@ use std::{any::Any, sync::Arc};
3
3
use crate :: {
4
4
emath:: { Align , Pos2 , Rect , Vec2 } ,
5
5
menu, Context , CursorIcon , Id , LayerId , PointerButton , Sense , Ui , WidgetRect , WidgetText ,
6
- NUM_POINTER_BUTTONS ,
7
6
} ;
8
7
9
8
// ----------------------------------------------------------------------------
@@ -15,7 +14,10 @@ use crate::{
15
14
///
16
15
/// Whenever something gets added to a [`Ui`], a [`Response`] object is returned.
17
16
/// [`ui.add`] returns a [`Response`], as does [`ui.button`], and all similar shortcuts.
18
- // TODO(emilk): we should be using bit sets instead of so many bools
17
+ ///
18
+ /// ⚠️ The `Response` contains a clone of [`Context`], and many methods lock the `Context`.
19
+ /// It can therefor be a deadlock to use `Context` from within a context-locking closures,
20
+ /// such as [`Context::input`].
19
21
#[ derive( Clone , Debug ) ]
20
22
pub struct Response {
21
23
// CONTEXT:
@@ -69,18 +71,23 @@ pub struct Response {
69
71
#[ doc( hidden) ]
70
72
pub highlighted : bool ,
71
73
72
- /// The pointer clicked this thing this frame.
73
- #[ doc( hidden) ]
74
- pub clicked : [ bool ; NUM_POINTER_BUTTONS ] ,
75
-
76
- // TODO(emilk): `released` for sliders
77
- /// The thing was double-clicked.
74
+ /// This widget was clicked this frame.
75
+ ///
76
+ /// Which pointer and how many times we don't know,
77
+ /// and ask [`crate::InputState`] about at runtime.
78
+ ///
79
+ /// This is only set to true if the widget was clicked
80
+ /// by an actual mouse.
78
81
#[ doc( hidden) ]
79
- pub double_clicked : [ bool ; NUM_POINTER_BUTTONS ] ,
82
+ pub clicked : bool ,
80
83
81
- /// The thing was triple-clicked.
84
+ /// This widget should act as if clicked due
85
+ /// to something else than a click.
86
+ ///
87
+ /// This is set to true if the widget has keyboard focus and
88
+ /// the user hit the Space or Enter key.
82
89
#[ doc( hidden) ]
83
- pub triple_clicked : [ bool ; NUM_POINTER_BUTTONS ] ,
90
+ pub fake_primary_click : bool ,
84
91
85
92
/// The widget started being dragged this frame.
86
93
#[ doc( hidden) ]
@@ -118,55 +125,62 @@ impl Response {
118
125
/// A click is registered when the mouse or touch is released within
119
126
/// a certain amount of time and distance from when and where it was pressed.
120
127
///
128
+ /// This will also return true if the widget was clicked via accessibility integration,
129
+ /// or if the widget had keyboard focus and the use pressed Space/Enter.
130
+ ///
121
131
/// Note that the widget must be sensing clicks with [`Sense::click`].
122
132
/// [`crate::Button`] senses clicks; [`crate::Label`] does not (unless you call [`crate::Label::sense`]).
123
133
///
124
134
/// You can use [`Self::interact`] to sense more things *after* adding a widget.
125
135
#[ inline( always) ]
126
136
pub fn clicked ( & self ) -> bool {
127
- self . clicked [ PointerButton :: Primary as usize ]
137
+ self . fake_primary_click || self . clicked_by ( PointerButton :: Primary )
128
138
}
129
139
130
- /// Returns true if this widget was clicked this frame by the given button.
140
+ /// Returns true if this widget was clicked this frame by the given mouse button.
141
+ ///
142
+ /// This will NOT return true if the widget was "clicked" via
143
+ /// some accessibility integration, or if the widget had keyboard focus and the
144
+ /// user pressed Space/Enter. For that, use [`Self::clicked`] instead.
131
145
#[ inline]
132
146
pub fn clicked_by ( & self , button : PointerButton ) -> bool {
133
- self . clicked [ button as usize ]
147
+ self . clicked && self . ctx . input ( |i| i . pointer . button_clicked ( button ) )
134
148
}
135
149
136
150
/// Returns true if this widget was clicked this frame by the secondary mouse button (e.g. the right mouse button).
137
151
#[ inline]
138
152
pub fn secondary_clicked ( & self ) -> bool {
139
- self . clicked [ PointerButton :: Secondary as usize ]
153
+ self . clicked_by ( PointerButton :: Secondary )
140
154
}
141
155
142
156
/// Returns true if this widget was clicked this frame by the middle mouse button.
143
157
#[ inline]
144
158
pub fn middle_clicked ( & self ) -> bool {
145
- self . clicked [ PointerButton :: Middle as usize ]
159
+ self . clicked_by ( PointerButton :: Middle )
146
160
}
147
161
148
162
/// Returns true if this widget was double-clicked this frame by the primary button.
149
163
#[ inline]
150
164
pub fn double_clicked ( & self ) -> bool {
151
- self . double_clicked [ PointerButton :: Primary as usize ]
165
+ self . double_clicked_by ( PointerButton :: Primary )
152
166
}
153
167
154
168
/// Returns true if this widget was triple-clicked this frame by the primary button.
155
169
#[ inline]
156
170
pub fn triple_clicked ( & self ) -> bool {
157
- self . triple_clicked [ PointerButton :: Primary as usize ]
171
+ self . triple_clicked_by ( PointerButton :: Primary )
158
172
}
159
173
160
174
/// Returns true if this widget was double-clicked this frame by the given button.
161
175
#[ inline]
162
176
pub fn double_clicked_by ( & self , button : PointerButton ) -> bool {
163
- self . double_clicked [ button as usize ]
177
+ self . clicked && self . ctx . input ( |i| i . pointer . button_double_clicked ( button ) )
164
178
}
165
179
166
180
/// Returns true if this widget was triple-clicked this frame by the given button.
167
181
#[ inline]
168
182
pub fn triple_clicked_by ( & self , button : PointerButton ) -> bool {
169
- self . triple_clicked [ button as usize ]
183
+ self . clicked && self . ctx . input ( |i| i . pointer . button_triple_clicked ( button ) )
170
184
}
171
185
172
186
/// `true` if there was a click *outside* this widget this frame.
@@ -917,27 +931,8 @@ impl Response {
917
931
contains_pointer : self . contains_pointer || other. contains_pointer ,
918
932
hovered : self . hovered || other. hovered ,
919
933
highlighted : self . highlighted || other. highlighted ,
920
- clicked : [
921
- self . clicked [ 0 ] || other. clicked [ 0 ] ,
922
- self . clicked [ 1 ] || other. clicked [ 1 ] ,
923
- self . clicked [ 2 ] || other. clicked [ 2 ] ,
924
- self . clicked [ 3 ] || other. clicked [ 3 ] ,
925
- self . clicked [ 4 ] || other. clicked [ 4 ] ,
926
- ] ,
927
- double_clicked : [
928
- self . double_clicked [ 0 ] || other. double_clicked [ 0 ] ,
929
- self . double_clicked [ 1 ] || other. double_clicked [ 1 ] ,
930
- self . double_clicked [ 2 ] || other. double_clicked [ 2 ] ,
931
- self . double_clicked [ 3 ] || other. double_clicked [ 3 ] ,
932
- self . double_clicked [ 4 ] || other. double_clicked [ 4 ] ,
933
- ] ,
934
- triple_clicked : [
935
- self . triple_clicked [ 0 ] || other. triple_clicked [ 0 ] ,
936
- self . triple_clicked [ 1 ] || other. triple_clicked [ 1 ] ,
937
- self . triple_clicked [ 2 ] || other. triple_clicked [ 2 ] ,
938
- self . triple_clicked [ 3 ] || other. triple_clicked [ 3 ] ,
939
- self . triple_clicked [ 4 ] || other. triple_clicked [ 4 ] ,
940
- ] ,
934
+ clicked : self . clicked || other. clicked ,
935
+ fake_primary_click : self . fake_primary_click || other. fake_primary_click ,
941
936
drag_started : self . drag_started || other. drag_started ,
942
937
dragged : self . dragged || other. dragged ,
943
938
drag_stopped : self . drag_stopped || other. drag_stopped ,
0 commit comments