Font picker works
This commit is contained in:
parent
7286f01035
commit
695393392f
11 changed files with 337 additions and 273 deletions
|
|
@ -19,6 +19,7 @@
|
|||
#include "../../../GUIStuff/ElementHelpers/ButtonHelpers.hpp"
|
||||
#include "../../../GUIStuff/ElementHelpers/NumberSliderHelpers.hpp"
|
||||
#include "../../../GUIStuff/Elements/PositionAdjustingPopupMenu.hpp"
|
||||
#include "../../../GUIStuff/Elements/FontPicker.hpp"
|
||||
|
||||
using namespace RichText;
|
||||
|
||||
|
|
@ -47,13 +48,16 @@ void TextBoxEditTool::edit_gui() {
|
|||
gui.new_id("edit tool text", [&] {
|
||||
text_label_centered(gui, "Edit Text");
|
||||
|
||||
//left_to_right_line_layout(gui, [&] {
|
||||
// text_label(gui, "Font");
|
||||
// if(gui.font_picker("font picker", &newFontName)) {
|
||||
// currentMods[TextStyleModifier::ModifierType::FONT_FAMILIES] = std::make_shared<FontFamiliesTextStyleModifier>(std::vector<SkString>{SkString{newFontName.c_str(), newFontName.size()}});
|
||||
// add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::FONT_FAMILIES]);});
|
||||
// }
|
||||
//});
|
||||
left_to_right_line_layout(gui, [&] {
|
||||
text_label(gui, "Font");
|
||||
gui.element<FontPicker>("Font picker", &newFontName, FontPickerData{
|
||||
.onFontChange = [&] {
|
||||
currentMods[TextStyleModifier::ModifierType::FONT_FAMILIES] = std::make_shared<FontFamiliesTextStyleModifier>(std::vector<SkString>{SkString{newFontName.c_str(), newFontName.size()}});
|
||||
add_undo_if_selecting_area(a, [&]() {a.textBox->set_text_style_modifier_between(a.cursor->selectionBeginPos, a.cursor->selectionEndPos, currentMods[TextStyleModifier::ModifierType::FONT_FAMILIES]);});
|
||||
commit_update_func();
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
left_to_right_line_centered_layout(gui, [&] {
|
||||
svg_icon_button(gui, "Bold button", "data/icons/RemixIcon/bold.svg", {
|
||||
|
|
@ -119,21 +123,27 @@ void TextBoxEditTool::edit_gui() {
|
|||
};
|
||||
|
||||
paragraph_operation_button("Align left button", "data/icons/RemixIcon/align-left.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kLeft, [&] {
|
||||
currentPStyle.textAlignment = skia::textlayout::TextAlign::kLeft;
|
||||
a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kLeft);
|
||||
});
|
||||
paragraph_operation_button("Align center button", "data/icons/RemixIcon/align-center.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kCenter, [&] {
|
||||
currentPStyle.textAlignment = skia::textlayout::TextAlign::kCenter;
|
||||
a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kCenter);
|
||||
});
|
||||
paragraph_operation_button("Align right button", "data/icons/RemixIcon/align-right.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kRight, [&] {
|
||||
currentPStyle.textAlignment = skia::textlayout::TextAlign::kRight;
|
||||
a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kRight);
|
||||
});
|
||||
paragraph_operation_button("Align justify button", "data/icons/RemixIcon/align-justify.svg", currentPStyle.textAlignment == skia::textlayout::TextAlign::kJustify, [&] {
|
||||
currentPStyle.textAlignment = skia::textlayout::TextAlign::kJustify;
|
||||
a.textBox->set_text_alignment_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextAlign::kJustify);
|
||||
});
|
||||
paragraph_operation_button("Text direction left button", "data/icons/RemixIcon/text-direction-l.svg", currentPStyle.textDirection == skia::textlayout::TextDirection::kLtr, [&] {
|
||||
currentPStyle.textDirection = skia::textlayout::TextDirection::kLtr;
|
||||
a.textBox->set_text_direction_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextDirection::kLtr);
|
||||
});
|
||||
paragraph_operation_button("Text direction right button", "data/icons/RemixIcon/text-direction-r.svg", currentPStyle.textDirection == skia::textlayout::TextDirection::kRtl, [&] {
|
||||
currentPStyle.textDirection = skia::textlayout::TextDirection::kRtl;
|
||||
a.textBox->set_text_direction_between(a.cursor->selectionBeginPos.fParagraphIndex, a.cursor->selectionEndPos.fParagraphIndex, skia::textlayout::TextDirection::kRtl);
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ ScrollArea* scroll_area_many_entries(GUIManager& gui, const char* id, const Scro
|
|||
.innerContent = [&](const ScrollArea::InnerContentParameters& params) {
|
||||
if(options.innerContentExtraCallback) options.innerContentExtraCallback(params);
|
||||
|
||||
float absScrollAmount = std::fabs(params.scrollOffset.y());
|
||||
float absScrollAmount = std::fabs(params.scrollOffset->y());
|
||||
size_t startPoint = absScrollAmount / options.entryHeight;
|
||||
size_t elementsContainable = (params.containerDimensions.y() / options.entryHeight) + 2; // Displaying 2 more elements ensures that there isn't any empty space in the container
|
||||
size_t endPoint = std::min(options.entryCount, startPoint + elementsContainable);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
|
||||
namespace GUIStuff { namespace ElementHelpers {
|
||||
|
||||
void input_color_component_255(GUIManager& gui, const char* id, float* val, const TextBoxOptions& options) {
|
||||
TextBox<float>* input_color_component_255(GUIManager& gui, const char* id, float* val, const TextBoxOptions& options) {
|
||||
InputManager::TextInputProperties textInputProps {
|
||||
.inputType = SDL_TextInputType::SDL_TEXTINPUT_TYPE_NUMBER,
|
||||
.capitalization = SDL_Capitalization::SDL_CAPITALIZE_NONE,
|
||||
|
|
@ -29,10 +29,10 @@ void input_color_component_255(GUIManager& gui, const char* id, float* val, cons
|
|||
return ss.str();
|
||||
};
|
||||
|
||||
gui.element<TextBox<float>>(id, d);
|
||||
return gui.element<TextBox<float>>(id, d);
|
||||
}
|
||||
|
||||
void input_text(GUIManager& gui, const char* id, std::string* val, const TextBoxOptions& options) {
|
||||
TextBox<std::string>* input_text(GUIManager& gui, const char* id, std::string* val, const TextBoxOptions& options) {
|
||||
InputManager::TextInputProperties textInputProps {
|
||||
.inputType = SDL_TextInputType::SDL_TEXTINPUT_TYPE_TEXT,
|
||||
.capitalization = SDL_Capitalization::SDL_CAPITALIZE_NONE,
|
||||
|
|
@ -51,14 +51,16 @@ void input_text(GUIManager& gui, const char* id, std::string* val, const TextBox
|
|||
return a;
|
||||
};
|
||||
|
||||
gui.element<TextBox<std::string>>(id, d);
|
||||
return gui.element<TextBox<std::string>>(id, d);
|
||||
}
|
||||
|
||||
void input_text_field(GUIManager& gui, const char* id, std::string_view name, std::string* val, const TextBoxOptions& options) {
|
||||
TextBox<std::string>* input_text_field(GUIManager& gui, const char* id, std::string_view name, std::string* val, const TextBoxOptions& options) {
|
||||
TextBox<std::string>* toRet;
|
||||
left_to_right_line_layout(gui, [&]() {
|
||||
text_label(gui, name);
|
||||
input_text(gui, id, val, options);
|
||||
toRet = input_text(gui, id, val, options);
|
||||
});
|
||||
return toRet;
|
||||
}
|
||||
|
||||
template <> void input_scalar<uint8_t>(GUIManager& gui, const char* id, uint8_t* val, uint8_t minVal, uint8_t maxVal, const TextBoxScalarOptions& options) {
|
||||
|
|
@ -91,7 +93,7 @@ template <> void input_scalar<uint8_t>(GUIManager& gui, const char* id, uint8_t*
|
|||
gui.element<TextBox<uint8_t>>(id, d);
|
||||
}
|
||||
|
||||
void input_path(GUIManager& gui, const char* id, std::filesystem::path* val, const TextBoxPathOptions& options) {
|
||||
TextBox<std::filesystem::path>* input_path(GUIManager& gui, const char* id, std::filesystem::path* val, const TextBoxPathOptions& options) {
|
||||
InputManager::TextInputProperties textInputProps {
|
||||
.inputType = SDL_TextInputType::SDL_TEXTINPUT_TYPE_TEXT,
|
||||
.capitalization = SDL_Capitalization::SDL_CAPITALIZE_NONE,
|
||||
|
|
@ -113,14 +115,16 @@ void input_path(GUIManager& gui, const char* id, std::filesystem::path* val, con
|
|||
return a.string();
|
||||
};
|
||||
|
||||
gui.element<TextBox<std::filesystem::path>>(id, d);
|
||||
return gui.element<TextBox<std::filesystem::path>>(id, d);
|
||||
}
|
||||
|
||||
void input_path_field(GUIManager& gui, const char* id, std::string_view name, std::filesystem::path* val, const TextBoxPathOptions& options) {
|
||||
TextBox<std::filesystem::path>* input_path_field(GUIManager& gui, const char* id, std::string_view name, std::filesystem::path* val, const TextBoxPathOptions& options) {
|
||||
TextBox<std::filesystem::path>* toRet;
|
||||
left_to_right_line_layout(gui, [&]() {
|
||||
text_label(gui, name);
|
||||
input_path(gui, id, val, options);
|
||||
toRet = input_path(gui, id, val, options);
|
||||
});
|
||||
return toRet;
|
||||
}
|
||||
|
||||
} }
|
||||
|
|
|
|||
|
|
@ -56,11 +56,11 @@ struct TextBoxHexColorOptions {
|
|||
std::function<void()> onDeselect;
|
||||
};
|
||||
|
||||
void input_color_component_255(GUIManager& gui, const char* id, float* val, const TextBoxOptions& options = {});
|
||||
void input_text(GUIManager& gui, const char* id, std::string* val, const TextBoxOptions& options = {});
|
||||
void input_text_field(GUIManager& gui, const char* id, std::string_view name, std::string* val, const TextBoxOptions& options = {});
|
||||
void input_path(GUIManager& gui, const char* id, std::filesystem::path* val, const TextBoxPathOptions& options = {});
|
||||
void input_path_field(GUIManager& gui, const char* id, std::string_view name, std::filesystem::path* val, const TextBoxPathOptions& options = {});
|
||||
TextBox<float>* input_color_component_255(GUIManager& gui, const char* id, float* val, const TextBoxOptions& options = {});
|
||||
TextBox<std::string>* input_text(GUIManager& gui, const char* id, std::string* val, const TextBoxOptions& options = {});
|
||||
TextBox<std::string>* input_text_field(GUIManager& gui, const char* id, std::string_view name, std::string* val, const TextBoxOptions& options = {});
|
||||
TextBox<std::filesystem::path>* input_path(GUIManager& gui, const char* id, std::filesystem::path* val, const TextBoxPathOptions& options = {});
|
||||
TextBox<std::filesystem::path>* input_path_field(GUIManager& gui, const char* id, std::string_view name, std::filesystem::path* val, const TextBoxPathOptions& options = {});
|
||||
|
||||
template <typename T> void input_scalar(GUIManager& gui, const char* id, T* val, T minVal, T maxVal, const TextBoxScalarOptions& options = {}) {
|
||||
InputManager::TextInputProperties textInputProps {
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ template <typename T> class DropDown : public Element {
|
|||
SkColor4f entryColor;
|
||||
if(selectedEntry)
|
||||
entryColor = gui.io.theme->backColor2;
|
||||
else if(hoveringOver.has_value() && hoveringOver.value() == i)
|
||||
else if(hoveringOver == i)
|
||||
entryColor = gui.io.theme->backColor2;
|
||||
else
|
||||
entryColor = gui.io.theme->backColor1;
|
||||
|
|
@ -145,15 +145,15 @@ template <typename T> class DropDown : public Element {
|
|||
auto oldHoveringOver = hoveringOver;
|
||||
if(mouseHovering)
|
||||
hoveringOver = i;
|
||||
else if(hoveringOver.has_value() && hoveringOver.value() == i)
|
||||
hoveringOver = std::nullopt;
|
||||
else if(hoveringOver == i)
|
||||
hoveringOver = std::numeric_limits<size_t>::max();
|
||||
if(oldHoveringOver != hoveringOver)
|
||||
gui.set_to_layout();
|
||||
}
|
||||
T* d;
|
||||
DropdownOptions opts;
|
||||
bool isOpen = false;
|
||||
std::optional<size_t> hoveringOver;
|
||||
size_t hoveringOver = std::numeric_limits<size_t>::max();
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "FontPicker.hpp"
|
||||
#include "Helpers/ConvertVec.hpp"
|
||||
#include <algorithm>
|
||||
#include <limits>
|
||||
#include <modules/skparagraph/include/DartTypes.h>
|
||||
#include <modules/skparagraph/include/ParagraphStyle.h>
|
||||
#include <modules/skparagraph/src/ParagraphBuilderImpl.h>
|
||||
|
|
@ -8,182 +9,222 @@
|
|||
#include <Helpers/Random.hpp>
|
||||
#include "../GUIManager.hpp"
|
||||
|
||||
#include "../ElementHelpers/ButtonHelpers.hpp"
|
||||
#include "../ElementHelpers/ScrollAreaHelpers.hpp"
|
||||
#include "../ElementHelpers/TextBoxHelpers.hpp"
|
||||
#include "TextParagraph.hpp"
|
||||
|
||||
std::vector<std::string> sortedFontList;
|
||||
std::vector<std::string> sortedFontListLowercase;
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
FontPicker::FontPicker(GUIManager& gui): Element(gui) {}
|
||||
|
||||
void FontPicker::layout(const Clay_ElementId& id, const Data& data) {
|
||||
d = data;
|
||||
//auto& io = *gui.io;
|
||||
void FontPicker::layout(const Clay_ElementId& id, std::string* newFontName, const FontPickerData& newData) {
|
||||
using namespace ElementHelpers;
|
||||
fontName = newFontName;
|
||||
data = newData;
|
||||
|
||||
//if(sortedFontList.empty()) {
|
||||
// auto icu = SkUnicodes::ICU::Make();
|
||||
// std::set<std::string> sortedFontSet;
|
||||
if(sortedFontList.empty()) {
|
||||
auto icu = SkUnicodes::ICU::Make();
|
||||
std::set<std::string> sortedFontSet;
|
||||
|
||||
// if(io.fonts->localFontMgr) {
|
||||
// for(int i = 0; i < io.fonts->localFontMgr->countFamilies(); i++) {
|
||||
// SkString familyNameSkString;
|
||||
// io.fonts->localFontMgr->getFamilyName(i, &familyNameSkString);
|
||||
// if(familyNameSkString.isEmpty())
|
||||
// continue;
|
||||
// std::string familyName(familyNameSkString.c_str(), familyNameSkString.size());
|
||||
// sortedFontSet.emplace(familyName);
|
||||
// }
|
||||
// }
|
||||
// for(int i = 0; i < io.fonts->defaultFontMgr->countFamilies(); i++) {
|
||||
// SkString familyNameSkString;
|
||||
// io.fonts->defaultFontMgr->getFamilyName(i, &familyNameSkString);
|
||||
// if(familyNameSkString.isEmpty())
|
||||
// continue;
|
||||
// std::string familyName(familyNameSkString.c_str(), familyNameSkString.size());
|
||||
// sortedFontSet.emplace(familyName);
|
||||
// }
|
||||
// sortedFontList = std::vector<std::string>(sortedFontSet.begin(), sortedFontSet.end());
|
||||
// sortedFontListLowercase = sortedFontList;
|
||||
// for(std::string& s : sortedFontListLowercase)
|
||||
// std::transform(s.begin(), s.end(), s.begin(), ::tolower);
|
||||
//}
|
||||
if(gui.io.fonts->localFontMgr) {
|
||||
for(int i = 0; i < gui.io.fonts->localFontMgr->countFamilies(); i++) {
|
||||
SkString familyNameSkString;
|
||||
gui.io.fonts->localFontMgr->getFamilyName(i, &familyNameSkString);
|
||||
if(familyNameSkString.isEmpty())
|
||||
continue;
|
||||
std::string familyName(familyNameSkString.c_str(), familyNameSkString.size());
|
||||
sortedFontSet.emplace(familyName);
|
||||
}
|
||||
}
|
||||
for(int i = 0; i < gui.io.fonts->defaultFontMgr->countFamilies(); i++) {
|
||||
SkString familyNameSkString;
|
||||
gui.io.fonts->defaultFontMgr->getFamilyName(i, &familyNameSkString);
|
||||
if(familyNameSkString.isEmpty())
|
||||
continue;
|
||||
std::string familyName(familyNameSkString.c_str(), familyNameSkString.size());
|
||||
sortedFontSet.emplace(familyName);
|
||||
}
|
||||
sortedFontList = std::vector<std::string>(sortedFontSet.begin(), sortedFontSet.end());
|
||||
sortedFontListLowercase = sortedFontList;
|
||||
for(std::string& s : sortedFontListLowercase)
|
||||
std::transform(s.begin(), s.end(), s.begin(), ::tolower);
|
||||
}
|
||||
|
||||
//bool fontChangedFromTextbox = false;
|
||||
//bool fontChangedFromSelection = false;
|
||||
auto sortedFontListValIt = std::find(sortedFontList.begin(), sortedFontList.end(), *fontName);
|
||||
size_t val = sortedFontListValIt != sortedFontList.end() ? sortedFontListValIt - sortedFontList.begin() : std::numeric_limits<size_t>::max();
|
||||
|
||||
//bool clickedOut = io.mouse.leftClick;
|
||||
const float ENTRY_HEIGHT = 25.0f;
|
||||
|
||||
//const float ENTRY_HEIGHT = 25.0f;
|
||||
CLAY(id, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIXED(250), .height = CLAY_SIZING_FIT(0)},
|
||||
.childGap = 4
|
||||
}
|
||||
}) {
|
||||
auto textboxElement = ElementHelpers::input_text(gui, "Font textbox", fontName, {
|
||||
.onEdit = [&] {
|
||||
auto newFontName = get_valid_font_name();
|
||||
if(newFontName.has_value()) {
|
||||
*fontName = newFontName.value();
|
||||
jumpToFontName = true;
|
||||
if(data.onFontChange) data.onFontChange();
|
||||
}
|
||||
gui.set_to_layout();
|
||||
},
|
||||
.onSelect = [&] {
|
||||
dropdownOpen = true;
|
||||
gui.set_to_layout();
|
||||
}
|
||||
});
|
||||
|
||||
//CLAY_AUTO_ID({
|
||||
// .layout = {
|
||||
// .sizing = {.width = CLAY_SIZING_FIXED(250), .height = CLAY_SIZING_FIT(0)},
|
||||
// .childGap = 4
|
||||
// }
|
||||
//}) {
|
||||
// fontChangedFromTextbox = gui.input_text("Font textbox", fontName, true, [&](SelectionHelper& s) {
|
||||
// if(s.selected) {
|
||||
// dropdownOpen = true;
|
||||
// clickedOut = false;
|
||||
// }
|
||||
// });
|
||||
auto dropdownButton = svg_icon_button(gui, "Open font dropdown", "data/icons/droparrowbold.svg", {
|
||||
.size = SMALL_BUTTON_SIZE,
|
||||
.onClick = [&] {
|
||||
dropdownOpen = !dropdownOpen;
|
||||
}
|
||||
});
|
||||
|
||||
// auto it = std::find(sortedFontList.begin(), sortedFontList.end(), *fontName);
|
||||
// size_t val = std::numeric_limits<size_t>::max();
|
||||
// if(it == sortedFontList.end()) {
|
||||
// std::string lowerFamilyName = *fontName;
|
||||
// std::transform(lowerFamilyName.begin(), lowerFamilyName.end(), lowerFamilyName.begin(), ::tolower);
|
||||
// auto itLower = std::find(sortedFontListLowercase.begin(), sortedFontListLowercase.end(), lowerFamilyName);
|
||||
// if(itLower != sortedFontListLowercase.end()) {
|
||||
// val = itLower - sortedFontListLowercase.begin();
|
||||
// *fontName = sortedFontList[val];
|
||||
// }
|
||||
// }
|
||||
// else
|
||||
// val = it - sortedFontList.begin();
|
||||
if(dropdownOpen) {
|
||||
gui.set_z_index(gui.get_z_index() + 1, [&] {
|
||||
gui.element<LayoutElement>("Font picker floating element", [&] (LayoutElement*, const Clay_ElementId& lId) {
|
||||
CLAY(lId, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIXED(250), .height = CLAY_SIZING_FIT(0, 300)},
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(gui.io.theme->backColor1),
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(4),
|
||||
.floating = {
|
||||
.offset = {
|
||||
.y = 2
|
||||
},
|
||||
.zIndex = gui.get_z_index(),
|
||||
.attachPoints = {
|
||||
.element = CLAY_ATTACH_POINT_LEFT_TOP,
|
||||
.parent = CLAY_ATTACH_POINT_LEFT_BOTTOM
|
||||
},
|
||||
.attachTo = CLAY_ATTACH_TO_PARENT
|
||||
},
|
||||
.border = {
|
||||
.color = convert_vec4<Clay_Color>(gui.io.theme->fillColor2),
|
||||
.width = CLAY_BORDER_OUTSIDE(1)
|
||||
}
|
||||
}) {
|
||||
scroll_area_many_entries(gui, "Font Selector", {
|
||||
.entryHeight = ENTRY_HEIGHT,
|
||||
.entryCount = sortedFontList.size(),
|
||||
.clipHorizontal = true,
|
||||
.elementContent = [&] (size_t i) {
|
||||
bool selectedEntry = val == i;
|
||||
gui.element<LayoutElement>("elem", [&](LayoutElement*, const Clay_ElementId& lId2) {
|
||||
CLAY(lId2, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIXED(250), .height = CLAY_SIZING_FIXED(25)},
|
||||
.childGap = 1,
|
||||
.childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_TOP},
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
}
|
||||
}) {
|
||||
SkColor4f entryColor;
|
||||
if(selectedEntry)
|
||||
entryColor = gui.io.theme->backColor2;
|
||||
else if(hoveringOver == i)
|
||||
entryColor = gui.io.theme->backColor2;
|
||||
else
|
||||
entryColor = gui.io.theme->backColor1;
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(25)},
|
||||
.padding = {.left = 2, .right = 2},
|
||||
.childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER}
|
||||
},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(entryColor)
|
||||
}) {
|
||||
skia::textlayout::ParagraphStyle pStyle;
|
||||
pStyle.setTextAlign(skia::textlayout::TextAlign::kLeft);
|
||||
pStyle.setTextHeightBehavior(skia::textlayout::kDisableAll);
|
||||
|
||||
skia::textlayout::StrutStyle strutStyle;
|
||||
strutStyle.setStrutEnabled(true);
|
||||
strutStyle.setForceStrutHeight(true);
|
||||
pStyle.setStrutStyle(strutStyle);
|
||||
|
||||
skia::textlayout::TextStyle tStyle;
|
||||
tStyle.setFontSize(gui.io.fontSize);
|
||||
tStyle.setFontFamilies({SkString{sortedFontList[i].c_str()}, SkString{"Roboto"}});
|
||||
tStyle.setForegroundColor(SkPaint{gui.io.theme->frontColor1});
|
||||
pStyle.setTextStyle(tStyle);
|
||||
|
||||
skia::textlayout::ParagraphBuilderImpl pBuilder(pStyle, gui.io.fonts->collection, SkUnicodes::ICU::Make());
|
||||
tStyle.setFontStyle(SkFontStyle::Normal());
|
||||
|
||||
pBuilder.pushStyle(tStyle);
|
||||
pBuilder.addText(sortedFontList[i].c_str(), sortedFontList[i].size());
|
||||
|
||||
std::shared_ptr<skia::textlayout::Paragraph> p = pBuilder.Build();
|
||||
|
||||
// if(gui.svg_icon_button("Open font dropdown", "data/icons/droparrowbold.svg", dropdownOpen, GUIManager::SMALL_BUTTON_SIZE)) {
|
||||
// dropdownOpen = !dropdownOpen;
|
||||
// clickedOut = false;
|
||||
// }
|
||||
// if(dropdownOpen) {
|
||||
// Clay_ElementId localID = CLAY_ID_LOCAL("Font picker floating element");
|
||||
// CLAY(localID, {
|
||||
// .layout = {
|
||||
// .sizing = {.width = CLAY_SIZING_FIXED(250), .height = CLAY_SIZING_FIT(0, 300)},
|
||||
// .layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
// },
|
||||
// .backgroundColor = convert_vec4<Clay_Color>(io.theme->backColor1),
|
||||
// .cornerRadius = CLAY_CORNER_RADIUS(4),
|
||||
// .floating = {
|
||||
// .offset = {
|
||||
// .y = 2
|
||||
// },
|
||||
// .attachPoints = {
|
||||
// .element = CLAY_ATTACH_POINT_LEFT_TOP,
|
||||
// .parent = CLAY_ATTACH_POINT_LEFT_BOTTOM
|
||||
// },
|
||||
// .attachTo = CLAY_ATTACH_TO_PARENT
|
||||
// },
|
||||
// .border = {
|
||||
// .color = convert_vec4<Clay_Color>(io.theme->fillColor2),
|
||||
// .width = CLAY_BORDER_OUTSIDE(1)
|
||||
// }
|
||||
// }) {
|
||||
// gui->obstructing_window(localID);
|
||||
// if(Clay_Hovered())
|
||||
// clickedOut = false;
|
||||
// gui->scroll_bar_many_entries_area("Font Selector", ENTRY_HEIGHT, sortedFontList.size(), true, [fontName, gui, &fontChangedFromSelection, &sortedFontList = sortedFontList, val, &io = io](size_t i, bool listHovered) {
|
||||
// bool selectedEntry = val == i;
|
||||
//
|
||||
// skia::textlayout::ParagraphStyle pStyle;
|
||||
// pStyle.setTextAlign(skia::textlayout::TextAlign::kLeft);
|
||||
// pStyle.setTextHeightBehavior(skia::textlayout::kDisableAll);
|
||||
//
|
||||
// skia::textlayout::StrutStyle strutStyle;
|
||||
// strutStyle.setStrutEnabled(true);
|
||||
// strutStyle.setForceStrutHeight(true);
|
||||
// pStyle.setStrutStyle(strutStyle);
|
||||
//
|
||||
// skia::textlayout::TextStyle tStyle;
|
||||
// tStyle.setFontSize(io.fontSize);
|
||||
// tStyle.setFontFamilies({SkString{sortedFontList[i].c_str()}, SkString{"Roboto"}});
|
||||
// tStyle.setForegroundColor(SkPaint{io.theme->frontColor1});
|
||||
// pStyle.setTextStyle(tStyle);
|
||||
//
|
||||
// skia::textlayout::ParagraphBuilderImpl pBuilder(pStyle, io.fonts->collection, SkUnicodes::ICU::Make());
|
||||
// tStyle.setFontStyle(SkFontStyle::Normal());
|
||||
//
|
||||
// pBuilder.pushStyle(tStyle);
|
||||
// pBuilder.addText(sortedFontList[i].c_str(), sortedFontList[i].size());
|
||||
//
|
||||
// auto p = pBuilder.Build();
|
||||
//
|
||||
// CLAY_AUTO_ID({
|
||||
// .layout = {
|
||||
// .sizing = {.width = CLAY_SIZING_FIXED(250), .height = CLAY_SIZING_FIXED(25)},
|
||||
// .childGap = 1,
|
||||
// .childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_TOP},
|
||||
// .layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
// }
|
||||
// }) {
|
||||
// SkColor4f entryColor;
|
||||
// if(selectedEntry)
|
||||
// entryColor = io.theme->backColor2;
|
||||
// else if(Clay_Hovered())
|
||||
// entryColor = io.theme->backColor2;
|
||||
// else
|
||||
// entryColor = io.theme->backColor1;
|
||||
// CLAY_AUTO_ID({
|
||||
// .layout = {
|
||||
// .sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(25)},
|
||||
// .padding = {.left = 2, .right = 2},
|
||||
// .childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_CENTER}
|
||||
// },
|
||||
// .backgroundColor = convert_vec4<Clay_Color>(entryColor)
|
||||
// }) {
|
||||
// gui->text_paragraph("font name", std::move(p), 10000.0f); // Setting width to numeric_limits::max will lead to multiplying it by any number greater than 1 to = infinity, which will cause issues
|
||||
//
|
||||
// if(io.mouse.leftClick && Clay_Hovered()) {
|
||||
// *fontName = sortedFontList[i];
|
||||
// fontChangedFromSelection = true;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }, [ENTRY_HEIGHT, fontChangedFromTextbox, io = &io, val](float scrollContentHeight, float containerHeight, float& scrollAmount) {
|
||||
// if(fontChangedFromTextbox && !io->mouse.leftClick && val != std::numeric_limits<size_t>::max())
|
||||
// scrollAmount = -static_cast<float>(val) * ENTRY_HEIGHT;
|
||||
// });
|
||||
// #ifdef __EMSCRIPTEN__
|
||||
// CLAY_AUTO_ID({
|
||||
// .layout = {
|
||||
// .padding = CLAY_PADDING_ALL(io.theme->padding1)
|
||||
// }}) {
|
||||
// gui->text_label_light_centered("Local fonts not usable in web version");
|
||||
// }
|
||||
// #endif
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
gui.element<TextParagraph>("font name", p, 10000.0f); // Setting width to numeric_limits::max will lead to multiplying it by any number greater than 1 to = infinity, which will cause issues
|
||||
}
|
||||
}
|
||||
}, LayoutElement::Callbacks{
|
||||
.mouseButton = [&, i](LayoutElement* l, const InputManager::MouseButtonCallbackArgs& button) {
|
||||
if(l->mouseHovering && button.down && button.button == InputManager::MouseButton::LEFT) {
|
||||
*fontName = sortedFontList[i];
|
||||
gui.set_post_callback_func([&] { if(data.onFontChange) data.onFontChange(); });
|
||||
gui.set_to_layout();
|
||||
}
|
||||
},
|
||||
.mouseMotion = [&, i](LayoutElement* l, const InputManager::MouseMotionCallbackArgs& motion) {
|
||||
size_t oldHovering = hoveringOver;
|
||||
if(l->mouseHovering)
|
||||
hoveringOver = i;
|
||||
else if(hoveringOver == i)
|
||||
hoveringOver = std::numeric_limits<size_t>::max();
|
||||
if(oldHovering != hoveringOver)
|
||||
gui.set_to_layout();
|
||||
}
|
||||
});
|
||||
},
|
||||
.innerContentExtraCallback = [&](const ScrollArea::InnerContentParameters& innerContentParams) {
|
||||
if(jumpToFontName) {
|
||||
if(val != std::numeric_limits<size_t>::max())
|
||||
innerContentParams.scrollOffset->y() = -static_cast<float>(val) * ENTRY_HEIGHT;
|
||||
jumpToFontName = false;
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}, LayoutElement::Callbacks{
|
||||
.mouseButton = [&, textboxElement, dropdownButton] (LayoutElement* l, const InputManager::MouseButtonCallbackArgs& button) {
|
||||
if(!textboxElement->mouseHovering && !dropdownButton->mouseHovering && !l->mouseHovering && !l->childMouseHovering) {
|
||||
dropdownOpen = false;
|
||||
gui.set_to_layout();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//if(clickedOut)
|
||||
// dropdownOpen = false;
|
||||
std::optional<std::string> FontPicker::get_valid_font_name() {
|
||||
auto it = std::find(sortedFontList.begin(), sortedFontList.end(), *fontName);
|
||||
if(it != sortedFontList.end())
|
||||
return *fontName;
|
||||
else {
|
||||
std::string lowerFamilyName = *fontName;
|
||||
std::transform(lowerFamilyName.begin(), lowerFamilyName.end(), lowerFamilyName.begin(), ::tolower);
|
||||
auto itLower = std::find(sortedFontListLowercase.begin(), sortedFontListLowercase.end(), lowerFamilyName);
|
||||
if(itLower != sortedFontListLowercase.end()) {
|
||||
size_t val = itLower - sortedFontListLowercase.begin();
|
||||
return sortedFontList[val];
|
||||
}
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,21 +1,27 @@
|
|||
#pragma once
|
||||
#include "Element.hpp"
|
||||
#include <limits>
|
||||
|
||||
namespace GUIStuff {
|
||||
|
||||
struct FontPickerData {
|
||||
std::function<void()> onFontChange;
|
||||
};
|
||||
|
||||
class FontPicker : public Element {
|
||||
public:
|
||||
struct Data {
|
||||
std::string* fontName = nullptr;
|
||||
std::function<void()> onFontChange;
|
||||
};
|
||||
FontPicker(GUIManager& gui);
|
||||
void layout(const Clay_ElementId& id, const Data& data);
|
||||
void layout(const Clay_ElementId& id, std::string* newFontName, const FontPickerData& newData = {});
|
||||
private:
|
||||
Data d;
|
||||
std::string* fontName;
|
||||
FontPickerData data;
|
||||
|
||||
size_t hoveringOver = std::numeric_limits<size_t>::max();
|
||||
|
||||
bool jumpToFontName = false;
|
||||
|
||||
std::optional<std::string> get_valid_font_name();
|
||||
|
||||
std::vector<std::string> sortedFontList;
|
||||
std::vector<std::string> sortedFontListLowercase;
|
||||
bool dropdownOpen = false;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,8 @@ void ScrollArea::layout(const Clay_ElementId& id, const Options& options) {
|
|||
},
|
||||
.clip = {.horizontal = opts.clipHorizontal, .vertical = opts.clipVertical, .childOffset = {.x = scrollOffset.x(), .y = scrollOffset.y()}}
|
||||
}) {
|
||||
opts.innerContent({.contentDimensions = contentDimensions, .containerDimensions = containerDimensions, .scrollOffset = scrollOffset});
|
||||
opts.innerContent({.contentDimensions = contentDimensions, .containerDimensions = containerDimensions, .scrollOffset = &scrollOffset});
|
||||
clamp_scroll();
|
||||
}
|
||||
|
||||
if(scrollData.contentDimensions.height > scrollData.scrollContainerDimensions.height) {
|
||||
|
|
@ -48,88 +49,90 @@ void ScrollArea::layout(const Clay_ElementId& id, const Options& options) {
|
|||
float scrollerPos = std::fabs(scrollOffset.y() / scrollPosMax);
|
||||
float areaAboveScrollerSize = scrollerPos * (sAreaDim - scrollerSize);
|
||||
|
||||
gui.element<LayoutElement>("scroll bar", [&] (LayoutElement*, const Clay_ElementId& lId) {
|
||||
CLAY(lId, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_FIXED(12), .height = CLAY_SIZING_GROW(0)},
|
||||
.childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_TOP},
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(gui.io.theme->backColor2)
|
||||
}) {
|
||||
SkColor4f scrollerColor;
|
||||
if(isScrollbarHeldY)
|
||||
scrollerColor = gui.io.theme->fillColor1;
|
||||
else if(isScrollbarHoveredY)
|
||||
scrollerColor = gui.io.theme->fillColor1;
|
||||
else
|
||||
scrollerColor = gui.io.theme->fillColor2;
|
||||
|
||||
CLAY_AUTO_ID({
|
||||
gui.set_z_index(gui.get_z_index() + 1, [&] {
|
||||
gui.element<LayoutElement>("scroll bar", [&] (LayoutElement*, const Clay_ElementId& lId) {
|
||||
CLAY(lId, {
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(areaAboveScrollerSize)}
|
||||
}
|
||||
}) {}
|
||||
.sizing = {.width = CLAY_SIZING_FIXED(12), .height = CLAY_SIZING_GROW(0)},
|
||||
.childAlignment = {.x = CLAY_ALIGN_X_LEFT, .y = CLAY_ALIGN_Y_TOP},
|
||||
.layoutDirection = CLAY_TOP_TO_BOTTOM
|
||||
},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(gui.io.theme->backColor2)
|
||||
}) {
|
||||
SkColor4f scrollerColor;
|
||||
if(isScrollbarHeldY)
|
||||
scrollerColor = gui.io.theme->fillColor1;
|
||||
else if(isScrollbarHoveredY)
|
||||
scrollerColor = gui.io.theme->fillColor1;
|
||||
else
|
||||
scrollerColor = gui.io.theme->fillColor2;
|
||||
|
||||
gui.element<LayoutElement>("scroller", [&] (LayoutElement*, const Clay_ElementId& lId2) {
|
||||
CLAY(lId2, {
|
||||
.layout = {.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(scrollerSize)}},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(scrollerColor),
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(3),
|
||||
CLAY_AUTO_ID({
|
||||
.layout = {
|
||||
.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(areaAboveScrollerSize)}
|
||||
}
|
||||
}) {}
|
||||
}, LayoutElement::Callbacks{
|
||||
.mouseMotion = [&] (LayoutElement* t, const InputManager::MouseMotionCallbackArgs& motion) {
|
||||
if(isHoveringOverScrollerY != t->mouseHovering) {
|
||||
isHoveringOverScrollerY = t->mouseHovering;
|
||||
|
||||
gui.element<LayoutElement>("scroller", [&] (LayoutElement*, const Clay_ElementId& lId2) {
|
||||
CLAY(lId2, {
|
||||
.layout = {.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_FIXED(scrollerSize)}},
|
||||
.backgroundColor = convert_vec4<Clay_Color>(scrollerColor),
|
||||
.cornerRadius = CLAY_CORNER_RADIUS(3),
|
||||
}) {}
|
||||
}, LayoutElement::Callbacks{
|
||||
.mouseMotion = [&] (LayoutElement* t, const InputManager::MouseMotionCallbackArgs& motion) {
|
||||
if(isHoveringOverScrollerY != t->mouseHovering) {
|
||||
isHoveringOverScrollerY = t->mouseHovering;
|
||||
gui.set_to_layout();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
CLAY_AUTO_ID({ .layout = {.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}}}) {}
|
||||
}
|
||||
}, LayoutElement::Callbacks{
|
||||
.mouseButton = [&, scrollPosMax, sAreaStart, sAreaDim, scrollerSize, areaAboveScrollerSize](LayoutElement* t, const InputManager::MouseButtonCallbackArgs& button) {
|
||||
if(button.button == InputManager::MouseButton::LEFT) {
|
||||
if(button.down && t->mouseHovering) {
|
||||
isScrollbarHeldY = true;
|
||||
if(isHoveringOverScrollerY)
|
||||
scrollerStartPosY = sAreaStart + areaAboveScrollerSize + scrollerSize * 0.5f;
|
||||
else
|
||||
scrollerStartPosY = std::clamp(button.pos.y(), sAreaStart + scrollerSize * 0.5f, sAreaStart + sAreaDim - scrollerSize * 0.5f);
|
||||
mouseStartPosY = button.pos.y();
|
||||
|
||||
float newScrollPosFrac;
|
||||
newScrollPosFrac = std::clamp((scrollerStartPosY - (mouseStartPosY - button.pos.y()) - sAreaStart - scrollerSize * 0.5f) / (sAreaDim - scrollerSize), 0.0f, 1.0f);
|
||||
scrollOffset.y() = newScrollPosFrac * (-scrollPosMax);
|
||||
|
||||
clamp_scroll();
|
||||
gui.set_to_layout();
|
||||
}
|
||||
else if(isScrollbarHeldY) {
|
||||
isScrollbarHeldY = false;
|
||||
gui.set_to_layout();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
CLAY_AUTO_ID({ .layout = {.sizing = {.width = CLAY_SIZING_GROW(0), .height = CLAY_SIZING_GROW(0)}}}) {}
|
||||
}
|
||||
}, LayoutElement::Callbacks{
|
||||
.mouseButton = [&, scrollPosMax, sAreaStart, sAreaDim, scrollerSize, areaAboveScrollerSize](LayoutElement* t, const InputManager::MouseButtonCallbackArgs& button) {
|
||||
if(button.button == InputManager::MouseButton::LEFT) {
|
||||
if(button.down && t->mouseHovering) {
|
||||
isScrollbarHeldY = true;
|
||||
if(isHoveringOverScrollerY)
|
||||
scrollerStartPosY = sAreaStart + areaAboveScrollerSize + scrollerSize * 0.5f;
|
||||
else
|
||||
scrollerStartPosY = std::clamp(button.pos.y(), sAreaStart + scrollerSize * 0.5f, sAreaStart + sAreaDim - scrollerSize * 0.5f);
|
||||
mouseStartPosY = button.pos.y();
|
||||
},
|
||||
.mouseMotion = [&, scrollPosMax, sAreaStart, sAreaDim, scrollerSize](LayoutElement* t, const InputManager::MouseMotionCallbackArgs& motion) {
|
||||
if(isScrollbarHoveredY != t->mouseHovering) {
|
||||
isScrollbarHoveredY = t->mouseHovering;
|
||||
gui.set_to_layout();
|
||||
}
|
||||
if(isScrollbarHeldY) {
|
||||
float oldScrollOffset = scrollOffset.y();
|
||||
|
||||
float newScrollPosFrac;
|
||||
newScrollPosFrac = std::clamp((scrollerStartPosY - (mouseStartPosY - button.pos.y()) - sAreaStart - scrollerSize * 0.5f) / (sAreaDim - scrollerSize), 0.0f, 1.0f);
|
||||
newScrollPosFrac = std::clamp((scrollerStartPosY - (mouseStartPosY - motion.pos.y()) - sAreaStart - scrollerSize * 0.5f) / (sAreaDim - scrollerSize), 0.0f, 1.0f);
|
||||
scrollOffset.y() = newScrollPosFrac * (-scrollPosMax);
|
||||
|
||||
clamp_scroll();
|
||||
gui.set_to_layout();
|
||||
}
|
||||
else if(isScrollbarHeldY) {
|
||||
isScrollbarHeldY = false;
|
||||
gui.set_to_layout();
|
||||
|
||||
if(oldScrollOffset != scrollOffset.y())
|
||||
gui.set_to_layout();
|
||||
}
|
||||
}
|
||||
},
|
||||
.mouseMotion = [&, scrollPosMax, sAreaStart, sAreaDim, scrollerSize](LayoutElement* t, const InputManager::MouseMotionCallbackArgs& motion) {
|
||||
if(isScrollbarHoveredY != t->mouseHovering) {
|
||||
isScrollbarHoveredY = t->mouseHovering;
|
||||
gui.set_to_layout();
|
||||
}
|
||||
if(isScrollbarHeldY) {
|
||||
float oldScrollOffset = scrollOffset.y();
|
||||
|
||||
float newScrollPosFrac;
|
||||
newScrollPosFrac = std::clamp((scrollerStartPosY - (mouseStartPosY - motion.pos.y()) - sAreaStart - scrollerSize * 0.5f) / (sAreaDim - scrollerSize), 0.0f, 1.0f);
|
||||
scrollOffset.y() = newScrollPosFrac * (-scrollPosMax);
|
||||
|
||||
clamp_scroll();
|
||||
|
||||
if(oldScrollOffset != scrollOffset.y())
|
||||
gui.set_to_layout();
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ class ScrollArea : public Element {
|
|||
struct InnerContentParameters {
|
||||
Vector2f contentDimensions;
|
||||
Vector2f containerDimensions;
|
||||
Vector2f scrollOffset;
|
||||
Vector2f* scrollOffset;
|
||||
};
|
||||
|
||||
struct Options {
|
||||
|
|
|
|||
|
|
@ -7,8 +7,8 @@ namespace GUIStuff {
|
|||
TextParagraph::TextParagraph(GUIManager& gui):
|
||||
Element(gui) {}
|
||||
|
||||
void TextParagraph::layout(const Clay_ElementId& id, std::unique_ptr<skia::textlayout::Paragraph> paragraph, float width) {
|
||||
data = std::move(paragraph);
|
||||
void TextParagraph::layout(const Clay_ElementId& id, const std::shared_ptr<skia::textlayout::Paragraph>& paragraph, float width) {
|
||||
data = paragraph;
|
||||
data->layout(width);
|
||||
CLAY(id, {
|
||||
.layout = {
|
||||
|
|
|
|||
|
|
@ -7,10 +7,10 @@ namespace GUIStuff {
|
|||
class TextParagraph : public Element {
|
||||
public:
|
||||
TextParagraph(GUIManager& gui);
|
||||
void layout(const Clay_ElementId& id, std::unique_ptr<skia::textlayout::Paragraph> paragraph, float width);
|
||||
void layout(const Clay_ElementId& id, const std::shared_ptr<skia::textlayout::Paragraph>& paragraph, float width);
|
||||
virtual void clay_draw(SkCanvas* canvas, UpdateInputData& io, Clay_RenderCommand* command, bool skiaAA) override;
|
||||
private:
|
||||
std::unique_ptr<skia::textlayout::Paragraph> data;
|
||||
std::shared_ptr<skia::textlayout::Paragraph> data;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue