-#endif
-
-#ifdef _WIN32
-int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpCmdLine,
- int nCmdShow) {
- (void)hInst;
- (void)hPrevInst;
- (void)lpCmdLine;
- (void)nCmdShow;
-#else
-int main(void) {
-#endif
- webview_t w = webview_create(0, NULL);
- webview_set_title(w, "Basic Example");
- webview_set_size(w, 480, 320, WEBVIEW_HINT_NONE);
- webview_set_html(w, "Thanks for using webview!");
- webview_run(w);
- webview_destroy(w);
- return 0;
-}
-```
-
-### Building the Example
-
-Build the project:
-
-```sh
-cmake -G Ninja -B build -S . -D CMAKE_BUILD_TYPE=Release
-cmake --build build
-```
-
-Find the executable in the `build/bin` directory.
-
-### Building Amalgamated Library
-
-An amalgamated library can be built when building the project using CMake, or the `amalgamate.py` script can be invoked directly.
-
-The latter is described below.
-
-```sh
-python3 scripts/amalgamate/amalgamate.py --base core --search include --output webview_amalgamation.h src
-```
-
-See `python3 scripts/amalgamate/amalgamate.py --help` for script usage.
-
-### Non-CMake Usage
-
-Here's an example for invoking GCC/Clang-like compilers directly. Use the `main.cc` file from the previous example.
-
-Place either the amalgamated `webview.h` header or all of the individual files into `libs/webview`, and `WebView2.h` from [MS WebView2][ms-webview2-sdk] into `libs`.
-
-Build the project on your chosen platform.
-
-
- macOS
- c++ main.cc -O2 --std=c++11 -Ilibs -framework WebKit -ldl -o example
-
-
-
- Linux
- c++ main.cc -O2 --std=c++11 -Ilibs $(pkg-config --cflags --libs gtk+-3.0 webkit2gtk-4.1) -ldl -o example
-
-
-
- Windows
- c++ main.cc -O2 --std=c++14 -static -mwindows -Ilibs -ladvapi32 -lole32 -lshell32 -lshlwapi -luser32 -lversion -o example
-
-
-## Customization
-
-### CMake Targets
-
-The following CMake targets are available:
-
-Name | Description
----- | -----------
-`webview::core` | Headers for C++.
-`webview::core_shared` | Shared library for C.
-`webview::core_static` | Static library for C.
-
-Special targets for on-demand checks and related tasks:
-
-Name | Description
----- | -----------
-`webview_format_check` | Check files with clang-format.
-`webview_reformat` | Reformat files with clang-format.
-
-### CMake Options
-
-The following boolean options can be used when building the webview project standalone or when building it as part of your project (e.g. with FetchContent).
-
-Option | Description
------- | -----------
-`WEBVIEW_BUILD` | Enable building
-`WEBVIEW_BUILD_AMALGAMATION` | Build amalgamated library
-`WEBVIEW_BUILD_DOCS` | Build documentation
-`WEBVIEW_BUILD_EXAMPLES` | Build examples
-`WEBVIEW_BUILD_SHARED_LIBRARY` | Build shared libraries
-`WEBVIEW_BUILD_STATIC_LIBRARY` | Build static libraries
-`WEBVIEW_BUILD_TESTS` | Build tests
-`WEBVIEW_ENABLE_CHECKS` | Enable checks
-`WEBVIEW_ENABLE_CLANG_FORMAT` | Enable clang-format
-`WEBVIEW_ENABLE_CLANG_TIDY` | Enable clang-tidy
-`WEBVIEW_ENABLE_PACKAGING` | Enable packaging
-`WEBVIEW_INSTALL_DOCS` | Install documentation
-`WEBVIEW_INSTALL_TARGETS` | Install targets
-`WEBVIEW_IS_CI` | Initialized by the `CI` environment variable
-`WEBVIEW_PACKAGE_AMALGAMATION` | Package amalgamated library
-`WEBVIEW_PACKAGE_DOCS` | Package documentation
-`WEBVIEW_PACKAGE_HEADERS` | Package headers
-`WEBVIEW_PACKAGE_LIB` | Package compiled libraries
-`WEBVIEW_STRICT_CHECKS` | Make checks strict
-`WEBVIEW_STRICT_CLANG_FORMAT` | Make clang-format check strict
-`WEBVIEW_STRICT_CLANG_TIDY` | Make clang-tidy check strict
-`WEBVIEW_USE_COMPAT_MINGW` | Use compatibility helper for MinGW
-`WEBVIEW_USE_STATIC_MSVC_RUNTIME` | Use static runtime library (MSVC)
-
-> [!NOTE]
-> Checks are *enabled* by default, but aren't *enforced* by default for local development (controlled by the `WEBVIEW_IS_CI` option).
-
-Non-boolean options:
-
-Option | Description
------- | -----------
-`WEBVIEW_CLANG_FORMAT_EXE` | Path of the `clang-format` executable.
-`WEBVIEW_CLANG_TIDY_EXE` | Path of the `clang-tidy` executable.
-
-### Package Consumer Options
-
-These options can be used when when using the webview CMake package.
-
-#### Linux-specific Options
-
-Option | Description
------- | -----------
-`WEBVIEW_WEBKITGTK_API` | WebKitGTK API to interface with, e.g. `6.0`, `4.1` (recommended) or `4.0`. This will also automatically decide the GTK version. Uses the latest recommended API by default if available, or the latest known and available API. Note that there can be major differences between API versions that can affect feature availability. See webview API documentation for details on feature availability.
-
-#### Windows-specific Options
-
-Option | Description
------- | -----------
-`WEBVIEW_MSWEBVIEW2_VERSION` | MS WebView2 version, e.g. `1.0.1150.38`.
-`WEBVIEW_USE_BUILTIN_MSWEBVIEW2`| Use built-in MS WebView2.
-
-### Compile-time Options
-
-These options can be specified as preprocessor macros to modify the build, but are not needed when using CMake.
-
-#### C API Linkage
-
-Name | Description
----- | -----------
-`WEBVIEW_API` | Controls C API linkage, symbol visibility and whether it's a shared library. By default this is `inline` for C++ and `extern` for C.
-`WEBVIEW_BUILD_SHARED` | Modifies `WEBVIEW_API` for building a shared library.
-`WEBVIEW_SHARED` | Modifies `WEBVIEW_API` for using a shared library.
-`WEBVIEW_STATIC` | Modifies `WEBVIEW_API` for building or using a static library.
-
-#### Backend Selection
-
-Name | Description
----- | -----------
-`WEBVIEW_GTK` | Compile the GTK/WebKitGTK backend.
-`WEBVIEW_COCOA` | Compile the Cocoa/WebKit backend.
-`WEBVIEW_EDGE` | Compile the Win32/WebView2 backend.
-
-#### Windows-specific Options
-
-Option | Description
------- | -----------
-`WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL` | Enables (`1`) or disables (`0`) the built-in implementation of the WebView2 loader. Enabling this avoids the need for `WebView2Loader.dll` but if the DLL is present then the DLL takes priority. This option is enabled by default.
-`WEBVIEW_MSWEBVIEW2_EXPLICIT_LINK`| Enables (`1`) or disables (`0`) explicit linking of `WebView2Loader.dll`. Enabling this avoids the need for import libraries (`*.lib`). This option is enabled by default if `WEBVIEW_MSWEBVIEW2_BUILTIN_IMPL` is enabled.
-
-## MinGW-w64 Requirements
-
-In order to build this library using MinGW-w64 on Windows then it must support C++14 and have an up-to-date Windows SDK.
-
-Distributions that are known to be compatible:
-
-* [LLVM MinGW](https://github.com/mstorsjo/llvm-mingw)
-* [MSYS2](https://www.msys2.org/)
-* [WinLibs](https://winlibs.com/)
-
-## MS WebView2 Loader
-
-Linking the WebView2 loader part of the Microsoft WebView2 SDK is not a hard requirement when using our webview library, and neither is distributing `WebView2Loader.dll` with your app.
-
-If, however, `WebView2Loader.dll` is loadable at runtime, e.g. from the executable's directory, then it will be used; otherwise our minimalistic implementation will be used instead.
-
-Should you wish to use the official loader then remember to distribute it along with your app unless you link it statically. Linking it statically is possible with Visual C++ but not MinGW-w64.
-
-Here are some of the noteworthy ways our implementation of the loader differs from the official implementation:
-
-* Does not support configuring WebView2 using environment variables such as `WEBVIEW2_BROWSER_EXECUTABLE_FOLDER`.
-* Microsoft Edge Insider (preview) channels are not supported.
-
-[Customization options](#Customization) can be used to change how the library integrates the WebView2 loader.
-
-## Thread Safety
-
-Since library functions generally do not have thread safety guarantees, `webview_dispatch()` (C) / `webview::dispatch()` (C++) can be used to schedule code to execute on the main/GUI thread and thereby make that execution safe in multi-threaded applications.
-
-`webview_return()` (C) / `webview::resolve()` (C++) uses `*dispatch()` internally and is therefore safe to call from another thread.
-
-The main/GUI thread should be the thread that calls `webview_run()` (C) / `webview::run()` (C++).
-
-## Development
-
-This project uses the CMake build system.
-
-### Development Dependencies
-
-In addition to the dependencies mentioned earlier in this document for developing *with* the webview library, the following are used during development *of* the webview library.
-
-* Amalgamation:
- * Python >= 3.9
-* Checks:
- * `clang-format`
- * `clang-tidy`
-* Documentation:
- * Doxygen
- * Graphvis
-
-### Building
-
-```sh
-cmake -G "Ninja Multi-Config" -B build -S .
-cmake --build build --config CONFIG
-```
-
-Replace `CONFIG` with one of `Debug`, `Release`, or `Profile`. Use `Profile` to enable code coverage (GCC/Clang).
-
-Run tests:
-
-```sh
-ctest --test-dir build --build-config CONFIG
-```
-
-Generate test coverage report:
-
-```sh
-gcovr
-```
-
-Find the coverage report in `build/coverage`.
-
-### Packaging
-
-Run this after building the `Debug` and `Release` configs of the project:
-
-```sh
-cd build
-cpack -G External -C "Debug;Release" --config CPackConfig.cmake
-```
-
-### Cross-compilation
-
-See CMake toolchain files in the `cmake/toolchains` directory.
-
-For example, this targets Windows x64 on Linux with POSIX threads:
-
-```sh
-cmake -G "Ninja Multi-Config" -B build -S . -D CMAKE_TOOLCHAIN_FILE=cmake/toolchains/x86_64-w64-mingw32.cmake -D WEBVIEW_TOOLCHAIN_EXECUTABLE_SUFFIX=-posix
-cmake --build build --config CONFIG
-```
-
-## Limitations
-
-### Browser Features
-
-Since a browser engine is not a full web browser it may not support every feature you may expect from a browser. If you find that a feature does not work as expected then please consult with the browser engine's documentation and [open an issue][issues-new] if you think that the library should support it.
-
-For example, the library does not attempt to support user interaction features like `alert()`, `confirm()` and `prompt()` and other non-essential features like `console.log()`.
-
-## Bindings
-
-Language | Project
----------- | -------
-Ada | [thechampagne/webview-ada](https://github.com/thechampagne/webview-ada)
-Bun | [tr1ckydev/webview-bun](https://github.com/tr1ckydev/webview-bun)
-C# | [webview/webview_csharp](https://github.com/webview/webview_csharp)
-C3 | [thechampagne/webview-c3](https://github.com/thechampagne/webview-c3)
-Crystal | [naqvis/webview](https://github.com/naqvis/webview)
-D | [thechampagne/webview-d](https://github.com/thechampagne/webview-d), [ronnie-w/webviewd](https://github.com/ronnie-w/webviewd)
-Deno | [webview/webview_deno](https://github.com/webview/webview_deno)
-Go | [webview/webview_go][webview_go]
-Harbour | [EricLendvai/Harbour_WebView](https://github.com/EricLendvai/Harbour_WebView)
-Haskell | [lettier/webviewhs](https://github.com/lettier/webviewhs)
-Janet | [janet-lang/webview](https://github.com/janet-lang/webview)
-Java | [webview/webview_java](https://github.com/webview/webview_java)
-Kotlin | [Winterreisender/webviewko](https://github.com/Winterreisender/webviewko)
-MoonBit | [justjavac/moonbit-webview](https://github.com/justjavac/moonbit-webview)
-Nim | [oskca/webview](https://github.com/oskca/webview), [neroist/webview](https://github.com/neroist/webview)
-Node.js | [Winterreisender/webview-nodejs](https://github.com/Winterreisender/webview-nodejs)
-Odin | [thechampagne/webview-odin](https://github.com/thechampagne/webview-odin)
-Pascal | [PierceNg/fpwebview](http://github.com/PierceNg/fpwebview)
-Python | [congzhangzh/webview_python](https://github.com/congzhangzh/webview_python),[zserge/webview-python](https://github.com/zserge/webview-python)
-PHP | [0hr/php-webview](https://github.com/0hr/php-webview), [KingBes/pebview](https://github.com/KingBes/pebview), [happystraw/php-ext-webview](https://github.com/happystraw/php-ext-webview)
-Ring | [ysdragon/webview](https://github.com/ysdragon/webview)
-Ruby | [Maaarcocr/webview_ruby](https://github.com/Maaarcocr/webview_ruby)
-Rust | [Boscop/web-view](https://github.com/Boscop/web-view)
-Swift | [jakenvac/SwiftWebview](https://github.com/jakenvac/SwiftWebview)
-V | [malisipi/mui](https://github.com/malisipi/mui/tree/main/webview), [ttytm/webview](https://github.com/ttytm/webview)
-Vala | [taozuhong/webview-vala](https://github.com/taozuhong/webview-vala)
-Zig | [thechampagne/webview-zig](https://github.com/thechampagne/webview-zig), [happystraw/zig-webview](https://github.com/happystraw/zig-webview)
-
-If you wish to add bindings to the list, feel free to submit a pull request or [open an issue][issues-new].
-
-## Generating Bindings
-
-You can generate bindings for the library by yourself using the included SWIG interface (`webview.i`).
-
-Here are some examples to get you started. Unix-style command lines are used for conciseness.
-
-```sh
-mkdir -p build/bindings/{python,csharp,java,ruby}
-swig -c++ -python -outdir build/bindings/python -o build/bindings/python/python_wrap.cpp webview.i
-swig -c++ -csharp -outdir build/bindings/csharp -o build/bindings/csharp/csharp_wrap.cpp webview.i
-swig -c++ -java -outdir build/bindings/java -o build/bindings/java/java_wrap.cpp webview.i
-swig -c++ -ruby -outdir build/bindings/ruby -o build/bindings/ruby/ruby_wrap.cpp webview.i
-```
-
-## License
-
-Code is distributed under MIT license, feel free to use it in your proprietary projects as well.
-
-[examples]: https://github.com/webview/webview/tree/master/examples
+[webview_go]: https://github.com/webview/webview_go
[gtk]: https://gtk.org/
-[issues]: https://github.com/webview/docs/issues
-[issues-new]: https://github.com/webview/webview/issues/new
[webkit]: https://webkit.org/
[webkitgtk]: https://webkitgtk.org/
-[webview]: https://github.com/webview/webview
-[webview_go]: https://github.com/webview/webview_go
-[webview.dev]: https://webview.dev
[ms-webview2]: https://developer.microsoft.com/en-us/microsoft-edge/webview2/
-[ms-webview2-sdk]: https://www.nuget.org/packages/Microsoft.Web.WebView2
-[ms-webview2-rt]: https://developer.microsoft.com/en-us/microsoft-edge/webview2/
[win32-api]: https://docs.microsoft.com/en-us/windows/win32/apiindex/windows-api-list
diff --git a/browser.ts b/browser.ts
new file mode 100644
index 000000000..81125ec5a
--- /dev/null
+++ b/browser.ts
@@ -0,0 +1,16 @@
+export const Alloy = {
+ Transpiler: class {
+ constructor(options) {
+ this.options = options || {};
+ }
+ transformSync(code, loader) {
+ // Browser fallback or WASM-based transform
+ return code;
+ }
+ async transform(code, loader) {
+ return this.transformSync(code, loader);
+ }
+ }
+};
+
+export default { Alloy };
diff --git a/core/CMakeLists.txt b/core/CMakeLists.txt
index 5c2083c73..c85fc34d7 100644
--- a/core/CMakeLists.txt
+++ b/core/CMakeLists.txt
@@ -6,7 +6,7 @@ target_include_directories(
INTERFACE
"$"
"$")
-target_link_libraries(webview_core_headers INTERFACE ${WEBVIEW_DEPENDENCIES})
+target_link_libraries(webview_core_headers INTERFACE ${WEBVIEW_DEPENDENCIES} sqlite3 yoga mquickjs)
# Note that we also use CMAKE_CXX_STANDARD which can override this
target_compile_features(webview_core_headers INTERFACE cxx_std_11)
set_target_properties(webview_core_headers PROPERTIES
@@ -20,7 +20,7 @@ endif()
if(WEBVIEW_BUILD_SHARED_LIBRARY)
add_library(webview_core_shared SHARED)
add_library(webview::core_shared ALIAS webview_core_shared)
- target_sources(webview_core_shared PRIVATE src/webview.cc)
+ target_sources(webview_core_shared PRIVATE src/webview.cc src/alloy_gui.cc)
target_link_libraries(webview_core_shared PUBLIC webview_core_headers)
set_target_properties(webview_core_shared PROPERTIES
OUTPUT_NAME webview
@@ -43,7 +43,7 @@ if(WEBVIEW_BUILD_STATIC_LIBRARY)
add_library(webview_core_static STATIC)
add_library(webview::core_static ALIAS webview_core_static)
- target_sources(webview_core_static PRIVATE src/webview.cc)
+ target_sources(webview_core_static PRIVATE src/webview.cc src/alloy_gui.cc)
target_link_libraries(webview_core_static PUBLIC webview_core_headers)
set_target_properties(webview_core_static PROPERTIES
OUTPUT_NAME "${STATIC_LIBRARY_OUTPUT_NAME}"
diff --git a/core/include/alloy/api.h b/core/include/alloy/api.h
new file mode 100644
index 000000000..4db763fe3
--- /dev/null
+++ b/core/include/alloy/api.h
@@ -0,0 +1,233 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_API_H
+#define ALLOY_API_H
+
+#include
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if defined(ALLOY_API_SHARED)
+#if defined(_WIN32) || defined(__CYGWIN__)
+#if defined(ALLOY_API_BUILD)
+#define ALLOY_API __declspec(dllexport)
+#else
+#define ALLOY_API __declspec(dllimport)
+#endif
+#else
+#define ALLOY_API __attribute__((visibility("default")))
+#endif
+#else
+#define ALLOY_API
+#endif
+
+// ── Types ──────────────────────────────────────────────────────────────────
+
+typedef void *alloy_component_t; // opaque component handle
+typedef void *alloy_signal_t; // opaque signal handle
+typedef void *alloy_computed_t; // opaque computed signal handle
+typedef void *alloy_effect_t; // opaque effect handle
+
+typedef enum {
+ ALLOY_OK = 0,
+ ALLOY_ERROR_INVALID_ARGUMENT,
+ ALLOY_ERROR_INVALID_STATE,
+ ALLOY_ERROR_PLATFORM,
+ ALLOY_ERROR_BUFFER_TOO_SMALL,
+ ALLOY_ERROR_NOT_SUPPORTED,
+} alloy_error_t;
+
+typedef enum {
+ ALLOY_EVENT_CLICK = 0,
+ ALLOY_EVENT_CHANGE,
+ ALLOY_EVENT_CLOSE,
+ ALLOY_EVENT_FOCUS,
+ ALLOY_EVENT_BLUR,
+} alloy_event_type_t;
+
+typedef enum {
+ ALLOY_PROP_TEXT = 0,
+ ALLOY_PROP_CHECKED,
+ ALLOY_PROP_VALUE,
+ ALLOY_PROP_ENABLED,
+ ALLOY_PROP_VISIBLE,
+ ALLOY_PROP_LABEL,
+} alloy_prop_id_t;
+
+typedef void (*alloy_event_cb_t)(alloy_component_t handle,
+ alloy_event_type_t event,
+ void *userdata);
+
+typedef struct {
+ unsigned int background; // RGBA packed
+ unsigned int foreground; // RGBA packed
+ float font_size; // points; 0 = inherit
+ const char *font_family; // NULL = inherit
+ float border_radius;// points
+ float opacity; // 0.0–1.0
+} alloy_style_t;
+
+// ── Error ──────────────────────────────────────────────────────────────────
+
+ALLOY_API const char *alloy_error_message(alloy_error_t err);
+
+// ── Signal system ──────────────────────────────────────────────────────────
+
+ALLOY_API alloy_signal_t alloy_signal_create_str(const char *initial);
+ALLOY_API alloy_signal_t alloy_signal_create_double(double initial);
+ALLOY_API alloy_signal_t alloy_signal_create_int(int initial);
+ALLOY_API alloy_signal_t alloy_signal_create_bool(int initial);
+
+ALLOY_API alloy_error_t alloy_signal_set_str(alloy_signal_t s, const char *v);
+ALLOY_API alloy_error_t alloy_signal_set_double(alloy_signal_t s, double v);
+ALLOY_API alloy_error_t alloy_signal_set_int(alloy_signal_t s, int v);
+ALLOY_API alloy_error_t alloy_signal_set_bool(alloy_signal_t s, int v);
+
+ALLOY_API const char *alloy_signal_get_str(alloy_signal_t s);
+ALLOY_API double alloy_signal_get_double(alloy_signal_t s);
+ALLOY_API int alloy_signal_get_int(alloy_signal_t s);
+ALLOY_API int alloy_signal_get_bool(alloy_signal_t s);
+
+ALLOY_API alloy_computed_t alloy_computed_create(
+ alloy_signal_t *deps, size_t dep_count,
+ void (*compute)(alloy_signal_t *deps, size_t dep_count, void *out, void *userdata),
+ void *userdata);
+
+ALLOY_API alloy_effect_t alloy_effect_create(
+ alloy_signal_t *deps, size_t dep_count,
+ void (*run)(void *userdata), void *userdata);
+
+ALLOY_API alloy_error_t alloy_signal_destroy(alloy_signal_t s);
+ALLOY_API alloy_error_t alloy_computed_destroy(alloy_computed_t c);
+ALLOY_API alloy_error_t alloy_effect_destroy(alloy_effect_t e);
+
+// ── Property binding ───────────────────────────────────────────────────────
+
+ALLOY_API alloy_error_t alloy_bind_property(alloy_component_t component,
+ alloy_prop_id_t property,
+ alloy_signal_t signal);
+ALLOY_API alloy_error_t alloy_unbind_property(alloy_component_t component,
+ alloy_prop_id_t property);
+
+// ── Component lifecycle ────────────────────────────────────────────────────
+
+ALLOY_API alloy_component_t alloy_create_window(const char *title,
+ int width, int height);
+ALLOY_API alloy_component_t alloy_create_button(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_textfield(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_textarea(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_label(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_checkbox(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_radiobutton(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_combobox(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_slider(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_spinner(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_loadingspinner(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_progressbar(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_listview(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_treeview(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_tabview(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_webview(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_vstack(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_hstack(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_scrollview(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_menu(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_menubar(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_toolbar(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_statusbar(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_splitter(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_dialog(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_filedialog(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_colorpicker(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_datepicker(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_timepicker(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_tooltip(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_divider(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_image(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_icon(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_separator(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_groupbox(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_accordion(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_popover(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_contextmenu(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_switch(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_badge(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_chip(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_card(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_link(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_rating(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_richtexteditor(alloy_component_t parent);
+ALLOY_API alloy_component_t alloy_create_codeeditor(alloy_component_t parent);
+
+ALLOY_API alloy_error_t alloy_destroy(alloy_component_t handle);
+
+// ── Property getters/setters ───────────────────────────────────────────────
+
+ALLOY_API alloy_error_t alloy_set_text(alloy_component_t h, const char *text);
+ALLOY_API alloy_error_t alloy_get_text(alloy_component_t h,
+ char *buf, size_t buf_len);
+ALLOY_API alloy_error_t alloy_set_checked(alloy_component_t h, int checked);
+ALLOY_API int alloy_get_checked(alloy_component_t h);
+ALLOY_API alloy_error_t alloy_set_value(alloy_component_t h, double value);
+ALLOY_API double alloy_get_value(alloy_component_t h);
+ALLOY_API alloy_error_t alloy_set_enabled(alloy_component_t h, int enabled);
+ALLOY_API int alloy_get_enabled(alloy_component_t h);
+ALLOY_API alloy_error_t alloy_set_visible(alloy_component_t h, int visible);
+ALLOY_API int alloy_get_visible(alloy_component_t h);
+ALLOY_API alloy_error_t alloy_set_style(alloy_component_t h,
+ const alloy_style_t *style);
+
+// ── Layout ─────────────────────────────────────────────────────────────────
+
+ALLOY_API alloy_error_t alloy_add_child(alloy_component_t container,
+ alloy_component_t child);
+ALLOY_API alloy_error_t alloy_set_flex(alloy_component_t h, float flex);
+ALLOY_API alloy_error_t alloy_set_padding(alloy_component_t h,
+ float top, float right,
+ float bottom, float left);
+ALLOY_API alloy_error_t alloy_set_margin(alloy_component_t h,
+ float top, float right,
+ float bottom, float left);
+ALLOY_API alloy_error_t alloy_layout(alloy_component_t window);
+
+// ── Events ─────────────────────────────────────────────────────────────────
+
+ALLOY_API alloy_error_t alloy_set_event_callback(alloy_component_t handle,
+ alloy_event_type_t event,
+ alloy_event_cb_t callback,
+ void *userdata);
+
+// ── Event loop ─────────────────────────────────────────────────────────────
+
+ALLOY_API alloy_error_t alloy_run(alloy_component_t window);
+ALLOY_API alloy_error_t alloy_terminate(alloy_component_t window);
+ALLOY_API alloy_error_t alloy_dispatch(alloy_component_t window,
+ void (*fn)(void *arg), void *arg);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // ALLOY_API_H
diff --git a/core/include/alloy/detail/backends/cocoa_gui.hh b/core/include/alloy/detail/backends/cocoa_gui.hh
new file mode 100644
index 000000000..167ddedb9
--- /dev/null
+++ b/core/include/alloy/detail/backends/cocoa_gui.hh
@@ -0,0 +1,32 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_BACKENDS_COCOA_GUI_HH
+#define ALLOY_BACKENDS_COCOA_GUI_HH
+
+#ifdef __APPLE__
+namespace alloy::detail {
+// Placeholder for Cocoa backend classes
+}
+#endif
+
+#endif // ALLOY_BACKENDS_COCOA_GUI_HH
diff --git a/core/include/alloy/detail/backends/gtk_gui.hh b/core/include/alloy/detail/backends/gtk_gui.hh
new file mode 100644
index 000000000..a30bb5f7e
--- /dev/null
+++ b/core/include/alloy/detail/backends/gtk_gui.hh
@@ -0,0 +1,58 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_BACKENDS_GTK_GUI_HH
+#define ALLOY_BACKENDS_GTK_GUI_HH
+
+#include "../components/window.hh"
+#include "../components/button.hh"
+#include "../components/textfield.hh"
+#include "../components/label.hh"
+#include "../components/checkbox.hh"
+#include "../components/textarea.hh"
+#include "../components/slider.hh"
+#include "../components/progressbar.hh"
+#include "../components/switch.hh"
+#include "../components/radiobutton.hh"
+#include "../components/combobox.hh"
+#include "../components/spinner.hh"
+#include "../components/statusbar.hh"
+#include "../components/listview.hh"
+#include "../components/tabview.hh"
+#include "../components/webview_comp.hh"
+#include "../components/layout_containers.hh"
+#include "../components/treeview.hh"
+#include "../components/scrollview.hh"
+#include "../components/image.hh"
+#include "../components/groupbox.hh"
+#include "../components/link.hh"
+#include "../components/menu.hh"
+#include "../components/toolbar.hh"
+#include "../components/dialog.hh"
+#include "../components/pickers.hh"
+#include "../components/misc.hh"
+#include "../components/advanced.hh"
+#include "../components/extras.hh"
+#include "../components/extras_2.hh"
+#include "../components/extras_3.hh"
+
+#endif // ALLOY_BACKENDS_GTK_GUI_HH
diff --git a/core/include/alloy/detail/backends/win32_gui.hh b/core/include/alloy/detail/backends/win32_gui.hh
new file mode 100644
index 000000000..a3804d185
--- /dev/null
+++ b/core/include/alloy/detail/backends/win32_gui.hh
@@ -0,0 +1,33 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_BACKENDS_WIN32_GUI_HH
+#define ALLOY_BACKENDS_WIN32_GUI_HH
+
+#ifdef _WIN32
+#include
+namespace alloy::detail {
+// Placeholder for Win32 backend classes
+}
+#endif
+
+#endif // ALLOY_BACKENDS_WIN32_GUI_HH
diff --git a/core/include/alloy/detail/component_base.hh b/core/include/alloy/detail/component_base.hh
new file mode 100644
index 000000000..6d74c1a0b
--- /dev/null
+++ b/core/include/alloy/detail/component_base.hh
@@ -0,0 +1,113 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENT_BASE_HH
+#define ALLOY_DETAIL_COMPONENT_BASE_HH
+
+#include "../api.h"
+#include
+#include
+#include
+#include
+
+// Forward decl
+namespace alloy::detail {
+class signal_base;
+struct signal_value;
+}
+
+#include
+
+namespace alloy::detail {
+
+struct event_slot {
+ alloy_event_cb_t fn{};
+ void *userdata{};
+};
+
+class component_base {
+public:
+ virtual ~component_base() {
+ if (m_yoga_node) {
+ YGNodeFree(m_yoga_node);
+ }
+ }
+
+ // Property setters — implemented by each backend subclass
+ virtual alloy_error_t set_text(std::string_view text) = 0;
+ virtual alloy_error_t get_text(char *buf, size_t len) = 0;
+ virtual alloy_error_t set_checked(bool v) = 0;
+ virtual bool get_checked() = 0;
+ virtual alloy_error_t set_value(double v) = 0;
+ virtual double get_value() = 0;
+ virtual alloy_error_t set_enabled(bool v) = 0;
+ virtual bool get_enabled() = 0;
+ virtual alloy_error_t set_visible(bool v) = 0;
+ virtual bool get_visible() = 0;
+ virtual alloy_error_t set_style(const alloy_style_t &s) = 0;
+
+ // Native handle access (for layout, embedding)
+ virtual void *native_handle() = 0;
+
+ // Yoga layout node
+ YGNodeRef yoga_node() const { return m_yoga_node; }
+
+ // Event dispatch — called by backend on native event
+ void fire_event(alloy_event_type_t ev) {
+ auto it = m_events.find(ev);
+ if (it != m_events.end() && it->second.fn) {
+ it->second.fn(static_cast(this), ev,
+ it->second.userdata);
+ }
+ }
+
+ void set_event_callback(alloy_event_type_t ev,
+ alloy_event_cb_t fn, void *ud) {
+ m_events[ev] = {fn, ud};
+ }
+
+ bool is_container() const { return m_is_container; }
+
+ void add_child(component_base *child) {
+ m_children.push_back(child);
+ YGNodeInsertChild(m_yoga_node, child->yoga_node(),
+ YGNodeGetChildCount(m_yoga_node));
+ }
+
+ const std::vector &children() const { return m_children; }
+
+protected:
+ explicit component_base(bool is_container = false)
+ : m_is_container{is_container},
+ m_yoga_node{YGNodeNew()} {}
+
+ YGNodeRef m_yoga_node{};
+ bool m_is_container{};
+ std::vector m_children;
+
+private:
+ std::unordered_map m_events;
+};
+
+} // namespace alloy::detail
+
+#endif // ALLOY_DETAIL_COMPONENT_BASE_HH
diff --git a/core/include/alloy/detail/components/advanced.hh b/core/include/alloy/detail/components/advanced.hh
new file mode 100644
index 000000000..65bab1e6f
--- /dev/null
+++ b/core/include/alloy/detail/components/advanced.hh
@@ -0,0 +1,117 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_ADVANCED_HH
+#define ALLOY_DETAIL_COMPONENTS_ADVANCED_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+
+class gtk_icon : public component_base {
+public:
+ explicit gtk_icon(component_base *parent) : component_base(false) {
+ m_widget = gtk_image_new_from_icon_name("help-about", GTK_ICON_SIZE_BUTTON);
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_icon() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override {
+ gtk_image_set_from_icon_name(GTK_IMAGE(m_widget), text.data(), GTK_ICON_SIZE_BUTTON);
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+private:
+ GtkWidget *m_widget;
+};
+
+class gtk_accordion : public component_base {
+public:
+ explicit gtk_accordion(component_base *parent) : component_base(true) {
+ m_widget = gtk_expander_new("");
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_accordion() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override {
+ gtk_expander_set_label(GTK_EXPANDER(m_widget), text.data());
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override {
+ const char *txt = gtk_expander_get_label(GTK_EXPANDER(m_widget));
+ if (txt) strncpy(buf, txt, len);
+ return ALLOY_OK;
+ }
+ alloy_error_t set_checked(bool v) override {
+ gtk_expander_set_expanded(GTK_EXPANDER(m_widget), v);
+ return ALLOY_OK;
+ }
+ bool get_checked() override { return gtk_expander_get_expanded(GTK_EXPANDER(m_widget)); }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+private:
+ GtkWidget *m_widget;
+};
+
+class gtk_popover : public component_base {
+public:
+ explicit gtk_popover(component_base *parent) : component_base(true) {
+ // Requires GTK 3.12+
+ m_widget = gtk_popover_new(parent ? GTK_WIDGET(parent->native_handle()) : NULL);
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_popover() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+private:
+ GtkWidget *m_widget;
+};
+
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/button.hh b/core/include/alloy/detail/components/button.hh
new file mode 100644
index 000000000..1a5c39258
--- /dev/null
+++ b/core/include/alloy/detail/components/button.hh
@@ -0,0 +1,159 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_COMPONENTS_BUTTON_HH
+#define ALLOY_COMPONENTS_BUTTON_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+
+namespace alloy::detail {
+
+class gtk_button : public component_base {
+public:
+ gtk_button(component_base* parent) : component_base(false) {
+ m_widget = gtk_button_new();
+ if (parent) {
+ gtk_container_add(GTK_CONTAINER(parent->native_handle()), m_widget);
+ gtk_widget_show(m_widget);
+ }
+ }
+
+ alloy_error_t set_text(std::string_view text) override {
+ gtk_button_set_label(GTK_BUTTON(m_widget), text.data());
+ return ALLOY_OK;
+ }
+
+ alloy_error_t get_text(char *buf, size_t len) override {
+ const char* label = gtk_button_get_label(GTK_BUTTON(m_widget));
+ if (strlen(label) >= len) return ALLOY_ERROR_BUFFER_TOO_SMALL;
+ strcpy(buf, label);
+ return ALLOY_OK;
+ }
+
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+
+ alloy_error_t set_enabled(bool v) override {
+ gtk_widget_set_sensitive(m_widget, v);
+ return ALLOY_OK;
+ }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+
+ alloy_error_t set_visible(bool v) override {
+ gtk_widget_set_visible(m_widget, v);
+ return ALLOY_OK;
+ }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+
+ alloy_error_t set_style(const alloy_style_t &s) override {
+ GdkRGBA bg, fg;
+ bg.red = ((s.background >> 24) & 0xFF) / 255.0;
+ bg.green = ((s.background >> 16) & 0xFF) / 255.0;
+ bg.blue = ((s.background >> 8) & 0xFF) / 255.0;
+ bg.alpha = (s.background & 0xFF) / 255.0;
+
+ fg.red = ((s.foreground >> 24) & 0xFF) / 255.0;
+ fg.green = ((s.foreground >> 16) & 0xFF) / 255.0;
+ fg.blue = ((s.foreground >> 8) & 0xFF) / 255.0;
+ fg.alpha = (s.foreground & 0xFF) / 255.0;
+
+ gtk_widget_override_background_color(m_widget, GTK_STATE_FLAG_NORMAL, &bg);
+ gtk_widget_override_color(m_widget, GTK_STATE_FLAG_NORMAL, &fg);
+ return ALLOY_OK;
+ }
+ void* native_handle() override { return m_widget; }
+
+private:
+ GtkWidget* m_widget;
+};
+
+} // namespace alloy::detail
+#endif
+
+#ifdef WEBVIEW_PLATFORM_DARWIN
+#include
+#if TARGET_OS_OSX
+#import
+
+namespace alloy::detail {
+
+class cocoa_button : public component_base {
+public:
+ cocoa_button(component_base* parent) : component_base(false) {
+ m_widget = [[NSButton alloc] initWithFrame:NSZeroRect];
+ [m_widget setButtonType:NSButtonTypeMomentaryLight];
+ [m_widget setBezelStyle:NSBezelStyleRounded];
+ if (parent) {
+ NSView* parent_view = (NSView*)parent->native_handle();
+ [parent_view addSubview:m_widget];
+ }
+ }
+
+ alloy_error_t set_text(std::string_view text) override {
+ [m_widget setTitle:[NSString stringWithUTF8String:text.data()]];
+ return ALLOY_OK;
+ }
+
+ alloy_error_t get_text(char *buf, size_t len) override {
+ const char* label = [[m_widget title] UTF8String];
+ if (strlen(label) >= len) return ALLOY_ERROR_BUFFER_TOO_SMALL;
+ strcpy(buf, label);
+ return ALLOY_OK;
+ }
+
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+
+ alloy_error_t set_enabled(bool v) override {
+ [m_widget setEnabled:v];
+ return ALLOY_OK;
+ }
+ bool get_enabled() override { return [m_widget isEnabled]; }
+
+ alloy_error_t set_visible(bool v) override {
+ [m_widget setHidden:!v];
+ return ALLOY_OK;
+ }
+ bool get_visible() override { return ![m_widget isHidden]; }
+
+ alloy_error_t set_style(const alloy_style_t &s) override {
+ // In Cocoa, basic styling of NSButton is limited unless using CALayer or custom cell
+ return ALLOY_OK;
+ }
+ void* native_handle() override { return m_widget; }
+
+private:
+ NSButton* m_widget;
+};
+
+} // namespace alloy::detail
+#endif
+#endif
+
+#endif // ALLOY_COMPONENTS_BUTTON_HH
diff --git a/core/include/alloy/detail/components/checkbox.hh b/core/include/alloy/detail/components/checkbox.hh
new file mode 100644
index 000000000..c8cc224dc
--- /dev/null
+++ b/core/include/alloy/detail/components/checkbox.hh
@@ -0,0 +1,67 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_CHECKBOX_HH
+#define ALLOY_DETAIL_COMPONENTS_CHECKBOX_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_checkbox : public component_base {
+public:
+ explicit gtk_checkbox(component_base *parent) : component_base(false) {
+ m_widget = gtk_check_button_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_checkbox() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override {
+ gtk_button_set_label(GTK_BUTTON(m_widget), text.data());
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override {
+ const char *txt = gtk_button_get_label(GTK_BUTTON(m_widget));
+ if (!txt) return ALLOY_ERROR_PLATFORM;
+ strncpy(buf, txt, len);
+ return ALLOY_OK;
+ }
+ alloy_error_t set_checked(bool v) override {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_widget), v);
+ return ALLOY_OK;
+ }
+ bool get_checked() override { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_widget)); }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/combobox.hh b/core/include/alloy/detail/components/combobox.hh
new file mode 100644
index 000000000..f520cfce6
--- /dev/null
+++ b/core/include/alloy/detail/components/combobox.hh
@@ -0,0 +1,66 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_COMBOBOX_HH
+#define ALLOY_DETAIL_COMPONENTS_COMBOBOX_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_combobox : public component_base {
+public:
+ explicit gtk_combobox(component_base *parent) : component_base(false) {
+ m_widget = gtk_combo_box_text_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_combobox() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override {
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(m_widget), text.data());
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override {
+ char* txt = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(m_widget));
+ if (txt) { strncpy(buf, txt, len); g_free(txt); }
+ return ALLOY_OK;
+ }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override {
+ gtk_combo_box_set_active(GTK_COMBO_BOX(m_widget), (int)v);
+ return ALLOY_OK;
+ }
+ double get_value() override { return gtk_combo_box_get_active(GTK_COMBO_BOX(m_widget)); }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/dialog.hh b/core/include/alloy/detail/components/dialog.hh
new file mode 100644
index 000000000..35caa9be6
--- /dev/null
+++ b/core/include/alloy/detail/components/dialog.hh
@@ -0,0 +1,63 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_DIALOG_HH
+#define ALLOY_DETAIL_COMPONENTS_DIALOG_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_dialog : public component_base {
+public:
+ explicit gtk_dialog(component_base *parent) : component_base(true) {
+ m_widget = gtk_dialog_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_dialog() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override {
+ gtk_window_set_title(GTK_WINDOW(m_widget), text.data());
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override {
+ const char *txt = gtk_window_get_title(GTK_WINDOW(m_widget));
+ if (txt) strncpy(buf, txt, len);
+ return ALLOY_OK;
+ }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/extras.hh b/core/include/alloy/detail/components/extras.hh
new file mode 100644
index 000000000..35c8be97d
--- /dev/null
+++ b/core/include/alloy/detail/components/extras.hh
@@ -0,0 +1,103 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_EXTRAS_HH
+#define ALLOY_DETAIL_COMPONENTS_EXTRAS_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+
+class gtk_badge : public component_base {
+public:
+ explicit gtk_badge(component_base *parent) : component_base(false) {
+ m_widget = gtk_label_new("");
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_badge() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { gtk_label_set_text(GTK_LABEL(m_widget), text.data()); return ALLOY_OK; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { return ALLOY_OK; }
+ bool get_enabled() override { return true; }
+ alloy_error_t set_visible(bool v) override { return ALLOY_OK; }
+ bool get_visible() override { return true; }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+private:
+ GtkWidget *m_widget;
+};
+
+class gtk_chip : public component_base {
+public:
+ explicit gtk_chip(component_base *parent) : component_base(false) {
+ m_widget = gtk_button_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_chip() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { gtk_button_set_label(GTK_BUTTON(m_widget), text.data()); return ALLOY_OK; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { return ALLOY_OK; }
+ bool get_enabled() override { return true; }
+ alloy_error_t set_visible(bool v) override { return ALLOY_OK; }
+ bool get_visible() override { return true; }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+private:
+ GtkWidget *m_widget;
+};
+
+class gtk_card : public component_base {
+public:
+ explicit gtk_card(component_base *parent) : component_base(true) {
+ m_widget = gtk_frame_new(NULL);
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_card() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { return ALLOY_OK; }
+ bool get_enabled() override { return true; }
+ alloy_error_t set_visible(bool v) override { return ALLOY_OK; }
+ bool get_visible() override { return true; }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+private:
+ GtkWidget *m_widget;
+};
+
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/extras_2.hh b/core/include/alloy/detail/components/extras_2.hh
new file mode 100644
index 000000000..9a207e27b
--- /dev/null
+++ b/core/include/alloy/detail/components/extras_2.hh
@@ -0,0 +1,80 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_EXTRAS_2_HH
+#define ALLOY_DETAIL_COMPONENTS_EXTRAS_2_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+
+class gtk_rating : public component_base {
+public:
+ explicit gtk_rating(component_base *parent) : component_base(false) {
+ m_widget = gtk_level_bar_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_rating() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { gtk_level_bar_set_value(GTK_LEVEL_BAR(m_widget), v); return ALLOY_OK; }
+ double get_value() override { return gtk_level_bar_get_value(GTK_LEVEL_BAR(m_widget)); }
+ alloy_error_t set_enabled(bool v) override { return ALLOY_OK; }
+ bool get_enabled() override { return true; }
+ alloy_error_t set_visible(bool v) override { return ALLOY_OK; }
+ bool get_visible() override { return true; }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+private:
+ GtkWidget *m_widget;
+};
+
+class gtk_separator : public component_base {
+public:
+ explicit gtk_separator(component_base *parent) : component_base(false) {
+ m_widget = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_separator() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { return ALLOY_OK; }
+ bool get_enabled() override { return true; }
+ alloy_error_t set_visible(bool v) override { return ALLOY_OK; }
+ bool get_visible() override { return true; }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+private:
+ GtkWidget *m_widget;
+};
+
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/extras_3.hh b/core/include/alloy/detail/components/extras_3.hh
new file mode 100644
index 000000000..4443b237e
--- /dev/null
+++ b/core/include/alloy/detail/components/extras_3.hh
@@ -0,0 +1,137 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_EXTRAS_3_HH
+#define ALLOY_DETAIL_COMPONENTS_EXTRAS_3_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+
+class gtk_filedialog : public component_base {
+public:
+ explicit gtk_filedialog(component_base *parent) : component_base(true) {
+ m_widget = gtk_file_chooser_dialog_new("Open File", parent ? GTK_WINDOW(parent->native_handle()) : NULL,
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ "_Cancel", GTK_RESPONSE_CANCEL,
+ "_Open", GTK_RESPONSE_ACCEPT, NULL);
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_filedialog() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { gtk_window_set_title(GTK_WINDOW(m_widget), text.data()); return ALLOY_OK; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { return ALLOY_OK; }
+ bool get_enabled() override { return true; }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+private:
+ GtkWidget *m_widget;
+};
+
+class gtk_contextmenu : public component_base {
+public:
+ explicit gtk_contextmenu(component_base *parent) : component_base(true) {
+ m_widget = gtk_menu_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_contextmenu() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { return ALLOY_OK; }
+ bool get_enabled() override { return true; }
+ alloy_error_t set_visible(bool v) override { return ALLOY_OK; }
+ bool get_visible() override { return true; }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+private:
+ GtkWidget *m_widget;
+};
+
+class gtk_richtexteditor : public component_base {
+public:
+ explicit gtk_richtexteditor(component_base *parent) : component_base(false) {
+ m_widget = gtk_text_view_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_richtexteditor() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override {
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_widget));
+ gtk_text_buffer_set_text(buffer, text.data(), -1);
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { return ALLOY_OK; }
+ bool get_enabled() override { return true; }
+ alloy_error_t set_visible(bool v) override { return ALLOY_OK; }
+ bool get_visible() override { return true; }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+private:
+ GtkWidget *m_widget;
+};
+
+class gtk_codeeditor : public component_base {
+public:
+ explicit gtk_codeeditor(component_base *parent) : component_base(false) {
+ m_widget = gtk_text_view_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_codeeditor() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override {
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_widget));
+ gtk_text_buffer_set_text(buffer, text.data(), -1);
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { return ALLOY_OK; }
+ bool get_enabled() override { return true; }
+ alloy_error_t set_visible(bool v) override { return ALLOY_OK; }
+ bool get_visible() override { return true; }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+private:
+ GtkWidget *m_widget;
+};
+
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/groupbox.hh b/core/include/alloy/detail/components/groupbox.hh
new file mode 100644
index 000000000..d3a0739ba
--- /dev/null
+++ b/core/include/alloy/detail/components/groupbox.hh
@@ -0,0 +1,63 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_GROUPBOX_HH
+#define ALLOY_DETAIL_COMPONENTS_GROUPBOX_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_groupbox : public component_base {
+public:
+ explicit gtk_groupbox(component_base *parent) : component_base(true) {
+ m_widget = gtk_frame_new(NULL);
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_groupbox() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override {
+ gtk_frame_set_label(GTK_FRAME(m_widget), text.data());
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override {
+ const char *txt = gtk_frame_get_label(GTK_FRAME(m_widget));
+ if (txt) strncpy(buf, txt, len);
+ return ALLOY_OK;
+ }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/image.hh b/core/include/alloy/detail/components/image.hh
new file mode 100644
index 000000000..4807b7b5b
--- /dev/null
+++ b/core/include/alloy/detail/components/image.hh
@@ -0,0 +1,59 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_IMAGE_HH
+#define ALLOY_DETAIL_COMPONENTS_IMAGE_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_image : public component_base {
+public:
+ explicit gtk_image(component_base *parent) : component_base(false) {
+ m_widget = gtk_image_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_image() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override {
+ gtk_image_set_from_file(GTK_IMAGE(m_widget), text.data());
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/label.hh b/core/include/alloy/detail/components/label.hh
new file mode 100644
index 000000000..cb310f590
--- /dev/null
+++ b/core/include/alloy/detail/components/label.hh
@@ -0,0 +1,122 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_LABEL_HH
+#define ALLOY_DETAIL_COMPONENTS_LABEL_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_label : public component_base {
+public:
+ explicit gtk_label(component_base *parent) : component_base(false) {
+ m_widget = gtk_label_new("");
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_label() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override {
+ gtk_label_set_text(GTK_LABEL(m_widget), text.data());
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override {
+ const char *txt = gtk_label_get_text(GTK_LABEL(m_widget));
+ if (!txt) return ALLOY_ERROR_PLATFORM;
+ strncpy(buf, txt, len);
+ return ALLOY_OK;
+ }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+
+#ifdef WEBVIEW_PLATFORM_DARWIN
+#include
+#if TARGET_OS_OSX
+#import
+
+namespace alloy::detail {
+
+class cocoa_label : public component_base {
+public:
+ cocoa_label(component_base* parent) : component_base(false) {
+ m_widget = [[NSTextField alloc] initWithFrame:NSZeroRect];
+ [m_widget setEditable:NO];
+ [m_widget setBezeled:NO];
+ [m_widget setDrawsBackground:NO];
+ [m_widget setSelectable:NO];
+ if (parent) {
+ NSView* parent_view = (NSView*)parent->native_handle();
+ [parent_view addSubview:m_widget];
+ }
+ }
+
+ alloy_error_t set_text(std::string_view text) override {
+ [m_widget setStringValue:[NSString stringWithUTF8String:text.data()]];
+ return ALLOY_OK;
+ }
+
+ alloy_error_t get_text(char *buf, size_t len) override {
+ const char* txt = [[m_widget stringValue] UTF8String];
+ if (strlen(txt) >= len) return ALLOY_ERROR_BUFFER_TOO_SMALL;
+ strcpy(buf, txt);
+ return ALLOY_OK;
+ }
+
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_enabled() override { return true; }
+
+ alloy_error_t set_visible(bool v) override {
+ [m_widget setHidden:!v];
+ return ALLOY_OK;
+ }
+ bool get_visible() override { return ![m_widget isHidden]; }
+
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+ void* native_handle() override { return m_widget; }
+
+private:
+ NSTextField* m_widget;
+};
+
+} // namespace alloy::detail
+#endif
+#endif
+
+#endif
diff --git a/core/include/alloy/detail/components/layout_containers.hh b/core/include/alloy/detail/components/layout_containers.hh
new file mode 100644
index 000000000..eb0986b89
--- /dev/null
+++ b/core/include/alloy/detail/components/layout_containers.hh
@@ -0,0 +1,69 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_LAYOUT_CONTAINERS_HH
+#define ALLOY_DETAIL_COMPONENTS_LAYOUT_CONTAINERS_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+
+class gtk_layout_container : public component_base {
+public:
+ explicit gtk_layout_container(bool horizontal) : component_base(true) {
+ m_widget = gtk_fixed_new();
+ g_object_ref_sink(m_widget);
+ YGNodeStyleSetFlexDirection(m_yoga_node, horizontal ? YGFlexDirectionRow : YGFlexDirectionColumn);
+ }
+ ~gtk_layout_container() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+protected:
+ GtkWidget *m_widget;
+};
+
+class gtk_vstack : public gtk_layout_container {
+public:
+ explicit gtk_vstack(component_base *parent) : gtk_layout_container(false) {}
+};
+
+class gtk_hstack : public gtk_layout_container {
+public:
+ explicit gtk_hstack(component_base *parent) : gtk_layout_container(true) {}
+};
+
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/link.hh b/core/include/alloy/detail/components/link.hh
new file mode 100644
index 000000000..7dbc1862c
--- /dev/null
+++ b/core/include/alloy/detail/components/link.hh
@@ -0,0 +1,67 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_LINK_HH
+#define ALLOY_DETAIL_COMPONENTS_LINK_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_link : public component_base {
+public:
+ explicit gtk_link(component_base *parent) : component_base(false) {
+ m_widget = gtk_link_button_new("");
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_link() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override {
+ gtk_button_set_label(GTK_BUTTON(m_widget), text.data());
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override {
+ const char *txt = gtk_button_get_label(GTK_BUTTON(m_widget));
+ if (txt) strncpy(buf, txt, len);
+ return ALLOY_OK;
+ }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override {
+ // Link URL can be stored in value or text? Reference table says Purpose: Clickable text
+ // Let's use set_value to set the URI
+ return ALLOY_ERROR_NOT_SUPPORTED;
+ }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/listview.hh b/core/include/alloy/detail/components/listview.hh
new file mode 100644
index 000000000..bf3be5a15
--- /dev/null
+++ b/core/include/alloy/detail/components/listview.hh
@@ -0,0 +1,69 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_LISTVIEW_HH
+#define ALLOY_DETAIL_COMPONENTS_LISTVIEW_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_listview : public component_base {
+public:
+ explicit gtk_listview(component_base *parent) : component_base(false) {
+ m_store = gtk_list_store_new(1, G_TYPE_STRING);
+ m_widget = gtk_tree_view_new_with_model(GTK_TREE_MODEL(m_store));
+ GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
+ GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes("Item", renderer, "text", 0, NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(m_widget), column);
+ m_scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+ gtk_container_add(GTK_CONTAINER(m_scrolled_window), m_widget);
+ g_object_ref_sink(m_scrolled_window);
+ }
+ ~gtk_listview() { g_object_unref(m_scrolled_window); }
+ void *native_handle() override { return m_scrolled_window; }
+ alloy_error_t set_text(std::string_view text) override {
+ GtkTreeIter iter;
+ gtk_list_store_append(m_store, &iter);
+ gtk_list_store_set(m_store, &iter, 0, text.data(), -1);
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_scrolled_window); else gtk_widget_hide(m_scrolled_window); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_scrolled_window); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+ GtkWidget *m_scrolled_window;
+ GtkListStore *m_store;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/menu.hh b/core/include/alloy/detail/components/menu.hh
new file mode 100644
index 000000000..c203846db
--- /dev/null
+++ b/core/include/alloy/detail/components/menu.hh
@@ -0,0 +1,80 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_MENU_HH
+#define ALLOY_DETAIL_COMPONENTS_MENU_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_menu : public component_base {
+public:
+ explicit gtk_menu(component_base *parent) : component_base(true) {
+ m_widget = gtk_menu_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_menu() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+
+class gtk_menubar : public component_base {
+public:
+ explicit gtk_menubar(component_base *parent) : component_base(true) {
+ m_widget = gtk_menu_bar_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_menubar() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/misc.hh b/core/include/alloy/detail/components/misc.hh
new file mode 100644
index 000000000..f3d3982ee
--- /dev/null
+++ b/core/include/alloy/detail/components/misc.hh
@@ -0,0 +1,97 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_MISC_HH
+#define ALLOY_DETAIL_COMPONENTS_MISC_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+
+class gtk_splitter : public component_base {
+public:
+ explicit gtk_splitter(component_base *parent) : component_base(true) {
+ m_widget = gtk_paned_new(GTK_ORIENTATION_HORIZONTAL);
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_splitter() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+private:
+ GtkWidget *m_widget;
+};
+
+class gtk_tooltip : public component_base {
+public:
+ explicit gtk_tooltip(component_base *parent) : component_base(false) {}
+ void *native_handle() override { return nullptr; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_OK; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_OK; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_OK; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_OK; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { return ALLOY_OK; }
+ bool get_enabled() override { return true; }
+ alloy_error_t set_visible(bool v) override { return ALLOY_OK; }
+ bool get_visible() override { return true; }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+};
+
+class gtk_divider : public component_base {
+public:
+ explicit gtk_divider(component_base *parent) : component_base(false) {
+ m_widget = gtk_separator_new(GTK_ORIENTATION_HORIZONTAL);
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_divider() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { return ALLOY_OK; }
+ bool get_enabled() override { return true; }
+ alloy_error_t set_visible(bool v) override { return ALLOY_OK; }
+ bool get_visible() override { return true; }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+private:
+ GtkWidget *m_widget;
+};
+
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/pickers.hh b/core/include/alloy/detail/components/pickers.hh
new file mode 100644
index 000000000..28d6d8cb3
--- /dev/null
+++ b/core/include/alloy/detail/components/pickers.hh
@@ -0,0 +1,105 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_PICKERS_HH
+#define ALLOY_DETAIL_COMPONENTS_PICKERS_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+
+class gtk_colorpicker : public component_base {
+public:
+ explicit gtk_colorpicker(component_base *parent) : component_base(false) {
+ m_widget = gtk_color_button_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_colorpicker() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+
+class gtk_datepicker : public component_base {
+public:
+ explicit gtk_datepicker(component_base *parent) : component_base(false) {
+ m_widget = gtk_calendar_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_datepicker() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+
+class gtk_timepicker : public component_base {
+public:
+ explicit gtk_timepicker(component_base *parent) : component_base(false) {
+ m_widget = gtk_spin_button_new_with_range(0, 23, 1);
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_timepicker() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { gtk_spin_button_set_value(GTK_SPIN_BUTTON(m_widget), v); return ALLOY_OK; }
+ double get_value() override { return gtk_spin_button_get_value(GTK_SPIN_BUTTON(m_widget)); }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+private:
+ GtkWidget *m_widget;
+};
+
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/progressbar.hh b/core/include/alloy/detail/components/progressbar.hh
new file mode 100644
index 000000000..d58a483b0
--- /dev/null
+++ b/core/include/alloy/detail/components/progressbar.hh
@@ -0,0 +1,66 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_PROGRESSBAR_HH
+#define ALLOY_DETAIL_COMPONENTS_PROGRESSBAR_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_progressbar : public component_base {
+public:
+ explicit gtk_progressbar(component_base *parent) : component_base(false) {
+ m_widget = gtk_progress_bar_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_progressbar() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override {
+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(m_widget), text.data());
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override {
+ const char *txt = gtk_progress_bar_get_text(GTK_PROGRESS_BAR(m_widget));
+ if (txt) strncpy(buf, txt, len);
+ return ALLOY_OK;
+ }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override {
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(m_widget), v);
+ return ALLOY_OK;
+ }
+ double get_value() override { return gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(m_widget)); }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/radiobutton.hh b/core/include/alloy/detail/components/radiobutton.hh
new file mode 100644
index 000000000..eed2747fd
--- /dev/null
+++ b/core/include/alloy/detail/components/radiobutton.hh
@@ -0,0 +1,66 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_RADIOBUTTON_HH
+#define ALLOY_DETAIL_COMPONENTS_RADIOBUTTON_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_radiobutton : public component_base {
+public:
+ explicit gtk_radiobutton(component_base *parent) : component_base(false) {
+ m_widget = gtk_radio_button_new(NULL);
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_radiobutton() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override {
+ gtk_button_set_label(GTK_BUTTON(m_widget), text.data());
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override {
+ const char *txt = gtk_button_get_label(GTK_BUTTON(m_widget));
+ if (txt) strncpy(buf, txt, len);
+ return ALLOY_OK;
+ }
+ alloy_error_t set_checked(bool v) override {
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(m_widget), v);
+ return ALLOY_OK;
+ }
+ bool get_checked() override { return gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m_widget)); }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/scrollview.hh b/core/include/alloy/detail/components/scrollview.hh
new file mode 100644
index 000000000..e242ef2ed
--- /dev/null
+++ b/core/include/alloy/detail/components/scrollview.hh
@@ -0,0 +1,56 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_SCROLLVIEW_HH
+#define ALLOY_DETAIL_COMPONENTS_SCROLLVIEW_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_scrollview : public component_base {
+public:
+ explicit gtk_scrollview(component_base *parent) : component_base(true) {
+ m_widget = gtk_scrolled_window_new(NULL, NULL);
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_scrollview() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/slider.hh b/core/include/alloy/detail/components/slider.hh
new file mode 100644
index 000000000..5945898df
--- /dev/null
+++ b/core/include/alloy/detail/components/slider.hh
@@ -0,0 +1,59 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_SLIDER_HH
+#define ALLOY_DETAIL_COMPONENTS_SLIDER_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_slider : public component_base {
+public:
+ explicit gtk_slider(component_base *parent) : component_base(false) {
+ m_widget = gtk_scale_new_with_range(GTK_ORIENTATION_HORIZONTAL, 0, 100, 1);
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_slider() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override {
+ gtk_range_set_value(GTK_RANGE(m_widget), v);
+ return ALLOY_OK;
+ }
+ double get_value() override { return gtk_range_get_value(GTK_RANGE(m_widget)); }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/spinner.hh b/core/include/alloy/detail/components/spinner.hh
new file mode 100644
index 000000000..6cedb97e5
--- /dev/null
+++ b/core/include/alloy/detail/components/spinner.hh
@@ -0,0 +1,85 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_SPINNER_HH
+#define ALLOY_DETAIL_COMPONENTS_SPINNER_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_spinner : public component_base {
+public:
+ explicit gtk_spinner(component_base *parent) : component_base(false) {
+ m_widget = gtk_spin_button_new_with_range(0, 100, 1);
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_spinner() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { gtk_spin_button_set_value(GTK_SPIN_BUTTON(m_widget), v); return ALLOY_OK; }
+ double get_value() override { return gtk_spin_button_get_value(GTK_SPIN_BUTTON(m_widget)); }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+
+class gtk_loadingspinner : public component_base {
+public:
+ explicit gtk_loadingspinner(component_base *parent) : component_base(false) {
+ m_widget = gtk_spinner_new();
+ g_object_ref_sink(m_widget);
+ gtk_spinner_start(GTK_SPINNER(m_widget));
+ }
+ ~gtk_loadingspinner() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override {
+ if (v) gtk_spinner_start(GTK_SPINNER(m_widget));
+ else gtk_spinner_stop(GTK_SPINNER(m_widget));
+ return ALLOY_OK;
+ }
+ bool get_checked() override { return true; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/statusbar.hh b/core/include/alloy/detail/components/statusbar.hh
new file mode 100644
index 000000000..b852ee6bb
--- /dev/null
+++ b/core/include/alloy/detail/components/statusbar.hh
@@ -0,0 +1,59 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_STATUSBAR_HH
+#define ALLOY_DETAIL_COMPONENTS_STATUSBAR_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_statusbar : public component_base {
+public:
+ explicit gtk_statusbar(component_base *parent) : component_base(false) {
+ m_widget = gtk_statusbar_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_statusbar() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override {
+ gtk_statusbar_push(GTK_STATUSBAR(m_widget), gtk_statusbar_get_context_id(GTK_STATUSBAR(m_widget), "default"), text.data());
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/switch.hh b/core/include/alloy/detail/components/switch.hh
new file mode 100644
index 000000000..8ba9d4771
--- /dev/null
+++ b/core/include/alloy/detail/components/switch.hh
@@ -0,0 +1,59 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_SWITCH_HH
+#define ALLOY_DETAIL_COMPONENTS_SWITCH_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_switch : public component_base {
+public:
+ explicit gtk_switch(component_base *parent) : component_base(false) {
+ m_widget = gtk_switch_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_switch() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override {
+ gtk_switch_set_active(GTK_SWITCH(m_widget), v);
+ return ALLOY_OK;
+ }
+ bool get_checked() override { return gtk_switch_get_active(GTK_SWITCH(m_widget)); }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/tabview.hh b/core/include/alloy/detail/components/tabview.hh
new file mode 100644
index 000000000..3d46c7213
--- /dev/null
+++ b/core/include/alloy/detail/components/tabview.hh
@@ -0,0 +1,59 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_TABVIEW_HH
+#define ALLOY_DETAIL_COMPONENTS_TABVIEW_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_tabview : public component_base {
+public:
+ explicit gtk_tabview(component_base *parent) : component_base(true) {
+ m_widget = gtk_notebook_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_tabview() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override {
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(m_widget), (int)v);
+ return ALLOY_OK;
+ }
+ double get_value() override { return gtk_notebook_get_current_page(GTK_NOTEBOOK(m_widget)); }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/textarea.hh b/core/include/alloy/detail/components/textarea.hh
new file mode 100644
index 000000000..a9cf612fa
--- /dev/null
+++ b/core/include/alloy/detail/components/textarea.hh
@@ -0,0 +1,72 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_TEXTAREA_HH
+#define ALLOY_DETAIL_COMPONENTS_TEXTAREA_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_textarea : public component_base {
+public:
+ explicit gtk_textarea(component_base *parent) : component_base(false) {
+ m_widget = gtk_text_view_new();
+ m_scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+ gtk_container_add(GTK_CONTAINER(m_scrolled_window), m_widget);
+ g_object_ref_sink(m_scrolled_window);
+ }
+ ~gtk_textarea() { g_object_unref(m_scrolled_window); }
+ void *native_handle() override { return m_scrolled_window; }
+ alloy_error_t set_text(std::string_view text) override {
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_widget));
+ gtk_text_buffer_set_text(buffer, text.data(), -1);
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override {
+ GtkTextBuffer *buffer = gtk_text_view_get_buffer(GTK_TEXT_VIEW(m_widget));
+ GtkTextIter start, end;
+ gtk_text_buffer_get_bounds(buffer, &start, &end);
+ char *txt = gtk_text_buffer_get_text(buffer, &start, &end, FALSE);
+ if (!txt) return ALLOY_ERROR_PLATFORM;
+ strncpy(buf, txt, len);
+ g_free(txt);
+ return ALLOY_OK;
+ }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_scrolled_window); else gtk_widget_hide(m_scrolled_window); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_scrolled_window); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+ GtkWidget *m_scrolled_window;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/textfield.hh b/core/include/alloy/detail/components/textfield.hh
new file mode 100644
index 000000000..d87d7bbe7
--- /dev/null
+++ b/core/include/alloy/detail/components/textfield.hh
@@ -0,0 +1,82 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_COMPONENTS_TEXTFIELD_HH
+#define ALLOY_COMPONENTS_TEXTFIELD_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+
+namespace alloy::detail {
+
+class gtk_textfield : public component_base {
+public:
+ gtk_textfield(component_base* parent) : component_base(false) {
+ m_widget = gtk_entry_new();
+ if (parent) {
+ gtk_container_add(GTK_CONTAINER(parent->native_handle()), m_widget);
+ gtk_widget_show(m_widget);
+ }
+ }
+
+ alloy_error_t set_text(std::string_view text) override {
+ gtk_entry_set_text(GTK_ENTRY(m_widget), text.data());
+ return ALLOY_OK;
+ }
+
+ alloy_error_t get_text(char *buf, size_t len) override {
+ const char* text = gtk_entry_get_text(GTK_ENTRY(m_widget));
+ if (strlen(text) >= len) return ALLOY_ERROR_BUFFER_TOO_SMALL;
+ strcpy(buf, text);
+ return ALLOY_OK;
+ }
+
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+
+ alloy_error_t set_enabled(bool v) override {
+ gtk_widget_set_sensitive(m_widget, v);
+ return ALLOY_OK;
+ }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+
+ alloy_error_t set_visible(bool v) override {
+ gtk_widget_set_visible(m_widget, v);
+ return ALLOY_OK;
+ }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+ void* native_handle() override { return m_widget; }
+
+private:
+ GtkWidget* m_widget;
+};
+
+} // namespace alloy::detail
+#endif
+
+#endif // ALLOY_COMPONENTS_TEXTFIELD_HH
diff --git a/core/include/alloy/detail/components/toolbar.hh b/core/include/alloy/detail/components/toolbar.hh
new file mode 100644
index 000000000..d44f4bea5
--- /dev/null
+++ b/core/include/alloy/detail/components/toolbar.hh
@@ -0,0 +1,56 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_TOOLBAR_HH
+#define ALLOY_DETAIL_COMPONENTS_TOOLBAR_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_toolbar : public component_base {
+public:
+ explicit gtk_toolbar(component_base *parent) : component_base(true) {
+ m_widget = gtk_toolbar_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_toolbar() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/treeview.hh b/core/include/alloy/detail/components/treeview.hh
new file mode 100644
index 000000000..83b3b9123
--- /dev/null
+++ b/core/include/alloy/detail/components/treeview.hh
@@ -0,0 +1,69 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_TREEVIEW_HH
+#define ALLOY_DETAIL_COMPONENTS_TREEVIEW_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_treeview : public component_base {
+public:
+ explicit gtk_treeview(component_base *parent) : component_base(false) {
+ m_store = gtk_tree_store_new(1, G_TYPE_STRING);
+ m_widget = gtk_tree_view_new_with_model(GTK_TREE_MODEL(m_store));
+ GtkCellRenderer *renderer = gtk_cell_renderer_text_new();
+ GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes("Node", renderer, "text", 0, NULL);
+ gtk_tree_view_append_column(GTK_TREE_VIEW(m_widget), column);
+ m_scrolled_window = gtk_scrolled_window_new(NULL, NULL);
+ gtk_container_add(GTK_CONTAINER(m_scrolled_window), m_widget);
+ g_object_ref_sink(m_scrolled_window);
+ }
+ ~gtk_treeview() { g_object_unref(m_scrolled_window); }
+ void *native_handle() override { return m_scrolled_window; }
+ alloy_error_t set_text(std::string_view text) override {
+ GtkTreeIter iter;
+ gtk_tree_store_append(m_store, &iter, NULL);
+ gtk_tree_store_set(m_store, &iter, 0, text.data(), -1);
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_scrolled_window); else gtk_widget_hide(m_scrolled_window); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_scrolled_window); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+ GtkWidget *m_scrolled_window;
+ GtkTreeStore *m_store;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/webview_comp.hh b/core/include/alloy/detail/components/webview_comp.hh
new file mode 100644
index 000000000..430fca0c2
--- /dev/null
+++ b/core/include/alloy/detail/components/webview_comp.hh
@@ -0,0 +1,63 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_COMPONENTS_WEBVIEW_COMP_HH
+#define ALLOY_DETAIL_COMPONENTS_WEBVIEW_COMP_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+namespace alloy::detail {
+class gtk_webview_comp : public component_base {
+public:
+ explicit gtk_webview_comp(component_base *parent) : component_base(false) {
+ m_widget = webkit_web_view_new();
+ g_object_ref_sink(m_widget);
+ }
+ ~gtk_webview_comp() { g_object_unref(m_widget); }
+ void *native_handle() override { return m_widget; }
+ alloy_error_t set_text(std::string_view text) override {
+ webkit_web_view_load_uri(WEBKIT_WEB_VIEW(m_widget), text.data());
+ return ALLOY_OK;
+ }
+ alloy_error_t get_text(char *buf, size_t len) override {
+ const char *uri = webkit_web_view_get_uri(WEBKIT_WEB_VIEW(m_widget));
+ if (uri) strncpy(buf, uri, len);
+ return ALLOY_OK;
+ }
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { gtk_widget_set_sensitive(m_widget, v); return ALLOY_OK; }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+ alloy_error_t set_visible(bool v) override { if (v) gtk_widget_show(m_widget); else gtk_widget_hide(m_widget); return ALLOY_OK; }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget *m_widget;
+};
+}
+#endif
+#endif
diff --git a/core/include/alloy/detail/components/window.hh b/core/include/alloy/detail/components/window.hh
new file mode 100644
index 000000000..3c44cabc3
--- /dev/null
+++ b/core/include/alloy/detail/components/window.hh
@@ -0,0 +1,144 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_COMPONENTS_WINDOW_HH
+#define ALLOY_COMPONENTS_WINDOW_HH
+
+#include "../component_base.hh"
+
+#ifdef WEBVIEW_PLATFORM_LINUX
+#include
+
+namespace alloy::detail {
+
+class gtk_window : public component_base {
+public:
+ gtk_window(const char* title, int width, int height) : component_base(true) {
+ m_widget = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+ gtk_window_set_title(GTK_WINDOW(m_widget), title);
+ gtk_window_set_default_size(GTK_WINDOW(m_widget), width, height);
+
+ m_fixed = gtk_fixed_new();
+ gtk_container_add(GTK_CONTAINER(m_widget), m_fixed);
+ gtk_widget_show(m_fixed);
+ gtk_widget_show(m_widget);
+ }
+
+ void *native_handle() override { return m_fixed; }
+
+ alloy_error_t set_text(std::string_view text) override {
+ gtk_window_set_title(GTK_WINDOW(m_widget), text.data());
+ return ALLOY_OK;
+ }
+
+ alloy_error_t get_text(char *buf, size_t len) override {
+ const char* text = gtk_window_get_title(GTK_WINDOW(m_widget));
+ if (strlen(text) >= len) return ALLOY_ERROR_BUFFER_TOO_SMALL;
+ strcpy(buf, text);
+ return ALLOY_OK;
+ }
+
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+
+ alloy_error_t set_enabled(bool v) override {
+ gtk_widget_set_sensitive(m_widget, v);
+ return ALLOY_OK;
+ }
+ bool get_enabled() override { return gtk_widget_get_sensitive(m_widget); }
+
+ alloy_error_t set_visible(bool v) override {
+ gtk_widget_set_visible(m_widget, v);
+ return ALLOY_OK;
+ }
+ bool get_visible() override { return gtk_widget_get_visible(m_widget); }
+
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+
+private:
+ GtkWidget* m_widget;
+ GtkWidget* m_fixed;
+};
+
+} // namespace alloy::detail
+#endif
+
+#ifdef WEBVIEW_PLATFORM_DARWIN
+#include
+#if TARGET_OS_OSX
+#import
+
+namespace alloy::detail {
+
+class cocoa_window : public component_base {
+public:
+ cocoa_window(const char* title, int width, int height) : component_base(true) {
+ m_window = [[NSWindow alloc] initWithContentRect:NSMakeRect(0, 0, width, height)
+ styleMask:(NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskResizable)
+ backing:NSBackingStoreBuffered
+ defer:NO];
+ [m_window setTitle:[NSString stringWithUTF8String:title]];
+ [m_window makeKeyAndOrderFront:nil];
+ m_content_view = [m_window contentView];
+ }
+
+ alloy_error_t set_text(std::string_view text) override {
+ [m_window setTitle:[NSString stringWithUTF8String:text.data()]];
+ return ALLOY_OK;
+ }
+
+ alloy_error_t get_text(char *buf, size_t len) override {
+ const char* title = [[m_window title] UTF8String];
+ if (strlen(title) >= len) return ALLOY_ERROR_BUFFER_TOO_SMALL;
+ strcpy(buf, title);
+ return ALLOY_OK;
+ }
+
+ alloy_error_t set_checked(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_checked() override { return false; }
+ alloy_error_t set_value(double v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ double get_value() override { return 0; }
+ alloy_error_t set_enabled(bool v) override { return ALLOY_ERROR_NOT_SUPPORTED; }
+ bool get_enabled() override { return true; }
+
+ alloy_error_t set_visible(bool v) override {
+ if (v) [m_window orderFront:nil];
+ else [m_window orderOut:nil];
+ return ALLOY_OK;
+ }
+ bool get_visible() override { return [m_window isVisible]; }
+
+ alloy_error_t set_style(const alloy_style_t &s) override { return ALLOY_OK; }
+ void* native_handle() override { return m_content_view; }
+
+private:
+ NSWindow* m_window;
+ NSView* m_content_view;
+};
+
+} // namespace alloy::detail
+#endif
+#endif
+
+#endif // ALLOY_COMPONENTS_WINDOW_HH
diff --git a/core/include/alloy/detail/signal.hh b/core/include/alloy/detail/signal.hh
new file mode 100644
index 000000000..b3863658c
--- /dev/null
+++ b/core/include/alloy/detail/signal.hh
@@ -0,0 +1,66 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_DETAIL_SIGNAL_HH
+#define ALLOY_DETAIL_SIGNAL_HH
+
+#include "../api.h"
+#include
+#include
+#include
+#include
+
+namespace alloy::detail {
+
+struct signal_value {
+ std::variant data;
+};
+
+class component_base;
+
+class signal_base {
+public:
+ virtual ~signal_base() = default;
+
+ struct subscription {
+ component_base* component;
+ alloy_prop_id_t prop;
+ };
+
+ void subscribe(component_base* c, alloy_prop_id_t p) {
+ m_subscribers.push_back({c, p});
+ }
+
+ void unsubscribe(component_base* c, alloy_prop_id_t p) {
+ // Basic implementation
+ }
+
+protected:
+ void notify_subscribers(const signal_value& val);
+
+private:
+ std::vector m_subscribers;
+};
+
+} // namespace alloy::detail
+
+#endif // ALLOY_DETAIL_SIGNAL_HH
diff --git a/core/include/alloy/engine/cron.hh b/core/include/alloy/engine/cron.hh
new file mode 100644
index 000000000..a441fe045
--- /dev/null
+++ b/core/include/alloy/engine/cron.hh
@@ -0,0 +1,95 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_ENGINE_CRON_HH
+#define ALLOY_ENGINE_CRON_HH
+
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+
+#ifdef _WIN32
+#include
+#else
+#include
+#endif
+
+namespace alloy::engine {
+
+class cron_manager {
+public:
+ static bool register_job(const std::string& path, const std::string& schedule, const std::string& title) {
+#ifdef _WIN32
+ std::string cmd = "schtasks /create /tn Alloy-cron-" + title + " /tr \"Alloy.exe run " + path + "\" /sc MINUTE /mo 5 /f";
+ return system(cmd.c_str()) == 0;
+#elif defined(__APPLE__)
+ std::string home = getenv("HOME");
+ std::string plist_path = home + "/Library/LaunchAgents/Alloy.cron." + title + ".plist";
+ std::ofstream f(plist_path);
+ // Simple 5-field cron parsing placeholder
+ std::stringstream ss(schedule); std::string min, hr, dom, mon, dow;
+ ss >> min >> hr >> dom >> mon >> dow;
+ f << "\n\n\n";
+ f << " LabelAlloy.cron." << title << "\n";
+ f << " ProgramArguments/usr/local/bin/Alloyrun" << path << "\n";
+ f << " StartCalendarInterval\n";
+ if (min != "*") f << " Minute" << min << "\n";
+ if (hr != "*") f << " Hour" << hr << "\n";
+ f << " \n\n";
+ f.close();
+ system(("launchctl load " + plist_path).c_str());
+ return true;
+#else
+ std::string Alloy_path = "/proc/self/exe";
+ std::string line = "# Alloy-cron: " + title + "\n" + schedule + " '" + Alloy_path + "' run --cron-title=" + title + " --cron-period='" + schedule + "' '" + path + "'";
+ FILE* fp = popen("crontab -", "w");
+ if (!fp) return false;
+ fprintf(fp, "%s", line.c_str());
+ return pclose(fp) == 0;
+#endif
+ }
+
+ static bool remove_job(const std::string& title) {
+#ifdef _WIN32
+ std::string cmd = "schtasks /delete /tn Alloy-cron-" + title + " /f";
+ return system(cmd.c_str()) == 0;
+#elif defined(__APPLE__)
+ std::string home = getenv("HOME");
+ std::string plist_path = home + "/Library/LaunchAgents/Alloy.cron." + title + ".plist";
+ system(("launchctl unload " + plist_path).c_str());
+ unlink(plist_path.c_str());
+ return true;
+#else
+ return true; // Simplified
+#endif
+ }
+};
+
+} // namespace alloy::engine
+
+#endif // ALLOY_ENGINE_CRON_HH
diff --git a/core/include/alloy/engine/engine_base.hh b/core/include/alloy/engine/engine_base.hh
new file mode 100644
index 000000000..948a451a9
--- /dev/null
+++ b/core/include/alloy/engine/engine_base.hh
@@ -0,0 +1,1072 @@
+/*
+ * AlloyScript Runtime - CC0 Unlicense Public Domain
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef ALLOY_ENGINE_ENGINE_BASE_HH
+#define ALLOY_ENGINE_ENGINE_BASE_HH
+
+#include "webview/errors.hh"
+#include "webview/types.h"
+#include "webview/types.hh"
+#include "webview/detail/json.hh"
+#include "webview/detail/user_script.hh"
+#include "cron.hh"
+#include "sqlite.hh"
+#include "subprocess.hh"
+#include "mquickjs.h"
+
+#include
+#include
+#include
+#include