@@ -8,10 +8,12 @@ import 'package:ensemble/framework/view/page_group.dart';
8
8
import 'package:ensemble/framework/widget/icon.dart' as ensemble;
9
9
import 'package:ensemble/framework/view/page.dart' ;
10
10
import 'package:ensemble/page_model.dart' ;
11
+ import 'package:ensemble/screen_controller.dart' ;
11
12
import 'package:ensemble/util/utils.dart' ;
12
13
import 'package:ensemble/widget/helpers/controllers.dart' ;
13
14
import 'package:ensemble_ts_interpreter/invokables/invokable.dart' ;
14
15
import 'package:flutter/material.dart' ;
16
+ import 'package:flutter/services.dart' ;
15
17
import 'package:pointer_interceptor/pointer_interceptor.dart' ;
16
18
import 'package:yaml/yaml.dart' ;
17
19
@@ -24,6 +26,8 @@ mixin UpdatableContainer<T extends Widget> {
24
26
/// base class for widgets that want to participate in Ensemble layout
25
27
abstract class WidgetState <W extends HasController > extends BaseWidgetState <W > {
26
28
ScopeManager ? scopeManager;
29
+ FocusNode ? widgetFocusNode;
30
+ bool hasFocus = false ;
27
31
28
32
@override
29
33
Widget build (BuildContext context) {
@@ -87,14 +91,59 @@ abstract class WidgetState<W extends HasController> extends BaseWidgetState<W> {
87
91
/// So if we put Expanded on the Column's child, layout exception will occur
88
92
rtn = Expanded (child: rtn);
89
93
}
94
+
95
+ if (widgetController.focusable && widgetFocusNode != null ) {
96
+ rtn = Focus (
97
+ focusNode: widgetFocusNode,
98
+ onKey: (node, event) => _onFocusByKey (node, event, widgetController),
99
+ child: Container (
100
+ decoration: BoxDecoration (
101
+ borderRadius: widgetController is BoxController
102
+ ? widgetController.borderRadius? .getValue ()
103
+ : null ,
104
+ border: Border .all (
105
+ color: hasFocus ? Colors .white : Colors .transparent,
106
+ width: 1 )),
107
+ child: ClipRRect (clipBehavior: Clip .hardEdge, child: rtn)));
108
+ }
109
+
90
110
return rtn;
91
111
}
92
112
throw LanguageError ("Wrong usage of widget controller!" );
93
113
}
94
114
115
+ KeyEventResult _onFocusByKey (FocusNode node, RawKeyEvent event, WidgetController controller) {
116
+ if (controller.onFocusSelect != null && event is RawKeyUpEvent && event.logicalKey == LogicalKeyboardKey .select) {
117
+ ScreenController ().executeAction (context, controller.onFocusSelect! );
118
+ return KeyEventResult .handled;
119
+ }
120
+ return KeyEventResult .ignored;
121
+ }
122
+
95
123
/// build your widget here
96
124
Widget buildWidget (BuildContext context);
97
125
126
+ @override
127
+ void initState () {
128
+ super .initState ();
129
+ if (widget.controller is WidgetController &&
130
+ (widget.controller as WidgetController ).focusable) {
131
+ widgetFocusNode = _initFocus ();
132
+ }
133
+ }
134
+
135
+ FocusNode _initFocus () {
136
+ var myFocusNode = FocusNode ();
137
+ myFocusNode.addListener (() {
138
+ if (myFocusNode.hasFocus != hasFocus) {
139
+ setState (() {
140
+ hasFocus = myFocusNode.hasFocus;
141
+ });
142
+ }
143
+ });
144
+ return myFocusNode;
145
+ }
146
+
98
147
@override
99
148
void didChangeDependencies () {
100
149
super .didChangeDependencies ();
@@ -107,6 +156,7 @@ abstract class WidgetState<W extends HasController> extends BaseWidgetState<W> {
107
156
if (widget is Invokable ) {
108
157
scopeManager? .removeBindingListeners (widget as Invokable );
109
158
}
159
+ widgetFocusNode? .dispose ();
110
160
super .dispose ();
111
161
}
112
162
0 commit comments