1# -*- coding: utf-8 -*-
2#
3# text (embedded windows) widget demo (called by 'widget')
4#
5
6# toplevel widget が存在すれば削除する
7if defined?($twind_demo) && $twind_demo
8  $twind_demo.destroy
9  $twind_demo = nil
10end
11
12# demo 用の toplevel widget を生成
13$twind_demo = TkToplevel.new {|w|
14  title("Text Demonstration - Embedded Windows")
15  iconname("Embedded Windows")
16  positionWindow(w)
17}
18
19base_frame = TkFrame.new($twind_demo).pack(:fill=>:both, :expand=>true)
20
21# frame 生成
22$twind_buttons = TkFrame.new(base_frame) {|frame|
23  TkButton.new(frame) {
24    #text '了解'
25    text '閉じる'
26    command proc{
27      tmppath = $twind_demo
28      $twind_demo = nil
29      tmppath.destroy
30    }
31  }.pack('side'=>'left', 'expand'=>'yes')
32
33  TkButton.new(frame) {
34    text 'コード参照'
35    command proc{showCode 'twind'}
36  }.pack('side'=>'left', 'expand'=>'yes')
37}
38$twind_buttons.pack('side'=>'bottom', 'fill'=>'x', 'pady'=>'2m')
39
40# frame 生成
41$twind_text = nil
42TkFrame.new(base_frame, 'highlightthickness'=>2, 'borderwidth'=>2,
43            'relief'=>'sunken') {|f|
44  $twind_text = TkText.new(f, 'setgrid'=>'true', 'font'=>$font,
45                          'width'=>'70', 'height'=>35, 'wrap'=>'word',
46                          'highlightthickness'=>0, 'borderwidth'=>0 ){|t|
47    TkScrollbar.new(f) {|s|
48      command proc{|*args| t.yview(*args)}
49      t.yscrollcommand proc{|first,last| s.set first,last}
50    }.pack('side'=>'right', 'fill'=>'y')
51  }.pack('expand'=>'yes', 'fill'=>'both')
52}.pack('expand'=>'yes', 'fill'=>'both')
53
54# タグ生成
55$tag_center = TkTextTag.new($twind_text,
56                            'justify' =>'center',
57                            'spacing1'=>'5m',
58                            'spacing3'=>'5m'  )
59$tag_buttons = TkTextTag.new($twind_text,
60                             'lmargin1'=>'1c',
61                             'lmargin2'=>'1c',
62                             'rmargin' =>'1c',
63                             'spacing1'=>'3m',
64                             'spacing2'=>0,
65                             'spacing3'=>0 )
66
67# テキストの生成
68$twind_text.insert('end',
69                  'テキストwidget上に他のwidgetを組み込むことができます。')
70$twind_text.insert('end',
71                  '組み込みウィンドウと呼ばれ、任意のwidgetが可能です。')
72$twind_text.insert('end',
73                  '例えば、ここに2つのボタンwidgetが組み込まれています。')
74$twind_text.insert('end', '最初のボタンをクリックすと水平方向のスクロールを')
75TkTextWindow.new($twind_text, 'end',
76                 'window'=>TkButton.new($twind_text) {
77                   #text 'ON'
78                   text 'オン'
79                   command proc{textWindOn $twind_text,$twind_buttons}
80                   cursor 'top_left_arrow'
81                 })
82$twind_text.insert('end', "にします。また2つめのボタンをクリックすると\n")
83$twind_text.insert('end', '水平方向のスクロールを')
84TkTextWindow.new($twind_text, 'end',
85                 'window'=>TkButton.new($twind_text) {
86                   #text 'OFF'
87                   text 'オフ'
88                   command proc{textWindOff $twind_text}
89                   cursor 'top_left_arrow'
90                 })
91$twind_text.insert('end', 'にします。')
92
93$twind_text.insert('end', 'もうひとつの例です。')
94TkTextWindow.new($twind_text, 'end',
95                 'window'=>TkButton.new($twind_text) {
96                   text 'ここをクリック'
97                   command proc{textWindPlot $twind_text}
98                   cursor 'top_left_arrow'
99                 })
100$twind_text.insert('end', 'すると、x-yプロットがここに現れます。')
101$mark_plot = TkTextMark.new($twind_text, 'insert')
102$mark_plot.gravity='left'
103$twind_text.insert('end', 'マウスでデータを描画することができます。')
104TkTextWindow.new($twind_text, 'end',
105                 'window'=>TkButton.new($twind_text) {
106                   text '消去'
107                   command proc{textWindDel $twind_text}
108                   cursor 'top_left_arrow'
109                 })
110$twind_text.insert('end', 'をクリックすると元に戻ります。
111
112')
113
114$twind_text.insert('end', '組み込みウィンドウだけをテキストwidget上に、実際の')
115$twind_text.insert('end', 'テキストはなしで組み込むことは便利です。')
116$twind_text.insert('end', 'この場合は、テキストwidgetはウィンドウマネージャの')
117$twind_text.insert('end', 'ように動作します。例えば、ここにはテキストwidgetに')
118$twind_text.insert('end', 'よってボタンがきれいに並べられています。')
119$twind_text.insert('end', 'これらのボタンで背景色を変えることができます')
120$twind_text.insert('end', '("Default"で元の色に戻すことができます)。')
121$twind_text.insert('end', '"Short"というボタンをクリックすると文字列の長さが')
122$twind_text.insert('end', '変わります。すると自動的にテキストwidgetが')
123$twind_text.insert('end', 'レイアウトを整えてくれます。')
124$twind_text.insert('end', 'もう一度同じボタンを押すと元に戻ります。
125
126')
127
128TkTextWindow.new($twind_text, 'end',
129                 'window'=>TkButton.new($twind_text) {|b|
130                   text 'デフォルト'
131                   command proc{embDefBg $twind_text}
132                   cursor 'top_left_arrow'
133                   $tag_buttons.add('end')
134                 },
135                 'padx'=>3 )
136embToggle = TkVariable.new('Short')
137TkTextWindow.new($twind_text, 'end',
138                 'window'=>TkCheckButton.new($twind_text) {
139                   textvariable embToggle
140                   indicatoron 0
141                   variable embToggle
142                   onvalue 'A much longer string'
143                   offvalue 'Short'
144                   cursor 'top_left_arrow'
145                   pady 5
146                   padx 2
147                 },
148                 'padx'=>3,
149                 'pady'=>2 )
150
151[ 'AntiqueWhite3', 'Bisque1', 'Bisque2', 'Bisque3', 'Bisque4',
152  'SlateBlue3', 'RoyalBlue1', 'SteelBlue2', 'DeepSkyBlue3', 'LightBlue1',
153  'DarkSlateGray1', 'Aquamarine2', 'DarkSeaGreen2', 'SeaGreen1',
154  'Yellow1', 'IndianRed1', 'IndianRed2', 'Tan1', 'Tan4'
155].each{|twind_color|
156  TkTextWindow.new($twind_text, 'end',
157                   'window'=>TkButton.new($twind_text) {
158                     text twind_color
159                     cursor 'top_left_arrow'
160                     command proc{$twind_text.bg twind_color}
161                   },
162                   'padx'=>3,
163                   'pady'=>2 )
164}
165
166# メソッド定義
167def textWindOn (w,f)
168  if defined? $twind_scroll
169    begin
170      $twind_scroll.destroy
171    rescue
172    end
173    $twind_scroll = nil
174  end
175
176  base = TkWinfo.parent( TkWinfo.parent(w) )
177  $twind_scroll = TkScrollbar.new(base) {|s|
178    orient 'horizontal'
179    command proc{|*args| w.xview(*args)}
180    w.xscrollcommand proc{|first,last| s.set first,last}
181    w.wrap 'none'
182    pack('after'=>f, 'side'=>'bottom', 'fill'=>'x')
183  }
184
185  return nil
186end
187
188def textWindOff (w)
189  if defined? $twind_scroll
190    begin
191      $twind_scroll.destroy
192    rescue
193    end
194    $twind_scroll = nil
195  end
196  w.xscrollcommand ''
197  w.wrap 'word'
198end
199
200def textWindPlot (t)
201  if (defined? $twind_plot) && (TkWinfo.exist?($twind_plot))
202    return
203  end
204
205  $twind_plot = TkCanvas.new(t) {
206    relief 'sunken'
207    width  450
208    height 300
209    cursor 'top_left_arrow'
210  }
211
212  if $tk_version =~ /^4.*/
213    font = '-Adobe-Helvetica-Medium-R-Normal--*-180-*-*-*-*-*-*'
214  else
215    font = 'Helvetica 18'
216  end
217
218  TkcLine.new($twind_plot, 100, 250, 400, 250, 'width'=>2)
219  TkcLine.new($twind_plot, 100, 250, 100,  50, 'width'=>2)
220  TkcText.new($twind_plot, 225, 20,
221              'text'=>"A Simple Plot", 'font'=>font, 'fill'=>'brown')
222
223  (0..10).each {|i|
224    x = 100 + (i * 30)
225    TkcLine.new($twind_plot, x, 250, x, 245, 'width'=>2)
226    TkcText.new($twind_plot, x, 254,
227                'text'=>10*i, 'font'=>font, 'anchor'=>'n')
228  }
229  (0..5).each {|i|
230    y = 250 - (i * 40)
231    TkcLine.new($twind_plot, 100, y, 105, y, 'width'=>2)
232    TkcText.new($twind_plot, 96, y,
233                'text'=>"#{i*50}.0", 'font'=>font, 'anchor'=>'e')
234  }
235
236  for xx, yy in [[12,56],[20,94],[33,98],[32,120],[61,180],[75,160],[98,223]]
237    x = 100 + (3*xx)
238    y = 250 - (4*yy)/5
239    item = TkcOval.new($twind_plot, x-6, y-6, x+6, y+6,
240                       'width'=>1, 'outline'=>'black', 'fill'=>'SkyBlue2')
241    item.addtag 'point'
242  end
243
244  $twind_plot.itembind('point', 'Any-Enter',
245                        proc{$twind_plot.itemconfigure 'current', 'fill', 'red'})
246  $twind_plot.itembind('point', 'Any-Leave',
247                        proc{$twind_plot.itemconfigure 'current', 'fill', 'SkyBlue2'})
248  $twind_plot.itembind('point', '1',
249                        proc{|x,y| embPlotDown $twind_plot,x,y}, "%x %y")
250  $twind_plot.itembind('point', 'ButtonRelease-1',
251                        proc{$twind_plot.dtag 'selected'})
252  $twind_plot.bind('B1-Motion',
253                    proc{|x,y| embPlotMove $twind_plot,x,y}, "%x %y")
254  while ($twind_text.get($mark_plot) =~ /[ \t\n]/)
255    $twind_text.delete $mark_plot
256  end
257  $twind_text.insert $mark_plot,"\n"
258  TkTextWindow.new($twind_text, $mark_plot, 'window'=>$twind_plot)
259  $tag_center.add $mark_plot
260  $twind_text.insert $mark_plot,"\n"
261end
262
263$embPlot = {'lastX'=>0, 'lastY'=>0}
264
265def embPlotDown (w, x, y)
266  w.dtag 'selected'
267  w.addtag_withtag 'selected', 'current'
268  w.raise 'current'
269  $embPlot['lastX'] = x
270  $embPlot['lastY'] = y
271end
272
273def embPlotMove (w, x, y)
274  w.move 'selected', x - $embPlot['lastX'], y - $embPlot['lastY']
275  $embPlot['lastX'] = x
276  $embPlot['lastY'] = y
277end
278
279def textWindDel (w)
280  if (defined? $twind_text) && TkWinfo.exist?($twind_plot)
281    $twind_text.delete $twind_plot
282    $twind_plot = nil
283    while ($twind_text.get($mark_plot) =~ /[ \t\n]/)
284      $twind_text.delete $mark_plot
285    end
286    $twind_text.insert $mark_plot,"  "
287  end
288end
289
290def embDefBg (w)
291  w['background'] = w.configinfo('background')[3]
292end
293