glimmer-cs-gladiator 0.1.6 → 0.2.2

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: 8d758e5b444ef3d48c0214ffb763e3dab3f9ca9748961e879b9ebdb626e9c2ea
4
- data.tar.gz: cb575fbe30017319190278483334256aeb04d277798a5e3351f944c3d3a61481
3
+ metadata.gz: 1de235cba50741874f8719322e8c35ffea667929d465e23f3fd2df8a4866acb4
4
+ data.tar.gz: 20273095f8e93bff72840e3094ff5f203bc57bf78e0c7ee8b14e0765f7025ca5
5
5
  SHA512:
6
- metadata.gz: 4223591b0608f621432a7ee1a1f710ad4a1684aaafb6d1d9152f064b8d707216ba3dc5fece5836764db058a9a88d209d161ee8abc5062d4fb9a4a821cb986c61
7
- data.tar.gz: 3296674924ae085c139919e9e22a32d1c5a322b163b7fc6954e89bc02af4cb2a7c80e9a49359d9d136f4113206c48ebfcedbbe917e3f97e35529575abed1832a
6
+ metadata.gz: 5aba5bf9ad1ba8f077486dbc0d04da40c2138bf02c32d0565e27a520935da088d811e51bd9c90f868ce24c0775add77914e3dbebdfa4abb89f9333719f79cdcb
7
+ data.tar.gz: cbb76756dae0901141a3c3b2d69849d1aed409e26d1f7a8ff1fa30a410c3e11edfecd93c4ff03e35023aa2ee64a7dccad276878bb563f94c1298c144e93dfc4d
data/README.md CHANGED
@@ -1,15 +1,18 @@
1
- # Gladiator (Glimmer Editor) 0.1.6 - 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.2 - [Ugliest Text Editor Ever](https://www.reddit.com/r/ruby/comments/hgve8k/gladiator_glimmer_editor_ugliest_text_editor_ever/)
2
+ ## [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.6'
96
+ gem 'glimmer-cs-gladiator', '~> 0.2.2'
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,11 @@ 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
155
+ Copyright (c) 2020 Andy Maleh. See [LICENSE.txt](LICENSE.txt) for
122
156
  further details.
157
+
158
+ --
159
+
160
+ Built with [Glimmer](https://github.com/AndyObtiva/glimmer) (Ruby Desktop Development GUI Library).
161
+
162
+ 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.2
@@ -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
@@ -66,7 +66,7 @@ module Glimmer
66
66
  def refresh(async: true, force: false)
67
67
  return if @refresh_paused && !force
68
68
  new_all_children = retrieve_all_children
69
- new_children = retrieve_children
69
+ new_children = retrieve_children
70
70
  refresh_operation = lambda do
71
71
  self.all_children = new_all_children
72
72
  self.children = new_children
@@ -5,11 +5,12 @@ 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)
@@ -40,6 +41,16 @@ module Glimmer
40
41
  # no op in case of a binary file
41
42
  end
42
43
  end
44
+
45
+ # to use for widget data-binding
46
+ def content=(value)
47
+ Command.do(self) # record a native (OS-widget) operation
48
+ self.dirty_content = value
49
+ end
50
+
51
+ def content
52
+ dirty_content
53
+ end
43
54
 
44
55
  def caret_position=(value)
45
56
  self.selection = Point.new(value, value + selection_count.to_i)
@@ -64,6 +75,7 @@ module Glimmer
64
75
 
65
76
  def dirty_content=(the_content)
66
77
  @dirty_content = the_content if ::File.exist?(path)
78
+ notify_observers(:content)
67
79
  end
68
80
 
69
81
  def start_filewatcher
@@ -149,6 +161,7 @@ module Glimmer
149
161
  line_indices_for_selection(caret_position, selection_count).reverse.each do | the_line_index |
150
162
  delta = 0
151
163
  the_line = old_lines[the_line_index]
164
+ return if the_line.nil?
152
165
  if the_line.strip.start_with?('# ')
153
166
  new_lines[the_line_index] = the_line.sub(/# /, '')
154
167
  delta -= 2
@@ -210,7 +223,7 @@ module Glimmer
210
223
  if the_line.to_s.start_with?(' ')
211
224
  new_lines[the_line_index] = the_line.sub(/ /, '')
212
225
  delta = -2
213
- elsif the_line.start_with?(' ')
226
+ elsif the_line&.start_with?(' ')
214
227
  new_lines[the_line_index] = the_line.sub(/ /, '')
215
228
  delta = -1
216
229
  end
@@ -264,7 +277,7 @@ module Glimmer
264
277
  end
265
278
 
266
279
  def find_next
267
- return if find_text.to_s.empty?
280
+ return if find_text.to_s.empty?
268
281
  all_lines = lines
269
282
  the_line_index = line_index_for_caret_position(caret_position)
270
283
  line_position = line_position_for_caret_position(caret_position)
@@ -275,8 +288,8 @@ module Glimmer
275
288
  the_index = (the_index + rotation)%all_lines.size
276
289
  start_position = 0
277
290
  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)
291
+ text_to_find_in = the_line[start_position..-1]
292
+ 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
293
  if occurrence_index
281
294
  self.caret_position = caret_position_for_line_index(the_index) + start_position + occurrence_index
282
295
  self.selection_count = find_text.to_s.size
@@ -340,10 +353,12 @@ module Glimmer
340
353
  end
341
354
 
342
355
  def home
356
+ self.selection_count = 0
343
357
  self.line_number = 1
344
358
  end
345
359
 
346
360
  def end
361
+ self.selection_count = 0
347
362
  self.line_number = lines.size
348
363
  end
349
364
 
@@ -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,29 +1,35 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer-cs-gladiator
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.6
4
+ version: 0.2.2
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-05-26 00:00:00.000000000 Z
11
+ date: 2020-07-21 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
+ - !ruby/object:Gem::Version
18
+ version: 0.4.1
19
+ - - "<"
17
20
  - !ruby/object:Gem::Version
18
- version: 0.7.6
19
- name: glimmer
21
+ version: 2.0.0
22
+ name: glimmer-dsl-swt
20
23
  type: :runtime
21
24
  prerelease: false
22
25
  version_requirements: !ruby/object:Gem::Requirement
23
26
  requirements:
24
- - - "~>"
27
+ - - ">="
25
28
  - !ruby/object:Gem::Version
26
- version: 0.7.6
29
+ version: 0.4.1
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: 2.0.0
27
33
  - !ruby/object:Gem::Dependency
28
34
  requirement: !ruby/object:Gem::Requirement
29
35
  requirements:
@@ -94,20 +100,6 @@ dependencies:
94
100
  - - ">="
95
101
  - !ruby/object:Gem::Version
96
102
  version: '0'
97
- - !ruby/object:Gem::Dependency
98
- requirement: !ruby/object:Gem::Requirement
99
- requirements:
100
- - - "~>"
101
- - !ruby/object:Gem::Version
102
- version: 0.8.1
103
- name: puts_debuggerer
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - "~>"
109
- - !ruby/object:Gem::Version
110
- version: 0.8.1
111
103
  description: Gladiator (short for Glimmer Editor) is a Glimmer sample project under
112
104
  on-going development. It is not intended to be a full-fledged editor by any means,
113
105
  yet mostly a fun educational exercise in using Glimmer to build a text editor. Gladiator
@@ -124,9 +116,11 @@ extra_rdoc_files:
124
116
  files:
125
117
  - LICENSE.txt
126
118
  - README.md
119
+ - VERSION
127
120
  - bin/gladiator
128
121
  - bin/gladiator_runner.rb
129
122
  - lib/glimmer-cs-gladiator.rb
123
+ - lib/models/glimmer/gladiator/command.rb
130
124
  - lib/models/glimmer/gladiator/dir.rb
131
125
  - lib/models/glimmer/gladiator/file.rb
132
126
  - lib/views/glimmer/gladiator.rb