Subversion-Projekte lars-tiefland.prado

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
1 lars 1
<?php
2
/**
3
 * IRepeatInfoUser, TRepeatInfo class file
4
 *
5
 * @author Qiang Xue <qiang.xue@gmail.com>
6
 * @link http://www.pradosoft.com/
7
 * @copyright Copyright &copy; 2005-2008 PradoSoft
8
 * @license http://www.pradosoft.com/license/
9
 * @version $Id: TRepeatInfo.php 2541 2008-10-21 15:05:13Z qiang.xue $
10
 * @package System.Web.UI.WebControls
11
 */
12
 
13
Prado::using('System.Web.UI.WebControls.TTable');
14
 
15
/**
16
 * IRepeatInfoUser interface.
17
 * This interface must be implemented by classes who want to use {@link TRepeatInfo}.
18
 *
19
 * @author Qiang Xue <qiang.xue@gmail.com>
20
 * @version $Id: TRepeatInfo.php 2541 2008-10-21 15:05:13Z qiang.xue $
21
 * @package System.Web.UI.WebControls
22
 * @since 3.0
23
 */
24
interface IRepeatInfoUser
25
{
26
	/**
27
	 * @return boolean whether the repeat user contains footer
28
	 */
29
	public function getHasFooter();
30
	/**
31
	 * @return boolean whether the repeat user contains header
32
	 */
33
	public function getHasHeader();
34
	/**
35
	 * @return boolean whether the repeat user contains separators
36
	 */
37
	public function getHasSeparators();
38
	/**
39
	 * @return integer number of items to be rendered (excluding header, footer and separators)
40
	 */
41
	public function getItemCount();
42
	/**
43
	 * @param string item type (Header,Footer,Item,AlternatingItem,SelectedItem,EditItem,Separator,Pager)
44
	 * @param integer zero-based index of the current rendering item.
45
	 * @return TStyle CSS style used for rendering items (including header, footer and separators)
46
	 */
47
	public function generateItemStyle($itemType,$index);
48
	/**
49
	 * Renders an item.
50
	 * @param THtmlWriter writer for the rendering purpose
51
	 * @param TRepeatInfo repeat information
52
	 * @param string item type
53
	 * @param integer zero-based index of the item being rendered
54
	 */
55
	public function renderItem($writer,$repeatInfo,$itemType,$index);
56
}
57
 
58
/**
59
 * TRepeatInfo class.
60
 * TRepeatInfo represents repeat information for controls like {@link TCheckBoxList}.
61
 * The layout of the repeated items is specified via {@link setRepeatLayout RepeatLayout},
62
 * which can be either Table (default), Flow or Raw.
63
 * A table layout uses HTML table cells to organize the items while
64
 * a flow layout uses line breaks to organize the items.
65
 * The number of columns used to display the items is specified via
66
 * {@link setRepeatColumns RepeatColumns} property, while the {@link setRepeatDirection RepeatDirection}
67
 * governs the order of the items being rendered.
68
 *
69
 * Note, the Raw layout does not contain any formatting tags and thus ignores
70
 * the column and repeat direction settings.
71
 *
72
 * @author Qiang Xue <qiang.xue@gmail.com>
73
 * @version $Id: TRepeatInfo.php 2541 2008-10-21 15:05:13Z qiang.xue $
74
 * @package System.Web.UI.WebControls
75
 * @since 3.0
76
 */
77
class TRepeatInfo extends TComponent
78
{
79
	/**
80
	 * @var string caption of the table used to organize the repeated items
81
	 */
82
	private $_caption='';
83
	/**
84
	 * @var TTableCaptionAlign alignment of the caption of the table used to organize the repeated items
85
	 */
86
	private $_captionAlign=TTableCaptionAlign::NotSet;
87
	/**
88
	 * @var integer number of columns that the items should be arranged in
89
	 */
90
	private $_repeatColumns=0;
91
	/**
92
	 * @var TRepeatDirection direction of the repetition
93
	 */
94
	private $_repeatDirection=TRepeatDirection::Vertical;
95
	/**
96
	 * @var TRepeatLayout layout of the repeated items
97
	 */
98
	private $_repeatLayout=TRepeatLayout::Table;
99
 
100
	/**
101
	 * @return string caption of the table layout
102
	 */
103
	public function getCaption()
104
	{
105
		return $this->_caption;
106
	}
107
 
108
	/**
109
	 * @param string caption of the table layout
110
	 */
111
	public function setCaption($value)
112
	{
113
		$this->_caption=$value;
114
	}
115
 
116
	/**
117
	 * @return TTableCaptionAlign alignment of the caption of the table layout. Defaults to TTableCaptionAlign::NotSet.
118
	 */
119
	public function getCaptionAlign()
120
	{
121
		return $this->_captionAlign;
122
	}
123
 
124
	/**
125
	 * @return TTableCaptionAlign alignment of the caption of the table layout.
126
	 */
127
	public function setCaptionAlign($value)
128
	{
129
		$this->_captionAlign=TPropertyValue::ensureEnum($value,'TTableCaptionAlign');
130
	}
131
 
132
	/**
133
	 * @return integer the number of columns that the repeated items should be displayed in. Defaults to 0, meaning not set.
134
	 */
135
	public function getRepeatColumns()
136
	{
137
		return $this->_repeatColumns;
138
	}
139
 
140
	/**
141
	 * @param integer the number of columns that the repeated items should be displayed in.
142
	 */
143
	public function setRepeatColumns($value)
144
	{
145
		if(($value=TPropertyValue::ensureInteger($value))<0)
146
			throw new TInvalidDataValueException('repeatinfo_repeatcolumns_invalid');
147
		$this->_repeatColumns=$value;
148
	}
149
 
150
	/**
151
	 * @return TRepeatDirection the direction of traversing the repeated items, defaults to TRepeatDirection::Vertical
152
	 */
153
	public function getRepeatDirection()
154
	{
155
		return $this->_repeatDirection;
156
	}
157
 
158
	/**
159
	 * @param TRepeatDirection the direction of traversing the repeated items
160
	 */
161
	public function setRepeatDirection($value)
162
	{
163
		$this->_repeatDirection=TPropertyValue::ensureEnum($value,'TRepeatDirection');
164
	}
165
 
166
	/**
167
	 * @return TRepeatLayout how the repeated items should be displayed, using table or using line breaks. Defaults to TRepeatLayout::Table.
168
	 */
169
	public function getRepeatLayout()
170
	{
171
		return $this->_repeatLayout;
172
	}
173
 
174
	/**
175
	 * @param TRepeatLayout how the repeated items should be displayed, using table or using line breaks.
176
	 */
177
	public function setRepeatLayout($value)
178
	{
179
		$this->_repeatLayout=TPropertyValue::ensureEnum($value,'TRepeatLayout');
180
	}
181
 
182
	/**
183
	 * Renders the repeated items.
184
	 * @param THtmlWriter writer for the rendering purpose
185
	 * @param IRepeatInfoUser repeat information user
186
	 */
187
	public function renderRepeater($writer, IRepeatInfoUser $user)
188
	{
189
		if($this->_repeatLayout===TRepeatLayout::Table)
190
		{
191
			$control=new TTable;
192
			if($this->_caption!=='')
193
			{
194
				$control->setCaption($this->_caption);
195
				$control->setCaptionAlign($this->_captionAlign);
196
			}
197
		}
198
		else if($this->_repeatLayout===TRepeatLayout::Raw)
199
		{
200
			$this->renderRawContents($writer,$user);
201
			return;
202
		}
203
		else
204
			$control=new TWebControl;
205
		$control->setID($user->getClientID());
206
		$control->copyBaseAttributes($user);
207
		if($user->getHasStyle())
208
			$control->getStyle()->copyFrom($user->getStyle());
209
		$control->renderBeginTag($writer);
210
		$writer->writeLine();
211
 
212
		if($this->_repeatDirection===TRepeatDirection::Vertical)
213
			$this->renderVerticalContents($writer,$user);
214
		else
215
			$this->renderHorizontalContents($writer,$user);
216
 
217
		$control->renderEndTag($writer);
218
	}
219
 
220
	/**
221
	 * Renders contents in raw format.
222
	 * @param THtmlWriter writer for the rendering purpose
223
	 * @param IRepeatInfoUser repeat information user
224
	 */
225
	protected function renderRawContents($writer,$user)
226
	{
227
		if($user->getHasHeader())
228
			$user->renderItem($writer,$this,'Header',-1);
229
 
230
		// render items
231
		$hasSeparators=$user->getHasSeparators();
232
		$itemCount=$user->getItemCount();
233
		for($i=0;$i<$itemCount;++$i)
234
		{
235
			$user->renderItem($writer,$this,'Item',$i);
236
			if($hasSeparators && $i!=$itemCount-1)
237
				$user->renderItem($writer,$this,'Separator',$i);
238
		}
239
		if($user->getHasFooter())
240
			$user->renderItem($writer,$this,'Footer',-1);
241
	}
242
 
243
	/**
244
	 * Renders contents in horizontal repeat direction.
245
	 * @param THtmlWriter writer for the rendering purpose
246
	 * @param IRepeatInfoUser repeat information user
247
	 */
248
	protected function renderHorizontalContents($writer,$user)
249
	{
250
		$tableLayout=($this->_repeatLayout===TRepeatLayout::Table);
251
		$hasSeparators=$user->getHasSeparators();
252
		$itemCount=$user->getItemCount();
253
		$columns=$this->_repeatColumns===0?$itemCount:$this->_repeatColumns;
254
		$totalColumns=$hasSeparators?$columns+$columns:$columns;
255
		$needBreak=$columns<$itemCount;
256
 
257
		if($user->getHasHeader())
258
			$this->renderHeader($writer,$user,$tableLayout,$totalColumns,$needBreak);
259
 
260
		// render items
261
		if($tableLayout)
262
		{
263
			$writer->renderBeginTag('tbody');
264
			$column=0;
265
			for($i=0;$i<$itemCount;++$i)
266
			{
267
				if($column==0)
268
					$writer->renderBeginTag('tr');
269
				if(($style=$user->generateItemStyle('Item',$i))!==null)
270
					$style->addAttributesToRender($writer);
271
				$writer->renderBeginTag('td');
272
				$user->renderItem($writer,$this,'Item',$i);
273
				$writer->renderEndTag();
274
				$writer->writeLine();
275
				if($hasSeparators && $i!=$itemCount-1)
276
				{
277
					if(($style=$user->generateItemStyle('Separator',$i))!==null)
278
						$style->addAttributesToRender($writer);
279
					$writer->renderBeginTag('td');
280
					$user->renderItem($writer,$this,'Separator',$i);
281
					$writer->renderEndTag();
282
					$writer->writeLine();
283
				}
284
				$column++;
285
				if($i==$itemCount-1)
286
				{
287
					$restColumns=$columns-$column;
288
					if($hasSeparators)
289
						$restColumns=$restColumns?$restColumns+$restColumns+1:1;
290
					for($j=0;$j<$restColumns;++$j)
291
						$writer->write("<td></td>\n");
292
				}
293
				if($column==$columns || $i==$itemCount-1)
294
				{
295
					$writer->renderEndTag();
296
					$writer->writeLine();
297
					$column=0;
298
				}
299
			}
300
			$writer->renderEndTag();
301
		}
302
		else
303
		{
304
			$column=0;
305
			for($i=0;$i<$itemCount;++$i)
306
			{
307
				$user->renderItem($writer,$this,'Item',$i);
308
				if($hasSeparators && $i!=$itemCount-1)
309
					$user->renderItem($writer,$this,'Separator',$i);
310
				$column++;
311
				if($column==$columns || $i==$itemCount-1)
312
				{
313
					if($needBreak)
314
						$writer->writeBreak();
315
					$column=0;
316
				}
317
				$writer->writeLine();
318
			}
319
		}
320
 
321
		if($user->getHasFooter())
322
			$this->renderFooter($writer,$user,$tableLayout,$totalColumns,$needBreak);
323
	}
324
 
325
	/**
326
	 * Renders contents in veritcal repeat direction.
327
	 * @param THtmlWriter writer for the rendering purpose
328
	 * @param IRepeatInfoUser repeat information user
329
	 */
330
	protected function renderVerticalContents($writer,$user)
331
	{
332
		$tableLayout=($this->_repeatLayout===TRepeatLayout::Table);
333
		$hasSeparators=$user->getHasSeparators();
334
		$itemCount=$user->getItemCount();
335
		if($this->_repeatColumns<=1)
336
		{
337
			$rows=$itemCount;
338
			$columns=1;
339
			$lastColumns=1;
340
		}
341
		else
342
		{
343
			$columns=$this->_repeatColumns;
344
			$rows=(int)(($itemCount+$columns-1)/$columns);
345
			if($rows==0 && $itemCount>0)
346
				$rows=1;
347
			if(($lastColumns=$itemCount%$columns)==0)
348
				$lastColumns=$columns;
349
		}
350
		$totalColumns=$hasSeparators?$columns+$columns:$columns;
351
 
352
		if($user->getHasHeader())
353
			$this->renderHeader($writer,$user,$tableLayout,$totalColumns,false);
354
 
355
		if($tableLayout)
356
		{
357
			$writer->renderBeginTag('tbody');
358
			$renderedItems=0;
359
			for($row=0;$row<$rows;++$row)
360
			{
361
				$index=$row;
362
				$writer->renderBeginTag('tr');
363
				for($col=0;$col<$columns;++$col)
364
				{
365
					if($renderedItems>=$itemCount)
366
						break;
367
					if($col>0)
368
					{
369
						$index+=$rows;
370
						if($col-1>=$lastColumns)
371
							$index--;
372
					}
373
					if($index>=$itemCount)
374
						continue;
375
					$renderedItems++;
376
					if(($style=$user->generateItemStyle('Item',$index))!==null)
377
						$style->addAttributesToRender($writer);
378
					$writer->renderBeginTag('td');
379
					$user->renderItem($writer,$this,'Item',$index);
380
					$writer->renderEndTag();
381
					$writer->writeLine();
382
					if(!$hasSeparators)
383
						continue;
384
					if($renderedItems<$itemCount-1)
385
					{
386
						if($columns==1)
387
						{
388
							$writer->renderEndTag();
389
							$writer->renderBeginTag('tr');
390
						}
391
						if(($style=$user->generateItemStyle('Separator',$index))!==null)
392
							$style->addAttributesToRender($writer);
393
						$writer->renderBeginTag('td');
394
						$user->renderItem($writer,$this,'Separator',$index);
395
						$writer->renderEndTag();
396
						$writer->writeLine();
397
					}
398
					else if($columns>1)
399
						$writer->write("<td></td>\n");
400
				}
401
				if($row==$rows-1)
402
				{
403
					$restColumns=$columns-$lastColumns;
404
					if($hasSeparators)
405
						$restColumns+=$restColumns;
406
					for($col=0;$col<$restColumns;++$col)
407
						$writer->write("<td></td>\n");
408
				}
409
				$writer->renderEndTag();
410
				$writer->writeLine();
411
			}
412
			$writer->renderEndTag();
413
		}
414
		else
415
		{
416
			$renderedItems=0;
417
			for($row=0;$row<$rows;++$row)
418
			{
419
				$index=$row;
420
				for($col=0;$col<$columns;++$col)
421
				{
422
					if($renderedItems>=$itemCount)
423
						break;
424
					if($col>0)
425
					{
426
						$index+=$rows;
427
						if($col-1>=$lastColumns)
428
							$index--;
429
					}
430
					if($index>=$itemCount)
431
						continue;
432
					$renderedItems++;
433
					$user->renderItem($writer,$this,'Item',$index);
434
					$writer->writeLine();
435
					if(!$hasSeparators)
436
						continue;
437
					if($renderedItems<$itemCount-1)
438
					{
439
						if($columns==1)
440
							$writer->writeBreak();
441
						$user->renderItem($writer,$this,'Separator',$index);
442
					}
443
					$writer->writeLine();
444
				}
445
				if($row<$rows-1 || $user->getHasFooter())
446
					$writer->writeBreak();
447
			}
448
		}
449
 
450
		if($user->getHasFooter())
451
			$this->renderFooter($writer,$user,$tableLayout,$totalColumns,false);
452
 
453
	}
454
 
455
	/**
456
	 * Renders header.
457
	 * @param THtmlWriter writer for the rendering purpose
458
	 * @param IRepeatInfoUser repeat information user
459
	 * @param boolean whether to render using table layout
460
	 * @param integer number of columns to be rendered
461
	 * @param boolean if a line break is needed at the end
462
	 */
463
	protected function renderHeader($writer,$user,$tableLayout,$columns,$needBreak)
464
	{
465
		if($tableLayout)
466
		{
467
			$writer->renderBeginTag('thead');
468
			$writer->renderBeginTag('tr');
469
			if($columns>1)
470
				$writer->addAttribute('colspan',"$columns");
471
			$writer->addAttribute('scope','col');
472
			if(($style=$user->generateItemStyle('Header',-1))!==null)
473
				$style->addAttributesToRender($writer);
474
			$writer->renderBeginTag('th');
475
			$user->renderItem($writer,$this,'Header',-1);
476
			$writer->renderEndTag();
477
			$writer->renderEndTag();
478
			$writer->renderEndTag();
479
		}
480
		else
481
		{
482
			$user->renderItem($writer,$this,'Header',-1);
483
			if($needBreak)
484
				$writer->writeBreak();
485
		}
486
		$writer->writeLine();
487
	}
488
 
489
	/**
490
	 * Renders footer.
491
	 * @param THtmlWriter writer for the rendering purpose
492
	 * @param IRepeatInfoUser repeat information user
493
	 * @param boolean whether to render using table layout
494
	 * @param integer number of columns to be rendered
495
	 */
496
	protected function renderFooter($writer,$user,$tableLayout,$columns)
497
	{
498
		if($tableLayout)
499
		{
500
			$writer->renderBeginTag('tfoot');
501
			$writer->renderBeginTag('tr');
502
			if($columns>1)
503
				$writer->addAttribute('colspan',"$columns");
504
			if(($style=$user->generateItemStyle('Footer',-1))!==null)
505
				$style->addAttributesToRender($writer);
506
			$writer->renderBeginTag('td');
507
			$user->renderItem($writer,$this,'Footer',-1);
508
			$writer->renderEndTag();
509
			$writer->renderEndTag();
510
			$writer->renderEndTag();
511
		}
512
		else
513
			$user->renderItem($writer,$this,'Footer',-1);
514
		$writer->writeLine();
515
	}
516
}
517
 
518
 
519
/**
520
 * TRepeatDirection class.
521
 * TRepeatDirection defines the enumerable type for the possible directions
522
 * that repeated contents can repeat along
523
 *
524
 * The following enumerable values are defined:
525
 * - Vertical
526
 * - Horizontal
527
 *
528
 * @author Qiang Xue <qiang.xue@gmail.com>
529
 * @version $Id: TRepeatInfo.php 2541 2008-10-21 15:05:13Z qiang.xue $
530
 * @package System.Web.UI.WebControls
531
 * @since 3.0.4
532
 */
533
class TRepeatDirection extends TEnumerable
534
{
535
	const Vertical='Vertical';
536
	const Horizontal='Horizontal';
537
}
538
 
539
/**
540
 * TRepeatLayout class.
541
 * TRepeatLayout defines the enumerable type for the possible layouts
542
 * that repeated contents can take.
543
 *
544
 * The following enumerable values are defined:
545
 * - Table: the repeated contents are organized using an HTML table
546
 * - Flow: the repeated contents are organized using HTML spans and breaks
547
 * - Raw: the repeated contents are stacked together without any additional decorations
548
 *
549
 * @author Qiang Xue <qiang.xue@gmail.com>
550
 * @version $Id: TRepeatInfo.php 2541 2008-10-21 15:05:13Z qiang.xue $
551
 * @package System.Web.UI.WebControls
552
 * @since 3.0.4
553
 */
554
class TRepeatLayout extends TEnumerable
555
{
556
	const Table='Table';
557
	const Flow='Flow';
558
	const Raw='Raw';
559
}
560