glimmer-cs-gladiator 0.1.7 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
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