]> 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/06/27 08:12:46 $
7   Version:   $Revision: 1.23 $
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
234
235 #if defined(_WIN32)
236       wxFrame::Refresh();
237 #endif
238
239       wxFrame::Update();
240       wxFrame::SetFocus();
241     if (bbGetBlackBox()) bbGetBlackBox()->bbUserOnShow();
242   }
243   //=========================================================================
244
245   //=========================================================================
246   void WxBlackBoxFrame::bbHide()
247   {
248     bbtkDebugMessage("wx",9,"WxBlackBoxFrame::bbHide()"<<std::endl);
249     WxBlackBoxWindow::bbHide();
250     wxFrame::Hide();
251     if (bbGetBlackBox()) bbGetBlackBox()->bbUserOnHide();
252   }
253   //=========================================================================
254
255   //=========================================================================
256   void WxBlackBoxFrame::bbClose()
257   {
258     wxFrame::Close();
259   }
260   //=========================================================================
261
262
263
264   //=========================================================================
265   // WxBlackBoxWidgetEventHandler
266   //=========================================================================
267
268   //=========================================================================
269   WxBlackBoxWidgetEventHandler::
270   WxBlackBoxWidgetEventHandler( WxBlackBox::Pointer box, 
271                                 wxWindow *widget )
272     :
273     mBox(box),
274     mWindow(widget)
275   { 
276     bbtkDebugMessage("wx",9,"WxBlackBoxWidgetEventHandler::WxBlackBoxWidgetEventHandler("<<mBox.lock()->bbGetFullName()<<")"<<std::endl);
277
278     mBox.lock()->bbSetWidgetEventHandler(this);
279
280     Connect (  mWindow->GetId(),
281                wxEVT_DESTROY,
282                (wxObjectEventFunction) 
283                (void (wxEvtHandler::*)(wxWindowDestroyEvent& c))
284                 &WxBlackBoxWidgetEventHandler::OnWindowDestroy );
285     
286     mWindow->PushEventHandler(this);
287     
288   }
289   //=========================================================================
290
291   //=========================================================================
292   WxBlackBoxWidgetEventHandler::~WxBlackBoxWidgetEventHandler()
293   {
294     if (mBox.expired()) return;
295     bbtkDebugMessage("wx",9,
296                      "WxBlackBoxWidgetEventHandler::~WxBlackBoxWidgetEventHandler() ["
297                      <<mBox.lock()->bbGetFullName()<<"]"<<std::endl);
298      mBox.lock()->bbSetWidgetEventHandler(0);   
299   }
300   //=========================================================================
301
302   //=========================================================================
303   void WxBlackBoxWidgetEventHandler::OnWindowDestroy(wxWindowDestroyEvent&)
304   {
305     if (mBox.expired()) return;
306     bbtkDebugMessage("wx",9,"WxBlackBoxWidgetEventHandler::OnWindowDestroy() ["
307                      <<mBox.lock()->bbGetFullName()<<"]"<<std::endl);
308     mBox.lock()->bbSetOutputWidget(0);
309     mBox.lock()->bbSetModifiedStatus();
310   }
311   //=========================================================================
312
313
314
315
316
317
318
319   //=========================================================================
320   // WxBlackBox
321   //=========================================================================
322
323   //=========================================================================
324   //=========================================================================
325   //=========================================================================
326   //=========================================================================
327   BBTK_BLACK_BOX_IMPLEMENTATION(WxBlackBox,AtomicBlackBox);
328   //=========================================================================
329   
330   //=========================================================================
331   void WxBlackBox::bbUserConstructor()
332   {
333     bbtkDebugMessage("Kernel",9,"WxBlackBox::bbUserConstructor()"<<std::endl);
334     bbInitAttributes();
335   }
336   //=========================================================================
337
338   //=========================================================================
339   void WxBlackBox::bbUserCopyConstructor()
340   {
341     bbtkDebugMessage("Kernel",9,"WxBlackBox::bbUserCopyConstructor()"
342                      <<std::endl);
343     bbInitAttributes();
344   }
345   //=========================================================================
346
347
348   //=========================================================================
349   void WxBlackBox::bbUserDestructor()
350   {
351     bbtkDebugMessage("wx",9,"==> WxBlackBox::bbUserDestructor() ["<<bbGetFullName()<<"]"<<std::endl);
352     if (bbGetWindow()) {
353       delete bbGetWindow();
354       bbSetWindow(0);
355     }
356     bbtkDebugMessage("wx",9,"<== WxBlackBox::bbUserDestructor() ["<<bbGetFullName()<<"]"<<std::endl);
357   }
358   //=========================================================================
359   
360
361   /*
362   //=========================================================================
363   WxBlackBox::Widget*  WxBlackBox::bbGetWidget()
364   { 
365     if (bbGetOutputWidget() && bbGetOutputWidget()->IsDead()) 
366       {
367         bbtkDebugMessage("wx",9,"WxBlackBox::bbGetWidget() ["<<
368                          bbGetFullName()<<"] : Widget is dead : deleting it"
369                          <<std::endl);
370         delete bbGetOutputWidget();
371         bbSetOutputWidget(0);
372       }
373     return bbGetOutputWidget();
374   }
375   //=========================================================================
376   */
377
378
379   //=========================================================================
380   /**
381    * \brief Initialize the attributes of the class
382    *
383    */
384   void WxBlackBox::bbInitAttributes()
385   {
386     bbmWindow = 0;
387     //    bbmWidget = 0;
388     //    bbSetInputWinParent(0);
389     bbSetInputWinTitle(bbGetName());
390     bbSetInputWinWidth(800);
391     bbSetInputWinHeight(800);
392     bbSetInputWinDialog(false);
393     bbSetOutputWidget(0);
394
395     bbSetWidgetEventHandler(0);
396     bbSetUpdateTransferedToParent(false);
397   }
398   //=========================================================================
399
400   //=========================================================================
401   /// Main processing method of the box.
402   void WxBlackBox::bbExecute(bool force)
403   {
404     bbtkDebugMessageInc("process",2,
405                         "=> WxBlackBox::bbExecute() ["
406                         <<bbGetFullName()<<"]"<<std::endl);
407
408     // If the output 'Widget' is connected then 
409     // we must execute the parent box
410     BlackBox::OutputConnectorMapType::const_iterator i 
411       = bbGetOutputConnectorMap().find("Widget");
412
413     if ( i->second->GetConnectionVector().size() != 0 ) 
414       {
415         bbtkDebugMessage("process",3,
416                          "-> Output 'Widget' connected : transfering execution to parent"
417                          <<std::endl);
418         
419         i->second->GetConnectionVector().front() //.lock()
420           ->GetBlackBoxTo()->bbExecute(force);
421
422       }
423     // else call 'standard' BlackBox execution method
424     else 
425       {
426         BlackBox::bbExecute(force);
427       }
428     //
429
430     bbtkDebugMessageDec("process",2,
431                         "<= WxBlackBox::bbExecute() ["
432                         <<bbGetFullName()<<"]"<<std::endl);
433   }
434   //=========================================================================
435
436
437   //=========================================================================
438   /// Main processing method of the box.
439   IOStatus WxBlackBox::bbBackwardUpdate( Connection::Pointer caller )
440   {
441     bbtkDebugMessage("process",3,
442                      "=> WxBlackBox::bbBackwardUpdate("
443                      <<(caller?caller->GetFullName():"0")<<") ["
444                      <<bbGetFullName()<<"]"<<std::endl);
445     // If the caller's box to is not the box to connected to the 
446     // output 'Widget'
447     if ( ! (( bbGetStatus() == MODIFIED ) ||
448             ( bbBoxProcessModeIsAlways() )) )
449       {
450         bbtkDebugMessage("process",3,"Up-to-date : nothing to do"<<std::endl);
451         bbtkDebugMessage("process",3,
452                          "<= WxBlackBox::bbBackwardUpdate("
453                          <<(caller?caller->GetFullName():"0")<<") ["
454                          <<bbGetFullName()<<"]"<<std::endl);
455         return bbGetStatus();
456       }
457  
458     BlackBox::OutputConnectorMapType::const_iterator i 
459       = bbGetOutputConnectorMap().find("Widget") ;
460     if ( i->second->GetConnectionVector().size() != 0 )
461       
462       {
463         BlackBox::Pointer to = 
464           i->second->GetConnectionVector()[0]->GetBlackBoxTo();
465                 
466         if (caller) 
467           {
468             bbtkDebugMessage("process",3,
469                              "-> Output 'Widget' connected to '"
470                              <<to->bbGetFullName()<<"' - caller->to = '"
471                              <<caller->GetBlackBoxTo()->bbGetFullName()
472                              <<"'"
473                              <<std::endl);
474           }
475         else
476           {
477             bbtkDebugMessage("process",3,
478                              "-> Output 'Widget' connected to '"
479                              <<to->bbGetFullName()<<"'"
480                              <<std::endl);
481           }
482         if ((caller==0) ||
483             ((caller!=0) && 
484              (caller->GetBlackBoxTo() != to))&&
485             (!bbGetUpdateTransferedToParent())&&
486             (to->bbGetStatus()!=UPDATING))
487           {
488             bbtkDebugMessage("process",3,
489                              "   ... Transfering update order to parent"
490                              <<std::endl);
491             
492             bbSetUpdateTransferedToParent(true);
493             i->second->GetConnectionVector().front() //.lock()
494               ->GetBlackBoxTo()->bbExecute(false);
495           }
496         else
497           {
498             bbSetUpdateTransferedToParent(false);
499             bbtkDebugMessage("process",3,
500                              "   ... No need to transfer to parent"
501                              <<std::endl);
502           }
503       }
504     /*    
505
506     // If the caller is not the connection to the output widget
507     // and the output 'Widget' is connected then 
508     // we must execute the parent box 
509     // but only one time 
510     // (this is the role of the flag UpdateTransferedToParent)
511     if ( (caller==0) ||
512          ((caller!=0)&&(caller->GetBlackBoxFromOutput()!="Widget"))
513          )
514       {
515       }
516     */
517     // call 'standard' BlackBox execution method
518     if (!bbGetUpdateTransferedToParent()) 
519       { 
520           AtomicBlackBox::bbBackwardUpdate(caller);
521       }
522     
523     bbtkDebugMessageDec("process",3,
524                         "<= WxBlackBox::bbBackwardUpdate() ["
525                         <<bbGetFullName()<<"]"<<std::endl);
526     
527    return bbGetStatus();
528      
529
530   }
531
532   //=========================================================================
533   void WxBlackBox::bbProcess()
534   { 
535     if (bbGetOutputWidget()==0) this->bbUserCreateWidget();
536     this->bbUserProcess(); 
537     bbShowWindow();
538     //    this->bbUserOnShow();
539   }
540   //=========================================================================
541   
542   //==================================================================
543   /// Specific methods for window creation during pipeline execution
544   /// Shows the window associated to the box 
545   /// (called after bbProcess during bbExecute)
546   void WxBlackBox::bbShowWindow()
547   {
548     bbtkDebugMessageInc("wx",1,"=> WxBlackBox::bbShowWindow() ["
549                         <<bbGetFullName()<<"]"<<std::endl);
550  
551     // If Event Handler for the widget does not exist or is obsolete : create it 
552     if (bbGetOutputWidget()!=0)
553       {
554         if (bbGetWidgetEventHandler()==0)
555           {
556             bbtkDebugMessage("wx",3,
557                              "-> No widget event handler : creating one"
558                              <<std::endl);
559             new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
560                                              bbGetOutputWidget());
561           }
562         else if ( ! bbGetWidgetEventHandler()->IsHandlerOf 
563                   ( bbGetOutputWidget() ) )
564           {
565             bbtkDebugMessage("wx",3,
566                              "-> Obsolete widget event handler : re-creating one"
567                              <<std::endl);
568             delete bbGetWidgetEventHandler();
569             new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
570                                              bbGetOutputWidget());
571           }
572         // Sets the name of the wxWindow to the input WinTitle
573         bbGetOutputWidget()->SetName(bbtk::std2wx(bbGetInputWinTitle()));
574       }
575
576     // If the output 'Widget' is connected then it's gonna 
577     // be captured by its parent window : nothing to do 
578     if ( (*bbGetOutputConnectorMap().find("Widget")).second
579          ->GetConnectionVector().size() != 0 ) 
580       {
581         
582         bbtkDebugMessage("wx",2,
583                          "-> Output 'Widget' connected : nothing to do"
584                          <<std::endl);
585         return;
586       }
587
588
589     Window* show = 0;
590     // If the window already exists : no need creating it
591     if (bbGetWindow()!=0)
592       {
593         bbtkDebugMessage("wx",2,
594                          "-> Window already exists"
595                          <<std::endl);
596         show = bbGetWindow();
597       }
598     // Else if the widget exists : create window 
599     else if (bbGetOutputWidget()!=0) 
600       {
601         bbtkDebugMessage("wx",2,
602                          "-> Widget exists : creating the window"
603                          <<std::endl);
604
605
606         // Input WinDialog set to true : creating a Dialog
607         if (bbGetInputWinDialog()) 
608           {
609             bbtkDebugMessage("wx",2,
610                              "   Input WinDialog set to true : creating a Dialog"
611                              <<std::endl);
612             show = (Window*) new WxBlackBoxDialog( GetThisPointer<WxBlackBox>(),
613                                                    bbGetWxParent(), 
614                                                    std2wx( bbGetInputWinTitle() + " - bbtk (c) CREATIS LRMN"),
615                                                    wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
616           }
617         // Input WinDialog set to false : creating a Frame
618         else 
619           {
620             bbtkDebugMessage("process",2,
621                              "   Input WinDialog set to false : creating a Frame"
622                              <<std::endl);
623             show = (Window*) new WxBlackBoxFrame( GetThisPointer<WxBlackBox>(),
624                                                   bbGetWxParent(), 
625                                                   std2wx( bbGetInputWinTitle()  + " - bbtk (c) CREATIS LRMN"),
626                                                   wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
627           }
628
629       }
630     // No window nor widget : error
631     else
632       {
633         bbtkError("WxBlackBox::bbShowWindow() ["
634                   <<bbGetFullName()
635                   <<"] : No widget. Did you set the box output 'Widget' in the processing method of the box ?");
636       }
637  
638     
639     // Show the window
640     if (true) //!show->IsShown())
641       {
642         show->bbShow(); 
643       }
644     else 
645       {
646         bbtkDebugMessage("wx",2,"-> Already shown : nothing to do"<<std::endl);
647       }
648   
649
650     bbtkDebugMessage("wx",1,"<= WxBlackBox::bbShowWindow() ["
651                         <<bbGetFullName()<<"]"<<std::endl);
652
653   }
654   //==================================================================
655
656
657
658
659   //==================================================================
660    void WxBlackBox::bbHideWindow()
661   {
662     bbtkDebugMessageInc("wx",1,"=> WxBlackBox::bbHideWindow() ["
663                         <<bbGetFullName()<<"]"<<std::endl);
664
665     if (bbGetWindow()!=0) bbGetWindow()->bbHide();
666
667     bbtkDebugMessageDec("wx",1,"<= WxBlackBox::bbHideWindow() ["
668                         <<bbGetFullName()<<"]"<<std::endl);
669   }
670   //==================================================================
671
672
673   //==================================================================
674    void WxBlackBox::bbCloseWindow()
675   {
676     bbtkDebugMessageInc("wx",1,"=> WxBlackBox::bbCloseWindow() ["
677                         <<bbGetFullName()<<"]"<<std::endl);
678
679     if (bbGetWindow()!=0) bbGetWindow()->bbClose();
680
681     bbtkDebugMessageDec("wx",1,"<= WxBlackBox::bbCloseWindow() ["
682                         <<bbGetFullName()<<"]"<<std::endl);
683   }
684   //==================================================================
685
686   //==================================================================
687   WxBlackBox::Window* WxBlackBox::bbGetContainingWindow()
688   {
689     if (bbGetWindow()!=0) return bbGetWindow();
690     BlackBox::OutputConnectorMapType::const_iterator i 
691       = bbGetOutputConnectorMap().find("Widget");
692     if ( i->second->GetConnectionVector().size() != 0 ) 
693       {
694         return boost::static_pointer_cast<WxBlackBox>
695           (i->second->GetConnectionVector().front() //.lock()
696            ->GetBlackBoxTo())->bbGetContainingWindow();
697       }
698     return 0;
699   }
700   //==================================================================
701
702
703   //==================================================================
704   wxWindow* WxBlackBox::bbGetWxParent() { return Wx::GetTopWindow(); }
705   //==================================================================
706   
707   
708   //==================================================================
709   bool WxBlackBox::bbIsShown()
710   {
711     if (bbGetContainingWindow()!=0)
712       return bbGetContainingWindow()->bbIsShown();
713     return false;
714   }
715   //==================================================================
716
717
718 }//namespace bbtk
719
720
721 #endif
722