WebUI wrapper

Share your advanced PureBasic knowledge/code with the community.
drgolf
Enthusiast
Enthusiast
Posts: 106
Joined: Tue Mar 03, 2009 3:40 pm
Location: france

WebUI wrapper

Post by drgolf »

Hello,

A wrapper for the WebUI DLL and use webbrowser as gui...
Tested with button...
Work with many browser.
I have not ported all the functions available...
If someone is more competent than me...

Code: Select all

; webui wrapper for PB
; WebUI is here : https://webui.me/#download
;
; PB 6.03b1 LTS x64 - Windows 10 Pro x64
; DrGolf - 06/2023
;
 #WEBUI_VERSION = "2.3.0"
 #WEBUI_MAX_IDS = 512
 ;
 Enumeration
   #WEBUI_EVENT_DISCONNECTED ; // 0. 
   #WEBUI_EVENT_CONNECTED ; // 1. 
   #WEBUI_EVENT_MULTI_CONNECTION ; // 2. 
   #WEBUI_EVENT_UNWANTED_CONNECTION ; // 3. 
   #WEBUI_EVENT_MOUSE_CLICK ; // 4. 
   #WEBUI_EVENT_NAVIGATION ; // 5. 
   #WEBUI_EVENT_CALLBACK ; // 6.   
 EndEnumeration
 
 ;
 Structure webui_event_t
    window.i
    event_type.i
    *element
    *_data
    event_number.i
 EndStructure
 ;
 PrototypeC.i webuinewwindow()
 PrototypeC.i webuishow(window,p_ascii)
 PrototypeC.i webuiwait()
 PrototypeC.i webuibind(window,p_ascii,func)
 ;
 Define.i window
 Define.webui_event_t e
 
 ;Define.s cont
 ;
 Procedure webuieventproc(*e.webui_event_t)
   Debug *e\window
   Debug *e\event_type
   Debug PeekS(*e\element,-1,#PB_Ascii)
   Debug *e\_data
   If *e\_data<>0
     Debug PeekS(*e\_data,-1,#PB_Ascii)
   EndIf
   Debug *e\event_number
 EndProcedure
 
 ;-debut
 
 If OpenLibrary(0,"webui.dll")
   newwindow.webuinewwindow=GetFunction(0,"webui_new_window")
   webui_show.webuishow=GetFunction(0,"webui_show")
   webui_wait.webuiwait=GetFunction(0,"webui_wait")
   webui_bind.webuibind=GetFunction(0,"webui_bind")
   
   ;
   window=newwindow()
   webui_bind(window,Ascii("button"),@webuieventproc())
   *cont=Ascii("<html><body><button id='button'>Click me!</button></body></html>")
   webui_show(window,*cont)
   ; or webui_show(window,ascii("htmlfile.html"))
   webui_wait()
   ;
   FreeMemory(*cont)
 CloseLibrary(0)  
 EndIf
 
firace
Addict
Addict
Posts: 946
Joined: Wed Nov 09, 2011 8:58 am

Re: WebUI wrapper

Post by firace »

Wow, first time I hear of WebUI! Really nice solution (no need for a webview2 dependency on Windows!), thanks for sharing.

Fred might find this quite interesting (possibly for a next-generation webgadget) IMHO
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: WebUI wrapper

Post by Fred »

Works fine here, that's a smart approach to have a WebUI :)
User avatar
Mijikai
Addict
Addict
Posts: 1517
Joined: Sun Sep 11, 2016 2:17 pm

Re: WebUI wrapper

Post by Mijikai »

Had some time, WebUI include (untested!):

Code: Select all

; /*
;   WebUI Library 2.3.0
;   http://webui.me
;   https://github.com/webui-dev/webui
;   Copyright (c) 2020-2023 Hassan Draga.
;   Licensed under MIT License.
;   All rights reserved.
;   Canada.
; */

#WEBUI_VERSION = "2.3.0"
#WEBUI_MAX_IDS = 512

Enumeration webui_browsers
  #AnyBrowser
  #Chrome
  #Firefox
  #Edge
  #Safari
  #Chromium
  #Opera
  #Brave
  #Vivaldi
  #Epic
  #Yandex
EndEnumeration

Enumeration webui_runtimes 
  #None
  #Deno
  #NodeJS
EndEnumeration

Enumeration webui_events
  #WEBUI_EVENT_DISCONNECTED
  #WEBUI_EVENT_CONNECTED
  #WEBUI_EVENT_MULTI_CONNECTION
  #WEBUI_EVENT_UNWANTED_CONNECTION
  #WEBUI_EVENT_MOUSE_CLICK
  #WEBUI_EVENT_NAVIGATION
  #WEBUI_EVENT_CALLBACK
EndEnumeration

Structure webui_event
  window.i
  event_type.i
  *element
  *data
  event_number.i
EndStructure

Import "webui-2-x64.lib"
  webui_new_window.i()
  webui_new_window_id.i(window_number.i)
  webui_get_new_window_id.i()
  webui_bind.i(window.i,element.s,*webui_event);
  webui_show.i(window.i,content.s)
  webui_show_browser(window.i,content.s,browser.i)
  webui_set_kiosk.i(window.i,status.b)
  webui_wait.i()
  webui_close.i(window.i)
  webui_destroy.i(window.i)
  webui_exit.i()
  webui_set_root_folder.b(window.i,path.s)
  webui_is_shown.b(window.i)
  webui_set_timeout.i(second.i)
  webui_set_icon.i(window.i,icon.s,icon_type.s)
  webui_set_multi_access.i(window.i,status.b)
  webui_run.i(window.i,script.s)
  webui_script.b(window.i,script.s,timeout.i,buffer.s,buffer_length.i)
  webui_set_runtime(window.i,run_time.i)
  webui_get_int.i(*event)
  webui_get_string.i(*event)
  webui_get_bool.b(*event)
  webui_return_int.i(*event,number.i)
  webui_return_string.i(*event,const.s)
  webui_return_bool.i(*event,bool.b)
  webui_encode.i(char.s)
  webui_decode.i(char.s)
  webui_free.i(*ptr)
  webui_interface_bind.i(window.i,element.s,*func)
  webui_interface_set_response.i(window.i,event_number.i,response.s)
  webui_interface_is_app_running.b()
  webui_interface_get_window_id.i(window.i)
  webui_interface_get_bind_id.i(window.i,element.s)
EndImport
Last edited by Mijikai on Sun Jun 11, 2023 9:38 pm, edited 2 times in total.
User avatar
Kuron
Addict
Addict
Posts: 1626
Joined: Sat Oct 17, 2009 10:51 pm
Location: Pacific Northwest

Re: WebUI wrapper

Post by Kuron »

Very interesting. :mrgreen:
Best wishes to the PB community. Thank you for the memories. ♥️
infratec
Always Here
Always Here
Posts: 7583
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: WebUI wrapper

Post by infratec »

Working version:

Code: Select all

; /*
;   WebUI Library 2.3.0
;   http://webui.me
;   https://github.com/webui-dev/webui
;   Copyright (c) 2020-2023 Hassan Draga.
;   Licensed under MIT License.
;   All rights reserved.
;   Canada.
; */


CompilerIf Not #PB_Compiler_Thread
  CompilerError "Enable threadsafe in compiler options"
CompilerEndIf

CompilerIf #PB_Compiler_IsMainFile
  EnableExplicit
CompilerEndIf


#WEBUI_VERSION = "2.3.0"
#WEBUI_MAX_IDS = 512

Enumeration webui_browsers
  #AnyBrowser
  #Chrome
  #Firefox
  #Edge
  #Safari
  #Chromium
  #Opera
  #Brave
  #Vivaldi
  #Epic
  #Yandex
EndEnumeration

Enumeration webui_runtimes 
  #None
  #Deno
  #NodeJS
EndEnumeration

Enumeration webui_events
  #WEBUI_EVENT_DISCONNECTED
  #WEBUI_EVENT_CONNECTED
  #WEBUI_EVENT_MULTI_CONNECTION
  #WEBUI_EVENT_UNWANTED_CONNECTION
  #WEBUI_EVENT_MOUSE_CLICK
  #WEBUI_EVENT_NAVIGATION
  #WEBUI_EVENT_CALLBACK
EndEnumeration

Structure webui_event_t Align #PB_Structure_AlignC
  window.i        ; The window object number
  event_type.i    ; Event type
  *element        ; HTML element ID
  *data           ; JavaScript data
  event_number.i  ; Internal WebUI
EndStructure

PrototypeC PrototypeC_webui_event(*e.webui_event_t)

CompilerSelect #PB_Compiler_OS
  CompilerCase #PB_OS_Windows
    ImportC "webui-2-x64.lib"
    ;ImportC "webui-2-static-x64.lib"
    CompilerCase #PB_OS_Linux
      ImportC "webui-2-x64.so"
      CompilerCase #PB_OS_MacOS
        ;ImportC "webui-2-x64.dyn"
        ImportC "webui-2-static-x64.a"
      CompilerEndSelect
      ; Create a new webui window object.
      webui_new_window()
      ; Create a new webui window object.
      webui_new_window_id(window_number.i)
      ; Get a free window ID that can be used with `webui_new_window_id()`
      webui_get_new_window_id.i()
      ; Bind a specific html element click event with a function. Empty element means all events.
      webui_bind.i(window.i, element.p-Ascii, webui_event.PrototypeC_webui_event)
      ; Show a window using a embedded HTML, or a file. If the window is already
      webui_show.i(window.i, content.p-Ascii)
      ; Same as webui_show(). But with a specific web browser.
      webui_show_browser(window.i, content.p-Ascii, browser.i)
      ; Set the window in Kiosk mode (Full screen)
      webui_set_kiosk(window.i, status.i)
      ; Wait until all opened windows get closed.
      webui_wait()
      ; Close a specific window only. The window object will still exist.
      webui_close(window.i)
      ; Close a specific window and free all memory resources.
      webui_destroy(window.i)
      ; Close all opened windows. webui_wait() will break.
      webui_exit()
      ; Set the web-server root folder path.
      webui_set_root_folder.i(window.i, path.p-Ascii)
      
      ; -- Other ---------------------------
      ; Check a specific window if it's still running
      webui_is_shown.i(window.i)
      ; Set the maximum time in seconds to wait for browser to start
      webui_set_timeout(second.i)
      ; Set the default embedded HTML favicon
      webui_set_icon(window.i, icon.p-Ascii, icon_type.p-Ascii)
      ; Allow the window URL to be re-used in normal web browsers
      webui_set_multi_access(window.i, status.b)
      
      ; -- JavaScript ----------------------
      ; Run JavaScript quickly with no waiting for the response.
      webui_run(window.i, script.p-Ascii)
      ; Run a JavaScript, and get the response back (Make sure your local buffer can hold the response).
      webui_script.i(window.i, script.p-Ascii, timeout.i, *buffer, buffer_length.i)
      ; Chose between Deno and Nodejs runtime for .js and .ts files.
      webui_set_runtime(window.i, run_time.i)
      ; Parse argument as integer.
      webui_get_int.q(*e.webui_event_t)
      ; Parse argument as string.
      webui_get_string.i(*e.webui_event_t)
      ; Parse argument as boolean.
      webui_get_bool.i(*e.webui_event_t)
      ; Return the response to JavaScript as integer.
      webui_return_int(*e.webui_event_t, number.i)
      ; Return the response to JavaScript as string.
      webui_return_string(*e.webui_event_t, const.p-Ascii)
      ; Return the response to JavaScript as boolean.
      webui_return_bool(*e.webui_event_t, bool.i)
      ; Base64 encoding. Use this to safely send text based data to the UI. If it fails it will return NULL.
      webui_encode.i(*char)
      ; Base64 decoding. Use this to safely decode received Base64 text from the UI. If it fails it will return NULL.
      webui_decode.i(char.p-Ascii)
      ; Safely free a buffer allocated by WebUI, For example when using webui_encode().
      webui_free(*ptr)
      
      ; -- Interface -----------------------
      ; Bind a specific html element click event with a function. Empty element means all events. This replace webui_bind(). The func is (Window, EventType, Element, Data, EventNumber)
      webui_interface_bind.i(window.i, element.p-Ascii, *func)
      ; When using `webui_interface_bind()` you may need this function to easily set your callback response.
      webui_interface_set_response(window.i, event_number.i, response.p-Ascii)
      ; Check if the app still running or not. This replace webui_wait().
      webui_interface_is_app_running.i()
      ; Get window unique ID
      webui_interface_get_window_id.i(window.i)
      ; Get a unique ID. Same ID as `webui_bind()`. Return > 0 if bind exist.
      webui_interface_get_bind_id.i(window.i, element.p-Ascii)
    EndImport
    
    CompilerIf #PB_Compiler_IsMainFile
      
      Enumeration WebUI_Examples
        #PB_Forum_Example
        #WEBUI_Example_C_call_c_from_js
        #WEBUI_Example_C_call_js_from_c
        #WEBUI_Example_C_minimal
        #WEBUI_Example_C_serve_a_folder
        #WEBUI_Example_C_text_editor
      EndEnumeration
      
      #WebUI_Example = #PB_Forum_Example
      
      CompilerSelect #WebUI_Example
        CompilerCase #PB_Forum_Example
          
          ProcedureC webui_event_proc(*e.webui_event_t)
            Debug "webui_event_proc"
            Debug "Window      : " + Str(*e\window)
            Select *e\event_type
              Case #WEBUI_EVENT_CALLBACK
                Debug "Event_Type  : callback"
              Case #WEBUI_EVENT_CONNECTED
                Debug "Event_Type  : connected"
              Case #WEBUI_EVENT_DISCONNECTED
                Debug "Event_Type  : disconnected"
              Case #WEBUI_EVENT_MOUSE_CLICK
                Debug "Event_Type  : mouse click"
              Case #WEBUI_EVENT_MULTI_CONNECTION
                Debug "Event_Type  : multi connection"
              Case #WEBUI_EVENT_NAVIGATION
                Debug "Event_Type  : navigation"
              Case #WEBUI_EVENT_UNWANTED_CONNECTION
                Debug "Event_Type  : unwanted connection"
            EndSelect
            Debug "Element ID  : " + PeekS(*e\element, -1, #PB_Ascii)
            If *e\data
              Debug "Data        : " + PeekS(*e\data, -1, #PB_Ascii)
            EndIf
            Debug "Event_Number: " + Str(*e\event_number)
          EndProcedure
          
          
          Define.i window
          
          window = webui_new_window()
          webui_bind(window, "button_1", @webui_event_proc())
          webui_show(window, "<html><body><button id='button_1'>Click me!</button></body></html>")
          webui_wait()
          
        CompilerCase #WEBUI_Example_C_call_c_from_js
          ProcedureC my_function_string(*e.webui_event_t)
            
            Protected *str
            
            ; JavaScript:
            ; webui_fn('MyID_One', 'Hello');
            
            *str = webui_get_string(*e)
            Debug "my_function_string: " + PeekS(*str, -1, #PB_Ascii)  ; Hello
            
            ; Need Multiple Arguments?
            ;
            ; WebUI support only one argument. To get multiple arguments
            ; you can send a JSON string from JavaScript then decode it.
            ; Example:
            ;
            ; my_json = my_json_decoder(str);
            ; foo = my_json[0];
            ; bar = my_json[1];
          EndProcedure
          
          ProcedureC my_function_integer(*e.webui_event_t)
            
            Protected number.q
            
            ; JavaScript:
            ; webui_fn('MyID_Two', 123456789);
            
            number = webui_get_int(*e)
            Debug "my_function_integer: " + Str(number) ; 123456789
            
          EndProcedure
          
          ProcedureC my_function_boolean(*e.webui_event_t)
            
            Protected status.i
            
            ; JavaScript:
            ; webui_fn('MyID_Three', true)
            
            status = webui_get_bool(*e) ; True
            If status
              Debug "my_function_boolean: True"
            Else
              Debug "my_function_boolean: False"
            EndIf
            
          EndProcedure
          
          ProcedureC my_function_with_response(*e.webui_event_t)
            
            Protected number.q
            
            ; JavaScript:
            ; const result = webui_fn('MyID_Four', number);
            
            number = webui_get_int(*e)
            number = number * 2
            Debug "my_function_with_response: " + Str(number)
            
            ; Send back the response To JavaScript
            webui_return_int(*e, number)
            
          EndProcedure
          
          
          Define my_html$, my_window.i
          
          my_html$ = ""
          my_html$ + ~"<html>"
          my_html$ + ~"  <head>"
          my_html$ + ~"    <title>Call C from JavaScript Example</title>"
          my_html$ + ~"    <style>"
          my_html$ + ~"      body {"
          my_html$ + ~"        color: white;"
          my_html$ + ~"        background: #0F2027;"
          my_html$ + ~"        text-align: center;"
          my_html$ + ~"        font-size: 16px;"
          my_html$ + ~"        font-family: sans-serif;"
          my_html$ + ~"      }"
          my_html$ + ~"    </style>"
          my_html$ + ~"  </head>"
          my_html$ + ~"  <body>"
          my_html$ + ~"    <h2>WebUI - Call C from JavaScript Example</h2>"
          my_html$ + ~"    <p>Call C function with argument (<em>See the logs in your terminal</em>)</p>"
          my_html$ + ~"    <br>"
          my_html$ + ~"    <button onclick=\"webui_fn('MyID_One', 'Hello');\">Call my_function_string()</button>"
          my_html$ + ~"    <br>"
          my_html$ + ~"    <br>"
          my_html$ + ~"    <button onclick=\"webui_fn('MyID_Two', 123456789);\">Call my_function_integer()</button>"
          my_html$ + ~"    <br>"
          my_html$ + ~"    <br>"
          my_html$ + ~"    <button onclick=\"webui_fn('MyID_Three', true);\">Call my_function_boolean()</button>"
          my_html$ + ~"    <br>"
          my_html$ + ~"    <br>"
          my_html$ + ~"    <p>Call C function and wait for the response</p>"
          my_html$ + ~"    <br>"
          my_html$ + ~"    <button onclick=\"MyJS();\">Call my_function_with_response()</button>"
          my_html$ + ~"    <br>"
          my_html$ + ~"    <br>"
          my_html$ + ~"    <input type=\"text\" id=\"MyInputID\" value=\"2\">"
          my_html$ + ~"    <script>"
          my_html$ + ~"      function MyJS() {"
          my_html$ + ~"        const MyInput = document.getElementById('MyInputID');"
          my_html$ + ~"        const number = MyInput.value;"
          my_html$ + ~"        webui_fn('MyID_Four', number).then((response) => {"
          my_html$ + ~"            MyInput.value = response;"
          my_html$ + ~"        });"
          my_html$ + ~"      }"
          my_html$ + ~"    </script>"
          my_html$ + ~"  </body>"
          my_html$ + ~"</html>"
          
          ; Create a window
          my_window = webui_new_window()
          
          ; Bind HTML elements With C functions
          webui_bind(my_window, "MyID_One", @my_function_string())
          webui_bind(my_window, "MyID_Two", @my_function_integer())
          webui_bind(my_window, "MyID_Three", @my_function_boolean())
          webui_bind(my_window, "MyID_Four", @my_function_with_response())
          
          ; Show the window
          webui_show(my_window, my_html$) ; webui_show_browser(my_window, my_html, Chrome)
          
          ; Wait Until all windows get closed
          webui_wait()
          
          
        CompilerCase #WEBUI_Example_C_call_js_from_c
          ProcedureC my_function_exit(*e.webui_event_t)
            webui_exit()
          EndProcedure
          
          ProcedureC my_function_count(*e.webui_event_t)
            ; This function gets called every time the user clicks on "MyButton1"
            
            ; Create a buffer To hold the response
            Protected *response, Count.i
            
            *response = AllocateMemory(64)
            
            ; Run JavaScript
            If Not webui_script(*e\window, "return GetCount();", 0, *response, 64)
              Debug "JavaScript Error: " + PeekS(*response, -1, #PB_Ascii)
              ProcedureReturn
            EndIf
            
            Debug PeekS(*response, -1, #PB_Ascii)
            
            ; Get the count
            count = Val(PeekS(*response, -1, #PB_Ascii))
            
            ; Increment
            count + 1
            
            ; Generate a JavaScript
            
            ; Run JavaScript (Quick Way)
            webui_run(*e\window, "SetCount(" + Str(Count) + ")")
          EndProcedure
          
          
          Define my_html$, my_window.i
          
          my_html$ = ~"<html>"
          my_html$ + ~"  <head>"
          my_html$ + ~"    <title>Call JavaScript from C Example</title>"
          my_html$ + ~"    <style>"
          my_html$ + ~"      body {"
          my_html$ + ~"        color: white;"
          my_html$ + ~"        background: #0F2027;"
          my_html$ + ~"        text-align: center;"
          my_html$ + ~"        font-size: 16px;"
          my_html$ + ~"        font-family: sans-serif;"
          my_html$ + ~"      }"
          my_html$ + ~"    </style>"
          my_html$ + ~"  </head>"
          my_html$ + ~"  <body>"
          my_html$ + ~"    <h2>WebUI - Call JavaScript from C Example</h2>"
          my_html$ + ~"    <br>"
          my_html$ + ~"    <h1 id=\"MyElementID\">Count is ?</h1>"
          my_html$ + ~"    <br>"
          my_html$ + ~"    <br>"
          my_html$ + ~"    <button id=\"MyButton1\">Count</button>"
          my_html$ + ~"    <br>"
          my_html$ + ~"    <br>"
          my_html$ + ~"    <button id=\"MyButton2\">Exit</button>"
          my_html$ + ~"    <script>"
          my_html$ + ~"      var count = 0;"
          my_html$ + ~"      function GetCount() {"
          my_html$ + ~"        return count;"
          my_html$ + ~"      }"
          my_html$ + ~"      function SetCount(number) {"
          my_html$ + ~"        const MyElement = document.getElementById('MyElementID');"
          my_html$ + ~"        MyElement.innerHTML = 'Count is ' + number;"
          my_html$ + ~"        count = number;"
          my_html$ + ~"      }"
          my_html$ + ~"    </script>"
          my_html$ + ~"  </body>"
          my_html$ + ~"</html>";
          
          ; Create a window
          my_window = webui_new_window()
          
          ; Bind HTML elements With C functions
          webui_bind(my_window, "MyButton1", @my_function_count())
          webui_bind(my_window, "MyButton2", @my_function_exit())
          
          ; Show the window
          webui_show(my_window, my_html$) ; webui_show_browser(my_window, my_html, Chrome)
          
          ; Wait Until all windows get closed
          webui_wait()
          
          
        CompilerCase #WEBUI_Example_C_minimal
          Define my_window.i
          
          my_window = webui_new_window();
          webui_show(my_window, "<html>Hello</html>")
          webui_wait()
          
          
        CompilerCase #WEBUI_Example_C_serve_a_folder
          
          #MyWindow = 1
          #MySecondWindow = 2
          
          ProcedureC exit_app(*e.webui_event_t)
            
            ; Close all opened windows
            webui_exit()
          EndProcedure
          
          ProcedureC events(*e.webui_event_t)
            
            ; This function gets called every time
            ; there is an event
            
            If *e\event_type = #WEBUI_EVENT_CONNECTED
              Debug "Connected."
            ElseIf *e\event_type = #WEBUI_EVENT_DISCONNECTED
              Debug "Disconnected."
            ElseIf *e\event_type = #WEBUI_EVENT_MOUSE_CLICK
              Debug "Click."
            ElseIf *e\event_type = #WEBUI_EVENT_NAVIGATION
              Debug "Starting navigation to: " + PeekS(*e\Data, -1, #PB_Ascii)
            EndIf
          EndProcedure
          
          ProcedureC switch_to_second_page(*e.webui_event_t)
            
            ; This function gets called every
            ; time the user clicks on "SwitchToSecondPage"
            
            ; Switch To `/second.html` in the same opened window.
            webui_show(*e\window, "second.html")
          EndProcedure
          
          ProcedureC show_second_window(*e.webui_event_t)
            
            ; This function gets called every
            ; time the user clicks on "OpenNewWindow"
            
            ; Show a new window, And navigate To `/second.html`
            ; If it's already open, then switch in the same window
            webui_show(#MySecondWindow, "second.html")
            
          EndProcedure
          
          
          
          ; Create new windows
          webui_new_window_id(#MyWindow)
          webui_new_window_id(#MySecondWindow)
          
          ; Bind HTML element IDs With a C functions
          webui_bind(#MyWindow, "SwitchToSecondPage", @switch_to_second_page())
          webui_bind(#MyWindow, "OpenNewWindow", @show_second_window())
          webui_bind(#MyWindow, "Exit", @exit_app())
          webui_bind(#MySecondWindow, "Exit", @exit_app())
          
          ; Bind events
          webui_bind(#MyWindow, "", @events())
          
          ; Make Deno As the `.ts` And `.js` interpreter
          webui_set_runtime(#MyWindow, #Deno)
          
          ; Show a new window
          ; webui_set_root_folder(MyWindow, "_MY_PATH_HERE_");
          ; webui_show_browser(MyWindow, "index.html", Chrome);
          webui_show(#MyWindow, "index.html")
          
          ; Wait Until all windows get closed
          webui_wait()
          
          
          
        CompilerCase #WEBUI_Example_C_text_editor
          
          #FULL_FILE_BUFFER_SIZE = (2 * 1024 * 1024)    ; 2 MB
          Global *FULL_FILE_BUFFER
          *FULL_FILE_BUFFER = AllocateMemory(#FULL_FILE_BUFFER_SIZE, #PB_Memory_NoClear)
          Global JAVASCRIPT_BUFFER$
          Global FILE_PATH$
          
          ProcedureC Close(*e.webui_event_t)
            Debug "Exit."
            
            ; Close all opened windows
            webui_exit()
          EndProcedure
          
          ProcedureC Save(*e.webui_event_t)
            
            Protected file.i
            
            Debug "Save."
            
            ; Save Data received from the UI
            file = CreateFile(#PB_Any, FILE_PATH$)
            If file
              WriteString(file, PeekS(*e\Data, -1, #PB_Ascii))
              CloseFile(file)
            EndIf
          EndProcedure
          
          ProcedureC Open(*e.webui_event_t)
            
            Protected bytes_read.i, file.i, *file_encoded, *path_encoded, *file_path
            
            Debug "Open."
            
            ; Open a new file
            
            ; Open file And save the path To FILE_PATH
            FILE_PATH$ = OpenFileRequester("Choose a text file", "", "All|*.*", 0)
            If Len(FILE_PATH$) = 0
              ProcedureReturn
            EndIf
            
            ; Read the full content To FULL_FILE_BUFFER
            file = ReadFile(#PB_Any, FILE_PATH$)
            If file
              bytes_read = ReadData(file, *FULL_FILE_BUFFER, Lof(file))
              If bytes_read <> Lof(file)
                CloseFile(file)
                ProcedureReturn
              EndIf
              CloseFile(file)
            EndIf
            
            ; Send file content
            ; Encode the full content To base64
            *file_encoded = webui_encode(*FULL_FILE_BUFFER)
            If *file_encoded = #Null
              ProcedureReturn
            EndIf
            JAVASCRIPT_BUFFER$ = "addText('" + PeekS(*file_encoded, -1, #PB_Ascii) + "')"
            webui_run(*e\window, JAVASCRIPT_BUFFER$)
            
            ; Send file name
            ; Encode the file path To base64
            *file_path = Ascii(FILE_PATH$)
            *path_encoded = webui_encode(*file_path)
            FreeMemory(*file_path)
            If *path_encoded = #Null
              webui_free(*file_encoded)
              ProcedureReturn
            EndIf
            JAVASCRIPT_BUFFER$ = "SetFile('" + PeekS(*path_encoded, -1, #PB_Ascii) + "')"
            webui_run(*e\window, JAVASCRIPT_BUFFER$)
            
            ; Clean
            webui_free(*file_encoded)
            webui_free(*path_encoded)
            
            ;         // Add line by line example:
            ;         FILE *file = fopen(FILE_PATH, "r");
            ;         If(file == NULL)
            ;             Return;
            ;         char line[1024] = {0};
            ;         While (fgets(line, 1024, file) != NULL) {
            ;             // Line
            ;             char* line_encoded = webui_encode(line);
            ;             If(line_encoded != NULL) {
            ;                 char js[1024] = {0};
            ;                 // JS
            ;                 sprintf(js, "addLine('%s')", line_encoded);
            ;                 // Send
            ;                 webui_run(e->window, js);
            ;                 // Clean
            ;                 webui_free(line_encoded);
            ;             }
            ;         }
            ;         fclose(file);
            
          EndProcedure
          
          Define MainWindow.i
          
          MainWindow = webui_new_window()
          
          ; Bind HTML element IDs With a C functions
          webui_bind(MainWindow, "Open", @Open())
          webui_bind(MainWindow, "Save", @Save())
          webui_bind(MainWindow, "Close", @Close())
          
          ; Show a new window
          webui_show(MainWindow, "ui/MainWindow.html")
          
          ; Wait Until all windows get closed
          webui_wait()
          
      CompilerEndSelect
      
    CompilerEndIf
Last edited by infratec on Tue Jun 13, 2023 9:58 pm, edited 8 times in total.
User avatar
idle
Always Here
Always Here
Posts: 5838
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

Re: WebUI wrapper

Post by idle »

looks good and is cross platform.

It's actually similar to my civetserver project, which just runs a local civetweb http/https server, so it facilitates you to use any browser, has webSocket, SSL, and works with PB and it compiles to one exe, with no dependences, even your www assets are bundled into the exe and caught from memory at runtime directly from memory.
User avatar
Kuron
Addict
Addict
Posts: 1626
Joined: Sat Oct 17, 2009 10:51 pm
Location: Pacific Northwest

Re: WebUI wrapper

Post by Kuron »

There were several older threads where people were asking for something like this and looking at other products to get them working with PB. Hopefully they will discover this thread.
Best wishes to the PB community. Thank you for the memories. ♥️
infratec
Always Here
Always Here
Posts: 7583
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: WebUI wrapper

Post by infratec »

But I miss the possibility to handle the window from extern, like size and position.
infratec
Always Here
Always Here
Posts: 7583
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: WebUI wrapper

Post by infratec »

Added the examples.
But the text_edit behaves a bit strange: Needed sometimes multiple clicks.
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: WebUI wrapper

Post by Fred »

infratec wrote: Mon Jun 12, 2023 6:42 am But I miss the possibility to handle the window from extern, like size and position.
Seems like you can do with javascript: https://github.com/webui-dev/webui/issues/98
infratec
Always Here
Always Here
Posts: 7583
Joined: Sun Sep 07, 2008 12:45 pm
Location: Germany

Re: WebUI wrapper

Post by infratec »

Yes,

but then you have to 'inject' this commands in an existing website which is not always from you.
That's why I wrote from extern.

If I want to open it in 800 by 600 screen centered before the web content is loaded I run into a problem.
Or I need again API per OS
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: WebUI wrapper

Post by Fred »

What do you mean by website ? You control all the UI as you are the only one to create it or I miss something ?
dige
Addict
Addict
Posts: 1391
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: WebUI wrapper

Post by dige »

That looks exciting! Can this also serve as a replacement for the WebGadget? How can I display the website https://www.whatsmybrowser.org/?
"Daddy, I'll run faster, then it is not so far..."
Fred
Administrator
Administrator
Posts: 18162
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: WebUI wrapper

Post by Fred »

I don't think it's meant to be a WebGadget replacement as you can't embed it in another window. May be you can access other website with an iframe.
Post Reply