Mercurial > libervia-web
comparison browser_side/panels.py @ 83:68d360caeecb
New widget system: first draft
- adaptation of Adrien's design
- widgets are now based on a flextable
- widgets now use a base class LiberviaWidget (the name is to avoid confustion with pyjamas' widgets)
- widgets have a title, and setting/close buttons
author | Goffi <goffi@goffi.org> |
---|---|
date | Sun, 26 Jun 2011 03:04:17 +0200 |
parents | 12680e220b35 |
children | 8f35e9970e7f |
comparison
equal
deleted
inserted
replaced
82:bd575203d456 | 83:68d360caeecb |
---|---|
25 from pyjamas.ui.VerticalPanel import VerticalPanel | 25 from pyjamas.ui.VerticalPanel import VerticalPanel |
26 from pyjamas.ui.HorizontalPanel import HorizontalPanel | 26 from pyjamas.ui.HorizontalPanel import HorizontalPanel |
27 from pyjamas.ui.ScrollPanel import ScrollPanel | 27 from pyjamas.ui.ScrollPanel import ScrollPanel |
28 from pyjamas.ui.TabPanel import TabPanel | 28 from pyjamas.ui.TabPanel import TabPanel |
29 from pyjamas.ui.HTMLPanel import HTMLPanel | 29 from pyjamas.ui.HTMLPanel import HTMLPanel |
30 from pyjamas.ui.FlexTable import FlexTable | |
30 from pyjamas.ui.Grid import Grid | 31 from pyjamas.ui.Grid import Grid |
31 from pyjamas.ui.TextArea import TextArea | 32 from pyjamas.ui.TextArea import TextArea |
32 from pyjamas.ui.Label import Label | 33 from pyjamas.ui.Label import Label |
34 from pyjamas.ui.Button import Button | |
33 from pyjamas.ui.HTML import HTML | 35 from pyjamas.ui.HTML import HTML |
36 from pyjamas.ui.Image import Image | |
34 from pyjamas.ui.DropWidget import DropWidget | 37 from pyjamas.ui.DropWidget import DropWidget |
35 from pyjamas.ui.ClickListener import ClickHandler | 38 from pyjamas.ui.ClickListener import ClickHandler |
36 from pyjamas.ui.KeyboardListener import KEY_ENTER | 39 from pyjamas.ui.KeyboardListener import KEY_ENTER |
40 from pyjamas.ui import HasAlignment | |
37 from pyjamas.Timer import Timer | 41 from pyjamas.Timer import Timer |
38 from pyjamas import Window | 42 from pyjamas import Window |
39 from pyjamas import DOM | 43 from pyjamas import DOM |
40 from card_game import CardPanel | 44 from card_game import CardPanel |
41 from menu import Menu | 45 from menu import Menu |
49 class DropCell(DropWidget): | 53 class DropCell(DropWidget): |
50 """Cell in the middle grid which replace itself with the dropped widget on DnD""" | 54 """Cell in the middle grid which replace itself with the dropped widget on DnD""" |
51 | 55 |
52 def __init__(self): | 56 def __init__(self): |
53 DropWidget.__init__(self) | 57 DropWidget.__init__(self) |
58 self.setStyleName('dropCell') | |
54 | 59 |
55 def onDragEnter(self, event): | 60 def onDragEnter(self, event): |
56 self.addStyleName('dragover') | 61 self.addStyleName('dragover') |
57 DOM.eventPreventDefault(event) | 62 DOM.eventPreventDefault(event) |
58 | 63 |
118 for panel in _unempty_panels: | 123 for panel in _unempty_panels: |
119 td_elt = panel.getElement().parentNode | 124 td_elt = panel.getElement().parentNode |
120 DOM.setStyleAttribute(td_elt, "width", "%s%%" % _width) | 125 DOM.setStyleAttribute(td_elt, "width", "%s%%" % _width) |
121 #FIXME: delete object ? Check the right way with pyjamas | 126 #FIXME: delete object ? Check the right way with pyjamas |
122 | 127 |
128 class LiberviaWidget(DropCell, VerticalPanel): | |
129 """Libervia's widget which can replace itself with a dropped widget on DnD""" | |
130 | |
131 def __init__(self, title=''): | |
132 VerticalPanel.__init__(self) | |
133 DropCell.__init__(self) | |
134 self.title_id = HTMLPanel.createUniqueId() | |
135 self.setting_button_id = HTMLPanel.createUniqueId() | |
136 self.close_button_id = HTMLPanel.createUniqueId() | |
137 header = AbsolutePanel() | |
138 self.title = Label(title) | |
139 self.title.setStyleName('widgetHeader_title') | |
140 header.add(self.title) | |
141 #header.setCellVerticalAlignment(self.title, HasAlignment.ALIGN_MIDDLE) | |
142 #header.setCellWidth(self.title, '100%') | |
143 button_group_wrapper = SimplePanel() | |
144 button_group_wrapper.setStyleName('widgetHeader_buttonsWrapper') | |
145 button_group = HorizontalPanel() | |
146 button_group.setStyleName('widgetHeader_buttonGroup') | |
147 setting_button = Image("media/icons/misc/settings.png") | |
148 setting_button.setStyleName('widgetHeader_settingButton') | |
149 close_button = Image("media/icons/misc/close.png") | |
150 close_button.setStyleName('widgetHeader_closeButton') | |
151 button_group.add(setting_button) | |
152 button_group.add(close_button) | |
153 button_group_wrapper.setWidget(button_group) | |
154 header.add(button_group_wrapper) | |
155 self.add(header) | |
156 header.addStyleName('widgetHeader') | |
157 self.setSize('100%', '100%') | |
158 self.addStyleName('widget') | |
159 | |
160 def setTitle(self, text): | |
161 """change the title in the header of the widget | |
162 @param text: text of the new title""" | |
163 self.title.setText(text) | |
164 | |
165 def setWidget(self, widget, scrollable=True): | |
166 """Set the widget that will be in the body of the LiberviaWidget | |
167 @param widget: widget to put in the body | |
168 @param scrollable: if true, the widget will be in a ScrollPanelWrapper""" | |
169 if scrollable: | |
170 _scrollpanelwrapper = ScrollPanelWrapper() | |
171 _scrollpanelwrapper.setStyleName('widgetBody') | |
172 _scrollpanelwrapper.setWidget(widget) | |
173 body_wid = _scrollpanelwrapper | |
174 else: | |
175 body_wid = widget | |
176 self.add(body_wid) | |
177 self.setCellHeight(body_wid, '100%') | |
178 | |
179 | |
123 class ScrollPanelWrapper(SimplePanel): | 180 class ScrollPanelWrapper(SimplePanel): |
124 """Scroll Panel like component, wich use the full available space | 181 """Scroll Panel like component, wich use the full available space |
125 to work around percent size issue, it use some of the ideas found | 182 to work around percent size issue, it use some of the ideas found |
126 here: http://code.google.com/p/google-web-toolkit/issues/detail?id=316 | 183 here: http://code.google.com/p/google-web-toolkit/issues/detail?id=316 |
127 specially in code given at comment #46, thanks to Stefan Bachert""" | 184 specially in code given at comment #46, thanks to Stefan Bachert""" |
152 """Empty dropable panel""" | 209 """Empty dropable panel""" |
153 | 210 |
154 def __init__(self, host): | 211 def __init__(self, host): |
155 SimplePanel.__init__(self) | 212 SimplePanel.__init__(self) |
156 self.host = host | 213 self.host = host |
157 _panel = HTMLPanel("") | 214 self.setSize('100%','100%') |
158 self.add(_panel) | |
159 self.setHeight('100%') | |
160 DropCell.__init__(self) | 215 DropCell.__init__(self) |
216 self.setWidget(HTML(' ')) | |
161 | 217 |
162 class UniBoxPanel(SimplePanel): | 218 class UniBoxPanel(SimplePanel): |
163 """Panel containing the UniBox""" | 219 """Panel containing the UniBox""" |
164 | 220 |
165 def __init__(self, host): | 221 def __init__(self, host): |
177 #AutoCompleteTextBox.__init__(self) | 233 #AutoCompleteTextBox.__init__(self) |
178 self._popup = None | 234 self._popup = None |
179 self._timer = Timer(notify=self._timeCb) | 235 self._timer = Timer(notify=self._timeCb) |
180 self.host = host | 236 self.host = host |
181 self.setStyleName('uniBox') | 237 self.setStyleName('uniBox') |
238 self.addKeyboardListener(self) | |
182 | 239 |
183 def addKey(self, key): | 240 def addKey(self, key): |
184 return | 241 return |
185 #self.getCompletionItems().completions.append(key) | 242 #self.getCompletionItems().completions.append(key) |
186 | 243 |
265 self._timeCb(None) #we remove the popup | 322 self._timeCb(None) #we remove the popup |
266 self.showWarning(_target) | 323 self.showWarning(_target) |
267 | 324 |
268 self._timer.schedule(2000) | 325 self._timer.schedule(2000) |
269 | 326 |
270 if keycode == KEY_ENTER and not self.visible: | 327 #if keycode == KEY_ENTER and not self.visible: |
328 if keycode == KEY_ENTER: | |
271 if _txt: | 329 if _txt: |
272 if _txt.startswith('@'): | 330 if _txt.startswith('@'): |
273 self.host.bridge.call('sendMblog', None, self.getText()) | 331 self.host.bridge.call('sendMblog', None, self.getText()) |
274 elif self.host.selected == None: | 332 elif self.host.selected == None: |
275 self.host.bridge.call('setStatus', None, _txt) | 333 self.host.bridge.call('setStatus', None, _txt) |
299 "body": html_sanitize(mblog_entry.content)} | 357 "body": html_sanitize(mblog_entry.content)} |
300 ) | 358 ) |
301 panel.setStyleName('microblogEntry') | 359 panel.setStyleName('microblogEntry') |
302 self.add(panel) | 360 self.add(panel) |
303 | 361 |
304 class MicroblogPanel(DropCell, ScrollPanelWrapper): | 362 class MicroblogPanel(LiberviaWidget): |
305 | 363 |
306 def __init__(self,host, title=' ', accept_all=False): | 364 def __init__(self, host, title='', accept_all=False): |
307 """Panel used to show microblog | 365 """Panel used to show microblog |
308 @param title: title of the panel | 366 @param title: title of the panel |
309 @param accept_all: if true, show every message, without filtering jids""" | 367 @param accept_all: if true, show every message, without filtering jids""" |
310 ScrollPanelWrapper.__init__(self) | 368 LiberviaWidget.__init__(self, title) |
311 DropCell.__init__(self) | 369 #ScrollPanelWrapper.__init__(self) |
370 #DropCell.__init__(self) | |
312 self.host = host | 371 self.host = host |
313 self.accept_all = accept_all | 372 self.accept_all = accept_all |
314 title=html_sanitize(title) | |
315 self.accepted_groups = [] | 373 self.accepted_groups = [] |
316 self.entries = {} | 374 self.entries = {} |
317 _class = ['mb_panel_header'] | |
318 if title == ' ': | |
319 _class.append('empty_header') | |
320 self.vpanel = VerticalPanel() | 375 self.vpanel = VerticalPanel() |
321 self.vpanel.add(HTMLPanel("<div class='%s'>%s</div>" % (','.join(_class),title))) | 376 self.vpanel.setStyleName('microblogPanel') |
322 self.vpanel.setWidth('100%') | |
323 self.setStyleName('microblogPanel') | |
324 self.setWidget(self.vpanel) | 377 self.setWidget(self.vpanel) |
325 | 378 |
326 def addEntry(self, mblog_entry): | 379 def addEntry(self, mblog_entry): |
327 """Add an entry to the panel | 380 """Add an entry to the panel |
328 @param text: main text of the entry | 381 @param text: main text of the entry |
331 @param date: when the entry was written""" | 384 @param date: when the entry was written""" |
332 if mblog_entry.id in self.entries: | 385 if mblog_entry.id in self.entries: |
333 return | 386 return |
334 _entry = MicroblogEntry(mblog_entry) | 387 _entry = MicroblogEntry(mblog_entry) |
335 self.entries[mblog_entry.id] = _entry | 388 self.entries[mblog_entry.id] = _entry |
336 self.vpanel.insert(_entry,1) | 389 self.vpanel.insert(_entry,0) |
337 | 390 |
338 def setAcceptedGroup(self, group): | 391 def setAcceptedGroup(self, group): |
339 """Set the group which can be displayed in this panel | 392 """Set the group which can be displayed in this panel |
340 @param group: string of the group, or list of string | 393 @param group: string of the group, or list of string |
341 """ | 394 """ |
546 """Return class managing the game type""" | 599 """Return class managing the game type""" |
547 #TODO: check that the game is launched, and manage errors | 600 #TODO: check that the game is launched, and manage errors |
548 if game_type=="Tarot": | 601 if game_type=="Tarot": |
549 return self.tarot_panel | 602 return self.tarot_panel |
550 | 603 |
604 class WidgetsPanel(SimplePanel): | |
605 | |
606 def __init__(self): | |
607 SimplePanel.__init__(self) | |
608 self.flextable = FlexTable() | |
609 self.flextable.setSize('100%','100%') | |
610 self.add(self.flextable) | |
611 self.setStyleName('widgetsPanel') | |
612 | |
613 def addWidget(self, wid): | |
614 """Add a widget to a new cell""" | |
615 row = max(0, self.flextable.getRowCount()-1) | |
616 try: | |
617 col = self.flextable.getCellCount(0) | |
618 except AttributeError: | |
619 col = 0 | |
620 print "putting widget %s at %d, %d" % (wid, row, col) | |
621 self.flextable.setWidget(row, col, wid) | |
622 | |
551 class MainDiscussionPanel(HorizontalPanel): | 623 class MainDiscussionPanel(HorizontalPanel): |
552 | 624 |
553 def __init__(self, host): | 625 def __init__(self, host): |
554 self.host=host | 626 self.host=host |
555 HorizontalPanel.__init__(self) | 627 HorizontalPanel.__init__(self) |
556 self._left = self.host.contact_panel | 628 self._left = self.host.contact_panel |
557 self._right = Grid(1,3) | 629 self._right = WidgetsPanel() |
558 self._right.setWidth('100%') | 630 self._right.setWidth('100%') |
559 self._right.setHeight('100%') | 631 self._right.setHeight('100%') |
560 self.add(self._left) | 632 self.add(self._left) |
561 self.setCellWidth(self._left, "15%") | 633 #self.setCellWidth(self._left, "15%") |
562 self.add(self._right) | 634 self.add(self._right) |
563 self.setCellWidth(self._right, "85%") | 635 #self.setCellWidth(self._right, "85%") |
636 self.setCellWidth(self._right, "100%") | |
637 | |
638 def addWidget(self, wid): | |
639 """Add a widget to the WidgetsPanel""" | |
640 print "main addWidget", wid | |
641 self._right.addWidget(wid) | |
564 | 642 |
565 def changePanel(self, idx, panel): | 643 def changePanel(self, idx, panel): |
566 self._right.setWidget(0,idx,panel) | 644 pass |
567 self._right.getCellFormatter().setWidth(0, idx, '5%' if isinstance(panel, EmptyPanel) else '90%') | 645 #self._right.setWidget(0,idx,panel) |
646 #self._right.getCellFormatter().setWidth(0, idx, '5%' if isinstance(panel, EmptyPanel) else '90%') | |
568 | 647 |
569 class MainTabPanel(TabPanel): | 648 class MainTabPanel(TabPanel): |
570 | 649 |
571 def __init__(self, host): | 650 def __init__(self, host): |
572 TabPanel.__init__(self) | 651 TabPanel.__init__(self) |