# HG changeset patch # User Goffi # Date 1277969756 -28800 # Node ID cb72fb2bfa0dd1e99428388581cbf0ef5adfc824 Primitivus: profile manager - new custom widgets: Password, List, GenericDialog, InputDialog, ConfirmationDialog diff -r 000000000000 -r cb72fb2bfa0d frontends/primitivus/custom_widgets.py --- /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 . +""" + +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)