1#
2#  tkextlib/blt/watch.rb
3#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
4#
5
6require 'tk'
7require 'tkextlib/blt.rb'
8
9module Tk::BLT
10  class Watch < TkObject
11    extend TkCore
12
13    TkCommandNames = ['::blt::watch'.freeze].freeze
14
15    WATCH_ID_TBL = TkCore::INTERP.create_table
16
17    (BLT_WATCH_ID = ['blt_watch_id'.freeze, TkUtil.untrust('00000')]).instance_eval{
18      @mutex = Mutex.new
19      def mutex; @mutex; end
20      freeze
21    }
22
23    TkCore::INTERP.init_ip_env{
24      WATCH_ID_TBL.mutex.synchronize{ WATCH_ID_TBL.clear }
25    }
26
27    def self.names(state = None)
28      lst = tk_split_list(tk_call('::blt::watch', 'names', state))
29      WATCH_ID_TBL.mutex.synchronize{
30        lst.collect{|name|
31          WATCH_ID_TBL[name] || name
32        }
33      }
34    end
35
36    def __numval_optkeys
37      ['maxlevel']
38    end
39    private :__numval_optkeys
40
41    def __boolval_optkeys
42      ['active']
43    end
44    private :__boolval_optkeys
45
46    def __config_cmd
47      ['::blt::watch', 'configure', self.path]
48    end
49    private :__config_cmd
50
51    def initialize(name = nil, keys = {})
52      if name.kind_of?(Hash)
53        keys = name
54        name = nil
55      end
56
57      if name
58        @id = name.to_s
59      else
60        BLT_WATCH_ID.mutex.synchronize{
61          @id = BLT_WATCH_ID.join(TkCore::INTERP._ip_id_)
62          BLT_WATCH_ID[1].succ!
63        }
64      end
65
66      @path = @id
67
68      WATCH_ID_TBL.mutex.synchronize{
69        WATCH_ID_TBL[@id] = self
70      }
71      tk_call('::blt::watch', 'create', @id, *hash_kv(keys))
72    end
73
74    def activate
75      tk_call('::blt::watch', 'activate', @id)
76      self
77    end
78    def deactivate
79      tk_call('::blt::watch', 'deactivate', @id)
80      self
81    end
82    def delete
83      tk_call('::blt::watch', 'delete', @id)
84      self
85    end
86    def info
87      ret = []
88      lst = tk_split_simplelist(tk_call('::blt::watch', 'info', @id))
89      until lst.empty?
90        k, v, *lst = lst
91        k = k[1..-1]
92        case k
93        when /^(#{__strval_optkeys.join('|')})$/
94          # do nothing
95
96        when /^(#{__numval_optkeys.join('|')})$/
97          begin
98            v = number(v)
99          rescue
100            v = nil
101          end
102
103        when /^(#{__numstrval_optkeys.join('|')})$/
104          v = num_or_str(v)
105
106        when /^(#{__boolval_optkeys.join('|')})$/
107          begin
108            v = bool(v)
109          rescue
110            v = nil
111          end
112
113        when /^(#{__listval_optkeys.join('|')})$/
114          v = simplelist(v)
115
116        when /^(#{__numlistval_optkeys.join('|')})$/
117          v = list(v)
118
119        else
120          if v.index('{')
121            v = tk_split_list(v)
122          else
123            v = tk_tcl2ruby(v)
124          end
125        end
126
127        ret << [k, v]
128      end
129
130      ret
131    end
132    def configinfo(slot = nil)
133      if slot
134        slot = slot.to_s
135        v = cget(slot)
136        if TkComm::GET_CONFIGINFO_AS_ARRAY
137          [slot, v]
138        else
139          {slot=>v}
140        end
141      else
142        if TkComm::GET_CONFIGINFO_AS_ARRAY
143          info
144        else
145          Hash[*(info.flatten)]
146        end
147      end
148    end
149    def cget_strict(key)
150      key = key.to_s
151      begin
152        info.assoc(key)[1]
153      rescue
154        fail ArgumentError, "unknown option '#{key}'"
155      end
156    end
157    def cget(key)
158      unless TkConfigMethod.__IGNORE_UNKNOWN_CONFIGURE_OPTION__
159        cget_strict(key)
160      else
161        begin
162          cget_strict(key)
163        rescue => e
164          if current_configinfo.has_key?(key.to_s)
165            # error on known option
166            fail e
167          else
168            # unknown option
169            nil
170          end
171        end
172      end
173    end
174  end
175end
176