1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24 """GUI element for the user input of spin IDs."""
25
26
27 from copy import deepcopy
28 import wx
29
30
31 from generic_fns.mol_res_spin import id_string_doc
32 from relax_errors import RelaxError
33
34
35 from gui.fonts import font
36 from gui.string_conv import gui_to_str, str_to_gui
37
38
40 """GUI element for the input of spin ID strings."""
41
42 - def __init__(self, name=None, default=None, parent=None, element_type='default', sizer=None, desc="spin ID string", combo_choices=None, combo_data=None, tooltip=None, divider=None, padding=0, spacer=None, height_element=27, can_be_none=True):
43 """Set up the base spin ID element.
44
45 @keyword name: The name of the element to use in titles, etc.
46 @type name: str
47 @keyword default: The default value.
48 @type default: str or None
49 @keyword parent: The parent GUI element.
50 @type parent: wx.Panel instance
51 @keyword element_type: The type of GUI element to create. This currently only supports the 'default' type.
52 @type element_type: str
53 @keyword sizer: The sizer to put the input field widget into.
54 @type sizer: wx.Sizer instance
55 @keyword desc: The text description.
56 @type desc: str
57 @keyword combo_choices: The list of choices to present to the user.
58 @type combo_choices: list of str
59 @keyword combo_data: The data returned by a call to GetValue(). 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.
60 @type combo_data: list
61 @keyword tooltip: The tooltip which appears on hovering over the text or input field.
62 @type tooltip: str
63 @keyword choices: The list of choices to present to the user.
64 @type choices: list of str
65 @keyword divider: The optional position of the divider. If None, the class variable _div_left will be used.
66 @type divider: None or int
67 @keyword padding: Spacing to the left and right of the widgets.
68 @type padding: int
69 @keyword spacer: The amount of spacing to add below the field in pixels. If None, a stretchable spacer will be used.
70 @type spacer: None or int
71 @keyword height_element: The height in pixels of the GUI element.
72 @type height_element: int
73 @keyword can_be_none: A flag which specifies if the element is allowed to have the None value.
74 @type can_be_none: bool
75 """
76
77
78 types = ['default']
79 if element_type not in types:
80 raise RelaxError("The %s element type '%s' must be one of %s." % (name, element_type, types))
81
82
83 self.name = name
84 self.default = default
85 self.can_be_none = can_be_none
86
87
88 if combo_choices == None or combo_choices == []:
89 combo_choices = ['@N', '@C', '@H', '@O', '@P']
90
91
92 sub_sizer = wx.BoxSizer(wx.HORIZONTAL)
93
94
95 sub_sizer.AddSpacer(padding)
96
97
98 text = wx.StaticText(parent, -1, desc, style=wx.ALIGN_LEFT)
99 text.SetFont(font.normal)
100 sub_sizer.Add(text, 0, wx.LEFT|wx.ALIGN_CENTER_VERTICAL, 0)
101
102
103 if not divider:
104 raise RelaxError("The divider position has not been supplied.")
105
106
107 x, y = text.GetSize()
108 sub_sizer.AddSpacer((divider - x, 0))
109
110
111 style = wx.CB_DROPDOWN
112 self._field = wx.ComboBox(parent, -1, '', style=style)
113
114
115 self.UpdateChoices(combo_choices=combo_choices, combo_data=combo_data, combo_default=default)
116
117
118 self._field.SetMinSize((50, height_element))
119 self._field.SetFont(font.normal)
120 sub_sizer.Add(self._field, 1, wx.ADJUST_MINSIZE|wx.ALIGN_CENTER_VERTICAL, 0)
121
122
123 sub_sizer.AddSpacer(padding)
124
125
126 sizer.Add(sub_sizer, 1, wx.EXPAND|wx.ALL, 0)
127
128
129 if spacer == None:
130 sizer.AddStretchSpacer()
131 else:
132 sizer.AddSpacer(spacer)
133
134
135 if tooltip == None:
136 tooltip = ''
137
138
139 for type, element in id_string_doc.element_loop():
140 if type == 'paragraph':
141
142 tooltip += '\n\n'
143
144
145 tooltip += element
146
147
148 text.SetToolTipString(tooltip)
149 self._field.SetToolTipString(tooltip)
150
151
153 """Special method for clearing or resetting the GUI element."""
154
155
156 self._field.Clear()
157 self._field.SetValue('')
158
159
161 """Special method for returning the value of the GUI element.
162
163 @return: The spin ID value.
164 @rtype: str or None
165 """
166
167
168 sel_index = self._field.GetSelection()
169 if sel_index == wx.NOT_FOUND:
170 value = None
171 else:
172 value = gui_to_str(self._field.GetClientData(sel_index))
173
174
175 if value == None:
176 value = gui_to_str(self._field.GetValue())
177
178
179 return value
180
181
183 """Special method for setting the value of the GUI element.
184
185 @param value: The spin ID to set.
186 @type value: str or None
187 """
188
189
190 found = False
191 for i in range(self._field.GetCount()):
192 if self._field.GetClientData(i) == value:
193 self._field.SetSelection(i)
194 found = True
195 break
196
197
198 if not found:
199 self._field.SetSelection(wx.NOT_FOUND)
200 self._field.SetValue(str_to_gui(value))
201
202
203 - def UpdateChoices(self, combo_choices=None, combo_data=None, combo_default=None):
204 """Special wizard method for updating the list of choices in a ComboBox type element.
205
206 @keyword combo_choices: The list of choices to present to the user.
207 @type combo_choices: list of str
208 @keyword combo_data: The data returned by a call to GetValue(). 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.
209 @type combo_data: list
210 @keyword combo_default: The default value of the ComboBox. This is only used if the element_type is set to 'combo'.
211 @type combo_default: str or None
212 """
213
214
215 sel_index = self._field.GetSelection()
216 if sel_index == wx.NOT_FOUND:
217 sel = None
218 else:
219 sel = self._field.GetClientData(sel_index)
220
221
222 self.Clear()
223
224
225 if combo_data == None:
226 combo_data = deepcopy(combo_choices)
227
228
229 for i in range(len(combo_choices)):
230 self._field.Insert(str_to_gui(combo_choices[i]), i, combo_data[i])
231
232
233 if sel == None and combo_default != None:
234
235 if combo_default in combo_choices:
236 string = combo_default
237 set_sel = True
238 elif combo_default not in combo_data:
239 string = combo_default
240 set_sel = False
241 else:
242 string = combo_choices[combo_data.index(combo_default)]
243 set_sel = True
244
245
246 if set_sel:
247 self._field.SetStringSelection(string)
248
249
250 else:
251 self._field.SetValue(string)
252
253
254 else:
255 for j in range(self._field.GetCount()):
256 if self._field.GetClientData(j) == sel:
257 self._field.SetSelection(j)
258