Mercurial > libervia-backend
comparison frontends/primitivus/primitivus @ 159:2fa58703f1b7
Primitivus: notification bar, first draft
- popup queue is now managed
- notifications can auto-hide when nothing to show
- ctrl-n show next notification
Primitivus: ctrl-s allow to temporarily hide a popup
Primitivus: cards in card_game now answer to mouse click
Primitivus: notification is shown when invalid card is played in card_game
Primitivus: SelectableText has now methods get_text and set_text
author | Goffi <goffi@goffi.org> |
---|---|
date | Wed, 04 Aug 2010 17:57:51 +0800 |
parents | 13888bdb72b6 |
children | b318d2b58887 |
comparison
equal
deleted
inserted
replaced
158:74aaf230a7c3 | 159:2fa58703f1b7 |
---|---|
55 ('other_nick', 'dark cyan,bold', 'default'), | 55 ('other_nick', 'dark cyan,bold', 'default'), |
56 ('menubar', 'light gray,bold', 'dark red'), | 56 ('menubar', 'light gray,bold', 'dark red'), |
57 ('selected_menu', 'light gray,bold', 'dark green'), | 57 ('selected_menu', 'light gray,bold', 'dark green'), |
58 ('menuitem', 'light gray,bold', 'dark red'), | 58 ('menuitem', 'light gray,bold', 'dark red'), |
59 ('menuitem_focus', 'light gray,bold', 'dark green'), | 59 ('menuitem_focus', 'light gray,bold', 'dark green'), |
60 ('notifs', 'black,bold', 'yellow'), | |
60 ('card_neutral', 'dark gray', 'white', 'standout,underline'), | 61 ('card_neutral', 'dark gray', 'white', 'standout,underline'), |
61 ('card_neutral_selected', 'dark gray', 'dark green', 'standout,underline'), | 62 ('card_neutral_selected', 'dark gray', 'dark green', 'standout,underline'), |
62 ('card_special', 'brown', 'white', 'standout,underline'), | 63 ('card_special', 'brown', 'white', 'standout,underline'), |
63 ('card_special_selected', 'brown', 'dark green', 'standout,underline'), | 64 ('card_special_selected', 'brown', 'dark green', 'standout,underline'), |
64 ('card_red', 'dark red', 'white', 'standout,underline'), | 65 ('card_red', 'dark red', 'white', 'standout,underline'), |
78 | 79 |
79 class PrimitivusApp(QuickApp): | 80 class PrimitivusApp(QuickApp): |
80 | 81 |
81 def __init__(self): | 82 def __init__(self): |
82 self.CM = QuickContactManagement() #FIXME: not the best place | 83 self.CM = QuickContactManagement() #FIXME: not the best place |
83 QuickApp.__init__(self) #XXX: yes it's an unusual place for the constructor of a parent class, but the init order is important | 84 QuickApp.__init__(self) |
84 | 85 |
85 ## main loop setup ## | 86 ## main loop setup ## |
86 self.main_widget = ProfileManager(self) | 87 self.main_widget = ProfileManager(self) |
87 self.loop = urwid.MainLoop(self.main_widget, const_PALETTE, event_loop=urwid.GLibEventLoop(), input_filter=self.inputFilter, unhandled_input=self.keyHandler) | 88 self.loop = urwid.MainLoop(self.main_widget, const_PALETTE, event_loop=urwid.GLibEventLoop(), input_filter=self.inputFilter, unhandled_input=self.keyHandler) |
88 | 89 |
89 ##misc setup## | 90 ##misc setup## |
90 self.chat_wins=ChatList(self) | 91 self.chat_wins=ChatList(self) |
92 self.notBar = custom_widgets.NotificationBar() | |
93 urwid.connect_signal(self.notBar,'change',self.onNotification) | |
94 self.__saved_overlay = None | |
91 | 95 |
92 def debug(self): | 96 def debug(self): |
93 """convenient method to reset screen and launch pdb""" | 97 """convenient method to reset screen and launch pdb""" |
94 import os | 98 import os |
95 os.system('reset') | 99 os.system('reset') |
109 self.i = 0 | 113 self.i = 0 |
110 self.loop.set_alarm_in(0,lambda a,b: self.postInit()) | 114 self.loop.set_alarm_in(0,lambda a,b: self.postInit()) |
111 self.loop.run() | 115 self.loop.run() |
112 | 116 |
113 def inputFilter(self, input, raw): | 117 def inputFilter(self, input, raw): |
118 if self.__saved_overlay and input != ['ctrl s']: | |
119 return | |
114 for i in input: | 120 for i in input: |
115 if isinstance(i,tuple): | 121 if isinstance(i,tuple): |
116 if i[0] == 'mouse press': | 122 if i[0] == 'mouse press': |
117 if i[1] == 4: #Mouse wheel up | 123 if i[1] == 4: #Mouse wheel up |
118 input[input.index(i)] = 'up' | 124 input[input.index(i)] = 'up' |
127 self.main_widget.header = self.menu_roller | 133 self.main_widget.header = self.menu_roller |
128 else: | 134 else: |
129 self.main_widget.header = None | 135 self.main_widget.header = None |
130 except AttributeError: | 136 except AttributeError: |
131 pass | 137 pass |
138 elif input == 'ctrl n': | |
139 """User wants to see next notification""" | |
140 self.notBar.showNext() | |
141 elif input == 'ctrl s': | |
142 """User wants to (un)hide overlay window""" | |
143 if isinstance(self.loop.widget,urwid.Overlay): | |
144 self.__saved_overlay = self.loop.widget | |
145 self.loop.widget = self.main_widget | |
146 else: | |
147 if self.__saved_overlay: | |
148 self.loop.widget = self.__saved_overlay | |
149 self.__saved_overlay = None | |
150 | |
132 elif input == 'ctrl d' and 'D' in self.bridge.getVersion(): #Debug only for dev versions | 151 elif input == 'ctrl d' and 'D' in self.bridge.getVersion(): #Debug only for dev versions |
133 self.debug() | 152 self.debug() |
134 elif input == 'f2': #user wants to (un)hide the contact_list | 153 elif input == 'f2': #user wants to (un)hide the contact_list |
135 try: | 154 try: |
136 center_widgets = self.center_part.widget_list | 155 center_widgets = self.center_part.widget_list |
188 | 207 |
189 def __buildMainWidget(self): | 208 def __buildMainWidget(self): |
190 self.contactList = ContactList(self, self.CM, on_click = self.contactSelected, on_change=lambda w: self.redraw()) | 209 self.contactList = ContactList(self, self.CM, on_click = self.contactSelected, on_change=lambda w: self.redraw()) |
191 #self.center_part = urwid.Columns([('weight',2,self.contactList),('weight',8,Chat('',self))]) | 210 #self.center_part = urwid.Columns([('weight',2,self.contactList),('weight',8,Chat('',self))]) |
192 self.center_part = urwid.Columns([('weight',2,self.contactList), ('weight',8,urwid.Filler(urwid.Text('')))]) | 211 self.center_part = urwid.Columns([('weight',2,self.contactList), ('weight',8,urwid.Filler(urwid.Text('')))]) |
193 editBar = custom_widgets.AdvancedEdit('> ') | 212 self.editBar = custom_widgets.AdvancedEdit('> ') |
194 urwid.connect_signal(editBar,'click',self.onTextEntered) | 213 urwid.connect_signal(self.editBar,'click',self.onTextEntered) |
195 self.menu_roller = self.__buildMenuRoller() | 214 self.menu_roller = self.__buildMenuRoller() |
196 self.main_widget = custom_widgets.FocusFrame(self.center_part, header=self.menu_roller, footer=editBar, focus_part='footer') | 215 self.main_widget = custom_widgets.FocusFrame(self.center_part, header=self.menu_roller, footer=self.editBar, focus_part='footer') |
197 return self.main_widget | 216 return self.main_widget |
198 | 217 |
199 def plug_profile(self, profile_key='@DEFAULT@'): | 218 def plug_profile(self, profile_key='@DEFAULT@'): |
200 self.loop.widget = self.__buildMainWidget() | 219 self.loop.widget = self.__buildMainWidget() |
201 QuickApp.plug_profile(self, profile_key) | 220 QuickApp.plug_profile(self, profile_key) |
202 | 221 |
203 def removePopUp(self, widget=None): | 222 def removePopUp(self, widget=None): |
223 "Remove current pop-up, and if there is other in queue, show it" | |
204 self.loop.widget = self.main_widget | 224 self.loop.widget = self.main_widget |
225 next_popup = self.notBar.getNextPopup() | |
226 if next_popup: | |
227 #we still have popup to show, we display it | |
228 self.showPopUp(next_popup) | |
205 | 229 |
206 def showPopUp(self, pop_up_widget): | 230 def showPopUp(self, pop_up_widget): |
207 display_widget = urwid.Overlay(pop_up_widget, self.main_widget, 'center', ('relative', 40), 'middle', ('relative', 40)) | 231 "Show a pop-up window if possible, else put it in queue" |
208 self.loop.widget = display_widget | 232 if not isinstance(self.loop.widget,urwid.Overlay): |
233 display_widget = urwid.Overlay(pop_up_widget, self.main_widget, 'center', ('relative', 40), 'middle', ('relative', 40)) | |
234 self.loop.widget = display_widget | |
235 else: | |
236 self.notBar.addPopUp(pop_up_widget) | |
237 | |
238 def notify(self, message): | |
239 self.notBar.addMessage(message) | |
209 | 240 |
210 def contactSelected(self, contact_list): | 241 def contactSelected(self, contact_list): |
211 contact = contact_list.get_contact() | 242 contact = contact_list.get_contact() |
212 if contact: | 243 if contact: |
213 assert(len(self.center_part.widget_list)==2) | 244 assert(len(self.center_part.widget_list)==2) |
230 return | 261 return |
231 QuickApp.newMessage(self, from_jid, msg, type, to_jid, profile) | 262 QuickApp.newMessage(self, from_jid, msg, type, to_jid, profile) |
232 sender = JID(from_jid) | 263 sender = JID(from_jid) |
233 if JID(self.contactList.selected).short != sender.short: | 264 if JID(self.contactList.selected).short != sender.short: |
234 self.contactList.putAlert(sender) | 265 self.contactList.putAlert(sender) |
266 | |
267 def onNotification(self, notBar): | |
268 """Called when a new notification has been received""" | |
269 if not isinstance(self.main_widget, custom_widgets.FocusFrame): | |
270 #if we are not in the main configuration, we ignore the notifications bar | |
271 return | |
272 if isinstance(self.main_widget.footer,custom_widgets.AdvancedEdit): | |
273 if not self.notBar.canHide(): | |
274 #the notification bar is not visible and has usefull informations, we show it | |
275 pile = urwid.Pile([self.notBar, self.editBar]) | |
276 self.main_widget.footer = pile | |
277 else: | |
278 if not isinstance(self.main_widget.footer, urwid.Pile): | |
279 error(_("INTERNAL ERROR: Unexpected class for main widget's footer")) | |
280 assert(False) | |
281 if self.notBar.canHide(): | |
282 #No notification left, we can hide the bar | |
283 self.main_widget.footer = self.editBar | |
235 | 284 |
236 def actionResult(self, type, id, data): | 285 def actionResult(self, type, id, data): |
237 if not id in self.current_action_ids: | 286 if not id in self.current_action_ids: |
238 debug (_('unknown id, ignoring')) | 287 debug (_('unknown id, ignoring')) |
239 return | 288 return |