glimmer 0.5.8 → 0.5.9

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.
@@ -8,7 +8,7 @@ module Glimmer
8
8
 
9
9
  def initialize(parent, *swt_constants, options, &content)
10
10
  super
11
- raise Error, 'Invalid custom shell body root! Must be a shell or another custom shell.' unless body_root.is_a?(SWT::ShellProxy) || body_root.is_a?(CustomShell)
11
+ raise Error, 'Invalid custom shell body root! Must be a shell or another custom shell.' unless body_root.swt_widget.is_a?(org.eclipse.swt.widgets.Shell)
12
12
  end
13
13
 
14
14
  # Classes may override
@@ -16,40 +16,59 @@ module Glimmer
16
16
  super_module_included do |klass|
17
17
  klass.include(Glimmer) unless klass.name.include?('Glimmer::UI::CustomShell')
18
18
  klass.prepend DataBinding::ObservableWidget
19
+ Glimmer::UI::CustomWidget.add_custom_widget_namespaces_for(klass) unless klass.name.include?('Glimmer::UI::CustomShell')
19
20
  end
20
21
 
21
22
  class << self
22
23
  def for(underscored_custom_widget_name)
23
- namespaces = underscored_custom_widget_name.
24
+ extracted_namespaces = underscored_custom_widget_name.
24
25
  to_s.
25
26
  split(/__/).map do |namespace|
26
27
  namespace.camelcase(:upper)
27
28
  end
28
- #TODO update code to avoid using reduce and going through all of them, yet stop right when it finds something
29
- custom_widget_class = [Object, Glimmer::UI].reduce([]) do |found, base|
30
- if found.empty?
31
- found << namespaces.reduce(base) do |result, namespace|
32
- namespace = namespace.to_sym
33
- if !result.constants.include?(namespace)
34
- namespace = result.constants.detect {|c| c.to_s.upcase == namespace.to_s.upcase } || namespace
35
- end
36
- begin
37
- result.const_get(namespace)
38
- rescue => e
39
- # Glimmer.logger&.debug "#{e.message}\n#{e.backtrace.join("\n")}"
40
- result
41
- end
29
+ custom_widget_namespaces.each do |base|
30
+ extracted_namespaces.reduce(base) do |result, namespace|
31
+ if !result.constants.include?(namespace)
32
+ namespace = result.constants.detect {|c| c.to_s.upcase == namespace.to_s.upcase } || namespace
33
+ end
34
+ begin
35
+ constant = result.const_get(namespace)
36
+ return constant if constant.ancestors.include?(Glimmer::UI::CustomWidget)
37
+ constant
38
+ rescue => e
39
+ # Glimmer.logger&.debug "#{e.message}\n#{e.backtrace.join("\n")}"
40
+ result
42
41
  end
43
42
  end
44
- found - [Object, Glimmer::UI]
45
- end.first
46
- raise "#{underscored_custom_widget_name} has no custom widget class!" if custom_widget_class.nil?
47
- custom_widget_class if custom_widget_class.ancestors.include?(Glimmer::UI::CustomWidget)
43
+ end
44
+ raise "#{underscored_custom_widget_name} has no custom widget class!"
48
45
  rescue => e
49
46
  Glimmer.logger&.debug e.message
50
47
  Glimmer.logger&.debug "#{e.message}\n#{e.backtrace.join("\n")}"
51
48
  nil
52
49
  end
50
+
51
+ def add_custom_widget_namespaces_for(klass)
52
+ Glimmer::UI::CustomWidget.namespaces_for_class(klass).drop(1).each do |namespace|
53
+ Glimmer::UI::CustomWidget.custom_widget_namespaces << namespace
54
+ end
55
+ end
56
+
57
+ def namespaces_for_class(m)
58
+ return [m] if m.name.nil?
59
+ namespace_constants = m.name.split(/::/).map(&:to_sym)
60
+ namespace_constants.reduce([Object]) do |output, namespace_constant|
61
+ output += [output.last.const_get(namespace_constant)]
62
+ end[1..-1].uniq.reverse
63
+ end
64
+
65
+ def custom_widget_namespaces
66
+ @custom_widget_namespaces ||= reset_custom_widget_namespaces
67
+ end
68
+
69
+ def reset_custom_widget_namespaces
70
+ @custom_widget_namespaces = Set[Object, Glimmer::UI]
71
+ end
53
72
 
54
73
  # Allows defining convenience option readers for an array of option names
55
74
  # Example: `options :color1, :color2` defines `#color1` and `#color2`
@@ -7,7 +7,6 @@ module Glimmer
7
7
  module UI
8
8
  class Video
9
9
  include Glimmer::UI::CustomWidget
10
-
11
10
  include_package 'org.eclipse.swt.browser'
12
11
 
13
12
  options :file, :url
@@ -0,0 +1,709 @@
1
+ require 'yaml'
2
+ require 'filewatcher'
3
+ require 'clipboard'
4
+
5
+ Clipboard.implementation = Clipboard::Java
6
+
7
+ # Gladiator (Glimmer Editor)
8
+ class Gladiator
9
+ include Glimmer
10
+
11
+ class Dir
12
+ class << self
13
+ def local_dir
14
+ @local_dir ||= new(ENV['LOCAL_DIR'] || '.')
15
+ end
16
+ end
17
+
18
+ attr_accessor :selected_child, :filter, :children, :filtered_path_options
19
+ attr_reader :path, :display_path
20
+
21
+ def initialize(path)
22
+ @path = @display_path = path
23
+ self.filtered_path_options = []
24
+ end
25
+
26
+ def children
27
+ ::Dir.glob(::File.join(@path, '*')).map {|p| ::File.file?(p) ? Gladiator::File.new(p) : Gladiator::Dir.new(p)}.sort_by {|c| c.path.to_s.downcase }.sort_by {|c| c.class.name }
28
+ end
29
+
30
+ def filter=(value)
31
+ if value.to_s.empty?
32
+ @filter = nil
33
+ else
34
+ @filter = value
35
+ end
36
+ self.filtered_path_options = filtered.to_a.map(&:display_path)
37
+ end
38
+
39
+ def filtered
40
+ return if filter.nil?
41
+ all_children_files.select do |child|
42
+ child.path.downcase.include?(filter.downcase) ||
43
+ child.path.downcase.gsub('_', '').include?(filter.downcase)
44
+ end.sort_by {|c| c.path.to_s.downcase}
45
+ end
46
+
47
+ def all_children
48
+ @all_children ||= ::Dir.glob(::File.join(@path, '**', '*')).map {|p| ::File.file?(p) ? Gladiator::File.new(p) : Gladiator::Dir.new(p)}
49
+ end
50
+
51
+ def all_children_files
52
+ @all_children_files ||= all_children.select {|child| child.is_a?(Gladiator::File) }
53
+ end
54
+
55
+ def selected_child_path=(selected_path)
56
+ if selected_path && ::File.file?(selected_path)
57
+ @selected_child&.write_dirty_content
58
+ new_child = Gladiator::File.new(selected_path)
59
+ begin
60
+ if new_child.lines.any?
61
+ self.selected_child&.stop_filewatcher
62
+ self.selected_child = new_child
63
+ self.selected_child.start_filewatcher
64
+ end
65
+ rescue
66
+ # no op
67
+ end
68
+ end
69
+ end
70
+
71
+ def selected_child_path
72
+ @selected_child&.path
73
+ end
74
+
75
+ alias filtered_path selected_child_path
76
+ alias filtered_path= selected_child_path=
77
+
78
+ def to_s
79
+ path
80
+ end
81
+ end
82
+
83
+ class File
84
+ include Glimmer
85
+
86
+ attr_accessor :dirty_content, :line_numbers_content, :caret_position, :selection_count, :line_number, :find_text, :replace_text, :top_index
87
+ attr_reader :path, :display_path
88
+
89
+ def initialize(path)
90
+ raise "Not a file path: #{path}" unless ::File.file?(path)
91
+ @display_path = path
92
+ @path = ::File.expand_path(path)
93
+ read_dirty_content = ::File.read(path)
94
+ begin
95
+ # test read dirty content
96
+ read_dirty_content.split("\n")
97
+ observe(self, :dirty_content) do
98
+ lines_text_size = lines.size.to_s.size
99
+ self.line_numbers_content = lines.size.times.map {|n| (' ' * (lines_text_size - (n+1).to_s.size)) + (n+1).to_s }.join("\n")
100
+ end
101
+ self.dirty_content = read_dirty_content
102
+ observe(self, :caret_position) do
103
+ self.line_number = line_index_for_caret_position(caret_position) + 1
104
+ end
105
+ observe(self, :line_number) do
106
+ if line_number
107
+ new_caret_position = lines[0...(line_number.to_i - 1)].map(&:size).sum + line_number.to_i - 1
108
+ self.caret_position = new_caret_position unless line_index_for_caret_position(new_caret_position) == line_index_for_caret_position(caret_position)
109
+ end
110
+ end
111
+ rescue
112
+ # no op in case of a binary file
113
+ end
114
+ end
115
+
116
+ def start_filewatcher
117
+ @filewatcher = Filewatcher.new(@path)
118
+ @thread = Thread.new(@filewatcher) do |fw|
119
+ fw.watch do |filename, event|
120
+ begin
121
+ read_dirty_content = ::File.read(path)
122
+ # test read dirty content
123
+ read_dirty_content.split("\n")
124
+ async_exec do
125
+ self.dirty_content = read_dirty_content if read_dirty_content != dirty_content
126
+ end
127
+ rescue
128
+ # no op in case of a binary file
129
+ end
130
+ end
131
+ end
132
+ end
133
+
134
+ def stop_filewatcher
135
+ @filewatcher&.stop
136
+ end
137
+
138
+ def write_dirty_content
139
+ new_dirty_content = "#{dirty_content.gsub("\r\n", "\n").gsub("\r", "\n").sub(/\n+\z/, '')}\n"
140
+ self.dirty_content = new_dirty_content if new_dirty_content != self.dirty_content
141
+ ::File.write(path, dirty_content) if ::File.exists?(path) && dirty_content.to_s.strip.size > 0
142
+ end
143
+
144
+ def comment_line!
145
+ old_lines = lines
146
+ old_selection_count = self.selection_count
147
+ old_caret_position = self.caret_position
148
+ old_caret_position_line_index = line_index_for_caret_position(old_caret_position)
149
+ old_caret_position_line_caret_position = caret_position_for_line_index(old_caret_position_line_index)
150
+ old_end_caret_line_index = end_caret_position_line_index(caret_position, selection_count)
151
+ new_lines = lines
152
+ delta = 0
153
+ line_indices_for_selection(caret_position, selection_count).reverse.each do | the_line_index |
154
+ delta = 0
155
+ the_line = old_lines[the_line_index]
156
+ if the_line.strip.start_with?('# ')
157
+ new_lines[the_line_index] = the_line.sub(/# /, '')
158
+ delta -= 2
159
+ elsif the_line.strip.start_with?('#')
160
+ new_lines[the_line_index] = the_line.sub(/#/, '')
161
+ delta -= 1
162
+ else
163
+ new_lines[the_line_index] = "# #{the_line}"
164
+ delta += 2
165
+ end
166
+ end
167
+ self.dirty_content = new_lines.join("\n")
168
+ if old_selection_count > 0
169
+ self.caret_position = caret_position_for_line_index(old_caret_position_line_index)
170
+ self.selection_count = (caret_position_for_line_index(old_end_caret_line_index + 1) - self.caret_position)
171
+ else
172
+ new_caret_position = old_caret_position + delta
173
+ new_caret_position = [new_caret_position, old_caret_position_line_caret_position].max
174
+ self.caret_position = new_caret_position
175
+ end
176
+ end
177
+
178
+ def indent!
179
+ old_lines = lines
180
+ old_selection_count = self.selection_count
181
+ old_caret_position = self.caret_position
182
+ old_caret_position_line_index = line_index_for_caret_position(old_caret_position)
183
+ old_caret_position_line_caret_position = caret_position_for_line_index(old_caret_position_line_index)
184
+ old_end_caret_line_index = end_caret_position_line_index(caret_position, selection_count)
185
+ new_lines = lines
186
+ delta = 2
187
+ line_indices_for_selection(caret_position, selection_count).each do |the_line_index|
188
+ the_line = old_lines[the_line_index]
189
+ new_lines[the_line_index] = " #{the_line}"
190
+ end
191
+ old_caret_position = self.caret_position
192
+ self.dirty_content = new_lines.join("\n")
193
+ if old_selection_count > 0
194
+ self.caret_position = caret_position_for_line_index(old_caret_position_line_index)
195
+ self.selection_count = (caret_position_for_line_index(old_end_caret_line_index + 1) - self.caret_position)
196
+ else
197
+ self.caret_position = old_caret_position + delta
198
+ end
199
+ end
200
+
201
+ def outdent!
202
+ old_lines = lines
203
+ old_selection_count = self.selection_count
204
+ old_caret_position = self.caret_position
205
+ old_caret_position_line_index = line_index_for_caret_position(old_caret_position)
206
+ old_caret_position_line_caret_position = caret_position_for_line_index(old_caret_position_line_index)
207
+ old_end_caret_line_index = end_caret_position_line_index(caret_position, selection_count)
208
+ new_lines = lines
209
+ delta = 0
210
+ line_indices_for_selection(caret_position, selection_count).each do |the_line_index|
211
+ the_line = old_lines[the_line_index]
212
+ if the_line.start_with?(' ')
213
+ new_lines[the_line_index] = the_line.sub(/ /, '')
214
+ delta = -2
215
+ elsif the_line.start_with?(' ')
216
+ new_lines[the_line_index] = the_line.sub(/ /, '')
217
+ delta = -1
218
+ end
219
+ end
220
+ self.dirty_content = new_lines.join("\n")
221
+ if old_selection_count > 0
222
+ self.caret_position = caret_position_for_line_index(old_caret_position_line_index)
223
+ self.selection_count = (caret_position_for_line_index(old_end_caret_line_index + 1) - self.caret_position)
224
+ else
225
+ new_caret_position = old_caret_position + delta
226
+ new_caret_position = [new_caret_position, old_caret_position_line_caret_position].max
227
+ self.caret_position = new_caret_position
228
+ end
229
+ end
230
+
231
+ def kill_line!
232
+ new_lines = lines
233
+ line_indices = line_indices_for_selection(caret_position, selection_count)
234
+ new_lines = new_lines[0...line_indices.first] + new_lines[(line_indices.last+1)...new_lines.size]
235
+ old_caret_position = self.caret_position
236
+ self.dirty_content = new_lines.join("\n")
237
+ self.caret_position = old_caret_position
238
+ end
239
+
240
+ def duplicate_line!
241
+ old_lines = lines
242
+ old_selection_count = self.selection_count
243
+ old_caret_position = self.caret_position
244
+ old_caret_position_line_index = line_index_for_caret_position(old_caret_position)
245
+ old_caret_position_line_caret_position = caret_position_for_caret_position_start_of_line(old_caret_position_line_index)
246
+ old_end_caret_line_index = end_caret_position_line_index(caret_position, selection_count)
247
+ new_lines = lines
248
+ the_line_indices = line_indices_for_selection(caret_position, selection_count)
249
+ the_lines = lines_for_selection(caret_position, selection_count)
250
+ delta = the_lines.join("\n").size + 1
251
+ the_lines.each_with_index do |the_line, i|
252
+ new_lines.insert(the_line_indices.first + i, the_line)
253
+ end
254
+ self.dirty_content = new_lines.join("\n")
255
+ if old_selection_count > 0
256
+ self.caret_position = caret_position_for_line_index(old_caret_position_line_index)
257
+ self.selection_count = (caret_position_for_line_index(old_end_caret_line_index + 1) - self.caret_position)
258
+ else
259
+ self.caret_position = old_caret_position + delta
260
+ end
261
+ end
262
+
263
+ def find_next
264
+ return if find_text.to_s.empty?
265
+ all_lines = lines
266
+ the_line_index = line_index_for_caret_position(caret_position)
267
+ all_lines.rotate(the_line_index + 1).each_with_index do |the_line, the_index|
268
+ the_index = (the_index + the_line_index + 1)%all_lines.size
269
+ if the_line.downcase.include?(find_text.to_s.downcase)
270
+ self.caret_position = the_line.downcase.index(find_text.to_s.downcase) + caret_position_for_line_index(the_index)
271
+ self.selection_count = find_text.to_s.size
272
+ return
273
+ end
274
+ end
275
+ end
276
+
277
+ def find_previous
278
+ return if find_text.to_s.empty?
279
+ all_lines = lines
280
+ the_line_index = line_index_for_caret_position(caret_position)
281
+ all_lines.rotate(the_line_index).each_with_index.map do |the_line, the_index|
282
+ the_index = (the_index + the_line_index)%all_lines.size
283
+ [the_line, the_index]
284
+ end.reverse.each do |the_line, the_index|
285
+ if the_line.downcase.include?(find_text.to_s.downcase)
286
+ self.caret_position = the_line.downcase.index(find_text.to_s.downcase) + caret_position_for_line_index(the_index)
287
+ self.selection_count = find_text.to_s.size
288
+ return
289
+ end
290
+ end
291
+ end
292
+
293
+ def ensure_find_next
294
+ find_next unless dirty_content[caret_position, find_text.size] == find_text
295
+ end
296
+
297
+ def replace_next
298
+ return if find_text.to_s.empty?
299
+ ensure_find_next
300
+ new_dirty_content = dirty_content
301
+ new_dirty_content[caret_position, find_text.size] = replace_text
302
+ self.dirty_content = new_dirty_content
303
+ find_next
304
+ end
305
+
306
+ def page_up
307
+ self.line_number = [(self.line_number - 15), 1].max
308
+ end
309
+
310
+ def page_down
311
+ self.line_number = [(self.line_number + 15), lines.size].min
312
+ end
313
+
314
+ def home
315
+ self.line_number = 1
316
+ end
317
+
318
+ def end
319
+ self.line_number = lines.size
320
+ end
321
+
322
+ def move_up!
323
+ old_lines = lines
324
+ old_selection_count = self.selection_count
325
+ old_caret_position = self.caret_position
326
+ old_caret_position_line_index = line_index_for_caret_position(old_caret_position)
327
+ old_caret_position_line_caret_position = caret_position_for_caret_position_start_of_line(old_caret_position_line_index)
328
+ old_end_caret_line_index = end_caret_position_line_index(caret_position, selection_count)
329
+ new_lines = lines
330
+ the_line_indices = line_indices_for_selection(caret_position, selection_count)
331
+ the_lines = lines_for_selection(caret_position, selection_count)
332
+ new_line_index = [the_line_indices.first - 1, 0].max
333
+ delta = -1 * (new_lines[new_line_index].size + 1)
334
+ new_lines[the_line_indices.first..the_line_indices.last] = []
335
+ new_lines[new_line_index...new_line_index] = the_lines
336
+ self.dirty_content = new_lines.join("\n")
337
+ if old_selection_count > 0
338
+ self.caret_position = caret_position_for_line_index(old_caret_position_line_index) + delta
339
+ self.selection_count = (caret_position_for_line_index(old_end_caret_line_index + 1) - self.caret_position + delta)
340
+ else
341
+ self.caret_position = old_caret_position + delta
342
+ end
343
+ end
344
+
345
+ def move_down!
346
+ old_lines = lines
347
+ old_selection_count = self.selection_count
348
+ old_caret_position = self.caret_position
349
+ old_caret_position_line_index = line_index_for_caret_position(old_caret_position)
350
+ old_caret_position_line_caret_position = caret_position_for_caret_position_start_of_line(old_caret_position_line_index)
351
+ old_end_caret_line_index = end_caret_position_line_index(caret_position, selection_count)
352
+ new_lines = lines
353
+ the_line_indices = line_indices_for_selection(caret_position, selection_count)
354
+ the_lines = lines_for_selection(caret_position, selection_count)
355
+ new_line_index = [the_line_indices.first + 1, new_lines.size - 1].min
356
+ delta = new_lines[new_line_index].size + 1
357
+ new_lines[the_line_indices.first..the_line_indices.last] = []
358
+ new_lines[new_line_index...new_line_index] = the_lines
359
+ self.dirty_content = new_lines.join("\n")
360
+ if old_selection_count > 0
361
+ self.caret_position = caret_position_for_line_index(old_caret_position_line_index) + delta
362
+ self.selection_count = (caret_position_for_line_index(old_end_caret_line_index + 1) - self.caret_position + delta)
363
+ else
364
+ self.caret_position = old_caret_position + delta
365
+ end
366
+ end
367
+
368
+ def lines
369
+ dirty_content.split("\n")
370
+ end
371
+
372
+ def line_for_caret_position(caret_position)
373
+ lines[line_index_for_caret_position(caret_position)]
374
+ end
375
+
376
+ def line_index_for_caret_position(caret_position)
377
+ dirty_content[0...caret_position].count("\n")
378
+ end
379
+
380
+ def caret_position_for_line_index(line_index)
381
+ lines[0...line_index].join("\n").size + 1
382
+ end
383
+
384
+ def caret_position_for_caret_position_start_of_line(caret_position)
385
+ caret_position_for_line_index(line_index_for_caret_position(caret_position))
386
+ end
387
+
388
+ def line_caret_positions_for_selection(caret_position, selection_count)
389
+ line_indices = line_indices_for_selection(caret_position, selection_count)
390
+ line_caret_positions = line_indices.map { |line_index| caret_position_for_line_index(line_index) }.to_a
391
+ end
392
+
393
+ def end_caret_position_line_index(caret_position, selection_count)
394
+ end_caret_position = caret_position + selection_count.to_i
395
+ end_caret_position -= 1 if dirty_content[end_caret_position - 1] == "\n"
396
+ end_line_index = line_index_for_caret_position(end_caret_position)
397
+ end
398
+
399
+ def lines_for_selection(caret_position, selection_count)
400
+ line_indices = line_indices_for_selection(caret_position, selection_count)
401
+ lines[line_indices.first..line_indices.last]
402
+ end
403
+
404
+ def line_indices_for_selection(caret_position, selection_count)
405
+ start_line_index = line_index_for_caret_position(caret_position)
406
+ if selection_count.to_i > 0
407
+ end_line_index = end_caret_position_line_index(caret_position, selection_count)
408
+ else
409
+ end_line_index = start_line_index
410
+ end
411
+ (start_line_index..end_line_index).to_a
412
+ end
413
+
414
+ def children
415
+ []
416
+ end
417
+
418
+ def to_s
419
+ path
420
+ end
421
+ end
422
+
423
+ def initialize
424
+ Display.setAppName('Gladiator')
425
+ @config_file_path = '.gladiator'
426
+ @config = {}
427
+ Gladiator::Dir.local_dir.all_children # pre-caches children
428
+ load_config
429
+ end
430
+
431
+ def load_config
432
+ if ::File.exists?(@config_file_path)
433
+ config_yaml = ::File.read(@config_file_path)
434
+ return if config_yaml.to_s.strip.empty?
435
+ @config = YAML.load(config_yaml)
436
+ Gladiator::Dir.local_dir.selected_child_path = @config[:selected_child_path] if @config[:selected_child_path]
437
+ Gladiator::Dir.local_dir.selected_child.caret_position = Gladiator::Dir.local_dir.selected_child.caret_position_for_caret_position_start_of_line(@config[:caret_position]) if @config[:caret_position]
438
+ Gladiator::Dir.local_dir.selected_child.top_index = @config[:top_index] if @config[:top_index]
439
+ end
440
+ end
441
+
442
+ def save_config
443
+ child = Gladiator::Dir.local_dir.selected_child
444
+ return if child.nil?
445
+ @config = {
446
+ selected_child_path: child.path,
447
+ caret_position: child.caret_position,
448
+ top_index: child.top_index,
449
+ }
450
+ config_yaml = YAML.dump(@config)
451
+ ::File.write(@config_file_path, config_yaml) unless config_yaml.to_s.empty?
452
+ rescue => e
453
+ puts e.full_message
454
+ end
455
+
456
+ def launch
457
+ @display = display {
458
+ on_event_keydown { |key_event|
459
+ if Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr.downcase == 'f'
460
+ if @text.swt_widget.getSelectionText && @text.swt_widget.getSelectionText.size > 0
461
+ @find_text.swt_widget.setText @text.swt_widget.getSelectionText
462
+ end
463
+ @find_text.swt_widget.selectAll
464
+ @find_text.swt_widget.setFocus
465
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command, :shift) && key_event.character.chr.downcase == 'c'
466
+ Clipboard.copy(Gladiator::Dir.local_dir.selected_child.path)
467
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command, :shift) && key_event.character.chr.downcase == 'g'
468
+ Gladiator::Dir.local_dir.selected_child.find_previous
469
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr.downcase == 'g'
470
+ Gladiator::Dir.local_dir.selected_child.find_next
471
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr.downcase == 'l'
472
+ @line_number_text.swt_widget.selectAll
473
+ @line_number_text.swt_widget.setFocus
474
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr.downcase == 'r'
475
+ @filter_text.swt_widget.selectAll
476
+ @filter_text.swt_widget.setFocus
477
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr.downcase == 't'
478
+ @tree.swt_widget.setFocus
479
+ end
480
+ }
481
+ }
482
+ @shell = shell {
483
+ text "Gladiator - #{::File.expand_path(Gladiator::Dir.local_dir.path)}"
484
+ minimum_size 720, 450
485
+ size 1440, 900
486
+ grid_layout 2, false
487
+ on_event_close {
488
+ Gladiator::Dir.local_dir.selected_child&.write_dirty_content
489
+ }
490
+ on_widget_disposed {
491
+ Gladiator::Dir.local_dir.selected_child&.write_dirty_content
492
+ }
493
+ composite {
494
+ grid_layout 1, false
495
+ layout_data(:fill, :fill, false, true) {
496
+ width_hint 300
497
+ }
498
+ @filter_text = text {
499
+ layout_data :fill, :center, true, false
500
+ text bind(Gladiator::Dir.local_dir, 'filter')
501
+ on_key_pressed { |key_event|
502
+ if key_event.keyCode == swt(:tab) ||
503
+ key_event.keyCode == swt(:cr) ||
504
+ key_event.keyCode == swt(:lf) ||
505
+ key_event.keyCode == swt(:arrow_up) ||
506
+ key_event.keyCode == swt(:arrow_down)
507
+ @list.swt_widget.setFocus
508
+ elsif key_event.keyCode == swt(:esc)
509
+ @text.swt_widget.setFocus
510
+ end
511
+ }
512
+ }
513
+ composite {
514
+ layout_data(:fill, :fill, true, true)
515
+ @list = list(:border, :h_scroll, :v_scroll) {
516
+ layout_data(:fill, :fill, true, true) {
517
+ #exclude bind(Gladiator::Dir.local_dir, :filter) {|f| !f}
518
+ }
519
+ #visible bind(Gladiator::Dir, 'local_dir.filter') {|f| !!f}
520
+ selection bind(Gladiator::Dir.local_dir, :filtered_path)
521
+ on_widget_selected {
522
+ Gladiator::Dir.local_dir.selected_child_path = @list.swt_widget.getSelection.first
523
+ }
524
+ on_key_pressed { |key_event|
525
+ if Glimmer::SWT::SWTProxy.include?(key_event.keyCode, :cr) || Glimmer::SWT::SWTProxy.include?(key_event.keyCode, :lf)
526
+ Gladiator::Dir.local_dir.selected_child_path = @list.swt_widget.getSelection.first
527
+ @text.swt_widget.setFocus
528
+ end
529
+ }
530
+ }
531
+ @tree = tree(:virtual, :border, :h_scroll, :v_scroll) {
532
+ layout_data(:fill, :fill, true, true) {
533
+ #exclude bind(Gladiator::Dir.local_dir, :filter) {|f| !!f}
534
+ }
535
+ #visible bind(Gladiator::Dir, 'local_dir.filter') {|f| !f}
536
+ items bind(Gladiator::Dir, :local_dir), tree_properties(children: :children, text: :display_path)
537
+ on_widget_selected {
538
+ Gladiator::Dir.local_dir.selected_child_path = @tree.swt_widget.getSelection.first.getText
539
+ }
540
+ on_paint_control {
541
+ root_item = @tree.swt_widget.getItems.first
542
+ if root_item && !root_item.getExpanded
543
+ root_item.setExpanded true
544
+ end
545
+ }
546
+ }
547
+ }
548
+ }
549
+ composite {
550
+ grid_layout 1, false
551
+ layout_data :fill, :fill, true, true
552
+ composite {
553
+ grid_layout 2, false
554
+ @file_path_label = styled_text(:none) {
555
+ layout_data(:fill, :fill, true, false) {
556
+ horizontal_span 2
557
+ }
558
+ background color(:widget_background)
559
+ editable false
560
+ caret nil
561
+ text bind(Gladiator::Dir.local_dir, 'selected_child.path')
562
+ on_mouse_up {
563
+ @file_path_label.swt_widget.selectAll
564
+ }
565
+ on_focus_lost {
566
+ @file_path_label.swt_widget.setSelection(0, 0)
567
+ }
568
+ }
569
+ label {
570
+ text 'Line:'
571
+ }
572
+ @line_number_text = text {
573
+ layout_data(:fill, :fill, true, false) {
574
+ minimum_width 200
575
+ }
576
+ text bind(Gladiator::Dir.local_dir, 'selected_child.line_number', on_read: :to_s, on_write: :to_i)
577
+ on_key_pressed { |key_event|
578
+ if key_event.keyCode == swt(:cr)
579
+ @text.swt_widget.setFocus
580
+ end
581
+ }
582
+ }
583
+ label {
584
+ text 'Find:'
585
+ }
586
+ @find_text = text {
587
+ layout_data(:fill, :fill, true, false) {
588
+ minimum_width 200
589
+ }
590
+ text bind(Gladiator::Dir.local_dir, 'selected_child.find_text')
591
+ on_key_pressed { |key_event|
592
+ if key_event.keyCode == swt(:cr)
593
+ Gladiator::Dir.local_dir.selected_child.find_next
594
+ elsif key_event.keyCode == swt(:esc)
595
+ @text.swt_widget.setFocus
596
+ end
597
+ }
598
+ }
599
+ label {
600
+ text 'Replace:'
601
+ }
602
+ @replace_text = text {
603
+ layout_data(:fill, :fill, true, false) {
604
+ minimum_width 200
605
+ }
606
+ text bind(Gladiator::Dir.local_dir, 'selected_child.replace_text')
607
+ on_focus_gained {
608
+ Gladiator::Dir.local_dir.selected_child.ensure_find_next
609
+ }
610
+ on_key_pressed { |key_event|
611
+ if key_event.keyCode == swt(:cr)
612
+ Gladiator::Dir.local_dir.selected_child.replace_next
613
+ elsif key_event.keyCode == swt(:esc)
614
+ @text.swt_widget.setFocus
615
+ end
616
+ }
617
+ }
618
+ }
619
+ composite {
620
+ layout_data :fill, :fill, true, true
621
+ grid_layout 2, false
622
+ @line_numbers_text = text(:multi) {
623
+ layout_data(:right, :fill, false, true)
624
+ font name: 'Consolas', height: 15
625
+ background color(:widget_background)
626
+ foreground rgb(75, 75, 75)
627
+ text bind(Gladiator::Dir.local_dir, 'selected_child.line_numbers_content')
628
+ top_index bind(Gladiator::Dir.local_dir, 'selected_child.top_index')
629
+ on_focus_gained {
630
+ @text&.swt_widget.setFocus
631
+ }
632
+ on_key_pressed {
633
+ @text&.swt_widget.setFocus
634
+ }
635
+ on_mouse_up {
636
+ @text&.swt_widget.setFocus
637
+ }
638
+ }
639
+ @text = text(:multi, :border, :h_scroll, :v_scroll) {
640
+ layout_data :fill, :fill, true, true
641
+ font name: 'Consolas', height: 15
642
+ foreground rgb(75, 75, 75)
643
+ text bind(Gladiator::Dir.local_dir, 'selected_child.dirty_content')
644
+ focus true
645
+ caret_position bind(Gladiator::Dir.local_dir, 'selected_child.caret_position')
646
+ selection_count bind(Gladiator::Dir.local_dir, 'selected_child.selection_count')
647
+ top_index bind(Gladiator::Dir.local_dir, 'selected_child.top_index')
648
+ on_focus_lost {
649
+ Gladiator::Dir.local_dir.selected_child&.write_dirty_content
650
+ }
651
+ on_key_pressed { |key_event|
652
+ if Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr.downcase == '/'
653
+ Gladiator::Dir.local_dir.selected_child.comment_line!
654
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr.downcase == 'k'
655
+ Gladiator::Dir.local_dir.selected_child.kill_line!
656
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr.downcase == 'd'
657
+ Gladiator::Dir.local_dir.selected_child.duplicate_line!
658
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr.downcase == '['
659
+ Gladiator::Dir.local_dir.selected_child.outdent!
660
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr.downcase == ']'
661
+ Gladiator::Dir.local_dir.selected_child.indent!
662
+ elsif key_event.keyCode == swt(:page_up)
663
+ Gladiator::Dir.local_dir.selected_child.page_up
664
+ key_event.doit = false
665
+ elsif key_event.keyCode == swt(:page_down)
666
+ Gladiator::Dir.local_dir.selected_child.page_down
667
+ key_event.doit = false
668
+ elsif key_event.keyCode == swt(:home)
669
+ Gladiator::Dir.local_dir.selected_child.home
670
+ key_event.doit = false
671
+ elsif key_event.keyCode == swt(:end)
672
+ Gladiator::Dir.local_dir.selected_child.end
673
+ key_event.doit = false
674
+ elsif key_event.stateMask == swt(:command) && key_event.keyCode == swt(:arrow_up)
675
+ Gladiator::Dir.local_dir.selected_child.move_up!
676
+ key_event.doit = false
677
+ elsif key_event.stateMask == swt(:command) && key_event.keyCode == swt(:arrow_down)
678
+ Gladiator::Dir.local_dir.selected_child.move_down!
679
+ key_event.doit = false
680
+ end
681
+ }
682
+ on_verify_text { |verify_event|
683
+ key_code = verify_event.keyCode
684
+ case key_code
685
+ when swt(:tab)
686
+ verify_event.text = ' '
687
+ end
688
+ }
689
+ }
690
+ }
691
+ }
692
+ }
693
+ observe(Gladiator::Dir.local_dir, 'selected_child.line_numbers_content') do
694
+ if @last_line_numbers_content != Gladiator::Dir.local_dir.selected_child.line_numbers_content
695
+ @shell.pack_same_size
696
+ @last_line_numbers_content = Gladiator::Dir.local_dir.selected_child.line_numbers_content
697
+ end
698
+ end
699
+ observe(Gladiator::Dir.local_dir, 'selected_child.caret_position') do
700
+ save_config
701
+ end
702
+ observe(Gladiator::Dir.local_dir, 'selected_child.top_index') do
703
+ save_config
704
+ end
705
+ @shell.open
706
+ end
707
+ end
708
+
709
+ Gladiator.new.launch