### # wxRuby3 wxWidgets interface director # Copyright (c) M.J.N. Corino, The Netherlands ### module WXRuby3 class Director class HelpProvider < Director def setup super spec.gc_as_object 'wxHelpProvider' # We need to create a C++ subclass b/c the base class is pure # virtual. To be used, a class must be inherited in Ruby which # implements the relevant virtual methods eg AddHelp, ShowHelp, # GetHelp. wxWidgets provides some pre-made classes (eg # wxSimpleHelpProvider) but these are so trivial in implementation that # it's not worth porting them - easier to write as pure-ruby classes. spec.rename_for_ruby('wxHelpProvider' => 'wxRubyHelpProvider') spec.disown 'wxRubyHelpProvider *' spec.include 'wx/cshelp.h' spec.add_header_code <<~__HEREDOC class wxRubyHelpProvider : public wxHelpProvider { public: // This is pure virtual in base Wx class, so won't compile unless an // implementation is provided wxString GetHelp(const wxWindowBase* window) { static WxRuby_ID get_help_id("get_help"); VALUE rb_win = wxRuby_WrapWxObjectInRuby( (wxWindow*)window ); VALUE self = SWIG_RubyInstanceFor(this); VALUE rb_help_str = rb_funcall(self, get_help_id(), 1, rb_win); wxString result; if ( TYPE(rb_help_str) == T_STRING ) result = wxString( StringValuePtr(rb_help_str), wxConvUTF8); else { rb_warn("HelpProvider#get_help must return a String"); } return result; } // RemoveHelp is called by Wx after the window deletion event has been // handled. A standard director here re-wraps the already destroyed // object, which will cause rapid segfaults when it is later marked. void RemoveHelp(wxWindowBase* window) { static WxRuby_ID remove_help_id("remove_help"); VALUE rb_win = SWIG_RubyInstanceFor( (void *)window ); if ( ! NIL_P(rb_win) ) { VALUE self = SWIG_RubyInstanceFor(this); rb_funcall(self, remove_help_id(), 1, rb_win); } } }; __HEREDOC spec.add_swig_code <<~__HEREDOC typedef wxWindow wxWindowBase; %ignore wxHelpProvider::GetHelp; // Must be supplied in Ruby // Need to avoid standard director as it will call with destroyed // objects %feature("nodirector") wxHelpProvider::RemoveHelp; __HEREDOC spec.map 'wxWindowBase' => 'Wx::Window', swig: false do map_in map_out end # this is just the SWIG interface description so we do not need # to mention the inheritance relation here as it is not important # for the Ruby implementation spec.add_interface_code <<~__HEREDOC class wxRubyHelpProvider { public: virtual ~wxRubyHelpProvider(); static wxRubyHelpProvider* Set(wxRubyHelpProvider* helpProvider); static wxRubyHelpProvider* Get(); virtual void AddHelp(wxWindowBase* window, const wxString& text); virtual void AddHelp(wxWindowID id, const wxString& text); virtual wxString GetHelp(const wxWindowBase* window); virtual void RemoveHelp(wxWindowBase* window); virtual bool ShowHelp(wxWindowBase* window); virtual bool ShowHelpAtPoint(wxWindowBase* window, const wxPoint point, wxHelpEvent::Origin origin); }; __HEREDOC end end # class HelpProvider end # class Director end # module WXRuby3