Elliptic CanvasGadget
Elliptic CanvasGadget
As the CanvasGadget is so useful, a good complement would be EllipticCanvasGadget, with the same coordinates than the normal one, like the GdipDrawEllipse function, that takes the four corners of the bounding rectangle that the ellipse is drawn within.
Re: Elliptic CanvasGadget
Couldn't this be solved by making the canvas gadget display with alpha? That way, just make whatever area is "outside" the control transparent.
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Elliptic CanvasGadget
There are a number of problems with this approach unfortunately. The gadget can't be layered as it's a child window, so it would have to be alphablended with the window background at each redraw. This is how the current ImageGadget functions, and when it contains a 32bit image it flickers a lot if it's updated too rapidly. The CanvasGadget needs to perform redraws smoothly because a lot of applications for it involve animations and so that doesn't leave too many options for making it partially transparent. One thing you can do on Windows though, is apply a region to it:Couldn't this be solved by making the canvas gadget display with alpha?
Code: Select all
OpenWindow(0,0,0,640,480,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
CanvasGadget(0,20,20,400,300)
hRgn = CreateEllipticRgn_(0,0,400,300)
SetWindowRgn_(GadgetID(0), hrgn, 1)
Repeat
EventID = WaitWindowEvent()
Select EventID
Case #PB_Event_Gadget
If EventGadget()=0 And EventType()=#PB_EventType_LeftButtonDown
Debug "Button Down!"
EndIf
EndSelect
Until EventID = #PB_Event_CloseWindow
BERESHEIT
Re: Elliptic CanvasGadget
Thanks Trond and Netmaestro.
I still think that a native multiplatform Elliptic Canvas could be useful.
I don't need this now; don't take it as coding question but only as an idea that Fred or Freak may or not consider interesting.
(As long as I remember, this is my first request in 8 years.
)
Cheers!

I still think that a native multiplatform Elliptic Canvas could be useful.
I don't need this now; don't take it as coding question but only as an idea that Fred or Freak may or not consider interesting.
(As long as I remember, this is my first request in 8 years.

Cheers!
Re: Elliptic CanvasGadget
Just because it's currently implemented with flicker, doesn't mean it has to be implemented that way.netmaestro wrote:...Couldn't this be solved by making the canvas gadget display with alpha?
This is how the current ImageGadget functions, and when it contains a 32bit image it flickers a lot if it's updated too rapidly.
Code: Select all
Global OldProc
Global BackBuffer = CreateImage(#PB_Any, 512, 512, 24)
; Procedure Blend(source, target)
; R = Red(source)
; B = Blue(source)
; G = Green(source)
;
; R2 = Red(target)
; B2 = Blue(target)
; G2 = Green(target)
;
; Alpha = Alpha(source)
;
; R = ((R*Alpha)/255) + ((R2*(255-Alpha)) / 255)
; G = ((G*Alpha)/255) + ((G2*(255-Alpha)) / 255)
; B = ((B*Alpha)/255) + ((B2*(255-Alpha)) / 255)
;
; ProcedureReturn RGB(R, G, B)
; EndProcedure
Procedure Callback(WindowID, Message, wParam, lParam)
Protected Result = #PB_ProcessPureBasicEvents
Select Message
Case #WM_ERASEBKGND
; Debug "erase bkgnd"
Result = 1
Case #WM_PAINT
hDC_b = StartDrawing(ImageOutput(BackBuffer))
Box(0, 0, 512, 512, GetSysColor_(#COLOR_3DFACE))
DrawingMode(#PB_2DDrawing_AlphaBlend)
DrawImage(ImageID(0), 0, 0)
hDC_w = BeginPaint_(WindowID, @paint.PAINTSTRUCT)
BitBlt_(hDC_w, 0, 0, 512, 512, hDC_b, 0, 0, #SRCCOPY)
EndPaint_(WindowID, @paint)
StopDrawing()
; Alternate blend code, without backbuffer, but too slow
; hDC_w = BeginPaint_(WindowID, @paint.PAINTSTRUCT)
; bg = GetSysColor_(#COLOR_3DFACE)
; hDC_i = StartDrawing(ImageOutput(0))
; DrawingMode(#PB_2DDrawing_AllChannels)
; For x = 0 To 511
; For y = 0 To 511
; color = Blend(Point(x, y), bg)
; SetPixel_(hDC_w, x, y, color)
; Next
; Next
; StopDrawing()
; EndPaint_(WindowID, @paint)
Result = 0
EndSelect
If Result = #PB_ProcessPureBasicEvents
ProcedureReturn CallWindowProc_(OldProc, WindowID, Message, wParam, lParam)
Else
ProcedureReturn Result
EndIf
EndProcedure
CreateImage(0, 512, 512, 32)
Procedure RotateImage()
Static Angle.d = 0
Angle + 0.5
Angle = Mod(Angle, 360)
StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_AllChannels | #PB_2DDrawing_Gradient)
GradientColor(0, RGBA(192, 128, 0, 255))
GradientColor(1, RGBA(192, 128, 0, 0))
ConicalGradient(256, 256, Angle)
Box(0, 0, 512, 512)
StopDrawing()
EndProcedure
#W = 600
#H = 600
OpenWindow(0, 0, 0, #W, #H, "", #PB_Window_ScreenCentered | #PB_Window_SystemMenu | #PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
ImageGadget(0, 0, 0, 0, 0, ImageID(0))
AddWindowTimer(0, 0, 30)
SmartWindowRefresh(0, 1) ; !!
hwnd = GadgetID(0)
OldProc = SetWindowLongPtr_(hwnd, #GWLP_WNDPROC, @Callback())
Repeat
Select WaitWindowEvent()
Case #PB_Event_Timer
RotateImage()
SetGadgetState(0, ImageID(0))
t2 = ElapsedMilliseconds()-t
Case #PB_Event_CloseWindow
Break
EndSelect
ForEver
- netmaestro
- PureBasic Bullfrog
- Posts: 8451
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Elliptic CanvasGadget
It's not that simple. You have to alphablend with the actual background, not just the solid color you expect it to be. A premultiplication is necessary followed by AlphaBlend_() with the background DC at each redraw. I trust that the PB implementation is performing about as well as is possible given the task and constraints.
BERESHEIT
Re: Elliptic CanvasGadget
I thought, that since PB manages both the window and the gadget, the gadget implementation could know which background brush or color was used on the window. Of course, this wouldn't work if the user painted the window background in a callback, but mixing API and PB were never guaranteed anyways.You have to alphablend with the actual background, not just the solid color you expect it to be.
Note that there is no "actual background", as SmartWindowRefresh() is on, causing the background paint of the window to not go where there are controls. The background must always be drawn by the gadget anyways in this case, and currently it doesn't work at all.
I agree it's not a 100% true solution, but I believe that when implemented correctly (without such assumptions as I made) it will work for 99% of users.