]>
git.ipfire.org Git - thirdparty/newt.git/blob - snack.py
1 # snack.py: maps C extension module _snack to proper python types in module
3 # The first section is a very literal mapping.
4 # The second section contains convenience classes that amalgamate
5 # the literal classes and make them more object-oriented.
8 This module provides the NEWT Windowing toolkit API for Python
9 This is a lightweight text-mode windowing library, based on slang.
43 from __future__
import absolute_import
, print_function
, unicode_literals
48 from _snack
import FLAG_DISABLED
, FLAGS_SET
, FLAGS_RESET
, FLAGS_TOGGLE
, FD_READ
, FD_WRITE
, FD_EXCEPT
56 snackArgs
= {"append":-1}
59 """Base class for NEWT toolkit - Do not use directly
64 - setCallback(self, obj, data = None) :
65 The callback for when object activated.
66 data is passed to obj.
68 def setCallback(self
, obj
, data
= None):
70 self
.w
.setCallback(obj
, data
)
72 self
.w
.setCallback(obj
)
75 raise NotImplementedError
78 """Basic button class, takes button text as parameter
82 - Button(self, text): returns a button
84 def __init__(self
, text
):
85 self
.w
= _snack
.button(text
)
87 class CompactButton(Widget
):
88 """Compact Button class (less frilly button decoration).
92 - CompactButton(self,text) : create button, with text.
94 def __init__(self
, text
):
95 self
.w
= _snack
.compactbutton(text
)
97 class Checkbox(Widget
):
102 - Checkbox(self, text, isOn = 0) : text, and boolean as to default value
103 - setValue(self) : set value
104 - value(self, value) : return checkbox value
105 - selected(self) : returns boolean
106 - setFlags(self, flag, sense) : set flags
108 flags: FLAG_DISABLED, FLAGS_SET, FLAGS_RESET
111 return self
.w
.checkboxValue
114 return self
.w
.checkboxValue
!= 0
116 def setFlags (self
, flag
, sense
):
118 return self
.w
.checkboxSetFlags(flag
, sense
)
120 def setValue (self
, value
):
121 return self
.w
.checkboxSetValue(value
)
123 def __init__(self
, text
, isOn
= 0):
124 self
.w
= _snack
.checkbox(text
, isOn
)
126 class SingleRadioButton(Widget
):
127 """Single Radio Button.
131 - SingleRadioButton(text, group, isOn = 0) : create button
132 - selected(self) : returns bool, whether or not is selected.
136 return self
.w
.key
== self
.w
.radioValue
;
138 def __init__(self
, text
, group
, isOn
= 0):
140 self
.w
= _snack
.radiobutton(text
, group
.w
, isOn
)
142 self
.w
= _snack
.radiobutton(text
, None, isOn
)
144 class Listbox(Widget
):
149 - Listbox(self, height, scroll = 0, returnExit = 0, width = 0, showCursor = 0, multiple = 0, border = 0)
150 - insert(self, text, item, before) : insert element; before = key to item to insert before, or None.
151 - delete(self, item) : delete item from list.
152 - replace(self, text,item) : Replace a given item's text
153 - current(self) : returns currently selected item
154 - getSelection(self) : returns a list of selected items
155 - setCurrent(self,i tem) : select current.
156 - clear(self) : clear listbox
159 def append(self
, text
, item
):
160 key
= self
.w
.listboxAddItem(text
)
161 self
.key2item
[key
] = item
162 self
.item2key
[item
] = key
164 def insert(self
, text
, item
, before
):
166 key
= self
.w
.listboxInsertItem(text
, 0)
168 key
= self
.w
.listboxInsertItem(text
, self
.item2key
[before
])
169 self
.key2item
[key
] = item
170 self
.item2key
[item
] = key
172 def delete(self
, item
):
173 self
.w
.listboxDeleteItem(self
.item2key
[item
])
174 del self
.key2item
[self
.item2key
[item
]]
175 del self
.item2key
[item
]
177 def replace(self
, text
, item
):
178 key
= self
.w
.listboxInsertItem(text
, self
.item2key
[item
])
179 self
.w
.listboxDeleteItem(self
.item2key
[item
])
180 del self
.key2item
[self
.item2key
[item
]]
181 self
.item2key
[item
] = key
182 self
.key2item
[key
] = item
185 return self
.key2item
[self
.w
.listboxGetCurrent()]
187 def getSelection(self
):
189 list = self
.w
.listboxGetSelection()
191 selection
.append(self
.key2item
[key
])
194 def setCurrent(self
, item
):
195 self
.w
.listboxSetCurrent(self
.item2key
[item
])
200 self
.w
.listboxClear()
202 def __init__(self
, height
, scroll
= 0, returnExit
= 0, width
= 0, showCursor
= 0, multiple
= 0, border
= 0):
203 self
.w
= _snack
.listbox(height
, scroll
, returnExit
, showCursor
, multiple
, border
)
207 self
.w
.listboxSetWidth(width
)
209 class Textbox(Widget
):
210 """Textbox, container for text.
214 - Textbox(self, width, height, scroll = 0, wrap = 0): scroll, wrap are flags
215 include scroll bars, or text wrap.
216 - setText(text) : set text.
217 - setHeight(height): set height.
220 def setText(self
, text
):
221 self
.w
.textboxText(text
)
223 def setHeight(self
, height
):
224 self
.w
.textboxHeight(height
)
226 def __init__(self
, width
, height
, text
, scroll
= 0, wrap
= 0):
227 self
.w
= _snack
.textbox(width
, height
, text
, scroll
, wrap
)
229 class TextboxReflowed(Textbox
):
231 def __init__(self
, width
, text
, flexDown
= 5, flexUp
= 10, maxHeight
= -1):
232 (newtext
, width
, height
) = reflow(text
, width
, flexDown
, flexUp
)
233 if maxHeight
!= -1 and height
> maxHeight
:
234 Textbox
.__init
__(self
, width
, maxHeight
, newtext
, 1)
236 Textbox
.__init
__(self
, width
, height
, newtext
, 0)
239 """A Label (simple text).
243 - Label(self,text) : create label
244 - setText(self,text) : change text.
245 - setColors(self, colorset) : change individual colors
247 def setText(self
, text
):
248 self
.w
.labelText(text
)
250 def __init__(self
, text
):
251 self
.w
= _snack
.label(text
)
253 def setColors(self
, colorset
):
254 self
.w
.labelSetColors(colorset
)
257 """A Scale (progress bar).
261 - Scale(self,width, total) : create scale; width: size on screen, fullamount: integer.
262 - set(self,amount) : set amount to integer.
264 def set(self
, amount
):
265 self
.w
.scaleSet(amount
)
267 def __init__(self
, width
, total
):
268 self
.w
= _snack
.scale(width
, total
)
275 - Entry(self, width, text = "", hidden = 0, password = 0, scroll = 1, returnExit = 0)
276 constructor. hidden doesn't show text, password stars it out,
277 scroll includes scroll bars;
278 if returnExit is set, return from Form when exiting this element, else
279 proceed to next entry widget.
280 - value(self): return value.
281 - set(text, cursorAtEnd = 1) : set the text
282 - setFlags (flag, sense) : flags can be FLAG_DISABLED, FLAGS_SET, FLAGS_RESET, FLAGS_TOGGLE
285 return self
.w
.entryValue
287 def set(self
, text
, cursorAtEnd
= 1):
288 return self
.w
.entrySetValue(text
, cursorAtEnd
)
290 def setFlags (self
, flag
, sense
):
291 return self
.w
.entrySetFlags(flag
, sense
)
293 def __init__(self
, width
, text
= "", hidden
= 0, password
= 0, scroll
= 1,
295 self
.w
= _snack
.entry(width
, text
, hidden
, password
, scroll
, returnExit
)
299 hotkeys
= { "F1" : _snack
.KEY_F1
, "F2" : _snack
.KEY_F2
, "F3" : _snack
.KEY_F3
,
300 "F4" : _snack
.KEY_F4
, "F5" : _snack
.KEY_F5
, "F6" : _snack
.KEY_F6
,
301 "F7" : _snack
.KEY_F7
, "F8" : _snack
.KEY_F8
, "F9" : _snack
.KEY_F9
,
302 "F10" : _snack
.KEY_F10
, "F11" : _snack
.KEY_F11
,
303 "F12" : _snack
.KEY_F12
, "ESC" : _snack
.KEY_ESC
,
304 "ENTER": _snack
.KEY_ENTER
, "SUSPEND" : _snack
.KEY_SUSPEND
,
305 "BACKSPACE": _snack
.KEY_BACKSPACE
, "DELETE": _snack
.KEY_DELETE
,
306 "INSERT": _snack
.KEY_INSERT
, "RESIZE": _snack
.KEY_RESIZE
,
309 for n
in list(hotkeys
.keys()):
310 hotkeys
[hotkeys
[n
]] = n
311 for o
,c
in [ (ord(c
),c
) for c
in string
.ascii_letters
+string
.digits
]:
316 """ Base Form class, from which Grid, etc. inherit
320 - Form(self, helpArg = None) : constructor.
321 - addHotKey(self, keyname) : keynames of form "F1" through "F12", "ESC"
322 - add(self, widget) : Add a widget
323 - run(self): run a form, expecting input
324 - draw(self): draw form.
325 - setTimer(self, timer) : add a timer
326 - watchFile(self, file, flags) : watch a named file
327 - setCurrent (self, co): Set a given widget as the current focus
329 def addHotKey(self
, keyname
):
330 self
.w
.addhotkey(hotkeys
[keyname
])
332 def add(self
, widget
):
333 if 'hotkeys' in widget
.__dict
__:
334 for key
in widget
.hotkeys
.keys():
337 if 'gridmembers' in widget
.__dict
__:
338 for w
in widget
.gridmembers
:
340 elif 'w' in widget
.__dict
__:
341 self
.trans
[widget
.w
.key
] = widget
342 return self
.w
.add(widget
.w
)
346 (what
, which
) = self
.w
.run()
347 if (what
== _snack
.FORM_EXIT_WIDGET
):
348 return self
.trans
[which
]
349 elif (what
== _snack
.FORM_EXIT_TIMER
):
351 elif (what
== _snack
.FORM_EXIT_FDREADY
):
352 return self
.filemap
[which
]
353 elif (what
== _snack
.FORM_EXIT_HOTKEY
):
354 return hotkeys
[which
]
355 raise RuntimeError("EOF or IO error")
361 def __init__(self
, helpArg
= None):
364 self
.w
= _snack
.form(helpArg
)
365 # we do the reference count for the helpArg in python! gross
366 self
.helpArg
= helpArg
368 def setCurrent (self
, co
):
369 self
.w
.setcurrent (co
.w
)
371 def setTimer (self
, timer
):
372 self
.w
.settimer (timer
)
374 def watchFile (self
, file, flags
):
375 self
.filemap
[file.fileno()] = file
376 self
.w
.watchfd (file.fileno(), flags
)
383 - place(self,x,y): Return what is placed at (x,y)
384 - setField(self, what, col, row, padding = (0, 0, 0, 0),
385 anchorLeft = 0, anchorTop = 0, anchorRight = 0,
386 anchorBottom = 0, growx = 0, growy = 0):
387 used to add widget 'what' to grid.
388 - Grid(self, *args): eg. g = Grid(2,3) for 2x3 grid
390 def place(self
, x
, y
):
391 return self
.g
.place(x
, y
)
393 def setField(self
, what
, col
, row
, padding
= (0, 0, 0, 0),
394 anchorLeft
= 0, anchorTop
= 0, anchorRight
= 0,
395 anchorBottom
= 0, growx
= 0, growy
= 0):
396 self
.gridmembers
.append(what
)
399 anchorFlags
= _snack
.ANCHOR_LEFT
401 anchorFlags
= _snack
.ANCHOR_RIGHT
404 anchorFlags
= anchorFlags | _snack
.ANCHOR_TOP
406 anchorFlags
= anchorFlags | _snack
.ANCHOR_BOTTOM
410 gridFlags
= _snack
.GRID_GROWX
412 gridFlags
= gridFlags | _snack
.GRID_GROWY
414 if 'g' in what
.__dict
__:
415 return self
.g
.setfield(col
, row
, what
.g
, padding
, anchorFlags
,
418 return self
.g
.setfield(col
, row
, what
.w
, padding
, anchorFlags
)
420 def __init__(self
, *args
):
421 self
.g
= _snack
.grid(*args
)
422 self
.gridmembers
= []
424 colorsets
= { "ROOT" : _snack
.COLORSET_ROOT
,
425 "BORDER" : _snack
.COLORSET_BORDER
,
426 "WINDOW" : _snack
.COLORSET_WINDOW
,
427 "SHADOW" : _snack
.COLORSET_SHADOW
,
428 "TITLE" : _snack
.COLORSET_TITLE
,
429 "BUTTON" : _snack
.COLORSET_BUTTON
,
430 "ACTBUTTON" : _snack
.COLORSET_ACTBUTTON
,
431 "CHECKBOX" : _snack
.COLORSET_CHECKBOX
,
432 "ACTCHECKBOX" : _snack
.COLORSET_ACTCHECKBOX
,
433 "ENTRY" : _snack
.COLORSET_ENTRY
,
434 "LABEL" : _snack
.COLORSET_LABEL
,
435 "LISTBOX" : _snack
.COLORSET_LISTBOX
,
436 "ACTLISTBOX" : _snack
.COLORSET_ACTLISTBOX
,
437 "TEXTBOX" : _snack
.COLORSET_TEXTBOX
,
438 "ACTTEXTBOX" : _snack
.COLORSET_ACTTEXTBOX
,
439 "HELPLINE" : _snack
.COLORSET_HELPLINE
,
440 "ROOTTEXT" : _snack
.COLORSET_ROOTTEXT
,
441 "EMPTYSCALE" : _snack
.COLORSET_EMPTYSCALE
,
442 "FULLSCALE" : _snack
.COLORSET_FULLSCALE
,
443 "DISENTRY" : _snack
.COLORSET_DISENTRY
,
444 "COMPACTBUTTON" : _snack
.COLORSET_COMPACTBUTTON
,
445 "ACTSELLISTBOX" : _snack
.COLORSET_ACTSELLISTBOX
,
446 "SELLISTBOX" : _snack
.COLORSET_SELLISTBOX
}
453 - Screen(self) : constructor
457 - doHelpCallback(self,arg) call callback with arg
458 - helpCallback(self,cb): Set help callback
459 - suspendcallback(self,cb, data=None) : set callback. data=data to pass to cb.
460 - openWindow(self,left, top, width, height, title): Open a window.
461 - pushHelpLine(self,text): put help line on screen. Returns current help line if text=None
462 - setColor(self, colorset, fg, bg): Set foreground and background colors;
463 colorset = key from snack.colorsets,
464 fg & bg = english color names defined by S-Lang
465 (ref: S-Lang Library C Programmer's Guide section:
466 8.4.4. Setting Character Attributes)
470 (self
.width
, self
.height
) = _snack
.size()
471 self
.pushHelpLine(None)
474 return _snack
.finish()
482 def doHelpCallback(self
, arg
):
483 self
.helpCb(self
, arg
)
485 def helpCallback(self
, cb
):
487 return _snack
.helpcallback(self
.doHelpCallback
)
489 def suspendCallback(self
, cb
, data
= None):
491 return _snack
.suspendcallback(cb
, data
)
492 return _snack
.suspendcallback(cb
)
494 def openWindow(self
, left
, top
, width
, height
, title
):
495 return _snack
.openwindow(left
, top
, width
, height
, title
)
497 def pushHelpLine(self
, text
):
499 return _snack
.pushhelpline("*default*")
501 return _snack
.pushhelpline(text
)
503 def popHelpLine(self
):
504 return _snack
.pophelpline()
506 def drawRootText(self
, left
, top
, text
):
507 return _snack
.drawroottext(left
, top
, text
)
509 def centeredWindow(self
, width
, height
, title
):
510 return _snack
.centeredwindow(width
, height
, title
)
512 def gridWrappedWindow(self
, grid
, title
, x
= None, y
= None):
514 return _snack
.gridwrappedwindow(grid
.g
, title
, x
, y
)
516 return _snack
.gridwrappedwindow(grid
.g
, title
)
518 def popWindow(self
, refresh
= True):
520 return _snack
.popwindow()
521 return _snack
.popwindownorefresh()
524 return _snack
.refresh()
526 def setColor(self
, colorset
, fg
, bg
):
527 if colorset
in colorsets
:
528 return _snack
.setcolor(colorsets
[colorset
], fg
, bg
)
530 # assume colorset is an integer for the custom color set
531 return _snack
.setcolor(colorset
, fg
, bg
)
533 def reflow(text
, width
, flexDown
= 5, flexUp
= 5):
534 """ returns a tuple of the wrapped text, the actual width, and the actual height
536 return _snack
.reflow(text
, width
, flexDown
, flexUp
)
540 class RadioGroup(Widget
):
541 """ Combo widget: Group of Radio buttons
545 - RadioGroup(self): constructor.
546 - add(self,title, value, default = None): add a button. Returns button.
547 - getSelection(self) : returns value of selected button | None
553 def add(self
, title
, value
, default
= None):
554 if not self
.prev
and default
== None:
555 # If the first element is not explicitly set to
556 # not be the default, make it be the default
558 b
= SingleRadioButton(title
, self
.prev
, default
)
560 self
.buttonlist
.append((b
, value
))
563 def getSelection(self
):
564 for (b
, value
) in self
.buttonlist
:
565 if b
.selected(): return value
569 class RadioBar(Grid
):
570 """ Bar of Radio buttons, based on Grid.
574 - RadioBar(self, screen, buttonlist) : constructor.
575 - getSelection(self): return value of selected button
578 def __init__(self
, screen
, buttonlist
):
581 self
.group
= RadioGroup()
582 Grid
.__init
__(self
, 1, len(buttonlist
))
583 for (title
, value
, default
) in buttonlist
:
584 b
= self
.group
.add(title
, value
, default
)
585 self
.list.append((b
, value
))
586 self
.setField(b
, 0, self
.item
, anchorLeft
= 1)
587 self
.item
= self
.item
+ 1
589 def getSelection(self
):
590 return self
.group
.getSelection()
593 # you normally want to pack a ButtonBar with growx = 1
595 class ButtonBar(Grid
):
596 """ Bar of buttons, based on grid.
600 - ButtonBar(screen, buttonlist,buttonlist, compact = 0):
601 - buttonPressed(self, result): Takes the widget returned by Form.run and looks to see
602 if it was one of the widgets in the ButtonBar.
604 def __init__(self
, screen
, buttonlist
, compact
= 0):
608 Grid
.__init
__(self
, len(buttonlist
), 1)
609 for blist
in buttonlist
:
610 if isinstance(blist
, str if sys
.version
>= '3' else basestring
):
612 value
= blist
.lower()
613 elif len(blist
) == 2:
614 (title
, value
) = blist
616 (title
, value
, hotkey
) = blist
617 self
.hotkeys
[hotkey
] = value
620 b
= CompactButton(title
)
623 self
.list.append((b
, value
))
624 self
.setField(b
, self
.item
, 0, (1, 0, 1, 0))
625 self
.item
= self
.item
+ 1
627 def buttonPressed(self
, result
):
628 if result
in self
.hotkeys
:
629 return self
.hotkeys
[result
]
631 for (button
, value
) in self
.list:
637 class GridFormHelp(Grid
):
638 """ Subclass of Grid, for the help form text.
642 - GridFormHelp(self, screen, title, help, *args) :
643 - add (self, widget, col, row, padding = (0, 0, 0, 0),
644 anchorLeft = 0, anchorTop = 0, anchorRight = 0,
645 anchorBottom = 0, growx = 0, growy = 0):
646 - runOnce(self, x = None, y = None): pop up the help window
647 - addHotKey(self, keyname):
648 - setTimer(self, keyname):
649 - create(self, x = None, y = None):
650 - run(self, x = None, y = None):
653 - setCurrent (self, co):
655 def __init__(self
, screen
, title
, help, *args
):
658 self
.form
= Form(help)
660 self
.form_created
= 0
663 Grid
.__init
__(*tuple(args
))
665 def add(self
, widget
, col
, row
, padding
= (0, 0, 0, 0),
666 anchorLeft
= 0, anchorTop
= 0, anchorRight
= 0,
667 anchorBottom
= 0, growx
= 0, growy
= 0):
668 self
.setField(widget
, col
, row
, padding
, anchorLeft
,
669 anchorTop
, anchorRight
, anchorBottom
,
671 self
.childList
.append(widget
)
673 def runOnce(self
, x
= None, y
= None):
674 result
= self
.run(x
, y
)
675 self
.screen
.popWindow()
678 def addHotKey(self
, keyname
):
679 self
.form
.addHotKey(keyname
)
681 def setTimer(self
, keyname
):
682 self
.form
.setTimer(keyname
)
684 def create(self
, x
= None, y
= None):
685 if not self
.form_created
:
687 for child
in self
.childList
:
689 self
.screen
.gridWrappedWindow(self
, self
.title
, x
, y
)
690 self
.form_created
= 1
692 def run(self
, x
= None, y
= None):
694 return self
.form
.run()
698 return self
.form
.draw()
702 self
.screen
.gridWrappedWindow(self
, self
.title
)
703 result
= self
.form
.run()
704 self
.screen
.popWindow()
707 def setCurrent (self
, co
):
708 self
.form
.setCurrent (co
)
710 class GridForm(GridFormHelp
):
711 """ GridForm class (extends GridFormHelp):
715 - GridForm(self, screen, title, *args):
717 def __init__(self
, screen
, title
, *args
):
718 myargs
= (self
, screen
, title
, None) + args
719 GridFormHelp
.__init
__(*myargs
)
721 class CheckboxTree(Widget
):
722 """ CheckboxTree combo widget,
726 - CheckboxTree(self, height, scroll = 0, width = None, hide_checkbox = 0, unselectable = 0)
728 - append(self, text, item = None, selected = 0):
729 - addItem(self, text, path, item = None, selected = 0):
731 - getSelection(self):
732 - setEntry(self, item, text):
733 - setCurrent(self, item):
734 - setEntryValue(self, item, selected = 1):
735 - getEntryValue(self, item):
737 def append(self
, text
, item
= None, selected
= 0):
738 self
.addItem(text
, (snackArgs
['append'], ), item
, selected
)
740 def addItem(self
, text
, path
, item
= None, selected
= 0):
743 key
= self
.w
.checkboxtreeAddItem(text
, path
, selected
)
744 self
.key2item
[key
] = item
745 self
.item2key
[item
] = key
747 def getCurrent(self
):
748 curr
= self
.w
.checkboxtreeGetCurrent()
749 return self
.key2item
[curr
]
751 def __init__(self
, height
, scroll
= 0, width
= None, hide_checkbox
= 0, unselectable
= 0):
752 self
.w
= _snack
.checkboxtree(height
, scroll
, hide_checkbox
, unselectable
)
756 self
.w
.checkboxtreeSetWidth(width
)
758 def getSelection(self
):
760 list = self
.w
.checkboxtreeGetSelection()
762 selection
.append(self
.key2item
[key
])
765 def setEntry(self
, item
, text
):
766 self
.w
.checkboxtreeSetEntry(self
.item2key
[item
], text
)
768 def setCurrent(self
, item
):
769 self
.w
.checkboxtreeSetCurrent(self
.item2key
[item
])
771 def setEntryValue(self
, item
, selected
= 1):
772 self
.w
.checkboxtreeSetEntryValue(self
.item2key
[item
], selected
)
774 def getEntryValue(self
, item
):
775 return self
.w
.checkboxtreeGetEntryValue(self
.item2key
[item
])
777 def ListboxChoiceWindow(screen
, title
, text
, items
,
778 buttons
= ('Ok', 'Cancel'),
779 width
= 40, scroll
= 0, height
= -1, default
= None,
782 - ListboxChoiceWindow(screen, title, text, items,
783 buttons = ('Ok', 'Cancel'),
784 width = 40, scroll = 0, height = -1, default = None,
787 if (height
== -1): height
= len(items
)
789 bb
= ButtonBar(screen
, buttons
)
790 t
= TextboxReflowed(width
, text
)
791 l
= Listbox(height
, scroll
= scroll
, returnExit
= 1)
794 if type(item
) == tuple:
800 if (default
== count
):
802 elif (default
== item
):
808 if (default
!= None):
809 l
.setCurrent (default
)
811 g
= GridFormHelp(screen
, title
, help, 1, 3)
813 g
.add(l
, 0, 1, padding
= (0, 1, 0, 1))
814 g
.add(bb
, 0, 2, growx
= 1)
818 return (bb
.buttonPressed(rc
), l
.current())
820 def ButtonChoiceWindow(screen
, title
, text
,
821 buttons
= [ 'Ok', 'Cancel' ],
822 width
= 40, x
= None, y
= None, help = None):
824 - ButtonChoiceWindow(screen, title, text,
825 buttons = [ 'Ok', 'Cancel' ],
826 width = 40, x = None, y = None, help = None):
828 bb
= ButtonBar(screen
, buttons
)
829 t
= TextboxReflowed(width
, text
, maxHeight
= screen
.height
- 12)
831 g
= GridFormHelp(screen
, title
, help, 1, 2)
832 g
.add(t
, 0, 0, padding
= (0, 0, 0, 1))
833 g
.add(bb
, 0, 1, growx
= 1)
834 return bb
.buttonPressed(g
.runOnce(x
, y
))
836 def EntryWindow(screen
, title
, text
, prompts
, allowCancel
= 1, width
= 40,
837 entryWidth
= 20, buttons
= [ 'Ok', 'Cancel' ], help = None):
839 EntryWindow(screen, title, text, prompts, allowCancel = 1, width = 40,
840 entryWidth = 20, buttons = [ 'Ok', 'Cancel' ], help = None):
842 bb
= ButtonBar(screen
, buttons
);
843 t
= TextboxReflowed(width
, text
)
856 if isinstance(e
, str if sys
.version
>= '3' else basestring
):
857 e
= Entry(entryWidth
, e
)
859 e
= Entry(entryWidth
)
861 sg
.setField(Label(n
), 0, count
, padding
= (0, 0, 1, 0), anchorLeft
= 1)
862 sg
.setField(e
, 1, count
, anchorLeft
= 1)
866 g
= GridFormHelp(screen
, title
, help, 1, 3)
868 g
.add(t
, 0, 0, padding
= (0, 0, 0, 1))
869 g
.add(sg
, 0, 1, padding
= (0, 0, 0, 1))
870 g
.add(bb
, 0, 2, growx
= 1)
877 entryValues
.append(entryList
[count
].value())
880 return (bb
.buttonPressed(result
), tuple(entryValues
))
882 class CListbox(Grid
):
883 """Clistbox convenience class.
887 - Clistbox(self, height, cols, cols_widths, scroll = 0) : constructor
888 - colFormText(self, col_text, align = None, adjust_width = 0) : column text.
889 - append(self, col_text, item, col_text_align = None) :
890 - insert(self, col_text, item, before, col_text_align = None)
892 - replace(self, col_text, item, col_text_align = None)
893 - current(self) : returns current item
894 - setCurrent(self, item): sets an item as current
895 - clear(self): clear the listbox
897 Alignments may be LEFT, RIGHT, CENTER, None
899 def __init__(self
, height
, cols
, col_widths
, scroll
= 0,
900 returnExit
= 0, width
= 0, col_pad
= 1,
901 col_text_align
= None, col_labels
= None,
902 col_label_align
= None, adjust_width
=0):
905 self
.col_widths
= col_widths
[:]
906 self
.col_pad
= col_pad
907 self
.col_text_align
= col_text_align
909 if col_labels
!= None:
910 Grid
.__init
__(self
, 1, 2)
913 lstr
= self
.colFormText(col_labels
, col_label_align
,
914 adjust_width
=adjust_width
)
915 self
.label
= Label(lstr
)
916 self
.setField(self
.label
, 0, 0, anchorLeft
=1)
919 Grid
.__init
__(self
, 1, 1)
923 self
.listbox
= Listbox(height
, scroll
, returnExit
, width
)
924 self
.setField(self
.listbox
, 0, box_y
, anchorRight
=1)
926 def colFormText(self
, col_text
, align
= None, adjust_width
=0):
929 c_len
= len(col_text
)
930 while (i
< self
.cols
) and (i
< c_len
):
933 cstrlen
= _snack
.wstrlen(cstr
)
934 if self
.col_widths
[i
] < cstrlen
:
936 self
.col_widths
[i
] = cstrlen
938 cstr
= cstr
[:self
.col_widths
[i
]]
940 delta
= self
.col_widths
[i
] - _snack
.wstrlen(cstr
)
949 cstr
= cstr
+ (" " * delta
)
951 cstr
= (" " * (delta
/ 2)) + cstr
+ \
952 (" " * ((delta
+ 1) / 2))
954 cstr
= (" " * delta
) + cstr
957 pstr
= (" " * self
.col_pad
)
961 str = str + cstr
+ pstr
967 def append(self
, col_text
, item
, col_text_align
= None):
968 if col_text_align
== None:
969 col_text_align
= self
.col_text_align
970 text
= self
.colFormText(col_text
, col_text_align
)
971 self
.listbox
.append(text
, item
)
973 def insert(self
, col_text
, item
, before
, col_text_align
= None):
974 if col_text_align
== None:
975 col_text_align
= self
.col_text_align
976 text
= self
.colFormText(col_text
, col_text_align
)
977 self
.listbox
.insert(text
, item
, before
)
979 def delete(self
, item
):
980 self
.listbox
.delete(item
)
982 def replace(self
, col_text
, item
, col_text_align
= None):
983 if col_text_align
== None:
984 col_text_align
= self
.col_text_align
985 text
= self
.colFormText(col_text
, col_text_align
)
986 self
.listbox
.replace(text
, item
)
989 return self
.listbox
.current()
991 def setCurrent(self
, item
):
992 self
.listbox
.setCurrent(item
)
997 def customColorset(x
):