]> 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/14 12:32:26 $
7   Version:   $Revision: 1.19 $
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     //    this->bbUserOnShow();
514   }
515   //=========================================================================
516   
517   //==================================================================
518   /// Specific methods for window creation during pipeline execution
519   /// Shows the window associated to the box 
520   /// (called after bbProcess during bbExecute)
521   void WxBlackBox::bbShowWindow()
522   {
523     bbtkDebugMessageInc("wx",1,"=> WxBlackBox::bbShowWindow() ["
524                         <<bbGetFullName()<<"]"<<std::endl);
525  
526     // If Event Handler for the widget does not exist or is obsolete : create it 
527     if (bbGetOutputWidget()!=0)
528       {
529         if (bbGetWidgetEventHandler()==0)
530           {
531             bbtkDebugMessage("wx",3,
532                              "-> No widget event handler : creating one"
533                              <<std::endl);
534             new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
535                                              bbGetOutputWidget());
536           }
537         else if ( ! bbGetWidgetEventHandler()->IsHandlerOf 
538                   ( bbGetOutputWidget() ) )
539           {
540             bbtkDebugMessage("wx",3,
541                              "-> Obsolete widget event handler : re-creating one"
542                              <<std::endl);
543             delete bbGetWidgetEventHandler();
544             new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
545                                              bbGetOutputWidget());
546           }
547         // Sets the name of the wxWindow to the input WinTitle
548         bbGetOutputWidget()->SetName(bbtk::std2wx(bbGetInputWinTitle()));
549       }
550
551     // If the output 'Widget' is connected then it's gonna 
552     // be captured by its parent window : nothing to do 
553     if ( (*bbGetOutputConnectorMap().find("Widget")).second
554          ->GetConnectionVector().size() != 0 ) 
555       {
556         
557         bbtkDebugMessage("wx",2,
558                          "-> Output 'Widget' connected : nothing to do"
559                          <<std::endl);
560         return;
561       }
562
563
564     Window* show = 0;
565     // If the window already exists : no need creating it
566     if (bbGetWindow()!=0)
567       {
568         bbtkDebugMessage("wx",2,
569                          "-> Window already exists"
570                          <<std::endl);
571         show = bbGetWindow();
572       }
573     // Else if the widget exists : create window 
574     else if (bbGetOutputWidget()!=0) 
575       {
576         bbtkDebugMessage("wx",2,
577                          "-> Widget exists : creating the window"
578                          <<std::endl);
579
580
581         // Input WinDialog set to true : creating a Dialog
582         if (bbGetInputWinDialog()) 
583           {
584             bbtkDebugMessage("wx",2,
585                              "   Input WinDialog set to true : creating a Dialog"
586                              <<std::endl);
587             show = (Window*) new WxBlackBoxDialog( GetThisPointer<WxBlackBox>(),
588                                                    bbGetWxParent(), 
589                                                    std2wx( bbGetInputWinTitle() + " - bbtk (c) CREATIS LRMN"),
590                                                    wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
591           }
592         // Input WinDialog set to false : creating a Frame
593         else 
594           {
595             bbtkDebugMessage("process",2,
596                              "   Input WinDialog set to false : creating a Frame"
597                              <<std::endl);
598             show = (Window*) new WxBlackBoxFrame( GetThisPointer<WxBlackBox>(),
599                                                   bbGetWxParent(), 
600                                                   std2wx( bbGetInputWinTitle()  + " - bbtk (c) CREATIS LRMN"),
601                                                   wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
602           }
603
604       }
605     // No window nor widget : error
606     else
607       {
608         bbtkError("WxBlackBox::bbShowWindow() ["
609                   <<bbGetFullName()
610                   <<"] : No widget. Did you set the box output 'Widget' in the processing method of the box ?");
611       }
612  
613     
614     // Show the window
615     if (true) //!show->IsShown())
616       {
617         show->bbShow(); 
618       }
619     else 
620       {
621         bbtkDebugMessage("wx",2,"-> Already shown : nothing to do"<<std::endl);
622       }
623   
624
625     bbtkDebugMessage("wx",1,"<= WxBlackBox::bbShowWindow() ["
626                         <<bbGetFullName()<<"]"<<std::endl);
627
628   }
629   //==================================================================
630
631
632
633
634   //==================================================================
635    void WxBlackBox::bbHideWindow()
636   {
637     bbtkDebugMessageInc("wx",1,"=> WxBlackBox::bbHideWindow() ["
638                         <<bbGetFullName()<<"]"<<std::endl);
639
640     if (bbGetWindow()!=0) bbGetWindow()->bbHide();
641
642     bbtkDebugMessageDec("wx",1,"<= WxBlackBox::bbHideWindow() ["
643                         <<bbGetFullName()<<"]"<<std::endl);
644   }
645   //==================================================================
646
647
648   //==================================================================
649   WxBlackBox::Window* WxBlackBox::bbGetContainingWindow()
650   {
651     if (bbGetWindow()!=0) return bbGetWindow();
652     BlackBox::OutputConnectorMapType::const_iterator i 
653       = bbGetOutputConnectorMap().find("Widget");
654     if ( i->second->GetConnectionVector().size() != 0 ) 
655       {
656         return boost::static_pointer_cast<WxBlackBox>
657           (i->second->GetConnectionVector().front() //.lock()
658            ->GetBlackBoxTo())->bbGetContainingWindow();
659       }
660     return 0;
661   }
662   //==================================================================
663
664
665   //==================================================================
666   wxWindow* WxBlackBox::bbGetWxParent() { return Wx::GetTopWindow(); }
667   //==================================================================
668   
669   
670   //==================================================================
671   bool WxBlackBox::bbIsShown()
672   {
673     if (bbGetContainingWindow()!=0)
674       return bbGetContainingWindow()->bbIsShown();
675     return false;
676   }
677   //==================================================================
678
679
680 }//namespace bbtk
681
682
683 #endif
684