Class: Shoes::Swt::ClickListener

Inherits:
Object
  • Object
show all
Includes:
Common::SafelyEvaluate, Swt::Widgets::Listener
Defined in:
shoes-swt/lib/shoes/swt/click_listener.rb

Overview

This class is intended as the single click listener held onto by the app. That lets us control dispatch of events to our DSL objects however we please, instead of relying on whatever SWT thinks is right. See #882.

Instance Attribute Summary collapse

Instance Method Summary collapse

Methods included from Common::SafelyEvaluate

#safely_evaluate

Constructor Details

#initialize(swt_app) ⇒ ClickListener

Returns a new instance of ClickListener.



14
15
16
17
18
19
20
# File 'shoes-swt/lib/shoes/swt/click_listener.rb', line 14

def initialize(swt_app)
  @clickable_elements = []
  @clicks   = {}
  @releases = {}
  swt_app.add_listener ::Swt::SWT::MouseDown, self
  swt_app.add_listener ::Swt::SWT::MouseUp, self
end

Instance Attribute Details

#clickable_elementsObject (readonly)

Returns the value of attribute clickable_elements.



12
13
14
# File 'shoes-swt/lib/shoes/swt/click_listener.rb', line 12

def clickable_elements
  @clickable_elements
end

Instance Method Details

#add_click_listener(dsl, block) ⇒ Object



22
23
24
25
# File 'shoes-swt/lib/shoes/swt/click_listener.rb', line 22

def add_click_listener(dsl, block)
  add_clickable_element(dsl)
  @clicks[dsl] = block
end

#add_clickable_element(dsl) ⇒ Object



38
39
40
# File 'shoes-swt/lib/shoes/swt/click_listener.rb', line 38

def add_clickable_element(dsl)
  @clickable_elements << dsl unless @clickable_elements.include?(dsl)
end

#add_release_listener(dsl, block) ⇒ Object



27
28
29
30
# File 'shoes-swt/lib/shoes/swt/click_listener.rb', line 27

def add_release_listener(dsl, block)
  add_clickable_element(dsl)
  @releases[dsl] = block
end

#eval_block(event, dsl, block) ⇒ Object



61
62
63
64
65
66
67
68
69
70
71
# File 'shoes-swt/lib/shoes/swt/click_listener.rb', line 61

def eval_block(event, dsl, block)
  return if block.nil?

  safely_evaluate do
    if dsl.pass_coordinates?
      block.call event.button, event.x, event.y
    else
      block.call(dsl)
    end
  end
end

#handle_event(event) ⇒ Object



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'shoes-swt/lib/shoes/swt/click_listener.rb', line 42

def handle_event(event)
  handlers = case event.type
             when ::Swt::SWT::MouseDown then @clicks
             when ::Swt::SWT::MouseUp   then @releases
             end
  return if handlers.nil? || handlers.empty?

  handlers = handlers.to_a
                     .reject { |dsl, _| dsl.hidden? }
                     .select { |dsl, _| dsl.in_bounds?(event.x, event.y) }

  # Take the last handler as an approximation of the "top-most" element
  # since we don't have a true z-index. For layouts that aren't too
  # dynamic this is sufficient to give the behavior we want.
  dsl, block = handlers.last

  eval_block(event, dsl, block)
end

#remove_listeners_for(dsl) ⇒ Object



32
33
34
35
36
# File 'shoes-swt/lib/shoes/swt/click_listener.rb', line 32

def remove_listeners_for(dsl)
  @clickable_elements.delete(dsl)
  @clicks.delete(dsl)
  @releases.delete(dsl)
end