Update C++ wrapper

This commit is contained in:
Hassan DRAGA 2023-10-06 17:25:47 -04:00
parent 6d5612c24d
commit 022391380f
4 changed files with 113 additions and 109 deletions

View File

@ -9,54 +9,55 @@
void my_function_string(webui::window::event* e) {
// JavaScript:
// webui.call('MyID_One', 'Hello');
// webui.call('MyID_One', 'Hello', 'World`);
std::string str = e->get_string();
std::cout << "my_function_string: " << str << std::endl; // Hello
std::string str_1 = e->get_string(); // Or e->get_string(0);
std::string str_2 = e->get_string(1);
// 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];
std::cout << "my_function_string 1: " << str_1 << std::endl; // Hello
std::cout << "my_function_string 2: " << str_2 << std::endl; // World
}
void my_function_integer(webui::window::event* e) {
// JavaScript:
// webui.call('MyID_Two', 123456789);
// webui.call('MyID_Two', 123, 456, 789);
long long number = e->get_int();
std::cout << "my_function_integer: " << number << std::endl; // 123456789
long long number_1 = e->get_int(); // Or e->get_int(0);
long long number_2 = e->get_int(1);
long long number_3 = e->get_int(2);
std::cout << "my_function_integer 1: " << number_1 << std::endl; // 123
std::cout << "my_function_integer 2: " << number_2 << std::endl; // 456
std::cout << "my_function_integer 3: " << number_3 << std::endl; // 789
}
void my_function_boolean(webui::window::event* e) {
// JavaScript:
// webui.call('MyID_Three', true);
// webui.call('MyID_Three', true, false);
bool status = e->get_bool(); // True
if(status)
std::cout << "my_function_boolean: True" << std::endl;
else
std::cout << "my_function_boolean: False" << std::endl;
bool status_1 = e->get_bool(); // Or e->get_bool(0);
bool status_2 = e->get_bool(1);
std::cout << "my_function_boolean 1: " << (status_1 ? "True" : "False") << std::endl;
std::cout << "my_function_boolean 2: " << (status_2 ? "True" : "False") << std::endl;
}
void my_function_with_response(webui::window::event* e) {
// JavaScript:
// const result = webui.call('MyID_Four', number);
// webui.call('MyID_Four', number, 2).then(...)
long long number = e->get_int();
number = number * 2;
std::cout << "my_function_with_response: " << number << std::endl;
long long number = e->get_int(0);
long long times = e->get_int(1);
long long res = number * times;
std::cout << "my_function_with_response: " << number << " * " << times << " = " << res << std::endl;
// Send back the response to JavaScript
e->return_int(number);
e->return_int(res);
}
int main() {
@ -85,11 +86,11 @@ int main() {
<body>
<h1>WebUI - Call C++ from JavaScript</h1>
<p>Call C++ functions with arguments (<em>See the logs in your terminal</em>)</p>
<button onclick="webui.call('MyID_One', 'Hello');">Call my_function_string()</button>
<button onclick="webui.call('MyID_One', 'Hello', 'World');">Call my_function_string()</button>
<br>
<button onclick="webui.call('MyID_Two', 123456789);">Call my_function_integer()</button>
<button onclick="webui.call('MyID_Two', 123, 456, 789);">Call my_function_integer()</button>
<br>
<button onclick="webui.call('MyID_Three', true);">Call my_function_boolean()</button>
<button onclick="webui.call('MyID_Three', true, false);">Call my_function_boolean()</button>
<br>
<p>Call a C++ function that returns a response</p>
<button onclick="MyJS();">Call my_function_with_response()</button>
@ -98,7 +99,7 @@ int main() {
function MyJS() {
const MyInput = document.getElementById('MyInputID');
const number = MyInput.value;
webui.call('MyID_Four', number).then((response) => {
webui.call('MyID_Four', number, 2).then((response) => {
MyInput.value = response;
});
}

View File

@ -30,7 +30,10 @@ void my_function_count(webui::window::event* e) {
// Run JavaScript
if(!e->get_window().script("return GetCount();", 0, response, 64)) {
std::cout << "JavaScript Error: " << response << std::endl;
if(!e->get_window().is_shown())
std::cout << "Window closed." << std::endl;
else
std::cout << "JavaScript Error: " << response << std::endl;
return;
}
@ -56,13 +59,12 @@ int main() {
<head>
<meta charset="UTF-8">
<script src="webui.js"></script>
<title>Call JavaScript from C++ Example</title>
<style>
body {
background: linear-gradient(to left, #36265a, #654da9);
color: AliceBlue;
font-size: 16px sans-serif;
font: 16px sans-serif;
text-align: center;
margin-top: 30px;
}
@ -74,7 +76,11 @@ int main() {
<body>
<h1>WebUI - Call JavaScript from C++</h1>
<br>
<button id="MyButton1">Count <span id="count">0</span></button>
<h1 id="count">0</h1>
<br>
<button id="MyButton1">Manual Count</button>
<br>
<button id="MyTest" onclick="AutoTest();">Auto Count (Every 10ms)</button>
<br>
<button id="MyButton2">Exit</button>
<script>
@ -86,6 +92,11 @@ int main() {
document.getElementById('count').innerHTML = number;
count = number;
}
function AutoTest(number) {
setInterval(function() {
webui.call('MyButton1');
}, 10);
}
</script>
</body>
</html>

View File

@ -14,7 +14,6 @@ class MyClass {
// This method gets called every time the
// user clicks on "OpenNewWindow"
void show_second_window(webui::window::event* e) {
// Show a new window, and navigate to `/second.html`
// if the window is already opened, then switch in the same window
my_second_window.show("second.html");
@ -23,7 +22,6 @@ class MyClass {
// This method gets called every time the
// user clicks on "SwitchToSecondPage"
void switch_to_second_page(webui::window::event* e) {
// Switch to `/second.html` in the same opened window.
e->get_window().show("second.html");
}
@ -32,34 +30,35 @@ class MyClass {
// This function receives all events because
// it's get bind with an empty HTML ID.
void events(webui::window::event* e) {
if (e->event_type == webui::CONNECTED)
std::cout << "Window Connected." << std::endl;
else if (e->event_type == webui::DISCONNECTED)
std::cout << "Window Disconnected." << std::endl;
else if (e->event_type == webui::MOUSE_CLICK)
std::cout << "Click on element: " << e->element << std::endl;
else if (e->event_type == webui::NAVIGATION)
std::cout << "Starting navigation to: " << e->data << std::endl;
else if (e->event_type == webui::NAVIGATION) {
std::string url = e->get_string();
std::cout << "Starting navigation to: " << url << std::endl;
e->get_window().navigate(url);
}
}
// Example of a simple function (Not a method)
void exit_app(webui::window::event* e) {
// Close all opened windows
webui::exit();
}
};
// Wrapper:
// Because WebUI is written in C, so it can not
// access `MyClass` directly. That's why we should
// create a simple C++ wrapper.
MyClass obj;
void show_second_window_wrp(webui::window::event* e) { obj.show_second_window(e); }
void switch_to_second_page_wrp(webui::window::event* e) { obj.switch_to_second_page(e); }
void events_wrp(webui::window::event* e) { obj.events(e); }
void exit_app_wrp(webui::window::event* e) { obj.exit_app(e); }
// -- MyClass C Wrapper ------------------------------------------------------------------------
// Because WebUI is written in C, so it can not access `MyClass` directly.
// That's why we should create a simple C++ wrapper.
MyClass myClassObj;
void show_second_window_wrp(webui::window::event* e) { myClassObj.show_second_window(e); }
void switch_to_second_page_wrp(webui::window::event* e) { myClassObj.switch_to_second_page(e); }
void events_wrp(webui::window::event* e) { myClassObj.events(e); }
void exit_app_wrp(webui::window::event* e) { myClassObj.exit_app(e); }
// ---------------------------------------------------------------------------------------------
int main() {
@ -76,7 +75,8 @@ int main() {
my_second_window.bind("Exit", exit_app_wrp);
// Bind all events
// my_window.bind("", events_wrp);
my_window.bind("", events_wrp);
my_second_window.bind("", events_wrp);
// Show a new window
my_window.show("index.html"); // my_window.show_browser("index.html", Chrome);

View File

@ -25,11 +25,9 @@ namespace webui {
static constexpr int DISCONNECTED = 0; // 0. Window disconnection event
static constexpr int CONNECTED = 1; // 1. Window connection event
static constexpr int MULTI_CONNECTION = 2; // 2. New window connection event
static constexpr int UNWANTED_CONNECTION = 3; // 3. New unwanted window connection event
static constexpr int MOUSE_CLICK = 4; // 4. Mouse click event
static constexpr int NAVIGATION = 5; // 5. Window navigation event
static constexpr int CALLBACKS = 6; // 6. Function call event
static constexpr int MOUSE_CLICK = 2; // 2. Mouse click event
static constexpr int NAVIGATION = 3; // 3. Window navigation event
static constexpr int CALLBACKS = 4; // 4. Function call event
class window {
private:
@ -69,28 +67,22 @@ namespace webui {
~handler() = delete;
static void add(size_t id, webui::window* win, callback_t func) {
// Save window object
window_list[id] = win;
// Save callback
callback_list[id] = func;
}
static void handle(webui_event_t* c_e) {
// Get a unique ID. Same ID as `webui_bind()`. Return > 0 if bind exist.
const size_t id = webui_interface_get_bind_id(c_e->window, c_e->element);
if(id < 1){
return;
// Get the binded unique ID
const size_t id = c_e->bind_id;
if(id > 0) {
// Create a new event struct
event e(*window_list[id], *c_e);
// Call the user callback
if(callback_list[id] != nullptr)
callback_list[id](&e);
}
// Create a new event struct
event e(*window_list[id], *c_e);
// Call the user callback
if(callback_list[id] != nullptr)
callback_list[id](&e);
}
static webui::window& get_window(const size_t index){
@ -98,23 +90,29 @@ namespace webui {
}
};
// Parse argument as integer.
long long int get_int() {
return webui_get_int(this);
// Get an argument as integer at a specific index.
long long int get_int(size_t index = 0) {
return webui_get_int_at(this, index);
}
// Parse argument as string.
std::string get_string() {
return std::string{webui_get_string(this)};
// Get the size in bytes of an argument at a specific index.
size_t get_size(size_t index = 0) {
return webui_get_size_at(this, index);
}
std::string_view get_string_view() {
return std::string_view{webui_get_string(this)};
// Get an argument as string at a specific index.
std::string get_string(size_t index = 0) {
return std::string{webui_get_string_at(this, index)};
}
// Parse argument as boolean.
bool get_bool() {
return webui_get_bool(this);
// Get an argument as string_view at a specific index.
std::string_view get_string_view(size_t index = 0) {
return std::string_view{webui_get_string_at(this, index)};
}
// Get an argument as boolean at a specific index.
bool get_bool(size_t index = 0) {
return webui_get_bool_at(this, index);
}
// Return the response to JavaScript as integer.
@ -144,10 +142,6 @@ namespace webui {
return std::string_view{element};
}
std::string_view get_data() const {
return std::string_view{data};
}
size_t number() const {
return event_number;
}
@ -155,10 +149,8 @@ namespace webui {
// Bind a specific html element click event with a function. Empty element means all events.
void bind(const std::string_view element, event::handler::callback_t func) {
// Get unique ID
const size_t id = webui_bind(webui_window, element.data(), event::handler::handle);
event::handler::add(id, this, func);
}
@ -197,11 +189,6 @@ namespace webui {
webui_set_icon(webui_window, icon.data(), icon_type.data());
}
// Allow the window URL to be re-used in normal web browsers
void set_multi_access(bool status) const {
webui_set_multi_access(webui_window, status);
}
// Safely send raw data to the UI
void send_raw(const std::string_view function, const void* raw, size_t size) const {
webui_send_raw(webui_window, function.data(), raw, size);
@ -237,23 +224,6 @@ namespace webui {
return webui_get_child_process_id(webui_window);
}
// -- JavaScript ----------------------
// Quickly run a JavaScript (no response waiting).
void run(const std::string_view script) const {
webui_run(webui_window, script.data());
}
// Run a JavaScript, and get the response back (Make sure your local buffer can hold the response).
bool script(const std::string_view script, unsigned int timeout, char* buffer, size_t buffer_length) const {
return webui_script(webui_window, script.data(), timeout, buffer, buffer_length);
}
// Chose between Deno and Nodejs runtime for .js and .ts files.
void set_runtime(unsigned int runtime) const {
webui_set_runtime(webui_window, runtime);
}
// Set the web-server root folder path for this specific window.
bool set_root_folder(const std::string_view path) const {
return webui_set_root_folder(webui_window, path.data());
@ -273,6 +243,28 @@ namespace webui {
std::string_view get_url() const {
return std::string_view{webui_get_url(webui_window)};
}
// Navigate to a specific URL.
void navigate(const std::string_view url) const {
webui_navigate(webui_window, url.data());
}
// -- JavaScript ----------------------
// Quickly run a JavaScript (no response waiting).
void run(const std::string_view script) const {
webui_run(webui_window, script.data());
}
// Run a JavaScript, and get the response back (Make sure your local buffer can hold the response).
bool script(const std::string_view script, unsigned int timeout, char* buffer, size_t buffer_length) const {
return webui_script(webui_window, script.data(), timeout, buffer, buffer_length);
}
// Chose between Deno and Nodejs runtime for .js and .ts files.
void set_runtime(unsigned int runtime) const {
webui_set_runtime(webui_window, runtime);
}
};
// Wait until all opened windows get closed.