|
Post by vovchik on Apr 12, 2019 11:35:14 GMT 1
Dear all, Here is a slightly "souped-up" dict version. It works find on mint but having problems with RPI3, since there is no function "webkit_form_submission_request_list_text_fields" in PI's webkit. There is "webkit_form_submission_request_get_text_fields", but it takes only one argument and returns a hashtable. With kind regards, vovchik
|
|
|
Post by Pjot on Apr 13, 2019 8:35:07 GMT 1
Thanks vovchik, Looks very good! As always your design skills improves the result tremendously. BR Peter
|
|
|
Post by ptitjoz on Apr 13, 2019 9:55:28 GMT 1
Some time ago I was thinking to use an HTML renderer (e.g. web browser) as a platform to host GUI programs. The advantages are obvious: - Multi platform GUI
- Using HTML forms which is generally available
- HTML has a simple declarative syntax
- Coloring and styling can easily be done
- All the required widgets are built-in and HUG was inspired by HTML widgets in the first place
Problem of course is how to handle events and do callbacks without using Javascript. So, accidentally, when updating the minimal web browser yesterday, I looked a little deeper in the webkit API, and to my surprise, there is a callback on the "submit-form" signal! Below a small Proof-of-Concept on a universal GUI based on HTML forms, using webkit. It is all BaCon code and allows callbacks. Of course further development of ideas and concepts is needed, but I think it can be done. Regards, Peter ' Do not choke on GTK functions OPTION PARSE FALSE
' Using GTK3 PRAGMA INCLUDE <gtk/gtk.h> PRAGMA OPTIONS `pkg-config --cflags gtk+-3.0` PRAGMA LDFLAGS `pkg-config --libs gtk+-3.0`
' Using libwebkit2 PRAGMA INCLUDE <webkit2/webkit2.h> PRAGMA OPTIONS `pkg-config --cflags webkit2gtk-3.0` PRAGMA LDFLAGS `pkg-config --libs webkit2gtk-3.0`
'---------------------------------------------------------------------------------------------------
[..ETC...] gtk_main()
EDIT: replaced the inline escaped double quotes for single quotes. Note the 'nbsp' tags, they are put here wrongly otherwise they are not being displayed properly.
Hello everyone I look at your project and it's very interesting. I tried to copy paste some programs some work and some do not. for example, I can run the following programs:
But if I run the program above (which I truncated on the display for more visibility) I get these messages:
Best Regards
|
|
|
Post by vovchik on Apr 13, 2019 14:33:16 GMT 1
Dear all, Here is another dict take using an inline svg. In order for the svg background to show, you first have to convert it to b64. All that is explained in the source. With kind regards, vovchik PS. ptitjoz: You might be experiencing some of the problems Alex, Joe and I have had on RP3 with header locations and actual lib functions. Check all the above comments.
|
|
|
Post by vovchik on Apr 13, 2019 19:02:03 GMT 1
Dear all, I am a terrible html progammer and haven't really done much of that for the past 15 years. I now want to create a combobox for selecting the dict source, and creating one visually works using <select>. I don't know how to get the selected value into the server name, however, to make it work. It now ends with a segfault -- after selecting a server, inputting a search term and pressing the "Lookup" button. I have tried using a hidden <input> but that doesn't seem to work. Any ideas or fixes? Thanks in advance. With kind regards, vovchik PS. UPDATED combo version. Now we have tooltips. Attachments:
dict-combo.tar.gz (4.87 KB)
|
|
|
Post by Pjot on Apr 14, 2019 9:57:01 GMT 1
Hi vovchik, Thanks again for the layout enhancements. Regarding the combobox, I faced the same issue. The Webkit API for form submission is somewhat limited. Somebody pointed me to the following text, which, apparently, we need to take literally: So, the API only submits genuine text fields, and not other types of widgets. Therefore, we need to apply a trick in order to make the drop down box work: <select name='selection'> <option value='volvo'>Volvo</option> <option value='saab'>Saab</option> <option value='mercedes'>Mercedes</option> <option value='audi'>Audi</option> </select> <input type='text' style='display: none' name='drop'> <input type='submit' value='Calculate' onclick='document.main_form.drop.value=document.main_form.selection.value;'>
As you can see, we have to create an additional hidden text field. After that, we need to add the 'onclick' event to the submit button, which will set the value from the drop down box into this hidden field. The 'onclick' event refers to the current HTML ("document"), then the name of the form where the widget resides ("main_form"), then the name of the drop down box ("selection") and then the field containing the text ("value").
When submitting the form, the key "drop" will show the selected value from the select widget.
Best regards Peter
|
|
|
Post by vovchik on Apr 14, 2019 10:46:40 GMT 1
Dear Peter, Thanks for the explanation and advice. I have tried to do it in my modded dict, and still no success- but a SEGFAULT at runtime. Can you posted a dict where it works, so that I can try to digest it? I suppose we have to add "drop" to the SELECT statement in the callback and assign the value to server$. I tried that but still get segfaults when I click on the Lookup button. With kind regards, vovchik
|
|
|
Post by Pjot on Apr 14, 2019 11:09:11 GMT 1
Below is the code. I tried some servers from this list but some of them seem not to exist anymore. Note that the selection will jump back to its original value after looking up a word, but I leave this problem as an exercise for you - SOLVED in the updated program below. Also note that I use a "DEFINE english <word>" API to lookup a word in an English dictionary, but this dictionary doesn't exist at the other servers - another nice exercise! - SOLVED by using "DEFINE * <word>" ' Do not choke on GTK functions OPTION PARSE FALSE
' Using GTK3 PRAGMA INCLUDE <gtk/gtk.h> PRAGMA OPTIONS `pkg-config --cflags gtk+-3.0` PRAGMA LDFLAGS `pkg-config --libs gtk+-3.0`
' Using libwebkit2 PRAGMA INCLUDE <webkit2/webkit2.h> PRAGMA OPTIONS `pkg-config --cflags webkit2gtk-4.0` PRAGMA LDFLAGS `pkg-config --libs webkit2gtk-4.0`
'---------------------------------------------------------------------------------------------------
' Define GUI CONST template$ = "<!DOCTYPE html>" \ "<html>" \ "<body bgcolor='#D3D3D3' style='font-size:12px;'>" \ "<form action='' id='about_form' method='post' target='_self'>" \ "<input type='text' style='display: none' name='about' value='about'>" \ "</form>" \ "<form action='' id='clear_form' method='post' target='_self'>" \ "<input type='text' style='display: none' name='clear' value='clear'>" \ "</form>" \ "<form action='' id='exit_form' method='post' target='_self'>" \ "<input type='text' style='display: none' name='exit' value='exit'>" \ "</form>" \ "<table style='width:100%'>" \ "<tr>" \ "<td>" \ "<fieldset>" \ "<legend>Control</legend>" \ "<input title='About this program.' type='submit' form='about_form' value=' About '>" \ "<input title='Clear form data.' type='submit' form='clear_form' value=' Clear '>" \ "<input title='Exit this program.' type='submit' form='exit_form' value=' Quit '>" \ "</fieldset>" \ "</td>" \ "<td title='A gratuitous tooltip here.' style='text-align:center'>" \ "<h3>BaCon dictionary</h3>The classic dictionary program" \ "</td>" \ "</tr>" \ "</table>" \ "<br>" \ "<fieldset title='Output appears here.'>" \ "<legend>Translation</legend>" \ "<textarea rows='8' cols='62'></textarea>" \ "</fieldset>" \ "<br>" \ "<form action='' name='word_form' method='post' target='_self'>" \ "<fieldset>" \ "<legend>Lookup</legend>" \ "<table style='width:100%'>" \ "<tr>" \ "<td style='text-align:left'>" \ "Server:" \ "<select title='Select dictionary source.' name='selection' value=''>" \ "<option value='dict.org'>dict.org</option>" \ "<option value='dict.saugus.net'>dict.saugus.net</option>" \ "<option value='dict.tu-chemnitz.de'>dict.tu-chemnitz.de</option>" \ "<option value='dict.mova.org'>dict.mova.org</option>" \ "<option value='dict.dvo.ru'>dict.dvo.ru</option>" \ "<option value='dict.bibleonline.ru'>dict.bibleonline.ru</option>" \ "</select>" \ "<input type='text' style='display: none' name='drop_selection' value=''>" \ "</td>" \ "<td style='text-align:right'>" \ "Word: <input type='text' size='20' name='word' value='' autofocus>" \ "<input title='Click here to search.' type='submit' value='Lookup' onclick='document.word_form.drop_selection.value=document.word_form.selection.value;'>" \ "</td>" \ "</tr>" \ "</table>" \ "</fieldset>" \ "</form>" \ "</body>" \ "</html>"
'---------------------------------------------------------------------------------------------------
SUB Show_Dialog(msg$, gui$)
LOCAL dialog
webkit_web_view_load_html(WEBKIT_WEB_VIEW(html), gui$, NULL)
dialog = gtk_message_dialog_new(GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_INFO, GTK_BUTTONS_CLOSE, NULL) gtk_message_dialog_set_markup(GTK_MESSAGE_DIALOG(dialog), msg$) gtk_dialog_run(GTK_DIALOG(dialog)) gtk_widget_destroy(GTK_WIDGET(dialog))
ENDSUB
'---------------------------------------------------------------------------------------------------
FUNCTION Lookup_Word$(server$, word$)
LOCAL req$, line$, total$ LOCAL mynet
req$ = "DEFINE * " & word$ & CR$ & NL$
OPEN server$ & ":2628" FOR NETWORK AS mynet SEND req$ TO mynet
REPEAT RECEIVE line$ FROM mynet total$ = total$ & line$ IF INSTR(line$, "250 ok") THEN BREAK UNTIL NOT(WAIT(mynet, 1000))
SEND "QUIT" TO mynet CLOSE NETWORK mynet
RETURN total$
ENDFUNCTION
'---------------------------------------------------------------------------------------------------
SUB Get_Event(WebKitWebView* widget, WebKitFormSubmissionRequest* form, void* data)
LOCAL key, value TYPE GPtrArray* LOCAL height, weight TYPE FLOATING LOCAL key$, value$, server$, word$, text$, gui$ LOCAL idx
' Get the values from the form IF form = NULL THEN PRINT "Internal error: no data - exiting..." END ENDIF
webkit_form_submission_request_submit(form)
' Get local copy from the GUI gui$ = data
' Get the values from the form IF webkit_form_submission_request_list_text_fields(form, &key, &value) THEN
REPEAT key$ = (char*)g_ptr_array_index(key, idx) value$ = (char*)g_ptr_array_index(value, idx)
' Find out the action SELECT key$ CASE "drop_selection" server$ = value$ CASE "word" word$ = value$ CASE "clear" gui$ = REPLACE$(gui$, "<textarea rows='8' cols='62'>.*</textarea>", "<textarea rows='8' cols='62'></textarea>", TRUE) BREAK CASE "about" Show_Dialog("<b>Demo program with Webkit</b>" & NL$ & TAB$(1) & "Using BaCon " & VERSION$ & NL$ & NL$ & "<i>(C) Peter van Eerten - April 11, 2019</i>", gui$) BREAK CASE "exit" END ENDSELECT
' Make sure to retain the current values in the GUI by updating the original template gui$ = REPLACE$(gui$, "name='" & key$ & "' value='[.]*'", "name='" & key$ & "' value='" & value$ & "'", TRUE)
' Is this a selection? Update selected item IF INSTR(key$, "selection") THEN gui$ = REPLACE$(gui$, "<option value='" & value$ & "'>" & value$ & "</option>", "<option value='" & value$ & "' selected>" & value$ & "</option>", TRUE)
INCR idx UNTIL idx = key->len
' Lookup word in English dictionaries IF LEN(word$) THEN text$ = Lookup_Word$(server$, word$) gui$ = REPLACE$(gui$, "<textarea rows='8' cols='62'>.*</textarea>", "<textarea rows='8' cols='62'>" & text$ & "</textarea>", TRUE) ENDIF
' Render created GUI with text result webkit_web_view_load_html(WEBKIT_WEB_VIEW(html), gui$, NULL) ENDIF
ENDSUB
'---------------------------------------------------------------------------------------------------
' Initialize GTK gtk_init(0, 0)
' Create main window window = gtk_window_new(0) gtk_window_set_title(GTK_WINDOW(window), "Proof of Concept Webkit - Dictionary") gtk_window_set_default_size(GTK_WINDOW(window), 500, 350) gtk_window_set_icon_name(GTK_WINDOW(window), "gtk-dialog-info") g_signal_connect_data(GTK_WIDGET(window), "delete-event", G_CALLBACK(exit), 0, 0, 0)
' Create HTML renderer html = webkit_web_view_new()
scrolled = gtk_scrolled_window_new(0, 0) gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled), 1, 1) gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), 3) gtk_container_add(GTK_CONTAINER(scrolled), GTK_WIDGET(html))
' Load GUI definition webkit_web_view_load_html(WEBKIT_WEB_VIEW(html), template$, NULL) g_signal_connect_data(GTK_WIDGET(html), "submit-form", G_CALLBACK(Get_Event), template$, 0, 0)
' Pack everything together and wait for event gtk_container_add(GTK_CONTAINER(window), GTK_WIDGET(scrolled)) gtk_widget_show_all(GTK_WIDGET(window)) gtk_main()
|
|
|
Post by vovchik on Apr 14, 2019 12:55:18 GMT 1
Dear Peter, Thanks - it works nicely. Here is a working version with the nice GUI bits. I haven't yet dealt with tweaks to the server parameters, so that the other servers also work, but at least we have tooltips and a working combobox. I am also learning something - although slowly. With kind regards, vovchik UPDATED: I added our old HUG-based bdict that allows a choice of sources on various servers for convenience. I think we can "steal" some code from ourselves here for a better webkit version.
|
|
|
Post by Pjot on Apr 14, 2019 18:48:23 GMT 1
I am also learning something - although slowly. Well that makes two of us. The principle of a declarative HTML syntax which needs dynamic updates is kind of hard to grasp But I have updated my program above, so those two exercises are solved. In the meantime, I got some ideas about setting up an API which will generate the HTML. As you may see in the program above, the general HTML layout now is a CONST, and behaves like a template. Any adjustments to the HTML should be done in the event handling. Furthermore I found out how to position a widget in HTML using inline CSS. This comes handy for layout issues. I will check out other widget types to see their peculiarities also. Though the Webkit API doesn't make things easy, this approach sure has benefits in terms of program size and portability BR Peter PS thanks for all those layout enhancements. Also the tooltips are really handy and easy to add.
|
|
|
Post by ptitjoz on Apr 14, 2019 19:54:20 GMT 1
Hello If there is one who does not understand things in what you are doing, it's mostly me.
I am angry (a little bit) for not being able to try your programs, which I can not understand without trying them. I'm wondering why you do not use Javascript that can do a lot of things quite easily. (Javascript, I know well to have developed several applications in a professional environment.) Best regards.
|
|
|
Post by Pjot on Apr 14, 2019 20:04:31 GMT 1
Hi ptitjoz, Of course I am not using Javascript! This is the place to program BaCon, obviously This whole idea is an experiment. Can we setup HTML form widgets in such a way that they can be used within BaCon? This is not possible within a browser, of course. Within a browser, we need to use Javascript.
However, the HTML widgets can be redirected to our BaCon program by embedding Webkit into our code. But there is no particular reason to do this. Mostly it is fun. It simply is pretty cool that HTML can generate a GUI, and we can manipulate that in BaCon. You don't have to use it. Feel free to use Javascript instead! Cordialement, Peter
|
|
|
Post by vovchik on Apr 15, 2019 0:10:35 GMT 1
Dear Peter, Great work on the update - we now get the whole set of dictionary entries from each site. incidentally, the Ukrainian mova site has Dutch, too (select the mova site and use the word "woord", for example). I updated my flashy version with your mods. It seems to work fine, too, in most case. There is a little problem with timeouts, though, if a word cannot be found. I wonder whether we shouldn't check for that, since the GUI goes blank waiting for a server response. With kind regards, vovchik
|
|
|
Post by bigbass on Apr 15, 2019 13:24:23 GMT 1
Hey Guys got css working with webkit and gtk3 This is a simple demo for documentation reasons but adding css wasn't so simple the idea is we will be able to just read in style.css no hacks needed and this way we can manually theme the look without having to recompile and manually embed the html code in the app as the program grows css will make life much easier to modify and quickly see the changes and this is the official way it is used in gtk3 to have many themes there are two versions included for RPI3 AND MINT however I don't have mint to test on I just used compile options that what worked for Peter TIP:you can edit the link without editing the main code just mouse over and edit for a new direction webkit-css.tar.gz (1.66 KB) Joe
|
|
|
Post by vovchik on Apr 15, 2019 13:57:37 GMT 1
Dear Joe,
Thanks for the example. It works in Mint and RPI3 with this bit at the top:
' Do not choke on GTK functions OPTION PARSE FALSE
'---this fixes true/false for bacon PRAGMA INCLUDE <stdbool.h>
' Using GTK3 PRAGMA INCLUDE <gtk/gtk.h> PRAGMA OPTIONS `pkg-config --cflags gtk+-3.0` PRAGMA LDFLAGS `pkg-config --libs gtk+-3.0`
' Using libwebkit2 IF INSTR(OS$, "armv") THEN PRAGMA INCLUDE <webkitgtk-4.0/webkit2/webkit2.h> PRAGMA OPTIONS `pkg-config --cflags webkit2gtk-4.0` PRAGMA LDFLAGS `pkg-config --libs webkit2gtk-4.0` ELSE PRAGMA INCLUDE <webkit2/webkit2.h> PRAGMA OPTIONS `pkg-config --cflags webkit2gtk-4.0` PRAGMA LDFLAGS `pkg-config --libs webkit2gtk-4.0` END IF
' Using GDK3 PRAGMA OPTIONS `pkg-config --cflags gdk-3.0` PRAGMA OPTIONS `pkg-config --libs gdk-3.0`
And then we, for this purpose, don't need two versions. The GDK bits allow us to load inline SVGs as images and icons using my functions SVG_BUFF and SET_WINICON (as in my version of the dict prog, for example).
With kind regards, vovchik
|
|