1 /*=========================================================================
3 Module: $RCSfile: bbtkWxBlackBox.cxx,v $
5 Date: $Date: 2008/11/25 11:17:13 $
6 Version: $Revision: 1.31 $
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)
425 bbtkDebugMessageInc("process",2,
426 "=> WxBlackBox::bbExecute("<<(int)force<<") ["
427 <<bbGetFullName()<<"]"<<std::endl);
429 // If the output 'Widget' is connected then
430 // we must execute the parent box
431 BlackBox::OutputConnectorMapType::const_iterator i
432 = bbGetOutputConnectorMap().find("Widget");
434 if ( i->second->GetConnectionVector().size() != 0 )
436 bbtkDebugMessage("process",3,
437 "-> Output 'Widget' connected : transfering execution to parent"
440 i->second->GetConnectionVector().front() //.lock()
441 ->GetBlackBoxTo()->bbExecute(force);
444 // else call 'standard' BlackBox execution method
447 BlackBox::bbExecute(force);
451 bbtkDebugMessageDec("process",2,
452 "<= WxBlackBox::bbExecute() ["
453 <<bbGetFullName()<<"]"<<std::endl);
455 //=========================================================================
458 //=========================================================================
459 /// Main processing method of the box.
460 IOStatus WxBlackBox::bbBackwardUpdate( Connection::Pointer caller )
462 bbtkDebugMessage("process",3,
463 "=> WxBlackBox::bbBackwardUpdate("
464 <<(caller?caller->GetFullName():"0")<<") ["
465 <<bbGetFullName()<<"]"<<std::endl);
467 if ( ! (( bbGetStatus() == MODIFIED ) ||
468 ( bbBoxProcessModeIsAlways() )) )
470 bbtkDebugMessage("process",3,"Up-to-date : nothing to do"<<std::endl);
471 bbtkDebugMessage("process",3,
472 "<= WxBlackBox::bbBackwardUpdate("
473 <<(caller?caller->GetFullName():"0")<<") ["
474 <<bbGetFullName()<<"]"<<std::endl);
475 return bbGetStatus();
478 // If the caller's box to is not the box to connected to the
481 BlackBox::OutputConnectorMapType::const_iterator i
482 = bbGetOutputConnectorMap().find("Widget") ;
483 if ( i->second->GetConnectionVector().size() != 0 )
486 BlackBox::Pointer to =
487 i->second->GetConnectionVector()[0]->GetBlackBoxTo();
491 bbtkDebugMessage("process",3,
492 "-> Output 'Widget' connected to '"
493 <<to->bbGetFullName()<<"' - caller->to = '"
494 <<caller->GetBlackBoxTo()->bbGetFullName()
500 bbtkDebugMessage("process",3,
501 "-> Output 'Widget' connected to '"
502 <<to->bbGetFullName()<<"'"
507 (caller->GetBlackBoxTo() != to)&&
508 (!bbGetUpdateTransferedToParent())&&
509 (!to->bbGetExecuting())
513 bbtkDebugMessage("process",3,
514 " ... Transfering update order to parent"
517 bbSetUpdateTransferedToParent(true);
518 i->second->GetConnectionVector().front() //.lock()
519 ->GetBlackBoxTo()->bbExecute(false);
523 bbSetUpdateTransferedToParent(false);
524 bbtkDebugMessage("process",3,
525 " ... No need to transfer to parent"
531 // If the caller is not the connection to the output widget
532 // and the output 'Widget' is connected then
533 // we must execute the parent box
535 // (this is the role of the flag UpdateTransferedToParent)
537 ((caller!=0)&&(caller->GetBlackBoxFromOutput()!="Widget"))
542 // call 'standard' BlackBox execution method
543 if (!bbGetUpdateTransferedToParent())
545 AtomicBlackBox::bbBackwardUpdate(caller);
548 bbtkDebugMessageDec("process",3,
549 "<= WxBlackBox::bbBackwardUpdate() ["
550 <<bbGetFullName()<<"]"<<std::endl);
552 return bbGetStatus();
557 //=========================================================================
558 void WxBlackBox::bbProcess()
561 if (bbGetOutputWidget()==0) this->bbUserCreateWidget();
562 this->bbUserProcess();
564 // this->bbUserOnShow();
566 // LG 22/11/08 : new widget pipeline
567 // If output widget not connected :
568 if ( (*bbGetOutputConnectorMap().find("Widget")).second
569 ->GetConnectionVector().size() == 0 )
572 // If the window already exists : no need creating it
573 if (bbGetWindow()!=0)
575 bbtkDebugMessage("wx",2,
576 "-> Window already exists"
578 show = bbGetWindow();
580 // Else create window
583 bbtkDebugMessage("wx",2,
584 "-> Creating the window"
588 // Input WinDialog set to true : creating a Dialog
589 if (bbGetInputWinDialog())
591 bbtkDebugMessage("wx",2,
592 " Input WinDialog set to true : creating a Dialog"
594 show = (Window*) new WxBlackBoxDialog( GetThisPointer<WxBlackBox>(),
596 // LG 24/11/08 : New widget pipeline
598 std2wx( bbGetInputWinTitle() + " - bbtk (c) CREATIS LRMN"),
599 wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
601 // Input WinDialog set to false : creating a Frame
604 bbtkDebugMessage("process",2,
605 " Input WinDialog set to false : creating a Frame"
607 show = (Window*) new WxBlackBoxFrame( GetThisPointer<WxBlackBox>(),
609 // LG 24/11/08 : New widget pipeline
611 std2wx( bbGetInputWinTitle() + " - bbtk (c) CREATIS LRMN"),
612 wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
622 this->bbUserProcess();
625 //=========================================================================
629 // LG 24/11/08 : New widget pipeline
630 void WxBlackBox::bbCreateWidgetAndEventHandler(wxWindow* parent)
632 if (bbGetOutputWidget()==0)
634 this->bbUserCreateWidget(parent);
636 // If Event Handler for the widget does not exist or is obsolete : create it
637 if (bbGetOutputWidget()!=0)
639 if (bbGetWidgetEventHandler()==0)
641 bbtkDebugMessage("wx",3,
642 "-> No widget event handler : creating one"
644 new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
645 bbGetOutputWidget());
647 else if ( ! bbGetWidgetEventHandler()->IsHandlerOf
648 ( bbGetOutputWidget() ) )
650 bbtkDebugMessage("wx",3,
651 "-> Obsolete widget event handler : re-creating one"
653 delete bbGetWidgetEventHandler();
654 new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
655 bbGetOutputWidget());
657 // Sets the name of the wxWindow to the input WinTitle
658 bbGetOutputWidget()->SetName(bbtk::std2wx(bbGetInputWinTitle()));
666 wxWindow* WxBlackBox::bbCreateWidgetOfInput(const std::string& in, wxWindow* parent)
669 // If input is connected
670 BlackBoxInputConnector* c = bbGetInputConnectorMap().find(in)->second ;
671 if ( c->IsConnected() )
673 // Get black box from
674 BlackBox::Pointer from =
675 c->GetConnection()->GetBlackBoxFrom();
676 // Cast it into a WxBlackBox
677 WxBlackBox::Pointer wfrom = boost::dynamic_pointer_cast<WxBlackBox>(from);
678 // Call bbCreateWidgetAndEventHandler
679 wfrom->bbCreateWidgetAndEventHandler(parent);
680 // Get the widget created
681 w = wfrom->bbGetOutputWidget();
687 //==================================================================
688 /// Specific methods for window creation during pipeline execution
689 /// Shows the window associated to the box
690 /// (called after bbProcess during bbExecute)
691 void WxBlackBox::bbShowWindow()
693 bbtkDebugMessageInc("wx",1,"=> WxBlackBox::bbShowWindow() ["
694 <<bbGetFullName()<<"]"<<std::endl);
696 // If Event Handler for the widget does not exist or is obsolete : create it
697 if (bbGetOutputWidget()!=0)
699 if (bbGetWidgetEventHandler()==0)
701 bbtkDebugMessage("wx",3,
702 "-> No widget event handler : creating one"
704 new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
705 bbGetOutputWidget());
707 else if ( ! bbGetWidgetEventHandler()->IsHandlerOf
708 ( bbGetOutputWidget() ) )
710 bbtkDebugMessage("wx",3,
711 "-> Obsolete widget event handler : re-creating one"
713 delete bbGetWidgetEventHandler();
714 new WxBlackBoxWidgetEventHandler(GetThisPointer<WxBlackBox>(),
715 bbGetOutputWidget());
717 // Sets the name of the wxWindow to the input WinTitle
718 bbGetOutputWidget()->SetName(bbtk::std2wx(bbGetInputWinTitle()));
721 // If the output 'Widget' is connected then it's gonna
722 // be captured by its parent window : nothing to do
723 if ( (*bbGetOutputConnectorMap().find("Widget")).second
724 ->GetConnectionVector().size() != 0 )
727 bbtkDebugMessage("wx",2,
728 "-> Output 'Widget' connected : nothing to do"
735 // If the window already exists : no need creating it
736 if (bbGetWindow()!=0)
738 bbtkDebugMessage("wx",2,
739 "-> Window already exists"
741 show = bbGetWindow();
743 // Else if the widget exists : create window
744 else if (bbGetOutputWidget()!=0)
746 bbtkDebugMessage("wx",2,
747 "-> Widget exists : creating the window"
751 // Input WinDialog set to true : creating a Dialog
752 if (bbGetInputWinDialog())
754 bbtkDebugMessage("wx",2,
755 " Input WinDialog set to true : creating a Dialog"
757 show = (Window*) new WxBlackBoxDialog( GetThisPointer<WxBlackBox>(),
759 // LG 24/11/08 : New widget pipeline
761 std2wx( bbGetInputWinTitle() + " - bbtk (c) CREATIS LRMN"),
762 wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
764 // Input WinDialog set to false : creating a Frame
767 bbtkDebugMessage("process",2,
768 " Input WinDialog set to false : creating a Frame"
770 show = (Window*) new WxBlackBoxFrame( GetThisPointer<WxBlackBox>(),
772 // LG 24/11/08 : New widget pipeline
774 std2wx( bbGetInputWinTitle() + " - bbtk (c) CREATIS LRMN"),
775 wxSize( bbGetInputWinWidth() , bbGetInputWinHeight() ) );
779 // No window nor widget : error
782 bbtkError("WxBlackBox::bbShowWindow() ["
784 <<"] : No widget. Did you set the box output 'Widget' in the processing method of the box ?");
789 if (true) //!show->IsShown())
795 bbtkDebugMessage("wx",2,"-> Already shown : nothing to do"<<std::endl);
799 bbtkDebugMessage("wx",2,"<= WxBlackBox::bbShowWindow() ["
800 <<bbGetFullName()<<"]"<<std::endl);
803 //==================================================================
808 //==================================================================
809 void WxBlackBox::bbHideWindow()
811 bbtkDebugMessageInc("wx",1,"=> WxBlackBox::bbHideWindow() ["
812 <<bbGetFullName()<<"]"<<std::endl);
814 if (bbGetWindow()!=0) bbGetWindow()->bbHide();
816 bbtkDebugMessageDec("wx",2,"<= WxBlackBox::bbHideWindow() ["
817 <<bbGetFullName()<<"]"<<std::endl);
819 //==================================================================
822 //==================================================================
823 void WxBlackBox::bbCloseWindow()
825 bbtkDebugMessageInc("wx",1,"=> WxBlackBox::bbCloseWindow() ["
826 <<bbGetFullName()<<"]"<<std::endl);
828 if (bbGetWindow()!=0) bbGetWindow()->bbClose();
830 bbtkDebugMessageDec("wx",2,"<= WxBlackBox::bbCloseWindow() ["
831 <<bbGetFullName()<<"]"<<std::endl);
833 //==================================================================
835 //==================================================================
836 WxBlackBox::Window* WxBlackBox::bbGetContainingWindow()
838 if (bbGetWindow()!=0) return bbGetWindow();
839 BlackBox::OutputConnectorMapType::const_iterator i
840 = bbGetOutputConnectorMap().find("Widget");
841 if ( i->second->GetConnectionVector().size() != 0 )
843 return boost::static_pointer_cast<WxBlackBox>
844 (i->second->GetConnectionVector().front() //.lock()
845 ->GetBlackBoxTo())->bbGetContainingWindow();
849 //==================================================================
852 //==================================================================
853 // LG 24/11/08 : New widget pipeline
854 // wxWindow* WxBlackBox::bbGetWxParent() { return Wx::GetTopWindow(); }
855 //==================================================================
858 //==================================================================
859 bool WxBlackBox::bbIsShown()
861 if (bbGetContainingWindow()!=0)
862 return bbGetContainingWindow()->bbIsShown();
865 //==================================================================