1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 """Module containing a set of special GUI elements to be used in the relax wizards."""
24
25
26 import wx
27 import wx.lib.mixins.listctrl
28
29
30 from gui.input_elements.sequence import Sequence, Sequence_list_ctrl, Sequence_window
31 from gui.string_conv import int_to_gui
32 from lib.check_types import is_list, is_list_of_lists
33 from status import Status; status = Status()
34
35
37 """Wizard GUI element for the input of all types of 2D Python sequence objects.
38
39 The supported Python types include:
40 - list of floats
41 - list of integers
42 - list of strings
43 - tuple of floats
44 - tuple of integers
45 - tuple of strings
46 """
47
48 - def __init__(self, name=None, default=None, parent=None, sizer=None, element_type='default', seq_type=None, value_type=None, dim=None, min=0, max=1000, titles=None, desc=None, combo_choices=None, combo_data=None, combo_list_min=None, tooltip=None, divider=None, padding=0, spacer=None, height_element=27, read_only=False, can_be_none=False):
49 """Set up the element.
50
51 @keyword name: The name of the element to use in titles, etc.
52 @type name: str
53 @keyword default: The default value of the element.
54 @type default: 2D sequence object
55 @keyword parent: The wizard GUI element.
56 @type parent: wx.Panel instance
57 @keyword sizer: The sizer to put the input field widget into.
58 @type sizer: wx.Sizer instance
59 @keyword element_type: The type of GUI element to create. If set to 'default', the wx.TextCtrl element with a button to bring up a dialog with ListCtrl will be used. If set to 'combo_list', the special gui.components.combo_list.Combo_list element will be used.
60 @type element_type: str
61 @keyword seq_type: The type of Python sequence. This should be one of 'list' or 'tuple'.
62 @type seq_type: str
63 @keyword value_type: The type of Python object that the value should be. This can be one of 'float', 'int', or 'str'.
64 @type value_type: str
65 @keyword dim: The dimensions that a list or tuple must conform to. For a 1D sequence, this can be a single value or a tuple of possible sizes. For a 2D sequence (a numpy matrix or list of lists), this must be a tuple of the fixed dimension sizes, e.g. a 3x5 matrix should be specified as (3, 5).
66 @type dim: int, tuple of int or None
67 @keyword min: For a SpinCtrl, the minimum value allowed.
68 @type min: int
69 @keyword max: For a SpinCtrl, the maximum value allowed.
70 @type max: int
71 @keyword titles: The titles of each of the elements of the fixed width second dimension.
72 @type titles: list of str
73 @keyword desc: The text description.
74 @type desc: str
75 @keyword combo_choices: The list of choices to present to the user. This is only used if the element_type is set to 'combo'.
76 @type combo_choices: list of str
77 @keyword combo_data: The data returned by a call to GetValue(). This is only used if the element_type is set to 'combo'. If supplied, it should be the same length at the combo_choices list. If not supplied, the combo_choices list will be used for the returned data.
78 @type combo_data: list
79 @keyword combo_list_min: The minimum length for the Combo_list object.
80 @type combo_list_min: int or None
81 @keyword tooltip: The tooltip which appears on hovering over the text or input field.
82 @type tooltip: str
83 @keyword divider: The optional position of the divider. If None, the class variable _div_left will be used.
84 @type divider: None or int
85 @keyword padding: Spacing to the left and right of the widgets.
86 @type padding: int
87 @keyword spacer: The amount of spacing to add below the field in pixels. If None, a stretchable spacer will be used.
88 @type spacer: None or int
89 @keyword height_element: The height in pixels of the GUI element.
90 @type height_element: int
91 @keyword read_only: A flag which if True means that the text of the element cannot be edited.
92 @type read_only: bool
93 @keyword can_be_none: A flag which specifies if the element is allowed to have the None value.
94 @type can_be_none: bool
95 """
96
97
98 self.titles = titles
99
100
101 Sequence.__init__(self, name=name, default=default, parent=parent, sizer=sizer, element_type=element_type, seq_type=seq_type, value_type=value_type, dim=dim, min=min, max=max, titles=titles, desc=desc, combo_choices=combo_choices, combo_data=combo_data, combo_list_min=combo_list_min, tooltip=tooltip, divider=divider, padding=padding, spacer=spacer, height_element=height_element, read_only=read_only, can_be_none=can_be_none)
102
103
105 """Open a special dialog for inputting a list of text values.
106
107 @param event: The wx event.
108 @type event: wx event
109 """
110
111
112 self.selection_win_show()
113
114
115 self.selection_win_data()
116
117
118 self.sel_win.Destroy()
119 del self.sel_win
120
121
123 """Show the selection window."""
124
125
126 if hasattr(self, 'sel_win'):
127 self.sel_win.Destroy()
128 del self.sel_win
129
130
131 self.sel_win = Sequence_window_2D(name=self.name, seq_type=self.seq_type, value_type=self.value_type, titles=self.titles, dim=self.dim)
132
133
134 self.sel_win.SetValue(self.GetValue())
135
136
137 if status.show_gui:
138 self.sel_win.ShowModal()
139 self.sel_win.Close()
140
141
142
144 """The Python 2D sequence object editor window."""
145
146 - def __init__(self, name='', seq_type='list', value_type='str', dim=None, titles=None):
147 """Set up the string list editor window.
148
149 @keyword name: The name of the window.
150 @type name: str
151 @keyword seq_type: The type of Python sequence. This should be one of 'list' or 'tuple'.
152 @type seq_type: str
153 @keyword value_type: The type of Python data expected in the sequence. This should be one of 'float', 'int', or 'str'.
154 @type value_type: str
155 @keyword dim: The fixed dimensions that the sequence must conform to.
156 @type dim: tuple of int or None
157 @keyword titles: The titles of each of the elements of the fixed width second dimension. If the dim argument is given, the length of this list must match the second number.
158 @type titles: list of str
159 """
160
161
162 self.titles = titles
163 if titles == None:
164 if dim == None:
165 self.titles = [wx.EmptyString]
166 else:
167 self.titles = [wx.EmptyString] * dim[1]
168
169
170 if dim == None:
171 dim = (None, len(self.titles))
172
173
174 self.variable_length = False
175 self.offset = 0
176 if dim[0] == None:
177 self.variable_length = True
178 self.offset = 1
179
180
181 Sequence_window.__init__(self, name=name, seq_type=seq_type, value_type=value_type, dim=dim, titles=self.titles)
182
183
185 """Return the values as a 2D sequence of values.
186
187 @return: The list of lists of values.
188 @rtype: list of lists of str or None
189 """
190
191
192 values = []
193
194
195 for i in range(self.sequence.GetItemCount()):
196
197 values.append([])
198
199
200 for j in range(self.dim[1]):
201
202 item = self.sequence.GetItem(i, j+self.offset)
203
204
205 try:
206 value = self.convert_from_gui(item.GetText())
207 except:
208 value = None
209 values[-1].append(value)
210
211
212 if self.seq_type == 'tuple':
213 values[-1] = tuple(values[-1])
214
215
216 if self.seq_type == 'tuple':
217 values = tuple(values)
218
219
220 empty = True
221 for i in range(len(values)):
222 for j in range(len(values[i])):
223 if values[i][j] != None:
224 empty = False
225 break
226
227
228 if empty:
229 return None
230
231
232 return values
233
234
236 """Set up the list of lists values.
237
238 @param values: The list of lists of values to add to the list.
239 @type values: list of lists of str or None
240 """
241
242
243 if values == None:
244 return
245
246
247 if is_list_of_lists(values):
248 pass
249 elif is_list(values):
250 values = [values]
251
252
253 if not is_list_of_lists(values):
254 return
255
256
257 if self.dim[0] != None and len(values) != self.dim[0]:
258 return
259
260
261 for i in range(len(values)):
262
263 if self.dim[1] != None and len(values[i]) != self.dim[1]:
264 continue
265
266
267 if self.variable_length and i != 0:
268 self.sequence.InsertStringItem(i, int_to_gui(i+1))
269
270
271 for j in range(self.dim[1]):
272
273 self.sequence.SetStringItem(i, j+self.offset, self.convert_to_gui(values[i][j]))
274
275
276 self.Refresh()
277
278
280 """Set up the list control.
281
282 @param sizer: A sizer object.
283 @type sizer: wx.Sizer instance
284 """
285
286
287 self.sequence = Sequence_list_ctrl(self)
288
289
290 title = "%s%s" % (self.name[0].upper(), self.name[1:])
291
292
293 index_width = 0
294 if self.variable_length:
295 index_width = 70
296 self.sequence.InsertColumn(0, "Number")
297 self.sequence.SetColumnWidth(0, index_width)
298
299
300 for i in range(self.dim[1]):
301 self.sequence.InsertColumn(i+self.offset, self.titles[i])
302 self.sequence.SetColumnWidth(i+self.offset, (self.width - index_width)/self.dim[1])
303
304
305 sizer.Add(self.sequence, 1, wx.ALL|wx.EXPAND, 0)
306
307
308 if not self.variable_length:
309 for i in range(self.dim[0]):
310 self.add_element(None)
311