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

Source Code for Module 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 Composite import Composite 
 17  from pyjamas import Factory 
 18  from Widget import Widget 
 19  from SimplePanel import SimplePanel 
 20  from 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 if kwargs.has_key('Element'): 28 element = kwargs.pop('Element') 29 else: 30 element = DOM.createAnchor() 31 SimplePanel.__init__(self, element) 32 self.disclosurePanel = disclosurePanel 33 element = self.getElement() 34 DOM.setAttribute(element, "href", "javascript:void(0);"); 35 DOM.setStyleAttribute(element, "display", "block") 36 self.sinkEvents(Event.ONCLICK) 37 self.setStyleName("header")
38
39 - def onBrowserEvent(self, event):
40 type = DOM.eventGetType(event) 41 if type == "click": 42 DOM.eventPreventDefault(event) 43 newstate = not self.disclosurePanel.getOpen() 44 self.disclosurePanel.setOpen(newstate)
45 46 Factory.registerClass('pyjamas.ui.ClickableHeader', ClickableHeader) 47
48 -class DefaultHeader(Widget):
49 - def __init__(self, text):
50 Widget.__init__(self) 51 self.imageBase = pygwt.getModuleBaseURL() 52 53 self.root = DOM.createTable() 54 self.tbody = DOM.createTBody() 55 self.tr = DOM.createTR() 56 self.imageTD = DOM.createTD() 57 self.labelTD = DOM.createTD() 58 self.imgElem = DOM.createImg() 59 60 self.setElement(self.root) 61 DOM.appendChild(self.root, self.tbody) 62 DOM.appendChild(self.tbody, self.tr) 63 DOM.appendChild(self.tr, self.imageTD) 64 DOM.appendChild(self.tr, self.labelTD) 65 DOM.appendChild(self.imageTD, self.imgElem) 66 67 self.setText(text)
68
69 - def getText(self):
70 return DOM.getInnerText(self.labelTD)
71
72 - def setText(self, text):
73 DOM.setInnerText(self.labelTD, text)
74
75 - def onOpen(self, panel):
76 self.updateState(True)
77
78 - def onClose(self, panel):
79 self.updateState(False)
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.DefaultHeader', DefaultHeader) 93
94 -class DisclosurePanel(Composite):
95
96 - def __init__(self, *args, **kwargs):
97 98 self.handlers = [] 99 self.content = None 100 101 # this is awkward: VerticalPanel is the composite, 102 # so we get the element here, and pass it in to VerticalPanel. 103 element = kwargs.pop('Element', None) 104 105 # process the passed arguments 106 headerText = headerWidget = None 107 isOpen = False 108 if len(args) == 1: 109 header = args[0] 110 if len(args) == 2: 111 header, isOpen = args[:2] 112 # apparently "basestring" is not understood 113 if isinstance(header, str): 114 headerText = header 115 else: 116 headerWidget = header 117 isOpen = kwargs.pop('isOpen', isOpen) 118 headerText = kwargs.pop('header', headerText) 119 headerWidget = kwargs.pop('header', headerWidget) 120 # TODO: add ImageBundle 121 # images = kwargs.pop('images', None) 122 123 # If both headerText and headerWidget are arguments, headerText will 124 # be used to preserve API compatibility. 125 headerContent = headerWidget 126 if headerText is not None or headerContent is None: 127 if headerText is None: 128 headerText = "" 129 headerContent = DefaultHeader(headerText) 130 131 self.mainPanel = VerticalPanel(Element=element) 132 133 self._init_header(headerContent) 134 135 self.contentWrapper = SimplePanel() 136 self.mainPanel.add(self.header) 137 self.mainPanel.add(self.contentWrapper) 138 DOM.setStyleAttribute(self.contentWrapper.getElement(), 139 "padding", "0px"); 140 DOM.setStyleAttribute(self.contentWrapper.getElement(), 141 "overflow", "hidden"); 142 143 if not kwargs.has_key('StyleName'): kwargs['StyleName']="gwt-DisclosurePanel" 144 Composite.__init__(self, self.mainPanel, **kwargs) 145 146 # Must call setOpen after creating the initializing the object 147 self.isOpen = None 148 self.setOpen(isOpen) 149 150 self.setContentDisplay()
151
152 - def _init_header(self, headerContent):
153 self.header = ClickableHeader(self) 154 self.headerObj = headerContent 155 self.addEventHandler(self.headerObj) 156 self.setHeader(self.headerObj)
157
158 - def add(self, widget):
159 if self.getContent() is None: 160 self.setContent(widget)
161
162 - def addEventHandler(self, handler):
163 self.handlers.append(handler)
164
165 - def removeEventHandler(self, handler):
166 self.handlers.remove(handler)
167
168 - def clear(self):
169 self.setContent(None)
170
171 - def getContent(self):
172 return self.content
173
174 - def getHeader(self):
175 return self.header.getWidget()
176
177 - def getOpen(self):
178 return self.isOpen
179
180 - def remove(self, widget):
181 if widget == self.getContent(): 182 self.setContent(None) 183 return True 184 return False
185
186 - def setContent(self, widget):
187 if self.content is not None: 188 self.contentWrapper.setWidget(None) 189 self.content.removeStyleName("content") 190 191 self.content = widget 192 if self.content is not None: 193 self.contentWrapper.setWidget(self.content) 194 self.content.addStyleName("content") 195 self.setContentDisplay()
196
197 - def setHeader(self, widget):
198 self.header.setWidget(widget)
199
200 - def setOpen(self, isOpen):
201 if self.isOpen == isOpen: 202 return 203 self.isOpen = isOpen 204 self.setContentDisplay() 205 self.fireEvent()
206
207 - def fireEvent(self):
208 for handler in self.handlers: 209 if self.isOpen: 210 handler.onOpen(self) 211 else: 212 handler.onClose(self)
213
214 - def setContentDisplay(self):
215 if self.isOpen: 216 self.addStyleName("open") 217 self.removeStyleName("closed") 218 else: 219 self.addStyleName("closed") 220 self.removeStyleName("open") 221 self.contentWrapper.setVisible(self.isOpen)
222 223 Factory.registerClass('pyjamas.ui.DisclosurePanel', DisclosurePanel) 224