glimmer-dsl-swt 0.6.4 → 0.6.9

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: 82c0437f480a9bfc7064ec9cf10bc196a3bbb644d8fe20832c02eda79565435a
4
- data.tar.gz: 418e810fad2c7f12280b78848931c743d619a8cc28f04f7a438092de9fed12e7
3
+ metadata.gz: f8cb96b5eda19eb65af0d9fa5b8f79050a341f5f148e78c13a27b18c07cef083
4
+ data.tar.gz: 6e925dab92f1ea52557c2f9078a1c7b0b0068225644da25ce81677e6d4b9fca4
5
5
  SHA512:
6
- metadata.gz: dadb4107a2480af548a5e1f79f60b44a798e0ae2aa130e14dae4e1878d7211418c53ab88be39cb8adcfe42a1fc3846b46e06f5e90dccb984299896eef90f15a9
7
- data.tar.gz: f902727a93b33a3aa0f013484b44f648fc2f991766f612ebb4e093c932389032417f8fe038de17609f7a28e3324d158419a1e502d07cd822b104658a7b4fb33c
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.4 (Desktop GUI)
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
  [![Gem Version](https://badge.fury.io/rb/glimmer-dsl-swt.svg)](http://badge.fury.io/rb/glimmer-dsl-swt)
3
3
  [![Travis CI](https://travis-ci.com/AndyObtiva/glimmer-dsl-swt.svg?branch=master)](https://travis-ci.com/github/AndyObtiva/glimmer-dsl-swt)
4
4
  [![Coverage Status](https://coveralls.io/repos/github/AndyObtiva/glimmer-dsl-swt/badge.svg?branch=master)](https://coveralls.io/github/AndyObtiva/glimmer-dsl-swt?branch=master)
5
5
  [![Maintainability](https://api.codeclimate.com/v1/badges/aaf1cba142dd351f84bd/maintainability)](https://codeclimate.com/github/AndyObtiva/glimmer-dsl-swt/maintainability)
6
6
  [![Join the chat at https://gitter.im/AndyObtiva/glimmer](https://badges.gitter.im/AndyObtiva/glimmer.svg)](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.4
1
+ 0.6.9
@@ -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
@@ -2,15 +2,11 @@ $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
2
2
 
3
3
  # External requires
4
4
  require 'java'
5
- if ENV['BUNDLER_REQUIRE'].to_s.downcase == 'true'
6
- require 'bundler'
7
- Bundler.require
8
- else
9
- require 'glimmer'
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, &block)
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
@@ -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
- TEXT_USAGE_PREFIX = <<~MULTI_LINE_STRING
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/tasks.
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
- Example: glimmer samples/hello_world.rb
24
+ Tasks are run via rake. Some tasks take arguments in square brackets.
35
25
 
36
- This runs the Glimmer application samples/hello_world.rb
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
- rakefile_dir = File.exist?('Rakefile') ? '.' : File.dirname(__FILE__)
184
- FileUtils.cd(rakefile_dir) do
185
- rake_tasks = `rake -T`.gsub('rake glimmer:', 'glimmer ').split("\n").select {|l| l.start_with?('glimmer ')}
186
- puts TEXT_USAGE_PREFIX
187
- puts rake_tasks.join("\n")
188
- puts TEXT_USAGE_SUFFIX
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|
@@ -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 = (Dir.glob(File.expand_path('../../../samples/hello/*.rb', __FILE__)) + Dir.glob(File.expand_path('../../../samples/elaborate/*.rb', __FILE__))).sort
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
- Rake::Task['glimmer:sample:list:hello'].invoke(args[:query])
32
- Rake::Task['glimmer:sample:list:elaborate'].invoke(args[:query])
33
- end
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
- puts
45
- puts " Glimmer Hello Samples (run all via: #{'bin/' if Glimmer::Launcher.dev_mode?}glimmer sample:run:hello):"
46
- puts Text::Table.new(
47
- :head => %w[Name Description Run],
48
- :rows => array_of_arrays,
49
- :horizontal_padding => 1,
50
- :vertical_boundary => ' ',
51
- :horizontal_boundary => ' ',
52
- :boundary_intersection => ' '
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
- samples = (Dir.glob(File.expand_path('../../../samples/hello/*.rb', __FILE__)) + Dir.glob(File.expand_path('../../../samples/elaborate/*.rb', __FILE__))).sort
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).each do |file|
83
- puts
84
- puts "# #{file}"
85
- puts
86
- puts File.read(file)
87
- puts
88
- puts '# # #'
89
- puts
90
- end
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'
@@ -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
- include Glimmer
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
- #{dsl_widget_name(custom_shell_name)}.open
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="
@@ -1,7 +1,6 @@
1
1
  require 'glimmer/swt/swt_proxy'
2
2
  require 'glimmer/swt/widget_proxy'
3
3
  require 'glimmer/swt/display_proxy'
4
- require 'glimmer/swt/swt_proxy'
5
4
 
6
5
  module Glimmer
7
6
  module SWT
@@ -18,6 +18,7 @@ module Glimmer
18
18
  end
19
19
 
20
20
  def constant_value_none
21
+ # TODO instead of raising error try a convention instead like CLASSNAME::NONE by default
21
22
  raise 'Not implemented! Mixer must implement!'
22
23
  end
23
24
 
@@ -36,7 +36,8 @@ module Glimmer
36
36
  class << self
37
37
  def editors
38
38
  @editors ||= {
39
- text: {
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
- layout = GridLayout.new
45
- layout.marginWidth = 15
46
- layout.marginHeight = 15
47
- composite.layout = layout
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.setLayout(GridLayout.new)
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
- def create(keyword, parent, args)
73
- widget_proxy_class(keyword).new(keyword, parent, args)
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
- @parent_proxy = parent_proxy_class.new(swt_widget: swt_widget.parent)
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 = 'button' if %w[radio checkbox toggle arrow].include?(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
- begin
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
- default_style(underscored_widget_name)
474
- else
475
- begin
476
- SWTProxy[*styles]
477
- rescue
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
- styles = DEFAULT_STYLES[underscored_widget_name] || [:none]
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
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-02 00:00:00.000000000 Z
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.3
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.3
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.0
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.0
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) - JRuby on SWT
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