diff frontends/primitivus/custom_widgets.py @ 113:e5ca22113280

Primitivus: profile manager - new custom widgets: Password, List, GenericDialog, InputDialog, ConfirmationDialog
author Goffi <goffi@goffi.org>
date Thu, 01 Jul 2010 15:35:56 +0800
parents
children 77f48939ad6e
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/frontends/primitivus/custom_widgets.py	Thu Jul 01 15:35:56 2010 +0800
@@ -0,0 +1,179 @@
+#!/usr/bin/python
+# -*- coding: utf-8 -*-
+
+"""
+Primitivus: a SAT frontend
+Copyright (C) 2009, 2010  Jérôme Poisson (goffi@goffi.org)
+
+This program is free software: you can redistribute it and/or modify
+it under the terms of the GNU General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program.  If not, see <http://www.gnu.org/licenses/>.
+"""
+
+import urwid
+
+class Password(urwid.Edit):
+
+    def __init__(self, *args, **kwargs):
+        self.hidden_char=kwargs['hidden_char'] if kwargs.has_key('hidden_char') else '*'
+        self.__real_text=''
+        super(Password, self).__init__(*args, **kwargs)
+
+    def set_edit_text(self, text):
+        self.__real_text = text
+        hidden_txt = len(text)*'*'
+        super(Password, self).set_edit_text(hidden_txt)
+
+    def get_edit_text(self):
+        return self.__real_text
+
+class SelectableText(urwid.FlowWidget):
+    signals = ['change']
+    
+    def __init__(self, text, align='left'):
+        self.text=unicode(text)
+        self.align = align
+        self.__selected=False
+
+    def getValue(self):
+        return self.text
+    
+    def setState(self, selected, invisible=False):
+        """Change state
+        @param selected: boolean state value
+        @param invisible: don't emit change signal if True"""
+        assert(type(selected)==bool)
+        self.__selected=selected
+        if not invisible:
+            self._emit("change", self.__selected)
+        self._invalidate()
+   
+    def getState(self):
+        return self.__selected
+
+    def selectable(self):
+        return True
+
+    def keypress(self, size, key):
+        if key==' ' or key=='enter':
+            self.setState(not self.__selected)
+        else:
+            return key
+
+    def rows(self,size,focus=False):
+        return self.display_widget(size, focus).rows(size, focus)
+
+    def render(self, size, focus=False):
+        return self.display_widget(size, focus).render(size, focus)
+
+    def display_widget(self, size, focus):
+        attr = 'selected' if self.__selected else 'default'
+        if focus:
+            attr+="_focus"
+        return urwid.Text((attr,self.text), align=self.align)
+
+class List(urwid.WidgetWrap):
+    signals = ['change']
+
+    def __init__(self, options, style=[], align='left', on_state_change=None, user_data=None):
+        assert(options)
+        self.single = 'single' in style
+        self.align = align
+        
+        if on_state_change:
+            urwid.connect_signal(self, 'change', on_state_change, user_data)
+        
+        widgets = [SelectableText(option,align) for option in options]
+        for widget in widgets:
+            urwid.connect_signal(widget, 'change', self.__onStateChange)
+        self.content = urwid.SimpleListWalker(widgets)
+        self.list_box = urwid.ListBox(self.content)
+        if self.single:
+            self.content[0].setState(True)
+        display_widget = urwid.BoxAdapter(self.list_box, min(len(options),5))
+        
+        urwid.WidgetWrap.__init__(self, display_widget)
+
+    def __onStateChange(self, widget, selected):
+        if self.single:
+            if not selected:
+                #if in single mode, it's forbidden to unselect a value
+                widget.setState(True, invisible=True)
+                return
+            else:
+                self.unselectAll(invisible=True)
+                widget.setState(True, invisible=True)
+        self._emit("change")
+
+
+    def unselectAll(self, invisible=False):
+        for widget in self.content:
+            if widget.getState():
+                widget.setState(False, invisible)
+                widget._invalidate()
+
+    def getValues(self):
+        result = []
+        for widget in self.content:
+            if widget.getState():
+                result.append(widget.getValue())
+        return result
+
+    def changeValues(self, new_values):
+        widgets = [SelectableText(self, option) for option in new_values]
+        self.content[:] = widgets
+        
+    def selectValue(self, value):
+        self.unselectAll()
+        idx = 0
+        for widget in self.content:
+            if widget.getValue() == value:
+                widget.setState(True)
+                self.list_box.set_focus(idx)
+                return
+            idx+=1
+
+class genericDialog(urwid.WidgetWrap):
+
+    def __init__(self, widgets_lst, title, style=[], **kwargs):
+        frame_header = urwid.AttrMap(urwid.Text(title,'center'),'title')
+       
+        buttons = None
+
+        if "OK/CANCEL" in style:
+            buttons = [urwid.Button(_("Cancel"), kwargs['cancel_cb']),
+                      urwid.Button(_("Ok"), kwargs['ok_cb'], kwargs['ok_value'])]
+        elif "YES/NO" in style:
+            buttons = [urwid.Button(_("Yes"), kwargs['yes_cb']),
+                      urwid.Button(_("No"), kwargs['no_cb'], kwargs['yes_value'])]
+        if buttons:
+            buttons_flow = urwid.GridFlow(buttons, max([len(button.get_label()) for button in buttons])+4, 1, 1, 'center')
+            widgets_lst.append(buttons_flow)
+        body_content = urwid.SimpleListWalker(widgets_lst)
+        frame_body = urwid.ListBox(body_content)
+        frame = urwid.Frame(frame_body, frame_header)
+        decorated_frame = urwid.LineBox(frame)
+        urwid.WidgetWrap.__init__(self, decorated_frame)
+
+
+
+class InputDialog(genericDialog):
+
+    def __init__(self, title, instrucions, style=['OK/CANCEL'], **kwargs):
+        instr_wid = urwid.Text(instrucions+':')
+        edit_box = urwid.Edit()
+        genericDialog.__init__(self, [instr_wid,edit_box], title, style, ok_value=edit_box, **kwargs)
+
+class ConfirmDialog(genericDialog):
+
+    def __init__(self, title, style=['YES/NO'], **kwargs):
+        genericDialog.__init__(self, [], title, style, yes_value=None, **kwargs)