---
name: "Wx::NewClass"
section: "3pm"
platform: "linux"
package: "libwx-perl"
version: "1:0.9932-9+b2"
release: "Debian 13 (Trixie)"
platforms: ["linux"]
url: "https://new.carta.tech/Wx::NewClass"
---

# Wx::NewClass(3pm)

adding a new class to wxPerl

## NAME

NewClass - adding a new class to wxPerl

## CHECKLIST

- •

  Are there constants or events that need to be wrapped?

  see "CONSTANTS" and "EVENTS".

- •

  Is the class is derived from wxObject, from wxEvtHandler or from another class?

  see "CHOOSING A TYPEMAP".

- •

  Are class instances destroyed by wxWidgets or should they be garbage collected like normal Perl objects?

  see "DESTRUCTORS AND THREADS".

- •

  Does the class have overloaded methods?

  see "OVERLOADING".

- •

  Does the class have virtual methods that should be overridable from Perl?

  see "VIRTUAL METHODS".

## SKELETON

Add a new file *XS/NewClass.xsp* and update the *MANIFEST*.  Choose a relevant *.xs* file in the top level directory (eg. *Controls.xs*) and add this line:

```
    INCLUDE_COMMAND: $^X -MExtUtils::XSpp::Cmd -e xspp -- -t typemap.xsp XS/NewClass.xsp
```

A skeleton for *NewClass.xsp*:

```
    %module{Wx};
    #include <wx/newclass.h> // 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 );
    };
```

Add the typemap definition to *typemap.tmpl*.  See "CHOOSING A TYPEMAP".

If adding a class related to one of the wxPerl submodules (`"Wx::RichText"`, `"Wx::Html"`, ...) add the *.xsp* file to the relevant subdirectory and modify the *.xs* and *typemap* files in that subdirectory.

## CHOOSING A TYPEMAP

There are five typemaps that should work for most wxWidgets objects:

- •

  `"O_NON_WXOBJECT"`

  for all classes that do not derive from `"wxObject"` AND do not need to be garbage collected.

- •

  `"O_NON_WXOBJECT_THR"`

  for all classes that do not derive from `"wxObject"` AND need to be garbage collected (see "DESTRUCTORS AND THREADS").

- •

  `"O_WXOBJECT"`

  for all classes that derive from `"wxObject"` AND do not need to be garbage collected.

- •

  `"O_WXOBJECT_THR"`

  for all classes derived from `"wxObject"` AND need to be garbage collected (see "DESTRUCTORS AND THREADS").

- •

  `"O_WXEVTHANDLER"`

  for all classes that derive from `"wxEvtHandler"`.  See also "CONSTRUCTORS".

## CONSTRUCTORS

For `"O_WXEVTHANDLER"` typemaps, there is some additional code that needs to be added to the constructor:

```
    wxNewClass( wxWindow* some_window, const wxString& str )
        %code{% RETVAL = new wxNewClass( some_window, str );
                wxPli_create_evthandler( aTHX_ RETVAL, CLASS );
                %};
```

## DESTRUCTORS AND THREADS

For many classes not derived from `"wxEvtHandler"` 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

```
    ~wxNewClass();
```

to the class definition, but there is a catch: the Perl threading model.

Without going into details, this is needed for Perl threads compatibility:

- •

  Use the correct typemap

  choose either `"O_NON_WXOBJECT_THR"` or `"O_WXOBJECT_THR"`.

- •

  Implement a `"CLONE"` method

  add this code inside the class declaration:

  ```
      %{
      static void
      wxNewClass::CLONE()
        CODE:
          wxPli_thread_sv_clone( aTHX_ CLASS, (wxPliCloneSV)wxPli_detach_object );
      %}
  ```

- •

  Fix the destructor.

  modify the destructor like this:

  ```
      ~wxNewClass()
          %code%{  wxPli_thread_sv_unregister( aTHX_ "Wx::NewClass", THIS, ST(0) );
                   delete THIS;
                   %};
  ```

## 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

```
    %loadplugin{build::Wx::XSP::Virtual};
```

and decorate virtual/pure virtual methods using the `%Virtual` directive

```
    // pure virtual
    virtual wxString GetTitle() const = 0 %Virtual{pure};
    // virtual, not pure
    virtual int GetBestFittingWidth(unsigned int idx) const %Virtual;
```

If the class contains pure virtual methods, it will be marked as abstract, and it will have no constructors.

For abstract classes, XS++ will create an additional Perl-level class, called `"Wx::Pl<classname>"`; in order to override the virtual methods, you must derive from this class, and not from `"Wx::<classname>"`.

TODO allow changing the default behaviour for abstract/concrete classes

TODO allow overriding the class name

TODO allow specifying custom code

TODO handle multiple return values

TODO customized type mapping
