glimmer-dsl-swt 0.6.4 → 0.6.9
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 +4 -4
- data/README.md +3 -2
- data/VERSION +1 -1
- data/lib/ext/glimmer/config.rb +17 -1
- data/lib/glimmer-dsl-swt.rb +5 -9
- data/lib/glimmer/data_binding/table_items_binding.rb +4 -1
- data/lib/glimmer/dsl/swt/exec_expression.rb +7 -1
- data/lib/glimmer/launcher.rb +37 -23
- data/lib/glimmer/rake_task.rb +61 -73
- data/lib/glimmer/scaffold.rb +19 -3
- data/lib/glimmer/swt/shell_proxy.rb +0 -1
- data/lib/glimmer/swt/style_constantizable.rb +1 -0
- data/lib/glimmer/swt/table_proxy.rb +16 -4
- data/lib/glimmer/swt/widget_proxy.rb +53 -37
- data/samples/elaborate/user_profile.rb +55 -0
- metadata +42 -7
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f8cb96b5eda19eb65af0d9fa5b8f79050a341f5f148e78c13a27b18c07cef083
|
4
|
+
data.tar.gz: 6e925dab92f1ea52557c2f9078a1c7b0b0068225644da25ce81677e6d4b9fca4
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: f23a464b36497e60e0379b90a1f17f630d84c0ff01359a89a9dd8cfe008306bbbd779c1b456c3ff17cdbaae331b795b1241597d57b653e063c3aa8af7f463ce7
|
7
|
+
data.tar.gz: 02a87c762461b89acac3385dfb2ab4ea0089e6b3b4320f60e843758e5b28df2036cb4524e8b0851b792576401857de3e77e9981bf92ee98205ddfadf425cbf8a
|
data/README.md
CHANGED
@@ -1,11 +1,11 @@
|
|
1
|
-
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for SWT 0.6.
|
1
|
+
# [<img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 />](https://github.com/AndyObtiva/glimmer) Glimmer DSL for SWT 0.6.9 (JRuby Desktop GUI)
|
2
2
|
[](http://badge.fury.io/rb/glimmer-dsl-swt)
|
3
3
|
[](https://travis-ci.com/github/AndyObtiva/glimmer-dsl-swt)
|
4
4
|
[](https://coveralls.io/github/AndyObtiva/glimmer-dsl-swt?branch=master)
|
5
5
|
[](https://codeclimate.com/github/AndyObtiva/glimmer-dsl-swt/maintainability)
|
6
6
|
[](https://gitter.im/AndyObtiva/glimmer?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
7
7
|
|
8
|
-
[Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [SWT](https://www.eclipse.org/swt/) enables desktop development with [Glimmer](https://github.com/AndyObtiva/glimmer).
|
8
|
+
[Glimmer](https://github.com/AndyObtiva/glimmer) DSL for [SWT](https://www.eclipse.org/swt/) enables desktop development with [Glimmer](https://github.com/AndyObtiva/glimmer) in [JRuby](https://www.jruby.org/).
|
9
9
|
|
10
10
|
[Glimmer](https://github.com/AndyObtiva/glimmer) is a native-GUI cross-platform desktop development library written in Ruby. Glimmer's main innovation is a JRuby DSL that enables productive and efficient authoring of desktop application user-interfaces while relying on the robust Eclipse SWT library. Glimmer additionally innovates by having built-in data-binding support to greatly facilitate synchronizing the GUI with domain models. As a result, that achieves true decoupling of object oriented components, enabling developers to solve business problems without worrying about GUI concerns, or alternatively drive development GUI-first, and then write clean business models test-first afterwards.
|
11
11
|
|
@@ -15,6 +15,7 @@ Other [Glimmer](https://github.com/AndyObtiva/glimmer) DSL gems:
|
|
15
15
|
- [glimmer-dsl-opal](https://github.com/AndyObtiva/glimmer-dsl-opal): Glimmer DSL for Opal (Web GUI Adapter for Desktop Apps)
|
16
16
|
- [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
|
17
17
|
- [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS (Cascading Style Sheets)
|
18
|
+
- [glimmer-dsl-tk](https://github.com/AndyObtiva/glimmer-dsl-tk): Glimmer DSL for Tk (MRI Ruby Desktop GUI)
|
18
19
|
|
19
20
|
## Example
|
20
21
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.9
|
data/lib/ext/glimmer/config.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'glimmer/config'
|
2
|
+
|
1
3
|
module Glimmer
|
2
4
|
module Config
|
3
5
|
DEFAULT_IMPORT_SWT_PACKAGES = [
|
@@ -9,6 +11,11 @@ module Glimmer
|
|
9
11
|
'org.eclipse.swt.custom',
|
10
12
|
'org.eclipse.swt.dnd',
|
11
13
|
]
|
14
|
+
|
15
|
+
# This may be configured with extra sample directories from custom widget/shell gems
|
16
|
+
# following the convention of a `samples/subdirectory` where subdirectory is the
|
17
|
+
# custom widget/shell name or something representative of a group of samples (e.g. c_date_time).
|
18
|
+
SAMPLE_DIRECTORIES = []
|
12
19
|
|
13
20
|
class << self
|
14
21
|
# Tells Glimmer to import SWT packages into including class (default: true)
|
@@ -48,6 +55,10 @@ module Glimmer
|
|
48
55
|
|
49
56
|
def logging_appender_options
|
50
57
|
@@logging_appender_options = {async: true, auto_flushing: 500, write_size: 500, flush_period: 60, immediate_at: [:error, :fatal], layout: logging_layout} unless defined? @@logging_appender_options
|
58
|
+
# TODO make this a glimmer command option
|
59
|
+
if ENV['GLIMMER_LOGGER_ASYNC'].to_s.downcase == 'false'
|
60
|
+
@@logging_appender_options.merge!(async: false, auto_flushing: 1, immediate_at: [:debug, :info, :warn, :error, :fatal])
|
61
|
+
end
|
51
62
|
@@logging_appender_options
|
52
63
|
end
|
53
64
|
|
@@ -90,12 +101,16 @@ module Glimmer
|
|
90
101
|
end
|
91
102
|
logger.appenders = appenders
|
92
103
|
end
|
104
|
+
|
93
105
|
end
|
106
|
+
|
94
107
|
end
|
108
|
+
|
95
109
|
end
|
110
|
+
|
96
111
|
end
|
97
112
|
|
98
|
-
Glimmer::Config.reset_logger!
|
113
|
+
Glimmer::Config.reset_logger! unless ENV['GLIMMER_LOGGER_ENABLED'].to_s.downcase == 'false'
|
99
114
|
if ENV['GLIMMER_LOGGER_LEVEL']
|
100
115
|
# if glimmer log level is being overridden for debugging purposes, then disable async logging making logging immediate
|
101
116
|
Glimmer::Config.logging_appender_options = Glimmer::Config.logging_appender_options.merge(async: false, auto_flushing: 1)
|
@@ -106,6 +121,7 @@ if ENV['GLIMMER_LOGGER_LEVEL']
|
|
106
121
|
puts e.message
|
107
122
|
end
|
108
123
|
end
|
124
|
+
|
109
125
|
Glimmer::Config.excluded_keyword_checkers << lambda do |method_symbol, *args|
|
110
126
|
method = method_symbol.to_s
|
111
127
|
result = false
|
data/lib/glimmer-dsl-swt.rb
CHANGED
@@ -2,15 +2,11 @@ $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
|
|
2
2
|
|
3
3
|
# External requires
|
4
4
|
require 'java'
|
5
|
-
if ENV['
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
require 'logging'
|
11
|
-
require 'nested_inherited_jruby_include_package'
|
12
|
-
require 'super_module'
|
13
|
-
end
|
5
|
+
require 'puts_debuggerer' if ("#{ENV['pd']}#{ENV['PD']}").to_s.downcase.include?('true')
|
6
|
+
require 'glimmer'
|
7
|
+
require 'logging'
|
8
|
+
require 'nested_inherited_jruby_include_package'
|
9
|
+
require 'super_module'
|
14
10
|
|
15
11
|
# Internal requires
|
16
12
|
require 'ext/glimmer/config'
|
@@ -30,7 +30,10 @@ module Glimmer
|
|
30
30
|
end
|
31
31
|
|
32
32
|
def call(new_model_collection=nil)
|
33
|
-
new_model_collection = @model_binding.evaluate_property # this ensures applying converters (e.g. :on_read)
|
33
|
+
new_model_collection = @model_binding.evaluate_property # this ensures applying converters (e.g. :on_read)
|
34
|
+
table_cells = @table.swt_widget.items.map {|item| @table.column_properties.size.times.map {|i| item.get_text(i)} }
|
35
|
+
model_cells = new_model_collection.to_a.map {|m| @table.cells_for(m)}
|
36
|
+
return if table_cells == model_cells
|
34
37
|
if new_model_collection and new_model_collection.is_a?(Array)
|
35
38
|
@table_items_observer_registration&.unobserve
|
36
39
|
@table_items_observer_registration = observe(new_model_collection, @column_properties)
|
@@ -20,7 +20,13 @@ module Glimmer
|
|
20
20
|
end
|
21
21
|
|
22
22
|
def interpret(parent, keyword, *args, &block)
|
23
|
-
Glimmer::SWT::DisplayProxy.instance.swt_display.send(exec_operation
|
23
|
+
Glimmer::SWT::DisplayProxy.instance.swt_display.send(exec_operation) do |*args|
|
24
|
+
begin
|
25
|
+
block.call(*args)
|
26
|
+
rescue => e
|
27
|
+
Glimmer::Config.logger.error e.full_message
|
28
|
+
end
|
29
|
+
end
|
24
30
|
end
|
25
31
|
end
|
26
32
|
end
|
data/lib/glimmer/launcher.rb
CHANGED
@@ -1,39 +1,30 @@
|
|
1
1
|
require 'fileutils'
|
2
|
-
|
3
|
-
require_relative 'rake_task'
|
2
|
+
require 'os'
|
4
3
|
|
5
4
|
module Glimmer
|
6
5
|
class Launcher
|
7
6
|
OPERATING_SYSTEMS_SUPPORTED = ["mac", "windows", "linux"]
|
8
7
|
|
9
|
-
|
8
|
+
TEXT_USAGE = <<~MULTI_LINE_STRING
|
10
9
|
Glimmer (Ruby Desktop Development GUI Library) - JRuby Gem: glimmer-dsl-swt v#{File.read(File.expand_path('../../../VERSION', __FILE__))}
|
11
10
|
Usage: glimmer [--quiet] [--debug] [--log-level=VALUE] [[ENV_VAR=VALUE]...] [[-jruby-option]...] (application.rb or task[task_args]) [[application2.rb]...]
|
12
11
|
|
13
|
-
Runs Glimmer applications
|
14
|
-
|
15
|
-
Either a single task or one or more applications may be specified.
|
16
|
-
|
17
|
-
When a task is specified, it runs via rake. Some tasks take arguments in square brackets.
|
18
|
-
|
19
|
-
Available tasks are below (if you do not see any, please add `require 'glimmer/rake_task'` to Rakefile and rerun or run rake -T):
|
20
|
-
MULTI_LINE_STRING
|
21
|
-
|
22
|
-
TEXT_USAGE_SUFFIX = <<~MULTI_LINE_STRING
|
12
|
+
Runs Glimmer applications and tasks.
|
23
13
|
|
24
14
|
When applications are specified, they are run using JRuby,
|
25
15
|
automatically preloading the glimmer Ruby gem and SWT jar dependency.
|
26
16
|
|
27
|
-
Optionally, extra Glimmer options, JRuby options and environment variables may be passed in.
|
17
|
+
Optionally, extra Glimmer options, JRuby options, and/or environment variables may be passed in.
|
28
18
|
|
29
19
|
Glimmer options:
|
30
20
|
- "--quiet" : Does not announce file path of Glimmer application being launched
|
31
21
|
- "--debug" : Displays extra debugging information, passes "--debug" to JRuby, and enables debug logging
|
32
22
|
- "--log-level=VALUE" : Sets Glimmer's Ruby logger level ("ERROR" / "WARN" / "INFO" / "DEBUG"; default is none)
|
33
23
|
|
34
|
-
|
24
|
+
Tasks are run via rake. Some tasks take arguments in square brackets.
|
35
25
|
|
36
|
-
|
26
|
+
Available tasks are below (if you do not see any, please add `require 'glimmer/rake_task'` to Rakefile and rerun or run rake -T):
|
27
|
+
|
37
28
|
MULTI_LINE_STRING
|
38
29
|
|
39
30
|
GLIMMER_LIB_LOCAL = File.expand_path(File.join('lib', 'glimmer-dsl-swt.rb'))
|
@@ -108,6 +99,7 @@ module Glimmer
|
|
108
99
|
if the_glimmer_lib == GLIMMER_LIB_LOCAL
|
109
100
|
devmode_require = '-r puts_debuggerer '
|
110
101
|
end
|
102
|
+
require_relative 'rake_task'
|
111
103
|
rake_tasks = Rake.application.tasks.map(&:to_s).map {|t| t.sub('glimmer:', '')}
|
112
104
|
|
113
105
|
# handle a bash quirk with calling package[msi] while there is a "packages" directory locally (it passes package[msi] as packages)
|
@@ -180,14 +172,36 @@ module Glimmer
|
|
180
172
|
end
|
181
173
|
|
182
174
|
def display_usage
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
175
|
+
puts TEXT_USAGE
|
176
|
+
display_tasks
|
177
|
+
end
|
178
|
+
|
179
|
+
def display_tasks
|
180
|
+
if OS.windows?
|
181
|
+
tasks = Rake.application.tasks
|
182
|
+
task_lines = tasks.reject do |task|
|
183
|
+
task.comment.nil?
|
184
|
+
end.map do |task|
|
185
|
+
max_task_size = tasks.map(&:name_with_args).map(&:size).max + 1
|
186
|
+
task_name = task.name_with_args.sub('glimmer:', '')
|
187
|
+
line = "glimmer #{task_name.ljust(max_task_size)} # #{task.comment}"
|
188
|
+
bound = TTY::Screen.width - 6
|
189
|
+
line.size <= bound ? line : "#{line[0..(bound - 3)]}..."
|
190
|
+
end
|
191
|
+
puts task_lines.to_a
|
192
|
+
else
|
193
|
+
require 'rake-tui'
|
194
|
+
require 'tty-screen'
|
195
|
+
require_relative 'rake_task'
|
196
|
+
Rake::TUI.run(branding_header: nil, prompt_question: 'Select a Glimmer task to run:') do |task, tasks|
|
197
|
+
max_task_size = tasks.map(&:name_with_args).map(&:size).max + 1
|
198
|
+
task_name = task.name_with_args.sub('glimmer:', '')
|
199
|
+
line = "glimmer #{task_name.ljust(max_task_size)} # #{task.comment}"
|
200
|
+
bound = TTY::Screen.width - 6
|
201
|
+
line.size <= bound ? line : "#{line[0..(bound - 3)]}..."
|
202
|
+
end
|
189
203
|
end
|
190
|
-
end
|
204
|
+
end
|
191
205
|
|
192
206
|
def extract_application_paths(options)
|
193
207
|
options.select do |option|
|
data/lib/glimmer/rake_task.rb
CHANGED
@@ -2,102 +2,91 @@ require 'rake'
|
|
2
2
|
|
3
3
|
require_relative 'package'
|
4
4
|
|
5
|
+
ENV['GLIMMER_LOGGER_ENABLED'] = 'false'
|
6
|
+
require_relative '../ext/glimmer/config.rb'
|
7
|
+
|
8
|
+
Glimmer::Config::SAMPLE_DIRECTORIES << File.expand_path('../../../samples/hello', __FILE__)
|
9
|
+
Glimmer::Config::SAMPLE_DIRECTORIES << File.expand_path('../../../samples/elaborate', __FILE__)
|
10
|
+
|
5
11
|
namespace :glimmer do
|
6
12
|
namespace :sample do
|
13
|
+
task :requires do
|
14
|
+
require 'text-table'
|
15
|
+
require 'facets/string/titlecase'
|
16
|
+
require 'facets/string/underscore'
|
17
|
+
|
18
|
+
require_relative 'launcher'
|
19
|
+
end
|
20
|
+
|
21
|
+
task :glimmer_gems do
|
22
|
+
glimmer_cw_gems = Gem.find_latest_files('glimmer-cw-*')
|
23
|
+
glimmer_cs_gems = Gem.find_latest_files('glimmer-cs-*')
|
24
|
+
glimmer_dsl_gems = Gem.find_latest_files('glimmer-dsl-*')
|
25
|
+
glimmer_gem_lib_files = glimmer_cw_gems + glimmer_cs_gems + glimmer_dsl_gems
|
26
|
+
glimmer_gem_lib_files = glimmer_gem_lib_files.map {|file| file.sub(/\.rb$/, '')}.uniq.reject {|file| file.include?('glimmer-cs-gladiator')}
|
27
|
+
glimmer_gem_lib_files.each {|file| require file}
|
28
|
+
end
|
29
|
+
|
7
30
|
desc 'Runs a Glimmer internal sample [included in gem]. If no name is supplied, it runs all samples.'
|
8
|
-
task :run, [:name] => :requires do |t, args|
|
31
|
+
task :run, [:name] => [:requires, :glimmer_gems] do |t, args|
|
9
32
|
name = args[:name]
|
10
33
|
name = name.underscore.downcase unless name.nil?
|
11
|
-
samples =
|
34
|
+
samples = Glimmer::Config::SAMPLE_DIRECTORIES.map {|dir| Dir.glob(File.join(dir, '*.rb'))}.reduce(:+).sort
|
12
35
|
samples = samples.select {|path| path.include?("#{name}.rb")} unless name.nil?
|
13
36
|
Rake::Task['glimmer:sample:code'].invoke(name) if samples.size == 1
|
14
37
|
Glimmer::Launcher.new(samples << '--quiet=false').launch
|
15
38
|
end
|
16
39
|
|
17
|
-
namespace :run do
|
18
|
-
task :hello do
|
19
|
-
samples = Dir.glob(File.expand_path('../../../samples/hello/*.rb', __FILE__)).sort
|
20
|
-
Glimmer::Launcher.new(samples << '--quiet=false').launch
|
21
|
-
end
|
22
|
-
|
23
|
-
task :elaborate do
|
24
|
-
samples = Dir.glob(File.expand_path('../../../samples/elaborate/*.rb', __FILE__)).sort
|
25
|
-
Glimmer::Launcher.new(samples << '--quiet=false').launch
|
26
|
-
end
|
27
|
-
end
|
28
|
-
|
29
40
|
desc 'Lists Glimmer internal samples [included in gem]. Filters by query if specified (query is optional)'
|
30
|
-
task :list, [:query] do |t, args|
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
namespace :list do
|
36
|
-
task :hello, [:query] => :requires do |t, args|
|
37
|
-
array_of_arrays = Dir.glob(File.expand_path('../../../samples/hello/*.rb', __FILE__)).map do |path|
|
41
|
+
task :list, [:query] => [:requires, :glimmer_gems] do |t, args|
|
42
|
+
Glimmer::Config::SAMPLE_DIRECTORIES.each do |dir|
|
43
|
+
sample_group_name = File.basename(dir)
|
44
|
+
human_sample_group_name = sample_group_name.underscore.titlecase
|
45
|
+
array_of_arrays = Dir.glob(File.join(dir, '*.rb')).map do |path|
|
38
46
|
File.basename(path, '.rb')
|
39
47
|
end.select do |path|
|
40
48
|
args[:query].nil? || path.include?(args[:query])
|
41
49
|
end.map do |path|
|
42
50
|
[path, path.underscore.titlecase, "#{'bin/' if Glimmer::Launcher.dev_mode?}glimmer sample:run[#{path}]"]
|
43
51
|
end.sort
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
52
|
+
if array_of_arrays.empty?
|
53
|
+
puts "No Glimmer #{human_sample_group_name} Samples match the query."
|
54
|
+
else
|
55
|
+
puts
|
56
|
+
puts " Glimmer #{human_sample_group_name} Samples:"
|
57
|
+
puts Text::Table.new(
|
58
|
+
:head => %w[Name Description Run],
|
59
|
+
:rows => array_of_arrays,
|
60
|
+
:horizontal_padding => 1,
|
61
|
+
:vertical_boundary => ' ',
|
62
|
+
:horizontal_boundary => ' ',
|
63
|
+
:boundary_intersection => ' '
|
64
|
+
)
|
65
|
+
end
|
54
66
|
end
|
55
|
-
|
56
|
-
task :elaborate, [:query] => :requires do |t, args|
|
57
|
-
array_of_arrays = Dir.glob(File.expand_path('../../../samples/elaborate/*.rb', __FILE__)).map do |path|
|
58
|
-
File.basename(path, '.rb')
|
59
|
-
end.select do |path|
|
60
|
-
args[:query].nil? || path.include?(args[:query])
|
61
|
-
end.map do |path|
|
62
|
-
[path, path.underscore.titlecase, "#{'bin/' if Glimmer::Launcher.dev_mode?}glimmer sample:run[#{path}]"]
|
63
|
-
end.sort
|
64
|
-
puts
|
65
|
-
puts " Glimmer Elaborate Samples (run all via: #{'bin/' if Glimmer::Launcher.dev_mode?}glimmer sample:run:elaborate):"
|
66
|
-
puts Text::Table.new(
|
67
|
-
:head => %w[Name Description Run],
|
68
|
-
:rows => array_of_arrays,
|
69
|
-
:horizontal_padding => 1,
|
70
|
-
:vertical_boundary => ' ',
|
71
|
-
:horizontal_boundary => ' ',
|
72
|
-
:boundary_intersection => ' '
|
73
|
-
)
|
74
|
-
end
|
75
67
|
end
|
76
|
-
|
68
|
+
|
77
69
|
desc 'Outputs code for a Glimmer internal sample [included in gem] (name is required)'
|
78
|
-
task :code, [:name] => :requires do |t, args|
|
79
|
-
|
70
|
+
task :code, [:name] => [:requires, :glimmer_gems] do |t, args|
|
71
|
+
require 'tty-markdown' unless OS.windows?
|
72
|
+
samples = Glimmer::Config::SAMPLE_DIRECTORIES.map {|dir| Dir.glob(File.join(dir, '*.rb'))}.reduce(:+).sort
|
80
73
|
sample = samples.detect {|path| path.include?("#{args[:name].to_s.underscore.downcase}.rb")}
|
81
74
|
sample_additional_files = Dir.glob(File.join(sample.sub('.rb', ''), '**', '*.rb'))
|
82
|
-
([sample] + sample_additional_files).
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
75
|
+
code = ([sample] + sample_additional_files).map do |file|
|
76
|
+
<<~RUBY
|
77
|
+
|
78
|
+
# #{file}
|
79
|
+
|
80
|
+
#{File.read(file)}
|
81
|
+
|
82
|
+
# # #
|
83
|
+
|
84
|
+
RUBY
|
85
|
+
end.join("\n")
|
86
|
+
code = TTY::Markdown.parse("```ruby\n#{code}\n```") unless OS.windows?
|
87
|
+
puts code
|
91
88
|
end
|
92
89
|
|
93
|
-
task :requires do
|
94
|
-
require 'text-table'
|
95
|
-
require 'facets/string/titlecase'
|
96
|
-
require 'facets/string/underscore'
|
97
|
-
|
98
|
-
require_relative 'launcher'
|
99
|
-
end
|
100
|
-
|
101
90
|
end
|
102
91
|
|
103
92
|
namespace :package do
|
@@ -137,7 +126,6 @@ namespace :glimmer do
|
|
137
126
|
Rake::Task['glimmer:package:native'].execute(args)
|
138
127
|
end
|
139
128
|
|
140
|
-
|
141
129
|
desc 'Scaffold Glimmer application directory structure to build a new app'
|
142
130
|
task :scaffold, [:app_name] do |t, args|
|
143
131
|
require_relative 'scaffold'
|
data/lib/glimmer/scaffold.rb
CHANGED
@@ -4,6 +4,8 @@ require 'facets'
|
|
4
4
|
|
5
5
|
# TODO refactor to nest under RakeTask namespace
|
6
6
|
|
7
|
+
MAIN_OBJECT = self
|
8
|
+
|
7
9
|
class Scaffold
|
8
10
|
class << self
|
9
11
|
include FileUtils
|
@@ -179,6 +181,13 @@ class Scaffold
|
|
179
181
|
def custom_shell_gem(custom_shell_name, namespace)
|
180
182
|
gem_name = "glimmer-cs-#{compact_name(custom_shell_name)}"
|
181
183
|
gem_summary = "#{human_name(custom_shell_name)} - Glimmer Custom Shell"
|
184
|
+
begin
|
185
|
+
custom_shell_keyword = dsl_widget_name(custom_shell_name)
|
186
|
+
MAIN_OBJECT.method(custom_shell_keyword)
|
187
|
+
return puts("CustomShell keyword `#{custom_shell_keyword}` is unavailable (occupied by a built-in Ruby method)! Please pick a different name.")
|
188
|
+
rescue NameError
|
189
|
+
# No Op (keyword is not taken by a built in Ruby method)
|
190
|
+
end
|
182
191
|
if namespace
|
183
192
|
gem_name += "-#{compact_name(namespace)}"
|
184
193
|
gem_summary += " (#{human_name(namespace)})"
|
@@ -350,12 +359,19 @@ class Scaffold
|
|
350
359
|
end
|
351
360
|
|
352
361
|
def gem_bin_file(gem_name, custom_shell_name, namespace)
|
362
|
+
# TODO change this so that it does not mix Glimmer unto the main object
|
353
363
|
<<~MULTI_LINE_STRING
|
354
364
|
require_relative '../lib/#{gem_name}'
|
355
365
|
|
356
|
-
|
366
|
+
class #{class_name(custom_shell_name)}App
|
367
|
+
include Glimmer
|
368
|
+
|
369
|
+
def open
|
370
|
+
#{dsl_widget_name(custom_shell_name)}.open
|
371
|
+
end
|
372
|
+
end
|
357
373
|
|
358
|
-
#{
|
374
|
+
#{class_name(custom_shell_name)}App.new.open
|
359
375
|
MULTI_LINE_STRING
|
360
376
|
end
|
361
377
|
|
@@ -394,7 +410,7 @@ class Scaffold
|
|
394
410
|
" -name '#{human_name(custom_shell_name)}'" +
|
395
411
|
" -title '#{human_name(custom_shell_name)}'" +
|
396
412
|
" -Bmac.CFBundleName='#{human_name(custom_shell_name)}'" +
|
397
|
-
" -Bmac.CFBundleIdentifier='org.#{namespace ? compact_name(namespace) : compact_name(custom_shell_name)}.application.#{compact_name(custom_shell_name)}'"
|
413
|
+
" -Bmac.CFBundleIdentifier='org.#{namespace ? compact_name(namespace) : compact_name(custom_shell_name)}.application.#{compact_name(custom_shell_name).capitalize}'"
|
398
414
|
# " -BlicenseType=" +
|
399
415
|
# " -Bmac.category=" +
|
400
416
|
# " -Bmac.signing-key-developer-id-app="
|
@@ -36,7 +36,8 @@ module Glimmer
|
|
36
36
|
class << self
|
37
37
|
def editors
|
38
38
|
@editors ||= {
|
39
|
-
|
39
|
+
# ensure editor can work with string keys not just symbols (leave one string in for testing)
|
40
|
+
'text' => {
|
40
41
|
widget_value_property: :text,
|
41
42
|
editor_gui: lambda do |args, model, property, table_proxy|
|
42
43
|
table_proxy.table_editor.minimumHeight = 20
|
@@ -209,9 +210,19 @@ module Glimmer
|
|
209
210
|
@editor = args
|
210
211
|
end
|
211
212
|
|
213
|
+
def cells_for(model)
|
214
|
+
column_properties.map {|property| model.send(property)}
|
215
|
+
end
|
216
|
+
|
217
|
+
def cells
|
218
|
+
column_count = @table.column_properties.size
|
219
|
+
swt_widget.items.map {|item| column_count.times.map {|i| item.get_text(i)} }
|
220
|
+
end
|
221
|
+
|
212
222
|
def sort
|
213
223
|
return unless sort_property && (sort_type || sort_block || sort_by_block)
|
214
224
|
array = model_binding.evaluate_property
|
225
|
+
array = array.sort_by(&:hash) # this ensures consistent subsequent sorting in case there are equivalent sorts to avoid an infinite loop
|
215
226
|
# Converting value to_s first to handle nil cases. Should work with numeric, boolean, and date fields
|
216
227
|
if sort_block
|
217
228
|
sorted_array = array.sort(&sort_block)
|
@@ -293,6 +304,7 @@ module Glimmer
|
|
293
304
|
end
|
294
305
|
|
295
306
|
def edit_table_item(table_item, column_index, before_write: nil, after_write: nil, after_cancel: nil)
|
307
|
+
require 'facets/hash/symbolize_keys'
|
296
308
|
return if table_item.nil?
|
297
309
|
model = table_item.data
|
298
310
|
property = column_properties[column_index]
|
@@ -304,10 +316,10 @@ module Glimmer
|
|
304
316
|
editor_config = editor_config.to_a
|
305
317
|
editor_widget_options = editor_config.last.is_a?(Hash) ? editor_config.last : {}
|
306
318
|
editor_widget_arg_last_index = editor_config.last.is_a?(Hash) ? -2 : -1
|
307
|
-
editor_widget = editor_config[0] || :text
|
319
|
+
editor_widget = (editor_config[0] || :text).to_sym
|
308
320
|
editor_widget_args = editor_config[1..editor_widget_arg_last_index]
|
309
321
|
model_editing_property = editor_widget_options[:property] || property
|
310
|
-
widget_value_property = TableProxy::editors[editor_widget][:widget_value_property]
|
322
|
+
widget_value_property = TableProxy::editors.symbolize_keys[editor_widget][:widget_value_property]
|
311
323
|
|
312
324
|
@cancel_edit = lambda do |event=nil|
|
313
325
|
@cancel_in_progress = true
|
@@ -344,7 +356,7 @@ module Glimmer
|
|
344
356
|
end
|
345
357
|
|
346
358
|
content {
|
347
|
-
@table_editor_widget_proxy = TableProxy::editors[editor_widget][:editor_gui].call(editor_widget_args, model, model_editing_property, self)
|
359
|
+
@table_editor_widget_proxy = TableProxy::editors.symbolize_keys[editor_widget][:editor_gui].call(editor_widget_args, model, model_editing_property, self)
|
348
360
|
}
|
349
361
|
@table_editor.setEditor(@table_editor_widget_proxy.swt_widget, table_item, column_index)
|
350
362
|
rescue => e
|
@@ -25,6 +25,7 @@ module Glimmer
|
|
25
25
|
"arrow" => [:arrow],
|
26
26
|
"button" => [:push],
|
27
27
|
"checkbox" => [:check],
|
28
|
+
"check" => [:check],
|
28
29
|
"drag_source" => [:drop_copy],
|
29
30
|
"drop_target" => [:drop_copy],
|
30
31
|
"list" => [:border, :v_scroll],
|
@@ -41,21 +42,17 @@ module Glimmer
|
|
41
42
|
|
42
43
|
DEFAULT_INITIALIZERS = {
|
43
44
|
"composite" => lambda do |composite|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
45
|
+
if composite.get_layout.nil?
|
46
|
+
layout = GridLayout.new
|
47
|
+
layout.marginWidth = 15
|
48
|
+
layout.marginHeight = 15
|
49
|
+
composite.layout = layout
|
50
|
+
end
|
48
51
|
end,
|
49
52
|
"scrolled_composite" => lambda do |scrolled_composite|
|
50
53
|
scrolled_composite.expand_horizontal = true
|
51
54
|
scrolled_composite.expand_vertical = true
|
52
55
|
end,
|
53
|
-
"shell" => lambda do |shell|
|
54
|
-
layout = FillLayout.new
|
55
|
-
layout.marginWidth = 15
|
56
|
-
layout.marginHeight = 15
|
57
|
-
shell.layout = layout
|
58
|
-
end,
|
59
56
|
"table" => lambda do |table|
|
60
57
|
table.setHeaderVisible(true)
|
61
58
|
table.setLinesVisible(true)
|
@@ -64,17 +61,35 @@ module Glimmer
|
|
64
61
|
table_column.setWidth(80)
|
65
62
|
end,
|
66
63
|
"group" => lambda do |group|
|
67
|
-
group.
|
64
|
+
group.layout = GridLayout.new if group.get_layout.nil?
|
68
65
|
end,
|
69
66
|
}
|
70
67
|
|
68
|
+
KEYWORD_ALIASES = {
|
69
|
+
'radio' => 'button',
|
70
|
+
'checkbox' => 'button',
|
71
|
+
'check' => 'button',
|
72
|
+
'toggle' => 'button',
|
73
|
+
'arrow' => 'button',
|
74
|
+
}
|
75
|
+
|
71
76
|
class << self
|
72
|
-
|
73
|
-
|
77
|
+
# Instantiates the right WidgetProxy subclass for passed in keyword
|
78
|
+
# Args are: keyword, parent, swt_widget_args (including styles)
|
79
|
+
def create(*init_args, swt_widget: nil)
|
80
|
+
return swt_widget.get_data('proxy') if swt_widget&.get_data('proxy')
|
81
|
+
keyword, parent, args = init_args
|
82
|
+
selected_widget_proxy_class = widget_proxy_class(keyword || underscored_widget_name(swt_widget))
|
83
|
+
if init_args.empty?
|
84
|
+
selected_widget_proxy_class.new(swt_widget: swt_widget)
|
85
|
+
else
|
86
|
+
selected_widget_proxy_class.new(*init_args)
|
87
|
+
end
|
74
88
|
end
|
75
89
|
|
76
90
|
def widget_proxy_class(keyword)
|
77
91
|
begin
|
92
|
+
keyword = KEYWORD_ALIASES[keyword] if KEYWORD_ALIASES[keyword]
|
78
93
|
class_name = "#{keyword.camelcase(:upper)}Proxy".to_sym
|
79
94
|
Glimmer::SWT.const_get(class_name)
|
80
95
|
rescue
|
@@ -88,11 +103,16 @@ module Glimmer
|
|
88
103
|
end
|
89
104
|
|
90
105
|
attr_reader :parent_proxy, :swt_widget, :drag_source_proxy, :drop_target_proxy, :drag_source_style, :drag_source_transfer, :drop_target_transfer
|
91
|
-
|
106
|
+
|
92
107
|
# Initializes a new SWT Widget
|
93
108
|
#
|
109
|
+
# It is preferred to use `::create` method instead since it instantiates the
|
110
|
+
# right subclass per widget keyword
|
111
|
+
#
|
112
|
+
# keyword, parent, swt_widget_args (including styles)
|
113
|
+
#
|
94
114
|
# Styles is a comma separate list of symbols representing SWT styles in lower case
|
95
|
-
def initialize(*init_args, swt_widget: nil)
|
115
|
+
def initialize(*init_args, swt_widget: nil)
|
96
116
|
if swt_widget.nil?
|
97
117
|
underscored_widget_name, parent, args = init_args
|
98
118
|
@parent_proxy = parent
|
@@ -103,11 +123,14 @@ module Glimmer
|
|
103
123
|
@swt_widget = swt_widget
|
104
124
|
underscored_widget_name = self.class.underscored_widget_name(@swt_widget)
|
105
125
|
parent_proxy_class = self.class.widget_proxy_class(self.class.underscored_widget_name(@swt_widget.parent))
|
106
|
-
|
126
|
+
parent = swt_widget.parent
|
127
|
+
@parent_proxy = parent.get_data('proxy') || parent_proxy_class.new(swt_widget: parent)
|
128
|
+
end
|
129
|
+
if @swt_widget&.get_data('proxy').nil?
|
130
|
+
@swt_widget.set_data('proxy', self)
|
131
|
+
DEFAULT_INITIALIZERS[underscored_widget_name]&.call(@swt_widget)
|
132
|
+
@parent_proxy.post_initialize_child(self)
|
107
133
|
end
|
108
|
-
@swt_widget.set_data('proxy', self)
|
109
|
-
DEFAULT_INITIALIZERS[underscored_widget_name]&.call(@swt_widget)
|
110
|
-
@parent_proxy.post_initialize_child(self)
|
111
134
|
end
|
112
135
|
|
113
136
|
# Subclasses may override to perform post initialization work on an added child
|
@@ -315,7 +338,7 @@ module Glimmer
|
|
315
338
|
|
316
339
|
# This supports widgets in and out of basic SWT
|
317
340
|
def self.swt_widget_class_for(underscored_widget_name)
|
318
|
-
underscored_widget_name =
|
341
|
+
underscored_widget_name = KEYWORD_ALIASES[underscored_widget_name] if KEYWORD_ALIASES[underscored_widget_name]
|
319
342
|
swt_widget_name = underscored_widget_name.camelcase(:upper)
|
320
343
|
swt_widget_class = eval(swt_widget_name)
|
321
344
|
unless swt_widget_class.ancestors.include?(org.eclipse.swt.widgets.Widget)
|
@@ -342,11 +365,7 @@ module Glimmer
|
|
342
365
|
end
|
343
366
|
|
344
367
|
def has_style?(style)
|
345
|
-
|
346
|
-
comparison = SWTProxy[style]
|
347
|
-
rescue
|
348
|
-
comparison = DNDProxy[style]
|
349
|
-
end
|
368
|
+
comparison = interpret_style(style)
|
350
369
|
(@swt_widget.style & comparison) == comparison
|
351
370
|
end
|
352
371
|
|
@@ -457,6 +476,7 @@ module Glimmer
|
|
457
476
|
rescue => e
|
458
477
|
Glimmer::Config.logger.debug {"Neither WidgetProxy nor #{swt_widget.class.name} can handle the method ##{method}"}
|
459
478
|
super
|
479
|
+
# TODO consider get_attribute too
|
460
480
|
end
|
461
481
|
|
462
482
|
def respond_to?(method, *args, &block)
|
@@ -468,21 +488,17 @@ module Glimmer
|
|
468
488
|
private
|
469
489
|
|
470
490
|
def style(underscored_widget_name, styles)
|
471
|
-
styles = [styles].flatten.compact
|
472
|
-
if styles.empty?
|
473
|
-
|
474
|
-
|
475
|
-
|
476
|
-
|
477
|
-
|
478
|
-
DNDProxy[*styles]
|
479
|
-
end
|
480
|
-
end
|
491
|
+
styles = [styles].flatten.compact
|
492
|
+
styles = default_style(underscored_widget_name) if styles.empty?
|
493
|
+
interpret_style(*styles)
|
494
|
+
end
|
495
|
+
|
496
|
+
def interpret_style(*styles)
|
497
|
+
SWTProxy[*styles] rescue DNDProxy[*styles]
|
481
498
|
end
|
482
499
|
|
483
500
|
def default_style(underscored_widget_name)
|
484
|
-
|
485
|
-
SWTProxy[styles] rescue DNDProxy[styles]
|
501
|
+
DEFAULT_STYLES[underscored_widget_name] || [:none]
|
486
502
|
end
|
487
503
|
|
488
504
|
def ruby_attribute_setter(attribute_name)
|
@@ -0,0 +1,55 @@
|
|
1
|
+
include Glimmer
|
2
|
+
|
3
|
+
shell {
|
4
|
+
text "User Profile"
|
5
|
+
|
6
|
+
composite {
|
7
|
+
grid_layout 2, false
|
8
|
+
|
9
|
+
group {
|
10
|
+
text "Name"
|
11
|
+
grid_layout 2, false
|
12
|
+
layout_data :fill, :fill, true, true
|
13
|
+
label {text "First"}; text {text "Bullet"}
|
14
|
+
label {text "Last"}; text {text "Tooth"}
|
15
|
+
}
|
16
|
+
|
17
|
+
group {
|
18
|
+
layout_data :fill, :fill, true, true
|
19
|
+
text "Gender"
|
20
|
+
radio {text "Male"; selection true}
|
21
|
+
radio {text "Female"}
|
22
|
+
}
|
23
|
+
|
24
|
+
group {
|
25
|
+
layout_data :fill, :fill, true, true
|
26
|
+
text "Role"
|
27
|
+
check {text "Student"; selection true}
|
28
|
+
check {text "Employee"; selection true}
|
29
|
+
}
|
30
|
+
|
31
|
+
group {
|
32
|
+
text "Experience"
|
33
|
+
row_layout
|
34
|
+
layout_data :fill, :fill, true, true
|
35
|
+
spinner {selection 5}; label {text "years"}
|
36
|
+
}
|
37
|
+
|
38
|
+
button {
|
39
|
+
text "save"
|
40
|
+
layout_data :right, :center, true, true
|
41
|
+
on_widget_selected {
|
42
|
+
message_box {
|
43
|
+
text 'Profile Saved!'
|
44
|
+
message 'User profile has been saved!'
|
45
|
+
}.open
|
46
|
+
}
|
47
|
+
}
|
48
|
+
|
49
|
+
button {
|
50
|
+
text "close"
|
51
|
+
layout_data :left, :center, true, true
|
52
|
+
on_widget_selected { exit(0) }
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}.open
|
metadata
CHANGED
@@ -1,21 +1,21 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: glimmer-dsl-swt
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.6.
|
4
|
+
version: 0.6.9
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- AndyMaleh
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-09-
|
11
|
+
date: 2020-09-17 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
requirement: !ruby/object:Gem::Requirement
|
15
15
|
requirements:
|
16
16
|
- - "~>"
|
17
17
|
- !ruby/object:Gem::Version
|
18
|
-
version: 0.10.
|
18
|
+
version: 0.10.4
|
19
19
|
name: glimmer
|
20
20
|
type: :runtime
|
21
21
|
prerelease: false
|
@@ -23,7 +23,7 @@ dependencies:
|
|
23
23
|
requirements:
|
24
24
|
- - "~>"
|
25
25
|
- !ruby/object:Gem::Version
|
26
|
-
version: 0.10.
|
26
|
+
version: 0.10.4
|
27
27
|
- !ruby/object:Gem::Dependency
|
28
28
|
requirement: !ruby/object:Gem::Requirement
|
29
29
|
requirements:
|
@@ -57,7 +57,7 @@ dependencies:
|
|
57
57
|
requirements:
|
58
58
|
- - "~>"
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version: 0.10.
|
60
|
+
version: 0.10.1
|
61
61
|
name: puts_debuggerer
|
62
62
|
type: :runtime
|
63
63
|
prerelease: false
|
@@ -65,7 +65,21 @@ dependencies:
|
|
65
65
|
requirements:
|
66
66
|
- - "~>"
|
67
67
|
- !ruby/object:Gem::Version
|
68
|
-
version: 0.10.
|
68
|
+
version: 0.10.1
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
71
|
+
requirements:
|
72
|
+
- - ">="
|
73
|
+
- !ruby/object:Gem::Version
|
74
|
+
version: 0.2.1
|
75
|
+
name: rake-tui
|
76
|
+
type: :runtime
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.2.1
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
requirement: !ruby/object:Gem::Requirement
|
71
85
|
requirements:
|
@@ -200,6 +214,26 @@ dependencies:
|
|
200
214
|
- - "<"
|
201
215
|
- !ruby/object:Gem::Version
|
202
216
|
version: 2.0.0
|
217
|
+
- !ruby/object:Gem::Dependency
|
218
|
+
requirement: !ruby/object:Gem::Requirement
|
219
|
+
requirements:
|
220
|
+
- - ">="
|
221
|
+
- !ruby/object:Gem::Version
|
222
|
+
version: 0.7.0
|
223
|
+
- - "<"
|
224
|
+
- !ruby/object:Gem::Version
|
225
|
+
version: 2.0.0
|
226
|
+
name: tty-markdown
|
227
|
+
type: :runtime
|
228
|
+
prerelease: false
|
229
|
+
version_requirements: !ruby/object:Gem::Requirement
|
230
|
+
requirements:
|
231
|
+
- - ">="
|
232
|
+
- !ruby/object:Gem::Version
|
233
|
+
version: 0.7.0
|
234
|
+
- - "<"
|
235
|
+
- !ruby/object:Gem::Version
|
236
|
+
version: 2.0.0
|
203
237
|
- !ruby/object:Gem::Dependency
|
204
238
|
requirement: !ruby/object:Gem::Requirement
|
205
239
|
requirements:
|
@@ -290,7 +324,7 @@ dependencies:
|
|
290
324
|
- - "~>"
|
291
325
|
- !ruby/object:Gem::Version
|
292
326
|
version: 0.7.0
|
293
|
-
description: Glimmer DSL for SWT (Desktop GUI)
|
327
|
+
description: Glimmer DSL for SWT (JRuby Desktop GUI)
|
294
328
|
email: andy.am@gmail.com
|
295
329
|
executables:
|
296
330
|
- glimmer
|
@@ -392,6 +426,7 @@ files:
|
|
392
426
|
- samples/elaborate/tic_tac_toe.rb
|
393
427
|
- samples/elaborate/tic_tac_toe/board.rb
|
394
428
|
- samples/elaborate/tic_tac_toe/cell.rb
|
429
|
+
- samples/elaborate/user_profile.rb
|
395
430
|
- samples/hello/hello_browser.rb
|
396
431
|
- samples/hello/hello_combo.rb
|
397
432
|
- samples/hello/hello_computed.rb
|