]> Creatis software - bbtk.git/blob - kernel/src/bbtkWxBlackBox.cxx
*** empty log message ***
[bbtk.git] / kernel / src / bbtkWxBlackBox.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   bbtk
4   Module:    $RCSfile: bbtkWxBlackBox.cxx,v $
5   Language:  C++
6   Date:      $Date: 2008/04/22 14:30:25 $
7   Version:   $Revision: 1.14 $
8                                                                                 
9   Copyright (c) CREATIS (Centre de Recherche et d'Applications en Traitement de
10   l'Image). All rights reserved. See Doc/License.txt or
11   http://www.creatis.insa-lyon.fr/Public/bbtk/License.html for details.
12                                                                                 
13      This software is distributed WITHOUT ANY WARRANTY; without even
14      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15      PURPOSE.  See the above copyright notices for more information.
16                                                                                 
17 =========================================================================*/
18
19 #ifdef _USE_WXWIDGETS_
20
21
22
23 /**
24  *  \file 
25  *  \brief 
26  */
27  
28 #include "bbtkWxBlackBox.h"
29 //#include "bbtkWxContainerBlackBox.h"
30 #include <wx/dialog.h>
31
32 //#include "bbtkData.h"
33 //#include "bbtkFactory.h"
34
35
36
37
38 namespace bbtk
39 {
40
41
42
43
44   //=========================================================================
45   // WxBlackBoxWindow
46   //=========================================================================
47
48
49
50   //=========================================================================
51   WxBlackBoxWindow::WxBlackBoxWindow(WxBlackBox::Pointer box)
52     : mBox(box), mShown(false)
53   {
54     bbtkDebugMessage("wx",9,"WxBlackBoxWindow::WxBlackBoxWindow("<<
55                      mBox.lock()->bbGetFullName()<<")"<<std::endl);
56     mBox.lock()->bbSetWindow(this);
57     Wx::IncNbWindowsAlive();
58     bbtkDebugMessage("wx",5," -> Number of windows alive = "
59                      <<Wx::GetNbWindowsAlive()<<std::endl);
60   }
61   //=========================================================================
62
63   //=========================================================================
64   WxBlackBoxWindow::~WxBlackBoxWindow()
65   {
66     bbtkDebugMessage("wx",9,"WxBlackBoxWindow::~WxBlackBoxWindow() "
67                      <<this<<std::endl);
68     bbHide();
69     Wx::DecNbWindowsAlive();
70     if (!mBox.expired())
71       {
72         mBox.lock()->bbSetWindow(0);
73       }
74     else 
75       {
76       }
77     bbtkDebugMessage("wx",5," -> Number of windows alive = "
78                      <<Wx::GetNbWindowsAlive()<<std::endl);
79   }
80   //========================================================================= 
81
82
83   //=========================================================================
84   void WxBlackBoxWindow::bbShow()
85   {
86     if (bbIsShown()) return;
87     bbtkDebugMessage("wx",9,"WxBlackBoxWindow::bbShow()"<<std::endl);
88     Wx::IncNbWindowsShown();
89     mShown = true;
90     bbtkDebugMessage("wx",5," -> Number of windows shown = "
91                      <<Wx::GetNbWindowsShown()<<std::endl);
92   }
93   //=========================================================================
94
95   //=========================================================================
96   void WxBlackBoxWindow::bbHide()
97   {
98     if (!bbIsShown()) return;
99     bbtkDebugMessage("wx",9,"WxBlackBoxWindow::bbHide()"<<std::endl);
100     Wx::DecNbWindowsShown();
101     mShown = false;
102     bbtkDebugMessage("wx",5," -> Number of windows shown = "
103                      <<Wx::GetNbWindowsShown()<<std::endl);
104   }
105   //=========================================================================
106
107
108
109   //=========================================================================
110   // WxBlackBoxDialog
111   //=========================================================================
112
113   //=========================================================================
114   WxBlackBoxDialog::WxBlackBoxDialog(WxBlackBox::Pointer box,
115                                      wxWindow *parent,
116                                      wxString title,
117                                      wxSize size)
118     :
119     WxBlackBoxWindow(box),
120     wxDialog( parent, 
121                 -1, 
122                 title,
123                 wxDefaultPosition,
124                 size,
125                 wxRESIZE_BORDER | 
126                 wxSYSTEM_MENU  |
127                 wxCLOSE_BOX |
128                 wxMAXIMIZE_BOX | 
129                 wxMINIMIZE_BOX | 
130                 wxCAPTION  
131                 )
132   {
133     bbtkDebugMessage("wx",9,"WxBlackBoxDialog::WxBlackBoxDialog("<<
134                      bbGetBlackBox()->bbGetFullName()<<","<<parent<<","
135                      <<title<<",size)"<<std::endl);
136     // Insert the widget into the window
137     wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
138     wxWindow* widget = bbGetBlackBox()->bbGetOutputWidget();
139     widget->Reparent(this);
140     sizer->Add( widget, 1, wxALL|wxEXPAND, 2);
141     //SetAutoLayout(true);
142     SetSizer(sizer);
143     Layout();
144   }
145   //=========================================================================
146   
147   //=========================================================================
148   void WxBlackBoxDialog::bbShow()
149   { 
150     bbtkDebugMessage("wx",5,"WxBlackBoxDialog::bbShow() ["
151                      <<bbGetBlackBox()->bbGetFullName()<<"]"<<std::endl);
152     WxBlackBoxWindow::bbShow();
153     SetReturnCode( wxDialog::ShowModal() ); 
154   }
155   //=========================================================================
156
157   //=========================================================================
158   void WxBlackBoxDialog::bbHide()
159   {
160     bbtkDebugMessage("wx",9,"WxBlackBoxDialog::bbHide()"<<std::endl);
161     WxBlackBoxWindow::bbHide();
162     Hide();
163   }
164   //=========================================================================
165
166   //=========================================================================
167   WxBlackBoxDialog::~WxBlackBoxDialog()
168   {
169   }
170   //=========================================================================
171
172
173
174
175
176   //=========================================================================
177   // WxBlackBoxFrame
178   //=========================================================================
179
180   //=========================================================================
181   WxBlackBoxFrame::WxBlackBoxFrame(WxBlackBox::Pointer box,
182                                    wxWindow *parent,
183                                    wxString title,
184                                    wxSize size)
185     : WxBlackBoxWindow(box),
186       wxFrame( parent, 
187                -1, 
188                title,
189                wxDefaultPosition,
190                size,
191                wxRESIZE_BORDER | 
192                wxSYSTEM_MENU  |
193                wxCLOSE_BOX |
194                wxMAXIMIZE_BOX | 
195                wxMINIMIZE_BOX | 
196                wxCAPTION  
197                )
198   {
199     bbtkDebugMessage("wx",9,"WxBlackBoxFrame::WxBlackBoxFrame("<<
200                      bbGetBlackBox()->bbGetFullName()<<","<<parent<<","
201                      <<title<<",size)"<<std::endl);
202     // Insert the widget into the window
203     wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
204     wxWindow* widget = bbGetBlackBox()->bbGetOutputWidget();
205     wxFrame* frame = (wxFrame*)this;
206     widget->Reparent(frame);
207     sizer->Add( widget, 1, wxALL|wxGROW, 2);
208     //  frame->SetAutoLayout(true);
209     frame->SetSizer(sizer);
210     //frame->Fit();
211     frame->Layout();
212   }
213   //=========================================================================
214   
215   //=========================================================================
216   WxBlackBoxFrame::~WxBlackBoxFrame()
217   {
218   }
219   //=========================================================================
220
221   //=========================================================================
222   void WxBlackBoxFrame::bbShow() 
223   { 
224     bbtkDebugMessage("wx",5,"WxBlackBoxFrame::bbShow("
225                      <<bbGetBlackBox()->bbGetFullName()<<")"<<std::endl);
226     WxBlackBoxWindow::bbShow();
227     wxFrame::Show();
228     // This Update is ** MANDATORY ** 
229     // to synchronize wxvtkRenderWindowInteractor objects
230     // (force wx objects creation **NOW**)
231     wxFrame::Update();
232     if (bbGetBlackBox()) bbGetBlackBox()->bbUserOnShow();
233     //    wxFrame::SetFocus();
234   }
235   //=========================================================================
236
237   //=========================================================================
238   void WxBlackBoxFrame::bbHide()
239   {
240     bbtkDebugMessage("wx",9,"WxBlackBoxFrame::bbHide()"<<std::endl);
241     WxBlackBoxWindow::bbHide();
242     wxFrame::Hide();
243     if (bbGetBlackBox()) bbGetBlackBox()->bbUserOnHide();
244   }
245   //=========================================================================
246
247
248
249
250   //=========================================================================
251   // WxBlackBoxWidgetEventHandler
252   //=========================================================================
253
254   //=========================================================================
255   WxBlackBoxWidgetEventHandler::
256   WxBlackBoxWidgetEventHandler( WxBlackBox::Pointer box, 
257                                 wxWindow *widget )
258     :
259     mBox(box),
260     mWindow(widget)
261   { 
262     bbtkDebugMessage("wx",9,"WxBlackBoxWidgetEventHandler::WxBlackBoxWidgetEventHandler("<<mBox.lock()->bbGetFullName()<<")"<<std::endl);
263
264     mBox.lock()->bbSetWidgetEventHandler(this);
265
266     Connect (  mWindow->GetId(),
267                wxEVT_DESTROY,
268                (wxObjectEventFunction) 
269                (void (wxEvtHandler::*)(wxWindowDestroyEvent& c))
270                 &WxBlackBoxWidgetEventHandler::OnWindowDestroy );
271     
272     mWindow->PushEventHandler(this);
273     
274   }
275   //=========================================================================
276
277   //=========================================================================
278   WxBlackBoxWidgetEventHandler::~WxBlackBoxWidgetEventHandler()
279   {
280     if (mBox.expired()) return;
281     bbtkDebugMessage("wx",9,
282                      "WxBlackBoxWidgetEventHandler::~WxBlackBoxWidgetEventHandler() ["
283                      <<mBox.lock()->bbGetFullName()<<"]"<<std::endl);
284      mBox.lock()->bbSetWidgetEventHandler(0);   
285   }
286   //=========================================================================
287
288   //=========================================================================
289   void WxBlackBoxWidgetEventHandler::OnWindowDestroy(wxWindowDestroyEvent&)
290   {
291     if (mBox.expired()) return;
292     bbtkDebugMessage("wx",9,"WxBlackBoxWidgetEventHandler::OnWindowDestroy() ["
293                      <<mBox.lock()->bbGetFullName()<<"]"<<std::endl);
294     mBox.lock()->bbSetOutputWidget(0);
295     mBox.lock()->bbSetModifiedStatus();
296   }
297   //=========================================================================
298
299
300
301
302
303
304
305   //=========================================================================
306   // WxBlackBox
307   //=========================================================================
308
309   //=========================================================================
310   //=========================================================================
311   //=========================================================================
312   //=========================================================================
313   BBTK_BLACK_BOX_IMPLEMENTATION(WxBlackBox,AtomicBlackBox);
314   //=========================================================================
315   
316   //=========================================================================
317   void WxBlackBox::bbUserConstructor()
318   {
319     bbtkDebugMessage("Kernel",9,"WxBlackBox::bbUserConstructor()"<<std::endl);
320     bbInitAttributes();
321   }
322   //=========================================================================
323
324   //=========================================================================
325   void WxBlackBox::bbUserCopyConstructor()
326   {
327     bbtkDebugMessage("Kernel",9,"WxBlackBox::bbUserCopyConstructor()"
328                      <<std::endl);
329     bbInitAttributes();
330   }
331   //=========================================================================
332
333
334   //=========================================================================
335   void WxBlackBox::bbUserDestructor()
336   {
337     bbtkDebugMessage("wx",9,"==> WxBlackBox::bbUserDestructor() ["<<bbGetFullName()<<"]"<<std::endl);
338     if (bbGetWindow()) {
339       delete bbGetWindow();
340       bbSetWindow(0);
341     }
342     bbtkDebugMessage("wx",9,"<== WxBlackBox::bbUserDestructor() ["<<bbGetFullName()<<"]"<<std::endl);
343   }
344   //=========================================================================
345   
346
347   /*
348   //=========================================================================
349   WxBlackBox::Widget*  WxBlackBox::bbGetWidget()
350   { 
351     if (bbGetOutputWidget() && bbGetOutputWidget()->IsDead()) 
352       {
353         bbtkDebugMessage("wx",9,"WxBlackBox::bbGetWidget() ["<<
354                          bbGetFullName()<<"] : Widget is dead : deleting it"
355                          <<std::endl);
356         delete bbGetOutputWidget();
357         bbSetOutputWidget(0);
358       }
359     return bbGetOutputWidget();
360   }
361   //=========================================================================
362   */
363
364
365   //=========================================================================
366   /**
367    * \brief Initialize the attributes of the class
368    *
369    */
370   void WxBlackBox::bbInitAttributes()
371   {
372     bbmWindow = 0;
373     //    bbmWidget = 0;
374     //    bbSetInputWinParent(0);
375     bbSetInputWinTitle(bbGetName());
376     bbSetInputWinWidth(800);
377     bbSetInputWinHeight(800);
378     bbSetInputWinDialog(false);
379     bbSetOutputWidget(0);
380
381     bbSetWidgetEventHandler(0);
382   }
383   //=========================================================================
384
385   //=========================================================================
386   /// Main processing method of the box.
387   void WxBlackBox::bbExecute(bool force)
388   {
389     bbtkDebugMessageInc("Process",1,
390                         "=> WxBlackBox::bbExecute() ["
391                         <<bbGetFullName()<<"]"<<std::endl);
392
393     // If the output 'Widget' is connected then 
394     // we must execute the parent box
395     BlackBox::OutputConnectorMapType::const_iterator i 
396       = bbGetOutputConnectorMap().find("Widget");
397
398     if ( i->second->GetConnectionVector().size() != 0 ) 
399       {
400         bbtkDebugMessage("Process",2,
401                          "-> Output 'Widget' connected : transfering execution to parent"
402                          <<std::endl);
403         
404         i->second->GetConnectionVector().front() //.lock()
405           ->GetBlackBoxTo()->bbExecute(force);
406
407       }
408     // else call 'standard' BlackBox execution method
409     else 
410       {
411         BlackBox::bbExecute(force);
412       }
413     //
414
415     bbtkDebugMessageDec("Process",1,
416                         "<= WxBlackBox::bbExecute() ["
417                         <<bbGetFullName()<<"]"<<std::endl);
418   }
419   //=========================================================================
420
421
422   //=========================================================================
423   /// Main processing method of the box.
424   IOStatus WxBlackBox::bbBackwardUpdate( Connection::Pointer caller )
425   {
426     bbtkDebugMessageInc("Process",1,
427                         "=> WxBlackBox::bbBackwardUpdate("
428                         <<(caller?caller->GetFullName():"0")<<") ["
429                         <<bbGetFullName()<<"]"<<std::endl);
430     // If the caller is not the connection to the output widget
431     // and the output 'Widget' is connected then 
432     // we must execute the parent box 
433     // but only one time 
434     // (this is the role of the flag UpdateTransferedToParent=
435     if ( (caller==0) ||
436          ((caller!=0)&&(caller->GetBlackBoxFromOutput()!="Widget"))
437          )
438       {
439         BlackBox::OutputConnectorMapType::const_iterator i 
440           = bbGetOutputConnectorMap().find("Widget") ;
441         if ( i->second->GetConnectionVector().size() != 0 )
442              
443           {
444             bbtkDebugMessage("Process",2,
445                              "-> Output 'Widget' connected : transfering update order to parent"
446                              <<std::endl);
447             if ( bbGetUpdateTransferedToParent() )          
448               {
449                 bbSetUpdateTransferedToParent(false);
450                 bbtkDebugMessage("Process",2,
451                                  "   ... already transfered : abort"
452                                  <<std::endl);
453               }
454             else 
455               {
456                 bbSetUpdateTransferedToParent(true);
457                 i->second->GetConnectionVector().front() //.lock()
458                   ->GetBlackBoxTo()->bbExecute(false);
459               }
460           }
461       }
462     // call 'standard' BlackBox execution method
463     if (!bbGetUpdateTransferedToParent()) 
464       { 
465         AtomicBlackBox::bbBackwardUpdate(caller);
466       }
467     
468     bbtkDebugMessageDec("Process",1,
469                         "<= WxBlackBox::bbBackwardUpdate() ["
470                         <<bbGetFullName()<<"]"<<std::endl);
471     
472   }
473
474   //=========================================================================
475   void WxBlackBox::bbProcess()
476   { 
477     if (bbGetOutputWidget()==0) this->bbUserCreateWidget();
478     this->bbUserProcess(); 
479     bbShowWindow();
480   }
481   //=========================================================================
482   
483   //==================================================================
484   /// Specific methods for window creation during pipeline execution
485   /// Shows the window associated to the box 
486   /// (called after bbProcess during bbExecute)
487   void WxBlackBox::bbShowWindow()
488   {
489     bbtkDebugMessageInc("Process",1,"=> WxBlackBox::bbShowWindow() ["
490                         <<bbGetFullName()<<"]"<<std::endl);
491  
492     // If Event Handler for the widget does not exist or is obsolete : create it 
493     if (bbGetOutputWidget()!=0)
494       {
495         if (bbGetWidgetEventHandler()==0)
496           {
497             bbtkDebugMessage("Process",3,
498                              "-> No widget event handler : creating one"
499                              <<std::endl);
500             new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
501                                              bbGetOutputWidget());
502           }
503         else if ( ! bbGetWidgetEventHandler()->IsHandlerOf 
504                   ( bbGetOutputWidget() ) )
505           {
506             bbtkDebugMessage("Process",3,
507                              "-> Obsolete widget event handler : re-creating one"
508                              <<std::endl);
509             delete bbGetWidgetEventHandler();
510             new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
511                                              bbGetOutputWidget());
512           }
513         // Sets the name of the wxWindow to the input WinTitle
514         bbGetOutputWidget()->SetName(bbtk::std2wx(bbGetInputWinTitle()));
515       }
516
517     // If the output 'Widget' is connected then it's gonna 
518     // be captured by its parent window : nothing to do 
519     if ( (*bbGetOutputConnectorMap().find("Widget")).second
520          ->GetConnectionVector().size() != 0 ) 
521       {
522         
523         bbtkDebugMessage("Process",2,
524                          "-> Output 'Widget' connected : nothing to do"
525                          <<std::endl);
526         bbtkDebugDecTab("Process",1);
527         return;
528       }
529
530
531     Window* show = 0;
532     // If the window already exists : no need creating it
533     if (bbGetWindow()!=0)
534       {
535         bbtkDebugMessage("Process",2,
536                          "-> Window already exists"
537                          <<std::endl);
538         show = bbGetWindow();
539       }
540     // Else if the widget exists : create window 
541     else if (bbGetOutputWidget()!=0) 
542       {
543         bbtkDebugMessage("Process",2,
544                          "-> Widget exists : creating the window"
545                          <<std::endl);
546
547
548         // Input WinDialog set to true : creating a Dialog
549         if (bbGetInputWinDialog()) 
550           {
551             bbtkDebugMessage("Process",2,
552                              "   Input WinDialog set to true : creating a Dialog"
553                              <<std::endl);
554             show = (Window*) new WxBlackBoxDialog( GetThisPointer<WxBlackBox>(),
555                                                    bbGetWxParent(), 
556                                                    std2wx( bbGetInputWinTitle() + " - bbtk (c) CREATIS LRMN"),
557                                                    wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
558           }
559         // Input WinDialog set to false : creating a Frame
560         else 
561           {
562             bbtkDebugMessage("Process",2,
563                              "   Input WinDialog set to false : creating a Frame"
564                              <<std::endl);
565             show = (Window*) new WxBlackBoxFrame( GetThisPointer<WxBlackBox>(),
566                                                   bbGetWxParent(), 
567                                                   std2wx( bbGetInputWinTitle()  + " - bbtk (c) CREATIS LRMN"),
568                                                   wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
569           }
570
571       }
572     // No window nor widget : error
573     else
574       {
575         bbtkError("WxBlackBox::bbShowWindow() ["
576                   <<bbGetFullName()
577                   <<"] : No widget. Did you set the box output 'Widget' in the processing method of the box ?");
578       }
579  
580     
581     // Show the window
582     if (true) //!show->IsShown())
583       {
584         show->bbShow(); 
585       }
586     else 
587       {
588         bbtkDebugMessage("Process",2,"-> Already shown : nothing to do"<<std::endl);
589       }
590   
591
592     bbtkDebugMessage("Process",1,"<= WxBlackBox::bbShowWindow() ["
593                         <<bbGetFullName()<<"]"<<std::endl);
594     bbtkDebugDecTab("Process",1);
595   }
596   //==================================================================
597
598
599
600
601   //==================================================================
602    void WxBlackBox::bbHideWindow()
603   {
604     bbtkDebugMessageInc("Process",1,"=> WxBlackBox::bbHideWindow() ["
605                         <<bbGetFullName()<<"]"<<std::endl);
606
607     if (bbGetWindow()!=0) bbGetWindow()->bbHide();
608
609     bbtkDebugMessageDec("Process",1,"<= WxBlackBox::bbHideWindow() ["
610                         <<bbGetFullName()<<"]"<<std::endl);
611   }
612   //==================================================================
613
614
615   //==================================================================
616   WxBlackBox::Window* WxBlackBox::bbGetContainingWindow()
617   {
618     if (bbGetWindow()!=0) return bbGetWindow();
619     BlackBox::OutputConnectorMapType::const_iterator i 
620       = bbGetOutputConnectorMap().find("Widget");
621     if ( i->second->GetConnectionVector().size() != 0 ) 
622       {
623         return boost::static_pointer_cast<WxBlackBox>
624           (i->second->GetConnectionVector().front() //.lock()
625            ->GetBlackBoxTo())->bbGetContainingWindow();
626       }
627     return 0;
628   }
629   //==================================================================
630
631
632   //==================================================================
633   wxWindow* WxBlackBox::bbGetWxParent() { return Wx::GetTopWindow(); }
634   //==================================================================
635   
636   
637   //==================================================================
638   bool WxBlackBox::bbIsShown()
639   {
640     if (bbGetContainingWindow()!=0)
641       return bbGetContainingWindow()->bbIsShown();
642     return false;
643   }
644   //==================================================================
645
646
647 }//namespace bbtk
648
649
650 #endif
651