1 /*  $Id: style_dialog.cpp 395498 2013-04-11 16:25:32Z thiessen $
2 * ===========================================================================
3 *
4 *                            PUBLIC DOMAIN NOTICE
5 *               National Center for Biotechnology Information
6 *
7 *  This software/database is a "United States Government Work" under the
8 *  terms of the United States Copyright Act.  It was written as part of
9 *  the author's official duties as a United States Government employee and
10 *  thus cannot be copyrighted.  This software/database is freely available
11 *  to the public for use. The National Library of Medicine and the U.S.
12 *  Government have not placed any restriction on its use or reproduction.
13 *
14 *  Although all reasonable efforts have been taken to ensure the accuracy
15 *  and reliability of the software and data, the NLM and the U.S.
16 *  Government do not and cannot warrant the performance or results that
17 *  may be obtained by using this software or data. The NLM and the U.S.
18 *  Government disclaim all warranties, express or implied, including
19 *  warranties of performance, merchantability or fitness for any particular
20 *  purpose.
21 *
22 *  Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Authors:  Paul Thiessen
27 *
28 * File Description:
29 *      dialog for setting styles
30 *
31 * ===========================================================================
32 */
33 
34 #include <ncbi_pch.hpp>
35 #include <corelib/ncbistd.hpp>
36 
37 #include "remove_header_conflicts.hpp"
38 
39 #include "style_dialog.hpp"
40 #include "style_manager.hpp"
41 #include "cn3d_tools.hpp"
42 #include "structure_set.hpp"
43 #include "messenger.hpp"
44 #include <algo/structure/wx_tools/wx_tools.hpp>
45 
46 #include <wx/colordlg.h>
47 
48 
49 ////////////////////////////////////////////////////////////////////////////////////////////////
50 // The following is taken unmodified from wxDesigner's C++ header from render_settings.wdr
51 ////////////////////////////////////////////////////////////////////////////////////////////////
52 
53 #include <wx/image.h>
54 #include <wx/statline.h>
55 #include <wx/spinbutt.h>
56 #include <wx/spinctrl.h>
57 #include <wx/splitter.h>
58 #include <wx/listctrl.h>
59 #include <wx/treectrl.h>
60 #include <wx/notebook.h>
61 
62 // Declare window functions
63 
64 #define ID_NOTEBOOK 10000
65 #define ID_DONE 10001
66 #define ID_CANCEL 10002
67 #define ID_TEXT 10003
68 #define ID_ALWAYS_APPLY 10004
69 #define ID_APPLY 10005
70 wxSizer *LayoutNotebook( wxPanel *parent, bool call_fit = TRUE, bool set_sizer = TRUE );
71 
72 #define ID_PBB_SHOW 10006
73 #define ID_PBB_RENDER 10007
74 #define ID_PBB_COLOR 10008
75 #define ID_PBB_USER 10009
76 #define ID_PSIDE_SHOW 10010
77 #define ID_PSIDE_RENDER 10011
78 #define ID_PSIDE_COLOR 10012
79 #define ID_PSIDE_USER 10013
80 #define ID_NUC_SHOW 10014
81 #define ID_NUC_RENDER 10015
82 #define ID_NUC_COLOR 10016
83 #define ID_NUC_USER 10017
84 #define ID_NSIDE_SHOW 10018
85 #define ID_NSIDE_RENDER 10019
86 #define ID_NSIDE_COLOR 10020
87 #define ID_NSIDE_USER 10021
88 #define ID_HET_SHOW 10022
89 #define ID_HET_RENDER 10023
90 #define ID_HET_COLOR 10024
91 #define ID_HET_USER 10025
92 #define ID_SOLV_SHOW 10026
93 #define ID_SOLV_RENDER 10027
94 #define ID_SOLV_COLOR 10028
95 #define ID_SOLV_USER 10029
96 #define ID_CONN_SHOW 10030
97 #define ID_CONN_RENDER 10031
98 #define ID_CONN_COLOR 10032
99 #define ID_CONN_USER 10033
100 #define ID_HELX_SHOW 10034
101 #define ID_HELX_RENDER 10035
102 #define ID_HELX_COLOR 10036
103 #define ID_HELX_USER 10037
104 #define ID_STRN_SHOW 10038
105 #define ID_STRN_RENDER 10039
106 #define ID_STRN_COLOR 10040
107 #define ID_STRN_USER 10041
108 #define ID_VSS_SHOW 10042
109 #define ID_VSS_USER 10043
110 #define ID_HYD_SHOW 10044
111 #define ID_BG_USER 10045
112 wxSizer *LayoutSettingsPage( wxPanel *parent, bool call_fit = TRUE, bool set_sizer = TRUE );
113 
114 #define ID_TEXTCTRL 10046
115 #define ID_SPINBUTTON 10047
116 wxSizer *LayoutDetailsPage( wxPanel *parent, bool call_fit = TRUE, bool set_sizer = TRUE );
117 
118 #define ID_S_PROT 10048
119 #define ID_S_NUC 10049
120 #define ID_C_PROT_TYPE 10050
121 #define ID_C_NUC_TYPE 10051
122 #define ID_C_PROT_NUM 10052
123 #define ID_C_NUC_NUM 10053
124 #define ID_K_PROT_CONTRAST 10054
125 #define ID_K_NUC_CONTRAST 10055
126 #define ID_K_PROT_TERM 10056
127 #define ID_K_NUC_TERM 10057
128 #define ID_LINE 10058
129 #define ID_K_ION 10059
130 wxSizer *LayoutLabelsPage( wxPanel *parent, bool call_fit = TRUE, bool set_sizer = TRUE );
131 
132 ////////////////////////////////////////////////////////////////////////////////////////////////
133 
134 USING_NCBI_SCOPE;
135 
136 // a bit of a kludge - but necessary to be able to use most of the wxDesigner code as is
137 static FloatingPointSpinCtrl *gfpSpaceFill, *gfpBallRadius, *gfpStickRadius, *gfpTubeRadius,
138     *gfpTubeWormRadius, *gfpHelixRadius, *gfpStrandWidth, *gfpStrandThickness;
139 
140 
141 BEGIN_SCOPE(Cn3D)
142 
143 TypeStringAssociator < StyleSettings::eBackboneType > StyleDialog::BackboneTypeStrings;
144 TypeStringAssociator < StyleSettings::eDrawingStyle > StyleDialog::DrawingStyleStrings;
145 TypeStringAssociator < StyleSettings::eColorScheme > StyleDialog::ColorSchemeStrings;
146 TypeStringAssociator < StyleSettings::eLabelType > StyleDialog::LabelTypeStrings;
147 TypeStringAssociator < StyleSettings::eNumberType > StyleDialog::NumberTypeStrings;
148 
BEGIN_EVENT_TABLE(StyleDialog,wxDialog)149 BEGIN_EVENT_TABLE(StyleDialog, wxDialog)
150     EVT_CLOSE       (       StyleDialog::OnCloseWindow)
151     EVT_CHOICE      (-1,    StyleDialog::OnChange)
152     EVT_CHECKBOX    (-1,    StyleDialog::OnChange)
153     EVT_SPINCTRL    (-1,    StyleDialog::OnSpin)
154     EVT_BUTTON      (-1,    StyleDialog::OnButton)
155     // generated when {Integer,FloatingPoint}SpinCtrl changes
156     EVT_COMMAND     (-1, WX_TOOLS_NOTIFY_CHANGED, StyleDialog::OnChange)
157 END_EVENT_TABLE()
158 
159 StyleDialog::StyleDialog(wxWindow* parent, StyleSettings *settingsToEdit, const StructureSet *set) :
160     wxDialog(parent, -1, "Style Options", wxPoint(400, 100), wxDefaultSize, wxDEFAULT_DIALOG_STYLE),
161     editedSettings(settingsToEdit), originalSettings(*settingsToEdit),
162     structureSet(set), changedSinceApply(false), changedEver(false), initialized(false)
163 {
164     // setup maps for associating style types with strings
165     SetupStyleStrings();
166 
167     // construct the panel
168     wxPanel *panel = new wxPanel(this, -1);
169     wxSizer *topSizer = LayoutNotebook(panel, false);
170 
171     // hook in the stuff that the wxDesigner-based code (LayoutPage2()) created
172     fpSpaceFill = gfpSpaceFill;
173     fpBallRadius = gfpBallRadius;
174     fpStickRadius = gfpStickRadius;
175     fpTubeRadius = gfpTubeRadius;
176     fpTubeWormRadius = gfpTubeWormRadius;
177     fpHelixRadius = gfpHelixRadius;
178     fpStrandWidth = gfpStrandWidth;
179     fpStrandThickness = gfpStrandThickness;
180 
181     // set defaults
182     SetControls(*editedSettings);
183 
184     // call sizer stuff
185     topSizer->Fit(this);
186     topSizer->Fit(panel);
187     topSizer->SetSizeHints(this);
188 
189     initialized = true;
190 }
191 
~StyleDialog(void)192 StyleDialog::~StyleDialog(void)
193 {
194     delete fpSpaceFill;
195     delete fpBallRadius;
196     delete fpStickRadius;
197     delete fpTubeRadius;
198     delete fpTubeWormRadius;
199     delete fpHelixRadius;
200     delete fpStrandWidth;
201     delete fpStrandThickness;
202 }
203 
SetupStyleStrings(void)204 void StyleDialog::SetupStyleStrings(void)
205 {
206     if (BackboneTypeStrings.Size() == 0) {
207 
208         BackboneTypeStrings.Associate(StyleSettings::eOff, "None");
209         BackboneTypeStrings.Associate(StyleSettings::eTrace, "Trace");
210         BackboneTypeStrings.Associate(StyleSettings::ePartial, "Partial");
211         BackboneTypeStrings.Associate(StyleSettings::eComplete, "Complete");
212 
213         DrawingStyleStrings.Associate(StyleSettings::eWire, "Wire");
214         DrawingStyleStrings.Associate(StyleSettings::eTubes, "Tubes");
215         DrawingStyleStrings.Associate(StyleSettings::eBallAndStick, "Ball and Stick");
216         DrawingStyleStrings.Associate(StyleSettings::eSpaceFill, "Space Fill");
217         DrawingStyleStrings.Associate(StyleSettings::eWireWorm, "Wire Worm");
218         DrawingStyleStrings.Associate(StyleSettings::eTubeWorm, "Tube Worm");
219         DrawingStyleStrings.Associate(StyleSettings::eWithArrows, "With Arrows");
220         DrawingStyleStrings.Associate(StyleSettings::eWithoutArrows, "Without Arrows");
221 
222         ColorSchemeStrings.Associate(StyleSettings::eElement, "Element");
223         ColorSchemeStrings.Associate(StyleSettings::eObject, "Object");
224         ColorSchemeStrings.Associate(StyleSettings::eMolecule, "Molecule");
225         ColorSchemeStrings.Associate(StyleSettings::eResidue, "Residue");
226         ColorSchemeStrings.Associate(StyleSettings::eDomain, "Domain");
227         ColorSchemeStrings.Associate(StyleSettings::eSecondaryStructure, "Secondary Structure");
228         ColorSchemeStrings.Associate(StyleSettings::eUserSelect, "User Selection");
229         ColorSchemeStrings.Associate(StyleSettings::eAligned, "Aligned");
230         ColorSchemeStrings.Associate(StyleSettings::eIdentity, "Identity");
231         ColorSchemeStrings.Associate(StyleSettings::eVariety, "Variety");
232         ColorSchemeStrings.Associate(StyleSettings::eWeightedVariety, "Weighted Variety");
233         ColorSchemeStrings.Associate(StyleSettings::eInformationContent, "Information Content");
234         ColorSchemeStrings.Associate(StyleSettings::eFit, "Fit");
235         ColorSchemeStrings.Associate(StyleSettings::eBlockFit, "Block Fit");
236         ColorSchemeStrings.Associate(StyleSettings::eBlockZFit, "Normalized Block Fit");
237         ColorSchemeStrings.Associate(StyleSettings::eBlockRowFit, "Block Row Fit");
238         ColorSchemeStrings.Associate(StyleSettings::eTemperature, "Temperature");
239         ColorSchemeStrings.Associate(StyleSettings::eHydrophobicity, "Hydrophobicity");
240         ColorSchemeStrings.Associate(StyleSettings::eRainbow, "Rainbow");
241         ColorSchemeStrings.Associate(StyleSettings::eCharge, "Charge");
242 
243         LabelTypeStrings.Associate(StyleSettings::eOneLetter, "One Letter");
244         LabelTypeStrings.Associate(StyleSettings::eThreeLetter, "Three Letter");
245 
246         NumberTypeStrings.Associate(StyleSettings::eNoNumbers, "None");
247         NumberTypeStrings.Associate(StyleSettings::eSequentialNumbering, "Sequential");
248         NumberTypeStrings.Associate(StyleSettings::ePDBNumbering, "From PDB");
249     }
250 }
251 
ConvertColor(const wxColour & wxcol,Vector * vec)252 static bool ConvertColor(const wxColour& wxcol, Vector *vec)
253 {
254     vec->Set(((double) wxcol.Red())/255.0, ((double) wxcol.Green())/255.0, ((double) wxcol.Blue())/255.0);
255     return true;
256 }
257 
GetBackboneStyle(StyleSettings::BackboneStyle * bbStyle,int showID,int renderID,int colorID,int userID)258 bool StyleDialog::GetBackboneStyle(StyleSettings::BackboneStyle *bbStyle,
259     int showID, int renderID, int colorID, int userID)
260 {
261     wxChoice *choice;
262     wxButton *button;
263     return (
264         (choice = wxDynamicCast(FindWindow(showID), wxChoice)) != NULL &&
265         BackboneTypeStrings.Get(WX_TO_STD(choice->GetStringSelection()), &(bbStyle->type)) &&
266         (choice = wxDynamicCast(FindWindow(renderID), wxChoice)) != NULL &&
267         DrawingStyleStrings.Get(WX_TO_STD(choice->GetStringSelection()), &(bbStyle->style)) &&
268         (choice = wxDynamicCast(FindWindow(colorID), wxChoice)) != NULL &&
269         ColorSchemeStrings.Get(WX_TO_STD(choice->GetStringSelection()), &(bbStyle->colorScheme)) &&
270         (button = wxDynamicCast(FindWindow(userID), wxButton)) != NULL &&
271         ConvertColor(button->GetBackgroundColour(), &(bbStyle->userColor))
272     );
273 }
274 
GetChecked(wxCheckBox * checkbox,bool * isChecked)275 static bool GetChecked(wxCheckBox *checkbox, bool *isChecked)
276 {
277     if (!checkbox) return false;
278     *isChecked = checkbox->GetValue();
279     return true;
280 }
281 
GetGeneralStyle(StyleSettings::GeneralStyle * gStyle,int showID,int renderID,int colorID,int userID)282 bool StyleDialog::GetGeneralStyle(StyleSettings::GeneralStyle *gStyle,
283     int showID, int renderID, int colorID, int userID)
284 {
285     wxCheckBox *checkbox;
286     wxChoice *choice;
287     wxButton *button;
288     return (
289         (checkbox = wxDynamicCast(FindWindow(showID), wxCheckBox)) != NULL &&
290         GetChecked(checkbox, &(gStyle->isOn)) &&
291         (choice = wxDynamicCast(FindWindow(renderID), wxChoice)) != NULL &&
292         DrawingStyleStrings.Get(WX_TO_STD(choice->GetStringSelection()), &(gStyle->style)) &&
293         (choice = wxDynamicCast(FindWindow(colorID), wxChoice)) != NULL &&
294         ColorSchemeStrings.Get(WX_TO_STD(choice->GetStringSelection()), &(gStyle->colorScheme)) &&
295         (button = wxDynamicCast(FindWindow(userID), wxButton)) != NULL &&
296         ConvertColor(button->GetBackgroundColour(), &(gStyle->userColor))
297     );
298 }
299 
GetInteger(wxSpinCtrl * spinctrl,int * value)300 static bool GetInteger(wxSpinCtrl *spinctrl, int *value)
301 {
302     if (!spinctrl) return false;
303     *value = spinctrl->GetValue();
304     return true;
305 }
306 
GetLabelStyle(StyleSettings::LabelStyle * lStyle,int spacingID,int typeID,int numberingID,int terminiID,int whiteID)307 bool StyleDialog::GetLabelStyle(StyleSettings::LabelStyle *lStyle,
308     int spacingID, int typeID, int numberingID, int terminiID, int whiteID)
309 {
310     wxSpinCtrl *spinctrl;
311     wxChoice *choice;
312     wxCheckBox *checkbox;
313     return (
314         (spinctrl = wxDynamicCast(FindWindow(spacingID), wxSpinCtrl)) != NULL &&
315         GetInteger(spinctrl, &(lStyle->spacing)) &&
316         (choice = wxDynamicCast(FindWindow(typeID), wxChoice)) != NULL &&
317         LabelTypeStrings.Get(WX_TO_STD(choice->GetStringSelection()), &(lStyle->type)) &&
318         (choice = wxDynamicCast(FindWindow(numberingID), wxChoice)) != NULL &&
319         NumberTypeStrings.Get(WX_TO_STD(choice->GetStringSelection()), &(lStyle->numbering)) &&
320         (checkbox = wxDynamicCast(FindWindow(terminiID), wxCheckBox)) != NULL &&
321         GetChecked(checkbox, &(lStyle->terminiOn)) &&
322         (checkbox = wxDynamicCast(FindWindow(whiteID), wxCheckBox)) != NULL &&
323         GetChecked(checkbox, &(lStyle->white))
324     );
325 }
326 
GetValues(StyleSettings * settings)327 bool StyleDialog::GetValues(StyleSettings *settings)
328 {
329     wxCheckBox *checkbox;
330     wxButton *button;
331     bool okay = (
332         settings != NULL &&
333         GetBackboneStyle(&(settings->proteinBackbone),
334             ID_PBB_SHOW, ID_PBB_RENDER, ID_PBB_COLOR, ID_PBB_USER) &&
335         GetGeneralStyle(&(settings->proteinSidechains),
336             ID_PSIDE_SHOW, ID_PSIDE_RENDER, ID_PSIDE_COLOR, ID_PSIDE_USER) &&
337         GetBackboneStyle(&(settings->nucleotideBackbone),
338             ID_NUC_SHOW, ID_NUC_RENDER, ID_NUC_COLOR, ID_NUC_USER) &&
339         GetGeneralStyle(&(settings->nucleotideSidechains),
340             ID_NSIDE_SHOW, ID_NSIDE_RENDER, ID_NSIDE_COLOR, ID_NSIDE_USER) &&
341         GetGeneralStyle(&(settings->heterogens),
342             ID_HET_SHOW, ID_HET_RENDER, ID_HET_COLOR, ID_HET_USER) &&
343         GetGeneralStyle(&(settings->solvents),
344             ID_SOLV_SHOW, ID_SOLV_RENDER, ID_SOLV_COLOR, ID_SOLV_USER) &&
345         GetGeneralStyle(&(settings->connections),
346             ID_CONN_SHOW, ID_CONN_RENDER, ID_CONN_COLOR, ID_CONN_USER) &&
347         GetGeneralStyle(&(settings->helixObjects),
348             ID_HELX_SHOW, ID_HELX_RENDER, ID_HELX_COLOR, ID_HELX_USER) &&
349         GetGeneralStyle(&(settings->strandObjects),
350             ID_STRN_SHOW, ID_STRN_RENDER, ID_STRN_COLOR, ID_STRN_USER) &&
351         (checkbox = wxDynamicCast(FindWindow(ID_VSS_SHOW), wxCheckBox)) != NULL &&
352         GetChecked(checkbox, &(settings->virtualDisulfidesOn)) &&
353         (button = wxDynamicCast(FindWindow(ID_VSS_USER), wxButton)) != NULL &&
354         ConvertColor(button->GetBackgroundColour(), &(settings->virtualDisulfideColor)) &&
355         (checkbox = wxDynamicCast(FindWindow(ID_HYD_SHOW), wxCheckBox)) != NULL &&
356         GetChecked(checkbox, &(settings->hydrogensOn)) &&
357         (button = wxDynamicCast(FindWindow(ID_BG_USER), wxButton)) != NULL &&
358         ConvertColor(button->GetBackgroundColour(), &(settings->backgroundColor)) &&
359         fpSpaceFill->GetDouble(&(settings->spaceFillProportion)) &&
360         fpBallRadius->GetDouble(&(settings->ballRadius)) &&
361         fpStickRadius->GetDouble(&(settings->stickRadius)) &&
362         fpTubeRadius->GetDouble(&(settings->tubeRadius)) &&
363         fpTubeWormRadius->GetDouble(&(settings->tubeWormRadius)) &&
364         fpHelixRadius->GetDouble(&(settings->helixRadius)) &&
365         fpStrandWidth->GetDouble(&(settings->strandWidth)) &&
366         fpStrandThickness->GetDouble(&(settings->strandThickness)) &&
367         GetLabelStyle(&(settings->proteinLabels),
368             ID_S_PROT, ID_C_PROT_TYPE, ID_C_PROT_NUM, ID_K_PROT_TERM, ID_K_PROT_CONTRAST) &&
369         GetLabelStyle(&(settings->nucleotideLabels),
370             ID_S_NUC, ID_C_NUC_TYPE, ID_C_NUC_NUM, ID_K_NUC_TERM, ID_K_NUC_CONTRAST) &&
371         (checkbox = wxDynamicCast(FindWindow(ID_K_ION), wxCheckBox)) != NULL &&
372         GetChecked(checkbox, &(settings->ionLabelsOn))
373     );
374     if (!okay) ERRORMSG("StyleDialog::GetValues() - control/parameter mismatch: invalid style?");
375     return okay;
376 }
377 
SetChoiceToString(wxChoice * choice,const string & name)378 static bool SetChoiceToString(wxChoice *choice, const string& name)
379 {
380     int field = choice->FindString(name.c_str());
381     if (field < 0) return false;
382     choice->SetSelection(field);
383     return true;
384 }
385 
SetButtonColor(wxButton * button,const Vector & color)386 static bool SetButtonColor(wxButton *button, const Vector& color)
387 {
388     if (!button) return false;
389     wxColour wxcol(
390         static_cast<unsigned char>((color[0] + 0.000001) * 255),
391         static_cast<unsigned char>((color[1] + 0.000001) * 255),
392         static_cast<unsigned char>((color[2] + 0.000001) * 255)
393     );
394     // set both foreground and background colors, so that if e.g. on wxGTK themes are
395     // used (and thus backgrounds are not user-selectable), at least the text (foreground)
396     // color will indicate the user's color choice
397     button->SetForegroundColour(wxcol);
398     button->SetBackgroundColour(wxcol);
399     return true;
400 }
401 
SetBackboneStyle(const StyleSettings::BackboneStyle & bbStyle,int showID,int renderID,int colorID,int userID)402 bool StyleDialog::SetBackboneStyle(const StyleSettings::BackboneStyle& bbStyle,
403     int showID, int renderID, int colorID, int userID)
404 {
405     string name;
406     wxChoice *choice;
407     wxButton *button;
408     return (
409         BackboneTypeStrings.Get(bbStyle.type, &name) &&
410         (choice = wxDynamicCast(FindWindow(showID), wxChoice)) != NULL &&
411         SetChoiceToString(choice, name) &&
412         DrawingStyleStrings.Get(bbStyle.style, &name) &&
413         (choice = wxDynamicCast(FindWindow(renderID), wxChoice)) != NULL &&
414         SetChoiceToString(choice, name) &&
415         ColorSchemeStrings.Get(bbStyle.colorScheme, &name) &&
416         (choice = wxDynamicCast(FindWindow(colorID), wxChoice)) != NULL &&
417         SetChoiceToString(choice, name) &&
418         (button = wxDynamicCast(FindWindow(userID), wxButton)) != NULL &&
419         SetButtonColor(button, bbStyle.userColor)
420     );
421 }
422 
SetChecked(wxCheckBox * checkbox,bool isChecked)423 static bool SetChecked(wxCheckBox *checkbox, bool isChecked)
424 {
425     if (!checkbox) return false;
426     checkbox->SetValue(isChecked);
427     return true;
428 }
429 
SetGeneralStyle(const StyleSettings::GeneralStyle & gStyle,int showID,int renderID,int colorID,int userID)430 bool StyleDialog::SetGeneralStyle(const StyleSettings::GeneralStyle& gStyle,
431     int showID, int renderID, int colorID, int userID)
432 {
433     string name;
434     wxCheckBox *checkbox;
435     wxChoice *choice;
436     wxButton *button;
437     return (
438         (checkbox = wxDynamicCast(FindWindow(showID), wxCheckBox)) != NULL &&
439         SetChecked(checkbox, gStyle.isOn) &&
440         DrawingStyleStrings.Get(gStyle.style, &name) &&
441         (choice = wxDynamicCast(FindWindow(renderID), wxChoice)) != NULL &&
442         SetChoiceToString(choice, name) &&
443         ColorSchemeStrings.Get(gStyle.colorScheme, &name) &&
444         (choice = wxDynamicCast(FindWindow(colorID), wxChoice)) != NULL &&
445         SetChoiceToString(choice, name) &&
446         (button = wxDynamicCast(FindWindow(userID), wxButton)) != NULL &&
447         SetButtonColor(button, gStyle.userColor)
448     );
449 }
450 
SetInteger(wxSpinCtrl * spinctrl,int value)451 static bool SetInteger(wxSpinCtrl *spinctrl, int value)
452 {
453     if (!spinctrl) return false;
454     spinctrl->SetValue(value);
455     return true;
456 }
457 
SetLabelStyle(const StyleSettings::LabelStyle & lStyle,int spacingID,int typeID,int numberingID,int terminiID,int whiteID)458 bool StyleDialog::SetLabelStyle(const StyleSettings::LabelStyle& lStyle,
459     int spacingID, int typeID, int numberingID, int terminiID, int whiteID)
460 {
461     string name;
462     wxSpinCtrl *spinctrl;
463     wxCheckBox *checkbox;
464     wxChoice *choice;
465     return (
466         (spinctrl = wxDynamicCast(FindWindow(spacingID), wxSpinCtrl)) != NULL &&
467         SetInteger(spinctrl, lStyle.spacing) &&
468         LabelTypeStrings.Get(lStyle.type, &name) &&
469         (choice = wxDynamicCast(FindWindow(typeID), wxChoice)) != NULL &&
470         SetChoiceToString(choice, name) &&
471         NumberTypeStrings.Get(lStyle.numbering, &name) &&
472         (choice = wxDynamicCast(FindWindow(numberingID), wxChoice)) != NULL &&
473         SetChoiceToString(choice, name) &&
474         (checkbox = wxDynamicCast(FindWindow(terminiID), wxCheckBox)) != NULL &&
475         SetChecked(checkbox, lStyle.terminiOn) &&
476         (checkbox = wxDynamicCast(FindWindow(whiteID), wxCheckBox)) != NULL &&
477         SetChecked(checkbox, lStyle.white)
478     );
479 }
480 
SetControls(const StyleSettings & settings)481 bool StyleDialog::SetControls(const StyleSettings& settings)
482 {
483     wxCheckBox *checkbox;
484     wxButton *button;
485     bool okay = (
486         SetBackboneStyle(settings.proteinBackbone,
487             ID_PBB_SHOW, ID_PBB_RENDER, ID_PBB_COLOR, ID_PBB_USER) &&
488         SetGeneralStyle(settings.proteinSidechains,
489             ID_PSIDE_SHOW, ID_PSIDE_RENDER, ID_PSIDE_COLOR, ID_PSIDE_USER) &&
490         SetBackboneStyle(settings.nucleotideBackbone,
491             ID_NUC_SHOW, ID_NUC_RENDER, ID_NUC_COLOR, ID_NUC_USER) &&
492         SetGeneralStyle(settings.nucleotideSidechains,
493             ID_NSIDE_SHOW, ID_NSIDE_RENDER, ID_NSIDE_COLOR, ID_NSIDE_USER) &&
494         SetGeneralStyle(settings.heterogens,
495             ID_HET_SHOW, ID_HET_RENDER, ID_HET_COLOR, ID_HET_USER) &&
496         SetGeneralStyle(settings.solvents,
497             ID_SOLV_SHOW, ID_SOLV_RENDER, ID_SOLV_COLOR, ID_SOLV_USER) &&
498         SetGeneralStyle(settings.connections,
499             ID_CONN_SHOW, ID_CONN_RENDER, ID_CONN_COLOR, ID_CONN_USER) &&
500         SetGeneralStyle(settings.helixObjects,
501             ID_HELX_SHOW, ID_HELX_RENDER, ID_HELX_COLOR, ID_HELX_USER) &&
502         SetGeneralStyle(settings.strandObjects,
503             ID_STRN_SHOW, ID_STRN_RENDER, ID_STRN_COLOR, ID_STRN_USER) &&
504         (checkbox = wxDynamicCast(FindWindow(ID_VSS_SHOW), wxCheckBox)) != NULL &&
505         SetChecked(checkbox, settings.virtualDisulfidesOn) &&
506         (button = wxDynamicCast(FindWindow(ID_VSS_USER), wxButton)) != NULL &&
507         SetButtonColor(button, settings.virtualDisulfideColor) &&
508         (checkbox = wxDynamicCast(FindWindow(ID_HYD_SHOW), wxCheckBox)) != NULL &&
509         SetChecked(checkbox, settings.hydrogensOn) &&
510         (button = wxDynamicCast(FindWindow(ID_BG_USER), wxButton)) != NULL &&
511         SetButtonColor(button, settings.backgroundColor) &&
512         fpSpaceFill->SetDouble(settings.spaceFillProportion) &&
513         fpBallRadius->SetDouble(settings.ballRadius) &&
514         fpStickRadius->SetDouble(settings.stickRadius) &&
515         fpTubeRadius->SetDouble(settings.tubeRadius) &&
516         fpTubeWormRadius->SetDouble(settings.tubeWormRadius) &&
517         fpHelixRadius->SetDouble(settings.helixRadius) &&
518         fpStrandWidth->SetDouble(settings.strandWidth) &&
519         fpStrandThickness->SetDouble(settings.strandThickness) &&
520         SetLabelStyle(settings.proteinLabels,
521             ID_S_PROT, ID_C_PROT_TYPE, ID_C_PROT_NUM, ID_K_PROT_TERM, ID_K_PROT_CONTRAST) &&
522         SetLabelStyle(settings.nucleotideLabels,
523             ID_S_NUC, ID_C_NUC_TYPE, ID_C_NUC_NUM, ID_K_NUC_TERM, ID_K_NUC_CONTRAST) &&
524         (checkbox = wxDynamicCast(FindWindow(ID_K_ION), wxCheckBox)) != NULL &&
525         SetChecked(checkbox, settings.ionLabelsOn)
526     );
527     if (!okay) ERRORMSG("StyleDialog::SetControls() - control/parameter mismatch: invalid style?");
528     return okay;
529 }
530 
531 // same as hitting done button
OnCloseWindow(wxCloseEvent & event)532 void StyleDialog::OnCloseWindow(wxCloseEvent& event)
533 {
534     StyleSettings dummy;
535     if (GetValues(&dummy)) {
536         if (changedSinceApply) {
537             *editedSettings = dummy;
538             GlobalMessenger()->PostRedrawAllStructures();
539             GlobalMessenger()->PostRedrawAllSequenceViewers();
540 //            structureSet->SetDataChanged(StructureSet::eStyleData);
541         }
542     } else
543         wxBell();
544     EndModal(wxOK);
545 }
546 
OnButton(wxCommandEvent & event)547 void StyleDialog::OnButton(wxCommandEvent& event)
548 {
549     switch (event.GetId()) {
550         case ID_DONE: {
551             StyleSettings dummy;
552             if (GetValues(&dummy)) {
553                 if (changedSinceApply) {
554                     *editedSettings = dummy;
555                     GlobalMessenger()->PostRedrawAllStructures();
556                     GlobalMessenger()->PostRedrawAllSequenceViewers();
557                 }
558 //                if (changedEver)
559 //                    structureSet->SetDataChanged(StructureSet::eStyleData);
560                 EndModal(wxOK);
561             } else
562                 wxBell();
563             break;
564         }
565         case ID_APPLY: {
566             StyleSettings dummy;
567             if (GetValues(&dummy)) {
568                 *editedSettings = dummy;
569                 GlobalMessenger()->PostRedrawAllStructures();
570                 GlobalMessenger()->PostRedrawAllSequenceViewers();
571                 changedSinceApply = false;
572 //                structureSet->SetDataChanged(StructureSet::eStyleData);
573             } else
574                 wxBell();
575             break;
576         }
577         case ID_CANCEL:
578             if (changedEver) {
579                 *editedSettings = originalSettings;
580                 GlobalMessenger()->PostRedrawAllStructures();
581                 GlobalMessenger()->PostRedrawAllSequenceViewers();
582             }
583             EndModal(wxCANCEL);
584             break;
585         default:
586             if (!HandleColorButton(event.GetId()))
587                 event.Skip();
588     }
589 }
590 
591 // return true if bID does actually correspond to a valid color button
HandleColorButton(int bID)592 bool StyleDialog::HandleColorButton(int bID)
593 {
594     // just a filter to make sure the button pushed is really a user color button
595     switch (bID) {
596         case ID_PBB_USER: case ID_PSIDE_USER: case ID_NUC_USER: case ID_NSIDE_USER:
597         case ID_HET_USER: case ID_SOLV_USER: case ID_CONN_USER: case ID_HELX_USER:
598         case ID_STRN_USER: case ID_VSS_USER: case ID_BG_USER:
599             break;
600         default:
601             return false;
602     }
603 
604     wxButton *button = wxDynamicCast(FindWindow(bID), wxButton);
605     if (!button) {
606         ERRORMSG("StyleDialog::HandleColorButton() - can't find button of given ID");
607         return false;
608     }
609 
610     wxColour userColor = wxGetColourFromUser(this, button->GetBackgroundColour());
611     if (userColor.Ok()) {
612         button->SetBackgroundColour(userColor);
613         wxCommandEvent fake;
614         OnChange(fake);
615     }
616     return true;
617 }
618 
OnChange(wxCommandEvent & event)619 void StyleDialog::OnChange(wxCommandEvent& event)
620 {
621     TRACEMSG("control changed");
622     StyleSettings tmpSettings;
623     if (!GetValues(&tmpSettings) ||
624         !structureSet->styleManager->CheckStyleSettings(&tmpSettings) ||
625         !SetControls(tmpSettings)) {
626         ERRORMSG("StyleDialog::OnChange() - error adjusting settings/controls");
627         return;
628     }
629     changedSinceApply = changedEver = true;
630     if ((wxDynamicCast(FindWindow(ID_ALWAYS_APPLY), wxCheckBox))->GetValue()) {
631         *editedSettings = tmpSettings;
632         GlobalMessenger()->PostRedrawAllStructures();
633         GlobalMessenger()->PostRedrawAllSequenceViewers();
634         changedSinceApply = false;
635     }
636 }
637 
OnSpin(wxSpinEvent & event)638 void StyleDialog::OnSpin(wxSpinEvent& event)
639 {
640     if (!initialized) {
641         event.Skip();
642         return;
643     }
644     wxCommandEvent fake;
645     OnChange(fake);
646 }
647 
END_SCOPE(Cn3D)648 END_SCOPE(Cn3D)
649 
650 
651 //////////////////////////////////////////////////////////////////////////////////////////////////
652 // Three of four of these following functions are taken *without* modification
653 // from wxDesigner C++ code generated from render_settings.wdr. The function LayoutDetailsPage()
654 // is modified from wxDesigner output in order to use custom FloatingPointSpinCtrl's
655 //////////////////////////////////////////////////////////////////////////////////////////////////
656 
657 wxSizer *LayoutNotebook( wxPanel *parent, bool call_fit, bool set_sizer )
658 {
659     wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
660 
661     wxNotebook *item2 = new wxNotebook( parent, ID_NOTEBOOK, wxDefaultPosition, wxDefaultSize, 0 );
662 //    wxNotebookSizer *item1 = new wxNotebookSizer( item2 );
663 
664     wxPanel *item3 = new wxPanel( item2, -1 );
665     LayoutSettingsPage( item3, FALSE );
666     item2->AddPage( item3, "Settings" );
667 
668     wxPanel *item4 = new wxPanel( item2, -1 );
669     LayoutLabelsPage( item4, FALSE );
670     item2->AddPage( item4, "Labels" );
671 
672     wxPanel *item5 = new wxPanel( item2, -1 );
673     LayoutDetailsPage( item5, FALSE );
674     item2->AddPage( item5, "Details" );
675 
676     item0->Add( item2, 0, wxALIGN_CENTRE|wxALL, 5 );
677 
678     wxBoxSizer *item6 = new wxBoxSizer( wxHORIZONTAL );
679 
680     wxButton *item7 = new wxButton( parent, ID_DONE, "Done", wxDefaultPosition, wxDefaultSize, 0 );
681     item7->SetDefault();
682     item6->Add( item7, 0, wxALIGN_CENTRE|wxALL, 5 );
683 
684     wxButton *item8 = new wxButton( parent, ID_CANCEL, "Cancel", wxDefaultPosition, wxDefaultSize, 0 );
685     item6->Add( item8, 0, wxALIGN_CENTRE|wxALL, 5 );
686 
687     item6->Add( 20, 20, 0, wxALIGN_CENTRE|wxALL, 5 );
688 
689     wxStaticText *item9 = new wxStaticText( parent, ID_TEXT, "Apply after each change?", wxDefaultPosition, wxDefaultSize, 0 );
690     item6->Add( item9, 0, wxALIGN_CENTRE|wxALL, 5 );
691 
692     wxCheckBox *item10 = new wxCheckBox( parent, ID_ALWAYS_APPLY, "", wxDefaultPosition, wxDefaultSize, 0 );
693     item10->SetValue( TRUE );
694     item6->Add( item10, 0, wxALIGN_CENTRE|wxALL, 5 );
695 
696     wxButton *item11 = new wxButton( parent, ID_APPLY, "Apply", wxDefaultPosition, wxDefaultSize, 0 );
697     item6->Add( item11, 0, wxALIGN_CENTRE|wxALL, 5 );
698 
699     item0->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 );
700 
701     if (set_sizer)
702     {
703         parent->SetAutoLayout( TRUE );
704         parent->SetSizer( item0 );
705         if (call_fit)
706         {
707             item0->Fit( parent );
708             item0->SetSizeHints( parent );
709         }
710     }
711 
712     return item0;
713 }
714 
LayoutSettingsPage(wxPanel * parent,bool call_fit,bool set_sizer)715 wxSizer *LayoutSettingsPage( wxPanel *parent, bool call_fit, bool set_sizer )
716 {
717     wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
718 
719     wxStaticBox *item2 = new wxStaticBox( parent, -1, "Rendering Settings" );
720     wxStaticBoxSizer *item1 = new wxStaticBoxSizer( item2, wxVERTICAL );
721 
722     wxFlexGridSizer *item3 = new wxFlexGridSizer( 5, 0, 0 );
723 
724     wxStaticText *item4 = new wxStaticText( parent, ID_TEXT, "Group", wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE );
725     item3->Add( item4, 0, wxALIGN_CENTRE|wxALL, 5 );
726 
727     wxStaticText *item5 = new wxStaticText( parent, ID_TEXT, "Show", wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE );
728     item3->Add( item5, 0, wxALIGN_CENTRE|wxALL, 5 );
729 
730     wxStaticText *item6 = new wxStaticText( parent, ID_TEXT, "Rendering", wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE );
731     item3->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 );
732 
733     wxStaticText *item7 = new wxStaticText( parent, ID_TEXT, "Color Scheme", wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE );
734     item3->Add( item7, 0, wxALIGN_CENTRE|wxALL, 5 );
735 
736     wxStaticText *item8 = new wxStaticText( parent, ID_TEXT, "User Color", wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE );
737     item3->Add( item8, 0, wxALIGN_CENTRE|wxALL, 5 );
738 
739     wxStaticText *item9 = new wxStaticText( parent, ID_TEXT, "Protein backbone:", wxDefaultPosition, wxDefaultSize, wxALIGN_CENTRE );
740     item3->Add( item9, 0, wxALIGN_CENTRE|wxALL, 5 );
741 
742     wxString strs10[] =
743     {
744         "None",
745         "Trace",
746         "Partial",
747         "Complete"
748     };
749     wxChoice *item10 = new wxChoice( parent, ID_PBB_SHOW, wxDefaultPosition, wxDefaultSize, 4, strs10, 0 );
750     item3->Add( item10, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
751 
752     wxString strs11[] =
753     {
754         "Wire Worm",
755         "Tube Worm",
756         "Wire",
757         "Tubes",
758         "Ball and Stick",
759         "Space Fill"
760     };
761     wxChoice *item11 = new wxChoice( parent, ID_PBB_RENDER, wxDefaultPosition, wxDefaultSize, 6, strs11, 0 );
762     item3->Add( item11, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
763 
764     wxString strs12[] =
765     {
766         "Element",
767         "Object",
768         "Molecule",
769         "Residue",
770         "Domain",
771         "Secondary Structure",
772         "Temperature",
773         "Rainbow",
774         "Charge",
775         "Hydrophobicity",
776         "User Selection",
777         "Aligned",
778         "Identity",
779         "Variety",
780         "Weighted Variety",
781         "Information Content",
782         "Fit",
783         "Block Fit",
784         "Normalized Block Fit",
785         "Block Row Fit"
786     };
787     wxChoice *item12 = new wxChoice( parent, ID_PBB_COLOR, wxDefaultPosition, wxDefaultSize, 20, strs12, 0 );
788     item3->Add( item12, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
789 
790     wxButton *item13 = new wxButton( parent, ID_PBB_USER, "Set Color", wxDefaultPosition, wxDefaultSize, 0 );
791     item3->Add( item13, 0, wxALIGN_CENTRE|wxALL, 5 );
792 
793     wxStaticText *item14 = new wxStaticText( parent, ID_TEXT, "Protein sidechains:", wxDefaultPosition, wxDefaultSize, 0 );
794     item3->Add( item14, 0, wxALIGN_CENTRE|wxALL, 5 );
795 
796     wxCheckBox *item15 = new wxCheckBox( parent, ID_PSIDE_SHOW, "", wxDefaultPosition, wxDefaultSize, 0 );
797     item3->Add( item15, 0, wxALIGN_CENTRE|wxALL, 5 );
798 
799     wxString strs16[] =
800     {
801         "Wire",
802         "Tubes",
803         "Ball and Stick",
804         "Space Fill"
805     };
806     wxChoice *item16 = new wxChoice( parent, ID_PSIDE_RENDER, wxDefaultPosition, wxDefaultSize, 4, strs16, 0 );
807     item3->Add( item16, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
808 
809     wxString strs17[] =
810     {
811         "Element",
812         "Object",
813         "Molecule",
814         "Residue",
815         "Domain",
816         "Temperature",
817         "Rainbow",
818         "Charge",
819         "Hydrophobicity",
820         "User Selection",
821         "Aligned",
822         "Identity",
823         "Variety",
824         "Weighted Variety",
825         "Information Content",
826         "Fit",
827         "Block Fit",
828         "Normalized Block Fit",
829         "Block Row Fit"
830     };
831     wxChoice *item17 = new wxChoice( parent, ID_PSIDE_COLOR, wxDefaultPosition, wxDefaultSize, 19, strs17, 0 );
832     item3->Add( item17, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
833 
834     wxButton *item18 = new wxButton( parent, ID_PSIDE_USER, "Set Color", wxDefaultPosition, wxDefaultSize, 0 );
835     item3->Add( item18, 0, wxALIGN_CENTRE|wxALL, 5 );
836 
837     wxStaticText *item19 = new wxStaticText( parent, ID_TEXT, "Nucleotide backbone:", wxDefaultPosition, wxDefaultSize, 0 );
838     item3->Add( item19, 0, wxALIGN_CENTRE|wxALL, 5 );
839 
840     wxString strs20[] =
841     {
842         "None",
843         "Trace",
844         "Partial",
845         "Complete"
846     };
847     wxChoice *item20 = new wxChoice( parent, ID_NUC_SHOW, wxDefaultPosition, wxDefaultSize, 4, strs20, 0 );
848     item3->Add( item20, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
849 
850     wxString strs21[] =
851     {
852         "Wire Worm",
853         "Tube Worm",
854         "Wire",
855         "Tubes",
856         "Ball and Stick",
857         "Space Fill"
858     };
859     wxChoice *item21 = new wxChoice( parent, ID_NUC_RENDER, wxDefaultPosition, wxDefaultSize, 6, strs21, 0 );
860     item3->Add( item21, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
861 
862     wxString strs22[] =
863     {
864         "Element",
865         "Object",
866         "Molecule",
867         "Residue",
868         "Domain",
869         "Temperature",
870         "Rainbow",
871         "User Selection"
872     };
873     wxChoice *item22 = new wxChoice( parent, ID_NUC_COLOR, wxDefaultPosition, wxDefaultSize, 8, strs22, 0 );
874     item3->Add( item22, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
875 
876     wxButton *item23 = new wxButton( parent, ID_NUC_USER, "Set Color", wxDefaultPosition, wxDefaultSize, 0 );
877     item3->Add( item23, 0, wxALIGN_CENTRE|wxALL, 5 );
878 
879     wxStaticText *item24 = new wxStaticText( parent, ID_TEXT, "Nucleotide sidechains:", wxDefaultPosition, wxDefaultSize, 0 );
880     item3->Add( item24, 0, wxALIGN_CENTRE|wxALL, 5 );
881 
882     wxCheckBox *item25 = new wxCheckBox( parent, ID_NSIDE_SHOW, "", wxDefaultPosition, wxDefaultSize, 0 );
883     item3->Add( item25, 0, wxALIGN_CENTRE|wxALL, 5 );
884 
885     wxString strs26[] =
886     {
887         "Wire",
888         "Tubes",
889         "Ball and Stick",
890         "Space Fill"
891     };
892     wxChoice *item26 = new wxChoice( parent, ID_NSIDE_RENDER, wxDefaultPosition, wxDefaultSize, 4, strs26, 0 );
893     item3->Add( item26, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
894 
895     wxString strs27[] =
896     {
897         "Element",
898         "Object",
899         "Molecule",
900         "Residue",
901         "Domain",
902         "Temperature",
903         "Rainbow",
904         "User Selection"
905     };
906     wxChoice *item27 = new wxChoice( parent, ID_NSIDE_COLOR, wxDefaultPosition, wxDefaultSize, 8, strs27, 0 );
907     item3->Add( item27, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
908 
909     wxButton *item28 = new wxButton( parent, ID_NSIDE_USER, "Set Color", wxDefaultPosition, wxDefaultSize, 0 );
910     item3->Add( item28, 0, wxALIGN_CENTRE|wxALL, 5 );
911 
912     wxStaticText *item29 = new wxStaticText( parent, ID_TEXT, "Heterogens:", wxDefaultPosition, wxDefaultSize, 0 );
913     item3->Add( item29, 0, wxALIGN_CENTRE|wxALL, 5 );
914 
915     wxCheckBox *item30 = new wxCheckBox( parent, ID_HET_SHOW, "", wxDefaultPosition, wxDefaultSize, 0 );
916     item3->Add( item30, 0, wxALIGN_CENTRE|wxALL, 5 );
917 
918     wxString strs31[] =
919     {
920         "Wire",
921         "Tubes",
922         "Ball and Stick",
923         "Space Fill"
924     };
925     wxChoice *item31 = new wxChoice( parent, ID_HET_RENDER, wxDefaultPosition, wxDefaultSize, 4, strs31, 0 );
926     item3->Add( item31, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
927 
928     wxString strs32[] =
929     {
930         "Element",
931         "Object",
932         "Molecule",
933         "Temperature",
934         "User Selection"
935     };
936     wxChoice *item32 = new wxChoice( parent, ID_HET_COLOR, wxDefaultPosition, wxDefaultSize, 5, strs32, 0 );
937     item3->Add( item32, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
938 
939     wxButton *item33 = new wxButton( parent, ID_HET_USER, "Set Color", wxDefaultPosition, wxDefaultSize, 0 );
940     item3->Add( item33, 0, wxALIGN_CENTRE|wxALL, 5 );
941 
942     wxStaticText *item34 = new wxStaticText( parent, ID_TEXT, "Solvents:", wxDefaultPosition, wxDefaultSize, 0 );
943     item3->Add( item34, 0, wxALIGN_CENTRE|wxALL, 5 );
944 
945     wxCheckBox *item35 = new wxCheckBox( parent, ID_SOLV_SHOW, "", wxDefaultPosition, wxDefaultSize, 0 );
946     item3->Add( item35, 0, wxALIGN_CENTRE|wxALL, 5 );
947 
948     wxString strs36[] =
949     {
950         "Wire",
951         "Tubes",
952         "Ball and Stick",
953         "Space Fill"
954     };
955     wxChoice *item36 = new wxChoice( parent, ID_SOLV_RENDER, wxDefaultPosition, wxDefaultSize, 4, strs36, 0 );
956     item3->Add( item36, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
957 
958     wxString strs37[] =
959     {
960         "Element",
961         "Object",
962         "Molecule",
963         "Temperature",
964         "User Selection"
965     };
966     wxChoice *item37 = new wxChoice( parent, ID_SOLV_COLOR, wxDefaultPosition, wxDefaultSize, 5, strs37, 0 );
967     item3->Add( item37, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
968 
969     wxButton *item38 = new wxButton( parent, ID_SOLV_USER, "Set Color", wxDefaultPosition, wxDefaultSize, 0 );
970     item3->Add( item38, 0, wxALIGN_CENTRE|wxALL, 5 );
971 
972     wxStaticText *item39 = new wxStaticText( parent, ID_TEXT, "Connections:", wxDefaultPosition, wxDefaultSize, 0 );
973     item3->Add( item39, 0, wxALIGN_CENTRE|wxALL, 5 );
974 
975     wxCheckBox *item40 = new wxCheckBox( parent, ID_CONN_SHOW, "", wxDefaultPosition, wxDefaultSize, 0 );
976     item3->Add( item40, 0, wxALIGN_CENTRE|wxALL, 5 );
977 
978     wxString strs41[] =
979     {
980         "Wire",
981         "Tubes"
982     };
983     wxChoice *item41 = new wxChoice( parent, ID_CONN_RENDER, wxDefaultPosition, wxDefaultSize, 2, strs41, 0 );
984     item3->Add( item41, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
985 
986     wxString strs42[] =
987     {
988         "User Selection"
989     };
990     wxChoice *item42 = new wxChoice( parent, ID_CONN_COLOR, wxDefaultPosition, wxDefaultSize, 1, strs42, 0 );
991     item3->Add( item42, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
992 
993     wxButton *item43 = new wxButton( parent, ID_CONN_USER, "Set Color", wxDefaultPosition, wxDefaultSize, 0 );
994     item3->Add( item43, 0, wxALIGN_CENTRE|wxALL, 5 );
995 
996     wxStaticText *item44 = new wxStaticText( parent, ID_TEXT, "Helix objects:", wxDefaultPosition, wxDefaultSize, 0 );
997     item3->Add( item44, 0, wxALIGN_CENTRE|wxALL, 5 );
998 
999     wxCheckBox *item45 = new wxCheckBox( parent, ID_HELX_SHOW, "", wxDefaultPosition, wxDefaultSize, 0 );
1000     item3->Add( item45, 0, wxALIGN_CENTRE|wxALL, 5 );
1001 
1002     wxString strs46[] =
1003     {
1004         "With Arrows",
1005         "Without Arrows"
1006     };
1007     wxChoice *item46 = new wxChoice( parent, ID_HELX_RENDER, wxDefaultPosition, wxDefaultSize, 2, strs46, 0 );
1008     item3->Add( item46, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1009 
1010     wxString strs47[] =
1011     {
1012         "Object",
1013         "Molecule",
1014         "Domain",
1015         "Secondary Structure",
1016         "User Selection"
1017     };
1018     wxChoice *item47 = new wxChoice( parent, ID_HELX_COLOR, wxDefaultPosition, wxDefaultSize, 5, strs47, 0 );
1019     item3->Add( item47, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1020 
1021     wxButton *item48 = new wxButton( parent, ID_HELX_USER, "Set Color", wxDefaultPosition, wxDefaultSize, 0 );
1022     item3->Add( item48, 0, wxALIGN_CENTRE|wxALL, 5 );
1023 
1024     wxStaticText *item49 = new wxStaticText( parent, ID_TEXT, "Strand objects:", wxDefaultPosition, wxDefaultSize, 0 );
1025     item3->Add( item49, 0, wxALIGN_CENTRE|wxALL, 5 );
1026 
1027     wxCheckBox *item50 = new wxCheckBox( parent, ID_STRN_SHOW, "", wxDefaultPosition, wxDefaultSize, 0 );
1028     item3->Add( item50, 0, wxALIGN_CENTRE|wxALL, 5 );
1029 
1030     wxString strs51[] =
1031     {
1032         "With Arrows",
1033         "Without Arrows"
1034     };
1035     wxChoice *item51 = new wxChoice( parent, ID_STRN_RENDER, wxDefaultPosition, wxDefaultSize, 2, strs51, 0 );
1036     item3->Add( item51, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1037 
1038     wxString strs52[] =
1039     {
1040         "Object",
1041         "Molecule",
1042         "Domain",
1043         "Secondary Structure",
1044         "User Selection"
1045     };
1046     wxChoice *item52 = new wxChoice( parent, ID_STRN_COLOR, wxDefaultPosition, wxDefaultSize, 5, strs52, 0 );
1047     item3->Add( item52, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1048 
1049     wxButton *item53 = new wxButton( parent, ID_STRN_USER, "Set Color", wxDefaultPosition, wxDefaultSize, 0 );
1050     item3->Add( item53, 0, wxALIGN_CENTRE|wxALL, 5 );
1051 
1052     wxStaticText *item54 = new wxStaticText( parent, ID_TEXT, "Virtual disulfides:", wxDefaultPosition, wxDefaultSize, 0 );
1053     item3->Add( item54, 0, wxALIGN_CENTRE|wxALL, 5 );
1054 
1055     wxCheckBox *item55 = new wxCheckBox( parent, ID_VSS_SHOW, "", wxDefaultPosition, wxDefaultSize, 0 );
1056     item3->Add( item55, 0, wxALIGN_CENTRE|wxALL, 5 );
1057 
1058     item3->Add( 5, 5, 0, wxALIGN_CENTRE|wxALL, 5 );
1059 
1060     item3->Add( 5, 5, 0, wxALIGN_CENTRE|wxALL, 5 );
1061 
1062     wxButton *item56 = new wxButton( parent, ID_VSS_USER, "Set Color", wxDefaultPosition, wxDefaultSize, 0 );
1063     item3->Add( item56, 0, wxALIGN_CENTRE|wxALL, 5 );
1064 
1065     wxStaticText *item57 = new wxStaticText( parent, ID_TEXT, "Hydrogens:", wxDefaultPosition, wxDefaultSize, 0 );
1066     item3->Add( item57, 0, wxALIGN_CENTRE|wxALL, 5 );
1067 
1068     wxCheckBox *item58 = new wxCheckBox( parent, ID_HYD_SHOW, "", wxDefaultPosition, wxDefaultSize, 0 );
1069     item3->Add( item58, 0, wxALIGN_CENTRE|wxALL, 5 );
1070 
1071     item3->Add( 5, 5, 0, wxALIGN_CENTRE|wxALL, 5 );
1072 
1073     wxStaticText *item59 = new wxStaticText( parent, ID_TEXT, "Background:", wxDefaultPosition, wxDefaultSize, 0 );
1074     item3->Add( item59, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1075 
1076     wxButton *item60 = new wxButton( parent, ID_BG_USER, "Set Color", wxDefaultPosition, wxDefaultSize, 0 );
1077     item3->Add( item60, 0, wxALIGN_CENTRE|wxALL, 5 );
1078 
1079     item1->Add( item3, 0, wxALIGN_CENTRE|wxALL, 5 );
1080 
1081     item0->Add( item1, 0, wxALIGN_CENTRE|wxALL, 5 );
1082 
1083     if (set_sizer)
1084     {
1085         parent->SetAutoLayout( TRUE );
1086         parent->SetSizer( item0 );
1087         if (call_fit)
1088         {
1089             item0->Fit( parent );
1090             item0->SetSizeHints( parent );
1091         }
1092     }
1093 
1094     return item0;
1095 }
1096 
LayoutLabelsPage(wxPanel * parent,bool call_fit,bool set_sizer)1097 wxSizer *LayoutLabelsPage( wxPanel *parent, bool call_fit, bool set_sizer )
1098 {
1099     wxBoxSizer *item0 = new wxBoxSizer( wxVERTICAL );
1100 
1101     wxStaticBox *item2 = new wxStaticBox( parent, -1, "Labeling Settings" );
1102     wxStaticBoxSizer *item1 = new wxStaticBoxSizer( item2, wxVERTICAL );
1103 
1104     wxBoxSizer *item3 = new wxBoxSizer( wxVERTICAL );
1105 
1106     wxGridSizer *item4 = new wxGridSizer( 3, 5, 0 );
1107 
1108     item4->Add( 20, 20, 0, wxALIGN_CENTRE|wxALL, 5 );
1109 
1110     wxStaticText *item5 = new wxStaticText( parent, ID_TEXT, "Protein backbone:", wxDefaultPosition, wxDefaultSize, 0 );
1111     item4->Add( item5, 0, wxALIGN_CENTRE|wxALL, 5 );
1112 
1113     wxStaticText *item6 = new wxStaticText( parent, ID_TEXT, "Nucleotide backbone:", wxDefaultPosition, wxDefaultSize, 0 );
1114     item4->Add( item6, 0, wxALIGN_CENTRE|wxALL, 5 );
1115 
1116     wxStaticText *item7 = new wxStaticText( parent, ID_TEXT, "Spacing (0 = none):", wxDefaultPosition, wxDefaultSize, 0 );
1117     item4->Add( item7, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1118 
1119     wxSpinCtrl *item8 = new wxSpinCtrl( parent, ID_S_PROT, "0", wxDefaultPosition, wxDefaultSize, 0, 0, 100, 0 );
1120     item4->Add( item8, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1121 
1122     wxSpinCtrl *item9 = new wxSpinCtrl( parent, ID_S_NUC, "0", wxDefaultPosition, wxDefaultSize, 0, 0, 100, 0 );
1123     item4->Add( item9, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1124 
1125     wxStaticText *item10 = new wxStaticText( parent, ID_TEXT, "Type:", wxDefaultPosition, wxDefaultSize, 0 );
1126     item4->Add( item10, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1127 
1128     wxString strs11[] =
1129     {
1130         "One Letter",
1131         "Three Letter"
1132     };
1133     wxChoice *item11 = new wxChoice( parent, ID_C_PROT_TYPE, wxDefaultPosition, wxDefaultSize, 2, strs11, 0 );
1134     item4->Add( item11, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1135 
1136     wxString strs12[] =
1137     {
1138         "One Letter",
1139         "Three Letter"
1140     };
1141     wxChoice *item12 = new wxChoice( parent, ID_C_NUC_TYPE, wxDefaultPosition, wxDefaultSize, 2, strs12, 0 );
1142     item4->Add( item12, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1143 
1144     wxStaticText *item13 = new wxStaticText( parent, ID_TEXT, "Numbering:", wxDefaultPosition, wxDefaultSize, 0 );
1145     item4->Add( item13, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1146 
1147     wxString strs14[] =
1148     {
1149         "None",
1150         "Sequential",
1151         "From PDB"
1152     };
1153     wxChoice *item14 = new wxChoice( parent, ID_C_PROT_NUM, wxDefaultPosition, wxDefaultSize, 3, strs14, 0 );
1154     item4->Add( item14, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1155 
1156     wxString strs15[] =
1157     {
1158         "None",
1159         "Sequential",
1160         "From PDB"
1161     };
1162     wxChoice *item15 = new wxChoice( parent, ID_C_NUC_NUM, wxDefaultPosition, wxDefaultSize, 3, strs15, 0 );
1163     item4->Add( item15, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1164 
1165     wxStaticText *item16 = new wxStaticText( parent, ID_TEXT, "Contrast with background:", wxDefaultPosition, wxDefaultSize, 0 );
1166     item4->Add( item16, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1167 
1168     wxCheckBox *item17 = new wxCheckBox( parent, ID_K_PROT_CONTRAST, "", wxDefaultPosition, wxDefaultSize, 0 );
1169     item4->Add( item17, 0, wxALIGN_CENTRE|wxALL, 5 );
1170 
1171     wxCheckBox *item18 = new wxCheckBox( parent, ID_K_NUC_CONTRAST, "", wxDefaultPosition, wxDefaultSize, 0 );
1172     item4->Add( item18, 0, wxALIGN_CENTRE|wxALL, 5 );
1173 
1174     wxStaticText *item19 = new wxStaticText( parent, ID_TEXT, "Termini:", wxDefaultPosition, wxDefaultSize, 0 );
1175     item4->Add( item19, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1176 
1177     wxCheckBox *item20 = new wxCheckBox( parent, ID_K_PROT_TERM, "", wxDefaultPosition, wxDefaultSize, 0 );
1178     item4->Add( item20, 0, wxALIGN_CENTRE|wxALL, 5 );
1179 
1180     wxCheckBox *item21 = new wxCheckBox( parent, ID_K_NUC_TERM, "", wxDefaultPosition, wxDefaultSize, 0 );
1181     item4->Add( item21, 0, wxALIGN_CENTRE|wxALL, 5 );
1182 
1183     item3->Add( item4, 0, wxGROW|wxALIGN_CENTER_VERTICAL, 5 );
1184 
1185     wxStaticLine *item22 = new wxStaticLine( parent, ID_LINE, wxDefaultPosition, wxSize(20,-1), wxLI_HORIZONTAL );
1186     item3->Add( item22, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5 );
1187 
1188     wxBoxSizer *item23 = new wxBoxSizer( wxHORIZONTAL );
1189 
1190     wxStaticText *item24 = new wxStaticText( parent, ID_TEXT, "Metal ion labels:", wxDefaultPosition, wxDefaultSize, 0 );
1191     item23->Add( item24, 0, wxALIGN_CENTRE|wxALL, 5 );
1192 
1193     item23->Add( 20, 20, 0, wxALIGN_CENTRE|wxALL, 5 );
1194 
1195     wxCheckBox *item25 = new wxCheckBox( parent, ID_K_ION, "", wxDefaultPosition, wxDefaultSize, 0 );
1196     item23->Add( item25, 0, wxALIGN_CENTRE|wxALL, 5 );
1197 
1198     item3->Add( item23, 0, wxALIGN_CENTRE|wxALL, 5 );
1199 
1200     item1->Add( item3, 0, wxALIGN_CENTRE|wxALL, 5 );
1201 
1202     item0->Add( item1, 0, wxALIGN_CENTRE|wxALL, 5 );
1203 
1204     if (set_sizer)
1205     {
1206         parent->SetAutoLayout( TRUE );
1207         parent->SetSizer( item0 );
1208         if (call_fit)
1209         {
1210             item0->Fit( parent );
1211             item0->SetSizeHints( parent );
1212         }
1213     }
1214 
1215     return item0;
1216 }
1217 
1218 
1219 /////
1220 // this is modified from wxDesigner output in order to use custom SpinCtrl's
1221 /////
1222 
LayoutDetailsPage(wxPanel * parent,bool call_fit,bool set_sizer)1223 wxSizer *LayoutDetailsPage(wxPanel *parent, bool call_fit, bool set_sizer)
1224 {
1225     wxBoxSizer *item0 = new wxBoxSizer(wxVERTICAL);
1226     wxStaticBox *item2 = new wxStaticBox(parent, -1, "Rendering Details");
1227     wxStaticBoxSizer *item1 = new wxStaticBoxSizer(item2, wxVERTICAL);
1228     wxFlexGridSizer *grid = new wxFlexGridSizer(3, 0, 0);
1229 
1230     // space fill proportion
1231     wxStaticText *item4 = new wxStaticText(parent, ID_TEXT, "Space fill size:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
1232     grid->Add(item4, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
1233     gfpSpaceFill = new FloatingPointSpinCtrl(parent,
1234         0.0, 10.0, 0.1, 1.0,
1235         wxDefaultPosition, wxSize(80, SPIN_CTRL_HEIGHT), 0,
1236         wxDefaultPosition, wxSize(-1, SPIN_CTRL_HEIGHT));
1237     grid->Add(gfpSpaceFill->GetTextCtrl(), 0, wxALIGN_CENTRE|wxLEFT|wxTOP|wxBOTTOM, 5);
1238     grid->Add(gfpSpaceFill->GetSpinButton(), 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5);
1239 
1240     // tube radius
1241     wxStaticText *item7 = new wxStaticText(parent, ID_TEXT, "Tube radius:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
1242     grid->Add(item7, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
1243     gfpTubeRadius = new FloatingPointSpinCtrl(parent,
1244         0.0, 5.0, 0.02, 0.3,
1245         wxDefaultPosition, wxSize(80, SPIN_CTRL_HEIGHT), 0,
1246         wxDefaultPosition, wxSize(-1, SPIN_CTRL_HEIGHT));
1247     grid->Add(gfpTubeRadius->GetTextCtrl(), 0, wxALIGN_CENTRE|wxLEFT|wxTOP|wxBOTTOM, 5);
1248     grid->Add(gfpTubeRadius->GetSpinButton(), 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5);
1249 
1250     // worm tube
1251     wxStaticText *item10 = new wxStaticText(parent, ID_TEXT, "Worm tube radius:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
1252     grid->Add(item10, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
1253     gfpTubeWormRadius = new FloatingPointSpinCtrl(parent,
1254         0.0, 5.0, 0.02, 0.3,
1255         wxDefaultPosition, wxSize(80, SPIN_CTRL_HEIGHT), 0,
1256         wxDefaultPosition, wxSize(-1, SPIN_CTRL_HEIGHT));
1257     grid->Add(gfpTubeWormRadius->GetTextCtrl(), 0, wxALIGN_CENTRE|wxLEFT|wxTOP|wxBOTTOM, 5);
1258     grid->Add(gfpTubeWormRadius->GetSpinButton(), 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5);
1259 
1260     // ball radius
1261     wxStaticText *item13 = new wxStaticText(parent, ID_TEXT, "Ball radius:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
1262     grid->Add(item13, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
1263     gfpBallRadius = new FloatingPointSpinCtrl(parent,
1264         0.0, 10.0, 0.05, 0.4,
1265         wxDefaultPosition, wxSize(80, SPIN_CTRL_HEIGHT), 0,
1266         wxDefaultPosition, wxSize(-1, SPIN_CTRL_HEIGHT));
1267     grid->Add(gfpBallRadius->GetTextCtrl(), 0, wxALIGN_CENTRE|wxLEFT|wxTOP|wxBOTTOM, 5);
1268     grid->Add(gfpBallRadius->GetSpinButton(), 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5);
1269 
1270     // stick radius
1271     wxStaticText *item16 = new wxStaticText(parent, ID_TEXT, "Stick radius:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
1272     grid->Add(item16, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
1273     gfpStickRadius = new FloatingPointSpinCtrl(parent,
1274         0.0, 5.0, 0.01, 0.2,
1275         wxDefaultPosition, wxSize(80, SPIN_CTRL_HEIGHT), 0,
1276         wxDefaultPosition, wxSize(-1, SPIN_CTRL_HEIGHT));
1277     grid->Add(gfpStickRadius->GetTextCtrl(), 0, wxALIGN_CENTRE|wxLEFT|wxTOP|wxBOTTOM, 5);
1278     grid->Add(gfpStickRadius->GetSpinButton(), 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5);
1279 
1280     // spacer
1281     grid->Add(1, 1, 0, wxALIGN_CENTRE|wxALL, 5);
1282     grid->Add(1, 1, 0, wxALIGN_CENTRE|wxALL, 5);
1283     grid->Add(1, 1, 0, wxALIGN_CENTRE|wxALL, 5);
1284 
1285     // helix radius
1286     wxStaticText *item19 = new wxStaticText(parent, ID_TEXT, "Helix radius:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
1287     grid->Add(item19, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
1288     gfpHelixRadius = new FloatingPointSpinCtrl(parent,
1289         0.0, 10.0, 0.1, 1.8,
1290         wxDefaultPosition, wxSize(80, SPIN_CTRL_HEIGHT), 0,
1291         wxDefaultPosition, wxSize(-1, SPIN_CTRL_HEIGHT));
1292     grid->Add(gfpHelixRadius->GetTextCtrl(), 0, wxALIGN_CENTRE|wxLEFT|wxTOP|wxBOTTOM, 5);
1293     grid->Add(gfpHelixRadius->GetSpinButton(), 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5);
1294 
1295     // strand width
1296     wxStaticText *item22 = new wxStaticText(parent, ID_TEXT, "Strand width:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
1297     grid->Add(item22, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
1298     gfpStrandWidth = new FloatingPointSpinCtrl(parent,
1299         0.0, 10.0, 0.1, 2.0,
1300         wxDefaultPosition, wxSize(80, SPIN_CTRL_HEIGHT), 0,
1301         wxDefaultPosition, wxSize(-1, SPIN_CTRL_HEIGHT));
1302     grid->Add(gfpStrandWidth->GetTextCtrl(), 0, wxALIGN_CENTRE|wxLEFT|wxTOP|wxBOTTOM, 5);
1303     grid->Add(gfpStrandWidth->GetSpinButton(), 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5);
1304 
1305     // strand thickness
1306     wxStaticText *item25 = new wxStaticText(parent, ID_TEXT, "Strand thickness:", wxDefaultPosition, wxDefaultSize, wxALIGN_RIGHT);
1307     grid->Add(item25, 0, wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL|wxALL, 5);
1308     gfpStrandThickness = new FloatingPointSpinCtrl(parent,
1309         0.0, 5.0, 0.05, 0.5,
1310         wxDefaultPosition, wxSize(80, SPIN_CTRL_HEIGHT), 0,
1311         wxDefaultPosition, wxSize(-1, SPIN_CTRL_HEIGHT));
1312     grid->Add(gfpStrandThickness->GetTextCtrl(), 0, wxALIGN_CENTRE|wxLEFT|wxTOP|wxBOTTOM, 5);
1313     grid->Add(gfpStrandThickness->GetSpinButton(), 0, wxALIGN_CENTRE|wxRIGHT|wxTOP|wxBOTTOM, 5);
1314 
1315     item1->Add(grid, 0, wxALIGN_CENTRE|wxALL, 5);
1316     item0->Add(item1, 0, wxALIGN_CENTRE|wxALL, 5);
1317     if (set_sizer)
1318     {
1319         parent->SetAutoLayout(TRUE);
1320         parent->SetSizer(item0);
1321         if (call_fit)
1322         {
1323             item0->Fit(parent);
1324             item0->SetSizeHints(parent);
1325         }
1326     }
1327 
1328     return item0;
1329 }
1330