under-os-ui 1.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (104) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +26 -0
  3. data/lib/assets/fontawesome-webfont.ttf +0 -0
  4. data/lib/assets/under-os.css +115 -0
  5. data/lib/core/kernel.rb +16 -0
  6. data/lib/under-os-ui.rb +6 -0
  7. data/lib/under_os/app.rb +26 -0
  8. data/lib/under_os/config.rb +25 -0
  9. data/lib/under_os/history.rb +53 -0
  10. data/lib/under_os/page.rb +178 -0
  11. data/lib/under_os/page/builder.rb +96 -0
  12. data/lib/under_os/page/layout.rb +43 -0
  13. data/lib/under_os/page/matcher.rb +128 -0
  14. data/lib/under_os/page/stylesheet.rb +67 -0
  15. data/lib/under_os/parser.rb +24 -0
  16. data/lib/under_os/parser/css.rb +37 -0
  17. data/lib/under_os/parser/html.rb +97 -0
  18. data/lib/under_os/ui.rb +3 -0
  19. data/lib/under_os/ui/alert.rb +52 -0
  20. data/lib/under_os/ui/button.rb +42 -0
  21. data/lib/under_os/ui/collection.rb +65 -0
  22. data/lib/under_os/ui/collection/cell.rb +21 -0
  23. data/lib/under_os/ui/collection/delegate.rb +70 -0
  24. data/lib/under_os/ui/collection/item.rb +32 -0
  25. data/lib/under_os/ui/collection/layout.rb +43 -0
  26. data/lib/under_os/ui/collection/styles.rb +15 -0
  27. data/lib/under_os/ui/div.rb +3 -0
  28. data/lib/under_os/ui/form.rb +60 -0
  29. data/lib/under_os/ui/icon.rb +61 -0
  30. data/lib/under_os/ui/icon/awesome.rb +376 -0
  31. data/lib/under_os/ui/icon/engine.rb +9 -0
  32. data/lib/under_os/ui/image.rb +31 -0
  33. data/lib/under_os/ui/input.rb +140 -0
  34. data/lib/under_os/ui/label.rb +21 -0
  35. data/lib/under_os/ui/locker.rb +42 -0
  36. data/lib/under_os/ui/navbar.rb +123 -0
  37. data/lib/under_os/ui/progress.rb +17 -0
  38. data/lib/under_os/ui/scroll.rb +102 -0
  39. data/lib/under_os/ui/select.rb +95 -0
  40. data/lib/under_os/ui/sidebar.rb +45 -0
  41. data/lib/under_os/ui/slider.rb +37 -0
  42. data/lib/under_os/ui/spinner.rb +23 -0
  43. data/lib/under_os/ui/style.rb +21 -0
  44. data/lib/under_os/ui/style/fonts.rb +56 -0
  45. data/lib/under_os/ui/style/margins.rb +164 -0
  46. data/lib/under_os/ui/style/outlining.rb +170 -0
  47. data/lib/under_os/ui/style/positioning.rb +183 -0
  48. data/lib/under_os/ui/switch.rb +26 -0
  49. data/lib/under_os/ui/textarea.rb +19 -0
  50. data/lib/under_os/ui/utils/animation.rb +101 -0
  51. data/lib/under_os/ui/utils/commons.rb +70 -0
  52. data/lib/under_os/ui/utils/dimensions.rb +37 -0
  53. data/lib/under_os/ui/utils/events.rb +210 -0
  54. data/lib/under_os/ui/utils/manipulation.rb +44 -0
  55. data/lib/under_os/ui/utils/position.rb +21 -0
  56. data/lib/under_os/ui/utils/size.rb +21 -0
  57. data/lib/under_os/ui/utils/styles.rb +89 -0
  58. data/lib/under_os/ui/utils/traversing.rb +44 -0
  59. data/lib/under_os/ui/utils/wrap.rb +77 -0
  60. data/lib/under_os/ui/view.rb +31 -0
  61. data/spec/assets/app.css +13 -0
  62. data/spec/assets/test.css +7 -0
  63. data/spec/assets/test.html +3 -0
  64. data/spec/assets/test.png +0 -0
  65. data/spec/assets/test_page.rb +2 -0
  66. data/spec/under_os/page/builder_spec.rb +128 -0
  67. data/spec/under_os/page/layout_spec.rb +18 -0
  68. data/spec/under_os/page/matcher_spec.rb +260 -0
  69. data/spec/under_os/page/stylesheet_spec.rb +83 -0
  70. data/spec/under_os/page_spec.rb +5 -0
  71. data/spec/under_os/parser/css_spec.rb +77 -0
  72. data/spec/under_os/parser/html_spec.rb +152 -0
  73. data/spec/under_os/parser_spec.rb +16 -0
  74. data/spec/under_os/ui/button_spec.rb +50 -0
  75. data/spec/under_os/ui/collection_spec.rb +19 -0
  76. data/spec/under_os/ui/div_spec.rb +24 -0
  77. data/spec/under_os/ui/form_spec.rb +156 -0
  78. data/spec/under_os/ui/icon_spec.rb +57 -0
  79. data/spec/under_os/ui/image_spec.rb +39 -0
  80. data/spec/under_os/ui/input_spec.rb +109 -0
  81. data/spec/under_os/ui/label_spec.rb +22 -0
  82. data/spec/under_os/ui/locker_spec.rb +31 -0
  83. data/spec/under_os/ui/progress_spec.rb +31 -0
  84. data/spec/under_os/ui/scroll_spec.rb +75 -0
  85. data/spec/under_os/ui/select_spec.rb +135 -0
  86. data/spec/under_os/ui/sidebar_spec.rb +35 -0
  87. data/spec/under_os/ui/slider_spec.rb +69 -0
  88. data/spec/under_os/ui/spinner_spec.rb +57 -0
  89. data/spec/under_os/ui/style/fonts_spec.rb +111 -0
  90. data/spec/under_os/ui/style/margins_spec.rb +106 -0
  91. data/spec/under_os/ui/style/outlining_spec.rb +101 -0
  92. data/spec/under_os/ui/style/positioning_spec.rb +69 -0
  93. data/spec/under_os/ui/style_spec.rb +19 -0
  94. data/spec/under_os/ui/switch_spec.rb +60 -0
  95. data/spec/under_os/ui/textarea_spec.rb +34 -0
  96. data/spec/under_os/ui/utils/commons_spec.rb +81 -0
  97. data/spec/under_os/ui/utils/events_spec.rb +87 -0
  98. data/spec/under_os/ui/utils/manipulation_spec.rb +130 -0
  99. data/spec/under_os/ui/utils/styles_spec.rb +140 -0
  100. data/spec/under_os/ui/utils/traversing_spec.rb +124 -0
  101. data/spec/under_os/ui/utils/wrap_spec.rb +69 -0
  102. data/spec/under_os/ui/view_spec.rb +39 -0
  103. data/under-os-ui.gemspec +23 -0
  104. metadata +216 -0
@@ -0,0 +1,21 @@
1
+ class UnderOs::UI::Label < UnderOs::UI::View
2
+ wraps UILabel, tag: 'label'
3
+
4
+ def initialize(options={})
5
+ super
6
+
7
+ self.text = options.delete(:text) || ''
8
+ @_.sizeToFit
9
+
10
+ @_.numberOfLines = 1;
11
+ @_.adjustsFontSizeToFitWidth = true;
12
+ end
13
+
14
+ def text
15
+ @_.text
16
+ end
17
+
18
+ def text=(text)
19
+ @_.text = text
20
+ end
21
+ end
@@ -0,0 +1,42 @@
1
+ class UnderOs::UI::Locker < UnderOs::UI::View
2
+ wraps UIView, tag: :locker
3
+
4
+ attr_reader :label, :spinner
5
+
6
+ def initialize(options={})
7
+ super options
8
+
9
+ @dialog = UnderOs::UI::View.new(class: 'locker-dialog')
10
+ @spinner = UnderOs::UI::Spinner.new
11
+ @label = UnderOs::UI::Label.new(text: options[:text] || '')
12
+
13
+ append @dialog.append(@spinner, @label)
14
+
15
+ addClass 'with-label' if options[:text]
16
+ end
17
+
18
+ def show
19
+ insertTo(UnderOs::App.history.current_page.view) if ! parent
20
+ repaint
21
+ end
22
+
23
+ def hide
24
+ remove
25
+ end
26
+
27
+ def text
28
+ @label.text
29
+ end
30
+
31
+ def text=(text)
32
+ @label.text = text
33
+ end
34
+
35
+ def show_for(&block)
36
+ show
37
+ 1.ms.later do
38
+ block.call
39
+ 1.ms.later { hide }
40
+ end
41
+ end
42
+ end
@@ -0,0 +1,123 @@
1
+ class UnderOs::UI::Navbar
2
+ attr_reader :_
3
+
4
+ def initialize(ui_navigation_controller)
5
+ @_ = ui_navigation_controller
6
+ end
7
+
8
+ def repaint(stylesheet)
9
+ end
10
+
11
+ def hide(animated=true)
12
+ @_.setNavigationBarHidden(true, animated:animated)
13
+ end
14
+
15
+ def show(animated=true)
16
+ @_.setNavigationBarHidden(false, animated:animated)
17
+ end
18
+
19
+ def hidden
20
+ @_.navigationBarHidden
21
+ end
22
+
23
+ def visible
24
+ !hidden
25
+ end
26
+
27
+ def disable_swipes
28
+ @_.interactivePopGestureRecognizer.enabled = false
29
+ end
30
+
31
+ def enable_swipes
32
+ @_.interactivePopGestureRecognizer.enabled = true
33
+ end
34
+
35
+ def left_button
36
+ @left_button
37
+ end
38
+
39
+ def left_button=(view)
40
+ @left_button = view
41
+ @_.topViewController.navigationItem.leftBarButtonItem = to_navigation_item(view)
42
+ end
43
+
44
+ def right_button
45
+ right_buttons[0]
46
+ end
47
+
48
+ def right_button=(view)
49
+ self.right_buttons = [view]
50
+ end
51
+
52
+ def right_buttons
53
+ @right_buttons || []
54
+ end
55
+
56
+ def right_buttons=(views)
57
+ views = [views] if views.is_a?(Hash)
58
+ @right_buttons = views
59
+ @_.topViewController.navigationItem.rightBarButtonItems =
60
+ views.map{|v| to_navigation_item(v)}.flatten.compact.reverse
61
+ end
62
+
63
+ private
64
+
65
+ def to_navigation_item(view)
66
+ view = to_raw_uiview(view)
67
+
68
+ if view.is_a?(UIBarButtonItem)
69
+ view
70
+ elsif view.is_a?(UIView)
71
+ UIBarButtonItem.alloc.initWithCustomView(view)
72
+ elsif view.is_a?(Hash)
73
+ view.map do |type, callback|
74
+ if SYSTEM_BUTTONS[type.to_sym]
75
+ UIBarButtonItem.alloc.initWithBarButtonSystemItem SYSTEM_BUTTONS[type.to_sym], target: callback, action: :call
76
+ elsif type.is_a?(UIImage)
77
+ UIBarButtonItem.alloc.initWithImage(type, style: UIBarButtonItemStylePlain, target: callback, action: :call)
78
+ else
79
+ UIBarButtonItem.alloc.initWithTitle(type.to_s, style: UIBarButtonItemStylePlain, target: callback, action: :call)
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ def to_raw_uiview(view)
86
+ view = view.to_sym if view.is_a?(String)
87
+ view = {view: Proc.new{}} if view.is_a?(Symbol)
88
+
89
+ if view.is_a?(UnderOs::UI::View)
90
+ view.addClass('navbar-item')
91
+ view.repaint(UnderOs::App.history.current_page.stylesheet)
92
+ view = view._
93
+ end
94
+
95
+ view
96
+ end
97
+
98
+ SYSTEM_BUTTONS = {
99
+ done: UIBarButtonSystemItemDone,
100
+ cancel: UIBarButtonSystemItemCancel,
101
+ edit: UIBarButtonSystemItemEdit,
102
+ save: UIBarButtonSystemItemSave,
103
+ add: UIBarButtonSystemItemAdd,
104
+ space: UIBarButtonSystemItemFlexibleSpace,
105
+ compose: UIBarButtonSystemItemCompose,
106
+ reply: UIBarButtonSystemItemReply,
107
+ action: UIBarButtonSystemItemAction,
108
+ organize: UIBarButtonSystemItemOrganize,
109
+ bookmarks: UIBarButtonSystemItemBookmarks,
110
+ search: UIBarButtonSystemItemSearch,
111
+ refresh: UIBarButtonSystemItemRefresh,
112
+ camera: UIBarButtonSystemItemCamera,
113
+ trash: UIBarButtonSystemItemTrash,
114
+ stop: UIBarButtonSystemItemStop,
115
+ play: UIBarButtonSystemItemPlay,
116
+ pause: UIBarButtonSystemItemPause,
117
+ rewind: UIBarButtonSystemItemRewind,
118
+ forward: UIBarButtonSystemItemFastForward,
119
+ undor: UIBarButtonSystemItemUndo,
120
+ redo: UIBarButtonSystemItemRedo,
121
+ curl: UIBarButtonSystemItemPageCurl,
122
+ }
123
+ end
@@ -0,0 +1,17 @@
1
+ class UnderOs::UI::Progress < UnderOs::UI::View
2
+ wraps UIProgressView, tag: :progress
3
+
4
+ def initialize(options={})
5
+ super
6
+
7
+ self.value = options[:value] if options[:value]
8
+ end
9
+
10
+ def value
11
+ @_.progress
12
+ end
13
+
14
+ def value=(value)
15
+ @_.setProgress value.to_f, animated: true
16
+ end
17
+ end
@@ -0,0 +1,102 @@
1
+ class UnderOs::UI::Scroll < UnderOs::UI::View
2
+ wraps UIScrollView, tag: :scroll
3
+
4
+ def initialize(options={})
5
+ super
6
+
7
+ self.paging = options.delete(:paging)
8
+
9
+ @_.delegate = self
10
+ end
11
+
12
+ def paging
13
+ @paging == nil ? false : @paging
14
+ end
15
+
16
+ def paging=(value)
17
+ @paging = value == true ? true : nil
18
+ @_.pagingEnabled = paging
19
+ end
20
+
21
+ def contentSize
22
+ UnderOs::Point.new(x: @_.contentSize.width, y: @_.contentSize.height)
23
+ end
24
+
25
+ def contentSize=(*args)
26
+ size = UnderOs::Point.new(*args)
27
+ @_.contentSize = CGSizeMake(size.x, size.y)
28
+ end
29
+
30
+ def contentOffset
31
+ UnderOs::Point.new(x: @_.contentOffset.x, y: @_.contentOffset.y)
32
+ end
33
+
34
+ def contentOffset=(*args)
35
+ offset = UnderOs::Point.new(*args)
36
+ @_.contentOffset = CGPointMake(offset.x, offset.y)
37
+ end
38
+
39
+ def repaint(*args)
40
+ content_size = {}
41
+
42
+ super *args do |styles|
43
+ styles.reject do |key, value|
44
+ if [:contentWidth, :contentHeight].include?(key)
45
+ content_size[key] = value
46
+ end
47
+ end
48
+ end
49
+
50
+ self.style = content_size unless content_size.empty?
51
+ end
52
+
53
+ def centerContent
54
+ left = @_.contentSize.width > @_.bounds.size.width ? 0 :
55
+ (@_.bounds.size.width - @_.contentSize.width) * 0.5
56
+
57
+ top = @_.contentSize.height > @_.bounds.size.height ? 0 :
58
+ (@_.bounds.size.height - @_.contentSize.height) * 0.5
59
+
60
+ @_.contentInset = UIEdgeInsetsMake(top, left, top, left)
61
+ end
62
+
63
+ def scale
64
+ @_.zoomScale
65
+ end
66
+
67
+ def scale=(scale)
68
+ @_.zoomScale = scale
69
+ end
70
+
71
+ def minScale
72
+ @_.minimumZoomScale
73
+ end
74
+
75
+ def minScale=(scale)
76
+ @_.minimumZoomScale = scale
77
+ end
78
+
79
+ def maxScale
80
+ @_.maximumZoomScale
81
+ end
82
+
83
+ def maxScale=(scale)
84
+ @_.maximumZoomScale = scale
85
+ end
86
+
87
+ def zoomItem
88
+ @zoomItem
89
+ end
90
+
91
+ def zoomItem=(item)
92
+ @zoomItem = item.is_a?(UnderOs::UI::View) ? item._ : item
93
+ end
94
+
95
+ def viewForZoomingInScrollView(scrollView)
96
+ @zoomItem
97
+ end
98
+
99
+ def scrollViewDidZoom(scrollView)
100
+ emit :zoom
101
+ end
102
+ end
@@ -0,0 +1,95 @@
1
+ class UnderOs::UI::Select < UnderOs::UI::Input
2
+ wraps UIPickerView, tag: :select
3
+
4
+ def initialize(options={})
5
+ super
6
+
7
+ self.options = options.delete(:options) if options[:options]
8
+ @_.showsSelectionIndicator = true if options[:lense]
9
+
10
+ @_.dataSource = self
11
+ end
12
+
13
+ def optgroups
14
+ @optgroups ||= [{}]
15
+ end
16
+
17
+ def optgroups=(list)
18
+ @optgroups = list.map do |hash|
19
+ {}.tap do |clean_hash|
20
+ hash.each do |key, value|
21
+ clean_hash[key.to_s] = value if key && value
22
+ end
23
+ end
24
+ end
25
+ end
26
+
27
+ def options
28
+ optgroups.size == 1 ? optgroups[0] : optgroups
29
+ end
30
+
31
+ def options=(value)
32
+ self.optgroups = value.is_a?(Array) ? value : [value]
33
+ @_.reloadAllComponents
34
+ end
35
+
36
+ def value
37
+ @value ||= []
38
+ optgroups.size == 1 ? @value[0] : @value
39
+ end
40
+
41
+ def value=(value)
42
+ prev_val = @value
43
+ @value = Array(value).map(&:to_s)
44
+ handle_change if @value != prev_val
45
+
46
+ @value.each_with_index do |value, group|
47
+ i = 0;
48
+ optgroups[group].each do |v, label|
49
+ if value == v
50
+ @_.selectRow i, inComponent: group, animated: false
51
+ else
52
+ i += 1
53
+ end
54
+ end
55
+ end
56
+ end
57
+
58
+ def show
59
+ page.find('select').each do |select|
60
+ select.hide if select.visible && select != self
61
+ end
62
+
63
+ self.style = {bottom: -size.y, display: :block}
64
+
65
+ animate bottom: 0
66
+ end
67
+
68
+ def hide
69
+ animate bottom: -size.y, complete: -> {
70
+ style.display = :none
71
+ }
72
+ end
73
+
74
+
75
+ # UIPickerView delegate
76
+
77
+ def numberOfComponentsInPickerView(picker)
78
+ optgroups.size
79
+ end
80
+
81
+ def pickerView(picker, numberOfRowsInComponent: group)
82
+ optgroups[group].size
83
+ end
84
+
85
+ def pickerView(picker, titleForRow:index, forComponent:group)
86
+ optgroups[group].to_a[index][1]
87
+ end
88
+
89
+ def pickerView(picker, didSelectRow:index, inComponent:group)
90
+ value = (@value || []).dup
91
+ value[group] = optgroups[group].to_a[index][0]
92
+
93
+ self.value = value
94
+ end
95
+ end
@@ -0,0 +1,45 @@
1
+ class UnderOs::UI::Sidebar < UnderOs::UI::View
2
+ wraps UIView, tag: :sidebar
3
+
4
+ LOCATIONS = [:top, :left, :right, :bottom]
5
+
6
+ def initialize(options={})
7
+ super
8
+
9
+ self.location = options.delete(:location) if options.has_key?(:location)
10
+ end
11
+
12
+ def location
13
+ @location || :bottom
14
+ end
15
+
16
+ def location=(value)
17
+ @location = value.to_sym
18
+ @location = nil if ! LOCATIONS.include?(@location)
19
+ end
20
+
21
+ def show
22
+ class_names = self.classNames
23
+ class_names.reject!{ |n| LOCATIONS.include?(n.to_sym) }
24
+
25
+ self.classNames = class_names + [location, 'visible']
26
+ self.style = {location => -slide_distance, display: :block}
27
+
28
+ animate location => 0
29
+ end
30
+
31
+ def hide
32
+ @_class_names -= ['visible']
33
+
34
+ animate location => -slide_distance
35
+ end
36
+
37
+ def hidden
38
+ !classNames.include?('visible')
39
+ end
40
+
41
+ def slide_distance
42
+ [:top, :bottom].include?(location) ? size.y : size.x
43
+ end
44
+
45
+ end