; Module/File: Window_BackgroundCairo_Demo+.pb ; Function: Window background with Cairo: Pic, scaled, repeated, paintings, clipping - Linux gtk2/gtk3.22+ ; Author: Shardiks example: http://www.purebasic.fr/english/viewtopic.php?f=15&t=64417&start=0, captured by Omi  ; Date: Jun. 17, 2018 ; Version: 0.3; Update for new Layout in PB5.46+ and newer gtk3 ; Target Compiler: PureBasic 5.42/5.46/5.62/5.7 ; Target OS: Linux: (X/K/L)ubuntu, Mint, 32/64, Ascii/Uni ; Link to topic: http://www.purebasic.fr/english/viewtopic.php?f=15&t=64417 ;-------------------------------------------------------------- ; added workaround for setting background color in gtk3.22+ EnableExplicit ImportC "" gtk_css_provider_load_from_data(*css_provider, data_.p-utf8, length, *error.GError) gtk_style_context_add_provider(*context, *provider, priority) gtk_widget_get_style_context(*widget.GtkWidget) CompilerIf Subsystem("gtk2") gdk_cairo_create(*Drawable.GdkDrawable) CompilerElse gtk_css_provider_new() CompilerEndIf cairo_arc(*CairoContext, xc.d, yc.d, radius.d, angle1.d, angle2.d) cairo_clip(*CairoContext) cairo_new_path(*CairoContext) cairo_scale(*CairoContext, sx.d, sy.d) cairo_destroy(*CairoContext) cairo_fill(*CairoContext) cairo_get_source(*CairoContext) cairo_image_surface_create_from_png(Filename.P-UTF8) cairo_move_to(*cairoT, x.d, y.d) cairo_line_to(*cairoT, x.d, y.d) cairo_stroke(*cairoT) cairo_paint(*CairoContext) cairo_pattern_create_for_surface(*CairoSurface) cairo_pattern_destroy(*CairoPattern) cairo_pattern_set_extend(*CairoPattern, Extend.I) cairo_rectangle(*CairoContext, x.d, y.d, Width.d, Height.d) cairo_set_line_width(*cairoT, width.d) cairo_set_source(*CairoContext, *CairoPattern) cairo_set_source_rgba(*cairoT, red.d, green.d, blue.d, alpha.d) cairo_set_source_surface(*CairoContext, *CairoSurface, x.d, y.d) cairo_surface_destroy(*CairoSurface) cairo_image_surface_get_height(*CairoSurface) cairo_image_surface_get_width(*CairoSurface) cairo_pattern_create_linear(x0.d, y0.d, x1.d, y1.d) cairo_pattern_create_radial(cx0.d, cy0.d, radius0.d, cx1.d, cy1.d, radius1.d) cairo_pattern_add_color_stop_rgba(*CairoPattern, offset.d, red.d, green.d, blue.d, alpha.d) EndImport ; Object constants #Win_Main= 0 Enumeration #But1 #But2 #But3 #But4 #But5 #But6 EndEnumeration Enumeration cairo_extend_t #CAIRO_EXTEND_NONE #CAIRO_EXTEND_REPEAT #CAIRO_EXTEND_REFLECT #CAIRO_EXTEND_PAD EndEnumeration EnumerationBinary MyPic #PicCenter #PicScale #PicRepeat #PicDrawLines #PicDrawBall #PicClip = 128 EndEnumeration #GTK_STYLE_PROVIDER_PRIORITY_USER= 800 CompilerIf #PB_Compiler_Version > 545 CompilerIf Subsystem("gtk2") = #False #ContainerMain= "GtkLayout" CompilerElse #ContainerMain= "GtkFixed" CompilerEndIf CompilerElse #ContainerMain= "GtkFixed" CompilerEndIf Global.i gPattern, gPattern2 Global.i gSurface Global.i gBackgroundType, gClip Global *gProvider CompilerIf Subsystem("gtk2") CompilerElse Procedure Window_SetCssBackColor(Window, PBColor); PB color desired -> please convert yourself ;-) Protected.s Color = "#" + RSet(Hex(Red(PBColor)), 2, "0") + RSet(Hex(Green(PBColor)), 2, "0") + RSet(Hex(Blue(PBColor)), 2, "0") Protected.s WinBkGndCSS= "window.background { background-color: " + Color + ";" + #LF$ + "}" gtk_css_provider_load_from_data(*gProvider, WinBkGndCSS, -1, #Null) gtk_style_context_add_provider(gtk_widget_get_style_context(WindowID(Window)), *gProvider, #GTK_STYLE_PROVIDER_PRIORITY_USER) EndProcedure CompilerEndIf CompilerIf Subsystem("gtk2") ProcedureC WidgetExposeHandler(*Widget.GtkWidget, *Event.GdkEventExpose, UserData) Protected CairoContext.I CairoContext = gdk_cairo_create(*Widget\window) CompilerElse ProcedureC WidgetDrawHandler(*Widget.GtkWidget, CairoContext.I, UserData) CompilerEndIf Protected.i I If gBackgroundType & #PicClip ;for e.g. additional round clipping, activate this ... cairo_arc(CairoContext, WindowWidth(UserData)/2, WindowHeight(UserData)/2, WindowWidth(UserData)/3, 0, 2*#PI) cairo_clip(CairoContext) cairo_new_path(CairoContext); /* path not consumed by clip()*/ EndIf If gBackgroundType & #PicCenter ;center the pic and show it ... cairo_set_source_surface(CairoContext, gSurface, WindowWidth(UserData)/2 - cairo_image_surface_get_width(gSurface), WindowHeight(UserData)/2 - cairo_image_surface_get_height(gSurface)) cairo_paint(CairoContext) EndIf If gBackgroundType & #PicScale ;scale the pic and show it ... cairo_scale(CairoContext, WindowWidth(UserData)/cairo_image_surface_get_width(gSurface), WindowHeight(UserData)/cairo_image_surface_get_height(gSurface)) cairo_set_source_surface(CairoContext, gSurface, 0, 0) cairo_paint(CairoContext) EndIf If gBackgroundType & #PicRepeat ;repeat the pic and show it ... cairo_set_source(CairoContext, gPattern) cairo_pattern_set_extend(cairo_get_source(CairoContext), #CAIRO_EXTEND_REPEAT) cairo_rectangle(CairoContext, 10, 10, WindowWidth(UserData) - 20, WindowHeight(UserData) - 20) cairo_fill(CairoContext) EndIf If gBackgroundType & #PicDrawLines ;or draw lines instead ... cairo_set_source_rgba(CairoContext, 0.7, 0.7, 0.7, 1) For I= 20 To WindowHeight(UserData) Step 20 cairo_move_to (CairoContext, 10, I) cairo_line_to (CairoContext, WindowWidth(UserData)- 10, I) Next I cairo_set_line_width(CairoContext, 1.0) cairo_stroke(CairoContext) EndIf If gBackgroundType & #PicDrawBall ;or a ball? the background with lin. gradient ... gPattern2= cairo_pattern_create_linear(0.0, 0.0, 0.5, WindowHeight(UserData)) cairo_pattern_add_color_stop_rgba(gPattern2, 0.2, 1.0, 1.0, 1.0, 0.8) cairo_pattern_add_color_stop_rgba(gPattern2, 0.8, 0.8, 0.8, 1.0, 1) cairo_rectangle(CairoContext, 0, 0, WindowWidth(UserData), WindowHeight(UserData)) cairo_set_source (CairoContext, gPattern2) cairo_fill(CairoContext) ;and the ball with rad. gradient ... gPattern2= cairo_pattern_create_radial(WindowWidth(UserData)/2+24, WindowHeight(UserData)/2-24, WindowWidth(UserData)/24, WindowWidth(UserData)/2-15, WindowHeight(UserData)/2-15, 128.0) cairo_pattern_add_color_stop_rgba(gPattern2, 0, 1.0, 1.0, 1.0, 1) cairo_pattern_add_color_stop_rgba(gPattern2, 1, 0.5, 0.5, 0.5, 1) cairo_set_source(CairoContext, gPattern2) cairo_arc(CairoContext, WindowWidth(UserData)/2, WindowHeight(UserData)/2, WindowWidth(UserData)/6, 0, 2 * #PI) cairo_fill(CairoContext) cairo_pattern_destroy(gPattern2) EndIf CompilerIf Subsystem("gtk2") = #True cairo_destroy(CairoContext) CompilerEndIf EndProcedure Procedure.i GetContainer(WindowID.i, ContainerName.s) Protected.i Widget= WindowID(WindowID) Protected.i Child = gtk_bin_get_child_(Widget), *List.GList Repeat *List= gtk_container_get_children_(Widget) Child= g_list_nth_data_(*List, 0) If Child = 0 Break Else Widget= Child EndIf Until PeekS(gtk_widget_get_name_(Child), -1, #PB_UTF8) = ContainerName ProcedureReturn Child EndProcedure Procedure Create_Window(BackgroundFile.s) OpenWindow(#Win_Main, 140, 100, 550, 530, "Window w. transp. CSS background (.png/drawing+clip)", #PB_Window_SizeGadget) CompilerIf #ContainerMain= "GtkFixed";Subsystem("gtk2") SetWindowColor(#Win_Main, $EFFFFF); doesn't work in gtk3 -> workaround: CompilerElse *gProvider= gtk_css_provider_new() Window_SetCssBackColor(#Win_Main, $EFFFFF); PB > 5.46: HEX value (#rrggbb) or all named CSS colors useable like "beige" as string CompilerEndIf OptionGadget (#But1, 10, 20, 140, 25, "Pic centered") OptionGadget (#But2, 10, 50, 140, 25, "Pic scaled") OptionGadget (#But3, 10, 80, 140, 25, "Pic repeated") OptionGadget (#But4, 10, 110, 140, 25, "Lines") OptionGadget (#But5, 10, 140, 140, 25, "Ball") CheckBoxGadget(#But6, 10, 170, 140, 26, "Round clipping") gSurface= cairo_image_surface_create_from_png(BackgroundFile) gPattern= cairo_pattern_create_for_surface(gSurface) CompilerIf Subsystem("gtk2") g_signal_connect_(GetContainer(#Win_Main, #ContainerMain), "expose-event", @WidgetExposeHandler(), #Win_Main); #Win_Main as UserData CompilerElse g_signal_connect_(GetContainer(#Win_Main, #ContainerMain), "draw", @WidgetDrawHandler(), #Win_Main); #Win_Main as UserData CompilerEndIf ; Force initial drawing of window gtk_widget_queue_draw_(WindowID(#Win_Main)) EndProcedure gBackgroundType= #PicCenter; #PicScale | #PicRepeat | #PicDrawLines | #PicDrawBall & #PicClip Create_Window(#PB_Compiler_Home + "./logo.png") Repeat Select WaitWindowEvent() Case #PB_Event_CloseWindow cairo_pattern_destroy(gPattern) cairo_surface_destroy(gSurface) Break Case #PB_Event_Gadget If GetGadgetState(#But6) gClip= #PicClip Else gClip= 0 EndIf Select EventGadget() Case #But1 gBackgroundType= #PicCenter | gClip gtk_widget_queue_draw_(WindowID(#Win_Main)) Case #But2 gBackgroundType= #PicScale | gClip gtk_widget_queue_draw_(WindowID(#Win_Main)) Case #But3 gBackgroundType= #PicRepeat | gClip gtk_widget_queue_draw_(WindowID(#Win_Main)) Case #But4 gBackgroundType= #PicDrawLines | gClip gtk_widget_queue_draw_(WindowID(#Win_Main)) Case #But5 gBackgroundType= #PicDrawBall | gClip gtk_widget_queue_draw_(WindowID(#Win_Main)) Case #But6 gBackgroundType= (gBackgroundType & $7F) | gClip gtk_widget_queue_draw_(WindowID(#Win_Main)) EndSelect EndSelect ForEver ; IDE Options = PureBasic 5.70 LTS beta 3 (Linux - x64) ; CursorPosition = 5 ; Folding = --- ; EnableXP ; EnableUnicode