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