OSDN Git Service

ruby-1.9.1-rc1
[splhack/AndroidRuby.git] / lib / ruby-1.9.1-rc1 / ext / tk / sample / tkextlib / bwidget / tree.rb
1 #
2 #  templdlg demo  ---  called from demo.rb
3 #
4 unless Object.const_defined?('DemoVar')
5   fail RuntimeError, "This is NOT a stand alone script. This script is called from 'demo.rb'. "
6 end
7
8 module DemoTree
9   @@count = 0
10   @@dblclick = false
11   @@top = nil
12
13   def self.create(nb)
14     frame = nb.insert('end', 'demoTree', :text=>'Tree')
15     pw = Tk::BWidget::PanedWindow.new(frame, :side=>:top)
16
17     pane = pw.add(:weight=>1)
18     title = Tk::BWidget::TitleFrame.new(pane, :text=>'Directory tree')
19     sw = Tk::BWidget::ScrolledWindow.new(title.get_frame, 
20                                          :relief=>:sunken, :borderwidth=>2)
21     tree = Tk::BWidget::Tree.new(sw, :relief=>:flat, :borderwidth=>0, 
22                                  :width=>15, :highlightthickness=>0, 
23                                  :redraw=>false, :dropenabled=>true, 
24                                  :dragenabled=>true, :dragevent=>3, 
25                                  :droptypes=>[
26                                    'TREE_NODE', [
27                                      :copy, [], 
28                                      :move, [],
29                                      :link, []
30                                    ], 
31                                    'LISTBOX_ITEM', [
32                                      :copy, [], 
33                                      :move, [],
34                                      :link, []
35                                    ]
36                                  ], 
37                                  :opencmd=>proc{|node| 
38                                    moddir(1, tree, node)
39                                  }, 
40                                  :closecmd=>proc{|node| 
41                                    moddir(0, tree, node)
42                                  })
43     sw.set_widget(tree)
44
45     sw.pack(:side=>:top, :expand=>true, :fill=>:both)
46     title.pack(:fill=>:both, :expand=>true)
47
48     pane = pw.add(:weight=>2)
49     lf = Tk::BWidget::TitleFrame.new(pane, :text=>'Content')
50     sw = Tk::BWidget::ScrolledWindow.new(lf.get_frame, 
51                                          :scrollbar=>:horizontal, 
52                                          :auto=>:none, :relief=>:sunken, 
53                                          :borderwidth=>2)
54
55     list = Tk::BWidget::ListBox.new(sw, :relief=>:flat, :borderwidth=>0, 
56                                     :highlightthickness=>0, :width=>20, 
57                                     :multicolumn=>true, :redraw=>false, 
58                                     :dragevent=>3, :dropenabled=>true, 
59                                     :dragenabled=>true, 
60                                  :droptypes=>[
61                                       'TREE_NODE', [
62                                         :copy, [], 
63                                         :move, [],
64                                         :link, []
65                                       ], 
66                                       'LISTBOX_ITEM', [
67                                         :copy, [], 
68                                         :move, [],
69                                         :link, []
70                                       ]
71                                     ])
72     sw.set_widget(list)
73
74     Tk.pack(sw, lf, :fill=>:both, :expand=>true)
75
76     pw.pack(:fill=>:both, :expand=>true)
77
78     tree.textbind('ButtonPress-1',
79                   proc{|node, ev| select('tree', 1, tree, list, node)})
80     tree.textbind('Double-ButtonPress-1', 
81                   proc{|node, ev| select('tree', 2, tree, list, node)})
82
83     list.textbind('ButtonPress-1',
84                   proc{|node, ev| select('list', 1, tree, list, node)})
85     list.textbind('Double-ButtonPress-1', 
86                   proc{|node, ev| select('list', 2, tree, list, node)})
87
88     list.imagebind('Double-ButtonPress-1', 
89                    proc{|node, ev| select('list', 2, tree, list, node)})
90
91     nb.itemconfigure('demoTree', 
92                      :createcmd=>proc{|*args| init(tree, list, *args)}, 
93                      :raisecmd=>proc{
94                        Tk.root.geometry =~ 
95                          /\d+x\d+([+-]{1,2}\d+)([+-]{1,2}\d+)/
96                        global_w = ($1 || 0).to_i
97                        global_h = ($2 || 0).to_i
98                        if @@top
99                          Tk::BWidget.place(@@top, 0, 0, :at, 
100                             global_w - Tk.root.winfo_screenwidth, global_h)
101                          @@top.deiconify
102                          Tk.root.bind('Unmap', proc{@@top.withdraw})
103                          Tk.root.bind('Map',   proc{@@top.deiconify})
104                          Tk.root.bind('Configure', proc{|w|
105                                 if w == Tk.root
106                                   Tk.root.geometry =~ 
107                                     /\d+x\d+([+-]{1,2}\d+)([+-]{1,2}\d+)/
108                                   global_w = ($1 || 0).to_i
109                                   global_h = ($2 || 0).to_i
110                                   Tk::BWidget.place(@@top, 0, 0, :at, 
111                                        global_w - Tk.root.winfo_screenwidth, 
112                                        global_h)
113                                 end
114                          }, '%W')
115                        end
116                      }, 
117                      :leavecmd=>proc{
118                        @@top.withdraw if @@top
119                        Tk.root.bind_remove('Unmap')
120                        Tk.root.bind_remove('Map')
121                        Tk.root.bind_remove('Configure')
122                        true
123                      })
124   end
125
126   def self.init(tree, list, *args)
127     @@count = 0
128     if Tk::PLATFORM['platform'] == 'unix'
129       rootdir = File.expand_path('~')
130     else
131       rootdir = 'c:'
132     end
133
134     tree.insert('end', 'root', 'home', 
135                 :text=>rootdir, :data=>rootdir, :open=>true, 
136                 :image=>Tk::BWidget::Bitmap.new('openfold'))
137     getdir(tree, 'home', rootdir)
138     select('tree', 1, tree, list, 'home')
139     tree.redraw(true)
140     list.redraw(true)
141
142     @@top = TkToplevel.new
143     @@top.withdraw
144     @@top.protocol('WM_DELETE_WINDOW'){
145       # don't kill me
146     }
147     @@top.resizable(false, false)
148     @@top.title('Drag rectangle to scroll directory tree')
149     @@top.transient(Tk.root)
150     Tk::BWidget::ScrollView.new(@@top, :window=>tree, :fill=>'white', 
151                                 :width=>300, :height=>300, :relief=>:sunken, 
152                                 :bd=>1).pack(:fill=>:both, :expand=>true)
153   end
154
155   def self.getdir(tree, node, path)
156     lentries = Dir.glob(File.join(path, '*')).sort
157     lfiles = []
158     lentries.each{|f|
159       basename = File.basename(f)      
160       if File.directory?(f)
161         Tk::BWidget::Tree::Node.new(tree, node, 
162                                     :index=>'end', :text=>basename, 
163                                     :image=>Tk::BWidget::Bitmap.new('folder'), 
164                                     :drawcross=>:allways, :data=>f)
165         @@count += 1
166       else
167         lfiles << basename
168       end
169     }
170     tree.itemconfigure(node, :drawcross=>:auto, :data=>lfiles)
171   end
172
173   def self.moddir(idx, tree, node)
174     if (idx != 0 && tree.itemcget(node, :drawcross).to_s == 'allways')
175       getdir(tree, node, tree.itemcget(node, :data))
176       if tree.nodes(node).empty?
177         tree.itemconfigure(node, :image=>Tk::BWidget::Bitmap.new('folder'))
178       else
179         tree.itemconfigure(node, :image=>Tk::BWidget::Bitmap.new('openfold'))
180       end
181     else
182       img = %w(folder openfold)[idx] || 'openfold'
183       tree.itemconfigure(node, :image=>Tk::BWidget::Bitmap.new(img))
184     end
185   end
186
187   def self.select(where, num, tree, list, node)
188     @@dblclick = true
189     if num == 1
190       if (where == 'tree' && 
191           tree.selection_get.find{|x|
192             TkUtil._get_eval_string(x) == TkUtil._get_eval_string(node)
193           })
194         @@dblclick = false
195         Tk.after(500, proc{edit('tree', tree, list, node)})
196         return
197       end
198       if (where == 'list' && 
199           list.selection_get.find{|x|
200             TkUtil._get_eval_string(x) == TkUtil._get_eval_string(node)
201           })
202         @@dblclick = false
203         Tk.after(500, proc{edit('list', tree, list, node)})
204         return
205       end
206       if where == 'tree'
207         select_node(tree, list, node)
208       else
209         list.selection_set(node)
210       end
211     elsif (where == 'list' && tree.exist?(node))
212       parent = tree.parent(node)
213       while TkUtil._get_eval_string(parent) != 'root'
214         tree.itemconfigure(parent, :open=>true)
215         parent = tree.parent(parent)
216       end
217       select_node(tree, list, node)
218     end
219   end
220
221   def self.select_node(tree, list, node)
222     tree.selection_set(node)
223     Tk.update
224     list.delete(*(list.items(0, 'end')))
225
226     dir = tree.itemcget(node, :data)
227     if tree.itemcget(node, :drawcross).to_s == 'allways'
228       getdir(tree, node, dir)
229       dir = tree.itemcget(node, :data)
230     end
231
232     tree.nodes(node).each{|subnode|
233       list.insert('end', subnode, 
234                   :text=>tree.itemcget(subnode, :text), 
235                   :image=>Tk::BWidget::Bitmap.new('folder'))
236     }
237
238     TkComm.simplelist(dir).each{|f|
239       Tk::BWidget::ListBox::Item.new(list, 'end', :text=>f, 
240                                      :image=>Tk::BWidget::Bitmap.new('file'))
241     }
242   end
243
244   def self.edit(where, tree, list, node)
245     return if @@dblclick
246
247     if (where == 'tree' && 
248         tree.selection_get.find{|x|
249           TkUtil._get_eval_string(x) == TkUtil._get_eval_string(node)
250         })
251       res = tree.edit(node, tree.itemcget(node, :text))
252       if res != ''
253         tree.itemconfigure(node, :text=>res)
254         if list.exist?(node)
255           list.itemconfigure(node, :text=>res)
256         end
257         tree.selection_set(node)
258       end
259       return
260     end
261
262     if (where == 'list')
263       res = list.edit(node, list.igemcget(node, :text))
264       if res != ''
265         list.itemconfigure(node, :text=>res)
266         if tree.exist?(node)
267           tree.itemconfigure(node, :text=>res)
268         else
269           cursel = tree.selection_get[0]
270           index  = list.index(node) - tree.nodes(cursel).size
271           data   = TkComm.simplelist(tree.itemcget(cursel, :data))
272           data[index] = res
273           tree.itemconfigure(cursel, :date=>data)
274         end
275         list.selection_set(node)
276       end
277     end
278   end
279
280   def self.expand(tree, but)
281     unless (cur = tree.selection_get).empty?
282       if TkComm.bool(but)
283         tree.opentree(cur)
284       else
285         tree.closetree(cur)
286       end
287     end
288   end
289 end