UNPKG

@babylonjs/gui

Version:

Babylon.js GUI module =====================

579 lines 20.5 kB
import { Rectangle } from "./rectangle.js"; import { StackPanel } from "./stackPanel.js"; import { Control } from "./control.js"; import { TextBlock } from "./textBlock.js"; import { Checkbox } from "./checkbox.js"; import { RadioButton } from "./radioButton.js"; import { Slider } from "./sliders/slider.js"; import { Container } from "./container.js"; /** Class used to create a RadioGroup * which contains groups of radio buttons */ export class SelectorGroup { /** * Creates a new SelectorGroup * @param name of group, used as a group heading */ constructor( /** name of SelectorGroup */ name) { this.name = name; this._groupPanel = new StackPanel(); this._selectors = []; this._groupPanel.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP; this._groupPanel.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT; this._groupHeader = this._addGroupHeader(name); } /** Gets the groupPanel of the SelectorGroup */ get groupPanel() { return this._groupPanel; } /** Gets the selectors array */ get selectors() { return this._selectors; } /** Gets and sets the group header */ get header() { return this._groupHeader.text; } set header(label) { if (this._groupHeader.text === "label") { return; } this._groupHeader.text = label; } /** * @internal */ _addGroupHeader(text) { const groupHeading = new TextBlock("groupHead", text); groupHeading.width = 0.9; groupHeading.height = "30px"; groupHeading.textWrapping = true; groupHeading.color = "black"; groupHeading.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT; groupHeading.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT; groupHeading.left = "2px"; this._groupPanel.addControl(groupHeading); return groupHeading; } /** * @internal */ _getSelector(selectorNb) { if (selectorNb < 0 || selectorNb >= this._selectors.length) { return; } return this._selectors[selectorNb]; } /** Removes the selector at the given position * @param selectorNb the position of the selector within the group */ removeSelector(selectorNb) { if (selectorNb < 0 || selectorNb >= this._selectors.length) { return; } this._groupPanel.removeControl(this._selectors[selectorNb]); this._selectors.splice(selectorNb, 1); } } /** Class used to create a CheckboxGroup * which contains groups of checkbox buttons */ export class CheckboxGroup extends SelectorGroup { /** Adds a checkbox as a control * @param text is the label for the selector * @param func is the function called when the Selector is checked * @param checked is true when Selector is checked */ // eslint-disable-next-line @typescript-eslint/no-unused-vars addCheckbox(text, func = (s) => { }, checked = false) { checked = checked || false; const button = new Checkbox(); button.width = "20px"; button.height = "20px"; button.color = "#364249"; button.background = "#CCCCCC"; button.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT; button.onIsCheckedChangedObservable.add(function (state) { func(state); }); const _selector = Control.AddHeader(button, text, "200px", { isHorizontal: true, controlFirst: true }); _selector.height = "30px"; _selector.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT; _selector.left = "4px"; this.groupPanel.addControl(_selector); this.selectors.push(_selector); button.isChecked = checked; if (this.groupPanel.parent && this.groupPanel.parent.parent) { button.color = this.groupPanel.parent.parent.buttonColor; button.background = this.groupPanel.parent.parent.buttonBackground; } } /** * @internal */ _setSelectorLabel(selectorNb, label) { this.selectors[selectorNb].children[1].text = label; } /** * @internal */ _setSelectorLabelColor(selectorNb, color) { this.selectors[selectorNb].children[1].color = color; } /** * @internal */ _setSelectorButtonColor(selectorNb, color) { this.selectors[selectorNb].children[0].color = color; } /** * @internal */ _setSelectorButtonBackground(selectorNb, color) { this.selectors[selectorNb].children[0].background = color; } } /** Class used to create a RadioGroup * which contains groups of radio buttons */ export class RadioGroup extends SelectorGroup { constructor() { super(...arguments); this._selectNb = 0; } /** Adds a radio button as a control * @param label is the label for the selector * @param func is the function called when the Selector is checked * @param checked is true when Selector is checked */ // eslint-disable-next-line @typescript-eslint/no-unused-vars addRadio(label, func = (n) => { }, checked = false) { const nb = this._selectNb++; const button = new RadioButton(); button.name = label; button.width = "20px"; button.height = "20px"; button.color = "#364249"; button.background = "#CCCCCC"; button.group = this.name; button.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT; button.onIsCheckedChangedObservable.add(function (state) { if (state) { func(nb); } }); const _selector = Control.AddHeader(button, label, "200px", { isHorizontal: true, controlFirst: true }); _selector.height = "30px"; _selector.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT; _selector.left = "4px"; this.groupPanel.addControl(_selector); this.selectors.push(_selector); button.isChecked = checked; if (this.groupPanel.parent && this.groupPanel.parent.parent) { button.color = this.groupPanel.parent.parent.buttonColor; button.background = this.groupPanel.parent.parent.buttonBackground; } } /** * @internal */ _setSelectorLabel(selectorNb, label) { this.selectors[selectorNb].children[1].text = label; } /** * @internal */ _setSelectorLabelColor(selectorNb, color) { this.selectors[selectorNb].children[1].color = color; } /** * @internal */ _setSelectorButtonColor(selectorNb, color) { this.selectors[selectorNb].children[0].color = color; } /** * @internal */ _setSelectorButtonBackground(selectorNb, color) { this.selectors[selectorNb].children[0].background = color; } } /** Class used to create a SliderGroup * which contains groups of slider buttons */ export class SliderGroup extends SelectorGroup { /** * Adds a slider to the SelectorGroup * @param label is the label for the SliderBar * @param func is the function called when the Slider moves * @param unit is a string describing the units used, eg degrees or metres * @param min is the minimum value for the Slider * @param max is the maximum value for the Slider * @param value is the start value for the Slider between min and max * @param onValueChange is the function used to format the value displayed, eg radians to degrees */ addSlider(label, // eslint-disable-next-line @typescript-eslint/no-unused-vars func = (v) => { }, unit = "Units", min = 0, max = 0, value = 0, onValueChange = (v) => { return v | 0; }) { const button = new Slider(); button.name = unit; button.value = value; button.minimum = min; button.maximum = max; button.width = 0.9; button.height = "20px"; button.color = "#364249"; button.background = "#CCCCCC"; button.borderColor = "black"; button.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT; button.left = "4px"; button.paddingBottom = "4px"; button.onValueChangedObservable.add(function (value) { button.parent.children[0].text = button.parent.children[0].name + ": " + onValueChange(value) + " " + button.name; func(value); }); const _selector = Control.AddHeader(button, label + ": " + onValueChange(value) + " " + unit, "30px", { isHorizontal: false, controlFirst: false }); _selector.height = "60px"; _selector.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT; _selector.left = "4px"; _selector.children[0].name = label; this.groupPanel.addControl(_selector); this.selectors.push(_selector); if (this.groupPanel.parent && this.groupPanel.parent.parent) { button.color = this.groupPanel.parent.parent.buttonColor; button.background = this.groupPanel.parent.parent.buttonBackground; } } /** * @internal */ _setSelectorLabel(selectorNb, label) { this.selectors[selectorNb].children[0].name = label; this.selectors[selectorNb].children[0].text = label + ": " + this.selectors[selectorNb].children[1].value + " " + this.selectors[selectorNb].children[1].name; } /** * @internal */ _setSelectorLabelColor(selectorNb, color) { this.selectors[selectorNb].children[0].color = color; } /** * @internal */ _setSelectorButtonColor(selectorNb, color) { this.selectors[selectorNb].children[1].color = color; } /** * @internal */ _setSelectorButtonBackground(selectorNb, color) { this.selectors[selectorNb].children[1].background = color; } } /** Class used to hold the controls for the checkboxes, radio buttons and sliders * @see https://doc.babylonjs.com/features/featuresDeepDive/gui/selector */ export class SelectionPanel extends Rectangle { /** * Creates a new SelectionPanel * @param name of SelectionPanel * @param groups is an array of SelectionGroups */ constructor( /** name of SelectionPanel */ name, /** an array of SelectionGroups */ groups = []) { super(name); this.name = name; this.groups = groups; this._buttonColor = "#364249"; this._buttonBackground = "#CCCCCC"; this._headerColor = "black"; this._barColor = "white"; this._barHeight = "2px"; this._spacerHeight = "20px"; this._bars = []; this._groups = groups; this.thickness = 2; this._panel = new StackPanel(); this._panel.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP; this._panel.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT; this._panel.top = 5; this._panel.left = 5; this._panel.width = 0.95; if (groups.length > 0) { for (let i = 0; i < groups.length - 1; i++) { this._panel.addControl(groups[i].groupPanel); this._addSpacer(); } this._panel.addControl(groups[groups.length - 1].groupPanel); } this.addControl(this._panel); } _getTypeName() { return "SelectionPanel"; } /** Gets the (stack) panel of the SelectionPanel */ get panel() { return this._panel; } /** Gets or sets the headerColor */ get headerColor() { return this._headerColor; } set headerColor(color) { if (this._headerColor === color) { return; } this._headerColor = color; this._setHeaderColor(); } _setHeaderColor() { for (let i = 0; i < this._groups.length; i++) { this._groups[i].groupPanel.children[0].color = this._headerColor; } } /** Gets or sets the button color */ get buttonColor() { return this._buttonColor; } set buttonColor(color) { if (this._buttonColor === color) { return; } this._buttonColor = color; this._setbuttonColor(); } _setbuttonColor() { for (let i = 0; i < this._groups.length; i++) { for (let j = 0; j < this._groups[i].selectors.length; j++) { this._groups[i]._setSelectorButtonColor(j, this._buttonColor); } } } /** Gets or sets the label color */ get labelColor() { return this._labelColor; } set labelColor(color) { if (this._labelColor === color) { return; } this._labelColor = color; this._setLabelColor(); } _setLabelColor() { for (let i = 0; i < this._groups.length; i++) { for (let j = 0; j < this._groups[i].selectors.length; j++) { this._groups[i]._setSelectorLabelColor(j, this._labelColor); } } } /** Gets or sets the button background */ get buttonBackground() { return this._buttonBackground; } set buttonBackground(color) { if (this._buttonBackground === color) { return; } this._buttonBackground = color; this._setButtonBackground(); } _setButtonBackground() { for (let i = 0; i < this._groups.length; i++) { for (let j = 0; j < this._groups[i].selectors.length; j++) { this._groups[i]._setSelectorButtonBackground(j, this._buttonBackground); } } } /** Gets or sets the color of separator bar */ get barColor() { return this._barColor; } set barColor(color) { if (this._barColor === color) { return; } this._barColor = color; this._setBarColor(); } _setBarColor() { for (let i = 0; i < this._bars.length; i++) { this._bars[i].children[0].background = this._barColor; } } /** Gets or sets the height of separator bar */ get barHeight() { return this._barHeight; } set barHeight(value) { if (this._barHeight === value) { return; } this._barHeight = value; this._setBarHeight(); } _setBarHeight() { for (let i = 0; i < this._bars.length; i++) { this._bars[i].children[0].height = this._barHeight; } } /** Gets or sets the height of spacers*/ get spacerHeight() { return this._spacerHeight; } set spacerHeight(value) { if (this._spacerHeight === value) { return; } this._spacerHeight = value; this._setSpacerHeight(); } _setSpacerHeight() { for (let i = 0; i < this._bars.length; i++) { this._bars[i].height = this._spacerHeight; } } /** Adds a bar between groups */ _addSpacer() { const separator = new Container(); separator.width = 1; separator.height = this._spacerHeight; separator.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT; const bar = new Rectangle(); bar.width = 1; bar.height = this._barHeight; bar.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT; bar.verticalAlignment = Control.VERTICAL_ALIGNMENT_CENTER; bar.background = this._barColor; bar.color = "transparent"; separator.addControl(bar); this._panel.addControl(separator); this._bars.push(separator); } /** Add a group to the selection panel * @param group is the selector group to add */ addGroup(group) { if (this._groups.length > 0) { this._addSpacer(); } this._panel.addControl(group.groupPanel); this._groups.push(group); group.groupPanel.children[0].color = this._headerColor; for (let j = 0; j < group.selectors.length; j++) { group._setSelectorButtonColor(j, this._buttonColor); group._setSelectorButtonBackground(j, this._buttonBackground); } } /** Remove the group from the given position * @param groupNb is the position of the group in the list */ removeGroup(groupNb) { if (groupNb < 0 || groupNb >= this._groups.length) { return; } const group = this._groups[groupNb]; this._panel.removeControl(group.groupPanel); this._groups.splice(groupNb, 1); if (groupNb < this._bars.length) { this._panel.removeControl(this._bars[groupNb]); this._bars.splice(groupNb, 1); } } /** Change a group header label * @param label is the new group header label * @param groupNb is the number of the group to relabel * */ setHeaderName(label, groupNb) { if (groupNb < 0 || groupNb >= this._groups.length) { return; } const group = this._groups[groupNb]; group.groupPanel.children[0].text = label; } /** Change selector label to the one given * @param label is the new selector label * @param groupNb is the number of the groupcontaining the selector * @param selectorNb is the number of the selector within a group to relabel * */ relabel(label, groupNb, selectorNb) { if (groupNb < 0 || groupNb >= this._groups.length) { return; } const group = this._groups[groupNb]; if (selectorNb < 0 || selectorNb >= group.selectors.length) { return; } group._setSelectorLabel(selectorNb, label); } /** For a given group position remove the selector at the given position * @param groupNb is the number of the group to remove the selector from * @param selectorNb is the number of the selector within the group */ removeFromGroupSelector(groupNb, selectorNb) { if (groupNb < 0 || groupNb >= this._groups.length) { return; } const group = this._groups[groupNb]; if (selectorNb < 0 || selectorNb >= group.selectors.length) { return; } group.removeSelector(selectorNb); } /** For a given group position of correct type add a checkbox button * @param groupNb is the number of the group to remove the selector from * @param label is the label for the selector * @param func is the function called when the Selector is checked * @param checked is true when Selector is checked */ addToGroupCheckbox(groupNb, label, func = () => { }, checked = false) { if (groupNb < 0 || groupNb >= this._groups.length) { return; } const group = this._groups[groupNb]; group.addCheckbox(label, func, checked); } /** For a given group position of correct type add a radio button * @param groupNb is the number of the group to remove the selector from * @param label is the label for the selector * @param func is the function called when the Selector is checked * @param checked is true when Selector is checked */ addToGroupRadio(groupNb, label, func = () => { }, checked = false) { if (groupNb < 0 || groupNb >= this._groups.length) { return; } const group = this._groups[groupNb]; group.addRadio(label, func, checked); } /** * For a given slider group add a slider * @param groupNb is the number of the group to add the slider to * @param label is the label for the Slider * @param func is the function called when the Slider moves * @param unit is a string describing the units used, eg degrees or metres * @param min is the minimum value for the Slider * @param max is the maximum value for the Slider * @param value is the start value for the Slider between min and max * @param onVal is the function used to format the value displayed, eg radians to degrees */ addToGroupSlider(groupNb, label, func = () => { }, unit = "Units", min = 0, max = 0, value = 0, onVal = (v) => { return v | 0; }) { if (groupNb < 0 || groupNb >= this._groups.length) { return; } const group = this._groups[groupNb]; group.addSlider(label, func, unit, min, max, value, onVal); } } //# sourceMappingURL=selector.js.map