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

Source Code for Module pyjamas.ui.SplitPanel

  1  """ 
  2  /* 
  3   * Copyright 2008 Google Inc. 
  4   * Copyright (C) 2009 Luke Kenneth Casson Leighton <lkcl@lkcl.net> 
  5   *  
  6   * Licensed under the Apache License, Version 2.0 (the "License") you may not 
  7   * use this file except in compliance with the License. You may obtain a copy of 
  8   * the License at 
  9   *  
 10   * http:#www.apache.org/licenses/LICENSE-2.0 
 11   *  
 12   * Unless required by applicable law or agreed to in writing, software 
 13   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 
 14   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 
 15   * License for the specific language governing permissions and limitations under 
 16   * the License. 
 17   */ 
 18  """ 
 19  from Panel import Panel 
 20  from pyjamas import Factory 
 21  from pyjamas.ui import Event 
 22   
 23  from pyjamas import DOM 
 24   
25 -class SplitPanel(Panel):
26 """ Abstract base class for {@link HorizontalSplitPanel} and 27 {@link VerticalSplitPanel}. 28 """ 29
30 - def __init__(self, mainElem, splitElem, headElem, tailElem, **kwargs):
31 """ Initializes the split panel. 32 @param mainElem the root element for the split panel 33 @param splitElem the element that acts as the splitter 34 @param headElem the element to contain the top or left most widget 35 @param tailElem the element to contain the bottom or right most widget 36 """ 37 38 self.widgets = [None, None] 39 self.elements = [headElem, tailElem] 40 self.isResizing = False 41 42 self.setElement(mainElem) 43 self.splitElem = splitElem 44 45 if not kwargs.has_key('ThumbImage'): 46 kwargs['ThumbImage'] = "splitPanelThumb.png" 47 48 Panel.__init__(self, **kwargs) 49 50 self.sinkEvents(Event.MOUSEEVENTS)
51
52 - def setThumbImage(self, ti):
53 self.thumb_image = ti
54
55 - def getThumbImageHTML(self):
56 if self.thumb_image: 57 return '<img src="%s" />' % self.thumb_image 58 return ""
59
60 - def addAbsolutePositoning(self, elem):
61 """ Sets an elements positioning to absolute. 62 """ 63 DOM.setStyleAttribute(elem, "position", "absolute")
64
65 - def addClipping(self, elem):
66 """ Adds clipping to an element. 67 """ 68 DOM.setStyleAttribute(elem, "overflow", "hidden")
69
70 - def addScrolling(self, elem):
71 """ Adds as-needed scrolling to an element. 72 """ 73 DOM.setStyleAttribute(elem, "overflow", "auto")
74
75 - def expandToFitParentUsingCssOffsets(self, elem):
76 """ Sizes and element to consume the full area of its parent 77 using the CSS properties left, right, top, and 78 bottom. This method is used for all browsers except IE6/7. 79 """ 80 zeroSize = "0px" 81 82 self.addAbsolutePositoning(elem) 83 self.setLeft(elem, zeroSize) 84 self.setRight(elem, zeroSize) 85 self.setTop(elem, zeroSize) 86 self.setBottom(elem, zeroSize)
87
88 - def expandToFitParentUsingPercentages(self, elem):
89 """ Sizes an element to consume the full areas of its parent 90 using 100% width and height. This method is used on IE6/7 91 where CSS offsets don't work reliably. 92 """ 93 zeroSize = "0px" 94 fullSize = "100%" 95 96 self.addAbsolutePositoning(elem) 97 self.setTop(elem, zeroSize) 98 self.setLeft(elem, zeroSize) 99 self.setElemWidth(elem, fullSize) 100 self.setElemHeight(elem, fullSize)
101
102 - def preventBoxStyles(self, elem):
103 """ Adds zero or none CSS values for padding, margin and 104 border to prevent stylesheet overrides. Returns the 105 element for convenience to support builder pattern. 106 """ 107 DOM.setIntStyleAttribute(elem, "padding", 0) 108 DOM.setIntStyleAttribute(elem, "margin", 0) 109 DOM.setStyleAttribute(elem, "border", "none") 110 return elem
111
112 - def setBottom(self, elem, size):
113 """ Convenience method to set bottom offset of an element. 114 """ 115 DOM.setStyleAttribute(elem, "bottom", size)
116
117 - def setElemHeight(self, elem, height):
118 """ Convenience method to set the height of an element. 119 """ 120 DOM.setStyleAttribute(elem, "height", height)
121
122 - def setLeft(self, elem, left):
123 """ Convenience method to set the left offset of an element. 124 """ 125 DOM.setStyleAttribute(elem, "left", left)
126
127 - def setRight(self, elem, right):
128 """ Convenience method to set the right offset of an element. 129 """ 130 DOM.setStyleAttribute(elem, "right", right)
131
132 - def setTop(self, elem, top):
133 """ Convenience method to set the top offset of an element. 134 """ 135 DOM.setStyleAttribute(elem, "top", top)
136
137 - def setElemWidth(self, elem, width):
138 """ Convenience method to set the width of an element. 139 """ 140 DOM.setStyleAttribute(elem, "width", width)
141
142 - def add(self, w):
143 if self.getWidget(0) is None: 144 self.setWidget(0, w) 145 elif self.getWidget(1) is None: 146 self.setWidget(1, w)
147 #else: 148 # raise IllegalStateException("A Splitter can only contain two Widgets.") 149
150 - def isResizing(self):
151 """ Indicates whether the split panel is being resized. 152 153 @return <code>True</code> if the user is dragging the splitter, 154 <code>False</code> otherwise 155 """ 156 return self.isResizing
157
158 - def __iter__(self):
159 return self.widgets.__iter__()
160
161 - def onBrowserEvent(self, event):
162 typ = DOM.eventGetType(event) 163 164 if typ == "mousedown": 165 target = DOM.eventGetTarget(event) 166 if DOM.isOrHasChild(self.splitElem, target): 167 self.startResizingFrom(DOM.eventGetClientX(event) - 168 self.getAbsoluteLeft(), 169 DOM.eventGetClientY(event) - self.getAbsoluteTop()) 170 DOM.setCapture(self.getElement()) 171 DOM.eventPreventDefault(event) 172 173 elif typ == "mouseup": 174 DOM.releaseCapture(self.getElement()) 175 self.stopResizing() 176 177 elif typ == 'mousemove': 178 if self.isResizing: 179 #assert DOM.getCaptureElement() is not None 180 self.onSplitterResize(DOM.eventGetClientX(event) - 181 self.getAbsoluteLeft(), 182 DOM.eventGetClientY(event) - self.getAbsoluteTop()) 183 DOM.eventPreventDefault(event)
184
185 - def remove(self, widget):
186 if widgets[0] == widget: 187 setWidget(0, None) 188 return True 189 elif widgets[1] == widget: 190 setWidget(1, None) 191 return True 192 return False
193
194 - def setSplitPosition(self, size):
195 """ Moves the position of the splitter. 196 @param size the new size of the left region in CSS units 197 (e.g. "10px", "1em") 198 """ 199 pass
200
201 - def getWidgetElement(self, index):
202 """ Gets the content element for the given index. 203 @param index the index of the element, only 0 and 1 are valid. 204 @return the element 205 """ 206 return self.elements[index]
207
208 - def getSplitElement(self):
209 """ Gets the element that is acting as the splitter. 210 @return the element 211 """ 212 return self.splitElem
213
214 - def getWidget(self, index):
215 """ Gets one of the contained widgets. 216 @param index the index of the widget, only 0 and 1 are valid. 217 @return the widget 218 """ 219 return self.widgets[index]
220
221 - def setWidget(self, index, w):
222 """ Sets one of the contained widgets. 223 @param index the index, only 0 and 1 are valid 224 @param w the widget 225 """ 226 oldWidget = self.widgets[index] 227 228 if oldWidget == w: 229 return 230 231 if w is not None: 232 w.removeFromParent() 233 234 # Remove the old child. 235 if oldWidget is not None: 236 # Orphan old. 237 self.disown(oldWidget) 238 # Physical detach old. 239 #DOM.removeChild(self.elements[index], oldWidget.getElement()) 240 241 # Logical detach old / attach new. 242 self.widgets[index] = w 243 244 if w is not None: 245 # Physical attach new. 246 DOM.appendChild(self.elements[index], w.getElement()) 247 248 # Adopt new. 249 self.adopt(w, None)
250
251 - def onSplitterResize(self, x, y):
252 """ Called on each mouse drag event as the user is dragging 253 the splitter. 254 @param x the x coord of the mouse relative to the panel's extent 255 @param y the y coord of the mosue relative to the panel's extent 256 """ 257 pass
258
259 - def onSplitterResizeStarted(self, x, y):
260 """ Called when the user starts dragging the splitter. 261 @param x the x coord of the mouse relative to the panel's extent 262 @param y the y coord of the mouse relative to the panel's extent 263 """
264
265 - def startResizingFrom(self, x, y):
266 self.isResizing = True 267 self.onSplitterResizeStarted(x, y)
268
269 - def stopResizing(self):
270 self.isResizing = False
271 272 # TODO: this is really an internal base class for Horizontal and Vertical 273 # SplitPanels? 274 #Factory.registerClass('pyjamas.ui.SplitPanel', SplitPanel) 275