1 /***************************************************************************
2   gdlwidgeteventhandler.cpp  -  GDL widget event handling
3                              -------------------
4     begin                : Fri May 7 2004
5     copyright            : (C) 2004-2013 by Marc Schellens
6     email                : m_schellens@users.sourceforge.net
7  ***************************************************************************/
8 
9 /***************************************************************************
10  *                                                                         *
11  *   This program is free software; you can redistribute it and/or modify  *
12  *   it under the terms of the GNU General Public License as published by  *
13  *   the Free Software Foundation; either version 2 of the License, or     *
14  *   (at your option) any later version.                                   *
15  *                                                                         *
16  ***************************************************************************/
17 
18 #include "includefirst.hpp"
19 
20 #ifdef HAVE_LIBWXWIDGETS
21 
22 #include <wx/clipbrd.h>
23 
24 #include "basegdl.hpp"
25 #include "dstructgdl.hpp"
26 #include "gdlwidget.hpp"
27 
28 //  #define GDL_DEBUG_ALL_EVENTS 1
29 //  #define GDL_DEBUG_MOVE_EVENTS 1
30 //  #define GDL_DEBUG_KBRD_EVENTS 1
31 //  #define GDL_DEBUG_TIMER_EVENTS 1
32 //  #define GDL_DEBUG_VISIBILITY_EVENTS 1
33 //  #define GDL_DEBUG_SIZE_EVENTS 1
34 //  #define GDL_DEBUG_TEXT_EVENTS 1
35 //  #define GDL_DEBUG_BUTTON_EVENTS 1
36 //  #define GDL_DEBUG_PAINT_EVENTS 1
37 // #define GDL_DEBUG_OTHER_EVENTS 1
38 
39 //TO BE DONE: CONTINUE to REPLACE ALL STATIC CONNECTS WITH DYNAMIC. SEE http://wxwidgets.blogspot.com/2007/01/in-praise-of-connect.html
40 // replace, e.g;
41 //
42 //BEGIN_EVENT_TABLE(MyFrame, wxFrame)
43 //  EVT_MENU(wxID_EXIT, MyFrame::OnQuit)
44 //END_EVENT_TABLE()
45 //instead write (in the body of some method of MyFrame and not at global scope as with the event tables)
46 //    MyFrame::MyFrame(...)
47 //    {
48 //      Connect(wxID_EXIT, wxEVT_COMMAND_MENU_SELECTED,
49 //      wxCommandEventHandler(MyFrame::OnQuit));
50 //    }
51 // see also the example of how to connect an event of some object to a method of another object.
52 // and note that in this particular case one should always remember to disconnect the event handler
53 // in the event handler object's destructor, otherwise the application may crash if/when the handler
54 // is called after the event handler object is destroyed.
55 //
56 // Note that this may be tedious since all the event_table events below are events that can be set or removed
57 // for each type of widget.
58 // Besides, the misuse of event.Skip() can pose severe problems (blank widgets, etc...) since (quoting documentation)
59 // "Sizers rely on size events to function correctly. Therefore, in a sizer-based layout, do not forget to call Skip
60 // on all size events you catch (and don't catch size events at all when you don't need to).
BEGIN_EVENT_TABLE(wxTreeCtrlGDL,wxTreeCtrl)61 BEGIN_EVENT_TABLE(wxTreeCtrlGDL, wxTreeCtrl)
62     EVT_TREE_BEGIN_DRAG(wxID_ANY, wxTreeCtrlGDL::OnDrag)
63 //    EVT_TREE_BEGIN_RDRAG(wxID_ANY, wxTreeCtrlGDL::OnBeginRDrag)
64     EVT_TREE_END_DRAG(wxID_ANY, wxTreeCtrlGDL::OnDrop)
65 //    EVT_TREE_BEGIN_LABEL_EDIT(wxID_ANY, wxTreeCtrlGDL::OnBeginLabelEdit)
66 //    EVT_TREE_END_LABEL_EDIT(wxID_ANY, wxTreeCtrlGDL::OnEndLabelEdit)
67 //    EVT_TREE_DELETE_ITEM(wxID_ANY, wxTreeCtrlGDL::OnDeleteItem)
68 //    EVT_TREE_GET_INFO(wxID_ANY, wxTreeCtrlGDL::OnGetInfo)
69 //    EVT_TREE_SET_INFO(wxID_ANY, wxTreeCtrlGDL::OnSetInfo)
70     EVT_TREE_ITEM_EXPANDED(wxID_ANY, wxTreeCtrlGDL::OnItemExpanded)
71 //    EVT_TREE_ITEM_EXPANDING(wxID_ANY, wxTreeCtrlGDL::OnItemExpanding)
72     EVT_TREE_ITEM_COLLAPSED(wxID_ANY, wxTreeCtrlGDL::OnItemCollapsed)
73 //    EVT_TREE_ITEM_COLLAPSING(wxID_ANY, wxTreeCtrlGDL::OnItemCollapsing)
74 
75     EVT_TREE_SEL_CHANGED(wxID_ANY, wxTreeCtrlGDL::OnItemSelected)
76 //    EVT_TREE_SEL_CHANGING(wxID_ANY, wxTreeCtrlGDL::OnSelChanging)
77     EVT_KEY_DOWN(wxTreeCtrlGDL::OnTreeKeyDown)
78     EVT_KEY_UP(wxTreeCtrlGDL::OnTreeKeyUp)
79     EVT_TREE_ITEM_ACTIVATED(wxID_ANY, wxTreeCtrlGDL::OnItemActivated)
80     EVT_TREE_STATE_IMAGE_CLICK(wxID_ANY, wxTreeCtrlGDL::OnItemStateClick)
81 
82 //    // so many different ways to handle right mouse button clicks...
83 //    EVT_CONTEXT_MENU(wxTreeCtrlGDL::OnContextMenu)
84 //    // EVT_TREE_ITEM_MENU is the preferred event for creating context menus
85 //    // on a tree control, because it includes the point of the click or item,
86 //    // meaning that no additional placement calculations are required.
87 //    EVT_TREE_ITEM_MENU(wxID_ANY, wxTreeCtrlGDL::OnItemMenu)
88 //    EVT_TREE_ITEM_RIGHT_CLICK(wxID_ANY, wxTreeCtrlGDL::OnItemRClick)
89 //
90 //    EVT_RIGHT_DOWN(wxTreeCtrlGDL::OnRMouseDown)
91 //    EVT_RIGHT_UP(wxTreeCtrlGDL::OnRMouseUp)
92 //    EVT_RIGHT_DCLICK(wxTreeCtrlGDL::OnRMouseDClick)
93 END_EVENT_TABLE()
94 
95 DEFINE_EVENT_TYPE(wxEVT_SHOW_REQUEST)
96 DEFINE_EVENT_TYPE(wxEVT_HIDE_REQUEST)
97 
98 //general-purpose events still left to Frame:
99 BEGIN_EVENT_TABLE(gdlwxFrame, wxFrame)
100 //impossible to replace with Connect() method?
101   EVT_MENU(wxID_ANY, gdlwxFrame::OnMenu)
102   //timed resize events happen only on one frame at a time, so the timer ID is fixed here.
103   // If this was not the case, then remove this line and Connect() to the timer at the timer creation place.
104   EVT_TIMER(RESIZE_TIMER, gdlwxFrame::OnTimerResize) //... where size event is really done here. But does not work (refresh not OK)
105 END_EVENT_TABLE()
106 
107 BEGIN_EVENT_TABLE(gdlwxPlotFrame, wxFrame)
108   EVT_TIMER(RESIZE_PLOT_TIMER, gdlwxPlotFrame::OnTimerPlotResize)
109 END_EVENT_TABLE()
110 
111 void wxTextCtrlGDL::OnChar(wxKeyEvent& event ) {
112 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_KBRD_EVENTS )
113   wxMessageOutputStderr().Printf(_T("in gdlTextCtrl::OnChar: %d Keycode:%d\n"),event.GetId(),event.GetKeyCode( ));
114 #endif
115 
116   //I cannot get cw_field to work if OnChar is not overwritten as it is here
117   GDLWidgetText* txt = static_cast<GDLWidgetText*>(GDLWidget::GetWidget( event.GetId()));
118   if( txt == NULL)
119   {
120 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_KBRD_EVENTS)
121     wxMessageOutputStderr().Printf(_T("GDLWidget == NULL: %d\n"),event.GetId());
122 #endif
123     event.Skip();
124     return;
125   }
126   DStructGDL* widg;
127   bool report = txt->HasEventType( GDLWidget::EV_ALL );
128   bool edit = txt->IsEditable( );
129   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
130   if ( !report ) {
131     if ( !edit ) {
132       event.Skip( );
133       return;
134     } else { //editable
135       if ( event.GetKeyCode( ) == WXK_RETURN ) { //only
136       widg = new DStructGDL( "WIDGET_TEXT_CH" );
137       widg->InitTag( "ID", DLongGDL( event.GetId( ) ) );
138       widg->InitTag( "TOP", DLongGDL( baseWidgetID ) );
139       widg->InitTag( "HANDLER", DLongGDL( baseWidgetID ) );
140       widg->InitTag( "TYPE", DIntGDL( 0 ) ); // selection
141       widg->InitTag( "OFFSET", DLongGDL( this->GetInsertionPoint() ) );
142       widg->InitTag( "CH", DByteGDL( 10 ) );
143       GDLWidget::PushEvent( baseWidgetID, widg );
144       if (txt->IsMultiline()) event.Skip( );
145       return;
146       }
147       event.Skip( );
148       return;
149     }
150   } else { //report ALL (text) events, editable or not but skip on <TAB>
151     int sign = 1;
152     long from, to;
153     this->GetSelection( &from, &to );
154     long oldpos = this->GetInsertionPoint( ), newpos;
155     switch ( event.GetKeyCode( ) ) {
156       case WXK_TAB:
157         event.Skip();  return;
158         break;
159       case WXK_END:
160         newpos = this->GetLastPosition( );
161         this->SetInsertionPoint( newpos );
162         break;
163       case WXK_HOME:
164         newpos = 0;
165         this->SetInsertionPoint( newpos );
166         break;
167       case WXK_LEFT:
168         sign = -1;
169       case WXK_RIGHT:
170         newpos = oldpos + sign * 1;
171         if ( newpos >= 0 && newpos <= this->GetLastPosition( ) ) this->SetInsertionPoint( newpos );
172         widg = new DStructGDL( "WIDGET_TEXT_SEL" );
173         widg->InitTag( "ID", DLongGDL( event.GetId( ) ) );
174         widg->InitTag( "TOP", DLongGDL( baseWidgetID ) );
175         widg->InitTag( "HANDLER", DLongGDL( baseWidgetID ) );
176         widg->InitTag( "TYPE", DIntGDL( 3 ) ); // selection
177         widg->InitTag( "OFFSET", DLongGDL( this->GetInsertionPoint( ) ) );
178         widg->InitTag( "LENGTH", DLongGDL( 0 ) );
179         GDLWidget::PushEvent( baseWidgetID, widg );
180         if (edit) event.Skip( );
181         return;
182         break;
183       case WXK_UP: //these two, I cannot compute the next line (or preceding line) postion with the methods provided
184                    //by wxWidgets. So I Skip(). At least most of the job is done.
185       case WXK_DOWN:
186         event.Skip();
187         return;
188         break;
189       case WXK_BACK:
190       case WXK_DELETE: //perform identically on idl/linux.
191         if ( oldpos > 0 ) {
192           widg = new DStructGDL( "WIDGET_TEXT_DEL" );
193           widg->InitTag( "ID", DLongGDL( event.GetId( ) ) );
194           widg->InitTag( "TOP", DLongGDL( baseWidgetID ) );
195           widg->InitTag( "HANDLER", DLongGDL( baseWidgetID ) );
196           widg->InitTag( "TYPE", DIntGDL( 2 ) ); // selection
197           widg->InitTag( "OFFSET", DLongGDL( from - 1 ) );
198           widg->InitTag( "LENGTH", DLongGDL( to - from + 1 ) );
199           GDLWidget::PushEvent( baseWidgetID, widg );
200         }
201         if (edit) event.Skip( ); //do it!
202         return;
203         break;
204       case WXK_RETURN: //important, *DL returns CH=10 instead of 13 for <CR>
205         widg = new DStructGDL( "WIDGET_TEXT_CH" );
206         widg->InitTag( "ID", DLongGDL( event.GetId( ) ) );
207         widg->InitTag( "TOP", DLongGDL( baseWidgetID ) );
208         widg->InitTag( "HANDLER", DLongGDL( baseWidgetID ) );
209         widg->InitTag( "TYPE", DIntGDL( 0 ) ); // selection
210         widg->InitTag( "OFFSET", DLongGDL( from ) );
211         widg->InitTag( "CH", DByteGDL( 10 ) );
212         GDLWidget::PushEvent( baseWidgetID, widg );
213         if (edit) event.Skip( );
214         return;
215         break;
216     }
217     if (edit) event.Skip( ); //else do it!
218   }
219 
220   //else return a CHAR event for most keys (as *DL)
221     widg = new DStructGDL( "WIDGET_TEXT_CH" );
222     widg->InitTag( "ID", DLongGDL( event.GetId( ) ) );
223     widg->InitTag( "TOP", DLongGDL( baseWidgetID ) );
224     widg->InitTag( "HANDLER", DLongGDL( baseWidgetID ) );
225     widg->InitTag( "TYPE", DIntGDL( 0 ) ); // single char
226     widg->InitTag( "OFFSET", DLongGDL( this->GetInsertionPoint( ) ) );
227     widg->InitTag( "CH", DByteGDL( event.GetKeyCode( ) ) );
228     GDLWidget::PushEvent( baseWidgetID, widg );
229     if (edit) event.Skip( );
230 }
231 
232 //this is necessary to reproduce IDL's behaviour
OnMouseEvents(wxMouseEvent & event)233 void wxTextCtrlGDL::OnMouseEvents( wxMouseEvent& event)
234 {
235   GDLWidgetText* txt = static_cast<GDLWidgetText*>(GDLWidget::GetWidget( event.GetId()));
236   if( txt == NULL)
237   {
238     event.Skip();
239     return;
240   }
241   int rot=event.GetWheelRotation();
242   if (rot>0) this->ScrollLines(-1); else this->ScrollLines(1);
243 }
244 
OnWidgetTimer(wxTimerEvent & event)245  void gdlwxFrame::OnWidgetTimer( wxTimerEvent& event)
246  {
247 //originating widget is stored in clientData
248     WidgetIDT * originating_id=static_cast<WidgetIDT*>(this->GetEventHandler()->GetClientData());
249 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_TIMER_EVENTS)
250    wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnWidgetTimer: %d issued by: %d\n"),event.GetId(),*originating_id);
251 #endif
252 
253 //Base Widget (frame) is retrieved such:
254     WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( *originating_id );
255   // create GDL event struct
256     DStructGDL* widgtimer = new DStructGDL( "WIDGET_TIMER" );
257     widgtimer->InitTag( "ID", DLongGDL(*originating_id));
258     widgtimer->InitTag( "TOP", DLongGDL( baseWidgetID ) );
259     widgtimer->InitTag( "HANDLER", DLongGDL(*originating_id) ); //will be set elsewhere
260     GDLWidget::PushEvent( baseWidgetID, widgtimer);
261  }
262 
OnShowRequest(wxCommandEvent & event)263 void gdlwxFrame::OnShowRequest( wxCommandEvent& event)
264 {
265 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_VISIBILITY_EVENTS)
266   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnShowRequest: %d\n"),event.GetId());
267 #endif
268 
269   GDLWidget* widget = GDLWidget::GetWidget( event.GetId());
270   if( widget == NULL)
271   {
272 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_VISIBILITY_EVENTS)
273     wxMessageOutputStderr().Printf(_T("GDLWidget == NULL: %d\n"),event.GetId());
274 #endif
275     return;
276   }
277   gdlwxFrame *frame = static_cast<gdlwxFrame*>( widget->GetWxWidget());
278   if( !frame->IsShown())
279   {
280 //    if (frame->isPlotFrame()) frame->ShowWithoutActivating();
281 //    else
282       bool stat = frame->Show(true);
283   }
284   event.Skip();
285 }
286 
OnHideRequest(wxCommandEvent & event)287 void gdlwxFrame::OnHideRequest( wxCommandEvent& event)
288 {
289 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_VISIBILITY_EVENTS)
290   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnHideRequest: %d\n"),event.GetId());
291 #endif
292 
293   GDLWidget* widget = GDLWidget::GetWidget( event.GetId());
294   if( widget == NULL)
295   {
296 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_VISIBILITY_EVENTS)
297     wxMessageOutputStderr().Printf(_T("GDLWidget == NULL: %d\n"),event.GetId());
298 #endif
299     return;
300   }
301   gdlwxFrame *frame = static_cast<gdlwxFrame*>( widget->GetWxWidget());
302   if( frame->IsShown())
303   {
304     bool stat = frame->Show(false);
305   }
306   event.Skip();
307 }
308 
OnButton(wxCommandEvent & event)309 void wxButtonGDL::OnButton( wxCommandEvent& event)
310 {
311 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_BUTTON_EVENTS)
312   wxMessageOutputStderr().Printf(_T("in gdlMenuButton::OnButton: %d\n"),event.GetId());
313 #endif
314  this->PopupMenu(dynamic_cast<wxMenu*>(popupMenu),position);
315  event.Skip();
316 }
317 
OnButton(wxCommandEvent & event)318 void wxBitmapButtonGDL::OnButton( wxCommandEvent& event)
319 {
320 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_BUTTON_EVENTS)
321   wxMessageOutputStderr().Printf(_T("in gdlMenuButtonBitmap::OnButton: %d\n"),event.GetId());
322 #endif
323  this->PopupMenu(dynamic_cast<wxMenu*>(popupMenu));
324  event.Skip();
325 }
326 
OnButton(wxCommandEvent & event)327 void gdlwxFrame::OnButton( wxCommandEvent& event)
328 {
329 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_BUTTON_EVENTS)
330   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnButton: %d\n"),event.GetId());
331 #endif
332 
333   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId());
334 
335   // create GDL event struct
336   DStructGDL*  widgbut = new DStructGDL( "WIDGET_BUTTON");
337   widgbut->InitTag("ID", DLongGDL( event.GetId()));
338   widgbut->InitTag("TOP", DLongGDL( baseWidgetID));
339   widgbut->InitTag("HANDLER", DLongGDL( baseWidgetID ));
340   widgbut->InitTag("SELECT", DLongGDL( 1));
341 
342   GDLWidget::PushEvent( baseWidgetID, widgbut);
343 }
344 
345 //change bitmap or parent button?
OnMenu(wxCommandEvent & event)346 void gdlwxFrame::OnMenu( wxCommandEvent& event)
347 {
348 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_BUTTON_EVENTS)
349   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnMenu: %d\n"),event.GetId());
350 #endif
351 //if widget is a checked menu, wxWidgets should not change its checked state all by itself. How to avoird this?
352   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId());
353   // create GDL event struct
354   DStructGDL*  widgbut = new DStructGDL( "WIDGET_BUTTON");
355   widgbut->InitTag("ID", DLongGDL( event.GetId()));
356   widgbut->InitTag("TOP", DLongGDL( baseWidgetID));
357   widgbut->InitTag("HANDLER", DLongGDL( baseWidgetID ));
358   widgbut->InitTag("SELECT", DLongGDL( 1));
359 
360   GDLWidget::PushEvent( baseWidgetID, widgbut);
361 }
362 
OnRadioButton(wxCommandEvent & event)363 void gdlwxFrame::OnRadioButton( wxCommandEvent& event)
364 {
365 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_BUTTON_EVENTS)
366   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnRadioButton: %d\n"),event.GetId());
367 #endif
368 
369   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId());
370 
371 //   bool selectValue = event.IsSelection();
372 //   int selectValue = event.GetSelection();
373 
374   GDLWidgetBase* gdlParentWidget = static_cast<GDLWidgetBase*>(GDLWidget::GetParent( event.GetId()));
375   WidgetIDT lastSelection = gdlParentWidget->GetLastRadioSelection();
376   if( lastSelection != GDLWidget::NullID)
377   {
378     if( lastSelection == event.GetId())
379       return;
380     // create GDL event struct
381     DStructGDL*  widgbut = new DStructGDL( "WIDGET_BUTTON");
382     widgbut->InitTag("ID", DLongGDL( lastSelection));
383     widgbut->InitTag("TOP", DLongGDL( baseWidgetID));
384     widgbut->InitTag("HANDLER", DLongGDL( baseWidgetID ));
385     widgbut->InitTag("SELECT", DLongGDL( 0));
386 
387     GDLWidgetButton* widget = static_cast<GDLWidgetButton*>(GDLWidget::GetWidget( lastSelection));
388     assert(widget!=NULL);
389     widget->SetRadioButton( false);
390     GDLWidget::PushEvent( baseWidgetID, widgbut);
391   }
392 
393   // create GDL event struct
394   DStructGDL*  widgbut = new DStructGDL( "WIDGET_BUTTON");
395   widgbut->InitTag("ID", DLongGDL( event.GetId()));
396   widgbut->InitTag("TOP", DLongGDL( baseWidgetID));
397   widgbut->InitTag("HANDLER", DLongGDL( baseWidgetID ));
398 //   widgbut->InitTag("SELECT", DLongGDL( selectValue ? 1 : 0));
399   widgbut->InitTag("SELECT", DLongGDL( 1));
400 
401   gdlParentWidget->SetLastRadioSelection(event.GetId());
402 
403   GDLWidget* widget = GDLWidget::GetWidget( event.GetId());
404   assert(widget->IsButton());
405   static_cast<GDLWidgetButton*>(widget)->SetRadioButton( true);
406   GDLWidget::PushEvent( baseWidgetID, widgbut);
407 }
408 
OnCheckBox(wxCommandEvent & event)409 void gdlwxFrame::OnCheckBox( wxCommandEvent& event)
410 {
411 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_BUTTON_EVENTS)
412   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnCheckBox: %d\n"),event.GetId());
413 #endif
414 
415   bool selectValue = event.IsChecked();
416 
417   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId());
418   GDLWidget* widget = GDLWidget::GetWidget( event.GetId());
419   assert(widget->IsButton());
420   static_cast<GDLWidgetButton*>(widget)->SetRadioButton( selectValue);
421 
422   // create GDL event struct
423   DStructGDL*  widgbut = new DStructGDL( "WIDGET_BUTTON");
424   widgbut->InitTag("ID", DLongGDL( event.GetId()));
425   widgbut->InitTag("TOP", DLongGDL( baseWidgetID));
426   widgbut->InitTag("HANDLER", DLongGDL( baseWidgetID ));
427   widgbut->InitTag("SELECT", DLongGDL( selectValue ? 1 : 0));
428 
429   GDLWidget::PushEvent( baseWidgetID, widgbut);
430 }
431 
OnComboBox(wxCommandEvent & event)432 void gdlwxFrame::OnComboBox( wxCommandEvent& event)
433 {
434 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
435   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnComboBox: %d\n"),event.GetId());
436 #endif
437 
438   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId());
439   int selectValue = event.GetSelection();
440 
441   // create GDL event struct
442   DStructGDL*  widgcbox;
443   wxString strValue = event.GetString();
444 
445   widgcbox = new DStructGDL( "WIDGET_COMBOBOX");
446   widgcbox->InitTag("ID", DLongGDL( event.GetId()));
447   widgcbox->InitTag("TOP", DLongGDL( baseWidgetID));
448   widgcbox->InitTag("HANDLER", DLongGDL( baseWidgetID ));
449   widgcbox->InitTag("INDEX", DLongGDL( selectValue));
450   widgcbox->InitTag("STR", DStringGDL( std::string(strValue.mb_str(wxConvUTF8)) ));
451 
452   GDLWidget::PushEvent( baseWidgetID, widgcbox);
453 }
OnComboBoxTextEnter(wxCommandEvent & event)454 void gdlwxFrame::OnComboBoxTextEnter( wxCommandEvent& event)
455 {
456 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_TEXT_EVENTS)
457   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnComboBoxTextEvent: %d\n"),event.GetId());
458 #endif
459 
460   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId());
461   int selectValue = event.GetSelection();
462 
463   // create GDL event struct
464   DStructGDL*  widgcbox;
465   wxString strValue = event.GetString();
466 
467   widgcbox = new DStructGDL( "WIDGET_COMBOBOX");
468   widgcbox->InitTag("ID", DLongGDL( event.GetId()));
469   widgcbox->InitTag("TOP", DLongGDL( baseWidgetID));
470   widgcbox->InitTag("HANDLER", DLongGDL( baseWidgetID ));
471   widgcbox->InitTag("INDEX", DLongGDL( selectValue));
472   widgcbox->InitTag("STR", DStringGDL( std::string(strValue.mb_str(wxConvUTF8)) ));
473 
474   GDLWidget::PushEvent( baseWidgetID, widgcbox);
475 }
OnDropList(wxCommandEvent & event)476 void gdlwxFrame::OnDropList( wxCommandEvent& event)
477 {
478 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
479   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnDropList: %d\n"),event.GetId());
480 #endif
481 
482   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId());
483   int selectValue = event.GetSelection();
484 
485   DStructGDL*  widdrplst;
486   widdrplst = new DStructGDL( "WIDGET_DROPLIST");
487   widdrplst->InitTag("ID", DLongGDL( event.GetId()));
488   widdrplst->InitTag("TOP", DLongGDL( baseWidgetID));
489   widdrplst->InitTag("HANDLER", DLongGDL( baseWidgetID ));
490   widdrplst->InitTag("INDEX", DLongGDL( selectValue));
491 
492   GDLWidget::PushEvent( baseWidgetID, widdrplst);
493 }
494 
OnListBoxDo(wxCommandEvent & event,DLong clicks)495 void gdlwxFrame::OnListBoxDo( wxCommandEvent& event, DLong clicks)
496 {
497 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
498   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnListBoxDo: %d\n"),event.GetId());
499 #endif
500 
501   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId());
502 
503   int selectValue = event.GetSelection();
504 
505   // create GDL event struct
506   DStructGDL*  widgcbox;
507   widgcbox = new DStructGDL( "WIDGET_LIST");
508   widgcbox->InitTag("ID", DLongGDL( event.GetId()));
509   widgcbox->InitTag("TOP", DLongGDL( baseWidgetID));
510   widgcbox->InitTag("HANDLER", DLongGDL( baseWidgetID ));
511   widgcbox->InitTag("INDEX", DLongGDL( selectValue));
512   widgcbox->InitTag("CLICKS", DLongGDL( clicks));
513 
514   GDLWidget::PushEvent( baseWidgetID, widgcbox);
515 }
OnListBox(wxCommandEvent & event)516 void gdlwxFrame::OnListBox( wxCommandEvent& event)
517 {
518 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
519   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnListBox: %d\n"),event.GetId());
520 #endif
521 
522   OnListBoxDo( event, 1);
523 }
OnListBoxDoubleClicked(wxCommandEvent & event)524 void gdlwxFrame::OnListBoxDoubleClicked( wxCommandEvent& event)
525 {
526 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
527   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnListBoxDoubleClicked: %d\n"),event.GetId());
528 #endif
529 
530 // Note: IDL sends one click AND two click event on double click
531   OnListBoxDo( event, 1);
532   OnListBoxDo( event, 2);
533 }
534 
535 //this is necessary to reproduce IDL's behaviour.
OnTextMouseEvents(wxMouseEvent & event)536 void gdlwxFrame::OnTextMouseEvents( wxMouseEvent& event)
537 {
538 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_TEXT_EVENTS)
539   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnTextMouseEvents: %d\n"),event.GetId());
540 #endif
541   GDLWidgetText* txtWidget = static_cast<GDLWidgetText*>(GDLWidget::GetWidget( event.GetId()));
542   if( txtWidget == NULL)
543   {
544 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_KBRD_EVENTS)
545     wxMessageOutputStderr().Printf(_T("GDLWidget == NULL: %d\n"),event.GetId());
546 #endif
547     event.Skip();
548     return;
549   }
550   DStructGDL* widg;
551   bool report = txtWidget->HasEventType( GDLWidget::EV_ALL );
552   bool edit = txtWidget->IsEditable( );
553   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
554   if ( report ) {
555     wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>(txtWidget->GetWxWidget());
556     if( textCtrl == NULL) {std::cerr<<"gdlwxFrame::OnTextMouseEvents() : No wxWidget!"<<std::endl;  event.Skip( ); return;}
557 
558     long from,to;
559     //signal entry (even if offset is bad)
560     if ( event.ButtonDown(wxMOUSE_BTN_LEFT)) {
561       //Do not report, as the selection (wxWidgets side) has not been made yet, it will be done AFTER event.skip
562       //We report only the true selection, made with ButtonUp
563 //      widg = new DStructGDL( "WIDGET_TEXT_SEL");
564 //      widg->InitTag("ID", DLongGDL( event.GetId()));
565 //      widg->InitTag("TOP", DLongGDL( baseWidgetID));
566 //      widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
567 //      widg->InitTag("TYPE", DIntGDL( 3)); // selection
568 //      from=textCtrl->GetInsertionPoint();
569 //      widg->InitTag("OFFSET", DLongGDL( from ));
570 //      widg->InitTag("LENGTH", DLongGDL( 0 ));
571 //      GDLWidget::PushEvent( baseWidgetID, widg);
572       // NOTE: "Process a wxEVT_LEFT_DOWN event. The handler of this event should normally call event.Skip()
573       // to allow the default processing to take place as otherwise the window under mouse wouldn't get the focus. "
574       event.Skip( );
575     } else if ( event.ButtonUp(wxMOUSE_BTN_LEFT)) {
576       widg = new DStructGDL( "WIDGET_TEXT_SEL");
577       widg->InitTag("ID", DLongGDL( event.GetId()));
578       widg->InitTag("TOP", DLongGDL( baseWidgetID));
579       widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
580       widg->InitTag("TYPE", DIntGDL( 3)); // selection
581       textCtrl->GetSelection(&from,&to);
582       widg->InitTag("OFFSET", DLongGDL( from ));
583       widg->InitTag("LENGTH", DLongGDL( to-from ));
584       GDLWidget::PushEvent( baseWidgetID, widg);
585       // NOTE: "Process a wxEVT_LEFT_DOWN event. The handler of this event should normally call event.Skip()
586       // to allow the default processing to take place as otherwise the window under mouse wouldn't get the focus. "
587       if (event.ButtonDown(wxMOUSE_BTN_LEFT)) event.Skip( );
588     }
589     return;
590     //middle button (paste) should be filtered. Here we just avoid the paste pollutes a not-edit widget (without creating a GDL event).
591     // So we do not do anything when report is true (as it will not be properly reported)
592   }
593   event.Skip( );
594 }
595 
OnTextPaste(wxClipboardTextEvent & event)596 void gdlwxFrame::OnTextPaste( wxClipboardTextEvent& event)
597 {
598 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_TEXT_EVENTS)
599   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnTextPaste: %d\n"),event.GetId());
600 #endif
601   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId());
602 
603   GDLWidgetText* widget = static_cast<GDLWidgetText*>(GDLWidget::GetWidget( event.GetId()));
604   if( widget == NULL)  {    event.Skip();    return;  }
605   bool report = widget->HasEventType( GDLWidget::EV_ALL );
606   bool edit = widget->IsEditable( );
607   if (report) {
608     wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>(widget->GetWxWidget());
609     if( textCtrl == NULL)
610     {
611       event.Skip();
612       std::cerr<<"No wxWidget!"<<std::endl; return; // happens on construction
613     }
614     wxString s;
615     if (wxTheClipboard->Open())
616     {
617       if (wxTheClipboard->IsSupported( wxDF_TEXT ))
618       {
619           wxTextDataObject data;
620           wxTheClipboard->GetData( data );
621           s=data.GetText();
622       }
623       wxTheClipboard->Close();
624     }
625     long pos=textCtrl->GetInsertionPoint();
626     DStructGDL*  widg;
627     widg = new DStructGDL( "WIDGET_TEXT_STR");
628     widg->InitTag("ID", DLongGDL( event.GetId()));
629     widg->InitTag("TOP", DLongGDL( baseWidgetID));
630     widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
631     widg->InitTag("TYPE", DIntGDL( 1)); // multiple char
632     widg->InitTag("OFFSET", DLongGDL( pos+s.length() ));
633     widg->InitTag("STR", DStringGDL(std::string(s.c_str())));
634     GDLWidget::PushEvent( baseWidgetID, widg);
635     if (edit) event.Skip();
636     return;
637   }
638   event.Skip();
639 }
640 
OnTextCut(wxClipboardTextEvent & event)641 void gdlwxFrame::OnTextCut( wxClipboardTextEvent& event)
642 {
643 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_TEXT_EVENTS)
644   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnTextCut: %d\n"),event.GetId());
645 #endif
646 
647   GDLWidgetText* widget = static_cast<GDLWidgetText*>(GDLWidget::GetWidget( event.GetId()));
648   if( widget == NULL)
649   {
650 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_TEXT_EVENTS)
651     wxMessageOutputStderr().Printf(_T("GDLWidget == NULL: %d\n"),event.GetId());
652 #endif
653     event.Skip();
654     return;
655   }
656   bool report = widget->HasEventType( GDLWidget::EV_ALL );
657   bool edit = widget->IsEditable( );
658   if (report) {
659   //Do nothing, better than anything.
660     return;
661   }
662   event.Skip();
663 }
664 
OnText(wxCommandEvent & event)665 void gdlwxFrame::OnText( wxCommandEvent& event)
666 {
667 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_TEXT_EVENTS)
668   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnText: %d\n"),event.GetId());
669 #endif
670 
671   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId());
672 
673   bool isModified=false;
674   long selStart, selEnd;
675   DLong offset;
676   std::string lastValue;
677   std::string newValue;
678 
679   GDLWidget* widget = GDLWidget::GetWidget( event.GetId());
680   if( widget == NULL)
681   {
682 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_TEXT_EVENTS)
683     wxMessageOutputStderr().Printf(_T("GDLWidget == NULL: %d\n"),event.GetId());
684 #endif
685     event.Skip();
686     return;
687   }
688   if( widget->IsText())
689   {
690     wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>(widget->GetWxWidget());
691     if( textCtrl == NULL)
692     {
693       event.Skip();
694       std::cerr<<"No wxWidget!"<<std::endl; return; // happens on construction
695     }
696     textCtrl->GetSelection( &selStart, &selEnd);
697     offset = textCtrl->GetInsertionPoint();
698     lastValue = static_cast<GDLWidgetText*>(widget)->GetLastValue();
699     newValue = textCtrl->GetValue().mb_str(wxConvUTF8);
700     isModified = lastValue != newValue;
701     static_cast<GDLWidgetText*>(widget)->SetLastValue(newValue);
702 //return without producing event struct if eventType is not set
703     if (!(widget->HasEventType( GDLWidget::EV_ALL ))) return;
704 
705   }
706   else if ( widget->IsComboBox())
707   {
708     wxComboBox* control = dynamic_cast<wxComboBox*>(widget->GetWxWidget());
709     if( control == NULL)
710     {
711       event.Skip();
712       std::cerr<<"No wxWidget!"<<std::endl; return; // happens on construction
713     }
714     if (!control->IsEditable()) return; //no OnText Events shoudl be generated!
715     int pos = control->GetCurrentSelection() ; //would be control->GetSelection( &selStart, &selEnd); // with GTK
716     offset = control->GetInsertionPoint();
717     lastValue = static_cast<GDLWidgetComboBox*>(widget)->GetLastValue();
718     newValue = control->GetValue().mb_str(wxConvUTF8);
719     isModified = lastValue != newValue;
720 //    if (isModified) control->SetString(pos,wxString(newValue.c_str(), wxConvUTF8 ));
721     static_cast<GDLWidgetComboBox*>(widget)->SetLastValue(newValue);
722     return;
723   }
724   else
725   {
726     assert( widget->IsDropList());
727     wxChoice* control = dynamic_cast<wxChoice*>(widget->GetWxWidget());
728     if( control == NULL)
729     {
730       event.Skip();
731       std::cerr<<"No wxWidget!"<<std::endl; return; // happens on construction
732     }
733     int where = control->GetSelection();
734     if (where !=  wxNOT_FOUND) {
735       newValue=control->GetString(where).mb_str(wxConvUTF8);
736       lastValue = static_cast<GDLWidgetDropList*>(widget)->GetLastValue();
737       isModified = lastValue != newValue;
738       static_cast<GDLWidgetDropList*>(widget)->SetLastValue(newValue);
739     }
740   }
741 
742   DStructGDL*  widg;
743   if( !isModified)
744   {
745     widg = new DStructGDL( "WIDGET_TEXT_SEL");
746     widg->InitTag("ID", DLongGDL( event.GetId()));
747     widg->InitTag("TOP", DLongGDL( baseWidgetID));
748     widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
749     widg->InitTag("TYPE", DIntGDL( 3)); // selection
750     widg->InitTag("OFFSET", DLongGDL( offset));
751     widg->InitTag("LENGTH", DLongGDL( selEnd-selStart));
752   }
753   else
754   {
755     int lengthDiff = newValue.length() - lastValue.length();
756     if( lengthDiff < 0) // deleted
757     {
758       widg = new DStructGDL( "WIDGET_TEXT_DEL");
759       widg->InitTag("ID", DLongGDL( event.GetId()));
760       widg->InitTag("TOP", DLongGDL( baseWidgetID));
761       widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
762       widg->InitTag("TYPE", DIntGDL( 2)); // delete
763       widg->InitTag("OFFSET", DLongGDL( offset-1));
764       widg->InitTag("LENGTH", DLongGDL( -lengthDiff));
765     }
766     else if( lengthDiff == 0) // replace TODO: just flag the real change
767     {
768       // 1st delete all
769       widg = new DStructGDL( "WIDGET_TEXT_DEL");
770       widg->InitTag("ID", DLongGDL( event.GetId()));
771       widg->InitTag("TOP", DLongGDL( baseWidgetID));
772       widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
773       widg->InitTag("TYPE", DIntGDL( 2)); // delete
774       widg->InitTag("OFFSET", DLongGDL( 0));
775       widg->InitTag("LENGTH", DLongGDL( lastValue.length()));
776 
777       GDLWidget::PushEvent( baseWidgetID, widg);
778 
779       // 2nd insert new
780       widg = new DStructGDL( "WIDGET_TEXT_STR");
781       widg->InitTag("ID", DLongGDL( event.GetId()));
782       widg->InitTag("TOP", DLongGDL( baseWidgetID));
783       widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
784       widg->InitTag("TYPE", DIntGDL( 1)); // multiple char
785       widg->InitTag("OFFSET", DLongGDL( 0));
786       widg->InitTag("STR", DStringGDL( newValue));
787     }
788     else if( lengthDiff == 1)
789     {
790       widg = new DStructGDL( "WIDGET_TEXT_CH");
791       widg->InitTag("ID", DLongGDL( event.GetId()));
792       widg->InitTag("TOP", DLongGDL( baseWidgetID));
793       widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
794       widg->InitTag("TYPE", DIntGDL( 0)); // single char
795       widg->InitTag("OFFSET", DLongGDL( offset+1));
796       widg->InitTag("CH", DByteGDL( newValue[offset<newValue.length()?offset:newValue.length()-1]));
797     }
798     else // > 1
799     {
800       int nVLenght = newValue.length();
801       if( offset < lengthDiff)
802 	lengthDiff = offset;
803       std::string str = "";
804       if( offset <= nVLenght && lengthDiff > 0)
805 	str = newValue.substr(offset-lengthDiff,lengthDiff);
806 
807       widg = new DStructGDL( "WIDGET_TEXT_STR");
808       widg->InitTag("ID", DLongGDL( event.GetId()));
809       widg->InitTag("TOP", DLongGDL( baseWidgetID));
810       widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
811       widg->InitTag("TYPE", DIntGDL( 1)); // multiple char
812       widg->InitTag("OFFSET", DLongGDL( offset));
813       widg->InitTag("STR", DStringGDL( str));
814     }
815   }
816 
817   GDLWidget::PushEvent( baseWidgetID, widg);
818 }
819 
820 
821 //NOT USED
822 //void gdlwxFrame::OnTextEnter( wxCommandEvent& event)
823 //{
824 //#if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_TEXT_EVENTS)
825 //  wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnTextEnter: %d\n"),event.GetId());
826 //#endif
827 //
828 //  WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId());
829 //
830 //  DLong offset;
831 //  std::string newValue;
832 //
833 //  GDLWidget* widget = GDLWidget::GetWidget( event.GetId());
834 //  if( widget == NULL)
835 //  {
836 //#if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_TEXT_EVENTS)
837 //    wxMessageOutputStderr().Printf(_T("GDLWidget == NULL: %d\n"),event.GetId());
838 //#endif
839 //    event.Skip();
840 //    return;
841 //  }
842 //  if( widget->IsText())
843 //  {
844 //    wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>(widget->GetWxWidget());
845 //    offset = textCtrl->GetInsertionPoint();
846 //    newValue = textCtrl->GetValue().mb_str(wxConvUTF8);
847 //    static_cast<GDLWidgetText*>(widget)->SetLastValue(newValue);
848 //  // create GDL event struct
849 //  DStructGDL*  widg;
850 //  widg = new DStructGDL( "WIDGET_TEXT_CH");
851 //  widg->InitTag("ID", DLongGDL( event.GetId()));
852 //  widg->InitTag("TOP", DLongGDL( baseWidgetID));
853 //  widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
854 //  widg->InitTag("TYPE", DIntGDL( 0)); // single char
855 //  widg->InitTag("OFFSET", DLongGDL( offset));
856 //  widg->InitTag("CH", DByteGDL( '\n'));
857 //
858 //  GDLWidget::PushEvent( baseWidgetID, widg);
859 //  }
860 //  else if( widget->IsComboBox())
861 //  {
862 //  // create GDL event struct
863 //  DStructGDL*  widgcbox;
864 //  int selectValue = event.GetSelection();
865 //  wxString strValue = event.GetString();
866 //
867 //  widgcbox = new DStructGDL( "WIDGET_COMBOBOX");
868 //  widgcbox->InitTag("ID", DLongGDL( event.GetId()));
869 //  widgcbox->InitTag("TOP", DLongGDL( baseWidgetID));
870 //  widgcbox->InitTag("HANDLER", DLongGDL( baseWidgetID ));
871 //  widgcbox->InitTag("INDEX", DLongGDL( selectValue));
872 //  widgcbox->InitTag("STR", DStringGDL( std::string(strValue.mb_str(wxConvUTF8)) ));
873 //
874 //  GDLWidget::PushEvent( baseWidgetID, widgcbox);
875 //  }
876 //  else
877 //  {
878 //  assert( widget->IsDropList());
879 //  // create GDL event struct
880 //  DStructGDL*  widdrplst;
881 //  int selectValue = event.GetSelection();
882 //  widdrplst = new DStructGDL( "WIDGET_DROPLIST");
883 //  widdrplst->InitTag("ID", DLongGDL( event.GetId()));
884 //  widdrplst->InitTag("TOP", DLongGDL( baseWidgetID));
885 //  widdrplst->InitTag("HANDLER", DLongGDL( baseWidgetID ));
886 //  widdrplst->InitTag("INDEX", DLongGDL( selectValue));
887 //
888 //  GDLWidget::PushEvent( baseWidgetID, widdrplst);
889 //  }
890 //}
891 
OnPageChanged(wxNotebookEvent & event)892 void gdlwxFrame::OnPageChanged( wxNotebookEvent& event)
893 {
894 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
895   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnPageChanged: %d\n"),event.GetId());
896 #endif
897 
898   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId());
899 
900   // create GDL event struct
901   DStructGDL*  widg;
902   widg = new DStructGDL( "WIDGET_TAB");
903   widg->InitTag("ID", DLongGDL( event.GetId()));
904   widg->InitTag("TOP", DLongGDL( baseWidgetID));
905   widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
906   widg->InitTag("TAB", DLongGDL( event.GetSelection()));
907 
908   GDLWidget::PushEvent( baseWidgetID, widg);
909   event.Skip();
910 }
911 
912 //Timer-filtered resizing for graphics.
913 
914 // mouse.LeftIsDown() is not present before wxWidgets  2.8.12 , find an alternative.
OnTimerPlotResize(wxTimerEvent & event)915 void gdlwxPlotFrame::OnTimerPlotResize(wxTimerEvent& event)
916 {
917 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_TIMER_EVENTS)
918   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnTimerPlotResize: %d (%d,%d).."), event.GetId(), frameSize.x, frameSize.y);
919 #endif
920   wxMouseState mouse = wxGetMouseState();
921 #if wxCHECK_VERSION(3,0,0)
922   if (mouse.LeftIsDown()) {
923 #else
924   if (mouse.LeftDown()) {
925 #endif
926     m_resizeTimer->Start(50, wxTIMER_ONE_SHOT);
927     return;
928   }
929   //there may have been size events since the start of the timer. Process them.
930 //   frameSize=this->GetSize();
931    gdlwxGraphicsPanel* w = dynamic_cast<gdlwxGraphicsPanel*> (this->GetChildren().GetFirst()->GetData());
932    if (w==NULL)     {
933       event.Skip();
934       std::cerr<<"No wxWidget!"<<std::endl; return; // happens on construction
935     }
936    wxSizeEvent sizeEvent(frameSize, w->GetId());
937    w->OnPlotWindowSize(sizeEvent);
938 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_TIMER_EVENTS)
939    wxMessageOutputStderr().Printf(_T("gdlwxFrame::OnTimerPlotResize() has been Processed.\n"));
940 #endif
941 }
942 
943 void gdlwxPlotFrame::OnPlotSizeWithTimer(wxSizeEvent& event) {
944   wxSize newSize = event.GetSize();
945   if (frameSize == newSize) {
946     event.Skip();
947     return;
948   }
949   frameSize = newSize; //no cost
950 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_SIZE_EVENTS)
951   wxMessageOutputStderr().Printf(_T("in gdlwxPlotWindow::OnPlotSizeWithTimer: new framesize is %d %d ; mouseState %d & Processed.\n"), frameSize.x, frameSize.y, wxGetMouseState().LeftIsDown());
952 #endif
953   //is it a resize of frame due to a manual intervention?
954   wxMouseState mouse = wxGetMouseState();
955 #if wxCHECK_VERSION(3,0,0)
956   if (mouse.LeftIsDown()) {
957 #else
958   if (mouse.LeftDown()) {
959 #endif
960     m_resizeTimer->Start(50, wxTIMER_ONE_SHOT);
961     return;
962   } else { //take it immediately.
963     m_resizeTimer->StartOnce(1);
964   }
965 }
966 void gdlwxPlotFrame::OnPlotWindowSize(wxSizeEvent &event) {
967 
968   wxSize newSize = event.GetSize(); //size returned by the external frame
969   gdlwxGraphicsPanel* w = dynamic_cast<gdlwxGraphicsPanel*> (this->GetChildren().GetFirst()->GetData());
970    if (w==NULL)     {
971       event.Skip();
972       std::cerr<<"No wxWidget!"<<std::endl; return; // happens on construction
973     }
974    wxSizeEvent sizeEvent(frameSize, w->GetId());
975    w->OnPlotWindowSize(sizeEvent);
976    event.Skip();
977 }
978 
979 //same for widget_draw
980 // mouse.LeftIsDown() is not present before wxWidgets  2.8.12 , find an alternative.
981 void gdlwxFrame::OnTimerResize(wxTimerEvent& event)
982 {
983 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_TIMER_EVENTS)
984   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnTimerResize: %d (%d,%d).."), event.GetId(), frameSize.x, frameSize.y);
985 #endif
986   wxMouseState mouse = wxGetMouseState();
987 #if wxCHECK_VERSION(3,0,0)
988   if (mouse.LeftIsDown()) {
989 #else
990   if (mouse.LeftDown()) {
991 #endif
992     m_resizeTimer->Start(50, wxTIMER_ONE_SHOT);
993     return;
994   }
995 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_TIMER_EVENTS)
996   wxMessageOutputStderr().Printf(_T("Processed.\n"));
997 #endif
998     if (!gdlOwner) {event.Skip(); return;}
999   GDLWidget* owner = static_cast<GDLWidget*> (gdlOwner);
1000   if (!owner) return;
1001   DULong flags = 0;
1002   if (owner) flags = owner->GetEventFlags();
1003   if (flags & GDLWidget::EV_SIZE) {
1004     WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase(owner->GetWidgetID());
1005     // create GDL event struct
1006     DStructGDL* widgbase = new DStructGDL("WIDGET_BASE");
1007     widgbase->InitTag("ID", DLongGDL(owner->GetWidgetID()));
1008     widgbase->InitTag("TOP", DLongGDL(baseWidgetID));
1009     widgbase->InitTag("HANDLER", DLongGDL(baseWidgetID));
1010     widgbase->InitTag("X", DLongGDL(frameSize.x));
1011     widgbase->InitTag("Y", DLongGDL(frameSize.y));
1012     GDLWidget::PushEvent(baseWidgetID, widgbase);
1013   } else event.Skip();
1014 }
1015 
1016 //The idea is to avoid redraw as long as the user has not released the mouse (doing a resize of the window).
1017 // if the event happens and the mouse is pressed, we register the new size and start a 50 ms timer that will, if not canceled, resize the window.
1018 // The timer will be canceled and the actual size processed if the event shows that the mouse is not pressed anymore.
1019 void gdlwxFrame::OnSizeWithTimer(wxSizeEvent& event)
1020 {
1021   wxSize newSize = event.GetSize();
1022   if (frameSize == newSize) {event.Skip();return;}
1023   frameSize = newSize; //no cost
1024 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_SIZE_EVENTS)
1025   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnSizeWithTimer: new framesize is %d %d ; mouseState %d & Processed.\n"), frameSize.x, frameSize.y, wxGetMouseState().LeftIsDown());
1026 #endif
1027   //is it a resize of frame due to a manual intervention?
1028   wxMouseState mouse = wxGetMouseState();
1029 #if wxCHECK_VERSION(3,0,0)
1030   if (mouse.LeftIsDown()) {
1031 #else
1032   if (mouse.LeftDown()) {
1033 #endif
1034     m_resizeTimer->Start(50, wxTIMER_ONE_SHOT);
1035     return;
1036   } else { //take it immediately.
1037     m_resizeTimer->StartOnce(1);
1038   }
1039 }
1040 
1041   //must override wxWidget's OnSize method
1042  void gdlwxFrame::OnSize( wxSizeEvent& event)
1043  {
1044     if (!gdlOwner) {event.Skip(); return;}
1045 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_SIZE_EVENTS)
1046    wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnSize: %d.."),event.GetId());
1047 #endif
1048   // current bug ? Still OK?
1049   // onsize should not be called 1) when TLB is resized with widget_control
1050   // and 2) only at the end of a mouse resizing (wxSizeEvent is sent multiple times
1051   // when resizing a TLB. But variant with timer does not work correctly...)
1052     if (!gdlOwner) {event.Skip(); return;}
1053   GDLWidget* owner=static_cast<GDLWidget*>(gdlOwner);
1054   if (owner->GetParentID() != 0) {
1055     event.Skip();
1056     return; //ignore non-TLB size events.
1057   }
1058   wxSize newSize = event.GetSize();
1059   if (frameSize == newSize) {event.Skip();return;}
1060   frameSize=newSize;
1061   DULong flags=0;
1062   if( owner ) flags=owner->GetEventFlags();
1063   if (flags & GDLWidget::EV_SIZE) {
1064     WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase(owner->GetWidgetID());
1065 
1066     // create GDL event struct
1067     DStructGDL* widgbase = new DStructGDL("WIDGET_BASE");
1068     widgbase->InitTag("ID", DLongGDL(event.GetId()));
1069     widgbase->InitTag("TOP", DLongGDL(baseWidgetID));
1070     widgbase->InitTag("HANDLER", DLongGDL(baseWidgetID));
1071     widgbase->InitTag("X", DLongGDL(frameSize.x));
1072     widgbase->InitTag("Y", DLongGDL(frameSize.y));
1073     GDLWidget::PushEvent(baseWidgetID, widgbase);
1074   } else event.Skip(); //important, pass to others!
1075  #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_SIZE_EVENTS)
1076    wxMessageOutputStderr().Printf(_T("Processed.\n"));
1077  #endif
1078  }
1079 
1080 void gdlwxFrame::OnThumbTrack( wxScrollEvent& event)
1081 {
1082 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
1083   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnScroll: %d\n"),event.GetId());
1084 #endif
1085 
1086   GDLWidget* widget = GDLWidget::GetWidget( event.GetId());
1087   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId());
1088 
1089 //only slider for now:  if( widget->IsSlider())
1090     GDLWidgetSlider* sl = static_cast<GDLWidgetSlider*>(widget);
1091     DLong oldValue = sl->GetValue();
1092 
1093     DLong newSelection = event.GetSelection();
1094 
1095     if( newSelection != oldValue)
1096     {
1097       sl->SetValue( newSelection);
1098 
1099       // create GDL event struct
1100       DStructGDL*  widg;
1101       widg = new DStructGDL( "WIDGET_SLIDER");
1102       widg->InitTag("ID", DLongGDL( event.GetId()));
1103       widg->InitTag("TOP", DLongGDL( baseWidgetID));
1104       widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
1105       widg->InitTag("VALUE", DLongGDL( newSelection));
1106       widg->InitTag("DRAG", DIntGDL( 1)); // dragging events from here
1107 
1108       GDLWidget::PushEvent( baseWidgetID, widg);
1109      }
1110     return;
1111 //  }
1112 }
1113 
1114 void gdlwxFrame::OnThumbRelease( wxScrollEvent& event)
1115 {
1116 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
1117   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnThumbRelease: %d\n"),event.GetId());
1118 #endif
1119 
1120   GDLWidget* widget = GDLWidget::GetWidget( event.GetId());
1121 
1122   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId());
1123 
1124 //only slider for now: if( widget->IsSlider())
1125     GDLWidgetSlider* sl = static_cast<GDLWidgetSlider*>(widget);
1126 
1127     DLong newSelection = event.GetSelection();
1128 
1129     sl->SetValue( newSelection);
1130 
1131     // create GDL event struct
1132     DStructGDL*  widg;
1133     widg = new DStructGDL( "WIDGET_SLIDER");
1134     widg->InitTag("ID", DLongGDL( event.GetId()));
1135     widg->InitTag("TOP", DLongGDL( baseWidgetID));
1136     widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
1137     widg->InitTag("VALUE", DLongGDL( newSelection));
1138     widg->InitTag("DRAG", DIntGDL( 0)); // set events from here
1139 
1140     GDLWidget::PushEvent( baseWidgetID, widg);
1141 
1142     return;
1143 }
1144 
1145 //TRACKING.
1146 void gdlwxFrame::OnEnterWindow( wxMouseEvent &event ) {
1147 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_VISIBILITY_EVENTS)
1148   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnEnterWindow: %d\n"),event.GetId());
1149 #endif
1150  GDLWidget* widget = GDLWidget::GetWidget( event.GetId());
1151   if( widget == NULL) {
1152      event.Skip();
1153      return;
1154     }
1155   if ( widget->GetEventFlags() & GDLWidget::EV_TRACKING ) {
1156     WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1157     DStructGDL* widgtracking = new DStructGDL( "WIDGET_TRACKING" );
1158     widgtracking->InitTag( "ID", DLongGDL( event.GetId( ) ) );
1159     widgtracking->InitTag( "TOP", DLongGDL( baseWidgetID ) );
1160     widgtracking->InitTag( "HANDLER", DLongGDL( baseWidgetID ) );
1161     widgtracking->InitTag( "ENTER", DIntGDL( 1 ) );
1162     GDLWidget::PushEvent( baseWidgetID, widgtracking );
1163   }
1164  event.Skip();
1165 }
1166 
1167 void gdlwxFrame::OnLeaveWindow( wxMouseEvent &event ) {
1168 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_VISIBILITY_EVENTS)
1169   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnLeaveWindow: %d\n"),event.GetId());
1170 #endif
1171  GDLWidget* widget = GDLWidget::GetWidget( event.GetId());
1172   if( widget == NULL) {
1173      event.Skip();
1174      return;
1175   }
1176   if ( widget->GetEventFlags() & GDLWidget::EV_TRACKING ) {
1177     WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1178     DStructGDL* widgtracking = new DStructGDL( "WIDGET_TRACKING" );
1179     widgtracking->InitTag( "ID", DLongGDL( event.GetId( ) ) );
1180     widgtracking->InitTag( "TOP", DLongGDL( baseWidgetID ) );
1181     widgtracking->InitTag( "HANDLER", DLongGDL( baseWidgetID ) );
1182     widgtracking->InitTag( "ENTER", DIntGDL( 0 ) );
1183     GDLWidget::PushEvent( baseWidgetID, widgtracking );
1184   }
1185  event.Skip();
1186 }
1187 
1188 void gdlwxFrame::OnKBRDFocusChange( wxFocusEvent &event ) {
1189 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_KBRD_EVENTS)
1190   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnFocusChange: %d\n"),event.GetId());
1191 #endif
1192   GDLWidget* widget = GDLWidget::GetWidget( event.GetId());
1193   if( widget == NULL) {event.Skip(); return;}
1194   if ( widget->GetEventFlags() & GDLWidget::EV_KBRD_FOCUS ) {
1195     WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1196     DStructGDL* widgkbrdfocus = new DStructGDL( "WIDGET_KBRD_FOCUS" );
1197     widgkbrdfocus->InitTag( "ID", DLongGDL( event.GetId( ) ) );
1198     widgkbrdfocus->InitTag( "TOP", DLongGDL( baseWidgetID ) );
1199     widgkbrdfocus->InitTag( "HANDLER", DLongGDL( baseWidgetID ) );
1200     int enter=(event.GetEventType()==wxEVT_SET_FOCUS);
1201     widgkbrdfocus->InitTag( "ENTER", DIntGDL( enter ) );
1202     GDLWidget::PushEvent( baseWidgetID, widgkbrdfocus );
1203   } else event.Skip(); //"The focus event handlers should almost invariably call wxEvent::Skip() on their event argument to allow the default handling to take place. Failure to do this may result in incorrect behaviour of the native controls."
1204 }
1205 
1206 void gdlwxFrame::OnContextEvent( wxContextMenuEvent& event) {
1207 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
1208   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnContextEvent: %d\n"),event.GetId());
1209 #endif
1210  GDLWidget* widget = GDLWidget::GetWidget( event.GetId());
1211  WidgetIDT baseWidgetID;
1212  WidgetIDT eventID;
1213  if( widget == NULL) {
1214     if (!gdlOwner) {event.Skip(); return;}
1215     GDLWidget* owner=static_cast<GDLWidgetBase*>(gdlOwner);
1216     if( owner == NULL)
1217    {
1218      event.Skip();
1219      return;
1220   } else {
1221       widget=owner;
1222       baseWidgetID = owner->GetWidgetID();
1223       eventID = owner->GetWidgetID();
1224    }
1225   } else {
1226     baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1227     eventID = event.GetId( );
1228   }
1229   if ( widget->GetEventFlags() & GDLWidget::EV_CONTEXT ) {
1230     DStructGDL* widgcontext = new DStructGDL( "WIDGET_CONTEXT" );
1231     widgcontext->InitTag( "ID", DLongGDL( eventID ) );
1232     widgcontext->InitTag( "TOP", DLongGDL( baseWidgetID ) );
1233     widgcontext->InitTag( "HANDLER", DLongGDL( baseWidgetID ) );
1234     wxPoint position=event.GetPosition( );
1235     if (position==wxDefaultPosition) { //issued from keyboard
1236       position=wxGetMousePosition();
1237     }
1238       widgcontext->InitTag( "X", DLongGDL( position.x ) );
1239       widgcontext->InitTag( "Y", DLongGDL( position.y ) );
1240 //ROW AND COL, to be added for TABLE Widget
1241     if (widget->IsTable()){
1242       wxGridGDL * grid = dynamic_cast<wxGridGDL*> (widget->GetWxWidget());
1243       int col = grid->XToCol(position.x);
1244       int row = grid->YToRow(position.y);
1245       widgcontext->InitTag( "ROW", DLongGDL( row ) );
1246       widgcontext->InitTag( "ROW", DLongGDL( col ) );
1247     }
1248     GDLWidget::PushEvent( baseWidgetID, widgcontext );
1249   } else event.Skip();//normal end of event processing!
1250 }
1251 
1252 void gdlwxFrame::OnIconize( wxIconizeEvent & event)
1253 {
1254 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_VISIBILITY_EVENTS)
1255   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnIconize: %d\n"),event.GetId());
1256 #endif
1257   GDLWidget* widget = GDLWidget::GetWidget( event.GetId());
1258   if( widget == NULL) {event.Skip(); return;}
1259   if (!gdlOwner) {event.Skip(); return;}
1260   GDLWidget* owner=static_cast<GDLWidget*>(gdlOwner);
1261   DULong flags=0;
1262   if( owner ) flags=owner->GetEventFlags();
1263   if ( flags & GDLWidget::EV_ICONIFY ) {
1264     WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1265     DStructGDL* widgtlb_iconify_events = new DStructGDL( "WIDGET_TLB_ICONIFY" );
1266     widgtlb_iconify_events->InitTag( "ID", DLongGDL( event.GetId( ) ) );
1267     widgtlb_iconify_events->InitTag( "TOP", DLongGDL( baseWidgetID ) );
1268     widgtlb_iconify_events->InitTag( "HANDLER", DLongGDL( baseWidgetID ) );
1269     widgtlb_iconify_events->InitTag( "ICONIFIED", DIntGDL( event.IsIconized() ) );
1270     GDLWidget::PushEvent( baseWidgetID, widgtlb_iconify_events );
1271   } else event.Skip();
1272 }
1273 
1274 void gdlwxFrame::OnMove( wxMoveEvent & event)
1275 {
1276 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_MOVE_EVENTS)
1277   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnMove: %d\n"),event.GetId());
1278 #endif
1279   GDLWidget* widget = GDLWidget::GetWidget( event.GetId());
1280   if( widget == NULL) {event.Skip(); return;}
1281   if (!gdlOwner) {event.Skip(); return;}
1282   GDLWidget* owner=static_cast<GDLWidget*>(gdlOwner);
1283   DULong flags=0;
1284   if( owner ) flags=owner->GetEventFlags();
1285 
1286   if ( flags & GDLWidget::EV_MOVE ) {
1287     WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1288     DStructGDL* widgtlb_move_events = new DStructGDL( "WIDGET_TLB_MOVE" );
1289     widgtlb_move_events->InitTag( "ID", DLongGDL( event.GetId( ) ) );
1290     widgtlb_move_events->InitTag( "TOP", DLongGDL( baseWidgetID ) );
1291     widgtlb_move_events->InitTag( "HANDLER", DLongGDL( baseWidgetID ) );
1292     widgtlb_move_events->InitTag( "X", DLongGDL( event.GetPosition().x ) );
1293     widgtlb_move_events->InitTag( "Y", DLongGDL( event.GetPosition().y ) );
1294     GDLWidget::PushEvent( baseWidgetID, widgtlb_move_events );
1295   } else event.Skip();
1296 }
1297 
1298 void gdlwxFrame::OnCloseFrame( wxCloseEvent & event) {
1299 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_VISIBILITY_EVENTS)
1300   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnCloseFrame: %d\n"), event.GetId());
1301 #endif
1302   GDLWidget* widget = GDLWidget::GetWidget(event.GetId());
1303   if (widget == NULL) {
1304     event.Skip();
1305     return;
1306   }
1307   if (!gdlOwner) {
1308     event.Skip();
1309     return;
1310   }
1311   GDLWidget* owner = static_cast<GDLWidget*> (gdlOwner);
1312   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase(event.GetId());
1313   DStructGDL* widgtlb_kill_request_events = new DStructGDL("WIDGET_KILL_REQUEST");
1314   widgtlb_kill_request_events->InitTag("ID", DLongGDL(event.GetId()));
1315   widgtlb_kill_request_events->InitTag("TOP", DLongGDL(baseWidgetID));
1316   widgtlb_kill_request_events->InitTag("HANDLER", DLongGDL(baseWidgetID));
1317   GDLWidget::PushEvent(baseWidgetID, widgtlb_kill_request_events);
1318 }
1319 
1320 void gdlwxFrame::OnUnhandledCloseFrame( wxCloseEvent & event)
1321 {
1322 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_VISIBILITY_EVENTS)
1323   wxMessageOutputStderr().Printf(_T("in gdlwxFrame::OnUnhandledCloseFrame: %d\n"),event.GetId());
1324 #endif
1325   GDLWidget* widget = GDLWidget::GetWidget( event.GetId());
1326   if( widget == NULL) {event.Skip(); return;}
1327   if (!gdlOwner) {event.Skip(); return;}
1328     //destroy TLB widget
1329    delete gdlOwner;
1330 }
1331 
1332 void gdlwxPlotFrame::OnUnhandledClosePlotFrame(wxCloseEvent & event) {
1333 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_VISIBILITY_EVENTS)
1334   wxMessageOutputStderr().Printf(_T("in gdlwxPlotFrame::OnUnhandledClosePlotFrame: %d\n"), event.GetId());
1335 #endif
1336   // just destroy the window, things should follow their course.
1337   gdlwxPlotPanel* w = static_cast<gdlwxPlotPanel*> (this->GetChildren().GetFirst()->GetData());
1338   if (w) {
1339     GraphicsDevice::GetDevice()->WDelete(w->pstreamIx);
1340   }
1341 }
1342 
1343 void gdlwxDrawPanel::OnErase(wxEraseEvent& event)
1344 {
1345 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_VISIBILITY_EVENTS)
1346   wxMessageOutputStderr().Printf(_T("in gdlwxDrawPanel::OnErase: %d\n"),event.GetId());
1347 #endif
1348   event.Skip();
1349 }
1350 //Draw
1351 
1352 void gdlwxGraphicsPanel::OnPaint(wxPaintEvent& event)
1353 {
1354   if (drawSize.x<1||drawSize.y<1) return;
1355 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_PAINT_EVENTS)
1356   wxMessageOutputStderr().Printf(_T("in gdlwxGraphicsPanel::OnPaint: %d (%d,%d)\n"),event.GetId(),drawSize.x, drawSize.y);
1357 #endif
1358   this->RepaintGraphics();
1359   event.Skip();
1360 }
1361 
1362 void gdlwxPlotPanel::OnPlotWindowSize(wxSizeEvent &event) {
1363 
1364   wxSize newSize = event.GetSize(); //size returned by the external frame
1365   gdlwxPlotFrame* p = this->GetMyFrame();
1366   p->SetSize(newSize);
1367   newSize = p->GetClientSize();
1368 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_SIZE_EVENTS)
1369   wxMessageOutputStderr().Printf(_T("in gdlwxPlotPanel::OnPlotWindowSize: %d (%d,%d), (%d,%d)\n"), event.GetId(), event.GetSize().x, event.GetSize().y,
1370     newSize.x, newSize.y);
1371 #endif
1372   if (p->IsScrolled()) {
1373     bool enlarge = false;
1374     wxSize oldVirtualSize = this->GetVirtualSize();
1375     if (oldVirtualSize.x < newSize.x) {
1376       enlarge = true;
1377       oldVirtualSize.x = newSize.x;
1378     }
1379     if (oldVirtualSize.y < newSize.y) {
1380       enlarge = true;
1381       oldVirtualSize.y = newSize.y;
1382     }
1383     this->SetMinSize(newSize);
1384     this->SetSize(newSize);
1385     if (enlarge) this->ResizeDrawArea(oldVirtualSize);
1386   (*static_cast<DLongGDL*>(SysVar::D()->GetTag(SysVar::D()->Desc()->TagIndex("X_SIZE"), 0)))[0]
1387       = oldVirtualSize.x;
1388   (*static_cast<DLongGDL*>(SysVar::D()->GetTag(SysVar::D()->Desc()->TagIndex("Y_SIZE"), 0)))[0]
1389       = oldVirtualSize.y;
1390   } else {
1391     this->SetMinClientSize(newSize);
1392     this->SetClientSize(newSize);
1393     this->ResizeDrawArea(newSize);
1394   (*static_cast<DLongGDL*>(SysVar::D()->GetTag(SysVar::D()->Desc()->TagIndex("X_SIZE"), 0)))[0]
1395       = newSize.x;
1396   (*static_cast<DLongGDL*>(SysVar::D()->GetTag(SysVar::D()->Desc()->TagIndex("Y_SIZE"), 0)))[0]
1397       = newSize.y;
1398   }
1399 
1400   (*static_cast<DLongGDL*>(SysVar::D()->GetTag(SysVar::D()->Desc()->TagIndex("X_VSIZE"), 0)))[0]
1401       = newSize.x;
1402   (*static_cast<DLongGDL*>(SysVar::D()->GetTag(SysVar::D()->Desc()->TagIndex("Y_VSIZE"), 0)))[0]
1403       = newSize.y;
1404   event.Skip();
1405 }
1406 void gdlwxGraphicsPanel::OnPlotWindowSize(wxSizeEvent &event)
1407 {
1408 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_SIZE_EVENTS)
1409   wxMessageOutputStderr().Printf(_T("in gdlwxGraphicsPanel::OnPlotWindowSize: %d (%d,%d)\n"), event.GetId(), event.GetSize().x, event.GetSize().y);
1410 #endif
1411   wxSize newSize = event.GetSize();
1412   if (newSize.x < 1 || newSize.y < 1) {
1413 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_SIZE_EVENTS)
1414     wxMessageOutputStderr().Printf(_T("in gdlwxGraphicsPanel::OnPlotWindowSize: negative size rejected !\n"));
1415 #endif
1416     return;
1417   }
1418   this->ResizeDrawArea(newSize);
1419   event.Skip();
1420 }
1421 
1422 void gdlwxDrawPanel::OnMouseMove( wxMouseEvent &event ) {
1423   DULong eventFlags=myWidgetDraw->GetEventFlags();
1424 
1425   if ( eventFlags & GDLWidget::EV_MOTION ) {
1426     WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1427     DStructGDL* widgdraw = new DStructGDL( "WIDGET_DRAW" );
1428     widgdraw->InitTag( "ID", DLongGDL( myWidgetDraw->GetWidgetID() ) );
1429     widgdraw->InitTag( "TOP", DLongGDL( baseWidgetID ) );
1430     widgdraw->InitTag( "HANDLER", DLongGDL( baseWidgetID ) );
1431     widgdraw->InitTag( "TYPE", DIntGDL( 2 ) ); //motion
1432     widgdraw->InitTag( "X", DLongGDL( event.GetX() ) );
1433     widgdraw->InitTag( "Y", DLongGDL( drawSize.y-event.GetY()  ) );
1434     GDLWidget::PushEvent( baseWidgetID, widgdraw );
1435   } else event.Skip(); //normal end of event processing!
1436 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_MOVE_EVENTS)
1437   wxMessageOutputStderr().Printf(_T("in gdlwxDrawPanel::OnMouseMove: ID=%d, coords=(%d,%d)\n"),event.GetId(),event.GetX(),event.GetY());
1438 #endif
1439 }
1440 
1441 void gdlwxDrawPanel::OnMouseDown( wxMouseEvent &event ) {
1442 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_KBRD_EVENTS)
1443   wxMessageOutputStderr().Printf(_T("in gdlwxDrawPanel::OnMouseDown: %d\n"),event.GetId());
1444 #endif
1445   DULong eventFlags=myWidgetDraw->GetEventFlags();
1446 
1447   if ( eventFlags & GDLWidget::EV_BUTTON ) {
1448     WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1449     DStructGDL* widgdraw = new DStructGDL( "WIDGET_DRAW" );
1450     widgdraw->InitTag( "ID", DLongGDL( myWidgetDraw->GetWidgetID() ) );
1451     widgdraw->InitTag( "TOP", DLongGDL( baseWidgetID ) );
1452     widgdraw->InitTag( "HANDLER", DLongGDL( baseWidgetID ) );
1453     widgdraw->InitTag( "TYPE", DIntGDL( 0 ) ); //button Press
1454     widgdraw->InitTag( "X", DLongGDL( event.GetX() ) );
1455     widgdraw->InitTag( "Y", DLongGDL( drawSize.y-event.GetY()  ) );
1456     unsigned long btn=1<<(event.GetButton()-1);
1457     widgdraw->InitTag( "PRESS", DByteGDL( btn ));
1458     widgdraw->InitTag( "RELEASE", DByteGDL( 0 ) );
1459     widgdraw->InitTag( "CLICKS", DLongGDL( 1 ) );
1460     widgdraw->InitTag( "MODIFIERS", DLongGDL( 0 ) );
1461     widgdraw->InitTag( "CH", DByteGDL( 0 ) );
1462     widgdraw->InitTag( "KEY", DLongGDL( 0 ) );
1463     GDLWidget::PushEvent( baseWidgetID, widgdraw );
1464   } else event.Skip(); //normal end of event processing!
1465 }
1466 
1467 void gdlwxDrawPanel::OnMouseUp( wxMouseEvent &event ) {
1468 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_KBRD_EVENTS)
1469   wxMessageOutputStderr().Printf(_T("in gdlwxDrawPanel::OnMouseUp: %d\n"),event.GetId());
1470 #endif
1471   DULong eventFlags=myWidgetDraw->GetEventFlags();
1472 
1473   if ( eventFlags & GDLWidget::EV_BUTTON ) {
1474     WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1475     DStructGDL* widgdraw = new DStructGDL( "WIDGET_DRAW" );
1476     widgdraw->InitTag( "ID", DLongGDL( myWidgetDraw->GetWidgetID() ) );
1477     widgdraw->InitTag( "TOP", DLongGDL( baseWidgetID ) );
1478     widgdraw->InitTag( "HANDLER", DLongGDL( baseWidgetID ) );
1479     widgdraw->InitTag( "TYPE", DIntGDL( 1 ) ); //button Release
1480     widgdraw->InitTag( "X", DLongGDL( event.GetX() ) );
1481     widgdraw->InitTag( "Y", DLongGDL( drawSize.y-event.GetY()  ) );
1482     unsigned long btn=1<<(event.GetButton()-1);
1483     widgdraw->InitTag( "PRESS", DByteGDL( 0 ) );
1484     widgdraw->InitTag( "RELEASE", DByteGDL( btn ) );
1485     widgdraw->InitTag( "CLICKS", DLongGDL( 1 ) );
1486     widgdraw->InitTag( "MODIFIERS", DLongGDL( 0 ) );
1487     widgdraw->InitTag( "CH", DByteGDL( 0 ) );
1488     widgdraw->InitTag( "KEY", DLongGDL( 0 ) );
1489     GDLWidget::PushEvent( baseWidgetID, widgdraw );
1490   } else event.Skip();//normal end of event processing!
1491 }
1492 
1493 void gdlwxDrawPanel::OnMouseWheel( wxMouseEvent &event ) {
1494 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_KBRD_EVENTS)
1495   wxMessageOutputStderr().Printf(_T("in gdlwxDrawPanel::OnMouseWheel: %d\n"),event.GetId());
1496 #endif
1497   DULong eventFlags=myWidgetDraw->GetEventFlags();
1498 
1499   if ( eventFlags & GDLWidget::EV_WHEEL ) {
1500     WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1501     DStructGDL* widgdraw = new DStructGDL( "WIDGET_DRAW" );
1502     widgdraw->InitTag( "ID", DLongGDL( myWidgetDraw->GetWidgetID()  ) );
1503     widgdraw->InitTag( "TOP", DLongGDL( baseWidgetID ) );
1504     widgdraw->InitTag( "HANDLER", DLongGDL( baseWidgetID ) );
1505     widgdraw->InitTag( "TYPE", DIntGDL( 7 ) ); //wheel event
1506     widgdraw->InitTag( "X", DLongGDL( event.GetX() ) );
1507     widgdraw->InitTag( "Y", DLongGDL( drawSize.y-event.GetY()  ) );
1508     widgdraw->InitTag( "PRESS", DByteGDL( 0 ) );
1509     widgdraw->InitTag( "RELEASE", DByteGDL( 0 ) );
1510     widgdraw->InitTag( "CLICKS", DLongGDL( event.GetWheelRotation() ) );
1511     widgdraw->InitTag( "MODIFIERS", DLongGDL( 0 ) );
1512     widgdraw->InitTag( "CH", DByteGDL( 0 ) );
1513     widgdraw->InitTag( "KEY", DLongGDL( 0 ) );
1514     GDLWidget::PushEvent( baseWidgetID, widgdraw );
1515   }  else event.Skip();
1516 }
1517 
1518 void gdlwxDrawPanel::OnKey( wxKeyEvent &event ) {
1519 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_KBRD_EVENTS)
1520   wxMessageOutputStderr().Printf(_T("in gdlwxDrawPanel::OnKey: %d\n"),event.GetId());
1521 #endif
1522   DULong eventFlags=myWidgetDraw->GetEventFlags();
1523 
1524   int mode=1;
1525   if ( eventFlags & GDLWidget::EV_KEYBOARD || eventFlags & GDLWidget::EV_KEYBOARD2 ) {
1526     if (eventFlags & GDLWidget::EV_KEYBOARD2) mode=2;
1527 
1528     WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1529     DStructGDL* widgdraw = new DStructGDL( "WIDGET_DRAW" );
1530     widgdraw->InitTag( "ID", DLongGDL( myWidgetDraw->GetWidgetID() ) );
1531     widgdraw->InitTag( "TOP", DLongGDL( baseWidgetID ) );
1532     widgdraw->InitTag( "HANDLER", DLongGDL( baseWidgetID ) );
1533     widgdraw->InitTag( "X", DLongGDL( event.GetX() ) );
1534     widgdraw->InitTag( "Y", DLongGDL( drawSize.y-event.GetY()  ) );
1535     widgdraw->InitTag( "CLICKS", DLongGDL( 0 ) );
1536     widgdraw->InitTag( "PRESS", DByteGDL( (event.GetEventType() == wxEVT_KEY_DOWN) ) );
1537     widgdraw->InitTag( "RELEASE", DByteGDL( (event.GetEventType() == wxEVT_KEY_UP) ) );
1538 
1539     int start=0;
1540     int keyc=event.GetKeyCode( );
1541     //get key
1542     switch ( keyc ) {
1543       case WXK_NUMPAD_END: case WXK_END:
1544         start++;
1545       case WXK_NUMPAD_HOME: case WXK_HOME:
1546         start++;
1547       case WXK_NUMPAD_PAGEDOWN: case WXK_PAGEDOWN:
1548         start++;
1549       case WXK_NUMPAD_PAGEUP: case WXK_PAGEUP:
1550         start++;
1551       case WXK_NUMPAD_DOWN:case WXK_DOWN:
1552         start++;
1553       case WXK_NUMPAD_UP:case WXK_UP:
1554         start++;
1555       case WXK_NUMPAD_RIGHT:case WXK_RIGHT:
1556         start++;
1557       case WXK_NUMPAD_LEFT:case WXK_LEFT:
1558         start++;
1559       case WXK_ALT:
1560         start++;
1561       case WXK_CAPITAL: //not sure OK!
1562         start++;
1563       case WXK_CONTROL:
1564         start++;
1565       case WXK_SHIFT:
1566         start++;
1567         if ( mode==2 || start > 4 ) {
1568           widgdraw->InitTag( "TYPE", DIntGDL( 6 ) ); //special key
1569           widgdraw->InitTag( "KEY", DLongGDL( start ) );
1570           widgdraw->InitTag( "CH", DByteGDL( 0 ) );
1571           widgdraw->InitTag( "MODIFIERS", DLongGDL( event.GetModifiers()) );
1572           GDLWidget::PushEvent( baseWidgetID, widgdraw );
1573         }
1574         break;
1575       default:
1576         widgdraw->InitTag( "TYPE", DIntGDL( 5 ) ); //normal key
1577         widgdraw->InitTag( "KEY", DLongGDL( 0 ) );
1578         widgdraw->InitTag( "CH", DByteGDL( event.GetKeyCode() & 0xFF ) );
1579         widgdraw->InitTag( "MODIFIERS", DLongGDL( event.GetModifiers() ) );
1580         GDLWidget::PushEvent( baseWidgetID, widgdraw );
1581     }
1582   } else event.Skip();
1583 }
1584 
1585 void wxGridGDL::OnTableRowResizing(wxGridSizeEvent & event){
1586 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
1587   wxMessageOutputStderr().Printf(_T("in gdlGrid::OnTableRowResizing: %d\n"),event.GetId());
1588 #endif
1589   GDLWidgetTable* table = static_cast<GDLWidgetTable*>(GDLWidget::GetWidget(GDLWidgetTableID));
1590   DULong eventFlags=table->GetEventFlags();
1591   if (eventFlags & GDLWidget::EV_ALL) {
1592     WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1593     DStructGDL* widgtablerowheight = new DStructGDL( "WIDGET_TABLE_ROW_HEIGHT");
1594     widgtablerowheight->InitTag("ID", DLongGDL( event.GetId( ) ));
1595     widgtablerowheight->InitTag("TOP", DLongGDL( baseWidgetID));
1596     widgtablerowheight->InitTag("HANDLER", DLongGDL( baseWidgetID ));
1597     widgtablerowheight->InitTag("TYPE", DIntGDL(6)); // 6
1598     widgtablerowheight->InitTag("ROW", DLongGDL( event.GetRowOrCol() ));
1599     widgtablerowheight->InitTag("HEIGHT",DLongGDL( this->GetRowSize(event.GetRowOrCol())));
1600     // insert into structList
1601     GDLWidget::PushEvent( baseWidgetID, widgtablerowheight );
1602   } else event.Skip();
1603 }
1604 
1605 void wxGridGDL::OnTableColResizing(wxGridSizeEvent & event){
1606 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
1607   wxMessageOutputStderr().Printf(_T("in gdlGrid::OnTableColResizing: %d\n"),event.GetId());
1608 #endif
1609   GDLWidgetTable* table = static_cast<GDLWidgetTable*>(GDLWidget::GetWidget(GDLWidgetTableID));
1610   DULong eventFlags=table->GetEventFlags();
1611   if (eventFlags & GDLWidget::EV_ALL) {
1612     WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1613     DStructGDL* widgtablerowheight = new DStructGDL( "WIDGET_TABLE_COL_WIDTH");
1614     widgtablerowheight->InitTag("ID", DLongGDL( event.GetId( ) ));
1615     widgtablerowheight->InitTag("TOP", DLongGDL( baseWidgetID));
1616     widgtablerowheight->InitTag("HANDLER", DLongGDL( baseWidgetID ));
1617     widgtablerowheight->InitTag("TYPE", DIntGDL(7)); // 7
1618     widgtablerowheight->InitTag("COL", DLongGDL( event.GetRowOrCol() ));
1619     widgtablerowheight->InitTag("WIDTH",DLongGDL( this->GetColSize(event.GetRowOrCol())));
1620     // insert into structList
1621     GDLWidget::PushEvent( baseWidgetID, widgtablerowheight );
1622   } else event.Skip();
1623 }
1624 void  wxGridGDL::OnTableRangeSelection(wxGridRangeSelectEvent & event){
1625 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
1626   wxMessageOutputStderr().Printf(_T("in gdlGrid::OnTableRangeSelection: %d\n"),event.GetId());
1627 #endif
1628   //this event is called when a selection is added or changed (control-click, etc).
1629   //If we are not in disjoint mode, clear previous selection to mimick idl's when the user control-clicked.
1630   GDLWidgetTable* table = static_cast<GDLWidgetTable*>(GDLWidget::GetWidget(GDLWidgetTableID));
1631 
1632   DULong eventFlags=table->GetEventFlags();
1633   if (eventFlags & GDLWidget::EV_ALL  && !table->IsUpdating() ) {
1634     if (event.Selecting())
1635     {
1636       WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1637       DStructGDL* widgtablecelsel = new DStructGDL( "WIDGET_TABLE_CELL_SEL");
1638       widgtablecelsel->InitTag("ID",  DLongGDL( event.GetId( ) ));
1639       widgtablecelsel->InitTag("TOP", DLongGDL( baseWidgetID));
1640       widgtablecelsel->InitTag("HANDLER", DLongGDL( baseWidgetID ));
1641       widgtablecelsel->InitTag("TYPE",DIntGDL(4)); // 4 or 9
1642       widgtablecelsel->InitTag("SEL_LEFT",  DLongGDL( event.GetLeftCol()));
1643       widgtablecelsel->InitTag("SEL_TOP",  DLongGDL( event.GetTopRow()));
1644       widgtablecelsel->InitTag("SEL_RIGHT",  DLongGDL( event.GetRightCol()));
1645       widgtablecelsel->InitTag("SEL_BOTTOM",  DLongGDL( event.GetBottomRow()));
1646       GDLWidget::PushEvent( baseWidgetID, widgtablecelsel );
1647     } else {
1648       int ncols = dynamic_cast<wxGrid*>(event.GetEventObject())->GetNumberCols();
1649       int nrows = dynamic_cast<wxGrid*>(event.GetEventObject())->GetNumberRows();
1650       if (event.GetLeftCol()==0 && event.GetRightCol()==ncols-1 && event.GetTopRow()==0 && event.GetBottomRow()==nrows-1 ) {
1651         WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1652         DStructGDL* widgtablecelsel = new DStructGDL( "WIDGET_TABLE_CELL_SEL");
1653         widgtablecelsel->InitTag("ID",  DLongGDL( event.GetId( ) ));
1654         widgtablecelsel->InitTag("TOP", DLongGDL( baseWidgetID ));
1655         widgtablecelsel->InitTag("HANDLER", DLongGDL( baseWidgetID ) );
1656         widgtablecelsel->InitTag("TYPE",DIntGDL( 4 )); //
1657         widgtablecelsel->InitTag("SEL_LEFT",  DLongGDL( -1 ));
1658         widgtablecelsel->InitTag("SEL_TOP",  DLongGDL( -1 ));
1659         widgtablecelsel->InitTag("SEL_RIGHT",  DLongGDL( -1 ));
1660         widgtablecelsel->InitTag("SEL_BOTTOM",  DLongGDL( -1 ));
1661         GDLWidget::PushEvent( baseWidgetID, widgtablecelsel );
1662       } else {
1663         if (!table->GetDisjointSelection()  && event.ControlDown() ) this->ClearSelection(); else {
1664         WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1665         DStructGDL* widgtablecelsel = new DStructGDL( "WIDGET_TABLE_CELL_DESEL");
1666         widgtablecelsel->InitTag("ID",  DLongGDL( event.GetId( ) ));
1667         widgtablecelsel->InitTag("TOP", DLongGDL( baseWidgetID ));
1668         widgtablecelsel->InitTag("HANDLER", DLongGDL( baseWidgetID ));
1669         widgtablecelsel->InitTag("TYPE",DIntGDL( 9 )); // 9
1670         widgtablecelsel->InitTag("SEL_LEFT",  DLongGDL( event.GetLeftCol() ));
1671         widgtablecelsel->InitTag("SEL_TOP",  DLongGDL( event.GetTopRow() ));
1672         widgtablecelsel->InitTag("SEL_RIGHT",  DLongGDL( event.GetRightCol() ));
1673         widgtablecelsel->InitTag("SEL_BOTTOM",  DLongGDL( event.GetBottomRow()));
1674         GDLWidget::PushEvent( baseWidgetID, widgtablecelsel );
1675         }
1676       }
1677     }
1678 }
1679   else event.Skip();
1680 }
1681 
1682  void  wxGridGDL::OnTableCellSelection(wxGridEvent & event){
1683 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
1684   wxMessageOutputStderr().Printf(_T("in gdlGrid::OnTableCellSelection: %d\n"),event.GetId());
1685 #endif
1686 //This event is called only when the user left-clicks somewhere, thus deleting all previous selection.
1687   GDLWidgetTable* table = static_cast<GDLWidgetTable*>(GDLWidget::GetWidget(GDLWidgetTableID));
1688   if (!table->GetDisjointSelection()  && event.ControlDown() ) {
1689     table->ClearSelection();
1690   }
1691 //For compatibility with idl, we should force to select the current table entry.
1692   this->SelectBlock(event.GetRow(),event.GetCol(),event.GetRow(),event.GetCol(),FALSE);
1693   event.Skip();
1694 }
1695 
1696 
1697 //Forget this function for the time being!
1698 
1699 //  void  gdlGrid::OnTableCellSelection(wxGridEvent & event){
1700 //#if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_ALL_EVENTS)
1701 //  wxMessageOutputStderr().Printf(_T("in gdlGrid::OnTableCellSelection: %d\n"),event.GetId());
1702 //#endif
1703 ////This event is called only when the user left-clicks somewhere, thus deleting all previous selection.
1704 //
1705 //  GDLWidgetTable* table = static_cast<GDLWidgetTable*>(GDLWidget::GetWidget(GDLWidgetTableID));
1706 //  DULong eventFlags=table->GetEventFlags();
1707 //
1708 //  if (eventFlags & GDLWidget::EV_ALL && !table->IsUpdating()) {
1709 //    WidgetIDT baseWidgetID = GDLWidget::GetTopLevelBase( event.GetId( ) );
1710 //    DStructGDL* widgtablecelsel = new DStructGDL( "WIDGET_TABLE_CELL_SEL");
1711 //    widgtablecelsel->InitTag("ID",  DLongGDL( event.GetId( ) ));
1712 //    widgtablecelsel->InitTag("TOP", DLongGDL( baseWidgetID));
1713 //    widgtablecelsel->InitTag("HANDLER", DLongGDL( baseWidgetID ));
1714 //    widgtablecelsel->InitTag("TYPE",DIntGDL(4)); // 4
1715 //    widgtablecelsel->InitTag("SEL_LEFT",  DLongGDL(event.Selecting()?event.GetCol():-1));
1716 //    widgtablecelsel->InitTag("SEL_TOP",  DLongGDL(event.Selecting()?event.GetRow(): -1 ));
1717 //    widgtablecelsel->InitTag("SEL_RIGHT",  DLongGDL( event.Selecting()?event.GetCol():-1 ));
1718 //    widgtablecelsel->InitTag("SEL_BOTTOM",  DLongGDL( event.Selecting()?event.GetCol():-1 ));
1719 //    GDLWidget::PushEvent( baseWidgetID, widgtablecelsel );
1720 //  }
1721 //  else event.Skip();
1722 ////For compatibility with idl, we should force to select the current table entry.
1723 ////  this->SelectBlock(event.GetRow(),event.GetCol(),event.GetRow(),event.GetCol(),FALSE);
1724 //  if (table->IsUpdating()) {cerr<<"cleared"<<endl; table->ClearUpdating();}
1725 //  }
1726 
1727 //void gdlGrid::OnTextEnter( wxCommandEvent& event)
1728 //{
1729 //#if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_ALL_EVENTS)
1730 //  wxMessageOutputStderr().Printf(_T("in gdlGrid::OnTextEnter: %d\n"),event.GetId());
1731 //#endif
1732 //}
1733 //void gdlGrid::OnText( wxCommandEvent& event)
1734 //{
1735 //#if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_ALL_EVENTS)
1736 //  wxMessageOutputStderr().Printf(_T("in gdlGrid::OnText: %d\n"),event.GetId());
1737 //#endif
1738 //  GDLWidgetTable* table = static_cast<GDLWidgetTable*>(GDLWidget::GetWidget(GDLWidgetTableID));
1739 //  DULong eventFlags=table->GetEventFlags();
1740 //
1741 //  WidgetIDT baseWidgetID = GDLWidget::GetTopLevelBase(GDLWidgetTableID);
1742 //
1743 //  bool isModified;
1744 //  long selStart, selEnd;
1745 //  DLong offset;
1746 //  std::string lastValue;
1747 //  std::string newValue;
1748 //
1749 //  wxTextCtrl* textCtrl = dynamic_cast<wxTextCtrl*>(event.GetEventObject());
1750 //  if( textCtrl == NULL)
1751 //  {
1752 //    event.Skip();
1753 //    std::cerr<<"No wxWidget!"<<std::endl; return; // happens on construction
1754 //  }
1755 //  textCtrl->GetSelection( &selStart, &selEnd);
1756 //  offset = textCtrl->GetInsertionPoint();
1757 //  lastValue = textCtrl->GetLabelText().mb_str(wxConvUTF8);
1758 //  newValue = textCtrl->GetValue().mb_str(wxConvUTF8);
1759 //  isModified = lastValue != newValue;
1760 ////  textCtrl->SetValue(wxString(newValue, wxConvUTF8));
1761 ////return without producing event struct if eventType is not set
1762 //  if (!(eventFlags & GDLWidget::EV_ALL )) return;
1763 //
1764 //  DStructGDL*  widg;
1765 //  if( !isModified)
1766 //  {
1767 //    widg = new DStructGDL( "WIDGET_TABLE_TEXT_SEL");
1768 //    widg->InitTag("ID", DLongGDL( GDLWidgetTableID));
1769 //    widg->InitTag("TOP", DLongGDL( baseWidgetID));
1770 //    widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
1771 //    widg->InitTag("TYPE", DIntGDL( 3)); // selection
1772 //    widg->InitTag("OFFSET", DLongGDL( offset));
1773 //    widg->InitTag("LENGTH", DLongGDL( selEnd-selStart));
1774 //    widg->InitTag("X", DLongGDL( 0 ));
1775 //    widg->InitTag("Y", DLongGDL( 0 ));
1776 //  }
1777 //  else
1778 //  {
1779 //    int lengthDiff = newValue.length() - lastValue.length();
1780 //    if( lengthDiff < 0) // deleted
1781 //    {
1782 //      widg = new DStructGDL( "WIDGET_TABLE_DEL");
1783 //      widg->InitTag("ID", DLongGDL(  GDLWidgetTableID));
1784 //      widg->InitTag("TOP", DLongGDL( baseWidgetID));
1785 //      widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
1786 //      widg->InitTag("TYPE", DIntGDL( 2)); // delete
1787 //      widg->InitTag("OFFSET", DLongGDL( offset-1));
1788 //      widg->InitTag("LENGTH", DLongGDL( -lengthDiff));
1789 //      widg->InitTag("X", DLongGDL( 0 ));
1790 //      widg->InitTag("Y", DLongGDL( 0 ));
1791 //    }
1792 //    else if( lengthDiff == 0) // replace TODO: just flag the real change
1793 //    {
1794 //      // 1st delete all
1795 //      widg = new DStructGDL( "WIDGET_TABLE_DEL");
1796 //      widg->InitTag("ID", DLongGDL(  GDLWidgetTableID));
1797 //      widg->InitTag("TOP", DLongGDL( baseWidgetID));
1798 //      widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
1799 //      widg->InitTag("TYPE", DIntGDL( 2)); // delete
1800 //      widg->InitTag("OFFSET", DLongGDL( 0));
1801 //      widg->InitTag("LENGTH", DLongGDL( lastValue.length()));
1802 //      widg->InitTag("X", DLongGDL( 0 ));
1803 //      widg->InitTag("Y", DLongGDL( 0 ));
1804 //
1805 //      GDLWidget::PushEvent( baseWidgetID, widg);
1806 //
1807 //      // 2nd insert new
1808 //      widg = new DStructGDL( "WIDGET_TABLE_STR");
1809 //      widg->InitTag("ID", DLongGDL(  GDLWidgetTableID));
1810 //      widg->InitTag("TOP", DLongGDL( baseWidgetID));
1811 //      widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
1812 //      widg->InitTag("TYPE", DIntGDL( 1)); // multiple char
1813 //      widg->InitTag("OFFSET", DLongGDL( 0));
1814 //      widg->InitTag("STR", DStringGDL( newValue));
1815 //      widg->InitTag("X", DLongGDL( 0 ));
1816 //      widg->InitTag("Y", DLongGDL( 0 ));
1817 //    }
1818 //    else if( lengthDiff == 1)
1819 //    {
1820 //      widg = new DStructGDL( "WIDGET_TABLE_CH");
1821 //      widg->InitTag("ID", DLongGDL(  GDLWidgetTableID));
1822 //      widg->InitTag("TOP", DLongGDL( baseWidgetID));
1823 //      widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
1824 //      widg->InitTag("TYPE", DIntGDL( 0)); // single char
1825 //      widg->InitTag("OFFSET", DLongGDL( offset+1));
1826 //      widg->InitTag("CH", DByteGDL( newValue[offset<newValue.length()?offset:newValue.length()-1]));
1827 //      widg->InitTag("X", DLongGDL( 0 ));
1828 //      widg->InitTag("Y", DLongGDL( 0 ));
1829 //    }
1830 //    else // lengthDiff > 1
1831 //    {
1832 //      int nVLenght = newValue.length();
1833 //      if( offset < lengthDiff)  lengthDiff = offset;
1834 //      std::string str = "";
1835 //      if( offset <= nVLenght && lengthDiff > 0)	 str = newValue.substr(offset-lengthDiff,lengthDiff+1);
1836 //
1837 //      widg = new DStructGDL( "WIDGET_TABLE_STR");
1838 //      widg->InitTag("ID", DLongGDL( GDLWidgetTableID));
1839 //      widg->InitTag("TOP", DLongGDL( baseWidgetID));
1840 //      widg->InitTag("HANDLER", DLongGDL( baseWidgetID ));
1841 //      widg->InitTag("TYPE", DIntGDL( 1)); // multiple char
1842 //      widg->InitTag("OFFSET", DLongGDL( offset));
1843 //      widg->InitTag("STR", DStringGDL( str));
1844 //      widg->InitTag("X", DLongGDL( 0 ));
1845 //      widg->InitTag("Y", DLongGDL( 0 ));
1846 //    }
1847 //  }
1848 //  GDLWidget::PushEvent( baseWidgetID, widg);
1849 //}
1850 //
1851 
1852 void wxTreeCtrlGDL::OnTreeKeyDown(wxKeyEvent & event){
1853 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
1854   wxMessageOutputStderr().Printf(_T("in gdlTreeCtrl::OnTreeKeyDown: %d\n"),event.GetId());
1855 #endif
1856   wxTreeCtrlGDL* me=dynamic_cast<wxTreeCtrlGDL*>(event.GetEventObject());
1857   me->SetCurrentModifier(event.GetKeyCode(), false); //add
1858 }
1859 void wxTreeCtrlGDL::OnTreeKeyUp(wxKeyEvent & event){
1860 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
1861   wxMessageOutputStderr().Printf(_T("in gdlTreeCtrl::OnTreeKeyUp: %d\n"),event.GetId());
1862 #endif
1863   wxTreeCtrlGDL* me=dynamic_cast<wxTreeCtrlGDL*>(event.GetEventObject());
1864   me->SetCurrentModifier(event.GetKeyCode(), true); //remove
1865 }
1866 void wxTreeCtrlGDL::OnItemActivated(wxTreeEvent & event){
1867 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
1868   wxMessageOutputStderr().Printf(_T("in gdlTreeCtrl::OnItemActivated: %d\n"),event.GetId());
1869 #endif
1870   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1871 //get GDLWidgetTree ID which was passed as wxTreeItemData at creation to identify
1872 //the GDL widget that received the event
1873     wxTreeCtrlGDL* me=dynamic_cast<wxTreeCtrlGDL*>(event.GetEventObject());
1874 
1875     DStructGDL* treeselect = new DStructGDL( "WIDGET_TREE_SEL");
1876     treeselect->InitTag("ID", DLongGDL( dynamic_cast<wxTreeItemDataGDL*>(me->GetItemData(event.GetItem()))->widgetID ));
1877     treeselect->InitTag("TOP", DLongGDL( baseWidgetID));
1878     treeselect->InitTag("HANDLER", DLongGDL( GDLWidgetTreeID ));
1879     treeselect->InitTag("TYPE", DIntGDL(0)); // 0
1880     treeselect->InitTag("CLICKS",DLongGDL(2));
1881     // insert into structList
1882     GDLWidget::PushEvent( baseWidgetID, treeselect );
1883     event.Skip();
1884     me->Refresh();
1885 }
1886 
1887 
1888 void wxTreeCtrlGDL::OnItemSelected(wxTreeEvent & event){
1889 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
1890   wxMessageOutputStderr().Printf(_T("in gdlTreeCtrl::OnItemSelected: %d\n"),event.GetId());
1891 #endif
1892   WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1893 //get GDLWidgetTree ID which was passed as wxTreeItemData at creation to identify
1894 //the GDL widget that received the event
1895     wxTreeCtrlGDL* me=dynamic_cast<wxTreeCtrlGDL*>(event.GetEventObject());
1896     WidgetIDT selected=dynamic_cast<wxTreeItemDataGDL*>(me->GetItemData(event.GetItem()))->widgetID;
1897     GDLWidgetTree* tree= static_cast<GDLWidgetTree*>(GDLWidget::GetWidget(selected));
1898     //inform root widget it is selected
1899     GDLWidgetTree* root=tree->GetMyRootGDLWidgetTree();
1900     DStructGDL* treeselect = new DStructGDL( "WIDGET_TREE_SEL");
1901     treeselect->InitTag("ID", DLongGDL( selected ));
1902     treeselect->InitTag("TOP", DLongGDL( baseWidgetID));
1903     treeselect->InitTag("HANDLER", DLongGDL( GDLWidgetTreeID ));
1904     treeselect->InitTag("TYPE", DIntGDL(0)); // 0
1905     treeselect->InitTag("CLICKS",DLongGDL(1));
1906     // insert into structList
1907     GDLWidget::PushEvent( baseWidgetID, treeselect );
1908     event.Skip();
1909     me->Refresh();
1910 }
1911 
1912 void wxTreeCtrlGDL::OnDrag(wxTreeEvent & event){
1913 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
1914   wxMessageOutputStderr().Printf(_T("in gdlTreeCtrl::OnDrag: %d "),event.GetId());
1915 #endif
1916   if (!event.GetItem().IsOk()) {    event.Skip(); return;}
1917 
1918     wxTreeCtrlGDL* me=dynamic_cast<wxTreeCtrlGDL*>(event.GetEventObject());
1919     WidgetIDT selected=dynamic_cast<wxTreeItemDataGDL*>(me->GetItemData(event.GetItem()))->widgetID;
1920     GDLWidgetTree* tree= static_cast<GDLWidgetTree*>(GDLWidget::GetWidget(selected));
1921 
1922     if (tree->GetDragability()) {//was set or inherited from one ancestor that was set
1923       me->SetDragged(selected);
1924       event.Allow();
1925 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
1926   wxMessageOutputStderr().Printf(_T("allowed.\n"),event.GetId());
1927 #endif
1928   return;
1929     }
1930 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
1931   wxMessageOutputStderr().Printf(_T("canceled.\n"),event.GetId());
1932 #endif
1933   event.Skip();
1934 }
1935 
1936 void wxTreeCtrlGDL::OnDrop(wxTreeEvent & event){
1937 
1938 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
1939   wxMessageOutputStderr().Printf(_T("in gdlTreeCtrl::OnDrop: %d\n"),event.GetId());
1940 #endif
1941   if (!event.GetItem().IsOk()) {    event.Skip(); return;}
1942 
1943     WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1944     wxTreeCtrlGDL* me=dynamic_cast<wxTreeCtrlGDL*>(event.GetEventObject());
1945     WidgetIDT selected=dynamic_cast<wxTreeItemDataGDL*>(me->GetItemData(event.GetItem()))->widgetID;
1946     GDLWidgetTree* item = static_cast<GDLWidgetTree*>(GDLWidget::GetWidget(selected));
1947     GDLWidgetTree* root=item->GetMyRootGDLWidgetTree();
1948 
1949     if (item->GetDropability()) { //was set or inherited from one ancestor that was set
1950  //get GDLWidgetTree ID which was passed as wxTreeItemData at creation to identify
1951 //the GDL widget that received the event
1952       DStructGDL* treedrop = new DStructGDL( "WIDGET_DROP");
1953       treedrop->InitTag("ID", DLongGDL( item->GetWidgetID()  )); //ID of the destination
1954       treedrop->InitTag("TOP", DLongGDL( baseWidgetID));
1955       treedrop->InitTag("HANDLER", DLongGDL( GDLWidgetTreeID ));
1956       treedrop->InitTag("DRAG_ID", DLongGDL( GDLWidgetTreeID )); // ID of the source TREE
1957       treedrop->InitTag("POSITION",item->IsFolder()?DIntGDL(2):DIntGDL(3)); //   1 above 2 on 3 below destination widget
1958       treedrop->InitTag("X",DLongGDL(event.GetPoint().x)); //x and Y coord of position wrt lower left corner of destination tree widget
1959       treedrop->InitTag("Y",DLongGDL(event.GetPoint().y));
1960       treedrop->InitTag("MODIFIERS",DIntGDL(me->GetCurrentModifier())); //mask with 1 shift 2 control 4 caps lock 8 alt
1961       // insert into structList
1962       GDLWidget::PushEvent( baseWidgetID, treedrop );
1963   }
1964     //unset dragged
1965     me->SetDragged(0);
1966 
1967   event.Skip();
1968     me->Refresh();
1969 
1970 }
1971 void wxTreeCtrlGDL::OnItemExpanded(wxTreeEvent & event){
1972 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
1973   wxMessageOutputStderr().Printf(_T("in gdlTreeCtrl::OnItemExpanded: %d\n"),event.GetId());
1974 #endif
1975   if (!event.GetItem().IsOk()) {    event.Skip(); return;}
1976 
1977       WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
1978 //get GDLWidgetTree ID which was passed as wxTreeItemData at creation to identify
1979 //the GDL widget that received the event
1980     wxTreeCtrlGDL* me=dynamic_cast<wxTreeCtrlGDL*>(event.GetEventObject());
1981     WidgetIDT whoID=dynamic_cast<wxTreeItemDataGDL*>(me->GetItemData(event.GetItem()))->widgetID;
1982     GDLWidgetTree* who=static_cast<GDLWidgetTree*>(GDLWidget::GetWidget(whoID));
1983     who->SetExpanded(true);
1984     DStructGDL* treeexpand = new DStructGDL( "WIDGET_TREE_EXPAND");
1985     treeexpand->InitTag("ID", DLongGDL( whoID ));
1986     treeexpand->InitTag("TOP", DLongGDL( baseWidgetID));
1987     treeexpand->InitTag("HANDLER", DLongGDL( GDLWidgetTreeID ));
1988     treeexpand->InitTag("TYPE", DIntGDL(1)); // 1
1989     treeexpand->InitTag("EXPAND",DLongGDL(1)); //1 expand
1990     // insert into structList
1991     GDLWidget::PushEvent( baseWidgetID, treeexpand );
1992     event.Skip();
1993     me->Refresh();
1994 }
1995 void wxTreeCtrlGDL::OnItemCollapsed(wxTreeEvent & event){
1996 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
1997   wxMessageOutputStderr().Printf(_T("in gdlTreeCtrl::OnItemCollapsed: %d\n"),event.GetId());
1998 #endif
1999   if (!event.GetItem().IsOk()) {    event.Skip(); return;}
2000 
2001       WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
2002 //get GDLWidgetTree ID which was passed as wxTreeItemData at creation to identify
2003 //the GDL widget that received the event
2004     wxTreeCtrlGDL* me=dynamic_cast<wxTreeCtrlGDL*>(event.GetEventObject());
2005     WidgetIDT whoID=dynamic_cast<wxTreeItemDataGDL*>(me->GetItemData(event.GetItem()))->widgetID;
2006     GDLWidgetTree* who=static_cast<GDLWidgetTree*>(GDLWidget::GetWidget(whoID));
2007     who->SetExpanded(false);
2008     DStructGDL* treeexpand = new DStructGDL( "WIDGET_TREE_EXPAND");
2009     treeexpand->InitTag("ID", DLongGDL( whoID ) );
2010     treeexpand->InitTag("TOP", DLongGDL( baseWidgetID));
2011     treeexpand->InitTag("HANDLER", DLongGDL( GDLWidgetTreeID ));
2012     treeexpand->InitTag("TYPE", DIntGDL(1)); // 1
2013     treeexpand->InitTag("EXPAND",DLongGDL(0)); //0 collapse
2014     // insert into structList
2015     GDLWidget::PushEvent( baseWidgetID, treeexpand );
2016     event.Skip();
2017     me->Refresh();
2018 }
2019  void wxTreeCtrlGDL::OnItemStateClick(wxTreeEvent & event){
2020 #if (GDL_DEBUG_ALL_EVENTS || GDL_DEBUG_OTHER_EVENTS)
2021   wxMessageOutputStderr().Printf(_T("in gdlTreeCtrl::OnItemCollapsed: %d\n"),event.GetId());
2022 #endif
2023   if (!event.GetItem().IsOk()) {    event.Skip(); return;}
2024   // change checked state first
2025   this->SetItemState(event.GetItem(),wxTREE_ITEMSTATE_NEXT);
2026 
2027       WidgetIDT baseWidgetID = GDLWidget::GetIdOfTopLevelBase( event.GetId( ) );
2028 //get GDLWidgetTree ID which was passed as wxTreeItemData at creation to identify
2029 //the GDL widget that received the event
2030     wxTreeCtrlGDL* me=dynamic_cast<wxTreeCtrlGDL*>(event.GetEventObject());
2031 
2032     DStructGDL* treeechecked = new DStructGDL( "WIDGET_TREE_CHECKED");
2033     treeechecked->InitTag("ID", DLongGDL( dynamic_cast<wxTreeItemDataGDL*>(me->GetItemData(event.GetItem()))->widgetID ));
2034     treeechecked->InitTag("TOP", DLongGDL( baseWidgetID));
2035     treeechecked->InitTag("HANDLER", DLongGDL( GDLWidgetTreeID ));
2036     treeechecked->InitTag("TYPE", DIntGDL(2)); // 2
2037     treeechecked->InitTag("STATE",DLongGDL(this->GetItemState(event.GetItem()))); //on off
2038     // insert into structList
2039     GDLWidget::PushEvent( baseWidgetID, treeechecked );
2040     event.Skip();
2041     me->Refresh();
2042  }
2043 #endif
2044