selector.ts 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568
  1. import {Rectangle} from "./rectangle";
  2. import {StackPanel} from "./stackPanel";
  3. import {Control} from "./control";
  4. import {TextBlock} from "./textBlock";
  5. import {Checkbox} from "./checkbox";
  6. import {RadioButton} from "./radioButton";
  7. import {Slider} from "./slider";
  8. /** Class used to create a RadioGroup
  9. * which contains groups of radio buttons
  10. */
  11. export class SelectorGroup {
  12. private _groupPanel = new StackPanel();
  13. private _selectors: StackPanel[] = new Array();
  14. private _groupHeader: TextBlock;
  15. /**
  16. * Creates a new SelectorGroup
  17. * @param name of group, used as a group heading
  18. */
  19. constructor(
  20. /** name of SelectorGroup */
  21. public name: string, ) {
  22. this._groupPanel.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
  23. this._groupPanel.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  24. this._groupHeader = this._addGroupHeader(name);
  25. }
  26. /** Gets the groupPanel of the SelectorGroup */
  27. public get groupPanel(): StackPanel {
  28. return this._groupPanel;
  29. }
  30. /** Gets the selectors array */
  31. public get selectors(): StackPanel[] {
  32. return this._selectors;
  33. }
  34. /** Gets and sets the group header */
  35. public get header() {
  36. return this._groupHeader.text;
  37. }
  38. public set header(label: string) {
  39. if(this._groupHeader.text === "label") {
  40. return
  41. }
  42. this._groupHeader.text = label
  43. }
  44. /** @hidden */
  45. private _addGroupHeader(text: string): TextBlock {
  46. var groupHeading = new TextBlock("groupHead", text);
  47. groupHeading.width = 0.9;
  48. groupHeading.height = "30px";
  49. groupHeading.textWrapping = true;
  50. groupHeading.color = "black";
  51. groupHeading.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  52. groupHeading.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  53. groupHeading.left = "2px";
  54. this._groupPanel.addControl(groupHeading);
  55. return groupHeading;
  56. }
  57. /** @hidden*/
  58. public _getSelector(selectorNb: number) {
  59. if(selectorNb < 0 || selectorNb >= this._selectors.length) {
  60. return;
  61. }
  62. return this._selectors[selectorNb];
  63. }
  64. /** Removes the selector at the given position
  65. * @param selectorNb the position of the selector within the group
  66. */
  67. public removeSelector(selectorNb: number) {
  68. if(selectorNb < 0 || selectorNb >= this._selectors.length) {
  69. return;
  70. }
  71. this._groupPanel.removeControl(this._selectors[selectorNb]);
  72. this._selectors.splice(selectorNb, 1);
  73. }
  74. }
  75. /** Class used to create a CheckboxGroup
  76. * which contains groups of checkbox buttons
  77. */
  78. export class CheckboxGroup extends SelectorGroup{
  79. /** Adds a checkbox as a control
  80. * @param text is the label for the selector
  81. * @param func is the function called when the Selector is checked
  82. * @param checked is true when Selector is checked
  83. */
  84. public addCheckbox(text: string, func = (s: boolean)=>{}, checked: boolean = false): void {
  85. var checked = checked || false;
  86. var button = new Checkbox();
  87. button.width = "20px";
  88. button.height = "20px";
  89. button.color = "#364249";
  90. button.background = "#CCCCCC";
  91. button.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  92. button.onIsCheckedChangedObservable.add(function(state) {
  93. func(state);
  94. });
  95. var _selector = Control.AddHeader(button, text, "200px", { isHorizontal: true, controlFirst: true });
  96. _selector.height = "30px";
  97. _selector.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  98. _selector.left = "4px";
  99. this.groupPanel.addControl(_selector);
  100. this.selectors.push(_selector);
  101. button.isChecked = checked;
  102. if(this.groupPanel.parent && this.groupPanel.parent.parent) {
  103. button.color = (<SelectionPanel>this.groupPanel.parent.parent).buttonColor;
  104. button.background = (<SelectionPanel>this.groupPanel.parent.parent).buttonBackground;
  105. }
  106. }
  107. /** @hidden */
  108. public _setSelectorLabel(selectorNb: number, label: string) {
  109. (<TextBlock>this.selectors[selectorNb].children[1]).text = label;
  110. }
  111. /** @hidden */
  112. public _setSelectorLabelColor(selectorNb: number, color: string) {
  113. (<TextBlock>this.selectors[selectorNb].children[1]).color = color;
  114. }
  115. /** @hidden */
  116. public _setSelectorButtonColor(selectorNb: number, color: string) {
  117. this.selectors[selectorNb].children[0].color = color;
  118. }
  119. /** @hidden */
  120. public _setSelectorButtonBackground(selectorNb: number, color: string) {
  121. (<Checkbox>this.selectors[selectorNb].children[0]).background = color;
  122. }
  123. }
  124. /** Class used to create a RadioGroup
  125. * which contains groups of radio buttons
  126. */
  127. export class RadioGroup extends SelectorGroup{
  128. private _selectNb = 0;
  129. /** Adds a radio button as a control
  130. * @param label is the label for the selector
  131. * @param func is the function called when the Selector is checked
  132. * @param checked is true when Selector is checked
  133. */
  134. public addRadio(label: string, func = (n:number) => {} , checked = false): void {
  135. var nb = this._selectNb++;
  136. var button = new RadioButton();
  137. button.name = label;
  138. button.width = "20px";
  139. button.height = "20px";
  140. button.color = "#364249";
  141. button.background = "#CCCCCC";
  142. button.group = this.name;
  143. button.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  144. button.onIsCheckedChangedObservable.add(function(state) {
  145. if(state) {
  146. func(nb);
  147. }
  148. });
  149. var _selector = Control.AddHeader(button, label, "200px", { isHorizontal: true, controlFirst: true });
  150. _selector.height = "30px";
  151. _selector.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  152. _selector.left = "4px";
  153. this.groupPanel.addControl(_selector);
  154. this.selectors.push(_selector);
  155. button.isChecked = checked;
  156. if(this.groupPanel.parent && this.groupPanel.parent.parent) {
  157. button.color = (<SelectionPanel>this.groupPanel.parent.parent).buttonColor;
  158. button.background = (<SelectionPanel>this.groupPanel.parent.parent).buttonBackground;
  159. }
  160. }
  161. /** @hidden */
  162. public _setSelectorLabel(selectorNb: number, label: string) {
  163. (<TextBlock>this.selectors[selectorNb].children[1]).text = label;
  164. }
  165. /** @hidden */
  166. public _setSelectorLabelColor(selectorNb: number, color: string) {
  167. (<TextBlock>this.selectors[selectorNb].children[1]).color = color;
  168. }
  169. /** @hidden */
  170. public _setSelectorButtonColor(selectorNb: number, color: string) {
  171. this.selectors[selectorNb].children[0].color = color;
  172. }
  173. /** @hidden */
  174. public _setSelectorButtonBackground(selectorNb: number, color: string) {
  175. (<RadioButton>this.selectors[selectorNb].children[0]).background = color;
  176. }
  177. }
  178. /** Class used to create a SliderGroup
  179. * which contains groups of slider buttons
  180. */
  181. export class SliderGroup extends SelectorGroup{
  182. /**
  183. * Adds a slider to the SelectorGroup
  184. * @param label is the label for the SliderBar
  185. * @param func is the function called when the Slider moves
  186. * @param unit is a string describing the units used, eg degrees or metres
  187. * @param min is the minimum value for the Slider
  188. * @param max is the maximum value for the Slider
  189. * @param value is the start value for the Slider between min and max
  190. * @param onValueChange is the function used to format the value displayed, eg radians to degrees
  191. */
  192. public addSlider(label: string, func = (v:number) => {}, unit: string = "Units", min: number = 0, max: number = 0, value: number = 0, onValueChange = (v:number)=>{return v | 0}): void {
  193. var button = new Slider();
  194. button.name = unit;
  195. button.value = value;
  196. button.minimum = min;
  197. button.maximum = max;
  198. button.width = 0.9;
  199. button.height = "20px";
  200. button.color = "#364249";
  201. button.background = "#CCCCCC";
  202. button.borderColor = "black";
  203. button.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  204. button.left = "4px";
  205. button.paddingBottom = "4px";
  206. button.onValueChangedObservable.add(function(value) {
  207. (<TextBlock>button.parent!.children[0]).text = button.parent!.children[0].name + ": " + onValueChange(value) + " " + button.name;
  208. func(value);
  209. });
  210. var _selector = Control.AddHeader(button, label + ": " + onValueChange(value) + " " + unit, "30px", { isHorizontal: false, controlFirst: false });
  211. _selector.height = "60px";
  212. _selector.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  213. _selector.left = "4px";
  214. _selector.children[0].name = label;
  215. this.groupPanel.addControl(_selector);
  216. this.selectors.push(_selector);
  217. if(this.groupPanel.parent && this.groupPanel.parent.parent) {
  218. button.color = (<SelectionPanel>this.groupPanel.parent.parent).buttonColor;
  219. button.background = (<SelectionPanel>this.groupPanel.parent.parent).buttonBackground;
  220. }
  221. }
  222. /** @hidden */
  223. public _setSelectorLabel(selectorNb: number, label: string) {
  224. this.selectors[selectorNb].children[0].name = label;
  225. (<TextBlock>this.selectors[selectorNb].children[0]).text = label + ": " + (<Slider>this.selectors[selectorNb].children[1]).value + " " + this.selectors[selectorNb].children[1].name;
  226. }
  227. /** @hidden */
  228. public _setSelectorLabelColor(selectorNb: number, color: string) {
  229. (<TextBlock>this.selectors[selectorNb].children[0]).color = color;
  230. }
  231. /** @hidden */
  232. public _setSelectorButtonColor(selectorNb: number, color: string) {
  233. this.selectors[selectorNb].children[1].color = color;
  234. }
  235. /** @hidden */
  236. public _setSelectorButtonBackground(selectorNb: number, color: string) {
  237. (<Slider>this.selectors[selectorNb].children[1]).background = color;
  238. }
  239. }
  240. /** Class used to hold the controls for the checkboxes, radio buttons and sliders */
  241. export class SelectionPanel extends Rectangle {
  242. private _panel: StackPanel;
  243. private _buttonColor: string = "#364249";
  244. private _buttonBackground: string = "#CCCCCC";
  245. private _headerColor: string = "black";
  246. private _barColor: string = "white";
  247. private _labelColor: string;
  248. private _groups: SelectorGroup[];
  249. private _bars: any[] = new Array();
  250. /**
  251. * Creates a new SelectionPanel
  252. * @param name of SelectionPanel
  253. * @param groups is an array of SelectionGroups
  254. */
  255. constructor(
  256. /** name of SelectionPanel */
  257. public name: string,
  258. /** an array of SelectionGroups */
  259. public groups: SelectorGroup[] = []) {
  260. super(name);
  261. this._groups = groups;
  262. this.thickness = 4;
  263. this._panel = new StackPanel();
  264. this._panel.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
  265. this._panel.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  266. this._panel.top = 5;
  267. this._panel.left = 5;
  268. this._panel.width = 0.95;
  269. if(groups.length > 0) {
  270. for(var i = 0; i < groups.length - 1; i++) {
  271. this._panel.addControl(groups[i].groupPanel);
  272. this._addSpacer();
  273. }
  274. this._panel.addControl(groups[groups.length - 1].groupPanel);
  275. }
  276. this.addControl(this._panel);
  277. }
  278. protected _getTypeName(): string {
  279. return "SelectionPanel";
  280. }
  281. /** Gets or sets the headerColor */
  282. public get headerColor(): string {
  283. return this._headerColor;
  284. }
  285. public set headerColor(color: string) {
  286. if(this._headerColor === color) {
  287. return;
  288. }
  289. this._headerColor = color;
  290. this._setHeaderColor();
  291. }
  292. private _setHeaderColor() {
  293. for(var i = 0; i < this._groups.length; i++) {
  294. this._groups[i].groupPanel.children[0].color = this._headerColor;
  295. }
  296. }
  297. /** Gets or sets the button color */
  298. public get buttonColor(): string {
  299. return this._buttonColor;
  300. }
  301. public set buttonColor(color: string) {
  302. if(this._buttonColor === color) {
  303. return;
  304. }
  305. this._buttonColor = color;
  306. this._setbuttonColor();
  307. }
  308. private _setbuttonColor() {
  309. for(var i = 0; i < this._groups.length; i++) {
  310. for(var j = 0; j < this._groups[i].selectors.length; j++) {
  311. (<CheckboxGroup|RadioGroup|SliderGroup>this._groups[i])._setSelectorButtonColor(j, this._buttonColor);
  312. }
  313. }
  314. }
  315. /** Gets or sets the label color */
  316. public get labelColor(): string {
  317. return this._labelColor;
  318. }
  319. public set labelColor(color: string) {
  320. if(this._labelColor === color) {
  321. return;
  322. }
  323. this._labelColor = color;
  324. this._setLabelColor();
  325. }
  326. private _setLabelColor() {
  327. for(var i = 0; i < this._groups.length; i++) {
  328. for(var j = 0; j < this._groups[i].selectors.length; j++) {
  329. (<CheckboxGroup|RadioGroup|SliderGroup>this._groups[i])._setSelectorLabelColor(j, this._labelColor);
  330. }
  331. }
  332. }
  333. /** Gets or sets the button background */
  334. public get buttonBackground(): string {
  335. return this._buttonBackground;
  336. }
  337. public set buttonBackground(color: string) {
  338. if(this._buttonBackground === color) {
  339. return;
  340. }
  341. this._buttonBackground = color;
  342. this._setButtonBackground();
  343. }
  344. private _setButtonBackground() {
  345. for(var i = 0; i < this._groups.length; i++) {
  346. for(var j = 0; j < this._groups[i].selectors.length; j++) {
  347. (<CheckboxGroup|RadioGroup|SliderGroup>this._groups[i])._setSelectorButtonBackground(j, this._buttonBackground);
  348. }
  349. }
  350. }
  351. /** Gets or sets the color of separator bar */
  352. public get barColor(): string {
  353. return this._barColor;
  354. }
  355. public set barColor(color: string) {
  356. if(this._barColor === color) {
  357. return;
  358. }
  359. this._barColor = color;
  360. this._setBarColor();
  361. }
  362. private _setBarColor() {
  363. for(var i = 0; i < this._bars.length; i++) {
  364. this._bars[i].background = this._barColor;
  365. }
  366. }
  367. /** Adds a bar between groups */
  368. private _addSpacer(): void {
  369. var separator = new Rectangle();
  370. separator.width = 1;
  371. separator.height = "5px";
  372. separator.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  373. separator.background = this._barColor;
  374. separator.color = "transparent";
  375. this._panel.addControl(separator);
  376. this._bars.push(separator);
  377. }
  378. /** Add a group to the selection panel
  379. * @param group is the selector group to add
  380. */
  381. public addGroup(group: SelectorGroup): void {
  382. if(this._groups.length > 0) {
  383. this._addSpacer();
  384. }
  385. this._panel.addControl(group.groupPanel);
  386. this._groups.push(group);
  387. group.groupPanel.children[0].color = this._headerColor;
  388. for(var j = 0; j < group.selectors.length; j++) {
  389. (<CheckboxGroup|RadioGroup|SliderGroup>group)._setSelectorButtonColor(j, this._buttonColor);
  390. (<CheckboxGroup|RadioGroup|SliderGroup>group)._setSelectorButtonBackground(j, this._buttonBackground);
  391. }
  392. }
  393. /** Remove the group from the given position
  394. * @param groupNb is the position of the group in the list
  395. */
  396. public removeGroup(groupNb: number): void {
  397. if(groupNb < 0 || groupNb >= this._groups.length) {
  398. return;
  399. }
  400. var group = this._groups[groupNb];
  401. this._panel.removeControl(group.groupPanel);
  402. this._groups.splice(groupNb, 1);
  403. if(groupNb < this._bars.length) {
  404. this._panel.removeControl(this._bars[groupNb]);
  405. this._bars.splice(groupNb, 1);
  406. }
  407. }
  408. /** Change a group header label
  409. * @param label is the new group header label
  410. * @param groupNb is the number of the group to relabel
  411. * */
  412. public setHeaderName(label: string, groupNb: number) {
  413. if(groupNb < 0 || groupNb >= this._groups.length) {
  414. return;
  415. }
  416. var group = this._groups[groupNb];
  417. (<TextBlock>group.groupPanel.children[0]).text = label;
  418. }
  419. /** Change selector label to the one given
  420. * @param label is the new selector label
  421. * @param groupNb is the number of the groupcontaining the selector
  422. * @param selectorNb is the number of the selector within a group to relabel
  423. * */
  424. public relabel(label: string, groupNb: number, selectorNb: number): void {
  425. if(groupNb < 0 || groupNb >= this._groups.length) {
  426. return;
  427. }
  428. var group = this._groups[groupNb];
  429. if(selectorNb < 0 || selectorNb >= group.selectors.length) {
  430. return;
  431. }
  432. (<CheckboxGroup|RadioGroup|SliderGroup>group)._setSelectorLabel(selectorNb, label);
  433. }
  434. /** For a given group position remove the selector at the given position
  435. * @param groupNb is the number of the group to remove the selector from
  436. * @param selectorNb is the number of the selector within the group
  437. */
  438. public removeFromGroupSelector(groupNb: number, selectorNb: number): void {
  439. if(groupNb < 0 || groupNb >= this._groups.length) {
  440. return;
  441. }
  442. var group = this._groups[groupNb];
  443. if(selectorNb < 0 || selectorNb >= group.selectors.length) {
  444. return;
  445. }
  446. group.removeSelector(selectorNb);
  447. }
  448. /** For a given group position of correct type add a checkbox button
  449. * @param groupNb is the number of the group to remove the selector from
  450. * @param label is the label for the selector
  451. * @param func is the function called when the Selector is checked
  452. * @param checked is true when Selector is checked
  453. */
  454. public addToGroupCheckbox(groupNb: number, label: string, func = () => {} , checked: boolean = false): void {
  455. if(groupNb < 0 || groupNb >= this._groups.length) {
  456. return;
  457. }
  458. var group = this._groups[groupNb];
  459. (<CheckboxGroup>group).addCheckbox(label, func, checked);
  460. }
  461. /** For a given group position of correct type add a radio button
  462. * @param groupNb is the number of the group to remove the selector from
  463. * @param label is the label for the selector
  464. * @param func is the function called when the Selector is checked
  465. * @param checked is true when Selector is checked
  466. */
  467. public addToGroupRadio(groupNb: number, label: string, func = () => {} , checked: boolean = false): void {
  468. if(groupNb < 0 || groupNb >= this._groups.length) {
  469. return;
  470. }
  471. var group = this._groups[groupNb];
  472. (<RadioGroup>group).addRadio(label, func, checked);
  473. }
  474. /**
  475. * For a given slider group add a slider
  476. * @param groupNb is the number of the group to add the slider to
  477. * @param label is the label for the Slider
  478. * @param func is the function called when the Slider moves
  479. * @param unit is a string describing the units used, eg degrees or metres
  480. * @param min is the minimum value for the Slider
  481. * @param max is the maximum value for the Slider
  482. * @param value is the start value for the Slider between min and max
  483. * @param onVal is the function used to format the value displayed, eg radians to degrees
  484. */
  485. public addToGroupSlider(groupNb: number, label: string, func = () => {}, unit: string = "Units", min: number = 0, max: number = 0, value: number = 0, onVal = (v:number)=>{return v | 0}): void {
  486. if(groupNb < 0 || groupNb >= this._groups.length) {
  487. return;
  488. }
  489. var group = this._groups[groupNb];
  490. (<SliderGroup>group).addSlider(label, func, unit, min, max, value, onVal);
  491. }
  492. }