mirror of
https://github.com/InstanceBrick/nightcap.git
synced 2026-10-20 01:00:54 +02:00
117 lines
3.4 KiB
C++
117 lines
3.4 KiB
C++
#ifndef MOCKTAIL_RUNTIME_ROBLOX_TEXT_DISPLAY_STATE_H_
|
|
#define MOCKTAIL_RUNTIME_ROBLOX_TEXT_DISPLAY_STATE_H_
|
|
|
|
#include <cmath>
|
|
#include <cstddef>
|
|
#include <cstdint>
|
|
#include <string>
|
|
|
|
#include "mocktail/status.h"
|
|
#include "runtime/roblox_text_editor.h"
|
|
|
|
namespace mocktail {
|
|
namespace runtime {
|
|
|
|
struct RobloxTextOverlayViewport {
|
|
int width = 0;
|
|
int height = 0;
|
|
float density_scale = 1.0F;
|
|
|
|
bool valid() const {
|
|
return width > 0 && height > 0 && std::isfinite(density_scale) &&
|
|
density_scale > 0.0F;
|
|
}
|
|
int coordinate_width() const;
|
|
int coordinate_height() const;
|
|
};
|
|
|
|
struct RobloxTextOverlayGeometry {
|
|
int x = 0;
|
|
int y = 0;
|
|
int width = 0;
|
|
int height = 0;
|
|
bool used_fallback = false;
|
|
|
|
bool valid() const { return width > 0 && height > 0; }
|
|
|
|
bool operator==(const RobloxTextOverlayGeometry& other) const {
|
|
return x == other.x && y == other.y && width == other.width &&
|
|
height == other.height && used_fallback == other.used_fallback;
|
|
}
|
|
bool operator!=(const RobloxTextOverlayGeometry& other) const {
|
|
return !(*this == other);
|
|
}
|
|
};
|
|
|
|
// Main-thread presentation owned by the host overlay. `display_utf8` is
|
|
// sensitive for ordinary fields and contains only bullets for password types.
|
|
// The destructor and move assignment wipe retained bytes before releasing
|
|
// their storage.
|
|
struct RobloxTextOverlayPresentation {
|
|
RobloxTextOverlayPresentation() = default;
|
|
~RobloxTextOverlayPresentation();
|
|
|
|
RobloxTextOverlayPresentation(const RobloxTextOverlayPresentation&) = delete;
|
|
RobloxTextOverlayPresentation& operator=(
|
|
const RobloxTextOverlayPresentation&) = delete;
|
|
RobloxTextOverlayPresentation(RobloxTextOverlayPresentation&& other);
|
|
RobloxTextOverlayPresentation& operator=(
|
|
RobloxTextOverlayPresentation&& other);
|
|
|
|
void ClearSensitive();
|
|
|
|
bool visible = false;
|
|
uint64_t generation = 0;
|
|
RobloxTextOverlayGeometry geometry;
|
|
float font_size = 0.0F;
|
|
bool multiline = false;
|
|
int32_t x_alignment = 0;
|
|
int32_t y_alignment = 1;
|
|
int32_t text_color = 0;
|
|
int32_t font = 0;
|
|
int32_t text_input_type = 0;
|
|
bool text_wrapped = false;
|
|
std::string display_utf8;
|
|
std::size_t caret_utf8_byte = 0;
|
|
std::size_t selection_begin_utf8_byte = 0;
|
|
std::size_t selection_end_utf8_byte = 0;
|
|
};
|
|
|
|
bool IsRobloxPasswordTextInputType(int32_t text_input_type);
|
|
|
|
RobloxTextOverlayGeometry ResolveRobloxTextOverlayGeometry(
|
|
const RobloxTextDisplayUpdate& update,
|
|
const RobloxTextOverlayViewport& viewport);
|
|
|
|
Status BuildRobloxTextOverlayPresentation(
|
|
const RobloxTextDisplayUpdate& update,
|
|
const RobloxTextOverlayViewport& viewport,
|
|
RobloxTextOverlayPresentation* presentation);
|
|
|
|
// Applies show/update/hide events in generation order. Stale events are
|
|
// harmless no-ops, which prevents a delayed hide from closing a newer field.
|
|
class RobloxTextDisplayState final {
|
|
public:
|
|
RobloxTextDisplayState() = default;
|
|
~RobloxTextDisplayState() = default;
|
|
|
|
RobloxTextDisplayState(const RobloxTextDisplayState&) = delete;
|
|
RobloxTextDisplayState& operator=(const RobloxTextDisplayState&) = delete;
|
|
|
|
Status Apply(const RobloxTextDisplayUpdate& update,
|
|
const RobloxTextOverlayViewport& viewport, bool* changed);
|
|
void Reset();
|
|
|
|
const RobloxTextOverlayPresentation& presentation() const {
|
|
return presentation_;
|
|
}
|
|
|
|
private:
|
|
RobloxTextOverlayPresentation presentation_;
|
|
};
|
|
|
|
} // namespace runtime
|
|
} // namespace mocktail
|
|
|
|
#endif // MOCKTAIL_RUNTIME_ROBLOX_TEXT_DISPLAY_STATE_H_
|