comparison browser_side/panels.py @ 34:ed935f763cc8

browser side: misc css/layout fixes - new ScrollPanelWrapper class, to try to handle correctly ScrollPanels in tables - removed   from EmptyPanel, because all td must appear empty, to use the absolute trick in ScrollPanelWrapper - when an empty panel is changed to a normal panel, cells widths are recalculated
author Goffi <goffi@goffi.org>
date Mon, 16 May 2011 03:10:11 +0200
parents e70521e6d803
children d43d6e4b9dc8
comparison
equal deleted inserted replaced
33:e70521e6d803 34:ed935f763cc8
22 import pyjd # this is dummy in pyjs 22 import pyjd # this is dummy in pyjs
23 from pyjamas.ui.SimplePanel import SimplePanel 23 from pyjamas.ui.SimplePanel import SimplePanel
24 from pyjamas.ui.FlowPanel import FlowPanel 24 from pyjamas.ui.FlowPanel import FlowPanel
25 from pyjamas.ui.AbsolutePanel import AbsolutePanel 25 from pyjamas.ui.AbsolutePanel import AbsolutePanel
26 from pyjamas.ui.VerticalPanel import VerticalPanel 26 from pyjamas.ui.VerticalPanel import VerticalPanel
27 from pyjamas.ui.DockPanel import DockPanel
27 from pyjamas.ui.HorizontalPanel import HorizontalPanel 28 from pyjamas.ui.HorizontalPanel import HorizontalPanel
28 from pyjamas.ui.ScrollPanel import ScrollPanel 29 from pyjamas.ui.ScrollPanel import ScrollPanel
29 from pyjamas.ui.TabPanel import TabPanel 30 from pyjamas.ui.TabPanel import TabPanel
30 from pyjamas.ui.HTMLPanel import HTMLPanel 31 from pyjamas.ui.HTMLPanel import HTMLPanel
31 from pyjamas.ui.PopupPanel import PopupPanel 32 from pyjamas.ui.PopupPanel import PopupPanel
148 _new_panel = MicroblogPanel(self.host, accept_all=True) 149 _new_panel = MicroblogPanel(self.host, accept_all=True)
149 self.host.mpanels.remove(self) 150 self.host.mpanels.remove(self)
150 self.host.mpanels.append(_new_panel) 151 self.host.mpanels.append(_new_panel)
151 grid = self.getParent() 152 grid = self.getParent()
152 row_idx, cell_idx = self._getCellAndRow(grid, event) 153 row_idx, cell_idx = self._getCellAndRow(grid, event)
153 self.removeFromParent()
154 if self.host.selected == self: 154 if self.host.selected == self:
155 self.host.select(None) 155 self.host.select(None)
156 self.removeFromParent()
156 grid.setWidget(row_idx, cell_idx, _new_panel) 157 grid.setWidget(row_idx, cell_idx, _new_panel)
158 _panels = list(grid) #this suppose that we only use 1 row, need to be changed in the futur
159 _unempty_panels = filter(lambda wid:not isinstance(wid,EmptyPanel),list(grid))
160 _width = 90/float(len(_unempty_panels) or 1)
161 #now we resize all the cell of the column
162 for panel in _unempty_panels:
163 td_elt = panel.getElement().parentNode
164 DOM.setStyleAttribute(td_elt, "width", "%s%%" % _width)
157 #FIXME: delete object ? Check the right way with pyjamas 165 #FIXME: delete object ? Check the right way with pyjamas
166
167 class ScrollPanelWrapper(SimplePanel):
168 """Scroll Panel like component, wich use the full available space
169 to work around percent size issue, it use some of the ideas found
170 here: http://code.google.com/p/google-web-toolkit/issues/detail?id=316
171 specially in code given at comment #46, thanks to Stefan Bachert"""
172
173 def __init__(self, *args, **kwargs):
174 SimplePanel.__init__(self)
175 self.spanel = ScrollPanel(*args, **kwargs)
176 SimplePanel.setWidget(self, self.spanel)
177 DOM.setStyleAttribute(self.getElement(), "position", "relative")
178 DOM.setStyleAttribute(self.getElement(), "top", "0px")
179 DOM.setStyleAttribute(self.getElement(), "left", "0px")
180 DOM.setStyleAttribute(self.getElement(), "width", "100%")
181 DOM.setStyleAttribute(self.getElement(), "height", "100%")
182 DOM.setStyleAttribute(self.spanel.getElement(), "position", "absolute")
183 DOM.setStyleAttribute(self.spanel.getElement(), "width", "100%")
184 DOM.setStyleAttribute(self.spanel.getElement(), "height", "100%")
185
186 def setWidget(self, widget):
187 self.spanel.setWidget(widget)
188
189 def setScrollPosition(self, position):
190 self.spanel.setScrollPosition(position)
191
192 def scrollToBottom(self):
193 self.setScrollPosition(self.spanel.getElement().scrollHeight)
158 194
159 class EmptyPanel(DropCell, SimplePanel): 195 class EmptyPanel(DropCell, SimplePanel):
160 """Empty dropable panel""" 196 """Empty dropable panel"""
161 197
162 def __init__(self, host): 198 def __init__(self, host):
163 SimplePanel.__init__(self) 199 SimplePanel.__init__(self)
164 self.host = host 200 self.host = host
165 _panel = HTMLPanel("&nbsp;") 201 _panel = HTMLPanel("")
166 self.add(_panel) 202 self.add(_panel)
167 self.setHeight('50%') 203 self.setHeight('100%')
168 DropCell.__init__(self) 204 DropCell.__init__(self)
169 205
170 class UniBoxPanel(SimplePanel): 206 class UniBoxPanel(SimplePanel):
171 """Panel containing the UniBox""" 207 """Panel containing the UniBox"""
172 208
296 "body": body} 332 "body": body}
297 ) 333 )
298 panel.setStyleName('microblogEntry') 334 panel.setStyleName('microblogEntry')
299 self.add(panel) 335 self.add(panel)
300 336
301 class MicroblogPanel(DropCell, ScrollPanel): 337 class MicroblogPanel(DropCell, ScrollPanelWrapper):
302 338
303 def __init__(self,host, title='&nbsp;', accept_all=False): 339 def __init__(self,host, title='&nbsp;', accept_all=False):
304 """Panel used to show microblog 340 """Panel used to show microblog
305 @param title: title of the panel 341 @param title: title of the panel
306 @param accept_all: if true, show every message, without filtering jids""" 342 @param accept_all: if true, show every message, without filtering jids"""
343 ScrollPanelWrapper.__init__(self)
344 DropCell.__init__(self)
307 self.host = host 345 self.host = host
308 self.accept_all = accept_all 346 self.accept_all = accept_all
309 title=title.replace('<','&lt;').replace('>','&gt;') 347 title=title.replace('<','&lt;').replace('>','&gt;')
310 self.accepted_groups = [] 348 self.accepted_groups = []
311 _class = ['mb_panel_header'] 349 _class = ['mb_panel_header']
312 if title == '&nbsp;': 350 if title == '&nbsp;':
313 _class.append('empty_header') 351 _class.append('empty_header')
314 ScrollPanel.__init__(self)
315 self.vpanel = VerticalPanel() 352 self.vpanel = VerticalPanel()
316 self.vpanel.add(HTMLPanel("<div class='%s'>%s</div>" % (','.join(_class),title))) 353 self.vpanel.add(HTMLPanel("<div class='%s'>%s</div>" % (','.join(_class),title)))
317 self.vpanel.setWidth('100%') 354 self.vpanel.setWidth('100%')
318 self.setHeight('50%')
319 self.setStyleName('microblogPanel') 355 self.setStyleName('microblogPanel')
320 self.add(self.vpanel) 356 self.setWidget(self.vpanel)
321 DropCell.__init__(self)
322 357
323 def addEntry(self, text, author=None, timestamp=None): 358 def addEntry(self, text, author=None, timestamp=None):
324 """Add an entry to the panel 359 """Add an entry to the panel
325 @param text: main text of the entry 360 @param text: main text of the entry
326 @param author: who wrote the entry 361 @param author: who wrote the entry
404 print "addOccupant: nick", nick 439 print "addOccupant: nick", nick
405 print _occupant 440 print _occupant
406 self.occupants.add(_occupant) 441 self.occupants.add(_occupant)
407 self.add(_occupant) 442 self.add(_occupant)
408 443
409 444 class ChatPanel(DropCell, ClickHandler, SimplePanel):
410
411
412 class ChatPanel(DropCell, ClickHandler, AbsolutePanel):
413 445
414 def __init__(self, host, target, type='one2one'): 446 def __init__(self, host, target, type='one2one'):
415 """Panel used for conversation (one 2 one or group chat) 447 """Panel used for conversation (one 2 one or group chat)
416 @param host: SatWebFrontend instance 448 @param host: SatWebFrontend instance
417 @param target: entity (JID) with who we have a conversation (contact's jid for one 2 one chat, or MUC room) 449 @param target: entity (JID) with who we have a conversation (contact's jid for one 2 one chat, or MUC room)
418 @param type: one2one for simple conversation, group for MUC""" 450 @param type: one2one for simple conversation, group for MUC"""
451 SimplePanel.__init__(self)
452 DropCell.__init__(self)
453 ClickHandler.__init__(self)
454 self.vpanel = VerticalPanel()
455 self.vpanel.setSize('100%','100%')
419 self.host = host 456 self.host = host
420 self.type = type 457 self.type = type
421 self.nick = None 458 self.nick = None
422 if not target: 459 if not target:
423 print "ERROR: Empty target !" 460 print "ERROR: Empty target !"
424 return 461 return
425 self.target = target 462 self.target = target
426 title="%s" % target.bare 463 title="%s" % target.bare
427 title.replace('<','&lt;').replace('>','&gt;') 464 title.replace('<','&lt;').replace('>','&gt;')
428 _class = ['mb_panel_header'] 465 _class = ['mb_panel_header']
429 AbsolutePanel.__init__(self)
430 self.header = HTMLPanel("<div class='%s'>%s</div>" % (','.join(_class),title)) 466 self.header = HTMLPanel("<div class='%s'>%s</div>" % (','.join(_class),title))
467 self.header.setStyleName('chatHeader')
431 self.body = AbsolutePanel() 468 self.body = AbsolutePanel()
432 self.body.setStyleName('chatPanel_body') 469 self.body.setStyleName('chatPanel_body')
433 #self.body.setWidth('100%')
434 #self.body.setHeight('50%')
435 chat_area = HorizontalPanel() 470 chat_area = HorizontalPanel()
436 chat_area.setStyleName('chatArea') 471 chat_area.setStyleName('chatArea')
437 #chat_area.setHeight('50%')
438 if type == 'group': 472 if type == 'group':
439 self.occupants_list = OccupantsList() 473 self.occupants_list = OccupantsList()
440 chat_area.add(self.occupants_list) 474 chat_area.add(self.occupants_list)
441 self.body.add(chat_area) 475 self.body.add(chat_area)
442 self.content = AbsolutePanel() 476 self.content = AbsolutePanel()
443 self.content.setStyleName('chatContent') 477 self.content.setStyleName('chatContent')
444 #_scrollp.setHeight('50%') 478 self.content_scroll = ScrollPanelWrapper(self.content)
445 #_scrollp.setWidth('100%') 479 chat_area.add(self.content_scroll)
446 chat_area.add(ScrollPanel(self.content, Size=("100%", "100%"))) 480 chat_area.setCellWidth(self.content_scroll, '100%')
447 self.add(self.header) 481 self.vpanel.add(self.header)
448 self.add(self.body) 482 self.vpanel.setCellHeight(self.header, '1%')
449 #self.content.setWidth('100%') 483 self.vpanel.add(self.body)
450 #self.main_panel.setVerticalAlignment(HasAlignment.ALIGN_TOP) 484 self.setWidget(self.vpanel)
451 #self.body.setVerticalAlignment(HasAlignment.ALIGN_TOP)
452 #chat_area.setVerticalAlignment(HasAlignment.ALIGN_TOP)
453 #self.setWidth('100%')
454 #self.setHeight('50%')
455 self.setStyleName('chatPanel') 485 self.setStyleName('chatPanel')
456 DropCell.__init__(self)
457 ClickHandler.__init__(self)
458 self.addClickListener(self) 486 self.addClickListener(self)
459 487
460 def onClick(self, sender, event): 488 def onClick(self, sender, event):
461 self.host.select(self) 489 self.host.select(self)
462 490
486 mymess = _jid.resource == self.nick if self.type == "group" else _jid.bare == self.host.whoami.bare #mymess = True if message comes from local user 514 mymess = _jid.resource == self.nick if self.type == "group" else _jid.bare == self.host.whoami.bare #mymess = True if message comes from local user
487 """if msg.startswith('/me '): 515 """if msg.startswith('/me '):
488 self.printInfo('* %s %s' % (nick, msg[4:]),type='me') 516 self.printInfo('* %s %s' % (nick, msg[4:]),type='me')
489 return""" 517 return"""
490 self.content.add(ChatText(timestamp, nick, mymess, msg)) 518 self.content.add(ChatText(timestamp, nick, mymess, msg))
491 519 self.content_scroll.scrollToBottom()
492 class MainDiscussionPannel(HorizontalPanel): 520
521 class MainDiscussionPanel(HorizontalPanel):
493 522
494 def __init__(self, host): 523 def __init__(self, host):
495 self.host=host 524 self.host=host
496 HorizontalPanel.__init__(self) 525 HorizontalPanel.__init__(self)
497 self._left = self.host.contact_panel 526 self._left = self.host.contact_panel
498 self._right = Grid(1,3) 527 self._right = Grid(1,3)
499 self._right.setWidth('100%') 528 self._right.setWidth('100%')
500 self._right.setHeight('50%') 529 self._right.setHeight('100%')
501 self.add(self._left) 530 self.add(self._left)
502 self.setCellWidth(self._left, "15%") 531 self.setCellWidth(self._left, "15%")
503 self.add(self._right) 532 self.add(self._right)
504 self.setCellWidth(self._right, "85%") 533 self.setCellWidth(self._right, "85%")
505 self.setHeight('50%')
506 534
507 def changePanel(self, idx, panel): 535 def changePanel(self, idx, panel):
508 self._right.setWidget(0,idx,panel) 536 self._right.setWidget(0,idx,panel)
509 537 self._right.getCellFormatter().setWidth(0, idx, '5%' if isinstance(panel, EmptyPanel) else '90%')
510 class MainTabPannel(TabPanel): 538
539 class MainTabPanel(TabPanel):
511 540
512 def __init__(self, host): 541 def __init__(self, host):
513 TabPanel.__init__(self) 542 TabPanel.__init__(self)
514 self.host=host 543 self.host=host
515 TabPanel() 544 TabPanel()
525 print ("ERROR: not TabBar found, it should exist !") 554 print ("ERROR: not TabBar found, it should exist !")
526 tab_bar_h = 0 555 tab_bar_h = 0
527 else: 556 else:
528 tab_bar_h = _elts.item(0).offsetHeight 557 tab_bar_h = _elts.item(0).offsetHeight
529 ideal_height = Window.getClientHeight() - tab_panel_elt.offsetTop - tab_bar_h - 5 558 ideal_height = Window.getClientHeight() - tab_panel_elt.offsetTop - tab_bar_h - 5
530 print "ideal_height =",ideal_height
531 self.setWidth("%s%s" % (width-5, "px")); 559 self.setWidth("%s%s" % (width-5, "px"));
532 self.setHeight("%s%s" % (ideal_height, "px")); 560 self.setHeight("%s%s" % (ideal_height, "px"));
533 561
534 def add(self, widget, tabText=None, asHTML=False): 562 def add(self, widget, tabText=None, asHTML=False):
535 TabPanel.add(self, widget, tabText, asHTML) 563 TabPanel.add(self, widget, tabText, asHTML)
536 if self.getWidgetCount()>1: 564 if self.getWidgetCount()>1:
537 self.tabBar.setVisible(True) 565 self.tabBar.setVisible(True)
538 self.host.resize() 566 self.host.resize()
539 567
540 """class MainTabPannel(FlowPanel):
541
542 def __init__(self, host):
543 FlowPanel.__init__(self)
544 self.host=host
545 self.tab_panel = TabPanel()
546 self.tab_panel.tabBar.setVisible(False)
547 self.addStyleName('mainTabPanel')
548 FlowPanel.add(self, self.tab_panel)
549 self.tab_panel.setWidth('100%')
550 self.tab_panel.setHeight('100%')
551 Window.addWindowResizeListener(self)
552
553 def onWindowResized(self, width, height):
554 print "onWindowResized"
555 tab_panel_elt = self.getElement()
556 _elts = doc().getElementsByClassName('gwt-TabBar')
557 if not _elts.length:
558 print ("ERROR: not TabBar found, it should exist !")
559 tab_bar_h = 0
560 else:
561 tab_bar_h = _elts.item(0).offsetHeight
562 ideal_height = Window.getClientHeight() - tab_panel_elt.offsetTop - tab_bar_h - 5
563 print "ideal_height =",ideal_height
564 self.setWidth("%s%s" % (width-5, "px"));
565 self.setHeight("%s%s" % (ideal_height, "px"));
566
567 def selectTab(self, idx):
568 self.tab_panel.selectTab(idx)
569
570 def add(self, widget, tabText=None, asHTML=False):
571 self.tab_panel.add(widget, tabText, asHTML)
572 if self.tab_panel.getWidgetCount()>1:
573 self.tab_panel.tabBar.setVisible(True)
574 self.host.resize()"""
575
576 class MainPanel(AbsolutePanel): 568 class MainPanel(AbsolutePanel):
577 569
578 def __init__(self, host): 570 def __init__(self, host):
579 self.host=host 571 self.host=host
580 AbsolutePanel.__init__(self) 572 AbsolutePanel.__init__(self)
584 576
585 menu = Menu(host) 577 menu = Menu(host)
586 unibox_panel = UniBoxPanel(host) 578 unibox_panel = UniBoxPanel(host)
587 self.host.setUniBox(unibox_panel.unibox) 579 self.host.setUniBox(unibox_panel.unibox)
588 status = host.status_panel 580 status = host.status_panel
589 self.tab_panel = MainTabPannel(host) 581 self.tab_panel = MainTabPanel(host)
590 #self.tab_panel.setWidth('100%') 582 self.discuss_panel = MainDiscussionPanel(self.host)
591 #self.tab_panel.setHeight('50%')
592 self.discuss_panel = MainDiscussionPannel(self.host)
593 self.discuss_panel.setWidth('100%')
594 self.discuss_panel.setHeight('50%')
595 self.tab_panel.add(self.discuss_panel, "Discussions") 583 self.tab_panel.add(self.discuss_panel, "Discussions")
596 self.tab_panel.selectTab(0) 584 self.tab_panel.selectTab(0)
597 585
598 self.add(menu) 586 self.add(menu)
599 self.add(unibox_panel) 587 self.add(unibox_panel)
600 self.add(status) 588 self.add(status)
601 self.add(self.tab_panel) 589 self.add(self.tab_panel)
602 #self.tab_panel.onWindowResized(Window.getClientWidth(), Window.getClientHeight())
603 590
604 """self.setCellHeight(menu, "5%")
605 self.setCellHeight(uni_box, "5%")
606 self.setCellVerticalAlignment(uni_box, HasAlignment.ALIGN_CENTER)
607 self.setCellHorizontalAlignment(uni_box, HasAlignment.ALIGN_CENTER)
608 self.setCellHeight(self.tab_panel, "90%")
609 self.setCellWidth(self.tab_panel, "100%")"""
610
611 self.setWidth("100%") 591 self.setWidth("100%")
612 #self.setHeight("99%") 592 #self.setHeight("99%")
613 Window.addWindowResizeListener(self) 593 Window.addWindowResizeListener(self)
614 594
615 def onWindowResized(self, width, height): 595 def onWindowResized(self, width, height):