# HG changeset patch # User Goffi # Date 1423514391 -3600 # Node ID 781ee3539252eff2484f563d2613b07edb46c5e2 # Parent 6c7d89843f1bd1e1f98696a34b655977c7ca4347 quick frontends(quick app): add a listeners (observer/observable) mechanism to call a callback when a event happen. Implemented an "avatar" event. diff -r 6c7d89843f1b -r 781ee3539252 frontends/src/quick_frontend/quick_app.py --- a/frontends/src/quick_frontend/quick_app.py Mon Feb 09 21:39:51 2015 +0100 +++ b/frontends/src/quick_frontend/quick_app.py Mon Feb 09 21:39:51 2015 +0100 @@ -195,6 +195,9 @@ # widgets self.selected_widget = None # widget currently selected (must be filled by frontend) + # listeners + self._listeners = {} # key: listerner type ("avatar", "selected", etc), value: list of callbacks + ## bridge ## try: self.bridge = create_bridge() @@ -284,6 +287,42 @@ handler(*args, **kwargs) self.bridge.register(functionName, signalReceived, iface) + def addListerner(self, type_, callback): + """Add a listerner for an event + + /!\ don't forget to remove listener when not used anymore (e.g. if you delete a widget) + @param type_: type of event, can be: + - avatar: called when avatar data is updated + args: (entity, avatar file, profile) + @param callback: method to call on event + """ + assert type_ in C.LISTENERS + self._listeners.setdefault(type_, []).append(callback) + + def removeListener(self, type_, callback): + """Remove a callback from listeners + + @param type_: same as for [addListerner] + @param callback: callback to remove + """ + assert type_ in C.LISTENERS + self._listeners[type_].remove(callback) + + def callListeners(self, type_, *args): + """Call all methods which listen of type_ event + + @param type_: same as for [addListerner] + @param *args: arguments sent to callback + """ + assert type_ in C.LISTENERS + try: + listeners = self._listeners[type_] + except KeyError: + pass + else: + for listener in listeners: + listener(*args) + def check_profile(self, profile): """Tell if the profile is currently followed by the application""" return profile in self.profiles @@ -611,6 +650,7 @@ if entity in self.contact_lists[profile]: def gotFilename(filename): self.contact_lists[profile].setCache(entity, 'avatar', filename) + self.callListeners('avatar', entity, filename, profile) self.bridge.getAvatarFile(value, callback=gotFilename) def askConfirmationHandler(self, confirm_id, confirm_type, data, profile):