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
@@ -3,6 +3,7 @@ include('../list.js');
3
3
  /**
4
4
  * Flyweight view rendering
5
5
  * Used in lists, tables, grids
6
+ * @class
6
7
  */
7
8
  uki.view.list.Render = uki.newClass({
8
9
  init: function() {},
@@ -1,3 +1,11 @@
1
+ /**
2
+ * Popup
3
+ *
4
+ * @author voloko
5
+ * @name uki.view.Popup
6
+ * @class
7
+ * @extends uki.view.Container
8
+ */
1
9
  uki.view.declare('uki.view.Popup', uki.view.Container, function(Base) {
2
10
 
3
11
  this._setup = function() {
@@ -16,8 +24,28 @@ uki.view.declare('uki.view.Popup', uki.view.Container, function(Base) {
16
24
  this.hideOnClick(true);
17
25
  };
18
26
 
27
+ /**
28
+ * @function
29
+ * @name uki.view.Popup#offset
30
+ */
31
+ /**
32
+ * @function
33
+ * @name uki.view.Popup#relativeTo
34
+ */
35
+ /**
36
+ * @function
37
+ * @name uki.view.Popup#horizontal
38
+ */
39
+ /**
40
+ * @function
41
+ * @name uki.view.Popup#flipOnResize
42
+ */
19
43
  uki.addProps(this, ['offset', 'relativeTo', 'horizontal', 'flipOnResize']);
20
44
 
45
+ /**
46
+ * @function
47
+ * @name uki.view.Popup#hideOnClick
48
+ */
21
49
  this.hideOnClick = function(state) {
22
50
  if (state === undefined) return this._clickHandler;
23
51
  if (state != !!this._clickHandler) {
@@ -38,6 +66,10 @@ uki.view.declare('uki.view.Popup', uki.view.Container, function(Base) {
38
66
  return this;
39
67
  };
40
68
 
69
+ /**
70
+ * @function
71
+ * @name uki.view.Popup#toggle
72
+ */
41
73
  this.toggle = function() {
42
74
  if (this.parent() && this.visible()) {
43
75
  this.hide();
@@ -46,6 +78,10 @@ uki.view.declare('uki.view.Popup', uki.view.Container, function(Base) {
46
78
  }
47
79
  };
48
80
 
81
+ /**
82
+ * @function
83
+ * @name uki.view.Popup#show
84
+ */
49
85
  this.show = function() {
50
86
  this.visible(true);
51
87
  if (!this.parent()) {
@@ -57,6 +93,10 @@ uki.view.declare('uki.view.Popup', uki.view.Container, function(Base) {
57
93
  this.trigger('toggle', { source: this });
58
94
  };
59
95
 
96
+ /**
97
+ * @function
98
+ * @name uki.view.Popup#hide
99
+ */
60
100
  this.hide = function() {
61
101
  this.visible(false);
62
102
  this.trigger('toggle', { source: this });
@@ -91,14 +131,18 @@ uki.view.declare('uki.view.Popup', uki.view.Container, function(Base) {
91
131
 
92
132
  if (this._anchors & ANCHOR_RIGHT) {
93
133
  position.x = relativeOffset.x + relativeRect.width - (this._horizontal ? 0 : rect.width) + hOffset;
94
- } else {
134
+ } else if (this._anchors & ANCHOR_LEFT) {
95
135
  position.x = relativeOffset.x - (this._horizontal ? rect.width : 0) - hOffset;
136
+ } else {
137
+ position.x = relativeOffset.x + ((relativeRect.width - rect.width) >> 1) - hOffset;
96
138
  }
97
139
 
98
140
  if (this._anchors & ANCHOR_BOTTOM) {
99
141
  position.y = relativeOffset.y + (this._horizontal ? relativeRect.height : 0) - rect.height - vOffset;
100
- } else {
142
+ } else if (this._anchors & ANCHOR_TOP) {
101
143
  position.y = relativeOffset.y + (this._horizontal ? 0 : relativeRect.height) + vOffset;
144
+ } else {
145
+ position.y = relativeOffset.y + ((relativeRect.height - rect.height) >> 1) + vOffset;
102
146
  }
103
147
 
104
148
  return new Rect(position.x, position.y, rect.width, rect.height);
@@ -1,23 +1,34 @@
1
1
  include('checkbox.js');
2
2
 
3
3
  (function() {
4
+ /**
5
+ * Radio button
6
+ *
7
+ * @author voloko
8
+ * @name uki.view.Radio
9
+ * @class
10
+ * @extends uki.view.Checkbox
11
+ */
4
12
  var manager = uki.view.declare('uki.view.Radio', uki.view.Checkbox, function(base) {
5
13
 
6
14
  this._backgroundPrefix = 'radio-';
7
15
 
16
+ /**
17
+ * @function
18
+ * @param {String} group
19
+ * @name uki.view.Popup#hide
20
+ */
8
21
  this.group = uki.newProp('_group', function(g) {
9
22
  manager.unregisterGroup(this);
10
23
  this._group = g;
11
24
  manager.registerGroup(this);
12
- manager.clearGroup(this);
25
+ if (this.checked()) manager.clearGroup(this);
13
26
  });
14
27
 
15
28
  this.value = this.checked = uki.newProp('_checked', function(state) {
16
- var changed = this._checked != !!state;
17
29
  this._checked = !!state;
18
30
  if (state) manager.clearGroup(this);
19
31
  this._updateBg();
20
- if (changed) this.trigger('change', {checked: this._checked, source: this});
21
32
  });
22
33
 
23
34
  this._mouseup = function() {
@@ -25,6 +36,7 @@ include('checkbox.js');
25
36
  this._down = false;
26
37
  if (!this._checked && !this._disabled) {
27
38
  this.checked(!this._checked);
39
+ this.trigger('change', { checked: this._checked, source: this });
28
40
  }
29
41
  }
30
42
  });
@@ -51,7 +63,10 @@ include('checkbox.js');
51
63
  manager.clearGroup = function(radio) {
52
64
  uki.each(manager.groups[radio.group()] || [], function(i, registered) {
53
65
  if (registered == radio) return;
54
- if (registered.checked()) registered.checked(false);
66
+ if (registered.checked()) {
67
+ registered.checked(false);
68
+ this.trigger('change', { checked: false, source: registered });
69
+ }
55
70
  });
56
71
  };
57
72
 
@@ -19,39 +19,77 @@
19
19
  }
20
20
 
21
21
  /**
22
- * Scroll pane. Pane with scrollbars with content overflowing the borders.
23
- * Works consistently across all supported browsers.
24
- */
22
+ * Scroll pane.
23
+ * Pane with scrollbars with content overflowing the borders.
24
+ * Works consistently across all supported browsers.
25
+ *
26
+ * @author voloko
27
+ * @name uki.view.ScrollPane
28
+ * @class
29
+ * @extends uki.view.Container
30
+ */
25
31
  uki.view.declare('uki.view.ScrollPane', uki.view.Container, function(Base) {
26
- this.typeName = function() {
27
- return 'uki.view.ScrollPane';
28
- };
29
-
32
+ uki.extend(this, {
33
+ _scrollableY: true,
34
+ _scrollableX: false,
35
+ _scrollY: false,
36
+ _scrollX: false,
37
+ _sbY: false,
38
+ _sbX: false
39
+ });
40
+
30
41
  this._setup = function() {
31
42
  Base._setup.call(this);
32
43
 
33
- uki.extend(this, {
34
- _clientRect: this.rect().clone(), // rect with scroll bars excluded
35
- _rectForChild: this.rect().clone(),
36
- _scrollableV: true,
37
- _scrollableH: false,
38
- _scrollV: false,
39
- _scrollH: false,
40
- _sbV: false,
41
- _sbH: false
42
- });
44
+ this._clientRect = this.rect().clone();
45
+ this._rectForChild = this.rect().clone();
43
46
  };
44
47
 
45
- uki.addProps(this, ['scrollableV', 'scrollableH', 'scrollH', 'scrollV']);
48
+ /**
49
+ * @function
50
+ * @name uki.view.ScrollPane#scrollableY
51
+ */
52
+ /**
53
+ * @function
54
+ * @name uki.view.ScrollPane#scrollableX
55
+ */
56
+ /**
57
+ * @function
58
+ * @name uki.view.ScrollPane#scrollX
59
+ */
60
+ /**
61
+ * @function
62
+ * @name uki.view.ScrollPane#scrollY
63
+ */
64
+ uki.addProps(this, ['scrollableY', 'scrollableX', 'scrollX', 'scrollY']);
65
+ this.scrollV = this.scrollY;
66
+ this.scrollH = this.scrollX;
67
+
68
+ this.scrollableV = this.scrollableY;
69
+ this.scrollableH = this.scrollableX;
46
70
 
47
71
  this.rectForChild = function() { return this._rectForChild; };
48
72
  this.clientRect = function() { return this._clientRect; };
49
73
 
74
+ /**
75
+ * @function
76
+ * @param {Number} dx
77
+ * @param {Number} dy
78
+ * @name uki.view.ScrollPane#scroll
79
+ */
50
80
  this.scroll = function(dx, dy) {
51
- if (dx) this.scrollTop(this.scrollLeft() + dy);
81
+ if (dx) this.scrollLeft(this.scrollLeft() + dx);
52
82
  if (dy) this.scrollTop(this.scrollTop() + dy);
53
83
  };
54
84
 
85
+ /**
86
+ * @function
87
+ * @name uki.view.ScrollPane#scrollTop
88
+ */
89
+ /**
90
+ * @function
91
+ * @name uki.view.ScrollPane#scrollLeft
92
+ */
55
93
  uki.each(['scrollTop', 'scrollLeft'], function(i, name) {
56
94
  this[name] = function(v) {
57
95
  if (v == undefined) return this._dom[name];
@@ -61,6 +99,11 @@
61
99
  };
62
100
  }, this);
63
101
 
102
+ /**
103
+ * @function
104
+ * @return {uki.geometry.Rect}
105
+ * @name uki.view.ScrollPane#visibleRect
106
+ */
64
107
  this.visibleRect = function() {
65
108
  var tmpRect = this._clientRect.clone();
66
109
  tmpRect.x = this.rect().x + this.scrollLeft();
@@ -91,15 +134,15 @@
91
134
 
92
135
  var cw = this.contentsWidth(),
93
136
  ch = this.contentsHeight(),
94
- sh = this._scrollableH ? cw > this._rect.width : false,
95
- sv = this._scrollableV ? ch > this._rect.height : false;
137
+ sx = this._scrollableX ? cw > this._rect.width : false,
138
+ sy = this._scrollableY ? ch > this._rect.height : false;
96
139
 
97
- this._sbH = sh || this._scrollH;
98
- this._sbV = sv || this._scrollV;
99
- this._clientRect = new Rect( this._rect.width + (sv ? -1 : 0) * scrollWidth,
100
- this._rect.height + (sh ? -1 : 0) * scrollWidth );
101
- this._rectForChild = new Rect( this._rect.width + (sv && !widthIncludesScrollBar ? -1 : 0) * scrollWidth,
102
- this._rect.height + (sh && !widthIncludesScrollBar ? -1 : 0) * scrollWidth );
140
+ this._sbX = sx || this._scrollX;
141
+ this._sbY = sy || this._scrollY;
142
+ this._clientRect = new Rect( this._rect.width + (sy ? -1 : 0) * scrollWidth,
143
+ this._rect.height + (sx ? -1 : 0) * scrollWidth );
144
+ this._rectForChild = new Rect( this._rect.width + ((sy && !widthIncludesScrollBar) ? -1 : 0) * scrollWidth,
145
+ this._rect.height + ((sx && !widthIncludesScrollBar) ? -1 : 0) * scrollWidth );
103
146
  };
104
147
 
105
148
  this._updateClientRects = function() {
@@ -128,19 +171,34 @@
128
171
  this._layoutDom = function(rect) {
129
172
  this._updateClientRects();
130
173
 
131
- if (this._layoutScrollH !== this._sbH) {
132
- this._dom.style.overflowX = this._sbH ? 'scroll' : 'hidden';
133
- this._layoutScrollH = this._sbH;
174
+ if (this._layoutScrollX !== this._sbX) {
175
+ this._dom.style.overflowX = this._sbX ? 'scroll' : 'hidden';
176
+ this._layoutScrollX = this._sbX;
134
177
  }
135
178
 
136
- if (this._layoutScrollV !== this._sbV) {
137
- this._dom.style.overflowY = this._sbV ? 'scroll' : 'hidden';
138
- this._layoutScrollV = this._sbV;
179
+ if (this._layoutScrollY !== this._sbY) {
180
+ this._dom.style.overflowY = this._sbY ? 'scroll' : 'hidden';
181
+ this._layoutScrollY = this._sbY;
139
182
  }
140
183
 
141
184
  Base._layoutDom.call(this, rect);
142
185
  };
186
+
187
+ this.childResized = function() {
188
+ this._needsLayout = true;
189
+ uki.after(uki.proxy(this.layoutIfNeeded, this));
190
+ };
191
+
192
+ this._contentChanged = this.childResized;
193
+
143
194
  });
144
195
 
145
196
  uki.view.ScrollPane.initScrollWidth = initScrollWidth;
146
197
  })();
198
+
199
+ uki.Collection.addAttrs(['scrollTop', 'scrollLeft']);
200
+ uki.fn.scroll = function(dx, dy) {
201
+ this.each(function() {
202
+ this.scroll(dx, dy);
203
+ });
204
+ };
@@ -1,4 +1,15 @@
1
- uki.view.declare('uki.view.Slider', uki.view.Base, uki.view.Focusable, function(Base, Focusable) {
1
+ /**
2
+ * Horizontal Slider.
3
+ *
4
+ * @author voloko
5
+ * @name uki.view.Slider
6
+ * @class
7
+ * @extends uki.view.Base
8
+ * @implements uki.view.Focusable
9
+ */
10
+ uki.view.declare('uki.view.Slider', uki.view.Container, uki.view.Focusable, function(Base, Focusable) {
11
+
12
+ this._handleSize = new Size(10,18);
2
13
 
3
14
  this._setup = function() {
4
15
  Base._setup.call(this);
@@ -11,6 +22,22 @@ uki.view.declare('uki.view.Slider', uki.view.Base, uki.view.Focusable, function(
11
22
  });
12
23
  };
13
24
 
25
+ /**
26
+ * @function
27
+ * @name uki.view.Slider#min
28
+ */
29
+ /**
30
+ * @function
31
+ * @name uki.view.Slider#max
32
+ */
33
+ /**
34
+ * @function
35
+ * @name uki.view.Slider#values
36
+ */
37
+ /**
38
+ * @function
39
+ * @name uki.view.Slider#keyStep
40
+ */
14
41
  uki.addProps(this, ['min', 'max', 'values', 'keyStep']);
15
42
 
16
43
  this.values = uki.newProp('_values', function(val) {
@@ -20,74 +47,69 @@ uki.view.declare('uki.view.Slider', uki.view.Base, uki.view.Focusable, function(
20
47
  });
21
48
 
22
49
  /**
23
- * @fires event:change
24
- */
50
+ * @function
51
+ * @fires event:change
52
+ * @name uki.view.Slider#value
53
+ */
25
54
  this.value = uki.newProp('_value', function(val) {
26
55
  this._value = MAX(this._min, MIN(this._max, val));
27
56
  this._position = this._val2pos(this._value);
28
57
  this._moveHandle();
29
- this.trigger('change', {source: this, value: this._value});
30
58
  });
31
59
 
32
60
  this._pos2val = function(pos, cacheIndex) {
33
61
  if (this._values) {
34
- var index = Math.round(1.0 * pos / this._rect.width * (this._values.length - 1));
62
+ var index = Math.round(1.0 * pos / (this._rect.width - this._handleSize.width) * (this._values.length - 1));
35
63
  if (cacheIndex) this._cachedIndex = index;
36
64
  return this._values[index];
37
65
  }
38
- return pos / this._rect.width * (this._max - this._min);
66
+ return pos / (this._rect.width - this._handleSize.width) * (this._max - this._min) + this._min;
39
67
  };
40
68
 
41
69
  this._val2pos = function(val) {
42
70
  if (this._values) {
43
71
  var index = this._cachedIndex !== undefined ? this._cachedIndex : uki.binarySearch(val, this._values);
44
- return index / (this._values.length - 1) * this._rect.width;
72
+ return index / (this._values.length - 1) * (this._rect.width - this._handleSize.width);
45
73
  }
46
- return val / (this._max - this._min) * this._rect.width;
74
+ return (val - this._min) / (this._max - this._min) * (this._rect.width - this._handleSize.width);
47
75
  };
48
76
 
49
77
  this._createDom = function() {
50
78
  this._dom = uki.createElement('div', this.defaultCss + 'height:18px;-moz-user-select:none;-webkit-user-select:none;overflow:visible;');
51
- this._handle = uki.createElement('div', this.defaultCss + 'overflow:hidden;cursor:default;background:url(' + uki.theme.image('x').src + ')');
52
- this._bg = uki.theme.image('slider-handle');
53
- this._focusBg = uki.theme.image('slider-focus');
54
- this._focusBg.style.cssText += this._bg.style.cssText += this.defaultCss + 'top:0;left:0;z-index:-1;position:absolute;';
55
- this._handle.appendChild(this._bg);
56
-
79
+ this._initClassName();
80
+ this._handle = uki({
81
+ view: 'SliderHandle',
82
+ rect: new Rect(0, (this._rect.height-this._handleSize.height)/2, this._handleSize.width, this._handleSize.height),
83
+ anchors: 'left top'
84
+ })[0];
85
+ this.appendChild(this._handle);
57
86
 
58
87
  uki.theme.background('slider-bar').attachTo(this);
59
- this._initFocusable();
60
-
61
- uki.image.load([this._bg, this._focusBg], uki.proxy(this._afterHandleLoad, this) );
62
- };
63
-
64
- this._afterHandleLoad = function() {
65
- this._focusBg.style.cssText += ';z-index:10;margin-left:-' + (this._focusBg.width) / 2 + 'px;margin-top:-' + (this._focusBg.height-(this._bg.height/2)+1)/2 + 'px;';
66
- this._handle.style.cssText += ';margin-left:-' + (this._bg.width / 2) + 'px;width:' +this._bg.width + 'px;height:' + (this._bg.height / 2) + 'px;';
67
- this._dom.appendChild(this._handle);
68
-
69
- uki.each(['mouseenter', 'mouseleave', 'draggesturestart', 'draggesture', 'draggestureend'], function(i, name) {
70
- uki.dom.bind(this._handle, name, uki.proxy(this['_' + name], this));
88
+ uki.each(['draggesturestart', 'draggesture', 'draggestureend'], function(i, name) {
89
+ this._handle.bind(name, uki.proxy(this['_' + name], this));
71
90
  }, this);
72
91
 
73
- this.bind('click', this._click);
74
92
  this.bind(uki.view.List.prototype.keyPressEvent(), this._keypress);
93
+ this.bind('click', this._click);
94
+
95
+ this._initFocusable();
75
96
  };
76
97
 
77
- this._mouseenter = function() {
78
- this._over = true;
79
- this._bg.style.top = - this._bg.height / 2 + 'px';
98
+ this._focus = function(e) {
99
+ this._handle._focus();
100
+ Focusable._focus.call(this, e);
80
101
  };
81
-
82
- this._mouseleave = function() {
83
- this._over = false;
84
- this._bg.style.top = this._dragging ? (- this._bg.height / 2 + 'px') : 0;
102
+
103
+ this._blur = function(e) {
104
+ this._handle._blur();
105
+ Focusable._blur.call(this, e);
85
106
  };
86
107
 
87
108
  this._click = function(e) {
88
- var x = e.pageX - uki.dom.offset(this._dom).x;
109
+ var x = e.pageX - uki.dom.offset(this._dom).x - this._handleSize.width/2;
89
110
  this.value(this._pos2val(x, true));
90
111
  this._cachedIndex = undefined;
112
+ this.trigger('change', {source: this, value: this._value});
91
113
  };
92
114
 
93
115
  this._keypress = function(e) {
@@ -99,13 +121,15 @@ uki.view.declare('uki.view.Slider', uki.view.Base, uki.view.Focusable, function(
99
121
  };
100
122
 
101
123
  this._moveHandle = function() {
102
- // this._focusBg.style.left = this._handle.style.left = 100.0*this._position/this._rect.width + '%';
103
- this._focusBg.style.left = this._handle.style.left = this._position + 'px';
124
+ var rect = this._handle.rect().clone();
125
+ rect.x = this._position;
126
+ rect.y = (this._rect.height - this._handleSize.height) / 2;
127
+ this._handle.rect(rect).layout();
104
128
  };
105
129
 
106
130
  this._draggesturestart = function(e) {
107
131
  this._dragging = true;
108
- this._initialPosition = new Point(parseInt(this._handle.style.left, 10), parseInt(this._handle.style.top, 10));
132
+ this._initialPosition = this._handle.rect().clone();
109
133
  return true;
110
134
  };
111
135
 
@@ -113,7 +137,7 @@ uki.view.declare('uki.view.Slider', uki.view.Base, uki.view.Focusable, function(
113
137
  * @fires event:change
114
138
  */
115
139
  this._draggesture = function(e) {
116
- var position = MAX(0, MIN(this._rect.width, this._initialPosition.x + e.dragOffset.x));
140
+ var position = MAX(0, MIN(this._rect.width - this._handleSize.width, this._initialPosition.x + e.dragOffset.x));
117
141
  this.value(this._pos2val(position, true));
118
142
  this._cachedIndex = undefined;
119
143
  };
@@ -121,26 +145,13 @@ uki.view.declare('uki.view.Slider', uki.view.Base, uki.view.Focusable, function(
121
145
  this._draggestureend = function(e) {
122
146
  this._dragging = false;
123
147
  this._initialPosition = null;
124
- if (!this._over) this._bg.style.top = 0;
125
148
  this.value(this._pos2val(this._position, true));
126
149
  this._cachedIndex = undefined;
127
- };
128
-
129
- this._focus = function(e) {
130
- this._dom.appendChild(this._focusBg);
131
- this._focusBg.style.left = this._handle.style.left;
132
- Focusable._focus.call(this, e);
133
- };
134
-
135
- this._blur = function(e) {
136
- this._dom.removeChild(this._focusBg);
137
- Focusable._blur.call(this, e);
150
+ this.trigger('change', {source: this, value: this._value});
138
151
  };
139
152
 
140
153
  this._layoutDom = function(rect) {
141
- var fixedRect = rect.clone();
142
- fixedRect.height = 18;
143
- Base._layoutDom.call(this, fixedRect);
154
+ Base._layoutDom.call(this, rect);
144
155
  this._position = this._val2pos(this._value);
145
156
  this._moveHandle();
146
157
  return true;
@@ -152,3 +163,5 @@ uki.view.declare('uki.view.Slider', uki.view.Base, uki.view.Focusable, function(
152
163
  };
153
164
 
154
165
  });
166
+
167
+ uki.view.declare('uki.view.SliderHandle', uki.view.Button, { _backgroundPrefix: 'slider-handle-', _focusable: false });