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('&nbsp;'))
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='&nbsp;', 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 == '&nbsp;':
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)