##// END OF EJS Templates
value_names is read-only
MinRK -
Show More
@@ -1,113 +1,118
1 1 """SelectionWidget classes.
2 2
3 3 Represents an enumeration using a widget.
4 4 """
5 5 #-----------------------------------------------------------------------------
6 6 # Copyright (c) 2013, the IPython Development Team.
7 7 #
8 8 # Distributed under the terms of the Modified BSD License.
9 9 #
10 10 # The full license is in the file COPYING.txt, distributed with this software.
11 11 #-----------------------------------------------------------------------------
12 12
13 13 #-----------------------------------------------------------------------------
14 14 # Imports
15 15 #-----------------------------------------------------------------------------
16 16
17 17 from collections import OrderedDict
18 18 from threading import Lock
19 19
20 20 from .widget import DOMWidget
21 21 from IPython.utils.traitlets import Unicode, List, Bool, Any, Dict, TraitError
22 22 from IPython.utils.py3compat import unicode_type
23 23
24 24 #-----------------------------------------------------------------------------
25 25 # SelectionWidget
26 26 #-----------------------------------------------------------------------------
27 27 class _SelectionWidget(DOMWidget):
28 28 """Base class for Selection widgets
29 29
30 30 ``values`` can be specified as a list or dict. If given as a list,
31 31 it will be transformed to a dict of the form ``{str(value):value}``.
32 32 """
33 33
34 34 value = Any(help="Selected value")
35 35 values = Dict(help="""Dictionary of {name: value} the user can select.
36 36
37 37 The keys of this dictionary are the strings that will be displayed in the UI,
38 38 representing the actual Python choices.
39 39
40 40 The keys of this dictionary are also available as value_names.
41 41 """)
42 42 value_name = Unicode(help="The name of the selected value", sync=True)
43 value_names = List(Unicode, help="""List of names for each value.
43 value_names = List(Unicode, help="""Read-only list of names for each value.
44 44
45 45 If values is specified as a list, this is the string representation of each element.
46 46 Otherwise, it is the keys of the values dictionary.
47 47
48 48 These strings are used to display the choices in the front-end.""", sync=True)
49 49 disabled = Bool(False, help="Enable or disable user changes", sync=True)
50 50 description = Unicode(help="Description of the value this widget represents", sync=True)
51 51
52 52
53 53 def __init__(self, *args, **kwargs):
54 54 self.value_lock = Lock()
55 self._in_values_changed = False
55 56 if 'values' in kwargs:
56 57 values = kwargs['values']
57 58 # convert list values to an dict of {str(v):v}
58 59 if isinstance(values, list):
59 60 # preserve list order with an OrderedDict
60 61 kwargs['values'] = OrderedDict((unicode_type(v), v) for v in values)
61 62 DOMWidget.__init__(self, *args, **kwargs)
62 63
63 64 def _values_changed(self, name, old, new):
64 65 """Handles when the values dict has been changed.
65 66
66 67 Setting values implies setting value names from the keys of the dict.
67 68 """
68 self.value_names = list(new.keys())
69 self._in_values_changed = True
70 try:
71 self.value_names = list(new.keys())
72 finally:
73 self._in_values_changed = False
69 74
70 75 def _value_names_changed(self, name, old, new):
71 if len(new) != len(self.values):
72 raise TraitError("Expected %i value names, got %i." % (len(self.values), len(new)))
76 if not self._in_values_changed:
77 raise TraitError("value_names is a read-only proxy to values.keys(). Use the values dict instead.")
73 78
74 79 def _value_changed(self, name, old, new):
75 80 """Called when value has been changed"""
76 81 if self.value_lock.acquire(False):
77 82 try:
78 83 # Make sure the value is one of the options
79 84 for k,v in self.values.items():
80 85 if new == v:
81 86 # set the selected value name
82 87 self.value_name = k
83 88 return
84 89 raise TraitError('Value not found: %r' % new)
85 90 finally:
86 91 self.value_lock.release()
87 92
88 93 def _value_name_changed(self, name, old, new):
89 94 """Called when the value name has been changed (typically by the frontend)."""
90 95 if self.value_lock.acquire(False):
91 96 try:
92 97 if new in self.values:
93 98 self.value = self.values[new]
94 99 else:
95 100 self.value = None
96 101 finally:
97 102 self.value_lock.release()
98 103
99 104
100 105 class ToggleButtonsWidget(_SelectionWidget):
101 106 _view_name = Unicode('ToggleButtonsView', sync=True)
102 107
103 108
104 109 class DropdownWidget(_SelectionWidget):
105 110 _view_name = Unicode('DropdownView', sync=True)
106 111
107 112
108 113 class RadioButtonsWidget(_SelectionWidget):
109 114 _view_name = Unicode('RadioButtonsView', sync=True)
110 115
111 116
112 117 class SelectWidget(_SelectionWidget):
113 118 _view_name = Unicode('SelectView', sync=True)
General Comments 0
You need to be logged in to leave comments. Login now