glimmer-cs-gladiator 0.1.6 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 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