# Copyright (c) 2023 M.J.N. Corino, The Netherlands # # This software is released under the MIT license. ### # wxRuby3 wxWidgets interface director ### require_relative './window' module WXRuby3 class Director class HtmlListBox < Window include Typemap::ClientData def setup spec.items << 'wxSimpleHtmlListBox' << 'wxItemContainer' super spec.override_inheritance_chain('wxHtmlListBox', %w[wxVListBox wxVScrolledWindow wxPanel wxWindow wxEvtHandler wxObject]) spec.make_abstract 'wxHtmlListBox' # provide base implementation for OnGetItem spec.add_header_code <<~__HEREDOC // Custom subclass implementation. class wxRubyHtmlListBox : public wxHtmlListBox { public: wxRubyHtmlListBox() : wxHtmlListBox () {} wxRubyHtmlListBox(wxWindow *parent, wxWindowID id=wxID_ANY, const wxPoint &pos=wxDefaultPosition, const wxSize &size=wxDefaultSize, long style=0, const wxString &name=wxHtmlListBoxNameStr) : wxHtmlListBox(parent, id, pos, size, style, name) {} protected: virtual wxString OnGetItem (size_t n) const { rb_raise(rb_eNoMethodError, "Not implemented"); } }; __HEREDOC # make Ruby director and wrappers use custom implementation spec.use_class_implementation('wxHtmlListBox', 'wxRubyHtmlListBox') # we do not want wxFileSystem exposed (not worth the trouble) spec.ignore 'wxHtmlListBox::GetFileSystem' # just add an extension to change the path for resolving relative paths in HTML spec.add_extend_code 'wxHtmlListBox', <<~__HEREDOC void change_filesystem_path_to(const wxString& location, bool is_dir=false) { $self->GetFileSystem().ChangePathTo(location, is_dir); } __HEREDOC # make sure protected methods are included spec.regard 'wxHtmlListBox::OnGetItem', 'wxHtmlListBox::OnGetItemMarkup', 'wxHtmlListBox::GetSelectedTextColour', 'wxHtmlListBox::GetSelectedTextBgColour', 'wxHtmlListBox::OnLinkClicked' # add missing protected overloads spec.extend_interface 'wxHtmlListBox', 'virtual void OnDrawItem(wxDC &dc, const wxRect &rect, size_t n) const', 'virtual wxCoord OnMeasureItem(size_t n) const', 'virtual void OnDrawBackground(wxDC &dc, const wxRect &rect, size_t n) const', 'virtual void OnDrawSeparator(wxDC& dc, wxRect& rect, size_t n) const', visibility: 'protected' # override inheritance chain spec.override_inheritance_chain('wxSimpleHtmlListBox', %w[wxHtmlListBox wxVListBox wxVScrolledWindow wxPanel wxWindow wxEvtHandler wxObject]) spec.fold_bases('wxSimpleHtmlListBox' => %w[wxItemContainer]) # override SWIG's confusion spec.make_concrete 'wxSimpleHtmlListBox' # not useful overload spec.ignore 'wxSimpleHtmlListBox::wxSimpleHtmlListBox(wxWindow *, wxWindowID, const wxPoint &, const wxSize &, int, const wxString[], long, const wxValidator &, const wxString &)' # add missing overloads spec.extend_interface 'wxSimpleHtmlListBox', 'virtual wxString GetString(unsigned int n) const', 'virtual void SetString(unsigned int n, const wxString &string)' spec.ignore([ 'wxItemContainer::Append(const wxString &, void *)', 'wxItemContainer::Append(const std::vector< wxString > &)', 'wxItemContainer::Append(const wxArrayString &, void **)', 'wxItemContainer::Append(unsigned int, const wxString *)', 'wxItemContainer::Append(unsigned int, const wxString *, void **)', 'wxItemContainer::Append(unsigned int, const wxString *, wxClientData **)', 'wxItemContainer::Insert(const wxString &, unsigned int, void *)', 'wxItemContainer::Insert(const std::vector< wxString > &)', 'wxItemContainer::Insert(const wxArrayString &, unsigned int, void **)', 'wxItemContainer::Insert(unsigned int, const wxString *, unsigned int)', 'wxItemContainer::Insert(unsigned int, const wxString *, unsigned int, void **)', 'wxItemContainer::Insert(unsigned int, const wxString *, unsigned int, wxClientData **)', 'wxItemContainer::Set(const std::vector< wxString > &)', 'wxItemContainer::Set(const wxArrayString &, void **)', 'wxItemContainer::Set(unsigned int, const wxString *)', 'wxItemContainer::Set(unsigned int, const wxString *, void **)', 'wxItemContainer::Set(unsigned int, const wxString *, wxClientData **)', 'wxItemContainer::GetClientData', 'wxItemContainer::SetClientData', 'wxItemContainer::HasClientUntypedData', 'wxItemContainer::Clear']) spec.ignore([ 'wxItemContainer::Append(const wxArrayString &, wxClientData **)', 'wxItemContainer::Insert(const wxArrayString &, unsigned int, wxClientData **)', 'wxItemContainer::Set(const wxArrayString &, wxClientData **)'], ignore_doc: false) # for doc only spec.map 'void** clientData' => 'Array', swig: false do map_in code: '' end # Replace the old Wx definitions of these methods adding # proper checks on the data arrays. # Also add an item enumerator. spec.add_extend_code 'wxSimpleHtmlListBox', <<~__HEREDOC VALUE DetachClientObject(unsigned int n) { VALUE rc = Qnil; wxClientData *wxcd = $self->DetachClientObject(n); wxRubyClientData *rbcd = wxcd ? dynamic_cast (wxcd) : nullptr; if (rbcd) { rc = rbcd->GetData(); delete rbcd; } return rc; } int Append(const wxArrayString &items, VALUE rb_clientData) { if (TYPE(rb_clientData) != T_ARRAY || static_cast (RARRAY_LEN(rb_clientData)) != items.GetCount()) { rb_raise(rb_eArgError, TYPE(rb_clientData) == T_ARRAY ? "expected Array for client_data" : "client_data Array needs to be equal in size to items Array"); } std::unique_ptr cd_arr = std::make_unique (RARRAY_LEN(rb_clientData)); for (int i=0; iAppend(items, cd_arr.get()); } int Insert(const wxArrayString &items, unsigned int pos, VALUE rb_clientData) { if (TYPE(rb_clientData) != T_ARRAY || static_cast (RARRAY_LEN(rb_clientData)) != items.GetCount()) { rb_raise(rb_eArgError, TYPE(rb_clientData) == T_ARRAY ? "expected Array for client_data" : "client_data Array needs to be equal in size to items Array"); } std::unique_ptr cd_arr = std::make_unique (RARRAY_LEN(rb_clientData)); for (int i=0; iInsert(items, pos, cd_arr.get()); } void Set(const wxArrayString &items, VALUE rb_clientData) { if (TYPE(rb_clientData) != T_ARRAY || static_cast (RARRAY_LEN(rb_clientData)) != items.GetCount()) { rb_raise(rb_eArgError, TYPE(rb_clientData) == T_ARRAY ? "expected Array for client_data" : "client_data Array needs to be equal in size to items Array"); } std::unique_ptr cd_arr = std::make_unique (RARRAY_LEN(rb_clientData)); for (int i=0; iSet(items, cd_arr.get()); } VALUE each_string() { VALUE rc = Qnil; for (unsigned int i=0; i<$self->GetCount() ;++i) { VALUE rb_s = WXSTR_TO_RSTR($self->GetString(i)); rc = rb_yield(rb_s); } return rc; } __HEREDOC end end # class HtmlListBox end # class Director end # module WXRuby3