Exemplo n.º 1
0
def parseAndTweakModule():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING, False)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxTextEntry')
    assert isinstance(c, etgtools.ClassDef)
    c.abstract = True
    tools.removeVirtuals(c)

    c.find('GetSelection.from').out = True
    c.find('GetSelection.to').out = True
    c.find('GetRange.from').name = 'from_'
    c.find('GetRange.to').name = 'to_'
    c.find('Remove.from').name = 'from_'
    c.find('Remove.to').name = 'to_'
    c.find('Replace.from').name = 'from_'
    c.find('Replace.to').name = 'to_'
    c.find('SetSelection.from').name = 'from_'
    c.find('SetSelection.to').name = 'to_'
    c.find('AutoComplete').findOverload('wxTextCompleter').find(
        'completer').transfer = True

    return module
Exemplo n.º 2
0
def parseAndTweakModule():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING, False)
    etgtools.parseDoxyXML(module, ITEMS)
    
    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.
    
    c = module.find('wxTextEntry')
    assert isinstance(c, etgtools.ClassDef)
    c.abstract = True
    tools.removeVirtuals(c)

    c.find('GetSelection.from').out = True
    c.find('GetSelection.to').out = True
    c.find('GetRange.from').name = 'from_'
    c.find('GetRange.to').name = 'to_'
    c.find('Remove.from').name = 'from_'
    c.find('Remove.to').name = 'to_'
    c.find('Replace.from').name = 'from_'
    c.find('Replace.to').name = 'to_'
    c.find('SetSelection.from').name = 'from_'
    c.find('SetSelection.to').name = 'to_'
    c.find('AutoComplete').findOverload('wxTextCompleter').find('completer').transfer = True

    return module
Exemplo n.º 3
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)
    
    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.
    
    c = module.find('wxImageList')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    c.addPrivateAssignOp()
    tools.removeVirtuals(c)

    c.find('GetSize').type = 'void'
    c.find('GetSize.width').out = True
    c.find('GetSize.height').out = True
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 4
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxImageList')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    c.addPrivateAssignOp()
    tools.removeVirtuals(c)

    c.find('GetSize').type = 'void'
    c.find('GetSize.width').out = True
    c.find('GetSize.height').out = True

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 5
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.


    c = module.find('wxRegion')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)
    c.mustHaveApp()

    # Replace one of the constructors with one having a more python-friendly API
    c.find('wxRegion').findOverload('points').ignore()
    c.addCppCode(tools.ObjArrayHelperTemplate('wxPoint', 'sipType_wxPoint',
                    "Expected a sequence of length-2 sequences or wx.Point objects."))
    c.addCppCtor_sip('(PyObject* points, wxPolygonFillMode fillStyle = wxODDEVEN_RULE)',
        doc="""\
        Constructs a region corresponding to the polygon made from the points
        in the provided sequence.""",
        body="""\
        size_t count;
        wxPoint* array = wxPoint_array_helper(points, &count);
        if ( array != NULL ) {
            sipCpp = new wxRegion(count, array, fillStyle);
            delete [] array;
        }
        if (PyErr_Occurred()) sipIsErr = 1;
        """)


    c.find('GetBox').findOverload('wxCoord').ignore()



    # Iterator stuff
    c.addPyMethod('__iter__', '(self)', 'return PyRegionIterator(self)',
                  """\
                  Returns a rectangle interator conforming to the Python iterator
                  protocol.""")
    c.addPyCode("""\
        class PyRegionIterator(object):
            "A Python iterator for wx.Region objects"
            def __init__(self, region):
                self._region = region
                self._iterator = wx.RegionIterator(region)
            def next(self):
                if not self._iterator:
                    raise StopIteration
                rect = self._iterator.GetRect()
                if self._iterator.HaveRects():
                    self._iterator.Next()
                return rect
            __next__ = next  # for Python 3
        """)



    c = module.find('wxRegionIterator')
    c.mustHaveApp()
    c.find('operator++').ignore()

    # SIP maps operator bool() to __int__, but Classic used __nonzero__. Does
    # it make any difference either way?
    c.find('operator bool').ignore()
    c.addCppMethod('int', '__nonzero__', '()', 'return (int)self->operator bool();',
                   'Returns true while there are still rectangles available in the iteration.')

    c.addCppMethod('void', 'Next', '()', 'self->operator++();',
                   'Move the iterator to the next rectangle in the region.')


    # This is defined in the docs, but not in any of the real headers!
    module.find('wxNullRegion').ignore()

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 6
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    # These enums are declared in files that we will not be using because
    # wxPython does not need the classes that are in those files. So just
    # inject the enums here instead.
    from etgtools import EnumDef, EnumValueDef
    e = EnumDef(name='wxStreamError')
    e.items.extend([ EnumValueDef(name='wxSTREAM_NO_ERROR'),
                     EnumValueDef(name='wxSTREAM_EOF'),
                     EnumValueDef(name='wxSTREAM_WRITE_ERROR'),
                     EnumValueDef(name='wxSTREAM_READ_ERROR'),
                     ])
    module.insertItem(0, e)

    e = EnumDef(name='wxSeekMode')
    e.items.extend([ EnumValueDef(name='wxFromStart'),
                     EnumValueDef(name='wxFromCurrent'),
                     EnumValueDef(name='wxFromEnd'),
                     ])
    module.insertItem(1, e)


    #-----------------------------------------------------------------
    c = module.find('wxStreamBase')
    assert isinstance(c, etgtools.ClassDef)
    c.abstract = True
    tools.removeVirtuals(c)
    c.find('operator!').ignore()


    #-----------------------------------------------------------------
    c = module.find('wxInputStream')
    c.abstract = True
    tools.removeVirtuals(c)

    # Include a C++ class that can wrap a Python file-like object so it can
    # be used as a wxInputStream
    c.includeCppCode('src/stream_input.cpp')

    # Use that class for the convert code
    c.convertFromPyObject = """\
        // is it just a typecheck?
        if (!sipIsErr) {
            if (wxPyInputStream::Check(sipPy))
                return 1;
            return 0;
        }
        // otherwise do the conversion
        *sipCppPtr = new wxPyInputStream(sipPy);
        return sipGetState(sipTransferObj);
        """

    # Add Python file-like methods so a wx.InputStream can be used as if it
    # was any other Python file object.
    c.addCppMethod('void', 'seek', '(wxFileOffset offset, int whence=0)', """\
        self->SeekI(offset, (wxSeekMode)whence);
        """)
    c.addCppMethod('wxFileOffset', 'tell', '()', """\
        return self->TellI();
        """);
    c.addCppMethod('void', 'close', '()', """\
        // ignored for now
        """)
    c.addCppMethod('void', 'flush', '()', """\
        // ignored for now
        """)
    c.addCppMethod('bool', 'eof', '()', """\
        return self->Eof();
        """)

    c.addCppCode("""\
        // helper used by the read and readline methods to make a PyObject
        static PyObject* _makeReadBufObj(wxInputStream* self, wxMemoryBuffer& buf) {
            PyObject* obj = NULL;

            wxPyThreadBlocker blocker;
            wxStreamError err = self->GetLastError();  // error check
            if (err != wxSTREAM_NO_ERROR && err != wxSTREAM_EOF) {
                PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
            }
            else {
                // Return the data as a string object.  TODO: Py3
                obj = PyBytes_FromStringAndSize(buf, buf.GetDataLen());
            }
            return obj;
        }
        """)


    c.addCppMethod('PyObject*', 'read', '()', """\
        wxMemoryBuffer buf;
        const ulong BUFSIZE = 1024;

        // read while bytes are available on the stream
        while ( self->CanRead() ) {
            self->Read(buf.GetAppendBuf(BUFSIZE), BUFSIZE);
            buf.UngetAppendBuf(self->LastRead());
        }
        return _makeReadBufObj(self, buf);
        """)

    c.addCppMethod('PyObject*', 'read', '(ulong size)', """\
        wxMemoryBuffer buf;

        // Read only size number of characters
        self->Read(buf.GetWriteBuf(size), size);
        buf.UngetWriteBuf(self->LastRead());
        return _makeReadBufObj(self, buf);
        """)

    c.addCppMethod('PyObject*', 'readline', '()', """\
        wxMemoryBuffer buf;
        char ch = 0;

        // read until \\n
        while ((ch != '\\n') && (self->CanRead())) {
            ch = self->GetC();
            buf.AppendByte(ch);
        }
        return _makeReadBufObj(self, buf);
        """)

    c.addCppMethod('PyObject*', 'readline', '(ulong size)', """\
        wxMemoryBuffer buf;
        int i;
        char ch;

        // read until \\n or byte limit reached
        for (i=ch=0; (ch != '\\n') && (self->CanRead()) && (i < size); i++) {
            ch = self->GetC();
            buf.AppendByte(ch);
        }
        return _makeReadBufObj(self, buf);
        """)


    c.addCppCode("""\
        PyObject* _wxInputStream_readline(wxInputStream* self);

        // This does the real work of the readlines methods
        static PyObject* _readlinesHelper(wxInputStream* self,
                                          bool useSizeHint=false, ulong sizehint=0) {
            PyObject* pylist;

            // init list
            {
                wxPyThreadBlocker blocker;
                pylist = PyList_New(0);

                if (!pylist) {
                    PyErr_NoMemory();
                    return NULL;
                }
            }

            // read sizehint bytes or until EOF
            ulong i;
            for (i=0; (self->CanRead()) && (useSizeHint || (i < sizehint));) {
                PyObject* s = _wxInputStream_readline(self);
                if (s == NULL) {
                    wxPyThreadBlocker blocker;
                    Py_DECREF(pylist);
                    return NULL;
                }
                wxPyThreadBlocker blocker;
                PyList_Append(pylist, s);
                i += PyBytes_Size(s);
            }

            // error check
            wxStreamError err = self->GetLastError();
            if (err != wxSTREAM_NO_ERROR && err != wxSTREAM_EOF) {
                wxPyThreadBlocker blocker;
                Py_DECREF(pylist);
                PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
                return NULL;
            }
            return pylist;
        }
        """)

    c.addCppMethod('PyObject*', 'readlines', '()', """\
        return _readlinesHelper(self);
        """)
    c.addCppMethod('PyObject*', 'readlines', '(ulong sizehint)', """\
        return _readlinesHelper(self, true, sizehint);
        """)


    #-----------------------------------------------------------------
    c = module.find('wxOutputStream')
    c.abstract = True
    tools.removeVirtuals(c)


    # Include a C++ class that can wrap a Python file-like object so it can
    # be used as a wxOutputStream
    c.includeCppCode('src/stream_output.cpp')

    # Use that class for the convert code
    c.convertFromPyObject = """\
        // is it just a typecheck?
        if (!sipIsErr) {
            if (wxPyOutputStream::Check(sipPy))
                return 1;
            return 0;
        }
        // otherwise do the conversion
        *sipCppPtr = new wxPyOutputStream(sipPy);
        return sipGetState(sipTransferObj);
        """


    # Add Python file-like methods so a wx.OutputStream can be used as if it
    # was any other Python file object.
    c.addCppMethod('void', 'seek', '(wxFileOffset offset, int whence=0)', """\
        self->SeekO(offset, (wxSeekMode)whence);
        """)
    c.addCppMethod('wxFileOffset', 'tell', '()', """\
        return self->TellO();
        """);
    c.addCppMethod('void', 'close', '()', """\
        self->Close();
        """)
    c.addCppMethod('void', 'flush', '()', """\
        self->Sync();
        """)
    c.addCppMethod('bool', 'eof', '()', """\
        return false; //self->Eof();
        """)

    c.addCppMethod('PyObject*', 'write', '(PyObject* data)', """\
        // We use only bytes objects (strings in 2.7) for the streams, never unicode
        wxPyThreadBlocker blocker;
        if (!PyBytes_Check(data)) {
            PyErr_SetString(PyExc_TypeError, "Bytes object expected");
            return NULL;
        }
        self->Write(PyBytes_AS_STRING(data), PyBytes_GET_SIZE(data));
        RETURN_NONE();
        """)

    # TODO: Add a writelines(sequence) method

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 7
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxMenuItem')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    tools.removeVirtuals(c)

    c.find('SetSubMenu.menu').transfer = True

    # These are MSW only. Make them be empty stubs for the other ports
    c.find('GetBackgroundColour').type = 'wxColour*'
    c.find('GetBackgroundColour').setCppCode("""\
        #ifdef __WXMSW__
            return &self->GetBackgroundColour();
        #else
            return &wxNullColour;
        #endif
        """)

    c.find('SetBackgroundColour').setCppCode("""\
        #ifdef __WXMSW__
            self->SetBackgroundColour(*colour);
        #endif
        """)

    c.find('GetFont').type = 'wxFont*'
    c.find('GetFont').setCppCode("""\
        #ifdef __WXMSW__
            return &self->GetFont();
        #else
            return &wxNullFont;
        #endif
        """)

    c.find('SetFont').setCppCode("""\
        #ifdef __WXMSW__
            self->SetFont(*font);
        #endif
        """)

    c.find('GetMarginWidth').setCppCode("""\
        #ifdef __WXMSW__
            return self->GetMarginWidth();
        #else
            return -1;
        #endif
        """)

    c.find('SetMarginWidth').setCppCode("""\
        #ifdef __WXMSW__
            self->SetMarginWidth(width);
        #endif
        """)

    c.find('GetTextColour').type = 'wxColour*'
    c.find('GetTextColour').setCppCode("""\
        #ifdef __WXMSW__
            return &self->GetTextColour();
        #else
            return &wxNullColour;
        #endif
        """)

    c.find('SetTextColour').setCppCode("""\
        #ifdef __WXMSW__
            self->SetTextColour(*colour);
        #endif
        """)

    c.find('GetBitmap').type = 'const wxBitmap*'
    c.find('GetBitmap').setCppCode("""\
        #ifdef __WXMSW__
            return &self->GetBitmap(checked);
        #else
            return &self->GetBitmap();
        #endif
        """)

    c.find('SetBitmap').setCppCode("""\
        #ifdef __WXMSW__
            self->SetBitmap(*bmp, checked);
        #else
            self->SetBitmap(*bmp); // no checked arg in this case
        #endif
        """)

    c.find('SetBitmaps').setCppCode("""\
        #ifdef __WXMSW__
            self->SetBitmaps(*checked, *unchecked);
        #else
            self->SetBitmap(*checked);
        #endif
        """)

    c.find('GetDisabledBitmap').type = 'const wxBitmap*'
    c.find('GetDisabledBitmap').setCppCode("""\
        #ifdef __WXMSW__
            return &self->GetDisabledBitmap();
        #else
            return &wxNullBitmap;
        #endif
        """)

    c.find('SetDisabledBitmap').setCppCode("""\
        #ifdef __WXMSW__
            self->SetDisabledBitmap(*disabled);
        #endif
        """)

    c.find('GetAccel').factory = True
    c.find('GetAccelFromString').ignore()  # Not implemented anywere?

    module.addItem(
        tools.wxListWrapperTemplate('wxMenuItemList', 'wxMenuItem', module))

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 8
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)
    
    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.
    
    c = module.find('wxIcon')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    c.find('wxIcon').findOverload('*bits').ignore()
    c.find('wxIcon').findOverload('bits[]').ignore()

    c.find('wxIcon.type').default = 'wxBITMAP_TYPE_ANY'    
    c.find('LoadFile.type').default = 'wxBITMAP_TYPE_ANY'

    c.find('ConvertToDisabled').ignore()

    c.addCppCtor('(const wxBitmap& bmp)',
        doc="Construct an Icon from a Bitmap.",
        body="""\
            wxIcon* icon = new wxIcon();
            icon->CopyFromBitmap(*bmp);
            return icon;
            """)
    
    c.addCppMethod('int', '__nonzero__', '()', """\
        return self->IsOk();""")
        
    c.addCppMethod('long', 'GetHandle', '()', """\
        #ifdef __WXMSW__
            return (long)self->GetHandle();
        #else
            return 0;
        #endif
        """)

    c.addCppMethod('void', 'SetHandle', '(long handle)', """\
        #ifdef __WXMSW__
            self->SetHandle((WXHANDLE)handle);
        #endif
        """)
    
    c.find('CreateFromHICON').ignore()
    c.addCppMethod('bool', 'CreateFromHICON', '(long hicon)',
        doc='MSW-only method to create a wx.Icon from a native icon handle.',
        body="""\
            #ifdef __WXMSW__
                return self->CreateFromHICON((WXHICON)hicon);
            #else
                return false;
            #endif
            """)
    
    
    # For compatibility:
    module.addPyFunction('EmptyIcon', '()',
                         deprecated="Use :class:`Icon` instead",
                         doc='A compatibility wrapper for the :class:`Icon` constructor',
                         body='return Icon()')
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 9
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxBrush')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    # Set mustHaveApp on all ctors except the default ctor
    for ctor in c.find('wxBrush').all():
        if ctor.isCtor and ctor.argsString != '()':
            ctor.mustHaveApp()

    c.addCppMethod('int', '__nonzero__', '()', "return self->IsOk();")
    c.addCppMethod('int', '__bool__', '()', "return self->IsOk();")

    c.addCppCode("""\
        #ifdef __WXMAC__
        #include <wx/osx/private.h>
        #endif
        """)
    c.addCppMethod(
        'void', 'MacSetTheme', '(int macThemeBrushID)', """\
        #ifdef __WXMAC__
            self->SetColour(wxColour(wxMacCreateCGColorFromHITheme(macThemeBrushID)));
        #else
            wxPyRaiseNotImplemented();
        #endif
        """)

    c.addAutoProperties()

    # The stock Brush items are documented as simple pointers, but in reality
    # they are macros that evaluate to a function call that returns a brush
    # pointer, and that is only valid *after* the wx.App object has been
    # created. That messes up the code that SIP generates for them, so we need
    # to come up with another solution. So instead we will just create
    # uninitialized brush in a block of Python code, that will then be
    # intialized later when the wx.App is created.
    c.addCppMethod('void',
                   '_copyFrom',
                   '(const wxBrush* other)',
                   "*self = *other;",
                   briefDoc="For internal use only.")  # ??
    pycode = '# These stock brushes will be initialized when the wx.App object is created.\n'
    for item in module:
        if '_BRUSH' in item.name:
            item.ignore()
            pycode += '%s = Brush()\n' % tools.removeWxPrefix(item.name)
    module.addPyCode(pycode)

    # it is delay-initialized, see stockgdi.sip
    module.find('wxTheBrushList').ignore()

    # Some aliases that should be phased out eventually, (sooner rather than
    # later.) They are already gone (or wrapped by an #if) in the C++ code,
    # and so are not found in the documentation...
    module.addPyCode("""\
        wx.STIPPLE_MASK_OPAQUE = int(wx.BRUSHSTYLE_STIPPLE_MASK_OPAQUE)
        wx.STIPPLE_MASK        = int(wx.BRUSHSTYLE_STIPPLE_MASK)
        wx.STIPPLE             = int(wx.BRUSHSTYLE_STIPPLE)
        wx.BDIAGONAL_HATCH     = int(wx.BRUSHSTYLE_BDIAGONAL_HATCH)
        wx.CROSSDIAG_HATCH     = int(wx.BRUSHSTYLE_CROSSDIAG_HATCH)
        wx.FDIAGONAL_HATCH     = int(wx.BRUSHSTYLE_FDIAGONAL_HATCH)
        wx.CROSS_HATCH         = int(wx.BRUSHSTYLE_CROSS_HATCH)
        wx.HORIZONTAL_HATCH    = int(wx.BRUSHSTYLE_HORIZONTAL_HATCH)
        wx.VERTICAL_HATCH      = int(wx.BRUSHSTYLE_VERTICAL_HATCH)
        """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 10
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxIcon')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)
    c.mustHaveApp()

    c.find('wxIcon').findOverload('*bits').ignore()
    c.find('wxIcon').findOverload('bits[]').ignore()

    c.find('wxIcon.type').default = 'wxBITMAP_TYPE_ANY'
    c.find('LoadFile.type').default = 'wxBITMAP_TYPE_ANY'

    c.find('ConvertToDisabled').ignore()

    c.addCppCtor('(const wxBitmap& bmp)',
                 doc="Construct an Icon from a Bitmap.",
                 body="""\
            wxIcon* icon = new wxIcon();
            icon->CopyFromBitmap(*bmp);
            return icon;
            """)

    c.addCppMethod('int', '__nonzero__', '()', """\
        return self->IsOk();""")

    c.addCppMethod(
        'long', 'GetHandle', '()', """\
        #ifdef __WXMSW__
            return (long)self->GetHandle();
        #else
            return 0;
        #endif
        """)

    c.addCppMethod(
        'void', 'SetHandle', '(long handle)', """\
        #ifdef __WXMSW__
            self->SetHandle((WXHANDLE)handle);
        #endif
        """)

    c.find('CreateFromHICON').ignore()
    c.addCppMethod(
        'bool',
        'CreateFromHICON',
        '(long hicon)',
        doc='MSW-only method to create a wx.Icon from a native icon handle.',
        body="""\
            #ifdef __WXMSW__
                return self->CreateFromHICON((WXHICON)hicon);
            #else
                return false;
            #endif
            """)

    # For compatibility:
    module.addPyFunction(
        'EmptyIcon',
        '()',
        deprecated="Use :class:`Icon` instead",
        doc='A compatibility wrapper for the :class:`Icon` constructor',
        body='return Icon()')

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 11
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.


    c = module.find('wxSizerItem')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)
    
    # ctors taking a sizer transfer ownership
    for m in c.find('wxSizerItem').all():
        if m.findItem('sizer'):
            m.find('sizer').transfer = True

    c.find('AssignSizer.sizer').transfer = True
    
    # userData args transfer ownership too, and we'll use wxPyUserData
    # instead of any wxObject
    for m in c.allItems():
        if isinstance(m, etgtools.MethodDef) and m.findItem('userData'):
            m.find('userData').transfer = True
            m.find('userData').type = 'wxPyUserData*'
            
    gud = c.find('GetUserData')
    gud.type = 'wxPyUserData*'
    gud.setCppCode('return dynamic_cast<wxPyUserData*>(self->GetUserData());')

    # these have been deprecated for a while so go ahead and get rid of them
    c.find('SetWindow').ignore()
    c.find('SetSizer').ignore()
    c.find('SetSpacer').ignore()

    c.addPrivateCopyCtor()

    #---------------------------------------------
    c = module.find('wxSizer')
    assert isinstance(c, etgtools.ClassDef)
    tools.fixSizerClass(c)
    c.addPrivateCopyCtor()
    c.addPrivateAssignOp()
    
    for func in c.findAll('Add') + c.findAll('Insert') + c.findAll('Prepend'):
        if func.findItem('sizer'):
            func.find('sizer').transfer = True
        if func.findItem('userData'):
            func.find('userData').transfer = True
            func.find('userData').type = 'wxPyUserData*'
        if func.findItem('item'):
            func.find('item').transfer = True
            
    c.find('GetChildren').overloads = []
    c.find('GetChildren').noCopy = True
    
    # Needs wxWin 2.6 compatibility
    c.find('Remove').findOverload('(wxWindow *window)').ignore()

    c.addPyMethod('AddMany', '(self, items)', 
        doc="""\
        :meth:`AddMany` is a convenience method for adding several items to a sizer
        at one time. Simply pass it a list of tuples, where each tuple
        consists of the parameters that you would normally pass to the :meth:`Add`
        method.
        """,        
        body="""\
        for item in items:
            if not isinstance(item, (tuple, list)):
                item = (item, )
            self.Add(*item)
        """)

    c.addCppMethod('wxSizerItem*', 'Add', 
                   '(const wxSize& size, int proportion=0, int flag=0, '
                   'int border=0, wxPyUserData* userData /Transfer/ = NULL)',
        doc="Add a spacer using a :class:`Size` object.",
        body="return self->Add(size->x, size->y, proportion, flag, border, userData);")

    c.addCppMethod('wxSizerItem*', 'Prepend', 
                   '(const wxSize& size, int proportion=0, int flag=0, '
                   'int border=0, wxPyUserData* userData /Transfer/ = NULL)',
        doc="Prepend a spacer using a :class:`Size` object.",
        body="return self->Prepend(size->x, size->y, proportion, flag, border, userData);")

    c.addCppMethod('wxSizerItem*', 'Insert', 
                   '(size_t index, const wxSize& size, int proportion=0, int flag=0, '
                   'int border=0, wxPyUserData* userData /Transfer/ = NULL)',
        doc="Insert a spacer using a :class:`Size` object.",
        body="return self->Insert(index, size->x, size->y, proportion, flag, border, userData);")


    c.addCppMethod('wxSizerItem*', 'Add', 
                   '(const wxSize& size, const wxSizerFlags& flags)',
        doc="Add a spacer using a :class:`Size` object.",
        body="return self->Add(size->x, size->y, *flags);")

    c.addCppMethod('wxSizerItem*', 'Prepend', 
                   '(const wxSize& size, const wxSizerFlags& flags)',
        doc="Prepend a spacer using a :class:`Size` object.",
        body="return self->Prepend(size->x, size->y, *flags);")

    c.addCppMethod('wxSizerItem*', 'Insert', 
                   '(size_t index, const wxSize& size, const wxSizerFlags& flags)',
        doc="Insert a spacer using a :class:`Size` object.",
        body="return self->Insert(index, size->x, size->y, *flags);")

    c.addPyMethod('__nonzero__', '(self)',
        doc="Can be used to test if the C++ part of the sizer still exists, with \n"
            "code like this::\n\n"
            "    if theSizer:\n"
            "        doSomething()",
        body="""\
        import wx.siplib
        return not wx.siplib.isdeleted(self)
        """)
    c.addPyCode('Sizer.__bool__ = Sizer.__nonzero__') # For Python 3


    
    #---------------------------------------------
    c = module.find('wxBoxSizer')
    tools.fixSizerClass(c)
    c.find('wxBoxSizer.orient').default = 'wxHORIZONTAL'


    #---------------------------------------------
    c = module.find('wxStaticBoxSizer')
    tools.fixSizerClass(c)
    c.find('wxStaticBoxSizer.orient').default = 'wxHORIZONTAL'


    #---------------------------------------------
    c = module.find('wxGridSizer')
    tools.fixSizerClass(c)

    c.addPyMethod('CalcRowsCols', '(self)',
        doc="""\
        CalcRowsCols() -> (rows, cols)

        Calculates how many rows and columns will be in the sizer based
        on the current number of items and also the rows, cols specified
        in the constructor.
        """,
        body="""\
        nitems = len(self.GetChildren())
        rows = self.GetRows()
        cols = self.GetCols()
        assert rows != 0 or cols != 0, "Grid sizer must have either rows or columns fixed"
        if cols != 0:
            rows = (nitems + cols - 1) / cols
        elif rows != 0:
            cols = (nitems + rows - 1) / rows
        return (rows, cols)
        """)
    
    #---------------------------------------------
    c = module.find('wxFlexGridSizer')
    tools.fixSizerClass(c)

    
    #---------------------------------------------
    c = module.find('wxStdDialogButtonSizer')
    tools.fixSizerClass(c)


    
    module.addPyCode("PySizer = wx.deprecated(Sizer, 'Use Sizer instead.')")
        
    module.addItem(tools.wxListWrapperTemplate('wxSizerItemList', 'wxSizerItem', module))
    

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 12
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    module.addHeaderCode('#include <wx/gdicmn.h>')

    def markCreateFactories(klass):
        """Mark all Create methods as factories"""
        for func in klass.allItems():
            if isinstance(func, etgtools.FunctionDef) \
               and func.name.startswith('Create') \
               and '*' in func.type:
                func.factory = True

    #---------------------------------------------
    c = module.find('wxGraphicsObject')
    assert isinstance(c, etgtools.ClassDef)
    c.mustHaveApp()
    c.addCppMethod('bool', 'IsOk', '()', 'return !self->IsNull();')
    c.addCppMethod('int', '__nonzero__', '()', "return !self->IsNull();")
    c.addCppMethod('int', '__bool__', '()', "return !self->IsNull();")

    #---------------------------------------------
    c = module.find('wxGraphicsContext')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)
    c.abstract = True
    c.mustHaveApp()

    c.addCppMethod('wxGraphicsContext*',
                   'Create',
                   '(wxAutoBufferedPaintDC* autoPaintDC /KeepReference/)',
                   pyArgsString='(autoPaintDC) -> GraphicsContext',
                   isStatic=True,
                   body="""\
            return wxGraphicsContext::Create(*autoPaintDC);
            """)

    m = c.find('Create').findOverload('wxEnhMetaFileDC')
    m.find('metaFileDC').type = 'const wxMetafileDC&'
    m.argsString = '(const wxMetafileDC& metaFileDC)'
    m.setCppCode("""\
        #ifdef __WXMSW__
        #if wxUSE_ENH_METAFILE
            return wxGraphicsContext::Create(*metaFileDC);
        #endif
        #endif
            wxPyRaiseNotImplemented();
            return NULL;
        """)

    markCreateFactories(c)

    # Ensure that the target DC or image passed to Create lives as long as the
    # GC does. NOTE: Since the Creates are static methods there is no self to
    # associate the extra reference with, but since they are factories then
    # that extra reference will be held by the return value of the factory
    # instead.
    for m in c.find('Create').all():
        for p in m.items:
            if 'DC' in p.name or p.name == 'image':
                p.keepReference = True

    c.find('GetSize.width').out = True
    c.find('GetSize.height').out = True
    c.find('GetDPI.dpiX').out = True
    c.find('GetDPI.dpiY').out = True

    m = c.find('GetPartialTextExtents')
    m.find('widths').ignore()
    m.type = 'wxArrayDouble*'
    m.factory = True  # a new instance is being created
    m.setCppCode("""\
        wxArrayDouble rval;
        self->GetPartialTextExtents(*text, rval);
        return new wxArrayDouble(rval);
        """)

    m = c.find('GetTextExtent')
    m.pyName = 'GetFullTextExtent'
    m.find('width').out = True
    m.find('height').out = True
    m.find('descent').out = True
    m.find('externalLeading').out = True

    c.addCppMethod(
        'PyObject*',
        'GetTextExtent',
        '(const wxString& text)',
        pyArgsString="(text) -> (width, height)",
        doc=
        "Gets the dimensions of the string using the currently selected font.",
        body="""\
        wxDouble width = 0.0, height = 0.0;
        self->GetTextExtent(*text, &width, &height, NULL, NULL);
        wxPyThreadBlocker blocker;
        return sipBuildResult(0, "(dd)", width, height);
        """)

    c.addPyCode(
        "GraphicsContext.DrawRotatedText = wx.deprecated(GraphicsContext.DrawText, 'Use DrawText instead.')"
    )

    c.addCppCode(
        tools.ObjArrayHelperTemplate(
            'wxPoint2D', 'sipType_wxPoint2DDouble',
            "Expected a sequence of length-2 sequences or wx.Point2D objects.")
    )

    # we'll reimplement this overload as StrokeLineSegments
    c.find('StrokeLines').findOverload('beginPoints').ignore()
    c.addCppMethod('void',
                   'StrokeLineSegments',
                   '(PyObject* beginPoints, PyObject* endPoints)',
                   pyArgsString="(beginPoint2Ds, endPoint2Ds)",
                   doc="Stroke disconnected lines from begin to end points.",
                   body="""\
        size_t c1, c2, count;
        wxPoint2D* beginP = wxPoint2D_array_helper(beginPoints, &c1);
        wxPoint2D* endP =   wxPoint2D_array_helper(endPoints, &c2);

        if ( beginP != NULL && endP != NULL ) {
            count = wxMin(c1, c2);
            self->StrokeLines(count, beginP, endP);
        }
        delete [] beginP;
        delete [] endP;
        """)

    # Also reimplement the main StrokeLines method to reuse the same helper
    # function as StrokeLineSegments
    m = c.find('StrokeLines').findOverload('points').ignore()
    c.addCppMethod('void',
                   'StrokeLines',
                   '(PyObject* points)',
                   pyArgsString="(point2Ds)",
                   doc="Stroke lines connecting all the points.",
                   body="""\
        size_t count;
        wxPoint2D* ptsArray = wxPoint2D_array_helper(points, &count);

        if ( ptsArray != NULL ) {
            self->StrokeLines(count, ptsArray);
            delete [] ptsArray;
        }
        """)

    # and once more for DrawLines
    m = c.find('DrawLines').ignore()
    c.addCppMethod(
        'void',
        'DrawLines',
        '(PyObject* points, wxPolygonFillMode fillStyle = wxODDEVEN_RULE)',
        pyArgsString="(point2Ds, fillStyle=ODDEVEN_RULE)",
        doc="Draws a polygon.",
        body="""\
        size_t count;
        wxPoint2D* ptsArray = wxPoint2D_array_helper(points, &count);

        if ( ptsArray != NULL ) {
            self->DrawLines(count, ptsArray, fillStyle);
            delete [] ptsArray;
        }
        """)

    # TODO: support this?
    c.find('CreateFromNativeHDC').ignore()

    #---------------------------------------------
    c = module.find('wxGraphicsPath')
    tools.removeVirtuals(c)
    c.find('GetBox').findOverload('wxDouble *x, wxDouble *y').ignore()
    c.find('GetCurrentPoint').findOverload('wxDouble *x, wxDouble *y').ignore()
    c.mustHaveApp()

    c.find('GetNativePath').setCppCode("""\
        if (self->IsNull())
            return (void*)0;
        return self->GetNativePath();
        """)

    #---------------------------------------------
    c = module.find('wxGraphicsRenderer')
    tools.removeVirtuals(c)
    markCreateFactories(c)
    c.abstract = True

    # The KeepReference annotation doesn't work for us in this case, as it will
    # hold the reference in the renderer object, but it is better to hold the
    # reference in the returned context object instead. Otherwise there is still
    # some possibility that the held DC will be destroyed before the context.
    c.addPyCode("""\
        def _ctx_hold_ref(f):
            from functools import wraps
            @wraps(f)
            def wrapper(self, obj):
                ctx = f(self, obj)
                if ctx is not None:
                    ctx._obj = obj
                return ctx
            return wrapper
        GraphicsRenderer.CreateContext = _ctx_hold_ref(GraphicsRenderer.CreateContext)
        GraphicsRenderer.CreateContextFromImage = _ctx_hold_ref(GraphicsRenderer.CreateContextFromImage)
        GraphicsRenderer.CreateContextFromUnknownDC = _ctx_hold_ref(GraphicsRenderer.CreateContextFromUnknownDC)
        """)

    # TODO: support this?
    c.find('CreateContext').findOverload('wxEnhMetaFileDC').ignore()

    # TODO: support this?
    c.find('CreateContextFromNativeHDC').ignore()

    c.addPyMethod('GetType',
                  '(self)',
                  doc="Returns the name of the GraphicsRenderer class.",
                  body="return self.GetClassInfo().GetClassName()")

    c.find('GetGDIPlusRenderer').ignore()
    c.addCppMethod('wxGraphicsRenderer*',
                   'GetGDIPlusRenderer',
                   '()',
                   isStatic=True,
                   doc="Returns GDI+ renderer (MSW only).",
                   body="""\
            #ifdef __WXMSW__
                return wxGraphicsRenderer::GetGDIPlusRenderer();
            #else
                return NULL;
            #endif
            """)

    c.find('GetDirect2DRenderer').ignore()
    c.addCppMethod('wxGraphicsRenderer*',
                   'GetDirect2DRenderer',
                   '()',
                   isStatic=True,
                   doc="Returns Direct2D renderer (MSW and Python3 only).",
                   body="""\
            #if wxUSE_GRAPHICS_DIRECT2D
                return wxGraphicsRenderer::GetDirect2DRenderer();
            #else
                return NULL;
            #endif
            """)

    #---------------------------------------------
    c = module.find('wxGraphicsMatrix')
    tools.removeVirtuals(c)
    c.mustHaveApp()

    c.find('Concat').overloads = []
    c.find('IsEqual').overloads = []

    c.find('Get.a').out = True
    c.find('Get.b').out = True
    c.find('Get.c').out = True
    c.find('Get.d').out = True
    c.find('Get.tx').out = True
    c.find('Get.ty').out = True

    c.find('TransformDistance.dx').inOut = True
    c.find('TransformDistance.dy').inOut = True

    c.find('TransformPoint.x').inOut = True
    c.find('TransformPoint.y').inOut = True

    c.find('GetNativeMatrix').setCppCode("""\
        if (self->IsNull())
            return (void*)0;
        return self->GetNativeMatrix();
        """)

    #---------------------------------------------
    c = module.find('wxGraphicsGradientStops')
    c.addCppMethod('SIP_SSIZE_T',
                   '__len__',
                   '()',
                   body="return (SIP_SSIZE_T)self->GetCount();")
    c.addCppMethod('wxGraphicsGradientStop*',
                   '__getitem__',
                   '(ulong n)',
                   pyArgsString='(n)',
                   body="return new wxGraphicsGradientStop(self->Item(n));",
                   factory=True)

    #---------------------------------------------
    c = module.find('wxGraphicsBitmap')
    c.find('GetNativeBitmap').setCppCode("""\
        if (self->IsNull())
            return (void*)0;
        return self->GetNativeBitmap();
        """)

    #---------------------------------------------
    c = module.find('wxGraphicsPenInfo')
    # Ignore Dashes for now
    # TODO: we need to do something like wx.Pen.SetDashes, but since
    # GraphicsPenInfo is transitory we can't save the reference in it to the
    # holder, and the pen will not have been created yet...
    c.find('Dashes').ignore()
    c.find('GetDashes').ignore()
    c.find('GetDashCount').ignore()
    c.find('GetDash').ignore()

    #---------------------------------------------
    # Use the pyNames we set for these classes in geometry.py so the old
    # names do not show up in the docstrings, etc.
    tools.changeTypeNames(module, 'wxPoint2DDouble', 'wxPoint2D')
    tools.changeTypeNames(module, 'wxRect2DDouble', 'wxRect2D')

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 13
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxDataFormat')
    assert isinstance(c, etgtools.ClassDef)
    c.find('GetType').setCppCode(
        "return static_cast<wxDataFormatId>(self->GetType());")

    item = module.find('wxFormatInvalid')
    module.items.remove(item)
    module.insertItemAfter(c, item)

    #------------------------------------------------------------
    c = module.find('wxDataObject')
    c.addPrivateCopyCtor()

    addGetAllFormats(c, True)

    # For initial testing only.  TODO: Remove later
    c.addPublic()
    c.addCppMethod('void',
                   '_testGetAllFormats',
                   '()',
                   body="""\
            size_t count = self->GetFormatCount();
            wxDataFormat* fmts = new wxDataFormat[count];
            self->GetAllFormats(fmts);
            """)

    # Replace the GetDataHere method with a version that uses a smarter
    # Python buffer object instead of a stupid void pointer.
    c.find('GetDataHere').ignore()
    c.addCppMethod(
        'bool',
        'GetDataHere',
        '(const wxDataFormat& format, wxPyBuffer* buf)',
        cppSignature='bool (const wxDataFormat& format, void* buf)',
        isVirtual=True,
        isPureVirtual=True,
        isConst=True,
        doc=
        "Copies this data object's data in the requested format to the buffer provided.",
        body="""\
            if (!buf->checkSize(self->GetDataSize(*format)))
                return false;
            return self->GetDataHere(*format, buf->m_ptr);
            """,

        # This code will be used in the function that calls a Python implementation
        # of this method.
        virtualCatcherCode="""\
            // Call self.GetDataSize() to find out how big the buffer should be
            PyObject* self = NULL; 
            PyObject* fmtObj = NULL;
            PyObject* sizeObj = NULL;
            PyObject* buffer = NULL;
            PyObject* resObj = NULL;
            Py_ssize_t size = 0;
            
            self = PyMethod_Self(sipMethod); // this shouldn't fail, and the reference is borrowed
            
            fmtObj = wxPyConstructObject((void*)&format, "wxDataFormat", false);
            if (!fmtObj) goto error;
            sizeObj = PyObject_CallMethod(self, "GetDataSize", "(O)", fmtObj, NULL);
            if (!sizeObj) goto error;
            size = wxPyInt_AsSsize_t(sizeObj);

            // Make a buffer that big using the pointer passed to us, and then 
            // call the Python method.
            buffer = wxPyMakeBuffer(buf, size);
            resObj = sipCallMethod(0, sipMethod, "SS", fmtObj, buffer);

            if (!resObj || sipParseResult(0,sipMethod,resObj,"b",&sipRes) < 0)
                PyErr_Print();
            
            error:
            Py_XDECREF(resObj);
            Py_XDECREF(buffer);
            Py_XDECREF(fmtObj);
            Py_XDECREF(sizeObj);
            """)

    # Replace the SetData method with an implementation that uses Python
    # buffer objects.
    c.find('SetData').ignore()
    c.addCppMethod(
        'bool',
        'SetData',
        '(const wxDataFormat& format, wxPyBuffer* buf)',
        cppSignature=
        'bool (const wxDataFormat& format, size_t len, const void* buf)',
        isVirtual=True,
        doc=
        "Copies data from the provided buffer to this data object for the specified format.",
        body="return self->SetData(*format, buf->m_len, buf->m_ptr);",

        # This code will be used in the function that calls a Python implementation
        # of this method.
        virtualCatcherCode="""\
            PyObject* buffer = wxPyMakeBuffer((void*)buf, len);
            PyObject *resObj = sipCallMethod(0,sipMethod,"NS",
                                   new wxDataFormat(format),sipType_wxDataFormat,NULL,
                                   buffer);
            if (!resObj || sipParseResult(0,sipMethod,resObj,"b",&sipRes) < 0)
                PyErr_Print();
            Py_XDECREF(resObj);
            Py_XDECREF(buffer);
            """)

    #------------------------------------------------------------
    c = module.find('wxDataObjectSimple')

    c.addCppCtor_sip(
        '(const wxString& formatName)',
        body='sipCpp = new sipwxDataObjectSimple(wxDataFormat(*formatName));')

    # As in wxDataObject above replace GetDataHere and SetData with methods
    # that use buffer objects instead of void*, but this time we do not pass
    # a DataFormat object with it.
    c.find('GetDataHere').ignore()
    c.addCppMethod(
        'bool',
        'GetDataHere',
        '(wxPyBuffer* buf)',
        cppSignature='bool (void* buf)',
        isVirtual=True,
        isConst=True,
        doc="Copies this data object's data bytes to the given buffer",
        body="""\
            if (!buf->checkSize(self->GetDataSize()))
                return false;
            return self->GetDataHere(buf->m_ptr);
            """,
        virtualCatcherCode="""\
            // Call self.GetDataSize() to find out how big the buffer should be
            PyObject* self = NULL; 
            PyObject* sizeObj = NULL;
            PyObject* buffer = NULL;
            PyObject* resObj = NULL;
            Py_ssize_t size = 0;
            
            self = PyMethod_Self(sipMethod);
            
            sizeObj = PyObject_CallMethod(self, "GetDataSize", "", NULL);
            if (!sizeObj) goto error;
            size = wxPyInt_AsSsize_t(sizeObj);

            // Make a buffer that big using the pointer passed to us, and then 
            // call the Python method.
            buffer = wxPyMakeBuffer(buf, size);
            resObj = sipCallMethod(0, sipMethod, "S", buffer);

            if (!resObj || sipParseResult(0,sipMethod,resObj,"b",&sipRes) < 0)
                PyErr_Print();
            
            error:
            Py_XDECREF(resObj);
            Py_XDECREF(buffer);
            Py_XDECREF(sizeObj);
            """)

    c.find('SetData').ignore()
    c.addCppMethod(
        'bool',
        'SetData',
        '(wxPyBuffer* buf)',
        cppSignature='bool (size_t len, const void* buf)',
        isVirtual=True,
        doc="Copies data from the provided buffer to this data object.",
        body="return self->SetData(buf->m_len, buf->m_ptr);",
        virtualCatcherCode="""\
            PyObject* buffer = wxPyMakeBuffer((void*)buf, len);
            PyObject *resObj = sipCallMethod(0,sipMethod,"S",buffer);
            if (!resObj || sipParseResult(0,sipMethod,resObj,"b",&sipRes) < 0)
                PyErr_Print();
            Py_XDECREF(resObj);
            Py_XDECREF(buffer);
            """)

    addGetAllFormats(c)
    addBaseVirtuals(c)

    #------------------------------------------------------------
    c = module.find('wxCustomDataObject')
    tools.removeVirtuals(c)

    c.addCppCtor_sip(
        '(const wxString& formatName)',
        body='sipCpp = new sipwxCustomDataObject(wxDataFormat(*formatName));')

    # remove the methods having to do with allocating or owning the data buffer
    c.find('Alloc').ignore()
    c.find('Free').ignore()
    c.find('TakeData').ignore()

    c.find('GetData').ignore()
    c.addCppMethod(
        'PyObject*',
        'GetData',
        '()',
        isConst=True,
        doc="Returns a reference to the data buffer.",
        body="return wxPyMakeBuffer(self->GetData(), self->GetSize());")

    c.find('SetData').ignore()
    c.addCppMethod(
        'bool',
        'SetData',
        '(wxPyBuffer* buf)',
        cppSignature='bool (size_t len, const void* buf)',
        isVirtual=True,
        doc="Copies data from the provided buffer to this data object's buffer",
        body="return self->SetData(buf->m_len, buf->m_ptr);")

    addGetAllFormats(c)
    addBaseVirtuals(c)
    addSimpleVirtuals(c)

    #------------------------------------------------------------
    c = module.find('wxDataObjectComposite')

    c.find('Add.dataObject').transfer = True

    addGetAllFormats(c)
    addBaseVirtuals(c)

    #------------------------------------------------------------
    c = module.find('wxTextDataObject')
    addGetAllFormats(c)
    addBaseVirtuals(c)
    addSimpleVirtuals(c)

    #------------------------------------------------------------
    c = module.find('wxURLDataObject')

    # wxURLDataObject derives from wxDataObjectComposite on some platforms,
    # and wxTextDataObject on others, so we need to take a least common
    # denominator approach here to be able to work on all platforms.
    c.bases = ['wxDataObject']

    addGetAllFormats(c)
    addBaseVirtuals(c)
    addSimpleVirtuals(c)

    #------------------------------------------------------------
    c = module.find('wxBitmapDataObject')
    addGetAllFormats(c)
    addBaseVirtuals(c)
    addSimpleVirtuals(c)

    #------------------------------------------------------------
    c = module.find('wxFileDataObject')
    addGetAllFormats(c)
    addBaseVirtuals(c)
    addSimpleVirtuals(c)

    #------------------------------------------------------------
    c = module.find('wxHTMLDataObject')
    addGetAllFormats(c)
    addBaseVirtuals(c)
    addSimpleVirtuals(c)

    #------------------------------------------------------------
    module.addPyCode(
        "PyDataObjectSimple = wx.deprecated(DataObjectSimple), 'Use DataObjectSimple instead.'"
    )
    module.addPyCode(
        "PyTextDataObject = wx.deprecated(TextDataObject, 'Use TextDataObject instead.')"
    )
    module.addPyCode(
        "PyBitmapDataObject = wx.deprecated(BitmapDataObject, 'Use TextDataObject instead.')"
    )

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 14
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    
    etgtools.parseDoxyXML(module, ITEMS)
    
    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.
    
    c = module.find('wxPageSetupDialogData')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)
    
    c.find('GetPrintData').overloads = []
    
    c.addCppMethod('int', '__nonzero__', '()', """\
        return self->IsOk();
        """)
    
    c.addProperty('MarginBottomRight', 'GetMarginBottomRight', 'SetMarginBottomRight')
    c.addProperty('MarginTopLeft', 'GetMarginTopLeft', 'SetMarginTopLeft')
    c.addProperty('MinMarginBottomRight', 'GetMinMarginBottomRight', 'SetMinMarginBottomRight')
    c.addProperty('MinMarginTopLeft', 'GetMinMarginTopLeft', 'SetMinMarginTopLeft')
    c.addProperty('PaperId', 'GetPaperId', 'SetPaperId')
    c.addProperty('PaperSize', 'GetPaperSize', 'SetPaperSize')
    c.addProperty('PrintData', 'GetPrintData', 'SetPrintData')



    c = module.find('wxPrintData')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    c.addCppMethod('int', '__nonzero__', '()', """\
        return self->IsOk();
        """)
    
    # TODO: These two methods should use something other than a PyString for
    # holding the data...
    c.addCppMethod('PyObject*', 'GetPrivData', '()', """\
        PyObject* data;
        wxPyThreadBlocker blocker;
        data = PyBytes_FromStringAndSize(self->GetPrivData(),
                                         self->GetPrivDataLen());
        return data;    
        """)
    
    c.addCppMethod('void', 'SetPrivData', '(PyObject* data)', """\
        wxPyThreadBlocker blocker;
        if (! PyBytes_Check(data)) {
            wxPyErr_SetString(PyExc_TypeError, "Expected string object");
            return;
        }

        self->SetPrivData(PyBytes_AS_STRING(data), PyBytes_GET_SIZE(data));
        """)
    
    c.addAutoProperties()
    


    c = module.find('wxPrintDialogData')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)
    c.find('SetSetupDialog').ignore()

    c.addCppMethod('int', '__nonzero__', '()', """\
        return self->IsOk();
        """)
    
    c.addAutoProperties()


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 15
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)
    
    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.
            
    c = module.find('wxDC')
    assert isinstance(c, etgtools.ClassDef)

    c.addPrivateCopyCtor()
    c.addPublic()
    tools.removeVirtuals(c)
    
    # rename the more complex overload for these two, like in classic wxPython
    c.find('GetTextExtent').findOverload('wxCoord *').pyName = 'GetFullTextExtent'
    c.find('GetMultiLineTextExtent').findOverload('wxCoord *').pyName = 'GetFullMultiLineTextExtent'                   
    
    # Keep only the wxSize overloads of these
    c.find('GetSize').findOverload('wxCoord').ignore()
    c.find('GetSizeMM').findOverload('wxCoord').ignore()
    
    # TODO: needs wxAffineMatrix2D support.
    c.find('GetTransformMatrix').ignore()
    c.find('SetTransformMatrix').ignore()

    # remove wxPoint* overloads, we use the wxPointList ones
    c.find('DrawLines').findOverload('wxPoint points').ignore()
    c.find('DrawPolygon').findOverload('wxPoint points').ignore()
    c.find('DrawSpline').findOverload('wxPoint points').ignore()

    # TODO: we'll need a custom method implementation for this since there
    # are multiple array parameters involved...
    c.find('DrawPolyPolygon').ignore()


    
    # Add output param annotations so the generated docstrings will be correct
    c.find('GetUserScale.x').out = True
    c.find('GetUserScale.y').out = True

    c.find('GetLogicalScale.x').out = True
    c.find('GetLogicalScale.y').out = True
    
    c.find('GetLogicalOrigin').overloads = []
    c.find('GetLogicalOrigin.x').out = True
    c.find('GetLogicalOrigin.y').out = True
    
    c.find('GetTextExtent.w').out = True
    c.find('GetTextExtent.h').out = True
    c.find('GetTextExtent.descent').out = True
    c.find('GetTextExtent.externalLeading').out = True

    c.find('GetMultiLineTextExtent.w').out = True
    c.find('GetMultiLineTextExtent.h').out = True
    c.find('GetMultiLineTextExtent.heightLine').out = True
    
    c.find('GetClippingBox.x').out = True
    c.find('GetClippingBox.y').out = True
    c.find('GetClippingBox.width').out = True
    c.find('GetClippingBox.height').out = True
    c.addPyMethod('GetClippingRect', '(self)', 
        doc="Gets the rectangle surrounding the current clipping region",
        body="return wx.Rect(*self.GetClippingBox())")

    
    # Add some alternate implementations for DC methods, in order to avoid
    # using parameters as return values, etc. as well as Classic
    # compatibility.
    c.find('GetPixel').ignore()
    c.addCppMethod('wxColour*', 'GetPixel', '(wxCoord x, wxCoord y)', 
        doc="Gets the colour at the specified location on the DC.", body="""\
        wxColour* col = new wxColour;
        self->GetPixel(x, y, col);
        return col;
        """, factory=True)

    # Return the rect instead of using an output parameter
    m = c.find('DrawLabel').findOverload('rectBounding')
    m.type = 'wxRect*'
    m.find('rectBounding').ignore()
    m.factory = True  # a new instance of wxRect is being created
    m.setCppCode("""\
        wxRect rv;
        self->DrawLabel(*text, *bitmap, *rect, alignment, indexAccel, &rv);
        return new wxRect(rv);
        """)
    c.addPyCode('DC.DrawImageLabel = wx.deprecated(DC.DrawLabel, "Use DrawLabel instead.")')


    # Return the array instead of using an output parameter
    m = c.find('GetPartialTextExtents')
    m.type = 'wxArrayInt*'
    m.find('widths').ignore()
    m.factory = True  # a new instance is being created
    m.setCppCode("""\
        wxArrayInt rval;
        self->GetPartialTextExtents(*text, rval);
        return new wxArrayInt(rval);
        """)

    
    c.addCppMethod('int', '__nonzero__', '()', """\
        return self->IsOk();
        """)
   
    c.addPyMethod('GetBoundingBox', '(self)', doc="""\
        GetBoundingBox() -> (x1,y1, x2,y2)\n
        Returns the min and max points used in drawing commands so far.""",
        body="return (self.MinX(), self.MinY(), self.MaxX(), self.MaxY())")
    
    
    c.addCppMethod('long', 'GetHDC', '()', """\
        #ifdef __WXMSW__
            return (long)self->GetHandle();
        #else
            wxPyRaiseNotImplemented();
            return 0;
        #endif""")
    c.addCppMethod('void*', 'GetCGContext', '()', """\
        #ifdef __WXMAC__
            return self->GetHandle();
        #else
            wxPyRaiseNotImplemented();
            return NULL;
        #endif""")
    c.addCppMethod('void*', 'GetGdkDrawable', '()', """\
        #ifdef __WXGTK__
            return self->GetHandle();
        #else
            wxPyRaiseNotImplemented();
            return NULL;
        #endif""")
    
    c.addPyCode('DC.GetHDC = wx.deprecated(DC.GetHDC, "Use GetHandle instead.")')
    c.addPyCode('DC.GetCGContext = wx.deprecated(DC.GetCGContext, "Use GetHandle instead.")')
    c.addPyCode('DC.GetGdkDrawable = wx.deprecated(DC.GetGdkDrawable, "Use GetHandle instead.")')
    
    
    # This file contains implementations of functions for quickly drawing
    # lists of items on the DC. They are called from the CppMethods defined
    # below, which in turn are called from the PyMethods below that.
    c.includeCppCode('src/dc_ex.cpp')
    
    c.addCppMethod('PyObject*', '_DrawPointList', '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body="return wxPyDrawXXXList(*self, wxPyDrawXXXPoint, pyCoords, pyPens, pyBrushes);")

    c.addCppMethod('PyObject*', '_DrawLineList', '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body="return wxPyDrawXXXList(*self, wxPyDrawXXXLine, pyCoords, pyPens, pyBrushes);")

    c.addCppMethod('PyObject*', '_DrawRectangleList', '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body="return wxPyDrawXXXList(*self, wxPyDrawXXXRectangle, pyCoords, pyPens, pyBrushes);")

    c.addCppMethod('PyObject*', '_DrawEllipseList', '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body="return wxPyDrawXXXList(*self, wxPyDrawXXXEllipse, pyCoords, pyPens, pyBrushes);")

    c.addCppMethod('PyObject*', '_DrawPolygonList', '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body="return wxPyDrawXXXList(*self, wxPyDrawXXXPolygon, pyCoords, pyPens, pyBrushes);")

    c.addCppMethod('PyObject*', '_DrawTextList', 
        '(PyObject* textList, PyObject* pyPoints, PyObject* foregroundList, PyObject* backgroundList)',
        body="return wxPyDrawTextList(*self, textList, pyPoints, foregroundList, backgroundList);")

    
    c.addPyMethod('DrawPointList', '(self, points, pens=None)',
        doc="""\
            Draw a list of points as quickly as possible.
    
            :param points: A sequence of 2-element sequences representing 
                           each point to draw, (x,y).
            :param pens:   If None, then the current pen is used.  If a single 
                           pen then it will be used for all points.  If a list of 
                           pens then there should be one for each point in points.
            """,
        body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(points):
                raise ValueError('points and pens must have same length')
            return self._DrawPointList(points, pens, [])
            """)

    c.addPyMethod('DrawLineList', '(self, lines, pens=None)',
        doc="""\
            Draw a list of lines as quickly as possible.
    
            :param lines: A sequence of 4-element sequences representing
                          each line to draw, (x1,y1, x2,y2).
            :param pens:  If None, then the current pen is used.  If a
                          single pen then it will be used for all lines.  If
                          a list of pens then there should be one for each line
                          in lines.
            """,
        body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(lines):
                raise ValueError('lines and pens must have same length')
            return self._DrawLineList(lines, pens, [])
            """)

    c.addPyMethod('DrawRectangleList', '(self, rectangles, pens=None, brushes=None)',
        doc="""\
            Draw a list of rectangles as quickly as possible.
    
            :param rectangles: A sequence of 4-element sequences representing
                               each rectangle to draw, (x,y, w,h).
            :param pens:       If None, then the current pen is used.  If a
                               single pen then it will be used for all rectangles.
                               If a list of pens then there should be one for each 
                               rectangle in rectangles.
            :param brushes:    A brush or brushes to be used to fill the rectagles,
                               with similar semantics as the pens parameter.
            """,
        body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(rectangles):
                raise ValueError('rectangles and pens must have same length')
            if brushes is None:
                brushes = []
            elif isinstance(brushes, wx.Brush):
                brushes = [brushes]
            elif len(brushes) != len(rectangles):
                raise ValueError('rectangles and brushes must have same length')
            return self._DrawRectangleList(rectangles, pens, brushes)
            """)
    
    c.addPyMethod('DrawEllipseList', '(self, ellipses, pens=None, brushes=None)',
        doc="""\
            Draw a list of ellipses as quickly as possible.
    
            :param ellipses: A sequence of 4-element sequences representing
                             each ellipse to draw, (x,y, w,h).
            :param pens:     If None, then the current pen is used.  If a
                             single pen then it will be used for all ellipses.
                             If a list of pens then there should be one for each 
                             ellipse in ellipses.
            :param brushes:  A brush or brushes to be used to fill the ellipses,
                             with similar semantics as the pens parameter.
            """,
        body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(ellipses):
                raise ValueError('ellipses and pens must have same length')
            if brushes is None:
                brushes = []
            elif isinstance(brushes, wx.Brush):
                brushes = [brushes]
            elif len(brushes) != len(ellipses):
                raise ValueError('ellipses and brushes must have same length')
            return self._DrawEllipseList(ellipses, pens, brushes)
            """)
    
    c.addPyMethod('DrawPolygonList', '(self, polygons, pens=None, brushes=None)',
        doc="""\
            Draw a list of polygons, each of which is a list of points.
    
            :param polygons: A sequence of sequences of sequences.
                             [[(x1,y1),(x2,y2),(x3,y3)...], [(x1,y1),(x2,y2),(x3,y3)...]]
                                  
            :param pens:     If None, then the current pen is used.  If a
                             single pen then it will be used for all polygons.
                             If a list of pens then there should be one for each 
                             polygon.
            :param brushes:  A brush or brushes to be used to fill the polygons,
                             with similar semantics as the pens parameter.
            """,
        body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(polygons):
                raise ValueError('polygons and pens must have same length')
            if brushes is None:
                brushes = []
            elif isinstance(brushes, wx.Brush):
                brushes = [brushes]
            elif len(brushes) != len(polygons):
                raise ValueError('polygons and brushes must have same length')
            return self._DrawPolygonList(polygons, pens, brushes)
            """)
    
    c.addPyMethod('DrawTextList', '(self, textList, coords, foregrounds=None, backgrounds=None)',
        doc="""\
            Draw a list of strings using a list of coordinants for positioning each string.
    
            :param textList:    A list of strings
            :param coords:      A list of (x,y) positions
            :param foregrounds: A list of `wx.Colour` objects to use for the
                                foregrounds of the strings.
            :param backgrounds: A list of `wx.Colour` objects to use for the
                                backgrounds of the strings.
    
            NOTE: Make sure you set background mode to wx.Solid (DC.SetBackgroundMode)
                  If you want backgrounds to do anything.
            """,
        body="""\
            if type(textList) == type(''):
                textList = [textList]
            elif len(textList) != len(coords):
                raise ValueError('textlist and coords must have same length')
            if foregrounds is None:
                foregrounds = []
            elif isinstance(foregrounds, wx.Colour):
                foregrounds = [foregrounds]
            elif len(foregrounds) != len(coords):
                raise ValueError('foregrounds and coords must have same length')
            if backgrounds is None:
                backgrounds = []
            elif isinstance(backgrounds, wx.Colour):
                backgrounds = [backgrounds]
            elif len(backgrounds) != len(coords):
                raise ValueError('backgrounds and coords must have same length')
            return  self._DrawTextList(textList, coords, foregrounds, backgrounds)
            """)




    # TODO: Port the PseudoDC from Classic


    
    #-----------------------------------------------------------------
    c = module.find('wxDCClipper')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'return False')

    
    #-----------------------------------------------------------------
    c = module.find('wxDCBrushChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'return False')

    
    #-----------------------------------------------------------------
    c = module.find('wxDCPenChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'return False')

    
    #-----------------------------------------------------------------
    c = module.find('wxDCTextColourChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'return False')

    
    #-----------------------------------------------------------------
    c = module.find('wxDCFontChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'return False')
    
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 16
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)
    
    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.    
    
    c = module.find('wxFont')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)
    
    # FFont factory function for backwards compatibility
    module.addCppFunction('wxFont*', 'FFont', 
                          """(int pointSize,
                              wxFontFamily family,
                              int flags = wxFONTFLAG_DEFAULT,
                              const wxString& faceName = wxEmptyString,
                              wxFontEncoding encoding = wxFONTENCODING_DEFAULT)""",
        pyArgsString="(pointSize, family, flags=FONTFLAG_DEFAULT, faceName=EmptyString, encoding=FONTENCODING_DEFAULT)",
        body="""\
        wxFont* font = wxFont::New(pointSize, family, flags, *faceName, encoding);
        return font;
        """, factory=True)
    
    for item in c.findAll('New'):
        item.factory = True
    
    c.addProperty('Encoding GetEncoding SetEncoding')
    c.addProperty('FaceName GetFaceName SetFaceName')
    c.addProperty('Family GetFamily SetFamily')
    c.addProperty('NativeFontInfoDesc GetNativeFontInfoDesc SetNativeFontInfo')
    c.addProperty('NativeFontInfoUserDesc GetNativeFontInfoUserDesc SetNativeFontInfoUserDesc')
    c.addProperty('PointSize GetPointSize SetPointSize')
    c.addProperty('PixelSize GetPixelSize SetPixelSize')
    c.addProperty('Style GetStyle SetStyle')
    c.addProperty('Weight GetWeight SetWeight')

    # TODO, there is now a Underlined method so we can't have a
    # property of the same name.
    #c.addProperty('Underlined GetUnderlined SetUnderlined')
    #c.addProperty('Strikethrough GetStrikethrough SetStrikethrough')

    c.addCppMethod('int', '__nonzero__', '()', """\
        return self->IsOk();
        """)

    c.addCppMethod('void*', 'GetHFONT', '()', 
        doc="Returns the font's native handle.",
        body="""\
        #ifdef __WXMSW__
            return self->GetHFONT();
        #else
            return 0;
        #endif
        """)
    
    c.addCppMethod('void*', 'OSXGetCGFont', '()', 
        doc="Returns the font's native handle.",
        body="""\
        #ifdef __WXMAC__
            return self->OSXGetCGFont();
        #else
            return 0;
        #endif
        """)

    c.addCppMethod('void*', 'GetPangoFontDescription', '()', 
        doc="Returns the font's native handle.",
        body="""\
        #ifdef __WXGTK__
            return self->GetNativeFontInfo()->description;
        #else
            return 0;
        #endif
        """)
    
    
       
    # The stock Font items are documented as simple pointers, but in reality
    # they are macros that evaluate to a function call that returns a font
    # pointer, and that is only valid *after* the wx.App object has been
    # created. That messes up the code that SIP generates for them, so we need
    # to come up with another solution. So instead we will just create
    # uninitialized fonts in a block of Python code, that will then be
    # initialized later when the wx.App is created.
    c.addCppMethod('void', '_copyFrom', '(const wxFont* other)', 
                   "*self = *other;",
                   briefDoc="For internal use only.")  # ??
    pycode = '# These stock fonts will be initialized when the wx.App object is created.\n'
    for item in module:
        if '_FONT' in item.name:
            item.ignore()
            pycode += '%s = Font()\n' % tools.removeWxPrefix(item.name)
    module.addPyCode(pycode)

    # it is delay-initialized, see stockgdi.sip
    module.find('wxTheFontList').ignore()

    module.find('wxFromString').ignore()
    module.find('wxToString').ignore()

    c.addPyMethod('SetNoAntiAliasing', '(self, no=True)', 'pass', deprecated=True)
    c.addPyMethod('GetNoAntiAliasing', '(self)', 'pass', deprecated=True)

    # Some aliases that should be phased out eventually, (sooner rather than
    # later.) They are already gone (or wrapped by an #if) in the C++ code,
    # and so are not found in the documentation...
    module.addPyCode("""\
        wx.DEFAULT    = int(wx.FONTFAMILY_DEFAULT)
        wx.DECORATIVE = int(wx.FONTFAMILY_DECORATIVE)
        wx.ROMAN      = int(wx.FONTFAMILY_ROMAN)
        wx.SCRIPT     = int(wx.FONTFAMILY_SCRIPT)
        wx.SWISS      = int(wx.FONTFAMILY_SWISS)
        wx.MODERN     = int(wx.FONTFAMILY_MODERN)
        wx.TELETYPE   = int(wx.FONTFAMILY_TELETYPE)

        wx.NORMAL = int(wx.FONTWEIGHT_NORMAL)
        wx.LIGHT  = int(wx.FONTWEIGHT_LIGHT)
        wx.BOLD   = int(wx.FONTWEIGHT_BOLD)
        
        wx.NORMAL = int(wx.FONTSTYLE_NORMAL)
        wx.ITALIC = int(wx.FONTSTYLE_ITALIC)
        wx.SLANT  = int(wx.FONTSTYLE_SLANT)
        """)        


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 17
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxAcceleratorEntry')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    c = module.find('wxAcceleratorTable')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    # Replace the implementation of the AcceleratorTable ctor so it can
    # accept a Python sequence of tuples or AcceleratorEntry objects like
    # Classic does. Using the arraySize and array annotations does let us
    # pass a list of entries, but they have to already be AccelertorEntry
    # obejcts. We want to allow Items in the list to be either
    # wx.AcceleratorEntry items or a 3-tuple containing the values to pass to
    # the wx.AcceleratorEntry ctor.

    # Ignore the current constructor
    c.find('wxAcceleratorTable').findOverload('entries').ignore()

    # and add the code for the new constructor
    c.addCppCtor(briefDoc="""\
            Constructs an AcceleratorTable from a sequence of items
            where each item is either a wx.AcceleratorEntry or a 
            corresponding 3-element tuple like (modifiers, keyCode, cmd).
            """,
                 argsString='(PyObject* entries)',
                 body="""\
    const char* errmsg = "Expected a sequence of 3-tuples or wx.AcceleratorEntry objects.";
    if (!PySequence_Check(entries)) {
        PyErr_SetString(PyExc_TypeError, errmsg);
        return NULL;
    }
    int count = PySequence_Size(entries);
    wxAcceleratorEntry* tmpEntries = new wxAcceleratorEntry[count];
    if (! tmpEntries) {
        PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
        return NULL;
    }
    int idx;
    for (idx=0; idx<count; idx++) {
        PyObject* obj = PySequence_ITEM(entries, idx);
        if (sipCanConvertToType(obj, sipType_wxAcceleratorEntry, SIP_NO_CONVERTORS)) {
            int err = 0;
            wxAcceleratorEntry* entryPtr = reinterpret_cast<wxAcceleratorEntry*>(
                sipConvertToType(obj, sipType_wxAcceleratorEntry, NULL, 0, 0, &err));
            tmpEntries[idx] = *entryPtr;
        }
        else if (PySequence_Check(obj) && PySequence_Size(obj) == 3) {
            PyObject* o1 = PySequence_ITEM(obj, 0);
            PyObject* o2 = PySequence_ITEM(obj, 1);
            PyObject* o3 = PySequence_ITEM(obj, 2);
            tmpEntries[idx].Set(wxPyInt_AsLong(o1), wxPyInt_AsLong(o2), wxPyInt_AsLong(o3));
            Py_DECREF(o1);
            Py_DECREF(o2);
            Py_DECREF(o3);
        }
        else {
            PyErr_SetString(PyExc_TypeError, errmsg);
            return NULL;
        }
        Py_DECREF(obj);
    }

    wxAcceleratorTable* table = new wxAcceleratorTable(count, tmpEntries);
    delete tmpEntries;
    return table;
    """)

    # Mac doesn't have this, and we don't real with resource files from
    # wxPython anyway.
    c.find('wxAcceleratorTable').findOverload('resource').ignore()

    module.addPyFunction('GetAccelFromString',
                         '(label)',
                         deprecated=True,
                         body="""\
            accel = wx.AcceleratorEntry()
            accel.FromString(label)
            return accel
            """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 18
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.
    c = module.find('wxPalette')
    tools.removeVirtuals(c)


    # Add a helper function for use with the Create method and the Ctor
    # accepting RGB data.
    c.addCppCode("""\
        // a helper function to be used in the Create method and one of the Ctors
        bool _paletteCreateHelper(wxPalette* self,
                                  PyObject* red, PyObject* green, PyObject* blue) {
            bool rval = false;
            wxPyThreadBlocker blocker;
            char* errMsg = "Expected a sequence of integer objects";

            if (!PySequence_Check(red) || !PySequence_Check(green) || !PySequence_Check(blue)) {
                PyErr_SetString(PyExc_TypeError, errMsg);
                return rval;
            }

            Py_ssize_t count = PySequence_Size(red);
            if (PySequence_Size(green) != count || PySequence_Size(blue) != count) {
                PyErr_SetString(PyExc_ValueError, "Sequence lengths must be equal");
                return rval;
            }

            unsigned char* redArray = new unsigned char[count];
            unsigned char* greenArray = new unsigned char[count];
            unsigned char* blueArray = new unsigned char[count];

            for (Py_ssize_t i = 0; i < count; i++) {
                PyObject* redItem = PySequence_ITEM(red, i);
                PyObject* greenItem = PySequence_ITEM(green, i);
                PyObject* blueItem = PySequence_ITEM(blue, i);
                if (!wxPyInt_Check(redItem) || !wxPyInt_Check(greenItem) || !wxPyInt_Check(blueItem)) {
                    PyErr_SetString(PyExc_TypeError, errMsg);
                    goto pch_exit;
                }

                long redLong = wxPyInt_AsLong(redItem);
                long greenLong = wxPyInt_AsLong(greenItem);
                long blueLong = wxPyInt_AsLong(blueItem);
                Py_DECREF(redItem);
                Py_DECREF(greenItem);
                Py_DECREF(blueItem);
                if (redLong < 0 || redLong > 255 || greenLong < 0 || greenLong > 255 || blueLong < 0 || blueLong > 255) {
                    PyErr_SetString(PyExc_ValueError, "Sequence values must be in the 0..255 range");
                    goto pch_exit;
                }
                redArray[i] = redLong;
                greenArray[i] = greenLong;
                blueArray[i] = blueLong;
            }

            rval = self->Create(count, redArray, greenArray, blueArray);

        pch_exit:
            delete[] redArray;
            delete[] greenArray;
            delete[] blueArray;
            return rval;
        }
        """)


    #-----------------------------------------------------------------

    # Replace the constructor accepting the arrays of RGB values with one that
    # understands any Python sequence.
    c.find('wxPalette').findOverload('red').ignore()
    c.addCppCtor('(PyObject* red, PyObject* green, PyObject* blue)',
        doc=dedent("""\
        Creates a palette from a set of sequences of integers,
        one for each red, green and blue color components.

        :param red: A sequence of integer values in the range 0..255 inclusive.
        :param green: A sequence of integer values in the range 0..255 inclusive.
        :param blue: A sequence of integer values in the range 0..255 inclusive.

        .. note:: All sequences must be the same length.
        """),
        body="""\
            wxPalette* pal = new wxPalette;
            _paletteCreateHelper(pal, red, green, blue);
            if (PyErr_Occurred()) {
                delete pal;
                return NULL;
            }
            return pal;
            """)

    c.find('GetPixel.red').pyInt = True
    c.find('GetPixel.green').pyInt = True
    c.find('GetPixel.blue').pyInt = True

    c.find('GetRGB').ignore()
    c.addCppMethod('PyObject*', 'GetRGB', '(int pixel)',
        pyArgsString="(pixel) -> (red, green, blue)",
        doc="Returns RGB values for a given palette index.",
        body="""\
            unsigned char red;
            unsigned char green;
            unsigned char blue;
            wxPyThreadBlocker blocker;
            if (!self->GetRGB(pixel, &red, &green, &blue)) {
                PyErr_SetString(PyExc_IndexError, "Pixel out of range");
                return NULL;
            }
            PyObject* rv = PyTuple_New(3);
            PyTuple_SetItem(rv, 0, wxPyInt_FromLong(red));
            PyTuple_SetItem(rv, 1, wxPyInt_FromLong(green));
            PyTuple_SetItem(rv, 2, wxPyInt_FromLong(blue));
            return rv;
            """)

    # Replace the Create method with one that understands any kind of Python sequence
    c.find('Create').ignore()
    c.addCppMethod('PyObject*', 'Create', '(PyObject* red, PyObject* green, PyObject* blue)',
        pyArgsString="(red, green, blue) -> bool",
        doc=dedent("""\
        Creates a palette from 3 sequences of integers, one for each red, blue or green component.

        :param red: A sequence of integer values in the range 0..255 inclusive.
        :param green: A sequence of integer values in the range 0..255 inclusive.
        :param blue: A sequence of integer values in the range 0..255 inclusive.

        .. note:: All sequences must be the same length.
        """),
        body="""\
            bool rval = _paletteCreateHelper(self, red, green, blue);
            wxPyThreadBlocker blocker;
            if (PyErr_Occurred())
                return NULL;
            if (rval)
                Py_RETURN_TRUE;
            else
                Py_RETURN_FALSE;
            """)


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 19
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxMask')
    c.mustHaveApp()

    c = module.find('wxBitmap')
    assert isinstance(c, etgtools.ClassDef)
    c.mustHaveApp()

    tools.removeVirtuals(c)

    c.find('wxBitmap.bits').type = 'const char*'
    c.find('wxBitmap.type').default = 'wxBITMAP_TYPE_ANY'
    c.find('LoadFile.type').default = 'wxBITMAP_TYPE_ANY'

    c.find('wxBitmap').findOverload('(const char *const *bits)').ignore()

    c.addCppCtor('(PyObject* listOfBytes)',
        doc="Construct a Bitmap from a list of strings formatted as XPM data.",
        body="""\
            wxPyThreadBlocker blocker;
            char**    cArray = NULL;
            int       count;
            char      errMsg[] = "Expected a list of bytes objects.";

            if (!PyList_Check(listOfBytes)) {
                PyErr_SetString(PyExc_TypeError, errMsg);
                return NULL;
            }
            count = PyList_Size(listOfBytes);
            cArray = new char*[count];

            for(int x=0; x<count; x++) {
                PyObject* item = PyList_GET_ITEM(listOfBytes, x);
                if (!PyBytes_Check(item)) {
                    PyErr_SetString(PyExc_TypeError, errMsg);
                    delete [] cArray;
                    return NULL;
                }
                cArray[x] = PyBytes_AsString(item);
            }
            wxBitmap* bmp = new wxBitmap(cArray);
            delete [] cArray;
            return bmp;
            """)


    c.find('SetMask.mask').transfer = True

    c.addCppMethod('void', 'SetMaskColour', '(const wxColour& colour)', """\
        wxMask* mask = new wxMask(*self, *colour);
        self->SetMask(mask);
        """)

    c.addCppMethod('int', '__nonzero__', '()', """\
        return self->IsOk();
        """)

    c.addCppMethod('long', 'GetHandle', '()',
        doc='MSW-only method to fetch the windows handle for the bitmap.',
        body="""\
            #ifdef __WXMSW__
                return (long)self->GetHandle();
            #else
                return 0;
            #endif
            """)

    c.addCppMethod('void', 'SetHandle', '(long handle)',
        doc='MSW-only method to set the windows handle for the bitmap.',
        body="""\
            #ifdef __WXMSW__
                self->SetHandle((WXHANDLE)handle);
            #endif
            """)

    c.addCppMethod('void', 'SetSize', '(const wxSize& size)',
        doc='Set the bitmap size (does not alter the existing native bitmap data or image size).',
        body="""\
            self->SetWidth(size->x);
            self->SetHeight(size->y);
            """)



    # On MSW the bitmap handler classes are different than what is
    # documented, and this causes compile errors. Nobody has needed them from
    # Python thus far, so just ignore them all for now.
    for m in c.find('FindHandler').all():
        m.ignore()
    c.find('AddHandler').ignore()
    c.find('CleanUpHandlers').ignore()
    c.find('GetHandlers').ignore()
    c.find('InsertHandler').ignore()
    c.find('RemoveHandler').ignore()

    # This one is called from the wx startup code, it's not needed in Python
    # so nuke it too since we're nuking all the others.
    c.find('InitStandardHandlers').ignore()

    module.find('wxBitmapHandler').ignore()
    #module.addItem(tools.wxListWrapperTemplate('wxList', 'wxBitmapHandler', module))


    #-----------------------------------------------------------------------
    # Declarations, helpers and methods for converting to/from buffer objects
    # with raw bitmap access.

    from etgtools import EnumDef, EnumValueDef
    e = EnumDef(name='wxBitmapBufferFormat')
    e.items.extend([ EnumValueDef(name='wxBitmapBufferFormat_RGB'),
                     EnumValueDef(name='wxBitmapBufferFormat_RGBA'),
                     EnumValueDef(name='wxBitmapBufferFormat_RGB32'),
                     EnumValueDef(name='wxBitmapBufferFormat_ARGB32'),
                     ])
    module.insertItem(0, e)

    c.includeCppCode('src/bitmap_ex.cpp')
    module.addHeaderCode('#include "bitmap_ex.h"')


    c.addCppMethod('void', 'CopyFromBuffer',
        '(wxPyBuffer* data, wxBitmapBufferFormat format=wxBitmapBufferFormat_RGB, int stride=-1)',
        doc="""\
            Copy data from a buffer object to replace the bitmap pixel data.
            Default format is plain RGB, but other formats are now supported as
            well.  The following symbols are used to specify the format of the
            bytes in the buffer:

                =============================  ================================
                wx.BitmapBufferFormat_RGB      A simple sequence of RGB bytes
                wx.BitmapBufferFormat_RGBA     A simple sequence of RGBA bytes
                wx.BitmapBufferFormat_ARGB32   A sequence of 32-bit values in native endian order, with alpha in the upper 8 bits, followed by red, green, and blue.
                wx.BitmapBufferFormat_RGB32    Same as above but the alpha byte is ignored.
                =============================  ================================""",
        body="""\
            wxPyCopyBitmapFromBuffer(self, (byte*)data->m_ptr, data->m_len, format, stride);
        """)


    c.addCppMethod('void', 'CopyToBuffer',
        '(wxPyBuffer* data, wxBitmapBufferFormat format=wxBitmapBufferFormat_RGB, int stride=-1)',
        doc="""\
            Copy pixel data to a buffer object.  See :meth:`CopyFromBuffer` for buffer
            format details.""",
        body="""\
            wxPyCopyBitmapToBuffer(self, (byte*)data->m_ptr, data->m_len, format, stride);
            """)


    # Some bitmap factories added as static methods

    c.addCppMethod('wxBitmap*', 'FromBufferAndAlpha',
        '(int width, int height, wxPyBuffer* data, wxPyBuffer* alpha)',
        isStatic=True,
        factory=True,
        doc="""\
            Creates a :class:`wx.Bitmap` from in-memory data.  The data and alpha
            parameters must be a Python object that implements the buffer
            interface, such as a string, bytearray, etc.  The data object
            is expected to contain a series of RGB bytes and be at least
            width*height*3 bytes long, while the alpha object is expected
            to be width*height bytes long and represents the image's alpha
            channel.  On Windows and Mac the RGB values will be
            'premultiplied' by the alpha values.  (The other platforms do
            the multiplication themselves.)

            Unlike :func:`wx.ImageFromBuffer` the bitmap created with this function
            does not share the memory block with the buffer object.  This is
            because the native pixel buffer format varies on different
            platforms, and so instead an efficient as possible copy of the
            data is made from the buffer object to the bitmap's native pixel
            buffer.
            """,
        body="""\
            if (!data->checkSize(width*height*3) || !alpha->checkSize(width*height))
                return NULL;

            byte* ddata = (byte*)data->m_ptr;
            byte* adata = (byte*)alpha->m_ptr;
            wxBitmap* bmp = new wxBitmap(width, height, 32);

            wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
            if (! pixData) {
                wxPyErr_SetString(PyExc_RuntimeError, "Failed to gain raw access to bitmap data.");
                return NULL;
            }

            wxAlphaPixelData::Iterator p(pixData);
            for (int y=0; y<height; y++) {
                wxAlphaPixelData::Iterator rowStart = p;
                for (int x=0; x<width; x++) {
                    byte a = *(adata++);
                    p.Red()   = wxPy_premultiply(*(ddata++), a);
                    p.Green() = wxPy_premultiply(*(ddata++), a);
                    p.Blue()  = wxPy_premultiply(*(ddata++), a);
                    p.Alpha() = a;
                    ++p;
                }
                p = rowStart;
                p.OffsetY(pixData, 1);
            }
            return bmp;
            """)

    c.addCppMethod('wxBitmap*', 'FromBuffer', '(int width, int height, wxPyBuffer* data)',
        isStatic=True,
        factory=True,
        doc="""\
            Creates a :class:`wx.Bitmap` from in-memory data.  The data parameter
            must be a Python object that implements the buffer interface, such
            as a string, bytearray, etc.  The data object is expected to contain
            a series of RGB bytes and be at least width*height*3 bytes long.

            Unlike :func:`wx.ImageFromBuffer` the bitmap created with this function
            does not share the memory block with the buffer object.  This is
            because the native pixel buffer format varies on different
            platforms, and so instead an efficient as possible copy of the
            data is made from the buffer object to the bitmap's native pixel
            buffer.
            """,
        body="""\
            wxBitmap* bmp = new wxBitmap(width, height, 24);
            wxPyCopyBitmapFromBuffer(bmp, (byte*)data->m_ptr, data->m_len, wxBitmapBufferFormat_RGB);
            wxPyThreadBlocker blocker;
            if (PyErr_Occurred()) {
                delete bmp;
                bmp = NULL;
            }
            return bmp;
            """)

    module.addPyFunction('BitmapFromBuffer', '(width, height, dataBuffer, alphaBuffer=None)',
        deprecated="Use :meth:`wx.Bitmap.FromBuffer` or :meth:`wx.Bitmap.FromBufferAndAlpha` instead.",
        doc='A compatibility wrapper for :meth:`wx.Bitmap.FromBuffer` and :meth:`wx.Bitmap.FromBufferAndAlpha`',
        body="""\
            if alphaBuffer is not None:
                return Bitmap.FromBufferAndAlpha(width, height, dataBuffer, alphaBuffer)
            else:
                return Bitmap.FromBuffer(width, height, dataBuffer)
            """)




    c.addCppMethod('wxBitmap*', 'FromBufferRGBA', '(int width, int height, wxPyBuffer* data)',
        isStatic=True,
        factory=True,
        doc="""\
            Creates a :class:`wx.Bitmap` from in-memory data.  The data parameter
            must be a Python object that implements the buffer interface, such
            as a string, bytearray, etc.  The data object is expected to contain
            a series of RGBA bytes and be at least width*height*4 bytes long.
            On Windows and Mac the RGB values will be 'premultiplied' by the
            alpha values.  (The other platforms do the multiplication themselves.)

            Unlike :func:`wx.ImageFromBuffer` the bitmap created with this function
            does not share the memory block with the buffer object.  This is
            because the native pixel buffer format varies on different
            platforms, and so instead an efficient as possible copy of the
            data is made from the buffer object to the bitmap's native pixel
            buffer.
            """,
        body="""\
            wxBitmap* bmp = new wxBitmap(width, height, 32);
            wxPyCopyBitmapFromBuffer(bmp, (byte*)data->m_ptr, data->m_len, wxBitmapBufferFormat_RGBA);
            wxPyThreadBlocker blocker;
            if (PyErr_Occurred()) {
                delete bmp;
                bmp = NULL;
            }
            return bmp;
            """)

    module.addPyFunction('BitmapFromBufferRGBA', '(width, height, dataBuffer)',
        deprecated="Use :meth:`wx.Bitmap.FromBufferRGBA` instead.",
        doc='A compatibility wrapper for :meth:`wx.Bitmap.FromBufferRGBA`',
        body='return Bitmap.FromBufferRGBA(width, height, dataBuffer)')




    c.addCppMethod('wxBitmap*', 'FromRGBA',
        '(int width, int height, byte red=0, byte green=0, byte blue=0, byte alpha=0)',
        isStatic=True,
        factory=True,
        doc="""\
            Creates a new empty 32-bit :class:`wx.Bitmap` where every pixel has been
            initialized with the given RGBA values.
            """,
        body="""\
            if ( !(width > 0 && height > 0) ) {
                wxPyErr_SetString(PyExc_ValueError, "Width and height must be greater than zero");
                return NULL;
            }

            wxBitmap* bmp = new wxBitmap(width, height, 32);
            wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
            if (! pixData) {
                wxPyErr_SetString(PyExc_RuntimeError, "Failed to gain raw access to bitmap data.");
                return NULL;
            }

            wxAlphaPixelData::Iterator p(pixData);
            for (int y=0; y<height; y++) {
                wxAlphaPixelData::Iterator rowStart = p;
                for (int x=0; x<width; x++) {
                    p.Red()   = wxPy_premultiply(red, alpha);
                    p.Green() = wxPy_premultiply(green, alpha);
                    p.Blue()  = wxPy_premultiply(blue, alpha);
                    p.Alpha() = alpha;
                    ++p;
                }
                p = rowStart;
                p.OffsetY(pixData, 1);
            }
            return bmp;
            """)

    module.addPyFunction('EmptyBitmapRGBA', '(width, height, red=0, green=0, blue=0, alpha=0)',
        deprecated="Use :meth:`wx.Bitmap.FromRGBA` instead.",
        doc='A compatibility wrapper for :meth:`wx.Bitmap.FromRGBA`',
        body='return Bitmap.FromRGBA(width, height, red, green, blue, alpha)')

    #-----------------------------------------------------------------------

    # For compatibility:
    module.addPyFunction('EmptyBitmap', '(width, height, depth=BITMAP_SCREEN_DEPTH)',
                         deprecated="Use :class:`wx.Bitmap` instead",
                         doc='A compatibility wrapper for the wx.Bitmap(width, height, depth) constructor',
                         body='return Bitmap(width, height, depth)')

    module.addPyFunction('BitmapFromImage', '(image)',
                         deprecated="Use :class:`wx.Bitmap` instead",
                         doc='A compatibility wrapper for the wx.Bitmap(wx.Image) constructor',
                         body='return Bitmap(image)')

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 20
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    # These enums are declared in files that we will not be using because
    # wxPython does not need the classes that are in those files. So just
    # inject the enums here instead.
    from etgtools import EnumDef, EnumValueDef
    e = EnumDef(name='wxStreamError')
    e.items.extend([
        EnumValueDef(name='wxSTREAM_NO_ERROR'),
        EnumValueDef(name='wxSTREAM_EOF'),
        EnumValueDef(name='wxSTREAM_WRITE_ERROR'),
        EnumValueDef(name='wxSTREAM_READ_ERROR'),
    ])
    module.insertItem(0, e)

    e = EnumDef(name='wxSeekMode')
    e.items.extend([
        EnumValueDef(name='wxFromStart'),
        EnumValueDef(name='wxFromCurrent'),
        EnumValueDef(name='wxFromEnd'),
    ])
    module.insertItem(1, e)

    #-----------------------------------------------------------------
    c = module.find('wxStreamBase')
    assert isinstance(c, etgtools.ClassDef)
    c.abstract = True
    tools.removeVirtuals(c)
    c.find('operator!').ignore()

    #-----------------------------------------------------------------
    c = module.find('wxInputStream')
    c.abstract = True
    tools.removeVirtuals(c)

    # Include a C++ class that can wrap a Python file-like object so it can
    # be used as a wxInputStream
    c.includeCppCode('src/stream_input.cpp')

    # Use that class for the convert code
    c.convertFromPyObject = """\
        // is it just a typecheck?
        if (!sipIsErr) {
            if (wxPyInputStream::Check(sipPy))
                return 1;
            return 0;
        }
        // otherwise do the conversion
        *sipCppPtr = new wxPyInputStream(sipPy);
        return sipGetState(sipTransferObj);
        """

    # Add Python file-like methods so a wx.InputStream can be used as if it
    # was any other Python file object.
    c.addCppMethod(
        'void', 'seek', '(wxFileOffset offset, int whence=0)', """\
        self->SeekI(offset, (wxSeekMode)whence);
        """)
    c.addCppMethod('wxFileOffset', 'tell', '()', """\
        return self->TellI();
        """)
    c.addCppMethod('void', 'close', '()', """\
        // ignored for now
        """)
    c.addCppMethod('void', 'flush', '()', """\
        // ignored for now
        """)
    c.addCppMethod('bool', 'eof', '()', """\
        return self->Eof();
        """)

    c.addCppCode("""\
        // helper used by the read and readline methods to make a PyObject
        static PyObject* _makeReadBufObj(wxInputStream* self, wxMemoryBuffer& buf) {
            PyObject* obj = NULL;

            wxPyThreadBlocker blocker;
            wxStreamError err = self->GetLastError();  // error check
            if (err != wxSTREAM_NO_ERROR && err != wxSTREAM_EOF) {
                PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
            }
            else {
                // Return the data as a string object.  TODO: Py3
                obj = PyBytes_FromStringAndSize(buf, buf.GetDataLen());
            }
            return obj;
        }
        """)

    c.addCppMethod(
        'PyObject*', 'read', '()', """\
        wxMemoryBuffer buf;
        const ulong BUFSIZE = 1024;

        // read while bytes are available on the stream
        while ( self->CanRead() ) {
            self->Read(buf.GetAppendBuf(BUFSIZE), BUFSIZE);
            buf.UngetAppendBuf(self->LastRead());
        }
        return _makeReadBufObj(self, buf);
        """)

    c.addCppMethod(
        'PyObject*', 'read', '(ulong size)', """\
        wxMemoryBuffer buf;

        // Read only size number of characters
        self->Read(buf.GetWriteBuf(size), size);
        buf.UngetWriteBuf(self->LastRead());
        return _makeReadBufObj(self, buf);
        """)

    c.addCppMethod(
        'PyObject*', 'readline', '()', """\
        wxMemoryBuffer buf;
        char ch = 0;

        // read until \\n 
        while ((ch != '\\n') && (self->CanRead())) {
            ch = self->GetC();
            buf.AppendByte(ch);
        }
        return _makeReadBufObj(self, buf);
        """)

    c.addCppMethod(
        'PyObject*', 'readline', '(ulong size)', """\
        wxMemoryBuffer buf;
        int i;
        char ch;

        // read until \\n or byte limit reached
        for (i=ch=0; (ch != '\\n') && (self->CanRead()) && (i < size); i++) {
            ch = self->GetC();
            buf.AppendByte(ch);
        }
        return _makeReadBufObj(self, buf);
        """)

    c.addCppCode("""\
        PyObject* _wxInputStream_readline(wxInputStream* self);
        
        // This does the real work of the readlines methods
        static PyObject* _readlinesHelper(wxInputStream* self, 
                                          bool useSizeHint=false, ulong sizehint=0) {
            PyObject* pylist;

            // init list
            {
                wxPyThreadBlocker blocker;
                pylist = PyList_New(0);

                if (!pylist) {
                    PyErr_NoMemory();
                    return NULL;
                }
            }
    
            // read sizehint bytes or until EOF
            ulong i;
            for (i=0; (self->CanRead()) && (useSizeHint || (i < sizehint));) {
                PyObject* s = _wxInputStream_readline(self);
                if (s == NULL) {
                    wxPyThreadBlocker blocker;
                    Py_DECREF(pylist);
                    return NULL;
                }
                wxPyThreadBlocker blocker;
                PyList_Append(pylist, s);
                i += PyBytes_Size(s);
            }
    
            // error check
            wxStreamError err = self->GetLastError();
            if (err != wxSTREAM_NO_ERROR && err != wxSTREAM_EOF) {
                wxPyThreadBlocker blocker;
                Py_DECREF(pylist);
                PyErr_SetString(PyExc_IOError,"IOError in wxInputStream");
                return NULL;
            }    
            return pylist;        
        }
        """)

    c.addCppMethod('PyObject*', 'readlines', '()', """\
        return _readlinesHelper(self);
        """)
    c.addCppMethod(
        'PyObject*', 'readlines', '(ulong sizehint)', """\
        return _readlinesHelper(self, true, sizehint);
        """)

    #-----------------------------------------------------------------
    c = module.find('wxOutputStream')
    c.abstract = True
    tools.removeVirtuals(c)

    # Include a C++ class that can wrap a Python file-like object so it can
    # be used as a wxOutputStream
    c.includeCppCode('src/stream_output.cpp')

    # Use that class for the convert code
    c.convertFromPyObject = """\
        // is it just a typecheck?
        if (!sipIsErr) {
            if (wxPyOutputStream::Check(sipPy))
                return 1;
            return 0;
        }
        // otherwise do the conversion
        *sipCppPtr = new wxPyOutputStream(sipPy);
        return sipGetState(sipTransferObj);
        """

    # Add Python file-like methods so a wx.OutputStream can be used as if it
    # was any other Python file object.
    c.addCppMethod(
        'void', 'seek', '(wxFileOffset offset, int whence=0)', """\
        self->SeekO(offset, (wxSeekMode)whence);
        """)
    c.addCppMethod('wxFileOffset', 'tell', '()', """\
        return self->TellO();
        """)
    c.addCppMethod('void', 'close', '()', """\
        self->Close();
        """)
    c.addCppMethod('void', 'flush', '()', """\
        self->Sync();
        """)
    c.addCppMethod('bool', 'eof', '()', """\
        return false; //self->Eof();
        """)

    c.addCppMethod(
        'PyObject*', 'write', '(PyObject* data)', """\
        // We use only bytes objects (strings in 2.7) for the streams, never unicode
        wxPyThreadBlocker blocker;
        if (!PyBytes_Check(data)) {
            PyErr_SetString(PyExc_TypeError, "Bytes object expected");
            return NULL;
        }
        self->Write(PyBytes_AS_STRING(data), PyBytes_GET_SIZE(data));
        RETURN_NONE();
        """)

    # TODO: Add a writelines(sequence) method

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 21
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.


    # Use wxPyUserData for the clientData values instead of a plain wxObject
    def _fixClientData(c):
        for item in c.allItems():
            if isinstance(item, etgtools.ParamDef) and item.name == 'clientData':
                item.type = 'wxPyUserData*'
                item.transfer = True


    #---------------------------------------------
    c = module.find('wxToolBarToolBase')
    assert isinstance(c, etgtools.ClassDef)
    c.abstract = True
    tools.removeVirtuals(c)
    _fixClientData(c)

    # Switch all wxToolBarBase to wxToolBar
    for item in c.allItems():
        if isinstance(item, etgtools.ParamDef) and item.name == 'tbar':
            item.type = 'wxToolBar*'

    c.find('GetToolBar').ignore()
    c.addCppMethod('wxToolBar*', 'GetToolBar', '()',
        doc="Return the toolbar this tool is a member of.",
        body="""\
            return (wxToolBar*)self->GetToolBar();
            """)

    gcd = c.find('GetClientData')
    gcd.type = 'wxPyUserData*'
    gcd.setCppCode('return dynamic_cast<wxPyUserData*>(self->GetClientData());')

    c.find('SetDropdownMenu.menu').transfer = True


    #---------------------------------------------
    c = module.find('wxToolBar')
    tools.fixWindowClass(c)
    tools.ignoreConstOverloads(c)
    _fixClientData(c)
    module.addGlobalStr('wxToolBarNameStr', c)

    gcd = c.find('GetToolClientData')
    gcd.type = 'wxPyUserData*'
    gcd.setCppCode('return dynamic_cast<wxPyUserData*>(self->GetToolClientData(toolId));')

    c.find('AddTool.tool').transfer = True
    c.find('InsertTool.tool').transfer = True

    # Conform the help text parameters.
    m = c.find('AddTool')
    for method in m.all():
        for helper in ('shortHelp', 'longHelp'):
            try:
                param = method.find("{}String".format(helper))
                param.name = helper
            except ExtractorError:
                pass

    c.find('OnLeftClick').ignore()
    c.find('OnMouseEnter').ignore()
    c.find('OnRightClick').ignore()
    c.find('OnLeftClick').ignore()

    c.find('SetDropdownMenu.menu').transfer = True


    # Add some deprecated methods to aid with Classic compatibility.
    # TODO: Which others are commonly enough used that they should be here too?
    c.addPyMethod('AddSimpleTool', '(self, toolId, bitmap, shortHelpString="", longHelpString="", isToggle=0)',
        doc='Old style method to add a tool to the toolbar.',
        deprecated='Use :meth:`AddTool` instead.',
        body="""\
            kind = wx.ITEM_NORMAL
            if isToggle: kind = wx.ITEM_CHECK
            return self.AddTool(toolId, '', bitmap, wx.NullBitmap, kind,
                                shortHelpString, longHelpString)
            """)
    c.addPyMethod('AddLabelTool',
                  '(self, id, label, bitmap, bmpDisabled=wx.NullBitmap, kind=wx.ITEM_NORMAL,'
                  ' shortHelp="", longHelp="", clientData=None)',
        doc='Old style method to add a tool in the toolbar.',
        deprecated='Use :meth:`AddTool` instead.',
        body="""\
            return self.AddTool(id, label, bitmap, bmpDisabled, kind,
                                shortHelp, longHelp, clientData)
            """)

    c.addPyMethod('InsertSimpleTool', '(self, pos, toolId, bitmap, shortHelpString="", longHelpString="", isToggle=0)',
        doc='Old style method to insert a tool in the toolbar.',
        deprecated='Use :meth:`InsertTool` instead.',
        body="""\
            kind = wx.ITEM_NORMAL
            if isToggle: kind = wx.ITEM_CHECK
            return self.InsertTool(pos, toolId, '', bitmap, wx.NullBitmap, kind,
                                   shortHelpString, longHelpString)
            """)
    c.addPyMethod('InsertLabelTool',
                  '(self, pos, id, label, bitmap, bmpDisabled=wx.NullBitmap, kind=wx.ITEM_NORMAL,'
                  ' shortHelp="", longHelp="", clientData=None)',
        doc='Old style method to insert a tool in the toolbar.',
        deprecated='Use :meth:`InsertTool` instead.',
        body="""\
            return self.InsertTool(pos, id, label, bitmap, bmpDisabled, kind,
                                   shortHelp, longHelp, clientData)
            """)




    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 22
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxDC')
    assert isinstance(c, etgtools.ClassDef)
    c.mustHaveApp()

    c.addPrivateCopyCtor()
    c.addPublic()
    tools.removeVirtuals(c)

    c.addDtor('public', True)

    # Keep only the wxSize overloads of these
    c.find('GetSize').findOverload('wxCoord').ignore()
    c.find('GetSizeMM').findOverload('wxCoord').ignore()

    # TODO: needs wxAffineMatrix2D support.
    #c.find('GetTransformMatrix').ignore()
    #c.find('SetTransformMatrix').ignore()

    # remove wxPoint* overloads, we use the wxPointList ones
    c.find('DrawLines').findOverload('wxPoint points').ignore()
    c.find('DrawPolygon').findOverload('wxPoint points').ignore()
    c.find('DrawSpline').findOverload('wxPoint points').ignore()

    # TODO: we'll need a custom method implementation for this since there
    # are multiple array parameters involved...
    c.find('DrawPolyPolygon').ignore()


    # Add output param annotations so the generated docstrings will be correct
    c.find('GetUserScale.x').out = True
    c.find('GetUserScale.y').out = True

    c.find('GetLogicalScale.x').out = True
    c.find('GetLogicalScale.y').out = True

    c.find('GetLogicalOrigin').overloads = []
    c.find('GetLogicalOrigin.x').out = True
    c.find('GetLogicalOrigin.y').out = True

    c.find('GetClippingBox.x').out = True
    c.find('GetClippingBox.y').out = True
    c.find('GetClippingBox.width').out = True
    c.find('GetClippingBox.height').out = True
    c.addPyMethod('GetClippingRect', '(self)',
        doc="Gets the rectangle surrounding the current clipping region",
        body="return wx.Rect(*self.GetClippingBox())")


    # Deal with the text-extent methods. In Classic we renamed one overloaded
    # method with a "Full" name, and the simpler one was left with the
    # original name.  I think a simpler approach here will be to remove the
    # simple version, rename the Full version as before, and then add a
    # CppMethod to reimplement the simple version.

    for name in ['GetTextExtent', 'GetMultiLineTextExtent']:
        m = c.find(name)
        # if these fail then double-check order of parsed methods, etc.
        assert len(m.overloads) == 1
        assert 'wxCoord' not in m.overloads[0].argsString
        m.overloads = []

    c.find('GetTextExtent').pyName = 'GetFullTextExtent'
    c.find('GetMultiLineTextExtent').pyName = 'GetFullMultiLineTextExtent'

    # Set output parameters
    c.find('GetTextExtent.w').out = True
    c.find('GetTextExtent.h').out = True
    c.find('GetTextExtent.descent').out = True
    c.find('GetTextExtent.externalLeading').out = True

    c.find('GetMultiLineTextExtent.w').out = True
    c.find('GetMultiLineTextExtent.h').out = True
    c.find('GetMultiLineTextExtent.heightLine').out = True


    # Update the docs to remove references to overloading, pointer values, etc.
    m = c.find('GetTextExtent')
    m.briefDoc = "Gets the dimensions of the string as it would be drawn."
    m.detailedDoc = [dedent("""\
        The ``string`` parameter is the string to measure.  The return value
        is a tuple of integer values consisting of ``widget``, ``height``,
        ``decent`` and ``externalLeading``. The ``descent`` is the dimension
        from the baseline of the font to the bottom of the descender, and
        ``externalLeading`` is any extra vertical space added to the font by the
        font designer (usually is zero).

        If the optional parameter ``font`` is specified and valid, then it is
        used for the text extent calculation. Otherwise the currently selected
        font is.

        .. seealso:: :class:`wx.Font`, :meth:`~wx.DC.SetFont`,
           :meth:`~wx.DC.GetPartialTextExtents, :meth:`~wx.DC.GetMultiLineTextExtent`
        """)]

    m = c.find('GetMultiLineTextExtent')
    m.briefDoc = "Gets the dimensions of the string as it would be drawn."
    m.detailedDoc = [dedent("""\
        The ``string`` parameter is the string to measure.  The return value
        is a tuple of integer values consisting of ``widget``, ``height`` and
        ``heightLine``.  The ``heightLine`` is the the height of a single line.

        If the optional parameter ``font`` is specified and valid, then it is
        used for the text extent calculation. Otherwise the currently selected
        font is.

        .. note:: This function works with both single-line and multi-line strings.

        .. seealso:: :class:`wx.Font`, :meth:`~wx.DC.SetFont`,
           :meth:`~wx.DC.GetPartialTextExtents, :meth:`~wx.DC.GetTextExtent`
        """)]

    # Now add the simpler versions of the extent methods
    c.addCppMethod('wxSize*', 'GetTextExtent', '(const wxString& st)', isConst=True,
        doc=dedent("""\
            Return the dimensions of the given string's text extent using the
            currently selected font.

            :param st: The string to be measured

            .. seealso:: :meth:`~wx.DC.GetFullTextExtent`
            """),
        body="""\
            return new wxSize(self->GetTextExtent(*st));
            """,
        overloadOkay=False, factory=True)

    c.addCppMethod('wxSize*', 'GetMultiLineTextExtent', '(const wxString& st)', isConst=True,
        doc=dedent("""\
            Return the dimensions of the given string's text extent using the
            currently selected font, taking into account multiple lines if
            present in the string.

            :param st: The string to be measured

            .. seealso:: :meth:`~wx.DC.GetFullMultiLineTextExtent`
            """),
        body="""\
            return new wxSize(self->GetMultiLineTextExtent(*st));
            """,
        overloadOkay=False, factory=True)




    # Add some alternate implementations for other DC methods, in order to
    # avoid using parameters as return values, etc. as well as Classic
    # compatibility.
    c.find('GetPixel').ignore()
    c.addCppMethod('wxColour*', 'GetPixel', '(wxCoord x, wxCoord y)',
        doc="Gets the colour at the specified location on the DC.",
        body="""\
            wxColour* col = new wxColour;
            self->GetPixel(x, y, col);
            return col;
            """,
        factory=True)

    # Return the rect instead of using an output parameter
    m = c.find('DrawLabel').findOverload('rectBounding')
    m.type = 'wxRect*'
    m.find('rectBounding').ignore()
    m.factory = True  # a new instance of wxRect is being created
    m.setCppCode("""\
        wxRect rv;
        self->DrawLabel(*text, *bitmap, *rect, alignment, indexAccel, &rv);
        return new wxRect(rv);
        """)
    c.addPyCode('DC.DrawImageLabel = wx.deprecated(DC.DrawLabel, "Use DrawLabel instead.")')


    # Return the array instead of using an output parameter
    m = c.find('GetPartialTextExtents')
    m.type = 'wxArrayInt*'
    m.find('widths').ignore()
    m.factory = True  # a new instance is being created
    m.setCppCode("""\
        wxArrayInt rval;
        self->GetPartialTextExtents(*text, rval);
        return new wxArrayInt(rval);
        """)


    c.addCppMethod('int', '__nonzero__', '()', "return self->IsOk();")
    c.addCppMethod('int', '__bool__', '()', "return self->IsOk();")

    c.addPyMethod('GetBoundingBox', '(self)', doc="""\
        GetBoundingBox() -> (x1,y1, x2,y2)\n
        Returns the min and max points used in drawing commands so far.""",
        body="return (self.MinX(), self.MinY(), self.MaxX(), self.MaxY())")


    m = c.find('GetHandle')
    m.type = 'wxUIntPtr*'
    m.setCppCode("return new wxUIntPtr((wxUIntPtr)self->GetHandle());")


    c.addCppMethod('long', 'GetHDC', '()', """\
        #ifdef __WXMSW__
            return (long)self->GetHandle();
        #else
            wxPyRaiseNotImplemented();
            return 0;
        #endif""")
    c.addCppMethod('wxUIntPtr*', 'GetCGContext', '()', """\
        #ifdef __WXMAC__
            return new wxUIntPtr((wxUIntPtr)self->GetHandle());
        #else
            wxPyRaiseNotImplemented();
            return NULL;
        #endif""")
    c.addCppMethod('wxUIntPtr*', 'GetGdkDrawable', '()', """\
        #ifdef __WXGTK__
            return new wxUIntPtr((wxUIntPtr)self->GetHandle());
        #else
            wxPyRaiseNotImplemented();
            return NULL;
        #endif""")

    c.addPyCode('DC.GetHDC = wx.deprecated(DC.GetHDC, "Use GetHandle instead.")')
    c.addPyCode('DC.GetCGContext = wx.deprecated(DC.GetCGContext, "Use GetHandle instead.")')
    c.addPyCode('DC.GetGdkDrawable = wx.deprecated(DC.GetGdkDrawable, "Use GetHandle instead.")')

    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'self.Destroy()')


    # This file contains implementations of functions for quickly drawing
    # lists of items on the DC. They are called from the CppMethods defined
    # below, which in turn are called from the PyMethods below that.
    c.includeCppCode('src/dc_ex.cpp')

    c.addCppMethod('PyObject*', '_DrawPointList', '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body="return wxPyDrawXXXList(*self, wxPyDrawXXXPoint, pyCoords, pyPens, pyBrushes);")

    c.addCppMethod('PyObject*', '_DrawLineList', '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body="return wxPyDrawXXXList(*self, wxPyDrawXXXLine, pyCoords, pyPens, pyBrushes);")

    c.addCppMethod('PyObject*', '_DrawRectangleList', '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body="return wxPyDrawXXXList(*self, wxPyDrawXXXRectangle, pyCoords, pyPens, pyBrushes);")

    c.addCppMethod('PyObject*', '_DrawEllipseList', '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body="return wxPyDrawXXXList(*self, wxPyDrawXXXEllipse, pyCoords, pyPens, pyBrushes);")

    c.addCppMethod('PyObject*', '_DrawPolygonList', '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body="return wxPyDrawXXXList(*self, wxPyDrawXXXPolygon, pyCoords, pyPens, pyBrushes);")

    c.addCppMethod('PyObject*', '_DrawTextList',
        '(PyObject* textList, PyObject* pyPoints, PyObject* foregroundList, PyObject* backgroundList)',
        body="return wxPyDrawTextList(*self, textList, pyPoints, foregroundList, backgroundList);")


    c.addPyMethod('DrawPointList', '(self, points, pens=None)',
        doc="""\
            Draw a list of points as quickly as possible.

            :param points: A sequence of 2-element sequences representing
                           each point to draw, (x,y).
            :param pens:   If None, then the current pen is used.  If a single
                           pen then it will be used for all points.  If a list of
                           pens then there should be one for each point in points.
            """,
        body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(points):
                raise ValueError('points and pens must have same length')
            return self._DrawPointList(points, pens, [])
            """)

    c.addPyMethod('DrawLineList', '(self, lines, pens=None)',
        doc="""\
            Draw a list of lines as quickly as possible.

            :param lines: A sequence of 4-element sequences representing
                          each line to draw, (x1,y1, x2,y2).
            :param pens:  If None, then the current pen is used.  If a
                          single pen then it will be used for all lines.  If
                          a list of pens then there should be one for each line
                          in lines.
            """,
        body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(lines):
                raise ValueError('lines and pens must have same length')
            return self._DrawLineList(lines, pens, [])
            """)

    c.addPyMethod('DrawRectangleList', '(self, rectangles, pens=None, brushes=None)',
        doc="""\
            Draw a list of rectangles as quickly as possible.

            :param rectangles: A sequence of 4-element sequences representing
                               each rectangle to draw, (x,y, w,h).
            :param pens:       If None, then the current pen is used.  If a
                               single pen then it will be used for all rectangles.
                               If a list of pens then there should be one for each
                               rectangle in rectangles.
            :param brushes:    A brush or brushes to be used to fill the rectagles,
                               with similar semantics as the pens parameter.
            """,
        body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(rectangles):
                raise ValueError('rectangles and pens must have same length')
            if brushes is None:
                brushes = []
            elif isinstance(brushes, wx.Brush):
                brushes = [brushes]
            elif len(brushes) != len(rectangles):
                raise ValueError('rectangles and brushes must have same length')
            return self._DrawRectangleList(rectangles, pens, brushes)
            """)

    c.addPyMethod('DrawEllipseList', '(self, ellipses, pens=None, brushes=None)',
        doc="""\
            Draw a list of ellipses as quickly as possible.

            :param ellipses: A sequence of 4-element sequences representing
                             each ellipse to draw, (x,y, w,h).
            :param pens:     If None, then the current pen is used.  If a
                             single pen then it will be used for all ellipses.
                             If a list of pens then there should be one for each
                             ellipse in ellipses.
            :param brushes:  A brush or brushes to be used to fill the ellipses,
                             with similar semantics as the pens parameter.
            """,
        body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(ellipses):
                raise ValueError('ellipses and pens must have same length')
            if brushes is None:
                brushes = []
            elif isinstance(brushes, wx.Brush):
                brushes = [brushes]
            elif len(brushes) != len(ellipses):
                raise ValueError('ellipses and brushes must have same length')
            return self._DrawEllipseList(ellipses, pens, brushes)
            """)

    c.addPyMethod('DrawPolygonList', '(self, polygons, pens=None, brushes=None)',
        doc="""\
            Draw a list of polygons, each of which is a list of points.

            :param polygons: A sequence of sequences of sequences.
                             [[(x1,y1),(x2,y2),(x3,y3)...], [(x1,y1),(x2,y2),(x3,y3)...]]

            :param pens:     If None, then the current pen is used.  If a
                             single pen then it will be used for all polygons.
                             If a list of pens then there should be one for each
                             polygon.
            :param brushes:  A brush or brushes to be used to fill the polygons,
                             with similar semantics as the pens parameter.
            """,
        body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(polygons):
                raise ValueError('polygons and pens must have same length')
            if brushes is None:
                brushes = []
            elif isinstance(brushes, wx.Brush):
                brushes = [brushes]
            elif len(brushes) != len(polygons):
                raise ValueError('polygons and brushes must have same length')
            return self._DrawPolygonList(polygons, pens, brushes)
            """)

    c.addPyMethod('DrawTextList', '(self, textList, coords, foregrounds=None, backgrounds=None)',
        doc="""\
            Draw a list of strings using a list of coordinants for positioning each string.

            :param textList:    A list of strings
            :param coords:      A list of (x,y) positions
            :param foregrounds: A list of `wx.Colour` objects to use for the
                                foregrounds of the strings.
            :param backgrounds: A list of `wx.Colour` objects to use for the
                                backgrounds of the strings.

            NOTE: Make sure you set background mode to wx.Solid (DC.SetBackgroundMode)
                  If you want backgrounds to do anything.
            """,
        body="""\
            if type(textList) == type(''):
                textList = [textList]
            elif len(textList) != len(coords):
                raise ValueError('textlist and coords must have same length')
            if foregrounds is None:
                foregrounds = []
            elif isinstance(foregrounds, wx.Colour):
                foregrounds = [foregrounds]
            elif len(foregrounds) != len(coords):
                raise ValueError('foregrounds and coords must have same length')
            if backgrounds is None:
                backgrounds = []
            elif isinstance(backgrounds, wx.Colour):
                backgrounds = [backgrounds]
            elif len(backgrounds) != len(coords):
                raise ValueError('backgrounds and coords must have same length')
            return  self._DrawTextList(textList, coords, foregrounds, backgrounds)
            """)




    #-----------------------------------------------------------------
    c = module.find('wxDCClipper')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'return False')


    #-----------------------------------------------------------------
    c = module.find('wxDCBrushChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'return False')


    #-----------------------------------------------------------------
    c = module.find('wxDCPenChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'return False')


    #-----------------------------------------------------------------
    c = module.find('wxDCTextColourChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'return False')


    #-----------------------------------------------------------------
    c = module.find('wxDCFontChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'return False')


    #-----------------------------------------------------------------
    c = module.find('wxDCTextBgColourChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'return False')


    #-----------------------------------------------------------------
    c = module.find('wxDCTextBgModeChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'return False')


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 23
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxMenuItem')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    tools.removeVirtuals(c)

    c.find('wxMenuItem.subMenu').transfer = True
    c.find('SetSubMenu.menu').transfer = True

    # deprecated and removed
    c.find('GetLabel').ignore()
    c.find('GetName').ignore()
    c.find('GetText').ignore()
    c.find('SetText').ignore()
    c.find('GetLabelFromText').ignore()

    # These are MSW only. Make them be empty stubs for the other ports. Several
    # have incorrect details in the interface docs, so we need to tweak their
    # return types too.
    c.find('GetBackgroundColour').type = 'wxColour*'
    c.find('GetBackgroundColour').factory = True
    c.find('GetBackgroundColour').setCppCode("""\
        #ifdef __WXMSW__
            return new wxColor(self->GetBackgroundColour());
        #else
            return new wxColour;
        #endif
        """)

    c.find('SetBackgroundColour').setCppCode("""\
        #ifdef __WXMSW__
            self->SetBackgroundColour(*colour);
        #endif
        """)

    c.find('GetFont').type = 'wxFont*'
    c.find('GetFont').factory = True
    c.find('GetFont').setCppCode("""\
        #ifdef __WXMSW__
            return new wxFont(self->GetFont());
        #else
            return new wxFont;
        #endif
        """)

    c.find('SetFont').setCppCode("""\
        #ifdef __WXMSW__
            self->SetFont(*font);
        #endif
        """)

    c.find('GetMarginWidth').setCppCode("""\
        #ifdef __WXMSW__
            return self->GetMarginWidth();
        #else
            return -1;
        #endif
        """)

    c.find('SetMarginWidth').setCppCode("""\
        #ifdef __WXMSW__
            self->SetMarginWidth(width);
        #endif
        """)

    c.find('GetTextColour').type = 'wxColour*'
    c.find('GetTextColour').factory = True
    c.find('GetTextColour').setCppCode("""\
        #ifdef __WXMSW__
            return new wxColour(self->GetTextColour());
        #else
            return new wxColour;
        #endif
        """)

    c.find('SetTextColour').setCppCode("""\
        #ifdef __WXMSW__
            self->SetTextColour(*colour);
        #endif
        """)

    c.find('GetBitmap').type = 'wxBitmap*'
    c.find('GetBitmap').factory = True
    c.find('GetBitmap').setCppCode("""\
        #ifdef __WXMSW__
            return new wxBitmap(self->GetBitmap(checked));
        #else
            return new wxBitmap(self->GetBitmap()); // no checked arg in this case
        #endif
        """)

    c.find('SetBitmap').setCppCode("""\
        #ifdef __WXMSW__
            self->SetBitmap(*bmp, checked);
        #else
            self->SetBitmap(*bmp); // no checked arg in this case
        #endif
        """)

    c.find('SetBitmaps').setCppCode("""\
        #ifdef __WXMSW__
            self->SetBitmaps(*checked, *unchecked);
        #else
            self->SetBitmap(*checked);
        #endif
        """)

    c.find('GetDisabledBitmap').type = 'wxBitmap*'
    c.find('GetDisabledBitmap').factory = True
    c.find('GetDisabledBitmap').setCppCode("""\
        #ifdef __WXMSW__
            return new wxBitmap(self->GetDisabledBitmap());
        #else
            return new wxBitmap;
        #endif
        """)

    c.find('SetDisabledBitmap').setCppCode("""\
        #ifdef __WXMSW__
            self->SetDisabledBitmap(*disabled);
        #endif
        """)

    c.addAutoProperties()
    c.addItem(etgtools.PropertyDef('Enabled', 'IsEnabled', 'Enable'))

    c.find('GetAccel').factory = True
    c.find('GetAccelFromString').ignore()  # Not implemented anywhere?

    module.addItem(
        tools.wxListWrapperTemplate('wxMenuItemList', 'wxMenuItem', module))

    # Documented wrongly in 3.1.6
    c.find('AddExtraAccel.accel').isConst = True
    c.find('AddExtraAccel.accel').type = 'wxAcceleratorEntry&'

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 24
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    module.addHeaderCode('#include <wx/gdicmn.h>')

    def markCreateFactories(klass):
        """Mark all Create methods as factories"""
        for func in klass.allItems():
            if isinstance(func, etgtools.FunctionDef) \
               and func.name.startswith('Create') \
               and '*' in func.type:
                func.factory = True

    #---------------------------------------------
    c = module.find('wxGraphicsObject')
    assert isinstance(c, etgtools.ClassDef)
    c.mustHaveApp()
    c.addCppMethod('bool', 'IsOk', '()', 'return !self->IsNull();')
    c.addCppMethod('int', '__nonzero__', '()', "return !self->IsNull();")
    c.addCppMethod('int', '__bool__', '()', "return !self->IsNull();")


    #---------------------------------------------
    c = module.find('wxGraphicsContext')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)
    c.abstract = True
    c.mustHaveApp()

    c.addCppMethod('wxGraphicsContext*', 'Create', '(wxAutoBufferedPaintDC* autoPaintDC /KeepReference/)',
        pyArgsString='(autoPaintDC) -> GraphicsContext',
        isStatic=True,
        body="""\
            return wxGraphicsContext::Create(*autoPaintDC);
            """)

    m = c.find('Create').findOverload('wxEnhMetaFileDC')
    m.find('metaFileDC').type = 'const wxMetafileDC&'
    m.argsString = '(const wxMetafileDC& metaFileDC)'
    m.setCppCode("""\
        #ifdef __WXMSW__
        #if wxUSE_ENH_METAFILE
            return wxGraphicsContext::Create(*metaFileDC);
        #endif
        #endif
            wxPyRaiseNotImplemented();
            return NULL;
        """)

    markCreateFactories(c)

    # Ensure that the target DC or image passed to Create lives as long as the
    # GC does. NOTE: Since the Creates are static methods there is no self to
    # associate the extra reference with, but since they are factories then
    # that extra reference will be held by the return value of the factory
    # instead.
    for m in c.find('Create').all():
        for p in m.items:
            if 'DC' in p.name or p.name == 'image':
                p.keepReference = True


    c.find('GetSize.width').out = True
    c.find('GetSize.height').out = True
    c.find('GetDPI.dpiX').out = True
    c.find('GetDPI.dpiY').out = True

    m = c.find('GetPartialTextExtents')
    m.find('widths').ignore()
    m.type = 'wxArrayDouble*'
    m.factory = True  # a new instance is being created
    m.setCppCode("""\
        wxArrayDouble rval;
        self->GetPartialTextExtents(*text, rval);
        return new wxArrayDouble(rval);
        """)

    m = c.find('GetTextExtent')
    m.pyName = 'GetFullTextExtent'
    m.find('width').out = True
    m.find('height').out = True
    m.find('descent').out = True
    m.find('externalLeading').out = True

    c.addCppMethod('PyObject*', 'GetTextExtent', '(const wxString& text)',
        pyArgsString="(text) -> (width, height)",
        doc="Gets the dimensions of the string using the currently selected font.",
        body="""\
        wxDouble width = 0.0, height = 0.0;
        self->GetTextExtent(*text, &width, &height, NULL, NULL);
        wxPyThreadBlocker blocker;
        return sipBuildResult(0, "(dd)", width, height);
        """)

    c.addPyCode("GraphicsContext.DrawRotatedText = wx.deprecated(GraphicsContext.DrawText, 'Use DrawText instead.')")


    c.addCppCode(tools.ObjArrayHelperTemplate('wxPoint2D', 'sipType_wxPoint2DDouble',
                    "Expected a sequence of length-2 sequences or wx.Point2D objects."))

    # we'll reimplement this overload as StrokeLineSegments
    c.find('StrokeLines').findOverload('beginPoints').ignore()
    c.addCppMethod('void', 'StrokeLineSegments', '(PyObject* beginPoints, PyObject* endPoints)',
        pyArgsString="(beginPoint2Ds, endPoint2Ds)",
        doc="Stroke disconnected lines from begin to end points.",
        body="""\
        size_t c1, c2, count;
        wxPoint2D* beginP = wxPoint2D_array_helper(beginPoints, &c1);
        wxPoint2D* endP =   wxPoint2D_array_helper(endPoints, &c2);

        if ( beginP != NULL && endP != NULL ) {
            count = wxMin(c1, c2);
            self->StrokeLines(count, beginP, endP);
        }
        delete [] beginP;
        delete [] endP;
        """)

    # Also reimplement the main StrokeLines method to reuse the same helper
    # function as StrokeLineSegments
    m = c.find('StrokeLines').findOverload('points').ignore()
    c.addCppMethod('void', 'StrokeLines', '(PyObject* points)',
        pyArgsString="(point2Ds)",
        doc="Stroke lines conencting all the points.",
        body="""\
        size_t count;
        wxPoint2D* ptsArray = wxPoint2D_array_helper(points, &count);

        if ( ptsArray != NULL ) {
            self->StrokeLines(count, ptsArray);
            delete [] ptsArray;
        }
        """)

    # and once more for DrawLines
    m = c.find('DrawLines').ignore()
    c.addCppMethod('void', 'DrawLines', '(PyObject* points, wxPolygonFillMode fillStyle = wxODDEVEN_RULE)',
        pyArgsString="(point2Ds, fillStyle=ODDEVEN_RULE)",
        doc="Draws a polygon.",
        body="""\
        size_t count;
        wxPoint2D* ptsArray = wxPoint2D_array_helper(points, &count);

        if ( ptsArray != NULL ) {
            self->DrawLines(count, ptsArray, fillStyle);
            delete [] ptsArray;
        }
        """)

    # TODO: support this?
    c.find('CreateFromNativeHDC').ignore()

    #---------------------------------------------
    c = module.find('wxGraphicsPath')
    tools.removeVirtuals(c)
    c.find('GetBox').findOverload('wxDouble *x, wxDouble *y').ignore()
    c.find('GetCurrentPoint').findOverload('wxDouble *x, wxDouble *y').ignore()
    c.mustHaveApp()


    #---------------------------------------------
    c = module.find('wxGraphicsRenderer')
    tools.removeVirtuals(c)
    markCreateFactories(c)
    c.abstract = True

    for m in c.find('CreateContext').all():
        for p in m.items:
            if 'DC' in p.name or p.name == 'image':
                p.keepReference = True
    c.find('CreateContextFromImage.image').keepReference = True

    # TODO: support this?
    c.find('CreateContext').findOverload('wxEnhMetaFileDC').ignore()

    # TODO: support this?
    c.find('CreateContextFromNativeHDC').ignore()


    c.find('GetGDIPlusRenderer').ignore()
    c.addCppMethod('wxGraphicsRenderer*', 'GetGDIPlusRenderer', '()', isStatic=True,
        doc="Returns GDI+ renderer (MSW only).",
        body="""\
            #ifdef __WXMSW__
                return wxGraphicsRenderer::GetGDIPlusRenderer();
            #else
                return NULL;
            #endif
            """)

    c.find('GetDirect2DRenderer').ignore()
    c.addCppMethod('wxGraphicsRenderer*', 'GetDirect2DRenderer', '()', isStatic=True,
        doc="Returns Direct2D renderer (MSW and Python3 only).",
        body="""\
            #if wxUSE_GRAPHICS_DIRECT2D
                return wxGraphicsRenderer::GetDirect2DRenderer();
            #else
                return NULL;
            #endif
            """)

    #---------------------------------------------
    c = module.find('wxGraphicsMatrix')
    tools.removeVirtuals(c)
    c.mustHaveApp()

    c.find('Concat').overloads = []
    c.find('IsEqual').overloads = []

    c.find('Get.a').out = True
    c.find('Get.b').out = True
    c.find('Get.c').out = True
    c.find('Get.d').out = True
    c.find('Get.tx').out = True
    c.find('Get.ty').out = True

    c.find('TransformDistance.dx').inOut = True
    c.find('TransformDistance.dy').inOut = True

    c.find('TransformPoint.x').inOut = True
    c.find('TransformPoint.y').inOut = True


    #---------------------------------------------
    c = module.find('wxGraphicsGradientStops')
    c.addCppMethod('SIP_SSIZE_T', '__len__', '()', body="return (SIP_SSIZE_T)self->GetCount();")
    c.addCppMethod('wxGraphicsGradientStop*', '__getitem__', '(ulong n)',
                   pyArgsString='(n)',
                   body="return new wxGraphicsGradientStop(self->Item(n));",
                   factory=True)


    #---------------------------------------------
    c = module.find('wxGraphicsPenInfo')
    # Ignore Dashes for now
    # TODO: we need to do something like wx.Pen.SetDashes, but since
    # GraphicsPenInfo is transitory we can't save the reference in it to the
    # holder, and the pen will not have been created yet...
    c.find('Dashes').ignore()


    #---------------------------------------------
    # Use the pyNames we set for these classes in geometry.py so the old
    # names do not show up in the docstrings, etc.
    tools.changeTypeNames(module, 'wxPoint2DDouble', 'wxPoint2D')
    tools.changeTypeNames(module, 'wxRect2DDouble', 'wxRect2D')


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 25
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    module.addCppCode("""
    #if !wxUSE_HOTKEY
    #define wxEVT_HOTKEY 0
    #endif
    """)

    # C macros that need to be ignored
    module.find('wx__DECLARE_EVT0').ignore()
    module.find('wx__DECLARE_EVT1').ignore()
    module.find('wx__DECLARE_EVT2').ignore()
    module.find('wxEVENT_HANDLER_CAST').ignore()
    module.find('wxDECLARE_EXPORTED_EVENT').ignore()
    module.find('wxDECLARE_EVENT').ignore()
    module.find('wxDEFINE_EVENT').ignore()


    module.addPyClass('PyEventBinder', ['object'],
        doc="""\
            Instances of this class are used to bind specific events to event handlers.
            """,
        items=[
            PyFunctionDef('__init__', '(self, evtType, expectedIDs=0)',
                body="""\
                    if expectedIDs not in [0, 1, 2]:
                        raise ValueError("Invalid number of expectedIDs")
                    self.expectedIDs = expectedIDs

                    if isinstance(evtType, (list, tuple)):
                        self.evtType = list(evtType)
                    else:
                        self.evtType = [evtType]
                    """),

            PyFunctionDef('Bind', '(self, target, id1, id2, function)',
                doc="""Bind this set of event types to target using its Connect() method.""",
                body="""\
                    for et in self.evtType:
                        target.Connect(id1, id2, et, function)
                    """),

            PyFunctionDef('Unbind', '(self, target, id1, id2, handler=None)',
                doc="""Remove an event binding.""",
                body="""\
                    success = 0
                    for et in self.evtType:
                        success += int(target.Disconnect(id1, id2, et, handler))
                    return success != 0
                    """),

            PyFunctionDef('_getEvtType', '(self)',
                doc="""\
                    Make it easy to get to the default wxEventType typeID for this
                    event binder.
                    """,
                body="""return self.evtType[0]"""),

            PyPropertyDef('typeId', '_getEvtType'),

            PyFunctionDef('__call__', '(self, *args)',
                deprecated="Use :meth:`EvtHandler.Bind` instead.",
                doc="""\
                    For backwards compatibility with the old ``EVT_*`` functions.
                    Should be called with either (window, func), (window, ID,
                    func) or (window, ID1, ID2, func) parameters depending on the
                    type of the event.
                    """,
                body="""\
                    assert len(args) == 2 + self.expectedIDs
                    id1 = ID_ANY
                    id2 = ID_ANY
                    target = args[0]
                    if self.expectedIDs == 0:
                        func = args[1]
                    elif self.expectedIDs == 1:
                        id1 = args[1]
                        func = args[2]
                    elif self.expectedIDs == 2:
                        id1 = args[1]
                        id2 = args[2]
                        func = args[3]
                    else:
                        raise ValueError("Unexpected number of IDs")

                    self.Bind(target, id1, id2, func)
                    """)
            ])


    module.includePyCode('src/event_ex.py')

    #---------------------------------------
    # wxEvtHandler
    c = module.find('wxEvtHandler')
    c.addPrivateCopyCtor()
    c.addPublic()

    c.includeCppCode('src/event_ex.cpp')

    # Ignore the Connect/Disconnect and Bind/Unbind methods (and all overloads) for now.
    for item in c.allItems():
        if item.name in ['Connect', 'Disconnect', 'Bind', 'Unbind']:
            item.ignore()


    # Connect and Disconnect methods for wxPython. Hold a reference to the
    # event handler function in the event table, so we can fetch it later when
    # it is time to handle the event.
    c.addCppMethod(
        'void', 'Connect', '(int id, int lastId, wxEventType eventType, PyObject* func)',
        doc="Make an entry in the dynamic event table for an event binding.",
        body="""\
            if (PyCallable_Check(func)) {
                self->Connect(id, lastId, eventType,
                              (wxObjectEventFunction)&wxPyCallback::EventThunker,
                              new wxPyCallback(func));
            }
            else if (func == Py_None) {
                self->Disconnect(id, lastId, eventType,
                                 (wxObjectEventFunction)(wxEventFunction)
                                 &wxPyCallback::EventThunker);
            }
            else {
                PyErr_SetString(PyExc_TypeError, "Expected callable object or None.");
            }
        """)


    c.addCppMethod(
        'bool', 'Disconnect', '(int id, int lastId=-1, '
                               'wxEventType eventType=wxEVT_NULL, '
                               'PyObject* func=NULL)',
        doc="Remove an event binding by removing its entry in the dynamic event table.",
        body="""\
            if (func && func != Py_None) {
                // Find the current matching binder that has this function
                // pointer and disconnect that one.  Unfortunately since we
                // wrapped the PyObject function pointer in another object we
                // have to do the searching ourselves...
                size_t cookie;
                wxDynamicEventTableEntry *entry = self->GetFirstDynamicEntry(cookie);
                while (entry)
                {
                    if ((entry->m_id == id) &&
                        ((entry->m_lastId == lastId) || (lastId == wxID_ANY)) &&
                        ((entry->m_eventType == eventType) || (eventType == wxEVT_NULL)) &&
                        entry->m_fn->IsMatching(wxObjectEventFunctor((wxObjectEventFunction)&wxPyCallback::EventThunker, NULL)) &&
                        (entry->m_callbackUserData != NULL))
                    {
                        wxPyThreadBlocker block;
                        wxPyCallback *cb = (wxPyCallback*)entry->m_callbackUserData;
                        // NOTE: Just comparing PyObject pointers is not enough, as bound
                        // methods can result in different PyObjects each time obj.Method
                        // is evaluated. (!!!)
                        if (PyObject_RichCompareBool(cb->m_func, func, Py_EQ) == 1) {
                            delete cb;
                            entry->m_callbackUserData = NULL;
                            // Now Disconnect should work
                            return self->Disconnect(id, lastId, eventType,
                                                    (wxObjectEventFunction)&wxPyCallback::EventThunker);
                        }
                    }
                    entry = self->GetNextDynamicEntry(cookie);
                }
                return false;
            }
            else {
                return self->Disconnect(id, lastId, eventType,
                                        (wxObjectEventFunction)&wxPyCallback::EventThunker);
            }
        """)


    # Ignore the C++ version of CallAfter. We have our own.
    # TODO: If we want to support this we'll need concrete implementations of
    # the template, probably using PyObject* args.
    for m in c.find('CallAfter').all():
        m.ignore()

    c.find('QueueEvent.event').transfer = True
    module.find('wxQueueEvent.event').transfer = True

    # TODO: If we don't need to use the wxEvtHandler's client data for our own
    # tracking then enable these....
    c.find('GetClientObject').ignore()
    c.find('SetClientObject').ignore()
    c.find('GetClientData').ignore()
    c.find('SetClientData').ignore()

    # We only care about overriding a few virtuals, ignore the rest.
    tools.removeVirtuals(c)
    c.find('ProcessEvent').isVirtual = True
    c.find('TryBefore').isVirtual = True
    c.find('TryAfter').isVirtual = True
    c.find('TryBefore').ignore(False)
    c.find('TryAfter').ignore(False)


    # Release the GIL for potentially blocking or long-running functions
    c.find('ProcessEvent').releaseGIL()
    c.find('ProcessEventLocally').releaseGIL()
    c.find('SafelyProcessEvent').releaseGIL()
    c.find('ProcessPendingEvents').releaseGIL()


    c.addPyMethod('Bind', '(self, event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY)',
        doc="""\
            Bind an event to an event handler.

            :param event: One of the ``EVT_*`` event binder objects that
                          specifies the type of event to bind.

            :param handler: A callable object to be invoked when the
                            event is delivered to self.  Pass ``None`` to
                            disconnect an event handler.

            :param source: Sometimes the event originates from a
                           different window than self, but you still
                           want to catch it in self.  (For example, a
                           button event delivered to a frame.)  By
                           passing the source of the event, the event
                           handling system is able to differentiate
                           between the same event type from different
                           controls.

            :param id: Used to spcify the event source by ID instead
                       of instance.

            :param id2: Used when it is desirable to bind a handler
                        to a range of IDs, such as with EVT_MENU_RANGE.
            """,
        body="""\
            assert isinstance(event, wx.PyEventBinder)
            assert callable(handler) or handler is None
            assert source is None or hasattr(source, 'GetId')
            if source is not None:
                id  = source.GetId()
            event.Bind(self, id, id2, handler)
            """)


    c.addPyMethod('Unbind', '(self, event, source=None, id=wx.ID_ANY, id2=wx.ID_ANY, handler=None)',
        doc="""\
            Disconnects the event handler binding for event from `self`.
            Returns ``True`` if successful.
            """,
        body="""\
            if source is not None:
                id  = source.GetId()
            return event.Unbind(self, id, id2, handler)
            """)

    module.addPyCode('PyEvtHandler = wx.deprecated(EvtHandler, "Use :class:`EvtHandler` instead.")')


    #---------------------------------------
    # wxEvent
    c = module.find('wxEvent')
    assert isinstance(c, etgtools.ClassDef)
    c.abstract = True
    c.find('Clone').factory = True

    c.addProperty('EventObject GetEventObject SetEventObject')
    c.addProperty('EventType GetEventType SetEventType')
    c.addProperty('Id GetId SetId')
    c.addProperty('Skipped GetSkipped')
    c.addProperty('Timestamp GetTimestamp SetTimestamp')


    #---------------------------------------
    # wxCommandEvent
    c = module.find('wxCommandEvent')

    # The [G|S]etClientData methods deal with untyped void* values, which we
    # don't support. The [G|S]etClientObject methods use wxClientData instances
    # which we have a MappedType for, so make the ClientData methods just be
    # aliases for ClientObjects. From the Python programmer's perspective they
    # would be virtually the same anyway.
    c.find('SetClientObject.clientObject').transfer = True
    c.find('SetClientObject.clientObject').name = 'data'
    c.find('GetClientData').ignore()
    c.find('SetClientData').ignore()
    c.find('GetClientObject').pyName = 'GetClientData'
    c.find('SetClientObject').pyName = 'SetClientData'
    c.addPyMethod('GetClientObject', '(self)',
        doc="Alias for :meth:`GetClientData`",
        body="return self.GetClientData()")
    c.addPyMethod('SetClientObject', '(self, data)',
        doc="Alias for :meth:`SetClientData`",
        body="self.SetClientData(data)")
    c.addPyProperty('ClientData GetClientData SetClientData')

    c.addProperty('ExtraLong GetExtraLong SetExtraLong')
    c.addProperty('Int GetInt SetInt')
    c.addProperty('Selection GetSelection')
    c.addProperty('String GetString SetString')


    #---------------------------------------
    # wxKeyEvent
    c = module.find('wxKeyEvent')

    c.find('GetPosition').findOverload('wxCoord').ignore()
    c.find('GetUnicodeKey').type = 'int'

    c.addProperty('X GetX')
    c.addProperty('Y GetY')
    c.addProperty('KeyCode GetKeyCode')
    c.addProperty('Position GetPosition')
    c.addProperty('RawKeyCode GetRawKeyCode')
    c.addProperty('RawKeyFlags GetRawKeyFlags')
    c.addProperty('UnicodeKey GetUnicodeKey')

    #---------------------------------------
    # wxScrollEvent
    c = module.find('wxScrollEvent')
    c.addProperty('Orientation GetOrientation SetOrientation')
    c.addProperty('Position GetPosition SetPosition')

    #---------------------------------------
    # wxScrollWinEvent
    c = module.find('wxScrollWinEvent')
    c.addProperty('Orientation GetOrientation SetOrientation')
    c.addProperty('Position GetPosition SetPosition')

    #---------------------------------------
    # wxMouseEvent
    c = module.find('wxMouseEvent')
    c.addProperty('LinesPerAction GetLinesPerAction')
    c.addProperty('LogicalPosition GetLogicalPosition')
    c.addProperty('WheelDelta GetWheelDelta')
    c.addProperty('WheelRotation GetWheelRotation')

    #---------------------------------------
    # wxSetCursorEvent
    c = module.find('wxSetCursorEvent')
    c.addProperty('Cursor GetCursor SetCursor')
    c.addProperty('X GetX')
    c.addProperty('Y GetY')

    #---------------------------------------
    # wxSizeEvent
    c = module.find('wxSizeEvent')
    c.addProperty('Rect GetRect SetRect')
    c.addProperty('Size GetSize SetSize')

    #---------------------------------------
    # wxMoveEvent
    c = module.find('wxMoveEvent')
    c.addProperty('Rect GetRect SetRect')
    c.addProperty('Position GetPosition SetPosition')

    #---------------------------------------
    # wxEraseEvent
    c = module.find('wxEraseEvent')
    c.addProperty('DC GetDC')

    #---------------------------------------
    # wxFocusEvent
    c = module.find('wxFocusEvent')
    c.addProperty('Window GetWindow SetWindow')

    #---------------------------------------
    # wxChildFocusEvent
    c = module.find('wxChildFocusEvent')
    c.addProperty('Window GetWindow')


    #---------------------------------------
    # wxActivateEvent
    c = module.find('wxActivateEvent')
    c.addProperty('Active GetActive')

    #---------------------------------------
    # wxMenuEvent
    c = module.find('wxMenuEvent')
    c.addProperty('Menu GetMenu')
    c.addProperty('MenuId GetMenuId')

    #---------------------------------------
    # wxShowEvent
    c = module.find('wxShowEvent')
    c.find('GetShow').ignore()  # deprecated
    c.addProperty('Show IsShown SetShow')

    #---------------------------------------
    # wxDropFilesEvent
    c = module.find('wxDropFilesEvent')

    # wxDropFilesEvent assumes that the C array of wxString objects will
    # continue to live as long as the event object does, and does not take
    # ownership of the array. Unfortunately the mechanism used to turn the
    # Python list into a C array will also delete it after the API call, and
    # so when wxDropFilesEvent tries to access it later the memory pointer is
    # bad. So we'll copy that array into a special holder class and give that
    # one to the API, and also assign a Python reference to it to the event
    # object, so it will get garbage collected later.
    c.find('wxDropFilesEvent.files').array = True
    c.find('wxDropFilesEvent.files').transfer = True
    c.find('wxDropFilesEvent.noFiles').arraySize = True
    c.addHeaderCode('#include "arrayholder.h"')
    c.find('wxDropFilesEvent').setCppCode_sip("""\
        if (files) {
            wxStringCArrayHolder* holder = new wxStringCArrayHolder;
            holder->m_array = files;
            // Make a PyObject for the holder, and transfer its ownership to self.
            PyObject* pyHolder = sipConvertFromNewType(
                    (void*)holder, sipType_wxStringCArrayHolder, (PyObject*)sipSelf);
            Py_DECREF(pyHolder);
            sipCpp = new sipwxDropFilesEvent(id,(int)noFiles, holder->m_array);
        }
        else
            sipCpp = new sipwxDropFilesEvent(id);
        """)



    c.find('GetFiles').type = 'PyObject*'
    c.find('GetFiles').setCppCode("""\
        int         count   = self->GetNumberOfFiles();
        wxString*   files   = self->GetFiles();
        wxPyThreadBlocker   blocker;
        PyObject*   list    = PyList_New(count);
        if (!list) {
            PyErr_SetString(PyExc_MemoryError, "Can't allocate list of files!");
            return NULL;
        }
        for (int i=0; i<count; i++) {
            PyObject* s = wx2PyString(files[i]);
            PyList_SET_ITEM(list, i, s);
        }
        return list;
        """)

    c.addProperty('Files GetFiles')
    c.addProperty('NumberOfFiles GetNumberOfFiles')
    c.addProperty('Position GetPosition')

    #---------------------------------------
    # wxUpdateUIEvent
    c = module.find('wxUpdateUIEvent')
    c.addProperty('Checked GetChecked Check')
    c.addProperty('Enabled GetEnabled Enable')
    c.addProperty('Shown GetShown Show')
    c.addProperty('Text GetText SetText')

    #---------------------------------------
    # wxMouseCaptureChangedEvent
    c = module.find('wxMouseCaptureChangedEvent')
    c.addProperty('CapturedWindow GetCapturedWindow')

    #---------------------------------------
    # wxPaletteChangedEvent
    c = module.find('wxPaletteChangedEvent')
    c.addProperty('ChangedWindow GetChangedWindow SetChangedWindow')

    #---------------------------------------
    # wxQueryNewPaletteEvent
    c = module.find('wxQueryNewPaletteEvent')
    c.addProperty('PaletteRealized GetPaletteRealized SetPaletteRealized')

    #---------------------------------------
    # wxNavigationKeyEvent
    c = module.find('wxNavigationKeyEvent')
    c.addProperty('CurrentFocus GetCurrentFocus SetCurrentFocus')
    c.addProperty('Direction GetDirection SetDirection')

    #---------------------------------------
    # wxWindowCreateEvent
    c = module.find('wxWindowCreateEvent')
    c.addProperty('Window GetWindow')

    #---------------------------------------
    # wxWindowDestroyEvent
    c = module.find('wxWindowDestroyEvent')
    c.addProperty('Window GetWindow')

    #---------------------------------------
    # wxContextMenuEvent
    c = module.find('wxContextMenuEvent')
    c.addProperty('Position GetPosition SetPosition')


    #---------------------------------------
    # wxIconizeEvent
    c = module.find('wxIconizeEvent')

    # deprecated and removed
    c.find('Iconized').ignore()



    # Apply common fixups for all the event classes
    for name in [n for n in ITEMS if n.endswith('Event')]:
        c = module.find(name)
        tools.fixEventClass(c)

    #---------------------------------------
    # wxEventBlocker
    c = module.find('wxEventBlocker')
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'return False')

    #---------------------------------------
    # wxPropagationDisabler
    c = module.find('wxPropagationDisabler')
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'return False')
    c.addPrivateCopyCtor()

    #---------------------------------------
    # wxPropagateOnce
    c = module.find('wxPropagateOnce')
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)', 'return False')
    c.addPrivateCopyCtor()

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 26
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    def addTransferAnnotations(c, arg):
        for method in c.findAll('Append') + c.findAll('Insert') + \
                      c.findAll('Replace') + c.findAll('Prepend'):
            arg_def = method.findItem(arg)
            if arg_def:
                arg_def.transfer = True

        for method in c.findAll('Remove') + c.findAll('Replace'):
            method.transferBack = True


    #-----------------------------------------------------------------
    c = module.find('wxMenu')
    assert isinstance(c, etgtools.ClassDef)
    c.mustHaveApp()
    tools.removeVirtuals(c)
    c.find('Prepend.item').name = 'menuItem'
    c.find('Prepend.submenu').name = 'subMenu'

    addTransferAnnotations(c, 'menuItem')
    addTransferAnnotations(c, 'subMenu')
    c.find('AppendSubMenu.submenu').transfer = True

    # We only need one of these overloads, the non-const/const is not enough
    # to distinguish a unique Python signature.
    c.find('GetMenuItems').overloads = []

    # Ensure that no copy is made of the list object, so we only wrap the
    # existing object and keep it owned by C++
    c.find('GetMenuItems').noCopy = True


    c.addPyMethod('AppendMenu', '(self, id, item, subMenu, help="")', deprecated='Use Append instead.',
                  body='return self.Append(id, item, subMenu, help)')
    c.addPyMethod('AppendItem', '(self, menuItem)', deprecated='Use Append instead.',
                  body='return self.Append(menuItem)')

    c.addPyMethod('InsertMenu', '(self, pos, id, item, subMenu, help="")', deprecated='Use Insert instead.',
                  body='return self.Insert(pos, id, item, subMenu, help)')
    c.addPyMethod('InsertItem', '(self, pos, menuItem)', deprecated='Use Insert instead.',
                  body='return self.Insert(pos, menuItem)')

    c.addPyMethod('PrependMenu', '(self, id, item, subMenu, help="")', deprecated='Use Prepend instead.',
                  body='return self.Prepend(id, item, subMenu, help)')
    c.addPyMethod('PrependItem', '(self, menuItem)', deprecated='Use Prepend instead.',
                  body='return self.Prepend(menuItem)')

    c.addPyMethod('RemoveMenu', '(self, id, item, subMenu, help="")', deprecated='Use Remove instead.',
                  body='return self.Remove(id, item, subMenu, help)')
    c.addPyMethod('RemoveItem', '(self, menuItem)', deprecated='Use Remove instead.',
                  body='return self.Remove(menuItem)')

    # Don't hide the Destroy inherited from wxObject
    c.find('Destroy').findOverload('int').pyName = 'DestroyItem'
    c.find('Destroy').findOverload('wxMenuItem').pyName = 'DestroyItem'

    c.find('FindChildItem.pos').out = True
    c.find('FindItem.menu').out = True
    c.addCppMethod('wxMenuItem*', 'FindItemById', '(int id)', isConst=True,
        doc="""\
            FindItemById(id) -> MenuItem

            Finds the menu item object associated with the given menu item identifier.""",
        body="""\
            return self->FindItem(id);""")


    #-----------------------------------------------------------------
    c = module.find('wxMenuBar')
    assert isinstance(c, etgtools.ClassDef)
    c.mustHaveApp()
    tools.removeVirtuals(c)
    addTransferAnnotations(c, 'menu')
    c.find('wxMenuBar').findOverload('wxMenu *menus[], const wxString titles[], long style=0)').ignore()

    c.find('FindItem.menu').out = True
    c.addCppMethod('wxMenuItem*', 'FindItemById', '(int id)', isConst=True,
        doc="""\
            FindItemById(id) -> MenuItem

            Finds the menu item object associated with the given menu item identifier.""",
        body="""\
            return self->FindItem(id);""")


    mac_scmb = c.find('MacSetCommonMenuBar')
    mac_scmb.setCppCode("""\
    #ifdef __WXMAC__
        wxMenuBar::MacSetCommonMenuBar(menubar);
    #endif
    """)

    mac_gcmb = c.find('MacGetCommonMenuBar')
    mac_gcmb.setCppCode("""\
    #ifdef __WXMAC__
        return wxMenuBar::MacGetCommonMenuBar();
    #else
        return NULL;
    #endif
    """)

    mac_gcmb = c.find('OSXGetAppleMenu')
    mac_gcmb.setCppCode("""\
    #ifdef __WXMAC__
        return self->OSXGetAppleMenu();
    #else
        return NULL;
    #endif
    """)

    # don't transfer on other platforms, as this is a no-op there.
    import sys
    if sys.platform.startswith('darwin'):
        mac_scmb.find('menubar').transfer = True

    c.find('FindItem.menu').out = True


    c.addPyMethod('GetMenus', '(self)',
        doc="""\
        GetMenus() -> (menu, label)\n
        Return a list of (menu, label) items for the menus in the :class:`MenuBar`.""",
        body="""\
        return [(self.GetMenu(i), self.GetLabelTop(i)) for i in range(self.GetMenuCount())]
        """)
    c.addPyMethod('SetMenus', '(self, items)',
        doc="""\
        SetMenus()\n
        Clear and add new menus to the :class:`MenuBar` from a list of (menu, label) items.""",
        body="""\
        for i in range(self.GetMenuCount()-1, -1, -1):
            self.Remove(i)
        for m, l in items:
            self.Append(m, l)
        """)
    c.addPyProperty('Menus GetMenus SetMenus')


    module.addItem(tools.wxListWrapperTemplate('wxMenuList', 'wxMenu', module))

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 27
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.


    c = module.find('wxBrush')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    # Set mustHaveApp on all ctors except the default ctor
    for ctor in c.find('wxBrush').all():
        if ctor.isCtor and ctor.argsString != '()':
            ctor.mustHaveApp()

    c.addCppMethod('int', '__nonzero__', '()', """\
        return self->IsOk();
        """)


    c.addCppCode("""\
        #ifdef __WXMAC__
        #include <wx/osx/private.h>
        #endif
        """)
    c.addCppMethod('void', 'MacSetTheme', '(int macThemeBrushID)', """\
        #ifdef __WXMAC__
            self->SetColour(wxColour(wxMacCreateCGColorFromHITheme(macThemeBrushID)));
        #else
            wxPyRaiseNotImplemented();
        #endif
        """)


    c.addAutoProperties()


    # The stock Brush items are documented as simple pointers, but in reality
    # they are macros that evaluate to a function call that returns a brush
    # pointer, and that is only valid *after* the wx.App object has been
    # created. That messes up the code that SIP generates for them, so we need
    # to come up with another solution. So instead we will just create
    # uninitialized brush in a block of Python code, that will then be
    # intialized later when the wx.App is created.
    c.addCppMethod('void', '_copyFrom', '(const wxBrush* other)',
                   "*self = *other;",
                   briefDoc="For internal use only.")  # ??
    pycode = '# These stock brushes will be initialized when the wx.App object is created.\n'
    for item in module:
        if '_BRUSH' in item.name:
            item.ignore()
            pycode += '%s = Brush()\n' % tools.removeWxPrefix(item.name)
    module.addPyCode(pycode)


    # it is delay-initialized, see stockgdi.sip
    module.find('wxTheBrushList').ignore()


    # Some aliases that should be phased out eventually, (sooner rather than
    # later.) They are already gone (or wrapped by an #if) in the C++ code,
    # and so are not found in the documentation...
    module.addPyCode("""\
        wx.STIPPLE_MASK_OPAQUE = int(wx.BRUSHSTYLE_STIPPLE_MASK_OPAQUE)
        wx.STIPPLE_MASK        = int(wx.BRUSHSTYLE_STIPPLE_MASK)
        wx.STIPPLE             = int(wx.BRUSHSTYLE_STIPPLE)
        wx.BDIAGONAL_HATCH     = int(wx.BRUSHSTYLE_BDIAGONAL_HATCH)
        wx.CROSSDIAG_HATCH     = int(wx.BRUSHSTYLE_CROSSDIAG_HATCH)
        wx.FDIAGONAL_HATCH     = int(wx.BRUSHSTYLE_FDIAGONAL_HATCH)
        wx.CROSS_HATCH         = int(wx.BRUSHSTYLE_CROSS_HATCH)
        wx.HORIZONTAL_HATCH    = int(wx.BRUSHSTYLE_HORIZONTAL_HATCH)
        wx.VERTICAL_HATCH      = int(wx.BRUSHSTYLE_VERTICAL_HATCH)
        """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 28
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)

    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxPageSetupDialogData')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    c.find('GetPrintData').overloads = []

    c.addCppMethod('int', '__nonzero__', '()', "return self->IsOk();")
    c.addCppMethod('int', '__bool__', '()', "return self->IsOk();")

    c.addProperty('MarginBottomRight', 'GetMarginBottomRight', 'SetMarginBottomRight')
    c.addProperty('MarginTopLeft', 'GetMarginTopLeft', 'SetMarginTopLeft')
    c.addProperty('MinMarginBottomRight', 'GetMinMarginBottomRight', 'SetMinMarginBottomRight')
    c.addProperty('MinMarginTopLeft', 'GetMinMarginTopLeft', 'SetMinMarginTopLeft')
    c.addProperty('PaperId', 'GetPaperId', 'SetPaperId')
    c.addProperty('PaperSize', 'GetPaperSize', 'SetPaperSize')
    c.addProperty('PrintData', 'GetPrintData', 'SetPrintData')



    c = module.find('wxPrintData')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    c.addCppMethod('wxSize*', 'GetPaperSize', '()', 'return new wxSize(self->GetPaperSize());')
    c.addCppMethod('void', 'SetPaperSize', '(const wxSize* sz)', 'self->SetPaperSize(*sz);')

    c.addCppMethod('int', '__nonzero__', '()', "return self->IsOk();")
    c.addCppMethod('int', '__bool__', '()', "return self->IsOk();")

    # TODO: These two methods should use something other than a PyString for
    # holding the data...
    c.addCppMethod('PyObject*', 'GetPrivData', '()', """\
        PyObject* data;
        wxPyThreadBlocker blocker;
        data = PyBytes_FromStringAndSize(self->GetPrivData(),
                                         self->GetPrivDataLen());
        return data;
        """)

    c.addCppMethod('void', 'SetPrivData', '(PyObject* data)', """\
        wxPyThreadBlocker blocker;
        if (! PyBytes_Check(data)) {
            wxPyErr_SetString(PyExc_TypeError, "Expected string object");
            return;
        }

        self->SetPrivData(PyBytes_AS_STRING(data), PyBytes_GET_SIZE(data));
        """)

    c.addAutoProperties()



    c = module.find('wxPrintDialogData')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)
    c.find('SetSetupDialog').ignore()

    c.addCppMethod('int', '__nonzero__', '()', "return self->IsOk();")
    c.addCppMethod('int', '__bool__', '()', "return self->IsOk();")

    c.addAutoProperties()


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 29
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxPen')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    # The stipple bitmap ctor is not implemented on wxGTK
    c.find('wxPen').findOverload('wxBitmap').ignore()

    m = c.find('GetDashes')
    assert isinstance(m, etgtools.MethodDef)
    m.find('dashes').ignore()
    m.type = 'wxArrayInt*'
    m.factory = True
    m.setCppCode("""\
        wxArrayInt* arr = new wxArrayInt;
        wxDash* dashes;
        int num = self->GetDashes(&dashes);
        for (int i=0; i<num; i++)
            arr->Add(dashes[i]);
        return arr;
        """)

    # SetDashes does not take ownership of the array passed to it, yet that
    # array must be kept alive as long as the pen lives, so we'll create an
    # array holder object that will be associated with the pen, and that will
    # delete the dashes array when it is deleted.
    #c.find('SetDashes').ignore()
    c.addHeaderCode('#include "arrayholder.h"')
    m = c.find('SetDashes')
    # ignore the existing parameters
    m.find('n').ignore()
    m.find('dash').ignore()
    # add a new one
    m.items.append(etgtools.ParamDef(type='const wxArrayInt&', name='dashes'))
    m.setCppCode_sip("""\
        size_t len = dashes->GetCount();
        wxDashCArrayHolder* holder = new wxDashCArrayHolder;
        holder->m_array = new wxDash[len];
        for (int idx=0; idx<len; idx+=1) {
            holder->m_array[idx] = (*dashes)[idx];
        }
        // Make a PyObject for the holder, and transfer its ownership to self.
        PyObject* pyHolder = sipConvertFromNewType(
                (void*)holder, sipType_wxDashCArrayHolder, (PyObject*)sipSelf);
        Py_DECREF(pyHolder);
        sipCpp->SetDashes(len, holder->m_array);
        """)

    c.addAutoProperties()

    # The stock Pen items are documented as simple pointers, but in reality
    # they are macros that evaluate to a function call that returns a pen
    # pointer, and that is only valid *after* the wx.App object has been
    # created. That messes up the code that SIP generates for them, so we need
    # to come up with another solution. So instead we will just create
    # uninitialized pens in a block of Python code, that will then be
    # intialized later when the wx.App is created.
    c.addCppMethod('void',
                   '_copyFrom',
                   '(const wxPen* other)',
                   "*self = *other;",
                   briefDoc="For internal use only.")  # ??
    pycode = '# These stock pens will be initialized when the wx.App object is created.\n'
    for item in module:
        if '_PEN' in item.name:
            item.ignore()
            pycode += '%s = Pen()\n' % tools.removeWxPrefix(item.name)
    module.addPyCode(pycode)

    # it is delay-initialized, see stockgdi.sip
    module.find('wxThePenList').ignore()

    # Some aliases that should be phased out eventually, (sooner rather than
    # later.) They are already gone (or wrapped by an #if) in the C++ code,
    # and so are not found in the documentation...
    module.addPyCode("""\
        wx.SOLID       = int(wx.PENSTYLE_SOLID)
        wx.DOT         = int(wx.PENSTYLE_DOT)
        wx.LONG_DASH   = int(wx.PENSTYLE_LONG_DASH)
        wx.SHORT_DASH  = int(wx.PENSTYLE_SHORT_DASH)
        wx.DOT_DASH    = int(wx.PENSTYLE_DOT_DASH)
        wx.USER_DASH   = int(wx.PENSTYLE_USER_DASH)
        wx.TRANSPARENT = int(wx.PENSTYLE_TRANSPARENT)
        """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 30
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxDC')
    assert isinstance(c, etgtools.ClassDef)

    c.addPrivateCopyCtor()
    c.addPublic()
    tools.removeVirtuals(c)

    # rename the more complex overload for these two, like in classic wxPython
    c.find('GetTextExtent').findOverload(
        'wxCoord *').pyName = 'GetFullTextExtent'
    c.find('GetMultiLineTextExtent').findOverload(
        'wxCoord *').pyName = 'GetFullMultiLineTextExtent'

    # Keep only the wxSize overloads of these
    c.find('GetSize').findOverload('wxCoord').ignore()
    c.find('GetSizeMM').findOverload('wxCoord').ignore()

    # TODO: needs wxAffineMatrix2D support.
    c.find('GetTransformMatrix').ignore()
    c.find('SetTransformMatrix').ignore()

    # remove wxPoint* overloads, we use the wxPointList ones
    c.find('DrawLines').findOverload('wxPoint points').ignore()
    c.find('DrawPolygon').findOverload('wxPoint points').ignore()
    c.find('DrawSpline').findOverload('wxPoint points').ignore()

    # TODO: we'll need a custom method implementation for this since there
    # are multiple array parameters involved...
    c.find('DrawPolyPolygon').ignore()

    # Add output param annotations so the generated docstrings will be correct
    c.find('GetUserScale.x').out = True
    c.find('GetUserScale.y').out = True

    c.find('GetLogicalScale.x').out = True
    c.find('GetLogicalScale.y').out = True

    c.find('GetLogicalOrigin').overloads = []
    c.find('GetLogicalOrigin.x').out = True
    c.find('GetLogicalOrigin.y').out = True

    c.find('GetTextExtent.w').out = True
    c.find('GetTextExtent.h').out = True
    c.find('GetTextExtent.descent').out = True
    c.find('GetTextExtent.externalLeading').out = True

    c.find('GetMultiLineTextExtent.w').out = True
    c.find('GetMultiLineTextExtent.h').out = True
    c.find('GetMultiLineTextExtent.heightLine').out = True

    c.find('GetClippingBox.x').out = True
    c.find('GetClippingBox.y').out = True
    c.find('GetClippingBox.width').out = True
    c.find('GetClippingBox.height').out = True
    c.addPyMethod(
        'GetClippingRect',
        '(self)',
        doc="Gets the rectangle surrounding the current clipping region",
        body="return wx.Rect(*self.GetClippingBox())")

    # Add some alternate implementations for DC methods, in order to avoid
    # using parameters as return values, etc. as well as Classic
    # compatibility.
    c.find('GetPixel').ignore()
    c.addCppMethod('wxColour*',
                   'GetPixel',
                   '(wxCoord x, wxCoord y)',
                   doc="Gets the colour at the specified location on the DC.",
                   body="""\
        wxColour* col = new wxColour;
        self->GetPixel(x, y, col);
        return col;
        """,
                   factory=True)

    # Return the rect instead of using an output parameter
    m = c.find('DrawLabel').findOverload('rectBounding')
    m.type = 'wxRect*'
    m.find('rectBounding').ignore()
    m.factory = True  # a new instance of wxRect is being created
    m.setCppCode("""\
        wxRect rv;
        self->DrawLabel(*text, *bitmap, *rect, alignment, indexAccel, &rv);
        return new wxRect(rv);
        """)
    c.addPyCode(
        'DC.DrawImageLabel = wx.deprecated(DC.DrawLabel, "Use DrawLabel instead.")'
    )

    # Return the array instead of using an output parameter
    m = c.find('GetPartialTextExtents')
    m.type = 'wxArrayInt*'
    m.find('widths').ignore()
    m.factory = True  # a new instance is being created
    m.setCppCode("""\
        wxArrayInt rval;
        self->GetPartialTextExtents(*text, rval);
        return new wxArrayInt(rval);
        """)

    c.addCppMethod('int', '__nonzero__', '()', """\
        return self->IsOk();
        """)

    c.addPyMethod(
        'GetBoundingBox',
        '(self)',
        doc="""\
        GetBoundingBox() -> (x1,y1, x2,y2)\n
        Returns the min and max points used in drawing commands so far.""",
        body="return (self.MinX(), self.MinY(), self.MaxX(), self.MaxY())")

    c.addCppMethod(
        'long', 'GetHDC', '()', """\
        #ifdef __WXMSW__
            return (long)self->GetHandle();
        #else
            wxPyRaiseNotImplemented();
            return 0;
        #endif""")
    c.addCppMethod(
        'void*', 'GetCGContext', '()', """\
        #ifdef __WXMAC__
            return self->GetHandle();
        #else
            wxPyRaiseNotImplemented();
            return NULL;
        #endif""")
    c.addCppMethod(
        'void*', 'GetGdkDrawable', '()', """\
        #ifdef __WXGTK__
            return self->GetHandle();
        #else
            wxPyRaiseNotImplemented();
            return NULL;
        #endif""")

    c.addPyCode(
        'DC.GetHDC = wx.deprecated(DC.GetHDC, "Use GetHandle instead.")')
    c.addPyCode(
        'DC.GetCGContext = wx.deprecated(DC.GetCGContext, "Use GetHandle instead.")'
    )
    c.addPyCode(
        'DC.GetGdkDrawable = wx.deprecated(DC.GetGdkDrawable, "Use GetHandle instead.")'
    )

    # This file contains implementations of functions for quickly drawing
    # lists of items on the DC. They are called from the CppMethods defined
    # below, which in turn are called from the PyMethods below that.
    c.includeCppCode('src/dc_ex.cpp')

    c.addCppMethod(
        'PyObject*',
        '_DrawPointList',
        '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body=
        "return wxPyDrawXXXList(*self, wxPyDrawXXXPoint, pyCoords, pyPens, pyBrushes);"
    )

    c.addCppMethod(
        'PyObject*',
        '_DrawLineList',
        '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body=
        "return wxPyDrawXXXList(*self, wxPyDrawXXXLine, pyCoords, pyPens, pyBrushes);"
    )

    c.addCppMethod(
        'PyObject*',
        '_DrawRectangleList',
        '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body=
        "return wxPyDrawXXXList(*self, wxPyDrawXXXRectangle, pyCoords, pyPens, pyBrushes);"
    )

    c.addCppMethod(
        'PyObject*',
        '_DrawEllipseList',
        '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body=
        "return wxPyDrawXXXList(*self, wxPyDrawXXXEllipse, pyCoords, pyPens, pyBrushes);"
    )

    c.addCppMethod(
        'PyObject*',
        '_DrawPolygonList',
        '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body=
        "return wxPyDrawXXXList(*self, wxPyDrawXXXPolygon, pyCoords, pyPens, pyBrushes);"
    )

    c.addCppMethod(
        'PyObject*',
        '_DrawTextList',
        '(PyObject* textList, PyObject* pyPoints, PyObject* foregroundList, PyObject* backgroundList)',
        body=
        "return wxPyDrawTextList(*self, textList, pyPoints, foregroundList, backgroundList);"
    )

    c.addPyMethod('DrawPointList',
                  '(self, points, pens=None)',
                  doc="""\
            Draw a list of points as quickly as possible.
    
            :param points: A sequence of 2-element sequences representing 
                           each point to draw, (x,y).
            :param pens:   If None, then the current pen is used.  If a single 
                           pen then it will be used for all points.  If a list of 
                           pens then there should be one for each point in points.
            """,
                  body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(points):
                raise ValueError('points and pens must have same length')
            return self._DrawPointList(points, pens, [])
            """)

    c.addPyMethod('DrawLineList',
                  '(self, lines, pens=None)',
                  doc="""\
            Draw a list of lines as quickly as possible.
    
            :param lines: A sequence of 4-element sequences representing
                          each line to draw, (x1,y1, x2,y2).
            :param pens:  If None, then the current pen is used.  If a
                          single pen then it will be used for all lines.  If
                          a list of pens then there should be one for each line
                          in lines.
            """,
                  body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(lines):
                raise ValueError('lines and pens must have same length')
            return self._DrawLineList(lines, pens, [])
            """)

    c.addPyMethod('DrawRectangleList',
                  '(self, rectangles, pens=None, brushes=None)',
                  doc="""\
            Draw a list of rectangles as quickly as possible.
    
            :param rectangles: A sequence of 4-element sequences representing
                               each rectangle to draw, (x,y, w,h).
            :param pens:       If None, then the current pen is used.  If a
                               single pen then it will be used for all rectangles.
                               If a list of pens then there should be one for each 
                               rectangle in rectangles.
            :param brushes:    A brush or brushes to be used to fill the rectagles,
                               with similar semantics as the pens parameter.
            """,
                  body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(rectangles):
                raise ValueError('rectangles and pens must have same length')
            if brushes is None:
                brushes = []
            elif isinstance(brushes, wx.Brush):
                brushes = [brushes]
            elif len(brushes) != len(rectangles):
                raise ValueError('rectangles and brushes must have same length')
            return self._DrawRectangleList(rectangles, pens, brushes)
            """)

    c.addPyMethod('DrawEllipseList',
                  '(self, ellipses, pens=None, brushes=None)',
                  doc="""\
            Draw a list of ellipses as quickly as possible.
    
            :param ellipses: A sequence of 4-element sequences representing
                             each ellipse to draw, (x,y, w,h).
            :param pens:     If None, then the current pen is used.  If a
                             single pen then it will be used for all ellipses.
                             If a list of pens then there should be one for each 
                             ellipse in ellipses.
            :param brushes:  A brush or brushes to be used to fill the ellipses,
                             with similar semantics as the pens parameter.
            """,
                  body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(ellipses):
                raise ValueError('ellipses and pens must have same length')
            if brushes is None:
                brushes = []
            elif isinstance(brushes, wx.Brush):
                brushes = [brushes]
            elif len(brushes) != len(ellipses):
                raise ValueError('ellipses and brushes must have same length')
            return self._DrawEllipseList(ellipses, pens, brushes)
            """)

    c.addPyMethod('DrawPolygonList',
                  '(self, polygons, pens=None, brushes=None)',
                  doc="""\
            Draw a list of polygons, each of which is a list of points.
    
            :param polygons: A sequence of sequences of sequences.
                             [[(x1,y1),(x2,y2),(x3,y3)...], [(x1,y1),(x2,y2),(x3,y3)...]]
                                  
            :param pens:     If None, then the current pen is used.  If a
                             single pen then it will be used for all polygons.
                             If a list of pens then there should be one for each 
                             polygon.
            :param brushes:  A brush or brushes to be used to fill the polygons,
                             with similar semantics as the pens parameter.
            """,
                  body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(polygons):
                raise ValueError('polygons and pens must have same length')
            if brushes is None:
                brushes = []
            elif isinstance(brushes, wx.Brush):
                brushes = [brushes]
            elif len(brushes) != len(polygons):
                raise ValueError('polygons and brushes must have same length')
            return self._DrawPolygonList(polygons, pens, brushes)
            """)

    c.addPyMethod(
        'DrawTextList',
        '(self, textList, coords, foregrounds=None, backgrounds=None)',
        doc="""\
            Draw a list of strings using a list of coordinants for positioning each string.
    
            :param textList:    A list of strings
            :param coords:      A list of (x,y) positions
            :param foregrounds: A list of `wx.Colour` objects to use for the
                                foregrounds of the strings.
            :param backgrounds: A list of `wx.Colour` objects to use for the
                                backgrounds of the strings.
    
            NOTE: Make sure you set background mode to wx.Solid (DC.SetBackgroundMode)
                  If you want backgrounds to do anything.
            """,
        body="""\
            if type(textList) == type(''):
                textList = [textList]
            elif len(textList) != len(coords):
                raise ValueError('textlist and coords must have same length')
            if foregrounds is None:
                foregrounds = []
            elif isinstance(foregrounds, wx.Colour):
                foregrounds = [foregrounds]
            elif len(foregrounds) != len(coords):
                raise ValueError('foregrounds and coords must have same length')
            if backgrounds is None:
                backgrounds = []
            elif isinstance(backgrounds, wx.Colour):
                backgrounds = [backgrounds]
            elif len(backgrounds) != len(coords):
                raise ValueError('backgrounds and coords must have same length')
            return  self._DrawTextList(textList, coords, foregrounds, backgrounds)
            """)

    # TODO: Port the PseudoDC from Classic

    #-----------------------------------------------------------------
    c = module.find('wxDCClipper')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------
    c = module.find('wxDCBrushChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------
    c = module.find('wxDCPenChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------
    c = module.find('wxDCTextColourChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------
    c = module.find('wxDCFontChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 31
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    def addTransferAnnotations(c, arg):
        for method in c.findAll('Append') + c.findAll('Insert') + \
                      c.findAll('Replace') + c.findAll('Prepend'):
            arg_def = method.findItem(arg)
            if arg_def:
                arg_def.transfer = True

        for method in c.findAll('Remove') + c.findAll('Replace'):
            method.transferBack = True

    #-----------------------------------------------------------------
    c = module.find('wxMenu')
    assert isinstance(c, etgtools.ClassDef)
    c.mustHaveApp()
    tools.removeVirtuals(c)
    c.find('Prepend.item').name = 'menuItem'
    c.find('Prepend.submenu').name = 'subMenu'

    addTransferAnnotations(c, 'menuItem')
    addTransferAnnotations(c, 'subMenu')
    c.find('AppendSubMenu.submenu').transfer = True

    # We only need one of these overloads, the non-const/const is not enough
    # to distinguish a unique Python signature.
    c.find('GetMenuItems').overloads = []

    # Ensure that no copy is made of the list object, so we only wrap the
    # existing object and keep it owned by C++
    c.find('GetMenuItems').noCopy = True

    c.addPyMethod('AppendMenu',
                  '(self, id, item, subMenu, help="")',
                  deprecated='Use Append instead.',
                  body='return self.Append(id, item, subMenu, help)')
    c.addPyMethod('AppendItem',
                  '(self, menuItem)',
                  deprecated='Use Append instead.',
                  body='return self.Append(menuItem)')

    c.addPyMethod('InsertMenu',
                  '(self, pos, id, item, subMenu, help="")',
                  deprecated='Use Insert instead.',
                  body='return self.Insert(pos, id, item, subMenu, help)')
    c.addPyMethod('InsertItem',
                  '(self, pos, menuItem)',
                  deprecated='Use Insert instead.',
                  body='return self.Insert(pos, menuItem)')

    c.addPyMethod('PrependMenu',
                  '(self, id, item, subMenu, help="")',
                  deprecated='Use Prepend instead.',
                  body='return self.Prepend(id, item, subMenu, help)')
    c.addPyMethod('PrependItem',
                  '(self, menuItem)',
                  deprecated='Use Prepend instead.',
                  body='return self.Prepend(menuItem)')

    c.addPyMethod('RemoveMenu',
                  '(self, id, item, subMenu, help="")',
                  deprecated='Use Remove instead.',
                  body='return self.Remove(id, item, subMenu, help)')
    c.addPyMethod('RemoveItem',
                  '(self, menuItem)',
                  deprecated='Use Remove instead.',
                  body='return self.Remove(menuItem)')

    # Don't hide the Destroy inherited from wxObject
    c.find('Destroy').findOverload('int').pyName = 'DestroyItem'
    c.find('Destroy').findOverload('wxMenuItem').pyName = 'DestroyItem'

    c.find('FindChildItem.pos').out = True
    c.find('FindItem.menu').out = True
    c.addCppMethod('wxMenuItem*',
                   'FindItemById',
                   '(int id)',
                   isConst=True,
                   doc="""\
            FindItemById(id) -> MenuItem

            Finds the menu item object associated with the given menu item identifier.""",
                   body="""\
            return self->FindItem(id);""")

    #-----------------------------------------------------------------
    c = module.find('wxMenuBar')
    assert isinstance(c, etgtools.ClassDef)
    c.mustHaveApp()
    tools.removeVirtuals(c)
    addTransferAnnotations(c, 'menu')
    c.find('wxMenuBar').findOverload(
        'wxMenu *menus[], const wxString titles[], long style=0)').ignore()

    c.find('FindItem.menu').out = True
    c.addCppMethod('wxMenuItem*',
                   'FindItemById',
                   '(int id)',
                   isConst=True,
                   doc="""\
            FindItemById(id) -> MenuItem

            Finds the menu item object associated with the given menu item identifier.""",
                   body="""\
            return self->FindItem(id);""")

    mac_scmb = c.find('MacSetCommonMenuBar')
    mac_scmb.setCppCode("""\
    #ifdef __WXMAC__
        wxMenuBar::MacSetCommonMenuBar(menubar);
    #endif
    """)

    mac_gcmb = c.find('MacGetCommonMenuBar')
    mac_gcmb.setCppCode("""\
    #ifdef __WXMAC__
        return wxMenuBar::MacGetCommonMenuBar();
    #else
        return NULL;
    #endif
    """)

    mac_gcmb = c.find('OSXGetAppleMenu')
    mac_gcmb.setCppCode("""\
    #ifdef __WXMAC__
        return self->OSXGetAppleMenu();
    #else
        return NULL;
    #endif
    """)

    # don't transfer on other platforms, as this is a no-op there.
    import sys
    if sys.platform.startswith('darwin'):
        mac_scmb.find('menubar').transfer = True

    c.find('FindItem.menu').out = True

    c.addPyMethod('GetMenus',
                  '(self)',
                  doc="""\
        GetMenus() -> (menu, label)\n
        Return a list of (menu, label) items for the menus in the :class:`MenuBar`.""",
                  body="""\
        return [(self.GetMenu(i), self.GetLabelTop(i)) for i in range(self.GetMenuCount())]
        """)
    c.addPyMethod('SetMenus',
                  '(self, items)',
                  doc="""\
        SetMenus()\n
        Clear and add new menus to the :class:`MenuBar` from a list of (menu, label) items.""",
                  body="""\
        for i in range(self.GetMenuCount()-1, -1, -1):
            self.Remove(i)
        for m, l in items:
            self.Append(m, l)
        """)
    c.addPyProperty('Menus GetMenus SetMenus')

    module.addItem(tools.wxListWrapperTemplate('wxMenuList', 'wxMenu', module))

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 32
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxRegion')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)
    c.mustHaveApp()

    # Replace one of the constructors with one having a more python-friendly API
    c.find('wxRegion').findOverload('points').ignore()
    c.addCppCode(
        tools.ObjArrayHelperTemplate(
            'wxPoint', 'sipType_wxPoint',
            "Expected a sequence of length-2 sequences or wx.Point objects."))
    c.addCppCtor_sip(
        '(PyObject* points, wxPolygonFillMode fillStyle = wxODDEVEN_RULE)',
        doc="""\
        Constructs a region corresponding to the polygon made from the points
        in the provided sequence.""",
        body="""\
        size_t count;
        wxPoint* array = wxPoint_array_helper(points, &count);
        if ( array != NULL ) {
            sipCpp = new wxRegion(count, array, fillStyle);
            delete [] array;
        }
        if (PyErr_Occurred()) sipIsErr = 1;
        """)

    c.find('GetBox').findOverload('wxCoord').ignore()

    # Iterator stuff
    c.addPyMethod(
        '__iter__', '(self)', 'return PyRegionIterator(self)', """\
                  Returns a rectangle interator conforming to the Python iterator
                  protocol.""")
    c.addPyCode("""\
        class PyRegionIterator(object):
            "A Python iterator for wx.Region objects"
            def __init__(self, region):
                self._region = region
                self._iterator = wx.RegionIterator(region)
            def next(self):
                if not self._iterator:
                    raise StopIteration
                rect = self._iterator.GetRect()
                if self._iterator.HaveRects():
                    self._iterator.Next()
                return rect
            __next__ = next  # for Python 3
        """)

    c = module.find('wxRegionIterator')
    c.mustHaveApp()
    c.find('operator++').ignore()

    c.find('operator bool').ignore()
    c.addCppMethod(
        'int', '__nonzero__', '()', 'return (int)self->operator bool();',
        'Returns true while there are still rectangles available in the iteration.'
    )
    c.addCppMethod(
        'int', '__bool__', '()', 'return (int)self->operator bool();',
        'Returns true while there are still rectangles available in the iteration.'
    )

    c.addCppMethod('void', 'Next', '()', 'self->operator++();',
                   'Move the iterator to the next rectangle in the region.')

    # This is defined in the docs, but not in any of the real headers!
    module.find('wxNullRegion').ignore()

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 33
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxFontInfo')
    assert isinstance(c, etgtools.ClassDef)
    ctor = c.find('wxFontInfo').findOverload('T pointSize')
    ctor.find('pointSize').type = 'float'

    c = module.find('wxFont')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    # Set mustHaveApp on all ctors except the default ctor
    for ctor in c.find('wxFont').all():
        if ctor.isCtor and ctor.argsString != '()':
            ctor.mustHaveApp()

    for func in c.find('New').all():
        func.mustHaveApp()

    c.find('GetDefaultEncoding').mustHaveApp()
    c.find('SetDefaultEncoding').mustHaveApp()

    # Tweak the documentation in this constructor a little, replacing the
    # link to another constructor with a simpler version of the text.
    ctor = c.find('wxFont').findOverload('int pointSize')
    # TODO: should implement an easier way to findDocNode() the node containing what we're looking for...
    ref = list(ctor.detailedDoc[0])[0]
    assert ref.text.startswith('wxFont(')
    ref.tag = 'para'
    ref.text = 'the constructor accepting a :ref:`wx.FontInfo`'

    # FFont factory function for backwards compatibility
    module.addCppFunction('wxFont*', 'FFont',
                          """(int pointSize,
                              wxFontFamily family,
                              int flags = wxFONTFLAG_DEFAULT,
                              const wxString& faceName = wxEmptyString,
                              wxFontEncoding encoding = wxFONTENCODING_DEFAULT)""",
        pyArgsString="(pointSize, family, flags=FONTFLAG_DEFAULT, faceName=EmptyString, encoding=FONTENCODING_DEFAULT)",
        body="""\
        wxFont* font = wxFont::New(pointSize, family, flags, *faceName, encoding);
        return font;
        """, factory=True)

    for item in c.findAll('New'):
        item.factory = True

    c.addProperty('Encoding GetEncoding SetEncoding')
    c.addProperty('FaceName GetFaceName SetFaceName')
    c.addProperty('Family GetFamily SetFamily')
    c.addProperty('NativeFontInfoDesc GetNativeFontInfoDesc SetNativeFontInfo')
    c.addProperty('NativeFontInfoUserDesc GetNativeFontInfoUserDesc SetNativeFontInfoUserDesc')
    c.addProperty('PointSize GetPointSize SetPointSize')
    c.addProperty('PixelSize GetPixelSize SetPixelSize')
    c.addProperty('Style GetStyle SetStyle')
    c.addProperty('Weight GetWeight SetWeight')

    # TODO, there is now an Underlined method so we can't have a
    # property of the same name.
    #c.addProperty('Underlined GetUnderlined SetUnderlined')
    #c.addProperty('Strikethrough GetStrikethrough SetStrikethrough')

    c.addCppMethod('int', '__nonzero__', '()', "return self->IsOk();")
    c.addCppMethod('int', '__bool__', '()', "return self->IsOk();")

    c.addCppMethod('void*', 'GetHFONT', '()',
        doc="Returns the font's native handle.",
        body="""\
        #ifdef __WXMSW__
            return self->GetHFONT();
        #else
            return 0;
        #endif
        """)

    c.addCppMethod('void*', 'OSXGetCGFont', '()',
        doc="Returns the font's native handle.",
        body="""\
        #ifdef __WXMAC__
            return self->OSXGetCGFont();
        #else
            return 0;
        #endif
        """)

    c.addCppMethod('void*', 'GetPangoFontDescription', '()',
        doc="Returns the font's native handle.",
        body="""\
        #ifdef __WXGTK__
            return self->GetNativeFontInfo()->description;
        #else
            return 0;
        #endif
        """)

    c.find('AddPrivateFont').setCppCode("""\
        #if wxUSE_PRIVATE_FONTS
            return wxFont::AddPrivateFont(*filename);
        #else
            wxPyRaiseNotImplemented();
            return false;
        #endif
        """)

    c.addCppMethod('bool', 'CanUsePrivateFont', '()', isStatic=True,
        doc="Returns ``True`` if this build of wxPython supports using :meth:`AddPrivateFont`.",
        body="return wxUSE_PRIVATE_FONTS;")


    # The stock Font items are documented as simple pointers, but in reality
    # they are macros that evaluate to a function call that returns a font
    # pointer, and that is only valid *after* the wx.App object has been
    # created. That messes up the code that SIP generates for them, so we need
    # to come up with another solution. So instead we will just create
    # uninitialized fonts in a block of Python code, that will then be
    # initialized later when the wx.App is created.
    c.addCppMethod('void', '_copyFrom', '(const wxFont* other)',
                   "*self = *other;",
                   briefDoc="For internal use only.")  # ??
    pycode = '# These stock fonts will be initialized when the wx.App object is created.\n'
    for item in module:
        if '_FONT' in item.name:
            item.ignore()
            pycode += '%s = Font()\n' % tools.removeWxPrefix(item.name)
    module.addPyCode(pycode)

    # it is delay-initialized, see stockgdi.sip
    module.find('wxTheFontList').ignore()

    module.find('wxFromString').ignore()
    module.find('wxToString').ignore()

    c.addPyMethod('SetNoAntiAliasing', '(self, no=True)', 'pass', deprecated=True)
    c.addPyMethod('GetNoAntiAliasing', '(self)', 'pass', deprecated=True)

    # Some aliases that should be phased out eventually, (sooner rather than
    # later.) They are already gone (or wrapped by an #if) in the C++ code,
    # and so are not found in the documentation...
    module.addPyCode("""\
        wx.DEFAULT    = int(wx.FONTFAMILY_DEFAULT)
        wx.DECORATIVE = int(wx.FONTFAMILY_DECORATIVE)
        wx.ROMAN      = int(wx.FONTFAMILY_ROMAN)
        wx.SCRIPT     = int(wx.FONTFAMILY_SCRIPT)
        wx.SWISS      = int(wx.FONTFAMILY_SWISS)
        wx.MODERN     = int(wx.FONTFAMILY_MODERN)
        wx.TELETYPE   = int(wx.FONTFAMILY_TELETYPE)

        wx.NORMAL = int(wx.FONTWEIGHT_NORMAL)
        wx.LIGHT  = int(wx.FONTWEIGHT_LIGHT)
        wx.BOLD   = int(wx.FONTWEIGHT_BOLD)

        wx.NORMAL = int(wx.FONTSTYLE_NORMAL)
        wx.ITALIC = int(wx.FONTSTYLE_ITALIC)
        wx.SLANT  = int(wx.FONTSTYLE_SLANT)
        """)


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 34
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxDC')
    assert isinstance(c, etgtools.ClassDef)
    c.mustHaveApp()

    c.addPrivateCopyCtor()
    c.addPublic()
    tools.removeVirtuals(c)

    c.addDtor('public', True)

    # Keep only the wxSize overloads of these
    c.find('GetSize').findOverload('wxCoord').ignore()
    c.find('GetSizeMM').findOverload('wxCoord').ignore()

    # TODO: needs wxAffineMatrix2D support.
    #c.find('GetTransformMatrix').ignore()
    #c.find('SetTransformMatrix').ignore()

    # remove wxPoint* overloads, we use the wxPointList ones
    c.find('DrawLines').findOverload('wxPoint points').ignore()
    c.find('DrawPolygon').findOverload('wxPoint points').ignore()
    c.find('DrawSpline').findOverload('wxPoint points').ignore()

    # TODO: we'll need a custom method implementation for this since there
    # are multiple array parameters involved...
    c.find('DrawPolyPolygon').ignore()

    # Add output param annotations so the generated docstrings will be correct
    c.find('GetUserScale.x').out = True
    c.find('GetUserScale.y').out = True

    c.find('GetLogicalScale.x').out = True
    c.find('GetLogicalScale.y').out = True

    c.find('GetLogicalOrigin').overloads = []
    c.find('GetLogicalOrigin.x').out = True
    c.find('GetLogicalOrigin.y').out = True

    c.find('GetClippingBox.x').out = True
    c.find('GetClippingBox.y').out = True
    c.find('GetClippingBox.width').out = True
    c.find('GetClippingBox.height').out = True
    c.addPyMethod(
        'GetClippingRect',
        '(self)',
        doc="Gets the rectangle surrounding the current clipping region",
        body="return wx.Rect(*self.GetClippingBox())")

    # Deal with the text-extent methods. In Classic we renamed one overloaded
    # method with a "Full" name, and the simpler one was left with the
    # original name.  I think a simpler approach here will be to remove the
    # simple version, rename the Full version as before, and then add a
    # CppMethod to reimplement the simple version.

    for name in ['GetTextExtent', 'GetMultiLineTextExtent']:
        m = c.find(name)
        # if these fail then double-check order of parsed methods, etc.
        assert len(m.overloads) == 1
        assert 'wxCoord' not in m.overloads[0].argsString
        m.overloads = []

    c.find('GetTextExtent').pyName = 'GetFullTextExtent'
    c.find('GetMultiLineTextExtent').pyName = 'GetFullMultiLineTextExtent'

    # Set output parameters
    c.find('GetTextExtent.w').out = True
    c.find('GetTextExtent.h').out = True
    c.find('GetTextExtent.descent').out = True
    c.find('GetTextExtent.externalLeading').out = True

    c.find('GetMultiLineTextExtent.w').out = True
    c.find('GetMultiLineTextExtent.h').out = True
    c.find('GetMultiLineTextExtent.heightLine').out = True

    # Update the docs to remove references to overloading, pointer values, etc.
    m = c.find('GetTextExtent')
    m.briefDoc = "Gets the dimensions of the string as it would be drawn."
    m.detailedDoc = [
        dedent("""\
        The ``string`` parameter is the string to measure.  The return value
        is a tuple of integer values consisting of ``widget``, ``height``,
        ``decent`` and ``externalLeading``. The ``descent`` is the dimension
        from the baseline of the font to the bottom of the descender, and
        ``externalLeading`` is any extra vertical space added to the font by the
        font designer (usually is zero).

        If the optional parameter ``font`` is specified and valid, then it is
        used for the text extent calculation. Otherwise the currently selected
        font is.

        .. seealso:: :class:`wx.Font`, :meth:`~wx.DC.SetFont`,
           :meth:`~wx.DC.GetPartialTextExtents, :meth:`~wx.DC.GetMultiLineTextExtent`
        """)
    ]

    m = c.find('GetMultiLineTextExtent')
    m.briefDoc = "Gets the dimensions of the string as it would be drawn."
    m.detailedDoc = [
        dedent("""\
        The ``string`` parameter is the string to measure.  The return value
        is a tuple of integer values consisting of ``widget``, ``height`` and
        ``heightLine``.  The ``heightLine`` is the the height of a single line.

        If the optional parameter ``font`` is specified and valid, then it is
        used for the text extent calculation. Otherwise the currently selected
        font is.

        .. note:: This function works with both single-line and multi-line strings.

        .. seealso:: :class:`wx.Font`, :meth:`~wx.DC.SetFont`,
           :meth:`~wx.DC.GetPartialTextExtents, :meth:`~wx.DC.GetTextExtent`
        """)
    ]

    # Now add the simpler versions of the extent methods
    c.addCppMethod('wxSize*',
                   'GetTextExtent',
                   '(const wxString& st)',
                   isConst=True,
                   doc=dedent("""\
            Return the dimensions of the given string's text extent using the
            currently selected font.

            :param st: The string to be measured

            .. seealso:: :meth:`~wx.DC.GetFullTextExtent`
            """),
                   body="""\
            return new wxSize(self->GetTextExtent(*st));
            """,
                   overloadOkay=False,
                   factory=True)

    c.addCppMethod('wxSize*',
                   'GetMultiLineTextExtent',
                   '(const wxString& st)',
                   isConst=True,
                   doc=dedent("""\
            Return the dimensions of the given string's text extent using the
            currently selected font, taking into account multiple lines if
            present in the string.

            :param st: The string to be measured

            .. seealso:: :meth:`~wx.DC.GetFullMultiLineTextExtent`
            """),
                   body="""\
            return new wxSize(self->GetMultiLineTextExtent(*st));
            """,
                   overloadOkay=False,
                   factory=True)

    # Add some alternate implementations for other DC methods, in order to
    # avoid using parameters as return values, etc. as well as Classic
    # compatibility.
    c.find('GetPixel').ignore()
    c.addCppMethod('wxColour*',
                   'GetPixel',
                   '(wxCoord x, wxCoord y)',
                   doc="Gets the colour at the specified location on the DC.",
                   body="""\
            wxColour* col = new wxColour;
            self->GetPixel(x, y, col);
            return col;
            """,
                   factory=True)

    # Return the rect instead of using an output parameter
    m = c.find('DrawLabel').findOverload('rectBounding')
    m.type = 'wxRect*'
    m.find('rectBounding').ignore()
    m.factory = True  # a new instance of wxRect is being created
    m.setCppCode("""\
        wxRect rv;
        self->DrawLabel(*text, *bitmap, *rect, alignment, indexAccel, &rv);
        return new wxRect(rv);
        """)
    c.addPyCode(
        'DC.DrawImageLabel = wx.deprecated(DC.DrawLabel, "Use DrawLabel instead.")'
    )

    # Return the array instead of using an output parameter
    m = c.find('GetPartialTextExtents')
    m.type = 'wxArrayInt*'
    m.find('widths').ignore()
    m.factory = True  # a new instance is being created
    m.setCppCode("""\
        wxArrayInt rval;
        self->GetPartialTextExtents(*text, rval);
        return new wxArrayInt(rval);
        """)

    c.addCppMethod('int', '__nonzero__', '()', "return self->IsOk();")
    c.addCppMethod('int', '__bool__', '()', "return self->IsOk();")

    c.addPyMethod(
        'GetBoundingBox',
        '(self)',
        doc="""\
        GetBoundingBox() -> (x1,y1, x2,y2)\n
        Returns the min and max points used in drawing commands so far.""",
        body="return (self.MinX(), self.MinY(), self.MaxX(), self.MaxY())")

    m = c.find('GetHandle')
    m.type = 'wxUIntPtr*'
    m.setCppCode("return new wxUIntPtr((wxUIntPtr)self->GetHandle());")

    c.addCppMethod(
        'long', 'GetHDC', '()', """\
        #ifdef __WXMSW__
            return (long)self->GetHandle();
        #else
            wxPyRaiseNotImplemented();
            return 0;
        #endif""")
    c.addCppMethod(
        'wxUIntPtr*', 'GetCGContext', '()', """\
        #ifdef __WXMAC__
            return new wxUIntPtr((wxUIntPtr)self->GetHandle());
        #else
            wxPyRaiseNotImplemented();
            return NULL;
        #endif""")
    c.addCppMethod(
        'wxUIntPtr*', 'GetGdkDrawable', '()', """\
        #ifdef __WXGTK__
            return new wxUIntPtr((wxUIntPtr)self->GetHandle());
        #else
            wxPyRaiseNotImplemented();
            return NULL;
        #endif""")

    c.addPyCode(
        'DC.GetHDC = wx.deprecated(DC.GetHDC, "Use GetHandle instead.")')
    c.addPyCode(
        'DC.GetCGContext = wx.deprecated(DC.GetCGContext, "Use GetHandle instead.")'
    )
    c.addPyCode(
        'DC.GetGdkDrawable = wx.deprecated(DC.GetGdkDrawable, "Use GetHandle instead.")'
    )

    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'self.Destroy()')

    # This file contains implementations of functions for quickly drawing
    # lists of items on the DC. They are called from the CppMethods defined
    # below, which in turn are called from the PyMethods below that.
    c.includeCppCode('src/dc_ex.cpp')

    c.addCppMethod(
        'PyObject*',
        '_DrawPointList',
        '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body=
        "return wxPyDrawXXXList(*self, wxPyDrawXXXPoint, pyCoords, pyPens, pyBrushes);"
    )

    c.addCppMethod(
        'PyObject*',
        '_DrawLineList',
        '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body=
        "return wxPyDrawXXXList(*self, wxPyDrawXXXLine, pyCoords, pyPens, pyBrushes);"
    )

    c.addCppMethod(
        'PyObject*',
        '_DrawRectangleList',
        '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body=
        "return wxPyDrawXXXList(*self, wxPyDrawXXXRectangle, pyCoords, pyPens, pyBrushes);"
    )

    c.addCppMethod(
        'PyObject*',
        '_DrawEllipseList',
        '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body=
        "return wxPyDrawXXXList(*self, wxPyDrawXXXEllipse, pyCoords, pyPens, pyBrushes);"
    )

    c.addCppMethod(
        'PyObject*',
        '_DrawPolygonList',
        '(PyObject* pyCoords, PyObject* pyPens, PyObject* pyBrushes)',
        body=
        "return wxPyDrawXXXList(*self, wxPyDrawXXXPolygon, pyCoords, pyPens, pyBrushes);"
    )

    c.addCppMethod(
        'PyObject*',
        '_DrawTextList',
        '(PyObject* textList, PyObject* pyPoints, PyObject* foregroundList, PyObject* backgroundList)',
        body=
        "return wxPyDrawTextList(*self, textList, pyPoints, foregroundList, backgroundList);"
    )

    c.addPyMethod('DrawPointList',
                  '(self, points, pens=None)',
                  doc="""\
            Draw a list of points as quickly as possible.

            :param points: A sequence of 2-element sequences representing
                           each point to draw, (x,y).
            :param pens:   If None, then the current pen is used.  If a single
                           pen then it will be used for all points.  If a list of
                           pens then there should be one for each point in points.
            """,
                  body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(points):
                raise ValueError('points and pens must have same length')
            return self._DrawPointList(points, pens, [])
            """)

    c.addPyMethod('DrawLineList',
                  '(self, lines, pens=None)',
                  doc="""\
            Draw a list of lines as quickly as possible.

            :param lines: A sequence of 4-element sequences representing
                          each line to draw, (x1,y1, x2,y2).
            :param pens:  If None, then the current pen is used.  If a
                          single pen then it will be used for all lines.  If
                          a list of pens then there should be one for each line
                          in lines.
            """,
                  body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(lines):
                raise ValueError('lines and pens must have same length')
            return self._DrawLineList(lines, pens, [])
            """)

    c.addPyMethod('DrawRectangleList',
                  '(self, rectangles, pens=None, brushes=None)',
                  doc="""\
            Draw a list of rectangles as quickly as possible.

            :param rectangles: A sequence of 4-element sequences representing
                               each rectangle to draw, (x,y, w,h).
            :param pens:       If None, then the current pen is used.  If a
                               single pen then it will be used for all rectangles.
                               If a list of pens then there should be one for each
                               rectangle in rectangles.
            :param brushes:    A brush or brushes to be used to fill the rectagles,
                               with similar semantics as the pens parameter.
            """,
                  body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(rectangles):
                raise ValueError('rectangles and pens must have same length')
            if brushes is None:
                brushes = []
            elif isinstance(brushes, wx.Brush):
                brushes = [brushes]
            elif len(brushes) != len(rectangles):
                raise ValueError('rectangles and brushes must have same length')
            return self._DrawRectangleList(rectangles, pens, brushes)
            """)

    c.addPyMethod('DrawEllipseList',
                  '(self, ellipses, pens=None, brushes=None)',
                  doc="""\
            Draw a list of ellipses as quickly as possible.

            :param ellipses: A sequence of 4-element sequences representing
                             each ellipse to draw, (x,y, w,h).
            :param pens:     If None, then the current pen is used.  If a
                             single pen then it will be used for all ellipses.
                             If a list of pens then there should be one for each
                             ellipse in ellipses.
            :param brushes:  A brush or brushes to be used to fill the ellipses,
                             with similar semantics as the pens parameter.
            """,
                  body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(ellipses):
                raise ValueError('ellipses and pens must have same length')
            if brushes is None:
                brushes = []
            elif isinstance(brushes, wx.Brush):
                brushes = [brushes]
            elif len(brushes) != len(ellipses):
                raise ValueError('ellipses and brushes must have same length')
            return self._DrawEllipseList(ellipses, pens, brushes)
            """)

    c.addPyMethod('DrawPolygonList',
                  '(self, polygons, pens=None, brushes=None)',
                  doc="""\
            Draw a list of polygons, each of which is a list of points.

            :param polygons: A sequence of sequences of sequences.
                             [[(x1,y1),(x2,y2),(x3,y3)...], [(x1,y1),(x2,y2),(x3,y3)...]]

            :param pens:     If None, then the current pen is used.  If a
                             single pen then it will be used for all polygons.
                             If a list of pens then there should be one for each
                             polygon.
            :param brushes:  A brush or brushes to be used to fill the polygons,
                             with similar semantics as the pens parameter.
            """,
                  body="""\
            if pens is None:
                pens = []
            elif isinstance(pens, wx.Pen):
                pens = [pens]
            elif len(pens) != len(polygons):
                raise ValueError('polygons and pens must have same length')
            if brushes is None:
                brushes = []
            elif isinstance(brushes, wx.Brush):
                brushes = [brushes]
            elif len(brushes) != len(polygons):
                raise ValueError('polygons and brushes must have same length')
            return self._DrawPolygonList(polygons, pens, brushes)
            """)

    c.addPyMethod(
        'DrawTextList',
        '(self, textList, coords, foregrounds=None, backgrounds=None)',
        doc="""\
            Draw a list of strings using a list of coordinants for positioning each string.

            :param textList:    A list of strings
            :param coords:      A list of (x,y) positions
            :param foregrounds: A list of `wx.Colour` objects to use for the
                                foregrounds of the strings.
            :param backgrounds: A list of `wx.Colour` objects to use for the
                                backgrounds of the strings.

            NOTE: Make sure you set background mode to wx.Solid (DC.SetBackgroundMode)
                  If you want backgrounds to do anything.
            """,
        body="""\
            if type(textList) == type(''):
                textList = [textList]
            elif len(textList) != len(coords):
                raise ValueError('textlist and coords must have same length')
            if foregrounds is None:
                foregrounds = []
            elif isinstance(foregrounds, wx.Colour):
                foregrounds = [foregrounds]
            elif len(foregrounds) != len(coords):
                raise ValueError('foregrounds and coords must have same length')
            if backgrounds is None:
                backgrounds = []
            elif isinstance(backgrounds, wx.Colour):
                backgrounds = [backgrounds]
            elif len(backgrounds) != len(coords):
                raise ValueError('backgrounds and coords must have same length')
            return  self._DrawTextList(textList, coords, foregrounds, backgrounds)
            """)

    #-----------------------------------------------------------------
    c = module.find('wxDCClipper')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------
    c = module.find('wxDCBrushChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------
    c = module.find('wxDCPenChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------
    c = module.find('wxDCTextColourChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------
    c = module.find('wxDCFontChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------
    c = module.find('wxDCTextBgColourChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------
    c = module.find('wxDCTextBgModeChanger')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    # context manager methods
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 35
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    module.addCppCode("""
    #if !wxUSE_HOTKEY
    #define wxEVT_HOTKEY 0
    #endif
    """)

    # Missing in 3.1.6
    module.addItem(
        etgtools.WigCode("""\
        wxEventType wxEVT_FULLSCREEN /PyName=wxEVT_FULLSCREEN/;
        """))

    module.addPyClass(
        'PyEventBinder', ['object'],
        doc="""\
            Instances of this class are used to bind specific events to event handlers.
            """,
        items=[
            PyFunctionDef('__init__',
                          '(self, evtType, expectedIDs=0)',
                          body="""\
                    if expectedIDs not in [0, 1, 2]:
                        raise ValueError("Invalid number of expectedIDs")
                    self.expectedIDs = expectedIDs

                    if isinstance(evtType, (list, tuple)):
                        self.evtType = list(evtType)
                    else:
                        self.evtType = [evtType]
                    """),
            PyFunctionDef(
                'Bind',
                '(self, target, id1, id2, function)',
                doc=
                """Bind this set of event types to target using its Connect() method.""",
                body="""\
                    for et in self.evtType:
                        target.Connect(id1, id2, et, function)
                    """),
            PyFunctionDef('Unbind',
                          '(self, target, id1, id2, handler=None)',
                          doc="""Remove an event binding.""",
                          body="""\
                    success = 0
                    for et in self.evtType:
                        success += int(target.Disconnect(id1, id2, et, handler))
                    return success != 0
                    """),
            PyFunctionDef('_getEvtType',
                          '(self)',
                          doc="""\
                    Make it easy to get to the default wxEventType typeID for this
                    event binder.
                    """,
                          body="""return self.evtType[0]"""),
            PyPropertyDef('typeId', '_getEvtType'),
            PyFunctionDef('__call__',
                          '(self, *args)',
                          deprecated="Use :meth:`EvtHandler.Bind` instead.",
                          doc="""\
                    For backwards compatibility with the old ``EVT_*`` functions.
                    Should be called with either (window, func), (window, ID,
                    func) or (window, ID1, ID2, func) parameters depending on the
                    type of the event.
                    """,
                          body="""\
                    assert len(args) == 2 + self.expectedIDs
                    id1 = ID_ANY
                    id2 = ID_ANY
                    target = args[0]
                    if self.expectedIDs == 0:
                        func = args[1]
                    elif self.expectedIDs == 1:
                        id1 = args[1]
                        func = args[2]
                    elif self.expectedIDs == 2:
                        id1 = args[1]
                        id2 = args[2]
                        func = args[3]
                    else:
                        raise ValueError("Unexpected number of IDs")

                    self.Bind(target, id1, id2, func)
                    """)
        ])

    module.includePyCode('src/event_ex.py')

    #---------------------------------------
    # wxEvtHandler
    c = module.find('wxEvtHandler')
    c.addPrivateCopyCtor()
    c.addPublic()

    c.includeCppCode('src/event_ex.cpp')

    # Ignore the Connect/Disconnect and Bind/Unbind methods (and all overloads) for now.
    for item in c.allItems():
        if item.name in ['Connect', 'Disconnect', 'Bind', 'Unbind']:
            item.ignore()

    # Connect and Disconnect methods for wxPython. Hold a reference to the
    # event handler function in the event table, so we can fetch it later when
    # it is time to handle the event.
    c.addCppMethod(
        'void',
        'Connect',
        '(int id, int lastId, wxEventType eventType, PyObject* func)',
        doc="Make an entry in the dynamic event table for an event binding.",
        body="""\
            if (PyCallable_Check(func)) {
                self->Connect(id, lastId, eventType,
                              (wxObjectEventFunction)&wxPyCallback::EventThunker,
                              new wxPyCallback(func));
            }
            else if (func == Py_None) {
                self->Disconnect(id, lastId, eventType,
                                 (wxObjectEventFunction)(wxEventFunction)
                                 &wxPyCallback::EventThunker);
            }
            else {
                PyErr_SetString(PyExc_TypeError, "Expected callable object or None.");
            }
        """)

    c.addCppMethod(
        'bool',
        'Disconnect', '(int id, int lastId=-1, '
        'wxEventType eventType=wxEVT_NULL, '
        'PyObject* func=NULL)',
        doc=
        "Remove an event binding by removing its entry in the dynamic event table.",
        body="""\
            if (func && func != Py_None) {
                // Find the current matching binder that has this function
                // pointer and disconnect that one.  Unfortunately since we
                // wrapped the PyObject function pointer in another object we
                // have to do the searching ourselves...
                size_t cookie;
                wxDynamicEventTableEntry *entry = self->GetFirstDynamicEntry(cookie);
                while (entry)
                {
                    if ((entry->m_id == id) &&
                        ((entry->m_lastId == lastId) || (lastId == wxID_ANY)) &&
                        ((entry->m_eventType == eventType) || (eventType == wxEVT_NULL)) &&
                        entry->m_fn->IsMatching(wxObjectEventFunctor((wxObjectEventFunction)&wxPyCallback::EventThunker, NULL)) &&
                        (entry->m_callbackUserData != NULL))
                    {
                        wxPyThreadBlocker block;
                        wxPyCallback *cb = (wxPyCallback*)entry->m_callbackUserData;
                        // NOTE: Just comparing PyObject pointers is not enough, as bound
                        // methods can result in different PyObjects each time obj.Method
                        // is evaluated. (!!!)
                        if (PyObject_RichCompareBool(cb->m_func, func, Py_EQ) == 1) {
                            delete cb;
                            // Set callback data to a known value instead of NULL to
                            // ensure Disconnect() removes the correct handler.
                            entry->m_callbackUserData = new wxObject();
                            // Now Disconnect should work
                            return self->Disconnect(id, lastId, eventType,
                                                    (wxObjectEventFunction)&wxPyCallback::EventThunker,
                                                    entry->m_callbackUserData);
                        }
                    }
                    entry = self->GetNextDynamicEntry(cookie);
                }
                return false;
            }
            else {
                return self->Disconnect(id, lastId, eventType,
                                        (wxObjectEventFunction)&wxPyCallback::EventThunker);
            }
        """)

    # Ignore the C++ version of CallAfter. We have our own.
    # TODO: If we want to support this we'll need concrete implementations of
    # the template, probably using PyObject* args.
    for m in c.find('CallAfter').all():
        m.ignore()

    c.find('QueueEvent.event').transfer = True
    module.find('wxQueueEvent.event').transfer = True

    # TODO: If we don't need to use the wxEvtHandler's client data for our own
    # tracking then enable these....
    c.find('GetClientObject').ignore()
    c.find('SetClientObject').ignore()
    c.find('GetClientData').ignore()
    c.find('SetClientData').ignore()

    # We only care about overriding a few virtuals, ignore the rest.
    tools.removeVirtuals(c)
    c.find('ProcessEvent').isVirtual = True
    c.find('TryBefore').isVirtual = True
    c.find('TryAfter').isVirtual = True
    c.find('TryBefore').ignore(False)
    c.find('TryAfter').ignore(False)

    # Release the GIL for potentially blocking or long-running functions
    c.find('ProcessEvent').releaseGIL()
    c.find('ProcessEventLocally').releaseGIL()
    c.find('SafelyProcessEvent').releaseGIL()
    c.find('ProcessPendingEvents').releaseGIL()

    c.addPyMethod(
        'Bind',
        '(self, event, handler, source=None, id=wx.ID_ANY, id2=wx.ID_ANY)',
        doc="""\
            Bind an event to an event handler.

            :param event: One of the ``EVT_*`` event binder objects that
                          specifies the type of event to bind.

            :param handler: A callable object to be invoked when the
                            event is delivered to self.  Pass ``None`` to
                            disconnect an event handler.

            :param source: Sometimes the event originates from a
                           different window than self, but you still
                           want to catch it in self.  (For example, a
                           button event delivered to a frame.)  By
                           passing the source of the event, the event
                           handling system is able to differentiate
                           between the same event type from different
                           controls.

            :param id: Used to spcify the event source by ID instead
                       of instance.

            :param id2: Used when it is desirable to bind a handler
                        to a range of IDs, such as with EVT_MENU_RANGE.
            """,
        body="""\
            assert isinstance(event, wx.PyEventBinder)
            assert callable(handler) or handler is None
            assert source is None or hasattr(source, 'GetId')
            if source is not None:
                id  = source.GetId()
            event.Bind(self, id, id2, handler)
            """)

    c.addPyMethod(
        'Unbind',
        '(self, event, source=None, id=wx.ID_ANY, id2=wx.ID_ANY, handler=None)',
        doc="""\
            Disconnects the event handler binding for event from `self`.
            Returns ``True`` if successful.
            """,
        body="""\
            if source is not None:
                id  = source.GetId()
            return event.Unbind(self, id, id2, handler)
            """)

    module.addPyCode(
        'PyEvtHandler = wx.deprecated(EvtHandler, "Use :class:`EvtHandler` instead.")'
    )

    #---------------------------------------
    # wxEvent
    c = module.find('wxEvent')
    assert isinstance(c, etgtools.ClassDef)
    c.abstract = True
    c.find('Clone').factory = True

    c.find('GetEventUserData').ignore()

    c.addProperty('EventObject GetEventObject SetEventObject')
    c.addProperty('EventType GetEventType SetEventType')
    c.addProperty('Id GetId SetId')
    c.addProperty('Skipped GetSkipped')
    c.addProperty('Timestamp GetTimestamp SetTimestamp')

    #---------------------------------------
    # wxCommandEvent
    c = module.find('wxCommandEvent')

    # The [G|S]etClientData methods deal with untyped void* values, which we
    # don't support. The [G|S]etClientObject methods use wxClientData instances
    # which we have a MappedType for, so make the ClientData methods just be
    # aliases for ClientObjects. From the Python programmer's perspective they
    # would be virtually the same anyway.
    c.find('SetClientObject.clientObject').transfer = True
    c.find('SetClientObject.clientObject').name = 'data'
    c.find('GetClientData').ignore()
    c.find('SetClientData').ignore()
    c.find('GetClientObject').pyName = 'GetClientData'
    c.find('SetClientObject').pyName = 'SetClientData'
    c.addPyMethod('GetClientObject',
                  '(self)',
                  doc="Alias for :meth:`GetClientData`",
                  body="return self.GetClientData()")
    c.addPyMethod('SetClientObject',
                  '(self, data)',
                  doc="Alias for :meth:`SetClientData`",
                  body="self.SetClientData(data)")
    c.addPyProperty('ClientData GetClientData SetClientData')

    c.addProperty('ExtraLong GetExtraLong SetExtraLong')
    c.addProperty('Int GetInt SetInt')
    c.addProperty('Selection GetSelection')
    c.addProperty('String GetString SetString')

    #---------------------------------------
    # wxPaintEvent
    c = module.find('wxPaintEvent')
    # Although the default ctor is listed as public in the interface, it is
    # magically made private for the users of the library as it can only be
    # created within wxWidgets.
    c.find('wxPaintEvent').protection = 'private'

    #---------------------------------------
    # wxKeyEvent
    c = module.find('wxKeyEvent')

    c.find('GetPosition').findOverload('wxCoord').ignore()
    c.find('GetUnicodeKey').type = 'int'

    c.addCppMethod('void',
                   'SetKeyCode',
                   '(int keyCode)',
                   body="self->m_keyCode = keyCode;")

    c.addCppMethod('void',
                   'SetRawKeyCode',
                   '(int rawKeyCode)',
                   body="self->m_rawCode = rawKeyCode;")

    c.addCppMethod('void',
                   'SetRawKeyFlags',
                   '(int rawFlags)',
                   body="self->m_rawFlags = rawFlags;")

    c.addCppMethod('void',
                   'SetUnicodeKey',
                   '(int uniChar)',
                   body="self->m_uniChar = uniChar;")

    c.addProperty('X GetX')
    c.addProperty('Y GetY')
    c.addProperty('KeyCode GetKeyCode SetKeyCode')
    c.addProperty('Position GetPosition')
    c.addProperty('RawKeyCode GetRawKeyCode SetRawKeyCode')
    c.addProperty('RawKeyFlags GetRawKeyFlags SetRawKeyFlags')
    c.addProperty('UnicodeKey GetUnicodeKey SetUnicodeKey')

    #---------------------------------------
    # wxScrollEvent
    c = module.find('wxScrollEvent')
    c.addProperty('Orientation GetOrientation SetOrientation')
    c.addProperty('Position GetPosition SetPosition')

    #---------------------------------------
    # wxScrollWinEvent
    c = module.find('wxScrollWinEvent')
    c.addProperty('Orientation GetOrientation SetOrientation')
    c.addProperty('Position GetPosition SetPosition')

    #---------------------------------------
    # wxMouseEvent
    c = module.find('wxMouseEvent')

    c.addCppMethod('void',
                   'SetWheelAxis',
                   '(wxMouseWheelAxis wheelAxis)',
                   body="self->m_wheelAxis = wheelAxis;")

    c.addCppMethod('void',
                   'SetWheelRotation',
                   '(int wheelRotation)',
                   body="self->m_wheelRotation = wheelRotation;")

    c.addCppMethod('void',
                   'SetWheelDelta',
                   '(int wheelDelta)',
                   body="self->m_wheelDelta = wheelDelta;")

    c.addCppMethod('void',
                   'SetLinesPerAction',
                   '(int linesPerAction)',
                   body="self->m_linesPerAction = linesPerAction;")

    c.addCppMethod('void',
                   'SetColumnsPerAction',
                   '(int columnsPerAction)',
                   body="self->m_columnsPerAction = columnsPerAction;")

    c.addProperty('WheelAxis GetWheelAxis SetWheelAxis')
    c.addProperty('WheelRotation GetWheelRotation SetWheelRotation')
    c.addProperty('WheelDelta GetWheelDelta SetWheelDelta')
    c.addProperty('LinesPerAction GetLinesPerAction SetLinesPerAction')
    c.addProperty('ColumnsPerAction GetColumnsPerAction SetColumnsPerAction')

    #---------------------------------------
    # wxSetCursorEvent
    c = module.find('wxSetCursorEvent')
    c.addProperty('Cursor GetCursor SetCursor')
    c.addProperty('X GetX')
    c.addProperty('Y GetY')

    #---------------------------------------
    # wxSizeEvent
    c = module.find('wxSizeEvent')
    c.addProperty('Rect GetRect SetRect')
    c.addProperty('Size GetSize SetSize')

    #---------------------------------------
    # wxMoveEvent
    c = module.find('wxMoveEvent')
    c.addProperty('Rect GetRect SetRect')
    c.addProperty('Position GetPosition SetPosition')

    #---------------------------------------
    # wxEraseEvent
    c = module.find('wxEraseEvent')
    c.addProperty('DC GetDC')

    #---------------------------------------
    # wxFocusEvent
    c = module.find('wxFocusEvent')
    c.addProperty('Window GetWindow SetWindow')

    #---------------------------------------
    # wxChildFocusEvent
    c = module.find('wxChildFocusEvent')
    c.addProperty('Window GetWindow')

    #---------------------------------------
    # wxActivateEvent
    c = module.find('wxActivateEvent')
    c.addProperty('Active GetActive')

    #---------------------------------------
    # wxMenuEvent
    c = module.find('wxMenuEvent')
    c.addProperty('Menu GetMenu')
    c.addProperty('MenuId GetMenuId')

    #---------------------------------------
    # wxShowEvent
    c = module.find('wxShowEvent')
    c.find('GetShow').ignore()  # deprecated
    c.addProperty('Show IsShown SetShow')

    #---------------------------------------
    # wxDropFilesEvent
    c = module.find('wxDropFilesEvent')

    # wxDropFilesEvent assumes that the C array of wxString objects will
    # continue to live as long as the event object does, and does not take
    # ownership of the array. Unfortunately the mechanism used to turn the
    # Python list into a C array will also delete it after the API call, and
    # so when wxDropFilesEvent tries to access it later the memory pointer is
    # bad. So we'll copy that array into a special holder class and give that
    # one to the API, and also assign a Python reference to it to the event
    # object, so it will get garbage collected later.
    c.find('wxDropFilesEvent.files').array = True
    c.find('wxDropFilesEvent.files').transfer = True
    c.find('wxDropFilesEvent.noFiles').arraySize = True
    c.addHeaderCode('#include "arrayholder.h"')
    c.find('wxDropFilesEvent').setCppCode_sip("""\
        if (files) {
            wxStringCArrayHolder* holder = new wxStringCArrayHolder;
            holder->m_array = files;
            // Make a PyObject for the holder, and transfer its ownership to self.
            PyObject* pyHolder = sipConvertFromNewType(
                    (void*)holder, sipType_wxStringCArrayHolder, (PyObject*)sipSelf);
            Py_DECREF(pyHolder);
            sipCpp = new sipwxDropFilesEvent(id,(int)noFiles, holder->m_array);
        }
        else
            sipCpp = new sipwxDropFilesEvent(id);
        """)

    c.find('GetFiles').type = 'PyObject*'
    c.find('GetFiles').setCppCode("""\
        int         count   = self->GetNumberOfFiles();
        wxString*   files   = self->GetFiles();
        wxPyThreadBlocker   blocker;
        PyObject*   list    = PyList_New(count);
        if (!list) {
            PyErr_SetString(PyExc_MemoryError, "Can't allocate list of files!");
            return NULL;
        }
        for (int i=0; i<count; i++) {
            PyObject* s = wx2PyString(files[i]);
            PyList_SET_ITEM(list, i, s);
        }
        return list;
        """)

    c.addProperty('Files GetFiles')
    c.addProperty('NumberOfFiles GetNumberOfFiles')
    c.addProperty('Position GetPosition')

    #---------------------------------------
    # wxUpdateUIEvent
    c = module.find('wxUpdateUIEvent')
    c.addProperty('Checked GetChecked Check')
    c.addProperty('Enabled GetEnabled Enable')
    c.addProperty('Shown GetShown Show')
    c.addProperty('Text GetText SetText')

    #---------------------------------------
    # wxMouseCaptureChangedEvent
    c = module.find('wxMouseCaptureChangedEvent')
    c.addProperty('CapturedWindow GetCapturedWindow')

    #---------------------------------------
    # wxPaletteChangedEvent
    c = module.find('wxPaletteChangedEvent')
    c.addProperty('ChangedWindow GetChangedWindow SetChangedWindow')

    #---------------------------------------
    # wxQueryNewPaletteEvent
    c = module.find('wxQueryNewPaletteEvent')
    c.addProperty('PaletteRealized GetPaletteRealized SetPaletteRealized')

    #---------------------------------------
    # wxNavigationKeyEvent
    c = module.find('wxNavigationKeyEvent')
    c.addProperty('CurrentFocus GetCurrentFocus SetCurrentFocus')
    c.addProperty('Direction GetDirection SetDirection')

    #---------------------------------------
    # wxWindowCreateEvent
    c = module.find('wxWindowCreateEvent')
    c.addProperty('Window GetWindow')

    #---------------------------------------
    # wxWindowDestroyEvent
    c = module.find('wxWindowDestroyEvent')
    c.addProperty('Window GetWindow')

    #---------------------------------------
    # wxContextMenuEvent
    c = module.find('wxContextMenuEvent')
    c.addProperty('Position GetPosition SetPosition')

    #---------------------------------------
    # wxIconizeEvent
    c = module.find('wxIconizeEvent')
    # deprecated and removed
    c.find('Iconized').ignore()

    # Apply common fixups for all the event classes
    for name in [n for n in ITEMS if n.endswith('Event')]:
        c = module.find(name)
        tools.fixEventClass(c)

    #---------------------------------------
    # wxEventBlocker
    c = module.find('wxEventBlocker')
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')

    #---------------------------------------
    # wxPropagationDisabler
    c = module.find('wxPropagationDisabler')
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')
    c.addPrivateCopyCtor()

    #---------------------------------------
    # wxPropagateOnce
    c = module.find('wxPropagateOnce')
    c.addPyMethod('__enter__', '(self)', 'return self')
    c.addPyMethod('__exit__', '(self, exc_type, exc_val, exc_tb)',
                  'return False')
    c.addPrivateCopyCtor()

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 36
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxPen')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    # The stipple bitmap ctor is not implemented on wxGTK
    c.find('wxPen').findOverload('wxBitmap').ignore()

    m = c.find('GetDashes')
    assert isinstance(m, etgtools.MethodDef)
    m.find('dashes').ignore()
    m.type = 'wxArrayInt*'
    m.factory = True
    m.setCppCode("""\
        wxArrayInt* arr = new wxArrayInt;
        wxDash* dashes;
        int num = self->GetDashes(&dashes);
        for (int i=0; i<num; i++)
            arr->Add(dashes[i]);
        return arr;
        """)

    # SetDashes does not take ownership of the array passed to it, yet that
    # array must be kept alive as long as the pen lives, so we'll create an
    # array holder object that will be associated with the pen, and that will
    # delete the dashes array when it is deleted.
    #c.find('SetDashes').ignore()
    c.addHeaderCode('#include "arrayholder.h"')
    m = c.find('SetDashes')
    # ignore the existing parameters
    m.find('n').ignore()
    m.find('dash').ignore()
    # add a new one
    m.items.append(etgtools.ParamDef(type='const wxArrayInt&', name='dashes'))
    m.setCppCode_sip("""\
        size_t len = dashes->GetCount();
        wxDashCArrayHolder* holder = new wxDashCArrayHolder;
        holder->m_array = new wxDash[len];
        for (int idx=0; idx<len; idx+=1) {
            holder->m_array[idx] = (*dashes)[idx];
        }
        // Make a PyObject for the holder, and transfer its ownership to self.
        PyObject* pyHolder = sipConvertFromNewType(
                (void*)holder, sipType_wxDashCArrayHolder, (PyObject*)sipSelf);
        Py_DECREF(pyHolder);
        sipCpp->SetDashes(len, holder->m_array);
        """)


    c.addAutoProperties()

    # The stock Pen items are documented as simple pointers, but in reality
    # they are macros that evaluate to a function call that returns a pen
    # pointer, and that is only valid *after* the wx.App object has been
    # created. That messes up the code that SIP generates for them, so we need
    # to come up with another solution. So instead we will just create
    # uninitialized pens in a block of Python code, that will then be
    # intialized later when the wx.App is created.
    c.addCppMethod('void', '_copyFrom', '(const wxPen* other)',
                   "*self = *other;",
                   briefDoc="For internal use only.")  # ??
    pycode = '# These stock pens will be initialized when the wx.App object is created.\n'
    for item in module:
        if '_PEN' in item.name:
            item.ignore()
            pycode += '%s = Pen()\n' % tools.removeWxPrefix(item.name)
    module.addPyCode(pycode)


    # it is delay-initialized, see stockgdi.sip
    module.find('wxThePenList').ignore()



    # Some aliases that should be phased out eventually, (sooner rather than
    # later.) They are already gone (or wrapped by an #if) in the C++ code,
    # and so are not found in the documentation...
    module.addPyCode("""\
        wx.SOLID       = int(wx.PENSTYLE_SOLID)
        wx.DOT         = int(wx.PENSTYLE_DOT)
        wx.LONG_DASH   = int(wx.PENSTYLE_LONG_DASH)
        wx.SHORT_DASH  = int(wx.PENSTYLE_SHORT_DASH)
        wx.DOT_DASH    = int(wx.PENSTYLE_DOT_DASH)
        wx.USER_DASH   = int(wx.PENSTYLE_USER_DASH)
        wx.TRANSPARENT = int(wx.PENSTYLE_TRANSPARENT)
        """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 37
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.


    # Add a ctor/factory for the Mac that can use the theme brush
    module.addCppCode("""\
    #ifdef __WXMAC__
    #include <wx/osx/private.h>
    #endif
    """)
    module.addCppFunction('wxColour*', 'MacThemeColour', '(int themeBrushID)', """\
    #ifdef __WXMAC__
        return new wxColour(wxMacCreateCGColorFromHITheme(themeBrushID));
    #else
        wxPyRaiseNotImplemented();
        return NULL;
    #endif
    """, factory=True)


    # Change this macro into a value so we wont have problems when SIP takes its
    # address
    module.addCppCode("""\
    #undef wxTransparentColour
    wxColour wxTransparentColour(0, 0, 0, wxALPHA_TRANSPARENT);
    """)


    module.find('wxFromString').ignore()
    module.find('wxToString').ignore()

    module.find('wxALPHA_TRANSPARENT').type = 'const int'
    module.find('wxALPHA_OPAQUE').type = 'const int'



    c = module.find('wxColour')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    # Just set mustHaveApp for the copy ctor as it may need to use the colour
    # database to look up color names.
    c.find('wxColour').findOverload('const wxColour &').mustHaveApp()

    # Hide the string ctor so our typemap will be invoked for the copy ctor instead.
    c.find('wxColour').findOverload('wxString').ignore()

    c.addProperty('Pixel GetPixel')
    c.addProperty('RGB GetRGB SetRGB')
    c.addProperty('RGBA GetRGBA SetRGBA')
    c.addProperty('red Red')
    c.addProperty('green Green')
    c.addProperty('blue Blue')
    c.addProperty('alpha Alpha')

    c.find('GetPixel').ignore()  # We need to add a typcast
    c.addCppMethod('wxIntPtr*', 'GetPixel', '()', """\
        #ifdef __WXGTK3__
            return new wxIntPtr(0);
        #else
            return new wxIntPtr((wxIntPtr)self->GetPixel());
        #endif
        """)

    # Set a flag on the return value and parameter types that are 'unsigned char'
    # such that they will be treated as an integer instead of a string.
    for item in c.allItems():
        if hasattr(item, 'type') and item.type == 'unsigned char':
            item.pyInt = True


    c.find('ChangeLightness.r').inOut = True
    c.find('ChangeLightness.g').inOut = True
    c.find('ChangeLightness.b').inOut = True

    c.find('MakeDisabled.r').inOut = True
    c.find('MakeDisabled.g').inOut = True
    c.find('MakeDisabled.b').inOut = True

    c.find('MakeGrey.r').inOut = True
    c.find('MakeGrey.g').inOut = True
    c.find('MakeGrey.b').inOut = True
    c.find('MakeGrey').findOverload('double').find('r').inOut = True
    c.find('MakeGrey').findOverload('double').find('g').inOut = True
    c.find('MakeGrey').findOverload('double').find('b').inOut = True

    c.find('MakeMono.r').out = True
    c.find('MakeMono.g').out = True
    c.find('MakeMono.b').out = True


    # The stock Colour items are documented as simple pointers, but in
    # reality they are macros that evaluate to a function call that returns a
    # Colour pointer, and that is only valid *after* the wx.App object has
    # been created. That messes up the code that SIP generates for them. So
    # instead we will just create uninitialized colours in a block of Python
    # code, that will then be initialized later when the wx.App is created.
    c.addCppMethod('void', '_copyFrom', '(const wxColour* other)',
                   "*self = *other;",
                   briefDoc="For internal use only.")  # ??
    pycode = '# These stock colours will be initialized when the wx.App object is created.\n'
    for name in [ 'wxBLACK',
                  'wxBLUE',
                  'wxCYAN',
                  'wxGREEN',
                  'wxYELLOW',
                  'wxLIGHT_GREY',
                  'wxRED',
                  'wxWHITE',
                  ]:
        item = module.find(name)
        item.ignore()
        pycode += '%s = Colour()\n' % tools.removeWxPrefix(item.name)
    module.addPyCode(pycode)


    c.addCppMethod('PyObject*', 'Get', '(bool includeAlpha=true)', """\
        int red = -1;
        int green = -1;
        int blue = -1;
        int alpha = wxALPHA_OPAQUE;
        if (self->IsOk()) {
            red =   self->Red();
            green = self->Green();
            blue =  self->Blue();
            alpha = self->Alpha();
        }
        wxPyThreadBlocker blocker;
        if (includeAlpha)
            return sipBuildResult(0, "(iiii)", red, green, blue, alpha);
        else
            return sipBuildResult(0, "(iii)", red, green, blue);
        """,
        pyArgsString="(includeAlpha=True) -> (r,g,b) or (r,g,b,a)",
        briefDoc="""\
        Returns the RGB intensity values as a tuple, optionally the alpha value as well.""")

    tools.addGetIMMethodTemplate(module, c, ['red', 'green', 'blue', 'alpha'])


    # Add sequence protocol methods and other goodies
    c.addPyMethod('__str__', '(self)',             'return str(self.Get())')
    c.addPyMethod('__repr__', '(self)',            'return "wx.Colour"+str(self.Get())')
    c.addPyMethod('__len__', '(self)',             'return len(self.Get())')
    c.addPyMethod('__nonzero__', '(self)',         'return self.IsOk()')
    c.addPyMethod('__reduce__', '(self)',          'return (Colour, self.Get())')
    c.addPyMethod('__getitem__', '(self, idx)',    'return self.Get()[idx]')
    c.addPyMethod('__setitem__', '(self, idx, val)',
                  """\
                  if idx == 0:   self.red = val
                  elif idx == 1: self.green = val
                  elif idx == 2: self.blue = val
                  elif idx == 3: self.alpha = val
                  else: raise IndexError
                  """)
    c.addPyCode('Colour.__safe_for_unpickling__ = True')

    # Types that can be converted to wx.Colour:
    #     wxColour (duh)
    #     Sequence with 3 or 4 integers
    #     String with color name or #RRGGBB or #RRGGBBAA format
    #     None  (converts to wxNullColour)
    c.allowNone = True
    c.convertFromPyObject = """\
        // is it just a typecheck?
        if (!sipIsErr) {
            if (sipPy == Py_None)
                return 1;
            if (sipCanConvertToType(sipPy, sipType_wxColour, SIP_NO_CONVERTORS))
                return 1;
            if (PyBytes_Check(sipPy) || PyUnicode_Check(sipPy))
                return 1;
            if (wxPyNumberSequenceCheck(sipPy, 4) || wxPyNumberSequenceCheck(sipPy, 3)) {
                return 1;
            }
            return 0;
        }

        // otherwise do the conversion
        // is it None?
        if (sipPy == Py_None) {
            *sipCppPtr = new wxColour(wxNullColour);
            return sipGetState(sipTransferObj);
        }
        // Is it a string?
        else if (PyBytes_Check(sipPy) || PyUnicode_Check(sipPy)) {
            wxString spec = Py2wxString(sipPy);
            if (!spec.empty()
                && spec.GetChar(0) == '#'
                && (spec.length() == 7 || spec.length() == 9)) {  // It's  #RRGGBB[AA]
                long red, green, blue;
                red = green = blue = 0;
                spec.Mid(1,2).ToLong(&red,   16);
                spec.Mid(3,2).ToLong(&green, 16);
                spec.Mid(5,2).ToLong(&blue,  16);

                if (spec.length() == 7)         // no alpha
                    *sipCppPtr = new wxColour(red, green, blue);
                else {                          // yes alpha
                    long alpha;
                    spec.Mid(7,2).ToLong(&alpha, 16);
                    *sipCppPtr = new wxColour(red, green, blue, alpha);
                }
                return sipGetState(sipTransferObj);
            }
            else {                                       // assume it's a colour name
                // check if alpha is there too
                int pos;
                if (((pos = spec.Find(':', true)) != wxNOT_FOUND) && (pos == spec.length()-3)) {
                    long alpha;
                    spec.Right(2).ToLong(&alpha, 16);
                    wxColour c = wxColour(spec.Left(spec.length()-3));
                    *sipCppPtr = new wxColour(c.Red(), c.Green(), c.Blue(), alpha);
                }
                else
                    *sipCppPtr = new wxColour(spec);
                return sipGetState(sipTransferObj);
            }
        }
        // Is it a sequence? (if so then length was checked above)
        else if (wxPyNumberSequenceCheck(sipPy)) {
            size_t len = PySequence_Size(sipPy);

            PyObject* o1 = PySequence_ITEM(sipPy, 0);
            PyObject* o2 = PySequence_ITEM(sipPy, 1);
            PyObject* o3 = PySequence_ITEM(sipPy, 2);
            if (len == 3)
                *sipCppPtr = new wxColour(wxPyInt_AsLong(o1), wxPyInt_AsLong(o2), wxPyInt_AsLong(o3));
            else {
                PyObject* o4 = PySequence_ITEM(sipPy, 3);
                *sipCppPtr = new wxColour(wxPyInt_AsLong(o1), wxPyInt_AsLong(o2), wxPyInt_AsLong(o3),
                                          wxPyInt_AsLong(o4));
                Py_DECREF(o4);
            }
            Py_DECREF(o1);
            Py_DECREF(o2);
            Py_DECREF(o3);
            return sipGetState(sipTransferObj);
        }

        // if we get this far then it must already be a wxColour instance
        *sipCppPtr = reinterpret_cast<wxColour*>(sipConvertToType(
            sipPy, sipType_wxColour, sipTransferObj, SIP_NO_CONVERTORS, 0, sipIsErr));
        return 0; // not a new instance
    """

    module.addPyCode('NamedColour = wx.deprecated(Colour, "Use Colour instead.")')


    # Just for TESTING, remove it later
    module.addCppCode("""\
    wxColour testColourTypeMap(const wxColour& c)
    {
        return c;
    }
    """)
    module.addItem(etgtools.WigCode("""\
    wxColour testColourTypeMap(const wxColour& c);
    """))


    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 38
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    # Add a ctor/factory for the Mac that can use the theme brush
    module.addCppCode("""\
    #ifdef __WXMAC__
    #include <wx/osx/private.h>
    #endif
    """)
    module.addCppFunction('wxColour*',
                          'MacThemeColour',
                          '(int themeBrushID)',
                          """\
    #ifdef __WXMAC__
        return new wxColour(wxMacCreateCGColorFromHITheme(themeBrushID));
    #else
        wxPyRaiseNotImplemented();
        return NULL;
    #endif
    """,
                          factory=True)

    # Change this macro into a value so we wont have problems when SIP takes its
    # address
    module.addCppCode("""\
    #undef wxTransparentColour
    wxColour wxTransparentColour(0, 0, 0, wxALPHA_TRANSPARENT);
    """)

    module.find('wxFromString').ignore()
    module.find('wxToString').ignore()

    module.find('wxALPHA_TRANSPARENT').type = 'const int'
    module.find('wxALPHA_OPAQUE').type = 'const int'

    c = module.find('wxColour')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    # Hide the string ctor so our typemap will be invoked for the copy ctor instead.
    c.find('wxColour').findOverload('wxString').ignore()

    c.addProperty('Pixel GetPixel')
    c.addProperty('RGB GetRGB SetRGB')
    c.addProperty('RGBA GetRGBA SetRGBA')
    c.addProperty('red Red')
    c.addProperty('green Green')
    c.addProperty('blue Blue')
    c.addProperty('alpha Alpha')

    c.find('GetPixel').ignore()  # We need to add a typcast
    c.addCppMethod(
        'wxIntPtr*', 'GetPixel', '()', """\
        #ifdef __WXGTK3__
            return new wxIntPtr(0);
        #else
            return new wxIntPtr((wxIntPtr)self->GetPixel());
        #endif
        """)

    # Set a flag on the return value and parameter types that are 'unsigned char'
    # such that they will be treated as an integer instead of a string.
    for item in c.allItems():
        if hasattr(item, 'type') and item.type == 'unsigned char':
            item.pyInt = True

    c.find('ChangeLightness.r').inOut = True
    c.find('ChangeLightness.g').inOut = True
    c.find('ChangeLightness.b').inOut = True

    c.find('MakeDisabled.r').inOut = True
    c.find('MakeDisabled.g').inOut = True
    c.find('MakeDisabled.b').inOut = True

    c.find('MakeGrey.r').inOut = True
    c.find('MakeGrey.g').inOut = True
    c.find('MakeGrey.b').inOut = True
    c.find('MakeGrey').findOverload('double').find('r').inOut = True
    c.find('MakeGrey').findOverload('double').find('g').inOut = True
    c.find('MakeGrey').findOverload('double').find('b').inOut = True

    c.find('MakeMono.r').out = True
    c.find('MakeMono.g').out = True
    c.find('MakeMono.b').out = True

    # The stock Colour items are documented as simple pointers, but in
    # reality they are macros that evaluate to a function call that returns a
    # Colour pointer, and that is only valid *after* the wx.App object has
    # been created. That messes up the code that SIP generates for them. So
    # instead we will just create uninitialized colours in a block of Python
    # code, that will then be initialized later when the wx.App is created.
    c.addCppMethod('void',
                   '_copyFrom',
                   '(const wxColour* other)',
                   "*self = *other;",
                   briefDoc="For internal use only.")  # ??
    pycode = '# These stock colours will be initialized when the wx.App object is created.\n'
    for name in [
            'wxBLACK',
            'wxBLUE',
            'wxCYAN',
            'wxGREEN',
            'wxYELLOW',
            'wxLIGHT_GREY',
            'wxRED',
            'wxWHITE',
    ]:
        item = module.find(name)
        item.ignore()
        pycode += '%s = Colour()\n' % tools.removeWxPrefix(item.name)
    module.addPyCode(pycode)

    c.addCppMethod('PyObject*',
                   'Get',
                   '(bool includeAlpha=true)',
                   """\
        int red = -1;
        int green = -1;
        int blue = -1;
        int alpha = wxALPHA_OPAQUE;
        if (self->IsOk()) {
            red =   self->Red();
            green = self->Green();
            blue =  self->Blue();
            alpha = self->Alpha();
        }
        if (includeAlpha)
            return sipBuildResult(0, "(iiii)", red, green, blue, alpha);
        else
            return sipBuildResult(0, "(iii)", red, green, blue);
        """,
                   pyArgsString="(includeAlpha=True) -> (r,g,b) or (r,g,b,a)",
                   briefDoc="""\
        Returns the RGB intensity values as a tuple, optionally the alpha value as well."""
                   )

    # Add sequence protocol methods and other goodies
    c.addPyMethod('__str__', '(self)', 'return str(self.Get())')
    c.addPyMethod('__repr__', '(self)', 'return "wx.Colour"+str(self.Get())')
    c.addPyMethod('__len__', '(self)', 'return len(self.Get())')
    c.addPyMethod('__nonzero__', '(self)', 'return self.IsOk()')
    c.addPyMethod('__reduce__', '(self)', 'return (Colour, self.Get())')
    c.addPyMethod('__getitem__', '(self, idx)', 'return self.Get()[idx]')
    c.addPyMethod(
        '__setitem__', '(self, idx, val)', """\
                  if idx == 0:   self.red = val
                  elif idx == 1: self.green = val
                  elif idx == 2: self.blue = val
                  elif idx == 3: self.alpha = val
                  else: raise IndexError
                  """)
    c.addPyCode('Colour.__safe_for_unpickling__ = True')

    # Types that can be converted to wx.Colour:
    #     wxColour (duh)
    #     Sequence with 3 or 4 integers
    #     String with color name or #RRGGBB or #RRGGBBAA format
    #     None  (converts to wxNullColour)
    c.allowNone = True
    c.convertFromPyObject = """\
        // is it just a typecheck?
        if (!sipIsErr) {
            if (sipPy == Py_None)
                return 1;
            if (sipCanConvertToType(sipPy, sipType_wxColour, SIP_NO_CONVERTORS))
                return 1;
            if (PyBytes_Check(sipPy) || PyUnicode_Check(sipPy))
                return 1;
            if (PySequence_Check(sipPy)) {
                size_t len = PySequence_Size(sipPy);
                if (len != 3 && len != 4)
                    return 0;
                // ensure all the items in the sequence are numbers
                for (int idx=0; idx<len; idx+=1) {
                    PyObject* o = PySequence_ITEM(sipPy, idx);
                    bool isNum = PyNumber_Check(o);
                    Py_DECREF(o);
                    if (!isNum)
                        return 0;
                }
                return 1;
            }
            return 0;
        }
        // otherwise do the conversion
        // is it None?
        if (sipPy == Py_None) {
            *sipCppPtr = new wxColour(wxNullColour);
            return sipGetState(sipTransferObj);
        }
        // Is it a string?
        else if (PyBytes_Check(sipPy) || PyUnicode_Check(sipPy)) {
            wxString spec = Py2wxString(sipPy);
            if (!spec.empty()
                && spec.GetChar(0) == '#'
                && (spec.length() == 7 || spec.length() == 9)) {  // It's  #RRGGBB[AA]
                long red, green, blue;
                red = green = blue = 0;
                spec.Mid(1,2).ToLong(&red,   16);
                spec.Mid(3,2).ToLong(&green, 16);
                spec.Mid(5,2).ToLong(&blue,  16);

                if (spec.length() == 7)         // no alpha
                    *sipCppPtr = new wxColour(red, green, blue);
                else {                          // yes alpha
                    long alpha;
                    spec.Mid(7,2).ToLong(&alpha, 16);
                    *sipCppPtr = new wxColour(red, green, blue, alpha);
                }
                return sipGetState(sipTransferObj);
            }
            else {                                       // assume it's a colour name
                // check if alpha is there too
                int pos;
                if (((pos = spec.Find(':', true)) != wxNOT_FOUND) && (pos == spec.length()-3)) {
                    long alpha;
                    spec.Right(2).ToLong(&alpha, 16);
                    wxColour c = wxColour(spec.Left(spec.length()-3));
                    *sipCppPtr = new wxColour(c.Red(), c.Green(), c.Blue(), alpha);
                }
                else
                    *sipCppPtr = new wxColour(spec);
                return sipGetState(sipTransferObj);
            }
        }
        // Is it a 3 or 4 element sequence?
        else if (PySequence_Check(sipPy)) {
            size_t len = PyObject_Length(sipPy);

            PyObject* o1 = PySequence_GetItem(sipPy, 0);
            PyObject* o2 = PySequence_GetItem(sipPy, 1);
            PyObject* o3 = PySequence_GetItem(sipPy, 2);
            if (len == 3)
                *sipCppPtr = new wxColour(wxPyInt_AsLong(o1), wxPyInt_AsLong(o2), wxPyInt_AsLong(o3));
            else {
                PyObject* o4 = PySequence_GetItem(sipPy, 3);
                *sipCppPtr = new wxColour(wxPyInt_AsLong(o1), wxPyInt_AsLong(o2), wxPyInt_AsLong(o3),
                                          wxPyInt_AsLong(o4));
                Py_DECREF(o4);
            }
            Py_DECREF(o1);
            Py_DECREF(o2);
            Py_DECREF(o3);
            return sipGetState(sipTransferObj);
        }

        // if we get this far then it must already be a wxColour instance
        *sipCppPtr = reinterpret_cast<wxColour*>(sipConvertToType(
            sipPy, sipType_wxColour, sipTransferObj, SIP_NO_CONVERTORS, 0, sipIsErr));
        return 0; // not a new instance
    """

    module.addPyCode(
        'NamedColour = wx.deprecated(Colour, "Use Colour instead.")')

    # Just for TESTING, remove it later
    module.addCppCode("""\
    wxColour testColourTypeMap(const wxColour& c)
    {
        return c;
    }
    """)
    module.addItem(
        etgtools.WigCode("""\
    wxColour testColourTypeMap(const wxColour& c);
    """))

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 39
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)
    
    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxBitmap')
    assert isinstance(c, etgtools.ClassDef)
    
    tools.removeVirtuals(c)

    c.find('wxBitmap.bits').type = 'const char*'
    c.find('wxBitmap.type').default = 'wxBITMAP_TYPE_ANY'
    c.find('LoadFile.type').default = 'wxBITMAP_TYPE_ANY'

    c.find('wxBitmap').findOverload('(const char *const *bits)').ignore()

    c.addCppCtor('(PyObject* listOfBytes)',
        doc="Construct a Bitmap from a list of strings formatted as XPM data.",
        body="""\
            wxPyThreadBlocker blocker;
            char**    cArray = NULL;
            int       count;
            char      errMsg[] = "Expected a list of bytes objects.";
            
            if (!PyList_Check(listOfBytes)) {
                PyErr_SetString(PyExc_TypeError, errMsg);
                return NULL;
            }
            count = PyList_Size(listOfBytes);
            cArray = new char*[count];

            for(int x=0; x<count; x++) {
                PyObject* item = PyList_GET_ITEM(listOfBytes, x);
                if (!PyBytes_Check(item)) {
                    PyErr_SetString(PyExc_TypeError, errMsg);
                    delete [] cArray;
                    return NULL;
                }
                cArray[x] = PyBytes_AsString(item);
            }
            wxBitmap* bmp = new wxBitmap(cArray);
            delete [] cArray;
            return bmp;
            """)


    c.find('SetMask.mask').transfer = True

    c.addCppMethod('void', 'SetMaskColour', '(const wxColour& colour)', """\
        wxMask* mask = new wxMask(*self, *colour);
        self->SetMask(mask);
        """)

    c.addCppMethod('int', '__nonzero__', '()', """\
        return self->IsOk();
        """)
        
    c.addCppMethod('long', 'GetHandle', '()',
        doc='MSW-only method to fetch the windows handle for the bitmap.',
        body="""\
            #ifdef __WXMSW__
                return (long)self->GetHandle();
            #else
                return 0;
            #endif
            """)
        
    c.addCppMethod('void', 'SetHandle', '(long handle)',
        doc='MSW-only method to set the windows handle for the bitmap.',
        body="""\
            #ifdef __WXMSW__
                self->SetHandle((WXHANDLE)handle);
            #endif
            """)

    c.addCppMethod('void', 'SetSize', '(const wxSize& size)',
        doc='Set the bitmap size (does not alter the existing native bitmap data or image size).',
        body="""\
            self->SetWidth(size->x);
            self->SetHeight(size->y);
            """)



    # On MSW the bitmap handler classes are different than what is
    # documented, and this causes compile errors. Nobody has needed them from
    # Python thus far, so just ignore them all for now.
    for m in c.find('FindHandler').all():
        m.ignore()
    c.find('AddHandler').ignore()
    c.find('CleanUpHandlers').ignore()
    c.find('GetHandlers').ignore()
    c.find('InsertHandler').ignore()
    c.find('RemoveHandler').ignore()
    
    # This one is called from the wx startup code, it's not needed in Python
    # so nuke it too since we're nuking all the others.
    c.find('InitStandardHandlers').ignore()
    
    module.find('wxBitmapHandler').ignore()
    #module.addItem(tools.wxListWrapperTemplate('wxList', 'wxBitmapHandler', module))


    #-----------------------------------------------------------------------
    # Declarations, helpers and methods for converting to/from buffer objects
    # with raw bitmap access.

    from etgtools import EnumDef, EnumValueDef
    e = EnumDef(name='wxBitmapBufferFormat')
    e.items.extend([ EnumValueDef(name='wxBitmapBufferFormat_RGB'),
                     EnumValueDef(name='wxBitmapBufferFormat_RGBA'),
                     EnumValueDef(name='wxBitmapBufferFormat_RGB32'),
                     EnumValueDef(name='wxBitmapBufferFormat_ARGB32'),
                     ])
    module.insertItem(0, e)

    c.includeCppCode('src/bitmap_ex.cpp')
    module.addHeaderCode('#include "bitmap_ex.h"')


    c.addCppMethod('void', 'CopyFromBuffer', 
        '(wxPyBuffer* data, wxBitmapBufferFormat format=wxBitmapBufferFormat_RGB, int stride=-1)',
        doc="""\
            Copy data from a buffer object to replace the bitmap pixel data.
            Default format is plain RGB, but other formats are now supported as
            well.  The following symbols are used to specify the format of the
            bytes in the buffer:
        
                =============================  ================================
                wx.BitmapBufferFormat_RGB      A simple sequence of RGB bytes
                wx.BitmapBufferFormat_RGBA     A simple sequence of RGBA bytes
                wx.BitmapBufferFormat_ARGB32   A sequence of 32-bit values in native endian order, with alpha in the upper 8 bits, followed by red, green, and blue.
                wx.BitmapBufferFormat_RGB32    Same as above but the alpha byte is ignored.
                =============================  ================================""",
        body="""\
            wxPyCopyBitmapFromBuffer(self, (byte*)data->m_ptr, data->m_len, format, stride);
        """)


    c.addCppMethod('void', 'CopyToBuffer',
        '(wxPyBuffer* data, wxBitmapBufferFormat format=wxBitmapBufferFormat_RGB, int stride=-1)',
        doc="""\
            Copy pixel data to a buffer object.  See :meth:`CopyFromBuffer` for buffer
            format details.""",
        body="""\
            wxPyCopyBitmapToBuffer(self, (byte*)data->m_ptr, data->m_len, format, stride);
            """)


    # Some bitmap factories added as static methods
    
    c.addCppMethod('wxBitmap*', 'FromBufferAndAlpha', 
        '(int width, int height, wxPyBuffer* data, wxPyBuffer* alpha)',
        isStatic=True,
        factory=True,
        doc="""\
            Creates a :class:`Bitmap` from in-memory data.  The data and alpha 
            parameters must be a Python object that implements the buffer 
            interface, such as a string, bytearray, etc.  The data object 
            is expected to contain a series of RGB bytes and be at least 
            width*height*3 bytes long, while the alpha object is expected 
            to be width*height bytes long and represents the image's alpha
            channel.  On Windows and Mac the RGB values will be 
            'premultiplied' by the alpha values.  (The other platforms do 
            the multiplication themselves.)
        
            Unlike :func:`wx.ImageFromBuffer` the bitmap created with this function
            does not share the memory block with the buffer object.  This is
            because the native pixel buffer format varies on different
            platforms, and so instead an efficient as possible copy of the
            data is made from the buffer object to the bitmap's native pixel
            buffer.            
            """,
        body="""\
            if (!data->checkSize(width*height*3) || !alpha->checkSize(width*height))
                return NULL;
            
            byte* ddata = (byte*)data->m_ptr;
            byte* adata = (byte*)alpha->m_ptr;
            wxBitmap* bmp = new wxBitmap(width, height, 32);
            
            wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
            if (! pixData) {
                wxPyErr_SetString(PyExc_RuntimeError, "Failed to gain raw access to bitmap data.");
                return NULL;
            }
                    
            wxAlphaPixelData::Iterator p(pixData);
            for (int y=0; y<height; y++) {
                wxAlphaPixelData::Iterator rowStart = p;
                for (int x=0; x<width; x++) {
                    byte a = *(adata++);
                    p.Red()   = wxPy_premultiply(*(ddata++), a);
                    p.Green() = wxPy_premultiply(*(ddata++), a);
                    p.Blue()  = wxPy_premultiply(*(ddata++), a);
                    p.Alpha() = a;
                    ++p; 
                }
                p = rowStart;
                p.OffsetY(pixData, 1);
            }
            return bmp;            
            """)

    c.addCppMethod('wxBitmap*', 'FromBuffer', '(int width, int height, wxPyBuffer* data)',
        isStatic=True,
        factory=True,
        doc="""\
            Creates a :class:`Bitmap` from in-memory data.  The data parameter 
            must be a Python object that implements the buffer interface, such 
            as a string, bytearray, etc.  The data object is expected to contain 
            a series of RGB bytes and be at least width*height*3 bytes long.
            
            Unlike :func:`wx.ImageFromBuffer` the bitmap created with this function
            does not share the memory block with the buffer object.  This is
            because the native pixel buffer format varies on different
            platforms, and so instead an efficient as possible copy of the
            data is made from the buffer object to the bitmap's native pixel
            buffer.            
            """,
        body="""\
            wxBitmap* bmp = new wxBitmap(width, height, 24);
            wxPyCopyBitmapFromBuffer(bmp, (byte*)data->m_ptr, data->m_len, wxBitmapBufferFormat_RGB);
            wxPyThreadBlocker blocker;
            if (PyErr_Occurred()) {
                delete bmp;
                bmp = NULL;
            }
            return bmp;
            """)

    module.addPyFunction('BitmapFromBuffer', '(width, height, dataBuffer, alphaBuffer=None)',
        deprecated="Use :meth:`Bitmap.FromBuffer` or :meth:`Bitmap.FromBufferAndAlpha` instead.",
        doc='A compatibility wrapper for :meth:`Bitmap.FromBuffer` and :meth:`Bitmap.FromBufferAndAlpha`',
        body="""\
            if alphaBuffer is not None:
                return Bitmap.FromBufferAndAlpha(width, height, dataBuffer, alphaBuffer)
            else:
                return Bitmap.FromBuffer(width, height, dataBuffer)
            """)




    c.addCppMethod('wxBitmap*', 'FromBufferRGBA', '(int width, int height, wxPyBuffer* data)',
        isStatic=True,
        factory=True,
        doc="""\
            Creates a :class:`Bitmap` from in-memory data.  The data parameter 
            must be a Python object that implements the buffer interface, such 
            as a string, bytearray, etc.  The data object is expected to contain 
            a series of RGBA bytes and be at least width*height*4 bytes long.
            On Windows and Mac the RGB values will be 'premultiplied' by the 
            alpha values.  (The other platforms do the multiplication themselves.)
            
            Unlike :func:`wx.ImageFromBuffer` the bitmap created with this function
            does not share the memory block with the buffer object.  This is
            because the native pixel buffer format varies on different
            platforms, and so instead an efficient as possible copy of the
            data is made from the buffer object to the bitmap's native pixel
            buffer.            
            """,
        body="""\
            wxBitmap* bmp = new wxBitmap(width, height, 32);
            wxPyCopyBitmapFromBuffer(bmp, (byte*)data->m_ptr, data->m_len, wxBitmapBufferFormat_RGBA);
            wxPyThreadBlocker blocker;
            if (PyErr_Occurred()) {
                delete bmp;
                bmp = NULL;
            }
            return bmp;
            """)

    module.addPyFunction('BitmapFromBufferRGBA', '(width, height, dataBuffer)',
        deprecated="Use :meth:`Bitmap.FromBufferRGBA` instead.",
        doc='A compatibility wrapper for :meth:`Bitmap.FromBufferRGBA`',
        body='return Bitmap.FromBufferRGBA(width, height, dataBuffer)')




    c.addCppMethod('wxBitmap*', 'FromRGBA', 
        '(int width, int height, byte red=0, byte green=0, byte blue=0, byte alpha=0)',
        isStatic=True,
        factory=True,
        doc="""\
            Creates a new empty 32-bit :class:`Bitmap` where every pixel has been
            initialized with the given RGBA values.
            """,
        body="""\
            if ( !(width > 0 && height > 0) ) {
                wxPyErr_SetString(PyExc_ValueError, "Width and height must be greater than zero");
                return NULL;
            }

            wxBitmap* bmp = new wxBitmap(width, height, 32);
            wxAlphaPixelData pixData(*bmp, wxPoint(0,0), wxSize(width,height));
            if (! pixData) {
                wxPyErr_SetString(PyExc_RuntimeError, "Failed to gain raw access to bitmap data.");
                return NULL;
            }
                
            wxAlphaPixelData::Iterator p(pixData);
            for (int y=0; y<height; y++) {
                wxAlphaPixelData::Iterator rowStart = p;
                for (int x=0; x<width; x++) {
                    p.Red()   = wxPy_premultiply(red, alpha);
                    p.Green() = wxPy_premultiply(green, alpha);
                    p.Blue()  = wxPy_premultiply(blue, alpha);
                    p.Alpha() = alpha;
                    ++p; 
                }
                p = rowStart;
                p.OffsetY(pixData, 1);
            }
            return bmp;        
            """)

    module.addPyFunction('EmptyBitmapRGBA', '(width, height, red=0, green=0, blue=0, alpha=0)',
        deprecated="Use :meth:`Bitmap.FromRGBA` instead.",
        doc='A compatibility wrapper for :meth:`Bitmap.FromRGBA`',
        body='return Bitmap.FromRGBA(width, height, red, green, blue, alpha)')

    #-----------------------------------------------------------------------

    # For compatibility:
    module.addPyFunction('EmptyBitmap', '(width, height, depth=BITMAP_SCREEN_DEPTH)',
                         deprecated="Use :class:`Bitmap` instead",
                         doc='A compatibility wrapper for the wx.Bitmap(width, height, depth) constructor',
                         body='return Bitmap(width, height, depth)')

    module.addPyFunction('BitmapFromImage', '(image)',
                         deprecated="Use :class:`Bitmap` instead",
                         doc='A compatibility wrapper for the wx.Bitmap(wx.Image) constructor',
                         body='return Bitmap(image)')

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 40
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    module.addHeaderCode('#include <wx/gdicmn.h>')

    def markFactories(klass):
        for func in klass.allItems():
            if isinstance(func, etgtools.FunctionDef) \
               and func.name.startswith('Create') \
               and '*' in func.type:
                func.factory = True

    #---------------------------------------------
    c = module.find('wxGraphicsObject')
    assert isinstance(c, etgtools.ClassDef)
    c.addCppMethod('bool', 'IsOk', '()', 'return !self->IsNull();')
    c.addCppMethod('int', '__nonzero__', '()', "return !self->IsNull();")

    #---------------------------------------------
    c = module.find('wxGraphicsContext')
    assert isinstance(c, etgtools.ClassDef)
    markFactories(c)
    tools.removeVirtuals(c)
    c.abstract = True

    # Ensure that the target DC or image lives as long as the GC does. NOTE:
    # Since the Creates are static methods there is no self to associate the
    # extra reference with, but since they are factories then that extra
    # reference will be held by the return value of the factory instead.
    for m in c.find('Create').all():
        for p in m.items:
            if 'DC' in p.name or p.name == 'image':
                p.keepReference = True

    # FIXME: Handle wxEnhMetaFileDC?
    c.find('Create').findOverload('wxEnhMetaFileDC').ignore()

    c.find('GetSize.width').out = True
    c.find('GetSize.height').out = True
    c.find('GetDPI.dpiX').out = True
    c.find('GetDPI.dpiY').out = True

    m = c.find('GetPartialTextExtents')
    m.find('widths').ignore()
    m.type = 'wxArrayDouble*'
    m.factory = True  # a new instance is being created
    m.setCppCode("""\
        wxArrayDouble rval;
        self->GetPartialTextExtents(*text, rval);
        return new wxArrayDouble(rval);
        """)

    m = c.find('GetTextExtent')
    m.pyName = 'GetFullTextExtent'
    m.find('width').out = True
    m.find('height').out = True
    m.find('descent').out = True
    m.find('externalLeading').out = True

    c.addCppMethod(
        'PyObject*',
        'GetTextExtent',
        '(const wxString& text)',
        pyArgsString="(text) -> (width, height)",
        doc=
        "Gets the dimensions of the string using the currently selected font.",
        body="""\
        wxDouble width = 0.0, height = 0.0;
        self->GetTextExtent(*text, &width, &height, NULL, NULL);
        return sipBuildResult(0, "(dd)", width, height);
        """)

    c.addPyCode(
        "GraphicsContext.DrawRotatedText = wx.deprecated(GraphicsContext.DrawText, 'Use DrawText instead.')"
    )

    c.addCppCode(
        tools.ObjArrayHelperTemplate(
            'wxPoint2D', 'sipType_wxPoint2DDouble',
            "Expected a sequence of length-2 sequences or wx.Point2D objects.")
    )

    # we'll reimplement this overload as StrokeLineSegments
    c.find('StrokeLines').findOverload('beginPoints').ignore()
    c.addCppMethod('void',
                   'StrokeLineSegments',
                   '(PyObject* beginPoints, PyObject* endPoints)',
                   pyArgsString="(beginPoint2Ds, endPoint2Ds)",
                   doc="Stroke disconnected lines from begin to end points.",
                   body="""\
        size_t c1, c2, count;
        wxPoint2D* beginP = wxPoint2D_array_helper(beginPoints, &c1);
        wxPoint2D* endP =   wxPoint2D_array_helper(endPoints, &c2);

        if ( beginP != NULL && endP != NULL ) {
            count = wxMin(c1, c2);
            self->StrokeLines(count, beginP, endP);
        }
        delete [] beginP;
        delete [] endP;
        """)

    # Also reimplement the main StrokeLines method to reuse the same helper
    # function as StrokLineSegments
    m = c.find('StrokeLines').findOverload('points').ignore()
    c.addCppMethod('void',
                   'StrokeLines',
                   '(PyObject* points)',
                   pyArgsString="(point2Ds)",
                   doc="Stroke lines conencting all the points.",
                   body="""\
        size_t count;
        wxPoint2D* ptsArray = wxPoint2D_array_helper(points, &count);

        if ( ptsArray != NULL ) {
            self->StrokeLines(count, ptsArray);
            delete [] ptsArray;
        }
        """)

    # and once more for DrawLines
    m = c.find('DrawLines').ignore()
    c.addCppMethod(
        'void',
        'DrawLines',
        '(PyObject* points, wxPolygonFillMode fillStyle = wxODDEVEN_RULE)',
        pyArgsString="(point2Ds, fillStyle=ODDEVEN_RULE)",
        doc="Draws a polygon.",
        body="""\
        size_t count;
        wxPoint2D* ptsArray = wxPoint2D_array_helper(points, &count);

        if ( ptsArray != NULL ) {
            self->DrawLines(count, ptsArray, fillStyle);
            delete [] ptsArray;
        }
        """)

    #---------------------------------------------
    c = module.find('wxGraphicsPath')
    tools.removeVirtuals(c)
    c.find('GetBox').findOverload('wxDouble *x, wxDouble *y').ignore()
    c.find('GetCurrentPoint').findOverload('wxDouble *x, wxDouble *y').ignore()

    #---------------------------------------------
    c = module.find('wxGraphicsRenderer')
    tools.removeVirtuals(c)
    markFactories(c)
    c.abstract = True

    for m in c.find('CreateContext').all():
        for p in m.items:
            if 'DC' in p.name or p.name == 'image':
                p.keepReference = True
    c.find('CreateContextFromImage.image').keepReference = True

    # FIXME: Handle wxEnhMetaFileDC?
    c.find('CreateContext').findOverload('wxEnhMetaFileDC').ignore()

    #---------------------------------------------
    c = module.find('wxGraphicsMatrix')
    tools.removeVirtuals(c)

    c.find('Concat').overloads = []
    c.find('IsEqual').overloads = []

    c.find('Get.a').out = True
    c.find('Get.b').out = True
    c.find('Get.c').out = True
    c.find('Get.d').out = True
    c.find('Get.tx').out = True
    c.find('Get.ty').out = True

    c.find('TransformDistance.dx').inOut = True
    c.find('TransformDistance.dy').inOut = True

    c.find('TransformPoint.x').inOut = True
    c.find('TransformPoint.y').inOut = True

    #---------------------------------------------
    c = module.find('wxGraphicsGradientStops')
    c.addCppMethod('SIP_SSIZE_T',
                   '__len__',
                   '()',
                   body="return (SIP_SSIZE_T)self->GetCount();")
    c.addCppMethod('wxGraphicsGradientStop*',
                   '__getitem__',
                   '(ulong n)',
                   pyArgsString='(n)',
                   body="return new wxGraphicsGradientStop(self->Item(n));",
                   factory=True)

    #---------------------------------------------
    # Use the pyNames we set for these classes in geometry.py so the old
    # names do not show up in the docstrings, etc.
    tools.changeTypeNames(module, 'wxPoint2DDouble', 'wxPoint2D')
    tools.changeTypeNames(module, 'wxRect2DDouble', 'wxRect2D')

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 41
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    # Use wxPyUserData for the clientData values instead of a plain wxObject
    def _fixClientData(c):
        for item in c.allItems():
            if isinstance(item,
                          etgtools.ParamDef) and item.name == 'clientData':
                item.type = 'wxPyUserData*'
                item.transfer = True

    #---------------------------------------------
    c = module.find('wxToolBarToolBase')
    assert isinstance(c, etgtools.ClassDef)
    c.abstract = True
    tools.removeVirtuals(c)
    _fixClientData(c)

    # Switch all wxToolBarBase to wxToolBar
    for item in c.allItems():
        if isinstance(item, etgtools.ParamDef) and item.name == 'tbar':
            item.type = 'wxToolBar*'

    c.find('GetToolBar').ignore()
    c.addCppMethod('wxToolBar*',
                   'GetToolBar',
                   '()',
                   doc="Return the toolbar this tool is a member of.",
                   body="""\
            return (wxToolBar*)self->GetToolBar();
            """)

    gcd = c.find('GetClientData')
    gcd.type = 'wxPyUserData*'
    gcd.setCppCode(
        'return dynamic_cast<wxPyUserData*>(self->GetClientData());')

    c.find('SetDropdownMenu.menu').transfer = True

    #---------------------------------------------
    c = module.find('wxToolBar')
    tools.fixWindowClass(c)
    tools.ignoreConstOverloads(c)
    _fixClientData(c)
    module.addGlobalStr('wxToolBarNameStr', c)

    gcd = c.find('GetToolClientData')
    gcd.type = 'wxPyUserData*'
    gcd.setCppCode(
        'return dynamic_cast<wxPyUserData*>(self->GetToolClientData(toolId));')

    c.find('AddTool.tool').transfer = True
    c.find('InsertTool.tool').transfer = True

    # Conform the help text parameters.
    m = c.find('AddTool')
    for method in m.all():
        for helper in ('shortHelp', 'longHelp'):
            try:
                param = method.find("{}String".format(helper))
                param.name = helper
            except ExtractorError:
                pass

    c.find('OnLeftClick').ignore()
    c.find('OnMouseEnter').ignore()
    c.find('OnRightClick').ignore()
    c.find('OnLeftClick').ignore()

    c.find('SetDropdownMenu.menu').transfer = True

    # Add some deprecated methods to aid with Classic compatibility.
    # TODO: Which others are commonly enough used that they should be here too?
    c.addPyMethod(
        'AddSimpleTool',
        '(self, toolId, bitmap, shortHelpString="", longHelpString="", isToggle=0)',
        doc='Old style method to add a tool to the toolbar.',
        deprecated='Use :meth:`AddTool` instead.',
        body="""\
            kind = wx.ITEM_NORMAL
            if isToggle: kind = wx.ITEM_CHECK
            return self.AddTool(toolId, '', bitmap, wx.NullBitmap, kind,
                                shortHelpString, longHelpString)
            """)
    c.addPyMethod(
        'AddLabelTool',
        '(self, id, label, bitmap, bmpDisabled=wx.NullBitmap, kind=wx.ITEM_NORMAL,'
        ' shortHelp="", longHelp="", clientData=None)',
        doc='Old style method to add a tool in the toolbar.',
        deprecated='Use :meth:`AddTool` instead.',
        body="""\
            return self.AddTool(id, label, bitmap, bmpDisabled, kind,
                                shortHelp, longHelp, clientData)
            """)

    c.addPyMethod(
        'InsertSimpleTool',
        '(self, pos, toolId, bitmap, shortHelpString="", longHelpString="", isToggle=0)',
        doc='Old style method to insert a tool in the toolbar.',
        deprecated='Use :meth:`InsertTool` instead.',
        body="""\
            kind = wx.ITEM_NORMAL
            if isToggle: kind = wx.ITEM_CHECK
            return self.InsertTool(pos, toolId, '', bitmap, wx.NullBitmap, kind,
                                   shortHelpString, longHelpString)
            """)
    c.addPyMethod(
        'InsertLabelTool',
        '(self, pos, id, label, bitmap, bmpDisabled=wx.NullBitmap, kind=wx.ITEM_NORMAL,'
        ' shortHelp="", longHelp="", clientData=None)',
        doc='Old style method to insert a tool in the toolbar.',
        deprecated='Use :meth:`InsertTool` instead.',
        body="""\
            return self.InsertTool(pos, id, label, bitmap, bmpDisabled, kind,
                                   shortHelp, longHelp, clientData)
            """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 42
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxDataFormat')
    assert isinstance(c, etgtools.ClassDef)
    c.find('GetType').setCppCode("return static_cast<wxDataFormatId>(self->GetType());")

    item = module.find('wxFormatInvalid')
    module.items.remove(item)
    module.insertItemAfter(c, item)


    #------------------------------------------------------------
    c = module.find('wxDataObject')
    c.addPrivateCopyCtor()

    addGetAllFormats(c, True)

    # For initial testing only.  TODO: Remove later
    c.addPublic()
    c.addCppMethod('void', '_testGetAllFormats', '()',
        body="""\
            size_t count = self->GetFormatCount();
            wxDataFormat* fmts = new wxDataFormat[count];
            self->GetAllFormats(fmts);
            """)

    # Replace the GetDataHere method with a version that uses a smarter
    # Python buffer object instead of a stupid void pointer.
    c.find('GetDataHere').ignore()
    c.addCppMethod('bool', 'GetDataHere', '(const wxDataFormat& format, wxPyBuffer* buf)',
        cppSignature='bool (const wxDataFormat& format, void* buf)',
        isVirtual=True, isPureVirtual=True,
        isConst=True,
        doc="Copies this data object's data in the requested format to the buffer provided.",
        body="""\
            if (!buf->checkSize(self->GetDataSize(*format)))
                return false;
            return self->GetDataHere(*format, buf->m_ptr);
            """,

        # This code will be used in the function that calls a Python implementation
        # of this method.
        virtualCatcherCode="""\
            // Call self.GetDataSize() to find out how big the buffer should be
            PyObject* self = NULL;
            PyObject* fmtObj = NULL;
            PyObject* sizeObj = NULL;
            PyObject* buffer = NULL;
            PyObject* resObj = NULL;
            Py_ssize_t size = 0;

            self = PyMethod_Self(sipMethod); // this shouldn't fail, and the reference is borrowed

            fmtObj = wxPyConstructObject((void*)&format, "wxDataFormat", false);
            if (!fmtObj) goto error;
            sizeObj = PyObject_CallMethod(self, "GetDataSize", "(O)", fmtObj, NULL);
            if (!sizeObj) goto error;
            size = wxPyInt_AsSsize_t(sizeObj);

            // Make a buffer that big using the pointer passed to us, and then
            // call the Python method.
            buffer = wxPyMakeBuffer(buf, size);
            resObj = sipCallMethod(0, sipMethod, "SS", fmtObj, buffer);

            if (!resObj || sipParseResult(0,sipMethod,resObj,"b",&sipRes) < 0)
                PyErr_Print();

            error:
            Py_XDECREF(resObj);
            Py_XDECREF(buffer);
            Py_XDECREF(fmtObj);
            Py_XDECREF(sizeObj);
            """)

    # Replace the SetData method with an implementation that uses Python
    # buffer objects.
    c.find('SetData').ignore()
    c.addCppMethod('bool', 'SetData', '(const wxDataFormat& format, wxPyBuffer* buf)',
        cppSignature='bool (const wxDataFormat& format, size_t len, const void* buf)',
        isVirtual=True,
        doc="Copies data from the provided buffer to this data object for the specified format.",
        body="return self->SetData(*format, buf->m_len, buf->m_ptr);",

        # This code will be used in the function that calls a Python implementation
        # of this method.
        virtualCatcherCode="""\
            PyObject* buffer = wxPyMakeBuffer((void*)buf, len);
            PyObject *resObj = sipCallMethod(0,sipMethod,"NS",
                                   new wxDataFormat(format),sipType_wxDataFormat,NULL,
                                   buffer);
            if (!resObj || sipParseResult(0,sipMethod,resObj,"b",&sipRes) < 0)
                PyErr_Print();
            Py_XDECREF(resObj);
            Py_XDECREF(buffer);
            """)


    #------------------------------------------------------------
    c = module.find('wxDataObjectSimple')

    c.addCppCtor_sip('(const wxString& formatName)',
        body='sipCpp = new sipwxDataObjectSimple(wxDataFormat(*formatName));')

    # As in wxDataObject above replace GetDataHere and SetData with methods
    # that use buffer objects instead of void*, but this time we do not pass
    # a DataFormat object with it.
    c.find('GetDataHere').ignore()
    c.addCppMethod('bool', 'GetDataHere', '(wxPyBuffer* buf)',
        cppSignature='bool (void* buf)',
        isVirtual=True,
        isConst=True,
        doc="Copies this data object's data bytes to the given buffer",
        body="""\
            if (!buf->checkSize(self->GetDataSize()))
                return false;
            return self->GetDataHere(buf->m_ptr);
            """,
        virtualCatcherCode="""\
            // Call self.GetDataSize() to find out how big the buffer should be
            PyObject* self = NULL;
            PyObject* sizeObj = NULL;
            PyObject* buffer = NULL;
            PyObject* resObj = NULL;
            Py_ssize_t size = 0;

            self = PyMethod_Self(sipMethod);

            sizeObj = PyObject_CallMethod(self, "GetDataSize", "", NULL);
            if (!sizeObj) goto error;
            size = wxPyInt_AsSsize_t(sizeObj);

            // Make a buffer that big using the pointer passed to us, and then
            // call the Python method.
            buffer = wxPyMakeBuffer(buf, size);
            resObj = sipCallMethod(0, sipMethod, "S", buffer);

            if (!resObj || sipParseResult(0,sipMethod,resObj,"b",&sipRes) < 0)
                PyErr_Print();

            error:
            Py_XDECREF(resObj);
            Py_XDECREF(buffer);
            Py_XDECREF(sizeObj);
            """)

    c.find('SetData').ignore()
    c.addCppMethod('bool', 'SetData', '(wxPyBuffer* buf)',
        cppSignature='bool (size_t len, const void* buf)',
        isVirtual=True,
        doc="Copies data from the provided buffer to this data object.",
        body="return self->SetData(buf->m_len, buf->m_ptr);",
        virtualCatcherCode="""\
            PyObject* buffer = wxPyMakeBuffer((void*)buf, len);
            PyObject *resObj = sipCallMethod(0,sipMethod,"S",buffer);
            if (!resObj || sipParseResult(0,sipMethod,resObj,"b",&sipRes) < 0)
                PyErr_Print();
            Py_XDECREF(resObj);
            Py_XDECREF(buffer);
            """)

    addGetAllFormats(c)
    addBaseVirtuals(c)


    #------------------------------------------------------------
    c = module.find('wxCustomDataObject')
    tools.removeVirtuals(c)

    c.addCppCtor_sip('(const wxString& formatName)',
        body='sipCpp = new sipwxCustomDataObject(wxDataFormat(*formatName));')

    # remove the methods having to do with allocating or owning the data buffer
    c.find('Alloc').ignore()
    c.find('Free').ignore()
    c.find('TakeData').ignore()

    c.find('GetData').ignore()
    c.addCppMethod('PyObject*', 'GetData', '()', isConst=True,
        doc="Returns a reference to the data buffer.",
        body="return wxPyMakeBuffer(self->GetData(), self->GetSize());")

    c.find('SetData').ignore()
    c.addCppMethod('bool', 'SetData', '(wxPyBuffer* buf)',
        cppSignature='bool (size_t len, const void* buf)',
        isVirtual=True,
        doc="Copies data from the provided buffer to this data object's buffer",
        body="return self->SetData(buf->m_len, buf->m_ptr);")

    addGetAllFormats(c)
    addBaseVirtuals(c)
    addSimpleVirtuals(c)

    #------------------------------------------------------------
    c = module.find('wxDataObjectComposite')

    c.find('Add.dataObject').transfer = True

    addGetAllFormats(c)
    addBaseVirtuals(c)



    #------------------------------------------------------------
    c = module.find('wxTextDataObject')
    addGetAllFormats(c)
    addBaseVirtuals(c)
    addSimpleVirtuals(c)


    #------------------------------------------------------------
    c = module.find('wxURLDataObject')

    # wxURLDataObject derives from wxDataObjectComposite on some platforms,
    # and wxTextDataObject on others, so we need to take a least common
    # denominator approach here to be able to work on all platforms.
    c.bases = ['wxDataObject']

    addGetAllFormats(c)
    addBaseVirtuals(c)
    addSimpleVirtuals(c)


    #------------------------------------------------------------
    c = module.find('wxBitmapDataObject')
    addGetAllFormats(c)
    addBaseVirtuals(c)
    addSimpleVirtuals(c)

    #------------------------------------------------------------
    c = module.find('wxFileDataObject')
    addGetAllFormats(c)
    addBaseVirtuals(c)
    addSimpleVirtuals(c)

    #------------------------------------------------------------
    c = module.find('wxHTMLDataObject')
    addGetAllFormats(c)
    addBaseVirtuals(c)
    addSimpleVirtuals(c)



    #------------------------------------------------------------
    module.addPyCode("PyDataObjectSimple = wx.deprecated(DataObjectSimple), 'Use DataObjectSimple instead.'")
    module.addPyCode("PyTextDataObject = wx.deprecated(TextDataObject, 'Use TextDataObject instead.')")
    module.addPyCode("PyBitmapDataObject = wx.deprecated(BitmapDataObject, 'Use TextDataObject instead.')")

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 43
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.
    c = module.find('wxPalette')
    tools.removeVirtuals(c)

    # Add a helper function for use with the Create method and the Ctor
    # accepting RGB data.
    c.addCppCode("""\
        // a helper function to be used in the Create method and one of the Ctors
        bool _paletteCreateHelper(wxPalette* self,
                                  PyObject* red, PyObject* green, PyObject* blue) {
            bool rval = false;
            wxPyThreadBlocker blocker;
            char* errMsg = "Expected a sequence of integer objects";

            if (!PySequence_Check(red) || !PySequence_Check(green) || !PySequence_Check(blue)) {
                PyErr_SetString(PyExc_TypeError, errMsg);
                return rval;
            }

            Py_ssize_t count = PySequence_Size(red);
            if (PySequence_Size(green) != count || PySequence_Size(blue) != count) {
                PyErr_SetString(PyExc_ValueError, "Sequence lengths must be equal");
                return rval;
            }

            unsigned char* redArray = new unsigned char[count];
            unsigned char* greenArray = new unsigned char[count];
            unsigned char* blueArray = new unsigned char[count];

            for (Py_ssize_t i = 0; i < count; i++) {
                PyObject* redItem = PySequence_ITEM(red, i);
                PyObject* greenItem = PySequence_ITEM(green, i);
                PyObject* blueItem = PySequence_ITEM(blue, i);
                if (!wxPyInt_Check(redItem) || !wxPyInt_Check(greenItem) || !wxPyInt_Check(blueItem)) {
                    PyErr_SetString(PyExc_TypeError, errMsg);
                    goto pch_exit;
                }

                long redLong = wxPyInt_AsLong(redItem);
                long greenLong = wxPyInt_AsLong(greenItem);
                long blueLong = wxPyInt_AsLong(blueItem);
                Py_DECREF(redItem);
                Py_DECREF(greenItem);
                Py_DECREF(blueItem);
                if (redLong < 0 || redLong > 255 || greenLong < 0 || greenLong > 255 || blueLong < 0 || blueLong > 255) {
                    PyErr_SetString(PyExc_ValueError, "Sequence values must be in the 0..255 range");
                    goto pch_exit;
                }
                redArray[i] = redLong;
                greenArray[i] = greenLong;
                blueArray[i] = blueLong;
            }

            rval = self->Create(count, redArray, greenArray, blueArray);

        pch_exit:
            delete[] redArray;
            delete[] greenArray;
            delete[] blueArray;
            return rval;
        }
        """)

    #-----------------------------------------------------------------

    # Replace the constructor accepting the arrays of RGB values with one that
    # understands any Python sequence.
    c.find('wxPalette').findOverload('red').ignore()
    c.addCppCtor('(PyObject* red, PyObject* green, PyObject* blue)',
                 doc=dedent("""\
        Creates a palette from a set of sequences of integers,
        one for each red, green and blue color components.

        :param red: A sequence of integer values in the range 0..255 inclusive.
        :param green: A sequence of integer values in the range 0..255 inclusive.
        :param blue: A sequence of integer values in the range 0..255 inclusive.

        .. note:: All sequences must be the same length.
        """),
                 body="""\
            wxPalette* pal = new wxPalette;
            _paletteCreateHelper(pal, red, green, blue);
            if (PyErr_Occurred()) {
                delete pal;
                return NULL;
            }
            return pal;
            """)

    c.find('GetPixel.red').pyInt = True
    c.find('GetPixel.green').pyInt = True
    c.find('GetPixel.blue').pyInt = True

    c.find('GetRGB').ignore()
    c.addCppMethod('PyObject*',
                   'GetRGB',
                   '(int pixel)',
                   pyArgsString="(pixel) -> (red, green, blue)",
                   doc="Returns RGB values for a given palette index.",
                   body="""\
            unsigned char red;
            unsigned char green;
            unsigned char blue;
            wxPyThreadBlocker blocker;
            if (!self->GetRGB(pixel, &red, &green, &blue)) {
                PyErr_SetString(PyExc_IndexError, "Pixel out of range");
                return NULL;
            }
            PyObject* rv = PyTuple_New(3);
            PyTuple_SetItem(rv, 0, wxPyInt_FromLong(red));
            PyTuple_SetItem(rv, 1, wxPyInt_FromLong(green));
            PyTuple_SetItem(rv, 2, wxPyInt_FromLong(blue));
            return rv;
            """)

    # Replace the Create method with one that understands any kind of Python sequence
    c.find('Create').ignore()
    c.addCppMethod('PyObject*',
                   'Create',
                   '(PyObject* red, PyObject* green, PyObject* blue)',
                   pyArgsString="(red, green, blue) -> bool",
                   doc=dedent("""\
        Creates a palette from 3 sequences of integers, one for each red, blue or green component.

        :param red: A sequence of integer values in the range 0..255 inclusive.
        :param green: A sequence of integer values in the range 0..255 inclusive.
        :param blue: A sequence of integer values in the range 0..255 inclusive.

        .. note:: All sequences must be the same length.
        """),
                   body="""\
            bool rval = _paletteCreateHelper(self, red, green, blue);
            wxPyThreadBlocker blocker;
            if (PyErr_Occurred())
                return NULL;
            if (rval)
                Py_RETURN_TRUE;
            else
                Py_RETURN_FALSE;
            """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 44
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    module.addHeaderCode('#include <wx/gdicmn.h>')
    
    def markFactories(klass):
        for func in klass.allItems():
            if isinstance(func, etgtools.FunctionDef) \
               and func.name.startswith('Create') \
               and '*' in func.type:
                func.factory = True

    #---------------------------------------------
    c = module.find('wxGraphicsObject')
    assert isinstance(c, etgtools.ClassDef)
    c.addCppMethod('bool', 'IsOk', '()', 'return !self->IsNull();')
    c.addCppMethod('int', '__nonzero__', '()', "return !self->IsNull();")


    #---------------------------------------------
    c = module.find('wxGraphicsContext')
    assert isinstance(c, etgtools.ClassDef)
    markFactories(c)
    tools.removeVirtuals(c)
    c.abstract = True

    # Ensure that the target DC or image lives as long as the GC does. NOTE:
    # Since the Creates are static methods there is no self to associate the
    # extra reference with, but since they are factories then that extra
    # reference will be held by the return value of the factory instead.
    for m in c.find('Create').all():
        for p in m.items:
            if 'DC' in p.name or p.name == 'image':
                p.keepReference = True
    
    
    # FIXME: Handle wxEnhMetaFileDC?
    c.find('Create').findOverload('wxEnhMetaFileDC').ignore()

    c.find('GetSize.width').out = True
    c.find('GetSize.height').out = True
    c.find('GetDPI.dpiX').out = True
    c.find('GetDPI.dpiY').out = True
    
    m = c.find('GetPartialTextExtents')
    m.find('widths').ignore()
    m.type = 'wxArrayDouble*'
    m.factory = True  # a new instance is being created
    m.setCppCode("""\
        wxArrayDouble rval;
        self->GetPartialTextExtents(*text, rval);
        return new wxArrayDouble(rval);
        """)
    
    m = c.find('GetTextExtent')
    m.pyName = 'GetFullTextExtent'
    m.find('width').out = True
    m.find('height').out = True
    m.find('descent').out = True
    m.find('externalLeading').out = True    
    
    c.addCppMethod('PyObject*', 'GetTextExtent', '(const wxString& text)', 
        pyArgsString="(text) -> (width, height)",
        doc="Gets the dimensions of the string using the currently selected font.",
        body="""\
        wxDouble width = 0.0, height = 0.0;
        self->GetTextExtent(*text, &width, &height, NULL, NULL);
        return sipBuildResult(0, "(dd)", width, height);
        """)

    c.addPyCode("GraphicsContext.DrawRotatedText = wx.deprecated(GraphicsContext.DrawText, 'Use DrawText instead.')")

    
    c.addCppCode(tools.ObjArrayHelperTemplate('wxPoint2D', 'sipType_wxPoint2DDouble',
                    "Expected a sequence of length-2 sequences or wx.Point2D objects."))

    # we'll reimplement this overload as StrokeLineSegments
    c.find('StrokeLines').findOverload('beginPoints').ignore()
    c.addCppMethod('void', 'StrokeLineSegments', '(PyObject* beginPoints, PyObject* endPoints)', 
        pyArgsString="(beginPoint2Ds, endPoint2Ds)",
        doc="Stroke disconnected lines from begin to end points.",
        body="""\
        size_t c1, c2, count;
        wxPoint2D* beginP = wxPoint2D_array_helper(beginPoints, &c1);
        wxPoint2D* endP =   wxPoint2D_array_helper(endPoints, &c2);

        if ( beginP != NULL && endP != NULL ) {
            count = wxMin(c1, c2);
            self->StrokeLines(count, beginP, endP);
        }
        delete [] beginP;
        delete [] endP;
        """)

    # Also reimplement the main StrokeLines method to reuse the same helper
    # function as StrokLineSegments
    m = c.find('StrokeLines').findOverload('points').ignore()
    c.addCppMethod('void', 'StrokeLines', '(PyObject* points)', 
        pyArgsString="(point2Ds)",
        doc="Stroke lines conencting all the points.",
        body="""\
        size_t count;
        wxPoint2D* ptsArray = wxPoint2D_array_helper(points, &count);

        if ( ptsArray != NULL ) {
            self->StrokeLines(count, ptsArray);
            delete [] ptsArray;
        }
        """)

    # and once more for DrawLines
    m = c.find('DrawLines').ignore()
    c.addCppMethod('void', 'DrawLines', '(PyObject* points, wxPolygonFillMode fillStyle = wxODDEVEN_RULE)', 
        pyArgsString="(point2Ds, fillStyle=ODDEVEN_RULE)",
        doc="Draws a polygon.",
        body="""\
        size_t count;
        wxPoint2D* ptsArray = wxPoint2D_array_helper(points, &count);

        if ( ptsArray != NULL ) {
            self->DrawLines(count, ptsArray, fillStyle);
            delete [] ptsArray;
        }
        """)
    
    #---------------------------------------------
    c = module.find('wxGraphicsPath')
    tools.removeVirtuals(c)
    c.find('GetBox').findOverload('wxDouble *x, wxDouble *y').ignore()
    c.find('GetCurrentPoint').findOverload('wxDouble *x, wxDouble *y').ignore()
    
    
    #---------------------------------------------
    c = module.find('wxGraphicsRenderer')
    tools.removeVirtuals(c)
    markFactories(c)
    c.abstract = True
    
    for m in c.find('CreateContext').all():
        for p in m.items:
            if 'DC' in p.name or p.name == 'image':
                p.keepReference = True
    c.find('CreateContextFromImage.image').keepReference = True
    
    # FIXME: Handle wxEnhMetaFileDC?
    c.find('CreateContext').findOverload('wxEnhMetaFileDC').ignore()

  
    #---------------------------------------------
    c = module.find('wxGraphicsMatrix')
    tools.removeVirtuals(c)

    c.find('Concat').overloads = []
    c.find('IsEqual').overloads = []
    
    c.find('Get.a').out = True
    c.find('Get.b').out = True
    c.find('Get.c').out = True
    c.find('Get.d').out = True
    c.find('Get.tx').out = True
    c.find('Get.ty').out = True
    
    c.find('TransformDistance.dx').inOut = True
    c.find('TransformDistance.dy').inOut = True

    c.find('TransformPoint.x').inOut = True
    c.find('TransformPoint.y').inOut = True
    
    
    #---------------------------------------------
    c = module.find('wxGraphicsGradientStops')
    c.addCppMethod('SIP_SSIZE_T', '__len__', '()', body="return (SIP_SSIZE_T)self->GetCount();")
    c.addCppMethod('wxGraphicsGradientStop*', '__getitem__', '(size_t n)',
                   pyArgsString='(n)',
                   body="return new wxGraphicsGradientStop(self->Item(n));",
                   factory=True)

    
    #---------------------------------------------
    # Use the pyNames we set for these classes in geometry.py so the old
    # names do not show up in the docstrings, etc.
    tools.changeTypeNames(module, 'wxPoint2DDouble', 'wxPoint2D')
    tools.changeTypeNames(module, 'wxRect2DDouble', 'wxRect2D')
    

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 45
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.

    c = module.find('wxAcceleratorEntry')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    c = module.find('wxAcceleratorTable')
    assert isinstance(c, etgtools.ClassDef)
    tools.removeVirtuals(c)

    # Replace the implementation of the AcceleratorTable ctor so it can
    # accept a Python sequence of tuples or AcceleratorEntry objects like
    # Classic does. Using the arraySize and array annotations does let us
    # pass a list of entries, but they have to already be AccelertorEntry
    # obejcts. We want to allow Items in the list to be either
    # wx.AcceleratorEntry items or a 3-tuple containing the values to pass to
    # the wx.AcceleratorEntry ctor.

    # Ignore the current constructor
    c.find('wxAcceleratorTable').findOverload('entries').ignore()

    # and add the code for the new constructor
    c.addCppCtor(
        briefDoc="TODO",
        argsString='(PyObject* entries)',
        body="""\
    const char* errmsg = "Expected a sequence of 3-tuples or wx.AcceleratorEntry objects.";
    if (!PySequence_Check(entries)) {
        PyErr_SetString(PyExc_TypeError, errmsg);
        return NULL;
    }
    int count = PySequence_Size(entries);
    wxAcceleratorEntry* tmpEntries = new wxAcceleratorEntry[count];
    if (! tmpEntries) {
        PyErr_SetString(PyExc_MemoryError, "Unable to allocate temporary array");
        return NULL;
    }
    int idx;
    for (idx=0; idx<count; idx++) {
        PyObject* obj = PySequence_ITEM(entries, idx);
        if (sipCanConvertToType(obj, sipType_wxAcceleratorEntry, SIP_NO_CONVERTORS)) {
            int err = 0;
            wxAcceleratorEntry* entryPtr = reinterpret_cast<wxAcceleratorEntry*>(
                sipConvertToType(obj, sipType_wxAcceleratorEntry, NULL, 0, 0, &err));
            tmpEntries[idx] = *entryPtr;
        }
        else if (PySequence_Check(obj) && PySequence_Size(obj) == 3) {
            PyObject* o1 = PySequence_ITEM(obj, 0);
            PyObject* o2 = PySequence_ITEM(obj, 1);
            PyObject* o3 = PySequence_ITEM(obj, 2);
            tmpEntries[idx].Set(wxPyInt_AsLong(o1), wxPyInt_AsLong(o2), wxPyInt_AsLong(o3));
            Py_DECREF(o1);
            Py_DECREF(o2);
            Py_DECREF(o3);
        }
        else {
            PyErr_SetString(PyExc_TypeError, errmsg);
            return NULL;
        }
        Py_DECREF(obj);
    }

    wxAcceleratorTable* table = new wxAcceleratorTable(count, tmpEntries);
    delete tmpEntries;
    return table;
    """)

    # Mac doesn't have this, and we don't real with resource files from
    # wxPython anyway.
    c.find('wxAcceleratorTable').findOverload('resource').ignore()


    module.addPyFunction('GetAccelFromString', '(label)',
        deprecated=True,
        body="""\
            accel = wx.AcceleratorEntry()
            accel.FromString(label)
            return accel
            """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Exemplo n.º 46
0
def run():
    # Parse the XML file(s) building a collection of Extractor objects
    module = etgtools.ModuleDef(PACKAGE, MODULE, NAME, DOCSTRING)
    etgtools.parseDoxyXML(module, ITEMS)

    #-----------------------------------------------------------------
    # Tweak the parsed meta objects in the module object as needed for
    # customizing the generated code and docstrings.


    c = module.find('wxMenuItem')
    assert isinstance(c, etgtools.ClassDef)
    c.addPrivateCopyCtor()
    tools.removeVirtuals(c)

    c.find('SetSubMenu.menu').transfer = True

    # deprecated and removed
    c.find('GetLabel').ignore()
    c.find('GetName').ignore()
    c.find('GetText').ignore()
    c.find('SetText').ignore()
    c.find('GetLabelFromText').ignore()


    # These are MSW only. Make them be empty stubs for the other ports
    c.find('GetBackgroundColour').type = 'wxColour*'
    c.find('GetBackgroundColour').setCppCode("""\
        #ifdef __WXMSW__
            return &self->GetBackgroundColour();
        #else
            return &wxNullColour;
        #endif
        """)

    c.find('SetBackgroundColour').setCppCode("""\
        #ifdef __WXMSW__
            self->SetBackgroundColour(*colour);
        #endif
        """)

    c.find('GetFont').type = 'wxFont*'
    c.find('GetFont').setCppCode("""\
        #ifdef __WXMSW__
            return &self->GetFont();
        #else
            return &wxNullFont;
        #endif
        """)

    c.find('SetFont').setCppCode("""\
        #ifdef __WXMSW__
            self->SetFont(*font);
        #endif
        """)

    c.find('GetMarginWidth').setCppCode("""\
        #ifdef __WXMSW__
            return self->GetMarginWidth();
        #else
            return -1;
        #endif
        """)

    c.find('SetMarginWidth').setCppCode("""\
        #ifdef __WXMSW__
            self->SetMarginWidth(width);
        #endif
        """)

    c.find('GetTextColour').type = 'wxColour*'
    c.find('GetTextColour').setCppCode("""\
        #ifdef __WXMSW__
            return &self->GetTextColour();
        #else
            return &wxNullColour;
        #endif
        """)

    c.find('SetTextColour').setCppCode("""\
        #ifdef __WXMSW__
            self->SetTextColour(*colour);
        #endif
        """)


    c.find('GetBitmap').type = 'const wxBitmap*'
    c.find('GetBitmap').setCppCode("""\
        #ifdef __WXMSW__
            return &self->GetBitmap(checked);
        #else
            return &self->GetBitmap();
        #endif
        """)

    c.find('SetBitmap').setCppCode("""\
        #ifdef __WXMSW__
            self->SetBitmap(*bmp, checked);
        #else
            self->SetBitmap(*bmp); // no checked arg in this case
        #endif
        """)

    c.find('SetBitmaps').setCppCode("""\
        #ifdef __WXMSW__
            self->SetBitmaps(*checked, *unchecked);
        #else
            self->SetBitmap(*checked);
        #endif
        """)


    c.find('GetDisabledBitmap').type = 'const wxBitmap*'
    c.find('GetDisabledBitmap').setCppCode("""\
        #ifdef __WXMSW__
            return &self->GetDisabledBitmap();
        #else
            return &wxNullBitmap;
        #endif
        """)

    c.find('SetDisabledBitmap').setCppCode("""\
        #ifdef __WXMSW__
            self->SetDisabledBitmap(*disabled);
        #endif
        """)


    c.find('GetAccel').factory = True
    c.find('GetAccelFromString').ignore()  # Not implemented anywere?

    module.addItem(tools.wxListWrapperTemplate('wxMenuItemList', 'wxMenuItem', module))



    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)