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