|
Post by vovchik on Dec 3, 2020 15:32:04 GMT 1
Dear all,
This is a little demo that creates a gtk2 or gtk3 tray app. It monitors the status of a file in tmp and changes the icon accordingly (right or left click). I ported some c code, modded it to accept inline svgs and am pleased that it seems to work.
PRAGMA OPTIONS `pkg-config --cflags gtk+-2.0` PRAGMA LDFLAGS `pkg-config --libs gtk+-2.0` PRAGMA INCLUDE <gtk-2.0/gtk/gtk.h>
' for gtk3, comment out the lines above and uncomment next PRAGMA lines 'PRAGMA OPTIONS `pkg-config --cflags gtk+-3.0` 'PRAGMA LDFLAGS `pkg-config --libs gtk+-3.0` 'PRAGMA INCLUDE <gtk-3.0/gtk/gtk.h> '' next line needed to avoid gtk3 deprecation warnings 'PRAGMA OPTIONS -Wno-deprecated-declarations
OPTION PARSE FALSE
DECLARE ball_orange$, ball_green$, status_file$ TYPE STRING DECLARE pixbuf_orange, pixbuf_green TYPE GdkPixbuf* DECLARE tray_icon TYPE GtkStatusIcon* DECLARE interval TYPE unsigned int interval = 3000 status_file$ = "/tmp/demotray.txt"
ALIAS gtk_init TO GTK_INIT ALIAS gtk_main TO GTK_MAIN
ball_orange$ = "<svg width='24' height='24' viewBox='0 0 84 84'>" \ " <radialGradient id='g1' cx='50%' cy='50%' " \ " r='50%' fx='25%' fy='25%'>" \ " <stop stop-color='orange' offset='0%'/>" \ " <stop stop-color='gray' offset='100%'/>" \ " </radialGradient>" \ " <g stroke='orange' stroke-width='3' stroke-opacity='0.9'>" \ " <circle fill='url(#g1)' cx='42' cy='42' r='40'/>" \ " <circle fill='url(#g1)' cx='42' cy='42' r='12'/>" \ " <circle fill='url(#g1)' cx='42' cy='42' r='4'/>" \ " </g>" \ "</svg>"
ball_green$ = REPLACE$(ball_orange$, "orange", "lawngreen")
' ------------------ FUNCTION SVG_BUFF(STRING svg$) TYPE GdkPixbuf* ' ------------------ LOCAL pixloader TYPE GdkPixbufLoader* LOCAL pixbuf TYPE GdkPixbuf* LOCAL size TYPE NUMBER LOCAL res TYPE int LOCAL raw_array TYPE unsigned char* size = LEN(svg$) raw_array = (unsigned char*)svg$ pixloader = gdk_pixbuf_loader_new() res = gdk_pixbuf_loader_write(pixloader, raw_array, size, 0) res = gdk_pixbuf_loader_close(pixloader, 0) pixbuf = gdk_pixbuf_loader_get_pixbuf(pixloader) RETURN pixbuf END FUNCTION
' ------------------ FUNCTION CHECK_STATUS() ' ------------------ ' State switcher - this does all the work ... IF FILEEXISTS(status_file$) THEN gtk_status_icon_set_from_pixbuf(tray_icon, pixbuf_green) gtk_status_icon_set_tooltip_text(tray_icon, "Status file exists.") ELSE gtk_status_icon_set_from_pixbuf(tray_icon, pixbuf_orange) gtk_status_icon_set_tooltip_text(tray_icon, "Status file is missing.") END IF RETURN TRUE END FUNCTION
' ------------------ SUB ON_LEFT_CLICK(GtkStatusIcon *status_icon, gpointer user_data) ' ------------------ IF FILEEXISTS(status_file$) THEN DELETE FILE status_file$ END IF END SUB
' ------------------ SUB ON_RIGHT_CLICK(GtkStatusIcon* status_icon, guint button, guint activate_time, gpointer user_data) ' ------------------ SAVE "" TO status_file$ ' Or .. you could just have: ' gtk_main_quit() END SUB
' ------------------ FUNCTION MK_TRAY_ICON() TYPE GtkStatusIcon* ' ------------------ tray_icon = gtk_status_icon_new() pixbuf_green = SVG_BUFF(ball_green$) pixbuf_orange = SVG_BUFF(ball_orange$) ' Connect handler functions to signals from X g_signal_connect(G_OBJECT(tray_icon), "activate", G_CALLBACK(ON_LEFT_CLICK), NULL) g_signal_connect(G_OBJECT(tray_icon), "popup-menu", G_CALLBACK(ON_RIGHT_CLICK), NULL) gtk_status_icon_set_tooltip_text(tray_icon, "Demo tray app") gtk_status_icon_set_visible(tray_icon, TRUE) RETURN tray_icon END FUNCTION
GTK_INIT(0, 0) tray_icon = MK_TRAY_ICON() g_timeout_add(interval, (GSourceFunc)CHECK_STATUS, NULL) GTK_MAIN()
With kind regards, vovchik
|
|
|
Post by bigbass on Dec 3, 2020 18:05:18 GMT 1
Hello vovchik
I like how you put events on the icon the left and right click with the added svg's! A nice demo for the gtk2 gtk3 collection
I don't have gtk2 installed at the moment so I used your gtk3 option I added some bassix macros so that you can see they are universal outside of bassix also
thanks again Joe
'PRAGMA OPTIONS `pkg-config --cflags gtk+-2.0` 'PRAGMA LDFLAGS `pkg-config --libs gtk+-2.0` 'PRAGMA INCLUDE <gtk-2.0/gtk/gtk.h>
' for gtk3, comment out the lines above and uncomment next PRAGMA lines PRAGMA OPTIONS `pkg-config --cflags gtk+-3.0` PRAGMA LDFLAGS `pkg-config --libs gtk+-3.0` PRAGMA INCLUDE <gtk-3.0/gtk/gtk.h> ' next line needed to avoid gtk3 deprecation warnings PRAGMA OPTIONS -Wno-deprecated-declarations
OPTION PARSE FALSE
'--- some bassix macros DEF FN CONNECT( widget, event,cb) = g_signal_connect_data(GTK_WIDGET(widget),event,G_CALLBACK (cb), 0, 0, 0) DEF FN CONNECT_DATA( widget, event,cb,t) = g_signal_connect_data(G_OBJECT (widget),event,G_CALLBACK (cb),(gpointer) t, 0, 0) DEF FN TIMEOUT_ADD(n,cb) = g_timeout_add(n,(GSourceFunc) cb, NULL) DEF FN REMOVE_TIMEOUT(id) = g_source_remove(id)
DECLARE ball_orange$, ball_green$, status_file$ TYPE STRING DECLARE pixbuf_orange, pixbuf_green TYPE GdkPixbuf* DECLARE tray_icon TYPE GtkStatusIcon* DECLARE interval TYPE unsigned int '---interval = 3000 status_file$ = "/tmp/demotray.txt"
ALIAS gtk_init TO GTK_INIT ALIAS gtk_main TO GTK_MAIN
ball_orange$ = "<svg width='24' height='24' viewBox='0 0 84 84'>" \ " <radialGradient id='g1' cx='50%' cy='50%' " \ " r='50%' fx='25%' fy='25%'>" \ " <stop stop-color='orange' offset='0%'/>" \ " <stop stop-color='gray' offset='100%'/>" \ " </radialGradient>" \ " <g stroke='orange' stroke-width='3' stroke-opacity='0.9'>" \ " <circle fill='url(#g1)' cx='42' cy='42' r='40'/>" \ " <circle fill='url(#g1)' cx='42' cy='42' r='12'/>" \ " <circle fill='url(#g1)' cx='42' cy='42' r='4'/>" \ " </g>" \ "</svg>"
ball_green$ = REPLACE$(ball_orange$, "orange", "lawngreen")
' ------------------ FUNCTION SVG_BUFF(STRING svg$) TYPE GdkPixbuf* ' ------------------ LOCAL pixloader TYPE GdkPixbufLoader* LOCAL pixbuf TYPE GdkPixbuf* LOCAL size TYPE NUMBER LOCAL res TYPE int LOCAL raw_array TYPE unsigned char* size = LEN(svg$) raw_array = (unsigned char*)svg$ pixloader = gdk_pixbuf_loader_new() res = gdk_pixbuf_loader_write(pixloader, raw_array, size, 0) res = gdk_pixbuf_loader_close(pixloader, 0) pixbuf = gdk_pixbuf_loader_get_pixbuf(pixloader) RETURN pixbuf END FUNCTION
' ------------------ FUNCTION CHECK_STATUS() ' ------------------ ' State switcher - this does all the work ... IF FILEEXISTS(status_file$) THEN gtk_status_icon_set_from_pixbuf(tray_icon, pixbuf_green) gtk_status_icon_set_tooltip_text(tray_icon, "Status file exists.") ELSE gtk_status_icon_set_from_pixbuf(tray_icon, pixbuf_orange) gtk_status_icon_set_tooltip_text(tray_icon, "Status file is missing.") END IF RETURN TRUE END FUNCTION
' ------------------ SUB ON_LEFT_CLICK(GtkStatusIcon *status_icon, gpointer user_data) ' ------------------ IF FILEEXISTS(status_file$) THEN DELETE FILE status_file$ END IF END SUB
' ------------------ SUB ON_RIGHT_CLICK(GtkStatusIcon* status_icon, guint button, guint activate_time, gpointer user_data) ' ------------------ SAVE "" TO status_file$ ' Or .. you could just have: ' gtk_main_quit() END SUB
' ------------------ FUNCTION MK_TRAY_ICON() TYPE GtkStatusIcon* ' ------------------ tray_icon = gtk_status_icon_new() pixbuf_green = SVG_BUFF(ball_green$) pixbuf_orange = SVG_BUFF(ball_orange$) ' Connect handler functions to signals from X '---g_signal_connect(G_OBJECT(tray_icon), "activate", G_CALLBACK(ON_LEFT_CLICK), NULL) CONNECT_DATA(tray_icon,"activate",ON_LEFT_CLICK,NULL) '--- g_signal_connect(G_OBJECT(tray_icon), "popup-menu", G_CALLBACK(ON_RIGHT_CLICK), NULL) CONNECT_DATA(tray_icon,"popup-menu",ON_RIGHT_CLICK,NULL) gtk_status_icon_set_tooltip_text(tray_icon, "Demo tray app") gtk_status_icon_set_visible(tray_icon, TRUE) RETURN tray_icon END FUNCTION
GTK_INIT(0, 0) tray_icon = MK_TRAY_ICON() '---g_timeout_add(interval, (GSourceFunc)CHECK_STATUS, NULL)
TIMEOUT_ADD(1000,CHECK_STATUS)
GTK_MAIN()
|
|
|
Post by vovchik on Dec 3, 2020 19:54:32 GMT 1
Dear Joe,
Thanks. I prefer your version with the macros. It looks much neater/cleaner.
With kind regards, vovchik
|
|
|
Post by bigbass on Dec 3, 2020 20:10:16 GMT 1
Hello vovchik
thanks for your code demo it was fun experimenting with It got me thinking to add some macros to bassix that were missing
I looked at SET and GET but they work only for widgets
here are a few more following your code exactly only adding some of the macros
thanks for posting the demo
Joe
'PRAGMA OPTIONS `pkg-config --cflags gtk+-2.0` 'PRAGMA LDFLAGS `pkg-config --libs gtk+-2.0` 'PRAGMA INCLUDE <gtk-2.0/gtk/gtk.h>
' for gtk3, comment out the lines above and uncomment next PRAGMA lines PRAGMA OPTIONS `pkg-config --cflags gtk+-3.0` PRAGMA LDFLAGS `pkg-config --libs gtk+-3.0` PRAGMA INCLUDE <gtk-3.0/gtk/gtk.h> ' next line needed to avoid gtk3 deprecation warnings PRAGMA OPTIONS -Wno-deprecated-declarations
OPTION PARSE FALSE
'--- some bassix macros DEF FN CONNECT( widget, event,cb) = g_signal_connect_data(GTK_WIDGET(widget),event,G_CALLBACK (cb), 0, 0, 0) DEF FN CONNECT_DATA( widget, event,cb,t) = g_signal_connect_data(G_OBJECT (widget),event,G_CALLBACK (cb),(gpointer) t, 0, 0) DEF FN TIMEOUT_ADD(n,cb) = g_timeout_add(n,(GSourceFunc) cb, NULL) DEF FN REMOVE_TIMEOUT(id) = g_source_remove(id) DEF FN DISPLAY() = gtk_main() DEF FN INIT() = gtk_init(0,0) DEF FN STREAM(im) = g_memory_input_stream_new_from_data(im, -1, g_free) DEF FN PIXBUF_MEM(stm) = gdk_pixbuf_new_from_stream(stm, NULL, NULL) DEF FN PIXBUFF(p) = gtk_image_new_from_pixbuf(p ) DEF FN ICON_SET(t,p) = gtk_status_icon_set_from_pixbuf(t, p) DEF FN PIXLOADER_ADD() = gdk_pixbuf_loader_new() DEF FN ICON_TOOLTIP(t,p) = gtk_status_icon_set_tooltip_text(t, p) DEF FN STATUS_ICON() = gtk_status_icon_new ()
DECLARE ball_orange$, ball_green$, status_file$ TYPE STRING DECLARE pixbuf_orange, pixbuf_green TYPE GdkPixbuf* DECLARE tray_icon TYPE GtkStatusIcon* DECLARE interval TYPE unsigned int
status_file$ = "/tmp/demotray.txt"
ALIAS gtk_init TO GTK_INIT ALIAS gtk_main TO GTK_MAIN
ball_orange$ = "<svg width='24' height='24' viewBox='0 0 84 84'>" \ " <radialGradient id='g1' cx='50%' cy='50%' " \ " r='50%' fx='25%' fy='25%'>" \ " <stop stop-color='orange' offset='0%'/>" \ " <stop stop-color='gray' offset='100%'/>" \ " </radialGradient>" \ " <g stroke='orange' stroke-width='3' stroke-opacity='0.9'>" \ " <circle fill='url(#g1)' cx='42' cy='42' r='40'/>" \ " <circle fill='url(#g1)' cx='42' cy='42' r='12'/>" \ " <circle fill='url(#g1)' cx='42' cy='42' r='4'/>" \ " </g>" \ "</svg>"
ball_green$ = REPLACE$(ball_orange$, "orange", "lawngreen")
' ------------------ FUNCTION SVG_BUFF(STRING svg$) TYPE GdkPixbuf* ' ------------------ LOCAL pixloader TYPE GdkPixbufLoader* LOCAL pixbuf TYPE GdkPixbuf* LOCAL size TYPE NUMBER LOCAL res TYPE int LOCAL raw_array TYPE unsigned char* size = LEN(svg$) raw_array = (unsigned char*)svg$ pixloader = PIXLOADER_ADD() res = gdk_pixbuf_loader_write(pixloader, raw_array, size, 0) res = gdk_pixbuf_loader_close(pixloader, 0) pixbuf = gdk_pixbuf_loader_get_pixbuf(pixloader) RETURN pixbuf END FUNCTION
' ------------------ FUNCTION CHECK_STATUS() ' ------------------ ' State switcher - this does all the work ... IF FILEEXISTS(status_file$) THEN
ICON_SET(tray_icon, pixbuf_green) ICON_TOOLTIP(tray_icon, "Status file exists.") ELSE ICON_SET(tray_icon, pixbuf_orange) ICON_TOOLTIP(tray_icon, "Status file is missing.") END IF RETURN TRUE END FUNCTION
' ------------------ SUB ON_LEFT_CLICK(GtkStatusIcon *status_icon, gpointer user_data) ' ------------------ IF FILEEXISTS(status_file$) THEN DELETE FILE status_file$ END IF END SUB
' ------------------ SUB ON_RIGHT_CLICK(GtkStatusIcon* status_icon, guint button, guint activate_time, gpointer user_data) ' ------------------ SAVE "" TO status_file$ ' Or .. you could just have: ' gtk_main_quit() END SUB
' ------------------ FUNCTION MK_TRAY_ICON() TYPE GtkStatusIcon* ' ------------------ tray_icon = gtk_status_icon_new() pixbuf_green = SVG_BUFF(ball_green$) pixbuf_orange = SVG_BUFF(ball_orange$) ' Connect handler functions to signals from X CONNECT_DATA(tray_icon,"activate",ON_LEFT_CLICK,NULL) CONNECT_DATA(tray_icon,"popup-menu",ON_RIGHT_CLICK,NULL) ICON_TOOLTIP(tray_icon, "Demo tray app") gtk_status_icon_set_visible(tray_icon, TRUE) RETURN tray_icon END FUNCTION
INIT
tray_icon = MK_TRAY_ICON() TIMEOUT_ADD(1000,CHECK_STATUS)
DISPLAY
|
|
|
Post by vovchik on Dec 3, 2020 21:30:08 GMT 1
Dear Joe, Thanks, again. it is getting more bacony with each iteration. With kind regards, vovchik PS. Maybe the gdk_pixbuf_loader... stuff could also get bassixed?
|
|
|
Post by bigbass on Dec 4, 2020 0:34:34 GMT 1
Hello vovchik
I only added the macros to your code demo I hope it works on your side also was able to reduce some args on the error cast
*gtk has some long names that are difficult for me to remember
P.S I am using the latest fossil 4.3 and good news with the macro parsing
Joe
'PRAGMA OPTIONS `pkg-config --cflags gtk+-2.0` 'PRAGMA LDFLAGS `pkg-config --libs gtk+-2.0` 'PRAGMA INCLUDE <gtk-2.0/gtk/gtk.h>
' for gtk3, comment out the lines above and uncomment next PRAGMA lines PRAGMA OPTIONS `pkg-config --cflags gtk+-3.0` PRAGMA LDFLAGS `pkg-config --libs gtk+-3.0` PRAGMA INCLUDE <gtk-3.0/gtk/gtk.h> ' next line needed to avoid gtk3 deprecation warnings PRAGMA OPTIONS -Wno-deprecated-declarations
OPTION PARSE FALSE
'--- some bassix macros DEF FN CONNECT( widget, event,cb) = g_signal_connect_data(GTK_WIDGET(widget),event,G_CALLBACK (cb), 0, 0, 0) DEF FN CONNECT_DATA( widget, event,cb,t) = g_signal_connect_data(G_OBJECT (widget),event,G_CALLBACK (cb),(gpointer) t, 0, 0) DEF FN TIMEOUT_ADD(n,cb) = g_timeout_add(n,(GSourceFunc) cb, NULL) DEF FN REMOVE_TIMEOUT(id) = g_source_remove(id) DEF FN DISPLAY() = gtk_main() DEF FN INIT() = gtk_init(0,0) DEF FN STREAM(im) = g_memory_input_stream_new_from_data(im, -1, g_free) DEF FN PIXBUF_MEM(stm) = gdk_pixbuf_new_from_stream(stm, NULL, NULL) DEF FN PIXBUFF(p) = gtk_image_new_from_pixbuf(p ) DEF FN ICON_SET(t,p) = gtk_status_icon_set_from_pixbuf(t, p)
DEF FN ICON_TOOLTIP(t,p) = gtk_status_icon_set_tooltip_text(t, p) DEF FN STATUS_ICON() = gtk_status_icon_new() DEF FN ICON_VISIBLE(t,b) = gtk_status_icon_set_visible(t,b) DEF FN LOADER() = gdk_pixbuf_loader_new() DEF FN LOADER_WRITE(pl,buf,cnt) = gdk_pixbuf_loader_write(GDK_PIXBUF_LOADER(pl),buf,cnt,0) DEF FN LOADER_CLOSE(pl) = gdk_pixbuf_loader_close(GDK_PIXBUF_LOADER(pl),0) DEF FN LOADER_GET(pl) = gdk_pixbuf_loader_get_pixbuf(pl)
DECLARE ball_orange$, ball_green$, status_file$ TYPE STRING DECLARE pixbuf_orange, pixbuf_green TYPE GdkPixbuf* DECLARE tray_icon TYPE GtkStatusIcon* DECLARE interval TYPE unsigned int
status_file$ = "/tmp/demotray.txt"
ball_orange$ = "<svg width='24' height='24' viewBox='0 0 84 84'>" \ " <radialGradient id='g1' cx='50%' cy='50%' " \ " r='50%' fx='25%' fy='25%'>" \ " <stop stop-color='orange' offset='0%'/>" \ " <stop stop-color='gray' offset='100%'/>" \ " </radialGradient>" \ " <g stroke='orange' stroke-width='3' stroke-opacity='0.9'>" \ " <circle fill='url(#g1)' cx='42' cy='42' r='40'/>" \ " <circle fill='url(#g1)' cx='42' cy='42' r='12'/>" \ " <circle fill='url(#g1)' cx='42' cy='42' r='4'/>" \ " </g>" \ "</svg>"
ball_green$ = REPLACE$(ball_orange$, "orange", "lawngreen")
' ------------------ FUNCTION SVG_BUFF(STRING svg$) TYPE GdkPixbuf* ' ------------------ LOCAL pixloader TYPE GdkPixbufLoader* LOCAL pixbuf TYPE GdkPixbuf* LOCAL size TYPE NUMBER LOCAL res TYPE int LOCAL raw_array TYPE unsigned char* size = LEN(svg$) raw_array = (unsigned char*)svg$ pixloader = LOADER() res = LOADER_WRITE(pixloader, raw_array, size) res = LOADER_CLOSE(pixloader) pixbuf = LOADER_GET(pixloader) RETURN pixbuf END FUNCTION
' ------------------ FUNCTION CHECK_STATUS() ' ------------------ ' State switcher - this does all the work ... IF FILEEXISTS(status_file$) THEN ICON_SET(tray_icon, pixbuf_green) ICON_TOOLTIP(tray_icon, "Status file exists.") ELSE ICON_SET(tray_icon, pixbuf_orange) ICON_TOOLTIP(tray_icon, "Status file is missing.") END IF RETURN TRUE END FUNCTION
' ------------------ SUB ON_LEFT_CLICK(GtkStatusIcon *status_icon, gpointer user_data) ' ------------------ IF FILEEXISTS(status_file$) THEN DELETE FILE status_file$ END IF END SUB
' ------------------ SUB ON_RIGHT_CLICK(GtkStatusIcon* status_icon, guint button, guint activate_time, gpointer user_data) ' ------------------ SAVE "" TO status_file$ ' Or .. you could just have: ' gtk_main_quit() END SUB
' ------------------ FUNCTION MK_TRAY_ICON() TYPE GtkStatusIcon* ' ------------------ tray_icon = gtk_status_icon_new() pixbuf_green = SVG_BUFF(ball_green$) pixbuf_orange = SVG_BUFF(ball_orange$) ' Connect handler functions to signals from X CONNECT_DATA(tray_icon,"activate",ON_LEFT_CLICK,NULL) CONNECT_DATA(tray_icon,"popup-menu",ON_RIGHT_CLICK,NULL) ICON_TOOLTIP(tray_icon, "Demo tray app") ICON_VISIBLE(tray_icon, TRUE) RETURN tray_icon END FUNCTION
INIT
tray_icon = MK_TRAY_ICON() TIMEOUT_ADD(1000,CHECK_STATUS)
DISPLAY
|
|
|
Post by vovchik on Dec 4, 2020 1:22:54 GMT 1
Dear Joe,
Perfect! And it all looks like BaCon, too, and it works! I used the latest fossil beta, and it is working fine with that.
Thanks.
With kind regards, vovchik
PS. I changed the first line of MK_TRAY_ICON to:
tray_icon = STATUS_ICON()
You defined it in the DEF FN section, but it wasn't in the code yet.
And we can get rid of raw_array in SVG_BUFF like this:
' ------------------ FUNCTION SVG_BUFF(STRING svg$) TYPE GdkPixbuf* ' ------------------ LOCAL pixloader TYPE GdkPixbufLoader* LOCAL pixbuf TYPE GdkPixbuf* LOCAL size TYPE NUMBER LOCAL res TYPE int 'LOCAL raw_array TYPE unsigned char* size = LEN(svg$) 'raw_array = (unsigned char*)svg$ pixloader = LOADER() res = LOADER_WRITE(pixloader, (unsigned char*)svg$, size) res = LOADER_CLOSE(pixloader) pixbuf = LOADER_GET(pixloader) RETURN pixbuf END FUNCTION
It seems to work, and we have one fewer variable. And maybe we can move the (unsigned char*) bit into the DEF FN of LOADER_WRITE.
PPS. I moved it and it works.
DEF FN LOADER_WRITE(pl,buf,cnt) = gdk_pixbuf_loader_write(GDK_PIXBUF_LOADER(pl), (unsigned char*)buf,cnt,0)
and SVG_BUF now looks like this:
' ------------------ FUNCTION SVG_BUFF(STRING svg$) TYPE GdkPixbuf* ' ------------------ LOCAL pixloader TYPE GdkPixbufLoader* LOCAL pixbuf TYPE GdkPixbuf* LOCAL size TYPE NUMBER LOCAL res TYPE int size = LEN(svg$) pixloader = LOADER() res = LOADER_WRITE(pixloader, svg$, size) res = LOADER_CLOSE(pixloader) pixbuf = LOADER_GET(pixloader) RETURN pixbuf END FUNCTION
|
|
|
Post by bigbass on Dec 4, 2020 6:17:06 GMT 1
Hello vovchik all your changes look really good I applied them and work on my side too!
if you want to shave a hair more you are not testing res so we could remove that also
thanks for all your improvements! it's hard to believe that's gtk c code hiding in there with no include files
Joe
' ------------------ FUNCTION SVG_BUFF(STRING svg$) TYPE GdkPixbuf* ' ------------------ LOCAL pixloader TYPE GdkPixbufLoader* LOCAL pixbuf TYPE GdkPixbuf* LOCAL size TYPE NUMBER size = LEN(svg$) pixloader = LOADER() LOADER_WRITE(pixloader, svg$, size) LOADER_CLOSE(pixloader) pixbuf = LOADER_GET(pixloader) RETURN pixbuf END FUNCTION
|
|
|
Post by vovchik on Dec 4, 2020 10:58:57 GMT 1
Dear Joe, Even better. Thanks. All of it looks very tidy and readable now. With kind regards, vovchik PS. I think we can now also get rid of the variable size in SVG_BUF: ' ------------------ FUNCTION SVG_BUFF(STRING svg$) TYPE GdkPixbuf* ' ------------------ LOCAL pixloader TYPE GdkPixbufLoader* LOCAL pixbuf TYPE GdkPixbuf* pixloader = LOADER() LOADER_WRITE(pixloader, svg$, LEN(svg$)) LOADER_CLOSE(pixloader) pixbuf = LOADER_GET(pixloader) RETURN pixbuf END FUNCTION PPS. And we can get rid of pixbuf, too: ' ------------------ FUNCTION SVG_BUFF(STRING svg$) TYPE GdkPixbuf* ' ------------------ LOCAL pixloader TYPE GdkPixbufLoader* pixloader = LOADER() LOADER_WRITE(pixloader, svg$, LEN(svg$)) LOADER_CLOSE(pixloader) RETURN LOADER_GET(pixloader) END FUNCTION
|
|
|
Post by bigbass on Dec 4, 2020 17:02:08 GMT 1
Hello vovchik you added the final touches I am glad that the RETURN is more robust I didn't feel safe before returning a function at some point that was enhanced and looks cleaner when we can use it thanks again for all the improvements joe ==================================== a side note sometimes glib types are better and sometimes no because they can make the code look more cryptic then again its a style preference as to what looks better here they expose the typdefs (alias) I prefer void* over gpointer for data this is a nice reference web.mit.edu/barnowl/share/gtk-doc/html/glib/glib-Basic-Types.html
|
|
|
Post by bigbass on Dec 5, 2020 18:03:28 GMT 1
Hello vovchik
I sometimes think its better to leave things alone when all looks perfect but sometimes my curiosity gets the best of me and I have to try some more
If we are not sending user_data on the callbacks by using NULL as the fourth arg of CONNECT_DATA
we can pass no args on the subs and simplify it a little more and looks a little more like the "bacon" idea
Joe
'PRAGMA OPTIONS `pkg-config --cflags gtk+-2.0` 'PRAGMA LDFLAGS `pkg-config --libs gtk+-2.0` 'PRAGMA INCLUDE <gtk-2.0/gtk/gtk.h>
' for gtk3, comment out the lines above and uncomment next PRAGMA lines PRAGMA OPTIONS `pkg-config --cflags gtk+-3.0` PRAGMA LDFLAGS `pkg-config --libs gtk+-3.0` PRAGMA INCLUDE <gtk-3.0/gtk/gtk.h> ' next line needed to avoid gtk3 deprecation warnings PRAGMA OPTIONS -Wno-deprecated-declarations
OPTION PARSE FALSE
'--- some bassix macros DEF FN CONNECT( widget, event,cb) = g_signal_connect_data(GTK_WIDGET(widget),event,G_CALLBACK (cb), 0, 0, 0) DEF FN CONNECT_DATA( widget, event,cb,t) = g_signal_connect_data(G_OBJECT (widget),event,G_CALLBACK (cb),(gpointer) t, 0, 0) DEF FN TIMEOUT_ADD(n,cb) = g_timeout_add(n,(GSourceFunc) cb, NULL) DEF FN REMOVE_TIMEOUT(id) = g_source_remove(id) DEF FN DISPLAY() = gtk_main() DEF FN INIT() = gtk_init(0,0) DEF FN STREAM(im) = g_memory_input_stream_new_from_data(im, -1, g_free) DEF FN PIXBUF_MEM(stm) = gdk_pixbuf_new_from_stream(stm, NULL, NULL) DEF FN PIXBUFF(p) = gtk_image_new_from_pixbuf(p ) DEF FN ICON_SET(t,p) = gtk_status_icon_set_from_pixbuf(t, p)
DEF FN ICON_TOOLTIP(t,p) = gtk_status_icon_set_tooltip_text(t, p) DEF FN STATUS_ICON() = gtk_status_icon_new() DEF FN ICON_VISIBLE(t,b) = gtk_status_icon_set_visible(t,b) DEF FN LOADER() = gdk_pixbuf_loader_new() DEF FN LOADER_WRITE(pl,buf,cnt) = gdk_pixbuf_loader_write(GDK_PIXBUF_LOADER(pl), (unsigned char*)buf,cnt,0)
DEF FN LOADER_CLOSE(pl) = gdk_pixbuf_loader_close(GDK_PIXBUF_LOADER(pl),0) DEF FN LOADER_GET(pl) = gdk_pixbuf_loader_get_pixbuf(pl)
DECLARE ball_orange$, ball_green$, status_file$ TYPE STRING DECLARE pixbuf_orange, pixbuf_green TYPE GdkPixbuf* DECLARE tray_icon TYPE GtkStatusIcon*
status_file$ = "/tmp/demotray.txt"
ball_orange$ = "<svg width='24' height='24' viewBox='0 0 84 84'>" \ " <radialGradient id='g1' cx='50%' cy='50%' " \ " r='50%' fx='25%' fy='25%'>" \ " <stop stop-color='orange' offset='0%'/>" \ " <stop stop-color='gray' offset='100%'/>" \ " </radialGradient>" \ " <g stroke='orange' stroke-width='3' stroke-opacity='0.9'>" \ " <circle fill='url(#g1)' cx='42' cy='42' r='40'/>" \ " <circle fill='url(#g1)' cx='42' cy='42' r='12'/>" \ " <circle fill='url(#g1)' cx='42' cy='42' r='4'/>" \ " </g>" \ "</svg>"
ball_green$ = REPLACE$(ball_orange$, "orange", "lawngreen")
' ------------------ FUNCTION SVG_BUFF(STRING svg$) TYPE GdkPixbuf* ' ------------------ LOCAL pixloader TYPE GdkPixbufLoader* pixloader = LOADER() LOADER_WRITE(pixloader, svg$, LEN(svg$)) LOADER_CLOSE(pixloader) RETURN LOADER_GET(pixloader) END FUNCTION
' ------------------ FUNCTION CHECK_STATUS() ' ------------------ ' State switcher - this does all the work ... IF FILEEXISTS(status_file$) THEN ICON_SET(tray_icon, pixbuf_green) ICON_TOOLTIP(tray_icon, "Status file exists.") ELSE ICON_SET(tray_icon, pixbuf_orange) ICON_TOOLTIP(tray_icon, "Status file is missing.") END IF RETURN TRUE END FUNCTION
' ------------------ SUB ON_LEFT_CLICK() ' ------------------ IF FILEEXISTS(status_file$) THEN DELETE FILE status_file$ END IF PRINT "left_clicked" END SUB
' ------------------ SUB ON_RIGHT_CLICK() ' ------------------ SAVE "" TO status_file$ ' Or .. you could just have: ' gtk_main_quit() PRINT "right_clicked" END SUB
' ------------------ FUNCTION MK_TRAY_ICON() TYPE GtkStatusIcon* ' ------------------ tray_icon = STATUS_ICON()
pixbuf_green = SVG_BUFF(ball_green$) pixbuf_orange = SVG_BUFF(ball_orange$) ' Connect handler functions to signals from X CONNECT_DATA(tray_icon,"activate",ON_LEFT_CLICK,NULL) CONNECT_DATA(tray_icon,"popup-menu",ON_RIGHT_CLICK,NULL) ICON_TOOLTIP(tray_icon, "Demo tray app") ICON_VISIBLE(tray_icon, TRUE) RETURN tray_icon END FUNCTION
INIT
tray_icon = MK_TRAY_ICON() TIMEOUT_ADD(1000,CHECK_STATUS)
DISPLAY
|
|
|
Post by vovchik on Dec 5, 2020 18:30:22 GMT 1
Dear Joe, Even better. Thanks. The simpler it looks, the more I like it. And it works, too. With kind regards, vovchik
|
|