glimmer 0.7.6 → 0.8.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -16,6 +16,8 @@ module Glimmer
16
16
  class DisplayProxy
17
17
  include_package 'org.eclipse.swt.widgets'
18
18
 
19
+ OBSERVED_MENU_ITEMS = ['about', 'preferences']
20
+
19
21
  class << self
20
22
  # Returns singleton instance
21
23
  def instance(*args)
@@ -52,6 +54,9 @@ module Glimmer
52
54
  if observation_request.start_with?('on_event_')
53
55
  constant_name = observation_request.sub(/^on_event_/, '')
54
56
  SWTProxy.has_constant?(constant_name)
57
+ elsif observation_request.start_with?('on_')
58
+ event_name = observation_request.sub(/^on_/, '')
59
+ OBSERVED_MENU_ITEMS.include?(event_name)
55
60
  else
56
61
  false
57
62
  end
@@ -61,6 +66,15 @@ module Glimmer
61
66
  if observation_request.start_with?('on_event_')
62
67
  constant_name = observation_request.sub(/^on_event_/, '')
63
68
  add_swt_event_listener(constant_name, &block)
69
+ elsif observation_request.start_with?('on_')
70
+ event_name = observation_request.sub(/^on_/, '')
71
+ if OBSERVED_MENU_ITEMS.include?(event_name)
72
+ if OS.mac?
73
+ system_menu = swt_display.getSystemMenu
74
+ menu_item = system_menu.getItems.find {|menu_item| menu_item.getID == SWTProxy["ID_#{event_name.upcase}"]}
75
+ menu_item.addListener(SWTProxy[:Selection], &block)
76
+ end
77
+ end
64
78
  end
65
79
  end
66
80
 
@@ -79,6 +79,23 @@ module Glimmer
79
79
  super(attribute_name)
80
80
  end
81
81
  end
82
+
83
+ def can_handle_observation_request?(observation_request, super_only: false)
84
+ super_result = super(observation_request)
85
+ if observation_request.start_with?('on_') && !super_result && !super_only
86
+ return menu_item_proxy.can_handle_observation_request?(observation_request)
87
+ else
88
+ super_result
89
+ end
90
+ end
91
+
92
+ def handle_observation_request(observation_request, &block)
93
+ if can_handle_observation_request?(observation_request, super_only: true)
94
+ super
95
+ else
96
+ menu_item_proxy.handle_observation_request(observation_request, &block)
97
+ end
98
+ end
82
99
  end
83
100
  end
84
101
  end
@@ -0,0 +1,48 @@
1
+ require 'glimmer/swt/swt_proxy'
2
+ require 'glimmer/swt/widget_proxy'
3
+ require 'glimmer/swt/display_proxy'
4
+ require 'glimmer/swt/shell_proxy'
5
+
6
+ module Glimmer
7
+ module SWT
8
+ # Proxy for org.eclipse.swt.widgets.Shell
9
+ #
10
+ # Follows the Proxy Design Pattern
11
+ class MessageBoxProxy
12
+ include_package 'org.eclipse.swt.widgets'
13
+
14
+ attr_reader :swt_widget
15
+
16
+ def initialize(parent, style)
17
+ parent = parent.swt_widget if parent.respond_to?(:swt_widget) && parent.swt_widget.is_a?(Shell)
18
+ @swt_widget = MessageBox.new(parent, style)
19
+ end
20
+
21
+ def open
22
+ @swt_widget.open
23
+ end
24
+
25
+ # TODO refactor the following methods to put in a JavaBean mixin or somethin (perhaps contribute to OSS project too)
26
+
27
+ def attribute_setter(attribute_name)
28
+ "set#{attribute_name.to_s.camelcase(:upper)}"
29
+ end
30
+
31
+ def attribute_getter(attribute_name)
32
+ "get#{attribute_name.to_s.camelcase(:upper)}"
33
+ end
34
+
35
+ def has_attribute?(attribute_name, *args)
36
+ @swt_widget.respond_to?(attribute_setter(attribute_name), args)
37
+ end
38
+
39
+ def set_attribute(attribute_name, *args)
40
+ @swt_widget.send(attribute_setter(attribute_name), *args) unless @swt_widget.send(attribute_getter(attribute_name)) == args.first
41
+ end
42
+
43
+ def get_attribute(attribute_name)
44
+ @swt_widget.send(attribute_getter(attribute_name))
45
+ end
46
+ end
47
+ end
48
+ end
@@ -14,7 +14,6 @@ module Glimmer
14
14
 
15
15
  WIDTH_MIN = 130
16
16
  HEIGHT_MIN = 0
17
- OBSERVED_MENU_ITEMS = ['about', 'preferences']
18
17
 
19
18
  attr_reader :opened_before
20
19
  alias opened_before? opened_before
@@ -103,13 +102,20 @@ module Glimmer
103
102
 
104
103
  def pack_same_size
105
104
  bounds = @swt_widget.getBounds
106
- width = @swt_widget.getBounds.width
107
- height = @swt_widget.getBounds.height
108
- x = @swt_widget.getBounds.x
109
- y = @swt_widget.getBounds.y
110
- @swt_widget.pack
111
- @swt_widget.setSize(width, height)
112
- @swt_widget.setLocation(x, y)
105
+ if OS.mac?
106
+ @swt_widget.pack
107
+ @swt_widget.setBounds(bounds)
108
+ elsif OS.windows? || OS::Underlying.windows?
109
+ minimum_size = @swt_widget.getMinimumSize
110
+ @swt_widget.setMinimumSize(bounds.width, bounds.height)
111
+ listener = on_control_resized { @swt_widget.setBounds(bounds) }
112
+ @swt_widget.pack
113
+ @swt_widget.removeControlListener(listener.swt_listener)
114
+ @swt_widget.setMinimumSize(minimum_size)
115
+ elsif OS.linux?
116
+ @swt_widget.layout(true, true)
117
+ @swt_widget.setBounds(bounds)
118
+ end
113
119
  end
114
120
 
115
121
  def content(&block)
@@ -128,30 +134,6 @@ module Glimmer
128
134
  end
129
135
  end
130
136
 
131
- def can_handle_observation_request?(observation_request)
132
- result = false
133
- if observation_request.start_with?('on_')
134
- event_name = observation_request.sub(/^on_/, '')
135
- result = OBSERVED_MENU_ITEMS.include?(event_name)
136
- end
137
- result || super
138
- end
139
-
140
- def handle_observation_request(observation_request, &block)
141
- if observation_request.start_with?('on_')
142
- event_name = observation_request.sub(/^on_/, '')
143
- if OBSERVED_MENU_ITEMS.include?(event_name)
144
- if OS.mac?
145
- system_menu = DisplayProxy.instance.swt_display.getSystemMenu
146
- menu_item = system_menu.getItems.find {|menu_item| menu_item.getID == SWTProxy["ID_#{event_name.upcase}"]}
147
- menu_item.addListener(SWTProxy[:Selection], &block)
148
- end
149
- else
150
- super
151
- end
152
- end
153
- end
154
-
155
137
  def add_observer(observer, property_name)
156
138
  case property_name.to_s
157
139
  when 'visible?' #TODO see if you must handle non-? version and/or move elsewhere
@@ -0,0 +1,150 @@
1
+ require 'glimmer/swt/widget_proxy'
2
+
3
+ module Glimmer
4
+ module SWT
5
+ class TableProxy < Glimmer::SWT::WidgetProxy
6
+ include Glimmer
7
+
8
+ module TableListenerEvent
9
+ def table_item
10
+ table_item_and_column_index[:table_item]
11
+ end
12
+
13
+ def column_index
14
+ table_item_and_column_index[:column_index]
15
+ end
16
+
17
+ private
18
+
19
+ def table_item_and_column_index
20
+ @table_item_and_column_index ||= find_table_item_and_column_index
21
+ end
22
+
23
+ def find_table_item_and_column_index
24
+ {}.tap do |result|
25
+ if respond_to?(:x) && respond_to?(:y)
26
+ result[:table_item] = widget.getItems.detect do |ti|
27
+ result[:column_index] = widget.getColumnCount.times.to_a.detect do |ci|
28
+ ti.getBounds(ci).contains(x, y)
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
34
+ end
35
+
36
+ attr_reader :table_editor, :table_editor_text_proxy
37
+ attr_accessor :column_properties
38
+
39
+ def initialize(underscored_widget_name, parent, args)
40
+ super
41
+ @table_editor = TableEditor.new(swt_widget)
42
+ @table_editor.horizontalAlignment = SWTProxy[:left]
43
+ @table_editor.grabHorizontal = true
44
+ @table_editor.minimumHeight = 20
45
+ end
46
+
47
+ # Performs a search for table items matching block condition
48
+ # If no condition block is passed, returns all table items
49
+ # Returns a Java TableItem array to easily set as selection on org.eclipse.swt.Table if needed
50
+ def search(&condition)
51
+ swt_widget.getItems.select {|item| condition.nil? || condition.call(item)}.to_java(TableItem)
52
+ end
53
+
54
+ # Returns all table items including descendants
55
+ def all_table_items
56
+ search
57
+ end
58
+
59
+ def widget_property_listener_installers
60
+ super.merge({
61
+ Java::OrgEclipseSwtWidgets::Table => {
62
+ selection: lambda do |observer|
63
+ on_widget_selected { |selection_event|
64
+ observer.call(@swt_widget.getSelection)
65
+ }
66
+ end
67
+ },
68
+ })
69
+ end
70
+
71
+ def edit_in_progress?
72
+ !!@edit_in_progress
73
+ end
74
+
75
+ def edit_selected_table_item(column_index, before_write: nil, after_write: nil, after_cancel: nil)
76
+ edit_table_item(swt_widget.getSelection.first, column_index, before_write: before_write, after_write: after_write, after_cancel: after_cancel)
77
+ end
78
+
79
+ def edit_table_item(table_item, column_index, before_write: nil, after_write: nil, after_cancel: nil)
80
+ return if table_item.nil?
81
+ content {
82
+ @table_editor_text_proxy = text {
83
+ focus true
84
+ text table_item.getText(column_index)
85
+ action_taken = false
86
+ cancel = lambda {
87
+ @table_editor_text_proxy.swt_widget.dispose
88
+ @table_editor_text_proxy = nil
89
+ after_cancel&.call
90
+ @edit_in_progress = false
91
+ }
92
+ action = lambda { |event|
93
+ if !action_taken && !@edit_in_progress
94
+ action_taken = true
95
+ @edit_in_progress = true
96
+ new_text = @table_editor_text_proxy.swt_widget.getText
97
+ if new_text == table_item.getText(column_index)
98
+ cancel.call
99
+ else
100
+ before_write&.call
101
+ table_item.setText(column_index, new_text)
102
+ model = table_item.getData
103
+ model.send("#{column_properties[column_index]}=", new_text) # makes table update itself, so must search for selected table item again
104
+ edited_table_item = search { |ti| ti.getData == model }.first
105
+ swt_widget.showItem(edited_table_item)
106
+ @table_editor_text_proxy.swt_widget.dispose
107
+ @table_editor_text_proxy = nil
108
+ after_write&.call(edited_table_item)
109
+ @edit_in_progress = false
110
+ end
111
+ end
112
+ }
113
+ on_focus_lost(&action)
114
+ on_key_pressed { |key_event|
115
+ if key_event.keyCode == swt(:cr)
116
+ action.call(key_event)
117
+ elsif key_event.keyCode == swt(:esc)
118
+ cancel.call
119
+ end
120
+ }
121
+ }
122
+ @table_editor_text_proxy.swt_widget.selectAll
123
+ }
124
+ @table_editor.setEditor(@table_editor_text_proxy.swt_widget, table_item, column_index)
125
+ end
126
+
127
+ def add_listener(underscored_listener_name, &block)
128
+ enhanced_block = lambda do |event|
129
+ event.extend(TableListenerEvent)
130
+ block.call(event)
131
+ end
132
+ super(underscored_listener_name, &enhanced_block)
133
+ end
134
+
135
+ private
136
+
137
+ def property_type_converters
138
+ super.merge({
139
+ selection: lambda do |value|
140
+ if value.is_a?(Array)
141
+ search {|ti| value.include?(ti.getData) }
142
+ else
143
+ search {|ti| ti.getData == value}
144
+ end
145
+ end,
146
+ })
147
+ end
148
+ end
149
+ end
150
+ end
@@ -95,7 +95,7 @@ module Glimmer
95
95
  }
96
96
  @tree_editor_text_proxy.swt_widget.selectAll
97
97
  }
98
- @tree_editor.setEditor(@tree_editor_text_proxy.swt_widget, tree_item);
98
+ @tree_editor.setEditor(@tree_editor_text_proxy.swt_widget, tree_item)
99
99
  end
100
100
 
101
101
  private
@@ -70,7 +70,7 @@ module Glimmer
70
70
  @custom_widget_namespaces = Set[Object, Glimmer::UI]
71
71
  end
72
72
 
73
- # Allows defining convenience option readers for an array of option names
73
+ # Allows defining convenience option accessors for an array of option names
74
74
  # Example: `options :color1, :color2` defines `#color1` and `#color2`
75
75
  # where they return the instance values `options[:color1]` and `options[:color2]`
76
76
  # respectively.
@@ -83,23 +83,26 @@ module Glimmer
83
83
  else
84
84
  new_options = new_options.reduce({}) {|new_options_hash, new_option| new_options_hash.merge(new_option => nil)}
85
85
  @options = options.merge(new_options)
86
- def_option_attr_readers(new_options)
86
+ def_option_attr_accessors(new_options)
87
87
  end
88
88
  end
89
89
 
90
- def option(new_option, new_option_default = nil)
90
+ def option(new_option, default: nil)
91
91
  new_option = new_option.to_s.to_sym
92
- new_options = {new_option => new_option_default}
92
+ new_options = {new_option => default}
93
93
  @options = options.merge(new_options)
94
- def_option_attr_readers(new_options)
94
+ def_option_attr_accessors(new_options)
95
95
  end
96
96
 
97
- def def_option_attr_readers(new_options)
97
+ def def_option_attr_accessors(new_options)
98
98
  new_options.each do |option, default|
99
99
  class_eval <<-end_eval, __FILE__, __LINE__
100
100
  def #{option}
101
101
  options[:#{option}]
102
102
  end
103
+ def #{option}=(option_value)
104
+ self.options[:#{option}] = option_value
105
+ end
103
106
  end_eval
104
107
  end
105
108
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: glimmer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.6
4
+ version: 0.8.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - AndyMaleh
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-05-26 00:00:00.000000000 Z
11
+ date: 2020-06-11 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
@@ -150,34 +150,6 @@ dependencies:
150
150
  - - "~>"
151
151
  - !ruby/object:Gem::Version
152
152
  version: 3.5.0
153
- - !ruby/object:Gem::Dependency
154
- requirement: !ruby/object:Gem::Requirement
155
- requirements:
156
- - - '='
157
- - !ruby/object:Gem::Version
158
- version: 0.8.5
159
- name: coveralls
160
- type: :development
161
- prerelease: false
162
- version_requirements: !ruby/object:Gem::Requirement
163
- requirements:
164
- - - '='
165
- - !ruby/object:Gem::Version
166
- version: 0.8.5
167
- - !ruby/object:Gem::Dependency
168
- requirement: !ruby/object:Gem::Requirement
169
- requirements:
170
- - - "~>"
171
- - !ruby/object:Gem::Version
172
- version: 0.10.0
173
- name: simplecov
174
- type: :development
175
- prerelease: false
176
- version_requirements: !ruby/object:Gem::Requirement
177
- requirements:
178
- - - "~>"
179
- - !ruby/object:Gem::Version
180
- version: 0.10.0
181
153
  - !ruby/object:Gem::Dependency
182
154
  requirement: !ruby/object:Gem::Requirement
183
155
  requirements:
@@ -192,7 +164,10 @@ dependencies:
192
164
  - - "~>"
193
165
  - !ruby/object:Gem::Version
194
166
  version: 0.8.1
195
- description: Desktop Development Library for Ruby
167
+ description: "Ruby Desktop Development GUI Library (JRuby on SWT). \n\nChanges: \n\
168
+ - `message_box` DSL keyword\n- Table single/multi selection databinding\n- Table\
169
+ \ cell editing databinding\n- Enhance table listener events with table_item and\
170
+ \ column_index methods\n- Fix `Glimmer::SWT::ShellProxy#pack_same_size` for Linux\n"
196
171
  email: andy.am@gmail.com
197
172
  executables:
198
173
  - glimmer
@@ -244,6 +219,7 @@ files:
244
219
  - lib/glimmer/dsl/swt/combo_selection_data_binding_expression.rb
245
220
  - lib/glimmer/dsl/swt/custom_widget_expression.rb
246
221
  - lib/glimmer/dsl/swt/data_binding_expression.rb
222
+ - lib/glimmer/dsl/swt/dialog_expression.rb
247
223
  - lib/glimmer/dsl/swt/display_expression.rb
248
224
  - lib/glimmer/dsl/swt/dsl.rb
249
225
  - lib/glimmer/dsl/swt/exec_expression.rb
@@ -252,6 +228,7 @@ files:
252
228
  - lib/glimmer/dsl/swt/list_selection_data_binding_expression.rb
253
229
  - lib/glimmer/dsl/swt/menu_bar_expression.rb
254
230
  - lib/glimmer/dsl/swt/menu_expression.rb
231
+ - lib/glimmer/dsl/swt/message_box_expression.rb
255
232
  - lib/glimmer/dsl/swt/observe_expression.rb
256
233
  - lib/glimmer/dsl/swt/property_expression.rb
257
234
  - lib/glimmer/dsl/swt/rgb_expression.rb
@@ -286,10 +263,12 @@ files:
286
263
  - lib/glimmer/swt/layout_data_proxy.rb
287
264
  - lib/glimmer/swt/layout_proxy.rb
288
265
  - lib/glimmer/swt/menu_proxy.rb
266
+ - lib/glimmer/swt/message_box_proxy.rb
289
267
  - lib/glimmer/swt/packages.rb
290
268
  - lib/glimmer/swt/shell_proxy.rb
291
269
  - lib/glimmer/swt/swt_proxy.rb
292
270
  - lib/glimmer/swt/tab_item_proxy.rb
271
+ - lib/glimmer/swt/table_proxy.rb
293
272
  - lib/glimmer/swt/tree_proxy.rb
294
273
  - lib/glimmer/swt/widget_listener_proxy.rb
295
274
  - lib/glimmer/swt/widget_proxy.rb
@@ -326,5 +305,5 @@ requirements: []
326
305
  rubygems_version: 3.0.6
327
306
  signing_key:
328
307
  specification_version: 4
329
- summary: Desktop Development Library for Ruby
308
+ summary: Ruby Desktop Development GUI Library
330
309
  test_files: []