glimmer-cw-cdatetime-nebula 1.4.0.2.1 → 1.5.0.3.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.
@@ -0,0 +1,326 @@
1
+ require 'glimmer/swt/widget_proxy'
2
+ #
3
+ module Glimmer
4
+ module SWT
5
+ class CDateTimeProxy < WidgetProxy
6
+ class << self
7
+ def create(keyword, parent, args, block)
8
+ # TODO support :tab_fields style
9
+ # TODO support :border style
10
+ # TODO support :compact style
11
+ # TODO support :spinner style
12
+ # TODO support :date_medium and :date_long styles
13
+ # TODO support :time_medium style
14
+ # TODO support :CLOCK_24_HOUR style in addition to :CLOCK_12_HOUR
15
+ # TODO support :BUTTON_ALWAYS, :BUTTON_AUTO, :BUTTON_MANUAL, :BUTTON_NEVER, :BUTTON_LEFT, and :BUTTON_RIGHT styles
16
+ # TODO support "Today" functionality
17
+ # TODO support pattern functionality
18
+ if [keyword].include_any?('c_date', 'c_date_drop_down', 'c_date_spinner', 'c_date_compact')
19
+ args += [:date_short]
20
+ end
21
+ if [keyword].include_any?('c_time', 'c_time_drop_down', 'c_time_spinner', 'c_time_compact')
22
+ args += [:time_short]
23
+ end
24
+ if keyword.end_with?('_drop_down')
25
+ args += [:drop_down]
26
+ elsif keyword.end_with?('_spinner')
27
+ args += [:spinner]
28
+ elsif keyword.end_with?('_compact')
29
+ args += [:compact]
30
+ else
31
+ args += [:simple]
32
+ end
33
+
34
+ new(parent, args, block)
35
+ end
36
+ end
37
+
38
+ def initialize(parent, args, block)
39
+ super(parent, args, block)
40
+ post_add_content if block.nil?
41
+ end
42
+
43
+ def post_add_content
44
+ if date?
45
+ options = {
46
+ changeMonth: true,
47
+ changeYear: true,
48
+ }
49
+ if drop_down?
50
+ options = options.merge(
51
+ showOn: 'both',
52
+ buttonImage: 'assets/glimmer/images/calendar.gif',
53
+ buttonImageOnly: true,
54
+ buttonText: 'Select date',
55
+ )
56
+ end
57
+ date_input_dom_element.datepicker(options)
58
+ end
59
+
60
+ if time?
61
+ clocklet
62
+ if drop_down?
63
+ time_button_dom_element.on('click') do |event|
64
+ `clocklet.open(document.getElementById(#{time_input_id}))`
65
+ end
66
+ end
67
+ end
68
+
69
+ selection_value = self.selection
70
+ @added_content = true
71
+ self.selection = selection_value
72
+ end
73
+
74
+ def clocklet
75
+ unless defined?(@@clocklet_default_options_set)
76
+ `clocklet.defaultOptions.appendTo = 'parent'`
77
+ `clocklet.defaultOptions.format = 'hh:mm A'`
78
+ @@clocklet_default_options_set = true
79
+ end
80
+ if simple?
81
+ @clocklet ||= Native(`clocklet.inline(document.getElementById(#{clock_id}), {input: document.getElementById(#{time_input_id})})`)
82
+ end
83
+ end
84
+
85
+ def date_time?
86
+ !args.to_a.include_any?(:date_short, :date_medium, :date_long) && !args.to_a.include_any?(:time_short, :time_medium)
87
+ end
88
+
89
+ def date?
90
+ args.to_a.include_any?(:date_short, :date_medium, :date_long) || date_time?
91
+ end
92
+
93
+ def time?
94
+ args.to_a.include_any?(:time_short, :time_medium) || date_time?
95
+ end
96
+
97
+ def drop_down?
98
+ args.to_a.include?(:drop_down)
99
+ end
100
+
101
+ def simple?
102
+ args.to_a.include?(:simple)
103
+ end
104
+
105
+ def compact?
106
+ args.to_a.include?(:compact)
107
+ end
108
+
109
+ def spinner?
110
+ args.to_a.include?(:spinner)
111
+ end
112
+
113
+ def selection
114
+ if @added_content
115
+ default_date = DateTime.new if @selection.nil?
116
+
117
+ current_year = @selection&.year || default_date.year
118
+ current_month = @selection&.month || default_date.month
119
+ current_day = @selection&.day || default_date.day
120
+ current_hour = @selection&.hour || default_date.hour
121
+ current_min = @selection&.min || default_date.min
122
+ current_sec = @selection&.sec || default_date.sec
123
+
124
+ if time?
125
+ time_string = time_input_dom_element.val
126
+ _, current_hour, current_min, am_pm = time_string.match(/(\d{1,2})\:(\d{1,2})[ ]?([APap]?\.?[Mm]?\.?)/).to_a
127
+ current_hour ||= default_hour
128
+ current_min ||= default_min
129
+ current_hour = current_hour.to_i
130
+ am_pm = am_pm.to_s.gsub('.', '').upcase
131
+ current_hour += 12 if am_pm == 'PM'
132
+ current_min = current_min.to_i
133
+ end
134
+
135
+ if date?
136
+ current_year = date_input_dom_element.datepicker('getDate')&.year.to_i
137
+ current_month = date_input_dom_element.datepicker('getDate')&.month.to_i
138
+ current_day = date_input_dom_element.datepicker('getDate')&.day.to_i
139
+ end
140
+
141
+ @selection = DateTime.new(current_year, current_month, current_day, current_hour, current_min, current_sec)
142
+ @selection = @selection&.to_datetime
143
+ else
144
+ @initial_selection
145
+ end
146
+ end
147
+
148
+ def selection=(value)
149
+ if @added_content
150
+ @selection = value&.to_datetime || DateTime.new
151
+
152
+ if time?
153
+ formatted_time = @selection.strftime('%I:%M %p')
154
+ if drop_down? || spinner? || compact?
155
+ time_input_dom_element.val(formatted_time)
156
+ else
157
+ clocklet.value(formatted_time)
158
+ end
159
+ end
160
+
161
+ if date?
162
+ date_input_dom_element.datepicker('setDate', @selection.to_time)
163
+ end
164
+ else
165
+ @initial_selection = value
166
+ end
167
+ end
168
+
169
+ def observation_request_to_event_mapping
170
+ {
171
+ 'on_widget_selected' => [
172
+ { # time
173
+ event: 'input',
174
+ },
175
+ { # date
176
+ event: 'change',
177
+ },
178
+ ],
179
+ }
180
+ end
181
+
182
+ def listener_path
183
+ if date_time?
184
+ "#{date_input_path}, #{time_input_path}"
185
+ elsif date?
186
+ date_input_path
187
+ else # time
188
+ time_input_path
189
+ end
190
+ end
191
+
192
+ def time_button_id
193
+ "#{id}-time-button"
194
+ end
195
+
196
+ def time_button_class
197
+ "#{name}-time-button"
198
+ end
199
+
200
+ def time_button_path
201
+ "#{path} ##{time_button_id}"
202
+ end
203
+
204
+ def time_button_dom_element
205
+ Document.find(time_button_path)
206
+ end
207
+
208
+ def element
209
+ 'span'
210
+ end
211
+
212
+ def date_input_id
213
+ "#{id}-date-input"
214
+ end
215
+
216
+ def date_input_class
217
+ "#{name}-date-input"
218
+ end
219
+
220
+ def date_input_path
221
+ "#{path} ##{date_input_id}"
222
+ end
223
+
224
+ def date_input_dom_element
225
+ Document.find(date_input_path)
226
+ end
227
+
228
+ def time_input_id
229
+ "#{id}-time-input"
230
+ end
231
+
232
+ def time_input_class
233
+ "#{name}-time-input"
234
+ end
235
+
236
+ def time_input_path
237
+ "#{path} ##{time_input_id}"
238
+ end
239
+
240
+ def time_input_dom_element
241
+ Document.find(time_input_path)
242
+ end
243
+
244
+ def clock_id
245
+ "#{id}-clock"
246
+ end
247
+
248
+ def clock_class
249
+ "#{name}-clock"
250
+ end
251
+
252
+ def clock_path
253
+ "#{path} .clocklet"
254
+ end
255
+
256
+ def clock_dom_element
257
+ Document.find(clock_path)
258
+ end
259
+
260
+ def dom
261
+ date_input_element = simple? ? 'div' : 'input'
262
+ date_input_attributes = {type: 'text', style: 'display: inline-block; vertical-align: top;', id: date_input_id, class: date_input_class}
263
+ time_input_class_value = "#{time_input_class} hide" if time? && simple?
264
+ time_input_attributes = {type: 'text', id: time_input_id, class: time_input_class_value}
265
+ time_input_attributes['data-clocklet'] = 'format: hh:mm A; appendTo: parent;' if time?
266
+ clock_attributes = {id: clock_id, class: clock_class, style: 'display: inline-block; vertical-align: top;'}
267
+ clock_attributes[:style] = 'display: inline-block; vertical-align: top; font-size: 13px; '
268
+ the_class = name
269
+ the_class += ' simple' if simple?
270
+ the_class += ' drop-down' if drop_down?
271
+ the_class += ' spinner' if spinner?
272
+ the_class += ' compact' if compact?
273
+ @dom ||= html {
274
+ span(id: id, class: the_class) {
275
+ # TODO move style somewhere to embed one time for all elements instead of repeating per element
276
+ style {
277
+ css {
278
+ s('.c-date-time.simple .clocklet, .c-date-time.drop-down .clocklet') {
279
+ pv 'font-size', '13px'
280
+ pv 'width', '207px'
281
+ pv 'height', '207px'
282
+ }
283
+ s('.c-date-time.compact .clocklet, .c-date-time.spinner .clocklet') {
284
+ pv 'display', 'none'
285
+ }
286
+ }
287
+ }
288
+ send(date_input_element, date_input_attributes) {} if date?
289
+ input(time_input_attributes) {} if time?
290
+ div(clock_attributes) {} if time? && simple?
291
+ button(id: time_button_id, class: time_button_class, style: "border: none; background: url(assets/glimmer/images/ui-icons_222222_256x240.png) -80px, -96px; width: 16px; height: 16px;") if time? && drop_down?
292
+ }
293
+ }.to_s
294
+ end
295
+
296
+ def widget_property_listener_installers
297
+ super.merge(
298
+ CDateTimeProxy => {
299
+ :selection => lambda do |observer|
300
+ on_widget_selected { |selection_event|
301
+ observer.call(selection)
302
+ }
303
+ end
304
+ },
305
+
306
+ )
307
+ end
308
+ end
309
+
310
+ # Aliases: `date`, `date_drop_down`, `time`, and `calendar`
311
+ # TODO
312
+ CDateProxy = CDateTimeProxy
313
+ CDateDropDownProxy = CDateTimeProxy
314
+ CDateSpinnerProxy = CDateTimeProxy
315
+ CDateCompactProxy = CDateTimeProxy
316
+ CTimeProxy = CDateTimeProxy
317
+ CTimeDropDownProxy = CDateTimeProxy
318
+ CTimeSpinnerProxy = CDateTimeProxy
319
+ CTimeCompactProxy = CDateTimeProxy
320
+ CDateTimeDropDownProxy = CDateTimeProxy
321
+ CDateTimeSpinnerProxy = CDateTimeProxy
322
+ CDateTimeCompactProxy = CDateTimeProxy
323
+
324
+ end
325
+
326
+ end
@@ -0,0 +1 @@
1
+ # TODO
@@ -1,5 +1,5 @@
1
1
  # Copyright (c) 2020 - Andy Maleh
2
- #
2
+ #
3
3
  # Permission is hereby granted, free of charge, to any person obtaining
4
4
  # a copy of this software and associated documentation files (the
5
5
  # "Software"), to deal in the Software without restriction, including
@@ -7,10 +7,10 @@
7
7
  # distribute, sublicense, and/or sell copies of the Software, and to
8
8
  # permit persons to whom the Software is furnished to do so, subject to
9
9
  # the following conditions:
10
- #
10
+ #
11
11
  # The above copyright notice and this permission notice shall be
12
12
  # included in all copies or substantial portions of the Software.
13
- #
13
+ #
14
14
  # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
15
  # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
16
  # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
@@ -19,16 +19,25 @@
19
19
  # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
20
  # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
21
21
 
22
- require_relative '../../lib/glimmer-cw-cdatetime-nebula'
22
+ $LOAD_PATH.unshift File.expand_path('../../../lib', __FILE__)
23
+
24
+ require 'glimmer-cw-cdatetime-nebula'
23
25
 
24
26
  class CDateTimeGallery
27
+ class Person
28
+ attr_accessor :date_of_birth
29
+ end
30
+
25
31
  include Glimmer
26
32
 
27
33
  def open
28
- shell {
34
+ person = Person.new
35
+ person.date_of_birth = DateTime.new(2013, 7, 12, 18, 37, 23)
36
+
37
+ shell {
29
38
  grid_layout(4, false) {
30
39
  vertical_spacing 20
31
- }
40
+ }
32
41
  text 'Nebula CDateTime Glimmer Custom Widget Gallery'
33
42
 
34
43
  label {
@@ -41,26 +50,32 @@ class CDateTimeGallery
41
50
 
42
51
  tab_folder {
43
52
  tab_item {
44
- grid_layout 2, false
53
+ grid_layout 2, false
45
54
  text 'Simple'
46
55
 
47
56
  label {
48
57
  text 'c_date_time'
49
58
  font name: 'Consolas', height: 14
50
59
  }
51
- c_date_time
60
+ c_date_time {
61
+ selection bind(person, :date_of_birth)
62
+ }
52
63
 
53
64
  label {
54
65
  text 'c_date'
55
66
  font name: 'Consolas', height: 14
56
67
  }
57
- c_date
68
+ c_date {
69
+ selection bind(person, :date_of_birth)
70
+ }
58
71
 
59
72
  label {
60
73
  text 'c_time'
61
74
  font name: 'Consolas', height: 14
62
75
  }
63
- c_time
76
+ c_time {
77
+ selection bind(person, :date_of_birth)
78
+ }
64
79
  }
65
80
 
66
81
  tab_item {
@@ -73,6 +88,7 @@ class CDateTimeGallery
73
88
  }
74
89
  c_date_time_drop_down {
75
90
  layout_data(:fill, :center, true, true)
91
+ selection bind(person, :date_of_birth)
76
92
  }
77
93
 
78
94
  label {
@@ -81,6 +97,7 @@ class CDateTimeGallery
81
97
  }
82
98
  c_date_drop_down {
83
99
  layout_data(:fill, :center, true, true)
100
+ selection bind(person, :date_of_birth)
84
101
  }
85
102
 
86
103
  label {
@@ -89,11 +106,12 @@ class CDateTimeGallery
89
106
  }
90
107
  c_time_drop_down {
91
108
  layout_data(:fill, :center, true, true)
109
+ selection bind(person, :date_of_birth)
92
110
  }
93
111
  }
94
112
 
95
113
  tab_item {
96
- grid_layout 2, false
114
+ grid_layout 2, false
97
115
  text 'Spinner'
98
116
 
99
117
  label {
@@ -102,6 +120,7 @@ class CDateTimeGallery
102
120
  }
103
121
  c_date_time_spinner {
104
122
  layout_data(:fill, :center, true, true)
123
+ selection bind(person, :date_of_birth)
105
124
  }
106
125
 
107
126
  label {
@@ -110,6 +129,7 @@ class CDateTimeGallery
110
129
  }
111
130
  c_date_spinner {
112
131
  layout_data(:fill, :center, true, true)
132
+ selection bind(person, :date_of_birth)
113
133
  }
114
134
 
115
135
  label {
@@ -118,11 +138,12 @@ class CDateTimeGallery
118
138
  }
119
139
  c_time_spinner {
120
140
  layout_data(:fill, :center, true, true)
141
+ selection bind(person, :date_of_birth)
121
142
  }
122
143
  }
123
144
 
124
145
  tab_item {
125
- grid_layout 2, false
146
+ grid_layout 2, false
126
147
  text 'Compact'
127
148
 
128
149
  label {
@@ -131,6 +152,7 @@ class CDateTimeGallery
131
152
  }
132
153
  c_date_time_compact {
133
154
  layout_data(:fill, :center, true, true)
155
+ selection bind(person, :date_of_birth)
134
156
  }
135
157
 
136
158
  label {
@@ -139,6 +161,7 @@ class CDateTimeGallery
139
161
  }
140
162
  c_date_compact {
141
163
  layout_data(:fill, :center, true, true)
164
+ selection bind(person, :date_of_birth)
142
165
  }
143
166
 
144
167
  label {
@@ -147,11 +170,12 @@ class CDateTimeGallery
147
170
  }
148
171
  c_time_compact {
149
172
  layout_data(:fill, :center, true, true)
173
+ selection bind(person, :date_of_birth)
150
174
  }
151
- }
175
+ }
152
176
  }
153
- }.open
154
- end
177
+ }.open
178
+ end
155
179
  end
156
180
 
157
181
  CDateTimeGallery.new.open