15#include <AUI/Util/AWordWrappingEngine.h>
16#include "AViewContainer.h"
17#include "AUI/Font/IFontView.h"
18#include <initializer_list>
20#include <AUI/Enum/WordBreak.h>
22namespace aui::detail {
23 class TextBaseEntry:
public AWordWrappingEngineBase::Entry {
25 virtual size_t getCharacterCount() = 0;
26 virtual glm::ivec2 getPosByIndex(
size_t characterIndex) = 0;
27 virtual void appendTo(AString& dst) = 0;
28 virtual void erase(
size_t begin, AOptional<size_t> end) {}
30 struct StopLineScanningHint{};
31 using HitTestResult = std::variant<std::nullopt_t, size_t, StopLineScanningHint>;
32 virtual HitTestResult hitTest(glm::ivec2 position) {
37 class CharEntry:
public TextBaseEntry {
44 CharEntry(IFontView* text,
char32_t ch)
45 : mText(text), mChar(ch) {}
47 glm::ivec2 getSize()
override {
48 return { mText->getFontStyle().getCharacter(mChar).advanceX, mText->getFontStyle().size };
51 void setPosition(glm::ivec2 position)
override {
55 const glm::ivec2& getPosition()
const {
59 char32_t getChar()
const {
63 size_t getCharacterCount()
override {
67 glm::ivec2 getPosByIndex(
size_t characterIndex)
override {
68 return mPosition + glm::ivec2{characterIndex * mText->getFontStyle().getCharacter(mChar).advanceX, 0};
71 void appendTo(AString& dst)
override {
75 class WordEntry:
public TextBaseEntry {
79 glm::ivec2 mPosition{};
82 WordEntry(IFontView* text, AString word)
83 : mText(text), mWord(std::move(word)){}
85 glm::ivec2 getSize()
override {
86 return { mText->getFontStyle().getWidth(mWord), mText->getFontStyle().size };
89 const AString& getWord()
const {
98 glm::ivec2 getPosition()
const {
102 void setPosition(glm::ivec2 position)
override {
103 TextBaseEntry::setPosition(position);
104 mPosition = position;
107 size_t getCharacterCount()
override {
111 glm::ivec2 getPosByIndex(
size_t characterIndex)
override {
112 return mPosition + glm::ivec2{mText->getFontStyle().getWidth(mWord.begin(), mWord.begin() +
long(characterIndex)), 0};
115 void appendTo(AString& dst)
override {
119 void erase(
size_t begin, AOptional<size_t> end)
override {
120 mWord.erase(mWord.begin() +
long(begin), mWord.begin() +
long(end.
valueOr(mWord.length())));
124 class WhitespaceEntry:
public TextBaseEntry {
129 WhitespaceEntry(IFontView* text) : mText(text) {}
131 glm::ivec2 getSize()
override {
132 return { mText->getFontStyle().getSpaceWidth(), mText->getFontStyle().size };
135 bool escapesEdges()
override {
139 ~WhitespaceEntry()
override =
default;
141 size_t getCharacterCount()
override {
145 glm::ivec2 getPosByIndex(
size_t characterIndex)
override {
146 throw AException(
"unimplemented");
149 void appendTo(AString& dst)
override {
154 class NextLineEntry:
public TextBaseEntry {
159 NextLineEntry(IFontView* text) : mText(text) {}
161 bool forcesNextLine()
const override {
165 glm::ivec2 getSize()
override {
166 return {0, mText->getFontStyle().size};
169 ~NextLineEntry()
override =
default;
171 size_t getCharacterCount()
override {
175 glm::ivec2 getPosByIndex(
size_t characterIndex)
override {
176 throw AException(
"unimplemented");
179 void appendTo(AString& dst)
override {
188template<
typename WordWrappingEngine = AWordWrappingEngine<>>
189class API_AUI_VIEWS ATextBase:
public AViewContainerBase,
public IFontView {
191 using Entries =
typename WordWrappingEngine::Entries;
193 ATextBase() =
default;
194 ~ATextBase()
override =
default;
198 doDrawString(context);
202 if (!mPrerenderedString) {
203 prerenderString(context);
205 if (mPrerenderedString) {
206 RenderHints::PushColor
c(context.render);
207 context.render.
setColor(getTextColor());
208 mPrerenderedString->draw();
212 void setSize(glm::ivec2 size)
override {
213 bool widthDiffers = size.x != getWidth();
214 AViewContainerBase::setSize(size);
216 mPrerenderedString =
nullptr;
217 markMinContentSizeInvalid();
232 for (
const auto& e : mEngine.entries()) {
233 if (e->forcesNextLine()) {
234 max = glm::max(max, accumulator);
238 if (accumulator + e->getSize().x > paddedMaxSize) {
239 if (accumulator == 0) {
245 accumulator += e->getSize().x;
248 return glm::max(max, accumulator);
251 if (!mPrerenderedString) {
255 if (
auto engineHeight = mEngine.height()) {
256 return *engineHeight;
262 void invalidateFont()
override {
263 mPrerenderedString.reset();
264 markMinContentSizeInvalid();
268 void commitStyle()
override {
269 AView::commitStyle();
274 invalidateAllStylesFont();
284 fillStringCanvas(multiStringCanvas);
287 mPrerenderedString = multiStringCanvas->finalize();
291 virtual void clearContent() {
293 mPrerenderedString =
nullptr;
298 WordWrappingEngine mEngine;
300 _<IRenderer::IPrerenderedString> mPrerenderedString;
303 void performLayout() {
304 APerformanceSection s(
"ATextBase::performLayout");
305 mEngine.setTextAlign(getFontStyle().align);
306 mEngine.setLineHeight(getFontStyle().lineSpacing);
307 mEngine.performLayout({mPadding.left, mPadding.top },
getSize() - glm::ivec2{mPadding.horizontal(), mPadding.vertical()});
T valueOr(F &&alternative) const
value or alternative (either value or callback)
Definition AOptional.h:233
void render(ARenderContext context) override
Draws this AView. Noone should call this function except rendering routine.
Definition ATextBase.h:195
int getContentMinimumWidth() override
Definition ATextBase.h:221
void invalidateAllStyles() override
Invalidates all styles, causing to iterate over all rules in global and parent stylesheets.
Definition ATextBase.h:273
int getContentMinimumHeight() override
Definition ATextBase.h:250
void removeAllViews()
Remove all views from container.
Definition AViewContainerBase.cpp:495
void invalidateAllStyles() override
Invalidates all styles, causing to iterate over all rules in global and parent stylesheets.
Definition AViewContainerBase.cpp:457
void render(ARenderContext context) override
Draws this AView. Noone should call this function except rendering routine.
Definition AViewContainerBase.cpp:235
auto expanding() const
Expansion coefficient. Hints layout manager how much this AView should be extended relative to other ...
Definition AView.h:134
glm::ivec2 mFixedSize
Fixed size.
Definition AView.h:1012
glm::ivec2 getSize() const noexcept
Size, including content area, border and padding.
Definition AView.h:217
glm::ivec2 mMaxSize
Maximal size.
Definition AView.h:1007
ABoxFields mPadding
Padding, which defines the spacing around content area inside the view. Processed by AView implementa...
Definition AView.h:1022
Interface of a AView that works with fonts (i.e., ALabel, ATextField, AText, etc.....
Definition IFontView.h:19
virtual _< IMultiStringCanvas > newMultiStringCanvas(const AFontStyle &style)=0
Creates new canvas for batching multiple prerender string calls.
void setColor(const AColor &color)
Sets the color which is multiplied with any brush. Unlike setColorForced, the new color is multiplied...
Definition IRenderer.h:432
An std::weak_ptr with AUI extensions.
Definition SharedPtrTypes.h:178
class_of c
Selects views that are of the specified classes.
Definition class_of.h:84
Render context passed to AView::render.
Definition ARenderContext.h:43