libervia-backend/frontends/primitivus/custom_widgets.py
Goffi ab067174ff Primitivus: profile manager
- new custom widgets: Password, List, GenericDialog, InputDialog, ConfirmationDialog
2010-07-01 15:35:56 +08:00

179 lines
6 KiB
Python

#!/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)