1#
2#  tkextlib/tcllib/tkpiechart.rb
3#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
4#
5#   * Part of tcllib extension
6#   * Create 2D or 3D pies with labels in Tcl canvases
7#
8
9require 'tk'
10require 'tk/canvas'
11require 'tkextlib/tcllib.rb'
12
13# TkPackage.require('tkpiechart', '6.6')
14TkPackage.require('tkpiechart')
15
16module Tk
17  module Tcllib
18    module Tkpiechart
19    end
20  end
21end
22
23module Tk::Tcllib::Tkpiechart
24  PACKAGE_NAME = 'tkpiechart'.freeze
25  def self.package_name
26    PACKAGE_NAME
27  end
28
29  def self.package_version
30    begin
31      TkPackage.require('tkpiechart')
32    rescue
33      ''
34    end
35  end
36
37  module ConfigMethod
38    include TkConfigMethod
39
40    def __pathname
41      self.path + ';' + self.tag
42    end
43    private :__pathname
44
45    def __cget_cmd
46      ['::switched::cget', self.tag]
47    end
48
49    def __config_cmd
50      ['::switched::configure', self.tag]
51    end
52    private :__config_cmd
53
54    def __configinfo_struct
55      {:key=>0, :alias=>nil, :db_name=>nil, :db_class=>nil,
56        :default_value=>1, :current_value=>2}
57    end
58    private :__configinfo_struct
59
60    def __boolval_optkeys
61      super() << 'select' << 'autoupdate' << 'selectable'
62    end
63    private :__boolval_optkeys
64
65    def __strval_optkeys
66      super() << 'bordercolor' << 'textbackground' <<
67        'widestvaluetext' << 'title'
68    end
69    private :__strval_optkeys
70
71    def __listval_optkeys
72      super() << 'colors'
73    end
74    private :__listval_optkeys
75  end
76
77  ####################################
78  class PieChartObj < TkcItem
79    include ConfigMethod
80
81    def __font_optkeys
82      ['titlefont']
83    end
84    private :__font_optkeys
85  end
86
87  ####################################
88  class Pie < TkcItem
89    include ConfigMethod
90
91    def create_self(x, y, width, height, keys=None)
92      if keys and keys != None
93        @tag_key = tk_call_without_enc('::stooop::new', 'pie',
94                                       @c, x, y, *hash_kv(keys, true))
95      else
96        @tag_key = tk_call_without_enc('::stooop::new', 'pie', @c, x, y)
97      end
98
99      @slice_tbl = {}
100
101      id = "pie(#{@tag_key})"
102
103      @tag = @tag_pie = TkcNamedTag(@c, id)
104      @tag_slices = TkcNamedTag(@c, "pieSlices(#{@tag_key})")
105
106      id
107    end
108    private :create_self
109
110    def tag_key
111      @tag_key
112    end
113    def tag
114      @tag
115    end
116    def canvas
117      @c
118    end
119    def _entry_slice(slice)
120      @slice_tbl[slice.to_eval] = slice
121    end
122    def _delete_slice(slice)
123      @slice_tbl.delete(slice.to_eval)
124    end
125
126    def delete
127      tk_call_without_enc('::stooop::delete', @tag_key)
128      CItemID_TBL.mutex.synchronize{
129        CItemID_TBL[@path].delete(@id) if CItemID_TBL[@path]
130      }
131      self
132    end
133
134    def new_slice(text=None)
135      Slice.new(self, text)
136    end
137
138    def delete_slice(slice)
139      unless slice.kind_of?(Slice)
140        unless (slice = @slice_tbl[slice])
141          return tk_call_without_enc('pie::deleteSlice', @tag_key, slice)
142        end
143      end
144      unless slice.kind_of?(Slice) && slice.pie == self
145        fail ArgumentError, "argument is not a slice of self"
146      end
147      slice.delete
148    end
149
150    def selected_slices
151      tk_split_simplelist(tk_call_without_enc('pie::selectedSlices',
152                                              @tag_key)).collect{|slice|
153        @slice_tbl[slice] || Slice.new(:no_create, self, slice)
154      }
155    end
156  end
157
158  ####################################
159  class Slice < TkcItem
160    include ConfigMethod
161
162    def __config_cmd
163      ['::switched::configure', self.tag]
164    end
165    private :__config_cmd
166
167    #------------------------
168
169    def initialize(pie, *args)
170      unless pie.kind_of?(Pie) && pie != :no_create
171        fail ArgumentError, "expects TkPiechart::Pie for 1st argument"
172      end
173
174      if pie == :no_create
175        @pie, @tag_key = args
176      else
177        text = args[0] || None
178        @pie = pie
179        @tag_key = tk_call_without_enc('pie::newSlice', @pie.tag_key, text)
180      end
181      @parent = @c = @pie.canvas
182      @path = @parent.path
183
184      @pie._entry_slice(self)
185
186      @id = "slices(#{@tag_key})"
187      @tag = TkcNamedTag.new(@pie.canvas, @id)
188
189      CItemID_TBL.mutex.synchronize{
190        CItemID_TBL[@path] = {} unless CItemID_TBL[@path]
191        CItemID_TBL[@path][@id] = self
192      }
193    end
194
195    def tag_key
196      @tag_key
197    end
198    def tag
199      @tag
200    end
201    def pie
202      @pie
203    end
204
205    def delete
206      tk_call_without_enc('pie::deleteSlice', @pie.tag_key, @tag_key)
207      CItemID_TBL.mutex.synchronize{
208        CItemID_TBL[@path].delete(@id) if CItemID_TBL[@path]
209      }
210      @pie._delete_slice(self)
211      self
212    end
213
214    def size(share, disp=None)
215      tk_call_without_enc('pie::sizeSlice',
216                          @pie.tag_key, @tag_key, share, disp)
217      self
218    end
219
220    def label(text)
221      tk_call_without_enc('pie::labelSlice', @pie.tag_key, @tag_key, text)
222      self
223    end
224  end
225
226  ####################################
227  class BoxLabeler < TkcItem
228    include ConfigMethod
229
230    def __config_cmd
231      ['::switched::configure', self.tag]
232    end
233    private :__config_cmd
234
235    #------------------------
236
237    def create_self(keys=None)
238      if keys and keys != None
239        @tag_key = tk_call_without_enc('::stooop::new', 'pieBoxLabeler',
240                                       *hash_kv(keys, true))
241      else
242        @tag_key = tk_call_without_enc('::stooop::new', 'pieBoxLabeler')
243      end
244
245      id = "pieBoxLabeler(#{@tag_key})"
246      @tag = TkcNamedTag(@c, id)
247
248      id
249    end
250    private :create_self
251  end
252
253  ####################################
254  class PeripheralLabeler < TkcItem
255    include ConfigMethod
256
257    def __font_optkeys
258      ['font', 'smallfont']
259    end
260    private :__font_optkeys
261
262    def __config_cmd
263      ['::switched::configure', self.tag]
264    end
265    private :__config_cmd
266
267    #------------------------
268
269    def create_self(keys=None)
270      if keys and keys != None
271        @tag_key = tk_call_without_enc('::stooop::new',
272                                       'piePeripheralLabeler',
273                                       *hash_kv(keys, true))
274      else
275        @tag_key = tk_call_without_enc('::stooop::new', 'piePeripheralLabeler')
276      end
277
278      id = "piePeripheralLabeler(#{@tag_key})"
279      @tag = TkcNamedTag(@c, id)
280
281      id
282    end
283    private :create_self
284  end
285
286  ####################################
287  class Label < TkcItem
288    include ConfigMethod
289
290    def __config_cmd
291      ['::switched::configure', self.tag]
292    end
293    private :__config_cmd
294
295    #------------------------
296
297    def create_self(x, y, keys=None)
298      if keys and keys != None
299        @tag_key = tk_call_without_enc('::stooop::new', 'canvasLabel',
300                                       @c, x, y, width, height,
301                                       *hash_kv(keys, true))
302      else
303        @tag_key = tk_call_without_enc('::stooop::new', 'canvasLabel',
304                                       @c, x, y, width, height)
305      end
306
307      id = "canvasLabel(#{@tag_key})"
308      @tag = TkcNamedTag(@c, id)
309
310      id
311    end
312    private :create_self
313  end
314end
315