1#
2# tk/toplevel.rb : treat toplevel widget
3#
4require 'tk'
5require 'tk/wm'
6require 'tk/menuspec'
7
8class Tk::Toplevel<TkWindow
9  include Wm
10  include TkMenuSpec
11
12  TkCommandNames = ['toplevel'.freeze].freeze
13  WidgetClassName = 'Toplevel'.freeze
14  WidgetClassNames[WidgetClassName] ||= self
15
16################# old version
17#  def initialize(parent=nil, screen=nil, classname=nil, keys=nil)
18#    if screen.kind_of? Hash
19#      keys = screen.dup
20#    else
21#      @screen = screen
22#    end
23#    @classname = classname
24#    if keys.kind_of? Hash
25#      keys = keys.dup
26#      @classname = keys.delete('classname') if keys.key?('classname')
27#      @colormap  = keys.delete('colormap')  if keys.key?('colormap')
28#      @container = keys.delete('container') if keys.key?('container')
29#      @screen    = keys.delete('screen')    if keys.key?('screen')
30#      @use       = keys.delete('use')       if keys.key?('use')
31#      @visual    = keys.delete('visual')    if keys.key?('visual')
32#    end
33#    super(parent, keys)
34#  end
35#
36#  def create_self
37#    s = []
38#    s << "-class"     << @classname if @classname
39#    s << "-colormap"  << @colormap  if @colormap
40#    s << "-container" << @container if @container
41#    s << "-screen"    << @screen    if @screen
42#    s << "-use"       << @use       if @use
43#    s << "-visual"    << @visual    if @visual
44#    tk_call 'toplevel', @path, *s
45#  end
46#################
47
48  def __boolval_optkeys
49    super() << 'container'
50  end
51  private :__boolval_optkeys
52
53  def __strval_optkeys
54    super() << 'screen'
55  end
56  private :__strval_optkeys
57
58  def __val2ruby_optkeys  # { key=>proc, ... }
59    super().update('menu'=>proc{|v| window(v)})
60  end
61  private :__val2ruby_optkeys
62
63  def __methodcall_optkeys  # { key=>method, ... }
64    TOPLEVEL_METHODCALL_OPTKEYS
65  end
66  private :__methodcall_optkeys
67
68  def _wm_command_option_chk(keys)
69    keys = {} unless keys
70    new_keys = {}
71    wm_cmds = {}
72
73    conf_methods = _symbolkey2str(__methodcall_optkeys())
74
75    keys.each{|k,v| # k is a String
76      if conf_methods.key?(k)
77        wm_cmds[conf_methods[k]] = v
78      elsif Wm.method_defined?(k)
79        case k
80        when 'screen','class','colormap','container','use','visual'
81          new_keys[k] = v
82        else
83          case self.method(k).arity
84          when -1,1
85            wm_cmds[k] = v
86          else
87            new_keys[k] = v
88          end
89        end
90      else
91        new_keys[k] = v
92      end
93    }
94    [new_keys, wm_cmds]
95  end
96  private :_wm_command_option_chk
97
98  def initialize(parent=nil, screen=nil, classname=nil, keys=nil)
99    my_class_name = nil
100    if self.class < WidgetClassNames[WidgetClassName]
101      my_class_name = self.class.name
102      my_class_name = nil if my_class_name == ''
103    end
104    if parent.kind_of? Hash
105      keys = _symbolkey2str(parent)
106      if keys.key?('classname')
107        keys['class'] = keys.delete('classname')
108      end
109      @classname = keys['class']
110      @colormap  = keys['colormap']
111      @container = keys['container']
112      @screen    = keys['screen']
113      @use       = keys['use']
114      @visual    = keys['visual']
115      if !@classname && my_class_name
116        keys['class'] = @classname = my_class_name
117      end
118      if @classname.kind_of? TkBindTag
119        @db_class = @classname
120        keys['class'] = @classname = @classname.id
121      elsif @classname
122        @db_class = TkDatabaseClass.new(@classname)
123        keys['class'] = @classname
124      else
125        @db_class = self.class
126        @classname = @db_class::WidgetClassName
127      end
128      keys, cmds = _wm_command_option_chk(keys)
129      super(keys)
130      cmds.each{|k,v|
131        if v.kind_of? Array
132          self.__send__(k,*v)
133        else
134          self.__send__(k,v)
135        end
136      }
137      return
138    end
139
140    if screen.kind_of? Hash
141      keys = screen
142    else
143      @screen = screen
144      if classname.kind_of? Hash
145        keys = classname
146      else
147        @classname = classname
148      end
149    end
150    if keys.kind_of? Hash
151      keys = _symbolkey2str(keys)
152      if keys.key?('classname')
153        keys['class'] = keys.delete('classname')
154      end
155      @classname = keys['class']  unless @classname
156      @colormap  = keys['colormap']
157      @container = keys['container']
158      @screen    = keys['screen'] unless @screen
159      @use       = keys['use']
160      @visual    = keys['visual']
161    else
162      keys = {}
163    end
164    if !@classname && my_class_name
165      keys['class'] = @classname = my_class_name
166    end
167    if @classname.kind_of? TkBindTag
168      @db_class = @classname
169      keys['class'] = @classname = @classname.id
170    elsif @classname
171      @db_class = TkDatabaseClass.new(@classname)
172      keys['class'] = @classname
173    else
174      @db_class = self.class
175      @classname = @db_class::WidgetClassName
176    end
177    keys, cmds = _wm_command_option_chk(keys)
178    super(parent, keys)
179    cmds.each{|k,v|
180      if v.kind_of? Array
181        self.send(k,*v)
182      else
183        self.send(k,v)
184      end
185    }
186  end
187
188  #def create_self(keys)
189  #  if keys and keys != None
190  #    tk_call_without_enc('toplevel', @path, *hash_kv(keys, true))
191  #  else
192  #    tk_call_without_enc('toplevel', @path)
193  #  end
194  #end
195  #private :create_self
196
197  def specific_class
198    @classname
199  end
200
201  def add_menu(menu_info, tearoff=false, opts=nil)
202    # See tk/menuspec.rb for menu_info.
203    # opts is a hash of default configs for all of cascade menus.
204    # Configs of menu_info can override it.
205    if tearoff.kind_of?(Hash)
206      opts = tearoff
207      tearoff = false
208    end
209    _create_menubutton(self, menu_info, tearoff, opts)
210  end
211
212  def add_menubar(menu_spec, tearoff=false, opts=nil)
213    # See tk/menuspec.rb for menu_spec.
214    # opts is a hash of default configs for all of cascade menus.
215    # Configs of menu_spec can override it.
216    menu_spec.each{|info| add_menu(info, tearoff, opts)}
217    self.menu
218  end
219
220  def self.database_class
221    if self == WidgetClassNames[WidgetClassName] || self.name == ''
222      self
223    else
224      TkDatabaseClass.new(self.name)
225    end
226  end
227  def self.database_classname
228    self.database_class.name
229  end
230
231  def self.bind(*args, &b)
232    if self == WidgetClassNames[WidgetClassName] || self.name == ''
233      super(*args, &b)
234    else
235      TkDatabaseClass.new(self.name).bind(*args, &b)
236    end
237  end
238  def self.bind_append(*args, &b)
239    if self == WidgetClassNames[WidgetClassName] || self.name == ''
240      super(*args, &b)
241    else
242      TkDatabaseClass.new(self.name).bind_append(*args, &b)
243    end
244  end
245  def self.bind_remove(*args)
246    if self == WidgetClassNames[WidgetClassName] || self.name == ''
247      super(*args)
248    else
249      TkDatabaseClass.new(self.name).bind_remove(*args)
250    end
251  end
252  def self.bindinfo(*args)
253    if self == WidgetClassNames[WidgetClassName] || self.name == ''
254      super(*args)
255    else
256      TkDatabaseClass.new(self.name).bindinfo(*args)
257    end
258  end
259end
260
261#TkToplevel = Tk::Toplevel unless Object.const_defined? :TkToplevel
262#Tk.__set_toplevel_aliases__(:Tk, Tk::Toplevel, :TkToplevel)
263Tk.__set_loaded_toplevel_aliases__('tk/toplevel.rb', :Tk, Tk::Toplevel,
264                                   :TkToplevel)
265