-
Notifications
You must be signed in to change notification settings - Fork 82
/
simple_button.dart
163 lines (130 loc) · 5.05 KB
/
simple_button.dart
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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
part of '../display.dart';
enum SimpleButtonState { Up, Over, Down }
/// The SimpleButton class lets you control all instances of button symbols.
class SimpleButton extends InteractiveObject {
/// Specifies a display object that is used as the visual object for the
/// button up state — the state that the button is in when the pointer is not
/// positioned over the button.
DisplayObject? upState;
/// Specifies a display object that is used as the visual object for the
/// button over state — the state that the button is in when the pointer is
/// positioned over the button.
DisplayObject? overState;
/// Specifies a display object that is used as the visual object for the
/// button down state - the state that the button is in when the user
/// selects the [hitTestState] object.
DisplayObject? downState;
/// Specifies a display object that is used as the hit testing object for the
/// button.
///
/// For a basic button, set the [hitTestState] property to the same display
/// object as the [overState] property. If you do not set the [hitTestState]
/// property, the [SimpleButton] is inactive — it does not respond to user
/// input events.
DisplayObject? hitTestState;
/// Creates a new [SimpleButton] instance.
///
/// Any or all of the display objects that represent the various button states
/// can be set as parameters in the constructor.
SimpleButton(
[this.upState, this.overState, this.downState, this.hitTestState]) {
useHandCursor = true;
onMouseOver.listen(_onMouseEvent);
onMouseOut.listen(_onMouseEvent);
onMouseDown.listen(_onMouseEvent);
onMouseUp.listen(_onMouseEvent);
onTouchOver.listen(_onTouchEvent);
onTouchOut.listen(_onTouchEvent);
onTouchBegin.listen(_onTouchEvent);
onTouchEnd.listen(_onTouchEvent);
}
//---------------------------------------------------------------------------
/// Specifies whether a button is enabled.
///
/// When a button is disabled (the enabled property is set to false), the
/// button is visible but cannot be clicked. The default value is true. This
/// property is useful if you want to disable part of your navigation; for
/// example, you might want to disable a button in the currently displayed
/// page so that it can't be clicked and the page cannot be reloaded.
///
/// Note: To prevent mouseClicks on a button, set both the enabled and
/// [mouseEnabled] properties to false.
bool get enabled => _enabled;
set enabled(bool value) {
if (_enabled != value) {
_enabled = value;
_state = SimpleButtonState.Up;
}
}
bool _enabled = true;
/// The current state of the button (Up, Over, Down).
///
/// This state is changing automatically if the mouse (or touch point) is
/// over the button or the button is pressed.
SimpleButtonState get state => _state;
SimpleButtonState _state = SimpleButtonState.Up;
//---------------------------------------------------------------------------
@override
Rectangle<num> get bounds {
final displayObject = _getDisplayObject();
return displayObject?.boundsTransformed ?? super.bounds;
}
@override
DisplayObject? hitTestInput(num localX, num localY) {
if (hitTestState == null) return null;
final matrix = hitTestState!.transformationMatrix;
final deltaX = localX - matrix.tx;
final deltaY = localY - matrix.ty;
final childX = (matrix.d * deltaX - matrix.c * deltaY) / matrix.det;
final childY = (matrix.a * deltaY - matrix.b * deltaX) / matrix.det;
return hitTestState!.hitTestInput(childX, childY) != null ? this : null;
}
@override
void render(RenderState renderState) {
final displayObject = _getDisplayObject();
if (displayObject != null) {
renderState.renderObject(displayObject);
}
}
//---------------------------------------------------------------------------
DisplayObject? _getDisplayObject() {
switch (_state) {
case SimpleButtonState.Up:
return upState;
case SimpleButtonState.Over:
return overState;
case SimpleButtonState.Down:
return downState;
default:
return null;
}
}
void _onMouseEvent(MouseEvent mouseEvent) {
if (_enabled == false) {
// don't change the state
}
if (mouseEvent.type == MouseEvent.MOUSE_OUT) {
_state = SimpleButtonState.Up;
} else if (mouseEvent.buttonDown) {
_state = SimpleButtonState.Down;
} else {
_state = SimpleButtonState.Over;
}
}
void _onTouchEvent(TouchEvent touchEvent) {
if (_enabled == false) {
// don't change the state
}
if (touchEvent.isPrimaryTouchPoint == false) {
// don't change the state
} else if (touchEvent.type == TouchEvent.TOUCH_OVER) {
_state = SimpleButtonState.Down;
} else if (touchEvent.type == TouchEvent.TOUCH_OUT) {
_state = SimpleButtonState.Up;
} else if (touchEvent.type == TouchEvent.TOUCH_BEGIN) {
_state = SimpleButtonState.Down;
} else if (touchEvent.type == TouchEvent.TOUCH_END) {
_state = SimpleButtonState.Up;
}
}
}