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