comparison frontends/src/primitivus/primitivus @ 1181:ca8ce5a47969

Primitivus: main_widget is now in its own class (PrimitivusTopWidget), menu and notification bar (un)hidding is cleaner
author Goffi <goffi@goffi.org>
date Mon, 08 Sep 2014 15:50:51 +0200
parents ca15fb1abbc4
children 6184779544c7
comparison
equal deleted inserted replaced
1180:69aace10b46d 1181:ca8ce5a47969
175 if contact: 175 if contact:
176 self.app.bridge.chatStateComposing(unescapePrivate(contact), self.app.profile) 176 self.app.bridge.chatStateComposing(unescapePrivate(contact), self.app.profile)
177 return super(EditBar, self).keypress(size, key) 177 return super(EditBar, self).keypress(size, key)
178 178
179 179
180 class PrimitivusTopWidget(sat_widgets.FocusPile):
181 """Top most widget used in Primitivus"""
182 _focus_inversed = True
183 positions = ('menu', 'body', 'notif_bar', 'edit_bar')
184 can_hide = ('menu', 'notif_bar')
185
186 def __init__(self, body, menu, notif_bar, edit_bar):
187 self._body = body
188 self._menu = menu
189 self._notif_bar = notif_bar
190 self._edit_bar = edit_bar
191 self._hidden = {'notif_bar'}
192 super(PrimitivusTopWidget, self).__init__([('pack', self._menu), self._body, ('pack', self._edit_bar)])
193 for position in self.positions:
194 setattr(self,
195 position,
196 property(lambda: self, self.widgetGet(position=position),
197 lambda pos, new_wid: self.widgetSet(new_wid, position=pos))
198 )
199 self.focus_position = len(self.contents)-1
200
201 def widgetGet(self, position):
202 if not position in self.positions:
203 raise ValueError("Unknown position {}".format(position))
204 return getattr(self, "_{}".format(position))
205
206 def widgetSet(self, widget, position):
207 if not position in self.positions:
208 raise ValueError("Unknown position {}".format(position))
209 return setattr(self, "_{}".format(position), widget)
210
211 def hideSwitch(self, position):
212 if not position in self.can_hide:
213 raise ValueError("Can't switch position {}".format(position))
214 hide = not position in self._hidden
215 visible_positions = [pos for pos in self.positions if pos == position or pos not in self._hidden] # we need to keep position to find its index
216 widget = self.widgetGet(position)
217 idx = visible_positions.index(position)
218 if hide:
219 del self.contents[idx]
220 self._hidden.add(position)
221 else:
222 self.contents.insert(idx, (widget, ('pack', None)))
223 self._hidden.remove(position)
224
225 def show(self, position):
226 if position in self._hidden:
227 self.hideSwitch(position)
228
229 def hide(self, position):
230 if not position in self._hidden:
231 self.hideSwitch(position)
232
233
180 class PrimitivusApp(QuickApp, InputHistory): 234 class PrimitivusApp(QuickApp, InputHistory):
181 235
182 def __init__(self): 236 def __init__(self):
183 QuickApp.__init__(self) 237 QuickApp.__init__(self)
184 238
186 self.main_widget = ProfileManager(self) 240 self.main_widget = ProfileManager(self)
187 self.loop = urwid.MainLoop(self.main_widget, C.PALETTE, event_loop=urwid.GLibEventLoop(), input_filter=self.inputFilter, unhandled_input=self.keyHandler) 241 self.loop = urwid.MainLoop(self.main_widget, C.PALETTE, event_loop=urwid.GLibEventLoop(), input_filter=self.inputFilter, unhandled_input=self.keyHandler)
188 242
189 ##misc setup## 243 ##misc setup##
190 self.chat_wins = ChatList(self) 244 self.chat_wins = ChatList(self)
191 self.notBar = sat_widgets.NotificationBar() 245 self.notif_bar = sat_widgets.NotificationBar()
192 urwid.connect_signal(self.notBar, 'change', self.onNotification) 246 urwid.connect_signal(self.notif_bar, 'change', self.onNotification)
193 self.progress_wid = Progress(self) 247 self.progress_wid = Progress(self)
194 urwid.connect_signal(self.notBar.progress, 'click', lambda x: self.addWindow(self.progress_wid)) 248 urwid.connect_signal(self.notif_bar.progress, 'click', lambda x: self.addWindow(self.progress_wid))
195 self.__saved_overlay = None 249 self.__saved_overlay = None
196 250
197 self.x_notify = Notify() 251 self.x_notify = Notify()
198 252
199 # we already manage exit with a_key['APP_QUIT'], so we don't want C-c 253 # we already manage exit with a_key['APP_QUIT'], so we don't want C-c
266 320
267 def keyHandler(self, input_): 321 def keyHandler(self, input_):
268 if input_ == a_key['MENU_HIDE']: 322 if input_ == a_key['MENU_HIDE']:
269 """User want to (un)hide the menu roller""" 323 """User want to (un)hide the menu roller"""
270 try: 324 try:
271 if self.main_widget.header == None: 325 self.main_widget.hideSwitch('menu')
272 self.main_widget.header = self.menu_roller
273 else:
274 self.main_widget.header = None
275 except AttributeError: 326 except AttributeError:
276 pass 327 pass
277 elif input_ == a_key['NOTIFICATION_NEXT']: 328 elif input_ == a_key['NOTIFICATION_NEXT']:
278 """User wants to see next notification""" 329 """User wants to see next notification"""
279 self.notBar.showNext() 330 self.notif_bar.showNext()
280 elif input_ == a_key['OVERLAY_HIDE']: 331 elif input_ == a_key['OVERLAY_HIDE']:
281 """User wants to (un)hide overlay window""" 332 """User wants to (un)hide overlay window"""
282 if isinstance(self.loop.widget,urwid.Overlay): 333 if isinstance(self.loop.widget,urwid.Overlay):
283 self.__saved_overlay = self.loop.widget 334 self.__saved_overlay = self.loop.widget
284 self.loop.widget = self.main_widget 335 self.loop.widget = self.main_widget
355 #self.center_part = urwid.Columns([('weight',2,self.contact_list),('weight',8,Chat('',self))]) 406 #self.center_part = urwid.Columns([('weight',2,self.contact_list),('weight',8,Chat('',self))])
356 self.center_part = urwid.Columns([('weight', 2, self.contact_list), ('weight', 8, urwid.Filler(urwid.Text('')))]) 407 self.center_part = urwid.Columns([('weight', 2, self.contact_list), ('weight', 8, urwid.Filler(urwid.Text('')))])
357 408
358 self.editBar = EditBar(self) 409 self.editBar = EditBar(self)
359 self.menu_roller = self._buildMenuRoller() 410 self.menu_roller = self._buildMenuRoller()
360 self.main_widget = sat_widgets.FocusFrame(self.center_part, header=self.menu_roller, footer=self.editBar, focus_part='footer') 411 self.main_widget = PrimitivusTopWidget(self.center_part, self.menu_roller, self.notif_bar, self.editBar)
361 return self.main_widget 412 return self.main_widget
362 413
363 def plug_profile_1(self, profile_key='@DEFAULT@'): 414 def plug_profile_1(self, profile_key='@DEFAULT@'):
364 self.loop.widget = self._buildMainWidget() 415 self.loop.widget = self._buildMainWidget()
365 self.redraw() 416 self.redraw()
373 del self._early_popup 424 del self._early_popup
374 425
375 def removePopUp(self, widget=None): 426 def removePopUp(self, widget=None):
376 "Remove current pop-up, and if there is other in queue, show it" 427 "Remove current pop-up, and if there is other in queue, show it"
377 self.loop.widget = self.main_widget 428 self.loop.widget = self.main_widget
378 next_popup = self.notBar.getNextPopup() 429 next_popup = self.notif_bar.getNextPopup()
379 if next_popup: 430 if next_popup:
380 #we still have popup to show, we display it 431 #we still have popup to show, we display it
381 self.showPopUp(next_popup) 432 self.showPopUp(next_popup)
382 433
383 def showPopUp(self, pop_up_widget, perc_width=40, perc_height=40, align='center', valign='middle'): 434 def showPopUp(self, pop_up_widget, perc_width=40, perc_height=40, align='center', valign='middle'):
385 if not isinstance(self.loop.widget, urwid.Overlay): 436 if not isinstance(self.loop.widget, urwid.Overlay):
386 display_widget = urwid.Overlay(pop_up_widget, self.main_widget, align, ('relative', perc_width), valign, ('relative', perc_height)) 437 display_widget = urwid.Overlay(pop_up_widget, self.main_widget, align, ('relative', perc_width), valign, ('relative', perc_height))
387 self.loop.widget = display_widget 438 self.loop.widget = display_widget
388 self.redraw() 439 self.redraw()
389 else: 440 else:
390 self.notBar.addPopUp(pop_up_widget) 441 self.notif_bar.addPopUp(pop_up_widget)
391 442
392 def notify(self, message): 443 def notify(self, message):
393 """"Notify message to user via notification bar""" 444 """"Notify message to user via notification bar"""
394 self.notBar.addMessage(message) 445 self.notif_bar.addMessage(message)
395 self.redraw() 446 self.redraw()
396 447
397 def addWindow(self, widget): 448 def addWindow(self, widget):
398 """Display a window if possible, 449 """Display a window if possible,
399 else add it in the notification bar queue 450 else add it in the notification bar queue
420 @param message: message to show to identify the progression""" 471 @param message: message to show to identify the progression"""
421 self.progress_wid.addProgress(id, message) 472 self.progress_wid.addProgress(id, message)
422 473
423 def setProgress(self, percentage): 474 def setProgress(self, percentage):
424 """Set the progression shown in notification bar""" 475 """Set the progression shown in notification bar"""
425 self.notBar.setProgress(percentage) 476 self.notif_bar.setProgress(percentage)
426 477
427 def contactSelected(self, contact_list): 478 def contactSelected(self, contact_list):
428 contact = contact_list.getContact() 479 contact = contact_list.getContact()
429 if contact: 480 if contact:
430 assert(len(self.center_part.widget_list)==2) 481 assert(len(self.center_part.widget_list)==2)
467 else: 518 else:
468 popup = sat_widgets.Alert(unicode(title), unicode(message), ok_cb=answer_cb or self.removePopUp) #FIXME: remove unicode here when DBus Bridge will no return dbus.String anymore 519 popup = sat_widgets.Alert(unicode(title), unicode(message), ok_cb=answer_cb or self.removePopUp) #FIXME: remove unicode here when DBus Bridge will no return dbus.String anymore
469 log.error(_('unmanaged dialog type: %s'), type_) 520 log.error(_('unmanaged dialog type: %s'), type_)
470 self.showPopUp(popup) 521 self.showPopUp(popup)
471 522
472 def onNotification(self, notBar): 523 def onNotification(self, notif_bar):
473 """Called when a new notification has been received""" 524 """Called when a new notification has been received"""
474 if not isinstance(self.main_widget, sat_widgets.FocusFrame): 525 if not isinstance(self.main_widget, PrimitivusTopWidget):
475 #if we are not in the main configuration, we ignore the notifications bar 526 #if we are not in the main configuration, we ignore the notifications bar
476 return 527 return
477 if isinstance(self.main_widget.footer,sat_widgets.AdvancedEdit): 528 if self.notif_bar.canHide():
478 if not self.notBar.canHide():
479 #the notification bar is not visible and has usefull informations, we show it
480 pile = urwid.Pile([self.notBar, self.editBar])
481 self.main_widget.footer = pile
482 else:
483 if not isinstance(self.main_widget.footer, urwid.Pile):
484 log.error(_("INTERNAL ERROR: Unexpected class for main widget's footer"))
485 assert(False)
486 if self.notBar.canHide():
487 #No notification left, we can hide the bar 529 #No notification left, we can hide the bar
488 self.main_widget.footer = self.editBar 530 self.main_widget.hide('notif_bar')
531 else:
532 self.main_widget.show('notif_bar')
489 533
490 def launchAction(self, callback_id, data=None, profile_key="@NONE@"): 534 def launchAction(self, callback_id, data=None, profile_key="@NONE@"):
491 """ Launch a dynamic action 535 """ Launch a dynamic action
492 @param callback_id: id of the action to launch 536 @param callback_id: id of the action to launch
493 @param data: data needed only for certain actions 537 @param data: data needed only for certain actions