Transparent Window Backgrounds

BlitzMax Modules Forums/Brucey's Modules/Transparent Window Backgrounds

Hello, I have recently been messing around with customized windows on Mac OS.

A good example is found on the apple development website:

http://developer.apple.com/samplecode/RoundTransparentWindow/index.html

However I seem to have stumbled into a small problem while using wxMax. While the window backgound colour can be set, I have been unable to clear it entirely. Is this possible within wxMax?

I have been able to, crudely, hack this functionality into MaxGUI using the following functions inserted after a window is created (within NSInitGadget, cocoa.macos.m):

[window setOpaque:NO];
[window setBackgroundColor: [NSColor clearColor]];
[window setHasShadow: YES];

But I am at a loss as where to include them within the wxMax module for a similar effect.

Any insight into this matter would be greatly appreciated.

Is this what you are after?
SuperStrict
 
Framework wx.wxApp
Import wx.wxFrame
 
New MyApp.Run()
 
Type MyApp Extends wxApp

	Method OnInit:Int()
	
		Local sim:Simple = Simple(New Simple.Create(Null, wxID_ANY, ..
			"Simple", -1, -1, 250, 150))
		
		' set alpha transparency
		sim.SetTransparent(128)
		
		sim.Show(True)
 
		Return True
	End Method

End Type

Type Simple Extends wxFrame
 
	Method OnInit()
		
		Centre()
 
	End Method
	
End Type



Not quite, while the transparency is exactly what I am after, the background colour itself remains and the effect covers any image that is drawn to it.

This is a quick example (replace circle.png with an alpha enabled png):

SuperStrict
 
Framework wx.wxApp
Import wx.wxFrame
Import wx.wxImage
 
New MyApp.Run()
 
Type MyApp Extends wxApp

	Method OnInit:Int()
		wxImage.AddHandler(New wxPNGHandler)

		Local txt:Example = Example(New Example.Create(Null, wxID_ANY, ..
			"Example", -1, -1, 300, 300))
		txt.Show(True)
 
		Return True
	End Method

End Type

Type Example Extends wxFrame
 
	Method OnInit()
		
		ConnectAny(wxEVT_PAINT, OnPaint)
		Centre()
		SetTransparent(100)
 
	End Method
	
	Function OnPaint(event:wxEvent)
		
		Local dc:wxPaintDC = New wxPaintDC.Create(wxWindow(event.parent))

		Local m_Image2:wxImage = wxImage.CreateFromFile("circle.png", wxBITMAP_TYPE_PNG)
		dc.DrawBitmap(wxBitmap.CreateFromImage(m_Image2),0,0,True)	

		dc.Free()
	End Function
	
End Type 


What I am aiming for is a Opaque image drawn to the window, with the desktop shown in the background and the areas where the image has alpha.

Okay... I think I'm getting the hang of it now...

How's about :
SuperStrict
 
Framework wx.wxApp
Import wx.wxFrame
Import wx.wxMouseEvent
Import BRL.RamStream

Incbin "donut.png"

New MyApp.Run()
 
Type MyApp Extends wxApp

	Method OnInit:Int()
	
		wxInitAllImageHandlers()
	
		Local sim:Shaped = Shaped(New Shaped.Create(Null, wxID_ANY, ..
			"Shaped", -1, -1, 100, 100, wxFRAME_SHAPED | wxSIMPLE_BORDER | wxFRAME_NO_TASKBAR | wxSTAY_ON_TOP))
		
		
		sim.Center()
		sim.Show(True)
 
		Return True
	End Method

End Type

Type Shaped Extends wxFrame

	Field bmp:wxBitmap
	
	Field deltaX:Int
	Field deltaY:Int
 
	Method OnInit()
		
		bmp = wxBitmap.CreateFromFile("incbin::donut.png", wxBITMAP_TYPE_PNG)
		
		SetClientSize(bmp.GetWidth(), bmp.GetHeight())
		
		SetWindowShape()
 
		Local dc:wxDC = New wxClientDC.Create(Self)
        dc.DrawBitmap(bmp, 0,0, True)
		dc.Free()
		
		ConnectAny(wxEVT_PAINT, OnPaint)
		ConnectAny(wxEVT_LEFT_DOWN, _OnLeftDown)
		ConnectAny(wxEVT_LEFT_UP, _OnLeftUp)
		ConnectAny(wxEVT_MOTION, _OnMouseMove)
	End Method
	
	Method SetWindowShape()
		Local r:wxRegion = New wxRegion.CreateWithBitmap(bmp, New wxColour.Create($ff, $66, $ff), 5)
		DebugLog SetShape(r)
	End Method


	Function OnPaint(event:wxEvent)
		Local frame:Shaped = Shaped(event.parent)
		Local dc:wxPaintDC = New wxPaintDC.Create(frame)
	    dc.DrawBitmap(frame.bmp, 0,0, True)
		dc.Free()
	End Function
	
	Function _OnLeftDown(event:wxEvent)
		Shaped(event.parent).OnLeftDown(wxMouseEvent(event))
	End Function

	Function _OnLeftUp(event:wxEvent)
		Shaped(event.parent).OnLeftUp(wxMouseEvent(event))
	End Function

	Function _OnMouseMove(event:wxEvent)
		Shaped(event.parent).OnMouseMove(wxMouseEvent(event))
	End Function
	
	Method OnLeftDown(event:wxMouseEvent)
		CaptureMouse()
		
		Local x:Int = event.GetX(), y:Int = event.GetY()
		ClientToScreen(x, y)
		
		Local originX:Int, originY:Int
		GetPosition(originX, originY)
		
		deltaX = x - originX
		deltaY = y - originY
	End Method

	Method OnLeftUp(event:wxMouseEvent)
		If HasCapture() Then
			ReleaseMouse()
		End If
	End Method

	Method OnMouseMove(event:wxMouseEvent)
		Local x:Int, y:Int
		event.GetPosition(x, y)
		
		If event.Dragging() And event.LeftIsDown() Then
			ClientToScreen(x, y)
			Move(x - deltaX, y - deltaY)
		End If
	End Method
	

End Type

and supporting image...


And, here's a zip of the above two files for convenience : shape_example.zip

Left-click and drag.... Cmd-Q to quit... Just the basics.

You will need to update your wxMax to the latest in SVN, for a wee fix/update to wxRegion.

And apologies for the purple haze around the edge of the donut... I just threw it all together 10 mins ago.

:-)

Main caveat is of course a lack of Alpha support... Not sure if it can do it this way, since it's Carbon, not Cocoa..

Yay! A shaped frame demo...