2026-04-27 22:43:30 -07:00
|
|
|
#include "SystemInterface_Aurora.h"
|
|
|
|
|
|
2026-04-29 23:43:08 -06:00
|
|
|
#include <SDL3/SDL_keyboard.h>
|
2026-04-30 00:05:37 -06:00
|
|
|
#include <SDL3/SDL_properties.h>
|
2026-04-29 23:43:08 -06:00
|
|
|
#include <algorithm>
|
|
|
|
|
|
2026-04-27 22:43:30 -07:00
|
|
|
#include "../logging.hpp"
|
|
|
|
|
#include "../window.hpp"
|
2026-05-05 23:13:31 -06:00
|
|
|
#include "../webgpu/gpu.hpp"
|
2026-04-27 22:43:30 -07:00
|
|
|
|
|
|
|
|
namespace aurora::rmlui {
|
2026-04-30 00:05:37 -06:00
|
|
|
namespace {
|
|
|
|
|
|
|
|
|
|
Module Log("aurora::rmlui");
|
|
|
|
|
|
|
|
|
|
SDL_TextInputType sdl_input_type(InputType type) noexcept {
|
|
|
|
|
switch (type) {
|
|
|
|
|
case InputType::Number:
|
|
|
|
|
return SDL_TEXTINPUT_TYPE_NUMBER;
|
|
|
|
|
case InputType::Text:
|
|
|
|
|
default:
|
|
|
|
|
return SDL_TEXTINPUT_TYPE_TEXT;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool start_text_input(SDL_Window* window, InputType type) {
|
|
|
|
|
if (type == InputType::Text) {
|
|
|
|
|
return SDL_StartTextInput(window);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SDL_PropertiesID props = SDL_CreateProperties();
|
|
|
|
|
if (props == 0) {
|
|
|
|
|
return SDL_StartTextInput(window);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SDL_SetNumberProperty(props, SDL_PROP_TEXTINPUT_TYPE_NUMBER, sdl_input_type(type));
|
|
|
|
|
const bool result = SDL_StartTextInputWithProperties(window, props);
|
|
|
|
|
SDL_DestroyProperties(props);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
} // namespace
|
2026-04-27 22:43:30 -07:00
|
|
|
|
2026-05-01 00:25:23 -06:00
|
|
|
SystemInterface_Aurora::SystemInterface_Aurora() : SystemInterface_SDL(window::get_sdl_window()) {}
|
2026-04-27 22:43:30 -07:00
|
|
|
|
2026-04-30 00:05:37 -06:00
|
|
|
void SystemInterface_Aurora::SetInputType(InputType type) noexcept { mTextInputType = type; }
|
|
|
|
|
|
2026-04-29 23:43:08 -06:00
|
|
|
void SystemInterface_Aurora::ActivateKeyboard(Rml::Vector2f caret_position, float line_height) {
|
|
|
|
|
SDL_Window* sdlWindow = window::get_sdl_window();
|
|
|
|
|
if (sdlWindow == nullptr) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const AuroraWindowSize size = window::get_window_size();
|
2026-05-05 23:13:31 -06:00
|
|
|
if (size.native_fb_width == 0 || size.native_fb_height == 0 || size.width == 0 || size.height == 0 ||
|
|
|
|
|
size.fb_width == 0 || size.fb_height == 0) {
|
2026-04-29 23:43:08 -06:00
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2026-05-05 23:13:31 -06:00
|
|
|
Rml::Vector2i contentSize{static_cast<int>(size.fb_width), static_cast<int>(size.fb_height)};
|
|
|
|
|
if (const Rml::Context* context = get_context()) {
|
|
|
|
|
contentSize = context->GetDimensions();
|
|
|
|
|
}
|
|
|
|
|
if (contentSize.x <= 0 || contentSize.y <= 0) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const auto viewport = webgpu::calculate_present_viewport(size.native_fb_width, size.native_fb_height,
|
|
|
|
|
static_cast<uint32_t>(contentSize.x),
|
|
|
|
|
static_cast<uint32_t>(contentSize.y));
|
|
|
|
|
if (viewport.width <= 0.f || viewport.height <= 0.f) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const float nativeToWindowX = static_cast<float>(size.width) / static_cast<float>(size.native_fb_width);
|
|
|
|
|
const float nativeToWindowY = static_cast<float>(size.height) / static_cast<float>(size.native_fb_height);
|
|
|
|
|
const float contentToNativeX = viewport.width / static_cast<float>(contentSize.x);
|
|
|
|
|
const float contentToNativeY = viewport.height / static_cast<float>(contentSize.y);
|
|
|
|
|
const float inputLineHeight = std::max(line_height * contentToNativeY * nativeToWindowY, 1.0f);
|
|
|
|
|
const float nativeCaretX = viewport.left + caret_position.x * contentToNativeX;
|
|
|
|
|
const float nativeCaretY = viewport.top + caret_position.y * contentToNativeY;
|
2026-04-29 23:43:08 -06:00
|
|
|
const SDL_Rect rect = {
|
2026-05-05 23:13:31 -06:00
|
|
|
.x = static_cast<int>(std::lround(nativeCaretX * nativeToWindowX)),
|
|
|
|
|
.y = static_cast<int>(std::lround(nativeCaretY * nativeToWindowY + inputLineHeight)),
|
2026-04-29 23:43:08 -06:00
|
|
|
.w = 1,
|
|
|
|
|
.h = static_cast<int>(std::lround(inputLineHeight)),
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
SDL_SetTextInputArea(sdlWindow, &rect, 0);
|
2026-04-30 00:05:37 -06:00
|
|
|
if (!SDL_TextInputActive(sdlWindow) || !mHasActiveTextInputType || mActiveTextInputType != mTextInputType) {
|
|
|
|
|
if (start_text_input(sdlWindow, mTextInputType)) {
|
|
|
|
|
mActiveTextInputType = mTextInputType;
|
|
|
|
|
mHasActiveTextInputType = true;
|
|
|
|
|
}
|
2026-04-29 23:49:27 -06:00
|
|
|
}
|
2026-04-29 23:43:08 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void SystemInterface_Aurora::DeactivateKeyboard() {
|
|
|
|
|
SDL_Window* sdlWindow = window::get_sdl_window();
|
2026-04-29 23:49:27 -06:00
|
|
|
if (sdlWindow != nullptr && SDL_TextInputActive(sdlWindow)) {
|
2026-04-29 23:43:08 -06:00
|
|
|
SDL_StopTextInput(sdlWindow);
|
|
|
|
|
}
|
2026-04-30 00:05:37 -06:00
|
|
|
mHasActiveTextInputType = false;
|
2026-04-29 23:43:08 -06:00
|
|
|
}
|
|
|
|
|
|
2026-04-27 22:43:30 -07:00
|
|
|
bool SystemInterface_Aurora::LogMessage(Rml::Log::Type type, const Rml::String& message) {
|
|
|
|
|
switch (type) {
|
2026-04-29 23:49:27 -06:00
|
|
|
case Rml::Log::Type::LT_ERROR:
|
|
|
|
|
Log.error("{}", message);
|
|
|
|
|
return false;
|
|
|
|
|
case Rml::Log::Type::LT_ASSERT:
|
|
|
|
|
Log.fatal("{}", message);
|
|
|
|
|
return false;
|
|
|
|
|
case Rml::Log::Type::LT_WARNING:
|
|
|
|
|
Log.warn("{}", message);
|
|
|
|
|
return true;
|
|
|
|
|
case Rml::Log::Type::LT_INFO:
|
|
|
|
|
Log.info("{}", message);
|
|
|
|
|
return true;
|
|
|
|
|
case Rml::Log::Type::LT_DEBUG:
|
|
|
|
|
Log.debug("{}", message);
|
|
|
|
|
return true;
|
|
|
|
|
default:
|
|
|
|
|
Log.info("{}", message);
|
|
|
|
|
return true;
|
2026-04-27 22:43:30 -07:00
|
|
|
}
|
|
|
|
|
}
|
2026-04-29 23:49:27 -06:00
|
|
|
} // namespace aurora::rmlui
|