Home | Trees | Indices | Help |
|
---|
|
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 """Defines the default implementation for the methods in IComponentContainer. 17 """ 18 19 from muntjac.ui.abstract_component import AbstractComponent 20 21 from muntjac.ui.component_container import \ 22 ComponentAttachEvent, IComponentAttachListener, IComponentContainer, \ 23 ComponentDetachEvent, IComponentDetachListener 24 25 26 _COMPONENT_ATTACHED_METHOD = getattr(IComponentAttachListener, 27 'componentAttachedToContainer') 28 29 _COMPONENT_DETACHED_METHOD = getattr(IComponentDetachListener, 30 'componentDetachedFromContainer') 31 3234 """Extension to L{AbstractComponent} that defines the default 35 implementation for the methods in L{IComponentContainer}. Basic 36 UI components that need to contain other components inherit this class 37 to easily qualify as a component container. 38 39 @author: Vaadin Ltd. 40 @version: 1.1.2 41 """ 4238144 """Constructs a new component container.""" 45 super(AbstractComponentContainer, self).__init__()46 4749 """Removes all components from the container. This should probably 50 be re-implemented in extending classes for a more powerful 51 implementation. 52 """ 53 l = list() 54 55 # Adds all components 56 for c in self.getComponentIterator(): 57 l.append(c) 58 59 # Removes all components 60 for c in l: 61 self.removeComponent(c)62 6365 # Moves all components from an another container into this container. 66 components = list() 67 68 for c in self.getComponentIterator(): 69 components.append(c) 70 71 for c in components: 72 source.removeComponent(c) 73 self.addComponent(c)74 7577 """Notifies all contained components that the container is attached 78 to a window. 79 80 @see: L{IComponent.attach} 81 """ 82 super(AbstractComponentContainer, self).attach() 83 84 for c in self.getComponentIterator(): 85 c.attach()86 8789 """Notifies all contained components that the container is detached 90 from a window. 91 92 @see: L{IComponent.detach} 93 """ 94 # Events 95 super(AbstractComponentContainer, self).detach() 96 97 for c in self.getComponentIterator(): 98 c.detach()99 100102 if (isinstance(listener, IComponentAttachListener) and 103 (iface is None or issubclass(iface, IComponentAttachListener))): 104 self.registerListener(ComponentAttachEvent, listener, 105 _COMPONENT_ATTACHED_METHOD) 106 107 if (isinstance(listener, IComponentDetachListener) and 108 (iface is None or issubclass(iface, IComponentDetachListener))): 109 self.registerListener(ComponentDetachEvent, listener, 110 _COMPONENT_DETACHED_METHOD) 111 112 super(AbstractComponentContainer, self).addListener(listener, iface)113 114116 if eventType is None: 117 eventType = callback._eventType 118 119 if issubclass(eventType, ComponentAttachEvent): 120 self.registerCallback(ComponentAttachEvent, callback, None, *args) 121 122 elif issubclass(eventType, ComponentDetachEvent): 123 self.registerCallback(ComponentDetachEvent, callback, None, *args) 124 125 else: 126 super(AbstractComponentContainer, self).addCallback(callback, 127 eventType, *args)128 129131 if (isinstance(listener, IComponentAttachListener) and 132 (iface is None or issubclass(iface, IComponentAttachListener))): 133 self.withdrawListener(ComponentAttachEvent, listener, 134 _COMPONENT_ATTACHED_METHOD) 135 136 if (isinstance(listener, IComponentDetachListener) and 137 (iface is None or issubclass(iface, IComponentDetachListener))): 138 self.withdrawListener(ComponentDetachEvent, listener, 139 _COMPONENT_DETACHED_METHOD) 140 141 super(AbstractComponentContainer, self).removeListener(listener, iface)142 143145 if eventType is None: 146 eventType = callback._eventType 147 148 if issubclass(eventType, ComponentAttachEvent): 149 self.withdrawCallback(ComponentAttachEvent, callback) 150 151 elif issubclass(eventType, ComponentDetachEvent): 152 self.withdrawCallback(ComponentDetachEvent, callback) 153 154 else: 155 super(AbstractComponentContainer, self).removeCallback(callback, 156 eventType)157 158160 """Fires the component attached event. This should be called by 161 the addComponent methods after the component have been added to 162 this container. 163 164 @param component: 165 the component that has been added to this container. 166 """ 167 event = ComponentAttachEvent(self, component) 168 self.fireEvent(event)169 170172 """Fires the component detached event. This should be called by 173 the removeComponent methods after the component have been removed 174 from this container. 175 176 @param component: 177 the component that has been removed from this container. 178 """ 179 event = ComponentDetachEvent(self, component) 180 self.fireEvent(event)181 182184 """This only implements the events and component parent calls. The 185 extending classes must implement component list maintenance and call 186 this method after component list maintenance. 187 188 @see: L{IComponentContainer.addComponent} 189 """ 190 if isinstance(c, IComponentContainer): 191 # Make sure we're not adding the component 192 # inside it's own content 193 parent = self 194 while parent is not None: 195 parent = parent.getParent() 196 if parent == c: 197 msg = 'Component cannot be added inside it\'s own content' 198 raise ValueError, msg 199 200 if c.getParent() is not None: 201 # If the component already has a parent, try to remove it 202 oldParent = c.getParent() 203 oldParent.removeComponent(c) 204 205 c.setParent(self) 206 self.fireComponentAttachEvent(c)207 208210 """This only implements the events and component parent calls. The 211 extending classes must implement component list maintenance and call 212 this method before component list maintenance. 213 214 @see: L{IComponentContainer.removeComponent} 215 """ 216 if c.getParent() == self: 217 c.setParent(None) 218 self.fireComponentDetachEvent(c)219 220222 super(AbstractComponentContainer, self).setEnabled(enabled) 223 224 if self.getParent() is not None and not self.getParent().isEnabled(): 225 # some ancestor still disabled, don't update children 226 return 227 else: 228 self.requestRepaintAll()229 230232 if unit is not None: 233 from muntjac.terminal.gwt.server.component_size_validator import \ 234 ComponentSizeValidator # FIXME: circular import 235 236 # child tree repaints may be needed, due to our fall back support 237 # for invalid relative sizes 238 dirtyChildren = None 239 childrenMayBecomeUndefined = False 240 if (self.getWidth() == self.SIZE_UNDEFINED 241 and width != self.SIZE_UNDEFINED): 242 # children currently in invalid state may need repaint 243 dirtyChildren = self.getInvalidSizedChildren(False) 244 245 elif ((width == self.SIZE_UNDEFINED 246 and self.getWidth() != self.SIZE_UNDEFINED) 247 or (unit == self.UNITS_PERCENTAGE 248 and self.getWidthUnits() != self.UNITS_PERCENTAGE 249 and not ComponentSizeValidator.parentCanDefineWidth(self))): 250 251 # relative width children may get to invalid state if width 252 # becomes invalid. Width may also become invalid if units become 253 # percentage due to the fallback support 254 childrenMayBecomeUndefined = True 255 dirtyChildren = self.getInvalidSizedChildren(False) 256 257 super(AbstractComponentContainer, self).setWidth(width, unit) 258 self.repaintChangedChildTrees(dirtyChildren, 259 childrenMayBecomeUndefined, False) 260 else: 261 super(AbstractComponentContainer, self).setWidth(width)262 263264 - def repaintChangedChildTrees(self, invalidChildren, 265 childrenMayBecomeUndefined, vertical):266 if childrenMayBecomeUndefined: 267 previouslyInvalidComponents = invalidChildren 268 269 invalidChildren = self.getInvalidSizedChildren(vertical) 270 271 if (previouslyInvalidComponents is not None 272 and invalidChildren is not None): 273 for component in invalidChildren: 274 if component in previouslyInvalidComponents: 275 # still invalid don't repaint 276 previouslyInvalidComponents.remove(component) 277 278 elif invalidChildren is not None: 279 stillInvalidChildren = self.getInvalidSizedChildren(vertical) 280 281 if stillInvalidChildren is not None: 282 for component in stillInvalidChildren: 283 # didn't become valid 284 invalidChildren.remove(component) 285 286 if invalidChildren is not None: 287 self.repaintChildTrees(invalidChildren)288 289291 components = None 292 293 from muntjac.ui.panel import Panel # FIXME: circular import 294 from muntjac.terminal.gwt.server.component_size_validator import \ 295 ComponentSizeValidator # FIXME: circular import 296 297 if isinstance(self, Panel): 298 p = self 299 content = p.getContent() 300 if vertical: 301 valid = ComponentSizeValidator.checkHeights(content) 302 else: 303 valid = ComponentSizeValidator.checkWidths(content) 304 if not valid: 305 components = set() 306 components.add(content) 307 else: 308 for component in self.getComponentIterator(): 309 if vertical: 310 valid = ComponentSizeValidator.checkHeights(component) 311 else: 312 valid = ComponentSizeValidator.checkWidths(component) 313 if not valid: 314 if components is None: 315 components = set() 316 components.add(component) 317 318 return components319 320322 for c in dirtyChildren: 323 if isinstance(c, IComponentContainer): 324 c.requestRepaintAll() 325 else: 326 c.requestRepaint()327 328330 if unit is not None: 331 from muntjac.terminal.gwt.server.component_size_validator import \ 332 ComponentSizeValidator # FIXME: circular import 333 334 # child tree repaints may be needed, due to our fall back support 335 # for invalid relative sizes 336 dirtyChildren = None 337 childrenMayBecomeUndefined = False 338 if (self.getHeight() == self.SIZE_UNDEFINED 339 and height != self.SIZE_UNDEFINED): 340 # children currently in invalid state may need repaint 341 dirtyChildren = self.getInvalidSizedChildren(True) 342 343 elif ((height == self.SIZE_UNDEFINED 344 and self.getHeight() != self.SIZE_UNDEFINED) 345 or (unit == self.UNITS_PERCENTAGE 346 and self.getHeightUnits() != self.UNITS_PERCENTAGE 347 and not ComponentSizeValidator.parentCanDefineHeight(self))): 348 349 # relative height children may get to invalid state if height 350 # becomes invalid. Height may also become invalid if units 351 # become percentage due to the fallback support. 352 childrenMayBecomeUndefined = True 353 dirtyChildren = self.getInvalidSizedChildren(True) 354 355 super(AbstractComponentContainer, self).setHeight(height, unit) 356 357 self.repaintChangedChildTrees(dirtyChildren, 358 childrenMayBecomeUndefined, True) 359 else: 360 super(AbstractComponentContainer, self).setHeight(height)361 362364 self.requestRepaint() 365 366 from muntjac.ui.form import Form # FIXME: circular import 367 from muntjac.ui.table import Table 368 369 for c in self.getComponentIterator(): 370 if isinstance(c, Form): 371 # Form has children in layout, but 372 # is not IComponentContainer 373 c.requestRepaint() 374 c.getLayout().requestRepaintAll() 375 elif isinstance(c, Table): 376 c.requestRepaintAll() 377 elif isinstance(c, IComponentContainer): 378 c.requestRepaintAll() 379 else: 380 c.requestRepaint()
Home | Trees | Indices | Help |
|
---|
Generated by Epydoc 3.0.1 on Wed Jun 10 22:40:30 2015 | http://epydoc.sourceforge.net |