Added SDK

This commit is contained in:
Andrew Zambazos
2026-06-11 14:01:22 +12:00
commit c0395a49bd
2155 changed files with 451005 additions and 0 deletions
+228
View File
@@ -0,0 +1,228 @@
/**************************************************************************************************
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
* *
* See <https://ultralig.ht> for licensing and more. *
* *
* (C) 2024 Ultralight, Inc. *
**************************************************************************************************/
#pragma once
#include "Defines.h"
#include <Ultralight/RefPtr.h>
#include <Ultralight/Renderer.h>
#include <Ultralight/platform/Config.h>
namespace ultralight {
class Monitor;
class Window;
///
/// Interface for all App-related events. @see App::set_listener
///
class AExport AppListener {
public:
virtual ~AppListener() {}
///
/// Called whenever the App updates. You should update all app logic here.
///
/// @note This event is fired right before the run loop calls
/// Renderer::Update and Renderer::Render.
///
virtual void OnUpdate() {}
};
///
/// App-specific settings.
///
struct AExport Settings {
///
/// The name of the developer of this app.
///
/// This is used to generate a unique path to store local application data
/// on the user's machine.
///
String developer_name = "MyCompany";
///
/// The name of this app.
///
/// This is used to generate a unique path to store local application data
/// on the user's machine.
///
String app_name = "MyApp";
///
/// The root file path for our file system. You should set this to the
/// relative path where all of your app data is.
///
/// This will be used to resolve all file URLs, eg file:///page.html
///
/// @note This relative path is resolved using the following logic:
/// - Windows: relative to the executable path
/// - Linux: relative to the executable path
/// - macOS: relative to YourApp.app/Contents/Resources/
///
String file_system_path = "./assets/";
///
/// Whether or not we should load and compile shaders from the file system
/// (eg, from the /shaders/ path, relative to file_system_path).
///
/// If this is false (the default), we will instead load pre-compiled shaders
/// from memory which speeds up application startup time.
///
bool load_shaders_from_file_system = false;
///
/// We try to use the GPU renderer when a compatible GPU is detected.
///
/// Set this to true to force the engine to always use the CPU renderer.
///
bool force_cpu_renderer = false;
};
///
/// Main application singleton (use this if you want to let the library manage window creation).
///
/// This convenience class sets up everything you need to display web-based content in a
/// desktop application.
///
/// The App class initializes the Platform singleton with OS-specific defaults, creates a Renderer,
/// and automatically manages window creation, run loop, input events, and painting.
///
/// ## Creating the App
///
/// Call App::Create() to initialize the library and create the App singleton.
///
/// ```
/// auto app = App::Create();
/// ```
///
/// ## Creating a Window
///
/// Call Window::Create() to create one or more windows during the lifetime of your app.
///
/// ```
/// auto window = Window::Create(app->main_monitor(), 1024, 768, false,
/// kWindowFlags_Titled | kWindowFlags_Resizable);
/// ```
///
/// ### Creating an Overlay in a Window
///
/// Each Window can have one or more Overlay instances. Overlays are used to display web-based
/// content in a portion of the window.
///
/// Call Overlay::Create() to create an overlay in a window.
///
/// ```
/// auto overlay = Overlay::Create(window, 1024, 768, 0, 0);
/// ```
///
/// Each Overlay has a View instance that you can use to load web content into.
///
/// ```
/// overlay->view()->LoadURL("https://google.com");
/// ```
///
/// ## Running the App
///
/// Call App::Run() to start the main run loop.
///
/// ```
/// #include <AppCore/AppCore.h>
///
/// using namespace ultralight;
///
/// int main() {
/// // Initialize app, window, overlay, etc. here...
///
/// app->Run();
///
/// return 0;
/// }
/// ```
///
/// ## Shutting Down the App
///
/// Call App::Quit() to stop the main run loop and shut down the app.
///
/// ```
/// app->Quit();
/// ```
/// @note This is optional, you can use the Renderer class directly if you want to manage your
/// own windows and run loop.
///
class AExport App : public RefCounted {
public:
///
/// Create the App singleton.
///
/// @param settings Settings to customize App runtime behavior.
///
/// @param config Config options for the Ultralight renderer.
///
/// @return Returns a ref-pointer to the created App instance.
///
/// @note You should only create one of these per application lifetime.
///
/// @note Certain Config options may be overridden during App creation,
/// most commonly Config::face_winding and Config::cache_path.
///
static RefPtr<App> Create(Settings settings = Settings(), Config config = Config());
///
/// Get the App singleton.
///
static App* instance();
///
/// Get the settings this App was created with.
///
virtual const Settings& settings() const = 0;
///
/// Set an AppListener to receive callbacks for app-related events.
///
/// @note Ownership remains with the caller.
///
virtual void set_listener(AppListener* listener) = 0;
///
/// Get the AppListener, if any.
///
virtual AppListener* listener() = 0;
///
/// Whether or not the App is running.
///
virtual bool is_running() const = 0;
///
/// Get the main monitor (this is never NULL).
///
/// @note We'll add monitor enumeration later.
///
virtual Monitor* main_monitor() = 0;
///
/// Get the underlying Renderer instance.
///
virtual RefPtr<Renderer> renderer() = 0;
///
/// Run the main loop.
///
virtual void Run() = 0;
///
/// Quit the application.
///
virtual void Quit() = 0;
protected:
virtual ~App();
};
} // namespace ultralight
+14
View File
@@ -0,0 +1,14 @@
/**************************************************************************************************
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
* *
* See <https://ultralig.ht> for licensing and more. *
* *
* (C) 2024 Ultralight, Inc. *
**************************************************************************************************/
#include <AppCore/App.h>
#include <AppCore/Dialogs.h>
#include <AppCore/Monitor.h>
#include <AppCore/Window.h>
#include <AppCore/Overlay.h>
#include <AppCore/JSHelpers.h>
#include <AppCore/Platform.h>
+548
View File
@@ -0,0 +1,548 @@
/**************************************************************************************************
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
* *
* See <https://ultralig.ht> for licensing and more. *
* *
* (C) 2024 Ultralight, Inc. *
**************************************************************************************************/
///
/// @file AppCore/CAPI.h
///
/// AppCore API interface.
///
/// `#include <AppCore/CAPI.h>`
///
/// AppCore is a convenient windowing system for desktop platforms built on top of the
/// Ultralight renderer.
///
/// It automatically sets up the Renderer, creates a run loop, and handles all window creation,
/// painting, and platform-specific operations for you.
///
/// ## Creating the App
///
/// Call ulCreateApp() to initialize the library and create the App singleton:
///
/// ```
/// // Create the App using default config and settings
/// ULApp app = ulCreateApp(NULL, NULL);
/// ```
///
/// ## Creating a Window
///
/// Call ulCreateWindow() to create one or more windows during the lifetime of your app:
///
/// ```
/// ULWindow window = ulCreateWindow(ulAppGetMainMonitor(app), 1024, 768, false,
/// kWindowFlags_Titled | kWindowFlags_Resizable);
/// ```
///
/// ## Creating an Overlay in a Window
///
/// Each Window can have one or more Overlay instances. Overlays are used to display web-based
/// content in a portion of the window.
///
/// Call ulCreateOverlay() to create an overlay in a window:
///
/// ```
/// ULOverlay overlay = ulCreateOverlay(window, 1024, 768, 0, 0);
/// ```
///
/// Each Overlay has a View instance that you can use to load web content into:
///
/// ```
/// ULString url = ulCreateString("https://google.com");
/// ULView view = ulOverlayGetView(overlay);
/// ulViewLoadURL(view, url);
/// ulDestroyString(url);
/// ```
///
/// ## Running the App
///
/// Call ulAppRun() to start the main run loop:
///
/// ```
/// #include <AppCore/CAPI.h>
///
/// int main() {
/// // Initialize app, window, overlay, etc. here...
///
/// ulAppRun(app);
///
/// ulDestroyApp(app);
/// return 0;
/// }
/// ```
///
#ifndef APPCORE_CAPI_H
#define APPCORE_CAPI_H
#include <Ultralight/CAPI.h>
#if defined(ULTRALIGHT_STATIC_BUILD)
# define ACExport
#else
# if defined(__WIN32__) || defined(_WIN32)
# if defined(APPCORE_IMPLEMENTATION)
# define ACExport __declspec(dllexport)
# else
# define ACExport __declspec(dllimport)
# endif
# else
# define ACExport __attribute__((visibility("default")))
# endif
#endif
#ifdef __cplusplus
extern "C" {
#endif
typedef struct C_Settings* ULSettings;
typedef struct C_App* ULApp;
typedef struct C_Window* ULWindow;
typedef struct C_Monitor* ULMonitor;
typedef struct C_Overlay* ULOverlay;
///
/// Window creation flags. @see Window::Create
///
typedef enum {
kWindowFlags_Borderless = 1 << 0,
kWindowFlags_Titled = 1 << 1,
kWindowFlags_Resizable = 1 << 2,
kWindowFlags_Maximizable = 1 << 3,
kWindowFlags_Hidden = 1 << 4,
} ULWindowFlags;
///
/// Create settings with default values (see <AppCore/App.h>).
///
ACExport ULSettings ulCreateSettings();
///
/// Destroy settings.
///
ACExport void ulDestroySettings(ULSettings settings);
///
/// Set the name of the developer of this app.
///
/// This is used to generate a unique path to store local application data
/// on the user's machine.
///
/// Default is "MyCompany"
///
ACExport void ulSettingsSetDeveloperName(ULSettings settings, ULString name);
///
/// Set the name of this app.
///
/// This is used to generate a unique path to store local application data
/// on the user's machine.
///
/// Default is "MyApp"
///
ACExport void ulSettingsSetAppName(ULSettings settings, ULString name);
///
/// Set the root file path for our file system, you should set this to the
/// relative path where all of your app data is.
///
/// This will be used to resolve all file URLs, eg file:///page.html
///
/// @note The default path is "./assets/"
///
/// This relative path is resolved using the following logic:
/// - Windows: relative to the executable path
/// - Linux: relative to the executable path
/// - macOS: relative to YourApp.app/Contents/Resources/
///
ACExport void ulSettingsSetFileSystemPath(ULSettings settings, ULString path);
///
/// Set whether or not we should load and compile shaders from the file system
/// (eg, from the /shaders/ path, relative to file_system_path).
///
/// If this is false (the default), we will instead load pre-compiled shaders
/// from memory which speeds up application startup time.
///
ACExport void ulSettingsSetLoadShadersFromFileSystem(ULSettings settings,
bool enabled);
///
/// We try to use the GPU renderer when a compatible GPU is detected.
///
/// Set this to true to force the engine to always use the CPU renderer.
///
ACExport void ulSettingsSetForceCPURenderer(ULSettings settings,
bool force_cpu);
///
/// Create the App singleton.
///
/// @param settings Settings to customize App runtime behavior. You can pass
/// NULL for this parameter to use default settings.
///
/// @param config Config options for the Ultralight renderer. You can pass
/// NULL for this parameter to use default config.
///
/// @note You should only create one of these per application lifetime.
///
/// @note Certain Config options may be overridden during App creation,
/// most commonly Config::face_winding and Config::device_scale_hint.
///
ACExport ULApp ulCreateApp(ULSettings settings, ULConfig config);
///
/// Destroy the App instance.
///
ACExport void ulDestroyApp(ULApp app);
typedef void
(*ULUpdateCallback) (void* user_data);
///
/// Set a callback for whenever the App updates. You should update all app
/// logic here.
///
/// @note This event is fired right before the run loop calls
/// Renderer::Update and Renderer::Render.
///
ACExport void ulAppSetUpdateCallback(ULApp app, ULUpdateCallback callback,
void* user_data);
///
/// Whether or not the App is running.
///
ACExport bool ulAppIsRunning(ULApp app);
///
/// Get the main monitor (this is never NULL).
///
/// @note We'll add monitor enumeration later.
///
ACExport ULMonitor ulAppGetMainMonitor(ULApp app);
///
/// Get the underlying Renderer instance.
///
ACExport ULRenderer ulAppGetRenderer(ULApp app);
///
/// Run the main loop.
///
ACExport void ulAppRun(ULApp app);
///
/// Quit the application.
///
ACExport void ulAppQuit(ULApp app);
///
/// Get the monitor's DPI scale (1.0 = 100%).
///
ACExport double ulMonitorGetScale(ULMonitor monitor);
///
/// Get the width of the monitor (in pixels).
///
ACExport unsigned int ulMonitorGetWidth(ULMonitor monitor);
///
/// Get the height of the monitor (in pixels).
///
ACExport unsigned int ulMonitorGetHeight(ULMonitor monitor);
///
/// Create a new Window.
///
/// @param monitor The monitor to create the Window on.
///
/// @param width The width (in screen coordinates).
///
/// @param height The height (in screen coordinates).
///
/// @param fullscreen Whether or not the window is fullscreen.
///
/// @param window_flags Various window flags.
///
ACExport ULWindow ulCreateWindow(ULMonitor monitor, unsigned int width,
unsigned int height, bool fullscreen,
unsigned int window_flags);
///
/// Destroy a Window.
///
ACExport void ulDestroyWindow(ULWindow window);
typedef void
(*ULCloseCallback) (void* user_data, ULWindow window);
///
/// Set a callback to be notified when a window closes.
///
ACExport void ulWindowSetCloseCallback(ULWindow window,
ULCloseCallback callback,
void* user_data);
typedef void
(*ULResizeCallback) (void* user_data, ULWindow window, unsigned int width, unsigned int height);
///
/// Set a callback to be notified when a window resizes
/// (parameters are passed back in pixels).
///
ACExport void ulWindowSetResizeCallback(ULWindow window,
ULResizeCallback callback,
void* user_data);
///
/// Get window width (in screen coordinates).
///
ACExport unsigned int ulWindowGetScreenWidth(ULWindow window);
///
/// Get window width (in pixels).
///
ACExport unsigned int ulWindowGetWidth(ULWindow window);
///
/// Get window height (in screen coordinates).
///
ACExport unsigned int ulWindowGetScreenHeight(ULWindow window);
///
/// Get window height (in pixels).
///
ACExport unsigned int ulWindowGetHeight(ULWindow window);
///
/// Move the window to a new position (in screen coordinates) relative to the top-left of the
/// monitor area.
///
ACExport void ulWindowMoveTo(ULWindow window, int x, int y);
///
/// Move the window to the center of the monitor.
///
ACExport void ulWindowMoveToCenter(ULWindow);
///
/// Get the x-position of the window (in screen coordinates) relative to the top-left of the
/// monitor area.
///
ACExport int ulWindowGetPositionX(ULWindow window);
///
/// Get the y-position of the window (in screen coordinates) relative to the top-left of the
/// monitor area.
///
ACExport int ulWindowGetPositionY(ULWindow window);
///
/// Get whether or not a window is fullscreen.
///
ACExport bool ulWindowIsFullscreen(ULWindow window);
///
/// Get the DPI scale of a window.
///
ACExport double ulWindowGetScale(ULWindow window);
///
/// Set the window title.
///
ACExport void ulWindowSetTitle(ULWindow window, const char* title);
///
/// Set the cursor for a window.
///
ACExport void ulWindowSetCursor(ULWindow window, ULCursor cursor);
///
/// Show the window (if it was previously hidden).
///
ACExport void ulWindowShow(ULWindow window);
///
/// Hide the window.
///
ACExport void ulWindowHide(ULWindow window);
///
/// Whether or not the window is currently visible (not hidden).
///
ACExport bool ulWindowIsVisible(ULWindow window);
///
/// Close a window.
///
ACExport void ulWindowClose(ULWindow window);
///
/// Convert screen coordinates to pixels using the current DPI scale.
///
ACExport int ulWindowScreenToPixels(ULWindow window, int val);
///
/// Convert pixels to screen coordinates using the current DPI scale.
///
ACExport int ulWindowPixelsToScreen(ULWindow window, int val);
///
/// Get the underlying native window handle.
///
/// @note This is: - HWND on Windows
/// - NSWindow* on macOS
/// - GLFWwindow* on Linux
///
ACExport void* ulWindowGetNativeHandle(ULWindow window);
///
/// Create a new Overlay.
///
/// @param window The window to create the Overlay in.
///
/// @param width The width in pixels.
///
/// @param height The height in pixels.
///
/// @param x The x-position (offset from the left of the Window), in
/// pixels.
///
/// @param y The y-position (offset from the top of the Window), in
/// pixels.
///
/// @note Each Overlay is essentially a View and an on-screen quad. You should
/// create the Overlay then load content into the underlying View.
///
ACExport ULOverlay ulCreateOverlay(ULWindow window, unsigned int width,
unsigned int height, int x, int y);
///
/// Create a new Overlay, wrapping an existing View.
///
/// @param window The window to create the Overlay in. (we currently only
/// support one window per application)
///
/// @param view The View to wrap (will use its width and height).
///
/// @param x The x-position (offset from the left of the Window), in
/// pixels.
///
/// @param y The y-position (offset from the top of the Window), in
/// pixels.
///
/// @note Each Overlay is essentially a View and an on-screen quad. You should
/// create the Overlay then load content into the underlying View.
///
ACExport ULOverlay ulCreateOverlayWithView(ULWindow window, ULView view,
int x, int y);
///
/// Destroy an overlay.
///
ACExport void ulDestroyOverlay(ULOverlay overlay);
///
/// Get the underlying View.
///
ACExport ULView ulOverlayGetView(ULOverlay overlay);
///
/// Get the width (in pixels).
///
ACExport unsigned int ulOverlayGetWidth(ULOverlay overlay);
///
/// Get the height (in pixels).
///
ACExport unsigned int ulOverlayGetHeight(ULOverlay overlay);
///
/// Get the x-position (offset from the left of the Window), in pixels.
///
ACExport int ulOverlayGetX(ULOverlay overlay);
///
/// Get the y-position (offset from the top of the Window), in pixels.
///
ACExport int ulOverlayGetY(ULOverlay overlay);
///
/// Move the overlay to a new position (in pixels).
///
ACExport void ulOverlayMoveTo(ULOverlay overlay, int x, int y);
///
/// Resize the overlay (and underlying View), dimensions should be
/// specified in pixels.
///
ACExport void ulOverlayResize(ULOverlay overlay, unsigned int width,
unsigned int height);
///
/// Whether or not the overlay is hidden (not drawn).
///
ACExport bool ulOverlayIsHidden(ULOverlay overlay);
///
/// Hide the overlay (will no longer be drawn).
///
ACExport void ulOverlayHide(ULOverlay overlay);
///
/// Show the overlay.
///
ACExport void ulOverlayShow(ULOverlay overlay);
///
/// Whether or not an overlay has keyboard focus.
///
ACExport bool ulOverlayHasFocus(ULOverlay overlay);
///
/// Grant this overlay exclusive keyboard focus.
///
ACExport void ulOverlayFocus(ULOverlay overlay);
///
/// Remove keyboard focus.
///
ACExport void ulOverlayUnfocus(ULOverlay overlay);
/******************************************************************************
* Platform
*****************************************************************************/
///
/// This is only needed if you are not calling ulCreateApp().
///
/// Initializes the platform font loader and sets it as the current FontLoader.
///
ACExport void ulEnablePlatformFontLoader();
///
/// This is only needed if you are not calling ulCreateApp().
///
/// Initializes the platform file system (needed for loading file:/// URLs) and
/// sets it as the current FileSystem.
///
/// You can specify a base directory path to resolve relative paths against.
///
ACExport void ulEnablePlatformFileSystem(ULString base_dir);
///
/// This is only needed if you are not calling ulCreateApp().
///
/// Initializes the default logger (writes the log to a file).
///
/// You should specify a writable log path to write the log to
/// for example "./ultralight.log".
///
ACExport void ulEnableDefaultLogger(ULString log_path);
#ifdef __cplusplus
}
#endif
#endif // APPCORE_CAPI_H
+55
View File
@@ -0,0 +1,55 @@
/**************************************************************************************************
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
* *
* See <https://ultralig.ht> for licensing and more. *
* *
* (C) 2024 Ultralight, Inc. *
**************************************************************************************************/
#pragma once
// Needed for limit defines, like INTMAX_MAX, which is used by the std C++ library
#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#include <cstdint>
#include <cstddef>
#include <limits.h>
#ifdef SWIG
#define AExport
#else
// Require C++11 Support
#if defined(_MSC_VER)
# if _MSC_VER < 1800
# error This project needs at least Visual Studio 2013 to build
# endif
#elif __cplusplus <= 199711L
# error This project can only be compiled with a compiler that supports C++11
#endif
#if defined(ULTRALIGHT_STATIC_BUILD)
# define AExport
#else
# if defined(__WIN32__) || defined(_WIN32)
# if defined(APPCORE_IMPLEMENTATION)
# define AExport __declspec(dllexport)
# else
# define AExport __declspec(dllimport)
# endif
# else
# define AExport __attribute__((visibility("default")))
# endif
#endif
#if defined(__WIN32__) || defined(_WIN32)
# define _thread_local __declspec(thread)
# ifndef _NATIVE_WCHAR_T_DEFINED
# define DISABLE_NATIVE_WCHAR_T
# endif
#else
# define _thread_local __thread
#endif
#endif
+59
View File
@@ -0,0 +1,59 @@
/**************************************************************************************************
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
* *
* See <https://ultralig.ht> for licensing and more. *
* *
* (C) 2024 Ultralight, Inc. *
**************************************************************************************************/
#pragma once
#include "Defines.h"
#include <Ultralight/String.h>
namespace ultralight {
///
/// Enum representing the icon to be displayed in a dialog.
///
enum class DialogIcon {
Info, ///< Information icon
Warning, ///< Warning icon
Error, ///< Error icon
Question ///< Question icon
};
///
/// Enum representing the button types in a dialog.
///
enum class ButtonType {
OK, ///< Single "OK" button
OKCancel, ///< "OK" and "Cancel" buttons
YesNo ///< "Yes" and "No" buttons
};
///
/// Enum representing the result of a dialog button press.
///
enum class ButtonResult {
OK, ///< "OK" button was pressed
Cancel, ///< "Cancel" button was pressed
Yes, ///< "Yes" button was pressed
No ///< "No" button was pressed
};
///
/// Shows a modal message box with the specified title, message, icon, and buttons.
///
/// @param title The title of the message box.
/// @param message The message to display in the message box.
/// @param icon The icon to display in the message box (default: DialogIcon::Info).
/// @param buttons The button type to display in the message box (default: ButtonType::OK).
///
/// @return The result of the button press.
///
AExport ButtonResult ShowMessageBox(const String& title, const String& message,
DialogIcon icon = DialogIcon::Info,
ButtonType buttons = ButtonType::OK);
} // namespace ultralight
+560
View File
@@ -0,0 +1,560 @@
/**************************************************************************************************
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
* *
* See <https://ultralig.ht> for licensing and more. *
* *
* (C) 2024 Ultralight, Inc. *
**************************************************************************************************/
#pragma once
#include <AppCore/Defines.h>
#include <JavaScriptCore/JavaScript.h>
#include <JavaScriptCore/JSStringRef.h>
#include <Ultralight/String.h>
#include <functional>
#include <memory>
namespace ultralight {
///
/// Set the current JSContext.
///
/// Most JavaScriptCore C API calls require an active JavaScript execution
/// context (JSContextRef). You can get the JSContextRef for a page via
/// `View::LockJSContext()`. This context changes with each page navigation.
///
/// @note You MUST set a JSContext before using most of the C++ API below.
///
void AExport SetJSContext(JSContextRef ctx);
///
/// Get the current JSContext.
///
JSContextRef AExport GetJSContext();
///
/// JavaScript String wrapper that automatically manages JSStringRef lifetime
/// and provides helpful conversions.
///
class AExport JSString {
public:
/// Create empty string
JSString();
/// Create from C-string
JSString(const char* str);
/// Create from Ultralight String
JSString(const String& str);
/// Create from existing JSStringRef
JSString(JSStringRef str);
/// Copy constructor
JSString(const JSString& other);
/// Destructor
~JSString();
/// Assignment operator
JSString& operator=(const JSString& other);
/// Cast to String
operator String();
/// Cast to underlying JSStringRef
operator JSStringRef() const { return instance_; }
protected:
JSStringRef instance_;
};
class JSArray;
class JSObject;
class JSFunction;
/// Tag type used with the JSValue constructor to create "Null" types
struct AExport JSValueNullTag {};
/// Tag type used with the JSValue constructor to create "Undefined" types
struct AExport JSValueUndefinedTag {};
///
/// JavaScript variant value wrapper that automatically manages JSValueRef
/// lifetime and provides helpful conversions.
///
class AExport JSValue {
public:
/// Create null (empty) JSValue
JSValue();
/// Create null JSValue explicitly
JSValue(JSValueNullTag);
/// Create undefined JSValue
JSValue(JSValueUndefinedTag);
/// Create boolean JSValue
JSValue(bool val);
/// Create unsigned integer JSValue (aka, Number) [will be cast to double]
JSValue(uint32_t val);
/// Create integer JSValue (aka, Number) [will be cast to double]
JSValue(int32_t val);
/// Create unsigned integer JSValue (aka, Number) [will be cast to double]
JSValue(uint64_t val);
/// Create integer JSValue (aka, Number) [will be cast to double]
JSValue(int64_t val);
/// Create double JSValue (aka, Number)
JSValue(double val);
/// Create string JSValue
JSValue(const char* val);
/// Create string JSValue
JSValue(const String& val);
/// Create string JSValue
JSValue(JSString val);
/// Create from existing JSValueRef
JSValue(JSValueRef val);
/// Create object JSValue
JSValue(JSObjectRef obj);
/// Copy constructor, a shallow copy is made, the constructed JSValue will
/// point to the same JSValueRef.
JSValue(const JSValue& other);
/// Destructor
virtual ~JSValue();
/// A shallow copy is made, this JSValue will point to the same JSValueRef
virtual JSValue& operator=(const JSValue& other);
/// Whether or not the value is a JavaScript Null type.
bool IsNull() const;
/// Whether or not the value is a JavaScript Undefined type.
bool IsUndefined() const;
/// Whether or not the value is a JavaScript Boolean type.
bool IsBoolean() const;
/// Whether or not the value is a JavaScript Number type.
bool IsNumber() const;
/// Whether or not the value is a JavaScript String type.
bool IsString() const;
/// Whether or not the value is a JavaScript Object type.
bool IsObject() const;
/// Whether or not the value is a JavaScript Array type.
bool IsArray() const;
/// Whether or not the value is a JavaScript Function type.
bool IsFunction() const;
/// Get the value as a Boolean
bool ToBoolean() const;
/// Get the value as a Number (Double)
double ToNumber() const;
/// Get the value as a Number (Integer)
int64_t ToInteger() const { return static_cast<int64_t>(ToNumber()); }
/// Get the value as a String
JSString ToString() const;
/// Get the value as an Object (will debug assert if not an Object)
JSObject ToObject() const;
/// Get the value as an Array (will debug asset if not an Array)
JSArray ToArray() const;
/// Get the value as a Function (will debug asset if not a Function)
JSFunction ToFunction() const;
operator bool() const { return ToBoolean(); }
operator double() const { return ToNumber(); }
operator uint32_t() const { return static_cast<uint32_t>(ToNumber()); }
operator int32_t() const { return static_cast<uint32_t>(ToNumber()); }
operator uint64_t() const { return static_cast<uint64_t>(ToNumber()); }
operator int64_t() const { return ToInteger(); }
operator String() const { return ToString(); }
operator JSString() const { return ToString(); }
operator JSObject() const;
operator JSObjectRef() const;
operator JSArray() const;
operator JSFunction() const;
/// Get the underlying JSValueRef
operator JSValueRef() const { return instance(); }
///
/// Get the bound context for this JSValue (it is cached at creation).
///
JSContextRef context() const { return ctx_; }
///
/// Set the JSContext for this JSValue.
///
/// @note
/// JSValues created from within a JSCallback have a temporary JSContext
/// that is destroyed when the callback returns. You will need to "move"
/// any JSValues created within these callbacks to the View's main context
/// (call set_context() with the main context) before using them outside
/// the callback.
///
void set_context(JSContextRef context) { ctx_ = context; }
protected:
JSValue(JSContextRef ctx);
JSValue(JSContextRef ctx, JSValueRef val);
virtual JSValueRef instance() const;
JSContextRef ctx_;
JSValueRef instance_ = nullptr;
friend class JSFunction;
};
///
/// A vector of JSValues, used for passing around arguments in JSCallback.
///
class AExport JSArgs {
public:
/// Create an empty list of JavaScript arguments
JSArgs();
/// Create a list of JavaScript arguments using a C++ initializer list
JSArgs(const std::initializer_list<JSValue>& values);
/// Copy-constructor
JSArgs(const JSArgs& other);
/// Destructor
~JSArgs();
/// Assignment operator
JSArgs& operator=(const JSArgs& other);
///
/// Access an element of the argument list by index.
///
/// @note
/// All JSValues are actually wrappers of JSValueRef instances so even
/// though this function doesn't return a JSValue& you are still operating
/// directly on the underlying JavaScript value instance.
///
JSValue operator[](size_t pos);
///
/// Access an element of the argument list by index. (const overload)
///
/// @note
/// All JSValues are actually wrappers of JSValueRef instances so even
/// though this function doesn't return a JSValue& you are still operating
/// directly on the underlying JavaScript value instance.
///
const JSValue operator[](size_t pos) const;
/// Whether or not the argument list is empty.
bool empty() const;
/// The number of elements in the argument list.
size_t size() const;
/// Clear the argument list.
void clear();
/// Add a new argument to the end of the list.
void push_back(const JSValue& val);
/// Remove the last item from the end of the list.
void pop_back();
/// Get the argument list as a C-array of JSValues
JSValue* data();
/// Get the argument list as a C-array of JSValues (const overload)
const JSValue* data() const;
protected:
void* instance_;
};
///
/// JSCallback typedef used for binding C++ callbacks to JavaScript functions.
///
/// Takes two arguments (const JSObject& thisObj, const JSArgs& args) and
/// returns nothing (void).
///
typedef std::function<void(const JSObject&, const JSArgs&)> JSCallback;
///
/// JSCallbackWithRetval typedef used for binding C++ callbacks to JavaScript
/// functions with an optional return value.
///
/// Takes two arguments (const JSObject& thisObj, const JSArgs& args) and
/// returns a JSValue back to JavaScript.
///
typedef std::function<JSValue(const JSObject&, const JSArgs&)> JSCallbackWithRetval;
///
/// Macro to help bind C++ member functions to a JSCallback
///
/// Usage: JSCallback callback = BindJSCallback(&MyClass::MyMemberFunction);
///
/// @note Expected to run from within an instance of 'MyClass', note the 'this' keyword in the
/// macro.
///
#define BindJSCallback(fn) (JSCallback)std::bind(fn, this, std::placeholders::_1, std::placeholders::_2)
///
/// Macro to help bind C++ member functions to a JSCallbackWithRetval
///
/// Usage: JSCallback callback = BindJSCallback(&MyClass::MyMemberFunction);
///
/// @note Expected to run from within an instance of 'MyClass', note the 'this' keyword in the
/// macro.
///
#define BindJSCallbackWithRetval(fn) (JSCallbackWithRetval)std::bind(fn, this, std::placeholders::_1, std::placeholders::_2)
///
/// Wrapper for JSObject property value (JSValue subclass). Allows new value assignment
/// to object property, binding C++ callbacks to object properties via function objects,
/// as well as value query via the JSValue interface.
///
class AExport JSPropertyValue : public JSValue {
public:
virtual ~JSPropertyValue();
/// Assign a new value to the property (internally calls JSObjectSetProperty)
virtual JSPropertyValue& operator=(const JSValue& value);
/// Bind to native C++ callback (creates a Function object that can be called from JS)
JSPropertyValue& operator=(const JSCallback& callback);
/// Bind to native C++ callback with return value (creates a Function object that can be called from JS)
JSPropertyValue& operator=(const JSCallbackWithRetval& callback);
protected:
virtual JSValueRef instance() const;
JSPropertyValue(JSContextRef ctx, JSObjectRef proxy_obj, unsigned idx);
JSPropertyValue(JSContextRef ctx, JSObjectRef proxy_obj, JSString idx);
JSPropertyValue(const JSPropertyValue&) = default;
JSPropertyValue& operator=(const JSPropertyValue&) = delete;
JSObject* proxyObj_;
bool using_numeric_idx_;
unsigned numeric_idx_;
JSString string_idx_;
friend class JSArray;
friend class JSObject;
};
///
/// JSArray wrapper that automatically manages lifetime and provides
/// convenient access to indices and Array functions.
///
class AExport JSArray {
public:
/// Create empty Array
JSArray();
/// Create Array from list of JSValues
JSArray(const std::initializer_list<JSValue>& values);
/// Create Array from existing JSObjectRef (JavaScriptCore C API)
JSArray(JSObjectRef array_obj);
/// Copy constructor (shallow copy, will point to same instance)
JSArray(const JSArray& other);
~JSArray();
/// Assignment (shallow assignment, will point to same instance)
JSArray& operator=(const JSArray& other);
/// Get number of elements in the Array
unsigned length();
/// Push an element to back of Array
void push(const JSValue& val);
/// Find the index (location) of a certain value, will return -1 if not found
int indexOf(const JSValue& val, int start = 0) const;
/// Get a property by array index (numbering starts at 0)
JSPropertyValue operator[](unsigned idx) const;
/// Get the underlying JSObjectRef (JavaScriptCore C API)
operator JSObjectRef() const { return instance_; }
///
/// Get the bound context for this JSArray (it is cached at creation).
///
JSContextRef context() const { return ctx_; }
///
/// Set the JSContext for this JSArray.
///
/// @note
/// JSArrays created from within a JSCallback have a temporary JSContext
/// that is destroyed when the callback returns. You will need to "move"
/// any JSArrays created within these callbacks to the View's main context
/// (call set_context() with the main context) before using them outside
/// the callback.
///
void set_context(JSContextRef context) { ctx_ = context; }
protected:
JSArray(JSContextRef ctx, JSValueRef val);
JSContextRef ctx_;
JSObjectRef instance_;
friend class JSValue;
};
///
/// JSObject wrapper that automatically manages lifetime and provides
/// convenient access to properties.
///
class AExport JSObject {
public:
/// Create empty Object
JSObject();
/// Create from existing JSObjectRef from JavaScriptCore C API
JSObject(JSObjectRef obj);
/// Copy constructor (shallow copy, will point to same instance)
JSObject(const JSObject& other);
~JSObject();
/// Assignment (shallow assignment, will point to same instance)
JSObject& operator=(const JSObject& other);
/// Get a property by name
JSPropertyValue operator[](JSString propertyName) const;
/// Check if a property exists
bool HasProperty(JSString propertyName) const;
/// Remove a property
bool DeleteProperty(JSString propertyName);
/// Get the underlying JSObjectRef (JavaScriptCore C API)
operator JSObjectRef() const { return instance_; }
///
/// Get the bound context for this JSObject (it is cached at creation).
///
JSContextRef context() const { return ctx_; }
///
/// Set the JSContext for this JSObject.
///
/// @note:
/// JSObjects created from within a JSCallback have a temporary JSContext
/// that is destroyed when the callback returns. You will need to "move"
/// any JSObjects created within these callbacks to the View's main context
/// (call set_context() with the main context) before using them outside
/// the callback.
///
void set_context(JSContextRef context) { ctx_ = context; }
protected:
JSObject(JSContextRef ctx, JSValueRef val);
JSObject(JSContextRef ctx, JSObjectRef obj);
JSContextRef ctx_;
JSObjectRef instance_;
friend class JSValue;
friend class JSPropertyValue;
};
///
/// JSFunction wrapper that automatically manages lifetime and provides
/// convenient function invocation operators.
///
class AExport JSFunction {
public:
/// Create an empty Function.
/// NOTE: It is OKAY to create this without calling SetJSContext() first.
JSFunction();
/// Copy constructor (shallow copy, will point to same instance)
JSFunction(const JSFunction& other);
~JSFunction();
/// Assignment (shallow assignment, will point to same instance)
JSFunction& operator=(const JSFunction& other);
/// Whether or not this is a valid, callable Function object.
bool IsValid() const;
/// Call function (using Global Object for 'this') and return the result.
JSValue operator()(const JSArgs& args);
/// Call function (with explicit object for 'this') and return the result
JSValue operator()(const JSObject& thisObject, const JSArgs& args);
/// Get the underlying JSObjectRef (JavaScriptCore C API)
operator JSObjectRef() const { return instance_; }
///
/// Get the bound context for this JSFunction (it is cached at creation).
///
JSContextRef context() const { return ctx_; }
///
/// Set the JSContext for this JSFunction.
///
/// @note
/// JSFunctions created from within a JSCallback have a temporary JSContext
/// that is destroyed when the callback returns. You will need to "move"
/// any JSFunctions created within these callbacks to the View's main context
/// (call set_context() with the main context) before using them outside
/// the callback.
///
void set_context(JSContextRef context) { ctx_ = context; }
protected:
JSFunction(JSContextRef ctx, JSValueRef val);
JSContextRef ctx_;
JSObjectRef instance_;
friend class JSValue;
};
///
/// Get the Global Object for the current JSContext.
/// In JavaScript, this would be equivalent to the "window" object.
///
JSObject AExport JSGlobalObject();
///
/// Evaluate a string of JavaScript and return a result.
///
JSValue AExport JSEval(const JSString& str);
} // namespace ultralight
+51
View File
@@ -0,0 +1,51 @@
/**************************************************************************************************
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
* *
* See <https://ultralig.ht> for licensing and more. *
* *
* (C) 2024 Ultralight, Inc. *
**************************************************************************************************/
#pragma once
#include "Defines.h"
namespace ultralight {
///
/// A platform-specific monitor.
///
class AExport Monitor {
public:
virtual ~Monitor() {}
///
/// Get the unique display ID of the monitor.
///
/// The renderer uses this ID to identify which monitor a View is on (ViewConfig::display_id).
///
/// AppCore internally tracks the display's hardware refresh event and automatically calls
/// Renderer::RefreshDisplay(id) to drive animation in all corresponding Views.
///
virtual uint32_t display_id() const = 0;
///
/// Get the DPI scale (1.0 = 100%)
///
virtual double scale() const = 0;
///
/// Get the width of the monitor (in pixels).
///
virtual uint32_t width() const = 0;
///
/// Get the height of the monitor (in pixels).
///
virtual uint32_t height() const = 0;
///
/// Get the refresh rate of the monitor (in Hz).
///
virtual uint32_t refresh_rate() const = 0;
};
} // namespace ultralight
+150
View File
@@ -0,0 +1,150 @@
/**************************************************************************************************
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
* *
* See <https://ultralig.ht> for licensing and more. *
* *
* (C) 2024 Ultralight, Inc. *
**************************************************************************************************/
#pragma once
#include "Window.h"
#include <Ultralight/View.h>
namespace ultralight {
///
/// Web-content overlay, displays a web-page within a portion of a Window.
///
/// Overlays are used to display web-based content in a portion of a window. They automatically
/// forward input events to the underlying View instance and handle rendering.
///
/// ## Creating an Overlay
///
/// Call Overlay::Create() to create an overlay in a window.
///
/// ```
/// auto overlay = Overlay::Create(window, 1024, 768, 0, 0);
/// ```
///
/// ## Loading Content into an Overlay
///
/// Each Overlay has a View instance that you can use to load web content into.
///
/// ```
/// overlay->view()->LoadURL("https://google.com");
/// ```
///
class AExport Overlay : public RefCounted {
public:
///
/// Create a new Overlay.
///
/// @param window The window to create the Overlay in.
///
/// @param width The width in pixels.
///
/// @param height The height in pixels.
///
/// @param x The x-position (offset from the left of the Window), in
/// pixels.
///
/// @param y The y-position (offset from the top of the Window), in
/// pixels.
///
static RefPtr<Overlay> Create(RefPtr<Window> window, uint32_t width,
uint32_t height, int x, int y);
///
/// Create a new Overlay, wrapping an existing View.
///
/// @param window The window to create the Overlay in.
///
/// @param view The View to wrap (will use its width and height).
///
/// @param x The x-position (offset from the left of the Window), in
/// pixels.
///
/// @param y The y-position (offset from the top of the Window), in
/// pixels.
///
static RefPtr<Overlay> Create(RefPtr<Window> window, RefPtr<View> view, int x, int y);
///
/// Get the underlying View.
///
virtual ultralight::RefPtr<ultralight::View> view() = 0;
///
/// Get the width (in pixels).
///
virtual uint32_t width() const = 0;
///
/// Get the height (in pixels).
///
virtual uint32_t height() const = 0;
///
/// Get the x-position (offset from the left of the Window), in pixels.
///
virtual int x() const = 0;
///
/// Get the y-position (offset from the top of the Window), in pixels.
///
virtual int y() const = 0;
///
/// Whether or not the overlay is hidden (not drawn).
///
virtual bool is_hidden() const = 0;
///
/// Hide the overlay (will no longer be drawn)
///
virtual void Hide() = 0;
///
/// Show the overlay.
///
virtual void Show() = 0;
///
/// Whether or not this overlay has keyboard focus.
///
virtual bool has_focus() const = 0;
///
/// Grant this overlay exclusive keyboard focus.
///
virtual void Focus() = 0;
///
/// Remove keyboard focus.
///
virtual void Unfocus() = 0;
///
/// Move the overlay to a new position (in pixels).
///
virtual void MoveTo(int x, int y) = 0;
///
/// Resize the overlay (and underlying View), dimensions should be
/// specified in pixels.
///
virtual void Resize(uint32_t width, uint32_t height) = 0;
///
/// Whether or not this Overlay needs repaint (either it has moved, resized,
/// or the internal View needs repaint).
///
virtual bool NeedsRepaint() = 0;
protected:
virtual ~Overlay();
virtual void Render() = 0;
virtual void Paint() = 0;
friend class OverlayManager;
};
} // namespace framework
+47
View File
@@ -0,0 +1,47 @@
/**************************************************************************************************
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
* *
* See <https://ultralig.ht> for licensing and more. *
* *
* (C) 2024 Ultralight, Inc. *
**************************************************************************************************/
#pragma once
#include "Defines.h"
#include <Ultralight/String.h>
#include <Ultralight/platform/FontLoader.h>
#include <Ultralight/platform/FileSystem.h>
#include <Ultralight/platform/Logger.h>
namespace ultralight {
///
/// Get the native font loader for the current platform.
///
/// @note This singleton is owned by the library, do not destroy it.
///
AExport FontLoader* GetPlatformFontLoader();
///
/// Get the native file system for the current platform, creating it if it
/// doesn't exist using the base directory provided.
///
/// This is used to load data for file:/// URLs.
///
/// @param baseDir An base file path that will be used to resolve relative
/// file paths. You can optionally specify "@resource_path"
/// on macOS to use the app bundle's resource path.
///
/// @note This singleton is owned by the library, do not destroy it.
///
AExport FileSystem* GetPlatformFileSystem(const String& baseDir);
///
/// Get the default logger (writes the log to a file on disk).
///
/// @param logPath A file path to write the log to.
///
/// @note This singleton is owned by the library, do not destroy it.
///
AExport Logger* GetDefaultLogger(const String& logPath);
} // namespace ultralight
+306
View File
@@ -0,0 +1,306 @@
/**************************************************************************************************
* This file is a part of Ultralight, an ultra-portable web-browser engine. *
* *
* See <https://ultralig.ht> for licensing and more. *
* *
* (C) 2024 Ultralight, Inc. *
**************************************************************************************************/
#pragma once
#include "Defines.h"
#include <Ultralight/RefPtr.h>
#include <Ultralight/Listener.h>
#include <Ultralight/Bitmap.h>
#include <Ultralight/KeyEvent.h>
#include <Ultralight/MouseEvent.h>
#include <Ultralight/ScrollEvent.h>
namespace ultralight {
class Monitor;
class OverlayManager;
class Surface;
class Window;
///
/// Interface for all Window-related events. @see Window::set_listener
///
class WindowListener {
public:
virtual ~WindowListener() {}
///
/// Called when the Window is closed.
///
virtual void OnClose(ultralight::Window* window) { }
///
/// Called when the Window is resized.
///
/// @param width The new width (in pixels).
///
/// @param height The new height (in pixels).
///
virtual void OnResize(ultralight::Window* window, uint32_t width_px, uint32_t height_px) { }
///
/// Called when a keyboard event is fired.
///
/// @param evt Details for the event.
///
/// @return Return false to consume the event and prevent it from propagating further.
///
virtual bool OnKeyEvent(const ultralight::KeyEvent& evt) { return true; }
///
/// Called when a mouse event is fired.
///
/// @param evt Details for the event.
///
/// @return Return false to consume the event and prevent it from propagating further.
///
virtual bool OnMouseEvent(const ultralight::MouseEvent& evt) { return true; }
///
/// Called when a scroll event is fired.
///
/// @param evt Details for the event.
///
/// @return Return false to consume the event and prevent it from propagating further.
///
virtual bool OnScrollEvent(const ultralight::ScrollEvent& evt) { return true; }
};
///
/// Window creation flags. @see Window::Create
///
enum WindowFlags : uint8_t {
kWindowFlags_Borderless = 1 << 0,
kWindowFlags_Titled = 1 << 1,
kWindowFlags_Resizable = 1 << 2,
kWindowFlags_Maximizable = 1 << 3,
kWindowFlags_Hidden = 1 << 4,
};
///
/// A platform-specific window.
///
/// This class describes a platform-specific window and provides methods for managing it.
///
/// ## Creating a Window
///
/// To create a new Window, use the static Window::Create method:
///
/// ```
/// auto window = Window::Create(monitor, 1024, 768, false, kWindowFlags_Titled);
/// ```
///
/// ## Setting a WindowListener
///
/// To receive callbacks for window-related events, set a WindowListener:
///
/// ```
/// class MyWindowListener : public WindowListener {
/// virtual void OnClose(Window* window) override {
/// printf("Window closed!\n");
/// }
/// };
///
/// auto listener = new MyWindowListener();
/// window->set_listener(listener);
/// ```
///
/// ## Coordinate Systems
///
/// Monitors and may windows may have a device scale applied by the OS (for example, a Retina
/// display on macOS may have a 2x or 3x DPI scale).
///
/// To convert between screen coordinates and pixel coordinates, use the following equation:
///
/// ```
/// pixel_coordinate = round(screen_coordinate * scale)
/// ```
///
class AExport Window : public RefCounted {
public:
///
/// Create a new Window.
///
/// @param monitor The monitor to create the Window on.
///
/// @param width The width (in screen coordinates).
///
/// @param height The height (in screen coordinates).
///
/// @param fullscreen Whether or not the window is fullscreen.
///
/// @param window_flags Various window flags.
///
/// @note
/// \parblock
///
/// Windows are immediately shown by default unless kWindowFlags_Hidden is set in the
/// window_flags parameter. (They can be shown later via Window::Show())
///
/// \endparblock
///
/// @note
/// \parblock
///
/// Screen coordinates are device-scale-independent and have the following relationship
/// to pixel coordinates:
///
/// \code
/// pixel_coordinate = round(screen_coordinate * scale)
/// \endcode
///
/// \endparblock
///
static RefPtr<Window> Create(Monitor* monitor, uint32_t width, uint32_t height,
bool fullscreen, unsigned int window_flags);
///
/// Set a WindowListener to receive callbacks for window-related events.
///
/// @note Ownership remains with the caller.
///
virtual void set_listener(WindowListener* listener) = 0;
///
/// Get the WindowListener, if any.
///
virtual WindowListener* listener() = 0;
///
/// Get the window width (in screen coordinates).
///
virtual uint32_t screen_width() const = 0;
///
/// Get the window width (in pixels).
///
virtual uint32_t width() const = 0;
///
/// Get the window height (in screen coordinates).
///
virtual uint32_t screen_height() const = 0;
///
/// Get the window height (in pixels).
///
virtual uint32_t height() const = 0;
///
/// Move the window to a new position (in screen coordinates) relative to the top-left of the
/// monitor area.
///
virtual void MoveTo(int x, int y) = 0;
///
/// Move the window to the center of the monitor.
///
virtual void MoveToCenter() = 0;
///
/// Get the x-position of the window (in screen coordinates) relative to the top-left of the
/// monitor area.
///
virtual int x() const = 0;
///
/// Get the y-position of the window (in screen coordinates) relative to the top-left of the
/// monitor area.
///
virtual int y() const = 0;
///
/// Whether or not the window is fullscreen.
///
virtual bool is_fullscreen() const = 0;
///
/// Whether or not the window is GPU accelerated.
///
virtual bool is_accelerated() const = 0;
///
/// The render buffer id of the the window's backing texture.
/// (This will be 0 if the window is not accelerated).
///
virtual uint32_t render_buffer_id() const = 0;
///
/// The DPI scale of the window.
///
virtual double scale() const = 0;
///
/// Set the window title.
///
virtual void SetTitle(const char* title) = 0;
///
/// Set the cursor.
///
virtual void SetCursor(ultralight::Cursor cursor) = 0;
///
/// Show the window (if it was previously hidden).
///
virtual void Show() = 0;
///
/// Hide the window.
///
virtual void Hide() = 0;
///
/// Whether or not the window is currently visible (not hidden).
///
virtual bool is_visible() const = 0;
///
/// Close the window.
///
virtual void Close() = 0;
///
/// Convert screen coordinates to pixels using the current DPI scale.
///
virtual int ScreenToPixels(int val) const = 0;
///
/// Convert pixels to screen coordinates using the current DPI scale.
///
virtual int PixelsToScreen(int val) const = 0;
///
/// Draw a surface directly to window, used only by CPU renderer
///
virtual void DrawSurface(int x, int y, Surface* surface) {}
///
/// Get the underlying native window handle.
///
/// @note
/// This is:
/// - HWND on Windows
/// - NSWindow* on macOS
/// - GLFWwindow* on Linux
///
virtual void* native_handle() const = 0;
///
/// Display frame statistics (FPS, frame times, etc.) in the titlebar.
///
virtual void EnableFrameStatistics() {}
protected:
virtual ~Window();
virtual bool platform_always_uses_cpu_renderer() const = 0;
virtual OverlayManager* overlay_manager() const = 0;
friend class OverlayImpl;
};
} // namespace ultralight