| Class | SimpleTable |
| In: |
lib/simple_table.rb
|
| Parent: | Object |
一覧テーブルのモデル。
| column_size | [R] | |
| column_width | [RW] | |
| row_height | [RW] | |
| row_size | [R] |
# File lib/simple_table.rb, line 6
6: def initialize(row=1, col=1, row_height = 0.0, column_width = 0.0)
7: @row_size = row
8: @column_size = col
9:
10: @table = Array.new(@row_size){ Array.new(@column_size){ SimpleCell.new("") } }
11: @row_height = Array.new(@row_size){ row_height }
12: @row_line_nums = Array.new(@row_size){ 1 }
13: @column_width = Array.new(@column_size){ column_width }
14: end
行 row、および真ならば列 col にアクセスする。
# File lib/simple_table.rb, line 17
17: def [](row, col=nil)
18: return col ? @table[row][col] : @table[row]
19: end
行および列に代入する。
# File lib/simple_table.rb, line 22
22: def []=(row, val_or_col, val=nil)
23: if val
24: @table[row][val_or_col] = val.dup
25: else
26: @table[row] = val_or_col.dup
27: end
28: end
# File lib/simple_table.rb, line 30
30: def each_index(&block)
31: @table.each_index(&block)
32: end
# File lib/simple_table.rb, line 34
34: def set_contents
35: @table.each_index do |r|
36: @table[r].each_index do |c|
37: @table[r][c] = yield(r, c)
38: end
39: end
40: end
split a big table into several pages
+————+—————-+ | | | | ts[0][0] | ts[0][1] | | | | |————+—————-| | | | | ts[1][0] | ts[1][1] | | | | | | | |————+—————-| | | | | ts[2][0] | ts[2][1] | | | | +————+—————-+
# File lib/simple_table.rb, line 59
59: def split(page_width, page_height)
60: ts = split_horizontally(page_height)
61: ts.collect!{ |t| t.split_vertically(page_width) }
62:
63: return ts
64: end
split this table horizontally into several tables
+————+ | | | tv[0] | | | |————+ | | | tv[1] | | | | | |————+ | | | tv[2] | | | +————+
# File lib/simple_table.rb, line 83
83: def split_horizontally(page_height)
84: tv = []
85: h = 0 # current height
86:
87: rows = @table.dup
88: stacked_rows = []
89: row_height = @row_height.dup
90: stacked_row_height = []
91:
92: proc = lambda do
93: t = SimpleTable.new(stacked_rows.size, @column_size)
94: t.row_height = stacked_row_height
95: t.column_width = @column_width.dup
96: t.each_index {|r| t[r] = stacked_rows[r]}
97: tv << t
98: end
99:
100: while row = rows.shift
101: dh = row_height.shift
102:
103: if (h + dh) < page_height
104: stacked_row_height << dh
105: stacked_rows << row
106: h += dh
107: else
108: need_tail_row = false
109: tail_row = Array.new(@column_size)
110: tail_row_height = 0
111: head_row = Array.new(@column_size)
112: head_row_height = 0
113:
114: @column_size.times do |c|
115: style = row[c].style
116: line_num = row[c].line_num
117:
118: if line_num < 1
119: tail_style = style.dup
120: tail_style.margin[:bottom] = 0
121: tail_row[c] = SimpleCell.new("", style.dup)
122:
123: head_style = style.dup
124: head_style.margin[:top] = 0
125: head_row[c] = SimpleCell.new("", style.dup)
126: ddh = 0
127: else
128: text = row[c].text(:array => true)
129: dht = style.margin[:top]
130: dhb = style.margin[:top] + style.line_height * line_num
131:
132: if (h + dht) >= page_height
133: tail_style = style.dup
134: tail_style.margin[:bottom] = 0
135: tail_row[c] = SimpleCell.new("", tail_style)
136:
137: head_style = style.dup
138: head_style.margin[:top] = 0 # ToDo: need to set correct value
139: head_row[c] = SimpleCell.new(text, head_style)
140: ddh = 0
141: elsif (h + dhb) >= page_height
142: need_tail_row = true
143: ln = 0
144: dhc = style.margin[:top] + style.line_height
145:
146: while (h + dhc) < page_height
147: dhc += style.line_height
148: ln += 1
149: end
150:
151: tail_style = style.dup
152: tail_style.margin[:bottom] = 0
153: tail_row[c] = SimpleCell.new(text[0...ln], tail_style)
154:
155: head_style = style.dup
156: head_style.margin[:top] = 0 # ToDo: need to set correct value
157: head_row[c] = SimpleCell.new(text[ln...line_num], head_style)
158: ddh = 0 # ToDo: need to set
159: else
160: need_tail_row = true
161: tail_style = style.dup
162: tail_style.margin[:bottom] = 0
163: tail_row[c] = SimpleCell.new(text, tail_style)
164:
165: head_style = style.dup
166: head_style.margin[:top] = 0 # ToDo: need to set correct value
167: head_row[c] = SimpleCell.new("", head_style)
168:
169: ddh = 0 # ToDo: need to set
170: end
171: end
172: end
173:
174: if need_tail_row
175: tail_height = 0
176: tail_row.each do |cell|
177: # calculate height
178: h = cell.style.margin[:top] +
179: cell.line_num * cell.style.line_height +
180: cell.style.margin[:bottom]
181: tail_height = h if h > tail_height
182:
183: # erase bottom border line
184: cell.style.border_width[:bottom] = 0
185: end
186: stacked_row_height << tail_height
187: stacked_rows << tail_row
188: end
189:
190: # copy the clipped table
191: proc.call
192:
193: h = 0
194: stacked_row_height = []
195: stacked_rows = []
196:
197: head_height = 0
198: head_row.each do |cell|
199: # calculate height
200: h = cell.style.margin[:top] +
201: cell.line_num * cell.style.line_height +
202: cell.style.margin[:bottom]
203: head_height = h if h > head_height
204:
205: # erase top border line
206: cell.style.border_width[:top] = 0
207: end
208: row_height.unshift(head_height)
209: rows.unshift(head_row)
210: end
211: end
212:
213: # tail rows
214: proc.call
215:
216: return tv
217: end
split this table vertically into several tables
+———+————+———+ | | | | | th[0] | th[1] | th[2] | | | | | +———+————+——- +
# File lib/simple_table.rb, line 227
227: def split_vertically(page_width)
228: th = []
229: w = 0 # current width
230: start_col = 0
231: proc = lambda do |c|
232: t = SimpleTable.new(@row_size, c - start_col)
233: t.row_height = @row_height.dup
234: t.column_width = @column_width[start_col...c]
235: t.each_index {|r| t[r] = @table[r][start_col...c]}
236: th << t
237: end
238:
239: @column_size.times do |c|
240: w += @column_width[c]
241: if w >= page_width
242: # copy the clipped table
243: proc.call(c)
244: w = @column_width[c]
245: start_col = c
246: end
247: end
248: # tail columns
249: proc.call(@column_size)
250:
251: return th
252: end