Module: Glimmer::Tk::DraggableAndDroppable

Included in:
WidgetProxy
Defined in:
lib/glimmer/tk/draggable_and_droppable.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#on_drag_motion_blockObject

Returns the value of attribute on_drag_motion_block.



28
29
30
# File 'lib/glimmer/tk/draggable_and_droppable.rb', line 28

def on_drag_motion_block
  @on_drag_motion_block
end

Instance Method Details

#drag_source=(value) ⇒ Object



43
44
45
46
47
48
49
50
# File 'lib/glimmer/tk/draggable_and_droppable.rb', line 43

def drag_source=(value)
  @drag_source = value
  if @drag_source
    make_draggable
  else
    make_non_draggable
  end
end

#drop_target=(value) ⇒ Object



52
53
54
55
56
57
58
59
# File 'lib/glimmer/tk/draggable_and_droppable.rb', line 52

def drop_target=(value)
  @drop_target = value
  if @drop_target
    make_droppable
  else
    make_non_droppable
  end
end

#handle_listener(listener_name, &listener) ⇒ Object



30
31
32
33
34
35
36
37
38
39
40
41
# File 'lib/glimmer/tk/draggable_and_droppable.rb', line 30

def handle_listener(listener_name, &listener)
  case listener_name.to_s.downcase
  when 'drag_start'
    self.on_drag_start_block = listener
  when 'drag_motion'
    self.on_drag_motion_block = listener
  when 'drop'
    self.on_drop_block = listener
  else
    super
  end
end

#make_draggableObject



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
# File 'lib/glimmer/tk/draggable_and_droppable.rb', line 82

def make_draggable
  drag_event = nil
  bind("<DropAcceptedEvent>", proc { |event| drag_event.drop_accepted = true })
  bind("B1-Motion", proc { |tk_event|
    if drag_event.nil?
      tooltip = WidgetProxy.new('toplevel', root_parent_proxy, [])
      tooltip.overrideredirect(1) #create tooltip window to display dragged data
      tooltip.geometry("+#{tk_event.x_root + 10}+#{tk_event.y_root - 2}")
      drag_event = Glimmer::Tk::DragAndDropEvent.new(self, nil, tooltip, tk_event.x_root, tk_event.y_root, nil, false)
      if @drag_source
        tk_event.widget.configure(:cursor => "hand2")
        # Default data to drag is text
        drag_event.data = if textvariable_defined?
          tk.textvariable.value
        elsif has_attribute?('text')
          tk.text
        elsif has_attribute?('selection')
          selection.first
        end
        tooltip_label = WidgetProxy.new('label', tooltip, [])
        tooltip_label.text = drag_event.data
        tooltip_label.pack # TODO look into using grid instead to be consistent with the modern Tk way
      elsif !@on_drag_start_block.nil?
        @on_drag_start_block.call(drag_event)
        if tooltip.winfo_children().length == 0
          tooltip_label = WidgetProxy.new('label', tooltip, [])
          tooltip_label.text = drag_event.data
          tooltip_label.pack # TODO look into using grid instead to be consistent with the modern Tk way
        end
      end
    else
      drag_event.x_root, drag_event.y_root = tk_event.x_root, tk_event.y_root
      drag_event.drop_accepted = false
      move_over_widget = tk_event.widget.winfo_containing(tk_event.x_root, tk_event.y_root)
      drag_event.target = move_over_widget.proxy
      move_over_widget.event_generate("<DropCheckEvent>", :data => drag_event.to_json)
      if @on_drag_motion_block.nil?
        # Default motion behavior:
        # 1.Change cursor to show whether text can be dropped.
        # 2.Move tooltip with dragged data.
        if drag_event.drop_accepted
          tk_event.widget.configure(:cursor => "hand1")
        else
          tk_event.widget.configure(:cursor => "hand2")
        end
        drag_event.tooltip.geometry("+#{tk_event.x_root + 10}+#{tk_event.y_root - 2}")
      else
        @on_drag_motion_block.call(drag_event)
      end
    end
  })
  bind("ButtonRelease-1", proc { |tk_event|
    if drag_event
      drag_event.target = tk_event.widget.winfo_containing(tk_event.x_root, tk_event.y_root).proxy
      drag_event.source.configure(:cursor => "")
      drag_event.target.event_generate("<DropEvent>", :data => drag_event.to_json)
      drag_event.tooltip.destroy
      drag_event = nil
    end
  })
end

#make_droppableObject



150
151
152
153
154
155
156
# File 'lib/glimmer/tk/draggable_and_droppable.rb', line 150

def make_droppable
  self.on_drop_block = Proc.new do |event|
    event.target.text = event.data if event.target.has_attribute?('text')
    event.target.items += [event.data] if event.target.has_attribute?('items')
    event.target.selection += [event.data] if event.target.has_attribute?('selection')
  end
end

#make_non_draggableObject



144
145
146
147
148
# File 'lib/glimmer/tk/draggable_and_droppable.rb', line 144

def make_non_draggable
  @tk.bind_remove("B1-Motion")
  @tk.bind_remove("ButtonRelease-1")
  @tk.bind_remove("<DropAcceptedEvent>")
end

#make_non_droppableObject



158
159
160
161
162
# File 'lib/glimmer/tk/draggable_and_droppable.rb', line 158

def make_non_droppable
  @tk.bind_remove('<DropEvent>')
  @tk.bind_remove('<DropCheckEvent>')
  @on_drop_block = nil
end

#on_drag_start_block=(block) ⇒ Object



61
62
63
64
# File 'lib/glimmer/tk/draggable_and_droppable.rb', line 61

def on_drag_start_block=(block)
  @on_drag_start_block = block
  make_draggable
end

#on_drop_block=(value) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
# File 'lib/glimmer/tk/draggable_and_droppable.rb', line 66

def on_drop_block=(value)
  @on_drop_block = value
  self.tk.bind("<DropEvent>", proc { |tk_event|
    drop_event = Glimmer::Tk::DragAndDropEvent.json_create(JSON.parse("{" + tk_event.detail + "}"))
    @on_drop_block.call(drop_event) if self == drop_event.target
  })
  self.tk.bind("<DropCheckEvent>", proc { |tk_event|
    drop_check_event = Glimmer::Tk::DragAndDropEvent.json_create(JSON.parse("{" + tk_event.detail + "}"))
    drop_check_event.source.event_generate("<DropAcceptedEvent>")
  })
end

#textvariable_defined?Boolean

Returns:

  • (Boolean)


78
79
80
# File 'lib/glimmer/tk/draggable_and_droppable.rb', line 78

def textvariable_defined?
  tk_widget_has_attribute_setter?(:textvariable) && !tk.textvariable.nil?
end