]> Creatis software - bbtk.git/blob - packages/wx/src/bbwxSlider.cxx
MagicBox : support of data synchronization + various related fixes
[bbtk.git] / packages / wx / src / bbwxSlider.cxx
1 /*=========================================================================                                                                               
2   Program:   bbtk
3   Module:    $RCSfile: bbwxSlider.cxx,v $
4   Language:  C++
5   Date:      $Date: 2009/03/30 14:42:28 $
6   Version:   $Revision: 1.21 $
7 =========================================================================*/
8
9 /* ---------------------------------------------------------------------
10
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
13 *
14 *  This software is governed by the CeCILL-B license under French law and 
15 *  abiding by the rules of distribution of free software. You can  use, 
16 *  modify and/ or redistribute the software under the terms of the CeCILL-B 
17 *  license as circulated by CEA, CNRS and INRIA at the following URL 
18 *  http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html 
19 *  or in the file LICENSE.txt.
20 *
21 *  As a counterpart to the access to the source code and  rights to copy,
22 *  modify and redistribute granted by the license, users are provided only
23 *  with a limited warranty  and the software's author,  the holder of the
24 *  economic rights,  and the successive licensors  have only  limited
25 *  liability. 
26 *
27 *  The fact that you are presently reading this means that you have had
28 *  knowledge of the CeCILL-B license and that you accept its terms.
29 * ------------------------------------------------------------------------ */                                                                         
30
31 /**
32  * \file 
33  * \brief Short description in one line
34  *
35  * Long 
36  * description
37  *  
38  */
39
40 #ifdef _USE_WXWIDGETS_
41
42 #include "bbwxSlider.h"
43 #include "bbwxPackage.h"
44 #include "bbtkUtilities.h"
45
46 namespace bbwx
47 {
48   //--------------------------------------------------------------------------
49   // The widget created by the box 
50   class SliderWidget : public wxPanel 
51   {
52   public:
53     /// Ctor with the two first params the parent window and the creator box
54     /// which must be passed to the WxBlackBoxWidget constructor.
55     /// The other params initialize the widget 
56     SliderWidget(Slider* box, wxWindow *parent,
57                  int orientation,
58                  bool changeresolution,
59                  bool label, 
60                  wxString title,
61                  int vmin,
62                  int vmax,
63                  int value,
64                  bool track);
65     /// Dtor
66     ~SliderWidget();
67     /// Events callbacks
68     /// Called when the slider is moved
69     void OnSliderTrack(wxScrollEvent& event);
70     /// Called when the slider is released
71     void OnSliderRelease(wxScrollEvent& event);
72     /// Called when the little slider which controls the resolution
73     /// of the main slider is moved (if activated)
74     void OnResolutionOfSlider(wxScrollEvent& event);
75
76     // Accessors
77     void SetValue(int v) { mwxSlider->SetValue(v); }
78     int  GetValue() { return mwxSlider->GetValue(); }
79     void SetRange(int min, int max);
80     // Update the texts which display the min/max/current values of the slider
81     void RefreshLabels();
82         
83   private:
84     Slider*    mBox;
85     wxSlider   *mwxSlider;
86     wxSlider   *mResolutionOfSlider;
87     int        min;
88     int        max;
89     bool       reactiveOnTrack;
90     wxStaticText        *label_vertical;
91     wxStaticText        *label_min;
92     wxStaticText        *label_max;
93   };
94   //------------------------------------------------------------------------
95   //------------------------------------------------------------------------
96   //------------------------------------------------------------------------
97
98   
99     
100   //-------------------------------------------------------------------------
101   SliderWidget::SliderWidget(Slider* box, wxWindow *parent,
102                              int orientation,
103                              bool changeresolution,
104                              bool labels,
105                              wxString title,
106                              int vmin,
107                              int vmax,
108                              int value,
109                              bool reactiveontrack)
110     :  
111     wxPanel( parent, -1, wxDefaultPosition, wxDefaultSize, wxTAB_TRAVERSAL),
112     mBox(box),
113     min(vmin),
114     max(vmax),
115     reactiveOnTrack(reactiveontrack)
116   {
117     wxPanel * panel = this;
118     
119     label_min           = NULL;
120     label_max           = NULL;
121     label_vertical      = NULL;
122     mResolutionOfSlider = NULL;
123
124     int sizeX,sizeY;
125     long wxlabels=0;
126     long wxorientation=0;
127     if (orientation==0) 
128       {
129         sizeX                   = 2; 
130         sizeY                   = 40;
131         wxorientation           = wxSL_HORIZONTAL;
132         if (labels==true)
133           {
134             wxlabels = wxSL_LABELS;
135           }
136       } 
137     else 
138       {
139         sizeX           = 20;
140         sizeY           = 2;
141         wxorientation   = wxSL_VERTICAL;
142       }
143     
144     //---------------------------------------------------------------------
145     // 1) Creation of the components of the widget
146     // Any top level sub-widget must have the panel returned by panel
147     // for parent
148     mwxSlider = new wxSlider( panel, 
149                               -1, 0 , 0, 500 , 
150                               wxDefaultPosition, 
151                               wxSize(sizeX,sizeY), 
152                               wxorientation  | wxlabels );
153
154     //    mwxSlider->SetInitialSize(wxSize(sizeX,sizeY));
155
156     //  mwxSlider->SetTickFreq(100,0);
157     mwxSlider->SetRange(min,max);
158     mwxSlider->SetValue(value);
159
160     //    RefreshLabels();
161
162     // Connecting events to callbacks
163     Connect( mwxSlider->GetId(), 
164              wxEVT_SCROLL_THUMBRELEASE, 
165              (wxObjectEventFunction) 
166              (void (wxPanel::*)(wxScrollEvent&))
167              &SliderWidget::OnSliderRelease ); 
168
169     Connect( mwxSlider->GetId(),  
170              wxEVT_SCROLL_THUMBTRACK, 
171              (wxObjectEventFunction) 
172              (void (wxPanel::*)(wxScrollEvent&))
173               &SliderWidget::OnSliderTrack ); 
174     
175     Connect( mwxSlider->GetId(),  
176              wxEVT_SCROLL_CHANGED, 
177              (wxObjectEventFunction) 
178              (void (wxPanel::*)(wxScrollEvent&))
179               &SliderWidget::OnSliderTrack );
180                
181     // If asked : creation of the other little slider which allows to change 
182     // the resolution of the main slider
183     if (changeresolution==true){
184       // has panel for parent too
185       mResolutionOfSlider = new wxSlider(panel,
186                                          -1,5,1,10,
187                                          wxDefaultPosition,
188                                          wxSize(25,45),
189                                          wxSL_VERTICAL | 
190                                          wxSL_AUTOTICKS |
191                                          wxSL_LEFT  );
192    
193
194       mResolutionOfSlider->SetRange(1,8);
195       mResolutionOfSlider->SetValue(5);
196       // Is wxEVT_COMMAND_SLIDER_UPDATED event 
197       // is connected to the method OnResolutionOfSlider
198       Connect(mResolutionOfSlider->GetId(),
199               wxEVT_COMMAND_SLIDER_UPDATED,
200               (wxObjectEventFunction) 
201               (void (wxPanel::*)(wxScrollEvent&))
202               &SliderWidget::OnResolutionOfSlider ); 
203     }
204     //---------------------------------------------------------------------
205
206     //---------------------------------------------------------------------
207     // 2) Insertion of the components in the window
208     
209     // We use a FlexGridSizer
210     wxFlexGridSizer *sizer;
211
212
213     if (orientation==0) 
214       {
215         // HORIZONTAL
216         if (mResolutionOfSlider!=NULL) 
217           {
218             sizer       = new wxFlexGridSizer(2);
219             if (title!=_T(""))
220               {
221                 sizer   -> Add( new wxStaticText(panel,-1, title ) ); 
222                 sizer   -> Add( new wxStaticText(panel,-1, _T("") ) ); 
223               }
224           } 
225         else 
226           {
227             sizer       = new wxFlexGridSizer(1);
228             if (title!=_T(""))
229               {
230                 sizer   -> Add( new wxStaticText(panel,-1, title ) ); 
231               }
232           }
233         sizer   -> Add( mwxSlider,1,wxGROW ); 
234         sizer   -> AddGrowableCol(0);
235         if (mResolutionOfSlider!=NULL) 
236           {
237             sizer       -> Add( mResolutionOfSlider ); 
238           }
239       } 
240     else 
241       {
242         // VERTICAL 
243         sizer   = new wxFlexGridSizer(1);
244         if (labels==true)  // with lable
245           {
246             label_vertical = new wxStaticText(panel,-1,_T(""));
247             label_min = new wxStaticText(panel,-1,_T(""));
248             label_max = new wxStaticText(panel,-1,_T(""));
249             if (title!=_T(""))
250               {
251                 sizer   -> Add( new wxStaticText(panel,-1, title ) );
252                 sizer   -> AddGrowableRow(3);
253               } 
254             else 
255               {
256                 sizer   -> AddGrowableRow(2);
257               }
258             sizer       -> Add( label_vertical );
259             sizer       -> Add( label_min );
260             sizer       -> Add( mwxSlider,1,wxGROW );
261             sizer       -> Add( label_max );
262             if (mResolutionOfSlider!=NULL) 
263               {
264                 sizer   -> Add( mResolutionOfSlider ); 
265               }
266           } 
267         else 
268           {
269             if (title!=_T(""))
270               {
271                 sizer   -> Add( new wxStaticText(panel,-1, title ) );
272                 sizer   -> AddGrowableRow(1);
273               } 
274             else 
275               {
276                 sizer   -> AddGrowableRow(0);
277               }
278             sizer       -> Add( mwxSlider,1,wxGROW );
279             if (mResolutionOfSlider!=NULL) 
280               {
281                 sizer   -> Add( mResolutionOfSlider ); 
282               }
283           }
284       }
285     // Initialize the labels 
286     RefreshLabels();  
287     // Insert the sizer in the main panel and refresh the layout
288     panel->SetSizer(sizer);
289   }
290   //-------------------------------------------------------------------------
291   
292
293   //-------------------------------------------------------------------------
294   SliderWidget::~SliderWidget()
295   {
296   }
297   //-------------------------------------------------------------------------
298
299
300   //-------------------------------------------------------------------------
301   void SliderWidget::OnResolutionOfSlider(wxScrollEvent& event)
302   {
303     int value = mwxSlider->GetValue();
304     int delta = (int) (pow( 4 , mResolutionOfSlider->GetValue() ));
305     int minTmp   = value - delta/2;
306     int maxTmp   = value + delta/2;
307     if (minTmp<min)
308       {
309         minTmp = min;
310         //              maxTmp = delta;
311       }
312     if (maxTmp>max)
313       {
314         maxTmp = max;
315       }
316     mwxSlider->SetRange(minTmp,maxTmp);
317     RefreshLabels();
318   }
319   //-------------------------------------------------------------------------
320
321
322
323   //-------------------------------------------------------------------------
324   void SliderWidget::OnSliderTrack(wxScrollEvent& event)
325   {
326     if(reactiveOnTrack)
327     {
328     // When user releases the slider 
329     // we update the output of the box
330     
331     mBox->bbSetOutputOut( mwxSlider->GetValue() );
332     mBox->bbSetInputIn( mwxSlider->GetValue() );
333     // and signal that the output has changed
334         mBox->bbSignalOutputModification(std::string("Out"));    
335     }
336     RefreshLabels();
337   }
338   //-------------------------------------------------------------------------
339
340
341   //-------------------------------------------------------------------------
342   void SliderWidget::OnSliderRelease(wxScrollEvent& event)
343   {
344     // When user releases the slider 
345     // we update the output of the box
346     mBox->bbSetOutputOut( mwxSlider->GetValue() );
347     mBox->bbSetInputIn( mwxSlider->GetValue() );
348     // and signal that the output has changed
349         mBox->bbSignalOutputModification(std::string("Out"));
350   }
351   //-------------------------------------------------------------------------
352   
353
354   //-------------------------------------------------------------------------
355   void SliderWidget::RefreshLabels()
356   {
357     wxString strValue;
358     if (label_vertical!=NULL)
359       {
360         strValue.Printf( _T("%d"), mwxSlider->GetValue() );
361         label_vertical->SetLabel(strValue);
362       }
363     if (label_min!=NULL)
364       {
365         strValue.Printf( _T("%d"), mwxSlider->GetMin() );
366         label_min->SetLabel(strValue);
367       }
368     if (label_max!=NULL)
369       {
370         strValue.Printf( _T("%d"), mwxSlider->GetMax() );
371         label_max->SetLabel(strValue);
372       }  
373   }
374   //-------------------------------------------------------------------------
375   
376
377   //-------------------------------------------------------------------------
378   void SliderWidget::SetRange(int min, int max)
379   {
380     this->min = min;
381     this->max = max;
382     mwxSlider->SetRange(min,max);
383     RefreshLabels();
384   }
385   //-------------------------------------------------------------------------
386
387  
388
389
390   //--------------------------------------------------------------------------
391   //-------------------------------------------------------------------------
392   // WxBlackBox implementation
393   //--------------------------------------------------------------------------
394   //--------------------------------------------------------------------------
395
396   //--------------------------------------------------------------------------
397   BBTK_BLACK_BOX_IMPLEMENTATION(Slider,bbtk::WxBlackBox);
398   BBTK_ADD_BLACK_BOX_TO_PACKAGE(wx,Slider);
399   
400   //--------------------------------------------------------------------------
401   void Slider::bbUserConstructor() 
402   { 
403     bbSetInputIn(0);
404     bbSetInputMin(0);
405     bbSetInputMax(500);
406     bbSetOutputOut(0);
407     bbSetInputOrientation("HORIZONTAL");
408     bbSetInputChangeResolution(false);
409     bbSetInputLabel(true);
410     bbSetInputReactiveOnTrack(false);    
411   }
412   
413   //--------------------------------------------------------------------------
414   void Slider::Process() 
415   {
416     bbtkDebugMessage("process",3,
417                      "Slider "<<bbGetName()<<" input="
418                      <<bbGetInputIn()<<std::endl);
419    
420     bbSetOutputOut( bbGetInputIn() );
421     if (bbGetOutputWidget()!=0)
422       {
423         ((SliderWidget*)bbGetOutputWidget())->SetValue(bbGetInputIn());
424       }
425   }
426
427   void Slider::CreateWidget(wxWindow* parent)
428   {
429
430     int orientation=0;
431     if (bbtk::Utilities::loosematch(bbGetInputOrientation(),"0|H|HORIZONTAL")==true)  { orientation=0; }
432     if (bbtk::Utilities::loosematch(bbGetInputOrientation(),"1|V|VERTICAL")==true)    { orientation=1; }
433     
434     
435     //    std::cout << "bbGetWxParent = "<<bbGetWxParent()<<std::endl;
436     SliderWidget *w =  new SliderWidget(this, 
437                                         parent, //bbGetWxParent(),
438                                         orientation , 
439                                         bbGetInputChangeResolution(), 
440                                         bbGetInputLabel(), 
441                                         bbtk::std2wx( bbGetInputTitle() ),
442                                         bbGetInputMin(), 
443                                         bbGetInputMax(),
444                                         bbGetInputIn(),
445                                         bbGetInputReactiveOnTrack()
446                                         ); 
447     //    std::cout << "w = "<<w<<std::endl;
448     //  w->SetName( bbtk::std2wx( bbGetInputWinTitle() ) );
449           
450     bbSetOutputWidget( w );
451   }
452   
453
454 } //namespace bbwx
455
456 #endif // _USE_WXWIDGETS_ 
457
458