1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 from pyjamas import DOM
17 from pyjamas import Factory
18 from __pyjamas__ import console
19 from sets import Set
20 import pygwt
21
22 from pyjamas.ui.Widget import Widget
23 from pyjamas.ui import Event
24 from pyjamas.ui import Focus
25 from pyjamas.ui.TreeItem import RootTreeItem, TreeItem
26 from pyjamas.ui import MouseListener
27 from pyjamas.ui import KeyboardListener
28 from pyjamas.ui import FocusListener
29
32 ka['StyleName'] = ka.get('StyleName', "gwt-Tree")
33
34 self.root = None
35 self.childWidgets = Set()
36 self.curSelection = None
37 self.focusable = None
38 self.focusListeners = []
39 self.mouseListeners = []
40 self.images = ka.pop('Images', False)
41 self.imageBase = pygwt.getImageBaseURL(self.images)
42 self.keyboardListeners = []
43 self.listeners = []
44 self.lastEventType = ""
45
46 element = ka.pop('Element', None) or DOM.createDiv()
47 self.setElement(element)
48 DOM.setStyleAttribute(self.getElement(), "position", "relative")
49 self.focusable = Focus.createFocusable()
50
51 DOM.setStyleAttribute(self.focusable, "outline", "0px")
52
53 DOM.setElemAttribute(self.focusable, "hideFocus", "true");
54
55 DOM.setStyleAttribute(self.focusable, "fontSize", "0")
56 DOM.setStyleAttribute(self.focusable, "position", "absolute")
57 DOM.setIntStyleAttribute(self.focusable, "zIndex", -1)
58 DOM.appendChild(self.getElement(), self.focusable)
59
60 self.root = RootTreeItem()
61 self.root.setTree(self)
62
63 Widget.__init__(self, **ka)
64
65 self.sinkEvents(Event.ONMOUSEDOWN | Event.ONCLICK | Event.KEYEVENTS)
66 DOM.sinkEvents(self.focusable, Event.FOCUSEVENTS)
67
68 - def add(self, widget):
70
72 self.focusListeners.append(listener)
73
76
88
90 self.keyboardListeners.append(listener)
91
93 self.mouseListeners.append(listener)
94
97
102
104 if self.curSelection is None:
105 return
106
107 parent = self.curSelection.getParentItem()
108 while parent is not None:
109 parent.setState(True)
110 parent = parent.getParentItem()
111
113 return self.imageBase
114
117
120
123
125 return self.curSelection
126
129
132
134 etype = DOM.eventGetType(event)
135
136 if etype == "click":
137 e = DOM.eventGetTarget(event)
138 if not self.shouldTreeDelegateFocusToElement(e) and \
139 self.curSelection is not None:
140 self.setFocus(True)
141 elif etype in MouseListener.MOUSE_EVENTS:
142 if etype == "mousedown":
143 self.elementClicked(self.root, DOM.eventGetTarget(event))
144 MouseListener.fireMouseEvent(self.mouseListeners, self, event)
145 elif etype == "blur" or etype == "focus":
146 FocusListener.fireFocusEvent(self.focusListeners, self, event)
147 elif etype == "keydown":
148 if self.curSelection is None:
149 if self.root.getChildCount() > 0:
150 self.onSelection(self.root.getChild(0), True)
151 Widget.onBrowserEvent(self, event)
152 return
153
154 if self.lastEventType == "keydown":
155 return
156
157 keycode = DOM.eventGetKeyCode(event)
158 if keycode == KeyboardListener.KEY_UP:
159 self.moveSelectionUp(self.curSelection, True)
160 DOM.eventPreventDefault(event)
161 elif keycode == KeyboardListener.KEY_DOWN:
162 self.moveSelectionDown(self.curSelection, True)
163 DOM.eventPreventDefault(event)
164 elif keycode == KeyboardListener.KEY_LEFT:
165 if self.curSelection.getState():
166 self.curSelection.setState(False)
167 DOM.eventPreventDefault(event)
168 elif keycode == KeyboardListener.KEY_RIGHT:
169 if not self.curSelection.getState():
170 self.curSelection.setState(True)
171 DOM.eventPreventDefault(event)
172 elif etype == "keyup":
173 if DOM.eventGetKeyCode(event) == KeyboardListener.KEY_TAB:
174 chain = []
175 self.collectElementChain(chain, self.getElement(),
176 DOM.eventGetTarget(event))
177 item = self.findItemByChain(chain, 0, self.root)
178 if item != self.getSelectedItem():
179 self.setSelectedItem(item, True)
180 elif etype == "keypress":
181 KeyboardListener.fireKeyboardEvent(self.keyboardListeners,
182 self, event)
183
184 Widget.onBrowserEvent(self, event)
185 self.lastEventType = etype
186
188 raise Exception("Widgets should never be directly removed from a tree")
189
191 self.focusListeners.remove(listener)
192
196
200
202 self.keyboardListeners.remove(listener)
203
206
209
215
219
221 if self.images == images:
222 return
223 self.images = images
224 self.setImageBase(pygwt.getImageBaseURL(self.images))
225
227 if item is None:
228 if self.curSelection is None:
229 return
230 self.curSelection.setSelected(False)
231 self.curSelection = None
232 return
233
234 self.onSelection(item, fireEvents)
235
238
243
250
265
270
285
287 focusableWidget = selection.getFocusableWidget()
288 if focusableWidget is not None:
289 focusableWidget.setFocus(True)
290 DOM.scrollIntoView(focusableWidget.getElement())
291 else:
292 selectedElem = selection.getContentElem()
293 containerLeft = self.getAbsoluteLeft()
294 containerTop = self.getAbsoluteTop()
295
296 left = DOM.getAbsoluteLeft(selectedElem) - containerLeft
297 top = DOM.getAbsoluteTop(selectedElem) - containerTop
298 width = DOM.getIntAttribute(selectedElem, "offsetWidth")
299 height = DOM.getIntAttribute(selectedElem, "offsetHeight")
300
301 DOM.setIntStyleAttribute(self.focusable, "left", "%spx" % left)
302 DOM.setIntStyleAttribute(self.focusable, "top", "%spx" % top)
303 DOM.setIntStyleAttribute(self.focusable, "width", "%spx" % width)
304 DOM.setIntStyleAttribute(self.focusable, "height", "%spx" % height)
305
306 DOM.scrollIntoView(self.focusable)
307 Focus.focus(self.focusable)
308
325
337
339 if item == self.root:
340 return
341
342 if fireEvents and len(self.listeners):
343 for listener in self.listeners:
344 onBefore = getattr(listener, "onBeforeTreeItemSelected", None)
345 if onBefore is not None:
346 if not onBefore(item):
347 return
348
349 if self.curSelection is not None:
350 self.curSelection.setSelected(False)
351
352 self.curSelection = item
353
354 if self.curSelection is not None:
355 self.moveFocus(self.curSelection)
356 self.curSelection.setSelected(True)
357 if fireEvents and len(self.listeners):
358 for listener in self.listeners:
359 listener.onTreeItemSelected(item)
360
365
370
373
374 - def adopt(self, content):
377
381
383 for listener in self.listeners:
384 if hasattr(listener, "onTreeItemStateChanged"):
385 listener.onTreeItemStateChanged(item)
386
389
391 name = str(elem.nodeName)
392 name = name.lower()
393 return name == 'select' or \
394 name == 'input' or \
395 name == 'checkbox'
396
397 Factory.registerClass('pyjamas.ui.Tree', 'Tree', Tree)
398