draw opaque on a transparent frame

I've been trying to devise a way to draw opaquely on a transparent
window frame with little success. Here is a barely working sample.
Does anyone know how this could be done better? The problems with
this example is that there is too much flicker when the window is drug
and the transparency does not update behind the text when what is
beneath changes. I plan on using this window as an instrument panel
that floats on top of a moving map, so it has to update smoothly.
Thanks in advance for any suggestions.

screenshots:
http://matrixmariner.com/ftpimages/mmg/transp1.jpg
http://matrixmariner.com/ftpimages/mmg/transp.jpg

import wx
class myframe (wx.Frame):
    def __init__(self, parent):
        wx.Frame.__init__ (self, parent, id = wx.ID_ANY, title =
wx.EmptyString, pos = wx.DefaultPosition, size = wx.Size( 500,300 ),
style = wx.RESIZE_BORDER|wx.SUNKEN_BORDER)
        self.SetSizeHintsSz(wx.DefaultSize, wx.DefaultSize)
        self.SetBackgroundColour(wx.Colour(0, 0, 0))
        self.Centre(wx.BOTH)
        self.Bind(wx.EVT_LEFT_DOWN, self.OnLeftDown)
        self.Bind(wx.EVT_LEFT_UP, self.OnLeftUp)
        self.Bind(wx.EVT_MOTION, self.OnMouseMove)
        self.Bind(wx.EVT_RIGHT_UP, self.OnExit)
        self.Bind(wx.EVT_PAINT, self.OnPaint)

    def OnExit(self, evt):
        self.SetEvtHandlerEnabled(False)
        self.Destroy()

    def OnLeftDown(self, evt):
        parent = wx.GetTopLevelParent(self)
        self.CaptureMouse()
        x, y = parent.ClientToScreen(evt.GetPosition())
        originx, originy = parent.GetPosition()
        dx = x - originx
        dy = y - originy
        self.delta = ((dx, dy))

    def OnLeftUp(self, evt):
        if self.HasCapture():
            self.ReleaseMouse()

    def OnMouseMove(self, evt):
        if evt.Dragging() and evt.LeftIsDown():
            parent = wx.GetTopLevelParent(self)
            x, y = self.ClientToScreen(evt.GetPosition())
            fp = (x - self.delta[0], y - self.delta[1])
            parent.Move(fp)

    def GetBg(self):
        x,y=self.GetPosition()
        xx,yy=self.GetSizeTuple()
        bmp = wx.EmptyBitmap(xx, yy)
        dc = wx.MemoryDC()
        dc.SelectObject(bmp)
        dc.Blit(x,y,xx,yy,wx.ScreenDC(),x,y)
        return bmp

    def OnPaint(self, evt):
        x,y=self.GetPosition()
        dc = wx.ScreenDC()
        bmp = self.GetBg()
        brush = wx.BrushFromBitmap(bmp)
        dc.SetBackground(brush)
        orange = wx.Colour(255,132.0)
        dc.SetTextForeground(orange)
        dc.DrawText('Hello transparent window! This text is not
transparent.', x+13, y+11)

app = wx.App(False)
fr = myframe(None)
fr.SetTransparent(150)
fr.Show()
app.MainLoop()

Make a shaped frame that is opaque that will overlay the transparent frame and follow it when moved.

This would involve painting the opaque bits to a bitmap which would then be used to set the region for the shaped frame and binding to the EVT_MOVE of the transparent frame to make the shaped frame smoothly follow it.

Toni

···

On Wed, 01 Dec 2010 03:33:04 +0100, manimaul <manimaul@gmail.com> wrote:

I've been trying to devise a way to draw opaquely on a transparent
window frame with little success. Here is a barely working sample.
Does anyone know how this could be done better? The problems with
this example is that there is too much flicker when the window is drug
and the transparency does not update behind the text when what is
beneath changes. I plan on using this window as an instrument panel
that floats on top of a moving map, so it has to update smoothly.
Thanks in advance for any suggestions.

screenshots:
http://matrixmariner.com/ftpimages/mmg/transp1.jpg
http://matrixmariner.com/ftpimages/mmg/transp.jpg

The overall frame needs to be semi-transparent (translucent) while certain portions need to be opaque. However, every pixel in a shaped Frame must either be set either at 100% transparency or at a fixed translucency (is this really a word ?!).

So, for the portions that will be opaque, “holes” need to be “cut out” of the translucent Frame’s mask. Those holes are 100% transparent. Then, the portions that are intended to be 100% opaque are overlaid with bitmaps. It’s not hard to do once it’s realized what needs to be done. Determining the sizes and positions of the bitmaps and masks can be challenging.

I’ve attached a working demo that was developed on MS Windows. It requires the PIL package due to inherent limitations in wxPython concerning manipulation of bitmap transparency. I’ve started with PNG image files and then derive PNG mask files from them. The individual mask files are combined as necessary to produce composite mask files that have the desired final shape. That is, the Frame mask has portions that indicate pixels in the shaped Frame that will be translucent and the rest indicating the pixels that will ultimately be overlaid with opaque pixels from an opaque bitmap.

This demo is somewhat more compex than you need, but it can be extended to produce a Frame that can have any number of different levels of transparency all at once. Remember that a shaped frame can only have pixels at either a fixed, defined transparency or be totally transparent. The “shaped” Frame certainly doesn’t need to be non-rectangular, but is the only kind of Frame that allows any transparency at all.

Ray Pasco

FANCY_SHAPED_WINDOW.zip.REMOVE_THIS_EXT (428 KB)

···

On Tue, Nov 30, 2010 at 9:33 PM, manimaul manimaul@gmail.com wrote:

I’ve been trying to devise a way to draw opaquely on a transparent
window frame with little success. Here is a barely working sample.

Does anyone know how this could be done better? The problems with
this example is that there is too much flicker when the window is drug
and the transparency does not update behind the text when what is
beneath changes. I plan on using this window as an instrument panel

that floats on top of a moving map, so it has to update smoothly.
Thanks in advance for any suggestions.

Ray,

Thanks for your example. It was very helpful. I will post some
example code that I end up using.

W