.\" -*- mode: troff; coding: utf-8 -*- .\" Automatically generated by Pod::Man 5.01 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" \*(C` and \*(C' are quotes in nroff, nothing in troff, for use with C<>. .ie n \{\ . ds C` "" . ds C' "" 'br\} .el\{\ . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "Wx::NewClass 3pm" .TH Wx::NewClass 3pm 2024-04-11 "perl v5.38.2" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH NAME NewClass \- adding a new class to wxPerl .SH CHECKLIST .IX Header "CHECKLIST" .IP \(bu 4 Are there constants or events that need to be wrapped? .Sp see "CONSTANTS" and "EVENTS". .IP \(bu 4 Is the class is derived from wxObject, from wxEvtHandler or from another class? .Sp see "CHOOSING A TYPEMAP". .IP \(bu 4 Are class instances destroyed by wxWidgets or should they be garbage collected like normal Perl objects? .Sp see "DESTRUCTORS AND THREADS". .IP \(bu 4 Does the class have overloaded methods? .Sp see "OVERLOADING". .IP \(bu 4 Does the class have virtual methods that should be overridable from Perl? .Sp see "VIRTUAL METHODS". .SH SKELETON .IX Header "SKELETON" Add a new file \fIXS/NewClass.xsp\fR and update the \fIMANIFEST\fR. Choose a relevant \fI.xs\fR file in the top level directory (eg. \fIControls.xs\fR) and add this line: .PP .Vb 1 \& INCLUDE_COMMAND: $^X \-MExtUtils::XSpp::Cmd \-e xspp \-\- \-t typemap.xsp XS/NewClass.xsp .Ve .PP A skeleton for \fINewClass.xsp\fR: .PP .Vb 1 \& %module{Wx}; \& \& #include // use the relevant wxWidgets header(s) \& \& %name{Wx::NewClass} class wxNewClass : public wxSomeBaseClass \& { \& # constructors see the CONSTRUCTORS section \& wxNewClass( wxWindow* some_window, const wxString& str ); \& \& # destructors \& ~wxNewClass(); \& \& # methods \& wxString GetString() const; \& void SetString( const wxString& str ); \& }; .Ve .PP Add the typemap definition to \fItypemap.tmpl\fR. See "CHOOSING A TYPEMAP". .PP If adding a class related to one of the wxPerl submodules (\f(CW\*(C`Wx::RichText\*(C'\fR, \f(CW\*(C`Wx::Html\*(C'\fR, ...) add the \fI.xsp\fR file to the relevant subdirectory and modify the \fI.xs\fR and \fItypemap\fR files in that subdirectory. .SH "CHOOSING A TYPEMAP" .IX Header "CHOOSING A TYPEMAP" There are five typemaps that should work for most wxWidgets objects: .IP \(bu 4 \&\f(CW\*(C`O_NON_WXOBJECT\*(C'\fR .Sp for all classes that do not derive from \f(CW\*(C`wxObject\*(C'\fR AND do not need to be garbage collected. .IP \(bu 4 \&\f(CW\*(C`O_NON_WXOBJECT_THR\*(C'\fR .Sp for all classes that do not derive from \f(CW\*(C`wxObject\*(C'\fR AND need to be garbage collected (see "DESTRUCTORS AND THREADS"). .IP \(bu 4 \&\f(CW\*(C`O_WXOBJECT\*(C'\fR .Sp for all classes that derive from \f(CW\*(C`wxObject\*(C'\fR AND do not need to be garbage collected. .IP \(bu 4 \&\f(CW\*(C`O_WXOBJECT_THR\*(C'\fR .Sp for all classes derived from \f(CW\*(C`wxObject\*(C'\fR AND need to be garbage collected (see "DESTRUCTORS AND THREADS"). .IP \(bu 4 \&\f(CW\*(C`O_WXEVTHANDLER\*(C'\fR .Sp for all classes that derive from \f(CW\*(C`wxEvtHandler\*(C'\fR. See also "CONSTRUCTORS". .SH CONSTRUCTORS .IX Header "CONSTRUCTORS" For \f(CW\*(C`O_WXEVTHANDLER\*(C'\fR typemaps, there is some additional code that needs to be added to the constructor: .PP .Vb 4 \& wxNewClass( wxWindow* some_window, const wxString& str ) \& %code{% RETVAL = new wxNewClass( some_window, str ); \& wxPli_create_evthandler( aTHX_ RETVAL, CLASS ); \& %}; .Ve .SH "DESTRUCTORS AND THREADS" .IX Header "DESTRUCTORS AND THREADS" For many classes not derived from \f(CW\*(C`wxEvtHandler\*(C'\fR you need to add a destructor to free the C++ object when the Perl object is garbage collected. At the XS++ level this means adding .PP .Vb 1 \& ~wxNewClass(); .Ve .PP to the class definition, but there is a catch: the Perl threading model. .PP Without going into details, this is needed for Perl threads compatibility: .IP \(bu 4 Use the correct typemap .Sp choose either \f(CW\*(C`O_NON_WXOBJECT_THR\*(C'\fR or \f(CW\*(C`O_WXOBJECT_THR\*(C'\fR. .IP \(bu 4 Implement a \f(CW\*(C`CLONE\*(C'\fR method .Sp add this code inside the class declaration: .Sp .Vb 6 \& %{ \& static void \& wxNewClass::CLONE() \& CODE: \& wxPli_thread_sv_clone( aTHX_ CLASS, (wxPliCloneSV)wxPli_detach_object ); \& %} .Ve .IP \(bu 4 Fix the destructor. .Sp modify the destructor like this: .Sp .Vb 4 \& ~wxNewClass() \& %code%{ wxPli_thread_sv_unregister( aTHX_ "Wx::NewClass", THIS, ST(0) ); \& delete THIS; \& %}; .Ve .SH "VIRTUAL METHODS" .IX Header "VIRTUAL METHODS" The wrapping of virtual functions whose arguments are simple C++ types (integrals, bool, floating point) and common wxWidgets types (wxString) should be automatic: at the top of the file, load the plugin that handles virtual methods .PP .Vb 1 \& %loadplugin{build::Wx::XSP::Virtual}; .Ve .PP and decorate virtual/pure virtual methods using the \f(CW%Virtual\fR directive .PP .Vb 2 \& // pure virtual \& virtual wxString GetTitle() const = 0 %Virtual{pure}; \& \& // virtual, not pure \& virtual int GetBestFittingWidth(unsigned int idx) const %Virtual; .Ve .PP If the class contains pure virtual methods, it will be marked as abstract, and it will have no constructors. .PP For abstract classes, XS++ will create an additional Perl-level class, called \f(CW\*(C`Wx::Pl\*(C'\fR; in order to override the virtual methods, you must derive from this class, and not from \&\f(CW\*(C`Wx::\*(C'\fR. .PP TODO allow changing the default behaviour for abstract/concrete classes .PP TODO allow overriding the class name .PP TODO allow specifying custom code .PP TODO handle multiple return values .PP TODO customized type mapping