1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160
|
"""
"""
import traceback
from .const import *
from .button import Button
from .basic import Label, Image
from .table import Table
class Select(Table):
"""A combo dropdown box widget.
Example:
w = Select(value="goats")
w.add("Cats","cats")
w.add("Goats","goats")
w.add("Dogs","Dogs")
w.value = 'dogs' #changes the value from goats to dogs
"""
# The drop-down arrow button for the selection widget
top_arrow = None
# A button displaying the currently selected item
top_selection = None
# The first option added to the selector
firstOption = None
# The PGU table of options
options = None
_value = None
def __init__(self,value=None,**params):
params.setdefault('cls','select')
Table.__init__(self,**params)
label = Label(" ",cls=self.cls+".option.label")
self.top_selected = Button(label, cls=self.cls+".selected")
Table.add(self,self.top_selected) #,hexpand=1,vexpand=1)#,0,0)
self.top_arrow = Button(Image(self.style.arrow), cls=self.cls+".arrow")
Table.add(self,self.top_arrow) #,hexpand=1,vexpand=1) #,1,0)
self.options = Table(cls=self.cls+".options")
self.options.connect(BLUR,self._close,None)
self.options.name = "pulldown-table"
self.values = []
self.value = value
def resize(self,width=None,height=None):
max_w,max_h = 0,0
for w in self.options.widgets:
w.rect.w,w.rect.h = w.resize()
max_w,max_h = max(max_w,w.rect.w),max(max_h,w.rect.h)
#xt,xr,xb,xl = self.top_selected.getspacing()
self.top_selected.style.width = max_w #+ xl + xr
self.top_selected.style.height = max_h #+ xt + xb
self.top_arrow.connect(CLICK,self._open,None)
self.top_selected.connect(CLICK,self._open,None)
w,h = Table.resize(self,width,height)
self.options.style.width = w
#HACK: sort of, but not a big one..
self.options.resize()
return w,h
def _open(self,value):
opts = self.options
opts.rect.w, opts.rect.h = opts.resize()
# y = self.rect.y
# c = self.container
# while hasattr(c, 'container'):
# y += c.rect.y
# if (not c.container):
# break
# c = c.container
# if y + self.rect.h + opts.rect.h <= c.rect.h: #down
# dy = self.rect.y + self.rect.h
# else: #up
# dy = self.rect.y - self.rect.h
opts.rect.w, opts.rect.h = opts.resize()
# TODO - make sure there is enough space to open down
# ...
yp = self.rect.bottom-1
self.container.open(opts, self.rect.x, yp)
self.firstOption.focus()
# TODO - this is a hack
for opt in self.options.widgets:
opt.repaint()
def _close(self,value):
self.options.close()
self.top_selected.focus()
def _setvalue(self,value):
self.value = value._value
if self.container:
#self.chsize()
#HACK: improper use of resize()
#self.resize() #to recenter the new value, etc.
pass
# #self._resize()
self._close(None)
#self.repaint() #this will happen anyways
@property
def value(self):
return self._value
@value.setter
def value(self, val):
mywidget = None
for w in self.values:
if w._value == val:
mywidget = w
oldval = self._value
self._value = val
if (oldval != val):
self.send(CHANGE)
self.repaint()
if not mywidget:
mywidget = Label(" ",cls=self.cls+".option.label")
self.top_selected.value = mywidget
def add(self,w,value=None):
"""Add a widget and associated value to the dropdown box."""
if type(w) == str: w = Label(w,cls=self.cls+".option.label")
w.style.align = -1
btn = Button(w,cls=self.cls+".option")
btn.connect(CLICK,self._setvalue,w)
self.options.tr()
self.options.add(btn)
if (not self.firstOption):
self.firstOption = btn
if value != None: w._value = value
else: w._value = w
if self.value == w._value:
self.top_selected.value = w
self.values.append(w)
|