lib/glimmer/swt/custom_widget.rb in glimmer-0.4.8 vs lib/glimmer/swt/custom_widget.rb in glimmer-0.4.9
- old
+ new
@@ -56,38 +56,60 @@
options[:#{option}]
end
end_eval
end
end
+
+ def before_body(&block)
+ @before_body_blocks ||= []
+ @before_body_blocks << block
+ end
+
+ def after_body(&block)
+ @after_body_blocks ||= []
+ @after_body_blocks << block
+ end
end
attr_reader :body_root, :widget, :parent, :swt_style, :options, :content
def initialize(parent, *swt_constants, options, &content)
@parent = parent
@swt_style = GSWT[*swt_constants]
options ||= {}
@options = self.class.options.merge(options)
@content = ProcTracker.new(content) if content
+ execute_hooks('before_body')
@body_root = body
+ execute_hooks('after_body')
@widget = @body_root.widget
end
def body
raise 'Not implemented!'
end
- # TODO consider using delegators
+ def can_handle_observation_request?(observation_request)
+ result = false
+ if observation_request.start_with?('on_updated_')
+ property = observation_request.sub(/^on_updated_/, '')
+ result = can_add_observer?(property)
+ end
+ result || body_root&.can_handle_observation_request?(observation_request)
+ end
- def can_add_listener?(underscored_listener_name)
- @body_root.can_add_listener?(underscored_listener_name)
+ def handle_observation_request(observation_request, &block)
+ if observation_request.start_with?('on_updated_')
+ property = observation_request.sub(/^on_updated_/, '')
+ add_observer(Observer::Proc.new(&block), property) if can_add_observer?(property)
+ else
+ body_root.handle_observation_request(observation_request, &block)
+ end
end
- # TODO clean up difference between add_listener and add_observer
-
- def add_listener(underscored_listener_name, &block)
- @body_root.add_listener(underscored_listener_name, &block)
+ def can_add_observer?(attribute_name)
+ respond_to?(attribute_name) || @body_root.can_add_observer?(attribute_name)
end
def add_observer(observer, attribute_name)
if respond_to?(attribute_name)
super
@@ -119,14 +141,56 @@
def attribute_setter(attribute_name)
"#{attribute_name}="
end
+ # TODO see if it is worth it to eliminate duplication of method_missing
+ # from GWidget using a module
+
+ def method_missing(method, *args, &block)
+ method_name = method.to_s
+ if can_handle_observation_request?(method_name)
+ handle_observation_request(method_name, &block)
+ else
+ super
+ end
+ end
+
def process_block(block)
if block.source_location == @content&.__getobj__.source_location
- @content.call unless @content.called?
+ @content.call(self) unless @content.called?
else
- block.call
+ block.call(self)
+ end
+ end
+
+ def has_style?(style)
+ (swt_style & GSWT[style]) == GSWT[style]
+ end
+
+ # TODO see if it is worth it to eliminate duplication of async_exec/sync_exec
+ # delegation to GDisplay, via a module
+
+ def async_exec(&block)
+ GDisplay.instance.async_exec(&block)
+ end
+
+ def sync_exec(&block)
+ GDisplay.instance.sync_exec(&block)
+ end
+
+ def add_content(&block)
+ body_root.add_content(&block)
+ end
+
+ private
+
+ def execute_hooks(hook_name)
+ self.class.instance_variable_get("@#{hook_name}_blocks")&.each_with_index do |hook_block, i|
+ hook_block_number = i + 1
+ self.class.define_method("__#{hook_name}#{hook_block_number}", hook_block)
+ send("__#{hook_name}#{hook_block_number}")
+ self.class.send(:undef_method, "__#{hook_name}#{hook_block_number}")
end
end
end
end
end