System Colours in wxPython Demo

Stani's Python Editor spe.stani.be at gmail.com
Mon Jun 18 07:54:09 PDT 2007


Hi Robin,
Currently developing a new cross-platform application, I want to use the
system colours as much as possible.  Unfortunately they are not
showcased in the demo. It is really hard to try them out one by one to
see how the colours match between platforms. So I've patched the
ColourDB demo, to append the system colours. Maybe it is better on its
own demo, but it is a good as a proof of concept. I'd like to have
something like this included in the wxPython demo. let me know how you
prefer to see it implemented, I'll be happy to provide it in the way you
want.
Thanks for considering,
Stani

PS Please cc the mail to me, as I am only subscribed to the digest.
-------------- next part --------------
import types
import wx
import wx.lib.colourdb

import images


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

class TestWindow(wx.ScrolledWindow):
    def __init__(self, parent,log):
        wx.ScrolledWindow.__init__(self, parent, -1)

        # Populate our color list
        clrList =3D wx.lib.colourdb.getColourInfoList()
        systemClrList =3D [(clr,wx.SystemSettings_GetColour(getattr(wx,clr)=
)) =

                            for clr in dir(wx) =

                            if clr[:11]=3D=3D'SYS_COLOUR_']
        systemClrList =3D [(clr,label,clr.Red(),clr.Green(),clr.Blue()) for=
 label,clr in systemClrList]
        self.clrList =3D clrList + systemClrList
        log.WriteText(str(len(self.clrList)))

        # Just for style points, we'll use this as a background image.
        self.bg_bmp =3D images.getGridBGBitmap()

        # This could also be done by getting the window's default font;
        # either way, we need to have a font loaded for later on.
        #self.SetBackgroundColour("WHITE")
        self.font =3D wx.Font(10, wx.SWISS, wx.NORMAL, wx.NORMAL)

        # Create drawing area and set its font
        dc =3D wx.ClientDC(self)
        dc.SetFont(self.font)

        # Using GetFullTextExtent(), we calculate a basic 'building block'
        # that will be used to draw a depiction of the color list. We're
        # using 'Wy' as the model becuase 'W' is a wide character and 'y' =

        # has a descender. This constitutes a 'worst case' scenario, which =
means
        # that no matter what we draw later, text-wise, we'll have room for=
 it
        w,h,d,e =3D dc.GetFullTextExtent("Wy") =


        # Height plus descender
        self.textHeight =3D h + d

        # Pad a little bit
        self.lineHeight =3D self.textHeight + 5

        # ... and this is the basic width.
        self.cellWidth =3D w

        # jmg 11/8/03: why 24?
        numCells =3D 24
        =

        # 'prep' our scroll bars.
        self.SetScrollbars(
            self.cellWidth, self.lineHeight, numCells, len(self.clrList) + 2
            )
            =

        # Event handlers - moved here so events won't fire before init is =

        # finished.
        self.SetBackgroundStyle(wx.BG_STYLE_CUSTOM)
        self.Bind(wx.EVT_PAINT, self.OnPaint)
        self.Bind(wx.EVT_ERASE_BACKGROUND, self.OnEraseBackground)


    # tile the background bitmap loaded in __init__()
    def TileBackground(self, dc):
        sz =3D self.GetClientSize()
        w =3D self.bg_bmp.GetWidth()
        h =3D self.bg_bmp.GetHeight()

        # adjust for scrolled position
        spx, spy =3D self.GetScrollPixelsPerUnit()
        vsx, vsy =3D self.GetViewStart()
        dx,  dy  =3D (spx * vsx) % w, (spy * vsy) % h

        x =3D -dx

        while x < sz.width:
            y =3D -dy
            while y < sz.height:
                dc.DrawBitmap(self.bg_bmp, x, y)
                y =3D y + h

            x =3D x + w

    # Redraw the background over a 'damaged' area.
    def OnEraseBackground(self, evt):
        dc =3D evt.GetDC()

        if not dc:
            dc =3D wx.ClientDC(self)
            rect =3D self.GetUpdateRegion().GetBox()
            dc.SetClippingRect(rect)

        self.TileBackground(dc)


    def OnPaint(self, evt):
        dc =3D wx.PaintDC(self)
        self.PrepareDC(dc)
        self.Draw(dc, self.GetUpdateRegion(), self.GetViewStart())


    def Draw(self, dc, rgn=3DNone, vs=3DNone):
        dc.SetTextForeground("BLACK")
        dc.SetPen(wx.Pen("BLACK", 1, wx.SOLID))
        dc.SetFont(self.font)
        colours =3D self.clrList
        numColours =3D len(colours)

        if rgn:
            # determine the subset of the color list that has been exposed =

            # and needs drawn. This is based on all the precalculation we
            # did in __init__()
            rect =3D rgn.GetBox()
            pixStart =3D vs[1]*self.lineHeight + rect.y
            pixStop  =3D pixStart + rect.height
            start =3D pixStart / self.lineHeight - 1
            stop =3D pixStop / self.lineHeight
        else:
            start =3D 0
            stop =3D numColours

        for line in range(max(0,start), min(stop,numColours)):
            clr =3D colours[line][0]
            if type(clr) in types.StringTypes:
                label =3D clr
                rgb   =3D colours[line][1:]
            else:
                label =3D colours[line][1]
                rgb   =3D colours[line][2:]
            y =3D (line+1) * self.lineHeight + 2

            dc.DrawText(label, self.cellWidth, y)

            brush =3D wx.Brush(clr, wx.SOLID)
            dc.SetBrush(brush)
            dc.DrawRectangle(15 * self.cellWidth, y,
                             6 * self.cellWidth, self.textHeight)
            =

            dc.DrawText(str(tuple(rgb)),
                        23 * self.cellWidth, y)


# On wxGTK there needs to be a panel under wx.ScrolledWindows if they are
# going to be in a wxNotebook. And, in this demo, we are.
class TestPanel(wx.Panel):
    def __init__(self, parent,log):
        wx.Panel.__init__(self, parent, -1)
        self.win =3D TestWindow(self,log)
        self.Bind(wx.EVT_SIZE, self.OnSize)


    def OnSize(self, evt):
        self.win.SetSize(evt.GetSize())



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


def runTest(frame, nb, log):
    # This loads a whole bunch of new color names and values
    # into TheColourDatabase
    #
    # Note 11/24/03 - jg - I moved this into runTest() because
    # there must be a wx.App existing before this function
    # can be called - this is a change from 2.4 -> 2.5.
    wx.lib.colourdb.updateColourDB()

    win =3D TestPanel(nb,log)

    return win

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

overview =3D """
<html>
<body>
<B><font size=3D+2>ColourDB</font></b>

<p>wxWindows maintains a database of standard RGB colours for a predefined =

set of named colours (such as "BLACK'', "LIGHT GREY''). The application =

may add to this set if desired by using Append. There is only one instance =

of this class: <b>TheColourDatabase</b>.

<p>The <code>colourdb</code> library is a lightweight API that pre-defines
a multitude of colors for you to use 'out of the box', and this demo serves
to show you these colors (it also serves as a handy reference).

<p>A secondary benefit of this demo is the use of the <b>ScrolledWindow</b>=
 class
and the use of various *DC() classes, including background tiling and the u=
se of
font data to generate a "building block" type of construct for repetitive u=
se.

<p>
<B><font size=3D+2>Important note</font></b>

<p>
With implementation of V2.5 and later, it is required to have a wx.App alre=
ady
initialized before <b><code>wx.updateColourDB()</code></b> can be called. =

Trying to do otherwise will cause an exception to be raised.
</body>
</html>
"""


if __name__ =3D=3D '__main__':
    import sys,os
    import run
    run.main(['', os.path.basename(sys.argv[0])] + sys.argv[1:])



More information about the wxpython-dev mailing list