@babylonjs/gui 7.12.0 → 7.13.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -12,15 +12,17 @@ import type { Style } from "../style";
12
12
  import { Matrix2D, Vector2WithInfo } from "../math2D";
13
13
  import type { ICanvasGradient, ICanvasRenderingContext } from "@babylonjs/core/Engines/ICanvas.js";
14
14
  import type { IAccessibilityTag } from "@babylonjs/core/IAccessibilityTag.js";
15
+ import type { IKeyboardEvent } from "@babylonjs/core/Events/deviceInputEvents.js";
15
16
  import type { IAnimatable } from "@babylonjs/core/Animations/animatable.interface.js";
16
17
  import type { Animation } from "@babylonjs/core/Animations/animation.js";
17
18
  import type { BaseGradient } from "./gradient/BaseGradient";
18
19
  import type { AbstractEngine } from "@babylonjs/core/Engines/abstractEngine.js";
20
+ import type { IFocusableControl } from "./focusableControl";
19
21
  /**
20
22
  * Root class used for all 2D controls
21
23
  * @see https://doc.babylonjs.com/features/featuresDeepDive/gui/gui#controls
22
24
  */
23
- export declare class Control implements IAnimatable {
25
+ export declare class Control implements IAnimatable, IFocusableControl {
24
26
  /** defines the name of the control */
25
27
  name?: string | undefined;
26
28
  /**
@@ -242,6 +244,10 @@ export declare class Control implements IAnimatable {
242
244
  * An event triggered when a control is clicked on
243
245
  */
244
246
  onPointerClickObservable: Observable<Vector2WithInfo>;
247
+ /**
248
+ * An event triggered when a control receives an ENTER key down event
249
+ */
250
+ onEnterPressedObservable: Observable<Control>;
245
251
  /**
246
252
  * An event triggered when pointer enters the control
247
253
  */
@@ -562,6 +568,52 @@ export declare class Control implements IAnimatable {
562
568
  * Array of animations
563
569
  */
564
570
  animations: Nullable<Animation[]>;
571
+ protected _focusedColor: Nullable<string>;
572
+ /**
573
+ * Border color when control is focused
574
+ * When not defined the ADT color will be used. If no ADT color is defined, focused state won't have any border
575
+ */
576
+ get focusedColor(): Nullable<string>;
577
+ set focusedColor(value: Nullable<string>);
578
+ /**
579
+ * The tab index of this control. -1 indicates this control is not part of the tab navigation.
580
+ * A positive value indicates the order of the control in the tab navigation.
581
+ * A value of 0 indicated the control will be focused after all controls with a positive index.
582
+ * More than one control can have the same tab index and the navigation would then go through all controls with the same value in an order defined by the layout or the hierarchy.
583
+ * The value can be changed at any time.
584
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex
585
+ */
586
+ tabIndex: number;
587
+ protected _isFocused: boolean;
588
+ protected _unfocusedColor: Nullable<string>;
589
+ /** Observable raised when the control gets the focus */
590
+ onFocusObservable: Observable<Control>;
591
+ /** Observable raised when the control loses the focus */
592
+ onBlurObservable: Observable<Control>;
593
+ /** Observable raised when a key event was processed */
594
+ onKeyboardEventProcessedObservable: Observable<IKeyboardEvent>;
595
+ /** @internal */
596
+ onBlur(): void;
597
+ /** @internal */
598
+ onFocus(): void;
599
+ /**
600
+ * Function called to get the list of controls that should not steal the focus from this control
601
+ * @returns an array of controls
602
+ */
603
+ keepsFocusWith(): Nullable<Control[]>;
604
+ /**
605
+ * Function to focus a button programmatically
606
+ */
607
+ focus(): void;
608
+ /**
609
+ * Function to unfocus a button programmatically
610
+ */
611
+ blur(): void;
612
+ /**
613
+ * Handles the keyboard event
614
+ * @param evt Defines the KeyboardEvent
615
+ */
616
+ processKeyboard(evt: IKeyboardEvent): void;
565
617
  /**
566
618
  * Creates a new control
567
619
  * @param name defines the name of the control
@@ -826,6 +826,67 @@ export class Control {
826
826
  this._disabledColorItem = value;
827
827
  this._markAsDirty();
828
828
  }
829
+ /**
830
+ * Border color when control is focused
831
+ * When not defined the ADT color will be used. If no ADT color is defined, focused state won't have any border
832
+ */
833
+ get focusedColor() {
834
+ return this._focusedColor;
835
+ }
836
+ set focusedColor(value) {
837
+ this._focusedColor = value;
838
+ }
839
+ /** @internal */
840
+ onBlur() {
841
+ if (this._isFocused) {
842
+ this._isFocused = false;
843
+ if (this.focusedColor && this._unfocusedColor != null) {
844
+ // Set color back to saved unfocused color
845
+ this.color = this._unfocusedColor;
846
+ }
847
+ this.onBlurObservable.notifyObservers(this);
848
+ }
849
+ }
850
+ /** @internal */
851
+ onFocus() {
852
+ this._isFocused = true;
853
+ if (this.focusedColor) {
854
+ // Save the unfocused color
855
+ this._unfocusedColor = this.color;
856
+ this.color = this.focusedColor;
857
+ }
858
+ this.onFocusObservable.notifyObservers(this);
859
+ }
860
+ /**
861
+ * Function called to get the list of controls that should not steal the focus from this control
862
+ * @returns an array of controls
863
+ */
864
+ keepsFocusWith() {
865
+ return null;
866
+ }
867
+ /**
868
+ * Function to focus a button programmatically
869
+ */
870
+ focus() {
871
+ this._host.moveFocusToControl(this);
872
+ }
873
+ /**
874
+ * Function to unfocus a button programmatically
875
+ */
876
+ blur() {
877
+ this._host.focusedControl = null;
878
+ }
879
+ /**
880
+ * Handles the keyboard event
881
+ * @param evt Defines the KeyboardEvent
882
+ */
883
+ processKeyboard(evt) {
884
+ // if enter, trigger the new observable
885
+ if (evt.key === "Enter") {
886
+ this.onEnterPressedObservable.notifyObservers(this);
887
+ }
888
+ this.onKeyboardEventProcessedObservable.notifyObservers(evt, -1, this);
889
+ }
829
890
  // Functions
830
891
  /**
831
892
  * Creates a new control
@@ -978,6 +1039,10 @@ export class Control {
978
1039
  * An event triggered when a control is clicked on
979
1040
  */
980
1041
  this.onPointerClickObservable = new Observable();
1042
+ /**
1043
+ * An event triggered when a control receives an ENTER key down event
1044
+ */
1045
+ this.onEnterPressedObservable = new Observable();
981
1046
  /**
982
1047
  * An event triggered when pointer enters the control
983
1048
  */
@@ -1012,6 +1077,25 @@ export class Control {
1012
1077
  * Array of animations
1013
1078
  */
1014
1079
  this.animations = null;
1080
+ // Focus functionality
1081
+ this._focusedColor = null;
1082
+ /**
1083
+ * The tab index of this control. -1 indicates this control is not part of the tab navigation.
1084
+ * A positive value indicates the order of the control in the tab navigation.
1085
+ * A value of 0 indicated the control will be focused after all controls with a positive index.
1086
+ * More than one control can have the same tab index and the navigation would then go through all controls with the same value in an order defined by the layout or the hierarchy.
1087
+ * The value can be changed at any time.
1088
+ * @see https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex
1089
+ */
1090
+ this.tabIndex = -1;
1091
+ this._isFocused = false;
1092
+ this._unfocusedColor = null;
1093
+ /** Observable raised when the control gets the focus */
1094
+ this.onFocusObservable = new Observable();
1095
+ /** Observable raised when the control loses the focus */
1096
+ this.onBlurObservable = new Observable();
1097
+ /** Observable raised when a key event was processed */
1098
+ this.onKeyboardEventProcessedObservable = new Observable();
1015
1099
  this._tmpMeasureA = new Measure(0, 0, 0, 0);
1016
1100
  }
1017
1101
  /** @internal */
@@ -2064,6 +2148,10 @@ export class Control {
2064
2148
  this.onPointerUpObservable.clear();
2065
2149
  this.onPointerClickObservable.clear();
2066
2150
  this.onWheelObservable.clear();
2151
+ // focus
2152
+ this.onBlurObservable.clear();
2153
+ this.onFocusObservable.clear();
2154
+ this.onKeyboardEventProcessedObservable.clear();
2067
2155
  if (this._styleObserver && this._style) {
2068
2156
  this._style.onChangedObservable.remove(this._styleObserver);
2069
2157
  this._styleObserver = null;