Bassix GTK3 webkit browser Wiki
A very small gtk3-webkit browser that runs well on the raspberry pi3
Brought to you by:
big-bass
Example code:bassix-radio-player.bac
place radio2.cfg in your home directory
install dependencies
sudo apt-get install mpg123
tested on linux mint 20.1 64 bit xfce
'--- bigbass GTK3 with FIXED placement and some new macros '--- for the lack of a name we can call it gtk3 bassix '--- a simple 'HUG' looking syntax idea but include only what you need as you go '--- June 25 2020 --- UPDATED MAY 1 2021 '--- added dynamic combobox '--- added songtrack automatically as a label '--- added timeout and refresh July 12 OPTION PARSE FALSE PRAGMA INCLUDE <gtk-3.0/gtk/gtk.h> PRAGMA OPTIONS `pkg-config --cflags gtk+-3.0` PRAGMA LDFLAGS `pkg-config --libs gtk+-3.0` PRAGMA OPTIONS -Wno-deprecated-declarations '--- new signal handlers to simplify the callbacks DEF FN CONNECT( widget, event,cb) = g_signal_connect_data(widget,event,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 WINDOW_ADD() = gtk_window_new(GTK_WINDOW_TOPLEVEL) DEF FN NEW(widget,...) = g_object_new(widget, __VA_ARGS__,NULL) DEF FN PLACE( widget, name,wid,high) = gtk_fixed_put(GTK_FIXED(widget), GTK_WIDGET(name),wid,high) DEF FN ADD_FIXED( widget, name) = gtk_container_add(GTK_CONTAINER(widget), GTK_WIDGET(name)) DEF FN SET(widget, name, ...) = g_object_set(GTK_WIDGET(widget), name, __VA_ARGS__, NULL) DEF FN GET( widget, name, ...) = g_object_get(widget, name, __VA_ARGS__, NULL) DEF FN SHOW( widget) = gtk_widget_show_all(GTK_WIDGET(widget)) DEF FN HIDE( widget) = gtk_widget_hide(GTK_WIDGET(widget)) DEF FN INIT() = gtk_init(0,0) DEF FN LABEL_ADD(t) = gtk_label_new(t) DEF FN BUTTON_ADD(t) = gtk_button_new_with_label(t) DEF FN TEXT_VIEW() = gtk_text_view_new () DEF FN FIXED() = gtk_fixed_new() DEF FN DISPLAY() = gtk_main() DEF FN ATTACH() = gtk_container_add() DEF FN SCROLLED_WINDOW() = gtk_scrolled_window_new (NULL, NULL) 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 SET_IMAGE(widget,im) = gtk_button_set_image (GTK_BUTTON (widget), im) DEF FN IMAGE_FILE(f) = gtk_image_new_from_file(f) DEF FN COMBO() = gtk_combo_box_text_new () DEF FN COMBO_GET(c) = gtk_combo_box_text_get_active_text (GTK_COMBO_BOX_TEXT(c)) DEF FN COMBO_ACTIVE(c) = gtk_combo_box_get_active (GTK_COMBO_BOX(c)) DEF FN COMBO_ADD(widget,arr) = gtk_combo_box_text_append_text (GTK_COMBO_BOX_TEXT (widget), arr) DEF FN VOLUME_GET(widget) = gtk_scale_button_get_value(GTK_SCALE_BUTTON(widget)) DEF FN VOLUME() = gtk_volume_button_new() DEF FN TIMEOUT_ADD(n,cb) = g_timeout_add(n,(GSourceFunc) cb, NULL) DEF FN REMOVE_TIMEOUT(id) = g_source_remove(id) ALIAS GTK_TYPE_WINDOW TO WINDOW ALIAS GTK_TYPE_BUTTON TO BUTTON ALIAS GTK_WIDGET TO WIDGET ALIAS GTK_CONTAINER TO CONTAINER ALIAS g_free TO FREE DECLARE window, scrolled_win ,exit_btn ,image ,label2 TYPE GtkWidget* DECLARE fixed TYPE GtkWidget* DECLARE image2 TYPE GtkWidget* DECLARE VOLUME2 TYPE GtkWidget* DECLARE combo_box TYPE GtkWidget* '===================== SUB exit_prog '===================== CLEAR SYSTEM(" killall mpg123 ") SLEEP 100 DELETE FILE "/tmp/MPG123_file.txt" END END SUB '===================== SUB exit_clicked () '===================== CLEAR SYSTEM(" killall mpg123 ") SLEEP 100 DELETE FILE "/tmp/MPG123_file.txt" END END SUB SUB song_title_cb HIDE(label2) count = 0 REPEAT SLEEP 200 LIVE_DATA$ = EXEC$("tail -n 1 /tmp/MPG123_file.txt &") '---now we will use bacon to parse for StreamTitle track$ = INBETWEEN$(LIVE_DATA$ , "StreamTitle='", "';") INCR count UNTIL LEN(track$) !=0 OR count > 35 'PRINT "live data test:",LIVE_DATA$ '---if no track is found in 3.5 seconds give up on the title '--- offer a visual aid if found + not found - as the icon IF LEN(track$) !=0 THEN SET(window, "icon-name","gtk-add") IF LEN(track$) > 70 THEN track$ = ALIGN$(track$, 70, 0) END IF 'SET(label2, "label", track$) label2 = LABEL_ADD(track$) PLACE(fixed ,label2,5,45) SHOW(label2) ELSE SET(window, "icon-name","gtk-remove") END IF END SUB '====================================================== SUB on_changed (GtkComboBox *widget, void* user_data) '====================================================== IF FILEEXISTS( "/tmp/MPG123_file.txt") THEN DELETE FILE "/tmp/MPG123_file.txt" END IF 'LOCAL combo_box TYPE GtkComboBox* 'combo_box = widget CLEAR '--- we dont want more than one station playing at a time SYSTEM(" killall mpg123 & ") LOCAL distro TYPE STRING '---get matching url is the index_num index_num = COMBO_ACTIVE(combo_box) distro = COMBO_GET(combo_box) HIDE(label2) PRINT distro FORMAT "%s\n" PRINT url$[index_num] FORMAT "%s\n" SETENVIRON "result_selected",url$[index_num] SYSTEM("mpg123 $result_selected 2> /tmp/MPG123_file.txt&") TIMEOUT_ADD(500,song_title_cb) END SUB ' ============================== SUB VOLUME2_CB(long widget, void* user_data) ' ============================== PRINT "VOLUME2_CB" '---we use strings to set env LOCAL audio_level_bacon$ TYPE STRING LOCAL audio_level_bacon TYPE double PRINT VOLUME_GET(VOLUME2) FORMAT "%.1f\n" audio_level_bacon = VOLUME_GET(VOLUME2) '---a hack to get scale 1-100 audio_level_bacon = audio_level_bacon * 100 audio_level_bacon$= STR$(audio_level_bacon) SETENVIRON "audio_level_bacon",audio_level_bacon$ '---debug whats happenning in the low level sys_vol$ = EXEC$("echo $audio_level_bacon") PRINT "sys volume: ",sys_vol$ SYSTEM "amixer -D pulse sset Master $audio_level_bacon% &" END SUB '---main code INIT '--- you could place all properties in the NEW() or use SET '--- and add what you need as you go window = WINDOW_ADD() '--- widget ,property , value or string SET(window, "icon-name", "media-record") SET(window, "title", "Internet Radio auto title Bassix ") SET(window, "resizable", TRUE) SET(window, "border-width", 10, "default-width", 590) SET(window, "default-height", 30) '--- place window into the fixed container fixed = FIXED() ADD_FIXED(window, fixed) '---new button and label exit_btn = BUTTON_ADD ("Exit") SET(exit_btn, "width_request", 80 ,"height_request",30) SET(exit_btn, "tooltip-text", "EXIT") '---make sure the image is visible SET(exit_btn, "always_show_image",TRUE) SET(exit_btn, "label","gtk-quit","use_stock",TRUE) '---placement inside fixed,widget,X,Y PLACE (fixed, exit_btn, 550, 5) SET(exit_btn, "width_request", 80 ,"height_request",30) SET(exit_btn, "tooltip-text", "refresh") refresh_btn = BUTTON_ADD ("Refresh") '---make sure the image is visible SET(refresh_btn, "always_show_image",TRUE) SET(refresh_btn, "label","gtk-refresh","use_stock",TRUE) '---placement inside fixed,widget,X,Y PLACE (fixed, refresh_btn, 390, 5) '---volume button , settings and placement VOLUME2 = VOLUME() SET(VOLUME2, "size", GTK_ICON_SIZE_DND) PLACE (fixed, VOLUME2, 500, 5) '--- handle callbacks widget,event,sub or function CONNECT(window, "delete-event", exit_prog) CONNECT(exit_btn, "clicked" ,exit_clicked ) '---DYNAMIC COMBO BOX read in a file LOCAL i TYPE int LOCAL view TYPE GtkWidget* '--- Create the combo box and append your string values to it. combo_box = COMBO() SET(combo_box, "height_request",10) SET(combo_box, "width_request", 80) '--- make a dynamic combobox read in any type of file '--- get names of station left side of pipe result_input$ = CHOP$(EXEC$("cat ~/radio2.cfg | cut -d'|' -f1")) '--- get urls right side of pipe result_input2$ = CHOP$(EXEC$("cat ~/radio2.cfg | cut -d'|' -f2")) SPLIT result_input$ BY NL$ TO words$ SIZE dim FOR i = 0 TO dim - 1 COMBO_ADD(combo_box,words$[i]) NEXT '--- a 2D array split in two parts station and url SPLIT result_input2$ BY NL$ TO url$ SIZE dim2 '---second url FOR i = 0 TO dim2 -1 IF NOT(INSTR(url$[i],"cannot access")) THEN PRINT url$[i] TO SIZE 8098 CLEAR '--- going to save the url part in memory ENDIF NEXT '--- Choose to set the first option as the active one by default SET(combo_box, "active",0) CONNECT_DATA(combo_box, "changed",on_changed,NULL) CONNECT_DATA(VOLUME2, "value-changed",VOLUME2_CB ,NULL) CONNECT_DATA(refresh_btn, "clicked",song_title_cb ,NULL) label2 = LABEL_ADD("") PLACE (fixed, combo_box, 5, 5) SHOW(window) HIDE(label2) '---got the g_timeout working for bassix DISPLAY