glimmer-cs-gladiator 0.1.7 → 0.2.3

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 18bd05231ab3815f4432ee79395284dbe6e5cd34244b1642b7bff4f7a3921c29
4
- data.tar.gz: f2b2a7d6faf0154d878a3c25944a9b3a59c256a45feaf5b2b975379b357f598b
3
+ metadata.gz: d8a4a941695d12f14347c9892758f974e5909455a73020eee8d635c4c38e86a3
4
+ data.tar.gz: 929ff0b362ca29394e80f918b65fbdb911892449d9876a4eca14a7ec4c01b8df
5
5
  SHA512:
6
- metadata.gz: e82f4d0a5306bb03d767fa3dd1f7b23b970ba5fc5fbc87010c3388d2fcaec010134d3780d0fcc7d29b0c85113bb9f5c8daf8ef6284d4fc6b561064ccdd6ba88d
7
- data.tar.gz: fb7a4b16181113d96478f0458a6abebe7c85c6be6d1b3568b39f412d56e278641a58d61e6aea1c977246aa21433f6084da7787db38ae3ee322d1ff5b1f1109f9
6
+ metadata.gz: 993c7ae4684351d97b8b583cf5f59aef4a6d2aec5a68d8c121b6a95bc4e2ee035d6d21f677c8cd79febd5b4379e81808f4b0b977a1aadb388ddba4ab74694b4b
7
+ data.tar.gz: 32d823df2493950f822fdcfceb28fc5d2b6998152ab233dd0e8668f013d0bd5301dd6ec220d4719bd88683f53bbbd33ddbdceac03bb8d1f02fa77bee2cc432b6
data/README.md CHANGED
@@ -1,15 +1,18 @@
1
- # Gladiator (Glimmer Editor) 0.1.7 - Glimmer Custom Shell
1
+ # <img src='https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-gladiator/master/images/glimmer-cs-gladiator-logo.svg' height=85 /> Gladiator 0.2.3 - [Ugliest Text Editor Ever](https://www.reddit.com/r/ruby/comments/hgve8k/gladiator_glimmer_editor_ugliest_text_editor_ever/)
2
+ ## [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=40 /> Glimmer Custom Shell](https://github.com/AndyObtiva/glimmer#custom-shell-gem)
2
3
  [![Gem Version](https://badge.fury.io/rb/glimmer-cs-gladiator.svg)](http://badge.fury.io/rb/glimmer-cs-gladiator)
3
4
 
4
5
  ![Gladiator](images/glimmer-gladiator.png)
5
6
 
6
- Gladiator (short for Glimmer Editor) is a Glimmer sample project under on-going development.
7
- It is not intended to be a full-fledged editor by any means, yet mostly a fun educational exercise in using Glimmer to build a text editor.
8
- Gladiator is also a personal tool for shaping an editor exactly the way I like.
9
- I leave building truly professional text editors to software tooling experts who would hopefully use Glimmer one day.
7
+ Gladiator (short for Glimmer Editor) is a [Glimmer](https://github.com/AndyObtiva/glimmer) sample project under on-going development that demonstrates how to build a text editor in [Glimmer](https://github.com/AndyObtiva/glimmer) (Ruby Desktop Development GUI Library).
8
+ It is not intended to be a full-fledged editor by any means, yet mostly a fun educational exercise in using [Glimmer](https://github.com/AndyObtiva/glimmer).
9
+ Gladiator is also a personal tool for shaping an editor exactly the way I like, with all the keyboard shortcuts I prefer.
10
+ I leave building truly professional text editors to software tooling experts who would hopefully use [Glimmer](https://github.com/AndyObtiva/glimmer) one day. Otherwise, I have been happily using Gladiator to develop all my [open-source projects](https://github.com/AndyObtiva) since May 2020.
10
11
 
11
- Gladiator currently supports the following text editing features:
12
- - File explorer navigation to open file, rename, delete, add new file, add new directory, or refresh tree (CMD+T)
12
+ ## Features
13
+
14
+ Gladiator currently supports the following text editing features (including keyboard shortcuts with Mac CMD=CTRL on Windows/Linux):
15
+ - File explorer navigation with context menu to open file, rename, delete, add new file, add new directory, or refresh tree (CMD+T)
13
16
  - File lookup by name ignoring slashes, underscores, and dots to ease lookup (CMD+R)
14
17
  - Watch open file for external changes to automatically refresh in editor
15
18
  - Watch project subdirectories for changes to automatically refresh in file explorer/file lookup
@@ -26,33 +29,63 @@ Gladiator currently supports the following text editing features:
26
29
  - Comment/Uncomment line/selection (CMD+/)
27
30
  - Indent/Unindent line/selection (CMD+] & CMD+[)
28
31
  - Insert/Prefix New Line (CMD+ENTER & CMD+SHIFT+ENTER)
32
+ - Drag and Drop Text Editor Split Screen (drag a file from File Tree or File Lookup List, and it splits the screen)
29
33
 
30
34
  ## Platforms
31
35
 
32
36
  - Mac: Gladiator works best on the Mac.
37
+ - Windows: Gladiator works well on Windows.
33
38
  - Linux: Gladiator works with handicaps on Linux (performing text editing operations causes scroll jitter)
34
- - Windows: Not tested on Windows yet, but should theoretically work there too.
35
39
 
36
40
  ## Pre-requisites
37
41
 
38
- - JRuby 9.2.11.1 (supporting Ruby 2.5.x syntax) (find at https://www.jruby.org/download)
39
- - Java SE Runtime Environment 7 or higher (find at https://www.oracle.com/java/technologies/javase-downloads.html)
42
+ - [Glimmer DSL for SWT](https://github.com/AndyObtiva/glimmer) (Ruby Desktop Development GUI Library): '>= 0.1.0', '< 2.0.0' (dependency included in Ruby gem).
43
+ - [JRuby](https://www.jruby.org/download): Same version required by [Glimmer](https://github.com/AndyObtiva/glimmer)
44
+ - [JDK](https://www.oracle.com/java/technologies/javase-downloads.html): Same version required by [Glimmer](https://github.com/AndyObtiva/glimmer)
40
45
 
41
46
  ## Setup Instructions
42
47
 
43
- Install Gladiator gem by running (`jgem`, `jruby -S gem`, or `gem` directly if you have RVM):
48
+ Install Gladiator gem by running (`jgem`, `jruby -S gem`, or `gem` directly if you have [RVM](https://rvm.io/)):
44
49
 
45
50
  ```
46
51
  jgem install glimmer-cs-gladiator
47
52
  ```
48
53
 
49
- Afterwards, you may run `gladiator` to bring up the text editor:
54
+ Or add to a JRuby project Bundler `Gemfile` under the `:developement` group:
55
+
56
+ ```
57
+ group :development do
58
+ gem 'glimmer-cs-gladiator'
59
+ end
60
+ ```
61
+
62
+ Run (`jruby -S bundle` or `bundle` directly if you have [RVM](https://rvm.io/)):
63
+
64
+ ```
65
+ jruby -S bundle
66
+ ```
67
+
68
+ ## Usage
69
+
70
+ You may run the `gladiator` command to bring up the text editor in the project directory you would like to edit:
50
71
 
51
72
  ```
52
73
  gladiator
53
74
  ```
54
75
 
55
- Note: If you cloned this project and bundle installed, you may invoke via `bin/gladiator` instead.
76
+ If you are in a different directory from the project you would like to edit, then pass its path as an argument:
77
+
78
+ ```
79
+ gladiator relative-or-absolute-path/to/project
80
+ ```
81
+
82
+ Note: If you cloned this project and bundle installed, you may invoke via `bin/gladiator` instead.
83
+
84
+ If your project is not a JRuby project, then you cannot install [glimmer-cs-gladiator](https://rubygems.org/gems/glimmer-cs-gladiator), so you must install in a separate JRuby environment and invoke by passing the project path as per command above. Alternatively, you may clone this project, and invoke gladiator via `bin/gladiator` (that's how I use Gladiator for most of my projects):
85
+
86
+ ```
87
+ bin/gladiator relative-or-absolute-path/to/project
88
+ ```
56
89
 
57
90
  ### Glimmer Custom Shell Reuse
58
91
 
@@ -60,7 +93,7 @@ To reuse Gladiator as a Glimmer Custom Shell inside another Glimmer application,
60
93
  following to the application's `Gemfile`:
61
94
 
62
95
  ```
63
- gem 'glimmer-cs-gladiator', '0.1.7'
96
+ gem 'glimmer-cs-gladiator', '~> 0.2.3'
64
97
  ```
65
98
 
66
99
  Run:
@@ -69,7 +102,7 @@ Run:
69
102
  jruby -S bundle
70
103
  ```
71
104
 
72
- And, then instantiate the Gladiator custom shell in your Glimmer application via the `gladiator` keyword.
105
+ And, then instantiate the Gladiator [custom shell](https://github.com/AndyObtiva/glimmer#custom-shells) in your [Glimmer](https://github.com/AndyObtiva/glimmer) application via the `gladiator` keyword assuming you already have `include Glimmer` in your class, module, or main object.
73
106
 
74
107
  ## Env Var Options
75
108
 
@@ -92,6 +125,7 @@ It currently remembers:
92
125
  - Last opened file
93
126
  - Caret position
94
127
  - Top line position
128
+ - Opened tabs
95
129
 
96
130
  ## Gotcha
97
131
 
@@ -118,5 +152,12 @@ The signal TERM is in use by the JVM and will not work correctly on this platfor
118
152
 
119
153
  ## Copyright
120
154
 
121
- Copyright (c) 2020 Andy Maleh. See LICENSE.txt for
122
- further details.
155
+ [MIT](https://opensource.org/licenses/MIT)
156
+
157
+ Copyright (c) 2020 Andy Maleh. See [LICENSE.txt](LICENSE.txt) for further details.
158
+
159
+ --
160
+
161
+ [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=40 />](https://github.com/AndyObtiva/glimmer) Built with [Glimmer](https://github.com/AndyObtiva/glimmer) (Ruby Desktop Development GUI Library)
162
+
163
+ Gladiator icon made by <a href="https://www.flaticon.com/authors/freepik" title="Freepik">Freepik</a> from <a href="https://www.flaticon.com/" title="Flaticon">www.flaticon.com</a>
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.2.3
@@ -2,4 +2,5 @@ $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
2
2
 
3
3
  require 'filewatcher'
4
4
  require 'clipboard'
5
+ require 'puts_debuggerer'
5
6
  require 'views/glimmer/gladiator'
@@ -0,0 +1,75 @@
1
+ module Glimmer
2
+ class Gladiator
3
+ class Command
4
+ class << self
5
+ def command_history
6
+ @command_history ||= {}
7
+ end
8
+
9
+ def command_history_for(file)
10
+ # keeping a first command to make redo support work by remembering next command after undoing all
11
+ command_history[file] ||= [Command.new(file)]
12
+ end
13
+
14
+ def do(file, method = nil, command: nil)
15
+ command ||= Command.new(file, method)
16
+ command_history_for(file)&.last&.next_command = command
17
+ command.do
18
+ command_history_for(file) << command
19
+ end
20
+
21
+ def undo(file)
22
+ return if command_history_for(file).size <= 1
23
+ command_history_for(file).pop.undo
24
+ end
25
+
26
+ def redo(file)
27
+ command_history_for(file).last&.redo
28
+ end
29
+ end
30
+
31
+ attr_accessor :file, :method, :next_command, :previous_file_content, :previous_file_caret_position, :previous_file_selection_count
32
+
33
+ def initialize(file, method = nil)
34
+ @file = file
35
+ @method = method
36
+ end
37
+
38
+ def native?
39
+ @method.nil?
40
+ end
41
+
42
+ def do
43
+ return if native?
44
+ backup
45
+ execute
46
+ end
47
+
48
+ def undo
49
+ return if native?
50
+ restore
51
+ end
52
+
53
+ def redo
54
+ return if next_command.nil?# || next_command.native?
55
+ Command.do(next_command.file, command: next_command)
56
+ end
57
+
58
+ def backup
59
+ @previous_file_dirty_content = @file.dirty_content.clone
60
+ @previous_file_caret_position = @file.caret_position
61
+ @previous_file_selection_count = @file.selection_count
62
+ end
63
+
64
+ def restore
65
+ @file.dirty_content = @previous_file_dirty_content.clone
66
+ @file.caret_position = @previous_file_caret_position
67
+ @file.selection_count = @previous_file_selection_count
68
+ end
69
+
70
+ def execute
71
+ @file.send(@method)
72
+ end
73
+ end
74
+ end
75
+ end
@@ -9,29 +9,32 @@ module Glimmer
9
9
 
10
10
  class << self
11
11
  def local_dir
12
- @local_dir ||= new(ENV['LOCAL_DIR'] || '.').tap do |dir|
13
- dir.refresh
14
- @filewatcher = Filewatcher.new(dir.path)
12
+ unless @local_dir
13
+ @local_dir = new(ENV['LOCAL_DIR'] || '.', true)
14
+ @local_dir.refresh
15
+ @filewatcher = Filewatcher.new(@local_dir.path)
15
16
  @thread = Thread.new(@filewatcher) do |fw|
16
17
  fw.watch do |filename, event|
17
18
  if @last_update.nil? || (Time.now.to_f - @last_update) > REFRESH_DELAY
18
- dir.refresh if !filename.include?('new_file') && !dir.selected_child_path_history.include?(filename) && filename != dir.selected_child_path
19
+ @local_dir.refresh if !filename.include?('new_file') && !@local_dir.selected_child_path_history.include?(filename) && filename != @local_dir.selected_child_path
19
20
  end
20
21
  @last_update = Time.now.to_f
21
22
  end
22
23
  end
23
24
  end
25
+ @local_dir
24
26
  end
25
27
  end
26
28
 
27
29
  attr_accessor :selected_child, :filter, :children, :filtered_path_options, :filtered_path, :path, :display_path
28
30
  attr_reader :name, :parent
29
- attr_writer :all_children, :children
31
+ attr_writer :all_children
30
32
 
31
- def initialize(path)
33
+ def initialize(path, is_local_dir = false)
32
34
  @display_path = path
33
35
  @path = ::File.expand_path(@display_path)
34
36
  @name = ::File.basename(::File.expand_path(path))
37
+ @display_path = @path.sub(Dir.local_dir.path, '').sub(/^\//, '') unless is_local_dir
35
38
  self.filtered_path_options = []
36
39
  end
37
40
 
@@ -48,7 +51,15 @@ module Glimmer
48
51
  end
49
52
 
50
53
  def retrieve_children
51
- ::Dir.glob(::File.join(@display_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 }
54
+ @children = ::Dir.glob(::File.join(@path, '*')).map do |p|
55
+ ::File.file?(p) ? Gladiator::File.new(p) : Gladiator::Dir.new(p)
56
+ end.sort_by do |c|
57
+ c.path.to_s.downcase
58
+ end.sort_by do |c|
59
+ c.class.name
60
+ end.each do |child|
61
+ child.retrieve_children if child.is_a?(Dir)
62
+ end
52
63
  end
53
64
 
54
65
  def selected_child_path_history
@@ -65,11 +76,11 @@ module Glimmer
65
76
 
66
77
  def refresh(async: true, force: false)
67
78
  return if @refresh_paused && !force
68
- new_all_children = retrieve_all_children
69
- new_children = retrieve_children
79
+ retrieve_children
80
+ collect_all_children
70
81
  refresh_operation = lambda do
71
- self.all_children = new_all_children
72
- self.children = new_children
82
+ notify_observers(:children)
83
+ notify_observers(:all_children)
73
84
  end
74
85
  if async
75
86
  async_exec(&refresh_operation)
@@ -84,23 +95,31 @@ module Glimmer
84
95
  else
85
96
  @filter = value
86
97
  end
87
- self.filtered_path_options = filtered.to_a.map(&:display_path)
98
+ @last_filtered = filtered.to_a
99
+ self.filtered_path_options = @last_filtered.map(&:display_path)
100
+ @last_filter = @filter
88
101
  end
89
102
 
90
103
  def filtered
91
104
  return if filter.nil?
92
- all_children_files.select do |child|
93
- child.path.downcase.include?(filter.downcase) ||
94
- child.path.downcase.gsub(/[_\/\.]/, '').include?(filter.downcase)
105
+ children_files = !@last_filter.to_s.empty? && filter.downcase.start_with?(@last_filter.downcase) ? @last_filtered : all_children_files
106
+ children_files.select do |child|
107
+ child_path = child.path.to_s.sub(Dir.local_dir.path, '')
108
+ child_path.downcase.include?(filter.downcase) ||
109
+ child_path.downcase.gsub(/[_\/.-]/, '').include?(filter.downcase.gsub(/[_\/.-]/, ''))
95
110
  end.sort_by {|c| c.path.to_s.downcase}
96
111
  end
97
112
 
98
113
  def all_children
99
- @all_children ||= retrieve_all_children
114
+ @all_children ||= collect_all_children
100
115
  end
101
116
 
102
- def retrieve_all_children
103
- ::Dir.glob(::File.join(@display_path, '**', '*')).map {|p| ::File.file?(p) ? Gladiator::File.new(p) : Gladiator::Dir.new(p)}
117
+ def collect_all_children
118
+ @all_children = children.reduce([]) do |output, child|
119
+ addition = [child]
120
+ addition += child.collect_all_children if child.is_a?(Dir)
121
+ output + addition
122
+ end
104
123
  end
105
124
 
106
125
  def all_children_files
@@ -108,9 +127,11 @@ module Glimmer
108
127
  end
109
128
 
110
129
  def selected_child_path=(selected_path)
130
+ full_selected_path = selected_path.include?(Dir.local_dir.path) ? selected_path : ::File.join(Dir.local_dir.path, selected_path)
111
131
  return if selected_path.nil? ||
112
- ::Dir.exist?(selected_path) ||
113
- (selected_child && ::File.expand_path(selected_child.path) == ::File.expand_path(selected_path))
132
+ ::Dir.exist?(full_selected_path) ||
133
+ (selected_child && selected_child.path == full_selected_path)
134
+ selected_path = full_selected_path
114
135
  if ::File.file?(selected_path)
115
136
  @selected_child&.write_dirty_content
116
137
  new_child = Gladiator::File.new(selected_path)
@@ -5,14 +5,16 @@ module Glimmer
5
5
  class File
6
6
  include Glimmer
7
7
 
8
- attr_accessor :line_numbers_content, :selection, :selection_count, :line_number, :find_text, :replace_text, :top_index, :path, :display_path
9
- attr_reader :name, :dirty_content
8
+ attr_accessor :dirty_content, :line_numbers_content, :selection, :selection_count, :line_number, :find_text, :replace_text, :top_index, :path, :display_path, :case_sensitive
9
+ attr_reader :name
10
10
 
11
11
  def initialize(path)
12
12
  raise "Not a file path: #{path}" unless ::File.file?(path)
13
+ @command_history = []
13
14
  @display_path = path
14
15
  @name = ::File.basename(path)
15
16
  @path = ::File.expand_path(path)
17
+ @display_path = @path.sub(Dir.local_dir.path, '').sub(/^\//, '')
16
18
  @top_index = 0
17
19
  @selection_count = 0
18
20
  @selection = Point.new(0, 0 + @selection_count)
@@ -40,6 +42,16 @@ module Glimmer
40
42
  # no op in case of a binary file
41
43
  end
42
44
  end
45
+
46
+ # to use for widget data-binding
47
+ def content=(value)
48
+ Command.do(self) # record a native (OS-widget) operation
49
+ self.dirty_content = value
50
+ end
51
+
52
+ def content
53
+ dirty_content
54
+ end
43
55
 
44
56
  def caret_position=(value)
45
57
  self.selection = Point.new(value, value + selection_count.to_i)
@@ -64,6 +76,7 @@ module Glimmer
64
76
 
65
77
  def dirty_content=(the_content)
66
78
  @dirty_content = the_content if ::File.exist?(path)
79
+ notify_observers(:content)
67
80
  end
68
81
 
69
82
  def start_filewatcher
@@ -149,6 +162,7 @@ module Glimmer
149
162
  line_indices_for_selection(caret_position, selection_count).reverse.each do | the_line_index |
150
163
  delta = 0
151
164
  the_line = old_lines[the_line_index]
165
+ return if the_line.nil?
152
166
  if the_line.strip.start_with?('# ')
153
167
  new_lines[the_line_index] = the_line.sub(/# /, '')
154
168
  delta -= 2
@@ -210,7 +224,7 @@ module Glimmer
210
224
  if the_line.to_s.start_with?(' ')
211
225
  new_lines[the_line_index] = the_line.sub(/ /, '')
212
226
  delta = -2
213
- elsif the_line.start_with?(' ')
227
+ elsif the_line&.start_with?(' ')
214
228
  new_lines[the_line_index] = the_line.sub(/ /, '')
215
229
  delta = -1
216
230
  end
@@ -264,7 +278,7 @@ module Glimmer
264
278
  end
265
279
 
266
280
  def find_next
267
- return if find_text.to_s.empty?
281
+ return if find_text.to_s.empty?
268
282
  all_lines = lines
269
283
  the_line_index = line_index_for_caret_position(caret_position)
270
284
  line_position = line_position_for_caret_position(caret_position)
@@ -275,8 +289,8 @@ module Glimmer
275
289
  the_index = (the_index + rotation)%all_lines.size
276
290
  start_position = 0
277
291
  start_position = line_position + find_text.to_s.size if i == 0 && the_index == the_line_index && found_text?(caret_position)
278
- text_to_find_in = the_line.downcase[start_position..-1]
279
- occurrence_index = text_to_find_in&.index(find_text.to_s.downcase)
292
+ text_to_find_in = the_line[start_position..-1]
293
+ occurrence_index = case_sensitive ? text_to_find_in&.index(find_text.to_s) : text_to_find_in&.downcase&.index(find_text.to_s.downcase)
280
294
  if occurrence_index
281
295
  self.caret_position = caret_position_for_line_index(the_index) + start_position + occurrence_index
282
296
  self.selection_count = find_text.to_s.size
@@ -340,10 +354,12 @@ module Glimmer
340
354
  end
341
355
 
342
356
  def home
357
+ self.selection_count = 0
343
358
  self.line_number = 1
344
359
  end
345
360
 
346
361
  def end
362
+ self.selection_count = 0
347
363
  self.line_number = lines.size
348
364
  end
349
365
 
@@ -1,18 +1,12 @@
1
- begin
2
- require 'puts_debuggerer' if ENV['puts_debuggerer'].to_s.downcase == 'true'
3
- rescue LoadError
4
- # no op
5
- end
6
1
  require 'fileutils'
7
2
  require 'os'
8
3
 
9
4
  require 'models/glimmer/gladiator/dir'
10
5
  require 'models/glimmer/gladiator/file'
6
+ require 'models/glimmer/gladiator/command'
11
7
 
12
8
  require 'views/glimmer/gladiator/text_editor'
13
9
 
14
- java_import 'org.eclipse.swt.custom.TreeEditor'
15
-
16
10
  Clipboard.implementation = Clipboard::Java
17
11
  Clipboard.copy(Clipboard.paste) # pre-initialize library to avoid slowdown during use
18
12
 
@@ -23,89 +17,118 @@ module Glimmer
23
17
 
24
18
  COMMAND_KEY = OS.mac? ? :command : :ctrl
25
19
 
20
+ class << self
21
+ attr_accessor :drag_and_drop
22
+ attr_accessor :drag
23
+ end
24
+
26
25
  ## Add options like the following to configure CustomShell by outside consumers
27
26
  #
28
27
  # options :title, :background_color
29
28
  # option :width, 320
30
29
  # option :height, 240
31
-
30
+
32
31
  ## Uncomment before_body block to pre-initialize variables to use in body
33
32
  #
34
33
  #
35
34
  before_body {
36
35
  Display.setAppName('Gladiator')
37
36
  @display = display {
38
- on_event_keydown { |key_event|
37
+ on_swt_keydown { |key_event|
39
38
  if key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'f'
40
- if @text_editor.text_widget.getSelectionText && @text_editor.text_widget.getSelectionText.size > 0
39
+ if @text_editor&.text_widget&.getSelectionText && @text_editor&.text_widget&.getSelectionText&.size.to_i > 0
41
40
  @find_text.swt_widget.setText @text_editor.text_widget.getSelectionText
42
41
  end
43
42
  @find_text.swt_widget.selectAll
44
43
  @find_text.swt_widget.setFocus
45
44
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == 'c'
46
- Clipboard.copy(Gladiator::Dir.local_dir.selected_child.path)
45
+ Clipboard.copy(Dir.local_dir.selected_child.path)
47
46
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == 'g'
48
- Gladiator::Dir.local_dir.selected_child.find_previous
47
+ Dir.local_dir.selected_child.find_previous
49
48
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == 'w'
50
49
  @tab_folder.swt_widget.getItems.each do |tab_item|
51
50
  Dir.local_dir.selected_child_path_history.delete(tab_item.getData('file_path'))
52
- tab_item.getData('proxy').dispose
51
+ tab_item.getData('proxy')&.dispose
53
52
  end
53
+ close_tab_folder
54
54
  @tab_item = @text_editor = Dir.local_dir.selected_child = nil
55
55
  @filter_text.swt_widget.selectAll
56
56
  @filter_text.swt_widget.setFocus
57
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && key_event.character == 8721
57
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :alt) && extract_char(key_event) == 'w'
58
58
  other_tab_items.each do |tab_item|
59
59
  Dir.local_dir.selected_child_path_history.delete(tab_item.getData('file_path'))
60
- tab_item.getData('proxy').dispose
60
+ tab_item.getData('proxy')&.dispose
61
61
  end
62
62
  elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'w'
63
63
  if selected_tab_item
64
64
  Dir.local_dir.selected_child_path_history.delete(Dir.local_dir.selected_child.path)
65
- selected_tab_item.getData('proxy').dispose
65
+ selected_tab_item.getData('proxy')&.dispose
66
+ close_tab_folder
66
67
  if selected_tab_item.nil?
67
68
  @tab_item = @text_editor = Dir.local_dir.selected_child = nil
68
69
  @filter_text.swt_widget.selectAll
69
70
  @filter_text.swt_widget.setFocus
70
71
  else
71
- @text_editor.text_widget.setFocus
72
+ @text_editor&.text_widget&.setFocus
72
73
  end
73
74
  end
74
75
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == ']'
75
- @tab_folder.swt_widget.setSelection([@tab_folder.swt_widget.getSelectionIndex() + 1, @tab_folder.swt_widget.getItemCount - 1].min) if @tab_folder.swt_widget.getItemCount > 0
76
- @text_editor.text_widget.setFocus
76
+ @tab_folder.swt_widget.setSelection((@tab_folder.swt_widget.getSelectionIndex() + 1) % @tab_folder.swt_widget.getItemCount) if @tab_folder.swt_widget.getItemCount > 0
77
+ @text_editor&.text_widget&.setFocus
77
78
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == '['
78
- @tab_folder.swt_widget.setSelection([@tab_folder.swt_widget.getSelectionIndex() - 1, 0].max) if @tab_folder.swt_widget.getItemCount > 0
79
- @text_editor.text_widget.setFocus
79
+ @tab_folder.swt_widget.setSelection((@tab_folder.swt_widget.getSelectionIndex() - 1) % @tab_folder.swt_widget.getItemCount) if @tab_folder.swt_widget.getItemCount > 0
80
+ @text_editor&.text_widget&.setFocus
81
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :ctrl) && extract_char(key_event) == ']'
82
+ if @tab_folder2
83
+ if @tab_folder == @tab_folder1
84
+ @tab_folder = @tab_folder2
85
+ else
86
+ @tab_folder = @tab_folder1
87
+ end
88
+ @tab_item = @tab_folder.swt_widget.getData('selected_tab_item')
89
+ Dir.local_dir.selected_child = @tab_item&.swt_tab_item&.getData('file')
90
+ @tab_item&.swt_tab_item&.getData('text_editor')&.text_widget&.setFocus
91
+ end
92
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :ctrl) && extract_char(key_event) == '['
93
+ if @tab_folder2
94
+ if @tab_folder == @tab_folder2
95
+ @tab_folder = @tab_folder1
96
+ else
97
+ @tab_folder = @tab_folder2
98
+ end
99
+ @tab_item = @tab_folder.swt_widget.getData('selected_tab_item')
100
+ Dir.local_dir.selected_child = @tab_item&.swt_tab_item&.getData('file')
101
+ @tab_item&.swt_tab_item&.getData('text_editor')&.text_widget&.setFocus
102
+ end
80
103
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '1'
81
104
  @tab_folder.swt_widget.setSelection(0) if @tab_folder.swt_widget.getItemCount >= 1
82
- @text_editor.text_widget.setFocus
105
+ @text_editor&.text_widget&.setFocus
83
106
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '2'
84
107
  @tab_folder.swt_widget.setSelection(1) if @tab_folder.swt_widget.getItemCount >= 2
85
- @text_editor.text_widget.setFocus
108
+ @text_editor&.text_widget&.setFocus
86
109
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '3'
87
110
  @tab_folder.swt_widget.setSelection(2) if @tab_folder.swt_widget.getItemCount >= 3
88
- @text_editor.text_widget.setFocus
111
+ @text_editor&.text_widget&.setFocus
89
112
  @tab_folder.swt_widget.setSelection(3) if @tab_folder.swt_widget.getItemCount >= 4
90
- @text_editor.text_widget.setFocus
113
+ @text_editor&.text_widget&.setFocus
91
114
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '5'
92
115
  @tab_folder.swt_widget.setSelection(4) if @tab_folder.swt_widget.getItemCount >= 5
93
- @text_editor.text_widget.setFocus
116
+ @text_editor&.text_widget&.setFocus
94
117
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '4'
95
118
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '6'
96
119
  @tab_folder.swt_widget.setSelection(5) if @tab_folder.swt_widget.getItemCount >= 6
97
- @text_editor.text_widget.setFocus
120
+ @text_editor&.text_widget&.setFocus
98
121
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '7'
99
122
  @tab_folder.swt_widget.setSelection(6) if @tab_folder.swt_widget.getItemCount >= 7
100
- @text_editor.text_widget.setFocus
123
+ @text_editor&.text_widget&.setFocus
101
124
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '8'
102
125
  @tab_folder.swt_widget.setSelection(7) if @tab_folder.swt_widget.getItemCount >= 8
103
- @text_editor.text_widget.setFocus
126
+ @text_editor&.text_widget&.setFocus
104
127
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '9'
105
128
  @tab_folder.swt_widget.setSelection(@tab_folder.swt_widget.getItemCount - 1) if @tab_folder.swt_widget.getItemCount > 0
106
- @text_editor.text_widget.setFocus
129
+ @text_editor&.text_widget&.setFocus
107
130
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == 'g'
108
- Gladiator::Dir.local_dir.selected_child.find_next
131
+ Dir.local_dir.selected_child.find_next
109
132
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == 'l'
110
133
  @line_number_text.swt_widget.selectAll
111
134
  @line_number_text.swt_widget.setFocus
@@ -118,7 +141,7 @@ module Glimmer
118
141
  elsif key_event.keyCode == swt(:esc)
119
142
  if @text_editor
120
143
  Dir.local_dir.selected_child_path = @text_editor.file.path
121
- @text_editor.text_widget.setFocus
144
+ @text_editor&.text_widget&.setFocus
122
145
  end
123
146
  end
124
147
  }
@@ -127,51 +150,79 @@ module Glimmer
127
150
  local_dir = ENV['LOCAL_DIR'] || '.'
128
151
  @config_file_path = ::File.join(local_dir, '.gladiator')
129
152
  @config = {}
130
- Gladiator::Dir.local_dir.all_children # pre-caches children
153
+ Dir.local_dir.all_children # pre-caches children
131
154
  }
132
155
 
133
156
  ## Uncomment after_body block to setup observers for widgets in body
134
157
  #
135
158
  after_body {
136
- observe(Gladiator::Dir.local_dir, 'children') do
159
+ observe(Dir.local_dir, 'children') do
137
160
  select_tree_item unless @rename_in_progress
138
161
  end
139
- observe(Gladiator::Dir.local_dir, 'selected_child') do
140
- select_tree_item unless @rename_in_progress
141
- selected_file = Gladiator::Dir.local_dir.selected_child
142
- found_tab_item = selected_tab_item
143
- if found_tab_item
144
- @tab_folder.swt_widget.setSelection(found_tab_item)
145
- @tab_item = found_tab_item.getData('tab_item')
146
- @text_editor = found_tab_item.getData('text_editor')
147
- elsif selected_file
148
- @tab_folder.content {
149
- @tab_item = tab_item { |the_tab_item|
150
- text selected_file.name
151
- fill_layout :horizontal
152
- @text_editor = the_text_editor = text_editor(file: selected_file)
153
- on_event_show {
154
- Gladiator::Dir.local_dir.selected_child = selected_file
155
- @tab_item = the_tab_item
156
- @text_editor = the_text_editor
157
- }
162
+ observe(Dir.local_dir, 'selected_child') do |selected_file|
163
+ if selected_file
164
+ if Gladiator.drag && !@tab_folder2
165
+ @tab_folder1 = @tab_folder
166
+ @tab_folder_sash_form.content {
167
+ @tab_folder = @tab_folder2 = tab_folder
168
+ @tab_folder.swt_widget.setData('proxy', @tab_folder)
158
169
  }
159
- @tab_item.swt_tab_item.setData('file_path', selected_file.path)
160
- @tab_item.swt_tab_item.setData('tab_item', @tab_item)
161
- @tab_item.swt_tab_item.setData('text_editor', @text_editor)
162
- @tab_item.swt_tab_item.setData('proxy', @tab_item)
163
- }
164
- @tab_folder.swt_widget.setSelection(@tab_item.swt_tab_item)
165
- body_root.pack_same_size
170
+ end
171
+ select_tree_item unless @rename_in_progress
172
+ found_tab_item = selected_tab_item
173
+ if found_tab_item
174
+ @tab_folder.swt_widget.setSelection(found_tab_item)
175
+ @tab_item = found_tab_item.getData('proxy')
176
+ @text_editor = found_tab_item.getData('text_editor')
177
+ @tab_folder.swt_widget.setData('selected_tab_item', @tab_item)
178
+ elsif selected_file
179
+ @tab_folder.content {
180
+ @tab_item = tab_item { |the_tab_item|
181
+ text selected_file.name
182
+ fill_layout :horizontal
183
+ @text_editor = the_text_editor = text_editor(file: selected_file)
184
+ @tab_folder.swt_widget.setData('selected_tab_item', @tab_item)
185
+ @text_editor.text_proxy.content {
186
+ on_focus_gained {
187
+ tab_folder = the_text_editor.swt_widget.getParent.getParent
188
+ @tab_folder = tab_folder.getData('proxy')
189
+ @tab_item = the_tab_item
190
+ @text_editor = the_text_editor
191
+ @tab_folder.swt_widget.setData('selected_tab_item', @tab_item)
192
+ @tab_folder.swt_widget.setSelection(@tab_item.swt_tab_item)
193
+ Dir.local_dir.selected_child = @tab_item.swt_tab_item.getData('file')
194
+ }
195
+ }
196
+ on_swt_show {
197
+ @tab_item = the_tab_item
198
+ @text_editor = the_text_editor
199
+ @tab_folder = @tab_item.swt_widget.getParent.getData('proxy')
200
+ @tab_folder.swt_widget.setData('selected_tab_item', @tab_item)
201
+ @tab_folder.swt_widget.setSelection(@tab_item.swt_tab_item)
202
+ Dir.local_dir.selected_child = selected_file
203
+ async_exec {
204
+ @text_editor&.text_widget&.setFocus
205
+ }
206
+ }
207
+ }
208
+ @tab_item.swt_tab_item.setData('file_path', selected_file.path)
209
+ @tab_item.swt_tab_item.setData('file', selected_file)
210
+ @tab_item.swt_tab_item.setData('text_editor', @text_editor)
211
+ @tab_item.swt_tab_item.setData('proxy', @tab_item)
212
+ }
213
+ @tab_folder.swt_widget.setSelection(@tab_item.swt_tab_item)
214
+ body_root.pack_same_size
215
+ end
216
+ @text_editor&.text_widget&.setFocus
166
217
  end
167
218
  end
168
- observe(Gladiator::Dir.local_dir, 'selected_child') do
219
+ observe(Dir.local_dir, 'selected_child') do
169
220
  save_config
170
221
  end
171
- observe(Gladiator::Dir.local_dir, 'selected_child.caret_position') do
222
+ observe(Dir.local_dir, 'selected_child.caret_position') do
172
223
  save_config
173
224
  end
174
- observe(Gladiator::Dir.local_dir, 'selected_child.top_index') do
225
+ observe(Dir.local_dir, 'selected_child.top_index') do
175
226
  save_config
176
227
  end
177
228
  load_config
@@ -182,15 +233,15 @@ module Glimmer
182
233
  #
183
234
  body {
184
235
  shell {
185
- text "Gladiator - #{::File.expand_path(Gladiator::Dir.local_dir.path)}"
186
- minimum_size 720, 450
236
+ text "Gladiator - #{::File.expand_path(Dir.local_dir.path)}"
237
+ minimum_size 520, 250
187
238
  size 1440, 900
188
239
  grid_layout 2, false
189
- on_event_close {
190
- Gladiator::Dir.local_dir.selected_child&.write_dirty_content
240
+ on_swt_close {
241
+ Dir.local_dir.selected_child&.write_dirty_content
191
242
  }
192
243
  on_widget_disposed {
193
- Gladiator::Dir.local_dir.selected_child&.write_dirty_content
244
+ Dir.local_dir.selected_child&.write_dirty_content
194
245
  }
195
246
  on_control_resized {
196
247
  save_config
@@ -208,7 +259,7 @@ module Glimmer
208
259
  }
209
260
  @filter_text = text {
210
261
  layout_data :fill, :center, true, false
211
- text bind(Gladiator::Dir.local_dir, 'filter')
262
+ text bind(Dir.local_dir, 'filter')
212
263
  on_key_pressed { |key_event|
213
264
  if key_event.keyCode == swt(:tab) ||
214
265
  key_event.keyCode == swt(:cr) ||
@@ -220,35 +271,48 @@ module Glimmer
220
271
  }
221
272
  }
222
273
  composite {
274
+ fill_layout(:vertical) {
275
+ spacing 5
276
+ }
223
277
  layout_data(:fill, :fill, true, true)
224
278
  @list = list(:border, :h_scroll, :v_scroll) {
225
- layout_data(:fill, :fill, true, true) {
226
- #exclude bind(Gladiator::Dir.local_dir, :filter) {|f| !f}
227
- minimum_height 400
228
- }
229
- #visible bind(Gladiator::Dir, 'local_dir.filter') {|f| !!f}
230
- selection bind(Gladiator::Dir.local_dir, :filtered_path)
279
+ #visible bind(Dir, 'local_dir.filter') {|f| !!f}
280
+ selection bind(Dir.local_dir, :filtered_path)
231
281
  on_mouse_up {
232
- Gladiator::Dir.local_dir.selected_child_path = @list.swt_widget.getSelection.first
282
+ Dir.local_dir.selected_child_path = @list.swt_widget.getSelection.first
233
283
  }
234
284
  on_key_pressed { |key_event|
235
285
  if Glimmer::SWT::SWTProxy.include?(key_event.keyCode, :cr)
236
- Gladiator::Dir.local_dir.selected_child_path = @list.swt_widget.getSelection.first
237
- @text_editor.text_widget.setFocus
286
+ Dir.local_dir.selected_child_path = @list.swt_widget.getSelection.first
287
+ @text_editor&.text_widget&.setFocus
238
288
  end
239
289
  }
290
+ drag_source(DND::DROP_COPY) {
291
+ transfer [TextTransfer.getInstance].to_java(Transfer)
292
+ on_drag_set_data { |event|
293
+ Gladiator.drag = true
294
+ list = event.widget.getControl
295
+ event.data = list.getSelection.first
296
+ }
297
+ }
240
298
  }
241
299
  @tree = tree(:virtual, :border, :h_scroll, :v_scroll) {
242
- layout_data(:fill, :fill, true, true) {
243
- #exclude bind(Gladiator::Dir.local_dir, :filter) {|f| !!f}
300
+ #visible bind(Dir, 'local_dir.filter') {|f| !f}
301
+ items bind(Dir, :local_dir), tree_properties(children: :children, text: :name)
302
+ drag_source(DND::DROP_COPY) {
303
+ transfer [TextTransfer.getInstance].to_java(Transfer)
304
+ on_drag_set_data { |event|
305
+ Gladiator.drag = true
306
+ tree = event.widget.getControl
307
+ tree_item = tree.getSelection.first
308
+ event.data = tree_item.getData.path
309
+ }
244
310
  }
245
- #visible bind(Gladiator::Dir, 'local_dir.filter') {|f| !f}
246
- items bind(Gladiator::Dir, :local_dir), tree_properties(children: :children, text: :name)
247
311
  menu {
248
312
  @open_menu_item = menu_item {
249
313
  text 'Open'
250
314
  on_widget_selected {
251
- Gladiator::Dir.local_dir.selected_child_path = extract_tree_item_path(@tree.swt_widget.getSelection.first)
315
+ Dir.local_dir.selected_child_path = extract_tree_item_path(@tree.swt_widget.getSelection.first)
252
316
  }
253
317
  }
254
318
  menu_item(:separator)
@@ -262,7 +326,7 @@ module Glimmer
262
326
  menu_item {
263
327
  text 'Refresh'
264
328
  on_widget_selected {
265
- Gladiator::Dir.local_dir.refresh
329
+ Dir.local_dir.refresh
266
330
  }
267
331
  }
268
332
  menu_item {
@@ -284,17 +348,21 @@ module Glimmer
284
348
  }
285
349
  }
286
350
  }
287
- on_event_menudetect { |event|
351
+ on_swt_menudetect { |event|
288
352
  path = extract_tree_item_path(@tree.swt_widget.getSelection.first)
289
353
  @open_menu_item.swt_widget.setEnabled(!::Dir.exist?(path)) if path
290
354
  }
291
355
  on_mouse_up {
292
- Gladiator::Dir.local_dir.selected_child_path = extract_tree_item_path(@tree.swt_widget.getSelection&.first)
293
- @text_editor&.text_widget&.setFocus
356
+ if Gladiator.drag_and_drop
357
+ Gladiator.drag_and_drop = false
358
+ else
359
+ Dir.local_dir.selected_child_path = extract_tree_item_path(@tree.swt_widget.getSelection&.first)
360
+ @text_editor&.text_widget&.setFocus
361
+ end
294
362
  }
295
363
  on_key_pressed { |key_event|
296
364
  if Glimmer::SWT::SWTProxy.include?(key_event.keyCode, :cr)
297
- Gladiator::Dir.local_dir.selected_child_path = extract_tree_item_path(@tree.swt_widget.getSelection&.first)
365
+ Dir.local_dir.selected_child_path = extract_tree_item_path(@tree.swt_widget.getSelection&.first)
298
366
  @text_editor&.text_widget&.setFocus
299
367
  end
300
368
  }
@@ -317,15 +385,18 @@ module Glimmer
317
385
  grid_layout 1, false
318
386
  layout_data :fill, :fill, true, true
319
387
  composite {
320
- grid_layout 2, false
388
+ grid_layout 3, false
389
+
390
+ # row 1
391
+
321
392
  @file_path_label = styled_text(:none) {
322
393
  layout_data(:fill, :fill, true, false) {
323
- horizontal_span 2
394
+ horizontal_span 3
324
395
  }
325
396
  background color(:widget_background)
326
397
  editable false
327
398
  caret nil
328
- text bind(Gladiator::Dir.local_dir, 'selected_child.path')
399
+ text bind(Dir.local_dir, 'selected_child.path')
329
400
  on_mouse_up {
330
401
  @file_path_label.swt_widget.selectAll
331
402
  }
@@ -333,6 +404,9 @@ module Glimmer
333
404
  @file_path_label.swt_widget.setSelection(0, 0)
334
405
  }
335
406
  }
407
+
408
+ # row 2
409
+
336
410
  label {
337
411
  text 'Line:'
338
412
  }
@@ -340,16 +414,20 @@ module Glimmer
340
414
  layout_data(:fill, :fill, true, false) {
341
415
  minimum_width 400
342
416
  }
343
- text bind(Gladiator::Dir.local_dir, 'selected_child.line_number', on_read: :to_s, on_write: :to_i)
417
+ text bind(Dir.local_dir, 'selected_child.line_number', on_read: :to_s, on_write: :to_i)
344
418
  on_key_pressed { |key_event|
345
419
  if key_event.keyCode == swt(:cr)
346
- @text_editor.text_widget.setFocus
420
+ @text_editor&.text_widget&.setFocus
347
421
  end
348
422
  }
349
423
  on_verify_text { |event|
350
424
  event.doit = !event.text.match(/^\d*$/).to_a.empty?
351
425
  }
352
426
  }
427
+ label
428
+
429
+ # row 3
430
+
353
431
  label {
354
432
  text 'Find:'
355
433
  }
@@ -357,13 +435,34 @@ module Glimmer
357
435
  layout_data(:fill, :fill, true, false) {
358
436
  minimum_width 400
359
437
  }
360
- text bind(Gladiator::Dir.local_dir, 'selected_child.find_text')
438
+ text bind(Dir.local_dir, 'selected_child.find_text')
361
439
  on_key_pressed { |key_event|
440
+ if key_event.stateMask == swt(COMMAND_KEY) && key_event.keyCode == swt(:cr)
441
+ Dir.local_dir.selected_child.case_sensitive = !Dir.local_dir.selected_child.case_sensitive
442
+ Dir.local_dir.selected_child&.find_next
443
+ end
362
444
  if key_event.keyCode == swt(:cr)
363
- Gladiator::Dir.local_dir.selected_child.find_next
445
+ Dir.local_dir.selected_child&.find_next
364
446
  end
365
447
  }
366
448
  }
449
+ composite {
450
+ row_layout
451
+ button(:check) {
452
+ selection bind(Dir.local_dir, 'selected_child.case_sensitive')
453
+ on_key_pressed { |key_event|
454
+ if key_event.keyCode == swt(:cr)
455
+ Dir.local_dir.selected_child&.find_next
456
+ end
457
+ }
458
+ }
459
+ label {
460
+ text 'Case-sensitive'
461
+ }
462
+ }
463
+
464
+ # row 4
465
+
367
466
  label {
368
467
  text 'Replace:'
369
468
  }
@@ -371,36 +470,59 @@ module Glimmer
371
470
  layout_data(:fill, :fill, true, false) {
372
471
  minimum_width 300
373
472
  }
374
- text bind(Gladiator::Dir.local_dir, 'selected_child.replace_text')
473
+ text bind(Dir.local_dir, 'selected_child.replace_text')
375
474
  on_focus_gained {
376
- Gladiator::Dir.local_dir.selected_child.ensure_find_next
475
+ Dir.local_dir.selected_child&.ensure_find_next
377
476
  }
378
477
  on_key_pressed { |key_event|
379
478
  if key_event.keyCode == swt(:cr)
380
- Gladiator::Dir.local_dir.selected_child.replace_next!
479
+ if Dir.local_dir.selected_child
480
+ Command.do(Dir.local_dir.selected_child, :replace_next!)
481
+ end
381
482
  end
382
483
  }
383
484
  }
485
+ label
384
486
  }
385
- @tab_folder = tab_folder {
386
- layout_data(:fill, :fill, true, true)
487
+ @tab_folder_sash_form = sash_form {
488
+ layout_data(:fill, :fill, true, true) {
489
+ width_hint 640
490
+ height_hint 480
491
+ }
492
+ sash_width 10
493
+ @tab_folder = tab_folder {
494
+ drag_source(DND::DROP_COPY) {
495
+ transfer [TextTransfer.getInstance].to_java(Transfer)
496
+ event_data = nil
497
+ on_drag_start {|event|
498
+ Gladiator.drag = true
499
+ tab_folder = event.widget.getControl
500
+ tab_item = tab_folder.getItem(Point.new(event.x, event.y))
501
+ event_data = tab_item.getData('file_path')
502
+ }
503
+ on_drag_set_data { |event|
504
+ event.data = event_data
505
+ }
506
+ }
507
+ }
508
+ @tab_folder.swt_widget.setData('proxy', @tab_folder)
387
509
  }
388
510
  }
389
511
  }
390
512
  }
391
-
513
+
392
514
  def load_config
393
515
  if ::File.exists?(@config_file_path)
394
516
  config_yaml = ::File.read(@config_file_path)
395
517
  return if config_yaml.to_s.strip.empty?
396
518
  @config = YAML.load(config_yaml)
397
519
  @config[:open_file_paths].to_a.each do |file_path|
398
- Gladiator::Dir.local_dir.selected_child_path = file_path
520
+ Dir.local_dir.selected_child_path = file_path
399
521
  end
400
- Gladiator::Dir.local_dir.selected_child_path = @config[:selected_child_path] if @config[:selected_child_path]
401
- 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].to_i) if @config[:caret_position]
402
- Gladiator::Dir.local_dir.selected_child&.top_index = @config[:top_index].to_i if @config[:top_index]
403
- body_root.on_event_show {
522
+ Dir.local_dir.selected_child_path = @config[:selected_child_path] if @config[:selected_child_path]
523
+ Dir.local_dir.selected_child&.caret_position = Dir.local_dir.selected_child&.caret_position_for_caret_position_start_of_line(@config[:caret_position].to_i) if @config[:caret_position]
524
+ Dir.local_dir.selected_child&.top_index = @config[:top_index].to_i if @config[:top_index]
525
+ body_root.on_swt_show {
404
526
  swt_widget.setSize(@config[:shell_width], @config[:shell_height]) if @config[:shell_width] && @config[:shell_height]
405
527
  swt_widget.setLocation(@config[:shell_x], @config[:shell_y]) if @config[:shell_x] && @config[:shell_y]
406
528
  @loaded_config = true
@@ -412,7 +534,7 @@ module Glimmer
412
534
 
413
535
  def save_config
414
536
  return unless @loaded_config
415
- child = Gladiator::Dir.local_dir.selected_child
537
+ child = Dir.local_dir.selected_child
416
538
  return if child.nil?
417
539
  @config = {
418
540
  selected_child_path: child.path,
@@ -430,12 +552,31 @@ module Glimmer
430
552
  puts e.full_message
431
553
  end
432
554
 
555
+ def close_tab_folder
556
+ if @tab_folder2 && !selected_tab_item
557
+ if @tab_folder == @tab_folder2
558
+ @tab_folder2.swt_widget.dispose
559
+ @tab_folder = @tab_folder1
560
+ else
561
+ @tab_folder1.swt_widget.dispose
562
+ @tab_folder = @tab_folder1 = @tab_folder2
563
+ end
564
+ @tab_folder2 = nil
565
+
566
+ @tab_item = @tab_folder.swt_widget.getData('selected_tab_item')
567
+ @text_editor = @tab_item.swt_tab_item.getData('text_editor')
568
+ Dir.local_dir.selected_child = @tab_item.swt_tab_item.getData('file')
569
+
570
+ body_root.pack_same_size
571
+ end
572
+ end
573
+
433
574
  def selected_tab_item
434
- @tab_folder.swt_widget.getItems.detect { |ti| ti.getData('file_path') == Gladiator::Dir.local_dir.selected_child&.path }
575
+ @tab_folder.swt_widget.getItems.detect { |ti| ti.getData('file_path') == Dir.local_dir.selected_child&.path }
435
576
  end
436
577
 
437
578
  def other_tab_items
438
- @tab_folder.swt_widget.getItems.reject { |ti| ti.getData('file_path') == Gladiator::Dir.local_dir.selected_child&.path }
579
+ @tab_folder.swt_widget.getItems.reject { |ti| ti.getData('file_path') == Dir.local_dir.selected_child&.path }
439
580
  end
440
581
 
441
582
  def extract_tree_item_path(tree_item)
@@ -448,15 +589,16 @@ module Glimmer
448
589
  end
449
590
 
450
591
  def select_tree_item
451
- return unless Gladiator::Dir.local_dir.selected_child&.name
452
- tree_items_to_select = @tree.depth_first_search { |ti| ti.getData.path == Gladiator::Dir.local_dir.selected_child.path }
592
+ return unless Dir.local_dir.selected_child&.name
593
+ tree_items_to_select = @tree.depth_first_search { |ti| ti.getData.path == Dir.local_dir.selected_child.path }
453
594
  @tree.swt_widget.setSelection(tree_items_to_select)
454
595
  end
455
596
 
456
597
  def delete_tree_item(tree_item)
598
+ return if tree_item.nil?
457
599
  file = tree_item.getData
458
600
  parent_path = ::File.dirname(file.path)
459
- file.delete!
601
+ file.delete! # TODO consider supporting command undo/redo
460
602
  Dir.local_dir.refresh(async: false)
461
603
  parent_tree_item = @tree.depth_first_search {|ti| ti.getData.path == parent_path}.first
462
604
  @tree.swt_widget.showItem(parent_tree_item)
@@ -465,6 +607,8 @@ module Glimmer
465
607
  # if file.is_a?(::File)
466
608
  # close tab
467
609
  # end
610
+ rescue => e
611
+ puts e.full_message
468
612
  end
469
613
 
470
614
  def rename_selected_tree_item
@@ -477,6 +621,7 @@ module Glimmer
477
621
  Dir.local_dir.pause_refresh
478
622
  tree_item = @tree.swt_widget.getSelection.first
479
623
  directory_path = extract_tree_item_path(tree_item)
624
+ return if directory_path.nil?
480
625
  if !::Dir.exist?(directory_path)
481
626
  tree_item = tree_item.getParentItem
482
627
  directory_path = ::File.dirname(directory_path)
@@ -5,10 +5,11 @@ module Glimmer
5
5
 
6
6
  options :file
7
7
 
8
- attr_reader :text_widget
8
+ attr_reader :text_proxy, :text_widget
9
9
 
10
10
  after_body {
11
11
  @text_widget = @text.swt_widget
12
+ @text_proxy = @text
12
13
  }
13
14
 
14
15
  body {
@@ -36,35 +37,52 @@ module Glimmer
36
37
  layout_data :fill, :fill, true, true
37
38
  font name: 'Consolas', height: OS.mac? ? 15 : 12
38
39
  foreground rgb(75, 75, 75)
39
- text bind(file, 'dirty_content')
40
+ text bind(file, :content)
40
41
  focus true
41
42
  selection bind(file, 'selection')
42
43
  selection_count bind(file, 'selection_count')
43
44
  top_index bind(file, 'top_index')
45
+ drop_target(DND::DROP_COPY) {
46
+ transfer [TextTransfer.getInstance].to_java(Transfer)
47
+ on_drag_enter { |event|
48
+ event.detail = DND::DROP_COPY
49
+ }
50
+ on_drop { |event|
51
+ Gladiator.drag_and_drop = true
52
+ Dir.local_dir.selected_child = nil
53
+ Dir.local_dir.selected_child_path = event.data
54
+ Gladiator.drag = false
55
+ }
56
+ }
57
+
44
58
  on_focus_lost {
45
59
  file&.write_dirty_content
46
60
  }
47
61
  on_key_pressed { |key_event|
48
- if key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == '/'
49
- file.comment_line!
50
- key_event.doit = false
62
+ if (Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == 'z') || (key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'y')
63
+ key_event.doit = !Command.redo(file)
64
+ elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'z'
65
+ key_event.doit = !Command.undo(file)
66
+ elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == '/'
67
+ Command.do(file, :comment_line!)
68
+ key_event.doit = false
51
69
  elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'k'
52
- file.kill_line!
70
+ Command.do(file, :kill_line!)
53
71
  key_event.doit = false
54
72
  elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'd'
55
- file.duplicate_line!
73
+ Command.do(file, :duplicate_line!)
56
74
  key_event.doit = false
57
75
  elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == '['
58
- file.outdent!
76
+ Command.do(file, :outdent!)
59
77
  key_event.doit = false
60
78
  elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == ']'
61
- file.indent!
79
+ Command.do(file, :indent!)
62
80
  key_event.doit = false
63
81
  elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && key_event.keyCode == swt(:cr)
64
- file.prefix_new_line!
82
+ Command.do(file, :prefix_new_line!)
65
83
  key_event.doit = false
66
84
  elsif key_event.stateMask == swt(COMMAND_KEY) && key_event.keyCode == swt(:cr)
67
- file.insert_new_line!
85
+ Command.do(file, :insert_new_line!)
68
86
  key_event.doit = false
69
87
  elsif key_event.keyCode == swt(:page_up)
70
88
  file.page_up
@@ -79,10 +97,10 @@ module Glimmer
79
97
  file.end
80
98
  key_event.doit = false
81
99
  elsif key_event.stateMask == swt(COMMAND_KEY) && key_event.keyCode == swt(:arrow_up)
82
- file.move_up!
100
+ Command.do(file, :move_up!)
83
101
  key_event.doit = false
84
102
  elsif key_event.stateMask == swt(COMMAND_KEY) && key_event.keyCode == swt(:arrow_down)
85
- file.move_down!
103
+ Command.do(file, :move_down!)
86
104
  key_event.doit = false
87
105
  end
88
106
  }
@@ -95,7 +113,7 @@ module Glimmer
95
113
  end
96
114
  when swt(:tab)
97
115
  if file.selection_count.to_i > 0
98
- file.indent!
116
+ Command.do(file, :indent!)
99
117
  verify_event.doit = false
100
118
  else
101
119
  verify_event.text = ' '
metadata CHANGED
@@ -1,32 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-cs-gladiator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.7
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andy Maleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-02 00:00:00.000000000 Z
11
+ date: 2020-07-23 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - ">="
17
17
  - !ruby/object:Gem::Version
18
- version: 0.7.0
18
+ version: 0.4.1
19
19
  - - "<"
20
20
  - !ruby/object:Gem::Version
21
21
  version: 2.0.0
22
- name: glimmer
22
+ name: glimmer-dsl-swt
23
23
  type: :runtime
24
24
  prerelease: false
25
25
  version_requirements: !ruby/object:Gem::Requirement
26
26
  requirements:
27
27
  - - ">="
28
28
  - !ruby/object:Gem::Version
29
- version: 0.7.0
29
+ version: 0.4.1
30
30
  - - "<"
31
31
  - !ruby/object:Gem::Version
32
32
  version: 2.0.0
@@ -100,20 +100,6 @@ dependencies:
100
100
  - - ">="
101
101
  - !ruby/object:Gem::Version
102
102
  version: '0'
103
- - !ruby/object:Gem::Dependency
104
- requirement: !ruby/object:Gem::Requirement
105
- requirements:
106
- - - "~>"
107
- - !ruby/object:Gem::Version
108
- version: 0.8.1
109
- name: puts_debuggerer
110
- type: :development
111
- prerelease: false
112
- version_requirements: !ruby/object:Gem::Requirement
113
- requirements:
114
- - - "~>"
115
- - !ruby/object:Gem::Version
116
- version: 0.8.1
117
103
  description: Gladiator (short for Glimmer Editor) is a Glimmer sample project under
118
104
  on-going development. It is not intended to be a full-fledged editor by any means,
119
105
  yet mostly a fun educational exercise in using Glimmer to build a text editor. Gladiator
@@ -130,9 +116,11 @@ extra_rdoc_files:
130
116
  files:
131
117
  - LICENSE.txt
132
118
  - README.md
119
+ - VERSION
133
120
  - bin/gladiator
134
121
  - bin/gladiator_runner.rb
135
122
  - lib/glimmer-cs-gladiator.rb
123
+ - lib/models/glimmer/gladiator/command.rb
136
124
  - lib/models/glimmer/gladiator/dir.rb
137
125
  - lib/models/glimmer/gladiator/file.rb
138
126
  - lib/views/glimmer/gladiator.rb