Package muntjac :: Package ui :: Module abstract_ordered_layout
[hide private]
[frames] | no frames]

Source Code for Module muntjac.ui.abstract_ordered_layout

  1  # Copyright (C) 2012 Vaadin Ltd.  
  2  # Copyright (C) 2012 Richard Lincoln 
  3  #  
  4  # Licensed under the Apache License, Version 2.0 (the "License");  
  5  # you may not use this file except in compliance with the License.  
  6  # You may obtain a copy of the License at  
  7  #  
  8  #     http://www.apache.org/licenses/LICENSE-2.0  
  9  #  
 10  # Unless required by applicable law or agreed to in writing, software  
 11  # distributed under the License is distributed on an "AS IS" BASIS,  
 12  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
 13  # See the License for the specific language governing permissions and  
 14  # limitations under the License. 
 15   
 16  from muntjac.ui.alignment import Alignment 
 17  from muntjac.ui.abstract_layout import AbstractLayout 
 18  from muntjac.ui.layout import IAlignmentHandler, ISpacingHandler 
 19  from muntjac.terminal.gwt.client.event_id import EventId 
 20   
 21  from muntjac.event.layout_events import \ 
 22      ILayoutClickNotifier, ILayoutClickListener, LayoutClickEvent 
 23   
 24   
25 -class AbstractOrderedLayout(AbstractLayout, IAlignmentHandler, 26 ISpacingHandler, ILayoutClickNotifier):
27 28 _CLICK_EVENT = EventId.LAYOUT_CLICK 29 30 ALIGNMENT_DEFAULT = Alignment.TOP_LEFT 31
32 - def __init__(self):
33 super(AbstractOrderedLayout, self).__init__() 34 35 # Custom layout slots containing the components. 36 self.components = list() 37 38 # Child component alignments 39 # Mapping from components to alignments (horizontal + vertical). 40 self._componentToAlignment = dict() 41 self._componentToExpandRatio = dict() 42 43 # Is spacing between contained components enabled. Defaults to false. 44 self._spacing = False
45 46
47 - def addComponent(self, c, index=None):
48 """Add a component into this container. The component is added 49 to the right or under the previous component or into the indexed 50 position in this container. 51 52 @param c: 53 the component to be added. 54 @param index: 55 the Index of the component position. The components 56 currently in and after the position are shifted 57 forwards. 58 """ 59 if index is None: 60 self.components.append(c) 61 else: 62 self.components.insert(index, c) 63 64 try: 65 super(AbstractOrderedLayout, self).addComponent(c) 66 self.requestRepaint() 67 except ValueError, e: 68 if c in self.components: 69 self.components.remove(c) 70 raise e
71 72
73 - def addComponentAsFirst(self, c):
74 """Adds a component into this container. The component is 75 added to the left or on top of the other components. 76 77 @param c: the component to be added. 78 """ 79 self.components.insert(0, c) 80 try: 81 super(AbstractOrderedLayout, self).addComponent(c) 82 self.requestRepaint() 83 except ValueError, e: 84 self.components.remove(c) 85 raise e
86 87
88 - def removeComponent(self, c):
89 """Removes the component from this container. 90 91 @param c: the component to be removed. 92 """ 93 if c in self.components: 94 self.components.remove(c) 95 if c in self._componentToAlignment: 96 del self._componentToAlignment[c] 97 if c in self._componentToExpandRatio: 98 del self._componentToExpandRatio[c] 99 super(AbstractOrderedLayout, self).removeComponent(c) 100 self.requestRepaint()
101 102
103 - def getComponentIterator(self):
104 """Gets the component container iterator for going through 105 all the components in the container. 106 107 @return: the Iterator of the components inside the container. 108 """ 109 return iter(self.components)
110 111
112 - def getComponentCount(self):
113 """Gets the number of contained components. Consistent with 114 the iterator returned by L{getComponentIterator}. 115 116 @return: the number of contained components 117 """ 118 return len(self.components)
119 120
121 - def paintContent(self, target):
122 """Paints the content of this component. 123 124 @param target: 125 the Paint Event. 126 @raise PaintException: 127 if the paint operation failed. 128 """ 129 super(AbstractOrderedLayout, self).paintContent(target) 130 131 # Add spacing attribute (omitted if false) 132 if self._spacing: 133 target.addAttribute('spacing', self._spacing) 134 135 # Adds all items in all the locations 136 for c in self.components: 137 # Paint child component UIDL 138 c.paint(target) 139 140 # Add child component alignment info to layout tag 141 target.addAttribute('alignments', self._componentToAlignment) 142 target.addAttribute('expandRatios', self._componentToExpandRatio)
143 144
145 - def replaceComponent(self, oldComponent, newComponent):
146 # Gets the locations 147 oldLocation = -1 148 newLocation = -1 149 location = 0 150 for component in self.components: 151 if component == oldComponent: 152 oldLocation = location 153 if component == newComponent: 154 newLocation = location 155 location += 1 156 157 if oldLocation == -1: 158 self.addComponent(newComponent) 159 elif newLocation == -1: 160 self.removeComponent(oldComponent) 161 self.addComponent(newComponent, oldLocation) 162 else: 163 if oldLocation > newLocation: 164 self.components.remove(oldComponent) 165 self.components.insert(newLocation, oldComponent) 166 self.components.remove(newComponent) 167 if newComponent in self._componentToAlignment: 168 del self._componentToAlignment[newComponent] 169 self.components.insert(oldLocation, newComponent) 170 else: 171 self.components.remove(newComponent) 172 self.components.insert(oldLocation, newComponent) 173 self.components.remove(oldComponent) 174 if oldComponent in self._componentToAlignment: 175 del self._componentToAlignment[oldComponent] 176 self.components.insert(newLocation, oldComponent) 177 178 self.requestRepaint()
179 180
181 - def setComponentAlignment(self, childComponent, alignment, 182 verticalAlignment=None):
183 """Sets the component alignment using a short hand string notation. 184 185 @deprecated: Replaced by L{setComponentAlignment} 186 187 @param childComponent: 188 A child component in this layout 189 @param alignment: 190 A short hand notation described in L{AlignmentUtils} 191 """ 192 if verticalAlignment is not None: 193 alignment = Alignment(alignment + verticalAlignment) 194 195 if childComponent in self.components: 196 self._componentToAlignment[childComponent] = alignment 197 self.requestRepaint() 198 else: 199 raise ValueError, ('Component must be added to layout ' 200 'before using setComponentAlignment()')
201 202
203 - def getComponentAlignment(self, childComponent):
204 alignment = self._componentToAlignment.get(childComponent) 205 if alignment is None: 206 return self.ALIGNMENT_DEFAULT 207 else: 208 return alignment
209 210
211 - def setSpacing(self, enabled):
212 self._spacing = enabled 213 self.requestRepaint()
214 215
216 - def isSpacingEnabled(self):
217 return self._spacing
218 219
220 - def isSpacing(self):
221 return self._spacing
222 223
224 - def setExpandRatio(self, component, ratio):
225 """This method is used to control how excess space in layout 226 is distributed among components. Excess space may exist if 227 layout is sized and contained non relatively sized components 228 don't consume all available space. 229 230 Example how to distribute 1:3 (33%) for component1 and 231 2:3 (67%) for component2:: 232 233 layout.setExpandRatio(component1, 1) 234 layout.setExpandRatio(component2, 2) 235 236 If no ratios have been set, the excess space is distributed 237 evenly among all components. 238 239 Note, that width or height (depending on orientation) needs 240 to be defined for this method to have any effect. 241 242 @see: L{ISizeable} 243 244 @param component: 245 the component in this layout which expand ratio 246 is to be set 247 @param ratio: 248 """ 249 if component in self.components: 250 self._componentToExpandRatio[component] = ratio 251 self.requestRepaint() 252 else: 253 raise ValueError, ('Component must be added to layout ' 254 'before using setExpandRatio()')
255 256
257 - def getExpandRatio(self, component):
258 """Returns the expand ratio of given component. 259 260 @param component: 261 which expand ratios is requested 262 @return: expand ratio of given component, 0.0 by default 263 """ 264 ratio = self._componentToExpandRatio.get(component) 265 return 0 if ratio is None else float(ratio)
266 267
268 - def addListener(self, listener, iface=None):
269 if (isinstance(listener, ILayoutClickListener) and 270 (iface is None or issubclass(iface, ILayoutClickListener))): 271 272 self.registerListener(self._CLICK_EVENT, LayoutClickEvent, 273 listener, ILayoutClickListener.clickMethod) 274 275 super(AbstractOrderedLayout, self).addListener(listener, iface)
276 277
278 - def addCallback(self, callback, eventType=None, *args):
279 if eventType is None: 280 eventType = callback._eventType 281 282 if issubclass(eventType, LayoutClickEvent): 283 self.registerCallback(LayoutClickEvent, callback, None, *args) 284 285 else: 286 super(AbstractOrderedLayout, self).addCallback(callback, 287 eventType, *args)
288 289
290 - def removeListener(self, listener, iface=None):
291 if (isinstance(listener, ILayoutClickListener) and 292 (iface is None or issubclass(iface, ILayoutClickListener))): 293 self.withdrawListener(self._CLICK_EVENT, LayoutClickEvent, listener) 294 295 super(AbstractOrderedLayout, self).removeListener(listener, iface)
296 297
298 - def removeCallback(self, callback, eventType=None):
299 if eventType is None: 300 eventType = callback._eventType 301 302 if issubclass(eventType, LayoutClickEvent): 303 self.withdrawCallback(LayoutClickEvent, callback, 304 self._CLICK_EVENT) 305 306 else: 307 super(AbstractOrderedLayout, self).removeCallback(callback, 308 eventType)
309 310
311 - def getComponentIndex(self, component):
312 """Returns the index of the given component. 313 314 @param component: 315 The component to look up. 316 @return: The index of the component or -1 if the component 317 is not a child. 318 """ 319 try: 320 return self.components.index(component) 321 except ValueError: 322 return -1
323 324
325 - def getComponent(self, index):
326 """Returns the component at the given position. 327 328 @param index: 329 The position of the component. 330 @return: The component at the given index. 331 @raise IndexError: 332 If the index is out of range. 333 """ 334 return self.components[index]
335