uki 1.1.1 → 1.1.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (144) hide show
  1. data/VERSION +1 -1
  2. data/bin/uki +1 -1
  3. data/frameworks/uki/README.rdoc +1 -1
  4. data/frameworks/uki/examples/core-examples/controls/controls.js +6 -6
  5. data/frameworks/uki/examples/core-examples/flow/flow.js +4 -4
  6. data/frameworks/uki/examples/core-examples/linearGradient/gradient.svg +11 -0
  7. data/frameworks/uki/examples/core-examples/linearGradient/linearGradient.js +87 -0
  8. data/frameworks/uki/examples/core-examples/popup/popup.js +23 -10
  9. data/frameworks/uki/examples/core-examples/resizeToContents/resizeToContents.js +12 -1
  10. data/frameworks/uki/examples/core-examples/slider/slider.js +1 -1
  11. data/frameworks/uki/examples/core-examples/splitPaneExtended/splitPaneExtended.js +1 -1
  12. data/frameworks/uki/examples/core-examples/table/table.js +19 -2
  13. data/frameworks/uki/examples/core-examples/wave/wave-theme.js +1 -1
  14. data/frameworks/uki/examples/core-examples/wave/wave.js +1 -1
  15. data/frameworks/uki/examples/more-examples/radioButton/radioButton.js +3 -3
  16. data/frameworks/uki/examples/more-examples/select/select.js +35 -0
  17. data/frameworks/uki/examples/touch-examples/scrollPane/scrollPane.js +53 -0
  18. data/frameworks/uki/spec/unit/background.spec.js +1 -1
  19. data/frameworks/uki/spec/unit/selector.spec.js +28 -12
  20. data/frameworks/uki/spec/unit/utils.spec.js +14 -0
  21. data/frameworks/uki/src/uki-core.js +3 -1
  22. data/frameworks/uki/src/uki-core/after.js +57 -0
  23. data/frameworks/uki/src/uki-core/attachment.js +15 -6
  24. data/frameworks/uki/src/uki-core/background.js +4 -3
  25. data/frameworks/uki/src/uki-core/background/css.js +1 -0
  26. data/frameworks/uki/src/uki-core/background/cssBox.js +5 -3
  27. data/frameworks/uki/src/uki-core/background/linearGradient.js +112 -0
  28. data/frameworks/uki/src/uki-core/background/multi.js +2 -2
  29. data/frameworks/uki/src/uki-core/background/rows.js +1 -0
  30. data/frameworks/uki/src/uki-core/background/sliced9.js +5 -2
  31. data/frameworks/uki/src/uki-core/builder.js +5 -4
  32. data/frameworks/uki/src/uki-core/collection.js +18 -13
  33. data/frameworks/uki/src/uki-core/dom/browser.js +114 -0
  34. data/frameworks/uki/src/uki-core/dom/event.js +3 -0
  35. data/frameworks/uki/src/uki-core/image.js +1 -26
  36. data/frameworks/uki/src/uki-core/selector.js +5 -0
  37. data/frameworks/uki/src/uki-core/theme.js +24 -23
  38. data/frameworks/uki/src/uki-core/theme/template.js +1 -1
  39. data/frameworks/uki/src/uki-core/uki.js +7 -4
  40. data/frameworks/uki/src/uki-core/utils.js +51 -26
  41. data/frameworks/uki/src/uki-core/view.js +6 -3
  42. data/frameworks/uki/src/uki-core/view/base.js +16 -1
  43. data/frameworks/uki/src/uki-core/view/container.js +15 -5
  44. data/frameworks/uki/src/uki-core/view/focusable.js +17 -4
  45. data/frameworks/uki/src/uki-core/view/observable.js +15 -2
  46. data/frameworks/uki/src/uki-core/view/styleable.js +4 -11
  47. data/frameworks/uki/src/uki-data/ajax.js +4 -30
  48. data/frameworks/uki/src/uki-data/json.js +191 -0
  49. data/frameworks/uki/src/uki-data/localStore.js +37 -0
  50. data/frameworks/uki/src/uki-data/model.js +1 -1
  51. data/frameworks/uki/src/uki-more.js +4 -0
  52. data/frameworks/uki/src/uki-more/more/background.js +2 -0
  53. data/frameworks/uki/src/uki-more/more/color.js +168 -0
  54. data/frameworks/uki/src/uki-more/more/utils.js +5 -12
  55. data/frameworks/uki/src/uki-more/more/view.js +3 -1
  56. data/frameworks/uki/src/uki-more/more/view/form.js +30 -0
  57. data/frameworks/uki/src/uki-more/more/view/hTile.js +59 -0
  58. data/frameworks/uki/src/uki-more/more/view/nativeButton.js +3 -0
  59. data/frameworks/uki/src/uki-more/more/view/nativeCheckbox.js +38 -0
  60. data/frameworks/uki/src/uki-more/more/view/nativeControl.js +40 -0
  61. data/frameworks/uki/src/uki-more/more/view/nativeInput.js +78 -0
  62. data/frameworks/uki/src/uki-more/more/view/nativeSelect.js +29 -0
  63. data/frameworks/uki/src/uki-more/more/view/radioButton.js +1 -1
  64. data/frameworks/uki/src/uki-more/more/view/select-theme.js +55 -0
  65. data/frameworks/uki/src/uki-more/more/view/select.js +208 -0
  66. data/frameworks/uki/src/uki-theme/airport.js +145 -88
  67. data/frameworks/uki/src/uki-theme/airport/i/table/a-down.png +0 -0
  68. data/frameworks/uki/src/uki-theme/airport/i/table/a-up.png +0 -0
  69. data/frameworks/uki/src/uki-touch.js +2 -0
  70. data/frameworks/uki/src/uki-touch/touch.js +1 -0
  71. data/frameworks/uki/src/uki-touch/touch/const.js +24 -0
  72. data/frameworks/uki/src/uki-touch/touch/setup.js +52 -0
  73. data/frameworks/uki/src/uki-touch/touch/view.js +4 -0
  74. data/frameworks/uki/src/uki-touch/touch/view/scrollPane.js +505 -0
  75. data/frameworks/uki/src/uki-touch/touch/view/scrollableList.js +27 -0
  76. data/frameworks/uki/src/uki-view/view/box.js +9 -0
  77. data/frameworks/uki/src/uki-view/view/button.js +36 -1
  78. data/frameworks/uki/src/uki-view/view/checkbox.js +32 -3
  79. data/frameworks/uki/src/uki-view/view/flow.js +37 -9
  80. data/frameworks/uki/src/uki-view/view/image.js +14 -1
  81. data/frameworks/uki/src/uki-view/view/label.js +72 -11
  82. data/frameworks/uki/src/uki-view/view/list.js +143 -13
  83. data/frameworks/uki/src/uki-view/view/list/render.js +1 -0
  84. data/frameworks/uki/src/uki-view/view/popup.js +46 -2
  85. data/frameworks/uki/src/uki-view/view/radio.js +19 -4
  86. data/frameworks/uki/src/uki-view/view/scrollPane.js +91 -33
  87. data/frameworks/uki/src/uki-view/view/slider.js +67 -54
  88. data/frameworks/uki/src/uki-view/view/splitPane.js +102 -9
  89. data/frameworks/uki/src/uki-view/view/table.js +59 -2
  90. data/frameworks/uki/src/uki-view/view/table/column.js +45 -17
  91. data/frameworks/uki/src/uki-view/view/table/header.js +40 -12
  92. data/frameworks/uki/src/uki-view/view/table/render.js +4 -0
  93. data/frameworks/uki/src/uki-view/view/textField.js +75 -21
  94. data/frameworks/uki/src/uki-view/view/toolbar.js +16 -0
  95. data/lib/uki/builder.rb +1 -1
  96. data/lib/uki/include_js.rb +2 -2
  97. data/lib/uki/project.rb +14 -14
  98. data/templates/index.html.erb +2 -2
  99. data/templates/myapp.js.erb +2 -2
  100. data/uki.gemspec +34 -48
  101. metadata +44 -47
  102. data/frameworks/uki/src/uki-core/dom/nativeLayout.js +0 -18
  103. data/frameworks/uki/src/uki-theme/airport/i/button/down-c.gif +0 -0
  104. data/frameworks/uki/src/uki-theme/airport/i/button/down-c.png +0 -0
  105. data/frameworks/uki/src/uki-theme/airport/i/button/down-h.gif +0 -0
  106. data/frameworks/uki/src/uki-theme/airport/i/button/down-h.png +0 -0
  107. data/frameworks/uki/src/uki-theme/airport/i/button/down-m.png +0 -0
  108. data/frameworks/uki/src/uki-theme/airport/i/button/down-v.png +0 -0
  109. data/frameworks/uki/src/uki-theme/airport/i/button/focusRing-c.png +0 -0
  110. data/frameworks/uki/src/uki-theme/airport/i/button/focusRing-h.png +0 -0
  111. data/frameworks/uki/src/uki-theme/airport/i/button/focusRing-m.png +0 -0
  112. data/frameworks/uki/src/uki-theme/airport/i/button/focusRing-v.png +0 -0
  113. data/frameworks/uki/src/uki-theme/airport/i/button/focusRing.png +0 -0
  114. data/frameworks/uki/src/uki-theme/airport/i/button/hover-c.gif +0 -0
  115. data/frameworks/uki/src/uki-theme/airport/i/button/hover-c.png +0 -0
  116. data/frameworks/uki/src/uki-theme/airport/i/button/hover-h.gif +0 -0
  117. data/frameworks/uki/src/uki-theme/airport/i/button/hover-h.png +0 -0
  118. data/frameworks/uki/src/uki-theme/airport/i/button/hover-m.png +0 -0
  119. data/frameworks/uki/src/uki-theme/airport/i/button/hover-v.png +0 -0
  120. data/frameworks/uki/src/uki-theme/airport/i/button/hover.png +0 -0
  121. data/frameworks/uki/src/uki-theme/airport/i/button/normal-c.gif +0 -0
  122. data/frameworks/uki/src/uki-theme/airport/i/button/normal-c.png +0 -0
  123. data/frameworks/uki/src/uki-theme/airport/i/button/normal-h.gif +0 -0
  124. data/frameworks/uki/src/uki-theme/airport/i/button/normal-h.png +0 -0
  125. data/frameworks/uki/src/uki-theme/airport/i/button/normal-m.png +0 -0
  126. data/frameworks/uki/src/uki-theme/airport/i/button/normal-v.png +0 -0
  127. data/frameworks/uki/src/uki-theme/airport/i/button/normal.png +0 -0
  128. data/frameworks/uki/src/uki-theme/airport/i/panel/dark-h.gif +0 -0
  129. data/frameworks/uki/src/uki-theme/airport/i/panel/dark-h.png +0 -0
  130. data/frameworks/uki/src/uki-theme/airport/i/panel/dark-m.png +0 -0
  131. data/frameworks/uki/src/uki-theme/airport/i/panel/dark.png +0 -0
  132. data/frameworks/uki/src/uki-theme/airport/i/popup/normal.png +0 -0
  133. data/frameworks/uki/src/uki-theme/airport/i/shadow/large-c.png +0 -0
  134. data/frameworks/uki/src/uki-theme/airport/i/shadow/large-h.png +0 -0
  135. data/frameworks/uki/src/uki-theme/airport/i/shadow/large-m.png +0 -0
  136. data/frameworks/uki/src/uki-theme/airport/i/shadow/large-v.png +0 -0
  137. data/frameworks/uki/src/uki-theme/airport/i/shadow/large.png +0 -0
  138. data/frameworks/uki/src/uki-theme/airport/i/slider/bar-m.gif +0 -0
  139. data/frameworks/uki/src/uki-theme/airport/i/slider/bar-m.png +0 -0
  140. data/frameworks/uki/src/uki-theme/airport/i/slider/bar-v.gif +0 -0
  141. data/frameworks/uki/src/uki-theme/airport/i/slider/bar-v.png +0 -0
  142. data/frameworks/uki/src/uki-theme/airport/i/slider/bar.png +0 -0
  143. data/frameworks/uki/src/uki-theme/airport/i/slider/focus.png +0 -0
  144. data/frameworks/uki/src/uki-theme/airport/i/slider/handle.gif +0 -0
@@ -1,2 +1,4 @@
1
1
  include('../more.js');
2
- uki.more.view = {};
2
+ uki.more.view = {};
3
+
4
+ uki.viewNamespaces.push('uki.more.view.');
@@ -0,0 +1,30 @@
1
+ include('../view.js');
2
+
3
+ uki.view.declare('uki.more.view.Form', uki.view.Container, function(Base) {
4
+
5
+ this._setup = function() {
6
+ Base._setup.call(this);
7
+ uki.extend(this, {
8
+ _method: 'GET',
9
+ _action: ''
10
+ });
11
+ };
12
+
13
+ this.action = uki.newProp('_action', function(action) {
14
+ this._dom.action = this._action = action;
15
+ });
16
+ this.method = uki.newProp('_method', function(method) {
17
+ this._dom.method = this._method = method;
18
+ });
19
+
20
+ this.submit = function() { this._dom.submit(); }
21
+ this.reset = function() { this._dom.reset(); }
22
+
23
+ this._createDom = function() {
24
+ this._dom = uki.createElement('form', Base.defaultCss);
25
+ this._initClassName();
26
+ this._dom.action = this._action;
27
+ this._dom.method = this._method;
28
+ };
29
+
30
+ });
@@ -0,0 +1,59 @@
1
+ include('../view.js');
2
+
3
+ uki.view.declare('uki.more.view.HTile', uki.view.VFlow, function(Base) {
4
+
5
+ function getTileGrid(childViews, maxWidth) {
6
+ var ti = {};
7
+
8
+ ti.width = uki.reduce(0, childViews, function(max, e) {
9
+ return (e.visible() && e.width() > max) ? e.width() : max
10
+ });
11
+
12
+ ti.height = uki.reduce(0, childViews, function(max, e) {
13
+ return (e.visible() && e.height() > max) ? e.height() : max
14
+ });
15
+
16
+ ti.across = Math.floor(maxWidth / ti.width);
17
+ if (ti.across <= 0 && ti.width >= 0) {
18
+ ti.across = 1
19
+ }
20
+
21
+ ti.down = Math.ceil(childViews.length / ti.across);
22
+
23
+ return ti;
24
+ }
25
+
26
+ this.contentsSize = function() {
27
+ var ti = getTileGrid(this._childViews, this.parent().width());
28
+ return new Size(this.contentsWidth(), ti.height * ti.down);
29
+ };
30
+
31
+ this._resizeChildViews = function(oldRect) {
32
+ var row = 0, col = 0;
33
+ var ti = getTileGrid(this._childViews, this.parent().width());
34
+ var view;
35
+
36
+ for (var i = 0, childViews = this.childViews(); i < childViews.length; i++) {
37
+ view = childViews[i];
38
+
39
+ view.parentResized(oldRect, this._rect);
40
+
41
+ view.rect().x = col * ti.width;
42
+ view.rect().y = row * ti.height;
43
+
44
+ if (view.visible()) {
45
+ if (this._hidePartlyVisible) {
46
+ view.visible(view._rect.width + ti.width <= this._rect.width);
47
+ }
48
+ col++;
49
+ if (col >= ti.across) {
50
+ col = 0;
51
+ row++;
52
+ }
53
+ }
54
+ }
55
+ this.rect().width = col * ti.width;
56
+ this.rect().height = row * ti.height
57
+ };
58
+
59
+ });
@@ -0,0 +1,3 @@
1
+ include('nativeControl.js');
2
+
3
+ uki.view.declare('uki.more.view.NativeButton', uki.more.view.NativeControl, function(Base) {});
@@ -0,0 +1,38 @@
1
+ include('nativeControl.js');
2
+
3
+ uki.view.declare('uki.more.view.NativeCheckbox', uki.more.view.NativeControl, function(Base) {
4
+ this.checked = function(value) {
5
+ if (value === undefined) return this._dom.checked;
6
+ this._dom.checked = this._dom.defaultChecked = value;
7
+ return this;
8
+ };
9
+
10
+ this.value = this.checked;
11
+
12
+ var inputSize;
13
+ function initInputSize () {
14
+ if (!inputSize) {
15
+ var input = uki.createElement('input', 'width:auto;height:auto;display:block;');
16
+ input.type = 'checkbox';
17
+ uki.dom.probe(input, function(input) {
18
+ inputSize = [input.offsetWidth, input.offsetHeight];
19
+ });
20
+ }
21
+ }
22
+
23
+ this._setup = function() {
24
+ Base._setup.call(this);
25
+ this._type = 'checkbox';
26
+ };
27
+
28
+ this._layoutDom = function(rect) {
29
+ initInputSize();
30
+ var l = {
31
+ left: rect.x + (rect.width - inputSize[0]) / 2,
32
+ top: rect.y + (rect.height - inputSize[1]) / 2
33
+ };
34
+
35
+ this._lastLayout = uki.dom.layout(this._dom.style, l, this._lastLayout);
36
+ return true;
37
+ };
38
+ });
@@ -0,0 +1,40 @@
1
+ include('../view.js');
2
+
3
+ uki.view.declare('uki.more.view.NativeControl', uki.view.Base, uki.view.Focusable, function(Base, Focusable) {
4
+ this._setup = function() {
5
+ Base._setup.call(this);
6
+ this._type = 'button';
7
+ };
8
+
9
+ uki.delegateProp(this, 'disabled', '_dom');
10
+ uki.delegateProp(this, 'value', '_dom');
11
+
12
+ this.domName = function(name) {
13
+ if (name === undefined) return this._dom.name;
14
+ this._dom.setAttribute('name', name);
15
+ this._dom.name = name;
16
+ this._initClassName();
17
+
18
+ if (/MSIE 6/.test(navigator.userAgent)) {
19
+ var clone = document.createElement('<input name="' + name + '" />');
20
+ clone.type = this._type; // type is not copied
21
+ clone.mergeAttributes(this._dom);
22
+ if (this._dom.parentNode) {
23
+ this._dom.parentNode.replaceChild(clone, this._dom);
24
+ }
25
+ this._dom = clone;
26
+ }
27
+
28
+ return this;
29
+ };
30
+
31
+ this._createDom = function() {
32
+ this._dom = uki.createElement('input', 'position:absolute;z-index:100;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;');
33
+ this._dom.type = this._type;
34
+ this._initFocusable(this._dom);
35
+ };
36
+
37
+ this._bindToDom = function(name) {
38
+ return Focusable._bindToDom.call(this, name) || Base._bindToDom.call(this, name);
39
+ };
40
+ });
@@ -0,0 +1,78 @@
1
+ include('nativeControl.js');
2
+
3
+ uki.view.declare('uki.more.view.NativeInput', uki.view.Base, uki.view.Focusable, function(Base,Focusable) {
4
+ this._createDom = function() {
5
+ Base._createDom.call(this);
6
+ this._dom.innerHTML = '<input type="text" style="position:absolute;z-index:100;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;width:100%;height:100%;" />'
7
+ this._input = this._dom.firstChild;
8
+ this._initFocusable(this._input);
9
+ };
10
+
11
+ uki.delegateProp(this, 'name', '_input');
12
+ uki.delegateProp(this, 'disabled', '_input');
13
+ uki.delegateProp(this, 'value', '_input');
14
+
15
+ this._layoutDom = function(rect) {
16
+ Base._layoutDom.apply(this, arguments);
17
+ this._lastInputLayout = uki.dom.layout(this._input.style, {width: rect.width}, this._lastInputLayout);
18
+ if (this._placeholderDom) {
19
+ this._placeholderDom.style.lineHeight = this._rect.height + 'px';
20
+ }
21
+ };
22
+
23
+ function getInputOffset (input) {
24
+ var clone1 = input.cloneNode(input),
25
+ clone2 = input.cloneNode(input);
26
+ clone1.style.cssText += ';padding:0;border:0;overflow:hidden;width:auto;-moz-box-sizing:auto;-webkit-box-sizing:auto;box-sizing:auto;';
27
+ clone2.style.cssText += ';width:auto;-moz-box-sizing:auto;-webkit-box-sizing:auto;box-sizing:auto;'
28
+ return (uki.dom.probe(clone2, function(clone) { return clone.offsetWidth; }) -
29
+ uki.dom.probe(clone1, function(clone) { return clone.offsetWidth; }))/2;
30
+ }
31
+
32
+ function nativePlaceholder (node) {
33
+ return typeof node.placeholder == 'string';
34
+ }
35
+
36
+ this.placeholder = uki.newProp('_placeholder', function(v) {
37
+ this._placeholder = v;
38
+ if (nativePlaceholder(this._dom)) {
39
+ this._dom.placeholder = v;
40
+ } else {
41
+ if (!this._placeholderDom) {
42
+ this._placeholderDom = uki.createElement('div', this.defaultCss + 'z-index:103;color:#999;cursor:text', v);
43
+ this._dom.appendChild(this._placeholderDom);
44
+ this._updatePlaceholderVis();
45
+ uki.each(['fontSize', 'fontFamily', 'fontWeight'], function(i, name) {
46
+ this._placeholderDom.style[name] = this.style(name);
47
+ }, this);
48
+ this._placeholderDom.style.left = getInputOffset(this._input) + 'px';
49
+
50
+ uki.dom.bind(this._placeholderDom, 'mousedown', uki.proxy(function(e) {
51
+ // e.preventDefault();
52
+ setTimeout(uki.proxy(this.focus, this), 1);
53
+ }, this));
54
+ } else {
55
+ this._placeholderDom.innerHTML = v;
56
+ }
57
+ }
58
+ });
59
+
60
+ this._updatePlaceholderVis = function() {
61
+ if (this._placeholderDom) this._placeholderDom.style.display = this.value() ? 'none' : 'block';
62
+ };
63
+
64
+ this._bindToDom = function(name) {
65
+ return Focusable._bindToDom.call(this, name) || Base._bindToDom.call(this, name);
66
+ };
67
+
68
+ this._focus = function(e) {
69
+ if (this._placeholderDom) this._placeholderDom.style.display = 'none';
70
+ Focusable._focus.call(this, e);
71
+ };
72
+
73
+ this._blur = function(e) {
74
+ this._updatePlaceholderVis();
75
+ Focusable._blur.call(this, e);
76
+ };
77
+
78
+ });
@@ -0,0 +1,29 @@
1
+ include('nativeControl.js');
2
+
3
+ uki.view.declare('uki.more.view.NativeSelect', uki.more.view.NativeControl, function(Base) {
4
+
5
+ this._createDom = function() {
6
+ this._dom = uki.createElement('select', 'position:absolute;z-index:100;-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box;margin:0;');
7
+ this._initClassName();
8
+ this._initFocusable(this._dom);
9
+ };
10
+
11
+ uki.delegateProp(this, 'name', '_dom');
12
+ uki.delegateProp(this, 'disabled', '_dom');
13
+ uki.delegateProp(this, 'value', '_dom');
14
+
15
+ this.options = function(val) {
16
+ if (val === undefined) return uki.map(this._dom.getElementsByTagName('option'), function(option) {
17
+ return { value: option.getAttribute('value'), html: option.innerHTML };
18
+ });
19
+
20
+ this._dom.innerHTML = '';
21
+ uki.each(val, function(i, option) {
22
+ var node = uki.createElement('option', '', option.text);
23
+ node.value = option.value;
24
+ node.selected = option.selected;
25
+ this._dom.appendChild(node);
26
+ }, this);
27
+ };
28
+
29
+ });
@@ -7,7 +7,7 @@ uki.view.declare('uki.more.view.RadioButton', uki.more.view.ToggleButton, functi
7
7
  manager.unregisterGroup(this);
8
8
  this._group = g;
9
9
  manager.registerGroup(this);
10
- manager.clearGroup(this);
10
+ if (this.checked()) manager.clearGroup(this);
11
11
  });
12
12
 
13
13
  this.value = this.checked = uki.newProp('_checked', function(state) {
@@ -0,0 +1,55 @@
1
+ include("../view.js");
2
+
3
+ (function() {
4
+ function selectHandle (image, css) {
5
+ return new uki.background.CssBox((css || '') + 'background: url(' + uki.theme.imageSrc(image) + '); background-position: 100% 50%; background-repeat: no-repeat;');
6
+ }
7
+
8
+ var theme = uki.extend({}, uki.theme.Base, {
9
+ backgrounds: {
10
+ // 'select-list': function() {
11
+ //
12
+ // },
13
+ // 'select-popup': function() {
14
+ //
15
+ // },
16
+ 'select-normal': function() {
17
+ return new uki.background.Multi(
18
+ selectHandle('select-handle-normal'),
19
+ uki.theme.background('button-normal')
20
+ );
21
+ },
22
+ 'select-hover': function() {
23
+ return new uki.background.Multi(
24
+ selectHandle('select-handle-normal'),
25
+ uki.theme.background('button-hover')
26
+ );
27
+ },
28
+ 'select-checked-normal': function() {
29
+ return new uki.background.Multi(
30
+ selectHandle('select-handle-normal'),
31
+ uki.theme.background('button-down')
32
+ );
33
+ },
34
+ 'select-disabled': function() {
35
+ return new uki.background.Multi(
36
+ selectHandle('select-handle-normal', 'opacity:0.4;'),
37
+ uki.theme.background('button-disabled')
38
+ );
39
+ },
40
+
41
+ 'select-popup': function() {
42
+ return uki.theme.background('popup-normal');
43
+ }
44
+ },
45
+
46
+ imageSrcs: {
47
+ 'select-handle-normal': function() {
48
+ return ["select-down-m.png", "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABcAAABkCAYAAABtnKvPAAAAeUlEQVRo3u3SMQ2AMBAFUCQgAQlIQUKTthq6IhEpOIAOTIWFABPvkr/c8IZ/15VStu6rgcPhcDgcDofD4XA4HA6HnybnvNRsF1ke4yGEoUJrA691379SS4xxavDx1c5TSvMBh08Oegv253A4HA6Hw+FwOBwOh8P/ie9z0RuWFOYPhAAAAABJRU5ErkJggg==", "select-down-m.gif"];
49
+ }
50
+ }
51
+ });
52
+ theme.backgrounds['select-checked-hover'] = theme.backgrounds['select-checked-normal'];
53
+
54
+ uki.theme.register(theme);
55
+ })();
@@ -0,0 +1,208 @@
1
+ include('../view.js');
2
+
3
+ uki.view.declare('uki.more.view.Select', uki.view.Checkbox, function(Base) {
4
+ this._backgroundPrefix = 'select-';
5
+ this._popupBackground = 'theme(select-popup)';
6
+ this._listBackground = 'theme(select-list)';
7
+ this._popupOffset = 0;
8
+
9
+ this._setup = function() {
10
+ Base._setup.call(this);
11
+ this._inset = new uki.geometry.Inset(0, 20, 0, 4);
12
+ this._selectFirst = true;
13
+ this._focusable = true;
14
+ this._options = [];
15
+ this._maxPopupHeight = 200;
16
+ this._lastScroll = 0;
17
+ };
18
+
19
+ this.Render = uki.newClass(uki.view.list.Render, function(Base) {
20
+ this.render = function(data, rect, i) {
21
+ return '<span style="line-height: 22px; text-align: left; white-space: nowrap; margin: 0 4px; cursor: default">' + data + '</span>';
22
+ }
23
+
24
+ this.setSelected = function(container, data, state, focus) {
25
+ container.style.backgroundColor = state ? '#3875D7' : '';
26
+ container.style.color = state ? '#FFF' : '#000';
27
+ }
28
+ });
29
+
30
+ this.selectFirst = uki.newProp('_selectFirst');
31
+
32
+ this.opened = function() {
33
+ return this._popup.visible() && this._popup.parent();
34
+ };
35
+
36
+ this.popupAnchors = function(v) {
37
+ if (v === undefined) return this._popup.anchors();
38
+ this._popup.anchors(v);
39
+ return this;
40
+ };
41
+
42
+ this._createDom = function() {
43
+ Base._createDom.call(this);
44
+ this.style({ fontWeight: 'normal', textAlign: 'left' });
45
+
46
+ this._label.style.overflow = 'hidden';
47
+ this._popup = uki(
48
+ { view: 'Popup', anchors: 'left top', rect: '100 100', style: {zIndex: 1000}, offset: this._popupOffset,
49
+ background: this._popupBackground, relativeTo: this, visible: false,
50
+ childViews: [
51
+ { view: 'ScrollPane', rect: '100 100', anchors: 'left top right bottom', childViews: [
52
+ { view: 'List', rect: '100 100', anchors: 'left top right bottom', rowHeight: 22,
53
+ textSelectable: false, focusable: true, background: this._listBackground,
54
+ render: new this.Render(), style: { fontSize: '12px' } }
55
+ ] }
56
+ ] }
57
+ )[0];
58
+
59
+ this._popup.hide();
60
+
61
+ this._list = uki('List', this._popup)[0];
62
+ this._scroll = uki('ScrollPane', this._popup)[0];
63
+
64
+ this._popup.bind('toggle', uki.proxy(function(e) {
65
+ this._down = this._popup.visible();
66
+ if (this._popup.visible()) {
67
+ this._updateWidth();
68
+ this._scroll.scrollTop(this._lastScroll);
69
+ }
70
+ this._checked = this._popup.visible();
71
+ this._updateBg();
72
+ }, this));
73
+
74
+ this.bind(this._list.keyPressEvent(), function(e) {
75
+ if (this.preventTransfer) {
76
+ this.preventTransfer = false;
77
+ return;
78
+ }
79
+ if (this._popup.visible()) {
80
+ this._list.trigger(e.type, e);
81
+ }
82
+ });
83
+
84
+ this.bind('blur', function() {
85
+ setTimeout(uki.proxy(function() {
86
+ if (!this._hasFocus && this.opened()) {
87
+ this._lastScroll = this._scroll.scrollTop();
88
+ this._popup.hide();
89
+ }
90
+ }, this), 50)
91
+ });
92
+
93
+ // refocus on list click
94
+ this._list.bind('focus', uki.proxy(function() {
95
+ this._hasFocus = false;
96
+ this.focus();
97
+ // setTimeout(uki.proxy(this.focus, this), 5);
98
+ }, this));
99
+
100
+ this._list.bind('click', uki.proxy(this.selectCurrent, this));
101
+ };
102
+
103
+ this.contentsSize = function(autosize) {
104
+ var html = this.html(), size;
105
+ this.html(this._longestText);
106
+ size = Base.contentsSize.call(this, autosize);
107
+ this.html(html);
108
+ return size;
109
+ };
110
+
111
+ this._keydown = function(e) {
112
+ if ((e.which == 32 || e.which == 13) && this._popup.visible()) {
113
+ this.selectCurrent(e);
114
+ } else if ((e.which == 40 || e.which == 38) && !this._popup.visible()) {
115
+ this._popup.toggle();
116
+ e.preventDefault();
117
+ this.preventTransfer = true;
118
+ } else {
119
+ Base._keydown.call(this, e);
120
+ }
121
+ };
122
+
123
+ this.selectCurrent = function(e) {
124
+ if (this.selectedIndex() == -1) {
125
+ this.text(this._selectFirst && this._options[0] ? this._options[0].text : '');
126
+ } else {
127
+ this.text(this._options[this.selectedIndex()].text);
128
+ }
129
+ this._lastScroll = this._scroll.scrollTop();
130
+ this._popup.hide();
131
+ if (e) this.trigger('change', { source: this });
132
+ };
133
+
134
+ this.value = function(v) {
135
+ if (v === undefined) {
136
+ return this._options[this.selectedIndex()] ? this._options[this.selectedIndex()].value : undefined;
137
+ } else {
138
+ var index = -1,
139
+ option,
140
+ l = this._options.length,
141
+ i;
142
+ for (i=0; i < l; i++) {
143
+ option = this._options[i];
144
+ if (option.value == v) {
145
+ index = i;
146
+ break;
147
+ }
148
+ };
149
+ this.selectedIndex(index);
150
+ this.selectCurrent();
151
+ }
152
+ };
153
+
154
+ this.maxPopupHeight = uki.newProp('_maxPopupHeight');
155
+
156
+ this._updateWidth = function() {
157
+ if (this._widthCached || !this._options.length) return;
158
+ var source = this._list.dom().firstChild.firstChild.firstChild, /// omg!
159
+ html = source.innerHTML;
160
+
161
+ source.innerHTML = this._longestText;
162
+ this._widthCached = source.offsetWidth + 8;
163
+ source.innerHTML = html;
164
+ this._popup.rect(new uki.geometry.Rect(
165
+ this._popup.rect().x,
166
+ this._popup.rect().y,
167
+ Math.max(this._widthCached, this.rect().width),
168
+ Math.min(this._maxPopupHeight, this._options.length * 22)
169
+ )).layout();
170
+ };
171
+
172
+ this.options = uki.newProp('_options', function(o) {
173
+ this._options = o;
174
+ this._list
175
+ .data(uki.map(o, 'text'))
176
+ .selectedIndex(0);
177
+
178
+ if (this._selectFirst && (o.length > 0)) this.text(o[0].text);
179
+ this._longestText = '';
180
+ uki.each(o, function(i, row) {
181
+ if (row.text.length > this._longestText.length) this._longestText = row.text;
182
+ }, this);
183
+ this._widthCached = false;
184
+ this._lastScroll = 0;
185
+ });
186
+
187
+ uki.delegateProp(this, 'selectedIndex', '_list');
188
+
189
+ this._updateBg = function() {
190
+ return Base._updateBg.call(this);
191
+ };
192
+
193
+ this._mousedown = function(e) {
194
+ Base._mousedown.call(this, e);
195
+ if (this.disabled()) return;
196
+ this._popup.toggle();
197
+ this.trigger('toggle', { opened: this.opened() });
198
+ // if (this._popup.visible()) this._list.focus();
199
+ };
200
+
201
+ this._mouseup = function(e) {
202
+ if (!this._down) return;
203
+ this._down = false;
204
+ };
205
+
206
+ });
207
+
208
+ uki.Collection.addAttrs(['options']);