Page 1 of 1

CanvasGadget and/or ImageGadget transparent

Posted: Sun Nov 24, 2024 4:11 am
by Jakala
I am a PureBasic novice but experienced with various BASIC languages. Believe this should not be so hard to do.

Is there a way to draw a CanvasGadget with/without ImageGadget in which transparency can be achieved?

Thank you

Re: CanvasGadget and/or ImageGadget transparent

Posted: Sun Nov 24, 2024 5:47 am
by TI-994A
Jakala wrote: Sun Nov 24, 2024 4:11 amIs there a way to draw a CanvasGadget with/without ImageGadget in which transparency can be achieved?
Hi Jakala, and welcome to the PureBasic forum!

PureBasic offers native functions to easily draw images while preserving their alpha values. Here's an example:

Code: Select all

UsePNGImageDecoder()

imgFile$ = GetTemporaryDirectory() + "superman.png"
If FileSize(imgFile$) < 1  ; download only if not downloaded before (file does not exist)
  ReceiveHTTPFile("https://www.dropbox.com/scl/fi/ti8u0vw4hgsmh63wy0bzp/superman.png?" + 
                  "rlkey=ba7bxdwi3etwho5bux4xg6zag&st=hl7vfe93&dl=1",
                  GetTemporaryDirectory() + "superman.png")
EndIf

LoadImage(0, imgFile$)
OpenWindow(0, 0, 0, ImageWidth(0), ImageHeight(0), "", 
           #PB_Window_ScreenCentered | #PB_Window_BorderLess)
CanvasGadget(0, 0, 0, ImageWidth(0), ImageHeight(0))

StartDrawing(CanvasOutput(0))
Box(0, 0, ImageWidth(0), ImageHeight(0), #Cyan)
DrawingMode(#PB_2DDrawing_AllChannels)
DrawAlphaImage(ImageID(0), 0, 0)
StopDrawing()   

While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend

It draws a PNG image (downloaded from my DropBox for convenience) onto a canvas which has been painted cyan.

Hope it helps. :D

Re: CanvasGadget and/or ImageGadget transparent

Posted: Sun Nov 24, 2024 6:02 am
by RASHAD
Hi TI-994A :D
Edit your snippet there is a dot at line 4 [FileSize(imgFile$) < 1.]

Re: CanvasGadget and/or ImageGadget transparent

Posted: Sun Nov 24, 2024 6:05 am
by TI-994A
RASHAD wrote: Sun Nov 24, 2024 6:02 am Hi TI-994A :D
Edit your snippet there is a dot at line 4 [FileSize(imgFile$) < 1.]
Thanks Rashad! The PureBasic editor thinks it's a wordprocessor. :lol:

Re: CanvasGadget and/or ImageGadget transparent

Posted: Sun Nov 24, 2024 6:18 am
by TI-994A
With the help of native APIs, even forms and windows could be shaped with transparency. This one works on Windows and macOS:

Code: Select all

UsePNGImageDecoder()

Declare imageProc(hwnd, msg, wParam, lParam)

imgFile$ = GetTemporaryDirectory() + "splash.png"
If FileSize(imgFile$) < 1  ; download only if not downloaded before (file does not exist)  
  ReceiveHTTPFile("https://www.dropbox.com/scl/fi/m7ozmkex5up88nnm2cffj/splash.png?" +
                  "rlkey=cgliz6745e0c1fc0688vdm0x5&st=vu9058gd&dl=1", 
                  GetTemporaryDirectory() + "splash.png")
EndIf

LoadImage(0, imgFile$)
OpenWindow(0, 0, 0, ImageWidth(0), ImageHeight(0), "", 
           #PB_Window_ScreenCentered | #PB_Window_BorderLess)
TextGadget(1, 10, 300, 100, 30, "PASSWORD:")
StringGadget(2, 100, 292, 300, 30, "", #PB_String_Password)
SetGadgetColor(2, #PB_Gadget_BackColor, RGB(255, 255, 250))
ButtonGadget(3, 410, 292, 100, 30, "LOGIN") 

CompilerIf #PB_Compiler_OS = #PB_OS_MacOS
  
  windowShape = CocoaMessage(0, 0, "NSColor colorWithPatternImage:", ImageID(0))
  CocoaMessage(0, WindowID(0), "setOpaque:", #NO)
  CocoaMessage(0, WindowID(0), "setHasShadow:", #YES)  
  CocoaMessage(0, WindowID(0), "setMovableByWindowBackground:", #YES)  
  CocoaMessage(0, WindowID(0), "setBackgroundColor:", windowShape)
  
CompilerElseIf #PB_Compiler_OS = #PB_OS_Windows
  
  SetWindowColor(0, #White)
  layeredStyle = GetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE) | #WS_EX_LAYERED
  SetWindowLongPtr_(WindowID(0), #GWL_EXSTYLE, layeredStyle)
  SetLayeredWindowAttributes_(WindowID(0), #White, 0, #LWA_COLORKEY) 
  ImageGadget(0, 0, 0, WindowWidth(0), WindowHeight(0), ImageID(0))
  sysProc = SetWindowLongPtr_(GadgetID(0), #GWL_WNDPROC, @imageProc())
  
  Procedure imageProc(hwnd, msg, wParam, lParam)
    Shared sysProc
    Select msg     
      Case #WM_LBUTTONDOWN  
        SendMessage_(WindowID(0), #WM_NCLBUTTONDOWN, #HTCAPTION, 0)      
    EndSelect 
    ProcedureReturn CallWindowProc_(sysProc, hwnd, msg, wParam, lParam)
  EndProcedure
  
CompilerElse
  
  MessageRequester("Transparent Window", "This feature is not supported.")  
  
CompilerEndIf

Repeat
  event = WaitWindowEvent()
  If event = #PB_Event_Gadget And EventGadget() = 3
    Break
  EndIf  
ForEver

Re: CanvasGadget and/or ImageGadget transparent

Posted: Sun Nov 24, 2024 6:21 am
by TI-994A
Hello again, Rashad. Trust you are well, my friend. :D

My last example, for window transparency, seems to work well on macOS, but for some reason, on Windows, the string gadget appears to click through.

Would you have any idea what could be causing this?

Re: CanvasGadget and/or ImageGadget transparent

Posted: Sun Nov 24, 2024 10:51 am
by RASHAD
Hi TI-994A :)
Sorry for late responding
You became a Global Computer user [Windows,Mac & Linux] :D
Any solid white color will be transparent

Code: Select all

StringGadget(2, 100, 292, 300, 30, "", #PB_String_Password)
SetGadgetColor(2, #PB_Gadget_BackColor,$FEFEFE)

Re: CanvasGadget and/or ImageGadget transparent

Posted: Sun Nov 24, 2024 11:02 am
by TI-994A
RASHAD wrote: Sun Nov 24, 2024 10:51 am Any solid white color will be transparent...
Thanks Rashad; it works! I would never have caught that. You're a genius. :D

RASHAD wrote: Sun Nov 24, 2024 10:51 am You became a Global Computer user [Windows,Mac & Linux] :D
Too much interaction with Linux at work, so I started to dabble with PureBasic Linux as well. :lol:

Re: CanvasGadget and/or ImageGadget transparent

Posted: Fri Nov 29, 2024 9:19 pm
by Jakala
Thank you all for attempting answer my query.
After opening a window and loading a background image I want to draw a separate image on it.

Wd = 6
Rnd = Height/2
Clear = RGBA(0,0,0,0)
If CreateImage(1, Width, Height)
If StartDrawing(ImageOutput(1))
DrawingMode(#PB_2DDrawing_Transparent) ;Tried many different modes
Box(0, 0, Width, Height, Clear)
RoundBox(0,0, Width, Height, Rnd, Rnd, #Blue)
RoundBox(Wd, Wd, Width - (Wd*2), Height - (wd*2), Rnd, Rnd, Clear)
StopDrawing()
ImageGadget(1, Left, Top, Width, Height, ImageID(1))
Rtn = #True
EndIf
EndIf
EndIf

This results ina RoundBox where desired but it's corners are black. Would like back image instead. Same for secound RoundBox which would want back image peeking through. Instead is black.

Ideas??

PS: How post code in yellow boxes as some of reply posts have done

Re: CanvasGadget and/or ImageGadget transparent

Posted: Sat Nov 30, 2024 6:47 am
by TI-994A
Jakala wrote: Fri Nov 29, 2024 9:19 pm... Would like back image instead. Same for secound RoundBox which would want back image peeking through.
If I've understood correctly, this might work:

Code: Select all

Width = 300 : Height = 300 : Wd = 6 : Rnd = Height/2
Left = 10 : Top = 10 : LineThickness = 10

win = OpenWindow(#PB_Any, 0, 0, 640, 320, "Transparent Drawing Example",
                 #PB_Window_SystemMenu | #PB_Window_ScreenCentered)

; without transparency
If CreateImage(0, Width, Height)
  If StartVectorDrawing(ImageVectorOutput(0))
    AddPathCircle(Width / 2, Width / 2, (Width / 2) - LineThickness, 0, 360)      
    ClosePath()
    VectorSourceColor(RGBA(0, 0, 255, 255))
    StrokePath(LineThickness)   
    StopVectorDrawing()
  EndIf  
EndIf

; with transparency
If CreateImage(1, Width, Height, 32, #PB_Image_Transparent)  
  If StartVectorDrawing(ImageVectorOutput(1))
    AddPathCircle(Width / 2, Width / 2, (Width / 2) - LineThickness, 0, 360)      
    ClosePath()
    VectorSourceColor(RGBA(0, 0, 255, 255))
    StrokePath(LineThickness)   
    StopVectorDrawing()
  EndIf  
EndIf

ImageGadget(0, Left, Top, Width, Height, ImageID(0))
ImageGadget(1, 320 + Left, Top, Width, Height, ImageID(1))
While WaitWindowEvent() ! #PB_Event_CloseWindow : Wend

Jakala wrote: Fri Nov 29, 2024 9:19 pmPS: How post code in yellow boxes...
Just place the code between code tags, like this (there should be no spaces inside tags - added for illustration purpose only):

Code: Select all

[code ]  <--- no spaces inside brackets

...insert the code here

[/code ]  <--- no spaces inside brackets
Alternatively, in the forum post editor, you code also simply click the button with the label </>.

Re: CanvasGadget and/or ImageGadget transparent

Posted: Sat Nov 30, 2024 10:25 pm
by Jakala
Hi guys and, again, thank you for all your help.

The problem was I was using a 24bit (#Blue), when what is needed is an Alpha (32bit) value

Code: Select all

#Clear = 0

Procedure ColorRGBA(Clr.I, Alp.I)
  Clr24.q = Clr
  Clr32   = Clr24 | Alp << 24
  ProcedureReturn clr32
 EndProcedure
 
 Procedure RoundBox_Draw(Left, Top, Width, Height)
  Rnd = Height / 2
  Wd  = 6
  Clr = ColorRGBA(#Blue, 255)
  Id = 0
  
  If CreateImage(Id, Width, Height, 32); 32 bit Depth
    If StartDrawing(ImgeOutput(Id))
      DrawingMode(#PB_2DDrawing_AlphaBlend | #PB_2DDrawing_AllChannels)
      Box(0, 0, Width, Height, Clear) ; Fully transparent background
      RoundBox(0, 0, Width, Height, Rnd, Rnd, Clr); Solid blue round box
      RoundBox(Wd, Wd, Width - (Wd * 2), Height - (Wd * 2), Rnd, Rnd, Clear) ; Clear inner box
      StopDrawing()
      ImageGadget(#Id, Left, Top, Width, Height, ImageId(Id))
    EndIf
  EndIf
EndProcedure
Will draw Roundbox, transparent hole in middle