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