glimmer-dsl-swt 0.1.3 → 0.2.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 3b097c051f15a0fd1a52677fd65d542a67532a2e1a51fc928fc22acd8e729953
4
- data.tar.gz: 203b4cd8bad18d912e83067fce0175e5667f7db503cfa67bf9beac6e72752508
3
+ metadata.gz: e33ae73c95946ba7fce0d3dc221cee2ca817968a03bbfe678ff9e0ecfbaf5a65
4
+ data.tar.gz: c95f41b789e3dee67c94dbf79d6e8367d5ad7a1fb94749e784a8c3b13ef8a4aa
5
5
  SHA512:
6
- metadata.gz: edb0568d6bcf252b89332050f2de545917bb6ce2bd687dae961e1aa1afb66d9a051420ea00745db028a93d3869ab5ca9229192d806daa3e0db652a5fffdc1df5
7
- data.tar.gz: 745dae7d8a1999c0267b4d4e7a66a37209bb59c29e4c0f9c7ccf31dc87b2bcd0903eef7c2a0bc6cb46a498200468ce9bcb28d1b5752b54a5a0340be350793e0e
6
+ metadata.gz: c4784a352196f496c4fce136da828352c9c92c2f7092e917f9c47a403bd91964566a2d493680b35f13d240a87dd37830153f3a37ea050ea0d84aa8b02071cfdc
7
+ data.tar.gz: 9080d1bdc15f375db58fa8719d5c6fb8d2017313fe52ea7e2ad7b4dd042f47daa8bf87edecffa819c6e1596839af619f989335839fa757dd2e645ce6c6e13fdb
data/README.md CHANGED
@@ -1,10 +1,12 @@
1
- # <img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 /> Glimmer DSL for SWT 0.1.3 (Desktop GUI)
1
+ # <img src="https://raw.githubusercontent.com/AndyObtiva/glimmer/master/images/glimmer-logo-hi-res.png" height=85 /> Glimmer DSL for SWT 0.2.4 (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
  [![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)
6
6
 
7
- [Glimmer](https://github.com/AndyObtiva/glimmer) DSL for SWT enables desktop development with Glimmer.
7
+ [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
+
9
+ [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.
8
10
 
9
11
  You may find full setup/usage instructions at the main [Glimmer project page](https://github.com/AndyObtiva/glimmer).
10
12
 
@@ -13,6 +15,23 @@ Other Glimmer DSL gems:
13
15
  - [glimmer-dsl-xml](https://github.com/AndyObtiva/glimmer-dsl-xml): Glimmer DSL for XML (& HTML)
14
16
  - [glimmer-dsl-css](https://github.com/AndyObtiva/glimmer-dsl-css): Glimmer DSL for CSS (Cascading Style Sheets)
15
17
 
18
+ ## Example
19
+
20
+ ```ruby
21
+ include Glimmer
22
+
23
+ shell {
24
+ text 'Glimmer'
25
+ label {
26
+ text 'Hello, World!'
27
+ }
28
+ }.open
29
+ ```
30
+
31
+ ![Glimmer DSL for SWT Hello World](https://github.com/AndyObtiva/glimmer/blob/master/images/glimmer-hello-world.png)
32
+
33
+ Learn more at the main [Glimmer project page](https://github.com/AndyObtiva/glimmer).
34
+
16
35
  ## Help
17
36
 
18
37
  ### Issues
@@ -1 +1 @@
1
- jruby-9.2.11.1
1
+ jruby-9.2.12.0
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.1.3
1
+ 0.2.4
@@ -3,11 +3,18 @@ require 'glimmer/swt/packages'
3
3
  module Glimmer
4
4
  class << self
5
5
  def included(klass)
6
+ if Object.const_defined?(:ActiveSupport) && ActiveSupport.const_defined?(:Dependencies)
7
+ begin
8
+ ActiveSupport::Dependencies.unhook!
9
+ rescue => e
10
+ # noop TODO support logging unimportant details below debug level
11
+ end
12
+ end
6
13
  if Config.import_swt_packages
7
14
  klass.include(SWT::Packages)
8
15
  klass.extend(SWT::Packages)
9
- klass.extend(Glimmer)
10
16
  end
17
+ klass.extend(Glimmer)
11
18
  end
12
19
  end
13
20
  end
@@ -1,16 +1,24 @@
1
1
  module Glimmer
2
2
  module Config
3
+ DEFAULT_IMPORT_SWT_PACKAGES = [
4
+ 'org.eclipse.swt',
5
+ 'org.eclipse.swt.widgets',
6
+ 'org.eclipse.swt.layout',
7
+ 'org.eclipse.swt.graphics',
8
+ 'org.eclipse.swt.browser',
9
+ 'org.eclipse.swt.custom',
10
+ 'org.eclipse.swt.dnd',
11
+ ]
12
+
3
13
  class << self
4
14
  # Tells Glimmer to import SWT packages into including class (default: true)
5
15
  def import_swt_packages=(value)
6
- @@import_swt_packages = !!value
16
+ @@import_swt_packages = value
7
17
  end
8
18
 
9
19
  # Returns whether Glimmer will import SWT packages into including class
10
20
  def import_swt_packages
11
- unless defined? @@import_swt_packages
12
- @@import_swt_packages = true
13
- end
21
+ @@import_swt_packages = DEFAULT_IMPORT_SWT_PACKAGES if !defined?(@@import_swt_packages) || (defined?(@@import_swt_packages) && @@import_swt_packages == true)
14
22
  @@import_swt_packages
15
23
  end
16
24
  end
@@ -2,9 +2,14 @@ $LOAD_PATH.unshift(File.expand_path('..', __FILE__))
2
2
 
3
3
  # External requires
4
4
  require 'java'
5
- require 'nested_inherited_jruby_include_package'
6
- require 'super_module'
7
- require 'glimmer'
5
+ if ENV['BUNDLER_REQUIRE'].to_s.downcase == 'true'
6
+ require 'bundler'
7
+ Bundler.require
8
+ else
9
+ require 'nested_inherited_jruby_include_package'
10
+ require 'super_module'
11
+ require 'glimmer'
12
+ end
8
13
 
9
14
  # Internal requires
10
15
  require 'ext/glimmer/config'
@@ -15,6 +15,7 @@ module Glimmer
15
15
  def initialize(parent, model_binding, column_properties)
16
16
  @table = parent
17
17
  @model_binding = model_binding
18
+ @table.swt_widget.data = @model_binding
18
19
  @column_properties = column_properties
19
20
  if @table.respond_to?(:column_properties=)
20
21
  @table.column_properties = @column_properties
@@ -22,14 +23,14 @@ module Glimmer
22
23
  @table.body_root.column_properties = @column_properties
23
24
  end
24
25
  call(@model_binding.evaluate_property)
25
- model = model_binding.base_model
26
- observe(model, model_binding.property_name_expression)
26
+ observe(model_binding)
27
27
  @table.on_widget_disposed do |dispose_event|
28
28
  unregister_all_observables
29
29
  end
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
34
  if new_model_collection and new_model_collection.is_a?(Array)
34
35
  observe(new_model_collection, @column_properties)
35
36
  @model_collection = new_model_collection
@@ -0,0 +1,20 @@
1
+ require 'glimmer/dsl/expression'
2
+
3
+ module Glimmer
4
+ module DSL
5
+ module SWT
6
+ class BlockPropertyExpression < Expression
7
+ def can_interpret?(parent, keyword, *args, &block)
8
+ block_given? and
9
+ args.size == 0 and
10
+ parent.respond_to?("#{keyword}_block=")
11
+ end
12
+
13
+ def interpret(parent, keyword, *args, &block)
14
+ parent.send("#{keyword}_block=", block)
15
+ nil
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
@@ -35,6 +35,10 @@ module Glimmer
35
35
  parent.on_widget_selected do
36
36
  model_binding.call(widget_binding.evaluate_property)
37
37
  end
38
+
39
+ parent.on_modify_text do
40
+ model_binding.call(widget_binding.evaluate_property)
41
+ end
38
42
  end
39
43
  end
40
44
  end
@@ -0,0 +1,25 @@
1
+ require 'glimmer/dsl/static_expression'
2
+ require 'glimmer/swt/dnd_proxy'
3
+
4
+ # TODO consider turning static keywords like bind into methods
5
+
6
+ module Glimmer
7
+ module DSL
8
+ module SWT
9
+ # Responsible for returning DND constant values
10
+ #
11
+ # Named DndExpression (not DNDExpression) so that the DSL engine
12
+ # discovers quickly by convention
13
+ class DndExpression < StaticExpression
14
+ def can_interpret?(parent, keyword, *args, &block)
15
+ block.nil? &&
16
+ args.size > 0
17
+ end
18
+
19
+ def interpret(parent, keyword, *args, &block)
20
+ Glimmer::SWT::DNDProxy[*args]
21
+ end
22
+ end
23
+ end
24
+ end
25
+ end
@@ -25,6 +25,7 @@ module Glimmer
25
25
  table_items_data_binding
26
26
  data_binding
27
27
  property
28
+ block_property
28
29
  widget
29
30
  custom_widget
30
31
  ]
@@ -14,10 +14,6 @@ module Glimmer
14
14
 
15
15
  include_package 'org.eclipse.swt.widgets'
16
16
 
17
- def can_interpret?(parent, keyword, *args, &block)
18
- keyword == 'message_box'
19
- end
20
-
21
17
  def interpret(parent, keyword, *args, &block)
22
18
  potential_parent = args.first
23
19
  parent = args.shift if potential_parent.is_a?(Shell) || (potential_parent.respond_to?(:swt_widget) && potential_parent.swt_widget.is_a?(Shell))
@@ -31,5 +31,7 @@ module Glimmer
31
31
  end
32
32
 
33
33
  require 'glimmer/swt/widget_proxy'
34
+ require 'glimmer/swt/scrolled_composite_proxy'
34
35
  require 'glimmer/swt/tree_proxy'
35
36
  require 'glimmer/swt/table_proxy'
37
+ require 'glimmer/swt/table_column_proxy'
@@ -7,6 +7,12 @@ module Glimmer
7
7
  class << self
8
8
  attr_accessor :javapackager_extra_args
9
9
 
10
+ def clean
11
+ require 'fileutils'
12
+ FileUtils.rm_rf('dist')
13
+ FileUtils.rm_rf('packages')
14
+ end
15
+
10
16
  def config
11
17
  project_name = File.basename(File.expand_path('.'))
12
18
  if !File.exists?('config/warble.rb')
@@ -15,7 +21,7 @@ module Glimmer
15
21
  system('warble config')
16
22
  new_config = File.read('config/warble.rb').split("\n").inject('') do |output, line|
17
23
  if line.include?('config.dirs =')
18
- line = line.sub('# ', '').sub(/=[^=\n]+$/, '= %w(app config db lib script bin docs fonts icons images sounds videos)')
24
+ line = line.sub('# ', '').sub(/=[^=\n]+$/, '= %w(app config db lib script bin docs fonts icons images sounds videos vendor)')
19
25
  end
20
26
  if line.include?('config.includes =')
21
27
  line = line.sub('# ', '').sub(/=[^=\n]+$/, "= FileList['LICENSE.txt', 'VERSION']")
@@ -4,6 +4,11 @@ require_relative 'package'
4
4
 
5
5
  namespace :glimmer do
6
6
  namespace :package do
7
+ desc 'Clean by removing "dist" and "packages" directories'
8
+ task :clean do
9
+ Glimmer::Package.clean
10
+ end
11
+
7
12
  desc 'Generate JAR config file'
8
13
  task :config do
9
14
  Glimmer::Package.config
@@ -58,7 +58,7 @@ class Scaffold
58
58
 
59
59
  # for a library or gem, you might want to ignore these files since the code is
60
60
  # intended to run in multiple environments; otherwise, check them in:
61
- Gemfile.lock
61
+ # Gemfile.lock
62
62
  # .ruby-version
63
63
  # .ruby-gemset
64
64
 
@@ -179,6 +179,7 @@ class Scaffold
179
179
  end
180
180
 
181
181
  def custom_shell_gem(custom_shell_name, namespace)
182
+ return puts('Namespace is required! Usage: glimmer scaffold:custom_shell_gem[custom_shell_name,namespace]') unless `git config --get github.user`.to_s.strip == 'AndyObtiva'
182
183
  gem_name = "glimmer-cs-#{compact_name(custom_shell_name)}"
183
184
  gem_summary = "#{human_name(custom_shell_name)} - Glimmer Custom Shell"
184
185
  if namespace
@@ -218,6 +219,7 @@ class Scaffold
218
219
  end
219
220
 
220
221
  def custom_widget_gem(custom_widget_name, namespace)
222
+ return puts('Namespace is required! Usage: glimmer scaffold:custom_widget_gem[custom_widget_name,namespace]') unless `git config --get github.user`.to_s.strip == 'AndyObtiva'
221
223
  gem_name = "glimmer-cw-#{compact_name(custom_widget_name)}"
222
224
  gem_summary = "#{human_name(custom_widget_name)} - Glimmer Custom Widget"
223
225
  if namespace
@@ -1,14 +1,16 @@
1
+ require 'ext/glimmer/config'
2
+
1
3
  module Glimmer
2
4
  module SWT
3
5
  # This contains Java imports of SWT Java packages
4
6
  module Packages
5
- include_package 'org.eclipse.swt'
6
- include_package 'org.eclipse.swt.widgets'
7
- include_package 'org.eclipse.swt.layout'
8
- include_package 'org.eclipse.swt.graphics'
9
- include_package 'org.eclipse.swt.browser'
10
- include_package 'org.eclipse.swt.custom'
11
- include_package 'org.eclipse.swt.dnd'
7
+ class << self
8
+ def included(klass)
9
+ Glimmer::Config.import_swt_packages.to_a.each do |package|
10
+ include_package(package) if package.is_a?(String)
11
+ end
12
+ end
13
+ end
12
14
  end
13
15
  end
14
16
  end
@@ -0,0 +1,21 @@
1
+ require 'glimmer/swt/widget_proxy'
2
+
3
+ module Glimmer
4
+ module SWT
5
+ class ScrolledCompositeProxy < Glimmer::SWT::WidgetProxy
6
+ def initialize(underscored_widget_name, parent, args)
7
+ unless args.first.is_a?(Numeric)
8
+ args.unshift(:h_scroll)
9
+ args.unshift(:v_scroll)
10
+ end
11
+ super
12
+ swt_widget.expand_horizontal = true
13
+ swt_widget.expand_vertical = true
14
+ end
15
+
16
+ def post_initialize_child(child)
17
+ swt_widget.content = child.swt_widget
18
+ end
19
+ end
20
+ end
21
+ end
@@ -31,7 +31,8 @@ module Glimmer
31
31
  end
32
32
 
33
33
  EXTRA_STYLES = {
34
- NO_RESIZE: self[:shell_trim, :resize!, :max!]
34
+ NO_RESIZE: self[:shell_trim, :resize!, :max!],
35
+ NO_SORT: -7,
35
36
  }
36
37
  end
37
38
  end
@@ -0,0 +1,24 @@
1
+ require 'glimmer/swt/widget_proxy'
2
+
3
+ module Glimmer
4
+ module SWT
5
+ class TableColumnProxy < Glimmer::SWT::WidgetProxy
6
+ attr_reader :no_sort, :sort_property
7
+ alias no_sort? no_sort
8
+ attr_accessor :sort_block, :sort_by_block
9
+
10
+ def initialize(underscored_widget_name, parent, args)
11
+ @no_sort = args.delete(:no_sort)
12
+ super
13
+ on_widget_selected do |event|
14
+ parent.sort_by_column(self)
15
+ end unless no_sort?
16
+ end
17
+
18
+ def sort_property=(args)
19
+ @sort_property = args.to_a.first
20
+ end
21
+
22
+ end
23
+ end
24
+ end
@@ -33,7 +33,7 @@ module Glimmer
33
33
  end
34
34
  end
35
35
 
36
- attr_reader :table_editor, :table_editor_text_proxy
36
+ attr_reader :table_editor, :table_editor_text_proxy, :sort_property, :sort_direction, :sort_block, :sort_type, :sort_by_block
37
37
  attr_accessor :column_properties
38
38
 
39
39
  def initialize(underscored_widget_name, parent, args)
@@ -43,7 +43,70 @@ module Glimmer
43
43
  @table_editor.grabHorizontal = true
44
44
  @table_editor.minimumHeight = 20
45
45
  end
46
-
46
+
47
+ def model_binding
48
+ swt_widget.data
49
+ end
50
+
51
+ def sort_by_column(table_column_proxy)
52
+ index = swt_widget.columns.to_a.index(table_column_proxy.swt_widget)
53
+ new_sort_property = table_column_proxy.sort_property || column_properties[index]
54
+ @sort_direction = @sort_direction.nil? || @sort_property != new_sort_property || @sort_direction == :descending ? :ascending : :descending
55
+ @sort_property = new_sort_property
56
+ if table_column_proxy.sort_by_block
57
+ @sort_by_block = table_column_proxy.sort_by_block
58
+ elsif table_column_proxy.sort_block
59
+ @sort_block = table_column_proxy.sort_block
60
+ else
61
+ detect_sort_type
62
+ end
63
+ sort
64
+ end
65
+
66
+ def detect_sort_type
67
+ @sort_type = String
68
+ array = model_binding.evaluate_property
69
+ values = array.map { |object| object.send(sort_property) }
70
+ value_classes = values.map(&:class).uniq
71
+ if value_classes.size == 1
72
+ @sort_type = value_classes.first
73
+ elsif value_classes.include?(Integer)
74
+ @sort_type = Integer
75
+ elsif value_classes.include?(Float)
76
+ @sort_type = Float
77
+ end
78
+ end
79
+
80
+ def sort
81
+ return unless sort_property && (sort_type || sort_block || sort_by_block)
82
+ array = model_binding.evaluate_property
83
+ # Converting value to_s first to handle nil cases. Should work with numeric, boolean, and date fields
84
+ if sort_block
85
+ sorted_array = array.sort do |object1, object2|
86
+ value1 = object1.send(sort_property)
87
+ value2 = object2.send(sort_property)
88
+ sort_block.call(value1, value2)
89
+ end
90
+ else
91
+ sorted_array = array.sort_by do |object|
92
+ value = object.send(sort_property)
93
+ # handle nil and difficult to compare types gracefully
94
+ if sort_by_block
95
+ value = sort_by_block.call(value)
96
+ elsif sort_type == Integer
97
+ value = value.to_i
98
+ elsif sort_type == Float
99
+ value = value.to_f
100
+ elsif sort_type == String
101
+ value = value.to_s
102
+ end
103
+ value
104
+ end
105
+ end
106
+ sorted_array = sorted_array.reverse if sort_direction == :descending
107
+ model_binding.call(sorted_array)
108
+ end
109
+
47
110
  # Performs a search for table items matching block condition
48
111
  # If no condition block is passed, returns all table items
49
112
  # Returns a Java TableItem array to easily set as selection on org.eclipse.swt.Table if needed
@@ -31,8 +31,8 @@ module Glimmer
31
31
  "list" => [:border, :v_scroll],
32
32
  "button" => [:push],
33
33
  "menu_item" => [:push],
34
- "drag_source" => DND::DROP_COPY,
35
- "drop_target" => DND::DROP_COPY,
34
+ "drag_source" => [:drop_copy],
35
+ "drop_target" => [:drop_copy],
36
36
  }
37
37
 
38
38
  DEFAULT_INITIALIZERS = {
@@ -51,7 +51,7 @@ module Glimmer
51
51
  end,
52
52
  }
53
53
 
54
- attr_reader :swt_widget
54
+ attr_reader :swt_widget, :drag_source_proxy, :drop_target_proxy, :drag_source_style, :drag_source_transfer, :drop_target_transfer
55
55
 
56
56
  # Initializes a new SWT Widget
57
57
  #
@@ -61,6 +61,12 @@ module Glimmer
61
61
  swt_widget_class = self.class.swt_widget_class_for(underscored_widget_name)
62
62
  @swt_widget = swt_widget_class.new(parent.swt_widget, style(underscored_widget_name, styles), *extra_options)
63
63
  DEFAULT_INITIALIZERS[underscored_widget_name]&.call(@swt_widget)
64
+ parent.post_initialize_child(self)
65
+ end
66
+
67
+ # Subclasses may override to perform post initialization work on an added child
68
+ def post_initialize_child(child)
69
+ # No Op by default
64
70
  end
65
71
 
66
72
  def extract_args(underscored_widget_name, args)
@@ -75,7 +81,18 @@ module Glimmer
75
81
  if @arg_extractor_mapping[underscored_widget_name]
76
82
  @arg_extractor_mapping[underscored_widget_name].call(args)
77
83
  else
78
- [args, []]
84
+ extra_options = []
85
+ style_args = args.select {|arg| arg.is_a?(Symbol) || arg.is_a?(String)}
86
+ if style_args.any?
87
+ style_arg_start_index = args.index(style_args.first)
88
+ style_arg_last_index = args.index(style_args.last)
89
+ extra_options = args[style_arg_last_index+1..-1]
90
+ args = args[style_arg_start_index..style_arg_last_index]
91
+ elsif args.first.is_a?(Integer)
92
+ extra_options = args[1..-1]
93
+ args = args[0..0]
94
+ end
95
+ [args, extra_options]
79
96
  end
80
97
  end
81
98
 
@@ -84,7 +101,7 @@ module Glimmer
84
101
  if widget_custom_attribute
85
102
  @swt_widget.respond_to?(widget_custom_attribute[:setter][:name])
86
103
  else
87
- @swt_widget.respond_to?(attribute_setter(attribute_name), args)
104
+ @swt_widget.respond_to?(attribute_setter(attribute_name), args) || respond_to?(ruby_attribute_setter(attribute_name), args)
88
105
  end
89
106
  end
90
107
 
@@ -92,9 +109,11 @@ module Glimmer
92
109
  widget_custom_attribute = widget_custom_attribute_mapping[attribute_name.to_s]
93
110
  if widget_custom_attribute
94
111
  widget_custom_attribute[:setter][:invoker].call(@swt_widget, args)
95
- else
112
+ elsif @swt_widget.respond_to?(attribute_setter(attribute_name), args)
96
113
  apply_property_type_converters(attribute_name, args)
97
114
  @swt_widget.send(attribute_setter(attribute_name), *args) unless @swt_widget.send(attribute_getter(attribute_name)) == args.first
115
+ else
116
+ send(ruby_attribute_setter(attribute_name), args)
98
117
  end
99
118
  end
100
119
 
@@ -132,6 +151,23 @@ module Glimmer
132
151
  observer.call(false)
133
152
  }
134
153
  end,
154
+ :selection => lambda do |observer|
155
+ on_widget_selected { |selection_event|
156
+ observer.call(@swt_widget.getSelection)
157
+ } if can_handle_observation_request?(:on_widget_selected)
158
+ end,
159
+ :text => lambda do |observer|
160
+ on_modify_text { |modify_event|
161
+ observer.call(@swt_widget.getText)
162
+ } if can_handle_observation_request?(:on_modify_text)
163
+ end,
164
+ },
165
+ Java::OrgEclipseSwtWidgets::Combo => {
166
+ :text => lambda do |observer|
167
+ on_modify_text { |modify_event|
168
+ observer.call(@swt_widget.getText)
169
+ }
170
+ end,
135
171
  },
136
172
  Java::OrgEclipseSwtWidgets::Text => {
137
173
  :text => lambda do |observer|
@@ -236,11 +272,11 @@ module Glimmer
236
272
  end
237
273
  swt_widget_class
238
274
  rescue NameError => e
239
- Glimmer::Config.logger&.debug e.message
275
+ Glimmer::Config.logger&.debug e.full_message
240
276
  # Glimmer::Config.logger&.debug("#{e.message}\n#{e.backtrace.join("\n")}")
241
277
  nil
242
278
  rescue => e
243
- Glimmer::Config.logger&.debug e.message
279
+ Glimmer::Config.logger&.debug e.full_message
244
280
  # Glimmer::Config.logger&.debug("#{e.message}\n#{e.backtrace.join("\n")}")
245
281
  nil
246
282
  end
@@ -276,15 +312,28 @@ module Glimmer
276
312
  def add_observer(observer, property_name)
277
313
  property_listener_installers = @swt_widget.class.ancestors.map {|ancestor| widget_property_listener_installers[ancestor]}.compact
278
314
  widget_listener_installers = property_listener_installers.map{|installer| installer[property_name.to_s.to_sym]}.compact if !property_listener_installers.empty?
279
- widget_listener_installers.to_a.each do |widget_listener_installer|
280
- widget_listener_installer.call(observer)
281
- end
315
+ widget_listener_installers.to_a.first&.call(observer)
282
316
  end
283
317
 
284
318
  def remove_observer(observer, property_name)
285
319
  # TODO consider implementing if remove_observer is needed (consumers can remove listener via SWT API)
286
320
  end
287
321
 
322
+ def ensure_drag_source_proxy(style=[])
323
+ @drag_source_proxy ||= self.class.new('drag_source', self, style).tap do |proxy|
324
+ proxy.set_attribute(:transfer, :text)
325
+ end
326
+ end
327
+
328
+ def ensure_drop_target_proxy(style=[])
329
+ @drop_target_proxy ||= self.class.new('drop_target', self, style).tap do |proxy|
330
+ proxy.set_attribute(:transfer, :text)
331
+ proxy.on_drag_enter { |event|
332
+ event.detail = DNDProxy[:drop_copy]
333
+ }
334
+ end
335
+ end
336
+
288
337
  # TODO eliminate duplication in the following methods perhaps by relying on exceptions
289
338
 
290
339
  def can_handle_observation_request?(observation_request)
@@ -294,9 +343,31 @@ module Glimmer
294
343
  SWTProxy.has_constant?(constant_name)
295
344
  elsif observation_request.start_with?('on_')
296
345
  event = observation_request.sub(/^on_/, '')
297
- can_add_listener?(event)
298
- else
299
- false
346
+ can_add_listener?(event) || can_handle_drag_observation_request?(observation_request) || can_handle_drop_observation_request?(observation_request)
347
+ end
348
+ end
349
+
350
+ def can_handle_drag_observation_request?(observation_request)
351
+ return false unless swt_widget.is_a?(Control)
352
+ potential_drag_source = @drag_source_proxy.nil?
353
+ ensure_drag_source_proxy
354
+ @drag_source_proxy.can_handle_observation_request?(observation_request).tap do |result|
355
+ if potential_drag_source && !result
356
+ @drag_source_proxy.swt_widget.dispose
357
+ @drag_source_proxy = nil
358
+ end
359
+ end
360
+ end
361
+
362
+ def can_handle_drop_observation_request?(observation_request)
363
+ return false unless swt_widget.is_a?(Control)
364
+ potential_drop_target = @drop_target_proxy.nil?
365
+ ensure_drop_target_proxy
366
+ @drop_target_proxy.can_handle_observation_request?(observation_request).tap do |result|
367
+ if potential_drop_target && !result
368
+ @drop_target_proxy.swt_widget.dispose
369
+ @drop_target_proxy = nil
370
+ end
300
371
  end
301
372
  end
302
373
 
@@ -306,7 +377,14 @@ module Glimmer
306
377
  add_swt_event_listener(constant_name, &block)
307
378
  elsif observation_request.start_with?('on_')
308
379
  event = observation_request.sub(/^on_/, '')
309
- add_listener(event, &block)
380
+ if can_add_listener?(event)
381
+ event = observation_request.sub(/^on_/, '')
382
+ add_listener(event, &block)
383
+ elsif can_handle_drag_observation_request?(observation_request)
384
+ @drag_source_proxy&.handle_observation_request(observation_request, &block)
385
+ elsif can_handle_drop_observation_request?(observation_request)
386
+ @drop_target_proxy&.handle_observation_request(observation_request, &block)
387
+ end
310
388
  end
311
389
  end
312
390
 
@@ -331,7 +409,11 @@ module Glimmer
331
409
 
332
410
  def default_style(underscored_widget_name)
333
411
  styles = DEFAULT_STYLES[underscored_widget_name] || [:none]
334
- SWTProxy[styles]
412
+ SWTProxy[styles] rescue DNDProxy[styles]
413
+ end
414
+
415
+ def ruby_attribute_setter(attribute_name)
416
+ "#{attribute_name}="
335
417
  end
336
418
 
337
419
  def attribute_setter(attribute_name)
@@ -355,7 +437,7 @@ module Glimmer
355
437
  def add_listener(underscored_listener_name, &block)
356
438
  widget_add_listener_method, listener_class, listener_method = self.class.find_listener(@swt_widget.getClass, underscored_listener_name)
357
439
  widget_listener_proxy = nil
358
- safe_block = lambda { |event| block.call(event) unless @swt_widget.isDisposed }
440
+ safe_block = lambda { |event| block.call(event) unless @swt_widget.isDisposed }
359
441
  listener = listener_class.new(listener_method => safe_block)
360
442
  @swt_widget.send(widget_add_listener_method, listener)
361
443
  widget_listener_proxy = WidgetListenerProxy.new(swt_widget: @swt_widget, swt_listener: listener, widget_add_listener_method: widget_add_listener_method, swt_listener_class: listener_class, swt_listener_method: listener_method)
@@ -432,6 +514,38 @@ module Glimmer
432
514
  }
433
515
  end
434
516
 
517
+ def drag_source_style=(style)
518
+ ensure_drag_source_proxy(style)
519
+ end
520
+
521
+ def drop_target_style=(style)
522
+ ensure_drop_target_proxy(style)
523
+ end
524
+
525
+ def drag_source_transfer=(args)
526
+ args = args.first if !args.empty? && args.first.is_a?(ArrayJavaProxy)
527
+ ensure_drag_source_proxy
528
+ @drag_source_proxy.set_attribute(:transfer, args)
529
+ end
530
+
531
+ def drop_target_transfer=(args)
532
+ args = args.first if !args.empty? && args.first.is_a?(ArrayJavaProxy)
533
+ ensure_drop_target_proxy
534
+ @drop_target_proxy.set_attribute(:transfer, args)
535
+ end
536
+
537
+ def drag_source_effect=(args)
538
+ args = args.first if args.is_a?(Array)
539
+ ensure_drag_source_proxy
540
+ @drag_source_proxy.set_attribute(:drag_source_effect, args)
541
+ end
542
+
543
+ def drop_target_effect=(args)
544
+ args = args.first if args.is_a?(Array)
545
+ ensure_drop_target_proxy
546
+ @drop_target_proxy.set_attribute(:drop_target_effect, args)
547
+ end
548
+
435
549
  def apply_property_type_converters(attribute_name, args)
436
550
  if args.count == 1
437
551
  value = args.first
@@ -495,6 +609,7 @@ module Glimmer
495
609
  end
496
610
  end,
497
611
  :transfer => lambda do |value|
612
+ value = value.first if value.is_a?(Array) && value.size == 1 && value.first.is_a?(Array)
498
613
  transfer_object_extrapolator = lambda do |transfer_name|
499
614
  transfer_type = "#{transfer_name.to_s.camelcase(:upper)}Transfer".to_sym
500
615
  transfer_type_alternative = "#{transfer_name.to_s.upcase}Transfer".to_sym
@@ -137,6 +137,11 @@ module Glimmer
137
137
  execute_hooks('after_body')
138
138
  @swt_widget = @body_root.swt_widget
139
139
  end
140
+
141
+ # Subclasses may override to perform post initialization work on an added child
142
+ def post_initialize_child(child)
143
+ body_root.post_initialize_child(child)
144
+ end
140
145
 
141
146
  def can_handle_observation_request?(observation_request)
142
147
  result = false
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.1.3
4
+ version: 0.2.4
5
5
  platform: ruby
6
6
  authors:
7
7
  - AndyMaleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-28 00:00:00.000000000 Z
11
+ date: 2020-07-15 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.9.3
18
+ version: 0.9.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.9.3
26
+ version: 0.9.4
27
27
  - !ruby/object:Gem::Dependency
28
28
  requirement: !ruby/object:Gem::Requirement
29
29
  requirements:
@@ -256,7 +256,7 @@ dependencies:
256
256
  - - "~>"
257
257
  - !ruby/object:Gem::Version
258
258
  version: 0.7.0
259
- description: Glimmer DSL for SWT (Desktop GUI)
259
+ description: Glimmer DSL for SWT (Desktop GUI) - JRuby on SWT
260
260
  email: andy.am@gmail.com
261
261
  executables:
262
262
  - glimmer
@@ -285,6 +285,7 @@ files:
285
285
  - lib/glimmer/data_binding/widget_binding.rb
286
286
  - lib/glimmer/dsl/swt/async_exec_expression.rb
287
287
  - lib/glimmer/dsl/swt/bind_expression.rb
288
+ - lib/glimmer/dsl/swt/block_property_expression.rb
288
289
  - lib/glimmer/dsl/swt/color_expression.rb
289
290
  - lib/glimmer/dsl/swt/column_properties_expression.rb
290
291
  - lib/glimmer/dsl/swt/combo_selection_data_binding_expression.rb
@@ -292,6 +293,7 @@ files:
292
293
  - lib/glimmer/dsl/swt/data_binding_expression.rb
293
294
  - lib/glimmer/dsl/swt/dialog_expression.rb
294
295
  - lib/glimmer/dsl/swt/display_expression.rb
296
+ - lib/glimmer/dsl/swt/dnd_expression.rb
295
297
  - lib/glimmer/dsl/swt/dsl.rb
296
298
  - lib/glimmer/dsl/swt/exec_expression.rb
297
299
  - lib/glimmer/dsl/swt/layout_data_expression.rb
@@ -327,10 +329,12 @@ files:
327
329
  - lib/glimmer/swt/menu_proxy.rb
328
330
  - lib/glimmer/swt/message_box_proxy.rb
329
331
  - lib/glimmer/swt/packages.rb
332
+ - lib/glimmer/swt/scrolled_composite_proxy.rb
330
333
  - lib/glimmer/swt/shell_proxy.rb
331
334
  - lib/glimmer/swt/style_constantizable.rb
332
335
  - lib/glimmer/swt/swt_proxy.rb
333
336
  - lib/glimmer/swt/tab_item_proxy.rb
337
+ - lib/glimmer/swt/table_column_proxy.rb
334
338
  - lib/glimmer/swt/table_proxy.rb
335
339
  - lib/glimmer/swt/tree_proxy.rb
336
340
  - lib/glimmer/swt/widget_listener_proxy.rb