commit f5890d070f1c6016d9991691b93c2c8c34f46036 Author: Mike Nolan Date: Tue Oct 14 23:17:27 2025 -0500 First Commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6a8bc10 --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +.vscode +build \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..fbdd8c7 --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,98 @@ +cmake_minimum_required(VERSION 3.16) + +option(TFWEBAPP_ENABLE_STATIC "Enable static build" ON) +option(TFWEBAPP_ENABLE_SHARED "Enable shared build" ON) +option(TFWEBAPP_ENABLE_EXAMPLES "Enable examples" OFF) +option(TFWEBAPP_FETCHCONTENT "Fetch content" ON) + +set(TFWEBAPP_SOURCES + src/lib.cpp +) + + +include(FetchContent) + +FetchContent_Declare( + WebView + GIT_REPOSITORY https://github.com/webview/webview.git +) +set(WEBVIEW_INSTALL_TARGETS ON) +FetchContent_MakeAvailable(WebView) + +list(APPEND TessesFrameworkWebAppLibs webview_core_headers) +if(TFWEBAPP_ENABLE_STATIC) +add_library(tessesframework_webapp STATIC ${TFWEBAPP_SOURCES}) +target_link_libraries(tessesframework_webapp PRIVATE webview::core) +list(APPEND TessesFrameworkWebAppLibs tessesframework_webapp) +target_include_directories(tessesframework_webapp + PUBLIC + "$" + "$" +) +endif() +if(TFWEBAPP_ENABLE_SHARED) +add_library(tessesframework_webapp_shared STATIC ${TFWEBAPP_SOURCES}) +target_link_libraries(tessesframework_webapp_shared PRIVATE webview::core) +list(APPEND TessesFrameworkWebAppLibs tessesframework_webapp_shared) + +target_include_directories(tessesframework_webapp_shared + PUBLIC + "$" + "$" +) +endif() + +if(TFWEBAPP_FETCHCONTENT) + +FetchContent_Declare( + TessesFramework + GIT_REPOSITORY https://onedev.site.tesses.net/tesses-framework.git +) + + +FetchContent_MakeAvailable(TessesFramework) + +if(TFWEBAPP_ENABLE_STATIC) +target_link_libraries(tessesframework_webapp PUBLIC tessesframework) + +endif() +if(TFWEBAPP_ENABLE_SHARED) +target_link_libraries(tessesframework_webapp_shared PUBLIC tessesframework_shared) +endif() +list(APPEND TessesFrameworkWebAppLibs ${TessesFrameworkTargets}) +else() +find_package(TessesFramework REQUIRED) +if(TFWEBAPP_ENABLE_STATIC) +target_link_libraries(tessesframework_webapp PUBLIC TessesFramework::tessesframework) +endif() +if(TFWEBAPP_ENABLE_SHARED) +target_link_libraries(tessesframework_webapp_shared PUBLIC TessesFramework::tessesframework_shared) +endif() +endif() + +if(TFWEBAPP_ENABLE_EXAMPLES) +add_executable(printargs examples/printargs.cpp) +target_link_libraries(printargs PUBLIC tessesframework_webapp) +endif() + +install(TARGETS ${TessesFrameworkWebAppLibs} + EXPORT TessesFrameworkWebAppTargets + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR} +) + +install(FILES include/TF_WebApp.hpp DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}) + +install(EXPORT TessesFrameworkWebAppTargets + FILE TessesFrameworkWebAppTargets.cmake + NAMESPACE TessesFrameworkWebApp:: + DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesFrameworkWebApp +) + +configure_package_config_file(${CMAKE_CURRENT_SOURCE_DIR}/Config.cmake.in "${CMAKE_CURRENT_BINARY_DIR}/TessesFrameworkWebAppConfig.cmake" +INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesFrameworkWebApp) + +install(FILES "${CMAKE_CURRENT_BINARY_DIR}/TessesFrameworkWebAppConfig.cmake" +DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/TessesFrameworkWebApp) \ No newline at end of file diff --git a/Config.cmake.in b/Config.cmake.in new file mode 100644 index 0000000..5108e9a --- /dev/null +++ b/Config.cmake.in @@ -0,0 +1,7 @@ +@PACKAGE_INIT@ + +include("${CMAKE_CURRENT_LIST_DIR}/TessesFrameworkWebAppTargets.cmake") + +check_required_components(TessesFrameworkWebApp) +find_package(TessesFramework REQUIRED) +find_package(webview REQUIRED) \ No newline at end of file diff --git a/examples/printargs.cpp b/examples/printargs.cpp new file mode 100644 index 0000000..c0fdc1c --- /dev/null +++ b/examples/printargs.cpp @@ -0,0 +1,23 @@ +#include "TF_WebApp.hpp" +using namespace Tesses::Framework::Http; +using namespace Tesses::Framework; +TF_WebApp(MyApp,nullptr) + + +std::shared_ptr MyApp(std::vector& args) +{ + TF_WebAppSetTitle("Print Args"); + return std::make_shared([&args](ServerContext& ctx)->bool { + if(ctx.path == "/") + { + std::string text = "

Hello, world

    "; + for(auto item : args) + text += "
  • " + HttpUtils::HtmlEncode(item) + "
  • "; + text += "
"; + + ctx.WithMimeType("text/html").SendText(text); + return true; + } + return false; + }); +} \ No newline at end of file diff --git a/include/TF_WebApp.hpp b/include/TF_WebApp.hpp new file mode 100644 index 0000000..10c0455 --- /dev/null +++ b/include/TF_WebApp.hpp @@ -0,0 +1,14 @@ +#pragma once +#include + +namespace Tesses::Framework { + #if defined(_WIN32) + int TF_Main(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd, std::function(std::vector& args)> cb, std::function)> clo); + #define TF_WebApp(fn,clo) std::shared_ptr fn(std::vector& args); int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) { return Tesses::Framework::TF_Main(hInstance,hPrevInstance,lpCmdLine,nShowCmd,fn,clo);} + #else + int TF_Main(int argc, char** argv, std::function(std::vector& args)> cb, std::function)> clo); + #define TF_WebApp(fn,clo) std::shared_ptr fn(std::vector& args); int main(int argc, char** argv) { return Tesses::Framework::TF_Main(argc, argv, fn, clo); } + #endif + + void TF_WebAppSetTitle(std::string title); +}; \ No newline at end of file diff --git a/src/lib.cpp b/src/lib.cpp new file mode 100644 index 0000000..d9b6d5f --- /dev/null +++ b/src/lib.cpp @@ -0,0 +1,99 @@ +#include "TF_WebApp.hpp" +#include "webview/webview.h" +namespace Tesses::Framework { + static std::string wv_title; + static webview::webview* wv_hdl=nullptr; + static Tesses::Framework::Threading::Mutex wv_mtx; + + void TF_WebAppSetTitle(std::string title) + { + wv_mtx.Lock(); + wv_title = title; + if(wv_hdl != nullptr) + { + + + wv_hdl->dispatch([title]()->void { + wv_hdl->set_title(title); + }); + + } + wv_mtx.Unlock(); + + + } + #if defined(_WIN32) + int TF_Main(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd, std::function(std::vector& args)> cb, std::function)> clo) + #else + int TF_Main(int argc, char** argv, std::function(std::vector& args)> cb, std::function)> clo) + #endif + { + + + TF_InitWithConsole(); + std::vector args; + + #if defined(_WIN32) + auto winargs = GetCommandLineW(); + int argc=0; + + auto argv = CommandLineToArgvW( + winargs, + &argc + ); + + for(int i = 0; i < argc; i++) + { + std::u16string str = (const char16_t*)argv[i]; + std::string utf8; + Tesses::Framework::Text::StringConverter::UTF8::FromUTF16(utf8,str); + args.push_back(utf8); + } + + LocalFree(argv); + #else + for(int i = 0; i < argc; i++) + { + args.push_back(argv[i]); + } + #endif + { + + auto req = cb(args); + + if(req) + { + Tesses::Framework::Http::HttpServer svr(0,req,false); + svr.StartAccepting(); + auto port = svr.GetPort(); + std::string url = "http://127.0.0.1:" + std::to_string((int)port) + "/"; + + webview::webview w(false, nullptr); + wv_mtx.Lock(); + wv_hdl = &w; + w.set_title(wv_title); + wv_mtx.Unlock(); + w.set_size(480, 320, WEBVIEW_HINT_NONE); + w.navigate(url); + + w.run(); + + wv_mtx.Lock(); + + wv_mtx.Unlock(); + } + else { + if(clo) + clo(req); + + TF_Quit(); + return 1; + } + if(clo) + clo(req); + } + + TF_Quit(); + return 0; + } +} \ No newline at end of file