ui.js 18 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132
  1. /**
  2. * @author mrdoob / http://mrdoob.com/
  3. */
  4. var UI = {};
  5. UI.Element = function ( dom ) {
  6. this.dom = dom;
  7. };
  8. UI.Element.prototype = {
  9. add: function () {
  10. for ( var i = 0; i < arguments.length; i ++ ) {
  11. var argument = arguments[ i ];
  12. if ( argument instanceof UI.Element ) {
  13. this.dom.appendChild( argument.dom );
  14. } else {
  15. console.error( 'UI.Element:', argument, 'is not an instance of UI.Element.' );
  16. }
  17. }
  18. return this;
  19. },
  20. remove: function () {
  21. for ( var i = 0; i < arguments.length; i ++ ) {
  22. var argument = arguments[ i ];
  23. if ( argument instanceof UI.Element ) {
  24. this.dom.removeChild( argument.dom );
  25. } else {
  26. console.error( 'UI.Element:', argument, 'is not an instance of UI.Element.' );
  27. }
  28. }
  29. return this;
  30. },
  31. clear: function () {
  32. while ( this.dom.children.length ) {
  33. this.dom.removeChild( this.dom.lastChild );
  34. }
  35. },
  36. setId: function ( id ) {
  37. this.dom.id = id;
  38. return this;
  39. },
  40. setClass: function ( name ) {
  41. this.dom.className = name;
  42. return this;
  43. },
  44. addClass: function ( name ) {
  45. this.dom.classList.add( name );
  46. return this;
  47. },
  48. removeClass: function ( name ) {
  49. this.dom.classList.remove( name );
  50. return this;
  51. },
  52. setStyle: function ( style, array ) {
  53. for ( var i = 0; i < array.length; i ++ ) {
  54. this.dom.style[ style ] = array[ i ];
  55. }
  56. return this;
  57. },
  58. setDisabled: function ( value ) {
  59. this.dom.disabled = value;
  60. return this;
  61. },
  62. setTextContent: function ( value ) {
  63. this.dom.textContent = value;
  64. return this;
  65. }
  66. };
  67. // properties
  68. var properties = [ 'position', 'left', 'top', 'right', 'bottom', 'width', 'height', 'border', 'borderLeft',
  69. 'borderTop', 'borderRight', 'borderBottom', 'borderColor', 'display', 'overflow', 'margin', 'marginLeft', 'marginTop', 'marginRight', 'marginBottom', 'padding', 'paddingLeft', 'paddingTop', 'paddingRight', 'paddingBottom', 'color',
  70. 'background', 'backgroundColor', 'opacity', 'fontSize', 'fontWeight', 'textAlign', 'textDecoration', 'textTransform', 'cursor', 'zIndex' ];
  71. properties.forEach( function ( property ) {
  72. var method = 'set' + property.substr( 0, 1 ).toUpperCase() + property.substr( 1, property.length );
  73. UI.Element.prototype[ method ] = function () {
  74. this.setStyle( property, arguments );
  75. return this;
  76. };
  77. } );
  78. // events
  79. var events = [ 'KeyUp', 'KeyDown', 'MouseOver', 'MouseOut', 'Click', 'DblClick', 'Change' ];
  80. events.forEach( function ( event ) {
  81. var method = 'on' + event;
  82. UI.Element.prototype[ method ] = function ( callback ) {
  83. this.dom.addEventListener( event.toLowerCase(), callback.bind( this ), false );
  84. return this;
  85. };
  86. } );
  87. // Span
  88. UI.Span = function () {
  89. UI.Element.call( this );
  90. this.dom = document.createElement( 'span' );
  91. return this;
  92. };
  93. UI.Span.prototype = Object.create( UI.Element.prototype );
  94. UI.Span.prototype.constructor = UI.Span;
  95. // Div
  96. UI.Div = function () {
  97. UI.Element.call( this );
  98. this.dom = document.createElement( 'div' );
  99. return this;
  100. };
  101. UI.Div.prototype = Object.create( UI.Element.prototype );
  102. UI.Div.prototype.constructor = UI.Div;
  103. // Row
  104. UI.Row = function () {
  105. UI.Element.call( this );
  106. var dom = document.createElement( 'div' );
  107. dom.className = 'Row';
  108. this.dom = dom;
  109. return this;
  110. };
  111. UI.Row.prototype = Object.create( UI.Element.prototype );
  112. UI.Row.prototype.constructor = UI.Row;
  113. // Panel
  114. UI.Panel = function () {
  115. UI.Element.call( this );
  116. var dom = document.createElement( 'div' );
  117. dom.className = 'Panel';
  118. this.dom = dom;
  119. return this;
  120. };
  121. UI.Panel.prototype = Object.create( UI.Element.prototype );
  122. UI.Panel.prototype.constructor = UI.Panel;
  123. // Text
  124. UI.Text = function ( text ) {
  125. UI.Element.call( this );
  126. var dom = document.createElement( 'span' );
  127. dom.className = 'Text';
  128. dom.style.cursor = 'default';
  129. dom.style.display = 'inline-block';
  130. dom.style.verticalAlign = 'middle';
  131. this.dom = dom;
  132. this.setValue( text );
  133. return this;
  134. };
  135. UI.Text.prototype = Object.create( UI.Element.prototype );
  136. UI.Text.prototype.constructor = UI.Text;
  137. UI.Text.prototype.getValue = function () {
  138. return this.dom.textContent;
  139. };
  140. UI.Text.prototype.setValue = function ( value ) {
  141. if ( value !== undefined ) {
  142. this.dom.textContent = value;
  143. }
  144. return this;
  145. };
  146. // Input
  147. UI.Input = function ( text ) {
  148. UI.Element.call( this );
  149. var scope = this;
  150. var dom = document.createElement( 'input' );
  151. dom.className = 'Input';
  152. dom.style.padding = '2px';
  153. dom.style.border = '1px solid transparent';
  154. dom.addEventListener( 'keydown', function ( event ) {
  155. event.stopPropagation();
  156. }, false );
  157. this.dom = dom;
  158. this.setValue( text );
  159. return this;
  160. };
  161. UI.Input.prototype = Object.create( UI.Element.prototype );
  162. UI.Input.prototype.constructor = UI.Input;
  163. UI.Input.prototype.getValue = function () {
  164. return this.dom.value;
  165. };
  166. UI.Input.prototype.setValue = function ( value ) {
  167. this.dom.value = value;
  168. return this;
  169. };
  170. // TextArea
  171. UI.TextArea = function () {
  172. UI.Element.call( this );
  173. var scope = this;
  174. var dom = document.createElement( 'textarea' );
  175. dom.className = 'TextArea';
  176. dom.style.padding = '2px';
  177. dom.spellcheck = false;
  178. dom.addEventListener( 'keydown', function ( event ) {
  179. event.stopPropagation();
  180. if ( event.keyCode === 9 ) {
  181. event.preventDefault();
  182. var cursor = dom.selectionStart;
  183. dom.value = dom.value.substring( 0, cursor ) + '\t' + dom.value.substring( cursor );
  184. dom.selectionStart = cursor + 1;
  185. dom.selectionEnd = dom.selectionStart;
  186. }
  187. }, false );
  188. this.dom = dom;
  189. return this;
  190. };
  191. UI.TextArea.prototype = Object.create( UI.Element.prototype );
  192. UI.TextArea.prototype.constructor = UI.TextArea;
  193. UI.TextArea.prototype.getValue = function () {
  194. return this.dom.value;
  195. };
  196. UI.TextArea.prototype.setValue = function ( value ) {
  197. this.dom.value = value;
  198. return this;
  199. };
  200. // Select
  201. UI.Select = function () {
  202. UI.Element.call( this );
  203. var scope = this;
  204. var dom = document.createElement( 'select' );
  205. dom.className = 'Select';
  206. dom.style.padding = '2px';
  207. this.dom = dom;
  208. return this;
  209. };
  210. UI.Select.prototype = Object.create( UI.Element.prototype );
  211. UI.Select.prototype.constructor = UI.Select;
  212. UI.Select.prototype.setMultiple = function ( boolean ) {
  213. this.dom.multiple = boolean;
  214. return this;
  215. };
  216. UI.Select.prototype.setOptions = function ( options ) {
  217. var selected = this.dom.value;
  218. while ( this.dom.children.length > 0 ) {
  219. this.dom.removeChild( this.dom.firstChild );
  220. }
  221. for ( var key in options ) {
  222. var option = document.createElement( 'option' );
  223. option.value = key;
  224. option.innerHTML = options[ key ];
  225. this.dom.appendChild( option );
  226. }
  227. this.dom.value = selected;
  228. return this;
  229. };
  230. UI.Select.prototype.getValue = function () {
  231. return this.dom.value;
  232. };
  233. UI.Select.prototype.setValue = function ( value ) {
  234. value = String( value );
  235. if ( this.dom.value !== value ) {
  236. this.dom.value = value;
  237. }
  238. return this;
  239. };
  240. // Checkbox
  241. UI.Checkbox = function ( boolean ) {
  242. UI.Element.call( this );
  243. var scope = this;
  244. var dom = document.createElement( 'input' );
  245. dom.className = 'Checkbox';
  246. dom.type = 'checkbox';
  247. this.dom = dom;
  248. this.setValue( boolean );
  249. return this;
  250. };
  251. UI.Checkbox.prototype = Object.create( UI.Element.prototype );
  252. UI.Checkbox.prototype.constructor = UI.Checkbox;
  253. UI.Checkbox.prototype.getValue = function () {
  254. return this.dom.checked;
  255. };
  256. UI.Checkbox.prototype.setValue = function ( value ) {
  257. if ( value !== undefined ) {
  258. this.dom.checked = value;
  259. }
  260. return this;
  261. };
  262. // Color
  263. UI.Color = function () {
  264. UI.Element.call( this );
  265. var scope = this;
  266. var dom = document.createElement( 'input' );
  267. dom.className = 'Color';
  268. dom.style.width = '64px';
  269. dom.style.height = '17px';
  270. dom.style.border = '0px';
  271. dom.style.padding = '2px';
  272. dom.style.backgroundColor = 'transparent';
  273. try {
  274. dom.type = 'color';
  275. dom.value = '#ffffff';
  276. } catch ( exception ) {}
  277. this.dom = dom;
  278. return this;
  279. };
  280. UI.Color.prototype = Object.create( UI.Element.prototype );
  281. UI.Color.prototype.constructor = UI.Color;
  282. UI.Color.prototype.getValue = function () {
  283. return this.dom.value;
  284. };
  285. UI.Color.prototype.getHexValue = function () {
  286. return parseInt( this.dom.value.substr( 1 ), 16 );
  287. };
  288. UI.Color.prototype.setValue = function ( value ) {
  289. this.dom.value = value;
  290. return this;
  291. };
  292. UI.Color.prototype.setHexValue = function ( hex ) {
  293. this.dom.value = '#' + ( '000000' + hex.toString( 16 ) ).slice( - 6 );
  294. return this;
  295. };
  296. // Number
  297. UI.Number = function ( number ) {
  298. UI.Element.call( this );
  299. var scope = this;
  300. var dom = document.createElement( 'input' );
  301. dom.className = 'Number';
  302. dom.value = '0.00';
  303. dom.addEventListener( 'keydown', function ( event ) {
  304. event.stopPropagation();
  305. if ( event.keyCode === 13 ) dom.blur();
  306. }, false );
  307. this.value = 0;
  308. this.min = - Infinity;
  309. this.max = Infinity;
  310. this.precision = 2;
  311. this.step = 1;
  312. this.unit = '';
  313. this.dom = dom;
  314. this.setValue( number );
  315. var changeEvent = document.createEvent( 'HTMLEvents' );
  316. changeEvent.initEvent( 'change', true, true );
  317. var distance = 0;
  318. var onMouseDownValue = 0;
  319. var pointer = [ 0, 0 ];
  320. var prevPointer = [ 0, 0 ];
  321. function onMouseDown( event ) {
  322. event.preventDefault();
  323. distance = 0;
  324. onMouseDownValue = scope.value;
  325. prevPointer = [ event.clientX, event.clientY ];
  326. document.addEventListener( 'mousemove', onMouseMove, false );
  327. document.addEventListener( 'mouseup', onMouseUp, false );
  328. }
  329. function onMouseMove( event ) {
  330. var currentValue = scope.value;
  331. pointer = [ event.clientX, event.clientY ];
  332. distance += ( pointer[ 0 ] - prevPointer[ 0 ] ) - ( pointer[ 1 ] - prevPointer[ 1 ] );
  333. var value = onMouseDownValue + ( distance / ( event.shiftKey ? 5 : 50 ) ) * scope.step;
  334. value = Math.min( scope.max, Math.max( scope.min, value ) );
  335. if ( currentValue !== value ) {
  336. scope.setValue( value );
  337. dom.dispatchEvent( changeEvent );
  338. }
  339. prevPointer = [ event.clientX, event.clientY ];
  340. }
  341. function onMouseUp( event ) {
  342. document.removeEventListener( 'mousemove', onMouseMove, false );
  343. document.removeEventListener( 'mouseup', onMouseUp, false );
  344. if ( Math.abs( distance ) < 2 ) {
  345. dom.focus();
  346. dom.select();
  347. }
  348. }
  349. function onTouchStart( event ) {
  350. if ( event.touches.length === 1 ) {
  351. distance = 0;
  352. onMouseDownValue = scope.value;
  353. prevPointer = [ event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ];
  354. document.addEventListener( 'touchmove', onTouchMove, false );
  355. document.addEventListener( 'touchend', onTouchEnd, false );
  356. }
  357. }
  358. function onTouchMove( event ) {
  359. var currentValue = scope.value;
  360. pointer = [ event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ];
  361. distance += ( pointer[ 0 ] - prevPointer[ 0 ] ) - ( pointer[ 1 ] - prevPointer[ 1 ] );
  362. var value = onMouseDownValue + ( distance / ( event.shiftKey ? 5 : 50 ) ) * scope.step;
  363. value = Math.min( scope.max, Math.max( scope.min, value ) );
  364. if ( currentValue !== value ) {
  365. scope.setValue( value );
  366. dom.dispatchEvent( changeEvent );
  367. }
  368. prevPointer = [ event.touches[ 0 ].pageX, event.touches[ 0 ].pageY ];
  369. }
  370. function onTouchEnd( event ) {
  371. if ( event.touches.length === 0 ) {
  372. document.removeEventListener( 'touchmove', onTouchMove, false );
  373. document.removeEventListener( 'touchend', onTouchEnd, false );
  374. }
  375. }
  376. function onChange( event ) {
  377. scope.setValue( dom.value );
  378. }
  379. function onFocus( event ) {
  380. dom.style.backgroundColor = '';
  381. dom.style.cursor = '';
  382. }
  383. function onBlur( event ) {
  384. dom.style.backgroundColor = 'transparent';
  385. dom.style.cursor = 'col-resize';
  386. }
  387. onBlur();
  388. dom.addEventListener( 'mousedown', onMouseDown, false );
  389. dom.addEventListener( 'touchstart', onTouchStart, false );
  390. dom.addEventListener( 'change', onChange, false );
  391. dom.addEventListener( 'focus', onFocus, false );
  392. dom.addEventListener( 'blur', onBlur, false );
  393. return this;
  394. };
  395. UI.Number.prototype = Object.create( UI.Element.prototype );
  396. UI.Number.prototype.constructor = UI.Number;
  397. UI.Number.prototype.getValue = function () {
  398. return this.value;
  399. };
  400. UI.Number.prototype.setValue = function ( value ) {
  401. if ( value !== undefined ) {
  402. value = parseFloat( value );
  403. if ( value < this.min ) value = this.min;
  404. if ( value > this.max ) value = this.max;
  405. this.value = value;
  406. this.dom.value = value.toFixed( this.precision );
  407. if ( this.unit !== '' ) this.dom.value += ' ' + this.unit;
  408. }
  409. return this;
  410. };
  411. UI.Number.prototype.setPrecision = function ( precision ) {
  412. this.precision = precision;
  413. return this;
  414. };
  415. UI.Number.prototype.setStep = function ( step ) {
  416. this.step = step;
  417. return this;
  418. };
  419. UI.Number.prototype.setRange = function ( min, max ) {
  420. this.min = min;
  421. this.max = max;
  422. return this;
  423. };
  424. UI.Number.prototype.setUnit = function ( unit ) {
  425. this.unit = unit;
  426. return this;
  427. };
  428. // Integer
  429. UI.Integer = function ( number ) {
  430. UI.Element.call( this );
  431. var scope = this;
  432. var dom = document.createElement( 'input' );
  433. dom.className = 'Number';
  434. dom.value = '0';
  435. dom.addEventListener( 'keydown', function ( event ) {
  436. event.stopPropagation();
  437. }, false );
  438. this.value = 0;
  439. this.min = - Infinity;
  440. this.max = Infinity;
  441. this.step = 1;
  442. this.dom = dom;
  443. this.setValue( number );
  444. var changeEvent = document.createEvent( 'HTMLEvents' );
  445. changeEvent.initEvent( 'change', true, true );
  446. var distance = 0;
  447. var onMouseDownValue = 0;
  448. var pointer = [ 0, 0 ];
  449. var prevPointer = [ 0, 0 ];
  450. function onMouseDown( event ) {
  451. event.preventDefault();
  452. distance = 0;
  453. onMouseDownValue = scope.value;
  454. prevPointer = [ event.clientX, event.clientY ];
  455. document.addEventListener( 'mousemove', onMouseMove, false );
  456. document.addEventListener( 'mouseup', onMouseUp, false );
  457. }
  458. function onMouseMove( event ) {
  459. var currentValue = scope.value;
  460. pointer = [ event.clientX, event.clientY ];
  461. distance += ( pointer[ 0 ] - prevPointer[ 0 ] ) - ( pointer[ 1 ] - prevPointer[ 1 ] );
  462. var value = onMouseDownValue + ( distance / ( event.shiftKey ? 5 : 50 ) ) * scope.step;
  463. value = Math.min( scope.max, Math.max( scope.min, value ) ) | 0;
  464. if ( currentValue !== value ) {
  465. scope.setValue( value );
  466. dom.dispatchEvent( changeEvent );
  467. }
  468. prevPointer = [ event.clientX, event.clientY ];
  469. }
  470. function onMouseUp( event ) {
  471. document.removeEventListener( 'mousemove', onMouseMove, false );
  472. document.removeEventListener( 'mouseup', onMouseUp, false );
  473. if ( Math.abs( distance ) < 2 ) {
  474. dom.focus();
  475. dom.select();
  476. }
  477. }
  478. function onChange( event ) {
  479. scope.setValue( dom.value );
  480. }
  481. function onFocus( event ) {
  482. dom.style.backgroundColor = '';
  483. dom.style.cursor = '';
  484. }
  485. function onBlur( event ) {
  486. dom.style.backgroundColor = 'transparent';
  487. dom.style.cursor = 'col-resize';
  488. }
  489. onBlur();
  490. dom.addEventListener( 'mousedown', onMouseDown, false );
  491. dom.addEventListener( 'change', onChange, false );
  492. dom.addEventListener( 'focus', onFocus, false );
  493. dom.addEventListener( 'blur', onBlur, false );
  494. return this;
  495. };
  496. UI.Integer.prototype = Object.create( UI.Element.prototype );
  497. UI.Integer.prototype.constructor = UI.Integer;
  498. UI.Integer.prototype.getValue = function () {
  499. return this.value;
  500. };
  501. UI.Integer.prototype.setValue = function ( value ) {
  502. if ( value !== undefined ) {
  503. value = parseInt( value );
  504. this.value = value;
  505. this.dom.value = value;
  506. }
  507. return this;
  508. };
  509. UI.Integer.prototype.setStep = function ( step ) {
  510. this.step = parseInt( step );
  511. return this;
  512. };
  513. UI.Integer.prototype.setRange = function ( min, max ) {
  514. this.min = min;
  515. this.max = max;
  516. return this;
  517. };
  518. // Break
  519. UI.Break = function () {
  520. UI.Element.call( this );
  521. var dom = document.createElement( 'br' );
  522. dom.className = 'Break';
  523. this.dom = dom;
  524. return this;
  525. };
  526. UI.Break.prototype = Object.create( UI.Element.prototype );
  527. UI.Break.prototype.constructor = UI.Break;
  528. // HorizontalRule
  529. UI.HorizontalRule = function () {
  530. UI.Element.call( this );
  531. var dom = document.createElement( 'hr' );
  532. dom.className = 'HorizontalRule';
  533. this.dom = dom;
  534. return this;
  535. };
  536. UI.HorizontalRule.prototype = Object.create( UI.Element.prototype );
  537. UI.HorizontalRule.prototype.constructor = UI.HorizontalRule;
  538. // Button
  539. UI.Button = function ( value ) {
  540. UI.Element.call( this );
  541. var dom = document.createElement( 'button' );
  542. dom.className = 'Button';
  543. this.dom = dom;
  544. this.dom.textContent = value;
  545. return this;
  546. };
  547. UI.Button.prototype = Object.create( UI.Element.prototype );
  548. UI.Button.prototype.constructor = UI.Button;
  549. UI.Button.prototype.setLabel = function ( value ) {
  550. this.dom.textContent = value;
  551. return this;
  552. };
  553. // TabbedPanel
  554. UI.TabbedPanel = function ( ) {
  555. UI.Element.call( this );
  556. var dom = document.createElement('div');
  557. this.dom = dom;
  558. this.setClass( 'TabbedPanel' );
  559. this.tabs = [];
  560. this.panels = [];
  561. this.tabsDiv = new UI.Div();
  562. this.tabsDiv.setClass( 'Tabs' );
  563. this.panelsDiv = new UI.Div();
  564. this.panelsDiv.setClass( 'Panels' );
  565. this.add( this.tabsDiv );
  566. this.add( this.panelsDiv );
  567. this.selected = '';
  568. return this;
  569. }
  570. UI.TabbedPanel.prototype = Object.create( UI.Element.prototype );
  571. UI.TabbedPanel.prototype.constructor = UI.TabbedPanel;
  572. UI.TabbedPanel.prototype.select = function ( id ) {
  573. var tab;
  574. var panel;
  575. var scope = this;
  576. // Deselect current selection
  577. if ( this.selected && this.selected.length ) {
  578. tab = this.tabs.find( function ( item ) { return item.dom.id === scope.selected } );
  579. panel = this.panels.find( function ( item ) { return item.dom.id === scope.selected } );
  580. if ( tab ) {
  581. tab.removeClass( 'selected' );
  582. }
  583. if( panel ) {
  584. panel.setDisplay( 'none' );
  585. }
  586. }
  587. tab = this.tabs.find( function ( item ) { return item.dom.id === id } );
  588. panel = this.panels.find( function ( item ) { return item.dom.id === id } );
  589. if ( tab ) {
  590. tab.addClass( 'selected' );
  591. }
  592. if( panel ) {
  593. panel.setDisplay( '' );
  594. }
  595. this.selected = id;
  596. return this;
  597. }
  598. UI.TabbedPanel.prototype.addTab = function ( id, label, items ) {
  599. var tab = new UI.TabbedPanel.Tab( label, this );
  600. tab.setId( id );
  601. this.tabs.push( tab );
  602. this.tabsDiv.add( tab );
  603. var panel = new UI.Div();
  604. panel.setId( id );
  605. panel.add( items );
  606. panel.setDisplay( 'none' );
  607. this.panels.push( panel );
  608. this.panelsDiv.add( panel );
  609. this.select( id );
  610. }
  611. UI.TabbedPanel.Tab = function ( text, parent ) {
  612. UI.Text.call( this, text );
  613. this.parent = parent;
  614. this.setClass( 'Tab' );
  615. var scope = this;
  616. this.dom.addEventListener( 'click', function ( event ) {
  617. scope.parent.select( scope.dom.id );
  618. } )
  619. return this;
  620. }
  621. UI.TabbedPanel.Tab.prototype = Object.create( UI.Text.prototype );
  622. UI.TabbedPanel.Tab.prototype.constructor = UI.TabbedPanel.Tab;