]> Creatis software - bbtk.git/blob - kernel/src/bbtkWxEditor.cxx
f178a89c4167023d460453ee9feb601eda0a5333
[bbtk.git] / kernel / src / bbtkWxEditor.cxx
1 /*=========================================================================
2                                                                                 
3   Program:   bbtk
4   Module:    $RCSfile: bbtkWxEditor.cxx,v $
5   Language:  C++
6   Date:      $Date: 2008/03/19 14:58:13 $
7   Version:   $Revision: 1.5 $
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  * \brief Short description in one line
19  * 
20  * Long description which 
21  * can span multiple lines
22  */
23 /**
24  * \file 
25  * \brief 
26  */
27 /**
28  * \class bbtk::
29  * \brief 
30  */
31
32
33 #ifdef _USE_WXWIDGETS_
34
35 #include <iostream>     
36 #include "bbtkWxEditor.h"
37 #include "bbtkWxBlackBox.h"
38 #include "bbtkConfigurationFile.h"
39 #include "bbtkWxStreamRedirector.h"
40
41
42     #include "icons/cc_new.xpm"
43     #include "icons/cc_open.xpm"
44     #include "icons/cc_save.xpm"
45     #include "icons/cc_run.xpm"
46     #include "icons/cc_exit.xpm"
47 //    #include "icons/copy.xpm"
48 //    #include "icons/cut.xpm"
49 //    #include "icons/preview.xpm"  // paste XPM
50 //    #include "icons/print.xpm"
51 //    #include "icons/help.xpm"
52
53 namespace bbtk
54 {
55
56
57   //================================================================
58   class WxTextCtrlGettingKeyEvents : public wxTextCtrl
59   {
60   public:
61     WxTextCtrlGettingKeyEvents(wxWindow *parent, wxWindowID id, const wxString &value,
62                 const wxPoint &pos, const wxSize &size, int style = 0)
63       : wxTextCtrl(parent, id, value, pos, size, style)
64     {
65     }
66     
67     void SetWxEditor(WxEditor* e) { mWxEditor = e; }
68     
69     void OnKeyDown(wxKeyEvent& event);
70     void OnKeyUp(wxKeyEvent& event);
71     void OnChar(wxKeyEvent& event);
72   private :
73     WxEditor* mWxEditor;
74     
75     DECLARE_EVENT_TABLE()
76       };
77   
78   BEGIN_EVENT_TABLE(WxTextCtrlGettingKeyEvents, wxTextCtrl)
79     EVT_KEY_DOWN(WxTextCtrlGettingKeyEvents::OnKeyDown)
80     EVT_KEY_UP(WxTextCtrlGettingKeyEvents::OnKeyUp)
81     EVT_CHAR(WxTextCtrlGettingKeyEvents::OnChar)
82     
83     END_EVENT_TABLE()
84     
85     
86     void WxTextCtrlGettingKeyEvents::OnChar(wxKeyEvent& event)
87   {
88     event.Skip();
89   }
90   
91   void WxTextCtrlGettingKeyEvents::OnKeyUp(wxKeyEvent& event)
92   {
93     mWxEditor->OnKeyUp(event);
94     event.Skip();
95   }
96   
97   void WxTextCtrlGettingKeyEvents::OnKeyDown(wxKeyEvent& event)
98   {
99     mWxEditor->OnKeyDown(event);
100     event.Skip();
101   }
102   //================================================================
103   
104
105
106
107   //================================================================
108   WxEditor::WxEditor( wxWindow *parent )
109     : wxPanel(parent, -1)
110   {     
111     mInterpreter = new bbtk::Interpreter();
112     //mInterpreter->SetWxEditor(this);
113     mInterpreter->SetCommandLine(true);
114
115     //==============
116     // Menu
117     wxInitAllImageHandlers();
118     
119     /*
120     wxMenu *menuFile = new wxMenu;
121     menuFile->Append( ID_Menu_Quit, _T("&Quit") );
122     
123     wxMenu *menuAbout = new wxMenu;
124     menuAbout->Append( ID_Menu_About, _T("&About...") );
125
126     wxMenu *menuTools = new wxMenu;
127     menuTools->Append( ID_Menu_EditConfig, _T("&Edit bbtk config") );
128     menuTools->Append( ID_Menu_CreatePackage, _T("Create &package") );
129     menuTools->Append( ID_Menu_CreateBlackBox, _T("Create &blackbox") );
130     menuTools->Append( ID_Menu_ShowImageGraph, _T("&Show last image graph") );
131     menuTools->Append( ID_Menu_CreateIndex, _T("&Generate index") );
132     
133     
134     wxMenuBar *menuBar = new wxMenuBar;
135     menuBar->Append( menuFile, _T("&File") );
136     menuBar->Append( menuTools, _T("&Tools") );
137     menuBar->Append( menuAbout, _T("About") );
138     
139     SetMenuBar( menuBar );
140     
141     CreateStatusBar();
142     SetStatusText( _T("Welcome to bbi !") );
143     */
144
145     //    wxFlexGridSizer *sizer= new wxFlexGridSizer(2);
146     wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
147     mwxSplit = new wxSplitterWindow(this,
148                                                    -1,
149                                                    wxDefaultPosition,
150                                                    wxDefaultSize,
151                                                    //wxSize(400,200),
152                                                    wxSP_3D |
153                                                    wxSP_LIVE_UPDATE );
154     mwxInputText = 
155       new WxTextCtrlGettingKeyEvents(mwxSplit,
156                      ID_InputText,
157                      _T(""),
158                      wxDefaultPosition,
159                      wxDefaultSize,
160                      wxTE_MULTILINE 
161                      //    |wxTE_PROCESS_ENTER
162                      | wxTE_PROCESS_TAB 
163                      //             | wxWANTS_CHARS 
164                      |  wxTAB_TRAVERSAL
165                      );
166     mwxInputText->SetWxEditor(this);
167
168     wxFont* FixedFont = new wxFont(10,
169                                    wxFONTFAMILY_MODERN,
170                                    wxFONTSTYLE_NORMAL,
171                                    wxFONTWEIGHT_NORMAL,
172                                    false);
173
174    mwxInputTextAttr = new wxTextAttr;
175    mwxInputTextAttr->SetFont(*FixedFont);
176
177    //   sizer->AddGrowableCol(0);
178    //   sizer->Add(mwxInputText,1,wxGROW);
179
180    mwxOutputText = 
181       new WxTextCtrlGettingKeyEvents(mwxSplit,
182                      ID_OutputText,
183                      _T(""),wxDefaultPosition,
184                      wxDefaultSize, //HistorySize,
185                      wxTE_READONLY |
186                      wxTE_MULTILINE );
187
188    mwxOutputText->SetWxEditor(this);
189
190    mwxOutputTextAttr = new wxTextAttr;
191    mwxOutputTextAttr->SetFont(*FixedFont);
192    mwxOutputText->Hide();
193
194    //   sizer->Add(mwxOutputText,1,wxGROW);
195   sizer->Add(mwxSplit,1,wxGROW);
196   mwxSplit->Initialize(mwxInputText);
197
198    // BUTTONS
199    wxPanel *btnsCtrlPanel = new wxPanel(this,-1);
200    wxBoxSizer *btnsSizer  = new wxBoxSizer(wxHORIZONTAL);
201
202    wxBitmap bmp_new(cc_new_xpm);
203    mwxButtonNew = new wxBitmapButton( btnsCtrlPanel,ID_ButtonNew,bmp_new);//_T("New")  );
204    btnsSizer->Add( mwxButtonNew );
205    wxBitmap bmp_open(cc_open_xpm);
206    mwxButtonOpen = new wxBitmapButton( btnsCtrlPanel,ID_ButtonOpen,bmp_open);//,_T("Open")  );
207    btnsSizer->Add( mwxButtonOpen );
208    wxBitmap bmp_save(cc_save_xpm);
209    mwxButtonSave = new wxBitmapButton( btnsCtrlPanel,ID_ButtonSave,bmp_save);//_T("Save")  );
210    btnsSizer->Add( mwxButtonSave );
211    wxBitmap bmp_run(cc_run_xpm);
212    mwxButtonRun = new wxBitmapButton( btnsCtrlPanel,ID_ButtonRun,bmp_run);//_T("Run")  );
213    btnsSizer->Add( mwxButtonRun );
214    wxBitmap bmp_quit(cc_exit_xpm);
215    mwxButtonQuit = new wxBitmapButton( btnsCtrlPanel,ID_ButtonQuit,bmp_quit);//_T("Quit")  );
216    btnsSizer->Add( mwxButtonQuit );
217    
218  
219    mwxPosition = new wxStaticText ( btnsCtrlPanel, -1, _T(""));
220    btnsSizer->Add( mwxPosition );
221   
222
223    btnsCtrlPanel->SetSizer(btnsSizer);
224    sizer->Add ( btnsCtrlPanel, 0, wxLEFT | wxRIGHT | wxBOTTOM  //| wxGROW
225                 , 10 );
226    
227    // Redirection of std::cout and std::cerr to mwxOutputText and printf
228    mRedirect_cout = 
229      new WxStreamRedirector(std::cout,mwxOutputText,*wxBLACK,true);
230    mRedirect_cerr = 
231      new WxStreamRedirector(std::cerr,mwxOutputText,*wxGREEN,true); 
232    
233    UpdatePosition();
234    mwxInputText->SetFocus();
235    
236    SetSizer(sizer);
237    SetAutoLayout(true);
238    Layout();
239   }
240   //================================================================
241   
242   //================================================================
243   WxEditor::~WxEditor()
244   {
245     delete mInterpreter;
246     delete mRedirect_cout;
247     delete mRedirect_cerr;
248   }
249   //================================================================
250
251
252   //================================================================  
253   void WxEditor::OnButtonOpen(wxCommandEvent& event) 
254   { 
255     Open(); 
256     mwxInputText->SetFocus();
257   } 
258   void WxEditor::Open()
259   {
260     std::cout << "-------------- OPEN ---------------"<<std::endl;
261     if (!AskSave()) {
262       std::cout << "-------------- CANCELLED ---------------"<<std::endl;
263       return;
264     }
265
266     wxFileDialog* fd = new wxFileDialog(this,_T("Open file"),_T(""),
267                                         _T(""),_T("*.bbs"),
268                                         wxOPEN | wxFILE_MUST_EXIST );
269     fd->ShowModal();
270     
271     if (fd->GetReturnCode()==wxID_OK)
272       {
273         std::cout << "file [" << wx2std(fd->GetPath()) << "]" <<std::endl;
274         mwxInputText->LoadFile(fd->GetPath());
275       }
276     else 
277       {
278         std::cout << "-------------- CANCELLED ---------------"<<std::endl;
279       }
280   }
281   //================================================================  
282   
283   //================================================================  
284   void WxEditor::Open(const std::string& filename)
285   {
286     mwxInputText->LoadFile(std2wx(filename));
287     mwxInputText->SetModified(false);
288     UpdatePosition();
289   }
290   //================================================================  
291
292   //================================================================  
293   void WxEditor::OnButtonSave(wxCommandEvent& event) 
294   { 
295     Save(); 
296     mwxInputText->SetFocus();
297   } 
298   void WxEditor::Save()
299   {
300     std::cout << "-------------- SAVE ---------------"<<std::endl;
301     wxFileDialog* fd = new wxFileDialog(this,_T("Save file"),_T(""),
302                                         _T(""),_T("*.bbs"),
303                                         wxSAVE | wxOVERWRITE_PROMPT );
304     fd->ShowModal();
305     
306     if (fd->GetReturnCode()==wxID_OK)
307       {
308         std::cout << "file [" << wx2std(fd->GetPath()) << "]" <<std::endl;
309         mwxInputText->SaveFile(fd->GetPath());
310         mwxInputText->SetModified(false);
311       }
312     else 
313       {
314         std::cout << "-------------- CANCELLED ---------------"<<std::endl;
315       }
316   }
317   //================================================================  
318
319   //================================================================  
320   void WxEditor::OnButtonQuit(wxCommandEvent& event) 
321   { 
322     Quit(); 
323     mwxInputText->SetFocus();
324   } 
325   void WxEditor::Quit()
326   {
327     std::cout << "-------------- QUIT ---------------"<<std::endl;
328     if (AskSave()) GetParent()->Close();
329   }
330   //================================================================  
331
332
333   //================================================================  
334   void WxEditor::OnButtonRun(wxCommandEvent& event) 
335   { 
336     Run(); 
337     mwxInputText->SetFocus();
338   }
339   void WxEditor::Run()
340   {
341     std::cout << "-------------- RUN ---------------"<<std::endl;
342
343     if (!mwxSplit->IsSplit()) 
344       {
345         int size = -100;
346         int minsize = - (int)(mwxInputText->GetSize().GetHeight() / 2.);
347         if (size<minsize) size = minsize;
348         mwxSplit->SplitHorizontally( mwxInputText, mwxOutputText, size);
349       }
350
351     std::stringstream* buffer = new std::stringstream(bbtk::wx2std(mwxInputText->GetValue()));
352     mInterpreter->InterpretLine("reset");
353     try 
354       {
355         mInterpreter->InterpretBuffer(buffer);
356       }
357     catch (...)
358       {
359       }
360   } 
361   //================================================================  
362   
363   //================================================================
364   bool WxEditor::AskSave()
365   {
366     if (!mwxInputText->IsModified()) return true;
367     wxMessageDialog* d = new wxMessageDialog(this,
368                                              _T("Buffer modified. Save it ?"), 
369                                              _T("Save buffer"), 
370                                              wxYES_NO | wxCANCEL | wxICON_QUESTION);
371     switch (d->ShowModal())
372       {
373       case wxID_YES : Save(); 
374       case wxID_NO : return true;
375       case wxID_CANCEL : return false;
376       }
377   }
378
379
380   //================================================================
381
382   //================================================================  
383   void WxEditor::OnButtonNew(wxCommandEvent& event) 
384   { 
385     New(); 
386     mwxInputText->SetFocus();
387   }
388   void WxEditor::New()
389   {
390     std::cout << "-------------- NEW ---------------" << std::endl;
391     AskSave();
392     mwxInputText->Clear();
393     UpdatePosition();
394   }
395   //================================================================
396
397   //================================================================
398   void WxEditor::UpdatePosition()
399   {
400
401     long line, column, pos;
402     pos = mwxInputText->GetInsertionPoint();
403     mwxInputText->PositionToXY(pos, &column, &line);
404     
405     
406      //                wxLogMessage(_T("Current position: %ld\nCurrent line, column: (%ld, %ld)\nNumber of lines: %ld\nCurrent line length: %ld\nTotal text length: %u (%ld)"),
407
408   
409      char mess[200];
410      sprintf(mess,"%ld:%ld/%ld:%ld",
411              line+1,column+1,
412              (long)mwxInputText->GetNumberOfLines(),
413              (long)mwxInputText->GetLineLength(line)+1);
414      //      pos+1,
415      //      (long)mwxInputText->GetValue().length())+1;
416
417      mwxPosition->SetLabel(wxString(mess));
418      mwxPosition->Show();
419     
420   }
421   //================================================================
422   //================================================================
423   void WxEditor::OnKeyUp(wxKeyEvent& event)
424   {
425     //  std::cout << "U" << std::endl;
426     UpdatePosition();
427   }
428   //================================================================
429
430   //================================================================
431   void WxEditor::OnKeyDown(wxKeyEvent& event)
432   {
433     //    std::cout << "D" << std::endl;
434     // std::cout << "Key="<<event.GetKeyCode()<<std::endl;
435     if ( event.ControlDown() )
436       {
437         switch (event.GetKeyCode())
438           {
439           case 'n': case 'N' : New(); break;
440           case 's': case 'S' : Save(); break;
441           case 'o': case 'O' : Open(); break;
442           case 'r': case 'R' : Run(); break;
443           case 'q': case 'Q' : Quit(); break;
444           }
445       }
446     /*
447     // Command completion  
448     std::vector<std::string> commands;
449     wxString sline( wx2std ( mwxTextCommand->GetValue() ) );
450     int ind = sline.size();
451     mInterpreter->FindCommandsWithPrefix( sline.c_str(),ind,commands);
452     if (commands.size()==1) 
453       {
454         std::string com = *commands.begin();
455         for (; ind<com.size(); ++ind) 
456           {
457             mwxTextCommand->TextAppend( std2wx ( com[ind]) ); 
458           }
459          mwxTextCommand->TextAppend(_T(" "));
460       }
461     else if (commands.size()>1) 
462       {
463         std::vector<std::string>::iterator i;
464         write(1,"\n",1);
465         for (i=commands.begin();i!=commands.end();++i) 
466           {
467             write(STDOUT_FILENO,(*i).c_str(),strlen((*i).c_str()));
468             PrintChar(' ');
469           }
470         write(STDOUT_FILENO,"\n> ",3);
471         //for (int j=0;j<ind;++j) 
472         //{
473         write(STDOUT_FILENO,line,ind); 
474         //  }
475       }
476     */
477   }
478   //================================================================
479   
480   //================================================================  
481   BEGIN_EVENT_TABLE(WxEditor, wxPanel)
482   //    EVT_CHAR(WxEditor::OnKeyPress)
483     EVT_BUTTON(WxEditor::ID_ButtonNew, WxEditor::OnButtonNew)
484     EVT_BUTTON(WxEditor::ID_ButtonOpen, WxEditor::OnButtonOpen)
485     EVT_BUTTON(WxEditor::ID_ButtonSave, WxEditor::OnButtonSave)
486     EVT_BUTTON(WxEditor::ID_ButtonRun, WxEditor::OnButtonRun)
487     EVT_BUTTON(WxEditor::ID_ButtonQuit, WxEditor::OnButtonQuit)
488     END_EVENT_TABLE()
489   //================================================================
490
491
492   //================================================================
493   WxEditorWindow::WxEditorWindow( wxWindow *parent, wxString title, wxSize size)
494     : wxFrame((wxFrame *)parent, -1, title, wxDefaultPosition, size)
495   {     
496     mEditor = new WxEditor(this);
497  
498     //wxFlexGridSizer *sizer= new wxFlexGridSizer(2);
499     wxBoxSizer *sizer = new wxBoxSizer(wxVERTICAL);
500     //sizer->AddGrowableCol(0);
501     sizer->Add(mEditor,1,wxGROW);
502     SetSizer(sizer);
503     // Creates and sets the parent window of all bbtk windows
504     wxWindow* top = new wxPanel(this,-1);//,_T("top"));
505     top->Hide();
506     //new wxFrame(this,-1,_T("bbtk"),
507     //                         wxDefaultPosition,
508     //                         wxSize(0,0),
509     //                         wxFRAME_TOOL_WINDOW) ;//wxMINIMIZE_BOX);
510     
511     Wx::SetTopWindow(top);
512    
513     
514     SetAutoLayout(true);
515     Layout();
516   }
517
518   WxEditorWindow::~WxEditorWindow()
519   {
520   }
521 } // namespace bbtk
522
523
524 #endif //_USE_WXWIDGETS_