source: GTP/trunk/App/Demos/Illum/EnvMap/Parameters.cpp @ 1488

Revision 1488, 14.6 KB checked in by szirmay, 18 years ago (diff)
RevLine 
[1488]1
2#include "dxstdafx.h"
3#include "Parameters.h"
4
5float noconvert(float a) {
6        return a;
7}
8
9void OnChange() {
10}
11
12//--------------------------------------------------------------------------------------
13/// \brief You can set the dialog that manages input and rendering for the GUI controls.
14//--------------------------------------------------------------------------------------
15void Parameters::Setup( CDXUTDialog* g_HUD ) {
16        Setup(g_HUD, OnChange, OnChange, OnChange);
17}
18
19//--------------------------------------------------------------------------------------
20/// \brief You can set the dialog that manages input and rendering for the GUI controls.
21///
22/// Additionally, you can specify actions (#ONCHANGE_CALLBACK) to the standard buttons
23/// Reset, Save and Load.
24//--------------------------------------------------------------------------------------
25void Parameters::Setup( CDXUTDialog* g_HUD, ONCHANGE_CALLBACK OnReset, ONCHANGE_CALLBACK OnSave, ONCHANGE_CALLBACK OnLoad )
26{
27        assert( g_HUD != NULL );
28        this->g_HUD = g_HUD;
29        g_HUD->GetDefaultElement( DXUT_CONTROL_STATIC, 0 )->dwTextFormat = DT_VCENTER | DT_LEFT;
30
31        for (int i=0; i<LAST_NUMBER; i++) {
32                ffunc[i] = noconvert;
33                chfunc[i] = OnChange;
34                rotate[i] = false;
35        }
36
37        for (int i=0; i<LAST_BOOL; i++) {
38                bchfunc[i] = OnChange;
39                radiogroup[i] = -1;
40        }
41
42        int posX = 380;
43        int posY = 40 + LAST_BOOL*16;
44        g_HUD->AddButton( IDC_RESET_BUTTON, L"[R] Reset", posX, posY += 30, 60, 16, 'R' );
45        g_HUD->AddButton( IDC_SAVE_BUTTON,  L"[S] Save",  posX + 70, posY, 60, 16, 'S' );
46        g_HUD->AddButton( IDC_LOAD_BUTTON,  L"[L] Load",  posX + 140, posY, 60, 16, 'L' );
47        chfunc[ LAST_NUMBER ] = OnReset;
48        chfunc[ LAST_NUMBER+1 ] = OnSave;
49        chfunc[ LAST_NUMBER+2 ] = OnLoad;
50}
51
52//--------------------------------------------------------------------------------------
53/// \brief Adds a boolean parameter represented by a GUI <b>radio button</b>. Specifies hotkey and callback function.
54///
55/// \param radiogroupID id of radio button group.
56/// Checking a radio button will clear all other radio buttons with the same radiogroupID.
57/// \param ID id of the given boolean parameter
58/// \param label label to be displayed for the control
59/// \param cHotkey Hotkey to change parameter value. (Note: keys R, S, L are reserved.)
60/// \param bchf callback to an action to be performed when the parameter changes
61//--------------------------------------------------------------------------------------
62void Parameters::Add( int radiogroupID, bool_t ID, char* label, char cHotKey, ONCHANGE_CALLBACK bchf )
63{
64        assert( cHotKey != 'R' && cHotKey != 'S' && cHotKey != 'L' );
65        mbstowcs( bname[ID], label, CHARBUFFER_SIZE );
66
67        int posX = 380;
68        int posY = 50;
69
70        if (radiogroupID >=0)
71                g_HUD->AddRadioButton( ID+checkboxID0, 0, bname[ID], posX, posY + ID*16, 220, 16, false, cHotKey, 0 );
72        else
73                g_HUD->AddCheckBox( ID+checkboxID0, bname[ID], posX, posY + ID*16, 220, 16, false, cHotKey, 0 );
74        // checked=false
75
76        bchfunc[ID] = bchf;
77        radiogroup[ ID ] = radiogroupID;
78}
79
80//--------------------------------------------------------------------------------------
81/// \brief Adds a boolean parameter represented by a GUI <b>checkbox</b>. Specifies hotkey and callback function.
82///
83/// \param ID id of the given boolean parameter
84/// \param label label to be displayed for the control
85/// \param cHotkey Hotkey to change parameter value. (Note: keys R, S, L are reserved.)
86/// \param bchf callback to an action to be performed when the parameter changes
87//--------------------------------------------------------------------------------------
88void Parameters::Add( bool_t ID, char* label, char cHotKey, ONCHANGE_CALLBACK bchf ) {
89
90        // not a radio button
91        Add( -1, ID, label, cHotKey, bchf );
92}
93
94//--------------------------------------------------------------------------------------
95/// \brief Adds a numeric parameter represented by a GUI <b>slider</b>.
96///
97/// \param ID id of the given numeric parameter
98/// \param label label to be displayed for the slider
99/// \param num_steps number of possible parameter values
100//--------------------------------------------------------------------------------------
101void Parameters::Add( number_t ID, char* label, int num_steps) {
102        Add( ID, label, num_steps, noconvert );
103}
104
105//--------------------------------------------------------------------------------------
106/// \brief Adds a numeric parameter represented by a GUI <b>slider</b>. Specifies callback functions.
107///
108/// \param ID id of the given numeric parameter
109/// \param label label to be displayed for the slider
110/// \param num_steps number of possible parameter values
111/// \param ff converter function to transform the parameter value
112/// \param chf callback to an action to be performed when the parameter changes
113//--------------------------------------------------------------------------------------
114void Parameters::Add( number_t ID, char* label, int num_steps, CONVERTER ff, ONCHANGE_CALLBACK chf ) {
115        char cKeyDown = 0;
116        char cKeyUp = 0;
117        Add( ID, label, num_steps, cKeyDown, cKeyUp, ff, chf);
118}
119
120//--------------------------------------------------------------------------------------
121/// \brief Adds a numeric parameter represented by a GUI <b>slider</b>. Specifies hotkeys and callback functions.
122///
123/// \param ID id of the given numeric parameter
124/// \param label label to be displayed for the slider
125/// \param num_steps number of possible parameter values
126/// \param cKeyDecr Hotkey to decrease parameter value. (Note: keys R, S, L are reserved.)
127/// \param cKeyIncr Hotkey to increase parameter value. (Note: keys R, S, L are reserved.)
128/// If 0, the slider will only have one hotkey that circulates between values min, min+1, ..., max-1, max, min, ...
129///
130/// \param ff converter function to transform the parameter value
131/// \param chf callback to an action to be performed when the parameter changes
132//--------------------------------------------------------------------------------------
133void Parameters::Add( number_t ID, char* label, int num_steps, char cKeyDecr, char cKeyIncr, CONVERTER ff, ONCHANGE_CALLBACK chf ) {
134
135        assert( cKeyDecr != 'R' && cKeyDecr != 'S' && cKeyDecr != 'L' );
136        assert( cKeyIncr != 'R' && cKeyIncr != 'S' && cKeyIncr != 'L' );
137
138        if (cKeyIncr == 0)
139        {
140                cKeyIncr = cKeyDecr; cKeyDecr = 0;      // swap
141                rotate[ID] = true;                                      // slider acts as a modulus
142        }
143
144        mbstowcs( name[ID], label, CHARBUFFER_SIZE );
145        /*wchar_t val[30];
146        _sntprintf( val, 30, L"%.2f", param[ID] / 100.0f );     // nem kell */
147
148        //cHotKey
149        ffunc[ID] = ff;
150        chfunc[ID] = chf;
151        numsteps[ID] = num_steps;
152
153        int posX = 210;
154        int posY = 50;
155        g_HUD->AddStatic( 0, name[ID], posX-180, posY + ID*16, 120, 14 );
156        g_HUD->AddStatic( ID+staticID0, L"", posX-50, posY + ID*16, 120, 14 );
157        g_HUD->GetStatic( ID+staticID0 )->SetTextColor( D3DCOLOR_ARGB(128,178,178,178) );
158        g_HUD->AddSlider( ID+sliderID0, posX, posY + ID*16, 120, 14, 0, num_steps );
159        //UpdateFromHUD( ID+sliderID0 );
160
161        // hogy ne kelljen azt eltárolni, hogy melyik hotkey melyik sliderhez tartozik,
162        // 2 láthatatlan checkboxot hozok létre ezekkel a hotkeyekkel.
163        // a checkbox id alapján azonosíthatom az érintett slidert.
164        CDXUTCheckBox* c;
165        g_HUD->AddCheckBox( ID+downID0, L"d", posX-20, posY + ID*16, 200, 16, 0, cKeyDecr, 0, &c );
166        c->m_bVisible = false;
167        g_HUD->AddCheckBox( ID+upID0, L"u", posX-20, posY + ID*16, 200, 16, 0, cKeyIncr, 0, &c );
168        c->m_bVisible = false;
169}
170
171/// \brief Returns value of the specified boolean parameter, e.g. Get( #bShowHelp ).
172bool Parameters::Get( bool_t i ) {
173        return bparam[i];
174}
175
176/// \brief Returns float value of the specified numeric parameter, in range 0..1.
177///
178/// Example: Get( refractionIndex ). Converter functions (if present) are applied to the result.
179float Parameters::Get( number_t i ) {
180        //assert( ffunc[i] != NULL );
181        return ffunc[i]( (float)param[i] / numsteps[i] );       // 0..1
182}
183
184/// \brief Returns integer value of the specified numeric parameter, in range 0...number-of-steps
185///
186/// Example: Get( fIntensity ) = 0..100. Converter functions (if present) are applied to the result.
187int Parameters::GetInt( number_t i ) {
188        //assert( ffunc[i] != NULL );
189        float r = ffunc[i]( param[i] );
190        return (int)(r+0.5);    // 0..numsteps[i]
191}
192
193void Parameters::SetBool( bool_t ID, bool b ) {
194        bparam[ID] = b;
195
196        CDXUTCheckBox* checkBox;
197        if ( radiogroup[ID] >= 0)
198                checkBox = g_HUD->GetRadioButton( ID+checkboxID0 );
199        else
200                checkBox = g_HUD->GetCheckBox( ID+checkboxID0 );
201
202        bSilent = true;
203        if( checkBox != NULL )
204                checkBox->SetChecked( bparam[ID] );
205        bSilent = false;
206
207        bchfunc[ID]();
208}
209
210void Parameters::SetFloat( number_t ID, float v ) {
211        SetInt( ID, (int)( v*numsteps[ID] + 0.5 ));
212}
213
214void Parameters::SetInt( number_t ID, int v ) {
215        param[ID] = v;
216        if ( param[ID] < 0 )    param[ID] = 0;
217        else if ( param[ID] > numsteps[ID] )   
218        {
219                if (rotate[ID])
220                        param[ID] = 0;
221                else
222                        param[ID] = numsteps[ID];
223        }
224
225        bSilent = true;
226
227        // everything is updated
228        if( g_HUD->GetSlider( ID+sliderID0 ) != NULL )
229                g_HUD->GetSlider( ID+sliderID0 )->SetValue( param[ID] );
230
231        wchar_t text[30];
232        _sntprintf( text, 30, L"%.2f", Get( (number_t)ID ) );
233
234        if( g_HUD->GetStatic( ID+staticID0 ) != NULL )
235                g_HUD->GetStatic( ID+staticID0 )->SetText( text );
236
237        // user-defined callback
238        //assert( chfunc[ID] != NULL );
239        chfunc[ID]();
240
241        bSilent = false;
242}
243
244void Parameters::SetEnabled( bool_t ID, bool bEnabled ) {
245
246        CDXUTCheckBox* checkBox;
247        if ( radiogroup[ID] >= 0)
248                checkBox = g_HUD->GetRadioButton( ID+checkboxID0 );
249        else
250                checkBox = g_HUD->GetCheckBox( ID+checkboxID0 );
251        checkBox->SetEnabled( bEnabled );
252}
253
254void Parameters::SetEnabled( number_t ID, bool bEnabled ) {
255        g_HUD->GetSlider( ID+sliderID0 )->SetEnabled( bEnabled );
256        g_HUD->GetCheckBox( ID+downID0 )->SetEnabled( bEnabled );
257        g_HUD->GetCheckBox( ID+upID0   )->SetEnabled( bEnabled );
258}
259
260/// \brief Updates the specified parameter from the GUI.
261///
262/// Since a GUI event provides the id of the sender (see OnGUIEvent() in Main.cpp),
263/// we can update the parameter value belonging to that control.
264///
265/// In case of Load/Save, parameters are loaded from/saved to the file called <b>.params</b>.
266/// In case of Reset, parameters are loaded from the file called <b>.params0</b>.
267
268void Parameters::UpdateFromHUD( int controlID ) {
269
270        //if (bSilent) return;
271
272        // Reset, Save & Load buttons
273        if (controlID == IDC_RESET_BUTTON ) {
274                LoadFromFile( ".params0" );
275                chfunc[ LAST_NUMBER ]();
276        }
277        else if (controlID == IDC_SAVE_BUTTON ) {
278                SaveToFile( ".params" );
279                chfunc[ LAST_NUMBER+1 ]();
280        }
281        else if (controlID == IDC_LOAD_BUTTON ) {
282                LoadFromFile( ".params" );
283                chfunc[ LAST_NUMBER+2 ]();
284        }
285
286        // a checkbox or radio button
287        else if (controlID >= checkboxID0 && controlID < checkboxID0+LAST_BOOL)
288        {
289                int ID = controlID - checkboxID0;
290
291                CDXUTCheckBox* checkBox;
292
293                // radio button
294                if ( radiogroup[ID] >= 0) {
295                        checkBox = g_HUD->GetRadioButton( controlID );  // get radio button...
296                        if (checkBox->GetChecked())
297                        {
298                                for (int i=0; i<LAST_BOOL; i++)
299                                  if ( i!=ID && radiogroup[i] == radiogroup[ID])
300                                          SetBool( (bool_t)i, false);                   // ... and clear all others in the group
301                        }
302                }
303                else
304                {
305                        // checkbox
306                        checkBox = g_HUD->GetCheckBox( controlID );
307                }
308
309                if ( checkBox->GetEnabled() )
310                        SetBool( (bool_t)ID, checkBox->GetChecked());
311        }
312
313        // a slider
314        else if (controlID >= sliderID0 && controlID < sliderID0+LAST_NUMBER)   {
315                int v = g_HUD->GetSlider( controlID )->GetValue();
316                int ID = controlID - sliderID0;
317                if ( g_HUD->GetSlider( controlID )->GetEnabled() )
318                        SetInt( (number_t)ID, v);
319        }
320
321        // a hotkey (bound to an invisible checkbox) that decrements a slider
322        else if (controlID >= downID0 && controlID < downID0+LAST_NUMBER)       {       // down
323                int ID = controlID-downID0;
324                if ( g_HUD->GetSlider( ID+sliderID0 )->GetEnabled() )
325                        SetInt( (number_t)ID, param[ID]-1 );
326        }
327
328        // a hotkey (bound to an invisible checkbox) that increments a slider
329        else if (controlID >= upID0 && controlID < upID0+LAST_NUMBER) {                 // up
330                int ID = controlID-upID0;
331                if ( g_HUD->GetSlider( ID+sliderID0 )->GetEnabled() )
332                        SetInt( (number_t)ID, param[ID]+1 );
333        }
334}
335
336/// \brief Writes all parameter values into the specified file.
337void Parameters::SaveToFile( char* fileName ) {
338        FILE* fileS;
339        if( ( fileS = fopen( fileName, "wt" ) ) == NULL )
340        {
341                wchar_t wbuf[ CHARBUFFER_SIZE ];
342                mbstowcs( wbuf, fileName, CHARBUFFER_SIZE );
343                MessageBox( NULL, wbuf, L"File creation failed!", MB_ICONERROR );                       // show error message
344                return;
345        }
346
347        int versionNum = LAST_BOOL*10 + LAST_NUMBER;
348        fwprintf( fileS, L"%i version ----- RayTraceEffects: Saved parameters of the algorithm -----\n",
349                versionNum );
350
351        fwprintf( fileS, L"Bool values:\n" );
352        for ( int i=0; i<LAST_BOOL; i++)
353                fwprintf( fileS, L"%i", (int)bparam[i] );
354        fwprintf( fileS, L"\n" );
355
356        fwprintf( fileS, L"(" );
357        for ( int i=0; i<LAST_BOOL; i++)
358                fwprintf( fileS, L"%s; ", bname[i] );
359        fwprintf( fileS, L")\n" );
360
361        fwprintf( fileS, L"Float values:\n" );
362
363        for ( int i=0; i<LAST_NUMBER; i++)
364                fwprintf( fileS, L"%i \t(%s, 0..%i)\n", param[i], name[i], numsteps[i] );
365
366        fclose(fileS);
367}
368
369/// \brief Loads all parameter values from the specified file.
370void Parameters::LoadFromFile( char* fileName ) {
371
372        char buf[ CHARBUFFER_SIZE ];
373        wchar_t wbuf[ CHARBUFFER_SIZE ];
374        mbstowcs( wbuf, fileName, CHARBUFFER_SIZE );
375
376        FILE* fileL;
377    if( ( fileL = fopen( fileName, "rt" ) ) == NULL )
378        {
379                MessageBox( NULL, wbuf, L"File not found!", MB_ICONERROR );                     // show error message
380                return;
381        }
382
383        fgets( buf, CHARBUFFER_SIZE, fileL );
384
385        int versionNum = LAST_BOOL*10 + LAST_NUMBER;
386        int savedVersionNum = -1;
387        sscanf( buf, "%i", &savedVersionNum );
388
389        if (versionNum != savedVersionNum)
390        {
391                wchar_t errbuf[ CHARBUFFER_SIZE ];
392                mbstowcs( wbuf, fileName, CHARBUFFER_SIZE );
393                swprintf( errbuf, L"Wrong param file: %s\n(Required version: %i, found: %i)\n\n"
394                        L"- Press [S]ave\n"
395                        L"- Then copy:\n      '.params' --> '.params0'!",
396                        wbuf, versionNum, savedVersionNum);
397                MessageBox( NULL, errbuf, L"Version mismatch!", MB_ICONERROR );                 // show error message
398                return;
399        }
400
401        fgets( buf, CHARBUFFER_SIZE, fileL );                   // skip comment
402
403        for ( int i=0; i<LAST_BOOL; i++)
404        {
405                int num = fgetc( fileL ) - '0';
406                SetBool( (bool_t)i, num > 0 );
407        }
408
409        fgets( buf, CHARBUFFER_SIZE, fileL );                   // skip line
410        fgets( buf, CHARBUFFER_SIZE, fileL );                   // skip comment
411        fgets( buf, CHARBUFFER_SIZE, fileL );                   // skip comment
412
413        for ( int i=0; i<LAST_NUMBER; i++)
414        {
415                fgets( buf, CHARBUFFER_SIZE, fileL );
416                int v;
417                sscanf( buf, "%i", &v );
418                SetInt( (number_t)i, v );
419        }
420
421        fclose(fileL);
422}
Note: See TracBrowser for help on using the repository browser.