1#
2#  tkextlib/blt/dragdrop.rb
3#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
4#
5
6require 'tk'
7require 'tk/itemconfig'
8require 'tkextlib/blt.rb'
9
10module Tk::BLT
11  module DragDrop
12    extend TkCore
13
14    TkCommandNames = ['::blt::drag&drop'.freeze].freeze
15
16    class Token < TkWindow
17      WidgetClassName = 'DragDropToken'.freeze
18      WidgetClassNames[WidgetClassName] ||= self
19
20      def initialize(arg)
21        if arg.kind_of?(Hash) # arg is a hash includes the widgetpath of token
22          arg = _symbolkey2str(arg)
23          install_win(nil, arg['widgetname'])
24        else  # arg is a drag&drop source
25          tk_call('::blt::drag&drop', 'source', arg)
26          install_win(nil, tk_call('::blt::drag&drop', 'token', arg))
27        end
28      end
29    end
30
31    ###################################
32
33    extend TkItemConfigMethod
34    extend Tk::ValidateConfigure
35
36    class << self
37      def __item_config_cmd(id)  # id := ['source'|'target', win]
38        ['::blt::drag&drop', id[0], id[1]]
39      end
40      private :__item_config_cmd
41
42      def __item_boolval_optkeys(id)
43        super(id) << 'selftarget'
44      end
45      private :__item_boolval_optkeys
46
47      def __item_listval_optkeys(id)
48        super(id) << 'send'
49      end
50      private :__item_listval_optkeys
51
52      def __item_strval_optkeys(id)
53        super(id) << 'rejectbg' << 'rejectfg' << 'tokenbg'
54      end
55      private :__item_strval_optkeys
56
57      undef itemcget
58      undef itemcget_tkstring
59      private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
60
61      def source_configure(win, slot, value=None)
62        itemconfigure(['source', win], slot, value)
63      end
64      def source_configinfo(win, slot=nil)
65        itemconfiginfo(['source', win], slot)
66      end
67      def current_source_configinfo(win, slot=nil)
68        current_itemconfiginfo(['source', win], slot)
69      end
70    end
71
72    class PackageCommand < TkValidateCommand
73      class ValidateArgs < TkUtil::CallbackSubst
74        KEY_TBL = [
75          [ ?t, ?w, :token ],
76          [ ?W, ?w, :widget ],
77          nil
78        ]
79
80        PROC_TBL = [
81          [ ?w, TkComm.method(:window) ],
82          nil
83        ]
84
85=begin
86        # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
87        KEY_TBL.map!{|inf|
88          if inf.kind_of?(Array)
89            inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
90            inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
91          end
92          inf
93        }
94
95        PROC_TBL.map!{|inf|
96          if inf.kind_of?(Array)
97            inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
98          end
99          inf
100        }
101=end
102
103        _setup_subst_table(KEY_TBL, PROC_TBL)
104
105        def self.ret_val(val)
106          val
107        end
108      end
109
110      def self._config_keys
111        ['packagecmd']
112      end
113    end
114
115    class SiteCommand < TkValidateCommand
116      class ValidateArgs < TkUtil::CallbackSubst
117        KEY_TBL = [
118          [ ?s, ?b, :compatible ],
119          [ ?t, ?w, :token ],
120          nil
121        ]
122
123        PROC_TBL = [
124          [ ?b, TkComm.method(:bool) ],
125          [ ?w, TkComm.method(:window) ],
126          nil
127        ]
128
129=begin
130        # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
131        KEY_TBL.map!{|inf|
132          if inf.kind_of?(Array)
133            inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
134            inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
135          end
136          inf
137        }
138
139        PROC_TBL.map!{|inf|
140          if inf.kind_of?(Array)
141            inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
142          end
143          inf
144        }
145=end
146
147        _setup_subst_table(KEY_TBL, PROC_TBL)
148
149        def self.ret_val(val)
150          val
151        end
152      end
153
154      def self._config_keys
155        ['sitecmd']
156      end
157    end
158
159    def self.__validation_class_list
160      super() << PackageCommand << SiteCommand
161    end
162
163    class << self
164      Tk::ValidateConfigure.__def_validcmd(binding, PackageCommand)
165      Tk::ValidateConfigure.__def_validcmd(binding, SiteCommand)
166    end
167
168    ###################################
169
170    class DnD_Handle < TkUtil::CallbackSubst
171      KEY_TBL = [
172        [ ?i, ?s, :ip_name ],
173        [ ?v, ?v, :value ],
174        [ ?W, ?w, :widget ],
175        nil
176      ]
177
178      PROC_TBL = [
179        [ ?i, TkComm.method(:string) ],
180        [ ?v, TkComm.method(:tk_tcl2ruby) ],
181        [ ?w, TkComm.method(:window) ],
182        nil
183      ]
184
185=begin
186      # for Ruby m17n :: ?x --> String --> char-code ( getbyte(0) )
187      KEY_TBL.map!{|inf|
188        if inf.kind_of?(Array)
189          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
190          inf[1] = inf[1].getbyte(0) if inf[1].kind_of?(String)
191        end
192        inf
193      }
194
195      PROC_TBL.map!{|inf|
196        if inf.kind_of?(Array)
197          inf[0] = inf[0].getbyte(0) if inf[0].kind_of?(String)
198        end
199        inf
200      }
201=end
202
203      _setup_subst_table(KEY_TBL, PROC_TBL)
204    end
205
206    def self.source_handler(win, datatype, cmd=Proc.new, *args)
207      _bind_for_event_class(DnD_Handle,
208                            ['::blt::drag&drop', 'source', win, 'handler'],
209                            cmd, *args)
210    end
211
212    def self.target_handler(win, datatype, cmd=Proc.new, *args)
213      _bind_for_event_class(DnD_Handle,
214                            ['::blt::drag&drop', 'target', win, 'handler'],
215                            cmd, *args)
216    end
217
218    ###################################
219
220    def self.init_source(win)
221      tk_call('::blt::drag&drop', 'source', win)
222    end
223
224    def self.source()
225      list(tk_call('::blt::drag&drop', 'source'))
226    end
227
228    def self.source_handler_list(win)
229      simplelist(tk_call('::blt::drag&drop', 'source', win, 'handler'))
230    end
231    def self.source_handler_info(win, type)
232      tk_tcl2ruby(tk_call('::blt::drag&drop', 'source', win, 'handler', type))
233    end
234
235    def self.target
236      list(tk_call('::blt::drag&drop', 'target'))
237    end
238    def self.target_handler_list(win)
239      simplelist(tk_call('::blt::drag&drop', 'target', win, 'handler'))
240    end
241
242    def self.handle_target(win, type, val=None)
243      tk_call('::blt::drag&drop', 'target', win, 'handle', type, val)
244    end
245
246    def self.token(win)
247      window(tk_call('::blt::drag&drop', 'token', win))
248    end
249
250    def self.drag(win, x, y)
251      tk_call('::blt::drag&drop', 'drag', win, x, y)
252    end
253    def self.drop(win, x, y)
254      tk_call('::blt::drag&drop', 'drop', win, x, y)
255    end
256
257    def self.errors(cmd=Proc.new)
258      tk_call('::blt::drag&drop', 'errors', cmd)
259    end
260
261    def self.active
262      bool(tk_call('::blt::drag&drop', 'active'))
263    end
264
265    def self.location(x=None, y=None)
266      list(tk_call('::blt::drag&drop', 'location', x, y))
267    end
268  end
269end
270