Class: Glimmer::SWT::DisplayProxy
- Inherits:
-
Object
- Object
- Glimmer::SWT::DisplayProxy
- Includes:
- Custom::Drawable
- Defined in:
- lib/glimmer/swt/display_proxy.rb
Overview
Proxy for org.eclipse.swt.widgets.Display
Maintains a singleton instance since SWT only supports a single active display at a time.
Supports SWT Display’s very useful asyncExec and syncExec methods to support proper multi-threaded manipulation of SWT UI objects
Invoking ‘#swt_display` returns the SWT Display object wrapped by this proxy
Follows the Proxy Design Pattern
Defined Under Namespace
Classes: ConcreteListener
Constant Summary collapse
- OBSERVED_MENU_ITEMS =
['about', 'preferences', 'quit']
Instance Attribute Summary collapse
-
#swt_display ⇒ Object
readonly
SWT Display object wrapped.
Attributes included from Custom::Drawable
#image_double_buffered, #requires_shape_disposal
Class Method Summary collapse
-
.instance(*args) ⇒ Object
Returns singleton instance.
- .thread ⇒ Object
Instance Method Summary collapse
- #add_swt_event_filter(swt_constant, &block) ⇒ Object
-
#async_exec(&block) ⇒ Object
asynchronously executes the block (required from threads other than first GUI thread) does not return the value produced by the block since it is async, running after the return.
- #async_exec_in_progress? ⇒ Boolean
-
#auto_exec(override_sync_exec: nil, override_async_exec: nil, &block) ⇒ Object
Invoke block with ‘sync_exec` only when necessary (running from a separate thread) Override sync_exec as `true` to force using or `false` to force avoiding Override async_exec as `true` to force using or `:unless_in_progress` to force using only if no `async_exec` is in progress Disable auto execution of `sync_exec` via `Glimmer::Config.auto_sync_exec = false` Otherwise, runs normally, thus allowing SWT to decide how to batch/optimize GUI updates.
- #can_handle_observation_request?(observation_request) ⇒ Boolean
- #content(&block) ⇒ Object
- #disposed? ⇒ Boolean
- #execs_in_progress ⇒ Object
- #handle_observation_request(observation_request, &block) ⇒ Object
-
#initialize(*args) ⇒ DisplayProxy
constructor
A new instance of DisplayProxy.
- #method_missing(method, *args, &block) ⇒ Object
- #on_widget_disposed(&block) ⇒ Object
- #respond_to?(method, *args, &block) ⇒ Boolean
-
#sync_exec(&block) ⇒ Object
synchronously executes the block (required from threads other than first GUI thread) returns the value produced by the block.
- #sync_exec_in_progress? ⇒ Boolean
-
#sync_exec_required? ⇒ Boolean
Indicates whether ‘sync_exec` is required because of running in a different thread from the GUI thread `async_exec` could be used as an alternative to `sync_exec` when required.
- #timer_exec(delay_in_millis, &block) ⇒ Object
Methods included from Custom::Drawable
#add_shape, #clear_shapes, #deregister_shape_painting, #expanded_shapes, #image_buffered_shapes, #paint_pixel_by_pixel, #setup_shape_painting, #shape_at_location, #shapes, #swt_drawable
Constructor Details
#initialize(*args) ⇒ DisplayProxy
Returns a new instance of DisplayProxy.
76 77 78 79 80 81 82 83 84 |
# File 'lib/glimmer/swt/display_proxy.rb', line 76 def initialize(*args) Display.app_name ||= 'Glimmer' @swt_display = Display.new(*args) @swt_display.set_data('proxy', self) @execs_in_progress = {} on_swt_Dispose { clear_shapes } end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(method, *args, &block) ⇒ Object
163 164 165 166 167 168 169 170 171 172 |
# File 'lib/glimmer/swt/display_proxy.rb', line 163 def method_missing(method, *args, &block) if can_handle_observation_request?(method) handle_observation_request(method, &block) else swt_display.send(method, *args, &block) end rescue => e Glimmer::Config.logger.debug {"Neither DisplayProxy nor #{swt_display.class.name} can handle the method ##{method}"} super end |
Instance Attribute Details
#swt_display ⇒ Object (readonly)
SWT Display object wrapped
74 75 76 |
# File 'lib/glimmer/swt/display_proxy.rb', line 74 def swt_display @swt_display end |
Class Method Details
.instance(*args) ⇒ Object
Returns singleton instance
59 60 61 62 63 64 65 |
# File 'lib/glimmer/swt/display_proxy.rb', line 59 def instance(*args) if @instance.nil? || @instance.swt_display.nil? || @instance.swt_display.isDisposed @thread = Thread.current @instance = new(*args) end @instance end |
.thread ⇒ Object
67 68 69 70 |
# File 'lib/glimmer/swt/display_proxy.rb', line 67 def thread instance # ensure instance @thread end |
Instance Method Details
#add_swt_event_filter(swt_constant, &block) ⇒ Object
213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/glimmer/swt/display_proxy.rb', line 213 def add_swt_event_filter(swt_constant, &block) event_type = SWTProxy[swt_constant] swt_listener = ConcreteListener.new(&block) @swt_display.addFilter(event_type, swt_listener) #WidgetListenerProxy.new(@swt_display.getListeners(event_type).last) WidgetListenerProxy.new( swt_display: @swt_display, event_type: event_type, filter: true, swt_listener: swt_listener, widget_add_listener_method: 'addFilter', swt_listener_class: ConcreteListener, swt_listener_method: 'handleEvent' ) end |
#async_exec(&block) ⇒ Object
asynchronously executes the block (required from threads other than first GUI thread) does not return the value produced by the block since it is async, running after the return
92 93 94 95 96 97 98 99 100 101 |
# File 'lib/glimmer/swt/display_proxy.rb', line 92 def async_exec(&block) @swt_display.asyncExec do execs_in_progress << :async_exec begin result = block.call ensure execs_in_progress.pop end end end |
#async_exec_in_progress? ⇒ Boolean
128 129 130 |
# File 'lib/glimmer/swt/display_proxy.rb', line 128 def async_exec_in_progress? execs_in_progress.last == :async_exec end |
#auto_exec(override_sync_exec: nil, override_async_exec: nil, &block) ⇒ Object
Invoke block with ‘sync_exec` only when necessary (running from a separate thread) Override sync_exec as `true` to force using or `false` to force avoiding Override async_exec as `true` to force using or `:unless_in_progress` to force using only if no `async_exec` is in progress Disable auto execution of `sync_exec` via `Glimmer::Config.auto_sync_exec = false` Otherwise, runs normally, thus allowing SWT to decide how to batch/optimize GUI updates
145 146 147 148 149 150 151 152 153 |
# File 'lib/glimmer/swt/display_proxy.rb', line 145 def auto_exec(override_sync_exec: nil, override_async_exec: nil, &block) if override_sync_exec || override_sync_exec.nil? && !override_async_exec && sync_exec_required? && Config.auto_sync_exec? && !sync_exec_in_progress? && !async_exec_in_progress? sync_exec(&block) elsif override_async_exec || override_async_exec.to_s == 'unless_in_progress' && !async_exec_in_progress? async_exec(&block) else block.call end end |
#can_handle_observation_request?(observation_request) ⇒ Boolean
180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/glimmer/swt/display_proxy.rb', line 180 def can_handle_observation_request?(observation_request) observation_request = observation_request.to_s if observation_request.start_with?('on_swt_') constant_name = observation_request.sub(/^on_swt_/, '') SWTProxy.has_constant?(constant_name) elsif observation_request.start_with?('on_') event_name = observation_request.sub(/^on_/, '') OBSERVED_MENU_ITEMS.include?(event_name) else false end end |
#content(&block) ⇒ Object
86 87 88 |
# File 'lib/glimmer/swt/display_proxy.rb', line 86 def content(&block) Glimmer::DSL::Engine.add_content(self, Glimmer::DSL::SWT::DisplayExpression.new, 'display', &block) end |
#disposed? ⇒ Boolean
159 160 161 |
# File 'lib/glimmer/swt/display_proxy.rb', line 159 def disposed? @swt_display.isDisposed end |
#execs_in_progress ⇒ Object
136 137 138 |
# File 'lib/glimmer/swt/display_proxy.rb', line 136 def execs_in_progress @execs_in_progress[Thread.current] ||= [] end |
#handle_observation_request(observation_request, &block) ⇒ Object
193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 |
# File 'lib/glimmer/swt/display_proxy.rb', line 193 def handle_observation_request(observation_request, &block) observation_request = observation_request.to_s if observation_request.start_with?('on_swt_') constant_name = observation_request.sub(/^on_swt_/, '') swt_event_reg = add_swt_event_filter(constant_name, &block) Glimmer::UI::CustomWidget..last&.observer_registrations&.push(swt_event_reg) swt_event_reg elsif observation_request.start_with?('on_') event_name = observation_request.sub(/^on_/, '') if OBSERVED_MENU_ITEMS.include?(event_name) && OS.mac? = swt_display.getSystemMenu = .getItems.find {|| .getID == SWTProxy["ID_#{event_name.upcase}"]} listener = ConcreteListener.new(&block) display_mac_event_registration = .addListener(SWTProxy[:Selection], listener) Glimmer::UI::CustomWidget..last&.observer_registrations&.push(display_mac_event_registration) display_mac_event_registration end end end |
#on_widget_disposed(&block) ⇒ Object
155 156 157 |
# File 'lib/glimmer/swt/display_proxy.rb', line 155 def (&block) on_swt_Dispose(&block) end |
#respond_to?(method, *args, &block) ⇒ Boolean
174 175 176 177 178 |
# File 'lib/glimmer/swt/display_proxy.rb', line 174 def respond_to?(method, *args, &block) super || can_handle_observation_request?(method) || swt_display.respond_to?(method, *args, &block) end |
#sync_exec(&block) ⇒ Object
synchronously executes the block (required from threads other than first GUI thread) returns the value produced by the block
105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/glimmer/swt/display_proxy.rb', line 105 def sync_exec(&block) result = nil @swt_display.syncExec do execs_in_progress << :sync_exec begin result = block.call ensure execs_in_progress.pop end end result end |
#sync_exec_in_progress? ⇒ Boolean
132 133 134 |
# File 'lib/glimmer/swt/display_proxy.rb', line 132 def sync_exec_in_progress? execs_in_progress.include?(:sync_exec) end |
#sync_exec_required? ⇒ Boolean
Indicates whether ‘sync_exec` is required because of running in a different thread from the GUI thread `async_exec` could be used as an alternative to `sync_exec` when required.
124 125 126 |
# File 'lib/glimmer/swt/display_proxy.rb', line 124 def sync_exec_required? Thread.current != DisplayProxy.thread end |
#timer_exec(delay_in_millis, &block) ⇒ Object
118 119 120 |
# File 'lib/glimmer/swt/display_proxy.rb', line 118 def timer_exec(delay_in_millis, &block) @swt_display.timerExec(delay_in_millis, &block) end |