Package library :: Package pyjamas :: Package ui :: Module DisclosurePanel
[hide private]
[frames] | no frames]

Source Code for Module library.pyjamas.ui.DisclosurePanel

  1  # Copyright 2006 James Tauber and contributors 
  2  # Copyright (C) 2009 Luke Kenneth Casson Leighton <lkcl@lkcl.net> 
  3  # Copyright (C) 2010 Glenn Washburn <crass@berlios.de> 
  4  # 
  5  # Licensed under the Apache License, Version 2.0 (the "License"); 
  6  # you may not use this file except in compliance with the License. 
  7  # You may obtain a copy of the License at 
  8  # 
  9  #     http://www.apache.org/licenses/LICENSE-2.0 
 10  # 
 11  # Unless required by applicable law or agreed to in writing, software 
 12  # distributed under the License is distributed on an "AS IS" BASIS, 
 13  # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
 14  # See the License for the specific language governing permissions and 
 15  # limitations under the License. 
 16  from pyjamas.ui.Composite import Composite 
 17  from pyjamas import Factory 
 18  from pyjamas.ui.Widget import Widget 
 19  from pyjamas.ui.SimplePanel import SimplePanel 
 20  from pyjamas.ui.VerticalPanel import VerticalPanel 
 21  from pyjamas.ui import Event 
 22  from pyjamas import DOM 
 23  import pygwt 
 24   
25 -class ClickableHeader(SimplePanel):
26 - def __init__(self, disclosurePanel, **kwargs):
27 element = kwargs.pop('Element', DOM.createAnchor()) 28 SimplePanel.__init__(self, element) 29 self.disclosurePanel = disclosurePanel 30 element = self.getElement() 31 DOM.setAttribute(element, "href", "javascript:void(0);"); 32 DOM.setStyleAttribute(element, "display", "block") 33 self.sinkEvents(Event.ONCLICK) 34 self.setStyleName("header")
35
36 - def onBrowserEvent(self, event):
37 etype = DOM.eventGetType(event) 38 if etype == "click": 39 DOM.eventPreventDefault(event) 40 newstate = not self.disclosurePanel.getOpen() 41 self.disclosurePanel.setOpen(newstate)
42 43 Factory.registerClass('pyjamas.ui.DisclosurePanel', 'ClickableHeader', ClickableHeader) 44
45 -class DefaultHeader(Widget):
46 - def __init__(self, text, images=True):
47 Widget.__init__(self) 48 self.setImageBase(images) 49 50 self.root = DOM.createTable() 51 self.tbody = DOM.createTBody() 52 self.tr = DOM.createTR() 53 self.imageTD = DOM.createTD() 54 self.labelTD = DOM.createTD() 55 self.imgElem = DOM.createImg() 56 57 self.setElement(self.root) 58 DOM.appendChild(self.root, self.tbody) 59 DOM.appendChild(self.tbody, self.tr) 60 DOM.appendChild(self.tr, self.imageTD) 61 DOM.appendChild(self.tr, self.labelTD) 62 DOM.appendChild(self.imageTD, self.imgElem) 63 64 self.setText(text)
65
66 - def getText(self):
67 return DOM.getInnerText(self.labelTD)
68
69 - def setText(self, text):
70 DOM.setInnerText(self.labelTD, text)
71
72 - def onOpen(self, panel):
73 self.updateState(True)
74
75 - def onClose(self, panel):
76 self.updateState(False)
77
78 - def setImageBase(self, images):
79 self.imageBase = pygwt.getImageBaseURL(images)
80
81 - def updateState(self, setOpen):
82 if setOpen: 83 DOM.setAttribute(self.imgElem, "src", 84 self.imageBase + "disclosurePanelOpen.png") 85 else: 86 DOM.setAttribute(self.imgElem, "src", 87 self.imageBase + "disclosurePanelClosed.png")
88 89 90 # TODO: must be able to pass in DisclosurePanel argument by a means 91 # *other* than an actual class instance. 92 #Factory.registerClass('pyjamas.ui.DisclosurePanel', 'DefaultHeader', DefaultHeader) 93
94 -class DisclosurePanel(Composite):
95
96 - def __init__(self, *args, **kwargs):
97 98 self.handlers = [] 99 self.content = None 100 self.images = False 101 102 # this is awkward: VerticalPanel is the composite, 103 # so we get the element here, and pass it in to VerticalPanel. 104 element = kwargs.pop('Element', None) 105 106 # process the passed arguments 107 headerText = headerWidget = None 108 isOpen = False 109 if len(args) == 1: 110 header = args[0] 111 if len(args) == 2: 112 header, isOpen = args[:2] 113 # apparently "basestring" is not understood 114 if isinstance(header, basestring): 115 headerText = header 116 else: 117 headerWidget = header 118 isOpen = kwargs.pop('isOpen', isOpen) 119 headerText = kwargs.pop('header', headerText) 120 headerWidget = kwargs.pop('header', headerWidget) 121 # TODO: add ImageBundle 122 # images = kwargs.pop('images', None) 123 124 # If both headerText and headerWidget are arguments, headerText will 125 # be used to preserve API compatibility. 126 headerContent = headerWidget 127 if headerText is not None or headerContent is None: 128 if headerText is None: 129 headerText = "" 130 headerContent = DefaultHeader(headerText) 131 132 self.mainPanel = VerticalPanel(Element=element) 133 134 self._init_header(headerContent) 135 136 self.contentWrapper = SimplePanel() 137 self.mainPanel.add(self.header) 138 self.mainPanel.add(self.contentWrapper) 139 DOM.setStyleAttribute(self.contentWrapper.getElement(), 140 "padding", "0px"); 141 DOM.setStyleAttribute(self.contentWrapper.getElement(), 142 "overflow", "hidden"); 143 144 kwargs['StyleName'] = kwargs.get('StyleName', "gwt-DisclosurePanel") 145 Composite.__init__(self, self.mainPanel, **kwargs) 146 147 # Must call setOpen after creating the initializing the object 148 self.isOpen = None 149 self.setOpen(isOpen) 150 151 self.setContentDisplay()
152
153 - def _init_header(self, headerContent):
154 self.header = ClickableHeader(self) 155 self.headerObj = headerContent 156 self.addEventHandler(self.headerObj) 157 self.setHeader(self.headerObj)
158
159 - def add(self, widget):
160 if self.getContent() is None: 161 self.setContent(widget)
162
163 - def addEventHandler(self, handler):
164 self.handlers.append(handler)
165
166 - def removeEventHandler(self, handler):
167 self.handlers.remove(handler)
168
169 - def clear(self):
170 self.setContent(None)
171
172 - def getContent(self):
173 return self.content
174
175 - def getHeader(self):
176 return self.header.getWidget()
177
178 - def getOpen(self):
179 return self.isOpen
180
181 - def getImages(self):
182 return self.images
183
184 - def remove(self, widget):
185 if widget == self.getContent(): 186 self.setContent(None) 187 return True 188 return False
189
190 - def setContent(self, widget):
191 if self.content is not None: 192 self.contentWrapper.setWidget(None) 193 self.content.removeStyleName("content") 194 195 self.content = widget 196 if self.content is not None: 197 self.contentWrapper.setWidget(self.content) 198 self.content.addStyleName("content") 199 self.setContentDisplay()
200
201 - def setHeader(self, widget):
202 self.header.setWidget(widget)
203
204 - def setOpen(self, isOpen):
205 if self.isOpen == isOpen: 206 return 207 self.isOpen = isOpen 208 self.setContentDisplay() 209 self.fireEvent()
210
211 - def setImages(self, images):
212 if self.images == images: 213 return 214 self.images = images 215 header = self.getHeader() 216 if header is not None and isinstance(header,DefaultHeader): 217 header.setImageBase(images) 218 header.updateState(self.getOpen())
219
220 - def fireEvent(self):
221 for handler in self.handlers: 222 if self.isOpen: 223 handler.onOpen(self) 224 else: 225 handler.onClose(self)
226
227 - def setContentDisplay(self):
228 if self.isOpen: 229 self.addStyleName("open") 230 self.removeStyleName("closed") 231 else: 232 self.addStyleName("closed") 233 self.removeStyleName("open") 234 self.contentWrapper.setVisible(self.isOpen)
235 236 Factory.registerClass('pyjamas.ui.DisclosurePanel', 'DisclosurePanel', DisclosurePanel) 237