1#
2#  ::vu::pie widget
3#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
4#
5require 'tk'
6
7# create module/class
8module Tk
9  module Vu
10    module PieSliceConfigMethod
11    end
12    class Pie < TkWindow
13    end
14    class PieSlice < TkObject
15    end
16    class NamedPieSlice < PieSlice
17    end
18  end
19end
20
21# call setup script  --  <libdir>/tkextlib/vu.rb
22require 'tkextlib/vu.rb'
23
24module Tk::Vu::PieSliceConfigMethod
25  include TkItemConfigMethod
26
27  def __item_pathname(tagOrId)
28    if tagOrId.kind_of?(Tk::Vu::PieSlice)
29      self.path + ';' + tagOrId.id.to_s
30    else
31      self.path + ';' + tagOrId.to_s
32    end
33  end
34  private :__item_pathname
35end
36
37class Tk::Vu::Pie < TkWindow
38  TkCommandNames = ['::vu::pie'.freeze].freeze
39  WidgetClassName = 'Pie'.freeze
40  WidgetClassNames[WidgetClassName] ||= self
41
42  def __destroy_hook__
43    Tk::Vu::PieSlice::SliceID_TBL.delete(@path)
44  end
45
46  ###############################
47
48  include Tk::Vu::PieSliceConfigMethod
49
50  def tagid(tag)
51    if tag.kind_of?(Tk::Vu::PieSlice)
52      tag.id
53    else
54      # tag
55      _get_eval_string(tag)
56    end
57  end
58
59  ###############################
60
61  def delete(*glob_pats)
62    tk_call(@path, 'delete', *glob_pats)
63    self
64  end
65
66  def explode(slice, *args)
67    tk_call(@path, 'explode', slice, *args)
68    self
69  end
70
71  def explode_value(slice)
72    num_or_str(tk_call(@path, 'explode', slice))
73  end
74
75  def lower(slice, below=None)
76    tk_call(@path, 'lower', slice, below)
77    self
78  end
79
80  def names(*glob_pats)
81    simplelist(tk_call(@path, 'names', *glob_pats))
82  end
83  alias slices names
84
85  def order(*args)
86    tk_call(@path, 'order', *args)
87    self
88  end
89
90  def raise(slice, above=None)
91    tk_call(@path, 'raise', slice, above)
92    self
93  end
94
95  def swap(slice1, slice2)
96    tk_call(@path, 'swap', slice1, slice2)
97    self
98  end
99
100  def set(slice, *args)
101    num_or_str(tk_call(@path, 'set', slice, *args))
102  end
103  alias set_value  set
104  alias set_values set
105  alias create     set
106
107  def slice_value(slice)
108    num_or_str(tk_call(@path, 'set', slice))
109  end
110
111  def value(val = None)
112    num_or_str(tk_call_without_enc(@path, 'value'))
113  end
114  alias sum_value value
115end
116
117class Tk::Vu::PieSlice
118  SliceID_TBL = TkCore::INTERP.create_table
119
120  (Pie_Slice_ID = ['vu:pie'.freeze, TkUtil.untrust('00000')]).instance_eval{
121    @mutex = Mutex.new
122    def mutex; @mutex; end
123    freeze
124  }
125
126  TkCore::INTERP.init_ip_env{
127    SliceID_TBL.mutex.synchronize{ SliceID_TBL.clear }
128  }
129
130  def self.id2obj(pie, id)
131    pie_path = pie.path
132    SliceID_TBL.mutex.synchronize{
133      if SliceID_TBL[pie_path]
134        SliceID_TBL[pie_path][id]? SliceID_TBL[pie_path][id]: id
135      else
136        id
137      end
138    }
139  end
140
141  def initialize(parent, *args)
142    unless parent.kind_of?(Tk::Vu::Pie)
143      fail ArgumentError, "expect a Tk::Vu::Pie instance for 1st argument"
144    end
145    @parent = @pie = parent
146    @ppath = parent.path
147    Pie_Slice_ID.mutex.synchronize{
148      @path = @id = Pie_Slice_ID.join(TkCore::INTERP._ip_id_)
149      Pie_Slice_ID[1].succ!
150    }
151    SliceID_TBL.mutex.synchronize{
152      SliceID_TBL[@ppath] = {} unless SliceID_TBL[@ppath]
153      SliceID_TBL[@ppath][@id] = self
154    }
155
156    if args[-1].kind_of?(Hash)
157      keys = args.unshift
158    end
159    @pie.set(@id, *args)
160    configure(keys)
161  end
162
163  def id
164    @id
165  end
166
167  def [](key)
168    cget key
169  end
170
171  def []=(key,val)
172    configure key, val
173    val
174  end
175
176  def cget_tkstring(slot)
177    @pie.itemcget_tkstring(@id, slot)
178  end
179
180  def cget(slot)
181    @pie.itemcget(@id, slot)
182  end
183
184  def cget_strict(slot)
185    @pie.itemcget_strict(@id, slot)
186  end
187
188  def configure(*args)
189    @pie.itemconfigure(@id, *args)
190    self
191  end
192
193  def configinfo(*args)
194    @pie.itemconfiginfo(@id, *args)
195  end
196
197  def current_configinfo(*args)
198    @pie.current_itemconfiginfo(@id, *args)
199  end
200
201  def delete
202    @pie.delete(@id)
203  end
204
205  def explode(value)
206    @pie.explode(@id, value)
207    self
208  end
209
210  def explode_value
211    @pie.explode_value(@id)
212  end
213
214  def lower(other=None)
215    @pie.lower(@id, other)
216    self
217  end
218
219  def raise(other=None)
220    @pie.raise(@id, other)
221    self
222  end
223
224  def set(value)
225    @pie.set(@id, value)
226    self
227  end
228  alias set_value set
229
230  def value
231    @pie.set(@id)
232  end
233end
234
235class Tk::Vu::NamedPieSlice
236  def self.new(parent, name, *args)
237    obj = nil
238    SliceID_TBL.mutex.synchronize{
239      if SliceID_TBL[parent.path] && SliceID_TBL[parent.path][name]
240        obj = SliceID_TBL[parent.path][name]
241      else
242        #super(parent, name, *args)
243        unless parent.kind_of?(Tk::Vu::Pie)
244          fail ArgumentError, "expect a Tk::Vu::Pie instance for 1st argument"
245        end
246        obj = self.allocate
247        obj.instance_eval{
248          @parent = @pie = parent
249          @ppath = parent.path
250          @path = @id = name.to_s
251          SliceID_TBL[@ppath] = {} unless SliceID_TBL[@ppath]
252          SliceID_TBL[@ppath][@id] = self
253        }
254      end
255    }
256    obj.instance_eval{
257      if args[-1].kind_of?(Hash)
258        keys = args.unshift
259      end
260      @pie.set(@id, *args)
261      configure(keys)
262    }
263
264    obj
265  end
266
267  def initialize(parent, name, *args)
268    # dummy:: not called by 'new' method
269    unless parent.kind_of?(Tk::Vu::Pie)
270      fail ArgumentError, "expect a Tk::Vu::Pie instance for 1st argument"
271    end
272    @parent = @pie = parent
273    @ppath = parent.path
274    @path = @id = name.to_s
275    SliceID_TBL.mutex.synchronize{
276      SliceID_TBL[@ppath] = {} unless SliceID_TBL[@ppath]
277      SliceID_TBL[@ppath][@id] = self
278    }
279
280    if args[-1].kind_of?(Hash)
281      keys = args.unshift
282    end
283    @pie.set(@id, *args)
284    configure(keys)
285  end
286end
287