fix compile against newer giflib
[rofl0r-obeditor.git] / src / common__ob_controls.cpp
blob39efb4e55ce7c3bb1bd7ab3771c8e58438385a41
1 /*
2 * common__ob_controls.cpp
4 * Created on: 28 avr. 2009
5 * Author: pat
6 */
8 #include "wx/wxprec.h"
9 #ifndef WX_PRECOMP
10 #include "wx/wx.h"
11 #endif
13 #include <wx/dir.h>
14 #include "common__ob_controls.h"
15 #include "common__ob_object.h"
16 #include "common__object_stage.h"
18 using namespace std;
21 //****************************************************
22 std::map<wxString,ob_property*> ob_props;
23 //****************************************************
25 //-------------------------------------------------------------
26 static
27 atom_path*
28 ANN__new_atom( const wxString& tag )
30 atom_path* t = new atom_path;
31 t->tag = tag;
32 t->num_token = -1;
33 return t;
36 //-------------------------------------------------------------
37 static
38 atom_path*
39 ANN__new_atom( int num_token )
41 atom_path* t = new atom_path;
42 t->tag = wxString();
43 t->num_token = num_token;
44 return t;
47 //-------------------------------------------------------------
48 static
49 atom_path*
50 ANN__new_atom( atom_path* at )
52 if( at == NULL )
53 return NULL;
55 atom_path* t = new atom_path;
56 t->tag = at->tag;
57 t->num_token = at->num_token;
58 return t;
61 //****************************************************
62 ob_token_path::ob_token_path( const wxString& tag, int num_token )
64 l_atoms.push_back( ANN__new_atom(tag) );
65 if( num_token >= 0 )
66 l_atoms.push_back( ANN__new_atom(num_token) );
69 //-------------------------------------------------------------
70 ob_token_path&
71 ob_token_path::operator=( const ob_token_path& obtp )
73 Clear_l_atoms();
74 std::list<atom_path*>::const_iterator it(obtp.l_atoms.begin())
75 , it_end (obtp.l_atoms.end());
76 for( ; it != it_end; it++ )
77 l_atoms.push_back( ANN__new_atom( *it ));
78 return *this;
81 //-------------------------------------------------------------
82 ob_token_path::ob_token_path(const ob_token_path& ob_tp, const wxString& subtag,int num_sub_token )
84 *this = ob_tp;
85 if( subtag != wxString() )
87 l_atoms.push_back( ANN__new_atom( subtag ) );
88 if( num_sub_token >= 0 )
89 l_atoms.push_back( ANN__new_atom(num_sub_token) );
93 //-------------------------------------------------------------
94 ob_token_path::ob_token_path( ob_token_path& src )
96 std::list<atom_path*>::iterator it(src.l_atoms.begin())
97 , it_end (src.l_atoms.end());
98 for( ; it != it_end; it++ )
99 l_atoms.push_back( ANN__new_atom( *it ));
102 //-------------------------------------------------------------
103 ob_token_path::~ob_token_path()
105 Clear_l_atoms();
108 //-------------------------------------------------------------
109 void
110 ob_token_path::Clear_l_atoms()
112 while( l_atoms.empty() == false )
114 atom_path* at = l_atoms.front();
115 l_atoms.pop_front();
116 if( at != NULL )
117 delete at;
121 //-------------------------------------------------------------
122 bool
123 ob_token_path::IsEmpty()
125 return l_atoms.empty();
128 //-------------------------------------------------------------
129 wxString
130 ob_token_path::GetPath()
132 wxString res;
133 std::list<atom_path*>::iterator it(l_atoms.begin())
134 , it_end (l_atoms.end());
135 for( ; it != it_end; it++ )
137 if( *it == NULL )
138 continue;
139 if( (*it)->tag != wxString() )
141 if( res.Len() == 0 )
142 res += (*it)->tag;
143 else
144 res += wxT(">") + (*it)->tag;
146 else
148 res += wxT("=") + IntToStr((*it)->num_token );
149 return res;
152 return res;
156 //-------------------------------------------------------------
157 ob_token_path*
158 ob_token_path::BuildPath_Sibling_Token( int decal )
160 if( l_atoms.size() < 2 )
161 return NULL;
162 ob_token_path* res = new ob_token_path;
163 std::list<atom_path*>::iterator it(l_atoms.begin())
164 , it_end (l_atoms.end());
165 int nb_tokens = 0;
166 bool b_ok = false;
167 for( ; it != it_end; it++ )
169 b_ok = false;
170 if( *it == NULL )
171 continue;
173 res->l_atoms.push_back( ANN__new_atom(*it) );
174 if( (*it)->tag == wxString() )
176 nb_tokens++;
177 b_ok = true;
181 if( nb_tokens != 1 || b_ok == false )
183 delete res;
184 return NULL;
186 atom_path* last_atom = res->l_atoms.back();
187 last_atom->num_token += decal;
188 if( last_atom->num_token <= 0 )
190 delete res;
191 return NULL;
194 return res;
197 //-------------------------------------------------------------
198 bool
199 ob_token_path::Append__SubToken( int num_sub_token )
201 if( num_sub_token <= 0 )
202 return false;
203 if( l_atoms.size() < 1 )
204 return false;
205 if( l_atoms.back()->tag != wxString() )
206 return false;
207 l_atoms.push_back( ANN__new_atom( num_sub_token ));
208 return true;
211 //-------------------------------------------------------------
212 bool
213 ob_token_path::Append__SubTag( const wxString& subtag )
215 if( subtag == wxString() );
216 return false;
217 if( l_atoms.back()->tag == wxString() )
218 return false;
219 l_atoms.push_back( ANN__new_atom( subtag ));
220 return true;
223 //-------------------------------------------------------------
224 ob_object*
225 ob_token_path::Resolve_With( ob_object* _o )
227 ob_object* res = _o;
228 std::list<atom_path*>::iterator it(l_atoms.begin())
229 , it_end (l_atoms.end());
230 for( ; it != it_end; it++ )
232 if( res == NULL )
233 return NULL;
234 atom_path* at = (*it);
235 if( at->tag != wxString() )
236 res = res->GetSubObject( at->tag );
237 else
238 break;
240 return res;
243 //-------------------------------------------------------------
244 wxString
245 ob_token_path::Get_With( ob_object* _o )
247 if( l_atoms.back()->tag != wxString() )
248 return wxString();
250 ob_object* subobj = Resolve_With( _o );
251 if( subobj == NULL )
252 return wxString();
253 return subobj->GetToken( l_atoms.back()->num_token );
256 //-------------------------------------------------------------
257 bool
258 ob_token_path::Set_To( ob_object* _o, wxString& val )
260 // FIXME ???
261 return false;
265 //****************************************************
266 //****************************************************
267 //****************************************************
268 //****************************************************
269 //****************************************************
270 //****************************************************
271 //****************************************************
272 //****************************************************
273 //****************************************************
275 //*********** new event
276 DEFINE_EVENT_TYPE(wxEVT_OBPROP_CHANGE)
278 wxColour ob_property::default_values_color( 200,200,255);
280 //****************************************************
281 ob_property::ob_property( const wxString& _tag,const int _num_token
282 , int _type_prop
283 , const wxString& _def_val, int _do_on_default )
285 int ind_dblpt = _tag.Find( wxT(":") );
286 if( ind_dblpt != wxNOT_FOUND )
288 prefix = _tag.Left(ind_dblpt);
289 tag = _tag.Right(_tag.Len()-ind_dblpt-1);
291 else
293 prefix = wxString();
294 tag = _tag;
296 num_token = _num_token;
297 type_prop = _type_prop;
298 def_val = _def_val;
299 do_on_default = _do_on_default;
303 //-------------------------------------------------------------
304 ob_property::~ob_property()
308 //-------------------------------------------------------------
309 void
310 ob_property::SetRange(wxWindow* _comboBox, int min,int max)
312 if( max < min )
313 return;
315 wxComboBox* comboBox = (wxComboBox*) _comboBox;
316 comboBox->Clear();
318 for( int i = min; i <= max; i++ )
320 wxStringClientData *_data = new wxStringClientData();
321 _data->SetData( IntToStr( i ) );
322 comboBox->Append( IntToStr( i ), _data );
326 //-------------------------------------------------------------
327 void
328 ob_property::SetEnums(wxWindow* _comboBox, const wxArrayString& _displayed, const wxArrayString& _values)
330 if( _displayed.Count() != _values.Count() )
332 wxMessageBox( wxT("BUG!!!\nob_property::SetEnums\n counts doesn't match !\n") );
333 return;
336 wxComboBox* comboBox = (wxComboBox*) _comboBox;
337 comboBox->Clear();
339 for( size_t i = 0; i < _displayed.Count(); i++ )
341 wxStringClientData *_data = new wxStringClientData();
342 _data->SetData( _values[i] );
343 comboBox->Append( _displayed[i], _data );
347 //-------------------------------------------------------------
348 wxSizer*
349 ob_property::BuildControls(
350 ob_object* obj
351 , wxWindow* parent
352 , wxWindow*& theCtrl
353 , const wxString& ctrlName, int ctrl_w
354 , const wxString& str_label, int label_w
355 , int more_styles
358 wxValidator* validator = NULL;
359 int _type;
360 switch( type_prop )
362 case PROPTYPE_STRING:
363 _type = 0;
364 validator = (wxValidator*) wxDefaultValidator.Clone();
365 break;
366 case PROPTYPE_STRING_NO_WS:
367 _type = 0;
368 validator = new wxTextValidator_NoWhiteSpace();
369 break;
370 case PROPTYPE_NUMBER:
371 _type = 0;
372 validator = new wxValidator_Restrict_Range('0','9');
373 break;
374 case PROPTYPE_NEGATIVENUMBER:
375 _type = 0;
376 validator = new wxValidator_Restrict_Range('0','9');
377 break;
378 case PROPTYPE_RELATIVENUMBER:
379 _type = 0;
380 validator = new wxValidatorIntegerRelative();
381 break;
382 case PROPTYPE_FLOAT:
383 _type = 0;
384 validator = new wxValidatorFloat();
385 break;
386 case PROPTYPE_FLOAT_POSITIVE:
387 _type = 0;
388 validator = new wxValidatorFloatPositive();
389 break;
392 case PROPTYPE_OBFILE:
393 _type = 1;
394 break;
396 case PROPTYPE_BOOL:
397 case PROPTYPE_BOOL_EXSISTENCE:
398 _type = 2;
399 break;
400 case PROPTYPE_ENUMS:
401 case PROPTYPE_RANGE:
402 _type = 3;
403 break;
405 default:
406 return NULL;
409 wxSizer* sizer_sub = NULL;
410 wxWindow* label = NULL;
411 theCtrl = NULL;
412 if( _type == 0 )
414 sizer_sub = new wxBoxSizer( wxHORIZONTAL );
416 if( str_label != wxString() )
418 label = new wxStaticText( parent, wxID_ANY, str_label
419 ,wxDefaultPosition,wxSize(label_w,-1) );
420 sizer_sub->Add(label, 0, wxALIGN_CENTER );
423 theCtrl = new wxTextCtrl(
424 parent, wxID_ANY, wxString()
425 , wxDefaultPosition, wxSize(ctrl_w,-1)
426 , wxBORDER_SUNKEN|wxTE_PROCESS_ENTER |more_styles
427 , *validator
428 , ctrlName );
429 theCtrl->Connect(
430 wxEVT_COMMAND_TEXT_UPDATED
431 , wxCommandEventHandler(ob_property::Evt_TxtChange)
432 , NULL, this );
433 sizer_sub->Add( theCtrl );
436 else if( _type == 1 )
438 sizer_sub = new wxBoxSizer( wxHORIZONTAL );
439 if( str_label != wxString() )
441 label = new wxStaticText( parent, wxID_ANY, str_label
442 ,wxDefaultPosition,wxSize(label_w,-1)
444 sizer_sub->Add(label, 0, wxALIGN_CENTER );
447 theCtrl = new prObFileChooserCtrl(
448 parent, wxID_ANY
449 , wxString()
450 , true
451 , ctrl_w
453 theCtrl->SetName( ctrlName );
454 theCtrl->Connect(
455 wxEVT_OBFILECHOOSER_CHANGE
456 , wxCommandEventHandler(ob_property::Evt_FileChange)
457 , NULL, this );
458 sizer_sub->Add( theCtrl );
460 else if( _type == 2 )
462 sizer_sub = new wxBoxSizer( wxHORIZONTAL );
463 theCtrl = new wxCheckBox(
464 parent, wxID_ANY, str_label
465 , wxDefaultPosition, wxSize(ctrl_w,-1)
466 , wxBORDER_SUNKEN |more_styles
467 , wxDefaultValidator
468 , ctrlName );
469 theCtrl->Connect(
470 wxEVT_COMMAND_CHECKBOX_CLICKED
471 , wxCommandEventHandler(ob_property::Evt_ChckChange)
472 , NULL, this );
473 sizer_sub->Add( theCtrl );
475 else if( _type == 3 )
477 sizer_sub = new wxBoxSizer( wxHORIZONTAL );
478 label = new wxStaticText( parent, wxID_ANY, str_label
479 ,wxDefaultPosition,wxSize(label_w,-1) );
480 sizer_sub->Add(label, 0, wxALIGN_CENTER );
482 theCtrl = new wxComboBox(
483 parent, wxID_ANY, wxString()
484 , wxDefaultPosition, wxSize( ctrl_w, -1 )
485 , 0, NULL
486 , more_styles
487 , wxDefaultValidator
488 , ctrlName );
489 theCtrl->Connect(
490 wxEVT_COMMAND_COMBOBOX_SELECTED
491 , wxCommandEventHandler(ob_property::Evt_Combo)
492 , NULL, this );
493 sizer_sub->Add( theCtrl );
496 if( theCtrl != NULL )
497 theCtrl->SetClientData( (void*) obj );
499 if( validator != NULL )
500 delete validator;
501 return sizer_sub;
504 //-------------------------------------------------------------
505 wxString
506 ob_property::Get_SpecialDefault_Val(ob_object* _o )
508 if( referer_path.IsEmpty() == true )
509 return wxString();
511 if( ob_stage::Is_Stage_Spawn_Type( _o ) == true )
513 ob_spawn* o = (ob_spawn*) _o;
514 if( o->entity_ref == NULL || o->entity_ref->obj_container == NULL)
515 return wxString();
517 return referer_path.Get_With( o->entity_ref->obj_container );
520 return wxString();
523 //-------------------------------------------------------------
524 bool
525 ob_property::Have_SpecialDefault_Val(ob_object* _o )
527 if( referer_path.IsEmpty() == true )
528 return false;
529 if( ob_stage::Is_Stage_Spawn_Type( _o ) == true )
531 ob_spawn* o = (ob_spawn*) _o;
532 if( o->entity_ref == NULL || o->entity_ref->obj_container == NULL)
533 return false;
535 return referer_path.Resolve_With( o->entity_ref->obj_container ) != NULL;
538 return false;
541 //-------------------------------------------------------------
542 wxString
543 ob_property::Get_Default_Val(ob_object* _o )
545 if( _o == NULL )
546 return def_val;
547 wxString res = Get_SpecialDefault_Val( _o );
548 if( res != wxString() )
549 return res;
550 return def_val;
553 //-------------------------------------------------------------
554 wxString
555 ob_property::Get_Curr_Value(ob_object* _o)
557 if( tag.Upper() == _o->name.Upper() || tag == wxString() )
558 return _o->GetToken( num_token );
560 ob_object* subobj = _o->GetSubObject( tag );
561 if( subobj == NULL )
562 return wxString();
564 return subobj->GetToken( num_token );
567 //-------------------------------------------------------------
568 bool
569 ob_property::Update_CtrlVal( wxWindow* ctrl )
571 // Some sanity checks
572 if( ctrl == NULL )
573 return false;
574 ob_object* obj = (ob_object*) ctrl->GetClientData();
575 if( obj == NULL)
576 return false;
577 wxString w_name = ctrl->GetName();
578 wxString typ_Ctrl = w_name.Left(2);
579 if( typ_Ctrl != wxT("TC")
580 && typ_Ctrl != wxT("CO")
581 && typ_Ctrl != wxT("CH")
583 return false;
585 // Get the curr val for the object
586 wxString val = Get_Curr_Value( obj );
588 if( typ_Ctrl == wxT("TC") )
590 wxTextCtrl* t = ((wxTextCtrl*)ctrl);
591 if( t->GetValue() == val )
592 return true;
593 obj->SetEdited( true );
594 t->ChangeValue( val );
595 return true;
598 if( typ_Ctrl == wxT("CO") )
600 wxComboBox* t = ((wxComboBox*)ctrl);
601 int curr_ind = t->GetCurrentSelection();
603 int new_ind = wxNOT_FOUND;
604 for( size_t i = 0 ; i < t->GetCount() ; i ++)
606 wxStringClientData* scd =
607 (wxStringClientData*)t->GetClientObject(i);
608 if( scd->GetData().Upper() == val.Upper() )
610 new_ind = i;
611 break;
614 if( new_ind == curr_ind )
615 return true;
617 obj->SetEdited( true );
618 t->SetSelection( new_ind );
619 return true;
622 if( typ_Ctrl == wxT("CH") )
624 wxCheckBox* t = ((wxCheckBox*)ctrl);
625 if( t->GetValue() == (val == wxT("1")) )
626 return true;
628 obj->SetEdited( true );
629 t->SetValue( ! t->GetValue() );
630 return true;
633 return false;
637 //-------------------------------------------------------------
638 ob_object*
639 ob_property::CreateDefaultObject(ob_object* o)
641 ob_object* subobj = new ob_object( tag );
642 wxString pref = tag;
643 if( prefix != wxString() )
644 pref = prefix + wxT(":") + pref;
645 // Insert default values
646 for( int i = 0; i < num_token - 1; i ++ )
648 wxString t_tag = pref + wxT("=") + IntToStr(i);
649 if( ob_props.find(t_tag) == ob_props.end() ||ob_props[t_tag] == NULL )
651 subobj->SetToken( i, wxT("0") );
653 else
655 subobj->SetToken( i, ob_props[t_tag]->Get_Default_Val(o) );
658 subobj->SetToken( num_token, Get_Default_Val(o) );
659 return subobj;
662 //-------------------------------------------------------------
663 void
664 ob_property::Signal_Modified( ob_object* obj, wxWindow* theCtrl)
666 if( obj == NULL )
667 return;
669 obj->edited = true;
670 if( obj->parent != NULL )
671 obj->parent->edited = true;
672 wxCommandEvent evt(wxEVT_OBPROP_CHANGE, theCtrl->GetId());
673 theCtrl->ProcessEvent(evt);
676 //-------------------------------------------------------------
677 void
678 ob_property::MayTruncate(ob_object* obj, ob_object* subobj, wxWindow* theCtrl )
680 size_t i = num_token + 1;
681 wxString pref = tag;
682 if( prefix != wxString() )
683 pref = prefix + wxT(":") + pref;
684 wxString t_tag = pref + wxT("=") + IntToStr(i);
685 while( ob_props.find(t_tag) != ob_props.end() && ob_props[t_tag] != NULL )
687 // Subobject deny truncation
688 if( ob_props[t_tag]->do_on_default != OBPROP_TRUNCATE )
689 return;
691 // Subobject is not on default val
692 if( ob_props[t_tag]->Get_Default_Val(obj)
693 != subobj->GetToken( i ) )
694 return;
696 i++;
697 wxString t_tag = pref + wxT("=") + IntToStr(i);
700 // truncate the uppers tokens
701 if( (int) subobj->nb_tokens > num_token )
703 Signal_Modified( obj, theCtrl );
704 subobj->nb_tokens = num_token;
707 // truncate the lowers tokens
708 for( i = num_token;i >= 0; i-- )
710 wxString t_tag = pref + wxT("=") + IntToStr(i);
711 if( ob_props.find(t_tag) != ob_props.end() && ob_props[t_tag] != NULL )
712 return;
714 if( ob_props[t_tag]->do_on_default != OBPROP_TRUNCATE )
715 return;
717 // Subobject is not on default val
718 if( ob_props[t_tag]->Get_Default_Val(obj)
719 != subobj->GetToken( i )
721 return;
723 if( subobj->nb_tokens > i-1 )
725 Signal_Modified( obj, theCtrl );
726 subobj->nb_tokens = i-1;
731 //-------------------------------------------------------------
732 void
733 ob_property::pUpdate( ob_object* obj, wxWindow* theCtrl, const wxString& val )
735 wxString prec_val;
736 ob_object* subobj = NULL;
737 if( tag.Upper() != obj->name.Upper() && tag != wxString() )
739 subobj = obj->GetSubObject( tag );
740 if( subobj == NULL && val == Get_Default_Val(obj) )
741 return;
743 else
744 subobj = obj;
746 if( subobj != NULL && val == Get_Default_Val(obj) )
748 switch (do_on_default & OBPROP_DEF_MASK)
750 case OBPROP_DEL_TAG:
751 Signal_Modified( obj, theCtrl);
752 subobj->Rm();
753 return;
754 case OBPROP_TRUNCATE:
755 subobj->SetToken( num_token, val );
756 MayTruncate(obj,subobj,theCtrl);
757 return;
761 if( subobj == NULL )
763 subobj = CreateDefaultObject(obj);
764 obj->Add_SubObj( subobj );
765 Signal_Modified( obj, theCtrl);
767 else
769 prec_val = subobj->GetToken( num_token );
770 if( prec_val == val )
771 return;
774 subobj->SetToken( num_token, val );
775 Signal_Modified( obj, theCtrl);
778 //-------------------------------------------------------------
779 void
780 ob_property::Evt_TxtChange(wxCommandEvent& evt)
782 wxTextCtrl* _ctrl = (wxTextCtrl*) evt.GetEventObject();
783 if( _ctrl == NULL)
784 return;
785 ob_object* obj = (ob_object*) _ctrl->GetClientData();
786 if( obj == NULL)
787 return;
789 wxString val = _ctrl->GetValue();
790 if( val == wxString() && (do_on_default & OBPROP_SETDEF_IFEMPTY) != 0 )
792 val = Get_Default_Val(obj);
793 _ctrl->ChangeValue( val );
796 if( val == Get_SpecialDefault_Val(obj) && Have_SpecialDefault_Val(obj) == true )
797 _ctrl->SetBackgroundColour( default_values_color );
798 else
799 _ctrl->SetBackgroundColour( *wxWHITE );
801 pUpdate( obj, _ctrl, val );
802 evt.Skip();
806 //-------------------------------------------------------------
807 void
808 ob_property::Evt_FileChange(wxCommandEvent& evt)
810 prObFileChooserCtrl* _ctrl = (prObFileChooserCtrl*) evt.GetEventObject();
811 if( _ctrl == NULL)
812 return;
813 ob_object* obj = (ob_object*) _ctrl->GetClientData();
814 if( obj == NULL)
815 return;
817 pUpdate( obj, _ctrl, _ctrl->GetObPath() );
818 evt.Skip();
821 //-------------------------------------------------------------
822 void
823 ob_property::Evt_ChckChange(wxCommandEvent& evt)
825 wxCheckBox* _ctrl = (wxCheckBox*) evt.GetEventObject();
826 if( _ctrl == NULL)
827 return;
828 ob_object* obj = (ob_object*) _ctrl->GetClientData();
829 if( obj == NULL)
830 return;
832 pUpdate( obj, _ctrl, BoolToStr(_ctrl->GetValue()) );
833 evt.Skip();
837 //-------------------------------------------------------------
838 void
839 ob_property::Evt_Combo(wxCommandEvent& evt)
841 wxComboBox* _ctrl = (wxComboBox*) evt.GetEventObject();
842 if( _ctrl == NULL)
843 return;
844 ob_object* obj = (ob_object*) _ctrl->GetClientData();
845 if( obj == NULL)
846 return;
848 if( _ctrl->GetSelection() == wxNOT_FOUND )
849 pUpdate( obj, _ctrl, Get_Default_Val(obj) );
850 else
852 wxStringClientData* _data =
853 (wxStringClientData*) _ctrl->GetClientObject(_ctrl->GetSelection());
854 pUpdate( obj, _ctrl, _data->GetData() );
856 evt.Skip();
860 //****************************************************
861 //****************************************************
862 //****************************************************
863 KalachnikofButton::KalachnikofButton(wxWindow* parent, wxWindowID id, const wxBitmap& bitmap, const size_t _clicks_interval, const wxPoint& pos, const wxSize& size , long style, const wxValidator& validator, const wxString& name )
864 :wxBitmapButton( parent, id, bitmap, pos,size,style,validator, name )
866 clicks_interval = _clicks_interval;
867 theTimer = new wxTimer( this, 1 );
868 b_clickedOn = false;
871 //------------------------------------------------------------------------
872 KalachnikofButton::~KalachnikofButton()
874 b_clickedOn = false;
875 delete theTimer;
878 //------------------------------------------------------------------------
879 void
880 KalachnikofButton::EvtTimerOut( wxTimerEvent& event )
882 if( b_clickedOn == true )
884 // AutoProcess the event to permit Connect() functions to work
885 wxCommandEvent _evt( wxEVT_COMMAND_BUTTON_CLICKED );
886 _evt.SetEventObject( this );
887 _evt.SetId( GetId() );
888 GetEventHandler()->ProcessEvent( _evt );
889 return;
892 theTimer->Stop();
895 //------------------------------------------------------------------------
896 void
897 KalachnikofButton::EvtMouseSomething( wxMouseEvent& event )
899 if( event.LeftDown() == true )
901 if( theTimer->IsRunning() == false )
903 b_clickedOn = true;
904 theTimer->Start( clicks_interval );
907 else if( event.Leaving() == true || event.LeftUp() == true )
909 b_clickedOn = false;
910 theTimer->Stop();
913 event.Skip();
916 //------------------------------------------------------------------------
917 BEGIN_EVENT_TABLE(KalachnikofButton, wxBitmapButton)
918 EVT_MOUSE_EVENTS( KalachnikofButton::EvtMouseSomething )
919 EVT_TIMER(1, KalachnikofButton::EvtTimerOut)
920 END_EVENT_TABLE()
923 //****************************************************
924 //****************************************************
925 //****************************************************
926 //*********** new event
927 DEFINE_EVENT_TYPE(wxEVT_OBFILECHOOSER_CHANGE)
930 //****************************************************
932 const int fileTextMinW = 150;
933 const int fileTextMaxH = 50;
934 const int filePickerW = 30;
935 const int filePickerH = 30;
937 //****************************************************
938 //****************************************************
939 // Event table
941 BEGIN_EVENT_TABLE(prObFileChooserCtrl, wxControl)
942 EVT_PAINT(prObFileChooserCtrl::EvtPaint)
943 EVT_SIZE(prObFileChooserCtrl::EvtSize)
944 EVT_SET_FOCUS(prObFileChooserCtrl::EvtGetFocus)
945 END_EVENT_TABLE()
947 //****************************************************
948 //****************************************************
949 //****************************************************
951 prObFileChooserCtrl::prObFileChooserCtrl(
952 wxWindow *_parent
953 , const int _id
954 , const wxString& _File_or_Directory
955 , const bool _b_file_must_exist
956 , const int _width
957 , const int _style
959 :wxControl( _parent, _id, wxDefaultPosition, wxDefaultSize,
960 _style | wxBORDER_SIMPLE | wxTE_PROCESS_TAB
963 b_file_must_exist = _b_file_must_exist;
964 File_or_Directory = _File_or_Directory;
965 b_init = false;
966 b_updating = false;
968 //******************************************
969 txtCtrl_file = new wxTextCtrl(this, wxID_ANY, wxString(),wxDefaultPosition, wxDefaultSize,
970 wxTE_PROCESS_ENTER | wxTE_PROCESS_TAB | wxTE_RIGHT );
971 txtCtrl_file->SetInsertionPointEnd();
972 txtCtrl_file->Connect( wxID_ANY, wxEVT_KEY_DOWN, wxKeyEventHandler(prObFileChooserCtrl::EvtCharPress), NULL, this );
974 if( _width == wxDefaultCoord )
975 minWidth = fileTextMinW + filePickerW;
976 else
977 minWidth = _width;
979 int txtW = minWidth - filePickerW;
981 txtCtrl_file->SetMinSize( wxSize( txtW, wxDefaultCoord) );
982 txtCtrl_file->SetSize( wxSize( txtW, wxDefaultCoord) );
983 txtCtrl_file->Move( 0, 0 );
986 //******************************************
987 int fp_style = wxFLP_OPEN | wxFLP_CHANGE_DIR;
988 if( _b_file_must_exist )
989 fp_style |= wxFLP_FILE_MUST_EXIST;
990 filePck_file = new wxFilePickerCtrl( this, wxID_ANY,
991 dataDirPath.GetFullPath(), wxT("Select custom selection screen file"), wxT("*.*"),
992 wxDefaultPosition, wxDefaultSize, fp_style );
993 filePck_file->SetMaxSize( wxSize(30, wxDefaultCoord ));
994 filePck_file->SetInitialSize(wxSize(filePickerW, filePickerH ));
995 filePck_file->Move( txtW, 0 );
997 filePck_file->Connect(wxEVT_COMMAND_FILEPICKER_CHANGED , wxFileDirPickerEventHandler(prObFileChooserCtrl::EvtImgPickerChg), NULL, this );
998 filePck_file->Connect(wxEVT_ENTER_WINDOW , wxMouseEventHandler(prObFileChooserCtrl::EvtImgPickerClick), NULL, this );
1003 //****************************************************
1005 prObFileChooserCtrl::~prObFileChooserCtrl()
1010 //****************************************************
1012 void prObFileChooserCtrl::EvtSize(wxSizeEvent& event)
1014 // Init();
1015 wxSize _s = event.GetSize();
1016 DoSetSize( wxDefaultCoord, wxDefaultCoord, _s.GetWidth(), _s.GetHeight() );
1018 event.Skip();
1022 //****************************************************
1024 void prObFileChooserCtrl::EvtGetFocus( wxFocusEvent& evt )
1026 txtCtrl_file->SetFocus();
1027 evt.Skip();
1031 //****************************************************
1033 void prObFileChooserCtrl::EvtCharPress( wxKeyEvent& event )
1035 int kc = event.GetKeyCode();
1036 if( kc == WXK_TAB )
1038 wxNavigationKeyEvent new_event;
1039 new_event.SetEventObject( GetParent() );
1040 new_event.SetDirection( !event.ShiftDown() );
1041 // CTRL-TAB changes the (parent) window, i.e. switch notebook page
1042 new_event.SetWindowChange( event.ControlDown() );
1043 new_event.SetCurrentFocus( this );
1044 GetParent()->GetEventHandler()->ProcessEvent( new_event );
1045 return;
1047 else if( kc == WXK_RETURN || kc == WXK_NUMPAD_ENTER )
1049 int err = Update(false);
1050 if( err != 0 )
1052 if( err == 1 )
1053 wxMessageBox( wxT("Not a valid OB file !"), wxT("WARNING"), wxOK | wxICON_EXCLAMATION, this );
1054 else if( err == 2 )
1055 wxMessageBox( wxT("File doesn't exist !"), wxT("WARNING"), wxOK | wxICON_EXCLAMATION, this );
1057 txtCtrl_file->SetBackgroundColour( wxColour( 255, 200,200));
1059 else
1060 txtCtrl_file->SetBackgroundColour( wxColour( 255, 255,255));
1061 return;
1064 event.Skip();
1068 //****************************************************
1070 void prObFileChooserCtrl::EvtImgPickerChg(wxFileDirPickerEvent& event )
1072 int err = Update(true);
1073 if( err != 0 )
1075 if( err == 1 )
1076 wxMessageBox( wxT("Not a valid OB file !"), wxT("WARNING"), wxOK | wxICON_EXCLAMATION, this );
1077 else if( err == 2 )
1078 wxMessageBox( wxT("File doesn't exist !"), wxT("WARNING"), wxOK | wxICON_EXCLAMATION, this );
1083 //****************************************************
1085 void prObFileChooserCtrl::EvtPaint( wxPaintEvent& event )
1087 // Init();
1088 event.Skip();
1092 //****************************************************
1094 void prObFileChooserCtrl::EvtImgPickerClick( wxMouseEvent& event )
1096 Init();
1097 event.Skip();
1100 //****************************************************
1101 // EVENTs END
1102 //****************************************************
1104 void prObFileChooserCtrl::DoSetSize(int x, int y, int width, int height)
1106 int txtW = width - filePickerW;
1107 if( txtW <= 0)
1108 txtW = 1;
1110 int _th = (height > fileTextMaxH ) ? fileTextMaxH : height;
1111 txtCtrl_file->SetSize( txtW, _th );
1112 if( _th < height )
1113 txtCtrl_file->Move( 0, (height - _th) / 2 );
1115 int fpY = (height - filePickerH) /2 ;
1116 if( fpY < 0 )
1117 fpY = 0;
1118 filePck_file->Move( txtW, fpY );
1119 wxControl::DoSetSize( x,y,width,height );
1121 // wxMessageBox( "W : " + IntToStr( width ) + "\nH" + IntToStr( height ) );
1125 //****************************************************
1127 wxSize prObFileChooserCtrl::DoGetBestSize() const
1129 return wxSize( fileTextMaxH, filePickerH );
1132 //****************************************************
1133 wxSize
1134 prObFileChooserCtrl::GetMinSize() const
1136 return wxSize( minWidth, filePickerH);
1141 //****************************************************
1143 prObFileChooserCtrl::Update(bool b_filePicker )
1145 if( b_updating == true )
1146 return true;
1147 b_updating = true;
1149 // Get the new file
1150 wxString fn;
1151 if( b_filePicker )
1153 fn = Convert_To_Ob_Path( filePck_file->GetPath() );
1155 // Not a valid obpath
1156 if( fn == wxString() )
1158 b_updating = false;
1159 return 1;
1162 txtCtrl_file->SetValue( fn );
1164 else
1166 fn = txtCtrl_file->GetValue();
1168 wxFileName wfn = GetObFile( fn );
1169 wxString f_p = wfn.GetFullPath();
1171 if( b_file_must_exist && wfn.FileExists() == false )
1173 b_updating = false;
1174 return 2;
1177 filePck_file->SetPath( f_p );
1180 File_or_Directory = filePck_file->GetPath();
1182 // AutoProcess the event to permit Connect() functions to work
1183 wxCommandEvent _evt( wxEVT_OBFILECHOOSER_CHANGE );
1184 _evt.SetEventObject( this );
1185 _evt.SetId( GetId() );
1186 GetEventHandler()->ProcessEvent( _evt );
1188 b_updating = false;
1189 return 0;
1193 //****************************************************
1194 bool
1195 prObFileChooserCtrl::SetFullPath( const wxString& _file )
1197 return SetObPath( Convert_To_Ob_Path( _file ) );
1201 //****************************************************
1203 bool prObFileChooserCtrl::SetObPath( const wxString& _file )
1205 wxString prev_fn = txtCtrl_file->GetValue();
1206 txtCtrl_file->SetValue( _file );
1207 if( Update(false) != 0 )
1209 txtCtrl_file->SetValue( prev_fn );
1210 return false;
1212 return true;
1215 //****************************************************
1217 wxFileName prObFileChooserCtrl::GetFileName()
1219 return GetObFile( txtCtrl_file->GetValue() );
1223 //****************************************************
1225 wxString prObFileChooserCtrl::GetFullPath()
1227 return Convert_To_Ob_Path( txtCtrl_file->GetValue() );
1231 //****************************************************
1233 wxString prObFileChooserCtrl::GetObPath()
1235 return txtCtrl_file->GetValue();
1238 //******************************************
1240 void prObFileChooserCtrl::Init()
1243 if( b_init )
1244 return;
1245 b_init = true;
1247 if( File_or_Directory != wxString() )
1248 if( SetFullPath( File_or_Directory ) )
1249 return;
1251 if( dataDirPath.DirExists() )
1253 wxString dummy_file = wxDir::FindFirst( dataDirPath.GetFullPath(), wxT("*"), wxDIR_FILES );
1254 if( wxFileName( dummy_file ).FileExists() )
1256 filePck_file->SetPath( dummy_file );
1257 // wxMessageBox( dummy_file , "WARNING", wxOK | wxICON_EXCLAMATION, this );
1260 else
1261 wxMessageBox( wxT("DataDir path invalid : <") + dataDirPath.GetFullPath() + wxT(">"), wxT("WARNING"), wxOK | wxICON_EXCLAMATION, this );
1267 //****************************************************
1268 //****************************************************
1269 //****************************************************
1270 //****************************************************
1271 //****************************************************
1272 //****************************************************
1273 //****************************************************
1274 //****************************************************
1275 //****************************************************
1276 // THE SCROLL PANNEL
1277 //****************************************************
1279 AScrollPanel::AScrollPanel( wxWindow *_parent )
1280 : wxScrolledWindow( _parent, wxID_ANY, wxDefaultPosition,wxDefaultSize,
1281 wxTAB_TRAVERSAL | wxVSCROLL | wxHSCROLL |wxFULL_REPAINT_ON_RESIZE )
1283 b_fix_V = false;
1284 b_fix_H = true;
1285 SetScrollRate( 15, 15 );
1286 EnableScrolling(!b_fix_H, !b_fix_V);
1287 SetAutoLayout( true );
1288 Fit();
1292 //************************************************************************************
1294 AScrollPanel::~AScrollPanel()
1298 //************************************************************************************
1300 void AScrollPanel::EvtSize( wxSizeEvent& event )
1302 // wxSize size = GetBestVirtualSize();
1303 // // wxSize s = event.GetSize();
1305 // SetVirtualSize( size );
1307 AdjustScrollbars();
1309 Refresh();
1310 Layout();
1312 event.Skip();
1316 //************************************************************************************
1318 bool AScrollPanel::Layout()
1320 // AdjustScrollbars();
1321 return wxScrolledWindow::Layout();
1326 //************************************************************************************
1328 wxSize AScrollPanel::GetMinSize()const
1330 wxSizer *m_sizer = GetSizer();
1331 if( m_sizer == NULL )
1332 return wxScrolledWindow::GetMinSize();
1334 wxSize s = m_sizer->GetMinSize();
1335 if( !b_fix_H )
1336 s.x = -1;
1337 if( !b_fix_V )
1338 s.y = -1;
1340 #ifndef __WXGTK__
1341 return s;
1342 #else
1344 // wxMessageBox( "Size : " + IntToStr( s.x ) + "," + IntToStr(s.y ) );
1345 if( b_fix_V && HasScrollbar( wxHORIZONTAL ))
1346 s.y = s.y + 20;
1348 if( b_fix_H && HasScrollbar( wxVERTICAL ))
1349 s.x = s.x + 20;
1351 return s;
1352 #endif
1356 //************************************************************************************
1358 wxSize AScrollPanel::DoGetBestSize() const
1360 return GetVirtualSize();
1364 //************************************************************************************
1366 void AScrollPanel::DoSetSize(int x, int y, int width, int height, int sizeFlags)
1368 wxScrolledWindow::DoSetSize( x,y,width,height,sizeFlags );
1372 //************************************************************************************
1374 void AScrollPanel::DoGetClientSize( int* width, int* height) const
1376 wxScrolledWindow::DoGetClientSize( width, height );
1377 return;
1381 //************************************************************************************
1383 void AScrollPanel::Set_FixedDirections( bool b_H, bool b_V )
1385 b_fix_V = b_V;
1386 b_fix_H = b_H;
1387 EnableScrolling(!b_fix_H, !b_fix_V);
1388 Refresh();
1392 //************************************************************************************
1394 void AScrollPanel::OnPaint( wxPaintEvent &event )
1396 // wxPaintDC dc( this );
1398 wxSize s = GetClientSize();
1399 dc.DrawLine( 0, 0, s.x, s.y );
1401 event.Skip();
1404 //************************************************************************************
1405 //************************************************************************************
1406 //************************************************************************************
1407 //************************************************************************************
1408 // Event table
1409 BEGIN_EVENT_TABLE(AScrollPanel, wxScrolledWindow)
1410 EVT_SIZE(AScrollPanel::EvtSize)
1411 EVT_PAINT(AScrollPanel::OnPaint)
1412 END_EVENT_TABLE()