glimmer-cs-gladiator 0.1.5 → 0.2.1

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: 62cc5d4c7f27c15b95f6eaad4637a379a8729455532b8d924ce29a21be2c91c9
4
- data.tar.gz: 43f501030aeca54b6a0339182ee0c064e81b0415a9cd440464950f89b6d83c6f
3
+ metadata.gz: 46513e411ce6bac81dafe471f6f8bc7834df2c82c0309f0f1db03c98abf709d7
4
+ data.tar.gz: 54321b16f31848472e812d12b43a461bb4e45fb45dd3c400dc943c68ff0669ac
5
5
  SHA512:
6
- metadata.gz: 87353d484e3ab966ef765520ef4463831d37393fc66b5aa88f8dce389b001ef245f83af59e220d54f5fb18cd882f11e919cafda32db94ffc927cbbc086c33d35
7
- data.tar.gz: 190d7ad3c6305a07763fc34187e12fc5c2bc6a1606f0a6ec8bef546eda63af1f6c38933c792e2f23fee9512948ddfef344ee352504d1d283ae2b1b8ba09be1c7
6
+ metadata.gz: a807b9c57b441c9f9aa06c5a4662ae436c5ae2409e8343c3fba5b220bf933b29965fc4b205c5fc5479d42d4fdb5796505cf9f33d56da0419193d684e2def2f60
7
+ data.tar.gz: 4b37d08afb361322aabcf54a046dd9bb2e5db7d1b557409fc28d124918a8687e1079bd9927dd83fb149f4428ef3c5b9daf7903c17e5c896d07f150d3191b5333
data/README.md CHANGED
@@ -1,51 +1,91 @@
1
- # Gladiator (Glimmer Editor) 0.1.5 - Glimmer Custom Shell
1
+ # <img src='https://raw.githubusercontent.com/AndyObtiva/glimmer-cs-gladiator/master/images/glimmer-cs-gladiator-logo.svg' height=85 /> Gladiator (Glimmer Editor) 0.2.1
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
13
- - File lookup by name ignoring slashes, underscores, and dots to ease lookup
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)
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
16
- - Find & Replace
19
+ - Find & Replace (CMD+F)
17
20
  - Show Line Numbers
18
- - Jump to Line
19
- - Multiple tab support
21
+ - Jump to Line (CMD+L)
22
+ - Multiple tab support (CMD+SHIFT+[ & CMD+SHIFT+] for tab navigation. CMD+1-9 to jump to a specific tab)
20
23
  - Remember opened tabs, caret position, top line, window size, and window location
21
- - Autosave on focus out/quit/open new file
22
- - Duplicate Line(s)/selection
23
- - Kill Line(s)/selection
24
- - Move line/selection up
25
- - Move line/selection down
26
- - Comment/Uncomment line/selection
27
- - Indent/Unindent line/selection
24
+ - Autosave on focus out/quit/open new file
25
+ - Duplicate Line(s)/selection (CMD+D)
26
+ - Kill Line(s)/selection (CMD+K)
27
+ - Move line/selection up (CMD+UP)
28
+ - Move line/selection down (CMD+DOWN)
29
+ - Comment/Uncomment line/selection (CMD+/)
30
+ - Indent/Unindent line/selection (CMD+] & CMD+[)
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)
33
+
34
+ ## Platforms
35
+
36
+ - Mac: Gladiator works best on the Mac.
37
+ - Windows: Gladiator works well on Windows.
38
+ - Linux: Gladiator works with handicaps on Linux (performing text editing operations causes scroll jitter)
28
39
 
29
40
  ## Pre-requisites
30
41
 
31
- - JRuby 9.2.11.1 (supporting Ruby 2.5.x syntax) (find at https://www.jruby.org/download)
32
- - 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)
33
45
 
34
46
  ## Setup Instructions
35
47
 
36
- 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/)):
37
49
 
38
50
  ```
39
51
  jgem install glimmer-cs-gladiator
40
52
  ```
41
53
 
42
- 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:
43
71
 
44
72
  ```
45
73
  gladiator
46
74
  ```
47
75
 
48
- 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
+ ```
49
89
 
50
90
  ### Glimmer Custom Shell Reuse
51
91
 
@@ -53,7 +93,7 @@ To reuse Gladiator as a Glimmer Custom Shell inside another Glimmer application,
53
93
  following to the application's `Gemfile`:
54
94
 
55
95
  ```
56
- gem 'glimmer-cs-gladiator', '0.1.5'
96
+ gem 'glimmer-cs-gladiator', '~> 0.2.1'
57
97
  ```
58
98
 
59
99
  Run:
@@ -62,7 +102,7 @@ Run:
62
102
  jruby -S bundle
63
103
  ```
64
104
 
65
- 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.
66
106
 
67
107
  ## Env Var Options
68
108
 
@@ -85,6 +125,7 @@ It currently remembers:
85
125
  - Last opened file
86
126
  - Caret position
87
127
  - Top line position
128
+ - Opened tabs
88
129
 
89
130
  ## Gotcha
90
131
 
@@ -113,3 +154,5 @@ The signal TERM is in use by the JVM and will not work correctly on this platfor
113
154
 
114
155
  Copyright (c) 2020 Andy Maleh. See LICENSE.txt for
115
156
  further details.
157
+
158
+ 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.1
@@ -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
@@ -117,7 +117,7 @@ module Glimmer
117
117
  begin
118
118
  unless new_child.dirty_content.nil?
119
119
  self.selected_child&.stop_filewatcher
120
- selected_child_path_history << self.selected_child.path if self.selected_child
120
+ selected_child_path_history << new_child.path if new_child && !selected_child_path_history.include?(new_child.path)
121
121
  self.selected_child = new_child
122
122
  self.selected_child.start_filewatcher
123
123
  end
@@ -140,6 +140,14 @@ module Glimmer
140
140
  def to_s
141
141
  path
142
142
  end
143
+
144
+ def eql?(other)
145
+ self.path.eql?(other&.path)
146
+ end
147
+
148
+ def hash
149
+ self.path.hash
150
+ end
143
151
  end
144
152
  end
145
153
  end
@@ -5,16 +5,18 @@ module Glimmer
5
5
  class File
6
6
  include Glimmer
7
7
 
8
- attr_accessor :line_numbers_content, :caret_position, :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)
16
- @caret_position = 0
17
- @line_number = 1
17
+ @top_index = 0
18
+ @selection_count = 0
19
+ @selection = Point.new(0, 0 + @selection_count)
18
20
  read_dirty_content = ::File.read(path)
19
21
  begin
20
22
  # test read dirty content
@@ -23,8 +25,9 @@ module Glimmer
23
25
  lines_text_size = lines.size.to_s.size
24
26
  self.line_numbers_content = lines.size.times.map {|n| (' ' * (lines_text_size - (n+1).to_s.size)) + (n+1).to_s }.join("\n")
25
27
  end
28
+ @line_number = 1
26
29
  self.dirty_content = read_dirty_content
27
- observe(self, :caret_position) do
30
+ observe(self, :selection) do
28
31
  self.line_number = line_index_for_caret_position(caret_position) + 1
29
32
  end
30
33
  observe(self, :line_number) do
@@ -38,7 +41,30 @@ module Glimmer
38
41
  # no op in case of a binary file
39
42
  end
40
43
  end
41
-
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
54
+
55
+ def caret_position=(value)
56
+ self.selection = Point.new(value, value + selection_count.to_i)
57
+ if OS.linux?
58
+ async_exec do
59
+ self.top_index = line_index_for_caret_position(value)
60
+ end
61
+ end
62
+ end
63
+
64
+ def caret_position
65
+ selection.x
66
+ end
67
+
42
68
  def name=(the_name)
43
69
  self.display_path = display_path.sub(/#{Regexp.escape(@name)}$/, the_name)
44
70
  @name = the_name
@@ -49,6 +75,7 @@ module Glimmer
49
75
 
50
76
  def dirty_content=(the_content)
51
77
  @dirty_content = the_content if ::File.exist?(path)
78
+ notify_observers(:content)
52
79
  end
53
80
 
54
81
  def start_filewatcher
@@ -134,6 +161,7 @@ module Glimmer
134
161
  line_indices_for_selection(caret_position, selection_count).reverse.each do | the_line_index |
135
162
  delta = 0
136
163
  the_line = old_lines[the_line_index]
164
+ return if the_line.nil?
137
165
  if the_line.strip.start_with?('# ')
138
166
  new_lines[the_line_index] = the_line.sub(/# /, '')
139
167
  delta -= 2
@@ -192,10 +220,10 @@ module Glimmer
192
220
  delta = 0
193
221
  line_indices_for_selection(caret_position, selection_count).each do |the_line_index|
194
222
  the_line = old_lines[the_line_index]
195
- if the_line.start_with?(' ')
223
+ if the_line.to_s.start_with?(' ')
196
224
  new_lines[the_line_index] = the_line.sub(/ /, '')
197
225
  delta = -2
198
- elsif the_line.start_with?(' ')
226
+ elsif the_line&.start_with?(' ')
199
227
  new_lines[the_line_index] = the_line.sub(/ /, '')
200
228
  delta = -1
201
229
  end
@@ -249,7 +277,7 @@ module Glimmer
249
277
  end
250
278
 
251
279
  def find_next
252
- return if find_text.to_s.empty?
280
+ return if find_text.to_s.empty?
253
281
  all_lines = lines
254
282
  the_line_index = line_index_for_caret_position(caret_position)
255
283
  line_position = line_position_for_caret_position(caret_position)
@@ -260,8 +288,8 @@ module Glimmer
260
288
  the_index = (the_index + rotation)%all_lines.size
261
289
  start_position = 0
262
290
  start_position = line_position + find_text.to_s.size if i == 0 && the_index == the_line_index && found_text?(caret_position)
263
- text_to_find_in = the_line.downcase[start_position..-1]
264
- 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)
265
293
  if occurrence_index
266
294
  self.caret_position = caret_position_for_line_index(the_index) + start_position + occurrence_index
267
295
  self.selection_count = find_text.to_s.size
@@ -315,18 +343,22 @@ module Glimmer
315
343
  end
316
344
 
317
345
  def page_up
346
+ self.selection_count = 0
318
347
  self.line_number = [(self.line_number - 15), 1].max
319
348
  end
320
349
 
321
350
  def page_down
351
+ self.selection_count = 0
322
352
  self.line_number = [(self.line_number + 15), lines.size].min
323
353
  end
324
354
 
325
355
  def home
356
+ self.selection_count = 0
326
357
  self.line_number = 1
327
358
  end
328
359
 
329
360
  def end
361
+ self.selection_count = 0
330
362
  self.line_number = lines.size
331
363
  end
332
364
 
@@ -430,6 +462,14 @@ module Glimmer
430
462
  def to_s
431
463
  path
432
464
  end
465
+
466
+ def eql?(other)
467
+ self.path.eql?(other&.path)
468
+ end
469
+
470
+ def hash
471
+ self.path.hash
472
+ end
433
473
  end
434
474
  end
435
475
  end
@@ -1,17 +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'
2
+ require 'os'
7
3
 
8
4
  require 'models/glimmer/gladiator/dir'
9
5
  require 'models/glimmer/gladiator/file'
6
+ require 'models/glimmer/gladiator/command'
10
7
 
11
8
  require 'views/glimmer/gladiator/text_editor'
12
9
 
13
- java_import 'org.eclipse.swt.custom.TreeEditor'
14
-
15
10
  Clipboard.implementation = Clipboard::Java
16
11
  Clipboard.copy(Clipboard.paste) # pre-initialize library to avoid slowdown during use
17
12
 
@@ -19,13 +14,20 @@ module Glimmer
19
14
  # Gladiator (Glimmer Editor)
20
15
  class Gladiator
21
16
  include Glimmer::UI::CustomShell
17
+
18
+ COMMAND_KEY = OS.mac? ? :command : :ctrl
19
+
20
+ class << self
21
+ attr_accessor :drag_and_drop
22
+ attr_accessor :drag
23
+ end
22
24
 
23
25
  ## Add options like the following to configure CustomShell by outside consumers
24
26
  #
25
27
  # options :title, :background_color
26
28
  # option :width, 320
27
29
  # option :height, 240
28
-
30
+
29
31
  ## Uncomment before_body block to pre-initialize variables to use in body
30
32
  #
31
33
  #
@@ -33,89 +35,113 @@ module Glimmer
33
35
  Display.setAppName('Gladiator')
34
36
  @display = display {
35
37
  on_event_keydown { |key_event|
36
- if key_event.stateMask == swt(:command) && key_event.character.chr == 'f'
37
- if @text_editor.text_widget.getSelectionText && @text_editor.text_widget.getSelectionText.size > 0
38
+ if key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'f'
39
+ if @text_editor&.text_widget&.getSelectionText && @text_editor&.text_widget&.getSelectionText&.size.to_i > 0
38
40
  @find_text.swt_widget.setText @text_editor.text_widget.getSelectionText
39
41
  end
40
42
  @find_text.swt_widget.selectAll
41
43
  @find_text.swt_widget.setFocus
42
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command, :shift) && key_event.character.chr == 'c'
43
- Clipboard.copy(Gladiator::Dir.local_dir.selected_child.path)
44
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command, :shift) && key_event.character.chr == 'g'
45
- Gladiator::Dir.local_dir.selected_child.find_previous
46
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command, :shift) && key_event.character.chr == 'w'
44
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == 'c'
45
+ Clipboard.copy(Dir.local_dir.selected_child.path)
46
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == 'g'
47
+ Dir.local_dir.selected_child.find_previous
48
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == 'w'
47
49
  @tab_folder.swt_widget.getItems.each do |tab_item|
48
50
  Dir.local_dir.selected_child_path_history.delete(tab_item.getData('file_path'))
49
- tab_item.getData('proxy').dispose
51
+ tab_item.getData('proxy')&.dispose
50
52
  end
53
+ close_tab_folder
51
54
  @tab_item = @text_editor = Dir.local_dir.selected_child = nil
52
55
  @filter_text.swt_widget.selectAll
53
56
  @filter_text.swt_widget.setFocus
54
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character == 8721
57
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :alt) && extract_char(key_event) == 'w'
55
58
  other_tab_items.each do |tab_item|
56
59
  Dir.local_dir.selected_child_path_history.delete(tab_item.getData('file_path'))
57
- tab_item.getData('proxy').dispose
60
+ tab_item.getData('proxy')&.dispose
58
61
  end
59
- elsif key_event.stateMask == swt(:command) && key_event.character.chr == 'w'
62
+ elsif key_event.stateMask == swt(COMMAND_KEY) && extract_char(key_event) == 'w'
60
63
  if selected_tab_item
61
64
  Dir.local_dir.selected_child_path_history.delete(Dir.local_dir.selected_child.path)
62
- selected_tab_item.getData('proxy').dispose
65
+ selected_tab_item.getData('proxy')&.dispose
66
+ close_tab_folder
63
67
  if selected_tab_item.nil?
64
68
  @tab_item = @text_editor = Dir.local_dir.selected_child = nil
65
69
  @filter_text.swt_widget.selectAll
66
70
  @filter_text.swt_widget.setFocus
67
71
  else
68
- @text_editor.text_widget.setFocus
69
- end
72
+ @text_editor&.text_widget&.setFocus
73
+ end
74
+ end
75
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == ']'
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
78
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY, :shift) && extract_char(key_event) == '['
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
70
91
  end
71
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command, :shift) && key_event.character.chr == ']'
72
- @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
73
- @text_editor.text_widget.setFocus
74
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command, :shift) && key_event.character.chr == '['
75
- @tab_folder.swt_widget.setSelection([@tab_folder.swt_widget.getSelectionIndex() - 1, 0].max) if @tab_folder.swt_widget.getItemCount > 0
76
- @text_editor.text_widget.setFocus
77
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr == '1'
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
103
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '1'
78
104
  @tab_folder.swt_widget.setSelection(0) if @tab_folder.swt_widget.getItemCount >= 1
79
- @text_editor.text_widget.setFocus
80
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr == '2'
105
+ @text_editor&.text_widget&.setFocus
106
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '2'
81
107
  @tab_folder.swt_widget.setSelection(1) if @tab_folder.swt_widget.getItemCount >= 2
82
- @text_editor.text_widget.setFocus
83
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr == '3'
108
+ @text_editor&.text_widget&.setFocus
109
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '3'
84
110
  @tab_folder.swt_widget.setSelection(2) if @tab_folder.swt_widget.getItemCount >= 3
85
- @text_editor.text_widget.setFocus
86
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr == '4'
111
+ @text_editor&.text_widget&.setFocus
87
112
  @tab_folder.swt_widget.setSelection(3) if @tab_folder.swt_widget.getItemCount >= 4
88
- @text_editor.text_widget.setFocus
89
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr == '5'
113
+ @text_editor&.text_widget&.setFocus
114
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '5'
90
115
  @tab_folder.swt_widget.setSelection(4) if @tab_folder.swt_widget.getItemCount >= 5
91
- @text_editor.text_widget.setFocus
92
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr == '6'
116
+ @text_editor&.text_widget&.setFocus
117
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '4'
118
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '6'
93
119
  @tab_folder.swt_widget.setSelection(5) if @tab_folder.swt_widget.getItemCount >= 6
94
- @text_editor.text_widget.setFocus
95
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr == '7'
120
+ @text_editor&.text_widget&.setFocus
121
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '7'
96
122
  @tab_folder.swt_widget.setSelection(6) if @tab_folder.swt_widget.getItemCount >= 7
97
- @text_editor.text_widget.setFocus
98
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr == '8'
123
+ @text_editor&.text_widget&.setFocus
124
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '8'
99
125
  @tab_folder.swt_widget.setSelection(7) if @tab_folder.swt_widget.getItemCount >= 8
100
- @text_editor.text_widget.setFocus
101
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr == '9'
126
+ @text_editor&.text_widget&.setFocus
127
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == '9'
102
128
  @tab_folder.swt_widget.setSelection(@tab_folder.swt_widget.getItemCount - 1) if @tab_folder.swt_widget.getItemCount > 0
103
- @text_editor.text_widget.setFocus
104
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr == 'g'
105
- Gladiator::Dir.local_dir.selected_child.find_next
106
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr == 'l'
129
+ @text_editor&.text_widget&.setFocus
130
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == 'g'
131
+ Dir.local_dir.selected_child.find_next
132
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == 'l'
107
133
  @line_number_text.swt_widget.selectAll
108
134
  @line_number_text.swt_widget.setFocus
109
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr == 'r'
135
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == 'r'
110
136
  @filter_text.swt_widget.selectAll
111
137
  @filter_text.swt_widget.setFocus
112
- elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, :command) && key_event.character.chr == 't'
138
+ elsif Glimmer::SWT::SWTProxy.include?(key_event.stateMask, COMMAND_KEY) && extract_char(key_event) == 't'
113
139
  select_tree_item unless @rename_in_progress
114
140
  @tree.swt_widget.setFocus
115
141
  elsif key_event.keyCode == swt(:esc)
116
142
  if @text_editor
117
143
  Dir.local_dir.selected_child_path = @text_editor.file.path
118
- @text_editor.text_widget.setFocus
144
+ @text_editor&.text_widget&.setFocus
119
145
  end
120
146
  end
121
147
  }
@@ -124,51 +150,79 @@ module Glimmer
124
150
  local_dir = ENV['LOCAL_DIR'] || '.'
125
151
  @config_file_path = ::File.join(local_dir, '.gladiator')
126
152
  @config = {}
127
- Gladiator::Dir.local_dir.all_children # pre-caches children
153
+ Dir.local_dir.all_children # pre-caches children
128
154
  }
129
155
 
130
156
  ## Uncomment after_body block to setup observers for widgets in body
131
157
  #
132
158
  after_body {
133
- observe(Gladiator::Dir.local_dir, 'children') do
159
+ observe(Dir.local_dir, 'children') do
134
160
  select_tree_item unless @rename_in_progress
135
161
  end
136
- observe(Gladiator::Dir.local_dir, 'selected_child') do
137
- select_tree_item unless @rename_in_progress
138
- selected_file = Gladiator::Dir.local_dir.selected_child
139
- found_tab_item = selected_tab_item
140
- if found_tab_item
141
- @tab_folder.swt_widget.setSelection(found_tab_item)
142
- @tab_item = found_tab_item.getData('tab_item')
143
- @text_editor = found_tab_item.getData('text_editor')
144
- elsif selected_file
145
- @tab_folder.content {
146
- @tab_item = tab_item { |the_tab_item|
147
- text selected_file.name
148
- fill_layout :horizontal
149
- @text_editor = the_text_editor = text_editor(file: selected_file)
150
- on_event_show {
151
- Gladiator::Dir.local_dir.selected_child = selected_file
152
- @tab_item = the_tab_item
153
- @text_editor = the_text_editor
154
- }
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)
155
169
  }
156
- @tab_item.swt_tab_item.setData('file_path', selected_file.path)
157
- @tab_item.swt_tab_item.setData('tab_item', @tab_item)
158
- @tab_item.swt_tab_item.setData('text_editor', @text_editor)
159
- @tab_item.swt_tab_item.setData('proxy', @tab_item)
160
- }
161
- @tab_folder.swt_widget.setSelection(@tab_item.swt_tab_item)
162
- 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_event_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
163
217
  end
164
218
  end
165
- observe(Gladiator::Dir.local_dir, 'selected_child') do
219
+ observe(Dir.local_dir, 'selected_child') do
166
220
  save_config
167
221
  end
168
- observe(Gladiator::Dir.local_dir, 'selected_child.caret_position') do
222
+ observe(Dir.local_dir, 'selected_child.caret_position') do
169
223
  save_config
170
224
  end
171
- observe(Gladiator::Dir.local_dir, 'selected_child.top_index') do
225
+ observe(Dir.local_dir, 'selected_child.top_index') do
172
226
  save_config
173
227
  end
174
228
  load_config
@@ -179,15 +233,15 @@ module Glimmer
179
233
  #
180
234
  body {
181
235
  shell {
182
- text "Gladiator - #{::File.expand_path(Gladiator::Dir.local_dir.path)}"
183
- minimum_size 720, 450
236
+ text "Gladiator - #{::File.expand_path(Dir.local_dir.path)}"
237
+ minimum_size 520, 250
184
238
  size 1440, 900
185
239
  grid_layout 2, false
186
240
  on_event_close {
187
- Gladiator::Dir.local_dir.selected_child&.write_dirty_content
241
+ Dir.local_dir.selected_child&.write_dirty_content
188
242
  }
189
243
  on_widget_disposed {
190
- Gladiator::Dir.local_dir.selected_child&.write_dirty_content
244
+ Dir.local_dir.selected_child&.write_dirty_content
191
245
  }
192
246
  on_control_resized {
193
247
  save_config
@@ -205,7 +259,7 @@ module Glimmer
205
259
  }
206
260
  @filter_text = text {
207
261
  layout_data :fill, :center, true, false
208
- text bind(Gladiator::Dir.local_dir, 'filter')
262
+ text bind(Dir.local_dir, 'filter')
209
263
  on_key_pressed { |key_event|
210
264
  if key_event.keyCode == swt(:tab) ||
211
265
  key_event.keyCode == swt(:cr) ||
@@ -217,35 +271,48 @@ module Glimmer
217
271
  }
218
272
  }
219
273
  composite {
274
+ fill_layout(:vertical) {
275
+ spacing 5
276
+ }
220
277
  layout_data(:fill, :fill, true, true)
221
278
  @list = list(:border, :h_scroll, :v_scroll) {
222
- layout_data(:fill, :fill, true, true) {
223
- #exclude bind(Gladiator::Dir.local_dir, :filter) {|f| !f}
224
- minimum_height 400
225
- }
226
- #visible bind(Gladiator::Dir, 'local_dir.filter') {|f| !!f}
227
- 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)
228
281
  on_mouse_up {
229
- Gladiator::Dir.local_dir.selected_child_path = @list.swt_widget.getSelection.first
282
+ Dir.local_dir.selected_child_path = @list.swt_widget.getSelection.first
230
283
  }
231
284
  on_key_pressed { |key_event|
232
285
  if Glimmer::SWT::SWTProxy.include?(key_event.keyCode, :cr)
233
- Gladiator::Dir.local_dir.selected_child_path = @list.swt_widget.getSelection.first
234
- @text_editor.text_widget.setFocus
286
+ Dir.local_dir.selected_child_path = @list.swt_widget.getSelection.first
287
+ @text_editor&.text_widget&.setFocus
235
288
  end
236
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
+ }
237
298
  }
238
299
  @tree = tree(:virtual, :border, :h_scroll, :v_scroll) {
239
- layout_data(:fill, :fill, true, true) {
240
- #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
+ }
241
310
  }
242
- #visible bind(Gladiator::Dir, 'local_dir.filter') {|f| !f}
243
- items bind(Gladiator::Dir, :local_dir), tree_properties(children: :children, text: :name)
244
311
  menu {
245
312
  @open_menu_item = menu_item {
246
313
  text 'Open'
247
314
  on_widget_selected {
248
- 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)
249
316
  }
250
317
  }
251
318
  menu_item(:separator)
@@ -259,7 +326,7 @@ module Glimmer
259
326
  menu_item {
260
327
  text 'Refresh'
261
328
  on_widget_selected {
262
- Gladiator::Dir.local_dir.refresh
329
+ Dir.local_dir.refresh
263
330
  }
264
331
  }
265
332
  menu_item {
@@ -286,12 +353,16 @@ module Glimmer
286
353
  @open_menu_item.swt_widget.setEnabled(!::Dir.exist?(path)) if path
287
354
  }
288
355
  on_mouse_up {
289
- Gladiator::Dir.local_dir.selected_child_path = extract_tree_item_path(@tree.swt_widget.getSelection&.first)
290
- @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
291
362
  }
292
363
  on_key_pressed { |key_event|
293
364
  if Glimmer::SWT::SWTProxy.include?(key_event.keyCode, :cr)
294
- 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)
295
366
  @text_editor&.text_widget&.setFocus
296
367
  end
297
368
  }
@@ -314,15 +385,18 @@ module Glimmer
314
385
  grid_layout 1, false
315
386
  layout_data :fill, :fill, true, true
316
387
  composite {
317
- grid_layout 2, false
388
+ grid_layout 3, false
389
+
390
+ # row 1
391
+
318
392
  @file_path_label = styled_text(:none) {
319
393
  layout_data(:fill, :fill, true, false) {
320
- horizontal_span 2
394
+ horizontal_span 3
321
395
  }
322
396
  background color(:widget_background)
323
397
  editable false
324
398
  caret nil
325
- text bind(Gladiator::Dir.local_dir, 'selected_child.path')
399
+ text bind(Dir.local_dir, 'selected_child.path')
326
400
  on_mouse_up {
327
401
  @file_path_label.swt_widget.selectAll
328
402
  }
@@ -330,6 +404,9 @@ module Glimmer
330
404
  @file_path_label.swt_widget.setSelection(0, 0)
331
405
  }
332
406
  }
407
+
408
+ # row 2
409
+
333
410
  label {
334
411
  text 'Line:'
335
412
  }
@@ -337,13 +414,20 @@ module Glimmer
337
414
  layout_data(:fill, :fill, true, false) {
338
415
  minimum_width 400
339
416
  }
340
- 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)
341
418
  on_key_pressed { |key_event|
342
419
  if key_event.keyCode == swt(:cr)
343
- @text_editor.text_widget.setFocus
420
+ @text_editor&.text_widget&.setFocus
344
421
  end
345
422
  }
423
+ on_verify_text { |event|
424
+ event.doit = !event.text.match(/^\d*$/).to_a.empty?
425
+ }
346
426
  }
427
+ label
428
+
429
+ # row 3
430
+
347
431
  label {
348
432
  text 'Find:'
349
433
  }
@@ -351,13 +435,34 @@ module Glimmer
351
435
  layout_data(:fill, :fill, true, false) {
352
436
  minimum_width 400
353
437
  }
354
- text bind(Gladiator::Dir.local_dir, 'selected_child.find_text')
438
+ text bind(Dir.local_dir, 'selected_child.find_text')
355
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
356
444
  if key_event.keyCode == swt(:cr)
357
- Gladiator::Dir.local_dir.selected_child.find_next
445
+ Dir.local_dir.selected_child&.find_next
358
446
  end
359
447
  }
360
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
+
361
466
  label {
362
467
  text 'Replace:'
363
468
  }
@@ -365,46 +470,71 @@ module Glimmer
365
470
  layout_data(:fill, :fill, true, false) {
366
471
  minimum_width 300
367
472
  }
368
- text bind(Gladiator::Dir.local_dir, 'selected_child.replace_text')
473
+ text bind(Dir.local_dir, 'selected_child.replace_text')
369
474
  on_focus_gained {
370
- Gladiator::Dir.local_dir.selected_child.ensure_find_next
475
+ Dir.local_dir.selected_child&.ensure_find_next
371
476
  }
372
477
  on_key_pressed { |key_event|
373
478
  if key_event.keyCode == swt(:cr)
374
- 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
375
482
  end
376
483
  }
377
484
  }
485
+ label
378
486
  }
379
- @tab_folder = tab_folder {
380
- 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)
381
509
  }
382
510
  }
383
511
  }
384
512
  }
385
-
513
+
386
514
  def load_config
387
515
  if ::File.exists?(@config_file_path)
388
516
  config_yaml = ::File.read(@config_file_path)
389
517
  return if config_yaml.to_s.strip.empty?
390
518
  @config = YAML.load(config_yaml)
391
519
  @config[:open_file_paths].to_a.each do |file_path|
392
- Gladiator::Dir.local_dir.selected_child_path = file_path
520
+ Dir.local_dir.selected_child_path = file_path
393
521
  end
394
- Gladiator::Dir.local_dir.selected_child_path = @config[:selected_child_path] if @config[:selected_child_path]
395
- 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]
396
- Gladiator::Dir.local_dir.selected_child&.top_index = @config[:top_index].to_i if @config[:top_index]
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]
397
525
  body_root.on_event_show {
398
526
  swt_widget.setSize(@config[:shell_width], @config[:shell_height]) if @config[:shell_width] && @config[:shell_height]
399
527
  swt_widget.setLocation(@config[:shell_x], @config[:shell_y]) if @config[:shell_x] && @config[:shell_y]
400
528
  @loaded_config = true
401
529
  }
530
+ else
531
+ @loaded_config = true
402
532
  end
403
533
  end
404
534
 
405
535
  def save_config
406
536
  return unless @loaded_config
407
- child = Gladiator::Dir.local_dir.selected_child
537
+ child = Dir.local_dir.selected_child
408
538
  return if child.nil?
409
539
  @config = {
410
540
  selected_child_path: child.path,
@@ -422,12 +552,31 @@ module Glimmer
422
552
  puts e.full_message
423
553
  end
424
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
+
425
574
  def selected_tab_item
426
- @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 }
427
576
  end
428
577
 
429
578
  def other_tab_items
430
- @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 }
431
580
  end
432
581
 
433
582
  def extract_tree_item_path(tree_item)
@@ -440,15 +589,16 @@ module Glimmer
440
589
  end
441
590
 
442
591
  def select_tree_item
443
- return unless Gladiator::Dir.local_dir.selected_child&.name
444
- 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 }
445
594
  @tree.swt_widget.setSelection(tree_items_to_select)
446
595
  end
447
596
 
448
597
  def delete_tree_item(tree_item)
598
+ return if tree_item.nil?
449
599
  file = tree_item.getData
450
600
  parent_path = ::File.dirname(file.path)
451
- file.delete!
601
+ file.delete! # TODO consider supporting command undo/redo
452
602
  Dir.local_dir.refresh(async: false)
453
603
  parent_tree_item = @tree.depth_first_search {|ti| ti.getData.path == parent_path}.first
454
604
  @tree.swt_widget.showItem(parent_tree_item)
@@ -457,6 +607,8 @@ module Glimmer
457
607
  # if file.is_a?(::File)
458
608
  # close tab
459
609
  # end
610
+ rescue => e
611
+ puts e.full_message
460
612
  end
461
613
 
462
614
  def rename_selected_tree_item
@@ -469,6 +621,7 @@ module Glimmer
469
621
  Dir.local_dir.pause_refresh
470
622
  tree_item = @tree.swt_widget.getSelection.first
471
623
  directory_path = extract_tree_item_path(tree_item)
624
+ return if directory_path.nil?
472
625
  if !::Dir.exist?(directory_path)
473
626
  tree_item = tree_item.getParentItem
474
627
  directory_path = ::File.dirname(directory_path)
@@ -512,5 +665,11 @@ module Glimmer
512
665
  }
513
666
  )
514
667
  end
668
+
669
+ def extract_char(event)
670
+ event.keyCode.chr
671
+ rescue => e
672
+ nil
673
+ end
515
674
  end
516
- end
675
+ end