1#
2#  tkextlib/iwidgets/tabset.rb
3#                               by Hidetoshi NAGAI (nagai@ai.kyutech.ac.jp)
4#
5
6require 'tk'
7require 'tkextlib/iwidgets.rb'
8
9module Tk
10  module Iwidgets
11    class Tabset < Tk::Itk::Widget
12    end
13  end
14end
15
16class Tk::Iwidgets::Tabset
17  TkCommandNames = ['::iwidgets::tabset'.freeze].freeze
18  WidgetClassName = 'Tabset'.freeze
19  WidgetClassNames[WidgetClassName] ||= self
20
21  ####################################
22
23  include TkItemConfigMethod
24
25  def __item_cget_cmd(id)
26    [self.path, 'tabcget', id]
27  end
28  private :__item_cget_cmd
29
30  def __item_config_cmd(id)
31    [self.path, 'tabconfigure', id]
32  end
33  private :__item_config_cmd
34
35  def tagid(tagOrId)
36    if tagOrId.kind_of?(Tk::Itk::Component)
37      tagOrId.name
38    else
39      #_get_eval_string(tagOrId)
40      tagOrId
41    end
42  end
43
44  alias tabcget_tkstring itemcget_tkstring
45  alias tabcget itemcget
46  alias tabcget_strict itemcget_strict
47  alias tabconfigure itemconfigure
48  alias tabconfiginfo itemconfiginfo
49  alias current_tabconfiginfo current_itemconfiginfo
50
51  private :itemcget_tkstring, :itemcget, :itemcget_strict
52  private :itemconfigure, :itemconfiginfo, :current_itemconfiginfo
53
54  ####################################
55
56  def __boolval_optkeys
57    super() << 'equaltabs' << 'raiseselect' << 'tabborders'
58  end
59  private :__boolval_optkeys
60
61  def __strval_optkeys
62    super() << 'backdrop'
63  end
64  private :__strval_optkeys
65
66  def add(keys={})
67    window(tk_call(@path, 'add', *hash_kv(keys)))
68  end
69
70  def delete(idx1, idx2=nil)
71    if idx2
72      tk_call(@path, 'delete', index(idx1), index(idx2))
73    else
74      tk_call(@path, 'delete', index(idx1))
75    end
76    self
77  end
78
79  def index(idx)
80    number(tk_call(@path, 'index', tagid(idx)))
81  end
82
83  def insert(idx, keys={})
84    window(tk_call(@path, 'insert', index(idx), *hash_kv(keys)))
85  end
86
87  def next
88    tk_call(@path, 'next')
89    self
90  end
91
92  def prev
93    tk_call(@path, 'prev')
94    self
95  end
96
97  def select(idx)
98    tk_call(@path, 'select', index(idx))
99    self
100  end
101
102  def show_tab(idx)
103    if index(idx) == 0
104      self.start = 0
105      return
106    end
107
108    reutrn unless @canvas ||= self.winfo_children[0]
109
110    delta = 1 if (delta = cget(:gap)) == 'overlap' ||
111                   (delta = self.winfo_pixels(delta) + 1) <= 0
112
113    case cget(:tabpos)
114    when 's', 'n'
115      if (head = tabcget(idx, :left)) < 0
116        self.start -= head
117        return
118      end
119      tabs_size = @canvas.winfo_width
120      tab_start, tab_end = @canvas .
121        find_overlapping(head, 0, head + delta, @canvas.winfo_height) .
122        find_all{|id| @canvas.itemtype(id) == TkcPolygon} .
123        map!{|id| bbox = @canvas.bbox(id); [bbox[0], bbox[2]]} . max
124
125    when 'e', 'w'
126      if (head = tabcget(idx, :top)) < 0
127        self.start -= head
128        return
129      end
130      tabs_size = @canvas.winfo_height
131      tab_start, tab_end = @canvas .
132        find_overlapping(0, head, @canvas.winfo_width, head + delta) .
133        find_all{|id| @canvas.itemtype(id) == TkcPolygon} .
134        map!{|id| bbox = @canvas.bbox(id); [bbox[1], bbox[3]]} . max
135    end
136
137    if (size = tab_end - tab_start + 1) > tabs_size
138      self.start -= tab_start
139    elsif head + size > tabs_size
140      self.start -= head + size - tabs_size
141    end
142
143    self
144  end
145end
146