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