Page 2 of 2

Re: Transparent window in linux

Posted: Sun Dec 09, 2018 8:16 am
by Oma
Hi vwidmer,
since I included shardik's useful example in the Linux API library, I took the liberty of modifying it to change the output text via a timer event. I hope he forgives me :wink: .
I packed the necessary data into a structure, which is passed to the WidgetDrawHandler(*Widget.GtkWidget, CairoContext.I, *UserData.HUDWIN) as parameter *UserData, -> @HUD_Data.
By the structure field HUD_Data\Window with the PB-WindowNo the WidgetDrawHandler() can work window independent.
With the timer event only the structure content must be updated and WidgetDrawHandler(Window, 0, @HUD_Data) must be called manually. (Tested with PB 5.62 + PB5.70B3 for gtk3)

Code: Select all

;from shardiks example
EnableExplicit

#CAIRO_OPERATOR_SOURCE = 1

ImportC ""
	gdk_cairo_create(*Drawable.GdkDrawable)
	gtk_widget_get_window(*Widget.GtkWidget)
	gtk_widget_is_composited(*Widget.GtkWidget)
EndImport

ImportC "-lcairo"
	cairo_paint(*CairoContext)
	cairo_set_operator(*CairoContext, CairoOperator.I)
	cairo_set_source_rgba(*CairoContext, Red.D, Green.D, Blue.D, Alpha.D)
EndImport

ImportC ""
	gdk_screen_get_rgba_visual(*Screen.GdkScreen)
	gdk_screen_get_system_visual(*Screen.GdkScreen)
	gtk_widget_set_visual(*Vidget.GtkWidget, *Visual.GdkVisual)
EndImport

; Object constants
;Window ...
#Win_Main  = 0
;Gadgets ...
#ImgGdgt   = 0

Define Container.I
Define Screen.I
Define Visual.I
Define Window.I

Structure HUDWIN
	Window.i
	Counter.i
	RumourBasic.s
	Rumour.s
	Exit.s
EndStructure
Global HUD_Data.HUDWIN
With HUD_Data
	\Counter    = 0
	\RumourBasic= "Text in HUD window"
	\Rumour     = \RumourBasic
	\Exit       = "<Esc> to close"
EndWith

ProcedureC WidgetDrawHandler(*Widget.GtkWidget, CairoContext.I, *UserData.HUDWIN)
	CairoContext = gdk_cairo_create(gtk_widget_get_window(*Widget))
	cairo_set_source_rgba(CairoContext, 1, 1, 1, 0)
	cairo_set_operator(CairoContext, #CAIRO_OPERATOR_SOURCE)
	cairo_paint(CairoContext)
	
	If StartDrawing(WindowOutput(HUD_Data\Window))
		; ----- Draw frame of HUD
		DrawingMode(#PB_2DDrawing_Default)
		Line(1, 1, WindowWidth(HUD_Data\Window), 1, $FF)
		Line(1, 2, WindowWidth(HUD_Data\Window), 1, $FF)
		Line(1, WindowHeight(HUD_Data\Window), WindowWidth(HUD_Data\Window), 1, $FF)
		Line(1, WindowHeight(HUD_Data\Window) - 1, WindowWidth(HUD_Data\Window), 1, $FF)
		Line(1, 1, 1, WindowHeight(HUD_Data\Window), $FF)
		Line(2, 1, 1, WindowHeight(HUD_Data\Window), $FF)
		Line(WindowWidth(HUD_Data\Window), 1, 1, WindowHeight(HUD_Data\Window) - 1, $FF)
		Line(WindowWidth(HUD_Data\Window) - 1, 1, 1, WindowHeight(HUD_Data\Window) - 2, $FF)
		
		; ----- Draw text into HUD window
		DrawingMode(#PB_2DDrawing_Transparent)
		DrawText((WindowWidth(HUD_Data\Window) - TextWidth(*UserData\Rumour)) / 2, 26, *UserData\Rumour, $FF0000)
		DrawText(48, 53, *UserData\Exit, $FF)
		StopDrawing()
	EndIf
EndProcedure

CreateImage(#ImgGdgt, 220, 100, 32, #PB_Image_Transparent)
Window = OpenWindow(#Win_Main, 200, 150, ImageWidth(#ImgGdgt), ImageHeight(#ImgGdgt), "HUD window", #PB_Window_Invisible)

HUD_Data\Window= #Win_Main

If gtk_widget_is_composited(WindowID(#Win_Main)) = #False
	MessageRequester("Error", "Sorry, but transparency is not supported on this system!")
	End
EndIf

; ----- Disable visibility of window frame
; gtk_window_set_decorated_(Window, #False)

; ----- Enable modification of window colors
gtk_widget_set_app_paintable_(Window, #True)

ImageGadget(#ImgGdgt, 0, 0, ImageWidth(#ImgGdgt), ImageHeight(#ImgGdgt), ImageID(#ImgGdgt))

; ----- Delete GdkWindow resources to be able to change colormap
gtk_widget_unrealize_(Window)

; ----- Get window's child container
Container = g_list_nth_data_(gtk_container_get_children_(gtk_bin_get_child_(WindowID(#Win_Main))), 0)

g_signal_connect_(GadgetID(#ImgGdgt), "draw", @WidgetDrawHandler(), @HUD_Data)
Screen = gtk_widget_get_screen_(Window)
Visual = gdk_screen_get_rgba_visual(Screen)

If Visual = 0
	Visual = gdk_screen_get_system_visual(Screen)
EndIf

gtk_widget_set_visual(Window, Visual)

; ----- Realize window and rebuild new GdkWindow
HideWindow(#Win_Main, #False)

; ----- Define <Esc> key to close splash window
AddKeyboardShortcut(#Win_Main, #PB_Shortcut_Escape, 0)

AddWindowTimer(#Win_Main, 999, 1000)

Repeat
	Select WaitWindowEvent()
		Case #PB_Event_CloseWindow
			Break
		Case #PB_Event_Menu
			If EventMenu() = 0
				Break
			EndIf
		Case #PB_Event_Timer
			HUD_Data\Counter+ 1
			HUD_Data\Rumour= HUD_Data\RumourBasic + " " + Str(HUD_Data\Counter)
    	WidgetDrawHandler(Window, #Null, @HUD_Data)
	EndSelect
ForEver
Regards, Charly

Re: Transparent window in linux

Posted: Sun Dec 09, 2018 10:18 pm
by Shardik
vwidmer wrote:I am trying the example with the text but I cant get it to change correctly it just keeps drawing on top of it self. I am not clear on what you mean by "define the text in this procedure dynamically using a Shared string variable"
Thank you Charly for the sophisticated extention of my example. Nevertheless I also want to demonstrate what I proposed by using a Shared string variable although Charly's approach is more flexible and therefore should be preferred... :wink:

In my modified example I added the declaration of the new string variable HUDText and in the procedure WidgetDrawHandler() I also added the definition of the Shared string variable HUDText (of course I also could have declared HUDText as global but global variables should be avoided). Now in the procedure WidgetDrawHandler() the content of HUDText is parsed (the 2 lines are separated by a linefeed) by StringField() and displayed. I have also used a timer like Charly. This timer counts down from 10 to 0, the remaining seconds are displayed in the HUD window and when reaching 0 the HUD window is closed (alternatives for immediate closing are pressing the escape key or closing the HUD window with the x-button in the title line).

In order to change the displayed HUD text, you have to call WidgetDrawHandler() by yourself after changing the content of HUDText with

Code: Select all

WidgetDrawHandler(Window, 0, 0)

Code: Select all

EnableExplicit

#CAIRO_OPERATOR_SOURCE = 1

ImportC ""
  gdk_cairo_create(*Drawable.GdkDrawable)
  gtk_widget_get_window(*Widget.GtkWidget)
  gtk_widget_is_composited(*Widget.GtkWidget)
EndImport

ImportC "-lcairo"
  cairo_paint(*CairoContext)
  cairo_set_operator(*CairoContext, CairoOperator.I)
  cairo_set_source_rgba(*CairoContext, Red.D, Green.D, Blue.D, Alpha.D)
EndImport

ImportC ""
  gdk_screen_get_rgba_visual(*Screen.GdkScreen)
  gdk_screen_get_system_visual(*Screen.GdkScreen)
  gtk_widget_set_visual(*Vidget.GtkWidget, *Visual.GdkVisual)
EndImport

Define Container.I
Define CountDownSeconds.I
Define HUDText.S
Define Screen.I
Define Visual.I
Define Window.I

ProcedureC WidgetDrawHandler(*Widget.GtkWidget, CairoContext.I, *UserData)
  Shared HUDText.S

  CairoContext = gdk_cairo_create(gtk_widget_get_window(*Widget))
  cairo_set_source_rgba(CairoContext, 1, 1, 1, 0)
  cairo_set_operator(CairoContext, #CAIRO_OPERATOR_SOURCE)
  cairo_paint(CairoContext)

  If StartDrawing(WindowOutput(0))
    ; ----- Draw frame of HUD
    DrawingMode(#PB_2DDrawing_Default)
    Line(1, 1, WindowWidth(0), 1, $FF)
    Line(1, 2, WindowWidth(0), 1, $FF)
    Line(1, WindowHeight(0), WindowWidth(0), 1, $FF)
    Line(1, WindowHeight(0) - 1, WindowWidth(0), 1, $FF)
    Line(1, 1, 1, WindowHeight(0), $FF)
    Line(2, 1, 1, WindowHeight(0), $FF)
    Line(WindowWidth(0), 1, 1, WindowHeight(0) - 1, $FF)
    Line(WindowWidth(0) - 1, 1, 1, WindowHeight(0) - 2, $FF)

    ; ----- Draw text into HUD window
    DrawingMode(#PB_2DDrawing_Transparent)
    DrawText(10, 26, StringField(HUDText, 1, #LF$), $FF0000)
    DrawText(32, 53, StringField(HUDText, 2, #LF$), $FF)
    StopDrawing()
  EndIf
EndProcedure

CreateImage(0, 240, 100, 32, #PB_Image_Transparent)
Window = OpenWindow(0, 500, 150, ImageWidth(0), ImageHeight(0),
  "HUD window", #PB_Window_Invisible)

If gtk_widget_is_composited(WindowID(0)) = #False
  MessageRequester("Error",
    "Sorry, but transparency is not supported on this system!")
  End
EndIf

; ----- Disable visibility of window frame
; gtk_window_set_decorated_(Window, #False)

; ----- Enable modification of window colors
gtk_widget_set_app_paintable_(Window, #True)

ImageGadget(0, 0, 0, ImageWidth(0), ImageHeight(0), ImageID(0))

; ----- Delete GdkWindow resources to be able to change colormap
gtk_widget_unrealize_(Window)

; ----- Get window's child container
Container = g_list_nth_data_(gtk_container_get_children_(0 +
  gtk_bin_get_child_(WindowID(0))), 0)

g_signal_connect_(GadgetID(0), "draw", @WidgetDrawHandler(), 0)
Screen = gtk_widget_get_screen_(Window)
Visual = gdk_screen_get_rgba_visual(Screen)
   
If Visual = 0
  Visual = gdk_screen_get_system_visual(Screen)
EndIf

gtk_widget_set_visual(Window, Visual)

; ----- Realize window and rebuild new GdkWindow
HideWindow(0, #False)

; ----- Define <Esc> key to close splash window
AddKeyboardShortcut(0, #PB_Shortcut_Escape, 0)

; ----- Set timer for countdown
CountDownSeconds = 10
AddWindowTimer(0, 0, 1000)

; ----- Set HUD text
HUDText = "Closing HUD in " + Str(CountDownSeconds) + " seconds" +
  #LF$ + "<Esc> To close now"

Repeat
  Select WaitWindowEvent()
    Case #PB_Event_CloseWindow
      Break
    Case #PB_Event_Menu
      If EventMenu() = 0
        Break
      EndIf
    Case #PB_Event_Timer
      CountDownSeconds - 1

      If CountDownSeconds = 0
        CloseWindow(0)
        Break
      Else
        HUDText = "Closing HUD in " + Str(CountDownSeconds) + " seconds" +
          #LF$ + "<Esc> to close now"
        WidgetDrawHandler(Window, 0, 0)
      EndIf
  EndSelect
ForEver

Re: Transparent window in linux

Posted: Mon Dec 10, 2018 5:23 pm
by vwidmer
Thanks for the examples.. you guys are awesome thanks again.

Re: Transparent window in linux

Posted: Tue Dec 11, 2018 2:35 am
by vwidmer
Is there a setting or way to make the transparency click through?

like now if u click somewhere in the transparent area it doesnt click whats under it.

Thanks

Re: Transparent window in linux

Posted: Tue Dec 11, 2018 8:14 pm
by ccode
vwidmer wrote:Is there a setting or way to make the transparency click through?

like now if u click somewhere in the transparent area it doesnt click whats under it.
How do you mean ?

A click event in the window works in the transparent area (of the image). (Or does not work?)
All you have to do is paint your GUI elements on the image and get the coordinates.
Or what do you want to achieve?

Re: Transparent window in linux

Posted: Thu Dec 13, 2018 12:50 am
by vwidmer
Sorry for not being clear.

What I mean is lets say is if I have the transparent window say over the [X] (for closing a window) of another window and I click in the transparent area I it selects the transparent app it does not click through to the window [X] under it.

I dont know the correct term but yes the window is transparent but its still there.

thanks

Re: Transparent window in linux

Posted: Sat Dec 15, 2018 6:55 am
by Oma
The transparency concerns only the display, the window area (and thus the action area) remains unaffected by this rectangular and on top.
I don't know any commands and haven't yet seen a simple procedure that forwards actions such as mouse clicks on transparent parts to underlying objects.
I don't mean to say it's not possible, but I could only do it in an extremely complex way.

Regards, Charly