1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 """Defines a container that consists of components with certain coordinates
17 on a grid."""
18
19 from warnings import warn
20
21 try:
22 from cStringIO import StringIO
23 except ImportError, e:
24 from StringIO import StringIO
25
26 from muntjac.ui.alignment import Alignment
27 from muntjac.ui.abstract_layout import AbstractLayout
28 from muntjac.ui.layout import IAlignmentHandler, ISpacingHandler
29 from muntjac.ui.alignment_utils import AlignmentUtils
30 from muntjac.terminal.gwt.client.event_id import EventId
31
32 from muntjac.event.layout_events import \
33 ILayoutClickNotifier, LayoutClickEvent, ILayoutClickListener
34
35 from muntjac.util import fullname
36
37
38 -class GridLayout(AbstractLayout, IAlignmentHandler, ISpacingHandler,
39 ILayoutClickNotifier):
40 """A container that consists of components with certain coordinates (cell
41 position) on a grid. It also maintains cursor for adding component in
42 left to right, top to bottom order.
43
44 Each component in a C{GridLayout} uses a certain L{area<grid_layout.Area>}
45 (column1,row1,column2,row2) from the grid. One should not add components
46 that would overlap with the existing components because in such case an
47 L{OverlapsException} is thrown. Adding component with cursor automatically
48 extends the grid by increasing the grid height.
49
50 @author: Vaadin Ltd.
51 @author: Richard Lincoln
52 @version: 1.1.2
53 """
54
55 CLIENT_WIDGET = None
56
57 _CLICK_EVENT = EventId.LAYOUT_CLICK
58 _ALIGNMENT_DEFAULT = Alignment.TOP_LEFT
59
61 """Constructor for grid of given size (number of cells). Note that
62 grid's final size depends on the items that are added into the grid.
63 Grid grows if you add components outside the grid's area.
64
65 @param columns:
66 Number of columns in the grid.
67 @param rows:
68 Number of rows in the grid.
69 """
70 super(GridLayout, self).__init__()
71
72
73 self._cols = 0
74
75
76 self._rows = 0
77
78
79
80 self._cursorX = 0
81
82
83
84 self._cursorY = 0
85
86
87
88 self._areas = list()
89
90
91 self._components = list()
92
93
94 self._componentToAlignment = dict()
95
96
97
98 self._spacing = False
99
100
101
102 self._structuralChange = False
103
104 self._columnExpandRatio = dict()
105 self._rowExpandRatio = dict()
106
107 self.setColumns(columns)
108 self.setRows(rows)
109
110
112 """Adds a component with a specified area to the grid. The area the
113 new component should take is defined by specifying the upper left
114 corner (column1, row1) and the lower right corner (column2, row2) of
115 the area.
116
117 If the new component overlaps with any of the existing components
118 already present in the grid the operation will fail and an
119 L{OverlapsException} is thrown.
120
121 Alternatively, adds the component into this container to cells
122 column1,row1 (NortWest corner of the area.) End coordinates (SouthEast
123 corner of the area) are the same as column1,row1. Component width and
124 height is 1.
125
126 Finally, adds the component into this container to the cursor position.
127 If the cursor position is already occupied, the cursor is moved
128 forwards to find free position. If the cursor goes out from the bottom
129 of the grid, the grid is automatically extended.
130
131 @param args: tuple of the form
132 - (c, column1, row1, column2, row2)
133 1. the component to be added.
134 2. the column of the upper left corner of the area
135 C{c} is supposed to occupy.
136 3. the row of the upper left corner of the area
137 C{c} is supposed to occupy.
138 4. the column of the lower right corner of the area
139 C{c} is supposed to occupy.
140 5. the row of the lower right corner of the area
141 C{c} is supposed to occupy.
142 - (c, column, row)
143 1. the component to be added.
144 2. the column index.
145 3. the row index.
146 - (c)
147 1. the component to be added.
148 @raise OverlapsException:
149 if the new component overlaps with any of the components
150 already in the grid.
151 @raise OutOfBoundsException:
152 if the cell is outside the grid area.
153 """
154 nargs = len(args)
155 if nargs == 1:
156 component, = args
157
158 done = False
159 while not done:
160 try:
161 area = Area(component, self._cursorX, self._cursorY,
162 self._cursorX, self._cursorY)
163 self.checkExistingOverlaps(area)
164 done = True
165 except OverlapsException, e:
166 self.space()
167
168
169 if self._cursorX >= self._cols:
170 self._cols = self._cursorX + 1
171 else:
172 self._cols = self._cols
173
174 if self._cursorY >= self._rows:
175 self._rows = self._cursorY + 1
176 else:
177 self._rows = self._rows
178
179 self.addComponent(component, self._cursorX, self._cursorY)
180 elif nargs == 3:
181 c, column, row = args
182 self.addComponent(c, column, row, column, row)
183 elif nargs == 5:
184 component, column1, row1, column2, row2 = args
185
186 if component is None:
187 raise ValueError, 'Component must not be null'
188
189
190 if component in self._components:
191 raise ValueError, 'Component is already in the container'
192
193
194 area = Area(component, column1, row1, column2, row2)
195
196
197 if column2 < column1 or row2 < row1:
198 raise ValueError, 'Illegal coordinates for the component'
199
200 if (column1 < 0 or row1 < 0 or column2 >= self._cols
201 or row2 >= self._rows):
202 raise OutOfBoundsException(area)
203
204
205 self.checkExistingOverlaps(area)
206
207
208
209
210 index = 0
211 done = False
212 while not done and (index < len(self._areas)):
213 existingArea = self._areas[index]
214 if ((existingArea._row1 >= row1
215 and existingArea._column1 > column1)
216 or (existingArea._row1 > row1)):
217 self._areas.insert(index, area)
218 self._components.insert(index, component)
219 done = True
220 index += 1
221
222 if not done:
223 self._areas.append(area)
224 self._components.append(component)
225
226
227 try:
228 super(GridLayout, self).addComponent(component)
229 except ValueError, e:
230 self._areas.remove(area)
231 self._components.remove(component)
232 raise e
233
234
235
236 if (self._cursorX >= column1 and self._cursorX <= column2
237 and self._cursorY >= row1 and self._cursorY <= row2):
238
239 self._cursorX = column2 + 1
240 if self._cursorX >= self._cols:
241
242 self._cursorX = 0
243
244
245 self._cursorY = (row2 if column1 == 0 else row1) + 1
246 else:
247 self._cursorY = row1
248
249 self.requestRepaint()
250 else:
251 raise ValueError, 'invalid number of arguments'
252
253
255 """Tests if the given area overlaps with any of the items already
256 on the grid.
257
258 @param area:
259 the Area to be checked for overlapping.
260 @raise OverlapsException:
261 if C{area} overlaps with any existing area.
262 """
263 for existingArea in self._areas:
264 if existingArea.overlaps(area):
265
266 raise OverlapsException(existingArea)
267
268
270 """Force the next component to be added to the beginning of the next
271 line. By calling this function user can ensure that no more components
272 are added to the right of the previous component.
273
274 @see: L{space}
275 """
276 self._cursorX = 0
277 self._cursorY += 1
278
279
281 """Moves the cursor forwards by one. If the cursor goes out of the
282 right grid border, move it to next line.
283
284 @see: L{newLine}
285 """
286 self._cursorX += 1
287 if self._cursorX >= self._cols:
288 self._cursorX = 0
289 self._cursorY += 1
290
291
293 """Removes the given component from this container or removes the
294 component specified with it's cell index.
295
296 @param args: tuple of the form
297 - (c)
298 1. the component to be removed.
299 - (column, row)
300 1. the component's column.
301 2. the component's row.
302 """
303
304 nargs = len(args)
305 if nargs == 1:
306 component, = args
307 if component is None or component not in self._components:
308 return
309 area = None
310 for a in self._areas:
311 if a.getComponent() == component:
312 area = a
313
314 self._components.remove(component)
315 if area is not None:
316 self._areas.remove(area)
317
318 if component in self._componentToAlignment:
319 del self._componentToAlignment[component]
320
321 super(GridLayout, self).removeComponent(component)
322
323 self.requestRepaint()
324 elif nargs == 2:
325 column, row = args
326
327 for area in self._areas:
328 if area.getColumn1() == column and area.getRow1() == row:
329 self.removeComponent(area.getComponent())
330 return
331 else:
332 raise ValueError, 'too many arguments'
333
334
336 """Gets an iterator to the component container contents. Using the
337 Iterator it's possible to step through the contents of the container.
338
339 @return: the iterator of the components inside the container.
340 """
341 return iter(self._components)
342
343
345 """Gets the number of contained components. Consistent with the
346 iterator returned by L{getComponentIterator}.
347
348 @return: the number of contained components
349 """
350 return len(self._components)
351
352
353 - def paintContent(self, target):
354 """Paints the contents of this component.
355
356 @param target: the Paint Event.
357 @raise PaintException: if the paint operation failed.
358 """
359 super(GridLayout, self).paintContent(target)
360
361
362 target.addAttribute('h', self._rows)
363 target.addAttribute('w', self._cols)
364
365 target.addAttribute('structuralChange', self._structuralChange)
366 self._structuralChange = False
367
368 if self._spacing:
369 target.addAttribute('spacing', self._spacing)
370
371
372 areaiterator = iter(self._areas)
373
374
375 try:
376 area = areaiterator.next()
377 except StopIteration:
378 area = None
379
380
381 cellUsed = dict()
382
383
384 emptyCells = 0
385
386 alignmentsArray = [None] * len(self._components)
387 columnExpandRatioArray = [None] * self._cols
388 rowExpandRatioArray = [None] * self._rows
389
390 realColExpandRatioSum = 0
391 colSum = self.getExpandRatioSum(self._columnExpandRatio)
392 if colSum == 0:
393
394
395 equalSize = 1 / float(self._cols)
396 myRatio = int( round(equalSize * 1000) )
397 for i in range(self._cols):
398 columnExpandRatioArray[i] = myRatio
399
400 realColExpandRatioSum = myRatio * self._cols
401 else:
402 for i in range(self._cols):
403 myRatio = int( round((self.getColumnExpandRatio(i) / colSum)
404 * 1000) )
405 columnExpandRatioArray[i] = myRatio
406 realColExpandRatioSum += myRatio
407
408 equallyDividedRows = False
409 realRowExpandRatioSum = 0
410 rowSum = self.getExpandRatioSum(self._rowExpandRatio)
411 if rowSum == 0:
412
413 equallyDividedRows = True
414 equalSize = 1 / float(self._rows)
415 myRatio = int( round(equalSize * 1000) )
416 for i in range(self._rows):
417 rowExpandRatioArray[i] = myRatio
418 realRowExpandRatioSum = myRatio * self._rows
419
420 index = 0
421
422 for cury in range(self._rows):
423 target.startTag('gr')
424
425 if not equallyDividedRows:
426 myRatio = int( round((self.getRowExpandRatio(cury) / rowSum)
427 * 1000) )
428 rowExpandRatioArray[cury] = myRatio
429 realRowExpandRatioSum += myRatio
430
431
432 for curx in range(self._cols):
433
434
435 if (area is not None and (area._row1 == cury)
436 and (area._column1 == curx)):
437
438
439 if emptyCells > 0:
440 target.startTag('gc')
441 target.addAttribute('x', curx - emptyCells)
442 target.addAttribute('y', cury)
443 if emptyCells > 1:
444 target.addAttribute('w', emptyCells)
445
446 target.endTag('gc')
447 emptyCells = 0
448
449
450 cols = (area._column2 - area._column1) + 1
451 rows = (area._row2 - area._row1) + 1
452 target.startTag('gc')
453
454 target.addAttribute('x', curx)
455 target.addAttribute('y', cury)
456
457 if cols > 1:
458 target.addAttribute('w', cols)
459
460 if rows > 1:
461 target.addAttribute('h', rows)
462
463 area.getComponent().paint(target)
464
465 ca = self.getComponentAlignment( area.getComponent() )
466 alignmentsArray[index] = str(ca.getBitMask())
467 index += 1
468
469 target.endTag('gc')
470
471
472 try:
473 area = areaiterator.next()
474 except StopIteration:
475 area = None
476
477
478 if rows > 1:
479 spannedx = curx
480 for _ in range(1, self._cols + 1):
481 cellUsed[int(spannedx)] = int((cury + rows) - 1)
482 spannedx += 1
483
484
485 if cols > 1:
486 curx += cols - 1
487 else:
488
489 if int(curx) in cellUsed:
490
491
492
493 rowspanDepth = int( cellUsed.get(int(curx)) )
494
495 if rowspanDepth >= cury:
496
497
498
499 if emptyCells > 0:
500 target.startTag('gc')
501 target.addAttribute('x', curx - emptyCells)
502 target.addAttribute('y', cury)
503 if emptyCells > 1:
504 target.addAttribute('w', emptyCells)
505
506 target.endTag('gc')
507
508 emptyCells = 0
509 else:
510
511
512 emptyCells += 1
513
514
515
516 del cellUsed[int(curx)]
517 else:
518
519 emptyCells += 1
520
521
522
523
524 if emptyCells > 0:
525 target.startTag('gc')
526 target.addAttribute('x', self._cols - emptyCells)
527 target.addAttribute('y', cury)
528 if emptyCells > 1:
529 target.addAttribute('w', emptyCells)
530
531 target.endTag('gc')
532
533 emptyCells = 0
534
535 target.endTag('gr')
536
537
538
539
540 if len(rowExpandRatioArray) > 0:
541 rowExpandRatioArray[0] -= realRowExpandRatioSum - 1000
542
543 if len(columnExpandRatioArray) > 0:
544 columnExpandRatioArray[0] -= realColExpandRatioSum - 1000
545
546 target.addAttribute('colExpand', columnExpandRatioArray)
547 target.addAttribute('rowExpand', rowExpandRatioArray)
548
549
550 target.addAttribute('alignments', alignmentsArray)
551
552
554 summ = 0.0
555 for v in ratioMap.values():
556 summ += v
557 return summ
558
559
566
567
568
570 """Sets the number of columns in the grid. The column count can
571 not be reduced if there are any areas that would be outside of the
572 shrunk grid.
573
574 @param columns: the new number of columns in the grid.
575 """
576
577 if columns < 1:
578 raise ValueError, ('The number of columns and rows in the '
579 'grid must be at least 1')
580
581
582 if self._cols == columns:
583 return
584
585
586 if self._cols > columns:
587 for area in self._areas:
588 if area.column2 >= columns:
589 raise OutOfBoundsException(area)
590
591 self._cols = columns
592
593 self.requestRepaint()
594
595
597 """Get the number of columns in the grid.
598
599 @return: the number of columns in the grid.
600 """
601 return self._cols
602
603
605 """Sets the number of rows in the grid. The number of rows can
606 not be reduced if there are any areas that would be outside of
607 the shrunk grid.
608
609 @param rows: the new number of rows in the grid.
610 """
611
612 if rows < 1:
613 raise ValueError, ('The number of columns and rows in the '
614 'grid must be at least 1')
615
616
617 if self._rows == rows:
618 return
619
620
621 if self._rows > rows:
622 for area in self._areas:
623 if area.row2 >= rows:
624 raise OutOfBoundsException(area)
625
626 self._rows = rows
627
628 self.requestRepaint()
629
630
632 """Get the number of rows in the grid.
633
634 @return: the number of rows in the grid.
635 """
636 return self._rows
637
638
640 """Gets the current cursor x-position. The cursor position points
641 the position for the next component that is added without specifying
642 its coordinates (grid cell). When the cursor position is occupied,
643 the next component will be added to first free position after the
644 cursor.
645
646 @return: the grid column the Cursor is on.
647 """
648 return self._cursorX
649
650
652 """Sets the current cursor x-position. This is usually handled
653 automatically by GridLayout.
654 """
655 self._cursorX = cursorX
656
657
659 """Gets the current cursor y-position. The cursor position points
660 the position for the next component that is added without specifying
661 its coordinates (grid cell). When the cursor position is occupied,
662 the next component will be added to first free position after the
663 cursor.
664
665 @return: the grid row the Cursor is on.
666 """
667 return self._cursorY
668
669
671 """Sets the current cursor y-position. This is usually handled
672 automatically by GridLayout.
673 """
674 self._cursorY = cursorY
675
676
701
702
709
710
712 """Sets the component alignment using a short hand string notation.
713
714 @deprecated: Replaced by L{setComponentAlignment}
715 @param args: tuple of the form
716 - (component, alignment)
717 1. A child component in this layout
718 2. A short hand notation described in L{AlignmentUtils}
719 - (childComponent, horizontalAlignment, verticalAlignment)
720 """
721 warn('replaced by setComponentAlignment', DeprecationWarning)
722
723 nargs = len(args)
724 if nargs == 2:
725 if isinstance(args[1], Alignment):
726 childComponent, alignment = args
727 self._componentToAlignment[childComponent] = alignment
728 self.requestRepaint()
729 else:
730 component, alignment = args
731 AlignmentUtils.setComponentAlignment(self, component,
732 alignment)
733 elif nargs == 3:
734 childComponent, horizontalAlignment, verticalAlignment = args
735 self._componentToAlignment[childComponent] = \
736 Alignment(horizontalAlignment + verticalAlignment)
737 self.requestRepaint()
738 else:
739 raise ValueError, 'invalid number of arguments'
740
741
745
746
749
750
753
754
756 """Inserts an empty row at the chosen position in the grid.
757
758 @param row: Number of the row the new row will be inserted before
759 """
760 if row > self._rows:
761 raise ValueError, ('Cannot insert row at '
762 + row + ' in a gridlayout with height ' + self._rows)
763
764 for existingArea in self._areas:
765
766 if existingArea.row2 >= row:
767 existingArea.row2 += 1
768
769 if existingArea.row1 >= row:
770 existingArea.row1 += 1
771
772 if self._cursorY >= row:
773 self._cursorY += 1
774
775 self.setRows(self._rows + 1)
776 self._structuralChange = True
777 self.requestRepaint()
778
779
781 """Removes row and all components in the row. Components which span
782 over several rows are removed if the selected row is the component's
783 first row.
784
785 If the last row is removed then all remaining components will be
786 removed and the grid will be reduced to one row. The cursor will be
787 moved to the upper left cell of the grid.
788
789 @param row: The row number to remove
790 """
791 if row >= self._rows:
792 raise ValueError, ('Cannot delete row '
793 + row + ' from a gridlayout with height ' + self._rows)
794
795
796 for col in range(self.getColumns()):
797 self.removeComponent(col, row)
798
799
800 for existingArea in self._areas:
801 if existingArea.row2 >= row:
802 existingArea.row2 -= 1
803
804 if existingArea.row1 > row:
805 existingArea.row1 -= 1
806
807 if self._rows == 1:
808
809
810
811 self._cursorX = 0
812 self._cursorY = 0
813 else:
814 self.setRows(self._rows - 1)
815 if self._cursorY > row:
816 self._cursorY -= 1
817
818 self._structuralChange = True
819 self.requestRepaint()
820
821
823 """Sets the expand ratio of given column. Expand ratio defines how
824 excess space is distributed among columns. Excess space means the
825 space not consumed by non relatively sized components.
826
827 By default excess space is distributed evenly.
828
829 Note, that width needs to be defined for this method to have any
830 effect.
831
832 @see: L{setWidth}
833 """
834 self._columnExpandRatio[columnIndex] = ratio
835 self.requestRepaint()
836
837
839 """Returns the expand ratio of given column
840
841 @see: L{setColumnExpandRatio}
842 @return: the expand ratio, 0.0 by default
843 """
844 r = self._columnExpandRatio.get(columnIndex)
845 return 0 if r is None else float(r)
846
847
849 """Sets the expand ratio of given row. Expand ratio defines how
850 excess space is distributed among rows. Excess space means the
851 space not consumed by non relatively sized components.
852
853 By default excess space is distributed evenly.
854
855 Note, that height needs to be defined for this method to have
856 any effect.
857
858 @see: L{setHeight}
859 """
860 self._rowExpandRatio[rowIndex] = ratio
861 self.requestRepaint()
862
863
865 """Returns the expand ratio of given row.
866
867 @see: L{setRowExpandRatio}
868 @return: the expand ratio, 0.0 by default
869 """
870 r = self._rowExpandRatio.get(rowIndex)
871 return 0 if r is None else float(r)
872
873
875 """Gets the Component at given index.
876
877 @param x:
878 x-index
879 @param y:
880 y-index
881 @return: Component in given cell or null if empty
882 """
883 for area in self._areas:
884 if (area.getColumn1() <= x and x <= area.getColumn2()
885 and area.getRow1() <= y and y <= area.getRow2()):
886 return area.getComponent()
887
888 return None
889
890
892 """Returns information about the area where given component is layed
893 in the GridLayout.
894
895 @param component:
896 the component whose area information is requested.
897 @return: an Area object that contains information how component is
898 layed in the grid
899 """
900 for area in self._areas:
901 if area.getComponent() == component:
902 return area
903 return None
904
905
913
914
915 - def addCallback(self, callback, eventType=None, *args):
924
925
933
934
945
946
948 """This class defines an area on a grid. An Area is defined by the cells
949 of its upper left corner (column1,row1) and lower right corner
950 (column2, row2).
951
952 @author: Vaadin Ltd.
953 @author: Richard Lincoln
954 @version: 1.1.2
955 """
956
957 - def __init__(self, component, column1, row1, column2, row2):
958 """Construct a new area on a grid.
959
960 @param component:
961 the component connected to the area.
962 @param column1:
963 The column of the upper left corner cell of the area
964 C{c} is supposed to occupy.
965 @param row1:
966 The row of the upper left corner cell of the area
967 C{c} is supposed to occupy.
968 @param column2:
969 The column of the lower right corner cell of the area
970 C{c} is supposed to occupy.
971 @param row2:
972 The row of the lower right corner cell of the area
973 C{c} is supposed to occupy.
974 @raise OverlapsException:
975 if the new component overlaps with any of the components
976 already in the grid
977 """
978
979 self._column1 = column1
980
981
982 self._row1 = row1
983
984
985 self._column2 = column2
986
987
988 self._row2 = row2
989
990
991 self._component = component
992
993
995 """Tests if the given Area overlaps with an another Area.
996
997 @param other:
998 the Another Area that's to be tested for overlap with this
999 area.
1000 @return: C{True} if C{other} overlaps with this
1001 area, C{False} if it doesn't.
1002 """
1003 return (self._column1 <= other.getColumn2()
1004 and self._row1 <= other.getRow2()
1005 and self._column2 >= other.getColumn1()
1006 and self._row2 >= other.getRow1())
1007
1008
1010 """Gets the component connected to the area.
1011
1012 @return: the Component.
1013 """
1014 return self._component
1015
1016
1018 """Sets the component connected to the area.
1019
1020 This function only sets the value in the datastructure and does not
1021 send any events or set parents.
1022
1023 @param newComponent:
1024 the new connected overriding the existing one.
1025 """
1026 self._component = newComponent
1027
1028
1030 """@deprecated: Use getColumn1() instead.
1031
1032 @see: L{GridLayout.getColumn1}
1033 """
1034 warn('Use getColumn1() instead.', DeprecationWarning)
1035 return self.getColumn1()
1036
1037
1039 """Gets the column of the top-left corner cell.
1040
1041 @return: the column of the top-left corner cell.
1042 """
1043 return self._column1
1044
1045
1047 """@deprecated: Use getColumn2() instead.
1048
1049 @see: L{GridLayout.getColumn2}
1050 """
1051 warn('Use getColumn2() instead.', DeprecationWarning)
1052 return self.getColumn2()
1053
1054
1056 """Gets the column of the bottom-right corner cell.
1057
1058 @return: the column of the bottom-right corner cell.
1059 """
1060 return self._column2
1061
1062
1064 """@deprecated: Use getRow1() instead.
1065
1066 @see: L{GridLayout.getRow1}
1067 """
1068 warn('Use getRow1() instead.', DeprecationWarning)
1069 return self.getRow1()
1070
1071
1073 """Gets the row of the top-left corner cell.
1074
1075 @return: the row of the top-left corner cell.
1076 """
1077 return self._row1
1078
1079
1081 """@deprecated: Use getRow2() instead.
1082
1083 @see: L{GridLayout.getRow2}
1084 """
1085 warn('Use getRow2() instead.', DeprecationWarning)
1086 return self.getRow2()
1087
1088
1090 """Gets the row of the bottom-right corner cell.
1091
1092 @return: the row of the bottom-right corner cell.
1093 """
1094 return self._row2
1095
1096
1098 """Gridlayout does not support laying components on top of each other.
1099 An C{OverlapsException} is thrown when a component already
1100 exists (even partly) at the same space on a grid with the new component.
1101
1102 @author: Vaadin Ltd.
1103 @author: Richard Lincoln
1104 @version: 1.1.2
1105 """
1106
1108 """Constructs an C{OverlapsException}.
1109 """
1110 self._existingArea = existingArea
1111
1112
1136
1137
1139 """Gets the area .
1140
1141 @return: the existing area.
1142 """
1143 return self._existingArea
1144
1145
1147 """An C{Exception} object which is thrown when an area
1148 exceeds the bounds of the grid.
1149
1150 @author: Vaadin Ltd.
1151 @author: Richard Lincoln
1152 @version: 1.1.2
1153 """
1154
1156 """Constructs an C{OoutOfBoundsException} with the
1157 specified detail message.
1158 """
1159 self._areaOutOfBounds = areaOutOfBounds
1160
1161
1163 """Gets the area that is out of bounds.
1164
1165 @return: the area out of Bound.
1166 """
1167 return self._areaOutOfBounds
1168