Пример #1
0
def addPixelDataClass(module, pd, img, bpp, doc=""):
    # This function creates a ClassDef for a PixelData class defined in C++.
    # The C++ versions are template instantiations, so this allows us to
    # create nearly identical classes and just substitute the image class
    # name and the pixel data class name.

    #itrName = 'Iterator'

    itrName = pd + '_Accessor'
    module.addHeaderCode('typedef %s::Iterator %s;' % (pd, itrName))

    # First generate the class and methods for the PixelData class
    cls = ClassDef(name=pd,
                   bases=['wxPixelDataBase'],
                   briefDoc=doc,
                   items=[
                       MethodDef(
                           name=pd,
                           isCtor=True,
                           items=[ParamDef(type=img + '&', name='bmp')],
                           overloads=[
                               MethodDef(name=pd,
                                         isCtor=True,
                                         items=[
                                             ParamDef(type=img + '&',
                                                      name='bmp'),
                                             ParamDef(type='const wxRect&',
                                                      name='rect')
                                         ]),
                               MethodDef(name=pd,
                                         isCtor=True,
                                         items=[
                                             ParamDef(type=img + '&',
                                                      name='bmp'),
                                             ParamDef(type='const wxPoint&',
                                                      name='pt'),
                                             ParamDef(type='const wxSize&',
                                                      name='sz')
                                         ]),
                           ]),
                       MethodDef(name='~' + pd, isDtor=True),
                       MethodDef(type=itrName, name='GetPixels', isConst=True),
                       CppMethodDef('int',
                                    '__nonzero__',
                                    '()',
                                    body="""\
                return (int)self->operator bool();
                """),
                   ])

    # add this class to the module
    module.addItem(cls)

    # Now do the class and methods for its C++ Iterator class
    icls = ClassDef(
        name=itrName,
        items=[
            # Constructors
            MethodDef(name=itrName,
                      isCtor=True,
                      items=[ParamDef(name='data', type=pd + '&')],
                      overloads=[
                          MethodDef(name=itrName,
                                    isCtor=True,
                                    items=[
                                        ParamDef(name='bmp', type=img + '&'),
                                        ParamDef(name='data', type=pd + '&')
                                    ]),
                          MethodDef(name=itrName, isCtor=True)
                      ]),
            MethodDef(name='~' + itrName, isDtor=True),

            # Methods
            MethodDef(type='void',
                      name='Reset',
                      items=[ParamDef(type='const %s&' % pd, name='data')]),
            MethodDef(type='bool', name='IsOk', isConst=True),
            CppMethodDef('int',
                         '__nonzero__',
                         '()',
                         body="""\
                return (int)self->IsOk();
                """),
            MethodDef(type='void',
                      name='Offset',
                      items=[
                          ParamDef(type='const %s&' % pd, name='data'),
                          ParamDef(type='int', name='x'),
                          ParamDef(type='int', name='y')
                      ]),
            MethodDef(type='void',
                      name='OffsetX',
                      items=[
                          ParamDef(type='const %s&' % pd, name='data'),
                          ParamDef(type='int', name='x')
                      ]),
            MethodDef(type='void',
                      name='OffsetY',
                      items=[
                          ParamDef(type='const %s&' % pd, name='data'),
                          ParamDef(type='int', name='y')
                      ]),
            MethodDef(type='void',
                      name='MoveTo',
                      items=[
                          ParamDef(type='const %s&' % pd, name='data'),
                          ParamDef(type='int', name='x'),
                          ParamDef(type='int', name='y')
                      ]),

            # should this return the iterator?
            CppMethodDef('void', 'nextPixel', '()', body="++(*self);"),

            # NOTE: For now I'm not wrapping the Red, Green, Blue and Alpha
            # functions because I can't hide the premultiplying needed on wxMSW
            # if only the individual components are wrapped, plus it would mean 3
            # or 4 trips per pixel from Python to C++ instead of just one.
            # Instead I'll add the Set and Get functions below and put the
            # premultiplying in there.
        ])

    assert bpp in [24, 32]

    if bpp == 24:
        icls.addCppMethod('void',
                          'Set',
                          '(byte red, byte green, byte blue)',
                          body="""\
                self->Red()   = red;
                self->Green() = green;
                self->Blue()  = blue;
                """)

        icls.addCppMethod('PyObject*',
                          'Get',
                          '()',
                          body="""\
                wxPyThreadBlocker blocker;
                PyObject* rv = PyTuple_New(3);
                PyTuple_SetItem(rv, 0, wxPyInt_FromLong(self->Red()));
                PyTuple_SetItem(rv, 1, wxPyInt_FromLong(self->Green()));
                PyTuple_SetItem(rv, 2, wxPyInt_FromLong(self->Blue()));
                return rv;
                """)

    elif bpp == 32:
        icls.addCppMethod('void',
                          'Set',
                          '(byte red, byte green, byte blue, byte alpha)',
                          body="""\
                self->Red()   = wxPy_premultiply(red,   alpha);
                self->Green() = wxPy_premultiply(green, alpha);
                self->Blue()  = wxPy_premultiply(blue,  alpha);
                self->Alpha() = alpha;
                """)

        icls.addCppMethod('PyObject*',
                          'Get',
                          '()',
                          body="""\
                wxPyThreadBlocker blocker;
                PyObject* rv = PyTuple_New(4);
                int red   = self->Red();
                int green = self->Green();
                int blue  = self->Blue();
                int alpha = self->Alpha();

                PyTuple_SetItem(rv, 0, wxPyInt_FromLong( wxPy_unpremultiply(red,   alpha) ));
                PyTuple_SetItem(rv, 1, wxPyInt_FromLong( wxPy_unpremultiply(green, alpha) ));
                PyTuple_SetItem(rv, 2, wxPyInt_FromLong( wxPy_unpremultiply(blue,  alpha) ));
                PyTuple_SetItem(rv, 3, wxPyInt_FromLong( alpha ));
                return rv;
                """)

    # add it to the main pixel data class as a nested class
    #cls.insertItem(0, icls)

    # It's really a nested class, but we're pretending that it isn't (see the
    # typedef above) so add it at the module level instead.
    module.addItem(icls)
Пример #2
0
def addPixelDataBaseClass(module):
    # wxPixelDataBase is the common base class of the other pixel data classes
    cls = ClassDef(
        name='wxPixelDataBase',
        items=[
            MethodDef(name='wxPixelDataBase',
                      isCtor=True,
                      protection='protected'),
            MethodDef(
                type='wxPoint',
                name='GetOrigin',
                isConst=True,
                briefDoc=
                "Return the origin of the area this pixel data represents."),
            MethodDef(
                type='int',
                name='GetWidth',
                isConst=True,
                briefDoc=
                "Return the width of the area this pixel data represents."),
            MethodDef(
                type='int',
                name='GetHeight',
                isConst=True,
                briefDoc=
                "Return the height of the area this pixel data represents."),
            MethodDef(
                type='wxSize',
                name='GetSize',
                isConst=True,
                briefDoc=
                "Return the size of the area this pixel data represents."),
            MethodDef(
                type='int',
                name='GetRowStride',
                isConst=True,
                briefDoc=
                "Returns the distance between the start of one row to the start of the next row."
            ),
        ])

    # TODO: Try to remember why I chose to do it this way instead of directly
    # returning an instance of the Iterator and giving it the methods needed
    # to be a Python iterator...

    # TODO: Determine how much of a performance difference not using the
    # PixelFacade class would make. Not using the __iter__ makes about 0.02
    # seconds difference per 100x100 bmp in samples/rawbmp/rawbmp1.py...

    cls.addPyMethod('__iter__',
                    '(self)',
                    doc="""\
            Create and return an iterator/generator object for traversing
            this pixel data object.
            """,
                    body="""\
            width  = self.GetWidth()
            height = self.GetHeight()
            pixels = self.GetPixels() # this is the C++ iterator

            # This class is a facade over the pixels object (using the one
            # in the enclosing scope) that only allows Get() and Set() to
            # be called.
            class PixelFacade(object):
                def Get(self):
                    return pixels.Get()
                def Set(self, *args, **kw):
                    return pixels.Set(*args, **kw)
                def __str__(self):
                    return str(self.Get())
                def __repr__(self):
                    return 'pixel(%d,%d): %s' % (x,y,self.Get())
                X = property(lambda self: x)
                Y = property(lambda self: y)

            import sys
            rangeFunc = range if sys.version_info >= (3,) else xrange

            pf = PixelFacade()
            for y in rangeFunc(height):
                pixels.MoveTo(self, 0, y)
                for x in rangeFunc(width):
                    # We always generate the same pf instance, but it
                    # accesses the pixels object which we use to iterate
                    # over the pixel buffer.
                    yield pf
                    pixels.nextPixel()
            """)

    module.addItem(cls)
Пример #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('wxIdManager')
    assert isinstance(c, etgtools.ClassDef)
    # no tweaks needed for this class

    # wxWindowIDRef is not documented (and probably rightly so) but we're going
    # to use it from Python anyway to help with preallocating IDs in a way that
    # allows them to be reused and be also be protected from conflicts from
    # other auto allocated IDs.

    # First, add defintions of the existing C++ class and its elements
    klass = ClassDef(
        name='wxWindowIDRef',
        bases=[],
        briefDoc="""\
            A wxWindowIDRef object wraps an ID value and marks it as being in-use until all references to that ID are gone.
            """,
        items=[
            MethodDef(name='wxWindowIDRef',
                      className='wxWindowIDRef',
                      isCtor=True,
                      briefDoc='Default constructor',
                      overloads=[
                          MethodDef(name='wxWindowIDRef',
                                    className='wxWindowIDRef',
                                    isCtor=True,
                                    briefDoc='Create reference from an ID',
                                    items=[ParamDef(type='int', name='id')]),
                          MethodDef(name='wxWindowIDRef',
                                    className='wxWindowIDRef',
                                    isCtor=True,
                                    briefDoc='Copy an ID reference',
                                    items=[
                                        ParamDef(type='const wxWindowIDRef&',
                                                 name='idref')
                                    ]),
                      ]),
            MethodDef(name='~wxWindowIDRef',
                      className='wxWindowIDRef',
                      isDtor=True),
            MethodDef(type='int', name='GetValue',
                      briefDoc='Get the ID value'),
        ])

    # Now tweak it a bit
    klass.addCppMethod(
        'int',
        'GetId',
        '()',
        doc=
        "Alias for GetValue allowing the IDRef to be passed as the source parameter to :meth:`wx.EvtHandler.Bind`.",
        body="""\
            return self->GetValue();
            """)

    klass.addCppMethod(
        'int',
        '__int__',
        '()',
        doc=
        "Alias for GetValue allowing the IDRef to be passed as the WindowID parameter when creating widgets or etc.",
        body="""\
            return self->GetValue();
            """)

    klass.addPyMethod('__repr__', '(self)',
                      'return "WindowIDRef: {}".format(self.GetId())')

    # and finish it up by adding it to the module
    module.addItem(klass)

    # Now, let's add a new Python function to the global scope that reserves an
    # ID (or range) and returns a ref object for it.
    module.addPyFunction('NewIdRef',
                         '(count=1)',
                         doc="""\
            Reserves a new Window ID (or range of WindowIDs) and returns a 
            :class:`wx.WindowIDRef` object (or list of them) that will help 
            manage the reservation of that ID.

            This function is intended to be a drop-in replacement of the old 
            and deprecated :func:`wx.NewId` function, with the added benefit 
            that the ID should never conflict with an in-use ID or other IDs 
            generated by this function.
            """,
                         body="""\
            if count == 1:
                return WindowIDRef(IdManager.ReserveId())
            else:
                start = IdManager.ReserveId(count)
                IDRefs = []
                for id in range(start, start+count):
                    IDRefs.append(WindowIDRef(id))
                return IDRefs
            """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Пример #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.

    scrolled = module.find('wxScrolled')
    assert isinstance(scrolled, etgtools.ClassDef)

    scrolled.find('GetViewStart').findOverload('()').ignore()
    scrolled.find('GetViewStart.x').out = True
    scrolled.find('GetViewStart.y').out = True

    m = scrolled.find('CalcScrolledPosition').findOverload('xx')
    m.find('xx').out = True
    m.find('yy').out = True

    m = scrolled.find('CalcUnscrolledPosition').findOverload('xx')
    m.find('xx').out = True
    m.find('yy').out = True

    scrolled.find('GetScrollPixelsPerUnit.xUnit').out = True
    scrolled.find('GetScrollPixelsPerUnit.yUnit').out = True

    # Just ignore this one and let the already tweaked versions be inherited from wx.Window.
    scrolled.find('GetVirtualSize').ignore()

    scrolled.addPrivateCopyCtor()
    scrolled.addPrivateAssignOp()
    tools.fixWindowClass(scrolled)

    # Add back some virtuals that were removed in fixWindowClass
    scrolled.find('OnDraw').isVirtual = True
    scrolled.find('GetSizeAvailableForScrollTarget').isVirtual = True
    scrolled.find('GetSizeAvailableForScrollTarget').ignore(False)
    scrolled.find('SendAutoScrollEvents').isVirtual = True

    # The wxScrolledCanvas typedef will be output normally and SIP will treat
    # it like a class that has a wxScrolled mix-in as one of the base classes.
    # Let's add some more info to them for the doc generators.
    docBase = """\
    The :ref:`{name}` class is a combination of the :ref:`{base}` and
    :ref:`Scrolled` classes, and manages scrolling for its client area,
    transforming the coordinates according to the scrollbar positions,
    and setting the scroll positions, thumb sizes and ranges according to
    the area in view.
    """
    item = module.find('wxScrolledCanvas')
    item.docAsClass = True
    item.bases = ['wxWindow', 'wxScrolled']
    item.briefDoc = docBase.format(name='ScrolledCanvas', base='Window')
    item.detailedDoc[0] = "This scrolled window is not intended to have children "\
                          "so it doesn't have special handling for TAB traversal "\
                          "or focus management."
    # move it ahead of wxScrolledWindow
    sw = module.find('wxScrolledWindow')
    module.items.remove(item)
    module.insertItemBefore(sw, item)

    # wxScrolledWindow is documented as a typedef but it's actually a class.
    # So we need to implement it that way here too in order to keep
    # static_casts and such happy.
    assert isinstance(sw, TypedefDef)

    # First, let's add a typedef to serve as the base class of
    # wxScrolledWindow, since SIP doesn't yet understand using template
    # instantiations as base classes.  Setting noTypeName tells SIP to not use
    # the typedef name in the actual generated code, but the typedef's type
    # instead.
    td = TypedefDef(name='_ScrolledWindowBase',
                    type='wxScrolled<wxPanel>',
                    noTypeName=True,
                    piIgnored=True)
    module.insertItemAfter(sw, td)
    module.addHeaderCode('typedef wxScrolled<wxPanel> _ScrolledWindowBase;')
    sw.ignore()

    # Now implement the class definition
    klass = ClassDef(
        name='wxScrolledWindow',
        bases=['_ScrolledWindowBase'],
        piBases=['Window', 'Scrolled'],
        briefDoc=sw.briefDoc,
        detailedDoc=sw.detailedDoc,
        items=[
            MethodDef(name='wxScrolledWindow',
                      isCtor=True,
                      items=[],
                      overloads=[
                          MethodDef(name='wxScrolledWindow',
                                    isCtor=True,
                                    items=[
                                        ParamDef(name='parent',
                                                 type='wxWindow*'),
                                        ParamDef(name='id',
                                                 type='wxWindowID',
                                                 default='wxID_ANY'),
                                        ParamDef(name='pos',
                                                 type='const wxPoint&',
                                                 default='wxDefaultPosition'),
                                        ParamDef(name='size',
                                                 type='const wxSize&',
                                                 default='wxDefaultSize'),
                                        ParamDef(
                                            name='style',
                                            type='long',
                                            default='wxScrolledWindowStyle'),
                                        ParamDef(name='name',
                                                 type='const wxString&',
                                                 default='wxPanelNameStr'),
                                    ]),
                      ]),
            MethodDef(name='SetFocusIgnoringChildren',
                      type='void',
                      items=[],
                      briefDoc="""\
                    In contrast to SetFocus() this will set the focus to the panel even if
                    there are child windows in the panel. This is only rarely needed."""
                      ),
        ],
    )
    tools.fixWindowClass(klass)
    module.insertItemAfter(td, klass)

    module.addPyCode(
        "PyScrolledWindow = wx.deprecated(ScrolledWindow, 'Use ScrolledWindow instead.')"
    )

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Пример #5
0
def addPixelDataBaseClass(module):
    # wxPixelDataBase is the common base class of the other pixel data classes
    cls = ClassDef(name='wxPixelDataBase', items=[
        MethodDef(
            name='wxPixelDataBase', isCtor=True, protection='protected'),
        MethodDef(
            type='wxPoint', name='GetOrigin',  isConst=True,
            briefDoc="Return the origin of the area this pixel data represents."),
        MethodDef(
            type='int', name='GetWidth', isConst=True, 
            briefDoc="Return the width of the area this pixel data represents."),
        MethodDef(
            type='int', name='GetHeight', isConst=True,
            briefDoc="Return the height of the area this pixel data represents."),
        MethodDef(
            type='wxSize', name='GetSize', isConst=True,
            briefDoc="Return the size of the area this pixel data represents."),
        MethodDef(
            type='int', name='GetRowStride', isConst=True,
            briefDoc="Returns the distance between the start of one row to the start of the next row."),
        ])
    
    # TODO: Try to remember why I chose to do it this way instead of directly
    # returning an instance of the Iterator and giving it the methods needed
    # to be a Python iterator...
    
    # TODO: Determine how much of a performance difference not using the
    # PixelFacade class would make. Not using the __iter__ makes about 0.02
    # seconds difference per 100x100 bmp in samples/rawbmp/rawbmp1.py...

    cls.addPyMethod('__iter__', '(self)',
        doc="""\
            Create and return an iterator/generator object for traversing 
            this pixel data object.
            """,        
        body="""\
            width  = self.GetWidth()
            height = self.GetHeight()
            pixels = self.GetPixels() # this is the C++ iterator
            
            # This class is a facade over the pixels object (using the one
            # in the enclosing scope) that only allows Get() and Set() to
            # be called.
            class PixelFacade(object):
                def Get(self):
                    return pixels.Get()
                def Set(self, *args, **kw):
                    return pixels.Set(*args, **kw)
                def __str__(self):
                    return str(self.Get())
                def __repr__(self):
                    return 'pixel(%d,%d): %s' % (x,y,self.Get())
                X = property(lambda self: x)
                Y = property(lambda self: y)
    
            import sys
            rangeFunc = range if sys.version_info >= (3,) else xrange
    
            pf = PixelFacade()        
            for y in rangeFunc(height):
                pixels.MoveTo(self, 0, y)
                for x in rangeFunc(width):
                    # We always generate the same pf instance, but it
                    # accesses the pixels object which we use to iterate
                    # over the pixel buffer.
                    yield pf    
                    pixels.nextPixel()
            """)
    
    module.addItem(cls)
Пример #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.

    c = module.find('wxVisualAttributes')
    assert isinstance(c, etgtools.ClassDef)
    # Mark the stucture memebers as read-only, and make copies of the values
    # when fetching them. This is to protect against cases where the
    # VisualAttributes object is transient and may be GC'd while we still are
    # using a reference to a C++ member value.
    c.find('colBg').noSetter = True
    c.find('colBg').getCode = """\
        wxColour* clr = new wxColour(sipCpp->colBg);
        sipPy = wxPyConstructObject((void*)clr, "wxColour", true);
    """
    c.find('colFg').noSetter = True
    c.find('colFg').getCode = """\
        wxColour* clr = new wxColour(sipCpp->colFg);
        sipPy = wxPyConstructObject((void*)clr, "wxColour", true);
    """
    c.find('font').noSetter = True
    c.find('font').getCode = """\
        wxFont* font = new wxFont(sipCpp->font);
        sipPy = wxPyConstructObject((void*)font, "wxFont", true);
    """

    c = module.find('wxWindow')
    assert isinstance(c, etgtools.ClassDef)
    module.addGlobalStr('wxPanelNameStr', c)

    c.find('FindFocus').mustHaveApp()
    c.find('GetCapture').mustHaveApp()

    # First we need to let the wrapper generator know about wxWindowBase since
    # AddChild and RemoveChild need to use that type in order to be virtualized.
    winbase = ClassDef(
        name='wxWindowBase',
        bases=['wxEvtHandler'],
        abstract=True,
        items=[
            MethodDef(name='AddChild',
                      isVirtual=True,
                      type='void',
                      protection='public',
                      items=[ParamDef(name='child', type='wxWindowBase*')]),
            MethodDef(name='RemoveChild',
                      isVirtual=True,
                      type='void',
                      protection='public',
                      items=[ParamDef(name='child', type='wxWindowBase*')])
        ])
    module.insertItemBefore(c, winbase)

    # Now change the base class of wxWindow
    c.bases = ['wxWindowBase']

    # And fix the arg types we get from Doxy
    c.find('AddChild.child').type = 'wxWindowBase*'
    c.find('RemoveChild.child').type = 'wxWindowBase*'

    # We now return you to our regularly scheduled programming...
    c.includeCppCode('src/window_ex.cpp')

    # ignore some overloads that will be ambiguous after wrapping
    c.find('GetChildren').overloads = []
    c.find('GetChildren').noCopy = True
    for name in ['GetVirtualSize', 'GetPosition', 'GetScreenPosition']:
        c.find(name).findOverload('int *').ignore()

    # Fix ClientToScreen/ScreenToClient int * overloads
    for name in ['ClientToScreen', 'ScreenToClient']:
        c.find(name).findOverload('int *').find('x').inOut = True
        c.find(name).findOverload('int *').find('y').inOut = True

    # Like the above, but these also need to transplant the docs from the
    # ignored item to the non-ignored overload.
    for name in ['GetClientSize', 'GetSize']:
        c.find(name).findOverload('int *').ignore()
        item = c.find(name)
        ov = item.overloads[0]
        item.briefDoc = ov.briefDoc
        item.detailedDoc = ov.detailedDoc

    # Release the GIL for potentially blocking or long-running functions
    c.find('PopupMenu').releaseGIL()
    c.find('ProcessEvent').releaseGIL()
    c.find('ProcessWindowEvent').releaseGIL()
    c.find('ProcessWindowEventLocally').releaseGIL()

    # Add a couple wrapper functions for symmetry with the getters of the same name
    c.addPyMethod('SetRect', '(self, rect)', 'return self.SetSize(rect)')
    c.addPyProperty('Rect GetRect SetRect')
    c.addPyMethod('SetClientRect', '(self, rect)',
                  'return self.SetClientSize(rect)')
    c.addPyProperty('ClientRect GetClientRect SetClientRect')

    # Split the overloaded GetTextExtent into two distinct methods, because the
    # resulting method signatures are not different enough from the Python
    # perspective.
    m1 = c.find('GetTextExtent')  #.findOverload('int *')
    assert len(m1.overloads) == 1
    m2 = m1.overloads.pop()
    c.insertItemAfter(m1, m2)

    # Now do the needed tweaks for the full GetFullTextExtent
    m1.pyName = 'GetFullTextExtent'
    m1.find('w').out = True
    m1.find('h').out = True
    m1.find('descent').out = True
    m1.find('externalLeading').out = True

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

    c.addCppMethod(
        'void*', 'GetGtkWidget', '()', """\
    #ifdef __WXGTK__
        return (void*)self->GetHandle();
    #else
        return NULL;
    #endif
    """)

    c.addCppMethod('void',
                   'AssociateHandle',
                   '(long handle)',
                   doc="Associate the window with a new native handle",
                   body="self->AssociateHandle((WXWidget)handle);")
    c.addCppMethod('void',
                   'DissociateHandle',
                   '()',
                   doc="Dissociate the current native handle from the window",
                   body="self->DissociateHandle();")

    # Add some new methods
    c.addCppMethod(
        'wxWindow*',
        'GetTopLevelParent',
        '()',
        'return wxGetTopLevelParent(self);',
        briefDoc=
        "Returns the first ancestor of this window which is a top-level window."
    )

    c.addCppMethod(
        'bool',
        'MacIsWindowScrollbar',
        '(const wxWindow* sb)',
        """\
    #ifdef __WXMAC__
        return self->MacIsWindowScrollbar(sb);
    #else
        return false;
    #endif
    """,
        pyArgsString="(sb)",
        briefDoc=
        "Is the given widget one of this window's built-in scrollbars?  Only applicable on Mac."
    )

    c.addCppMethod(
        'void',
        'SetDimensions',
        '(int x, int y, int width, int height, int sizeFlags=wxSIZE_AUTO)',
        pyArgsString="(x, y, width, height, sizeFlags=SIZE_AUTO)",
        body="""\
        self->SetSize(x, y, width, height, sizeFlags);
        """)
    c.addPyCode(
        "Window.SetDimensions = wx.deprecated(Window.SetDimensions, 'Use SetSize instead.')"
    )

    # Make the Register/UnregisterHotKey functions be available on Windows,
    # and empty stubs otherwise
    c.find('RegisterHotKey').setCppCode("""\
    #if wxUSE_HOTKEY
        return self->RegisterHotKey(hotkeyId, modifiers, virtualKeyCode);
    #else
        return false;
    #endif
    """)
    c.find('UnregisterHotKey').setCppCode("""\
    #if wxUSE_HOTKEY
        return self->UnregisterHotKey(hotkeyId);
    #else
        return false;
    #endif
    """)
    c.find('RegisterHotKey').isVirtual = False
    c.find('UnregisterHotKey').isVirtual = False

    c.find('SetDoubleBuffered').setCppCode("""\
    #if defined(__WXGTK20__) || defined(__WXGTK3__) || defined(__WXMSW__)
        self->SetDoubleBuffered(on);
    #endif
    """)

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

    c.addPyMethod('DestroyLater',
                  '(self)',
                  doc="""\
           Schedules the window to be destroyed in the near future.

           This should be used whenever Destroy could happen too soon, such
           as when there may still be events for this window or its children
           waiting in the event queue.
           """,
                  body="""\
            self.Hide()
            wx.GetApp().ScheduleForDestruction(self)
            """)

    c.addPyMethod('DLG_UNIT',
                  '(self, dlg_unit)',
                  doc="""\
            A convenience wrapper for :meth:`ConvertDialogToPixels`.
            """,
                  body="""\
            is_wxType = isinstance(dlg_unit, (wx.Size, wx.Point))
            pix = self.ConvertDialogToPixels(dlg_unit)
            if not is_wxType:
                pix = tuple(pix)
            return pix
            """)

    # wxAccessbile is MSW only. Provide a NotImplemented fallback for the
    # other platforms.
    c.find('GetAccessible').setCppCode("""\
        #if wxUSE_ACCESSIBILITY
            return self->GetAccessible();
        #else
            wxPyRaiseNotImplemented();
            return NULL;
        #endif
        """)
    c.find('SetAccessible.accessible').transfer = True
    c.find('SetAccessible').setCppCode("""\
        #if wxUSE_ACCESSIBILITY
            self->SetAccessible(accessible);
        #else
            wxPyRaiseNotImplemented();
        #endif
        """)

    # Make some of the protected methods visible and overridable from Python
    c.find('SendDestroyEvent').ignore(False)

    c.find('Destroy').transferThis = True
    c.addPyMethod('PostCreate',
                  '(self, pre)',
                  'pass',
                  deprecated='PostCreate is no longer necessary.')

    # transfer ownership of these parameters to the C++ object
    c.find('SetCaret.caret').transfer = True
    c.find('SetToolTip.tip').transfer = True
    c.find('SetDropTarget.target').transfer = True
    c.find('SetConstraints.constraints').transfer = True
    c.find('SetSizer.sizer').transfer = True
    c.find('SetSizerAndFit.sizer').transfer = True

    # Change some =0 default values to =NULL so the docs will make more sense
    c.find('FindWindowById.parent').default = 'NULL'
    c.find('FindWindowByLabel.parent').default = 'NULL'
    c.find('FindWindowByName.parent').default = 'NULL'

    # Transfer ownership of the wx.EvtHandler when pushing/popping them...
    c.find('PushEventHandler.handler').transfer = True
    c.find('PopEventHandler').transferBack = True

    # ...and for Set/RemoveEventHandler too
    c.find('SetEventHandler.handler').transfer = True
    c.find('RemoveEventHandler.handler').transferBack = True

    # Define some properties using the getter and setter methods
    c.addProperty('AcceleratorTable GetAcceleratorTable SetAcceleratorTable')
    c.addProperty('AutoLayout GetAutoLayout SetAutoLayout')
    c.addProperty('BackgroundColour GetBackgroundColour SetBackgroundColour')
    c.addProperty('BackgroundStyle GetBackgroundStyle SetBackgroundStyle')
    c.addProperty('EffectiveMinSize GetEffectiveMinSize')
    c.addProperty('BestSize GetBestSize')
    c.addProperty('BestVirtualSize GetBestVirtualSize')
    c.addProperty('Border GetBorder')
    c.addProperty('Caret GetCaret SetCaret')
    c.addProperty('CharHeight GetCharHeight')
    c.addProperty('CharWidth GetCharWidth')
    c.addProperty('Children GetChildren')
    c.addProperty('ClientAreaOrigin GetClientAreaOrigin')
    c.addProperty('ClientSize GetClientSize SetClientSize')
    c.addProperty('Constraints GetConstraints SetConstraints')
    c.addProperty('ContainingSizer GetContainingSizer SetContainingSizer')
    c.addProperty('Cursor GetCursor SetCursor')
    c.addProperty('DefaultAttributes GetDefaultAttributes')
    c.addProperty('DropTarget GetDropTarget SetDropTarget')
    c.addProperty('EventHandler GetEventHandler SetEventHandler')
    c.addProperty('ExtraStyle GetExtraStyle SetExtraStyle')
    c.addProperty('Font GetFont SetFont')
    c.addProperty('ForegroundColour GetForegroundColour SetForegroundColour')
    c.addProperty('GrandParent GetGrandParent')
    c.addProperty('TopLevelParent GetTopLevelParent')
    c.addProperty('Handle GetHandle')
    c.addProperty('HelpText GetHelpText SetHelpText')
    c.addProperty('Id GetId SetId')
    c.addProperty('Label GetLabel SetLabel')
    c.addProperty('LayoutDirection GetLayoutDirection SetLayoutDirection')
    c.addProperty('MaxHeight GetMaxHeight')
    c.addProperty('MaxSize GetMaxSize SetMaxSize')
    c.addProperty('MaxWidth GetMaxWidth')
    c.addProperty('MinHeight GetMinHeight')
    c.addProperty('MinSize GetMinSize SetMinSize')
    c.addProperty('MinWidth GetMinWidth')
    c.addProperty('Name GetName SetName')
    c.addProperty('Parent GetParent')
    c.addProperty('Position GetPosition SetPosition')
    c.addProperty('ScreenPosition GetScreenPosition')
    c.addProperty('ScreenRect GetScreenRect')
    c.addProperty('Size GetSize SetSize')
    c.addProperty('Sizer GetSizer SetSizer')
    c.addProperty('ThemeEnabled GetThemeEnabled SetThemeEnabled')
    c.addProperty('ToolTip GetToolTip SetToolTip')
    c.addProperty('UpdateClientRect GetUpdateClientRect')
    c.addProperty('UpdateRegion GetUpdateRegion')
    c.addProperty('Validator GetValidator SetValidator')
    c.addProperty('VirtualSize GetVirtualSize SetVirtualSize')
    c.addProperty('WindowStyle GetWindowStyle SetWindowStyle')
    c.addProperty('WindowStyleFlag GetWindowStyleFlag SetWindowStyleFlag')
    c.addProperty('WindowVariant GetWindowVariant SetWindowVariant')
    c.addProperty('Shown IsShown Show')
    c.addProperty('Enabled IsEnabled Enable')
    c.addProperty('TopLevel IsTopLevel')
    c.addProperty('MinClientSize GetMinClientSize SetMinClientSize')
    c.addProperty('MaxClientSize GetMaxClientSize SetMaxClientSize')
    ##c.addProperty('GtkWidget GetGtkWidget')

    tools.fixWindowClass(c)
    tools.addSipConvertToSubClassCode(c)

    # for compatibility with Classic
    c.addPyMethod('GetPositionTuple',
                  '(self)',
                  'return self.GetPosition()',
                  deprecated='Use GetPosition instead')
    c.addPyMethod('GetSizeTuple',
                  '(self)',
                  'return self.GetSize()',
                  deprecated='Use GetSize instead')
    c.addPyMethod('MoveXY',
                  '(self, x, y)',
                  'return self.Move(x, y)',
                  deprecated='Use Move instead.')
    c.addPyMethod('SetSizeWH',
                  '(self, w, h)',
                  'return self.SetSize(w,h)',
                  deprecated='Use SetSize instead.')
    c.addPyMethod('SetVirtualSizeWH',
                  '(self, w, h)',
                  'return self.SetVirtualSize(w,h)',
                  deprecated='Use SetVirtualSize instead.')
    c.addPyMethod('GetVirtualSizeTuple',
                  '(self)',
                  'return self.GetVirtualSize()',
                  deprecated='Use GetVirtualSize instead.')
    c.addPyMethod('SetToolTipString',
                  '(self, string)',
                  'return self.SetToolTip(string)',
                  deprecated='Use SetToolTip instead.')
    c.addPyMethod('ConvertDialogPointToPixels',
                  '(self, point)',
                  'return self.ConvertDialogToPixels(point)',
                  deprecated='Use ConvertDialogToPixels instead.')
    c.addPyMethod('ConvertDialogSizeToPixels',
                  '(self, size)',
                  'return self.ConvertDialogToPixels(point)',
                  deprecated='Use ConvertDialogToPixels instead.')

    c.addPyMethod(
        'SetSizeHintsSz',
        '(self, minSize, maxSize=wx.DefaultSize, incSize=wx.DefaultSize)',
        'return self.SetSizeHints(minSize, maxSize, incSize)',
        deprecated='Use SetSizeHints instead.')

    # TODO: the C++ DoEraseBackground is protected in wxMSW. We need a way to
    # unprotect it, like adding a shim in the sip class...
    #c.addHeaderCode("""\
    #    #ifdef __WXMSW__
    #    #include <wx/msw/dc.h>
    #    #endif
    #    """)
    #c.addCppMethod('bool', 'DoEraseBackground', '(wxDC* dc)',
    #    doc="Default erase background implementation.",
    #    body="""\
    #    #ifdef __WXMSW__
    #        return self->DoEraseBackground(((wxMSWDCImpl*)dc->GetImpl())->GetHDC());
    #    #else
    #        dc->SetBackground(wxBrush(self->GetBackgroundColour()));
    #        dc->Clear();
    #        return true;
    #    #endif
    #    """)

    # this is a nested class
    c.find('ChildrenRepositioningGuard').addPrivateCopyCtor()
    module.insertItem(
        0,
        etgtools.TypedefDef(type='wxWindow::ChildrenRepositioningGuard',
                            name='ChildrenRepositioningGuard'))

    #-----------------------------------------------------------------------
    # Other stuff

    module.addPyCode('''\
    class FrozenWindow(object):
        """
        A context manager to be used with Python 'with' statements
        that will freeze the given window for the duration of the
        with block.
        """
        def __init__(self, window):
            self._win = window
        def __enter__(self):
            self._win.Freeze()
            return self
        def __exit__(self, exc_type, exc_val, exc_tb):
            self._win.Thaw()
    ''')

    module.addPyCode('''\
        def DLG_UNIT(win, dlg_unit, val2=None):
            """
            Convenience function for converting a wx.Point, wx.Size or
            (x,y) in dialog units to pixels, using the given window as a
            reference.
            """
            if val2 is not None:
                dlg_unit = (dlg_unit, val2)
            is_wxType = isinstance(dlg_unit, (wx.Size, wx.Point))
            pix = win.ConvertDialogToPixels(dlg_unit)
            if not is_wxType:
                pix = tuple(pix)
            return pix

        DLG_PNT = wx.deprecated(DLG_UNIT, "Use DLG_UNIT instead.")
        DLG_SZE = wx.deprecated(DLG_UNIT, "Use DLG_UNIT instead.")
        ''')

    # Add a wrapper for wxWindowList and a new iterator class for it that
    # makes wxWindowList quack like a read-only Python sequence.
    module.addItem(
        tools.wxListWrapperTemplate('wxWindowList', 'wxWindow', module))

    module.addCppFunction(
        'wxWindowList*',
        'GetTopLevelWindows',
        '()',
        noCopy=True,
        briefDoc=
        "Returns a list-like object of the the application's top-level windows, (frames,dialogs, etc.)",
        body="return &wxTopLevelWindows;")

    module.addPyCode("PyWindow = wx.deprecated(Window, 'Use Window instead.')")

    module.find('wxFindWindowAtPointer.pt').out = True

    module.find('wxFindWindowAtPointer').mustHaveApp()
    module.find('wxGetActiveWindow').mustHaveApp()
    module.find('wxGetTopLevelParent').mustHaveApp()

    module.addCppFunction('wxWindow*',
                          'FindWindowById',
                          '(long id, const wxWindow* parent=NULL)',
                          doc="""\
            FindWindowById(id, parent=None) -> Window

            Find the first window in the application with the given id. If parent
            is None, the search will start from all top-level frames and dialog
            boxes; if non-None, the search will be limited to the given window
            hierarchy. The search is recursive in both cases.
            """,
                          body="return wxWindow::FindWindowById(id, parent);",
                          mustHaveAppFlag=True)

    module.addCppFunction(
        'wxWindow*',
        'FindWindowByName',
        '(const wxString& name, const wxWindow* parent=NULL)',
        doc="""\
            FindWindowByName(name, parent=None) -> Window

            Find a window by its name (as given in a window constructor or Create
            function call). If parent is None, the search will start from all
            top-level frames and dialog boxes; if non-None, the search will be
            limited to the given window hierarchy. The search is recursive in both
            cases.

            If no window with the name is found, wx.FindWindowByLabel is called.""",
        body="return wxWindow::FindWindowByName(*name, parent);",
        mustHaveAppFlag=True)

    module.addCppFunction(
        'wxWindow*',
        'FindWindowByLabel',
        '(const wxString& label, const wxWindow* parent=NULL)',
        doc="""\
            FindWindowByLabel(label, parent=None) -> Window

            Find a window by its label. Depending on the type of window, the label
            may be a window title or panel item label. If parent is None, the
            search will start from all top-level frames and dialog boxes; if
            non-None, the search will be limited to the given window
            hierarchy. The search is recursive in both cases.""",
        body="return wxWindow::FindWindowByLabel(*label, parent);",
        mustHaveAppFlag=True)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Пример #7
0
def addPixelDataClass(module, pd, img, bpp, doc=""):
    # This function creates a ClassDef for a PixelData class defined in C++.
    # The C++ versions are template instantiations, so this allows us to
    # create nearly identical classes and just substitute the image class
    # name and the pixel data class name.

    #itrName = 'Iterator'
    
    itrName = pd + '_Accessor'
    module.addHeaderCode('typedef %s::Iterator %s;' % (pd, itrName))
    

    # First generate the class and methods for the PixelData class
    cls = ClassDef(name=pd, bases=['wxPixelDataBase'], briefDoc=doc, items=[
        MethodDef(name=pd, isCtor=True, items=[
            ParamDef(type=img+'&', name='bmp')],
            overloads=[        
                MethodDef(name=pd, isCtor=True, items=[
                    ParamDef(type=img+'&',         name='bmp'),
                    ParamDef(type='const wxRect&', name='rect')]),
                
                MethodDef(name=pd, isCtor=True, items=[
                    ParamDef(type=img+'&',          name='bmp'),
                    ParamDef(type='const wxPoint&', name='pt' ),
                    ParamDef(type='const wxSize&',  name='sz' )]),
                ]),
        
        MethodDef(name='~'+pd, isDtor=True),
        
        MethodDef(type=itrName, name='GetPixels', isConst=True),
        
        CppMethodDef('int', '__nonzero__', '()', 
            body="""\
                return (int)self->operator bool();
                """),
        ])
    
    # add this class to the module
    module.addItem(cls)
    
    
    # Now do the class and methods for its C++ Iterator class
    icls = ClassDef(name=itrName, items=[
        # Constructors
        MethodDef(name=itrName, isCtor=True, items=[
            ParamDef(name='data', type=pd+'&')],
            overloads=[
                MethodDef(name=itrName, isCtor=True, items=[
                    ParamDef(name='bmp', type=img+'&'),
                    ParamDef(name='data', type=pd+'&')]),
                MethodDef(name=itrName, isCtor=True)]),
        
        MethodDef(name='~'+itrName, isDtor=True),

        # Methods
        MethodDef(type='void', name='Reset', items=[
            ParamDef(type='const %s&' % pd, name='data')]),
        
        MethodDef(type='bool', name='IsOk', isConst=True),

        CppMethodDef('int', '__nonzero__', '()', 
            body="""\
                return (int)self->IsOk();
                """),

        MethodDef(type='void', name='Offset', items=[
            ParamDef(type='const %s&' % pd, name='data'),
            ParamDef(type='int', name='x'),
            ParamDef(type='int', name='y')]),
        
        MethodDef(type='void', name='OffsetX', items=[
            ParamDef(type='const %s&' % pd, name='data'),
            ParamDef(type='int', name='x')]),
        
        MethodDef(type='void', name='OffsetY', items=[
            ParamDef(type='const %s&' % pd, name='data'),
            ParamDef(type='int', name='y')]),
        
        MethodDef(type='void', name='MoveTo', items=[
            ParamDef(type='const %s&' % pd, name='data'),
            ParamDef(type='int', name='x'),
            ParamDef(type='int', name='y')]),
    
        # should this return the iterator?    
        CppMethodDef('void', 'nextPixel', '()', body="++(*self);"),
        
        # NOTE: For now I'm not wrapping the Red, Green, Blue and Alpha
        # functions because I can't hide the premultiplying needed on wxMSW
        # if only the individual components are wrapped, plus it would mean 3
        # or 4 trips per pixel from Python to C++ instead of just one.
        # Instead I'll add the Set and Get functions below and put the
        # premultiplying in there.
        ])
    
    assert bpp in [24, 32]
    
    if bpp == 24:
        icls.addCppMethod('void', 'Set', '(byte red, byte green, byte blue)',
            body="""\
                self->Red()   = red;
                self->Green() = green;
                self->Blue()  = blue;
                """)
        
        icls.addCppMethod('PyObject*', 'Get', '()',
            body="""\
                wxPyThreadBlocker blocker;
                PyObject* rv = PyTuple_New(3);
                PyTuple_SetItem(rv, 0, wxPyInt_FromLong(self->Red()));
                PyTuple_SetItem(rv, 1, wxPyInt_FromLong(self->Green()));
                PyTuple_SetItem(rv, 2, wxPyInt_FromLong(self->Blue()));
                return rv;            
                """)
    
    elif bpp == 32:
        icls.addCppMethod('void', 'Set', '(byte red, byte green, byte blue, byte alpha)',
            body="""\
                self->Red()   = wxPy_premultiply(red,   alpha);
                self->Green() = wxPy_premultiply(green, alpha);
                self->Blue()  = wxPy_premultiply(blue,  alpha);
                self->Alpha() = alpha;
                """)
        
        icls.addCppMethod('PyObject*', 'Get', '()',
            body="""\
                wxPyThreadBlocker blocker;
                PyObject* rv = PyTuple_New(4);
                int red   = self->Red();
                int green = self->Green();
                int blue  = self->Blue();
                int alpha = self->Alpha();
                
                PyTuple_SetItem(rv, 0, wxPyInt_FromLong( wxPy_unpremultiply(red,   alpha) ));
                PyTuple_SetItem(rv, 1, wxPyInt_FromLong( wxPy_unpremultiply(green, alpha) ));
                PyTuple_SetItem(rv, 2, wxPyInt_FromLong( wxPy_unpremultiply(blue,  alpha) ));
                PyTuple_SetItem(rv, 3, wxPyInt_FromLong( alpha ));
                return rv;
                """)
    
        
    
    # add it to the main pixel data class as a nested class
    #cls.insertItem(0, icls)
    
    # It's really a nested class, but we're pretending that it isn't (see the
    # typedef above) so add it at the module level instead.
    module.addItem(icls)
Пример #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)
    module.check4unittest = False

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

    module.addHeaderCode('#include <wxpy_api.h>')
    module.addImport('_core')
    module.addImport('_xml')
    module.addPyCode('import wx', order=10)
    module.addInclude(INCLUDES)

    module.addInitializerCode("""\
        //wxXmlInitResourceModule();
        wxXmlResource::Get()->InitAllHandlers();
        """)

    module.addHeaderCode('#include <wx/xrc/xmlres.h>')
    module.addHeaderCode('#include <wx/fs_mem.h>')
    module.addHeaderCode('#include "wxpybuffer.h"')

    module.insertItem(
        0,
        etgtools.WigCode("""\
        // forward declarations
        class wxAnimation;
        """))

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

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

    # Add a bit of code to the ctors to call InitAllHandlers(), for
    # compatibility with Classic
    for ctor in c.find('wxXmlResource').all():
        template = """\
        Py_BEGIN_ALLOW_THREADS
        sipCpp = new sipwxXmlResource({args});
        sipCpp->InitAllHandlers();
        Py_END_ALLOW_THREADS 
        """
        if 'filemask' in ctor.argsString:
            args = '*filemask,flags,*domain'
        else:
            args = 'flags,*domain'
        ctor.setCppCode_sip(template.format(args=args))

    c.addPublic()
    c.addCppMethod(
        'bool',
        'LoadFromString',
        '(wxPyBuffer* data)',
        doc=
        "Load the resource from a string or other data buffer compatible object.",
        #protection='public',
        body="""\
            static int s_memFileIdx = 0;

            // Check for memory FS. If not present, load the handler:
            wxMemoryFSHandler::AddFile(wxT("XRC_resource/dummy_file"),
                                       wxT("dummy data"));
            wxFileSystem fsys;
            wxFSFile *f = fsys.OpenFile(wxT("memory:XRC_resource/dummy_file"));
            wxMemoryFSHandler::RemoveFile(wxT("XRC_resource/dummy_file"));
            if (f)
                delete f;
            else
                wxFileSystem::AddHandler(new wxMemoryFSHandler);

            // Now put the resource data into the memory FS
            wxString filename(wxT("XRC_resource/data_string_"));
            filename << s_memFileIdx;
            s_memFileIdx += 1;
            wxMemoryFSHandler::AddFile(filename, data->m_ptr, data->m_len);

            // Load the "file" into the resource object
            bool retval = self->Load(wxT("memory:") + filename );
            return retval;
            """)

    c.find('AddHandler.handler').transfer = True
    c.find('InsertHandler.handler').transfer = True
    c.find('Set.res').transfer = True
    c.find('Set').transferBack = True
    c.find('AddSubclassFactory.factory').transfer = True

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

    # un-ignore all the protected methods
    for item in c.allItems():
        if isinstance(item, etgtools.MethodDef):
            item.ignore(False)

    c.find('DoCreateResource').factory = True

    #-----------------------------------------------------------------
    module.addPyFunction(
        'EmptyXmlResource',
        '(flags=XRC_USE_LOCALE, domain="")',
        deprecated="Use :class:`xrc.XmlResource` instead",
        doc=
        'A compatibility wrapper for the XmlResource(flags, domain) constructor',
        body='return XmlResource(flags, domain)')

    module.addPyFunction(
        'XRCID',
        '(str_id, value_if_not_found=wx.ID_NONE)',
        doc=
        'Returns a numeric ID that is equivalent to the string ID used in an XML resource.',
        body='return XmlResource.GetXRCID(str_id, value_if_not_found)')

    module.addPyFunction(
        'XRCCTRL',
        '(window, str_id, *ignoreargs)',
        doc=
        'Returns the child window associated with the string ID in an XML resource.',
        body='return window.FindWindowById(XRCID(str_id))')

    cls = ClassDef(name='wxXmlSubclassFactory',
                   briefDoc="",
                   items=[
                       MethodDef(name='wxXmlSubclassFactory', isCtor=True),
                       MethodDef(name='~wxXmlSubclassFactory', isDtor=True),
                       MethodDef(name='Create',
                                 type='wxObject*',
                                 isVirtual=True,
                                 isPureVirtual=True,
                                 items=[
                                     ParamDef(type='const wxString&',
                                              name='className')
                                 ])
                   ])
    module.addItem(cls)

    module.addPyCode("""\
        # Create a factory for handling the subclass property of XRC's 
        # object tag.  This factory will search for the specified 
        # package.module.class and will try to instantiate it for XRC's 
        # use.  The class must support instantiation with no parameters and 
        # delayed creation of the UI widget (aka 2-phase create).

        def _my_import(name):
            try:
                mod = __import__(name)
            except ImportError:
                import traceback
                print traceback.format_exc()
                raise
            components = name.split('.')
            for comp in components[1:]:
                mod = getattr(mod, comp)
            return mod
        
        class XmlSubclassFactory_Python(XmlSubclassFactory):
            def __init__(self):
                XmlSubclassFactory.__init__(self)
        
            def Create(self, className):
                assert className.find('.') != -1, "Module name must be specified!"
                mname = className[:className.rfind('.')]
                cname = className[className.rfind('.')+1:]
                module = _my_import(mname)
                klass = getattr(module, cname)
                inst = klass()
                return inst        
        
        XmlResource.AddSubclassFactory(XmlSubclassFactory_Python())
        """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Пример #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('wxIdManager')
    assert isinstance(c, etgtools.ClassDef)
    # no tweaks needed for this class


    # wxWindowIDRef is not documented (and probably rightly so) but we're going
    # to use it from Python anyway to help with preallocating IDs in a way that
    # allows them to be reused and be also be protected from conflicts from
    # other auto allocated IDs.

    # First, add defintions of the existing C++ class and its elements
    klass = ClassDef(name='wxWindowIDRef', bases = [],
        briefDoc="""\
            A wxWindowIDRef object wraps an ID value and marks it as being in-use until all references to that ID are gone.
            """,
        items = [
            MethodDef(name='wxWindowIDRef', className='wxWindowIDRef', isCtor=True,
                briefDoc='Default constructor',
                overloads=[
                MethodDef(name='wxWindowIDRef', className='wxWindowIDRef', isCtor=True,
                    briefDoc='Create reference from an ID',
                    items=[ ParamDef(type='int', name='id') ]),
                
                MethodDef(name='wxWindowIDRef', className='wxWindowIDRef', isCtor=True,
                    briefDoc='Copy an ID reference',
                    items=[ ParamDef(type='const wxWindowIDRef&', name='idref') ]),
                ]),
            
            MethodDef(name='~wxWindowIDRef', className='wxWindowIDRef', isDtor=True),

            MethodDef(type='int', name='GetValue',
                briefDoc='Get the ID value'),
        ])

    # Now tweak it a bit
    klass.addCppMethod('int', 'GetId', '()',
        doc="Alias for GetValue allowing the IDRef to be passed as the source parameter to :meth:`wx.EvtHandler.Bind`.",
        body="""\
            return self->GetValue();
            """)

    klass.addCppMethod('int', '__int__', '()',
        doc="Alias for GetValue allowing the IDRef to be passed as the WindowID parameter when creating widgets or etc.",
        body="""\
            return self->GetValue();
            """)
    
    klass.addCppMethod('bool', '__eq__', '(wxWindowID id)', "return self->GetValue() == id;")
    klass.addCppMethod('bool', '__ne__', '(wxWindowID id)', "return self->GetValue() != id;")
    klass.addCppMethod('bool', '__lt__', '(wxWindowID id)', "return self->GetValue() < id;")
    klass.addCppMethod('bool', '__gt__', '(wxWindowID id)', "return self->GetValue() > id;")
    klass.addCppMethod('bool', '__le__', '(wxWindowID id)', "return self->GetValue() <= id;")
    klass.addCppMethod('bool', '__ge__', '(wxWindowID id)', "return self->GetValue() >= id;")

    klass.addPyMethod('__repr__', '(self)', 'return "WindowIDRef: {}".format(self.GetId())')
    klass.addPyMethod('__hash__', '(self)', 'return hash(self.GetValue())')


    # and finish it up by adding it to the module
    module.addItem(klass)

    # Now, let's add a new Python function to the global scope that reserves an 
    # ID (or range) and returns a ref object for it. 
    module.addPyFunction('NewIdRef', '(count=1)', 
        doc="""\
            Reserves a new Window ID (or range of WindowIDs) and returns a 
            :class:`wx.WindowIDRef` object (or list of them) that will help 
            manage the reservation of that ID.

            This function is intended to be a drop-in replacement of the old 
            and deprecated :func:`wx.NewId` function, with the added benefit 
            that the ID should never conflict with an in-use ID or other IDs 
            generated by this function.
            """,
        body="""\
            if count == 1:
                return WindowIDRef(IdManager.ReserveId())
            else:
                start = IdManager.ReserveId(count)
                IDRefs = []
                for id in range(start, start+count):
                    IDRefs.append(WindowIDRef(id))
                return IDRefs
            """)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Пример #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)

    #-----------------------------------------------------------------
    # The wxPyAxBaseWindow class does not come from the parsed Doxygen xml,
    # instead it is manufactured entirely in this ETG script.  We're doing it
    # here instead of in a raw .sip file so we can run the generators on it
    # and get things like documentation and .pyi files generated like any
    # normal class.

    # First, output some C++ code
    module.addHeaderCode("""\
        class wxPyAxBaseWindow : public wxWindow
        {
            DECLARE_DYNAMIC_CLASS(wxPyAxBaseWindow)
        public:
            wxPyAxBaseWindow(wxWindow* parent, const wxWindowID id=-1,
                            const wxPoint& pos = wxDefaultPosition,
                            const wxSize& size = wxDefaultSize,
                            long style = 0,
                            const wxString& name = wxPanelNameStr)
            : wxWindow(parent, id, pos, size, style, name) {}
            wxPyAxBaseWindow() : wxWindow() {}
            virtual bool MSWTranslateMessage(WXMSG* msg)
            {
                return wxWindow::MSWTranslateMessage(msg);
            }
        };
        """)
    module.addCppCode("""\
        IMPLEMENT_DYNAMIC_CLASS(wxPyAxBaseWindow, wxWindow);
        """)

    # Now create the extractor objects that will be run through the generators
    module.addItem(TypedefDef(type='void', name='WXMSG'))

    cls = ClassDef(name='wxPyAxBaseWindow',
                   bases=['wxWindow'],
                   briefDoc="""\
            A Window class for use with ActiveX controls.

            This Window class exposes some low-level Microsoft Windows
            specific methods which can be overridden in Python.  Intended for
            use as an ActiveX container, but could also be useful
            elsewhere.""",
                   items=[
                       MethodDef(name='wxPyAxBaseWindow',
                                 isCtor=True,
                                 items=[
                                     ParamDef(type='wxWindow*', name='parent'),
                                     ParamDef(type='const wxWindowID',
                                              name='id',
                                              default='-1'),
                                     ParamDef(type='const wxPoint&',
                                              name='pos',
                                              default='wxDefaultPosition'),
                                     ParamDef(type='const wxSize&',
                                              name='size',
                                              default='wxDefaultSize'),
                                     ParamDef(type='long',
                                              name='style',
                                              default='0'),
                                     ParamDef(type='const wxString&',
                                              name='name',
                                              default='wxPanelNameStr'),
                                 ],
                                 overloads=[
                                     MethodDef(name='wxPyAxBaseWindow',
                                               isCtor=True),
                                 ]),
                       MethodDef(type='bool',
                                 name='MSWTranslateMessage',
                                 isVirtual=True,
                                 items=[ParamDef(type='WXMSG*', name='msg')])
                   ])

    module.addItem(cls)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
Пример #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('wxWindow')
    assert isinstance(c, etgtools.ClassDef)
    module.addGlobalStr('wxPanelNameStr', c)
        
    
    # First we need to let the wrapper generator know about wxWindowBase since
    # AddChild and RemoveChild need to use that type in order to be virtualized.
    winbase = ClassDef(name='wxWindowBase', bases=['wxEvtHandler'], abstract=True,
            items=[MethodDef(name='AddChild', isVirtual=True, type='void', protection='public',
                        items=[ParamDef(name='child', type='wxWindowBase*')]),
                   MethodDef(name='RemoveChild', isVirtual=True, type='void', protection='public',
                        items=[ParamDef(name='child', type='wxWindowBase*')])
                   ])
    module.insertItemBefore(c, winbase)
    
    # Now change the base class of wxWindow
    c.bases = ['wxWindowBase']
    
    # And fix the arg types we get from Doxy
    c.find('AddChild.child').type = 'wxWindowBase*'
    c.find('RemoveChild.child').type = 'wxWindowBase*'
    
    
    # We now return you to our regularly scheduled programming...
    c.includeCppCode('src/window_ex.cpp')

    # ignore some overloads that will be ambiguous afer wrapping
    c.find('GetChildren').overloads = []
    c.find('GetChildren').noCopy = True
    c.find('GetClientSize').findOverload('int *').ignore()
    c.find('GetSize').findOverload('int *').ignore()
    c.find('GetVirtualSize').findOverload('int *').ignore()
    c.find('GetPosition').findOverload('int *').ignore()
    c.find('GetScreenPosition').findOverload('int *').ignore()
    c.find('ClientToScreen').findOverload('int *').ignore()
    c.find('ScreenToClient').findOverload('int *').ignore()

    # Release the GIL for potentially blocking or long-running functions
    c.find('PopupMenu').releaseGIL()
    c.find('ProcessEvent').releaseGIL()
    c.find('ProcessWindowEvent').releaseGIL()
    c.find('ProcessWindowEventLocally').releaseGIL()
    
    # Add a couple wrapper functions for symmetry with the getters of the same name
    c.addPyMethod('SetRect', '(self, rect)', 'return self.SetSize(rect)')
    c.addPyProperty('Rect GetRect SetRect')
    c.addPyMethod('SetClientRect', '(self, rect)', 'return self.SetClientSize(rect)')
    c.addPyProperty('ClientRect GetClientRect SetClientRect')
                    
    m = c.find('GetTextExtent').findOverload('int *')
    m.pyName = 'GetFullTextExtent'
    m.find('w').out = True
    m.find('h').out = True
    m.find('descent').out = True
    m.find('externalLeading').out = True
    
    c.find('GetHandle').type = 'unsigned long'
    c.find('GetHandle').setCppCode("return wxPyGetWinHandle(self);")
    
    c.addCppMethod('void*', 'GetGtkWidget', '()', """\
    #ifdef __WXGTK__
        return (void*)self->GetHandle();
    #else
        return NULL;
    #endif
    """)
    
    c.addCppMethod('void', 'AssociateHandle', '(long handle)',
        doc="Associate the window with a new native handle",
        body="self->AssociateHandle((WXWidget)handle);")
    c.addCppMethod('void', 'DissociateHandle', '()',
        doc="Dissociate the current native handle from the window",
        body="self->DissociateHandle();")
        
    
    # Add some new methods
    c.addCppMethod('wxWindow*', 'GetTopLevelParent', '()',
                   'return wxGetTopLevelParent(self);',
                   briefDoc="Returns the first ancestor of this window which is a top-level window.")

    c.addCppMethod('bool', 'MacIsWindowScrollbar', '(const wxWindow* sb)', """\
    #ifdef __WXMAC__
        return self->MacIsWindowScrollbar(sb); 
    #else
        return false;
    #endif
    """,
    pyArgsString="(sb)",
    briefDoc="Is the given widget one of this window's built-in scrollbars?  Only applicable on Mac.")

    
    c.addCppMethod('void', 'SetDimensions', '(int x, int y, int width, int height, int sizeFlags=wxSIZE_AUTO)', 
        pyArgsString="(x, y, width, height, sizeFlags=SIZE_AUTO)",
        body="""\
        self->SetSize(x, y, width, height, sizeFlags);
        """)
    c.addPyCode("Window.SetDimensions = wx.deprecated(Window.SetDimensions, 'Use SetSize instead.')")
    
    # Make the Register/UnregisterHotKey functions be available on Windows,
    # and empty stubs otherwise
    c.find('RegisterHotKey').setCppCode("""\
    #if wxUSE_HOTKEY
        return self->RegisterHotKey(hotkeyId, modifiers, virtualKeyCode);
    #else
        return false;
    #endif
    """)
    c.find('UnregisterHotKey').setCppCode("""\
    #if wxUSE_HOTKEY
        return self->UnregisterHotKey(hotkeyId);
    #else
        return false;
    #endif
    """)    
    c.find('RegisterHotKey').isVirtual = False
    c.find('UnregisterHotKey').isVirtual = False

    
    c.find('SetDoubleBuffered').setCppCode("""\
    #if defined(__WXGTK20__) || defined(__WXMSW__)
        self->SetDoubleBuffered(on);
    #endif
    """)

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


    c.addPyMethod('DestroyLater', '(self)',
        doc="""\
           Schedules the window to be destroyed in the near future.
           
           This should be used whenever Destroy could happen too soon, such
           as when there may still be events for this window or its children
           waiting in the event queue. 
           """,
        body="""\
            self.Hide()
            wx.GetApp().ScheduleForDestruction(self)
            """)
    
    
    # MSW only.  Do we want them wrapped?
    c.find('GetAccessible').ignore()
    c.find('SetAccessible').ignore()
    
    # Make some of the protected methods visible and overridable from Python
    c.find('SendDestroyEvent').ignore(False)

    c.find('Destroy').transferThis=True
    c.addPyMethod('PostCreate', '(self, pre)', 'pass', deprecated='PostCreate is no longer necessary.')
    
    # transfer ownership of these parameters to the C++ object
    c.find('SetCaret.caret').transfer = True
    c.find('SetToolTip.tip').transfer = True
    c.find('SetDropTarget.target').transfer = True
    c.find('SetConstraints.constraints').transfer = True
    c.find('SetSizer.sizer').transfer = True
    c.find('SetSizerAndFit.sizer').transfer = True
    
    # Define some properties using the getter and setter methods
    c.addProperty('AcceleratorTable GetAcceleratorTable SetAcceleratorTable')
    c.addProperty('AutoLayout GetAutoLayout SetAutoLayout')
    c.addProperty('BackgroundColour GetBackgroundColour SetBackgroundColour')
    c.addProperty('BackgroundStyle GetBackgroundStyle SetBackgroundStyle')
    c.addProperty('EffectiveMinSize GetEffectiveMinSize')
    c.addProperty('BestSize GetBestSize')
    c.addProperty('BestVirtualSize GetBestVirtualSize')
    c.addProperty('Border GetBorder')
    c.addProperty('Caret GetCaret SetCaret')
    c.addProperty('CharHeight GetCharHeight')
    c.addProperty('CharWidth GetCharWidth')
    c.addProperty('Children GetChildren')
    c.addProperty('ClientAreaOrigin GetClientAreaOrigin')
    c.addProperty('ClientSize GetClientSize SetClientSize')
    c.addProperty('Constraints GetConstraints SetConstraints')
    c.addProperty('ContainingSizer GetContainingSizer SetContainingSizer')
    c.addProperty('Cursor GetCursor SetCursor')
    c.addProperty('DefaultAttributes GetDefaultAttributes')
    c.addProperty('DropTarget GetDropTarget SetDropTarget')
    c.addProperty('EventHandler GetEventHandler SetEventHandler')
    c.addProperty('ExtraStyle GetExtraStyle SetExtraStyle')
    c.addProperty('Font GetFont SetFont')
    c.addProperty('ForegroundColour GetForegroundColour SetForegroundColour')
    c.addProperty('GrandParent GetGrandParent')
    c.addProperty('TopLevelParent GetTopLevelParent')
    c.addProperty('Handle GetHandle')
    c.addProperty('HelpText GetHelpText SetHelpText')
    c.addProperty('Id GetId SetId')
    c.addProperty('Label GetLabel SetLabel')
    c.addProperty('LayoutDirection GetLayoutDirection SetLayoutDirection')
    c.addProperty('MaxHeight GetMaxHeight')
    c.addProperty('MaxSize GetMaxSize SetMaxSize')
    c.addProperty('MaxWidth GetMaxWidth')
    c.addProperty('MinHeight GetMinHeight')
    c.addProperty('MinSize GetMinSize SetMinSize')
    c.addProperty('MinWidth GetMinWidth')
    c.addProperty('Name GetName SetName')
    c.addProperty('Parent GetParent')
    c.addProperty('Position GetPosition SetPosition')
    c.addProperty('ScreenPosition GetScreenPosition')
    c.addProperty('ScreenRect GetScreenRect')
    c.addProperty('Size GetSize SetSize')
    c.addProperty('Sizer GetSizer SetSizer')
    c.addProperty('ThemeEnabled GetThemeEnabled SetThemeEnabled')
    c.addProperty('ToolTip GetToolTip SetToolTip')
    c.addProperty('UpdateClientRect GetUpdateClientRect')
    c.addProperty('UpdateRegion GetUpdateRegion')
    c.addProperty('Validator GetValidator SetValidator')
    c.addProperty('VirtualSize GetVirtualSize SetVirtualSize')
    c.addProperty('WindowStyle GetWindowStyle SetWindowStyle')
    c.addProperty('WindowStyleFlag GetWindowStyleFlag SetWindowStyleFlag')
    c.addProperty('WindowVariant GetWindowVariant SetWindowVariant')
    c.addProperty('Shown IsShown Show')
    c.addProperty('Enabled IsEnabled Enable')
    c.addProperty('TopLevel IsTopLevel')
    c.addProperty('MinClientSize GetMinClientSize SetMinClientSize')
    c.addProperty('MaxClientSize GetMaxClientSize SetMaxClientSize')
    ##c.addProperty('GtkWidget GetGtkWidget')

    tools.fixWindowClass(c)
    tools.addSipConvertToSubClassCode(c)

    # for compatibility with Classic
    c.addPyMethod('GetPositionTuple', '(self)', 'return self.GetPosition()', deprecated='Use GetPosition instead')
    c.addPyMethod('MoveXY',  '(self, x, y)', 'return self.Move(x, y)', deprecated='Use Move instead.')
    c.addPyMethod('SetSizeWH', '(self, w, h)', 'return self.SetSize(w,h)', deprecated='Use SetSize instead.')
    c.addPyMethod('SetVirtualSizeWH', '(self, w, h)', 'return self.SetVirtualSize(w,h)', deprecated='Use SetVirtualSize instead.')
    c.addPyMethod('GetVirtualSizeTuple', '(self)', 'return self.GetVirtualSize()', deprecated='Use GetVirtualSize instead.')
    c.addPyMethod('SetToolTipString',  '(self, string)', 'return self.SetToolTip(string)', deprecated='Use SetToolTip instead.')
    c.addPyMethod('ConvertDialogPointToPixels', '(self, point)', 'return self.ConvertDialogToPixels(point)', deprecated='Use ConvertDialogToPixels instead.')
    c.addPyMethod('ConvertDialogSizeToPixels', '(self, size)', 'return self.ConvertDialogToPixels(point)', deprecated='Use ConvertDialogToPixels instead.')


    # this is a nested class
    c.find('ChildrenRepositioningGuard').addPrivateCopyCtor()
    module.insertItem(0, 
            etgtools.TypedefDef(type='wxWindow::ChildrenRepositioningGuard',
                                name='ChildrenRepositioningGuard'))

        
    #-----------------------------------------------------------------------
    # Other stuff
    
    module.addPyCode('''\
    class FrozenWindow(object):
        """
        A context manager to be used with Python 'with' statements
        that will freeze the given window for the duration of the
        with block.
        """
        def __init__(self, window):
            self._win = window
        def __enter__(self):
            self._win.Freeze()
            return self
        def __exit__(self, exc_type, exc_val, exc_tb):
            self._win.Thaw()
    ''')
    
    
    # Add a wrapper for wxWindowList and a new iterator class for it that
    # makes wxWindowList quack like a read-only Python sequence.
    module.addItem(tools.wxListWrapperTemplate('wxWindowList', 'wxWindow', module))
    
    module.addCppFunction('wxWindowList*', 'GetTopLevelWindows', '()', 
        noCopy=True,
        briefDoc="Returns a list-like object of the the application's top-level windows, (frames,dialogs, etc.)",
        body="return &wxTopLevelWindows;")
    
    module.addPyCode("PyWindow = wx.deprecated(Window, 'Use Window instead.')")


    module.find('wxFindWindowAtPointer.pt').out = True
    
   
    module.addCppFunction('wxWindow*', 'FindWindowById', '(long id, const wxWindow* parent=NULL)', 
        doc="""\
            FindWindowById(id, parent=None) -> Window
        
            Find the first window in the application with the given id. If parent
            is None, the search will start from all top-level frames and dialog
            boxes; if non-None, the search will be limited to the given window
            hierarchy. The search is recursive in both cases.
            """,
        body="return wxWindow::FindWindowById(id, parent);")
    
    module.addCppFunction('wxWindow*', 'FindWindowByName', '(const wxString& name, const wxWindow* parent=NULL)', 
        doc="""\
            FindWindowByName(name, parent=None) -> Window
            
            Find a window by its name (as given in a window constructor or Create
            function call). If parent is None, the search will start from all
            top-level frames and dialog boxes; if non-None, the search will be
            limited to the given window hierarchy. The search is recursive in both
            cases.

            If no window with the name is found, wx.FindWindowByLabel is called.""",
        body="return wxWindow::FindWindowByName(*name, parent);")
    
    module.addCppFunction('wxWindow*', 'FindWindowByLabel', '(const wxString& label, const wxWindow* parent=NULL)', 
        doc="""\
            FindWindowByLabel(label, parent=None) -> Window
            
            Find a window by its label. Depending on the type of window, the label
            may be a window title or panel item label. If parent is None, the
            search will start from all top-level frames and dialog boxes; if
            non-None, the search will be limited to the given window
            hierarchy. The search is recursive in both cases.""",
        body="return wxWindow::FindWindowByLabel(*label, parent);")
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)