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