1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 from pyjamas import DOM
16 from pyjamas import Factory
17 from __pyjamas__ import console
18 from sets import Set
19 import pygwt
20
21 from Widget import Widget
22 from pyjamas.ui import Event
23 from pyjamas.ui import Focus
24 from TreeItem import RootTreeItem, TreeItem
25 from pyjamas.ui import MouseListener
26 from pyjamas.ui import KeyboardListener
27 from pyjamas.ui import FocusListener
28
31 if not kwargs.has_key('StyleName'): kwargs['StyleName']="gwt-Tree"
32
33 self.root = None
34 self.childWidgets = Set()
35 self.curSelection = None
36 self.focusable = None
37 self.focusListeners = []
38 self.mouseListeners = []
39 self.imageBase = pygwt.getModuleBaseURL()
40 self.keyboardListeners = []
41 self.listeners = []
42 self.lastEventType = ""
43
44 if kwargs.has_key('Element'):
45 element = kwargs.pop('Element')
46 else:
47 element = DOM.createDiv()
48 self.setElement(element)
49 DOM.setStyleAttribute(self.getElement(), "position", "relative")
50 self.focusable = Focus.createFocusable()
51
52 DOM.setStyleAttribute(self.focusable, "outline", "0px")
53
54 DOM.setElemAttribute(self.focusable, "hideFocus", "true");
55
56 DOM.setStyleAttribute(self.focusable, "fontSize", "0")
57 DOM.setStyleAttribute(self.focusable, "position", "absolute")
58 DOM.setIntStyleAttribute(self.focusable, "zIndex", -1)
59 DOM.appendChild(self.getElement(), self.focusable)
60
61 self.root = RootTreeItem()
62 self.root.setTree(self)
63
64 Widget.__init__(self, **kwargs)
65
66 self.sinkEvents(Event.ONMOUSEDOWN | Event.ONCLICK | Event.KEYEVENTS)
67
68 DOM.sinkEvents(self.focusable, Event.FOCUSEVENTS)
69
70 - def add(self, widget):
72
74 self.focusListeners.append(listener)
75
78
90
92 self.keyboardListeners.append(listener)
93
95 self.mouseListeners.append(listener)
96
99
104
106 if self.curSelection is None:
107 return
108
109 parent = self.curSelection.getParentItem()
110 while parent is not None:
111 parent.setState(True)
112 parent = parent.getParentItem()
113
115 return self.imageBase
116
119
122
124 return self.curSelection
125
128
131
133 type = DOM.eventGetType(event)
134
135 if type == "click":
136 e = DOM.eventGetTarget(event)
137 if not self.shouldTreeDelegateFocusToElement(e) and \
138 self.curSelection is not None:
139 self.setFocus(True)
140 elif type == "mousedown":
141 MouseListener.fireMouseEvent(self.mouseListeners, self, event)
142 self.elementClicked(self.root, DOM.eventGetTarget(event))
143 elif type == "mouseup" or type == "mousemove" or type == "mouseover" or type == "mouseout":
144 MouseListener.fireMouseEvent(self.mouseListeners, self, event)
145 elif type == "blur" or type == "focus":
146 FocusListener.fireFocusEvent(self.focusListeners, self, event)
147 elif type == "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 type == "keyup":
173 if DOM.eventGetKeyCode(event) == KeyboardListener.KEY_TAB:
174 chain = []
175 self.collectElementChain(chain, self.getElement(), DOM.eventGetTarget(event))
176 item = self.findItemByChain(chain, 0, self.root)
177 if item != self.getSelectedItem():
178 self.setSelectedItem(item, True)
179 elif type == "keypress":
180 KeyboardListener.fireKeyboardEvent(self.keyboardListeners, self, event)
181
182 Widget.onBrowserEvent(self, event)
183 self.lastEventType = type
184
186
187 console.error("Widgets should never be directly removed from a tree")
188
190 self.focusListeners.remove(listener)
191
195
199
201 self.keyboardListeners.remove(listener)
202
205
208
214
218
220 if item is None:
221 if self.curSelection is None:
222 return
223 self.curSelection.setSelected(False)
224 self.curSelection = None
225 return
226
227 self.onSelection(item, fireEvents)
228
231
236
243
258
263
278
280 focusableWidget = selection.getFocusableWidget()
281 if focusableWidget is not None:
282 focusableWidget.setFocus(True)
283 DOM.scrollIntoView(focusableWidget.getElement())
284 else:
285 selectedElem = selection.getContentElem()
286 containerLeft = self.getAbsoluteLeft()
287 containerTop = self.getAbsoluteTop()
288
289 left = DOM.getAbsoluteLeft(selectedElem) - containerLeft
290 top = DOM.getAbsoluteTop(selectedElem) - containerTop
291 width = DOM.getIntAttribute(selectedElem, "offsetWidth")
292 height = DOM.getIntAttribute(selectedElem, "offsetHeight")
293
294 DOM.setIntStyleAttribute(self.focusable, "left", left)
295 DOM.setIntStyleAttribute(self.focusable, "top", top)
296 DOM.setIntStyleAttribute(self.focusable, "width", width)
297 DOM.setIntStyleAttribute(self.focusable, "height", height)
298
299 DOM.scrollIntoView(self.focusable)
300 Focus.focus(self.focusable)
301
318
330
332 if item == self.root:
333 return
334
335 if self.curSelection is not None:
336 self.curSelection.setSelected(False)
337
338 self.curSelection = item
339
340 if self.curSelection is not None:
341 self.moveFocus(self.curSelection)
342 self.curSelection.setSelected(True)
343 if fireEvents and len(self.listeners):
344 for listener in self.listeners:
345 listener.onTreeItemSelected(item)
346
351
356
359
360 - def adopt(self, content):
363
367
369 for listener in self.listeners:
370 if hasattr(listener, "onTreeItemStateChanged"):
371 listener.onTreeItemStateChanged(item)
372
375
377 name = str(elem.nodeName)
378 name = name.lower()
379 return name == 'select' or\
380 name == 'input' or\
381 name == 'checkbox'
382
383 Factory.registerClass('pyjamas.ui.Tree', Tree)
384