예제 #1
0
def wx2Sphinx(name):
    """
    Converts a wxWidgets specific string into a Phoenix-ReST-ready string.

    :param string `name`: any string.
    """
    from etgtools.tweaker_tools import removeWxPrefix

    if '<' in name:
        name = name[0:name.index('<')]

    name = name.strip()
    newname = fullname = removeWxPrefix(name)

    if '.' in newname and len(newname) > 3:
        lookup, remainder = newname.split('.')
        remainder = '.%s' % remainder
    else:
        lookup = newname
        remainder = ''

    from etgtools.item_module_map import ItemModuleMap
    imm = ItemModuleMap()
    if lookup in imm:
        fullname = imm[lookup] + lookup + remainder

    return newname, fullname
예제 #2
0
def wx2Sphinx(name):
    """
    Converts a wxWidgets specific string into a Phoenix-ReST-ready string.

    :param string `name`: any string.
    """
    from etgtools.tweaker_tools import removeWxPrefix

    if '<' in name:
        name = name[0:name.index('<')]

    name = name.strip()
    newname = fullname = removeWxPrefix(name)

    if '.' in newname and len(newname) > 3:
        lookup, remainder = newname.split('.')
        remainder = '.%s' % remainder
    else:
        lookup = newname
        remainder = ''

    from etgtools.item_module_map import ItemModuleMap
    imm = ItemModuleMap()
    if lookup in imm:
        fullname = imm[lookup] + lookup + remainder
        
    return newname, fullname
예제 #3
0
def convertToPython(text):
    """
    Converts the input `text` into a more ReSTified version of it.

    This involves the following steps:

    1. Any C++ specific declaration (like ``unsigned``, ``size_t`` and so on
       is removed.
    2. Lines starting with "Include file" or "#include" are ignored.
    3. Uppercase constants (i.e., like ID_ANY, HORIZONTAL and so on) are converted
       into inline literals (i.e., ``ID_ANY``, ``HORIZONTAL``).
    4. The "wx" prefix is removed from all the words in the input `text`.  #***

    :param string `text`: any string.

    :rtype: `string`
    """
    from etgtools.tweaker_tools import removeWxPrefix
    from etgtools.item_module_map import ItemModuleMap

    newlines = []
    unwanted = ['Include file', '#include']

    for line in text.splitlines():

        newline = []

        for remove in unwanted:
            if remove in line:
                line = line[0:line.index(remove)]
                break

        spacer = ' ' * (len(line) - len(line.lstrip()))

        line = replaceCppItems(line)

        for word in RE_KEEP_SPACES.split(line):

            if word == VERSION:
                newline.append(word)
                continue

            newword = word
            for s in PUNCTUATION:
                newword = newword.replace(s, "")

            if newword in VALUE_MAP:
                word = word.replace(newword, VALUE_MAP[newword])
                newline.append(word)
                continue

            if newword not in IGNORE and not newword.startswith('wx.'):
                word = removeWxPrefix(word)
                newword = removeWxPrefix(newword)

            if "::" in word and not word.endswith("::"):
                # Bloody SetCursorEvent...
                word = word.replace("::wx", ".")  # ***
                word = word.replace("::", ".")
                word = "`%s`" % word
                newline.append(word)
                continue

            if (newword.upper() == newword and newword not in PUNCTUATION
                    and newword not in IGNORE and len(newword.strip()) > 1
                    and not isNumeric(newword)
                    and newword not in ['DC', 'GCDC']):

                if '``' not in newword and '()' not in word and '**' not in word:
                    word = word.replace(
                        newword,
                        "``%s``" % ItemModuleMap().get_fullname(newword))

            word = word.replace('->', '.')
            newline.append(word)

        newline = spacer + ''.join(newline)
        newline = newline.replace(':see:', '.. seealso::')
        newline = newline.replace(':note:', '.. note::')
        newlines.append(newline)

    formatted = "\n".join(newlines)
    formatted = formatted.replace('\\', '\\\\')

    return formatted
예제 #4
0
def pythonizeType(ptype, is_param):
    """
    Replaces various C++ specific stuff with more Pythonized version of them,
    for parameter lists and return types (i.e., the `:param:` and `:rtype:`
    ReST roles).

    :param string `ptype`: any string;
    :param bool `is_param`: ``True`` if this is a parameter description, ``False``
     if it is a return type.

    :rtype: `string`
    """
    from etgtools.tweaker_tools import removeWxPrefix

    if 'size_t' in ptype:
        ptype = 'int'
    elif 'wx.' in ptype:
        ptype = ptype[3:]  # ***
    else:
        ptype = wx2Sphinx(replaceCppItems(ptype))[1]

    ptype = ptype.replace('::', '.').replace('*&', '')
    ptype = ptype.replace('int const', 'int')
    ptype = ptype.replace('Uint32', 'int').replace('**',
                                                   '').replace('Int32', 'int')
    ptype = ptype.replace('FILE', 'file')
    ptype = ptype.replace('boolean', 'bool')

    for item in ['unsignedchar', 'unsignedint', 'unsignedlong', 'unsigned']:
        ptype = ptype.replace(item, 'int')

    ptype = ptype.strip()
    ptype = removeWxPrefix(ptype)

    if '. wx' in ptype:  #***
        ptype = ptype.replace('. wx', '.')

    plower = ptype.lower()

    if plower == 'double':
        ptype = 'float'

    if plower in ['string', 'char', 'artid', 'artclient']:
        ptype = 'string'

    if plower in [
            'coord', 'byte', 'fileoffset', 'short', 'time_t', 'intptr',
            'uintptr', 'windowid'
    ]:
        ptype = 'int'

    if plower in ['longlong']:
        ptype = 'long'

    cpp = ['ArrayString', 'ArrayInt', 'ArrayDouble']
    python = ['list of strings', 'list of integers', 'list of floats']

    for c, p in zip(cpp, python):
        ptype = ptype.replace(c, p)

    if 'Image.' in ptype:
        ptype = ptype.split('.')[-1]

    if 'FileName' in ptype:
        ptype = 'string'

    if ptype.endswith('&'):
        ptype = ptype[0:-1]
        if ' ' not in ptype:
            ptype = ':class:`%s`' % ptype

    else:
        if is_param and '.' in ptype:
            modules = list(MODULENAME_REPLACE.values())
            modules.sort()
            modules = modules[1:]
            if ptype.split('.')[0] + '.' in modules:
                ptype = ':ref:`%s`' % ptype

    return ptype
예제 #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.

    # 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)
예제 #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.


    # 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)
예제 #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('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)
예제 #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('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)
예제 #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('wxCursor')
    assert isinstance(c, etgtools.ClassDef)

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


    c.find('wxCursor').findOverload('bits').ignore()
    c.find('wxCursor').findOverload('cursorName').find('type').default='wxBITMAP_TYPE_ANY'
    # TODO: This ctor ^^ in Classic has a custom implementation for wxGTK that
    # sets the hotspot. Is that still needed?

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

    c.addCppMethod('long', 'GetHandle', '()', """\
    #ifdef __WXMSW__
        return (long)self->GetHandle();
    #else
        return 0;
    #endif""",
    briefDoc="Get the handle for the Cursor.  Windows only.")

    c.addCppMethod('void', 'SetHandle', '(long handle)', """\
    #ifdef __WXMSW__
        self->SetHandle((WXHANDLE)handle);
    #endif""",
    briefDoc="Set the handle to use for this Cursor.  Windows only.")

    # TODO:  Classic has MSW-only getters and setters for width, height, depth, and size.

    # The stock Cursor items are documented as simple pointers, but in reality
    # they are macros that evaluate to a function call that returns a cursor
    # 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 cursor in a block of Python code, that will then be
    # intialized later when the wx.App is created.
    c.addCppMethod('void', '_copyFrom', '(const wxCursor* other)',
                   "*self = *other;",
                   briefDoc="For internal use only.")  # ??
    pycode = '# These stock cursors will be initialized when the wx.App object is created.\n'
    for item in module:
        if '_CURSOR' in item.name:
            item.ignore()
            pycode += '%s = Cursor()\n' % tools.removeWxPrefix(item.name)
    module.addPyCode(pycode)

    # former renamed constructors
    module.addPyCode('StockCursor = wx.deprecated(Cursor, "Use Cursor instead.")')
    module.addPyCode('CursorFromImage = wx.deprecated(Cursor, "Use Cursor instead.")')

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

    #-----------------------------------------------------------------
    # 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)
예제 #11
0
def findControlImages(elementOrString):
    """
    Given the input `element` (an instance of `xml.etree.ElementTree.Element`
    or a plain string)
    representing a Phoenix class description, this function will scan the
    doxygen image folder ``DOXYROOT`` to look for a widget screenshot.

    If this class indeed represents a widget and a screenshot is found, it is
    then copied to the appropriate Sphinx input folder ``WIDGETS_IMAGES_ROOT``
    in one of its sub-folders (``wxmsw``, ``wxgtk``, ``wxmac``) depending on
    which platform the screenshot was taken.

    :param `elementOrString`: the XML element we want to examine (an instance of
     xml.etree.ElementTree.Element) or a plain string (usually for wx.lib).

    :rtype: `list`

    :returns: A list of image paths, every element of it representing a screenshot on
     a different platform. An empty list if returned if no screenshots have been found.
     
    .. note:: If a screenshot doesn't exist for one (or more) platform but it
       exists for others, the missing images will be replaced by the "no_appearance.png"
       file (you can find it inside the ``WIDGETS_IMAGES_ROOT`` folder.

    """
    from etgtools.tweaker_tools import removeWxPrefix

    if isinstance(elementOrString, string_base):
        class_name = py_class_name = elementOrString.lower()
    else:
        element = elementOrString
        class_name = element.pyName if element.pyName else removeWxPrefix(element.name)
        py_class_name = wx2Sphinx(class_name)[1]

        class_name = class_name.lower()
        py_class_name = py_class_name.lower()

    image_folder = os.path.join(DOXYROOT, 'images')

    appearance = ODict()

    for sub_folder in ['wxmsw', 'wxmac', 'wxgtk']:

        png_file = class_name + '.png'
        appearance[sub_folder] = ''
        
        possible_image = os.path.join(image_folder, sub_folder, png_file)
        new_path = os.path.join(WIDGETS_IMAGES_ROOT, sub_folder)

        py_png_file = py_class_name + '.png'        
        new_file = os.path.join(new_path, py_png_file)

        if os.path.isfile(new_file):

            appearance[sub_folder] = py_png_file
        
        elif os.path.isfile(possible_image):

            if not os.path.isdir(new_path):
                os.makedirs(new_path)
                            
            if not os.path.isfile(new_file):
                shutil.copyfile(possible_image, new_file)

            appearance[sub_folder] = py_png_file
            
    if not any(list(appearance.values())):
        return []
    
    for sub_folder, image in list(appearance.items()):
        if not image:
            appearance[sub_folder] = '../no_appearance.png'

    return list(appearance.values())
예제 #12
0
def convertToPython(text):
    """
    Converts the input `text` into a more ReSTified version of it.

    This involves the following steps:

    1. Any C++ specific declaration (like ``unsigned``, ``size_t`` and so on
       is removed.
    2. Lines starting with "Include file" or "#include" are ignored.
    3. Uppercase constants (i.e., like ID_ANY, HORIZONTAL and so on) are converted
       into inline literals (i.e., ``ID_ANY``, ``HORIZONTAL``).
    4. The "wx" prefix is removed from all the words in the input `text`.  #***
    
    :param string `text`: any string.

    :rtype: `string`
    """
    from etgtools.tweaker_tools import removeWxPrefix
    from etgtools.item_module_map import ItemModuleMap

    newlines = []
    unwanted = ['Include file', '#include']
    
    for line in text.splitlines():

        newline = []

        for remove in unwanted:
            if remove in line:
                line = line[0:line.index(remove)]
                break

        spacer = ' '*(len(line) - len(line.lstrip()))

        line = replaceCppItems(line)
        
        for word in RE_KEEP_SPACES.split(line):

            if word == VERSION:
                newline.append(word)
                continue
            
            newword = word
            for s in PUNCTUATION:
                newword = newword.replace(s, "")
            
            if newword in VALUE_MAP:
                word = word.replace(newword, VALUE_MAP[newword])
                newline.append(word)
                continue
                
            if newword not in IGNORE and not newword.startswith('wx.'):
                word = removeWxPrefix(word)
                newword = removeWxPrefix(newword)

            if "::" in word and not word.endswith("::"):
                # Bloody SetCursorEvent...
                word = word.replace("::wx", ".") # ***
                word = word.replace("::", ".")
                word = "`%s`" % word
                newline.append(word)
                continue
                
            if (newword.upper() == newword and newword not in PUNCTUATION and
                newword not in IGNORE and len(newword.strip()) > 1 and
                not isNumeric(newword) and newword not in ['DC', 'GCDC']):

                if '``' not in newword and '()' not in word and '**' not in word:
                    word = word.replace(newword, "``%s``" %
                                        ItemModuleMap().get_fullname(newword))

            word = word.replace('->', '.')
            newline.append(word)

        newline = spacer + ''.join(newline)
        newline = newline.replace(':see:', '.. seealso::')
        newline = newline.replace(':note:', '.. note::')
        newlines.append(newline)

    formatted = "\n".join(newlines)
    formatted = formatted.replace('\\', '\\\\')

    return formatted
예제 #13
0
def pythonizeType(ptype, is_param):
    """
    Replaces various C++ specific stuff with more Pythonized version of them,
    for parameter lists and return types (i.e., the `:param:` and `:rtype:`
    ReST roles).

    :param string `ptype`: any string;
    :param bool `is_param`: ``True`` if this is a parameter description, ``False``
     if it is a return type.

    :rtype: `string`
    """
    from etgtools.tweaker_tools import removeWxPrefix

    if 'size_t' in ptype:
        ptype = 'int'
    elif 'wx.' in ptype:
        ptype = ptype[3:]
    else:
        ptype = wx2Sphinx(replaceCppItems(ptype))[1]
        
    ptype = ptype.replace('::', '.').replace('*&', '')
    ptype = ptype.replace('int const', 'int')
    ptype = ptype.replace('Uint32', 'int').replace('**', '').replace('Int32', 'int')
    ptype = ptype.replace('FILE', 'file')
    ptype = ptype.replace('boolean', 'bool')

    for item in ['unsignedchar', 'unsignedint', 'unsignedlong', 'unsigned']:
        ptype = ptype.replace(item, 'int')
    
    ptype = ptype.strip()        
    ptype = removeWxPrefix(ptype)

    if '. wx' in ptype: #***
        ptype = ptype.replace('. wx', '.')

    plower = ptype.lower()
    
    if plower == 'double':
        ptype = 'float'

    if plower in ['string', 'char', 'artid', 'artclient']:
        ptype = 'string'

    if plower in ['coord', 'byte', 'fileoffset', 'short', 'time_t', 'intptr', 'uintptr', 'windowid']:
        ptype = 'int'
        
    if plower in ['longlong']:
        ptype = 'long'
                  
    cpp =    ['ArrayString', 'ArrayInt', 'ArrayDouble']
    python = ['list of strings', 'list of integers', 'list of floats']
    
    for c, p in zip(cpp, python):
        ptype = ptype.replace(c, p)

    if 'Image.' in ptype:
        ptype = ptype.split('.')[-1]

    if 'FileName' in ptype:
        ptype = 'string'
        
    if ptype.endswith('&'):
        ptype = ptype[0:-1]
        if ' ' not in ptype:
            ptype = ':class:`%s`'%ptype

    else:
        if is_param and '.' in ptype:
            modules = list(MODULENAME_REPLACE.values())
            modules.sort()
            modules = modules[1:]
            if ptype.split('.')[0] + '.' in modules:
                ptype = ':ref:`%s`'%ptype

    return ptype
예제 #14
0
파일: image.py 프로젝트: swt2c/Phoenix
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('wxImage')
    assert isinstance(c, etgtools.ClassDef)
    c.find('wxImage').findOverload('(const char *const *xpmData)').ignore()

    c.find('GetHandlers').ignore()  # TODO

    c.find('wxImage').findOverload('wxBitmap').mustHaveApp()

    # Ignore the ctors taking raw data buffers, so we can add in our own
    # versions that are a little smarter (accept any buffer object, check
    # the data length, etc.)
    c.find('wxImage').findOverload(
        'int width, int height, unsigned char *data, bool static_data').ignore(
        )
    c.find('wxImage').findOverload(
        'const wxSize &sz, unsigned char *data, bool static_data').ignore()
    c.find('wxImage').findOverload(
        'int width, int height, unsigned char *data, unsigned char *alpha, bool static_data'
    ).ignore()
    c.find('wxImage').findOverload(
        'const wxSize &sz, unsigned char *data, unsigned char *alpha, bool static_data'
    ).ignore()

    c.addCppCtor_sip('(int width, int height, wxPyBuffer* data)',
                     doc="Creates an image from RGB data in memory.",
                     body="""\
            if (! data->checkSize(width*height*3))
                return NULL;
            void* copy = data->copy();
            if (! copy)
                return NULL;
            sipCpp = new sipwxImage;
            sipCpp->Create(width, height, (byte*)copy);
            """)

    c.addCppCtor_sip(
        '(int width, int height, wxPyBuffer* data, wxPyBuffer* alpha)',
        doc="Creates an image from RGB data in memory, plus an alpha channel",
        body="""\
            void* dcopy; void* acopy;
            if (!data->checkSize(width*height*3) || !alpha->checkSize(width*height))
                return NULL;
            if ((dcopy = data->copy()) == NULL || (acopy = alpha->copy()) == NULL)
                return NULL;
            sipCpp = new sipwxImage;
            sipCpp->Create(width, height, (byte*)dcopy, (byte*)acopy, false);
            """)

    c.addCppCtor_sip('(const wxSize& size, wxPyBuffer* data)',
                     doc="Creates an image from RGB data in memory.",
                     body="""\
            if (! data->checkSize(size->x*size->y*3))
                return NULL;
            void* copy = data->copy();
            if (! copy)
                return NULL;
            sipCpp = new sipwxImage;
            sipCpp->Create(size->x, size->y, (byte*)copy, false);
            """)

    c.addCppCtor_sip(
        '(const wxSize& size, wxPyBuffer* data, wxPyBuffer* alpha)',
        doc="Creates an image from RGB data in memory, plus an alpha channel",
        body="""\
            void* dcopy; void* acopy;
            if (!data->checkSize(size->x*size->y*3) || !alpha->checkSize(size->x*size->y))
                return NULL;
            if ((dcopy = data->copy()) == NULL || (acopy = alpha->copy()) == NULL)
                return NULL;
            sipCpp = new sipwxImage;
            sipCpp->Create(size->x, size->y, (byte*)dcopy, (byte*)acopy, false);
            """)

    # Do the same for the Create method overloads that need to deal with data buffers
    c.find('Create').findOverload(
        'int width, int height, unsigned char *data, bool static_data').ignore(
        )
    c.find('Create').findOverload(
        'const wxSize &sz, unsigned char *data, bool static_data').ignore()
    c.find('Create').findOverload(
        'int width, int height, unsigned char *data, unsigned char *alpha, bool static_data'
    ).ignore()
    c.find('Create').findOverload(
        'const wxSize &sz, unsigned char *data, unsigned char *alpha, bool static_data'
    ).ignore()

    c.addCppMethod(
        'bool',
        'Create',
        '(int width, int height, wxPyBuffer* data)',
        doc="Create a new image initialized with the given RGB data.",
        body="""\
            if (! data->checkSize(width*height*3))
                return false;
            void* copy = data->copy();
            if (! copy)
                return false;
            return self->Create(width, height, (byte*)copy);
            """)

    c.addCppMethod(
        'bool',
        'Create',
        '(int width, int height, wxPyBuffer* data, wxPyBuffer* alpha)',
        doc=
        "Create a new image initialized with the given RGB data and Alpha data.",
        body="""\
            void* dcopy; void* acopy;
            if (!data->checkSize(width*height*3) || !alpha->checkSize(width*height))
                return false;
            if ((dcopy = data->copy()) == NULL || (acopy = alpha->copy()) == NULL)
                return false;
            return self->Create(width, height, (byte*)dcopy, (byte*)acopy);
            """)

    c.addCppMethod(
        'bool',
        'Create',
        '(const wxSize& size, wxPyBuffer* data)',
        doc="Create a new image initialized with the given RGB data.",
        body="""\
            if (! data->checkSize(size->x*size->y*3))
                return false;
            void* copy = data->copy();
            if (! copy)
                return false;
            return self->Create(size->x, size->y, (byte*)copy);
            """)

    c.addCppMethod(
        'bool',
        'Create',
        '(const wxSize& size, wxPyBuffer* data, wxPyBuffer* alpha)',
        doc=
        "Create a new image initialized with the given RGB data and Alpha data.",
        body="""\
            void* dcopy; void* acopy;
            if (!data->checkSize(size->x*size->y*3) || !alpha->checkSize(size->x*size->y))
                return false;
            if ((dcopy = data->copy()) == NULL || (acopy = alpha->copy()) == NULL)
                return false;
            return self->Create(size->x, size->y, (byte*)dcopy, (byte*)acopy);
            """)

    # And also do similar for SetData and SetAlpha
    m = c.find('SetData').findOverload('unsigned char *data')
    bd, dd = m.briefDoc, m.detailedDoc
    m.ignore()
    c.addCppMethod('void',
                   'SetData',
                   '(wxPyBuffer* data)',
                   briefDoc=bd,
                   detailedDoc=dd,
                   body="""\
        if (!data->checkSize(self->GetWidth()*self->GetHeight()*3))
            return;
        void* copy = data->copy();
        if (!copy)
            return;
        self->SetData((byte*)copy, false);
        """)

    c.find('SetData').findOverload('int new_width').ignore()
    c.addCppMethod('void',
                   'SetData',
                   '(wxPyBuffer* data, int new_width, int new_height)',
                   body="""\
        if (!data->checkSize(new_width*new_height*3))
            return;
        void* copy = data->copy();
        if (!copy)
            return;
        self->SetData((byte*)copy, new_width, new_height, false);
        """)

    m = c.find('SetAlpha').findOverload('unsigned char *alpha')
    bd, dd = m.briefDoc, m.detailedDoc
    m.ignore()
    c.addCppMethod('void',
                   'SetAlpha',
                   '(wxPyBuffer* alpha)',
                   briefDoc=bd,
                   detailedDoc=dd,
                   body="""\
        if (!alpha->checkSize(self->GetWidth()*self->GetHeight()))
            return;
        void* copy = alpha->copy();
        if (!copy)
            return;
        self->SetAlpha((byte*)copy, false);
        """)

    # GetData() and GetAlpha() return a copy of the image data/alpha bytes as
    # a bytearray object.
    c.find('GetData').ignore()
    c.addCppMethod('PyObject*',
                   'GetData',
                   '()',
                   doc="Returns a copy of the RGB bytes of the image.",
                   body="""\
            byte* data = self->GetData();
            Py_ssize_t len = self->GetWidth() * self->GetHeight() * 3;
            PyObject* rv = NULL;
            wxPyBLOCK_THREADS( rv = PyByteArray_FromStringAndSize((const char*)data, len));
            return rv;
            """)

    c.find('GetAlpha').findOverload('()').ignore()
    c.addCppMethod('PyObject*',
                   'GetAlpha',
                   '()',
                   doc="Returns a copy of the Alpha bytes of the image.",
                   body="""\
            byte* data = self->GetAlpha();
            Py_ssize_t len = self->GetWidth() * self->GetHeight();
            PyObject* rv = NULL;
            wxPyBLOCK_THREADS( rv = PyByteArray_FromStringAndSize((const char*)data, len));
            return rv;
            """)

    # GetDataBuffer, GetAlphaBuffer provide direct access to the image's
    # internal buffers as a writable buffer object.  We'll use memoryview
    # objects.
    c.addCppMethod('PyObject*',
                   'GetDataBuffer',
                   '()',
                   doc="""\
        Returns a writable Python buffer object that is pointing at the RGB
        image data buffer inside the :class:`Image`. You need to ensure that you do
        not use this buffer object after the image has been destroyed.""",
                   body="""\
            byte* data = self->GetData();
            Py_ssize_t len = self->GetWidth() * self->GetHeight() * 3;
            PyObject* rv;
            wxPyThreadBlocker blocker;
            rv = wxPyMakeBuffer(data, len);
            return rv;
            """)

    c.addCppMethod('PyObject*',
                   'GetAlphaBuffer',
                   '()',
                   doc="""\
        Returns a writable Python buffer object that is pointing at the Alpha
        data buffer inside the :class:`Image`. You need to ensure that you do
        not use this buffer object after the image has been destroyed.""",
                   body="""\
            byte* data = self->GetAlpha();
            Py_ssize_t len = self->GetWidth() * self->GetHeight();
            PyObject* rv;
            wxPyThreadBlocker blocker;
            rv = wxPyMakeBuffer(data, len);
            return rv;
            """)

    # SetDataBuffer, SetAlphaBuffer tell the image to use some other memory
    # buffer pointed to by a Python buffer object.
    c.addCppMethod('void',
                   'SetDataBuffer',
                   '(wxPyBuffer* data)',
                   doc="""\
        Sets the internal image data pointer to point at a Python buffer
        object.  This can save making an extra copy of the data but you must
        ensure that the buffer object lives lives at least as long as the
        :class:`Image` does.""",
                   body="""\
            if (!data->checkSize(self->GetWidth() * self->GetHeight() * 3))
                return;
            // True means don't free() the pointer
            self->SetData((byte*)data->m_ptr, true);
            """)
    c.addCppMethod('void',
                   'SetDataBuffer',
                   '(wxPyBuffer* data, int new_width, int new_height)',
                   doc="""\
        Sets the internal image data pointer to point at a Python buffer
        object.  This can save making an extra copy of the data but you must
        ensure that the buffer object lives lives at least as long as the
        :class:`Image` does.""",
                   body="""\
            if (!data->checkSize(new_width * new_height * 3))
                return;
            // True means don't free() the pointer
            self->SetData((byte*)data->m_ptr, new_width, new_height, true);
            """)

    c.addCppMethod('void',
                   'SetAlphaBuffer',
                   '(wxPyBuffer* alpha)',
                   doc="""\
        Sets the internal image alpha pointer to point at a Python buffer
        object.  This can save making an extra copy of the data but you must
        ensure that the buffer object lives lives at least as long as the
        :class:`Image` does.""",
                   body="""\
            if (!alpha->checkSize(self->GetWidth() * self->GetHeight()))
                return;
            // True means don't free() the pointer
            self->SetAlpha((byte*)alpha->m_ptr, true);
            """)

    def setParamsPyInt(name):
        """Set the pyInt flag on 'unsigned char' params"""
        method = c.find(name)
        for m in [method] + method.overloads:
            for p in m.items:
                if p.type == 'unsigned char':
                    p.pyInt = True

    setParamsPyInt('Replace')
    setParamsPyInt('ConvertAlphaToMask')
    setParamsPyInt('ConvertToMono')
    setParamsPyInt('ConvertToDisabled')
    setParamsPyInt('IsTransparent')
    setParamsPyInt('SetAlpha')
    setParamsPyInt('SetMaskColour')
    setParamsPyInt('SetMaskFromImage')
    setParamsPyInt('SetRGB')

    c.find('FindFirstUnusedColour').type = 'void'
    c.find('FindFirstUnusedColour.r').pyInt = True
    c.find('FindFirstUnusedColour.g').pyInt = True
    c.find('FindFirstUnusedColour.b').pyInt = True
    c.find('FindFirstUnusedColour.startR').pyInt = True
    c.find('FindFirstUnusedColour.startG').pyInt = True
    c.find('FindFirstUnusedColour.startB').pyInt = True
    c.find('FindFirstUnusedColour.r').out = True
    c.find('FindFirstUnusedColour.g').out = True
    c.find('FindFirstUnusedColour.b').out = True

    c.find('GetAlpha').findOverload('int x, int y').pyInt = True
    c.find('GetRed').pyInt = True
    c.find('GetGreen').pyInt = True
    c.find('GetBlue').pyInt = True
    c.find('GetMaskRed').pyInt = True
    c.find('GetMaskGreen').pyInt = True
    c.find('GetMaskBlue').pyInt = True

    c.find('GetOrFindMaskColour').type = 'void'
    c.find('GetOrFindMaskColour.r').pyInt = True
    c.find('GetOrFindMaskColour.g').pyInt = True
    c.find('GetOrFindMaskColour.b').pyInt = True
    c.find('GetOrFindMaskColour.r').out = True
    c.find('GetOrFindMaskColour.g').out = True
    c.find('GetOrFindMaskColour.b').out = True

    c.find('RGBValue.red').pyInt = True
    c.find('RGBValue.green').pyInt = True
    c.find('RGBValue.blue').pyInt = True
    c.find('RGBValue.RGBValue.r').pyInt = True
    c.find('RGBValue.RGBValue.g').pyInt = True
    c.find('RGBValue.RGBValue.b').pyInt = True

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

    c.addPyMethod('ConvertToBitmap',
                  '(self, depth=-1)',
                  doc="""\
        ConvertToBitmap(depth=-1) -> Bitmap\n
        Convert the image to a :class:`wx.Bitmap`.""",
                  body="""\
        bmp = wx.Bitmap(self, depth)
        return bmp
        """)

    c.addPyMethod('ConvertToMonoBitmap',
                  '(self, red, green, blue)',
                  doc="""\
        ConvertToMonoBitmap(red, green, blue) -> Bitmap\n
        Creates a monochrome version of the image and returns it as a :class:`wx.Bitmap`.""",
                  body="""\
        mono = self.ConvertToMono( red, green, blue )
        bmp = wx.Bitmap( mono, 1 )
        return bmp
        """)

    c.addCppMethod(
        'wxImage*',
        'AdjustChannels',
        '(double factor_red, double factor_green, double factor_blue, double factor_alpha=1.0)',
        doc="""\
        This function muliplies all 4 channels (red, green, blue, alpha) with
        a factor (around 1.0). Useful for gamma correction, colour correction
        and to add a certain amount of transparency to a image (fade in fade
        out effects). If factor_alpha is given but the original image has no
        alpha channel then a alpha channel will be added.
        """,
        body="""\
        wxCHECK_MSG( self->Ok(), NULL, wxT("invalid image") );

        wxImage* dest = new wxImage( self->GetWidth(), self->GetHeight(), false );
        wxCHECK_MSG( dest && dest->IsOk(), NULL, wxT("unable to create image") );

        unsigned rgblen =   3 * self->GetWidth() * self->GetHeight();
        unsigned alphalen = self->GetWidth() * self->GetHeight();
        byte* src_data =  self->GetData();
        byte* src_alpha = self->GetAlpha();
        byte* dst_data =  dest->GetData();
        byte* dst_alpha = NULL;

        // adjust rgb
        if ( factor_red == 1.0 && factor_green == 1.0 && factor_blue == 1.0)
        {
            // nothing to do for RGB
            memcpy(dst_data, src_data, rgblen);
        }
        else
        {
            // rgb pixel for pixel
            for ( unsigned i = 0; i < rgblen; i= i + 3 )
            {
                dst_data[i] =     (byte) wxMin( 255, (int) (factor_red * src_data[i]) );
                dst_data[i + 1] = (byte) wxMin( 255, (int) (factor_green * src_data[i + 1]) );
                dst_data[i + 2] = (byte) wxMin( 255, (int) (factor_blue * src_data[i + 2]) );
            }
        }

        // adjust the mask colour
        if ( self->HasMask() )
        {
            dest->SetMaskColour((byte) wxMin( 255, (int) (factor_red * self->GetMaskRed() ) ),
                                (byte) wxMin( 255, (int) (factor_green * self->GetMaskGreen() ) ),
                                (byte) wxMin( 255, (int) (factor_blue * self->GetMaskBlue() ) ) );
        }

        // adjust the alpha channel
        if ( src_alpha )
        {
            // source image already has alpha information
            dest->SetAlpha(); // create an empty alpha channel (not initialized)
            dst_alpha = dest->GetAlpha();

            wxCHECK_MSG( dst_alpha, NULL, wxT("unable to create alpha data") );

            if ( factor_alpha == 1.0)
            {
                // no need to adjust
                memcpy(dst_alpha, src_alpha, alphalen);
            }
            else
            {
                // alpha value for alpha value
                for ( unsigned i = 0; i < alphalen; ++i )
                {
                    dst_alpha[i] = (byte) wxMin( 255, (int) (factor_alpha * src_alpha[i]) );
                }
            }
        }
        else if ( factor_alpha != 1.0 )
        {
            // no alpha yet but we want to adjust -> create
            dest->SetAlpha(); // create an empty alpha channel (not initialized)
            dst_alpha = dest->GetAlpha();

            wxCHECK_MSG( dst_alpha, NULL, wxT("unable to create alpha data") );

            for ( unsigned i = 0; i < alphalen; ++i )
            {
                dst_alpha[i] = (byte) wxMin( 255, (int) (factor_alpha * 255) );
            }
        }

        // do we have an alpha channel and a mask in the new image?
        if ( dst_alpha && dest->HasMask() )
        {
            // make the mask transparent honoring the alpha channel
            const byte mr = dest->GetMaskRed();
            const byte mg = dest->GetMaskGreen();
            const byte mb = dest->GetMaskBlue();

            for ( unsigned i = 0; i < alphalen; ++i )
            {
                int n = i * 3;
                dst_alpha[i] = ( dst_data[n] == mr && dst_data[n + 1] == mg && dst_data[n + 2] == mb )
                    ? wxIMAGE_ALPHA_TRANSPARENT
                    : dst_alpha[i];
            }

            // remove the mask now
            dest->SetMask(false);
        }

        return dest;""",
        factory=True)

    c.addProperty('Width GetWidth')
    c.addProperty('Height GetHeight')
    c.addProperty('MaskBlue GetMaskBlue')
    c.addProperty('MaskGreen GetMaskGreen')
    c.addProperty('MaskRed GetMaskRed')
    c.addProperty('Type GetType SetType')

    # For compatibility:
    module.addPyFunction(
        'EmptyImage',
        '(width=0, height=0, clear=True)',
        deprecated="Use :class:`Image` instead.",
        doc=
        'A compatibility wrapper for the wx.Image(width, height) constructor',
        body='return Image(width, height, clear)')

    module.addPyFunction(
        'ImageFromBitmap',
        '(bitmap)',
        deprecated="Use bitmap.ConvertToImage instead.",
        doc='Create a :class:`Image` from a :class:`wx.Bitmap`',
        body='return bitmap.ConvertToImage()')

    module.addPyFunction('ImageFromStream',
                         '(stream, type=BITMAP_TYPE_ANY, index=-1)',
                         deprecated="Use :class:`Image` instead.",
                         doc='Load an image from a stream (file-like object)',
                         body='return wx.Image(stream, type, index)')

    module.addPyFunction(
        'ImageFromData',
        '(width, height, data)',
        deprecated="Use :class:`Image` instead.",
        doc='Compatibility wrapper for creating an image from RGB data',
        body='return Image(width, height, data)')

    module.addPyFunction(
        'ImageFromDataWithAlpha',
        '(width, height, data, alpha)',
        deprecated="Use :class:`Image` instead.",
        doc=
        'Compatibility wrapper for creating an image from RGB and Alpha data',
        body='return Image(width, height, data, alpha)')

    module.addPyFunction('ImageFromBuffer',
                         '(width, height, dataBuffer, alphaBuffer=None)',
                         doc="""\
            Creates a :class:`Image` from the data in `dataBuffer`.  The `dataBuffer`
            parameter must be a Python object that implements the buffer interface,
            such as a string, array, etc.  The `dataBuffer` object is expected to
            contain a series of RGB bytes and be width*height*3 bytes long.  A buffer
            object can optionally be supplied for the image's alpha channel data, and
            it is expected to be width*height bytes long.

            The :class:`Image` will be created with its data and alpha pointers initialized
            to the memory address pointed to by the buffer objects, thus saving the
            time needed to copy the image data from the buffer object to the :class:`Image`.
            While this has advantages, it also has the shoot-yourself-in-the-foot
            risks associated with sharing a C pointer between two objects.

            To help alleviate the risk a reference to the data and alpha buffer
            objects are kept with the :class:`Image`, so that they won't get deleted until
            after the wx.Image is deleted.  However please be aware that it is not
            guaranteed that an object won't move its memory buffer to a new location
            when it needs to resize its contents.  If that happens then the :class:`Image`
            will end up referring to an invalid memory location and could cause the
            application to crash.  Therefore care should be taken to not manipulate
            the objects used for the data and alpha buffers in a way that would cause
            them to change size.
            """,
                         body="""\
            img = Image(width, height)
            img.SetDataBuffer(dataBuffer)
            if alphaBuffer:
                img.SetAlphaBuffer(alphaBuffer)
            img._buffer = dataBuffer
            img._alpha = alphaBuffer
            return img
            """)

    #-------------------------------------------------------
    c = module.find('wxImageHistogram')
    c.bases = []  # wxImageHistogramBase doesn't actually exist
    setParamsPyInt('MakeKey')
    c.find('FindFirstUnusedColour').type = 'void'
    c.find('FindFirstUnusedColour.r').pyInt = True
    c.find('FindFirstUnusedColour.g').pyInt = True
    c.find('FindFirstUnusedColour.b').pyInt = True
    c.find('FindFirstUnusedColour.startR').pyInt = True
    c.find('FindFirstUnusedColour.startG').pyInt = True
    c.find('FindFirstUnusedColour.startB').pyInt = True
    c.find('FindFirstUnusedColour.r').out = True
    c.find('FindFirstUnusedColour.g').out = True
    c.find('FindFirstUnusedColour.b').out = True

    #-------------------------------------------------------
    c = module.find('wxImageHandler')
    c.addPrivateCopyCtor()
    c.find('GetLibraryVersionInfo').ignore()

    c.find('DoGetImageCount').ignore(False)
    c.find('DoCanRead').ignore(False)

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

    module.find('wxIMAGE_ALPHA_TRANSPARENT').pyInt = True
    module.find('wxIMAGE_ALPHA_OPAQUE').pyInt = True
    module.find('wxIMAGE_ALPHA_THRESHOLD').pyInt = True

    # These are defines for string objects, not integers, so we can't
    # generate code for them the same way as integer values. Since they are
    # #defines we can't just tell SIP that they are global wxString objects
    # because it will then end up taking the address of temporary values when
    # it makes the getters for them. So instead we'll just make some python
    # code to insert into the .py module and hope that the interface file
    # always has the correct values of these options.
    pycode = ""
    for item in module:
        if 'IMAGE_OPTION' in item.name and isinstance(item,
                                                      etgtools.DefineDef):
            item.ignore()
            name = tools.removeWxPrefix(item.name)
            value = item.value
            for txt in ['wxString(', 'wxT(', ')']:
                value = value.replace(txt, '')

            pycode += '%s = %s\n' % (name, value)
    module.addPyCode(pycode)

    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
예제 #15
0
def findControlImages(elementOrString):
    """
    Given the input `element` (an instance of `xml.etree.ElementTree.Element`
    or a plain string)
    representing a Phoenix class description, this function will scan the
    doxygen image folder ``DOXYROOT`` to look for a widget screenshot.

    If this class indeed represents a widget and a screenshot is found, it is
    then copied to the appropriate Sphinx input folder ``WIDGETS_IMAGES_ROOT``
    in one of its sub-folders (``wxmsw``, ``wxgtk``, ``wxmac``) depending on
    which platform the screenshot was taken.

    :param `elementOrString`: the XML element we want to examine (an instance of
     xml.etree.ElementTree.Element) or a plain string (usually for wx.lib).

    :rtype: `list`

    :returns: A list of image paths, every element of it representing a screenshot on
     a different platform. An empty list if returned if no screenshots have been found.

    .. note:: If a screenshot doesn't exist for one (or more) platform but it
       exists for others, the missing images will be replaced by the "no_appearance.png"
       file (you can find it inside the ``WIDGETS_IMAGES_ROOT`` folder.

    """
    from etgtools.tweaker_tools import removeWxPrefix

    if isinstance(elementOrString, string_base):
        class_name = py_class_name = elementOrString.lower()
    else:
        element = elementOrString
        class_name = element.pyName if element.pyName else removeWxPrefix(
            element.name)
        py_class_name = wx2Sphinx(class_name)[1]

        class_name = class_name.lower()
        py_class_name = py_class_name.lower()

    image_folder = os.path.join(DOXYROOT, 'images')

    appearance = ODict()

    for sub_folder in ['wxmsw', 'wxmac', 'wxgtk']:

        png_file = class_name + '.png'
        appearance[sub_folder] = ''

        possible_image = os.path.join(image_folder, sub_folder, png_file)
        new_path = os.path.join(WIDGETS_IMAGES_ROOT, sub_folder)

        py_png_file = py_class_name + '.png'
        new_file = os.path.join(new_path, py_png_file)

        if os.path.isfile(new_file):

            appearance[sub_folder] = py_png_file

        elif os.path.isfile(possible_image):

            if not os.path.isdir(new_path):
                os.makedirs(new_path)

            if not os.path.isfile(new_file):
                shutil.copyfile(possible_image, new_file)

            appearance[sub_folder] = py_png_file

    if not any(list(appearance.values())):
        return []

    for sub_folder, image in list(appearance.items()):
        if not image:
            appearance[sub_folder] = '../no_appearance.png'

    return list(appearance.values())
예제 #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('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)
예제 #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('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)
예제 #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('wxImage')
    assert isinstance(c, etgtools.ClassDef)
    c.find('wxImage').findOverload('(const char *const *xpmData)').ignore()

    c.find('GetHandlers').ignore()  # TODO
    
    
    # Ignore the ctors taking raw data buffers, so we can add in our own
    # versions that are a little smarter (accept any buffer object, check
    # the data length, etc.)
    c.find('wxImage').findOverload('int width, int height, unsigned char *data, bool static_data').ignore()
    c.find('wxImage').findOverload('const wxSize &sz, unsigned char *data, bool static_data').ignore()
    c.find('wxImage').findOverload('int width, int height, unsigned char *data, unsigned char *alpha, bool static_data').ignore()
    c.find('wxImage').findOverload('const wxSize &sz, unsigned char *data, unsigned char *alpha, bool static_data').ignore()

    c.addCppCtor_sip('(int width, int height, wxPyBuffer* data)',
        doc="Creates an image from RGB data in memory.",
        body="""\
            if (! data->checkSize(width*height*3)) 
                return NULL;
            void* copy = data->copy();
            if (! copy) 
                return NULL;
            sipCpp = new sipwxImage;
            sipCpp->Create(width, height, (byte*)copy);            
            """)
      
    c.addCppCtor_sip('(int width, int height, wxPyBuffer* data, wxPyBuffer* alpha)',
        doc="Creates an image from RGB data in memory, plus an alpha channel",
        body="""\
            void* dcopy; void* acopy;
            if (!data->checkSize(width*height*3) || !alpha->checkSize(width*height))
                return NULL;
            if ((dcopy = data->copy()) == NULL || (acopy = alpha->copy()) == NULL)
                return NULL;
            sipCpp = new sipwxImage;
            sipCpp->Create(width, height, (byte*)dcopy, (byte*)acopy, false);
            """)
      
    c.addCppCtor_sip('(const wxSize& size, wxPyBuffer* data)',
        doc="Creates an image from RGB data in memory.",
        body="""\
            if (! data->checkSize(size->x*size->y*3)) 
                return NULL;
            void* copy = data->copy();
            if (! copy) 
                return NULL;
            sipCpp = new sipwxImage;
            sipCpp->Create(size->x, size->y, (byte*)copy, false);
            """)
      
    c.addCppCtor_sip('(const wxSize& size, wxPyBuffer* data, wxPyBuffer* alpha)',
        doc="Creates an image from RGB data in memory, plus an alpha channel",
        body="""\
            void* dcopy; void* acopy;
            if (!data->checkSize(size->x*size->y*3) || !alpha->checkSize(size->x*size->y))
                return NULL;
            if ((dcopy = data->copy()) == NULL || (acopy = alpha->copy()) == NULL)
                return NULL;
            sipCpp = new sipwxImage;
            sipCpp->Create(size->x, size->y, (byte*)dcopy, (byte*)acopy, false);
            """)
      
      
    # Do the same for the Create method overloads that need to deal with data buffers
    c.find('Create').findOverload('int width, int height, unsigned char *data, bool static_data').ignore()
    c.find('Create').findOverload('const wxSize &sz, unsigned char *data, bool static_data').ignore()
    c.find('Create').findOverload('int width, int height, unsigned char *data, unsigned char *alpha, bool static_data').ignore()
    c.find('Create').findOverload('const wxSize &sz, unsigned char *data, unsigned char *alpha, bool static_data').ignore()
      
    c.addCppMethod('bool', 'Create', '(int width, int height, wxPyBuffer* data)', 
        doc="Create a new image initialized with the given RGB data.",
        body="""\
            if (! data->checkSize(width*height*3)) 
                return false;
            void* copy = data->copy();
            if (! copy) 
                return false;
            return self->Create(width, height, (byte*)copy);
            """)
      
    c.addCppMethod('bool', 'Create', '(int width, int height, wxPyBuffer* data, wxPyBuffer* alpha)', 
        doc="Create a new image initialized with the given RGB data and Alpha data.",
        body="""\
            void* dcopy; void* acopy;
            if (!data->checkSize(width*height*3) || !alpha->checkSize(width*height))
                return false;
            if ((dcopy = data->copy()) == NULL || (acopy = alpha->copy()) == NULL)
                return false;
            return self->Create(width, height, (byte*)dcopy, (byte*)acopy);
            """)
      
    c.addCppMethod('bool', 'Create', '(const wxSize& size, wxPyBuffer* data)', 
        doc="Create a new image initialized with the given RGB data.",
        body="""\
            if (! data->checkSize(size->x*size->y*3)) 
                return false;
            void* copy = data->copy();
            if (! copy) 
                return false;
            return self->Create(size->x, size->y, (byte*)copy);
            """)
      
    c.addCppMethod('bool', 'Create', '(const wxSize& size, wxPyBuffer* data, wxPyBuffer* alpha)', 
        doc="Create a new image initialized with the given RGB data and Alpha data.",
        body="""\
            void* dcopy; void* acopy;
            if (!data->checkSize(size->x*size->y*3) || !alpha->checkSize(size->x*size->y))
                return false;
            if ((dcopy = data->copy()) == NULL || (acopy = alpha->copy()) == NULL)
                return false;
            return self->Create(size->x, size->y, (byte*)dcopy, (byte*)acopy);
            """)
      
      
    # And also do similar for SetData and SetAlpha
    m = c.find('SetData').findOverload('unsigned char *data')
    bd, dd = m.briefDoc, m.detailedDoc
    m.ignore()
    c.addCppMethod('void', 'SetData', '(wxPyBuffer* data)',
        briefDoc=bd, detailedDoc=dd,
        body="""\
        if (!data->checkSize(self->GetWidth()*self->GetHeight()*3))
            return;
        void* copy = data->copy();
        if (!copy)
            return;
        self->SetData((byte*)copy, false);
        """)

    c.find('SetData').findOverload('int new_width').ignore()
    c.addCppMethod('void', 'SetData', '(wxPyBuffer* data, int new_width, int new_height)',
        body="""\
        if (!data->checkSize(new_width*new_height*3))
            return;
        void* copy = data->copy();
        if (!copy)
            return;
        self->SetData((byte*)copy, new_width, new_height, false);
        """)
      
    m = c.find('SetAlpha').findOverload('unsigned char *alpha')
    bd, dd = m.briefDoc, m.detailedDoc
    m.ignore()
    c.addCppMethod('void', 'SetAlpha', '(wxPyBuffer* alpha)',
        briefDoc=bd, detailedDoc=dd,
        body="""\
        if (!alpha->checkSize(self->GetWidth()*self->GetHeight()))
            return;
        void* copy = alpha->copy();
        if (!copy)
            return;
        self->SetAlpha((byte*)copy, false);
        """)


    # GetData() and GetAlpha() return a copy of the image data/alpha bytes as
    # a bytearray object. 
    c.find('GetData').ignore()
    c.addCppMethod('PyObject*', 'GetData', '()',
        doc="Returns a copy of the RGB bytes of the image.",
        body="""\
            byte* data = self->GetData();
            Py_ssize_t len = self->GetWidth() * self->GetHeight() * 3;
            PyObject* rv = NULL;
            wxPyBLOCK_THREADS( rv = PyByteArray_FromStringAndSize((const char*)data, len));
            return rv;           
            """)
    
    c.find('GetAlpha').findOverload('()').ignore()
    c.addCppMethod('PyObject*', 'GetAlpha', '()',
        doc="Returns a copy of the Alpha bytes of the image.",
        body="""\
            byte* data = self->GetAlpha();
            Py_ssize_t len = self->GetWidth() * self->GetHeight();
            PyObject* rv = NULL;
            wxPyBLOCK_THREADS( rv = PyByteArray_FromStringAndSize((const char*)data, len));
            return rv;           
            """)
    
    
    # GetDataBuffer, GetAlphaBuffer provide direct access to the image's
    # internal buffers as a writable buffer object.  We'll use memoryview 
    # objects.
    c.addCppMethod('PyObject*', 'GetDataBuffer', '()',
        doc="""\
        Returns a writable Python buffer object that is pointing at the RGB
        image data buffer inside the :class:`Image`. You need to ensure that you do
        not use this buffer object after the image has been destroyed.""",
        body="""\
            byte* data = self->GetData();
            Py_ssize_t len = self->GetWidth() * self->GetHeight() * 3;
            PyObject* rv;
            wxPyThreadBlocker blocker;
            rv = wxPyMakeBuffer(data, len);
            return rv;
            """)

    c.addCppMethod('PyObject*', 'GetAlphaBuffer', '()',
        doc="""\
        Returns a writable Python buffer object that is pointing at the Alpha
        data buffer inside the :class:`Image`. You need to ensure that you do
        not use this buffer object after the image has been destroyed.""",
        body="""\
            byte* data = self->GetAlpha();
            Py_ssize_t len = self->GetWidth() * self->GetHeight();
            PyObject* rv;
            wxPyThreadBlocker blocker;
            rv = wxPyMakeBuffer(data, len);
            return rv;
            """)

    # SetDataBuffer, SetAlphaBuffer tell the image to use some other memory
    # buffer pointed to by a Python buffer object.
    c.addCppMethod('void', 'SetDataBuffer', '(wxPyBuffer* data)',
        doc="""\
        Sets the internal image data pointer to point at a Python buffer
        object.  This can save making an extra copy of the data but you must
        ensure that the buffer object lives lives at least as long as the 
        :class:`Image` does.""",
        body="""\
            if (!data->checkSize(self->GetWidth() * self->GetHeight() * 3))
                return;
            // True means don't free() the pointer
            self->SetData((byte*)data->m_ptr, true);  
            """)
    c.addCppMethod('void', 'SetDataBuffer', '(wxPyBuffer* data, int new_width, int new_height)',
        doc="""\
        Sets the internal image data pointer to point at a Python buffer
        object.  This can save making an extra copy of the data but you must
        ensure that the buffer object lives lives at least as long as the 
        :class:`Image` does.""",
        body="""\
            if (!data->checkSize(new_width * new_height * 3))
                return;
            // True means don't free() the pointer
            self->SetData((byte*)data->m_ptr, new_width, new_height, true);  
            """)


    c.addCppMethod('void', 'SetAlphaBuffer', '(wxPyBuffer* alpha)',
        doc="""\
        Sets the internal image alpha pointer to point at a Python buffer
        object.  This can save making an extra copy of the data but you must
        ensure that the buffer object lives lives at least as long as the 
        :class:`Image` does.""",
        body="""\
            if (!alpha->checkSize(self->GetWidth() * self->GetHeight()))
                return;
            // True means don't free() the pointer
            self->SetAlpha((byte*)alpha->m_ptr, true);
            """)



      
    def setParamsPyInt(name):
        """Set the pyInt flag on 'unsigned char' params"""
        method = c.find(name)
        for m in [method] + method.overloads:
            for p in m.items:
                if p.type == 'unsigned char':
                    p.pyInt = True
                
    setParamsPyInt('Replace')
    setParamsPyInt('ConvertAlphaToMask')
    setParamsPyInt('ConvertToMono')
    setParamsPyInt('ConvertToDisabled')
    setParamsPyInt('IsTransparent')
    setParamsPyInt('SetAlpha')
    setParamsPyInt('SetMaskColour')
    setParamsPyInt('SetMaskFromImage')
    setParamsPyInt('SetRGB')

    c.find('FindFirstUnusedColour').type = 'void'
    c.find('FindFirstUnusedColour.r').pyInt = True
    c.find('FindFirstUnusedColour.g').pyInt = True
    c.find('FindFirstUnusedColour.b').pyInt = True
    c.find('FindFirstUnusedColour.startR').pyInt = True
    c.find('FindFirstUnusedColour.startG').pyInt = True
    c.find('FindFirstUnusedColour.startB').pyInt = True
    c.find('FindFirstUnusedColour.r').out = True
    c.find('FindFirstUnusedColour.g').out = True
    c.find('FindFirstUnusedColour.b').out = True
    
    c.find('GetAlpha').findOverload('int x, int y').pyInt = True
    c.find('GetRed').pyInt = True
    c.find('GetGreen').pyInt = True
    c.find('GetBlue').pyInt = True
    c.find('GetMaskRed').pyInt = True
    c.find('GetMaskGreen').pyInt = True
    c.find('GetMaskBlue').pyInt = True
    
    c.find('GetOrFindMaskColour').type = 'void'
    c.find('GetOrFindMaskColour.r').pyInt = True
    c.find('GetOrFindMaskColour.g').pyInt = True
    c.find('GetOrFindMaskColour.b').pyInt = True
    c.find('GetOrFindMaskColour.r').out = True
    c.find('GetOrFindMaskColour.g').out = True
    c.find('GetOrFindMaskColour.b').out = True
    
    c.find('RGBValue.red').pyInt = True
    c.find('RGBValue.green').pyInt = True
    c.find('RGBValue.blue').pyInt = True
    c.find('RGBValue.RGBValue.r').pyInt = True
    c.find('RGBValue.RGBValue.g').pyInt = True
    c.find('RGBValue.RGBValue.b').pyInt = True
   
   
    c.addCppMethod('int', '__nonzero__', '()', 'return self->IsOk();')

    c.addPyMethod('ConvertToBitmap', '(self, depth=-1)', 
        doc="""\
        ConvertToBitmap(depth=-1) -> Bitmap\n
        Convert the image to a :class:`wx.Bitmap`.""",
        body="""\
        bmp = wx.Bitmap(self, depth)
        return bmp
        """)
    
    c.addPyMethod('ConvertToMonoBitmap', '(self, red, green, blue)', 
        doc="""\
        ConvertToMonoBitmap(red, green, blue) -> Bitmap\n
        Creates a monochrome version of the image and returns it as a :class:`wx.Bitmap`.""",
        body="""\
        mono = self.ConvertToMono( red, green, blue )
        bmp = wx.Bitmap( mono, 1 )
        return bmp    
        """)
   

    c.addCppMethod('wxImage*', 'AdjustChannels', 
        '(double factor_red, double factor_green, double factor_blue, double factor_alpha=1.0)',
        doc="""\
        This function muliplies all 4 channels (red, green, blue, alpha) with
        a factor (around 1.0). Useful for gamma correction, colour correction
        and to add a certain amount of transparency to a image (fade in fade
        out effects). If factor_alpha is given but the original image has no
        alpha channel then a alpha channel will be added.
        """,
        body="""\
        wxCHECK_MSG( self->Ok(), NULL, wxT("invalid image") );

        wxImage* dest = new wxImage( self->GetWidth(), self->GetHeight(), false );
        wxCHECK_MSG( dest && dest->IsOk(), NULL, wxT("unable to create image") );

        unsigned rgblen =   3 * self->GetWidth() * self->GetHeight();
        unsigned alphalen = self->GetWidth() * self->GetHeight();
        byte* src_data =  self->GetData();
        byte* src_alpha = self->GetAlpha();
        byte* dst_data =  dest->GetData();
        byte* dst_alpha = NULL;

        // adjust rgb
        if ( factor_red == 1.0 && factor_green == 1.0 && factor_blue == 1.0)
        {
            // nothing to do for RGB
            memcpy(dst_data, src_data, rgblen);
        }
        else
        {
            // rgb pixel for pixel
            for ( unsigned i = 0; i < rgblen; i= i + 3 )
            {
                dst_data[i] =     (byte) wxMin( 255, (int) (factor_red * src_data[i]) );
                dst_data[i + 1] = (byte) wxMin( 255, (int) (factor_green * src_data[i + 1]) );
                dst_data[i + 2] = (byte) wxMin( 255, (int) (factor_blue * src_data[i + 2]) );
            }
        }

        // adjust the mask colour
        if ( self->HasMask() )
        {
            dest->SetMaskColour((byte) wxMin( 255, (int) (factor_red * self->GetMaskRed() ) ),
                                (byte) wxMin( 255, (int) (factor_green * self->GetMaskGreen() ) ),
                                (byte) wxMin( 255, (int) (factor_blue * self->GetMaskBlue() ) ) );
        }

        // adjust the alpha channel
        if ( src_alpha )
        {
            // source image already has alpha information
            dest->SetAlpha(); // create an empty alpha channel (not initialized)
            dst_alpha = dest->GetAlpha();

            wxCHECK_MSG( dst_alpha, NULL, wxT("unable to create alpha data") );

            if ( factor_alpha == 1.0)
            {
                // no need to adjust
                memcpy(dst_alpha, src_alpha, alphalen);
            }
            else
            {
                // alpha value for alpha value
                for ( unsigned i = 0; i < alphalen; ++i )
                {
                    dst_alpha[i] = (byte) wxMin( 255, (int) (factor_alpha * src_alpha[i]) );
                }
            }
        }
        else if ( factor_alpha != 1.0 )
        {
            // no alpha yet but we want to adjust -> create
            dest->SetAlpha(); // create an empty alpha channel (not initialized)
            dst_alpha = dest->GetAlpha();
    
            wxCHECK_MSG( dst_alpha, NULL, wxT("unable to create alpha data") );
    
            for ( unsigned i = 0; i < alphalen; ++i )
            {
                dst_alpha[i] = (byte) wxMin( 255, (int) (factor_alpha * 255) );
            }
        }

        // do we have an alpha channel and a mask in the new image?
        if ( dst_alpha && dest->HasMask() )
        {
            // make the mask transparent honoring the alpha channel
            const byte mr = dest->GetMaskRed();
            const byte mg = dest->GetMaskGreen();
            const byte mb = dest->GetMaskBlue();

            for ( unsigned i = 0; i < alphalen; ++i )
            {
                int n = i * 3;
                dst_alpha[i] = ( dst_data[n] == mr && dst_data[n + 1] == mg && dst_data[n + 2] == mb )
                    ? wxIMAGE_ALPHA_TRANSPARENT
                    : dst_alpha[i];
            }

            // remove the mask now
            dest->SetMask(false);
        }

        return dest;""",
        factory=True)
                               
    c.addProperty('Width GetWidth')
    c.addProperty('Height GetHeight')
    c.addProperty('MaskBlue GetMaskBlue')
    c.addProperty('MaskGreen GetMaskGreen')
    c.addProperty('MaskRed GetMaskRed')
    c.addProperty('Type GetType SetType')


    # For compatibility:
    module.addPyFunction('EmptyImage', '(width=0, height=0, clear=True)',
                         deprecated="Use :class:`Image` instead.",
                         doc='A compatibility wrapper for the wx.Image(width, height) constructor',
                         body='return Image(width, height, clear)')
    
    module.addPyFunction('ImageFromBitmap', '(bitmap)',
                         deprecated="Use bitmap.ConvertToImage instead.",
                         doc='Create a :class:`Image` from a :class:`wx.Bitmap`',
                         body='return bitmap.ConvertToImage()')

    module.addPyFunction('ImageFromStream', '(stream, type=BITMAP_TYPE_ANY, index=-1)',
                         deprecated="Use :class:`Image` instead.",
                         doc='Load an image from a stream (file-like object)',
                         body='return wx.Image(stream, type, index)')

    module.addPyFunction('ImageFromData', '(width, height, data)',
                         deprecated="Use :class:`Image` instead.",
                         doc='Compatibility wrapper for creating an image from RGB data',
                         body='return Image(width, height, data)')

    module.addPyFunction('ImageFromDataWithAlpha', '(width, height, data, alpha)',
                         deprecated="Use :class:`Image` instead.",
                         doc='Compatibility wrapper for creating an image from RGB and Alpha data',
                         body='return Image(width, height, data, alpha)')


    
    module.addPyFunction('ImageFromBuffer', '(width, height, dataBuffer, alphaBuffer=None)',
        doc="""\
            Creates a :class:`Image` from the data in `dataBuffer`.  The `dataBuffer`
            parameter must be a Python object that implements the buffer interface,
            such as a string, array, etc.  The `dataBuffer` object is expected to
            contain a series of RGB bytes and be width*height*3 bytes long.  A buffer
            object can optionally be supplied for the image's alpha channel data, and
            it is expected to be width*height bytes long.
        
            The :class:`Image` will be created with its data and alpha pointers initialized
            to the memory address pointed to by the buffer objects, thus saving the
            time needed to copy the image data from the buffer object to the :class:`Image`.
            While this has advantages, it also has the shoot-yourself-in-the-foot
            risks associated with sharing a C pointer between two objects.
        
            To help alleviate the risk a reference to the data and alpha buffer
            objects are kept with the :class:`Image`, so that they won't get deleted until
            after the wx.Image is deleted.  However please be aware that it is not
            guaranteed that an object won't move its memory buffer to a new location
            when it needs to resize its contents.  If that happens then the :class:`Image`
            will end up referring to an invalid memory location and could cause the
            application to crash.  Therefore care should be taken to not manipulate
            the objects used for the data and alpha buffers in a way that would cause
            them to change size.
            """,
        body="""\
            img = Image(width, height)
            img.SetDataBuffer(dataBuffer)
            if alphaBuffer:
                img.SetAlphaBuffer(alphaBuffer)
            img._buffer = dataBuffer
            img._alpha = alphaBuffer
            return img
            """)
    
    #-------------------------------------------------------
    c = module.find('wxImageHistogram')
    c.bases = ['wxObject']
    setParamsPyInt('MakeKey')
    c.find('FindFirstUnusedColour').type = 'void'
    c.find('FindFirstUnusedColour.r').pyInt = True
    c.find('FindFirstUnusedColour.g').pyInt = True
    c.find('FindFirstUnusedColour.b').pyInt = True
    c.find('FindFirstUnusedColour.startR').pyInt = True
    c.find('FindFirstUnusedColour.startG').pyInt = True
    c.find('FindFirstUnusedColour.startB').pyInt = True
    c.find('FindFirstUnusedColour.r').out = True
    c.find('FindFirstUnusedColour.g').out = True
    c.find('FindFirstUnusedColour.b').out = True
    
    

    #-------------------------------------------------------
    c = module.find('wxImageHandler')
    c.abstract = True
    c.addPrivateCopyCtor()
    c.find('GetLibraryVersionInfo').ignore()

    c.find('DoGetImageCount').ignore(False)
    c.find('DoCanRead').ignore(False)
    

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

    module.find('wxIMAGE_ALPHA_TRANSPARENT').pyInt = True
    module.find('wxIMAGE_ALPHA_OPAQUE').pyInt = True
    module.find('wxIMAGE_ALPHA_THRESHOLD').pyInt = True
    
    # These are defines for string objects, not integers, so we can't
    # generate code for them the same way as integer values. Since they are
    # #defines we can't just tell SIP that they are global wxString objects
    # because it will then end up taking the address of temporary values when
    # it makes the getters for them. So instead we'll just make some python
    # code to insert into the .py module and hope that the interface file
    # always has the correct values of these options.
    pycode = ""
    for item in module:
        if 'IMAGE_OPTION' in item.name and isinstance(item, etgtools.DefineDef):
            item.ignore()
            name = tools.removeWxPrefix(item.name)
            value = item.value
            for txt in ['wxString(', 'wxT(', ')']:
                value = value.replace(txt, '')
                
            pycode += '%s = %s\n' % (name, value)
    module.addPyCode(pycode)
    
    #-----------------------------------------------------------------
    tools.doCommonTweaks(module)
    tools.runGenerators(module)
예제 #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('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)