BLT::Tabnotebook - tabnotebook.tcl not found

Hi,

I tried to use BLT::Tabnotebook to put my existing Tk components in
Tabs, but it just doesn’t work.
A simple example:

require ‘tk’
require ‘tkextlib/blt’

parent = Tk::BLT::Tile::Frame.new

Tk::BLT::Tile::Label.new(parent)

Tk::BLT::Tabnotebook.new(parent)

gives

/usr/lib/ruby/1.8/tk.rb:1807:in _invoke_without_enc': couldn't read file "tabnotebook.tcl": no such file or directory (RuntimeError) from /usr/lib/ruby/1.8/tk.rb:1807:in_ip_invoke_core’
from /usr/lib/ruby/1.8/tk.rb:1843:in _tk_call_core' from /usr/lib/ruby/1.8/tk.rb:1871:intk_call_without_enc’
from /usr/lib/ruby/1.8/tk.rb:4920:in create_self' from /usr/lib/ruby/1.8/tk.rb:4875:ininitialize’
from /home/philip/workspaces/ruby/test/tabtest.rb:8:in `new’
from /home/philip/workspaces/ruby/test/tabtest.rb:8

So, what did I do wrong? There’s a tabnotebook.tcl in /usr/lib/blt2.4 .

From: Philip Müller [email protected]
Subject: BLT::Tabnotebook - tabnotebook.tcl not found
Date: Sat, 22 Nov 2008 03:57:43 +0900
Message-ID: [email protected]

I tried to use BLT::Tabnotebook to put my existing Tk components in
Tabs, but it just doesn’t work.

I’m very sorry. Probably, it depends on a bug on tkextlib/blt.rb.
Please try the following patch.

Index: blt/vector.rb

— blt/vector.rb (revision 20298)
+++ blt/vector.rb (working copy)
@@ -49,11 +49,11 @@
size = size.join(‘:’)
end
if size

  •    @id = INTERP._invoke('::blt::vector', 'create',
    
  •                         "#auto(#{size})", *hash_kv(keys))
    
  •    @id = TkCore::INTERP._invoke('::blt::vector', 'create',
    
  •                                 "#auto(#{size})", *hash_kv(keys))
     else
    
  •    @id = INTERP._invoke('::blt::vector', 'create',
    
  •                         "#auto", *hash_kv(keys))
    
  •    @id = TkCore::INTERP._invoke('::blt::vector', 'create',
    
  •                                 "#auto", *hash_kv(keys))
     end
    
     TkVar_ID_TBL.mutex.synchronize{
    

@@ -68,7 +68,7 @@
@trace_opts = nil

   # teach Tk-ip that @id is global var
  •  INTERP._invoke_without_enc('global', @id)
    
  •  TkCore::INTERP._invoke_without_enc('global', @id)
    

    end

    def destroy
    @@ -250,7 +250,7 @@
    @trace_opts = nil

     # teach Tk-ip that @id is global var
    
  •  INTERP._invoke_without_enc('global', @id)
    
  •  TkCore::INTERP._invoke_without_enc('global', @id)
    

    end
    end
    end
    Index: blt.rb
    ===================================================================
    — blt.rb (revision 20298)
    +++ blt.rb (working copy)
    @@ -26,14 +26,14 @@
    PATCH_LEVEL = tk_call(‘set’, ‘blt_patchLevel’)

    begin

  •  lib = INTERP._invoke('set', 'blt_library')
    
  •  lib = TkCore::INTERP._invoke('set', 'blt_library')
    

    rescue
    lib = ‘’
    end
    LIBRARY = TkVarAccess.new(‘blt_library’, lib)

    begin

  •  lib = INTERP._invoke('set', 'blt_libPath')
    
  •  lib = TkCore::INTERP._invoke('set', 'blt_libPath')
    
    rescue
    lib = ‘’
    end

From: Philip Müller [email protected]
Subject: Re: BLT::Tabnotebook - tabnotebook.tcl not found
Date: Sun, 23 Nov 2008 04:25:27 +0900
Message-ID: [email protected]

/usr/lib/ruby/1.8/tk.rb:2762:in `__invoke’: unknown option
“blt_tabset_tab00000” (RuntimeError)
(snip)
Is this my fault this time?

I’m sorry. It’s MY fault.
I misunderstood the relation between Tabset and Tabnotebook.
So, tabnotebook.rb doesn’t work properly.
I’ll rewrite tabnotebook.rb. Please give me a few days.

Hi,

thanks, Tabnotebook.new works now.
However, if I do this

require ‘tk’
require ‘tkextlib/blt’

parent = Tk::BLT::Tile::Frame.new

nb = Tk::BLT::Tabnotebook.new(parent)

tab = Tk::BLT::Tabset::Tab.new(nb)

I get

/usr/lib/ruby/1.8/tk.rb:2762:in __invoke': unknown option "blt_tabset_tab00000" (RuntimeError) from /usr/lib/ruby/1.8/tk.rb:2762:in_invoke’
from /usr/lib/ruby/1.8/tk.rb:1809:in _ip_invoke_core' from /usr/lib/ruby/1.8/tk.rb:1843:in_tk_call_core’
from /usr/lib/ruby/1.8/tk.rb:1867:in tk_call' from /usr/lib/ruby/1.8/tkextlib/blt/tabset.rb:88:ininitialize’
from /usr/lib/ruby/1.8/tkextlib/blt/tabset.rb:54:in new' from /usr/lib/ruby/1.8/tkextlib/blt/tabset.rb:53:ininstance_eval’
from /usr/lib/ruby/1.8/tkextlib/blt/tabset.rb:53:in new' from /usr/lib/ruby/1.8/tkextlib/blt/tabset.rb:48:insynchronize’
from /usr/lib/ruby/1.8/tkextlib/blt/tabset.rb:48:in `new’
from /home/philip/workspaces/ruby/test/tabtest.rb:8

Is this my fault this time?
I don’t really know how to use the Tabnotebook and tabs. Could you give
me some hints?

From: Hidetoshi NAGAI [email protected]
Subject: Re: BLT::Tabnotebook - tabnotebook.tcl not found
Date: Mon, 24 Nov 2008 08:19:44 +0900
Message-ID: [email protected]

I’ll rewrite tabnotebook.rb. Please give me a few days.

Please try the following patch.
And now, please use Tk::BLT::Tabnotebook::Tab for Tabnotebook objects.
^^^^^^^^^^^

Index: ext/tk/lib/tkextlib/blt/tabset.rb

— ext/tk/lib/tkextlib/blt/tabset.rb (revision 20347)
+++ ext/tk/lib/tkextlib/blt/tabset.rb (working copy)
@@ -27,7 +27,7 @@
tpath = tabset.path
TabID_TBL.mutex.synchronize{
if TabID_TBL[tpath]

  •        TabID_TBL[tpath][id]? TabID_TBL[tpath]: id
    
  •        TabID_TBL[tpath][id]? TabID_TBL[tpath][id]: id
         else
           id
         end
    

@@ -48,6 +48,13 @@
TabID_TBL.mutex.synchronize{
if name && TabID_TBL[parent.path] &&
TabID_TBL[parent.path][name]
obj = TabID_TBL[parent.path][name]

  •        if pos
    
  •          if pos.to_s == 'end'
    
  •            obj.move_after('end')
    
  •          else
    
  •            obj.move_before(pos)
    
  •          end
    
  •        end
           obj.configure if keys && ! keys.empty?
         else
           (obj = self.allocate).instance_eval{
    

@@ -69,9 +76,9 @@
if pos
idx = tk_call(@tpath, ‘index’, ‘-name’, @id)
if pos.to_s == ‘end’

  •            tk_call(@tpath, idx, 'moveto', 'after', 'end')
    
  •            tk_call(@tpath, 'move', idx, 'after', 'end')
             else
    
  •            tk_call(@tpath, idx, 'moveto', 'before', pos)
    
  •            tk_call(@tpath, 'move', idx, 'before', pos)
             end
           end
           tk_call(@tpath, 'tab', 'configure', @id, keys)
    

@@ -80,11 +87,11 @@
tk_call(@tpath, ‘insert’, pos, @id, keys)
end
else

  •      pos = 'end' unless pos
         TabsetTab_ID.mutex.synchronize{
           @path = @id = TabsetTab_ID.join(TkCore::INTERP._ip_id_)
           TabsetTab_ID[1].succ!
         }
    
  •      pos = 'end' unless pos
         tk_call(@tpath, 'insert', pos, @id, keys)
       end
     end
    

@@ -173,10 +180,10 @@
end

   def perforation_highlight(mode)
  •    @t.perforation.highlight(self.index, mode)
    
  •    @t.perforation_highlight(self.index, mode)
     end
     def perforation_invoke()
    
  •    @t.perforation.invoke(self.index)
    
  •    @t.perforation_invoke(self.index)
     end
    
     def see()
    

@@ -335,19 +342,43 @@
end

 def get_tab(index)
  •  Tk::BLT::Tabset::Tab.id2obj(tk_send_without_enc('get', 
    

tagindex(index)))

  •  if (idx = tk_send_without_enc('get', tagindex(index))).empty?
    
  •    nil
    
  •  else
    
  •    Tk::BLT::Tabset::Tab.id2obj(self, idx)
    
  •  end
    

    end

  • def get_tabobj(index)

  •  if (idx = tk_send_without_enc('get', tagindex(index))).empty?
    
  •    nil
    
  •  else
    
  •   Tk::BLT::Tabset::Tab.new(self, nil, name, {})
    
  •  end
    
  • end

    def index(str)
    num_or_str(tk_send(‘index’, str))
    end
    def index_name(tab)

  •  num_or_str(tk_send('index', '-mame', tagid(tab)))
    
  •  num_or_str(tk_send('index', '-name', tagid(tab)))
    

    end

    def insert(pos, tab, keys={})

  •  pos = 'end' if pos.nil?
     Tk::BLT::Tabset::Tab.new(self, tagindex(pos), tagid(tab), keys)
    

    end

  • def insert_tabs(pos, *tabs)

  •  pos = 'end' if pos.nil?
    
  •  if tabs[-1].kind_of?(Hash)
    
  •    keys = tabs.pop
    
  •  else
    
  •    keys = {}
    
  •  end
    
  •  fail ArgumentError, 'no tabs is given' if tabs.empty?
    
  •  tabs.map!{|tab| tagid(tab)}
    
  •  tk_send('insert', tagindex(pos), *(tabs + [keys]))
    
  •  tabs.collect{|tab| Tk::BLT::Tabset::Tab.new(self, nil, 
    

tagid(tab))}

  • end

    def invoke(index)
    tk_send(‘invoke’, tagindex(index))
    @@ -363,16 +394,32 @@
    end

    def nearest(x, y)

Tk::BLT::Tabset::Tab.id2obj(num_or_str(tk_send_without_enc(‘nearest’, x,
y)))

  •  Tk::BLT::Tabset::Tab.id2obj(self, 
    

num_or_str(tk_send_without_enc(‘nearest’, x, y)))
end

  • def perforation_highlight(index, mode)
  •  tk_send('perforation', 'highlight', tagindex(index), mode)
    
  • def perforation_activate(mode)
  •  tk_send('perforation', 'activate', mode)
     self
    
    end
  • def perforation_invoke(index)
  •  tk_send('perforation', 'invoke', tagindex(index))
    
  • def perforation_highlight(index, *args)

  •  if args.empty?
    
  •    # index --> mode
    
  •    tk_send('perforation', 'highlight', index)
    
  •  elsif args.size == 1
    
  •    # args[0] --> mode
    
  •    tk_send('perforation', 'highlight', tagindex(index), args[0])
    
  •  else # Error: call to get Tcl's error message
    
  •    tk_send('perforation', 'highlight', tagindex(index), *args)
    
  •  end
    
  •  self
    

    end

  • def perforation_invoke(index=nil)

  •  if index
    
  •    tk_send('perforation', 'invoke', tagindex(index))
    
  •  else
    
  •    tk_send('perforation', 'invoke')
    
  •  end
    
  • end

    def scan_mark(x, y)
    tk_send_without_enc(‘scan’, ‘mark’, x, y)
    @@ -397,16 +444,39 @@
    self
    end

  • def tab_dockall

  •  tk_send('tab', 'dockall')
    
  •  self
    
  • end

  • def tab_names(pat=None)
    simplelist(tk_send(‘tab’, ‘names’, pat)).collect{|name|

  •    Tk::BLT::Tabset::Tab.id2obj(name)
    
  •    Tk::BLT::Tabset::Tab.id2obj(self, name)
     }
    
    end
  • def tab_tearoff(index, name=None)
  •  window(tk_send('tab', 'tearoff', tagindex(index), name))
    
  • def tab_objs(pat=None)

  •  simplelist(tk_send('tab', 'names', pat)).collect{|name|
    
  •    Tk::BLT::Tabset::Tab.new(self, nil, name, {})
    
  •  }
    

    end

  • def tab_ids(pat=None)

  •  simplelist(tk_send('tab', 'names', pat))
    
  • end

  • def tab_pageheight

  •  number(tk_send('tab', 'pageheight'))
    
  • end

  • def tab_pagewidth

  •  number(tk_send('tab', 'pagewidth'))
    
  • end

  • def tab_tearoff(index, parent=None)

  •  window(tk_send('tab', 'tearoff', tagindex(index), parent))
    
  • end

  • def xscrollcommand(cmd=Proc.new)
    configure_cmd ‘scrollcommand’, cmd
    self
    Index: ext/tk/lib/tkextlib/blt/tabnotebook.rb
    ===================================================================
    — ext/tk/lib/tkextlib/blt/tabnotebook.rb (revision 20347)
    +++ ext/tk/lib/tkextlib/blt/tabnotebook.rb (working copy)
    @@ -13,9 +13,98 @@
    WidgetClassName = ‘Tabnotebook’.freeze
    WidgetClassNames[WidgetClassName] = self

  • class Tab < Tk::BLT::Tabset::Tab

  •  def self.new(parent, pos=nil, name=nil, keys={})
    
  •    if pos.kind_of?(Hash)
    
  •      keys = pos
    
  •      name = nil
    
  •      pos  = nil
    
  •    end
    
  •    if name.kind_of?(Hash)
    
  •      keys = name
    
  •      name = nil
    
  •    end
    
  •    obj = nil
    
  •    TabID_TBL.mutex.synchronize{
    
  •      if name && TabID_TBL[parent.path] && 
    

TabID_TBL[parent.path][name]

  •        obj = TabID_TBL[parent.path][name]
    
  •        if pos
    
  •          if pos.to_s == 'end'
    
  •            obj.move_after('end')
    
  •          else
    
  •            obj.move_before(pos)
    
  •          end
    
  •        end
    
  •        obj.configure if keys && ! keys.empty?
    
  •      else
    
  •        (obj = self.allocate).instance_eval{
    
  •          initialize(parent, pos, name, keys)
    
  •          TabID_TBL[@tpath] = {} unless TabID_TBL[@tpath]
    
  •          TabID_TBL[@tpath][@id] = self
    
  •        }
    
  •      end
    
  •    }
    
  •    obj
    
  •  end
    
  •  def initialize(parent, pos, name, keys)
    
  •    @t = parent
    
  •    @tpath = parent.path
    
  •    if name
    
  •      @path = @id = name
    
  •      unless (list(tk_call(@tpath, 'tab', 'names', @id)).empty?)
    
  •        if pos
    
  •          idx = tk_call(@tpath, 'index', @id)
    
  •          if pos.to_s == 'end'
    
  •            tk_call(@tpath, 'move', idx, 'after', 'end')
    
  •          else
    
  •            tk_call(@tpath, 'move', idx, 'before', pos)
    
  •          end
    
  •        end
    
  •        tk_call(@tpath, 'tab', 'configure', @id, keys)
    
  •      else
    
  •        fail ArgumentError, "can't find tab \"#{@id}\" in #{@t}"
    
  •      end
    
  •    else
    
  •      pos = 'end' unless pos
    
  •      @path = @id = tk_call(@tpath, 'insert', pos, keys)
    
  •    end
    
  •  end
    
  • end
  • #######################################
  • def get_tab(index)
  •  Tk::BLT::Tabset::Tab.id2obj(tk_send_without_enc('id', 
    

tagindex(index)))

  •  if (idx = tk_send_without_enc('id', tagindex(index))).empty?
    
  •    nil
    
  •  else
    
  •    Tk::BLT::Tabset::Tab.id2obj(self, idx)
    
  •  end
    
    end
    alias get_id get_tab
  • def get_tabobj(index)
  •  if (idx = tk_send_without_enc('id', tagindex(index))).empty?
    
  •    nil
    
  •  else
    
  •    Tk::BLT::Tabnotebook::Tab.new(self, nil, idx)
    
  •  end
    
  • end
  • alias index_name index
  • def insert(pos=nil, keys={})
  •  if pos.kind_of?(Hash)
    
  •    keys = pos
    
  •    pos = nil
    
  •  end
    
  •  pos = 'end' if pos.nil?
    
  •  Tk::BLT::Tabnotebook::Tab.new(self, nil,
    
  •                                tk_send('insert', tagindex(pos), 
    

keys))
+

  • end
  • undef :insert_tabs
  • undef :tab_pageheight, :tab_pagewidth
    end
    end

From: Philip Müller [email protected]
Subject: Re: BLT::Tabnotebook - tabnotebook.tcl not found
Date: Thu, 27 Nov 2008 06:39:32 +0900
Message-ID: [email protected]

t1 = Tk::BLT::Tabnotebook::Tab.new(nb)
Tk::BLT::Tile::Label.new(t1)

A Tab object cannot be a parent of other widet.
Please use a Tabnotebook object as a parent of contents.
For example, the following will work.

require ‘tk’
require ‘tkextlib/blt’

nb = Tk::BLT::Tabnotebook.new(TkRoot.new).pack

t1 = Tk::BLT::Tabnotebook::Tab.new(nb)
t1.window = Tk::BLT::Tile::Label.new(nb)

And, the following will work, too.

nb = Tk::BLT::Tabnotebook.new(TkRoot.new).pack

t1 = nb.insert(:end, :text=>‘LABEL1’,
:window=>Tk::BLT::Tile::Label.new(nb, :text=>‘fooooo’))
t2 = nb.insert(:end, :text=>‘LABEL2’,
:window=>Tk::BLT::Tile::Label.new(nb, :text=>‘baaaaa’))

It works!

Thank you very much for all that patching and the example.

Best Regards

Philip

Hi,
thanks for the patches!

We can now create tabs. However, when we try to insert elements into the
tabs, we still get errors.

E.g.:

require ‘tk’
require ‘tkextlib/blt’

nb = Tk::BLT::Tabnotebook.new(TkRoot.new).pack

t1 = Tk::BLT::Tabnotebook::Tab.new(nb)
Tk::BLT::Tile::Label.new(t1)

alternatively (gives the same error):

Tk::BLT::Tile::Label.new(nb.get_tab(0))

error message:

/usr/lib/ruby/1.8/tk.rb:1807:in _invoke_without_enc': bad window path name "tab0" (RuntimeError) from /usr/lib/ruby/1.8/tk.rb:1807:in_ip_invoke_core’
from /usr/lib/ruby/1.8/tk.rb:1843:in _tk_call_core' from /usr/lib/ruby/1.8/tk.rb:1871:intk_call_without_enc’
from /usr/lib/ruby/1.8/tk.rb:4920:in create_self' from /usr/lib/ruby/1.8/tk.rb:4875:ininitialize’
from /home/philip/workspaces/ruby/test/tabtest.rb:11:in `new’
from /home/philip/workspaces/ruby/test/tabtest.rb:11