1 /*=========================================================================
3 Module: $RCSfile: bbtkWxBlackBox.cxx,v $
5 Date: $Date: 2008/12/03 09:38:02 $
6 Version: $Revision: 1.32 $
7 =========================================================================*/
9 /* ---------------------------------------------------------------------
11 * Copyright (c) CREATIS-LRMN (Centre de Recherche en Imagerie Medicale)
12 * Authors : Eduardo Davila, Laurent Guigues, Jean-Pierre Roux
14 * This software is governed by the CeCILL-B license under French law and
15 * abiding by the rules of distribution of free software. You can use,
16 * modify and/ or redistribute the software under the terms of the CeCILL-B
17 * license as circulated by CEA, CNRS and INRIA at the following URL
18 * http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
19 * or in the file LICENSE.txt.
21 * As a counterpart to the access to the source code and rights to copy,
22 * modify and redistribute granted by the license, users are provided only
23 * with a limited warranty and the software's author, the holder of the
24 * economic rights, and the successive licensors have only limited
27 * The fact that you are presently reading this means that you have had
28 * knowledge of the CeCILL-B license and that you accept its terms.
29 * ------------------------------------------------------------------------ */
32 #ifdef _USE_WXWIDGETS_
41 #include "bbtkWxBlackBox.h"
42 //#include "bbtkWxContainerBlackBox.h"
43 #include <wx/dialog.h>
45 //#include "bbtkData.h"
46 //#include "bbtkFactory.h"
57 //=========================================================================
59 //=========================================================================
63 //=========================================================================
64 WxBlackBoxWindow::WxBlackBoxWindow(WxBlackBox::Pointer box)
65 : mBox(box), mShown(false)
67 bbtkDebugMessage("wx",9,"WxBlackBoxWindow::WxBlackBoxWindow("<<
68 mBox.lock()->bbGetFullName()<<")"<<std::endl);
69 mBox.lock()->bbSetWindow(this);
70 Wx::IncNbWindowsAlive();
72 //=========================================================================
74 //=========================================================================
75 WxBlackBoxWindow::~WxBlackBoxWindow()
77 bbtkDebugMessage("wx",9,"WxBlackBoxWindow::~WxBlackBoxWindow() "
80 Wx::DecNbWindowsAlive();
83 mBox.lock()->bbSetWindow(0);
86 //=========================================================================
89 //=========================================================================
90 void WxBlackBoxWindow::bbShow()
92 if (bbIsShown()) return;
93 bbtkDebugMessage("wx",9,"WxBlackBoxWindow::bbShow()"<<std::endl);
94 Wx::IncNbWindowsShown();
97 //=========================================================================
99 //=========================================================================
100 void WxBlackBoxWindow::bbHide()
102 if (!bbIsShown()) return;
103 bbtkDebugMessage("wx",9,"WxBlackBoxWindow::bbHide()"<<std::endl);
104 Wx::DecNbWindowsShown();
107 //=========================================================================
109 //=========================================================================
110 void WxBlackBoxWindow::bbClose()
113 //=========================================================================
116 //=========================================================================
118 //=========================================================================
120 //=========================================================================
121 WxBlackBoxDialog::WxBlackBoxDialog(WxBlackBox::Pointer box,
138 WxBlackBoxWindow(box)
140 bbtkDebugMessage("wx",9,"WxBlackBoxDialog::WxBlackBoxDialog("<<
141 bbGetBlackBox()->bbGetFullName()<<","<<parent<<","
142 <<title<<",size)"<<std::endl);
143 // Insert the widget into the window
144 wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
145 // LG 22/11/08 : new widget pipeline
146 bbGetBlackBox()->bbCreateWidgetAndEventHandler(this);
147 wxWindow* widget = bbGetBlackBox()->bbGetOutputWidget();
148 // old : widget->Reparent(this);
149 sizer->Add( widget, 1, wxALL|wxEXPAND, 2);
150 //SetAutoLayout(true);
154 //=========================================================================
156 //=========================================================================
157 void WxBlackBoxDialog::bbShow()
159 if (bbIsShown()) return;
160 bbtkDebugMessage("wx",5,"WxBlackBoxDialog::bbShow() ["
161 <<bbGetBlackBox()->bbGetFullName()<<"]"<<std::endl);
162 WxBlackBoxWindow::bbShow();
163 SetReturnCode( wxDialog::ShowModal() );
166 //=========================================================================
168 //=========================================================================
169 void WxBlackBoxDialog::bbHide()
171 bbtkDebugMessage("wx",9,"WxBlackBoxDialog::bbHide()"<<std::endl);
172 WxBlackBoxWindow::bbHide();
175 //=========================================================================
177 //=========================================================================
178 void WxBlackBoxDialog::bbClose()
180 bbtkDebugMessage("wx",9,"WxBlackBoxDialog::bbClose()"<<std::endl);
183 //=========================================================================
185 //=========================================================================
186 WxBlackBoxDialog::~WxBlackBoxDialog()
189 //=========================================================================
195 //=========================================================================
197 //=========================================================================
199 //=========================================================================
200 WxBlackBoxFrame::WxBlackBoxFrame(WxBlackBox::Pointer box,
216 WxBlackBoxWindow(box)
218 bbtkDebugMessage("wx",9,"WxBlackBoxFrame::WxBlackBoxFrame("<<
219 bbGetBlackBox()->bbGetFullName()<<","<<parent<<","
220 <<title<<",size)"<<std::endl);
221 // Insert the widget into the window
222 wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
223 // LG 22/11/08 : new widget pipeline
224 bbGetBlackBox()->bbCreateWidgetAndEventHandler(this);
225 wxWindow* widget = bbGetBlackBox()->bbGetOutputWidget();
226 wxFrame* frame = (wxFrame*)this;
227 // old : widget->Reparent(frame);
228 sizer->Add( widget, 1, wxALL|wxGROW, 2);
229 // frame->SetAutoLayout(true);
230 frame->SetSizer(sizer);
234 //=========================================================================
236 //=========================================================================
237 WxBlackBoxFrame::~WxBlackBoxFrame()
240 //=========================================================================
242 //=========================================================================
243 void WxBlackBoxFrame::bbShow()
245 if (bbIsShown()) return;
246 bbtkDebugMessage("wx",5,"WxBlackBoxFrame::bbShow("
247 <<bbGetBlackBox()->bbGetFullName()<<")"<<std::endl);
248 WxBlackBoxWindow::bbShow();
250 // This Update is ** MANDATORY **
251 // to synchronize wxvtkRenderWindowInteractor objects
252 // (force wx objects creation **NOW**)
261 if (bbGetBlackBox()) bbGetBlackBox()->bbUserOnShow();
263 //=========================================================================
265 //=========================================================================
266 void WxBlackBoxFrame::bbHide()
268 bbtkDebugMessage("wx",9,"WxBlackBoxFrame::bbHide()"<<std::endl);
269 WxBlackBoxWindow::bbHide();
271 if (bbGetBlackBox()) bbGetBlackBox()->bbUserOnHide();
273 //=========================================================================
275 //=========================================================================
276 void WxBlackBoxFrame::bbClose()
278 bbtkDebugMessage("wx",9,"WxBlackBoxFrame::bbClose()"<<std::endl);
281 //=========================================================================
285 //=========================================================================
286 // WxBlackBoxWidgetEventHandler
287 //=========================================================================
289 //=========================================================================
290 WxBlackBoxWidgetEventHandler::
291 WxBlackBoxWidgetEventHandler( WxBlackBox::Pointer box,
297 bbtkDebugMessage("wx",9,"WxBlackBoxWidgetEventHandler::WxBlackBoxWidgetEventHandler("<<mBox.lock()->bbGetFullName()<<")"<<std::endl);
299 mBox.lock()->bbSetWidgetEventHandler(this);
301 Connect ( mWindow->GetId(),
303 (wxObjectEventFunction)
304 (void (wxEvtHandler::*)(wxWindowDestroyEvent& c))
305 &WxBlackBoxWidgetEventHandler::OnWindowDestroy );
307 mWindow->PushEventHandler(this);
310 //=========================================================================
312 //=========================================================================
313 WxBlackBoxWidgetEventHandler::~WxBlackBoxWidgetEventHandler()
315 if (mBox.expired()) return;
316 bbtkDebugMessage("wx",9,
317 "WxBlackBoxWidgetEventHandler::~WxBlackBoxWidgetEventHandler() ["
318 <<mBox.lock()->bbGetFullName()<<"]"<<std::endl);
319 mBox.lock()->bbSetWidgetEventHandler(0);
321 //=========================================================================
323 //=========================================================================
324 void WxBlackBoxWidgetEventHandler::OnWindowDestroy(wxWindowDestroyEvent&)
326 if (mBox.expired()) return;
327 bbtkDebugMessage("wx",9,"WxBlackBoxWidgetEventHandler::OnWindowDestroy() ["
328 <<mBox.lock()->bbGetFullName()<<"]"<<std::endl);
329 mBox.lock()->bbSetOutputWidget(0);
330 mBox.lock()->bbSetModifiedStatus();
332 //=========================================================================
340 //=========================================================================
342 //=========================================================================
344 //=========================================================================
345 //=========================================================================
346 //=========================================================================
347 //=========================================================================
348 BBTK_BLACK_BOX_IMPLEMENTATION(WxBlackBox,AtomicBlackBox);
349 //=========================================================================
351 //=========================================================================
352 void WxBlackBox::bbUserConstructor()
354 bbtkDebugMessage("Kernel",9,"WxBlackBox::bbUserConstructor()"<<std::endl);
357 //=========================================================================
359 //=========================================================================
360 void WxBlackBox::bbUserCopyConstructor(bbtk::BlackBox::Pointer)
362 bbtkDebugMessage("Kernel",9,"WxBlackBox::bbUserCopyConstructor()"
366 //=========================================================================
369 //=========================================================================
370 void WxBlackBox::bbUserDestructor()
372 bbtkDebugMessage("wx",9,"==> WxBlackBox::bbUserDestructor() ["<<bbGetFullName()<<"]"<<std::endl);
374 delete bbGetWindow();
377 bbtkDebugMessage("wx",9,"<== WxBlackBox::bbUserDestructor() ["<<bbGetFullName()<<"]"<<std::endl);
379 //=========================================================================
383 //=========================================================================
384 WxBlackBox::Widget* WxBlackBox::bbGetWidget()
386 if (bbGetOutputWidget() && bbGetOutputWidget()->IsDead())
388 bbtkDebugMessage("wx",9,"WxBlackBox::bbGetWidget() ["<<
389 bbGetFullName()<<"] : Widget is dead : deleting it"
391 delete bbGetOutputWidget();
392 bbSetOutputWidget(0);
394 return bbGetOutputWidget();
396 //=========================================================================
400 //=========================================================================
402 * \brief Initialize the attributes of the class
405 void WxBlackBox::bbInitAttributes()
409 // bbSetInputWinParent(0);
410 bbSetInputWinTitle(bbGetName());
411 bbSetInputWinWidth(800);
412 bbSetInputWinHeight(800);
413 bbSetInputWinDialog(false);
414 bbSetOutputWidget(0);
416 bbSetWidgetEventHandler(0);
417 bbSetUpdateTransferedToParent(false);
419 //=========================================================================
421 //=========================================================================
422 /// Main processing method of the box.
423 void WxBlackBox::bbExecute(bool force)
426 bbtkDebugMessageInc("process",2,
427 "=> WxBlackBox::bbExecute("<<(int)force<<") ["
428 <<bbGetFullName()<<"]"<<std::endl);
431 // If the output 'Widget' is connected then
432 // we must execute the parent box
433 BlackBox::OutputConnectorMapType::const_iterator i
434 = bbGetOutputConnectorMap().find("Widget");
436 if ( i->second->GetConnectionVector().size() != 0 )
438 bbtkDebugMessage("process",3,
439 "-> Output 'Widget' connected : transfering execution to parent"
442 i->second->GetConnectionVector().front() //.lock()
443 ->GetBlackBoxTo()->bbExecute(force);
451 // else call 'standard' BlackBox execution method
455 return AtomicBlackBox::bbExecute(force);
460 bbtkDebugMessageDec("process",2,
461 "<= WxBlackBox::bbExecute() ["
462 <<bbGetFullName()<<"]"<<std::endl);
465 //=========================================================================
468 //=========================================================================
469 /// Main processing method of the box.
470 IOStatus WxBlackBox::bbBackwardUpdate( Connection::Pointer caller )
472 bbtkDebugMessage("process",3,
473 "=> WxBlackBox::bbBackwardUpdate("
474 <<(caller?caller->GetFullName():"0")<<") ["
475 <<bbGetFullName()<<"]"<<std::endl);
477 if ( ! (( bbGetStatus() == MODIFIED ) ||
478 ( bbBoxProcessModeIsAlways() )) )
480 bbtkDebugMessage("process",3,"Up-to-date : nothing to do"<<std::endl);
481 bbtkDebugMessage("process",3,
482 "<= WxBlackBox::bbBackwardUpdate("
483 <<(caller?caller->GetFullName():"0")<<") ["
484 <<bbGetFullName()<<"]"<<std::endl);
485 return bbGetStatus();
488 // If the caller's box to is not the box to connected to the
491 BlackBox::OutputConnectorMapType::const_iterator i
492 = bbGetOutputConnectorMap().find("Widget") ;
493 if ( i->second->GetConnectionVector().size() != 0 )
496 BlackBox::Pointer to =
497 i->second->GetConnectionVector()[0]->GetBlackBoxTo();
501 bbtkDebugMessage("process",3,
502 "-> Output 'Widget' connected to '"
503 <<to->bbGetFullName()<<"' - caller->to = '"
504 <<caller->GetBlackBoxTo()->bbGetFullName()
510 bbtkDebugMessage("process",3,
511 "-> Output 'Widget' connected to '"
512 <<to->bbGetFullName()<<"'"
517 (caller->GetBlackBoxTo() != to)&&
518 (!bbGetUpdateTransferedToParent())&&
519 (!to->bbGetExecuting())
523 bbtkDebugMessage("process",3,
524 " ... Transfering update order to parent"
527 bbSetUpdateTransferedToParent(true);
528 i->second->GetConnectionVector().front() //.lock()
529 ->GetBlackBoxTo()->bbExecute(false);
533 bbSetUpdateTransferedToParent(false);
534 bbtkDebugMessage("process",3,
535 " ... No need to transfer to parent"
542 // If the caller is not the connection to the output widget
543 // and the output 'Widget' is connected then
544 // we must execute the parent box
546 // (this is the role of the flag UpdateTransferedToParent)
548 ((caller!=0)&&(caller->GetBlackBoxFromOutput()!="Widget"))
553 // call 'standard' BlackBox execution method
554 if (!bbGetUpdateTransferedToParent())
556 AtomicBlackBox::bbBackwardUpdate(caller);
559 bbtkDebugMessageDec("process",3,
560 "<= WxBlackBox::bbBackwardUpdate() ["
561 <<bbGetFullName()<<"]"<<std::endl);
563 return bbGetStatus();
568 //=========================================================================
569 void WxBlackBox::bbProcess()
572 if (bbGetOutputWidget()==0) this->bbUserCreateWidget();
573 this->bbUserProcess();
575 // this->bbUserOnShow();
577 // LG 22/11/08 : new widget pipeline
578 // If output widget not connected :
579 if ( (*bbGetOutputConnectorMap().find("Widget")).second
580 ->GetConnectionVector().size() == 0 )
583 // If the window already exists : no need creating it
584 if (bbGetWindow()!=0)
586 bbtkDebugMessage("wx",2,
587 "-> Window already exists"
589 show = bbGetWindow();
591 // Else create window
594 bbtkDebugMessage("wx",2,
595 "-> Creating the window"
599 // Input WinDialog set to true : creating a Dialog
600 if (bbGetInputWinDialog())
602 bbtkDebugMessage("wx",2,
603 " Input WinDialog set to true : creating a Dialog"
605 show = (Window*) new WxBlackBoxDialog( GetThisPointer<WxBlackBox>(),
607 // LG 24/11/08 : New widget pipeline
609 std2wx( bbGetInputWinTitle() + " - bbtk (c) CREATIS LRMN"),
610 wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
612 // Input WinDialog set to false : creating a Frame
615 bbtkDebugMessage("process",2,
616 " Input WinDialog set to false : creating a Frame"
618 show = (Window*) new WxBlackBoxFrame( GetThisPointer<WxBlackBox>(),
620 // LG 24/11/08 : New widget pipeline
622 std2wx( bbGetInputWinTitle() + " - bbtk (c) CREATIS LRMN"),
623 wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
633 this->bbUserProcess();
636 //=========================================================================
640 // LG 24/11/08 : New widget pipeline
641 void WxBlackBox::bbCreateWidgetAndEventHandler(wxWindow* parent)
643 if (bbGetOutputWidget()==0)
645 this->bbUserCreateWidget(parent);
647 // If Event Handler for the widget does not exist or is obsolete : create it
648 if (bbGetOutputWidget()!=0)
650 if (bbGetWidgetEventHandler()==0)
652 bbtkDebugMessage("wx",3,
653 "-> No widget event handler : creating one"
655 new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
656 bbGetOutputWidget());
658 else if ( ! bbGetWidgetEventHandler()->IsHandlerOf
659 ( bbGetOutputWidget() ) )
661 bbtkDebugMessage("wx",3,
662 "-> Obsolete widget event handler : re-creating one"
664 delete bbGetWidgetEventHandler();
665 new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
666 bbGetOutputWidget());
668 // Sets the name of the wxWindow to the input WinTitle
669 bbGetOutputWidget()->SetName(bbtk::std2wx(bbGetInputWinTitle()));
677 wxWindow* WxBlackBox::bbCreateWidgetOfInput(const std::string& in, wxWindow* parent)
680 // If input is connected
681 BlackBoxInputConnector* c = bbGetInputConnectorMap().find(in)->second ;
682 if ( c->IsConnected() )
684 // Get black box from
685 BlackBox::Pointer from =
686 c->GetConnection()->GetBlackBoxFrom();
687 // Cast it into a WxBlackBox
688 WxBlackBox::Pointer wfrom = boost::dynamic_pointer_cast<WxBlackBox>(from);
689 // Call bbCreateWidgetAndEventHandler
690 wfrom->bbCreateWidgetAndEventHandler(parent);
691 // Get the widget created
692 w = wfrom->bbGetOutputWidget();
698 //==================================================================
699 /// Specific methods for window creation during pipeline execution
700 /// Shows the window associated to the box
701 /// (called after bbProcess during bbExecute)
702 void WxBlackBox::bbShowWindow()
704 bbtkDebugMessageInc("wx",1,"=> WxBlackBox::bbShowWindow() ["
705 <<bbGetFullName()<<"]"<<std::endl);
707 // If Event Handler for the widget does not exist or is obsolete : create it
708 if (bbGetOutputWidget()!=0)
710 if (bbGetWidgetEventHandler()==0)
712 bbtkDebugMessage("wx",3,
713 "-> No widget event handler : creating one"
715 new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
716 bbGetOutputWidget());
718 else if ( ! bbGetWidgetEventHandler()->IsHandlerOf
719 ( bbGetOutputWidget() ) )
721 bbtkDebugMessage("wx",3,
722 "-> Obsolete widget event handler : re-creating one"
724 delete bbGetWidgetEventHandler();
725 new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
726 bbGetOutputWidget());
728 // Sets the name of the wxWindow to the input WinTitle
729 bbGetOutputWidget()->SetName(bbtk::std2wx(bbGetInputWinTitle()));
732 // If the output 'Widget' is connected then it's gonna
733 // be captured by its parent window : nothing to do
734 if ( (*bbGetOutputConnectorMap().find("Widget")).second
735 ->GetConnectionVector().size() != 0 )
738 bbtkDebugMessage("wx",2,
739 "-> Output 'Widget' connected : nothing to do"
746 // If the window already exists : no need creating it
747 if (bbGetWindow()!=0)
749 bbtkDebugMessage("wx",2,
750 "-> Window already exists"
752 show = bbGetWindow();
754 // Else if the widget exists : create window
755 else if (bbGetOutputWidget()!=0)
757 bbtkDebugMessage("wx",2,
758 "-> Widget exists : creating the window"
762 // Input WinDialog set to true : creating a Dialog
763 if (bbGetInputWinDialog())
765 bbtkDebugMessage("wx",2,
766 " Input WinDialog set to true : creating a Dialog"
768 show = (Window*) new WxBlackBoxDialog( GetThisPointer<WxBlackBox>(),
770 // LG 24/11/08 : New widget pipeline
772 std2wx( bbGetInputWinTitle() + " - bbtk (c) CREATIS LRMN"),
773 wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
775 // Input WinDialog set to false : creating a Frame
778 bbtkDebugMessage("process",2,
779 " Input WinDialog set to false : creating a Frame"
781 show = (Window*) new WxBlackBoxFrame( GetThisPointer<WxBlackBox>(),
783 // LG 24/11/08 : New widget pipeline
785 std2wx( bbGetInputWinTitle() + " - bbtk (c) CREATIS LRMN"),
786 wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
790 // No window nor widget : error
793 bbtkError("WxBlackBox::bbShowWindow() ["
795 <<"] : No widget. Did you set the box output 'Widget' in the processing method of the box ?");
800 if (true) //!show->IsShown())
806 bbtkDebugMessage("wx",2,"-> Already shown : nothing to do"<<std::endl);
810 bbtkDebugMessage("wx",2,"<= WxBlackBox::bbShowWindow() ["
811 <<bbGetFullName()<<"]"<<std::endl);
814 //==================================================================
819 //==================================================================
820 void WxBlackBox::bbHideWindow()
822 bbtkDebugMessageInc("wx",1,"=> WxBlackBox::bbHideWindow() ["
823 <<bbGetFullName()<<"]"<<std::endl);
825 if (bbGetWindow()!=0) bbGetWindow()->bbHide();
827 bbtkDebugMessageDec("wx",2,"<= WxBlackBox::bbHideWindow() ["
828 <<bbGetFullName()<<"]"<<std::endl);
830 //==================================================================
833 //==================================================================
834 void WxBlackBox::bbCloseWindow()
836 bbtkDebugMessageInc("wx",1,"=> WxBlackBox::bbCloseWindow() ["
837 <<bbGetFullName()<<"]"<<std::endl);
839 if (bbGetWindow()!=0) bbGetWindow()->bbClose();
841 bbtkDebugMessageDec("wx",2,"<= WxBlackBox::bbCloseWindow() ["
842 <<bbGetFullName()<<"]"<<std::endl);
844 //==================================================================
846 //==================================================================
847 WxBlackBox::Window* WxBlackBox::bbGetContainingWindow()
849 if (bbGetWindow()!=0) return bbGetWindow();
850 BlackBox::OutputConnectorMapType::const_iterator i
851 = bbGetOutputConnectorMap().find("Widget");
852 if ( i->second->GetConnectionVector().size() != 0 )
854 return boost::static_pointer_cast<WxBlackBox>
855 (i->second->GetConnectionVector().front() //.lock()
856 ->GetBlackBoxTo())->bbGetContainingWindow();
860 //==================================================================
863 //==================================================================
864 // LG 24/11/08 : New widget pipeline
865 // wxWindow* WxBlackBox::bbGetWxParent() { return Wx::GetTopWindow(); }
866 //==================================================================
869 //==================================================================
870 bool WxBlackBox::bbIsShown()
872 if (bbGetContainingWindow()!=0)
873 return bbGetContainingWindow()->bbIsShown();
876 //==================================================================