Forum: Ruby BLT::Tabnotebook - tabnotebook.tcl not found

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
887b6077c9bf05507c7adbce6e746f8b?d=identicon&s=25 Philip Müller (alienemperor)
on 2008-11-21 20:01
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:in `tk_call_without_enc'
  from /usr/lib/ruby/1.8/tk.rb:4920:in `create_self'
  from /usr/lib/ruby/1.8/tk.rb:4875:in `initialize'
  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 .
E4f967492dbd03c526cc9b397e68021d?d=identicon&s=25 Hidetoshi NAGAI (Guest)
on 2008-11-22 02:30
(Received via mailing list)
From: Philip Müller <me@alienemperor.de>
Subject: BLT::Tabnotebook - tabnotebook.tcl not found
Date: Sat, 22 Nov 2008 03:57:43 +0900
Message-ID: <caea0cee3b4ab89f3e99b5804ae0b4f5@ruby-forum.com>
> 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
887b6077c9bf05507c7adbce6e746f8b?d=identicon&s=25 Philip Müller (alienemperor)
on 2008-11-22 20:29
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:in `initialize'
  from /usr/lib/ruby/1.8/tkextlib/blt/tabset.rb:54:in `new'
  from /usr/lib/ruby/1.8/tkextlib/blt/tabset.rb:53:in `instance_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:in `synchronize'
  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?
E4f967492dbd03c526cc9b397e68021d?d=identicon&s=25 Hidetoshi NAGAI (Guest)
on 2008-11-24 00:24
(Received via mailing list)
From: Philip Müller <me@alienemperor.de>
Subject: Re: BLT::Tabnotebook - tabnotebook.tcl not found
Date: Sun, 23 Nov 2008 04:25:27 +0900
Message-ID: <1abee2f75d481bc2304cdb5871ab2f67@ruby-forum.com>
> /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.
E4f967492dbd03c526cc9b397e68021d?d=identicon&s=25 Hidetoshi NAGAI (Guest)
on 2008-11-24 20:12
(Received via mailing list)
From: Hidetoshi NAGAI <nagai@ai.kyutech.ac.jp>
Subject: Re: BLT::Tabnotebook - tabnotebook.tcl not found
Date: Mon, 24 Nov 2008 08:19:44 +0900
Message-ID: <20081124.082406.71096111.nagai@ai.kyutech.ac.jp>
> 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
887b6077c9bf05507c7adbce6e746f8b?d=identicon&s=25 Philip Müller (alienemperor)
on 2008-11-26 22:44
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:in `tk_call_without_enc'
  from /usr/lib/ruby/1.8/tk.rb:4920:in `create_self'
  from /usr/lib/ruby/1.8/tk.rb:4875:in `initialize'
  from /home/philip/workspaces/ruby/test/tabtest.rb:11:in `new'
  from /home/philip/workspaces/ruby/test/tabtest.rb:11
E4f967492dbd03c526cc9b397e68021d?d=identicon&s=25 Hidetoshi NAGAI (Guest)
on 2008-11-27 04:48
(Received via mailing list)
From: Philip Müller <me@alienemperor.de>
Subject: Re: BLT::Tabnotebook - tabnotebook.tcl not found
Date: Thu, 27 Nov 2008 06:39:32 +0900
Message-ID: <9827e8810cfd28d90e4025f4d4275b94@ruby-forum.com>
> > 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'))
887b6077c9bf05507c7adbce6e746f8b?d=identicon&s=25 Philip Müller (alienemperor)
on 2008-11-27 19:52
It works!

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

Best Regards

Philip
This topic is locked and can not be replied to.