refactor(new_editor): snapshot hosted editor restructuring
This commit is contained in:
@@ -1,9 +1,12 @@
|
||||
#pragma once
|
||||
|
||||
#include <XCEngine/UI/Text/UITextEditing.h>
|
||||
#include <XCEngine/UI/DrawData.h>
|
||||
|
||||
#include <algorithm>
|
||||
#include <chrono>
|
||||
#include <cmath>
|
||||
#include <string>
|
||||
|
||||
namespace XCEngine::UI::Editor::Widgets {
|
||||
|
||||
@@ -32,4 +35,79 @@ inline ::XCEngine::UI::UIRect ResolveUIEditorTextClipRect(
|
||||
rect.height + extraPadding + 1.0f);
|
||||
}
|
||||
|
||||
inline float MeasureUIEditorTextWidth(
|
||||
const std::string& text,
|
||||
float fontSize) {
|
||||
return fontSize * 0.56f *
|
||||
static_cast<float>(::XCEngine::UI::Text::CountUtf8Codepoints(text));
|
||||
}
|
||||
|
||||
inline float MeasureUIEditorTextWidthToCaret(
|
||||
const std::string& text,
|
||||
std::size_t caretOffset,
|
||||
float fontSize) {
|
||||
return fontSize * 0.56f *
|
||||
static_cast<float>(::XCEngine::UI::Text::CountUtf8CodepointsInRange(
|
||||
text,
|
||||
0u,
|
||||
(std::min)(caretOffset, text.size())));
|
||||
}
|
||||
|
||||
inline std::uint64_t GetUIEditorTextCaretClockNanoseconds() {
|
||||
using Clock = std::chrono::steady_clock;
|
||||
const auto now = Clock::now().time_since_epoch();
|
||||
return static_cast<std::uint64_t>(
|
||||
std::chrono::duration_cast<std::chrono::nanoseconds>(now).count());
|
||||
}
|
||||
|
||||
inline bool ShouldBlinkUIEditorTextCaret(std::uint64_t blinkStartNanoseconds) {
|
||||
constexpr std::uint64_t kInitialVisibleDurationNanoseconds = 500000000ull;
|
||||
constexpr std::uint64_t kBlinkPhaseDurationNanoseconds = 500000000ull;
|
||||
|
||||
if (blinkStartNanoseconds == 0u) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::uint64_t nowNanoseconds = GetUIEditorTextCaretClockNanoseconds();
|
||||
if (nowNanoseconds <= blinkStartNanoseconds) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::uint64_t elapsedNanoseconds = nowNanoseconds - blinkStartNanoseconds;
|
||||
if (elapsedNanoseconds < kInitialVisibleDurationNanoseconds) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const std::uint64_t blinkElapsedNanoseconds =
|
||||
elapsedNanoseconds - kInitialVisibleDurationNanoseconds;
|
||||
return ((blinkElapsedNanoseconds / kBlinkPhaseDurationNanoseconds) % 2u) == 0u;
|
||||
}
|
||||
|
||||
inline void AppendUIEditorTextCaret(
|
||||
::XCEngine::UI::UIDrawList& drawList,
|
||||
const ::XCEngine::UI::UIRect& rect,
|
||||
const std::string& text,
|
||||
std::size_t caretOffset,
|
||||
std::uint64_t blinkStartNanoseconds,
|
||||
const ::XCEngine::UI::UIColor& color,
|
||||
float fontSize,
|
||||
float insetX,
|
||||
float insetY = 0.0f,
|
||||
float thickness = 1.0f) {
|
||||
if (color.a <= 0.0f || !ShouldBlinkUIEditorTextCaret(blinkStartNanoseconds)) {
|
||||
return;
|
||||
}
|
||||
|
||||
const float caretX = (std::min)(
|
||||
rect.x + rect.width - 1.0f,
|
||||
rect.x + insetX + MeasureUIEditorTextWidthToCaret(text, caretOffset, fontSize));
|
||||
const float top = ResolveUIEditorTextTop(rect, fontSize, insetY);
|
||||
const float bottom = top + MeasureUIEditorTextLayoutHeight(fontSize);
|
||||
drawList.AddLine(
|
||||
::XCEngine::UI::UIPoint(caretX, top),
|
||||
::XCEngine::UI::UIPoint(caretX, bottom),
|
||||
color,
|
||||
thickness);
|
||||
}
|
||||
|
||||
} // namespace XCEngine::UI::Editor::Widgets
|
||||
|
||||
Reference in New Issue
Block a user