ImageGadget: set opacity/use as overlay?

Just starting out? Need help? Post your questions and find answers here.
hss
User
User
Posts: 69
Joined: Thu Mar 08, 2007 6:02 pm

ImageGadget: set opacity/use as overlay?

Post by hss »

hello,

didn't found a solution for this: is there an API-way to set ImageGadget's opacity while it's on top of other gadgets?
(having a second window w/ #LWA_ALPHA is no solution for my case, btw.)
User avatar
netmaestro
PureBasic Bullfrog
PureBasic Bullfrog
Posts: 8451
Joined: Wed Jul 06, 2005 5:42 am
Location: Fort Nelson, BC, Canada

Re: ImageGadget: set opacity/use as overlay?

Post by netmaestro »

The answer to your question is pretty much "no". You can manipulate an image gadget in various ways but the OS will not draw things the way you want it to. Here is an imagegadget trying to be semitransparent. All looks well until you move the mouse over the other gadgets and we see that they show right through as though punching a hole:

Code: Select all

; Create a transparent image to test with
CreateImage(0,300,300,32,#PB_Image_Transparent)
StartVectorDrawing(ImageVectorOutput(0))
AddPathCircle(149,149,128)
VectorSourceColor(RGBA(255,0,0,25))
FillPath()
StopVectorDrawing()

OpenWindow(0,0,0,800,600,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_MinimizeGadget)
StringGadget(0, 100,200,200,20,"Stringy thingy...")
ButtonGadget(1, 200, 260, 80,20,"Close")
SetActiveGadget(0)
ImageGadget(2, 100,100,300,300,ImageID(0))
DisableGadget(2,1)
SetWindowLongPtr_(GadgetID(2), #GWL_EXSTYLE,GetWindowLongPtr_(GadgetID(2), #GWL_EXSTYLE) | #WS_EX_TRANSPARENT)

Repeat
  ev = WaitWindowEvent()
  Select ev
    Case #PB_Event_Gadget
      If EventGadget()=1
        End
      EndIf
  EndSelect
  
Until ev = #PB_Event_CloseWindow
Using the method you want to avoid we can achieve the full effect:

Code: Select all

; We need a callback for keeping the image "gadget" where it belongs
Declare Win0Proc(hwnd, msg, wParam, lParam)

; Create a transparent image to test with
CreateImage(0,300,300,32,#PB_Image_Transparent)
StartVectorDrawing(ImageVectorOutput(0))
AddPathCircle(149,149,128)
VectorSourceColor(RGBA(255,0,0,255))
FillPath()
StopVectorDrawing()

; First, a host window
OpenWindow(0,0,0,800,600,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_MinimizeGadget)

; Next, a window to serve as the image "gadget"
OpenWindow(1,WindowX(0)+100,WindowY(0)+125,300,300,"",#PB_Window_BorderLess, WindowID(0))
SetWindowLongPtr_(WindowID(1), #GWL_EXSTYLE, #WS_EX_LAYERED|#WS_EX_TOOLWINDOW|#WS_EX_TRANSPARENT)
SetWindowLongPtr_(WindowID(1), #GWL_STYLE,GetWindowLongPtr_(WindowID(1), #GWL_STYLE)| #WS_CLIPCHILDREN)

; A "SetGadgetState" for our fake imagegadget
hDC = StartDrawing(ImageOutput(0)) 
  With sz.SIZE
    \cx = ImageWidth(0)
    \cy = ImageHeight(0)
  EndWith
  With BlendMode.BLENDFUNCTION 
    \SourceConstantAlpha = 40 ; Adjust opacity here
    \AlphaFormat = 1
  EndWith
  UpdateLayeredWindow_(WindowID(1),0,0,@sz,hDC,@ContextOffset.POINT,0,@BlendMode,2)
StopDrawing() 
DisableWindow(1,1)
SetWindowCallback(@Win0Proc(), 0)
UseGadgetList(WindowID(0))
StringGadget(0, 100,200,200,20,"Stringy thingy...")
ButtonGadget(1, 200, 260, 80,20,"Close")
SetActiveGadget(0)
Repeat
  ev = WaitWindowEvent()
  Select ev
    Case #PB_Event_Gadget
      If EventGadget()=1
        End
      EndIf
  EndSelect
  
Until ev = #PB_Event_CloseWindow

; End of main loop

Procedure Win0Proc(hwnd, msg, wParam, lParam)
  result=#PB_ProcessPureBasicEvents
  Select msg
    Case #WM_ACTIVATE,#WM_MOVE,#WM_MOVING
      ResizeWindow(1, WindowX(0)+100,WindowY(0)+125,#PB_Ignore,#PB_Ignore)
      
    Case #WM_TIMER
      HideWindow(1,0)
      RemoveWindowTimer(0,1)
      
    Case #WM_SYSCOMMAND
      Select  wParam & $FFF0
        Case #SC_MINIMIZE
          HideWindow(1,1)
        Case #SC_RESTORE
          AddWindowTimer(0, 1, 300)
      EndSelect
      
  EndSelect
  ProcedureReturn result
EndProcedure

But nobody can make you use something you don't want to use. However, for the full effect that's your only option imho. But someone else may have a better idea, you never know.
BERESHEIT
hss
User
User
Posts: 69
Joined: Thu Mar 08, 2007 6:02 pm

Re: ImageGadget: set opacity/use as overlay?

Post by hss »

thanks, netmaestro

to specify:

Image

so, if doing w/ 2nd window (which also fits delayed while moving), i guess a 3rd window is needed to put the "menu" onto;

since the background gadgets aren't "needed" while the menu is opened, i managed by calling PrintWindow_ and putting a darkened version of the screenshot here.

however, this might be a better way:

Code: Select all

CreateImage(0,300,300,32)
StartDrawing(ImageOutput(0))
DrawingMode(#PB_2DDrawing_AlphaChannel)
Box(0,0,300,300,RGBA(0,0,0,190))
StopDrawing()




OpenWindow(0,0,0,800,600,"",#PB_Window_ScreenCentered|#PB_Window_SystemMenu|#PB_Window_MinimizeGadget)
StringGadget(0, 100,200,200,20,"Stringy thingy...")
ButtonGadget(1, 200, 260, 80,20,"Close")
For j=0 To 1
  DisableGadget(j,1)
  
Next


ImageGadget(2, 100,100,300,300,ImageID(0))






Repeat
  ev = WaitWindowEvent()
  Select ev
    Case #PB_Event_Gadget
      If EventGadget()=1
        End
      EndIf
  EndSelect
  
Until ev = #PB_Event_CloseWindow
Post Reply