comparison browser_side/base_widget.py @ 196:c2639c9f86ea

Browser Side: Widgets can now be moved, header (title bar) is draggable: - DragLabel moved to tools - new LiberviaDragWidget which manage currently dragged widget - getLiberviaWidgetsCount give number of widget of WidgetsPanel - LiberviaWidget's header has now its own class - new "WIDGET" drag type /!\ not fully finished, can crash if moved on the bad border (like last row border if the widget is the only one on this row)
author Goffi <goffi@goffi.org>
date Tue, 05 Mar 2013 01:20:59 +0100
parents dd27072d8ae0
children 0fc32122a877
comparison
equal deleted inserted replaced
195:dd27072d8ae0 196:c2639c9f86ea
34 from pyjamas.ui.DropWidget import DropWidget 34 from pyjamas.ui.DropWidget import DropWidget
35 from pyjamas.ui.ClickListener import ClickHandler 35 from pyjamas.ui.ClickListener import ClickHandler
36 from pyjamas.ui import HasAlignment 36 from pyjamas.ui import HasAlignment
37 from pyjamas import DOM 37 from pyjamas import DOM
38 import dialog 38 import dialog
39 from tools import LiberviaDragWidget
39 from pyjamas import Window 40 from pyjamas import Window
40 from __pyjamas__ import doc 41 from __pyjamas__ import doc
41 42
42 class DropCell(DropWidget): 43 class DropCell(DropWidget):
43 """Cell in the middle grid which replace itself with the dropped widget on DnD""" 44 """Cell in the middle grid which replace itself with the dropped widget on DnD"""
51 @classmethod 52 @classmethod
52 def addDropKey(cls, key, callback): 53 def addDropKey(cls, key, callback):
53 DropCell.drop_keys[key] = callback 54 DropCell.drop_keys[key] = callback
54 55
55 def onDragEnter(self, event): 56 def onDragEnter(self, event):
57 if self == LiberviaDragWidget.current:
58 return
56 self.addStyleName('dragover') 59 self.addStyleName('dragover')
57 DOM.eventPreventDefault(event) 60 DOM.eventPreventDefault(event)
58 61
59 def onDragLeave(self, event): 62 def onDragLeave(self, event):
60 if event.clientX <= self.getAbsoluteLeft() or event.clientY <= self.getAbsoluteTop() or\ 63 if event.clientX <= self.getAbsoluteLeft() or event.clientY <= self.getAbsoluteTop() or\
87 except: 90 except:
88 print "no message found" 91 print "no message found"
89 item='&nbsp;' 92 item='&nbsp;'
90 item_type = None 93 item_type = None
91 DOM.eventPreventDefault(event) 94 DOM.eventPreventDefault(event)
92 if item_type in self.drop_keys: 95 if item_type == "WIDGET":
96 if not LiberviaDragWidget.current:
97 print "ERROR: No widget registered in LiberviaDragWidget !"
98 return
99 _new_panel = LiberviaDragWidget.current
100 if self == _new_panel: # We can't drop on ourself
101 return
102 # we need to remove the widget from the panel as it will be inserted elsewhere
103 widgets_panel = _new_panel.getWidgetsPanel()
104 if widgets_panel.getLiberviaWidgetsCount() == 1:
105 # the dropped widget is the only one in the panel,
106 # we don't do anything
107 self.removeStyleName('dragover')
108 return
109 widgets_panel.removeWidget(_new_panel)
110 elif item_type in self.drop_keys:
93 _new_panel = self.drop_keys[item_type](self.host,item) 111 _new_panel = self.drop_keys[item_type](self.host,item)
94 else: 112 else:
95 return False 113 print "WARNING: unmanaged item type"
114 return
96 if isinstance(self, LiberviaWidget): 115 if isinstance(self, LiberviaWidget):
97 self.host.unregisterWidget(self) 116 self.host.unregisterWidget(self)
98 self.onQuit() 117 self.onQuit()
99 if not isinstance(_new_panel, LiberviaWidget): 118 if not isinstance(_new_panel, LiberviaWidget):
100 print ('WARNING: droping an object which is not a class of LiberviaWidget') 119 print ('WARNING: droping an object which is not a class of LiberviaWidget')
110 for panel in _unempty_panels: 129 for panel in _unempty_panels:
111 td_elt = panel.getElement().parentNode 130 td_elt = panel.getElement().parentNode
112 DOM.setStyleAttribute(td_elt, "width", "%s%%" % _width)""" 131 DOM.setStyleAttribute(td_elt, "width", "%s%%" % _width)"""
113 #FIXME: delete object ? Check the right way with pyjamas 132 #FIXME: delete object ? Check the right way with pyjamas
114 133
134 class WidgetHeader(AbsolutePanel, LiberviaDragWidget):
135
136 def __init__(self, parent, title):
137 AbsolutePanel.__init__(self)
138 self.add(title)
139 button_group_wrapper = SimplePanel()
140 button_group_wrapper.setStyleName('widgetHeader_buttonsWrapper')
141 button_group = HorizontalPanel()
142 button_group.setStyleName('widgetHeader_buttonGroup')
143 setting_button = Image("media/icons/misc/settings.png")
144 setting_button.setStyleName('widgetHeader_settingButton')
145 setting_button.addClickListener(parent.onSetting)
146 close_button = Image("media/icons/misc/close.png")
147 close_button.setStyleName('widgetHeader_closeButton')
148 close_button.addClickListener(parent.onClose)
149 button_group.add(setting_button)
150 button_group.add(close_button)
151 button_group_wrapper.setWidget(button_group)
152 self.add(button_group_wrapper)
153 self.addStyleName('widgetHeader')
154 LiberviaDragWidget.__init__(self, "", "WIDGET", parent)
155
115 class LiberviaWidget(DropCell, VerticalPanel, ClickHandler): 156 class LiberviaWidget(DropCell, VerticalPanel, ClickHandler):
116 """Libervia's widget which can replace itself with a dropped widget on DnD""" 157 """Libervia's widget which can replace itself with a dropped widget on DnD"""
117 158
118 def __init__(self, host, title='', selectable=False): 159 def __init__(self, host, title='', selectable=False):
119 """Init the widget 160 """Init the widget
125 ClickHandler.__init__(self) 166 ClickHandler.__init__(self)
126 self.__selectable = selectable 167 self.__selectable = selectable
127 self.__title_id = HTMLPanel.createUniqueId() 168 self.__title_id = HTMLPanel.createUniqueId()
128 self.__setting_button_id = HTMLPanel.createUniqueId() 169 self.__setting_button_id = HTMLPanel.createUniqueId()
129 self.__close_button_id = HTMLPanel.createUniqueId() 170 self.__close_button_id = HTMLPanel.createUniqueId()
130 header = AbsolutePanel()
131 self.__title = Label(title) 171 self.__title = Label(title)
132 self.__title.setStyleName('widgetHeader_title') 172 self.__title.setStyleName('widgetHeader_title')
133 header.add(self.__title) 173 header = WidgetHeader(self, self.__title)
134 button_group_wrapper = SimplePanel()
135 button_group_wrapper.setStyleName('widgetHeader_buttonsWrapper')
136 button_group = HorizontalPanel()
137 button_group.setStyleName('widgetHeader_buttonGroup')
138 setting_button = Image("media/icons/misc/settings.png")
139 setting_button.setStyleName('widgetHeader_settingButton')
140 setting_button.addClickListener(self.onSetting)
141 close_button = Image("media/icons/misc/close.png")
142 close_button.setStyleName('widgetHeader_closeButton')
143 close_button.addClickListener(self.onClose)
144 button_group.add(setting_button)
145 button_group.add(close_button)
146 button_group_wrapper.setWidget(button_group)
147 header.add(button_group_wrapper)
148 self.add(header) 174 self.add(header)
149 header.addStyleName('widgetHeader')
150 self.setSize('100%', '100%') 175 self.setSize('100%', '100%')
151 self.addStyleName('widget') 176 self.addStyleName('widget')
152 if self.__selectable: 177 if self.__selectable:
153 self.addClickListener(self) 178 self.addClickListener(self)
154 self.host.registerWidget(self) 179 self.host.registerWidget(self)
155 180
156 def _getWidgetsPanel(self): 181 def getWidgetsPanel(self):
157 current = self 182 current = self
158 while current is not None and current.__class__ != WidgetsPanel: 183 while current is not None and current.__class__ != WidgetsPanel:
159 current = current.getParent() 184 current = current.getParent()
160 if current is None: 185 if current is None:
161 print "Error: can't find WidgetsPanel" 186 print "Error: can't find WidgetsPanel"
164 def onClick(self, sender): 189 def onClick(self, sender):
165 self.host.setSelected(self) 190 self.host.setSelected(self)
166 191
167 def onClose(self, sender): 192 def onClose(self, sender):
168 """ Called when the close button is pushed """ 193 """ Called when the close button is pushed """
169 _widgetspanel = self._getWidgetsPanel() 194 _widgetspanel = self.getWidgetsPanel()
170 _widgetspanel.removeWidget(self) 195 _widgetspanel.removeWidget(self)
171 self.onQuit() 196 self.onQuit()
172 197
173 def onQuit(self): 198 def onQuit(self):
174 """ Called when the widget is actually ending """ 199 """ Called when the widget is actually ending """
175 pass 200 pass
176 201
177 def onSetting(self, sender): 202 def onSetting(self, sender):
178 widpanel = self._getWidgetsPanel() 203 widpanel = self.getWidgetsPanel()
179 row, col = widpanel.getIndex(self) 204 row, col = widpanel.getIndex(self)
180 body = VerticalPanel() 205 body = VerticalPanel()
181 206
182 #colspan & rowspan 207 #colspan & rowspan
183 colspan = widpanel.getColSpan(row, col) 208 colspan = widpanel.getColSpan(row, col)
443 if _max_cols != self._max_cols: 468 if _max_cols != self._max_cols:
444 self._max_cols = _max_cols 469 self._max_cols = _max_cols
445 self._sizesAdjust() 470 self._sizesAdjust()
446 current = self 471 current = self
447 472
448 blank_page = not [wid for wid in self.flextable if isinstance(wid, LiberviaWidget)] # do we still have widgets on the page ? 473 blank_page = self.getLiberviaWidgetsCount() == 0 # do we still have widgets on the page ?
449 474
450 if blank_page and not self.isLocked(): 475 if blank_page and not self.isLocked():
451 #we now notice the MainTabPanel that the WidgetsPanel is empty and need to be removed 476 #we now notice the MainTabPanel that the WidgetsPanel is empty and need to be removed
452 while current is not None: 477 while current is not None:
453 if isinstance(current, MainTabPanel): 478 if isinstance(current, MainTabPanel):
454 current.onWidgetPanelRemove(self) 479 current.onWidgetPanelRemove(self)
455 return 480 return
456 current = current.getParent() 481 current = current.getParent()
457 print "Error: no MainTabPanel found !" 482 print "Error: no MainTabPanel found !"
458 483
484 def getLiberviaWidgetsCount(self):
485 """ Get count of contained widgets """
486 return len([wid for wid in self.flextable if isinstance(wid, LiberviaWidget)])
487
459 def getIndex(self, wid): 488 def getIndex(self, wid):
460 return self.flextable.getIndex(wid) 489 return self.flextable.getIndex(wid)
461 490
462 def getColSpan(self, row, col): 491 def getColSpan(self, row, col):
463 cellFormatter = self.flextable.getFlexCellFormatter() 492 cellFormatter = self.flextable.getFlexCellFormatter()