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:234
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.
void invalidateAllStyles() override
Invalidates all styles, causing to iterate over all rules in global and parent stylesheets.
void render(ARenderContext context) override
Draws this AView. Noone should call this function except rendering routine.
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:1045
glm::ivec2 getSize() const noexcept
Size, including content area, border and padding.
Definition AView.h:217
glm::ivec2 mMaxSize
Maximal size.
Definition AView.h:1040
ABoxFields mPadding
Padding, which defines the spacing around content area inside the view. Processed by AView implementa...
Definition AView.h:1059
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:179
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