Mercurial > libervia-web
comparison browser_side/panels.py @ 279:2d6bd975a72d
browser_side: set your own presence status and display those of others
author | souliane <souliane@mailoo.org> |
---|---|
date | Sat, 23 Nov 2013 14:46:03 +0100 |
parents | aebb96bfa8d1 |
children | ae3ec654836d |
comparison
equal
deleted
inserted
replaced
278:4517978a2e7e | 279:2d6bd975a72d |
---|---|
35 from pyjamas.ui.StackPanel import StackPanel | 35 from pyjamas.ui.StackPanel import StackPanel |
36 from pyjamas.ui.ClickListener import ClickHandler | 36 from pyjamas.ui.ClickListener import ClickHandler |
37 from pyjamas.ui.KeyboardListener import KEY_ENTER, KEY_UP, KEY_DOWN | 37 from pyjamas.ui.KeyboardListener import KEY_ENTER, KEY_UP, KEY_DOWN |
38 from pyjamas.ui.Event import BUTTON_LEFT, BUTTON_MIDDLE, BUTTON_RIGHT | 38 from pyjamas.ui.Event import BUTTON_LEFT, BUTTON_MIDDLE, BUTTON_RIGHT |
39 from pyjamas.ui.MouseListener import MouseHandler | 39 from pyjamas.ui.MouseListener import MouseHandler |
40 from pyjamas.ui.ListBox import ListBox | |
40 from pyjamas.Timer import Timer | 41 from pyjamas.Timer import Timer |
41 from pyjamas import DOM | 42 from pyjamas import DOM |
42 from card_game import CardPanel | 43 from card_game import CardPanel |
43 from radiocol import RadioColPanel | 44 from radiocol import RadioColPanel |
44 from menu import Menu | 45 from menu import Menu |
45 from jid import JID | 46 from jid import JID |
46 from tools import html_sanitize, addURLToText, inlineRoot | 47 from tools import html_sanitize, addURLToText, inlineRoot, setPresenceStyle |
47 from datetime import datetime | 48 from datetime import datetime |
48 from time import time | 49 from time import time |
49 import dialog | 50 import dialog |
50 import base_widget | 51 import base_widget |
51 from richtext import RichTextEditor | 52 from richtext import RichTextEditor |
52 from plugin_xep_0085 import ChatStateMachine | 53 from plugin_xep_0085 import ChatStateMachine |
53 from pyjamas import Window | 54 from pyjamas import Window |
54 from __pyjamas__ import doc | 55 from __pyjamas__ import doc |
55 from sat_frontends.tools.games import SYMBOLS | 56 from sat_frontends.tools.games import SYMBOLS |
57 from sat_frontends import constants | |
58 from pyjamas.ui.ContextMenuPopupPanel import ContextMenuPopupPanel | |
59 | |
60 | |
61 const = constants.Const # to directly import 'const' doesn't work | |
56 | 62 |
57 | 63 |
58 class UniBoxPanel(HorizontalPanel): | 64 class UniBoxPanel(HorizontalPanel): |
59 """Panel containing the UniBox""" | 65 """Panel containing the UniBox""" |
60 | 66 |
585 if self.host.contact_panel.isContactInGroup(group, jid): | 591 if self.host.contact_panel.isContactInGroup(group, jid): |
586 return True | 592 return True |
587 return False | 593 return False |
588 | 594 |
589 | 595 |
590 class StatusPanel(HTMLPanel, ClickHandler): | 596 class StatusPanel(HTMLPanel): |
591 def __init__(self, host, status=''): | 597 def __init__(self, host, status=''): |
592 self.host = host | 598 self.host = host |
593 self.status = status or ' ' | 599 self.status = status or ' ' |
594 HTMLPanel.__init__(self, self.__getContent()) | 600 HTMLPanel.__init__(self, self.__getContent()) |
595 self.setStyleName('statusPanel') | 601 self.setStyleName('statusPanel') |
596 ClickHandler.__init__(self) | |
597 self.addClickListener(self) | |
598 | 602 |
599 def __getContent(self): | 603 def __getContent(self): |
600 return "<span class='status'>%(status)s</span>" % {'status': html_sanitize(self.status)} | 604 return "<span class='status'>%(status)s</span>" % {'status': html_sanitize(self.status)} |
601 | 605 |
602 def changeStatus(self, new_status): | 606 def changeStatus(self, new_status): |
603 self.status = new_status or ' ' | 607 self.status = new_status or ' ' |
604 self.setHTML(self.__getContent()) | 608 self.setHTML(self.__getContent()) |
609 | |
610 | |
611 class PresenceStatusPanel(HorizontalPanel, ClickHandler): | |
612 | |
613 def __init__(self, host, presence="", status=""): | |
614 self.host = host | |
615 HorizontalPanel.__init__(self, Width='100%') | |
616 self.presence_button = Label(u"◉") | |
617 self.presence_button.setStyleName("presence-button") | |
618 self.status_panel = StatusPanel(host, status=status) | |
619 self.setPresence(presence) | |
620 entries = {} | |
621 for value in const.PRESENCE.keys(): | |
622 entries.update({const.PRESENCE[value]: {"value": value}}) | |
623 | |
624 def callback(sender, key): | |
625 self.setPresence(entries[key]["value"]) # order matters | |
626 self.host.send([("STATUS", None)], self.status_panel.status) | |
627 | |
628 self.presence_list = PopupMenuPanel(entries, callback=callback, style={"menu": "gwt-ListBox"}) | |
629 self.presence_list.registerClickSender(self.presence_button) | |
630 | |
631 panel = HorizontalPanel() | |
632 panel.add(self.presence_button) | |
633 panel.add(self.status_panel) | |
634 panel.setStyleName("marginAuto") | |
635 self.add(panel) | |
636 | |
637 ClickHandler.__init__(self) | |
638 self.addClickListener(self) | |
639 | |
640 def getPresence(self): | |
641 return self.presence | |
642 | |
643 def setPresence(self, presence): | |
644 status = self.status_panel.status | |
645 if not status.strip() or status == " " or status == const.PRESENCE[self.presence]: | |
646 self.changeStatus(const.PRESENCE[presence]) | |
647 self.presence = presence | |
648 setPresenceStyle(self.presence_button, self.presence) | |
649 | |
650 def changeStatus(self, new_status): | |
651 self.status_panel.changeStatus(new_status) | |
605 | 652 |
606 def onClick(self, sender): | 653 def onClick(self, sender): |
607 # As status is the default target of uniBar, we don't want to select anything if click on it | 654 # As status is the default target of uniBar, we don't want to select anything if click on it |
608 self.host.setSelected(None) | 655 self.host.setSelected(None) |
609 | 656 |
976 """This implementation of a popup menu (context menu) allow you to assign | 1023 """This implementation of a popup menu (context menu) allow you to assign |
977 two special methods which are common to all the items, in order to hide | 1024 two special methods which are common to all the items, in order to hide |
978 certain items and also easily define their callbacks. The menu can be | 1025 certain items and also easily define their callbacks. The menu can be |
979 bound to any of the mouse button (left, middle, right). | 1026 bound to any of the mouse button (left, middle, right). |
980 """ | 1027 """ |
981 def __init__(self, entries, hide=None, callback=None, vertical=True, item_style="popupMenuItem", menu_style=None, **kwargs): | 1028 def __init__(self, entries, hide=None, callback=None, vertical=True, style={}, **kwargs): |
982 """ | 1029 """ |
983 @param entries: a dict of dicts, where each sub-dict is representing | 1030 @param entries: a dict of dicts, where each sub-dict is representing |
984 one menu item: the sub-dict key can be used as the item text and | 1031 one menu item: the sub-dict key can be used as the item text and |
985 description, but optional "title" and "desc" entries would be used | 1032 description, but optional "title" and "desc" entries would be used |
986 if they exists. The sub-dicts may be extended later to do | 1033 if they exists. The sub-dicts may be extended later to do |
987 more complicated stuff or overwrite the common methods. | 1034 more complicated stuff or overwrite the common methods. |
988 @param hide: function with 2 args: widget, key as string and | 1035 @param hide: function with 2 args: widget, key as string and |
989 returns True if that item should be hidden from the context menu. | 1036 returns True if that item should be hidden from the context menu. |
990 @param callback: function with 2 args: widget, key as string | 1037 @param callback: function with 2 args: sender, key as string |
991 @param vertical: True or False, to set the direction | 1038 @param vertical: True or False, to set the direction |
992 @param item_style: alternative CSS class for the menu items | 1039 @param item_style: alternative CSS class for the menu items |
993 @param menu_style: supplementary CSS class for the sender widget | 1040 @param menu_style: supplementary CSS class for the sender widget |
994 """ | 1041 """ |
995 PopupPanel.__init__(self, autoHide=True, **kwargs) | 1042 PopupPanel.__init__(self, autoHide=True, **kwargs) |
996 self._entries = entries | 1043 self._entries = entries |
997 self._hide = hide | 1044 self._hide = hide |
998 self._callback = callback | 1045 self._callback = callback |
999 self.vertical = vertical | 1046 self.vertical = vertical |
1000 self.item_style = item_style | 1047 self.style = {"selected": None, "menu": "recipientTypeMenu", "item": "popupMenuItem"} |
1001 self.menu_style = menu_style | 1048 self.style.update(style) |
1002 self._senders = {} | 1049 self._senders = {} |
1003 | 1050 |
1004 def _show(self, sender): | 1051 def _show(self, sender): |
1005 """Popup the menu relative to this sender's position. | 1052 """Popup the menu relative to this sender's position. |
1006 @param sender: the widget that has been clicked | 1053 @param sender: the widget that has been clicked |
1007 """ | 1054 """ |
1008 menu = VerticalPanel() if self.vertical is True else HorizontalPanel() | 1055 menu = VerticalPanel() if self.vertical is True else HorizontalPanel() |
1009 menu.setStyleName("recipientTypeMenu") | 1056 menu.setStyleName(self.style["menu"]) |
1010 | 1057 |
1011 def button_cb(item): | 1058 def button_cb(item): |
1012 """You can not put that method in the loop and rely | 1059 """You can not put that method in the loop and rely |
1013 on _key, because it is overwritten by each step. | 1060 on _key, because it is overwritten by each step. |
1014 You can rely on item.key instead, which is copied | 1061 You can rely on item.key instead, which is copied |
1024 if self._hide is not None and self._hide(sender=sender, key=_key) is True: | 1071 if self._hide is not None and self._hide(sender=sender, key=_key) is True: |
1025 continue | 1072 continue |
1026 title = entry["title"] if "title" in entry.keys() else _key | 1073 title = entry["title"] if "title" in entry.keys() else _key |
1027 item = Button(title, button_cb) | 1074 item = Button(title, button_cb) |
1028 item.key = _key | 1075 item.key = _key |
1029 item.setStyleName(self.item_style) | 1076 item.setStyleName(self.style["item"]) |
1030 item.setTitle(entry["desc"] if "desc" in entry.keys() else title) | 1077 item.setTitle(entry["desc"] if "desc" in entry.keys() else title) |
1031 menu.add(item) | 1078 menu.add(item) |
1032 if len(menu.getChildren()) == 0: | 1079 if len(menu.getChildren()) == 0: |
1033 return | 1080 return |
1034 self.add(menu) | 1081 self.add(menu) |
1038 else: | 1085 else: |
1039 x = sender.getAbsoluteLeft() | 1086 x = sender.getAbsoluteLeft() |
1040 y = sender.getAbsoluteTop() + sender.getOffsetHeight() | 1087 y = sender.getAbsoluteTop() + sender.getOffsetHeight() |
1041 self.setPopupPosition(x, y) | 1088 self.setPopupPosition(x, y) |
1042 self.show() | 1089 self.show() |
1043 if self.menu_style: | 1090 if self.style["selected"]: |
1044 sender.addStyleDependentName(self.menu_style) | 1091 sender.addStyleDependentName(self.style["selected"]) |
1045 | 1092 |
1046 def _onHide(popup): | 1093 def _onHide(popup): |
1047 if hasattr(self, "menu_style") and self.menu_style is not None: | 1094 if self.style["selected"]: |
1048 sender.removeStyleDependentName(self.menu_style) | 1095 sender.removeStyleDependentName(self.style["selected"]) |
1049 return PopupPanel.onHideImpl(self, popup) | 1096 return PopupPanel.onHideImpl(self, popup) |
1050 | 1097 |
1051 self.onHideImpl = _onHide | 1098 self.onHideImpl = _onHide |
1052 | 1099 |
1053 def registerClickSender(self, sender, button=BUTTON_LEFT): | 1100 def registerClickSender(self, sender, button=BUTTON_LEFT): |