selector.ts 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382
  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. /**
  9. * Class used to store Selector properties
  10. */
  11. export class Selector {
  12. /** Text used for label */
  13. private _text: string;
  14. /** Function called when selected */
  15. private _func: () => any;
  16. /** whether checked or not */
  17. private _checked: boolean;
  18. /** position in array */
  19. private _nb: number;
  20. /**
  21. * Creates a new Selector
  22. * @param text is the label for the selector
  23. * @param func is the function called when the Selector is checked
  24. * @param checked is true when Selector is checked
  25. * @param nb is the position of the Selector in the SelectionGroup it is added to
  26. */
  27. constructor(text:string, func: ()=> any, checked:boolean, nb: number) {
  28. this._text = text;
  29. this._func = func;
  30. this._checked = checked;
  31. this._nb = nb;
  32. }
  33. /** Gets the text */
  34. public get text(): string {
  35. return this._text;
  36. }
  37. /** Gets the function that is called when checked */
  38. public get func(): ()=>any {
  39. return this._func;
  40. }
  41. /** Gets the checked value */
  42. public get checked(): boolean {
  43. return this._checked;
  44. }
  45. /** Gets the position number */
  46. public get nb(): number {
  47. return this._nb;
  48. }
  49. }
  50. /**
  51. * Class used to store SliderBar properties
  52. */
  53. export class SliderBar{
  54. /** Text used for label */
  55. private _text: string;
  56. /** Function called when selected */
  57. private _func: () => any;
  58. /** unit name, eg degrees, metres, etc */
  59. private _unit: string;
  60. /** Function to format value */
  61. private _onVal: (v:number)=> any;
  62. /** Minimum of value range */
  63. private _min: number;
  64. /** Maximum of value range */
  65. private _max: number;
  66. /** starting value */
  67. private _value: number;
  68. /**
  69. * Creates a new SliderBar
  70. * @param text is the label for the SliderBar
  71. * @param func is the function called when the Slider moves
  72. * @param unit is a string describing the units used, eg degrees or metres
  73. * @param onVal is the function used to format the value displayed, eg radians to degrees
  74. * @param min is the minimum value for the Slider
  75. * @param max is the maximum value for the Slider
  76. * @param value is the start value for the Slider between min and max
  77. */
  78. constructor(text:string, func: ()=> any, unit: string, onVal: (v:number)=> any, min: number, max: number, value: number) {
  79. this._text = text;
  80. this._func = func;
  81. this._unit = unit;
  82. this._onVal = onVal;
  83. this._min = min;
  84. this._max = max;
  85. this._value = value;
  86. }
  87. /** Gets the text */
  88. public get text(): string {
  89. return this._text;
  90. }
  91. /** Gets the function that is called when slider moves */
  92. public get func(): ()=>any {
  93. return this._func;
  94. }
  95. /** Gets the function used to format the value of the slider */
  96. public get onVal(): (v: number)=>any {
  97. return this._onVal;
  98. }
  99. /** Gets the units used */
  100. public get unit(): string {
  101. return this._unit;
  102. }
  103. /** Gets the min value */
  104. public get min(): number {
  105. return this._min;
  106. }
  107. /** Gets the max value */
  108. public get max(): number {
  109. return this._max;
  110. }
  111. /** Gets the current value */
  112. public get value(): number {
  113. return this._value;
  114. }
  115. }
  116. /** Class used to create a SelectorGroup
  117. * which contains groups of checkboxes, radio buttons and sliders
  118. */
  119. export class SelectorGroup {
  120. private _selectors: any[] = new Array();
  121. private _selectNb = 0;
  122. /**
  123. * Creates a new SelectorGroup
  124. * @param name of group, used as a heading
  125. * @param type specifies a check box, radio button or slider grouping
  126. */
  127. constructor(public name: string, public type: string) {
  128. if (type === void 0) { type = "C"; }
  129. type = type.substr(0,1).toUpperCase();
  130. if(type !="R") {
  131. if(type != "S") {
  132. if(type != "C") {
  133. type = "C";
  134. }
  135. }
  136. }
  137. }
  138. /** Gets selectors array */
  139. public get selectors(): any[] {
  140. return this._selectors
  141. }
  142. /** Gets position */
  143. public get selectNb(): number {
  144. return this._selectNb
  145. }
  146. /** Adds a checkbox or radio button to the SelectorGroup
  147. * @param text is the label for the selector
  148. * @param func is the function called when the Selector is checked
  149. * @param checked is true when Selector is checked
  150. */
  151. public addSelector(text?: string, func?: () => any , checked?: boolean): void {
  152. if (text === void 0) { text = ""; }
  153. if (func === void 0) { func = function(){}; }
  154. if (checked === void 0) { checked = false; }
  155. let selector = new Selector(text, func, checked, this._selectNb);
  156. this.selectors.push(selector);
  157. if(this.type === "R") {
  158. this._selectNb++;
  159. }
  160. };
  161. /**
  162. * Adds a slider to the SelectorGroup
  163. * @param text is the label for the SliderBar
  164. * @param func is the function called when the Slider moves
  165. * @param unit is a string describing the units used, eg degrees or metres
  166. * @param min is the minimum value for the Slider
  167. * @param max is the maximum value for the Slider
  168. * @param value is the start value for the Slider between min and max
  169. * @param onVal is the function used to format the value displayed, eg radians to degrees
  170. */
  171. public addSlider(text?: string, func?: () => any, unit?: string, min?: number, max?: number, value?: number, onVal?: (v:number)=>number) {
  172. if (text === void 0) { text = ""; }
  173. if (func === void 0) { func = function(){}; }
  174. if (unit === void 0) { unit = "Units"; }
  175. if (onVal === void 0) { onVal = function(v: number){return v | 0}; }
  176. if (min === void 0) { min = 0; }
  177. if (max === void 0) { max = 100; }
  178. if (value === void 0) { value = 0; }
  179. let slider_bar = new SliderBar(text, func, unit, onVal, min, max, value);
  180. this.selectors.push(slider_bar);
  181. };
  182. }
  183. /** Class used to hold the controls for the checkboxes, radio buttons and sliders */
  184. export class SelectionPanel extends Rectangle {
  185. private _panel: StackPanel;
  186. /**
  187. * Creates a new SelectorGroup
  188. * @param name of SelectionPanel
  189. * @param groups is an array of SelectionGroups
  190. */
  191. constructor(public name: string, public groups: SelectorGroup[]) {
  192. super(name);
  193. this.color = "black";
  194. this.thickness = 4;
  195. this.background = "white";
  196. this._panel = new StackPanel();
  197. this._panel.verticalAlignment = Control.VERTICAL_ALIGNMENT_TOP;
  198. this._panel.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  199. this._panel.top = 5;
  200. this._panel.left = 5;
  201. this._addGroupHeader(groups[0].name);
  202. this._addGroup(groups[0]);
  203. for(var i = 1; i < groups.length; i++) {
  204. this._addSpacer(groups[i].name);
  205. this._addGroup(groups[i]);
  206. }
  207. this.addControl(this._panel);
  208. return this;
  209. }
  210. /** Adds the given group to the SelectionPanel
  211. * @param group, the SelectionGroup to be added
  212. */
  213. protected _addGroup(group: SelectorGroup) {
  214. if(group.type === "R") {
  215. for(var i = 0; i < group.selectors.length; i++) {
  216. this._addRadio(group.selectors[i].text, group.selectors[i].nb, group.name, group.selectors[i].func, group.selectors[i].checked);
  217. }
  218. }
  219. else if(group.type === "S") {
  220. this._panel.width = 1;
  221. for(var i = 0; i < group.selectors.length; i++) {
  222. this._addSldr(group.selectors[i].text, group.selectors[i].func, group.selectors[i].unit, group.selectors[i].min, group.selectors[i].max, group.selectors[i].value, group.selectors[i].onVal);
  223. }
  224. }
  225. else {
  226. for(var i = 0; i < group.selectors.length; i++) {
  227. this._addCheckbox(group.selectors[i].text, group.selectors[i].func, group.selectors[i].checked);
  228. }
  229. }
  230. }
  231. /** Adds a heading to the group
  232. * @param name is used as heading
  233. */
  234. protected _addGroupHeader(name: string) {
  235. var groupHeading = new TextBlock("groupHead", name);
  236. groupHeading.width = 0.9;
  237. groupHeading.height = "30px";
  238. groupHeading.textWrapping = true;
  239. groupHeading.color = "black";
  240. groupHeading.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  241. groupHeading.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  242. groupHeading.left = "2px";
  243. this._panel.addControl(groupHeading);
  244. }
  245. /** Adds a bar between groups
  246. * @param name is used as heading for the group after the bar
  247. */
  248. protected _addSpacer(name: string) {
  249. var separator = new Rectangle();
  250. separator.width = 0.9;
  251. separator.height = "2px";
  252. separator.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  253. separator.background = "#364249";
  254. separator.color = "#364249";
  255. this._panel.addControl(separator);
  256. this._addGroupHeader(name);
  257. }
  258. /** Adds a checkbox as a control
  259. * @param text is the label for the selector
  260. * @param func is the function called when the Selector is checked
  261. * @param checked is true when Selector is checked
  262. */
  263. protected _addCheckbox(text: string, func: (s: any)=>any, checked: boolean) {
  264. var checked = checked || false;
  265. var button = new Checkbox();
  266. button.width = "20px";
  267. button.height = "20px";
  268. button.color = "#364249";
  269. button.background = "white";
  270. button.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  271. button.onIsCheckedChangedObservable.add(function(state) {
  272. func(state);
  273. });
  274. var header = Control.AddHeader(button, text, "200px", { isHorizontal: true, controlFirst: true });
  275. header.height = "30px";
  276. header.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  277. header.left = "4px";
  278. this._panel.addControl(header);
  279. button.isChecked = checked;
  280. }
  281. /** Adds a radio button as a control
  282. * @param text is the label for the selector
  283. * @param func is the function called when the Selector is checked
  284. * @param checked is true when Selector is checked
  285. */
  286. protected _addRadio(text: string, nb: number, name: string, func: (n: number)=>any, checked: boolean) {
  287. checked = checked || false;
  288. var button = new RadioButton();
  289. button.name = text;
  290. button.width = "20px";
  291. button.height = "20px";
  292. button.color = "#364249";
  293. button.background = "white";
  294. button.group = name;
  295. button.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  296. button.onIsCheckedChangedObservable.add(function(state) {
  297. if(state) {
  298. func(nb);
  299. }
  300. });
  301. var header = Control.AddHeader(button, text, "200px", { isHorizontal: true, controlFirst: true });
  302. header.height = "30px";
  303. header.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  304. header.left = "4px";
  305. this._panel.addControl(header);
  306. button.isChecked = checked;
  307. }
  308. /**
  309. * Adds a slider as a control
  310. * @param text is the label for the SliderBar
  311. * @param func is the function called when the Slider moves
  312. * @param unit is a string describing the units used, eg degrees or metres
  313. * @param min is the minimum value for the Slider
  314. * @param max is the maximum value for the Slider
  315. * @param value is the start value for the Slider between min and max
  316. * @param onVal is the function used to format the value displayed, eg radians to degrees
  317. */
  318. protected _addSldr(text: string, func: (v: any)=>any, unit: string, min: number, max:number, value: number, onValueChange: (v: number)=>number) {
  319. var button = new Slider();
  320. button.value = value;
  321. button.minimum = min;
  322. button.maximum = max;
  323. button.width = "0.9";
  324. button.height = "20px";
  325. button.color = "#364249";
  326. button.background = "#CCCCCC";
  327. button.borderColor = "black";
  328. button.horizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  329. button.left = "4px";
  330. var header = new TextBlock();
  331. header.text = text+": " + value + " " + unit;
  332. header.height = "30px";
  333. header.color = "black";
  334. header.textHorizontalAlignment = Control.HORIZONTAL_ALIGNMENT_LEFT;
  335. header.left = "4px";
  336. this._panel.addControl(header);
  337. button.onValueChangedObservable.add(function(value) {
  338. header.text = text + ": " + onValueChange(value) + " " + unit;
  339. func(value);
  340. });
  341. this._panel.addControl(button);
  342. }
  343. }