Module: Glimmer::Tk::DraggableAndDroppable

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

Defined Under Namespace

Classes: DragAndDropEvent

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#on_drag_motion_blockObject

Returns the value of attribute on_drag_motion_block.



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

def on_drag_motion_block
  @on_drag_motion_block
end

Instance Method Details

#drag_source=(value) ⇒ Object



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

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

#drop_target=(value) ⇒ Object



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

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

#handle_listener(listener_name, &listener) ⇒ Object



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

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



81
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
# File 'lib/glimmer/tk/draggable_and_droppable.rb', line 81

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 = 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



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

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



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

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

#make_non_droppableObject



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

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

#on_drag_start_block=(block) ⇒ Object



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

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

#on_drop_block=(value) ⇒ Object



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

def on_drop_block=(value)
  @on_drop_block = value
  self.tk.bind("<DropEvent>", proc { |tk_event|
    drop_event = 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 = DragAndDropEvent.json_create(JSON.parse("{" + tk_event.detail + "}"))
    drop_check_event.source.event_generate("<DropAcceptedEvent>")
  })
end

#textvariable_defined?Boolean

Returns:

  • (Boolean)


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

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