Mercurial > libervia-web
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=' ' | 92 item=' ' |
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() |