WebUI 2.0

This commit is contained in:
Hassan DRAGA 2022-09-24 19:35:56 -04:00
parent afce31edc3
commit a89dfd8a2d
30 changed files with 11896 additions and 5488 deletions

27
.gitignore vendored
View File

@ -1,21 +1,14 @@
build/
**/logs
*/logs
*.logs
**/exe
*/exe
# Bin
*.exe
*.dll
*.so
*.dylib
*.a
**/obj
*/obj
*.obj
**/o
*/o
# Obj
*.out
*.o
**/.vscode
*/.vscode
*..vscode
# IDE
.idea/
.vscode/

View File

@ -1,63 +0,0 @@
cmake_minimum_required(VERSION 3.13.0)
# --[ WebUI version ] --------------------------------------------------------------
project(webui VERSION 1.0.20 DESCRIPTION
"Use your web browser as UI, and bring the web technologies to your app.")
message("-- [ WebUI version ${CMAKE_PROJECT_VERSION} ]")
# --[ Boost ] ----------------------------------------------------------------------
set(Boost_Version_Needed "1.76.0")
set(Boost_NO_WARN_NEW_VERSIONS ON)
if (WIN32)
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if(EXISTS "C:/Alif3/")
# Windows - Boost
message("[*] Using Boost embeded with Alif v3 'C:/Alif3/boost'")
set(Boost_Root "C:/Alif3/boost/include")
set(Boost_Lib "C:/Alif3/boost/lib")
set(BOOST_ROOT ${Boost_Root})
set(Boost_LIBRARY_DIR ${Boost_Lib})
message("[*] Using Boost root: ${BOOST_ROOT}")
message("[*] Using Boost lib: ${Boost_LIBRARY_DIR}")
endif()
endif()
endif()
# --[ C++ ] ------------------------------------------------------------------------
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
# --[ Targets ] --------------------------------------------------------------------
if (WIN32)
set(webui_lib "webui_win_x86_64")
set(cwebui_lib "cwebui_win_x86_64")
elseif(UNIX)
set(webui_lib "webui_linux_x86_64")
set(cwebui_lib "cwebui_linux_x86_64")
else()
set(webui_lib "webui_macos_x86_64")
set(cwebui_lib "cwebui_macos_x86_64")
endif()
# --[ Directories ] ----------------------------------------------------------------
# WebUI Library
add_subdirectory(${webui_SOURCE_DIR}/src webui)
# Examples
add_subdirectory(${webui_SOURCE_DIR}/examples)
# cWebUI Library
# if(TARGET cwebui)
add_subdirectory(${webui_SOURCE_DIR}/cwebui EXCLUDE_FROM_ALL)
# endif()
# Test
# include(CTest)
# enable_testing()
# add_subdirectory(${webui_SOURCE_DIR}/test)

View File

@ -1,152 +0,0 @@
# Info
set(Info_Title "cWebUI")
set(Info_Source ${webui_SOURCE_DIR}/src/webui.cpp "cwebui.cpp")
set(Info_App ${cwebui_lib})
# --[ cWebUI ] -----------------------------------------------------------------
include_directories(${webui_SOURCE_DIR}/include)
link_directories(${webui_BIN_DIR}/webui)
# --[ Boost ] ----------------------------------------------------------------------
message("[*] Initializing Boost for ${Info_Title}...")
set(Boost_NO_WARN_NEW_VERSIONS ON)
if (WIN32)
set(Boost_ARCHITECTURE "-x64")
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(Boost_USE_STATIC_RUNTIME OFF)
else()
set(Boost_USE_STATIC_RUNTIME ON)
endif()
# set(Boost_COMPILER "-mgw8")
# set(Boost_DETAILED_FAILURE_MSG OFF)
# set(Boost_DEBUG OFF)
# set(Boost_THREADAPI "win32")
# set(Boost_COMPILER "-vc142")
# add_definitions( -DBOOST_ALL_NO_LIB )
else()
# set(Boost_DEBUG OFF)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
# set(Boost_ARCHITECTURE "-x64")
# set(Boost_THREADAPI "pthread")
# set(Boost_DETAILED_FAILURE_MSG ON)
# set(Boost_COMPILER "-gcc")
add_definitions( -DBOOST_ALL_NO_LIB )
endif()
message("[*] Searching for Boost libs...")
find_package(Boost ${Boost_Version_Needed} REQUIRED COMPONENTS date_time filesystem regex)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
else()
message("[!] Please install Boost lib.")
return()
endif()
# --[ pThread ] -----------------------------------------------------------------
if(UNIX)
message("[*] Using POSIX threading (pThread).")
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
endif (UNIX)
# --[ Python ] ------------------------------------------------------------------
message("[*] Searching for Python...")
find_package (Python 3.8.0 COMPONENTS Development)
if(Python_FOUND)
include_directories(${Python_INCLUDE_DIRS})
link_directories(${Python_LIBRARY_DIRS})
else()
message("[!] Please install Python.")
#return()
endif()
# --[ Target ] ------------------------------------------------------------------
add_library(${Info_App} SHARED ${Info_Source})
set_target_properties(${Info_App} PROPERTIES VERSION ${PROJECT_VERSION})
# --[ Compiler flags ] ----------------------------------------------------------
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# using Clang
message("[*] Initializing '${Info_Title}' settings for Clang.")
target_compile_options(${Info_App} PUBLIC -shared -fPIC -O2)
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if (WIN32)
# using MinGW/GCC Windows
message("[*] Initializing '${Info_Title}' settings for MinGW/GCC (Windows).")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj -fvisibility=hidden -Wall -O3 -std=gnu++17" )
target_compile_options(${Info_App} PUBLIC -fPIC -Wl,-Bstatic -lboost_filesystem -Wl,-Bshared)
else()
# using GCC lINUX
message("[*] Initializing '${Info_Title}' settings for GCC (Linux).")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -O3 -std=gnu++17" )
target_compile_options(${Info_App} PUBLIC -fPIC -Wl,-Bstatic -lboost_filesystem -Wl,-Bshared)
endif()
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
# using Intel C++
message("[*] Initializing '${Info_Title}' settings for Intel.")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# Microsoft build tools
message("[*] Initializing '${Info_Title}' settings for MSVC.")
# Flags (WINDOWS / CONSOLE)
#add_link_options("/SUBSYSTEM:WINDOWS")
#set_target_properties(${Info_App} PROPERTIES LINK_FLAGS "/WHOLEARCHIVE")
set_property(TARGET ${Info_App} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
set(CMAKE_CXX_STANDARD 20)
#add_compile_options("-shared -fPIC -O2")
#SET(F_PIC "-shared -fPIC -O2")
#SET(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${F_PIC}")
#target_compile_options(${Info_App} PUBLIC --enable-pic -O2)
endif()
# --[ Build ] -------------------------------------------------------------------
# Add the static lib WebUI to our shared
# lib cWebUI.
#target_link_libraries(${Info_App} webui)
if(UNIX)
target_link_libraries(${Info_App} PRIVATE ${Boost_LIBRARIES} ${PYTHON_LIBRARIES} Threads::Threads)
else()
target_link_libraries(${Info_App} PRIVATE ws2_32 wsock32 ${Boost_LIBRARIES} ${PYTHON_LIBRARIES})
endif (UNIX)
configure_file(${webui_SOURCE_DIR}/cwebui/helloworld.py ${CMAKE_CURRENT_BINARY_DIR}/helloworld.py COPYONLY)

View File

@ -1,137 +0,0 @@
/*
cWebUI Library
- - - - - - -
http://webui.me
https://github.com/alifcommunity/webui
Licensed under GNU General Public License v3.0.
Copyright (C)2020 Hassan DRAGA <https://github.com/hassandraga>.
*/
#ifndef UNICODE
#define UNICODE
#endif
// C++ headers
#include <iostream>
#include <string>
#include <new>
#include <thread>
#include <vector>
// WebUI headers
#include <webui/webui.hpp>
// Python headers
#define PY_SSIZE_T_CLEAN
#include <Python.h>
// Defines
#ifdef _WIN32
#define DLLEXPORT extern "C" __declspec(dllexport)
#else
#define DLLEXPORT extern "C"
#endif
bool py_initialized = false;
static std::vector<PyObject *> callback_obj_v;
static std::vector<void (*)()> callback_void_v;
DLLEXPORT void c_handler(webui::event e) {
if (!PyCallable_Check(callback_obj_v[e.id])){
std::cerr << "WebUI Err: callback obj not callable. " << std::endl;
return;
}
try {
// Calling python function using PyObject
// PyObject *result;
// result = PyObject_CallObject(callback_obj_v[e.id], NULL); <-- This crash python interepter!
// if(result == NULL)
// std::cerr << "WebUI Err: failed to call obj (null return). " << std::endl;
// Calling python function using void pointer
if(callback_void_v[e.id])
(*callback_void_v[e.id])();
}
catch(...) {
std::cerr << "WebUI Err: failed to call obj (exception). " << std::endl;
}
}
DLLEXPORT void * c_create_window(void) {
return new(std::nothrow) webui::window;
}
DLLEXPORT void c_destroy_window(void *ptr) {
if(ptr)
delete ptr;
}
DLLEXPORT int c_show_window(void *ptr, char * html) {
try {
std::string _html = html;
webui::window * ref = reinterpret_cast<webui::window *>(ptr);
return ref->show(_html);
}
catch(...) {
return -1;
}
}
DLLEXPORT void c_bind_element(void *ptr, char const *id, PyObject *callback_obj, void (*callback_void)()) {
// callback_obj: python function as PyObject
// callback_void: python function as void pointer
static PyObject *callback_obj_temp = NULL;
std::string _id = id;
webui::window * ref = reinterpret_cast<webui::window *>(ptr);
if (!PyCallable_Check(callback_obj)){
std::cerr << "WebUI Err: callback obj not callable. " << std::endl;
return;
}
int elem_id = ref->bind(_id, c_handler);
Py_XINCREF(callback_obj); // Add a reference to new callback
Py_XDECREF(callback_obj_temp); // Dispose of previous callback
callback_obj_temp = callback_obj; // Remember new callback
callback_obj_v.push_back(callback_obj_temp);
callback_void_v.push_back(callback_void);
}
DLLEXPORT void c_loop (void) {
std::thread ui(webui::loop);
ui.join();
}
DLLEXPORT bool c_any_is_show (void) {
return webui::any_is_show();
}
DLLEXPORT void c_ini (void) {
if(!py_initialized){
py_initialized = true;
callback_obj_v.clear();
callback_obj_v.push_back(NULL);
callback_void_v.clear();
callback_void_v.push_back(NULL);
webui::ini();
}
}

View File

@ -1,108 +0,0 @@
# -------------------------------------------------------------------------------
# cWebUI
# - - - -
# http://webui.me
# https://github.com/alifcommunity/webui
# Licensed under GNU General Public License v3.0.
# Copyright (C)2020 Hassan DRAGA <https://github.com/hassandraga>.
# -------------------------------------------------------------------------------
# ---[ WebUI Class ]--------------------------------------------------------------
import os
import platform
import sys
import ctypes
from ctypes import cdll, c_void_p, CFUNCTYPE, POINTER
class WebUI:
webui_lib = None
window = None
cb_fun = None
cb_fun_list = []
def __init__(self):
webui_wrapper = None
try:
if platform.system() == 'Darwin':
self.webui_lib = ctypes.CDLL('cwebui.dylib')
elif platform.system() == 'Windows':
if sys.version_info.major == 3 and sys.version_info.minor == 8:
os.chdir(os.getcwd())
os.add_dll_directory(os.getcwd())
self.webui_lib = ctypes.CDLL('cwebui.dll')
#self.webui_lib = cdll.LoadLibrary('cwebui.dll')
elif platform.system() == 'Linux':
os.chdir(os.getcwd())
self.webui_lib = ctypes.CDLL(os.getcwd() + '/libcwebui.so')
webui_wrapper = self.webui_lib.c_create_window
webui_wrapper.restype = c_void_p
self.window = c_void_p(webui_wrapper())
self.webui_lib.c_ini()
except OSError as e:
print("WebUI Err: %s" % e)
sys.exit(1)
def __del__(self):
if self.window is not None and self.webui_lib is not None:
self.webui_lib.c_destroy_window(self.window)
def bind(self, element, func_ref):
if self.window is None or self.webui_lib is None:
return
cb_fun_type = None
prototype = None
fun = None
cb_fun_type = ctypes.CFUNCTYPE(ctypes.c_void_p) # define C pointer to a function type
self.cb_fun = cb_fun_type(func_ref) # define a C function equivalent to the python function
self.cb_fun_list.append(self.cb_fun)
prototype = ctypes.PYFUNCTYPE(
ctypes.c_void_p, # fun return
ctypes.c_void_p, # arg 1
ctypes.c_char_p, # arg 2
ctypes.py_object, # arg 3
ctypes.c_void_p # arg 4
)
fun = prototype(('c_bind_element', self.webui_lib))
fun(self.window, element.encode('utf-8'), func_ref, self.cb_fun_list[-1])
def show(self, html):
if self.window is not None and self.webui_lib is not None:
self.webui_lib.c_show_window(self.window, html.encode('utf-8'))
def loop(self):
if self.webui_lib is not None:
self.webui_lib.c_loop()
# -------------------------------------------------------------------------------
# HTML
my_html = """
<html>
<head>
<title>My first WebUI Python script</title>
</head>
<body style="background-color:#515C6B; color:#fff; font-family:"Lucida Console", Courier, monospace">
<h1>Welcome to WebUI Python!</h1>
<button id="MyButtonID1">Click on me!</button> | <button id="MyButtonID2">Exit!</button>
</body>
</html>
"""
# a sample function to be called
# when a specific button has clicked
def my_function():
print('You clicked on the first button!')
def my_function_two():
print('You clicked on the second button!')
# Create a window object
MyWindow = WebUI()
# Bind am HTML element ID with a python function
MyWindow.bind('MyButtonID1', my_function)
MyWindow.bind('MyButtonID2', my_function_two)
# Show the window
MyWindow.show(my_html)
# Wait unitil all windows are closed
MyWindow.loop()
print('Good! All windows are closed now.')
sys.exit(0)

View File

@ -1,144 +0,0 @@
# Info
set(Info_Title "Examples")
# --[ WebUI Lib ] ------------------------------------------------------------------
include_directories(${webui_SOURCE_DIR}/include)
link_directories(${webui_BIN_DIR}/webui)
# --[ Boost ] ----------------------------------------------------------------------
message("[*] Initializing Boost for ${Info_Title}... ")
set(Boost_NO_WARN_NEW_VERSIONS ON)
if (WIN32)
set(Boost_ARCHITECTURE "-x64")
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(Boost_USE_STATIC_RUNTIME OFF)
else()
set(Boost_USE_STATIC_RUNTIME ON)
endif()
# set(Boost_COMPILER "-mgw8")
# set(Boost_DETAILED_FAILURE_MSG OFF)
# set(Boost_DEBUG OFF)
# set(Boost_THREADAPI "win32")
# set(Boost_COMPILER "-vc142")
# add_definitions( -DBOOST_ALL_NO_LIB )
else()
# set(Boost_DEBUG OFF)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
# set(Boost_ARCHITECTURE "-x64")
# set(Boost_THREADAPI "pthread")
# set(Boost_DETAILED_FAILURE_MSG ON)
# set(Boost_COMPILER "-gcc")
add_definitions( -DBOOST_ALL_NO_LIB )
endif()
message("[*] Searching for Boost libs...")
find_package(Boost ${Boost_Version_Needed} REQUIRED COMPONENTS date_time filesystem regex)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
else()
message("[!] Please install Boost lib.")
return()
endif()
# --[ pThread ] -----------------------------------------------------------------
if(UNIX)
message("[*] Using POSIX threading (pThread).")
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
endif (UNIX)
# --[ Compiler flags ] ----------------------------------------------------------
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# using Clang
message("[*] Initializing '${Info_Title}' settings for Clang.")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if (WIN32)
# using MinGW/GCC Windows
message("[*] Initializing '${Info_Title}' settings for MinGW/GCC (Windows).")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj -fvisibility=hidden -Wall -O3 -std=gnu++17" )
else()
# using GCC lINUX
message("[*] Initializing '${Info_Title}' settings for GCC (Linux).")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -O3 -std=gnu++17" )
endif()
# Flags
# set_target_properties(${Info_Appzzzzzzzzzzzz} PROPERTIES LINK_FLAGS_RELEASE -s)
# set(CMAKE_CXX_FLAGS_RELEASE " -O3 ")
# set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -s ")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mbig-obj")
#set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -O3 -Wa,-mbig-obj -std=gnu++17" )
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
# using Intel C++
message("[*] Initializing '${Info_Title}' settings for Intel.")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# Microsoft build tools
message("[*] Initializing '${Info_Title}' settings for MSVC.")
# Flags (WINDOWS / CONSOLE)
# add_link_options("/SUBSYSTEM:WINDOWS")
# set_target_properties(${Info_Appzzzzzzzzzzzz} PROPERTIES LINK_FLAGS /SUBSYSTEM:WINDOWS)
# set_property(TARGET ${Info_Appzzzzzzzzzzzz} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
set(CMAKE_CXX_STANDARD 20)
#add_compile_options("/std:c++latest")
endif()
# --[ Target / Build ] ----------------------------------------------------------
file(GLOB files ${webui_SOURCE_DIR}/examples/*.cpp)
foreach(filePath ${files})
# Remove path
get_filename_component(file ${filePath} NAME)
# Remove extension
string(REPLACE ".cpp" "" example_app ${file})
message("[*] Found WebUI example: ${file} ")
add_executable(${example_app} ${file})
if(UNIX)
#Linux
target_link_libraries(${example_app} PRIVATE ${webui_lib} ${Boost_LIBRARIES} Threads::Threads)
else()
#Windows
target_link_libraries(${example_app} PUBLIC ${webui_lib} ws2_32 wsock32 ${Boost_LIBRARIES})
endif (UNIX)
endforeach()
# Copy files for serve_folder example
configure_file(${webui_SOURCE_DIR}/examples/index.html ${CMAKE_CURRENT_BINARY_DIR}/index.html COPYONLY)
configure_file(${webui_SOURCE_DIR}/examples/style.css ${CMAKE_CURRENT_BINARY_DIR}/style.css COPYONLY)

View File

@ -0,0 +1,68 @@
# WebUI Library 2.0.0
#
# http://webui.me
# https://github.com/alifcommunity/webui
#
# Licensed under GNU General Public License v3.0.
# Copyright (C)2022 Hassan DRAGA <https://github.com/hassandraga>.
# [!] IMPORTANT
# Please build a dynamic version of WebUI library using
# your favorite C compiler, then copy file 'webui-2-x64'
# into this folder.
import webui # Importing 'webui.py' file
# HTML
my_html = """
<!DOCTYPE html>
<html>
<head>
<title>WebUI 2.0 Example</title>
<style>
body{
color: white;
background: #0F2027;
background: -webkit-linear-gradient(to right, #2C5364, #203A43, #0F2027);
background: linear-gradient(to right, #2C5364, #203A43, #0F2027);
text-align:center;
font-size: 18px;
font-family: sans-serif;
}
</style>
</head>
<body>
<h1>WebUI 2.0 Example</h1>
<br>
<input type="password" id="MyInput">
<br><br>
<button id="MyButton1">Check Password</button> - <button id="MyButton2">Exit</button>
</body>
</html>
"""
# a sample function to be called
# when a specific button has clicked
def check_the_password(e : webui.event):
print('Element_id: ' + str(e.element_id))
print('Window_id: ' + str(e.window_id))
print('Element_name: ' + e.element_name.decode('utf-8'))
print('[!] The next coming version will include running JavaScript from Python.')
def close_the_application(e : webui.event):
webui.exit()
# Create a window object
MyWindow = webui.window()
# Bind am HTML element ID with a python function
MyWindow.bind('MyButton1', check_the_password)
MyWindow.bind('MyButton2', close_the_application)
# Show the window
MyWindow.show(my_html)
# Wait until all windows are closed
webui.loop()
print('Bye.')

144
examples/Python/webui.py Normal file
View File

@ -0,0 +1,144 @@
# WebUI Library 2.0.0
#
# http://webui.me
# https://github.com/alifcommunity/webui
#
# Licensed under GNU General Public License v3.0.
# Copyright (C)2022 Hassan DRAGA <https://github.com/hassandraga>.
# [!] IMPORTANT
# Please build a dynamic version of WebUI library using
# your favorite C compiler, then copy file 'webui-2-x64'
# into this folder.
import os
import platform
import sys
import ctypes
from ctypes import cdll, c_void_p, CFUNCTYPE, POINTER
webui_lib_loader = None
class window:
window = None
c_events = None
cb_fun_list = [64]
def __init__(self):
global webui_lib_loader
try:
# Load WebUI Shared Library
load_library()
# Check library if correctly loaded
if webui_lib_loader is None:
print('Please download the latest library from https://webui.me')
sys.exit(1)
# Create new WebUI window
webui_wrapper = None
webui_wrapper = webui_lib_loader.webui_new_window
webui_wrapper.restype = c_void_p
self.window = c_void_p(webui_wrapper())
# Initializing events() to be called from WebUI Library
py_fun = ctypes.CFUNCTYPE(ctypes.c_void_p, ctypes.c_uint, ctypes.c_uint, ctypes.c_char_p)
self.c_events = py_fun(self.events)
except OSError as e:
print("WebUI Exception: %s" % e)
sys.exit(1)
def __del__(self):
global webui_lib_loader
if self.window is not None and webui_lib_loader is not None:
webui_lib_loader.webui_close(self.window)
def events(self, element_id, window_id, element_name):
if self.cb_fun_list[int(element_id)] is None:
print('WebUI Error: Callback is None.')
return
e = event()
e.element_id = element_id
e.window_id = window_id
e.element_name = element_name
self.cb_fun_list[element_id](e)
def bind(self, element, func):
global webui_lib_loader
if self.window is None:
err_window_is_none('bind')
return
if webui_lib_loader is None:
err_library_not_found('bind')
return
cb_index = int(webui_lib_loader.webui_bind_py(self.window, element.encode('utf-8'), self.c_events))
self.cb_fun_list.insert(cb_index, func)
def show(self, html):
global webui_lib_loader
if self.window is None:
err_window_is_none('show')
return
if webui_lib_loader is None:
err_library_not_found('show')
return
webui_lib_loader.webui_show(self.window, html.encode('utf-8'))
def close(self):
global webui_lib_loader
if webui_lib_loader is None:
err_library_not_found('close')
return
webui_lib_loader.webui_close(self.window)
# Exit app
def load_library():
global webui_lib_loader
if platform.system() == 'Darwin':
webui_lib_loader = ctypes.CDLL('webui-2-x64.dylib')
if webui_lib_loader is None:
print("WebUI Error: Failed to load 'webui-2-x64.dylib' library.")
elif platform.system() == 'Windows':
if sys.version_info.major == 3 and sys.version_info.minor <= 8:
os.chdir(os.getcwd())
os.add_dll_directory(os.getcwd())
webui_lib_loader = ctypes.CDLL('webui-2-x64.dll')
else:
os.chdir(os.getcwd())
os.add_dll_directory(os.getcwd())
webui_lib_loader = cdll.LoadLibrary('webui-2-x64.dll')
if webui_lib_loader is None:
print("WebUI Error: Failed to load 'webui-2-x64.dll' library.")
elif platform.system() == 'Linux':
os.chdir(os.getcwd())
webui_lib_loader = ctypes.CDLL(os.getcwd() + '/webui-2-x64.so')
if webui_lib_loader is None:
print("WebUI Error: Failed to load 'webui-2-x64.so' library.")
else:
print("WebUI Error: Unsupported OS")
# Exit app
def exit():
global webui_lib_loader
if webui_lib_loader is None:
err_library_not_found('exit')
return
webui_lib_loader.webui_exit()
# Wait until all windows get closed
def loop():
global webui_lib_loader
if webui_lib_loader is None:
err_library_not_found('loop')
return
webui_lib_loader.webui_loop()
def err_library_not_found(f):
print('WebUI ' + f + '(): Library Not Found.')
def err_window_is_none(f):
print('WebUI ' + f + '(): Window is None.')
# Event
class event:
element_id = 0
window_id = 0
element_name = ""

View File

@ -0,0 +1,45 @@
# Build WebUI Dynamic & Static library
# Windows - GCC - GNU Compiler Collection
all: static
dynamic:
gcc -O3 -fPIC -m64 -o mongoose.o -I "../../../include" -c "../../../src/mongoose.c"
gcc -O3 -fPIC -m64 -o webui.o -I "../../../include" -c "../../../src/webui.c"
gcc -shared -o webui-2-x64.dll webui.o mongoose.o -lws2_32
gcc -m64 -o example_dynamic.exe "../../example.c" -I "../../../include" -L. webui-2-x64.dll -lws2_32 -Wall -Wl,-subsystem=windows -luser32
- del webui.o
- del mongoose.o
dynamic-debug:
gcc -g -fPIC -m64 -o mongoose.o -I "../../../include" -c "../../../src/mongoose.c"
gcc -g -fPIC -m64 -o webui.o -I "../../../include" -c "../../../src/webui.c"
gcc -g -shared -o webui-2-x64.dll webui.o mongoose.o -lws2_32
gcc -g -m64 -o example_dynamic_debug.exe "../../example.c" -I "../../../include" -L. webui-2-x64.dll -lws2_32
- del webui.o
- del mongoose.o
static:
gcc -Os -m64 -o mongoose.o -I "../../../include" -c "../../../src/mongoose.c"
gcc -Os -m64 -o webui.o -I "../../../include" -c "../../../src/webui.c"
ar rc libwebui-2-x64.a webui.o mongoose.o
ranlib libwebui-2-x64.a
gcc -static -Os -m64 -o example_static.exe "../../example.c" -I "../../../include" -L. -lwebui-2-x64 -lws2_32 -Wall -Wl,-subsystem=windows -luser32
strip --strip-all example_static.exe
- del webui.o
- del mongoose.o
static-debug:
gcc -g -m64 -o mongoose.o -I "../../../include" -c "../../../src/mongoose.c"
gcc -g -m64 -o webui.o -I "../../../include" -c "../../../src/webui.c"
ar rc libwebui-2-x64.a webui.o mongoose.o
ranlib libwebui-2-x64.a
gcc -g -m64 -o example_static_debug.exe "../../example.c" -I "../../../include" -L. -lwebui-2-x64 -lws2_32
- del webui.o
- del mongoose.o
clean:
- del *.o >nul 2>&1
- del *.dll >nul 2>&1
- del *.a >nul 2>&1
- del *.exe >nul 2>&1

View File

@ -0,0 +1,45 @@
# Build WebUI Dynamic & Static library
# Windows - MSVC - Microsoft Visual C
all: static
dynamic:
cl /Fomongoose.obj /c /EHsc "../../../src/mongoose.c" /I "../../../include"
cl /Fowebui.obj /c /EHsc "../../../src/webui.c" /I "../../../include"
link /DLL /OUT:webui-2-x64.dll webui.obj mongoose.obj
cl "../../example.c" /I "../../../include" /link /MACHINE:X64 /SUBSYSTEM:WINDOWS webui-2-x64.lib /OUT:example_dynamic.exe
- del *.obj >nul 2>&1
- del example_dynamic.exp
- del example_dynamic.lib
dynamic-debug:
cl /Zi /Fomongoose.obj /c /EHsc "../../../src/mongoose.c" /I "../../../include"
cl /Zi /Fowebui.obj /c /EHsc "../../../src/webui.c" /I "../../../include"
link /DLL /OUT:webui-2-x64.dll webui.obj mongoose.obj
cl /Zi "../../example.c" /I "../../../include" /link /MACHINE:X64 /SUBSYSTEM:CONSOLE webui-2-x64.lib /OUT:example_dynamic_debug.exe
- del *.obj >nul 2>&1
static:
cl /Fomongoose.obj /c /EHsc "../../../src/mongoose.c" /I "../../../include"
cl /Fowebui.obj /c /EHsc "../../../src/webui.c" /I "../../../include"
lib /OUT:webui-2-x64.lib webui.obj mongoose.obj
cl "../../example.c" /I "../../../include" /link /MACHINE:X64 /SUBSYSTEM:WINDOWS webui-2-x64.lib /OUT:example_static.exe
- del *.obj >nul 2>&1
- del example_static.exp
- del example_static.lib
static-debug:
cl /Zi /Fomongoose.obj /c /EHsc "../../../src/mongoose.c" /I "../../../include"
cl /Zi /Fowebui.obj /c /EHsc "../../../src/webui.c" /I "../../../include"
lib /OUT:webui-2-x64.lib webui.obj mongoose.obj
cl /Zi "../../example.c" /I "../../../include" /link /MACHINE:X64 /SUBSYSTEM:CONSOLE webui-2-x64.lib /OUT:example_static_debug.exe
- del *.obj >nul 2>&1
clean:
- del *.obj >nul 2>&1
- del *.dll >nul 2>&1
- del *.exe >nul 2>&1
- del *.ilk >nul 2>&1
- del *.pdb >nul 2>&1
- del *.lib >nul 2>&1
- del *.exp >nul 2>&1

View File

@ -0,0 +1,45 @@
# Build WebUI Dynamic & Static library
# Windows - GCC - Tiny C Compiler
all: static
dynamic:
tcc -fPIC -m64 -o mongoose.o -I "../../../include" -c "../../../src/mongoose.c"
tcc -fPIC -m64 -o webui.o -I "../../../include" -c "../../../src/webui.c"
tcc -shared -o webui-2-x64.dll webui.o mongoose.o -lws2_32
tcc -impdef webui-2-x64.dll -o webui-2-x64.def
tcc -m64 -o example_dynamic.exe "../../example.c" -I "../../../include" -L. webui-2-x64.def -lws2_32 -Wall -Wl,-subsystem=windows -luser32
- del webui.o
- del mongoose.o
dynamic-debug:
tcc -g -fPIC -m64 -o mongoose.o -I "../../../include" -c "../../../src/mongoose.c"
tcc -g -fPIC -m64 -o webui.o -I "../../../include" -c "../../../src/webui.c"
tcc -g -shared -o webui-2-x64.dll webui.o mongoose.o -lws2_32
tcc -impdef webui-2-x64.dll -o webui-2-x64.def
tcc -g -m64 -o example_dynamic.exe "../../example.c" -I "../../../include" -L. webui-2-x64.def -lws2_32 -Wall -Wl,-subsystem=windows -luser32
- del webui.o
- del mongoose.o
static:
tcc -m64 -o mongoose.o -I "../../../include" -c "../../../src/mongoose.c"
tcc -m64 -o webui.o -I "../../../include" -c "../../../src/webui.c"
tcc -m64 -ar rcs libwebui-2-x64.a webui.o mongoose.o
tcc -m64 -o example_static.exe "../../example.c" -I "../../../include" -L. -lwebui-2-x64 -lws2_32 -Wall -Wl,-subsystem=windows -luser32
- del webui.o
- del mongoose.o
static-debug:
tcc -g -m64 -o mongoose.o -I "../../../include" -c "../../../src/mongoose.c"
tcc -g -m64 -o webui.o -I "../../../include" -c "../../../src/webui.c"
tcc -m64 -ar rcs libwebui-2-x64.a webui.o mongoose.o
tcc -g -m64 -o example_static_debug.exe "../../example.c" -I "../../../include" -L. -lwebui-2-x64 -lws2_32
- del webui.o
- del mongoose.o
clean:
- del *.o >nul 2>&1
- del *.dll >nul 2>&1
- del *.a >nul 2>&1
- del *.exe >nul 2>&1
- del *.def >nul 2>&1

View File

@ -1,123 +0,0 @@
#ifndef UNICODE
#define UNICODE
#endif
// WebUI header
#include <webui/webui.hpp>
// C++ headers
#include <iostream>
// Win32 headers
#ifdef _WIN32
#include <windows.h>
#endif
// HTML Code
const std::string my_html = R"V0G0N(
<!DOCTYPE html>
<html>
<head>
<title>Custom Browser - WebUI</title>
<style>
body{
background: #ad5389; /* fallback for old browsers */
background: -webkit-linear-gradient(to right, #3c1053, #ad5389); /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #3c1053, #ad5389); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
color:#fff;
font-family: Avant Garde,Avantgarde,Century Gothic,CenturyGothic,AppleGothic,sans-serif;
font-size: 18px;
text-align: center;
}
</style>
</head>
<body>
<h1>Welcome to WebUI!</h1>
<h2>Custom Browser Example</h2>
<br>
<p>This example show how to use custom settings to run your favorite web browser.</p>
<button id="MyButtonID1">Exit</button>
</body>
</html>
)V0G0N";
webui::window my_window;
void close(webui::event e){
std::cout << "Bye!" << std::endl;
my_window.close();
}
int main(){
// This example show how to make
// WebUI use a custom browser of
// our choice.
// Linux - Firefox
webui::custom_browser_t Linux_Firefox {
// Firefox on Linux
// Command: 'firefox -private -url http://127.0.0.1:1234'
.app = "firefox",
.arg = "-private -url ",
.link = true
};
// Linux - Chrome
webui::custom_browser_t Windows_Firefox {
// Firefox on Linux
// Command: 'start firefox -private -url http://127.0.0.1:1234'
.app = "start firefox",
.arg = "-private -url ",
.link = true
};
// Linux - Chrome
webui::custom_browser_t Linux_Chrome {
// Firefox on Linux
// Command: 'chrome -private --app=http://127.0.0.1:1234'
.app = "chrome",
.arg = "-private --app=",
.link = true
};
// Windows - Chrome
webui::custom_browser_t Windows_Chrome {
// Firefox on Linux
// Command: 'start chrome -private --app=http://127.0.0.1:1234'
.app = "start chrome",
.arg = "-private --app=",
.link = true
};
my_window.bind("MyButtonID1", close);
// Show window (Windows Firefox)
if(!my_window.show(&my_html, &Windows_Firefox)){
// Failed to start our custom web browser
std::cout << "WebUI has failed to start the web browser\nPlease change settings." << std::endl;
}
// Loop
std::thread ui(webui::loop);
ui.join();
// All windows are closed.
printf("Good! All WebUI windows are closed now.\n");
return 0;
}
// Win32 entry point (if needed)
#ifdef _WIN32
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow){
main();
return 0;
}
#endif

97
examples/example.c Normal file
View File

@ -0,0 +1,97 @@
/*
WebUI Library 2.x
http://webui.me
https://github.com/alifcommunity/webui
Licensed under GNU General Public License v3.0.
Copyright (C)2022 Hassan DRAGA <https://github.com/hassandraga>.
*/
#include "webui.h"
// Window struct
webui_window_t* my_window;
// UI HTML
const char* my_html = "<!DOCTYPE html>"
"<html><head><title>WebUI 2.0 Example</title>"
"<style>body{color: white; background: #0F2027;"
"background: -webkit-linear-gradient(to right, #2C5364, #203A43, #0F2027);"
"background: linear-gradient(to right, #2C5364, #203A43, #0F2027);"
"text-align:center; font-size: 18px; font-family: sans-serif;}</style></head><body>"
"<h1>WebUI 2.0 Example</h1><br>"
"<input type=\"password\" id=\"MyInput\"><br><br>"
"<button id=\"MyButton1\">Check Password</button> - <button id=\"MyButton2\">Exit</button>"
"</body></html>";
// Check the password function
void check_the_password(const webui_event_t e) {
// This function get called every time the user click on "MyButton1"
webui_javascript_t js = {
.script = " return document.getElementById(\"MyInput\").value; ",
.timeout = 3
};
// Run the JavaScript on the UI (Web Browser)
webui_run_js(my_window, &js);
// Check if there is any JavaScript error
if(js.result.error) {
printf("JavaScript Error: %s\n", js.result.data);
return;
}
// Get the password
const char* password = js.result.data;
printf("Password: %s\n", password);
// Check the password
if(strcmp(password, "123456") == 0) {
// Correct password
js.script = "alert('Password is correct.')";
webui_run_js(my_window, &js);
}
else {
// Wrong password
js.script = "alert('Sorry. Wrong password.')";
webui_run_js(my_window, &js);
}
}
void close_the_application(const webui_event_t e){
// Close all opened windows
webui_exit();
}
int main() {
// Create a window
my_window = webui_new_window();
// Bind HTML elements with functions
webui_bind(my_window, "MyButton1", check_the_password);
webui_bind(my_window, "MyButton2", close_the_application);
// Show the window
if(!webui_show(my_window, my_html, webui.browser.chrome)) // Run the window on Chrome
webui_show(my_window, my_html, webui.browser.any); // If not, run on any other installed web browser
// Wait until all windows get closed
webui_loop();
return 0;
}
#if defined(_MSC_VER)
int APIENTRY WinMain(HINSTANCE hInst, HINSTANCE hInstPrev, PSTR cmdline, int cmdshow) {
main();
}
#endif

View File

@ -1,87 +0,0 @@
#ifndef UNICODE
#define UNICODE
#endif
// WebUI header
#include <webui/webui.hpp>
// C++ headers
#include <iostream>
// Win32 headers
#ifdef _WIN32
#include <windows.h>
#endif
// HTML Code
const std::string my_html = R"V0G0N(
<!DOCTYPE html>
<html>
<head>
<title>Favicon - WebUI</title>
<style>
body{
background: #485563; /* fallback for old browsers */
background: -webkit-linear-gradient(to right, #29323c, #485563); /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #29323c, #485563); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
color:#fff;
font-family: Avant Garde,Avantgarde,Century Gothic,CenturyGothic,AppleGothic,sans-serif;
font-size: 18px;
text-align: center;
}
</style>
</head>
<body>
<h1>Welcome to WebUI!</h1>
<h2>Favicon Example</h2>
<br>
<p>Actually this window is using a custom favicon in SVG format.<br>You can use any image format web browsers support.<br><br><small>Example: image/avif, image/webp, image/apng, image/svg+xml and more!</small></p>
<button id="MyButtonID1">execute welcome() function</button>
</body>
</html>
)V0G0N";
// It's recommended to remove all blank spaces.
const std::string my_favicon = "<?xml version=\"1.0\" ?><svg data-name=\"Layer 1\" id=\"Layer_1\" viewBox=\"0 0 64 64\" xmlns=\"http://www.w3.org/2000/svg\"><defs><style>.cls-1{fill:#4f4c5f;}.cls-2{fill:#484559;}.cls-3{fill:#403d4f;}.cls-4{fill:#fbb03b;}.cls-5{fill:#292733;}</style></defs><path class=\"cls-1\" d=\"M63.866,20.823A14.407,14.407,0,0,1,53.9,34.515a5.845,5.845,0,0,1-2.981-5.592,8.219,8.219,0,0,0,6.764-8.686A8.439,8.439,0,0,0,49.156,12.6H40.223a6.176,6.176,0,0,1-6.167-6.167A6.172,6.172,0,0,1,40.223.264h7.2A3.09,3.09,0,0,1,50.5,3.348a3.04,3.04,0,0,1-.74,1.994,3.035,3.035,0,0,1-2.344,1.09h2.056A14.407,14.407,0,0,1,63.866,20.823Z\"/><path class=\"cls-1\" d=\"M27.888,10.5V21.691c-3.5-.433-7.195-2.686-8.439-5.51l6.682-6.373A1.038,1.038,0,0,1,27.888,10.5Z\"/><path class=\"cls-1\" d=\"M4.976,9.808l6.681,6.373a11.131,11.131,0,0,1-8.439,5.51V10.5A1.038,1.038,0,0,1,4.976,9.808Z\"/><path class=\"cls-1\" d=\"M54.61,39.33V60.92a3.028,3.028,0,0,1-.02.31,2.941,2.941,0,0,1-.12.59,3.281,3.281,0,0,1-2.32,2.12,3.179,3.179,0,0,1-.62.06,3.308,3.308,0,0,1-.55-.05c-.15-.04-.29-.08-.44-.13a3.2,3.2,0,0,1-.93-.57c-.01-.01-.03-.02-.04-.03a3.391,3.391,0,0,1-1.12-2.58v-10a3.11,3.11,0,0,0-3.83-2.99,3.257,3.257,0,0,0-2.34,3.21V60.92a3.107,3.107,0,0,1-3.82,2.99,3.263,3.263,0,0,1-2.35-3.2V51.66a4.13,4.13,0,0,0-5.61-3.82,4.278,4.278,0,0,0-2.61,4.02v9.06a3.112,3.112,0,0,1-3.82,2.99,3.263,3.263,0,0,1-2.35-3.2V50.64a3.1,3.1,0,0,0-3.82-2.99,3.263,3.263,0,0,0-2.35,3.2V60.92a3.112,3.112,0,0,1-3.82,2.99A3.275,3.275,0,0,1,9.39,60.7V42.56A19.684,19.684,0,0,1,28.92,22.88h9.25a16.419,16.419,0,0,1,12.74,6.05,16.495,16.495,0,0,1,3.7,10.4Z\"/><path class=\"cls-2\" d=\"M54.61,39.33V60.92a3.028,3.028,0,0,1-.02.31,2.941,2.941,0,0,1-.12.59,2.978,2.978,0,0,1-.76,1.28,3.215,3.215,0,0,1-1.56.84,3.179,3.179,0,0,1-.62.06,3.308,3.308,0,0,1-.55-.05c-.15-.04-.29-.08-.44-.13a3.2,3.2,0,0,1-.93-.57,1.428,1.428,0,0,0,.18-.15,3.077,3.077,0,0,0,.91-2.18V39.33A16.495,16.495,0,0,0,47,28.93a16.439,16.439,0,0,0-12.75-6.05h3.92a16.419,16.419,0,0,1,12.74,6.05,16.495,16.495,0,0,1,3.7,10.4Z\"/><path class=\"cls-3\" d=\"M28.813,22.817c-.287-.442-.606-.864-.925-1.264a16.172,16.172,0,0,0-8.439-5.51,15.641,15.641,0,0,0-7.792,0,16.176,16.176,0,0,0-8.439,5.51A17.193,17.193,0,0,0,.134,27.371,17.471,17.471,0,0,0,2.344,32a16.54,16.54,0,0,0,4.092,4.235c.349.257.709.494,1.079.72a17.642,17.642,0,0,0,1.963,1,15.5,15.5,0,0,0,14.114-1c.37-.226.729-.463,1.079-.72A16.537,16.537,0,0,0,28.762,32a17.44,17.44,0,0,0,2.21-4.625A17.157,17.157,0,0,0,28.813,22.817Z\"/><path class=\"cls-4\" d=\"M23.777,24.934a3.076,3.076,0,1,1-2.056-2.909A3.074,3.074,0,0,1,23.777,24.934Z\"/><path class=\"cls-4\" d=\"M13.5,24.934a3.075,3.075,0,1,1-2.055-2.909A3.073,3.073,0,0,1,13.5,24.934Z\"/><path class=\"cls-5\" d=\"M16.818,29.965H14.289a1.026,1.026,0,0,0-.884,1.553l.39.647a2.022,2.022,0,0,0,.73.716v1.31a1.028,1.028,0,1,0,2.056,0v-1.31a2.022,2.022,0,0,0,.73-.716l.391-.647A1.027,1.027,0,0,0,16.818,29.965Z\"/><path class=\"cls-5\" d=\"M29.944,33.163H22.749a1.029,1.029,0,0,1,0-2.057h7.2a1.029,1.029,0,0,1,0,2.057Z\"/><path class=\"cls-5\" d=\"M8.358,33.163h-7.2a1.029,1.029,0,0,1,0-2.057h7.2a1.029,1.029,0,0,1,0,2.057Z\"/><path class=\"cls-5\" d=\"M6.3,39.33a1.028,1.028,0,0,1-.727-1.754l3.084-3.084a1.027,1.027,0,0,1,1.453,1.453L7.029,39.029A1.024,1.024,0,0,1,6.3,39.33Z\"/><path class=\"cls-5\" d=\"M24.805,39.33a1.024,1.024,0,0,1-.727-.3l-3.084-3.084a1.028,1.028,0,0,1,1.454-1.453l3.083,3.084a1.028,1.028,0,0,1-.726,1.754Z\"/><path class=\"cls-5\" d=\"M21.721,22.025v5.818a3.107,3.107,0,0,1-2.056,0V22.025a3.124,3.124,0,0,1,2.056,0Z\"/><path class=\"cls-5\" d=\"M11.442,22.025v5.818a3.107,3.107,0,0,1-2.056,0V22.025a3.124,3.124,0,0,1,2.056,0Z\"/><path class=\"cls-2\" d=\"M49.763,5.342a3.035,3.035,0,0,1-2.344,1.09H38.054A3.754,3.754,0,0,1,40.7,5.342Z\"/></svg>";
webui::window my_window;
void welcome(webui::event e){
std::cout << "Welcome!" << std::endl;
}
int main(){
// This example show how to
// use a custom favicon.
my_window.set_favicon(
&my_favicon,
"image/svg+xml" // image/avif, image/webp, image/apng, image/svg+xml and more..!
);
// Link the HTML button
my_window.bind("MyButtonID1", welcome);
// Show the window
my_window.show(&my_html);
// Loop
std::thread ui(webui::loop);
ui.join();
return 0;
}
// Win32 entry point (if needed)
#ifdef _WIN32
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow){
main();
return 0;
}
#endif

View File

@ -1,156 +0,0 @@
#ifndef UNICODE
#define UNICODE
#endif
// WebUI header
#include <webui/webui.hpp>
// C++ headers
#include <iostream>
// Win32 headers
#ifdef _WIN32
#include <windows.h>
#endif
// HTML Code
const std::string my_html = R"V0G0N(
<!DOCTYPE html>
<html>
<head>
<title>Custom Browser - WebUI</title>
<style>
body{
background: #E44D26; /* fallback for old browsers */
background: -webkit-linear-gradient(to right, #F16529, #E44D26); /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #F16529, #E44D26); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
color:#fff;
font-family: Avant Garde,Avantgarde,Century Gothic,CenturyGothic,AppleGothic,sans-serif;
font-size: 18px;
text-align: center;
}
</style>
</head>
<body>
<h1>Welcome to WebUI!</h1>
<h2>Hello World Example</h2>
<br>
<p>You can access the dahboard in the same window or in a new one.</p>
<button id="MyButtonID1">Switch to dashboard</button> | <button id="MyButtonID2">Open dashboard in a new window</button>
</body>
</html>
)V0G0N";
const std::string dashboard = R"V0G0N(
<!DOCTYPE html>
<html>
<head>
<title>Custom Browser - WebUI</title>
<style>
body{
background: #485563; /* fallback for old browsers */
background: -webkit-linear-gradient(to right, #29323c, #485563); /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #29323c, #485563); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
color:#fff;
font-family: Avant Garde,Avantgarde,Century Gothic,CenturyGothic,AppleGothic,sans-serif;
font-size: 18px;
text-align: center;
}
</style>
</head>
<body>
<h1>Dashboard</h1>
<br>
<button id="MyDashButton1">Run JS from C++ app</button> | <button id="MyDashButton2">Close this window</button> | <button id="MyDashButton3">Close app</button>
</body>
</html>
)V0G0N";
webui::window my_window;
webui::window dashboard_window;
void run_javascript(webui::event e){
// Run a JavaScript code
if(dashboard_window.is_show())
dashboard_window.run_js("alert('A message from your C++ application!');");
else
my_window.run_js("alert('It\\'s seem you chose to open the dashboard in the same window.');");
}
void switch_to_dashboard(webui::event e){
// Switch same window to the dashboard HTML script
my_window.show(&dashboard);
}
void open_dashboard(webui::event e){
// Open dashboard in a new window
dashboard_window.show(&dashboard);
}
void close_dashboard(webui::event e){
// Close dashboard window
if(dashboard_window.is_show())
dashboard_window.close();
else
my_window.close();
}
void close_app(webui::event e){
// Close all opened windows
// this make webui::loop() to finish
webui::exit();
}
int main(){
// Bind 'MyButtonID' with my_handler().
// Mean: Execute my_handler() when the user click
// on an HTML DOM element with id 'MyButtonID'.
// Bind two first buttons
my_window.bind("MyButtonID1", switch_to_dashboard);
my_window.bind("MyButtonID2", open_dashboard);
// Bind dashboard buttons with first window (for switch)
my_window.bind("MyDashButton1", run_javascript);
my_window.bind("MyDashButton2", close_dashboard);
my_window.bind("MyDashButton3", close_app);
// Bind dashboard buttons
dashboard_window.bind("MyDashButton1", run_javascript);
dashboard_window.bind("MyDashButton2", close_dashboard);
dashboard_window.bind("MyDashButton3", close_app);
// Show window
if(!my_window.show(&my_html, webui::browser::chrome)) // If Google Chrome not installed
my_window.show(&my_html); // try other web browsers.
// Loop
std::thread ui(webui::loop);
ui.join();
// All windows are closed.
printf("Good! All WebUI windows are closed now.\n");
return 0;
}
// Win32 entry point (if needed)
#ifdef _WIN32
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow){
main();
return 0;
}
#endif

View File

@ -1,105 +0,0 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta http-equiv="X-UA-Compatible" content="ie=edge" />
<title>Swiss Design Watch - WebUI</title>
<link rel="stylesheet" href="style.css" />
</head>
<body translate="no" >
<div class="wrapper">
<div class="watch-strap">
<div class="strap-circle"></div>
<div class="strap"></div>
<div class="watch-strap-holder left-up"></div>
<div class="watch-strap-holder left-bottom"></div>
<div class="watch-strap-holder right-up"></div>
<div class="watch-strap-holder right-bottom"></div>
<div class="watch-lace">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<span class="top"></span>
<span class="bottom"></span>
</div>
</div>
<div class="watch-case">
<div class="reflection"></div>
<div class="reflection bottom"></div>
<div class="watch-center" id="MyDiv">
<div class="watch-points"><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i><i></i></div>
<div class="watch-tips">
<span class="hours"></span>
<span class="minutes"></span>
<span class="seconds"></span>
</div>
<div class="watch-date">WebUI</div>
<div class="watch-alert">Click to Run The <strong>Welcome</strong> function!</div>
<div class="watch-week">
<span class="week-arrow"></span>
<ul>
<div>S</div>
<div>M</div>
<div>T</div>
<div>W</div>
<div>T</div>
<div>F</div>
<div>S</div>
</ul>
</div>
<div class="watch-day">
<div class="sun">
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
<div></div>
</div>
</div>
<div class="watch-week days">
<span class="week-arrow"></span>
<ul>
<div>3</div>
<div>6</div>
<div>9</div>
</ul>
</div>
</div>
</div>
</div>
</body>
<!-- WebUI Core ---------------------------------------------------->
<script type="text/javascript">
document.addEventListener("DOMContentLoaded", function (event) {
if (typeof _webui_ws === "undefined") {
let webui_searchParams = new URLSearchParams(window.location.search);
if (webui_searchParams.has("webui")) {
let webui_url = webui_searchParams.get("webui");
var webui_elem = document.createElement("script");
webui_elem.async = true;
webui_elem.type = "text/javascript";
webui_elem.src = webui_url;
document.body.appendChild(webui_elem);
} else alert("Failed to get the WebUI Core link.");
}
});
// Callbacks
function webui_ready() {
// WebUI is ready
webui_debug(false);
}
</script>
<!-- ------------------------------------------------------------ -->
</html>

View File

@ -1,97 +0,0 @@
#ifndef UNICODE
#define UNICODE
#endif
// WebUI header
#include <webui/webui.hpp>
// C++ headers
#include <iostream>
// Win32 headers
#ifdef _WIN32
#include <windows.h>
#endif
// HTML Code
const std::string my_html = R"V0G0N(
<!DOCTYPE html>
<html>
<head>
<title>Custom Browser - WebUI</title>
<style>
body{
background: #485563; /* fallback for old browsers */
background: -webkit-linear-gradient(to right, #29323c, #485563); /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #29323c, #485563); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
color:#fff;
font-family: Avant Garde,Avantgarde,Century Gothic,CenturyGothic,AppleGothic,sans-serif;
font-size: 18px;
text-align: center;
}
</style>
</head>
<body>
<h1>Welcome to WebUI!</h1>
<h2>Multi Access Example</h2>
<br>
<p>You can access this window from multiple browser using the same address.</p>
<button id="MyButtonID1">execute welcome() function</button>
</body>
</html>
)V0G0N";
webui::window my_window;
void welcome(webui::event e){
std::cout << "Welcome!" << std::endl;
}
int main(){
// This example show how to
// get the link and make the
// WebUI loop() wait for us.
// Set WebUI to wait forever!
// 0: infinit loop
// n: wait for n seconds
webui::set_timeout_sec(0);
// Set WebUI to allow multi
// window serving, so we can
// access the same address
// multiple times
my_window.allow_multi_serving(true);
// Link the HTML button
my_window.bind("MyButtonID1", welcome);
// Create a new server (HTTP & Websocket)
// and get URL
std::string url = my_window.new_server(&my_html);
std::cout << "Starting WebUI server.." << std::endl;
std::cout << "Please goto to this address: " << url << std::endl;
std::cout << std::endl << "Wait forever!.." << std::endl;
std::cout << "To stop just press Ctrl + C" << std::endl;
// Loop
std::thread ui(webui::loop);
ui.join();
return 0;
}
// Win32 entry point (if needed)
#ifdef _WIN32
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow){
main();
return 0;
}
#endif

View File

@ -1,74 +0,0 @@
#ifndef UNICODE
#define UNICODE
#endif
// WebUI header
#include <webui/webui.hpp>
// C++ headers
#include <iostream>
// Win32 headers
#ifdef _WIN32
#include <windows.h>
#endif
webui::window my_window;
void welcome(webui::event e){
std::cout << "Welcome! You clicked on the watch!" << std::endl;
}
int main(){
// This example show how to
// make the WebUI server files
// in a specific folder.
// Path to server
// Note: if it's empty the WebUI
// automaticaly server the current folder.
my_window.serve_folder("");
// Set WebUI to wait for first request
// 0: infinit wait
// n: wait for n seconds
webui::set_timeout_sec(0);
// Set WebUI to allow multi
// window serving, this is
// because each file is a new
// request
my_window.allow_multi_serving(true);
// Link the HTML button
my_window.bind("MyDiv", welcome);
// Create a new server (HTTP & Websocket)
// and get URL
std::string url = my_window.new_server();
std::cout << "Starting WebUI server.." << std::endl;
std::cout << "Please goto to this address: " << url << std::endl;
std::cout << std::endl << "Infinite wait.." << std::endl;
std::cout << "To stop just press Ctrl + C" << std::endl;
// Open a window!
std::string full_link = webui::get_current_path() + "index.html?webui=" + url + "/webuicore.js";
my_window.open_window(full_link, webui::browser::chrome);
// Loop
std::thread ui(webui::loop);
ui.join();
return 0;
}
// Win32 entry point (if needed)
#ifdef _WIN32
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow){
main();
return 0;
}
#endif

View File

@ -1,981 +0,0 @@
@import url("https://fonts.googleapis.com/css?family=Open+Sans:400,600,700");
body {
background-color: #fff;
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
font-family: 'Open Sans', sans-serif;
}
.wrapper {
position: relative;
}
.watch-case {
position: absolute;
z-index: 4;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 400px;
width: 400px;
overflow: hidden;
background-image: linear-gradient(-45deg, #fdfdfd, #ceced6, #fdfdfd);
border-radius: 50%;
box-shadow: 0 0 1px 2px rgba(180,177,193,0.7);
}
.watch-center {
background-image: radial-gradient(#fff, #eeeeef);
height: 380px;
width: 380px;
border-radius: 50%;
position: absolute;
z-index: 4;
left: 50%;
top: 50%;
transform: translate(-50%, -50%);
box-shadow: -1px -1px 1px 0 #fdfdfd, 0 0 0 2px #b8b7c3, inset 0 0 0 2px #d1d1d6, inset 0 0 0 4px rgba(255,255,255,0.7), inset 0 0 8px 8px rgba(0,0,0,0.1), inset 0 0 50px 50px rgba(0,0,0,0.05);
}
.watch-strap {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 480px;
width: 220px;
background-color: #101022;
border-radius: 6px;
z-index: 2;
}
.watch-strap .strap-circle {
position: absolute;
height: 409px;
width: 409px;
background-color: transparent;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
border-radius: 50%;
box-shadow: inset -1px 0 8px 3px #151427, 0 0 2px 1px rgba(255,255,255,0.8);
}
.watch-strap .strap-circle:after {
content: "";
display: block;
height: 100%;
width: 72px;
left: -2px;
position: absolute;
background-color: #fff;
}
.watch-strap .strap-circle:before {
content: "";
display: block;
height: 100%;
width: 72px;
background-color: #fff;
position: absolute;
right: -2px;
}
.watch-strap .strap {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
height: 480px;
width: 220px;
background-color: #101022;
border-radius: 6px;
z-index: 2;
box-shadow: -1px 0 1px 0 #000, inset 0 20px 40px -20px #172365, inset 0 -20px 40px -20px rgba(23,35,101,0.7);
}
.watch-strap-holder {
position: absolute;
background-color: #e7e7ea;
height: 150px;
width: 20px;
left: -20px;
border-radius: 3px;
top: -2px;
z-index: -1;
box-shadow: inset 0 0 4px 1px rgba(0,0,0,0.2);
}
.watch-strap-holder.left-bottom {
transform: scaleY(-1);
top: 332px;
left: -20px;
}
.watch-strap-holder.right-up {
transform: scaleX(-1);
left: 220px;
box-shadow: inset 0 0 4px 1px rgba(0,0,0,0.2);
}
.watch-strap-holder.right-up:after {
border-radius: 14px 70px 0 0;
box-shadow: inset 0px 3px 1px -2px rgba(255,255,255,0.6), inset -10px -15px 1px 2px #dcdce4, inset -2px 10px 4px 2px #181820;
}
.watch-strap-holder.right-bottom {
transform: scaleY(-1) scaleX(-1);
top: 332px;
left: 220px;
}
.watch-strap-holder.right-bottom:after {
border-radius: 14px 70px 0 0;
box-shadow: inset 0px 3px 1px -2px rgba(255,255,255,0.6), inset -10px -15px 1px 2px #dcdce4, inset -2px 10px 4px 2px #181820;
}
.watch-strap-holder:before {
content: "";
display: block;
position: absolute;
background-color: #e7e7ea;
height: 150px;
width: 10px;
border-radius: 3px 0;
transform: rotate(4deg);
left: -5px;
box-shadow: inset 5px 5px 4px -5px rgba(0,0,0,0.2);
}
.watch-strap-holder:after {
content: "";
display: block;
position: absolute;
background-color: transparent;
background-image: linear-gradient(to bottom, transparent, #fff);
height: 150px;
width: 30px;
border-radius: 12px;
transform: rotate(4deg);
top: 10px;
left: -4px;
box-shadow: inset -3px 8px 2px 2px #181820;
}
.reflection {
content: "";
display: block;
height: 16px;
width: 30px;
position: absolute;
top: 50px;
left: 50px;
background-color: #080817;
filter: blur(1px);
transform: rotate(-56deg) skewX(30deg) scale(0.6);
}
.reflection.bottom {
top: 337px;
left: 312px;
}
.reflection.bottom:after {
height: 39px;
width: 43px;
left: -60px;
top: -14px;
transform: rotate(-44deg);
box-shadow: 34px 17px 0 8px #080817;
}
.reflection:after {
content: "";
display: block;
background-color: transparent;
height: 40px;
width: 30px;
border-radius: 50%;
background-color: transparent;
position: absolute;
left: -48px;
top: -11px;
transform: rotate(-69deg);
box-shadow: 34px 17px 0 20px #080817;
}
.reflection:before {
content: "";
display: block;
background-color: transparent;
height: 40px;
width: 30px;
border-radius: 50%;
background-color: transparent;
position: absolute;
right: 25px;
top: 32px;
transform: rotate(-69deg);
box-shadow: 34px 17px 0 10px #080817, 14px 32px 0 20px #080817;
}
.watch-points {
position: absolute;
z-index: 5;
top: calc(50% - 6px);
left: calc(50% - 1px);
transform: translate(-50%, -50%);
}
.watch-points:after {
content: "";
display: block;
height: 325px;
width: 325px;
position: absolute;
border: 2px solid #dededf;
top: calc(50% + 6px);
left: calc(50% + 1px);
transform: translate(-50%, -50%);
border-radius: 50%;
}
.watch-points i {
display: block;
height: 12px;
width: 2px;
background-image: linear-gradient(to bottom, #c6c6cb, #e0e0e1);
position: absolute;
}
i:nth-child(1) {
transform: rotate(6deg) translate(0, -172px);
}
i:nth-child(2) {
transform: rotate(12deg) translate(0, -172px);
}
i:nth-child(3) {
transform: rotate(18deg) translate(0, -172px);
}
i:nth-child(4) {
transform: rotate(24deg) translate(0, -172px);
}
i:nth-child(5) {
transform: rotate(30deg) translate(0, -172px);
}
i:nth-child(6) {
transform: rotate(36deg) translate(0, -172px);
}
i:nth-child(7) {
transform: rotate(42deg) translate(0, -172px);
}
i:nth-child(8) {
transform: rotate(48deg) translate(0, -172px);
}
i:nth-child(9) {
transform: rotate(54deg) translate(0, -172px);
}
i:nth-child(10) {
transform: rotate(60deg) translate(0, -172px);
}
i:nth-child(11) {
transform: rotate(66deg) translate(0, -172px);
}
i:nth-child(12) {
transform: rotate(72deg) translate(0, -172px);
}
i:nth-child(13) {
transform: rotate(78deg) translate(0, -172px);
}
i:nth-child(14) {
transform: rotate(84deg) translate(0, -172px);
}
i:nth-child(15) {
transform: rotate(90deg) translate(0, -172px);
}
i:nth-child(16) {
transform: rotate(96deg) translate(0, -172px);
}
i:nth-child(17) {
transform: rotate(102deg) translate(0, -172px);
}
i:nth-child(18) {
transform: rotate(108deg) translate(0, -172px);
}
i:nth-child(19) {
transform: rotate(114deg) translate(0, -172px);
}
i:nth-child(20) {
transform: rotate(120deg) translate(0, -172px);
}
i:nth-child(21) {
transform: rotate(126deg) translate(0, -172px);
}
i:nth-child(22) {
transform: rotate(132deg) translate(0, -172px);
}
i:nth-child(23) {
transform: rotate(138deg) translate(0, -172px);
}
i:nth-child(24) {
transform: rotate(144deg) translate(0, -172px);
}
i:nth-child(25) {
transform: rotate(150deg) translate(0, -172px);
}
i:nth-child(26) {
transform: rotate(156deg) translate(0, -172px);
}
i:nth-child(27) {
transform: rotate(162deg) translate(0, -172px);
}
i:nth-child(28) {
transform: rotate(168deg) translate(0, -172px);
}
i:nth-child(29) {
transform: rotate(174deg) translate(0, -172px);
}
i:nth-child(30) {
transform: rotate(180deg) translate(0, -172px);
}
i:nth-child(31) {
transform: rotate(186deg) translate(0, -172px);
}
i:nth-child(32) {
transform: rotate(192deg) translate(0, -172px);
}
i:nth-child(33) {
transform: rotate(198deg) translate(0, -172px);
}
i:nth-child(34) {
transform: rotate(204deg) translate(0, -172px);
}
i:nth-child(35) {
transform: rotate(210deg) translate(0, -172px);
}
i:nth-child(36) {
transform: rotate(216deg) translate(0, -172px);
}
i:nth-child(37) {
transform: rotate(222deg) translate(0, -172px);
}
i:nth-child(38) {
transform: rotate(228deg) translate(0, -172px);
}
i:nth-child(39) {
transform: rotate(234deg) translate(0, -172px);
}
i:nth-child(40) {
transform: rotate(240deg) translate(0, -172px);
}
i:nth-child(41) {
transform: rotate(246deg) translate(0, -172px);
}
i:nth-child(42) {
transform: rotate(252deg) translate(0, -172px);
}
i:nth-child(43) {
transform: rotate(258deg) translate(0, -172px);
}
i:nth-child(44) {
transform: rotate(264deg) translate(0, -172px);
}
i:nth-child(45) {
transform: rotate(270deg) translate(0, -172px);
}
i:nth-child(46) {
transform: rotate(276deg) translate(0, -172px);
}
i:nth-child(47) {
transform: rotate(282deg) translate(0, -172px);
}
i:nth-child(48) {
transform: rotate(288deg) translate(0, -172px);
}
i:nth-child(49) {
transform: rotate(294deg) translate(0, -172px);
}
i:nth-child(50) {
transform: rotate(300deg) translate(0, -172px);
}
i:nth-child(51) {
transform: rotate(306deg) translate(0, -172px);
}
i:nth-child(52) {
transform: rotate(312deg) translate(0, -172px);
}
i:nth-child(53) {
transform: rotate(318deg) translate(0, -172px);
}
i:nth-child(54) {
transform: rotate(324deg) translate(0, -172px);
}
i:nth-child(55) {
transform: rotate(330deg) translate(0, -172px);
}
i:nth-child(56) {
transform: rotate(336deg) translate(0, -172px);
}
i:nth-child(57) {
transform: rotate(342deg) translate(0, -172px);
}
i:nth-child(58) {
transform: rotate(348deg) translate(0, -172px);
}
i:nth-child(59) {
transform: rotate(354deg) translate(0, -172px);
}
i:nth-child(60) {
transform: rotate(360deg) translate(0, -172px);
}
.watch-week {
position: absolute;
top: calc(50% - 6px);
left: calc(50% - 6px);
transform: translate(-120px, 40px) rotate(-70deg);
z-index: 10;
}
.watch-week.days {
transform: translate(50px, 40px) rotate(-70deg);
}
.watch-week.days:after {
transform: rotate(256deg);
}
.watch-week.days ul {
transform: rotate(169deg) translate(-58px, -17px);
}
.watch-week.days div {
color: #1f1f21;
}
.watch-week.days div:nth-child(1) {
transform: rotate(0) translate(0, -37px) scaleX(-1);
}
.watch-week.days div:nth-child(2) {
transform: rotate(80deg) translate(0, -37px) scaleX(-1) scaleY(-1);
}
.watch-week.days div:nth-child(3) {
transform: rotate(160deg) translate(0, -37px);
}
.watch-week.days .week-arrow {
transform: rotate(115deg) translate(35px, -8px);
}
.watch-week:after {
content: "";
display: block;
height: 100px;
width: 100px;
border-radius: 50%;
background-color: transparent;
transform: rotate(-64deg);
box-shadow: 1px 2px 0 0px #d6d6d3;
position: absolute;
left: -2px;
top: -28px;
}
.watch-week .week-arrow {
position: absolute;
top: 50%;
left: 50%;
transform: translate(19px, 21px) rotate(22deg);
width: 45px;
height: 2px;
background-color: #0f1743;
z-index: 5;
}
.watch-week .week-arrow:after,
.watch-week .week-arrow:before {
content: "";
position: absolute;
display: block;
height: 14px;
width: 14px;
background-color: #ff5456;
border-radius: 50%;
left: -6px;
top: -6px;
z-index: -1;
}
.watch-week .week-arrow:after {
background-color: #0f1743;
height: 10px;
width: 10px;
top: -4px;
left: -4px;
z-index: -1;
}
.watch-week div {
font-weight: bold;
font-size: 11px;
position: absolute;
z-index: 10;
height: 12px;
width: 12px;
display: block;
color: #d6d6d3;
}
.watch-week div:nth-child(1) {
transform: rotate(0) translate(0, -45px);
}
.watch-week div:nth-child(2) {
transform: rotate(25deg) translate(0, -45px);
}
.watch-week div:nth-child(3) {
transform: rotate(50deg) translate(0, -45px);
}
.watch-week div:nth-child(4) {
transform: rotate(75deg) translate(0, -45px);
}
.watch-week div:nth-child(5) {
transform: rotate(100deg) translate(0, -45px);
}
.watch-week div:nth-child(6) {
transform: rotate(125deg) translate(0, -45px);
color: #ff5456;
}
.watch-week div:nth-child(7) {
transform: rotate(150deg) translate(0, -45px);
}
.watch-date {
position: absolute;
top: calc(50% - 100px);
left: 50%;
font-size: 14px;
font-weight: 600;
letter-spacing: 1px;
transform: translate(-50%, -50%);
}
.watch-alert {
position: absolute;
top: calc(50% + 100px);
text-transform: uppercase;
text-align: center;
left: 50%;
font-size: 14px;
color: #bfbcd8;
font-weight: 600;
transform: translate(-50%, -50%);
}
.watch-alert strong {
color: #f00;
font-weight: 600;
}
.watch-tips {
height: 300px;
width: 300px;
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%) rotate(-90deg);
z-index: 11;
}
.hours {
width: 190px;
height: 6px;
position: absolute;
top: calc(50% - 3px);
left: calc(50% - 30px);
transform: rotate(153deg);
background-color: #fff;
transform-origin: 30px center;
box-shadow: 0 4px 12px 2px rgba(0,0,0,0.15);
border-radius: 0 20px 20px 0;
z-index: 12;
}
.hours:after {
content: "";
display: block;
position: absolute;
left: 23px;
top: -5px;
height: 14px;
width: 14px;
background-color: #fff;
border-radius: 50%;
}
.seconds {
width: 197px;
height: 2px;
position: absolute;
top: 50%;
left: calc(50% - 30px);
transform: rotate(0deg);
-webkit-animation: 10s seconds linear infinite;
animation: 10s seconds linear infinite;
background-color: #fe0806;
transform-origin: 30px center;
box-shadow: 0 0 16px 2px rgba(254,8,6,0.2);
border-radius: 0 20px 20px 0;
z-index: 15;
}
.seconds:after {
content: "";
display: block;
position: absolute;
left: 25px;
top: -4px;
height: 10px;
width: 10px;
background-color: #fe0806;
border-radius: 50%;
z-index: 15;
}
.minutes {
width: 170px;
height: 6px;
position: absolute;
top: calc(50% - 3px);
left: calc(50% - 30px);
transform: rotate(15deg);
background-color: #000004;
transform-origin: 30px center;
border-radius: 0 20px 20px 0;
z-index: 11;
}
.watch-lace {
width: 0;
height: 20px;
border-bottom: 10px solid transparent;
border-top: 10px solid transparent;
border-right: 8px solid #32322a;
position: absolute;
right: -98px;
top: calc(50% - 20px);
border-radius: 6px;
z-index: 30;
transform: scaleX(0.9) scaleY(1.1);
}
.watch-lace:after {
content: "";
display: block;
height: 40px;
width: 10px;
right: -16px;
top: -10px;
background-color: #dedede 0;
border-radius: 3px;
position: absolute;
}
.watch-lace:before {
content: "";
display: block;
height: 40px;
width: 4px;
background-color: #c3c4cb;
background-image: linear-gradient(to left, transparent, rgba(0,0,0,0.1));
z-index: 20;
position: absolute;
right: -17px;
border-radius: 4px;
top: -10px;
}
.watch-lace span {
display: block;
position: absolute;
background-image: linear-gradient(to left, #eae9e9, transparent);
height: 4px;
width: 20px;
top: -4px;
left: -10px;
transform: rotate(-45deg);
}
.watch-lace span.bottom {
top: 18px;
transform: rotate(45deg);
background-image: linear-gradient(to left, #eae9e9, transparent);
opacity: 0.7;
}
.watch-lace div {
height: 2px;
width: 7px;
background-color: #c4c4c4;
border: 1px solid #999891;
position: relative;
right: -7px;
z-index: 20;
top: 7px;
}
.watch-lace div:nth-child(2) {
top: -4px;
}
.watch-lace div:nth-child(3) {
top: 6px;
}
.watch-lace div:nth-child(4) {
top: -17px;
filter: brightness(110%);
}
.watch-lace div:nth-child(5) {
top: 4px;
filter: brightness(110%);
}
.watch-lace div:nth-child(6) {
top: -28px;
transform: rotate(-4deg);
filter: brightness(115%);
}
.watch-lace div:nth-child(6):before {
transform: rotate(-8deg);
}
.watch-lace div:nth-child(7) {
top: -1px;
transform: rotate(4deg);
filter: brightness(115%);
}
.watch-lace div:nth-child(7):after {
transform: rotate(8deg);
}
.watch-lace div:after,
.watch-lace div:before {
content: "";
position: relative;
background-color: #b8b8bb;
height: 3px;
width: 10px;
display: block;
top: 0px;
left: -3px;
border-radius: 3px;
}
.watch-lace div:before {
top: -3px;
}
.watch-day {
height: 90px;
width: 90px;
display: block;
position: absolute;
top: 50%;
left: 50%;
transform: translate(42px, -23px);
background-color: #1341d1;
-webkit-animation: 8s day-bg infinite;
animation: 8s day-bg infinite;
border-radius: 50%;
overflow: hidden;
box-shadow: inset 0 -1px 1px 1px #f6f6f6;
background-image: radial-gradient(#f6f6f6 18px, transparent 19px), radial-gradient(#f6f6f6 14px, transparent 15px), radial-gradient(#f6f6f6 18px, transparent 19px), radial-gradient(#f6f6f6 60px, transparent 61px);
background-repeat: no-repeat;
background-position: -28px 6px, 0 6px, 28px 6px, 0 42px;
}
.sun {
height: 10px;
width: 10px;
background-color: transparent;
position: absolute;
border: 3px solid #fff;
border-radius: 50%;
left: calc(50% - 8px);
top: 12px;
-webkit-animation: 8s sun infinite;
animation: 8s sun infinite;
}
.sun:after {
content: "";
display: block;
position: absolute;
height: 20px;
width: 20px;
background-color: #212045;
border-radius: 50%;
top: calc(50% - 10px);
left: calc(50% - 10px);
-webkit-animation: 8s moon infinite;
animation: 8s moon infinite;
}
.sun div {
position: absolute;
height: 7px;
width: 1px;
background-color: #fff;
top: calc(50% - 7px / 2);
left: calc(50% - 1px);
border-radius: 10px;
-webkit-animation: 8s sun-arms infinite;
animation: 8s sun-arms infinite;
}
.sun div:after,
.sun div:before {
content: "";
display: block;
height: 7px;
width: 2px;
background-color: #fff;
position: absolute;
left: 1px;
border-radius: 4px;
transform: rotate(-10deg);
}
.sun div:before {
transform: rotate(10deg);
left: -1px;
}
.sun div:nth-child(1) {
transform: rotate(0) translate(0, -9px);
}
.sun div:nth-child(2) {
transform: rotate(45deg) translate(0, -9px);
}
.sun div:nth-child(3) {
transform: rotate(90deg) translate(0, -9px);
}
.sun div:nth-child(4) {
transform: rotate(135deg) translate(0, -9px);
}
.sun div:nth-child(5) {
transform: rotate(180deg) translate(0, -9px);
}
.sun div:nth-child(6) {
transform: rotate(225deg) translate(0, -9px);
}
.sun div:nth-child(7) {
transform: rotate(270deg) translate(0, -9px);
}
.sun div:nth-child(8) {
transform: rotate(315deg) translate(0, -9px);
}
.sun div:nth-child(9) {
transform: rotate(360deg) translate(0, -9px);
}
@-webkit-keyframes seconds {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@keyframes seconds {
0% {
transform: rotate(0deg);
}
100% {
transform: rotate(360deg);
}
}
@-webkit-keyframes sun {
0%, 33% {
transform: rotate(0);
height: 12px;
width: 12px;
}
33% {
background-color: #fff;
transform: rotate(180deg);
height: 12px;
width: 12px;
}
66% {
transform: rotate(180deg);
background-color: #fff;
height: 12px;
width: 12px;
}
100% {
background-color: transparent;
transform: rotate(360deg);
height: 10px;
width: 10px;
}
}
@keyframes sun {
0%, 33% {
transform: rotate(0);
height: 12px;
width: 12px;
}
33% {
background-color: #fff;
transform: rotate(180deg);
height: 12px;
width: 12px;
}
66% {
transform: rotate(180deg);
background-color: #fff;
height: 12px;
width: 12px;
}
100% {
background-color: transparent;
transform: rotate(360deg);
height: 10px;
width: 10px;
}
}
@-webkit-keyframes sun-arms {
0% {
opacity: 1;
}
20%, 55% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@keyframes sun-arms {
0% {
opacity: 1;
}
20%, 55% {
opacity: 0;
}
100% {
opacity: 1;
}
}
@-webkit-keyframes moon {
0% {
transform: translate(-14px, 14px);
opacity: 0;
}
25% {
transform: translate(-14px, 14px);
opacity: 1;
}
45% {
transform: translate(0px, 0px);
opacity: 1;
}
50% {
transform: translate(14px, -14px);
opacity: 0;
}
50% {
opacity: 0;
}
100% {
transform: translate(0, 0);
opacity: 0;
}
}
@keyframes moon {
0% {
transform: translate(-14px, 14px);
opacity: 0;
}
25% {
transform: translate(-14px, 14px);
opacity: 1;
}
45% {
transform: translate(0px, 0px);
opacity: 1;
}
50% {
transform: translate(14px, -14px);
opacity: 0;
}
50% {
opacity: 0;
}
100% {
transform: translate(0, 0);
opacity: 0;
}
}
@-webkit-keyframes day-bg {
0% {
background-color: #2b7edc;
}
8%, 50% {
background-color: #212045;
}
60% {
background-color: #1341d1;
}
100% {
background-color: #2b7edc;
}
}
@keyframes day-bg {
0% {
background-color: #2b7edc;
}
8%, 50% {
background-color: #212045;
}
60% {
background-color: #1341d1;
}
100% {
background-color: #2b7edc;
}
}

View File

@ -1,91 +0,0 @@
#ifndef UNICODE
#define UNICODE
#endif
// WebUI header
#include <webui/webui.hpp>
// C++ headers
#include <iostream>
// Win32 headers
#ifdef _WIN32
#include <windows.h>
#endif
// HTML Code
const std::string my_html = R"V0G0N(
<!DOCTYPE html>
<html>
<head>
<title>Text Editor - WebUI</title>
<style>
body{
background: #485563; /* fallback for old browsers */
background: -webkit-linear-gradient(to right, #29323c, #485563); /* Chrome 10-25, Safari 5.1-6 */
background: linear-gradient(to right, #29323c, #485563); /* W3C, IE 10+/ Edge, Firefox 16+, Chrome 26+, Opera 12+, Safari 7+ */
color:#fff;
font-family: Avant Garde,Avantgarde,Century Gothic,CenturyGothic,AppleGothic,sans-serif;
font-size: 18px;
text-align: center;
}
</style>
</head>
<body>
<h1>Welcome to WebUI!</h1>
<h2>Text Editor (Beta)</h2>
<br>
<p>In future, this example will show how to use WebUI for an text editor app.</p>
<button id="MyButtonID1">Click on me!</button>
<button id="MyButtonID2">Click on me!</button>
</body>
</html>
)V0G0N";
// It's recommended to remove all blank spaces.
const std::string my_favicon = "<?xml version=\"1.0\" ?><svg data-name=\"Layer 1\" id=\"Layer_1\" viewBox=\"0 0 64 64\" xmlns=\"http://www.w3.org/2000/svg\"><defs><style>.cls-1{fill:#4f4c5f;}.cls-2{fill:#484559;}.cls-3{fill:#403d4f;}.cls-4{fill:#fbb03b;}.cls-5{fill:#292733;}</style></defs><path class=\"cls-1\" d=\"M63.866,20.823A14.407,14.407,0,0,1,53.9,34.515a5.845,5.845,0,0,1-2.981-5.592,8.219,8.219,0,0,0,6.764-8.686A8.439,8.439,0,0,0,49.156,12.6H40.223a6.176,6.176,0,0,1-6.167-6.167A6.172,6.172,0,0,1,40.223.264h7.2A3.09,3.09,0,0,1,50.5,3.348a3.04,3.04,0,0,1-.74,1.994,3.035,3.035,0,0,1-2.344,1.09h2.056A14.407,14.407,0,0,1,63.866,20.823Z\"/><path class=\"cls-1\" d=\"M27.888,10.5V21.691c-3.5-.433-7.195-2.686-8.439-5.51l6.682-6.373A1.038,1.038,0,0,1,27.888,10.5Z\"/><path class=\"cls-1\" d=\"M4.976,9.808l6.681,6.373a11.131,11.131,0,0,1-8.439,5.51V10.5A1.038,1.038,0,0,1,4.976,9.808Z\"/><path class=\"cls-1\" d=\"M54.61,39.33V60.92a3.028,3.028,0,0,1-.02.31,2.941,2.941,0,0,1-.12.59,3.281,3.281,0,0,1-2.32,2.12,3.179,3.179,0,0,1-.62.06,3.308,3.308,0,0,1-.55-.05c-.15-.04-.29-.08-.44-.13a3.2,3.2,0,0,1-.93-.57c-.01-.01-.03-.02-.04-.03a3.391,3.391,0,0,1-1.12-2.58v-10a3.11,3.11,0,0,0-3.83-2.99,3.257,3.257,0,0,0-2.34,3.21V60.92a3.107,3.107,0,0,1-3.82,2.99,3.263,3.263,0,0,1-2.35-3.2V51.66a4.13,4.13,0,0,0-5.61-3.82,4.278,4.278,0,0,0-2.61,4.02v9.06a3.112,3.112,0,0,1-3.82,2.99,3.263,3.263,0,0,1-2.35-3.2V50.64a3.1,3.1,0,0,0-3.82-2.99,3.263,3.263,0,0,0-2.35,3.2V60.92a3.112,3.112,0,0,1-3.82,2.99A3.275,3.275,0,0,1,9.39,60.7V42.56A19.684,19.684,0,0,1,28.92,22.88h9.25a16.419,16.419,0,0,1,12.74,6.05,16.495,16.495,0,0,1,3.7,10.4Z\"/><path class=\"cls-2\" d=\"M54.61,39.33V60.92a3.028,3.028,0,0,1-.02.31,2.941,2.941,0,0,1-.12.59,2.978,2.978,0,0,1-.76,1.28,3.215,3.215,0,0,1-1.56.84,3.179,3.179,0,0,1-.62.06,3.308,3.308,0,0,1-.55-.05c-.15-.04-.29-.08-.44-.13a3.2,3.2,0,0,1-.93-.57,1.428,1.428,0,0,0,.18-.15,3.077,3.077,0,0,0,.91-2.18V39.33A16.495,16.495,0,0,0,47,28.93a16.439,16.439,0,0,0-12.75-6.05h3.92a16.419,16.419,0,0,1,12.74,6.05,16.495,16.495,0,0,1,3.7,10.4Z\"/><path class=\"cls-3\" d=\"M28.813,22.817c-.287-.442-.606-.864-.925-1.264a16.172,16.172,0,0,0-8.439-5.51,15.641,15.641,0,0,0-7.792,0,16.176,16.176,0,0,0-8.439,5.51A17.193,17.193,0,0,0,.134,27.371,17.471,17.471,0,0,0,2.344,32a16.54,16.54,0,0,0,4.092,4.235c.349.257.709.494,1.079.72a17.642,17.642,0,0,0,1.963,1,15.5,15.5,0,0,0,14.114-1c.37-.226.729-.463,1.079-.72A16.537,16.537,0,0,0,28.762,32a17.44,17.44,0,0,0,2.21-4.625A17.157,17.157,0,0,0,28.813,22.817Z\"/><path class=\"cls-4\" d=\"M23.777,24.934a3.076,3.076,0,1,1-2.056-2.909A3.074,3.074,0,0,1,23.777,24.934Z\"/><path class=\"cls-4\" d=\"M13.5,24.934a3.075,3.075,0,1,1-2.055-2.909A3.073,3.073,0,0,1,13.5,24.934Z\"/><path class=\"cls-5\" d=\"M16.818,29.965H14.289a1.026,1.026,0,0,0-.884,1.553l.39.647a2.022,2.022,0,0,0,.73.716v1.31a1.028,1.028,0,1,0,2.056,0v-1.31a2.022,2.022,0,0,0,.73-.716l.391-.647A1.027,1.027,0,0,0,16.818,29.965Z\"/><path class=\"cls-5\" d=\"M29.944,33.163H22.749a1.029,1.029,0,0,1,0-2.057h7.2a1.029,1.029,0,0,1,0,2.057Z\"/><path class=\"cls-5\" d=\"M8.358,33.163h-7.2a1.029,1.029,0,0,1,0-2.057h7.2a1.029,1.029,0,0,1,0,2.057Z\"/><path class=\"cls-5\" d=\"M6.3,39.33a1.028,1.028,0,0,1-.727-1.754l3.084-3.084a1.027,1.027,0,0,1,1.453,1.453L7.029,39.029A1.024,1.024,0,0,1,6.3,39.33Z\"/><path class=\"cls-5\" d=\"M24.805,39.33a1.024,1.024,0,0,1-.727-.3l-3.084-3.084a1.028,1.028,0,0,1,1.454-1.453l3.083,3.084a1.028,1.028,0,0,1-.726,1.754Z\"/><path class=\"cls-5\" d=\"M21.721,22.025v5.818a3.107,3.107,0,0,1-2.056,0V22.025a3.124,3.124,0,0,1,2.056,0Z\"/><path class=\"cls-5\" d=\"M11.442,22.025v5.818a3.107,3.107,0,0,1-2.056,0V22.025a3.124,3.124,0,0,1,2.056,0Z\"/><path class=\"cls-2\" d=\"M49.763,5.342a3.035,3.035,0,0,1-2.344,1.09H38.054A3.754,3.754,0,0,1,40.7,5.342Z\"/></svg>";
webui::window my_window;
void my_all_events(webui::event e){
std::cout << "Something just happen!" << std::endl;
std::cout << "Window ID: " << e.window_id << std::endl;
std::cout << "Element ID: " << e.element_id << std::endl;
std::cout << "Element Name: " << e.element_name << std::endl << std::endl;
}
int main(){
// This example show how to
// use a custom favicon.
my_window.set_favicon(
&my_favicon,
"image/svg+xml" // image/avif, image/webp, image/apng, image/svg+xml and more..!
);
// Bind all HTML elements
my_window.bind_all(my_all_events);
// Show the window
my_window.show(&my_html);
// Loop
std::thread ui(webui::loop);
ui.join();
return 0;
}
// Win32 entry point (if needed)
#ifdef _WIN32
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow){
main();
return 0;
}
#endif

1494
include/mongoose.h Normal file

File diff suppressed because it is too large Load Diff

248
include/webui.h Normal file
View File

@ -0,0 +1,248 @@
/*
WebUI Library 2.0.0
http://webui.me
https://github.com/alifcommunity/webui
Licensed under GNU General Public License v3.0.
Copyright (C)2022 Hassan DRAGA <https://github.com/hassandraga>.
*/
#ifndef _WEBUI_H
#define _WEBUI_H
#if defined(_MSC_VER) || defined(__TINYC__)
#define EXPORT __declspec(dllexport)
#else
#define EXPORT extern
#endif
#define WEBUI_HEADER_SIGNATURE 0xFF // All packets should start with this 8bit
#define WEBUI_HEADER_JS 0xFE // Javascript result in frontend
#define WEBUI_HEADER_CLICK 0xFD // Click event
#define WEBUI_HEADER_SWITCH 0xFC // Frontend refresh
#define WEBUI_HEADER_CLOSE 0xFB // Close window
#define WEBUI_HEADER_CALL_FUNC 0xFA // Call a backend function
#define WEBUI_MAX_ARRAY (32) // Max thread, servers, windows..
#define WEBUI_MIN_PORT (8080) // Minimum socket port
#define WEBUI_MAX_PORT (8335) // Should be less than 65535
#define WEBUI_MAX_BUF (512000) // 512 Kb max dynamic memory
#define WEBUI_DEFAULT_PATH "." // Default root path
// -- C STD -----------------------------------
#include <stdbool.h>
#include <inttypes.h>
#include <assert.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <ctype.h>
#include <stddef.h>
#include <time.h>
#include <errno.h>
#if defined(__GNUC__) || defined(__TINYC__)
#include <dirent.h>
#endif
// -- Windows ---------------------------------
#ifdef _WIN32
// #include <SDKDDKVer.h> // Fix _WIN32_WINNT warning
#include <winsock2.h>
#include <windows.h>
#include <ws2tcpip.h>
#include <direct.h>
#include <io.h>
#include <tchar.h>
#define WEBUI_GET_CURRENT_DIR _getcwd
#define WEBUI_FILE_EXIST _access
#endif
// -- Linux -----------------------------------
#ifdef __linux__
#include <pthread.h> // POSIX threading
#include <unistd.h>
#define WEBUI_GET_CURRENT_DIR getcwd
#define WEBUI_FILE_EXIST _access
#endif
// -- macOS -----------------------------------
// ...
typedef struct webui_event_t {
unsigned int window_id;
unsigned int element_id;
char* element_name;
} webui_event_t;
typedef struct webui_window_core_t {
unsigned int window_number;
bool server_running;
bool connected;
bool server_handled;
bool multi_access;
bool server_root;
unsigned int server_port;
bool is_bind_all;
char* url;
void (*cb_all[1]) (webui_event_t e);
#ifdef _WIN32
HANDLE server_thread;
#else
unsigned int server_thread;
#endif
// Pointing to external user data
const char* html;
const char* icon;
const char* icon_type;
unsigned int CurrentBrowser;
char* browser_path;
char* profile_path;
unsigned int connections;
} webui_window_core_t;
typedef struct webui_window_t {
webui_window_core_t core;
char* path;
} webui_window_t;
typedef struct webui_javascript_result_t {
bool error;
unsigned int length;
const char* data;
} webui_javascript_result_t;
typedef struct webui_javascript_t {
char *script;
unsigned int timeout;
webui_javascript_result_t result;
} webui_javascript_t;
typedef struct webui_cb_t {
webui_window_t* win;
char* element_id;
char* element_name;
} webui_cb_t;
typedef struct webui_custom_browser_t {
char* app;
char* arg;
bool auto_link;
} webui_custom_browser_t;
typedef struct webui_browser_t {
unsigned int any; // 0
unsigned int chrome; // 1
unsigned int firefox; // 2
unsigned int edge; // 3
unsigned int safari; // 4
unsigned int chromium; // 5
unsigned int custom; // 99
} webui_browser_t;
typedef struct webui_t {
unsigned int servers;
unsigned int connections;
webui_custom_browser_t *custom_browser;
bool wait_for_socket_window;
char* html_elements[WEBUI_MAX_ARRAY];
unsigned int used_ports[WEBUI_MAX_ARRAY];
unsigned int last_window;
unsigned int startup_timeout;
bool use_timeout;
bool timeout_extra;
bool exit_now;
char* run_responses[WEBUI_MAX_ARRAY];
bool run_done[WEBUI_MAX_ARRAY];
bool run_error[WEBUI_MAX_ARRAY];
unsigned int run_last_id;
struct mg_mgr* mg_mgrs[WEBUI_MAX_ARRAY];
struct mg_connection* mg_connections[WEBUI_MAX_ARRAY];
webui_browser_t browser;
bool initialized;
void (*cb[WEBUI_MAX_ARRAY]) (webui_event_t e);
// Pointers Tracker
void *ptr_list[WEBUI_MAX_ARRAY];
size_t ptr_position;
size_t ptr_size[WEBUI_MAX_ARRAY];
} webui_t;
// -- Definitions --------------------
EXPORT webui_t webui;
EXPORT void webui_loop();
EXPORT void webui_exit();
EXPORT bool webui_any_window_is_open();
EXPORT void webui_set_timeout(unsigned int second);
EXPORT webui_window_t* webui_new_window();
EXPORT bool webui_show(webui_window_t* win, const char* html, unsigned int browser);
EXPORT void webui_set_icon(webui_window_t* win, const char* icon_s, const char* type_s);
EXPORT void webui_allow_multi_access(webui_window_t* win, bool status);
EXPORT bool webui_set_root_folder(webui_window_t* win, const char* path);
EXPORT const char* webui_new_server(webui_window_t* win, const char* html);
EXPORT void webui_close(webui_window_t* win);
EXPORT bool webui_is_show(webui_window_t* win);
EXPORT void webui_run_js(webui_window_t* win, webui_javascript_t* javascript);
EXPORT unsigned int webui_bind(webui_window_t* win, const char* element, void (*func) (webui_event_t e));
EXPORT void webui_bind_all(webui_window_t* win, void (*func) (webui_event_t e));
EXPORT bool webui_open(webui_window_t* win, char* url, unsigned int browser);
// Python wrapper
EXPORT unsigned int webui_bind_py(webui_window_t* win, const char* element, void (*func)(unsigned int, unsigned int, char*));
// Core
EXPORT void _webui_ini();
EXPORT unsigned int _webui_get_cb_index(char* element);
EXPORT unsigned int _webui_set_cb_index(char* element);
EXPORT unsigned int _webui_get_free_port();
EXPORT unsigned int _webui_get_new_window_number();
EXPORT void _webui_wait_for_startup();
EXPORT void _webui_free_port(unsigned int port);
EXPORT void _webui_set_custom_browser(webui_custom_browser_t* p);
EXPORT char* _webui_get_current_path();
EXPORT void _webui_window_receive(webui_window_t* win, const char* packet, size_t len);
EXPORT void _webui_window_send(webui_window_t* win, char* packet, size_t packets_size);
EXPORT void _webui_window_event(webui_window_t* win, char* element_id, char* element);
EXPORT unsigned int _webui_window_get_window_number(webui_window_t* win);
EXPORT void _webui_window_open(webui_window_t* win, char* link, unsigned int browser);
EXPORT int _webui_cmd_sync(char* cmd);
EXPORT int _webui_cmd_async(char* cmd);
EXPORT void _webui_browser_clean();
EXPORT bool _webui_browser_exist(webui_window_t* win, unsigned int browser);
EXPORT char* _webui_browser_get_temp_path(unsigned int browser);
EXPORT bool _webui_browser_folder_exist(char* folder);
EXPORT bool _webui_browser_create_profile_folder(webui_window_t* win, unsigned int browser);
EXPORT bool _webui_browser_start_edge(webui_window_t* win, char* address);
EXPORT bool _webui_browser_start_firefox(webui_window_t* win, char* address);
EXPORT bool _webui_browser_start_custom(webui_window_t* win, char* address);
EXPORT bool _webui_browser_start_chrome(webui_window_t* win, char* address);
EXPORT bool _webui_browser_start(webui_window_t* win, char* address, unsigned int browser);
#ifdef _WIN32
EXPORT DWORD WINAPI _webui_cb(LPVOID _arg);
#else
EXPORT void _webui_cb(void* _arg);
#endif
#endif /* _WEBUI_H */

View File

@ -1,285 +0,0 @@
/*
WebUI Library
- - - - - - -
http://webui.me
https://github.com/alifcommunity/webui
Licensed under GNU General Public License v3.0.
Copyright (C)2020 Hassan DRAGA <https://github.com/hassandraga>.
*/
#pragma once
#ifndef WEBUI_H
#define WEBUI_H
// -- C++ Standard -----------------------------
#include <array> //
#include <iostream> //
#include <string> //
#include <vector> //
#include <thread> // Standard threading
#ifdef __linux__
#include <pthread.h> // POSIX threading
#endif
namespace webui{
namespace browser{
unsigned short chrome = 1;
unsigned short firefox = 2;
unsigned short edge = 3;
unsigned short safari = 4;
unsigned short custom = 99;
}
struct event{
unsigned short window_id = 0;
unsigned short element_id = 0;
std::string element_name = "";
};
struct custom_browser_t {
std::string app;
std::string arg;
bool link = true;
};
void ini();
void loop();
void exit();
bool any_is_show();
void set_custom_browser(const webui::custom_browser_t *b);
void set_timeout_sec(unsigned short s);
std::string get_current_path();
// -- Class ----
class _window {
public:
_window();
~_window();
struct {
std::thread * webserver_thread = nullptr;
std::thread * websocket_thread = nullptr;
std::string number_s;
unsigned short number = 0;
bool webserver_running = false;
bool websocket_running = false;
bool webserver_served = false;
bool webserver_allow_multi = false;
bool webserver_local_files = false;
std::string webserver_local_root;
std::string webserver_port = "0";
std::string websocket_port = "0";
const std::string * html = nullptr;
const std::string * icon = nullptr;
std::string icon_type;
std::array<void(*)(webui::event e), 1> key_action_all;
bool is_bind_all = false;
} settings;
void receive(std::vector<std::uint8_t> &packets_v);
void send(std::vector<std::uint8_t> &packets_v) const;
void event(const std::string& id, const std::string& element);
void websocket_session_clean();
unsigned short bind(std::string key_id, void(*function_ref)(webui::event e)) const;
void bind_all(void(*function_ref)(webui::event e));
bool window_show(const std::string * html, unsigned short browser);
void set_window_icon(const std::string * icon_s, const std::string type_s);
void allow_multi_access(bool status);
void set_root_folder(std::string local_path);
std::string new_server(const std::string * html);
unsigned short get_window_number() const;
bool window_is_running() const;
bool any_window_is_running() const;
void destroy();
std::string run(std::string js, unsigned short seconds) const;
void open_window(std::string link, unsigned short browser);
};
class window{
private:
union {
//_window o_win = _window::_window();
_window o_win = _window();
};
const std::string * p_html = nullptr;
public:
window(){
webui::ini();
}
~window(){
o_win.~_window();
}
// -- Window -----------------------------
bool is_show() const{
return o_win.window_is_running();
}
bool any_is_show() const{
return o_win.any_window_is_running();
}
bool show(const std::string * html){
// if(o_win.window_is_running())
// return true;
this->p_html = html;
return o_win.window_show(this->p_html, 0);
}
bool show(const std::string * html, unsigned short browser){
// if(o_win.window_is_running())
// return true;
this->p_html = html;
return o_win.window_show(this->p_html, browser);
}
bool show(const std::string html){
std::string * _html = new std::string(html);
//return this->show(_html, 0);
return o_win.window_show(_html, 0);
}
bool show(const std::string * html, const webui::custom_browser_t *b){
// if(o_win.window_is_running())
// return true;
// Update custom browser reference
webui::set_custom_browser(b);
this->p_html = html;
return o_win.window_show(this->p_html, webui::browser::custom);
}
unsigned short bind(const std::string& id, void (* func_ref)(webui::event e)) const{
return o_win.bind(id, func_ref);
}
unsigned short get_window_id() const{
return o_win.get_window_number();
}
void bind_all(void (* func_ref)(webui::event e)){
o_win.bind_all(func_ref);
}
void serve_folder(std::string p){
o_win.set_root_folder(p);
}
void serve_folder(){
o_win.set_root_folder("");
}
void close(){
o_win.run(" webui_close_window(); ", 1);
// if(o_win.window_is_running())
// o_win.destroy();
}
void allow_multi_serving(bool b){
o_win.allow_multi_access(b);
}
void set_favicon(const std::string * icon, const std::string& type){
o_win.set_window_icon(icon, type);
}
std::string new_server(const std::string * html){
return o_win.new_server(html);
}
std::string new_server(){
return o_win.new_server(nullptr);
}
std::string get_current_path(){
return webui::get_current_path();
}
void open_window(std::string link, unsigned short browser){
o_win.open_window(link, browser);
}
// -- JavaScript ------------------------------------------
std::string run_js(const std::string& js) const{
if(!o_win.window_is_running())
return "";
return o_win.run(js, 1);
}
std::string run_js(const std::string& js, unsigned short s) const{
if(!o_win.window_is_running())
return "";
return o_win.run(js, s);
}
std::string get_value(const std::string& id) const{
if(!o_win.window_is_running())
return "";
std::string buf;
buf.append(" return String(document.getElementById('");
buf.append(id);
buf.append("').value); ");
return o_win.run(buf, 1);
}
std::string set_value(const std::string& id, const std::string& data){
if(!o_win.window_is_running())
return "";
std::string buf;
buf.append(" const rawdata = String.raw`");
buf.append(data);
buf.append("`; document.getElementById('");
buf.append(id);
buf.append("').value = `${rawdata}`; ");
return o_win.run(buf, 1);
}
};
}
#endif

Binary file not shown.

Before

Width:  |  Height:  |  Size: 415 KiB

After

Width:  |  Height:  |  Size: 239 KiB

View File

@ -1,148 +0,0 @@
# Info
set(Info_Title "WebUI")
set(Info_Source "webui.cpp")
set(Info_App ${webui_lib})
# --[ WebUI ] -------------------------------------------------------------------
include_directories(${webui_SOURCE_DIR}/include)
link_directories(${webui_BIN_DIR}/webui)
# --[ Boost ] -----------------------------------------------------------------
message("[*] Initializing Boost for ${Info_Title}...")
set(Boost_NO_WARN_NEW_VERSIONS ON)
if (WIN32)
set(Boost_ARCHITECTURE "-x64")
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
if (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
set(Boost_USE_STATIC_RUNTIME OFF)
else()
set(Boost_USE_STATIC_RUNTIME ON)
endif()
# set(Boost_COMPILER "-mgw8")
# set(Boost_DETAILED_FAILURE_MSG OFF)
# set(Boost_DEBUG OFF)
# set(Boost_THREADAPI "win32")
# set(Boost_COMPILER "-vc142")
# add_definitions( -DBOOST_ALL_NO_LIB )
else()
# set(Boost_DEBUG OFF)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
# set(Boost_ARCHITECTURE "-x64")
# set(Boost_THREADAPI "pthread")
# set(Boost_DETAILED_FAILURE_MSG ON)
# set(Boost_COMPILER "-gcc")
add_definitions( -DBOOST_ALL_NO_LIB )
endif()
message("[*] Searching for Boost libs...")
find_package(Boost ${Boost_Version_Needed} REQUIRED COMPONENTS date_time filesystem regex)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
else()
message("[!] Please install Boost lib.")
return()
endif()
# --[ pThread ] ---------------------------------------------------------------
if(UNIX)
message("[*] Using POSIX threading (pThread).")
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
endif (UNIX)
# --[ Target ] ----------------------------------------------------------------
# Windows
# WebUI --> static lib
# depend --> static boost lib
# Linux
# WebUI --> static lib
# depend --> shared boost lib
add_library(${Info_App} STATIC ${Info_Source})
set_target_properties(${Info_App} PROPERTIES PUBLIC_HEADER ${webui_SOURCE_DIR}/include/webui/webui.hpp)
# --[ Compiler flags ] --------------------------------------------------------
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# using Clang
message("[*] Initializing '${Info_Title}' settings for Clang.")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if (WIN32)
# using MinGW/GCC Windows
message("[*] Initializing '${Info_Title}' settings for MinGW/GCC (Windows).")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj -fvisibility=hidden -Wall -O3 -std=gnu++17" )
else()
# using GCC Linux
message("[*] Initializing '${Info_Title}' settings for GCC (Linux).")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -O3 -std=gnu++17" )
endif()
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
# using Intel C++
message("[*] Initializing '${Info_Title}' settings for Intel.")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# Microsoft build tools
message("[*] Initializing '${Info_Title}' settings for MSVC.")
# Flags (WINDOWS / CONSOLE)
# add_link_options("/SUBSYSTEM:WINDOWS")
# set_target_properties(${Info_App} PROPERTIES LINK_FLAGS /SUBSYSTEM:WINDOWS)
# set_property(TARGET ${Info_App} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
set(CMAKE_CXX_STANDARD 20)
endif()
# --[ Build ] -----------------------------------------------------------------
# ...
# --[ Install ] ---------------------------------------------------------------
if(UNIX)
message("[*] Initializing installation...")
install (TARGETS ${Info_App}
PUBLIC_HEADER DESTINATION include
ARCHIVE DESTINATION lib
LIBRARY DESTINATION lib
RUNTIME DESTINATION lib)
endif (UNIX)
# --[ Package ] ---------------------------------------------------------------
if(UNIX)
message("[*] Initializing debian package...")
SET(CPACK_GENERATOR "DEB")
SET(CPACK_DEBIAN_PACKAGE_MAINTAINER "webui") #required
INCLUDE(CPack)
endif (UNIX)

7288
src/mongoose.c Normal file

File diff suppressed because it is too large Load Diff

2412
src/webui.c Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,125 +0,0 @@
# Info
set(Info_Title "Test")
set(Info_Source "test.cpp")
set(Info_App "webui_test")
# --[ WebUI ] -------------------------------------------------------------------
include_directories(${webui_SOURCE_DIR}/include)
link_directories(${webui_BIN_DIR}/webui)
# --[ Boost ] ----------------------------------------------------------------------
message("[*] Initializing Boost for ${Info_Title}...")
set(Boost_NO_WARN_NEW_VERSIONS ON)
if (WIN32)
set(BOOST_ROOT ${Boost_Root})
set(Boost_LIBRARY_DIR ${Boost_Lib})
message("[*] Using Boost root: ${BOOST_ROOT}")
message("[*] Using Boost lib: ${Boost_LIBRARY_DIR}")
set(Boost_ARCHITECTURE "-x64")
set(Boost_USE_STATIC_LIBS ON)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME ON)
# set(Boost_COMPILER "-mgw8")
# set(Boost_DETAILED_FAILURE_MSG OFF)
# set(Boost_DEBUG OFF)
# set(Boost_THREADAPI "win32")
# set(Boost_COMPILER "-vc142")
# add_definitions( -DBOOST_ALL_NO_LIB )
else()
# set(Boost_DEBUG OFF)
set(Boost_USE_STATIC_LIBS OFF)
set(Boost_USE_MULTITHREADED ON)
set(Boost_USE_STATIC_RUNTIME OFF)
# set(Boost_ARCHITECTURE "-x64")
# set(Boost_THREADAPI "pthread")
# set(Boost_DETAILED_FAILURE_MSG ON)
# set(Boost_COMPILER "-gcc")
add_definitions( -DBOOST_ALL_NO_LIB )
endif()
message("[*] Searching for Boost libs...")
find_package(Boost ${Boost_Version_Needed} REQUIRED COMPONENTS date_time filesystem regex)
if(Boost_FOUND)
include_directories(${Boost_INCLUDE_DIRS})
link_directories(${Boost_LIBRARY_DIRS})
else()
message("[!] Please install Boost lib.")
return()
endif()
# --[ pThread ] -----------------------------------------------------------------
if(UNIX)
message("[*] Using POSIX threading (pThread).")
set(THREADS_PREFER_PTHREAD_FLAG ON)
find_package(Threads REQUIRED)
endif (UNIX)
# --[ Target ] ------------------------------------------------------------------
add_executable(${Info_App} ${Info_Source})
# --[ Compiler flags ] ----------------------------------------------------------
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
# using Clang
message("[*] Initializing '${Info_Title}' settings for Clang.")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
if (WIN32)
# using MinGW/GCC Windows
message("[*] Initializing '${Info_Title}' settings for MinGW/GCC (Windows).")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wa,-mbig-obj -fvisibility=hidden -Wall -O3 -std=gnu++17" )
else()
# using GCC lINUX
message("[*] Initializing '${Info_Title}' settings for GCC (Linux).")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fvisibility=hidden -Wall -O3 -std=gnu++17" )
endif()
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "Intel")
# using Intel C++
message("[*] Initializing '${Info_Title}' settings for Intel.")
elseif (CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# Microsoft build tools
message("[*] Initializing '${Info_Title}' settings for MSVC.")
# Flags (WINDOWS / CONSOLE)
# add_link_options("/SUBSYSTEM:WINDOWS")
# set_target_properties(${Info_App} PROPERTIES LINK_FLAGS /SUBSYSTEM:WINDOWS)
# set_property(TARGET ${Info_App} PROPERTY MSVC_RUNTIME_LIBRARY "MultiThreaded")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /bigobj")
endif()
# --[ Build ] -------------------------------------------------------------------
if(UNIX)
target_link_libraries(${Info_App} PRIVATE ${webui_lib} ${Boost_LIBRARIES} Threads::Threads)
else()
target_link_libraries(${Info_App} PRIVATE ${webui_lib} ws2_32 wsock32 ${Boost_LIBRARIES})
endif (UNIX)
# --[ Test ] --------------------------------------------------------------------
add_test(webui_test_run webui_test argv1 argv2 argv3)

View File

@ -1,56 +0,0 @@
#ifndef UNICODE
#define UNICODE
#endif
// WebUI header
#include <webui/webui.hpp>
// C++ headers
#include <iostream>
// Win32 headers
#ifdef _WIN32
#include <windows.h>
#endif
const std::string html = R"V0G0N(
<!DOCTYPE html>
<html>
<head>
<title>WebUI TEST</title>
</head>
<body style="background-color:#515C6B; color:#fff; font-family:"Lucida Console", Courier, monospace">
<h1>Please close this window.</h1>
<p>This is WebUI test application.</p>
<input type="hidden" id="testinput" value="webui-test-communication">
</body>
</html>
)V0G0N";
webui::window win;
void bar(webui::event e){
printf("WebUI Test");
}
int main(){
win.bind("foo", bar);
if(!win.show(&html, webui::browser::chrome))
win.show(&html);
std::thread t(webui::loop);
t.join();
return 0;
}
// Win32 entry point (if needed)
#ifdef _WIN32
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow){
main();
return 0;
}
#endif