mirror of https://github.com/AxioDL/metaforce.git
Merge branch 'master' of ssh://git.axiodl.com:6431/AxioDL/specter
This commit is contained in:
commit
2a367df869
|
@ -63,6 +63,25 @@ add_library(specter
|
|||
include/specter/specter.hpp
|
||||
)
|
||||
|
||||
if (MSVC)
|
||||
target_compile_options(specter PRIVATE
|
||||
# Enforce various standards compliant behavior.
|
||||
/permissive-
|
||||
|
||||
# Enable standard volatile semantics.
|
||||
/volatile:iso
|
||||
|
||||
# Reports the proper value for the __cplusplus preprocessor macro.
|
||||
/Zc:__cplusplus
|
||||
|
||||
# Allow constexpr variables to have explicit external linkage.
|
||||
/Zc:externConstexpr
|
||||
|
||||
# Assume that new throws exceptions, allowing better code generation.
|
||||
/Zc:throwingNew
|
||||
)
|
||||
endif()
|
||||
|
||||
target_link_libraries(specter PUBLIC
|
||||
freetype
|
||||
hecl-full
|
||||
|
|
|
@ -226,8 +226,7 @@ private:
|
|||
|
||||
public:
|
||||
FileBrowser(ViewResources& res, View& parentView, std::string_view title, Type type,
|
||||
std::function<void(bool, hecl::SystemStringView)> returnFunc)
|
||||
: FileBrowser(res, parentView, title, type, hecl::GetcwdStr(), returnFunc) {}
|
||||
std::function<void(bool, hecl::SystemStringView)> returnFunc);
|
||||
FileBrowser(ViewResources& res, View& parentView, std::string_view title, Type type,
|
||||
hecl::SystemStringView initialPath, std::function<void(bool, hecl::SystemStringView)> returnFunc);
|
||||
~FileBrowser() override;
|
||||
|
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
#include <functional>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
@ -66,7 +65,7 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
using FCharFilter = std::pair<std::string, std::function<bool(uint32_t)>>;
|
||||
using FCharFilter = std::pair<std::string_view, bool (*)(uint32_t)>;
|
||||
|
||||
class FontAtlas {
|
||||
FT_Face m_face;
|
||||
|
@ -99,13 +98,13 @@ private:
|
|||
std::vector<Glyph> m_glyphs;
|
||||
std::unordered_map<atUint16, std::vector<std::pair<atUint16, atInt16>>> m_kernAdjs;
|
||||
|
||||
struct TT_KernHead : athena::io::DNA<athena::Big> {
|
||||
struct TT_KernHead : athena::io::DNA<athena::Endian::Big> {
|
||||
AT_DECL_DNA
|
||||
Value<atUint32> length;
|
||||
Value<atUint16> coverage;
|
||||
};
|
||||
|
||||
struct TT_KernSubHead : athena::io::DNA<athena::Big> {
|
||||
struct TT_KernSubHead : athena::io::DNA<athena::Endian::Big> {
|
||||
AT_DECL_DNA
|
||||
Value<atUint16> nPairs;
|
||||
Value<atUint16> searchRange;
|
||||
|
@ -113,7 +112,7 @@ private:
|
|||
Value<atUint16> rangeShift;
|
||||
};
|
||||
|
||||
struct TT_KernPair : athena::io::DNA<athena::Big> {
|
||||
struct TT_KernPair : athena::io::DNA<athena::Endian::Big> {
|
||||
AT_DECL_DNA
|
||||
Value<atUint16> left;
|
||||
Value<atUint16> right;
|
||||
|
@ -176,6 +175,8 @@ class FontCache {
|
|||
|
||||
public:
|
||||
FontCache(const hecl::Runtime::FileStoreManager& fileMgr);
|
||||
~FontCache();
|
||||
|
||||
FontCache(const FontCache& other) = delete;
|
||||
FontCache& operator=(const FontCache& other) = delete;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
#include <array>
|
||||
#include <cstddef>
|
||||
|
||||
#include "specter/View.hpp"
|
||||
|
@ -15,9 +16,9 @@ class ViewResources;
|
|||
|
||||
struct Icon {
|
||||
boo::ObjToken<boo::ITexture> m_tex;
|
||||
zeus::CVector2f m_uvCoords[4];
|
||||
std::array<zeus::CVector2f, 4> m_uvCoords;
|
||||
Icon() = default;
|
||||
Icon(const boo::ObjToken<boo::ITexture>& tex, float rect[4]) : m_tex(tex) {
|
||||
Icon(boo::ObjToken<boo::ITexture> tex, const std::array<float, 4>& rect) : m_tex(std::move(tex)) {
|
||||
m_uvCoords[0][0] = rect[0];
|
||||
m_uvCoords[0][1] = -rect[3];
|
||||
|
||||
|
@ -35,19 +36,23 @@ struct Icon {
|
|||
template <size_t COLS, size_t ROWS>
|
||||
class IconAtlas {
|
||||
boo::ObjToken<boo::ITextureS> m_tex;
|
||||
Icon m_icons[COLS][ROWS];
|
||||
std::array<std::array<Icon, ROWS>, COLS> m_icons;
|
||||
|
||||
Icon MakeIcon(float x, float y) {
|
||||
float rect[] = {x / float(COLS), y / float(ROWS), x / float(COLS) + 1.f / float(COLS),
|
||||
y / float(ROWS) + 1.f / float(ROWS)};
|
||||
Icon MakeIcon(float x, float y) const {
|
||||
const std::array<float, 4> rect{
|
||||
x / float(COLS),
|
||||
y / float(ROWS),
|
||||
x / float(COLS) + 1.f / float(COLS),
|
||||
y / float(ROWS) + 1.f / float(ROWS),
|
||||
};
|
||||
return Icon(m_tex.get(), rect);
|
||||
}
|
||||
|
||||
public:
|
||||
IconAtlas() = default;
|
||||
operator bool() const { return m_tex.operator bool(); }
|
||||
void initializeAtlas(const boo::ObjToken<boo::ITextureS>& tex) {
|
||||
m_tex = tex;
|
||||
void initializeAtlas(boo::ObjToken<boo::ITextureS> tex) {
|
||||
m_tex = std::move(tex);
|
||||
for (size_t c = 0; c < COLS; ++c)
|
||||
for (size_t r = 0; r < ROWS; ++r)
|
||||
m_icons[c][r] = MakeIcon(c, r);
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include "specter/View.hpp"
|
||||
|
||||
#include <boo/BooObject.hpp>
|
||||
#include <boo/DeferredWindowEvents.hpp>
|
||||
#include <boo/IWindow.hpp>
|
||||
#include <boo/graphicsdev/IGraphicsDataFactory.hpp>
|
||||
#include <hecl/UniformBufferPool.hpp>
|
||||
|
|
|
@ -1,7 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include <algorithm>
|
||||
#include <iterator>
|
||||
#include <optional>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#include <boo/BooObject.hpp>
|
||||
|
@ -111,20 +113,19 @@ public:
|
|||
|
||||
void load(const VertStruct* data, size_t count) {
|
||||
if (m_vertsBuf) {
|
||||
VertStruct* out = m_vertsBuf.access();
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
out[i] = data[i];
|
||||
VertStruct* const out = m_vertsBuf.access();
|
||||
std::copy(data, data + count, out);
|
||||
}
|
||||
}
|
||||
template <typename VertArray>
|
||||
void load(const VertArray data) {
|
||||
static_assert(std::is_same<std::remove_all_extents_t<VertArray>, VertStruct>::value, "mismatched type");
|
||||
if (m_vertsBuf) {
|
||||
constexpr size_t count = sizeof(VertArray) / sizeof(VertStruct);
|
||||
VertStruct* out = m_vertsBuf.access();
|
||||
for (size_t i = 0; i < count; ++i)
|
||||
out[i] = data[i];
|
||||
}
|
||||
template <typename ContiguousContainer>
|
||||
void load(const ContiguousContainer& container) {
|
||||
// All contiguous containers (even those that aren't containers like C arrays) are usable
|
||||
// with std::begin(). Because of that, we can use it to deduce the contained type.
|
||||
static_assert(std::is_same_v<std::remove_reference_t<decltype(*std::begin(std::declval<ContiguousContainer&>()))>,
|
||||
VertStruct>,
|
||||
"Supplied container doesn't contain same type of vertex struct");
|
||||
|
||||
load(std::data(container), std::size(container));
|
||||
}
|
||||
|
||||
operator const boo::ObjToken<boo::IShaderDataBinding>&() { return m_shaderBinding; }
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#include "specter/TextView.hpp"
|
||||
#include "specter/ViewResources.hpp"
|
||||
|
||||
#include <boo/graphicsdev/IGraphicsCommandQueue.hpp>
|
||||
#include <logvisor/logvisor.hpp>
|
||||
|
||||
namespace specter {
|
||||
|
@ -67,8 +68,8 @@ Button::Button(ViewResources& res, View& parentView, IButtonBinding* controlBind
|
|||
return true;
|
||||
});
|
||||
|
||||
m_buttonTarget.m_view.reset(new ButtonTarget(res, *this));
|
||||
m_menuTarget.m_view.reset(new MenuTarget(res, *this));
|
||||
m_buttonTarget.m_view = std::make_unique<ButtonTarget>(res, *this);
|
||||
m_menuTarget.m_view = std::make_unique<MenuTarget>(res, *this);
|
||||
|
||||
if (style == Style::Block) {
|
||||
zeus::CColor c1 = res.themeData().button1Inactive() * bgColor;
|
||||
|
@ -96,13 +97,15 @@ Button::Button(ViewResources& res, View& parentView, IButtonBinding* controlBind
|
|||
m_verts[i].m_color = m_textColor;
|
||||
_loadVerts();
|
||||
|
||||
if (controlBinding)
|
||||
if (controlBinding != nullptr) {
|
||||
m_menuStyle = controlBinding->menuStyle(this);
|
||||
}
|
||||
|
||||
if (icon)
|
||||
m_icon.reset(new IconView(res, *this, *icon));
|
||||
if (icon != nullptr) {
|
||||
m_icon = std::make_unique<IconView>(res, *this, *icon);
|
||||
}
|
||||
|
||||
m_text.reset(new TextView(res, *this, res.m_mainFont, TextView::Alignment::Center));
|
||||
m_text = std::make_unique<TextView>(res, *this, res.m_mainFont, TextView::Alignment::Center);
|
||||
setText(m_textStr);
|
||||
}
|
||||
|
||||
|
@ -226,10 +229,12 @@ void Button::setText(std::string_view text, const zeus::CColor& textColor) {
|
|||
}
|
||||
|
||||
void Button::setIcon(Icon* icon) {
|
||||
if (icon)
|
||||
m_icon.reset(new IconView(rootView().viewRes(), *this, *icon));
|
||||
else
|
||||
if (icon != nullptr) {
|
||||
m_icon = std::make_unique<IconView>(rootView().viewRes(), *this, *icon);
|
||||
} else {
|
||||
m_icon.reset();
|
||||
}
|
||||
|
||||
setText(m_textStr);
|
||||
updateSize();
|
||||
}
|
||||
|
|
|
@ -7,11 +7,8 @@
|
|||
#include "specter/TextField.hpp"
|
||||
|
||||
#include <hecl/hecl.hpp>
|
||||
#include <logvisor/logvisor.hpp>
|
||||
|
||||
namespace specter {
|
||||
static logvisor::Module Log("specter::FileBrowser");
|
||||
|
||||
#define BROWSER_MARGIN 8
|
||||
#define BROWSER_MIN_WIDTH 600
|
||||
#define BROWSER_MIN_HEIGHT 300
|
||||
|
@ -43,6 +40,10 @@ std::vector<hecl::SystemString> FileBrowser::PathComponents(hecl::SystemStringVi
|
|||
return ret;
|
||||
}
|
||||
|
||||
FileBrowser::FileBrowser(ViewResources& res, View& parentView, std::string_view title, Type type,
|
||||
std::function<void(bool, hecl::SystemStringView)> returnFunc)
|
||||
: FileBrowser(res, parentView, title, type, hecl::GetcwdStr(), std::move(returnFunc)) {}
|
||||
|
||||
FileBrowser::FileBrowser(ViewResources& res, View& parentView, std::string_view title, Type type,
|
||||
hecl::SystemStringView initialPath,
|
||||
std::function<void(bool, hecl::SystemStringView)> returnFunc)
|
||||
|
@ -59,23 +60,21 @@ FileBrowser::FileBrowser(ViewResources& res, View& parentView, std::string_view
|
|||
, m_systemBookmarkBind(*this)
|
||||
, m_projectBookmarkBind(*this)
|
||||
, m_recentBookmarkBind(*this)
|
||||
, m_returnFunc(returnFunc) {
|
||||
, m_returnFunc(std::move(returnFunc)) {
|
||||
setBackground({0, 0, 0, 0.5});
|
||||
|
||||
IViewManager& vm = rootView().viewManager();
|
||||
m_pathButtons.m_view.reset(new PathButtons(res, *this, *this));
|
||||
m_fileField.m_view.reset(new TextField(res, *this, &m_fileFieldBind));
|
||||
m_fileListing.m_view.reset(new Table(res, *this, &m_fileListingBind, &m_fileListingBind, 3));
|
||||
m_systemBookmarks.m_view.reset(new Table(res, *this, &m_systemBookmarkBind, &m_systemBookmarkBind, 1));
|
||||
m_systemBookmarksLabel.reset(new TextView(res, *this, res.m_mainFont));
|
||||
m_systemBookmarksLabel->typesetGlyphs(vm.translate<locale::system_locations>(),
|
||||
res.themeData().uiText());
|
||||
m_projectBookmarks.m_view.reset(new Table(res, *this, &m_projectBookmarkBind, &m_projectBookmarkBind, 1));
|
||||
m_projectBookmarksLabel.reset(new TextView(res, *this, res.m_mainFont));
|
||||
m_projectBookmarksLabel->typesetGlyphs(vm.translate<locale::recent_projects>(),
|
||||
res.themeData().uiText());
|
||||
m_recentBookmarks.m_view.reset(new Table(res, *this, &m_recentBookmarkBind, &m_recentBookmarkBind, 1));
|
||||
m_recentBookmarksLabel.reset(new TextView(res, *this, res.m_mainFont));
|
||||
m_pathButtons.m_view = std::make_unique<PathButtons>(res, *this, *this);
|
||||
m_fileField.m_view = std::make_unique<TextField>(res, *this, &m_fileFieldBind);
|
||||
m_fileListing.m_view = std::make_unique<Table>(res, *this, &m_fileListingBind, &m_fileListingBind, 3);
|
||||
m_systemBookmarks.m_view = std::make_unique<Table>(res, *this, &m_systemBookmarkBind, &m_systemBookmarkBind, 1);
|
||||
m_systemBookmarksLabel = std::make_unique<TextView>(res, *this, res.m_mainFont);
|
||||
m_systemBookmarksLabel->typesetGlyphs(vm.translate<locale::system_locations>(), res.themeData().uiText());
|
||||
m_projectBookmarks.m_view = std::make_unique<Table>(res, *this, &m_projectBookmarkBind, &m_projectBookmarkBind, 1);
|
||||
m_projectBookmarksLabel = std::make_unique<TextView>(res, *this, res.m_mainFont);
|
||||
m_projectBookmarksLabel->typesetGlyphs(vm.translate<locale::recent_projects>(), res.themeData().uiText());
|
||||
m_recentBookmarks.m_view = std::make_unique<Table>(res, *this, &m_recentBookmarkBind, &m_recentBookmarkBind, 1);
|
||||
m_recentBookmarksLabel = std::make_unique<TextView>(res, *this, res.m_mainFont);
|
||||
m_recentBookmarksLabel->typesetGlyphs(vm.translate<locale::recent_files>(), res.themeData().uiText());
|
||||
|
||||
/* Populate system bookmarks */
|
||||
|
@ -98,8 +97,8 @@ FileBrowser::FileBrowser(ViewResources& res, View& parentView, std::string_view
|
|||
|
||||
navigateToPath(initialPath);
|
||||
|
||||
m_split.m_view.reset(new SplitView(res, *this, nullptr, SplitView::Axis::Vertical, 0.2, 200 * res.pixelFactor(),
|
||||
400 * res.pixelFactor()));
|
||||
m_split.m_view = std::make_unique<SplitView>(res, *this, nullptr, SplitView::Axis::Vertical, 0.2,
|
||||
200 * res.pixelFactor(), 400 * res.pixelFactor());
|
||||
m_split.m_view->setContentView(0, &m_left);
|
||||
m_split.m_view->setContentView(1, &m_right);
|
||||
|
||||
|
@ -207,17 +206,16 @@ void FileBrowser::okActivated(bool viaButton) {
|
|||
return;
|
||||
}
|
||||
if (!err && !S_ISDIR(theStat.st_mode)) {
|
||||
m_confirmWindow.reset(
|
||||
new MessageWindow(rootView().viewRes(), *this, MessageWindow::Type::ConfirmOkCancel,
|
||||
vm.translate<locale::overwrite_confirm>(hecl::SystemUTF8Conv(path)),
|
||||
[&, path](bool ok) {
|
||||
m_confirmWindow = std::make_unique<MessageWindow>(
|
||||
rootView().viewRes(), *this, MessageWindow::Type::ConfirmOkCancel,
|
||||
vm.translate<locale::overwrite_confirm>(hecl::SystemUTF8Conv(path)), [&, path](bool ok) {
|
||||
if (ok) {
|
||||
m_returnFunc(true, path);
|
||||
m_confirmWindow->close();
|
||||
close();
|
||||
} else
|
||||
m_confirmWindow->close();
|
||||
}));
|
||||
});
|
||||
updateSize();
|
||||
return;
|
||||
}
|
||||
|
@ -334,8 +332,7 @@ void FileBrowser::FileListingDataBind::updateListing(const hecl::DirectoryEnumer
|
|||
m_entries.reserve(dEnum.size());
|
||||
|
||||
for (const hecl::DirectoryEnumerator::Entry& d : dEnum) {
|
||||
m_entries.emplace_back();
|
||||
Entry& ent = m_entries.back();
|
||||
Entry& ent = m_entries.emplace_back();
|
||||
ent.m_path = d.m_path;
|
||||
hecl::SystemUTF8Conv nameUtf8(d.m_name);
|
||||
ent.m_name = nameUtf8.str();
|
||||
|
@ -587,16 +584,16 @@ void FileBrowser::RightSide::draw(boo::IGraphicsCommandQueue* gfxQ) {
|
|||
}
|
||||
|
||||
FileBrowser::OKButton::OKButton(FileBrowser& fb, ViewResources& res, std::string_view text) : m_fb(fb), m_text(text) {
|
||||
m_button.m_view.reset(
|
||||
new Button(res, fb, this, text, nullptr, Button::Style::Block, zeus::skWhite,
|
||||
RectangleConstraint(100 * res.pixelFactor(), -1, RectangleConstraint::Test::Minimum)));
|
||||
m_button.m_view =
|
||||
std::make_unique<Button>(res, fb, this, text, nullptr, Button::Style::Block, zeus::skWhite,
|
||||
RectangleConstraint(100 * res.pixelFactor(), -1, RectangleConstraint::Test::Minimum));
|
||||
}
|
||||
|
||||
FileBrowser::CancelButton::CancelButton(FileBrowser& fb, ViewResources& res, std::string_view text)
|
||||
: m_fb(fb), m_text(text) {
|
||||
m_button.m_view.reset(new Button(
|
||||
m_button.m_view = std::make_unique<Button>(
|
||||
res, fb, this, text, nullptr, Button::Style::Block, zeus::skWhite,
|
||||
RectangleConstraint(m_fb.m_ok.m_button.m_view->nominalWidth(), -1, RectangleConstraint::Test::Minimum)));
|
||||
RectangleConstraint(m_fb.m_ok.m_button.m_view->nominalWidth(), -1, RectangleConstraint::Test::Minimum));
|
||||
}
|
||||
|
||||
} // namespace specter
|
||||
|
|
|
@ -43,15 +43,16 @@ extern "C" const FT_Driver_ClassRec tt_driver_class;
|
|||
namespace specter {
|
||||
static logvisor::Module Log("specter::FontCache");
|
||||
|
||||
const FCharFilter AllCharFilter = std::make_pair("all-glyphs", [](uint32_t) -> bool { return true; });
|
||||
const FCharFilter AllCharFilter{"all-glyphs", [](uint32_t) { return true; }};
|
||||
|
||||
const FCharFilter LatinCharFilter =
|
||||
std::make_pair("latin-glyphs", [](uint32_t c) -> bool { return c <= 0xff || ((c - 0x2200) <= (0x23FF - 0x2200)); });
|
||||
const FCharFilter LatinCharFilter{"latin-glyphs",
|
||||
[](uint32_t c) { return c <= 0xff || (c - 0x2200) <= (0x23FF - 0x2200); }};
|
||||
|
||||
const FCharFilter LatinAndJapaneseCharFilter = std::make_pair("latin-and-jp-glyphs", [](uint32_t c) -> bool {
|
||||
return LatinCharFilter.second(c) || ((c - 0x2E00) <= (0x30FF - 0x2E00)) || ((c - 0x4E00) <= (0x9FFF - 0x4E00)) ||
|
||||
((c - 0xFF00) <= (0xFFEF - 0xFF00));
|
||||
});
|
||||
const FCharFilter LatinAndJapaneseCharFilter{"latin-and-jp-glyphs", [](uint32_t c) {
|
||||
return LatinCharFilter.second(c) || (c - 0x2E00) <= (0x30FF - 0x2E00) ||
|
||||
(c - 0x4E00) <= (0x9FFF - 0x4E00) ||
|
||||
(c - 0xFF00) <= (0xFFEF - 0xFF00);
|
||||
}};
|
||||
|
||||
FontTag::FontTag(std::string_view name, bool subpixel, float points, uint32_t dpi) {
|
||||
XXH64_state_t st;
|
||||
|
@ -147,7 +148,7 @@ void FontAtlas::buildKernTable(FT_Face face) {
|
|||
TT_KernHead kernHead;
|
||||
kernHead.read(r);
|
||||
if (kernHead.coverage >> 8 != 0) {
|
||||
r.seek(kernHead.length - 6, athena::Current);
|
||||
r.seek(kernHead.length - 6, athena::SeekOrigin::Current);
|
||||
continue;
|
||||
}
|
||||
|
||||
|
@ -198,7 +199,7 @@ static void WriteCompressed(athena::io::FileWriter& writer, const atUint8* data,
|
|||
writer.writeUBytes(compBuf, ZLIB_BUF_SZ - z.avail_out);
|
||||
}
|
||||
|
||||
writer.seek(adlerPos, athena::Begin);
|
||||
writer.seek(adlerPos, athena::SeekOrigin::Begin);
|
||||
writer.writeUint32Big(z.adler);
|
||||
|
||||
deflateEnd(&z);
|
||||
|
@ -307,13 +308,10 @@ FontAtlas::FontAtlas(FT_Face face, uint32_t dpi, bool subpixel, FCharFilter& fil
|
|||
charcode = FT_Get_Next_Char(face, charcode, &gindex);
|
||||
continue;
|
||||
}
|
||||
|
||||
FT_Load_Glyph(face, gindex, FT_LOAD_RENDER | baseFlags);
|
||||
FT_UInt width, height;
|
||||
GridFitGlyph(face->glyph, width, height);
|
||||
m_glyphLookup[charcode] = m_glyphs.size();
|
||||
m_glyphs.emplace_back();
|
||||
Glyph& g = m_glyphs.back();
|
||||
|
||||
if (curLineWidth + width + 1 > TEXMAP_DIM) {
|
||||
totalHeight += curLineHeight + 1;
|
||||
curLineHeight = 0;
|
||||
|
@ -328,6 +326,8 @@ FontAtlas::FontAtlas(FT_Face face, uint32_t dpi, bool subpixel, FCharFilter& fil
|
|||
curLineWidth = 1;
|
||||
}
|
||||
|
||||
m_glyphLookup.insert_or_assign(charcode, m_glyphs.size());
|
||||
Glyph& g = m_glyphs.emplace_back();
|
||||
g.m_unicodePoint = charcode;
|
||||
g.m_glyphIdx = gindex;
|
||||
g.m_layerIdx = m_fullTexmapLayers;
|
||||
|
@ -369,13 +369,10 @@ FontAtlas::FontAtlas(FT_Face face, uint32_t dpi, bool subpixel, FCharFilter& fil
|
|||
charcode = FT_Get_Next_Char(face, charcode, &gindex);
|
||||
continue;
|
||||
}
|
||||
|
||||
FT_Load_Glyph(face, gindex, FT_LOAD_RENDER | baseFlags);
|
||||
FT_UInt width, height;
|
||||
GridFitGlyph(face->glyph, width, height);
|
||||
m_glyphLookup[charcode] = m_glyphs.size();
|
||||
m_glyphs.emplace_back();
|
||||
Glyph& g = m_glyphs.back();
|
||||
|
||||
if (curLineWidth + width + 1 > TEXMAP_DIM) {
|
||||
totalHeight += curLineHeight + 1;
|
||||
curLineHeight = 0;
|
||||
|
@ -390,6 +387,8 @@ FontAtlas::FontAtlas(FT_Face face, uint32_t dpi, bool subpixel, FCharFilter& fil
|
|||
curLineWidth = 1;
|
||||
}
|
||||
|
||||
m_glyphLookup.insert_or_assign(charcode, m_glyphs.size());
|
||||
Glyph& g = m_glyphs.emplace_back();
|
||||
g.m_unicodePoint = charcode;
|
||||
g.m_glyphIdx = gindex;
|
||||
g.m_layerIdx = m_fullTexmapLayers;
|
||||
|
@ -468,13 +467,10 @@ FontAtlas::FontAtlas(FT_Face face, uint32_t dpi, bool subpixel, FCharFilter& fil
|
|||
charcode = FT_Get_Next_Char(face, charcode, &gindex);
|
||||
continue;
|
||||
}
|
||||
|
||||
FT_Load_Glyph(face, gindex, baseFlags);
|
||||
FT_UInt width, height;
|
||||
GridFitGlyph(face->glyph, width, height);
|
||||
m_glyphLookup[charcode] = m_glyphs.size();
|
||||
m_glyphs.emplace_back();
|
||||
Glyph& g = m_glyphs.back();
|
||||
|
||||
if (curLineWidth + width + 1 > TEXMAP_DIM) {
|
||||
totalHeight += curLineHeight + 1;
|
||||
curLineHeight = 0;
|
||||
|
@ -489,6 +485,8 @@ FontAtlas::FontAtlas(FT_Face face, uint32_t dpi, bool subpixel, FCharFilter& fil
|
|||
curLineWidth = 1;
|
||||
}
|
||||
|
||||
m_glyphLookup.insert_or_assign(charcode, m_glyphs.size());
|
||||
Glyph& g = m_glyphs.emplace_back();
|
||||
g.m_unicodePoint = charcode;
|
||||
g.m_glyphIdx = gindex;
|
||||
g.m_layerIdx = m_fullTexmapLayers;
|
||||
|
@ -530,13 +528,10 @@ FontAtlas::FontAtlas(FT_Face face, uint32_t dpi, bool subpixel, FCharFilter& fil
|
|||
charcode = FT_Get_Next_Char(face, charcode, &gindex);
|
||||
continue;
|
||||
}
|
||||
|
||||
FT_Load_Glyph(face, gindex, baseFlags);
|
||||
FT_UInt width, height;
|
||||
GridFitGlyph(face->glyph, width, height);
|
||||
m_glyphLookup[charcode] = m_glyphs.size();
|
||||
m_glyphs.emplace_back();
|
||||
Glyph& g = m_glyphs.back();
|
||||
|
||||
if (curLineWidth + width + 1 > TEXMAP_DIM) {
|
||||
totalHeight += curLineHeight + 1;
|
||||
curLineHeight = 0;
|
||||
|
@ -551,6 +546,8 @@ FontAtlas::FontAtlas(FT_Face face, uint32_t dpi, bool subpixel, FCharFilter& fil
|
|||
curLineWidth = 1;
|
||||
}
|
||||
|
||||
m_glyphLookup.insert_or_assign(charcode, m_glyphs.size());
|
||||
Glyph& g = m_glyphs.emplace_back();
|
||||
g.m_unicodePoint = charcode;
|
||||
g.m_glyphIdx = gindex;
|
||||
g.m_layerIdx = m_fullTexmapLayers;
|
||||
|
@ -613,6 +610,8 @@ FontCache::FontCache(const hecl::Runtime::FileStoreManager& fileMgr)
|
|||
hecl::MakeDir(m_cacheRoot.c_str());
|
||||
}
|
||||
|
||||
FontCache::~FontCache() = default;
|
||||
|
||||
FontTag FontCache::prepCustomFont(std::string_view name, FT_Face face, FCharFilter filter, bool subpixel, float points,
|
||||
uint32_t dpi) {
|
||||
/* Quick validation */
|
||||
|
@ -626,10 +625,11 @@ FontTag FontCache::prepCustomFont(std::string_view name, FT_Face face, FCharFilt
|
|||
FT_Set_Char_Size(face, 0, points * 64.0, 0, dpi);
|
||||
|
||||
/* Make tag and search for cached version */
|
||||
FontTag tag(std::string(name) + '_' + filter.first, subpixel, points, dpi);
|
||||
auto search = m_cachedAtlases.find(tag);
|
||||
if (search != m_cachedAtlases.end())
|
||||
const FontTag tag(std::string(name).append(1, '_').append(filter.first), subpixel, points, dpi);
|
||||
const auto search = m_cachedAtlases.find(tag);
|
||||
if (search != m_cachedAtlases.end()) {
|
||||
return tag;
|
||||
}
|
||||
|
||||
/* Now check filesystem cache */
|
||||
hecl::SystemString cachePath = m_cacheRoot + _SYS_STR('/') + fmt::format(fmt(_SYS_STR("{}")), tag.hash());
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#include "specter/Icon.hpp"
|
||||
#include "specter/RootView.hpp"
|
||||
|
||||
#include <boo/graphicsdev/IGraphicsCommandQueue.hpp>
|
||||
|
||||
namespace specter {
|
||||
|
||||
IconView::IconView(ViewResources& res, View& parentView, Icon& icon) : View(res, parentView) {
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
#include "specter/TextView.hpp"
|
||||
#include "specter/ViewResources.hpp"
|
||||
|
||||
#include <boo/graphicsdev/IGraphicsCommandQueue.hpp>
|
||||
|
||||
#define ROW_HEIGHT 18
|
||||
#define ITEM_MARGIN 1
|
||||
|
||||
|
@ -17,9 +19,9 @@ Menu::Menu(ViewResources& res, View& parentView, IMenuNode* rootNode) : View(res
|
|||
m_vertsBinding.init(ctx, res, 8, m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
m_headText.reset(new TextView(res, *this, res.m_mainFont));
|
||||
m_scroll.m_view.reset(new ScrollView(res, *this, ScrollView::Style::ThinIndicator));
|
||||
m_content.reset(new ContentView(res, *this));
|
||||
m_headText = std::make_unique<TextView>(res, *this, res.m_mainFont);
|
||||
m_scroll.m_view = std::make_unique<ScrollView>(res, *this, ScrollView::Style::ThinIndicator);
|
||||
m_content = std::make_unique<ContentView>(res, *this);
|
||||
m_scroll.m_view->setContentView(m_content.get());
|
||||
reset(rootNode);
|
||||
}
|
||||
|
@ -53,12 +55,10 @@ void Menu::reset(IMenuNode* rootNode) {
|
|||
for (size_t i = 0; i < subCount; ++i) {
|
||||
IMenuNode* node = rootNode->subNode(i);
|
||||
const std::string* nodeText = node->text();
|
||||
ViewChild<std::unique_ptr<ItemView>>& item = m_items.emplace_back();
|
||||
|
||||
m_items.emplace_back();
|
||||
ViewChild<std::unique_ptr<ItemView>>& item = m_items.back();
|
||||
|
||||
if (nodeText) {
|
||||
item.m_view.reset(new ItemView(res, *this, *nodeText, i, node));
|
||||
if (nodeText != nullptr) {
|
||||
item.m_view = std::make_unique<ItemView>(res, *this, *nodeText, i, node);
|
||||
m_cWidth = std::max(m_cWidth, int(item.m_view->m_textView->nominalWidth() + 10 * pf));
|
||||
}
|
||||
|
||||
|
@ -74,9 +74,9 @@ Menu::Menu(ViewResources& res, View& parentView, IMenuNode* rootNode, IMenuNode*
|
|||
m_vertsBinding.init(ctx, res, 8, m_viewVertBlockBuf);
|
||||
return true;
|
||||
});
|
||||
m_headText.reset(new TextView(res, *this, res.m_mainFont));
|
||||
m_scroll.m_view.reset(new ScrollView(res, *this, ScrollView::Style::ThinIndicator));
|
||||
m_content.reset(new ContentView(res, *this));
|
||||
m_headText = std::make_unique<TextView>(res, *this, res.m_mainFont);
|
||||
m_scroll.m_view = std::make_unique<ScrollView>(res, *this, ScrollView::Style::ThinIndicator);
|
||||
m_content = std::make_unique<ContentView>(res, *this);
|
||||
m_scroll.m_view->setContentView(m_content.get());
|
||||
}
|
||||
|
||||
|
@ -99,7 +99,7 @@ Menu::ItemView::ItemView(ViewResources& res, Menu& menu, std::string_view text,
|
|||
buildResources(ctx, res);
|
||||
return true;
|
||||
});
|
||||
m_textView.reset(new specter::TextView(res, *this, res.m_mainFont));
|
||||
m_textView = std::make_unique<TextView>(res, *this, res.m_mainFont);
|
||||
m_textView->typesetGlyphs(text, res.themeData().uiText());
|
||||
}
|
||||
|
||||
|
|
|
@ -16,18 +16,20 @@ MessageWindow::MessageWindow(ViewResources& res, View& parentView, Type type, st
|
|||
: ModalWindow(res, parentView, RectangleConstraint(),
|
||||
type == Type::ErrorOk ? res.themeData().splashErrorBackground() : res.themeData().splashBackground())
|
||||
, m_type(type)
|
||||
, m_func(func)
|
||||
, m_func(std::move(func))
|
||||
, m_okBind(*this, rootView().viewManager().translate<locale::ok>())
|
||||
, m_cancelBind(*this, rootView().viewManager().translate<locale::cancel>()) {
|
||||
m_text.reset(new MultiLineTextView(res, *this, res.m_mainFont, TextView::Alignment::Center));
|
||||
m_text = std::make_unique<MultiLineTextView>(res, *this, res.m_mainFont, TextView::Alignment::Center);
|
||||
m_text->typesetGlyphs(message, res.themeData().uiText(), 380 * res.pixelFactor());
|
||||
constraint() = RectangleConstraint(400 * res.pixelFactor(), 80 * res.pixelFactor() + m_text->nominalHeight());
|
||||
|
||||
m_ok.m_view.reset(new Button(res, *this, &m_okBind, m_okBind.m_name, nullptr, Button::Style::Block,
|
||||
zeus::skWhite, RectangleConstraint(150 * res.pixelFactor())));
|
||||
if (type == Type::ConfirmOkCancel)
|
||||
m_cancel.m_view.reset(new Button(res, *this, &m_cancelBind, m_cancelBind.m_name, nullptr, Button::Style::Block,
|
||||
zeus::skWhite, RectangleConstraint(150 * res.pixelFactor())));
|
||||
m_ok.m_view = std::make_unique<Button>(res, *this, &m_okBind, m_okBind.m_name, nullptr, Button::Style::Block,
|
||||
zeus::skWhite, RectangleConstraint(150 * res.pixelFactor()));
|
||||
if (type == Type::ConfirmOkCancel) {
|
||||
m_cancel.m_view =
|
||||
std::make_unique<Button>(res, *this, &m_cancelBind, m_cancelBind.m_name, nullptr, Button::Style::Block,
|
||||
zeus::skWhite, RectangleConstraint(150 * res.pixelFactor()));
|
||||
}
|
||||
|
||||
updateContentOpacity(0.0);
|
||||
}
|
||||
|
|
|
@ -1,10 +1,13 @@
|
|||
#include "specter/ModalWindow.hpp"
|
||||
|
||||
#include <algorithm>
|
||||
|
||||
#include "specter/MultiLineTextView.hpp"
|
||||
#include "specter/RootView.hpp"
|
||||
#include "specter/ViewResources.hpp"
|
||||
|
||||
#include <boo/System.hpp>
|
||||
#include <boo/graphicsdev/IGraphicsCommandQueue.hpp>
|
||||
|
||||
namespace specter {
|
||||
|
||||
|
@ -20,9 +23,9 @@ namespace specter {
|
|||
#define WINDOW_MIN_DIM 16
|
||||
|
||||
void ModalWindow::setLineVerts(int width, int height, float pf, float t) {
|
||||
std::pair<int, int> margin = m_cornersOutline[0]->queryGlyphDimensions(0);
|
||||
float t1 = zeus::clamp(0.f, t * 2.f, 1.f);
|
||||
float t2 = zeus::clamp(0.f, t * 2.f - 1.f, 1.f);
|
||||
const std::pair<int, int> margin = m_cornersOutline[0]->queryGlyphDimensions(0);
|
||||
const float t1 = std::clamp(t * 2.f, 0.f, 1.f);
|
||||
const float t2 = std::clamp(t * 2.f - 1.f, 0.f, 1.f);
|
||||
|
||||
float lineLeft = 0;
|
||||
float lineRight = pf * LINE_WIDTH;
|
||||
|
@ -68,9 +71,9 @@ void ModalWindow::setLineVerts(int width, int height, float pf, float t) {
|
|||
}
|
||||
|
||||
void ModalWindow::setLineVertsOut(int width, int height, float pf, float t) {
|
||||
std::pair<int, int> margin = m_cornersOutline[0]->queryGlyphDimensions(0);
|
||||
float t1 = zeus::clamp(0.f, t * 2.f - 1.f, 1.f);
|
||||
float t2 = zeus::clamp(0.f, t * 2.f, 1.f);
|
||||
const std::pair<int, int> margin = m_cornersOutline[0]->queryGlyphDimensions(0);
|
||||
const float t1 = std::clamp(t * 2.f - 1.f, 0.f, 1.f);
|
||||
const float t2 = std::clamp(t * 2.f, 0.f, 1.f);
|
||||
|
||||
float lineLeft = 0;
|
||||
float lineRight = pf * LINE_WIDTH;
|
||||
|
@ -116,13 +119,13 @@ void ModalWindow::setLineVertsOut(int width, int height, float pf, float t) {
|
|||
}
|
||||
|
||||
void ModalWindow::setLineColors(float t) {
|
||||
float t1 = zeus::clamp(0.f, t * 2.f, 1.f);
|
||||
float t2 = zeus::clamp(0.f, t * 2.f - 1.f, 1.f);
|
||||
float t3 = zeus::clamp(0.f, t * 2.f - 2.f, 1.f);
|
||||
const float t1 = std::clamp(t * 2.f, 0.f, 1.f);
|
||||
const float t2 = std::clamp(t * 2.f - 1.f, 0.f, 1.f);
|
||||
const float t3 = std::clamp(t * 2.f - 2.f, 0.f, 1.f);
|
||||
|
||||
zeus::CColor c1 = zeus::CColor::lerp(m_line1, m_line2, t1);
|
||||
zeus::CColor c2 = zeus::CColor::lerp(m_line1, m_line2, t2);
|
||||
zeus::CColor c3 = zeus::CColor::lerp(m_line1, m_line2, t3);
|
||||
const zeus::CColor c1 = zeus::CColor::lerp(m_line1, m_line2, t1);
|
||||
const zeus::CColor c2 = zeus::CColor::lerp(m_line1, m_line2, t2);
|
||||
const zeus::CColor c3 = zeus::CColor::lerp(m_line1, m_line2, t3);
|
||||
|
||||
m_cornersOutline[0]->colorGlyphs(c1);
|
||||
if (t < 0.5) {
|
||||
|
@ -167,13 +170,13 @@ void ModalWindow::setLineColors(float t) {
|
|||
}
|
||||
|
||||
void ModalWindow::setLineColorsOut(float t) {
|
||||
float t1 = zeus::clamp(0.f, t * 2.f, 1.f);
|
||||
float t2 = zeus::clamp(0.f, t * 2.f - 1.f, 1.f);
|
||||
float t3 = zeus::clamp(0.f, t * 2.f - 2.f, 1.f);
|
||||
const float t1 = std::clamp(t * 2.f, 0.f, 1.f);
|
||||
const float t2 = std::clamp(t * 2.f - 1.f, 0.f, 1.f);
|
||||
const float t3 = std::clamp(t * 2.f - 2.f, 0.f, 1.f);
|
||||
|
||||
zeus::CColor c1 = zeus::CColor::lerp(m_line2Clear, m_line2, t1);
|
||||
zeus::CColor c2 = zeus::CColor::lerp(m_line2Clear, m_line2, t2);
|
||||
zeus::CColor c3 = zeus::CColor::lerp(m_line2Clear, m_line2, t3);
|
||||
const zeus::CColor c1 = zeus::CColor::lerp(m_line2Clear, m_line2, t1);
|
||||
const zeus::CColor c2 = zeus::CColor::lerp(m_line2Clear, m_line2, t2);
|
||||
const zeus::CColor c3 = zeus::CColor::lerp(m_line2Clear, m_line2, t3);
|
||||
|
||||
m_cornersOutline[2]->colorGlyphs(c1);
|
||||
if (t < 0.5) {
|
||||
|
@ -253,7 +256,7 @@ void ModalWindow::setFillVerts(int width, int height, float pf) {
|
|||
}
|
||||
|
||||
void ModalWindow::setFillColors(float t) {
|
||||
t = zeus::clamp(0.f, t, 1.f);
|
||||
t = std::clamp(t, 0.f, 1.f);
|
||||
zeus::CColor color = zeus::CColor::lerp(m_windowBgClear, m_windowBg, t);
|
||||
|
||||
for (int i = 0; i < 16; ++i)
|
||||
|
@ -285,9 +288,9 @@ ModalWindow::ModalWindow(ViewResources& res, View& parentView, const RectangleCo
|
|||
} BooTrace);
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
m_cornersOutline[i].reset(
|
||||
new specter::TextView(res, *this, res.m_curveFont, specter::TextView::Alignment::Left, 1));
|
||||
m_cornersFilled[i].reset(new specter::TextView(res, *this, res.m_curveFont, specter::TextView::Alignment::Left, 1));
|
||||
m_cornersOutline[i] =
|
||||
std::make_unique<TextView>(res, *this, res.m_curveFont, specter::TextView::Alignment::Left, 1);
|
||||
m_cornersFilled[i] = std::make_unique<TextView>(res, *this, res.m_curveFont, specter::TextView::Alignment::Left, 1);
|
||||
}
|
||||
m_cornersOutline[0]->typesetGlyphs(L"\xF4F0");
|
||||
m_cornersFilled[0]->typesetGlyphs(L"\xF4F1", res.themeData().splashBackground());
|
||||
|
@ -324,7 +327,7 @@ void ModalWindow::think() {
|
|||
int doneCount = 0;
|
||||
if (m_frame > WIRE_START) {
|
||||
float wt = (m_frame - WIRE_START) / float(WIRE_FRAMES);
|
||||
wt = zeus::clamp(0.f, wt, 2.f);
|
||||
wt = std::clamp(wt, 0.f, 2.f);
|
||||
m_lineTime = CubicEase(wt);
|
||||
setLineVerts(m_width, m_height, pf, m_lineTime);
|
||||
setLineColors(wt);
|
||||
|
@ -334,7 +337,7 @@ void ModalWindow::think() {
|
|||
}
|
||||
if (m_frame > SOLID_START) {
|
||||
float ft = (m_frame - SOLID_START) / float(SOLID_FRAMES);
|
||||
ft = zeus::clamp(0.f, ft, 2.f);
|
||||
ft = std::clamp(ft, 0.f, 2.f);
|
||||
setFillColors(ft);
|
||||
if (ft == 2.f)
|
||||
++doneCount;
|
||||
|
@ -344,7 +347,7 @@ void ModalWindow::think() {
|
|||
if (!m_contentStartFrame)
|
||||
m_contentStartFrame = m_frame;
|
||||
float tt = (m_frame - m_contentStartFrame) / float(CONTENT_FRAMES);
|
||||
tt = zeus::clamp(0.f, tt, 1.f);
|
||||
tt = std::clamp(tt, 0.f, 1.f);
|
||||
updateContentOpacity(tt);
|
||||
if (tt == 1.f)
|
||||
++doneCount;
|
||||
|
@ -366,7 +369,7 @@ void ModalWindow::think() {
|
|||
case Phase::BuildOut: {
|
||||
{
|
||||
float wt = (WIRE_FRAMES - m_frame) / float(WIRE_FRAMES);
|
||||
wt = zeus::clamp(0.f, wt, 1.f);
|
||||
wt = std::clamp(wt, 0.f, 1.f);
|
||||
m_lineTime = CubicEase(wt);
|
||||
setLineVertsOut(m_width, m_height, pf, m_lineTime);
|
||||
setLineColorsOut(wt);
|
||||
|
@ -375,12 +378,12 @@ void ModalWindow::think() {
|
|||
}
|
||||
{
|
||||
float ft = (SOLID_FRAMES - m_frame) / float(SOLID_FRAMES);
|
||||
ft = zeus::clamp(0.f, ft, 1.f);
|
||||
ft = std::clamp(ft, 0.f, 1.f);
|
||||
setFillColors(ft);
|
||||
}
|
||||
if (res.fontCacheReady()) {
|
||||
float tt = (CONTENT_FRAMES - m_frame) / float(CONTENT_FRAMES);
|
||||
tt = zeus::clamp(0.f, tt, 1.f);
|
||||
tt = std::clamp(tt, 0.f, 1.f);
|
||||
updateContentOpacity(tt);
|
||||
}
|
||||
_loadVerts();
|
||||
|
|
|
@ -164,10 +164,9 @@ void MultiLineTextView::typesetGlyphs(std::string_view str, const zeus::CColor&
|
|||
utf8proc_int32_t ch;
|
||||
utf8proc_ssize_t sz = utf8proc_iterate(it, -1, &ch);
|
||||
if (ch == '\n' || ch == '\0') {
|
||||
TextView& tv =
|
||||
(lineIt < m_lines.size())
|
||||
? *m_lines[lineIt]
|
||||
: *m_lines.emplace_back(new TextView(m_viewSystem, *this, m_fontAtlas, m_align, m_lineCapacity));
|
||||
TextView& tv = (lineIt < m_lines.size()) ? *m_lines[lineIt]
|
||||
: *m_lines.emplace_back(std::make_unique<TextView>(
|
||||
m_viewSystem, *this, m_fontAtlas, m_align, m_lineCapacity));
|
||||
tv.typesetGlyphs(std::string((char*)beginIt, it - beginIt), defaultColor);
|
||||
m_width = std::max(m_width, tv.nominalWidth());
|
||||
beginIt = it + 1;
|
||||
|
@ -206,10 +205,9 @@ void MultiLineTextView::typesetGlyphs(std::wstring_view str, const zeus::CColor&
|
|||
|
||||
while (rem) {
|
||||
if (*it == L'\n' || *it == L'\0') {
|
||||
TextView& tv =
|
||||
(lineIt < m_lines.size())
|
||||
? *m_lines[lineIt]
|
||||
: *m_lines.emplace_back(new TextView(m_viewSystem, *this, m_fontAtlas, m_align, m_lineCapacity));
|
||||
TextView& tv = (lineIt < m_lines.size()) ? *m_lines[lineIt]
|
||||
: *m_lines.emplace_back(std::make_unique<TextView>(
|
||||
m_viewSystem, *this, m_fontAtlas, m_align, m_lineCapacity));
|
||||
tv.typesetGlyphs(std::wstring(beginIt, it), defaultColor);
|
||||
m_width = std::max(m_width, tv.nominalWidth());
|
||||
beginIt = it + 1;
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "specter/RootView.hpp"
|
||||
#include "specter/ViewResources.hpp"
|
||||
|
||||
#include <boo/graphicsdev/IGraphicsCommandQueue.hpp>
|
||||
|
||||
namespace specter {
|
||||
struct PathButtons::PathButton final : IButtonBinding {
|
||||
PathButtons& m_pb;
|
||||
|
@ -11,7 +13,7 @@ struct PathButtons::PathButton final : IButtonBinding {
|
|||
ViewChild<std::unique_ptr<Button>> m_button;
|
||||
|
||||
PathButton(PathButtons& pb, ViewResources& res, size_t idx, const hecl::SystemString& str) : m_pb(pb), m_idx(idx) {
|
||||
m_button.m_view.reset(new Button(res, pb, this, hecl::SystemUTF8Conv(str).str()));
|
||||
m_button.m_view = std::make_unique<Button>(res, pb, this, hecl::SystemUTF8Conv(str).str());
|
||||
}
|
||||
|
||||
std::string_view name(const Control* control) const override { return m_button.m_view->getText(); }
|
||||
|
@ -93,7 +95,7 @@ struct PathButtons::ContentView : public View {
|
|||
|
||||
PathButtons::PathButtons(ViewResources& res, View& parentView, IPathButtonsBinding& binding, bool fillContainer)
|
||||
: ScrollView(res, parentView, ScrollView::Style::SideButtons), m_binding(binding), m_fillContainer(fillContainer) {
|
||||
m_contentView.m_view.reset(new ContentView(res, *this));
|
||||
m_contentView.m_view = std::make_unique<ContentView>(res, *this);
|
||||
setContentView(m_contentView.m_view.get());
|
||||
}
|
||||
|
||||
|
|
|
@ -8,10 +8,9 @@
|
|||
#include "specter/Tooltip.hpp"
|
||||
#include "specter/ViewResources.hpp"
|
||||
|
||||
#include <logvisor/logvisor.hpp>
|
||||
#include <boo/graphicsdev/IGraphicsCommandQueue.hpp>
|
||||
|
||||
namespace specter {
|
||||
static logvisor::Module Log("specter::RootView");
|
||||
|
||||
RootView::RootView(IViewManager& viewMan, ViewResources& res, boo::IWindow* window)
|
||||
: View(res), m_window(window), m_viewMan(viewMan), m_viewRes(&res), m_events(*this) {
|
||||
|
@ -507,13 +506,13 @@ void RootView::modKeyUp(boo::EModifierKey mod) {
|
|||
boo::ITextInputCallback* RootView::getTextInputCallback() { return m_activeTextView; }
|
||||
|
||||
void RootView::resetTooltip(ViewResources& res) {
|
||||
m_tooltip.reset(
|
||||
new Tooltip(res, *this, "Test",
|
||||
m_tooltip = std::make_unique<Tooltip>(
|
||||
res, *this, "Test",
|
||||
"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Morbi hendrerit nisl quis lobortis mattis. "
|
||||
"Mauris efficitur, est a vestibulum iaculis, leo orci pellentesque nunc, non rutrum ipsum lectus "
|
||||
"eget nisl. Aliquam accumsan vestibulum turpis. Duis id lacus ac lectus sollicitudin posuere vel sit "
|
||||
"amet metus. Aenean nec tortor id enim efficitur accumsan vitae eu ante. Lorem ipsum dolor sit amet, "
|
||||
"consectetur adipiscing elit. Fusce magna eros, lacinia a leo eget, volutpat rhoncus urna."));
|
||||
"consectetur adipiscing elit. Fusce magna eros, lacinia a leo eget, volutpat rhoncus urna.");
|
||||
}
|
||||
|
||||
void RootView::displayTooltip(std::string_view name, std::string_view help) {}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "specter/RootView.hpp"
|
||||
#include "specter/ViewResources.hpp"
|
||||
|
||||
#include <boo/graphicsdev/IGraphicsCommandQueue.hpp>
|
||||
|
||||
namespace specter {
|
||||
#define MAX_SCROLL_SPEED 100
|
||||
|
||||
|
@ -19,8 +21,8 @@ ScrollView::ScrollView(ViewResources& res, View& parentView, Style style)
|
|||
});
|
||||
|
||||
if (style == Style::SideButtons) {
|
||||
m_sideButtons[0].m_view.reset(new Button(res, *this, &m_sideButtonBind, "<"));
|
||||
m_sideButtons[1].m_view.reset(new Button(res, *this, &m_sideButtonBind, ">"));
|
||||
m_sideButtons[0].m_view = std::make_unique<Button>(res, *this, &m_sideButtonBind, "<");
|
||||
m_sideButtons[1].m_view = std::make_unique<Button>(res, *this, &m_sideButtonBind, ">");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -4,11 +4,9 @@
|
|||
#include "specter/RootView.hpp"
|
||||
#include "specter/ViewResources.hpp"
|
||||
|
||||
#include <logvisor/logvisor.hpp>
|
||||
#include <boo/graphicsdev/IGraphicsCommandQueue.hpp>
|
||||
|
||||
namespace specter {
|
||||
static logvisor::Module Log("specter::Space");
|
||||
|
||||
#define TRIANGLE_DIM 12
|
||||
#define TRIANGLE_DIM1 10
|
||||
#define TRIANGLE_DIM2 8
|
||||
|
@ -43,10 +41,12 @@ Space::Space(ViewResources& res, View& parentView, ISpaceController& controller,
|
|||
return true;
|
||||
});
|
||||
setBackground(res.themeData().spaceBackground());
|
||||
if (controller.spaceSplitAllowed())
|
||||
m_cornerView.m_view.reset(new CornerView(res, *this, TriColor));
|
||||
if (tbPos != Toolbar::Position::None)
|
||||
m_toolbar.m_view.reset(new Toolbar(res, *this, tbPos, tbUnits));
|
||||
if (controller.spaceSplitAllowed()) {
|
||||
m_cornerView.m_view = std::make_unique<CornerView>(res, *this, TriColor);
|
||||
}
|
||||
if (tbPos != Toolbar::Position::None) {
|
||||
m_toolbar.m_view = std::make_unique<Toolbar>(res, *this, tbPos, tbUnits);
|
||||
}
|
||||
}
|
||||
|
||||
Space::~Space() = default;
|
||||
|
|
|
@ -1,8 +1,11 @@
|
|||
#include "logvisor/logvisor.hpp"
|
||||
#include "specter/SplitView.hpp"
|
||||
|
||||
#include "specter/Space.hpp"
|
||||
#include "specter/RootView.hpp"
|
||||
#include "specter/ViewResources.hpp"
|
||||
#include "specter/Space.hpp"
|
||||
|
||||
#include <boo/graphicsdev/IGraphicsCommandQueue.hpp>
|
||||
#include <logvisor/logvisor.hpp>
|
||||
|
||||
namespace specter {
|
||||
static logvisor::Module Log("specter::SplitView");
|
||||
|
|
|
@ -2,9 +2,12 @@
|
|||
|
||||
#include "specter/RootView.hpp"
|
||||
#include "specter/ScrollView.hpp"
|
||||
|
||||
#include "specter/TextView.hpp"
|
||||
#include "specter/ViewResources.hpp"
|
||||
|
||||
#include <boo/graphicsdev/IGraphicsCommandQueue.hpp>
|
||||
|
||||
namespace specter {
|
||||
static logvisor::Module Log("specter::Table");
|
||||
#define ROW_HEIGHT 18
|
||||
|
@ -40,12 +43,13 @@ Table::Table(ViewResources& res, View& parentView, ITableDataBinding* data, ITab
|
|||
, m_data(data)
|
||||
, m_state(state)
|
||||
, m_maxColumns(maxColumns)
|
||||
, m_hVerts(new SolidShaderVert[maxColumns * 6])
|
||||
, m_hVerts(std::make_unique<SolidShaderVert[]>(maxColumns * 6))
|
||||
, m_rowsView(*this, res) {
|
||||
if (!maxColumns)
|
||||
if (maxColumns == 0) {
|
||||
Log.report(logvisor::Fatal, fmt("0-column tables not supported"));
|
||||
}
|
||||
|
||||
m_scroll.m_view.reset(new ScrollView(res, *this, ScrollView::Style::ThinIndicator));
|
||||
m_scroll.m_view = std::make_unique<ScrollView>(res, *this, ScrollView::Style::ThinIndicator);
|
||||
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool {
|
||||
buildResources(ctx, res);
|
||||
|
@ -60,7 +64,7 @@ Table::Table(ViewResources& res, View& parentView, ITableDataBinding* data, ITab
|
|||
Table::~Table() = default;
|
||||
|
||||
Table::RowsView::RowsView(Table& t, ViewResources& res)
|
||||
: View(res, t), m_t(t), m_verts(new SolidShaderVert[SPECTER_TABLE_MAX_ROWS * t.m_maxColumns * 6]) {
|
||||
: View(res, t), m_t(t), m_verts(std::make_unique<SolidShaderVert[]>(SPECTER_TABLE_MAX_ROWS * t.m_maxColumns * 6)) {
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool {
|
||||
buildResources(ctx, res);
|
||||
m_vertsBinding.init(ctx, res, SPECTER_TABLE_MAX_ROWS * t.m_maxColumns * 6, m_viewVertBlockBuf);
|
||||
|
@ -69,7 +73,7 @@ Table::RowsView::RowsView(Table& t, ViewResources& res)
|
|||
}
|
||||
|
||||
Table::CellView::CellView(Table& t, ViewResources& res)
|
||||
: View(res, t), m_t(t), m_text(new TextView(res, *this, res.m_mainFont)) {}
|
||||
: View(res, t), m_t(t), m_text(std::make_unique<TextView>(res, *this, res.m_mainFont)) {}
|
||||
|
||||
void Table::_setHeaderVerts(const boo::SWindowRect& sub) {
|
||||
;
|
||||
|
@ -522,30 +526,33 @@ bool Table::CellView::reset(size_t c, size_t r) {
|
|||
|
||||
std::vector<Table::ColumnPool>& Table::ensureCellPools(size_t rows, size_t cols, ViewResources& res) {
|
||||
if (m_cellPools.size() < cols) {
|
||||
m_cellPools.reserve(cols);
|
||||
for (size_t i = m_cellPools.size(); i < cols; ++i)
|
||||
m_cellPools.emplace_back();
|
||||
m_cellPools.resize(cols);
|
||||
m_ensuredRows = 0;
|
||||
}
|
||||
if (m_ensuredRows < rows) {
|
||||
for (size_t i = 0; i < cols; ++i) {
|
||||
ColumnPool& cp = m_cellPools[i];
|
||||
if (rows > SPECTER_TABLE_MAX_ROWS) {
|
||||
for (int p = 0; p < 2; ++p)
|
||||
for (ViewChild<std::unique_ptr<CellView>>& cv : cp[p])
|
||||
if (!cv.m_view)
|
||||
cv.m_view.reset(new CellView(*this, res));
|
||||
for (int p = 0; p < 2; ++p) {
|
||||
for (ViewChild<std::unique_ptr<CellView>>& cv : cp[p]) {
|
||||
if (cv.m_view == nullptr) {
|
||||
cv.m_view = std::make_unique<CellView>(*this, res);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
size_t r = 0;
|
||||
for (ViewChild<std::unique_ptr<CellView>>& cv : cp[0]) {
|
||||
if (!cv.m_view)
|
||||
cv.m_view.reset(new CellView(*this, res));
|
||||
if (cv.m_view == nullptr) {
|
||||
cv.m_view = std::make_unique<CellView>(*this, res);
|
||||
}
|
||||
++r;
|
||||
if (r >= rows)
|
||||
if (r >= rows) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_ensuredRows = rows;
|
||||
}
|
||||
return m_cellPools;
|
||||
|
@ -566,9 +573,7 @@ void Table::_updateData() {
|
|||
if (newViewChildren) {
|
||||
m_headerViews.clear();
|
||||
m_cellPools.clear();
|
||||
m_headerViews.reserve(m_columns);
|
||||
for (size_t c = 0; c < m_columns; ++c)
|
||||
m_headerViews.emplace_back();
|
||||
m_headerViews.resize(m_columns);
|
||||
m_ensuredRows = 0;
|
||||
}
|
||||
ensureCellPools(m_rows, m_columns, res);
|
||||
|
@ -580,10 +585,12 @@ void Table::_updateData() {
|
|||
|
||||
for (size_t c = 0; c < m_columns; ++c) {
|
||||
std::unique_ptr<CellView>& cv = m_headerViews[c].m_view;
|
||||
if (!cv)
|
||||
cv.reset(new CellView(*this, res));
|
||||
if (cv->reset(c))
|
||||
if (cv == nullptr) {
|
||||
cv = std::make_unique<CellView>(*this, res);
|
||||
}
|
||||
if (cv->reset(c)) {
|
||||
m_header = true;
|
||||
}
|
||||
|
||||
ColumnPool& col = m_cellPools[c];
|
||||
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "specter/TextView.hpp"
|
||||
#include "specter/ViewResources.hpp"
|
||||
|
||||
#include <boo/graphicsdev/IGraphicsCommandQueue.hpp>
|
||||
|
||||
namespace specter {
|
||||
|
||||
TextField::TextField(ViewResources& res, View& parentView, IStringBinding* strBind)
|
||||
|
@ -19,10 +21,11 @@ TextField::TextField(ViewResources& res, View& parentView, IStringBinding* strBi
|
|||
setInactive();
|
||||
m_vertsBinding.load<decltype(m_verts)>(m_verts);
|
||||
|
||||
m_text.reset(new TextView(res, *this, res.m_mainFont, TextView::Alignment::Left, 1024));
|
||||
if (strBind)
|
||||
m_text = std::make_unique<TextView>(res, *this, res.m_mainFont, TextView::Alignment::Left, 1024);
|
||||
if (strBind != nullptr) {
|
||||
setText(strBind->getDefault(this));
|
||||
}
|
||||
}
|
||||
|
||||
TextField::~TextField() = default;
|
||||
|
||||
|
@ -603,7 +606,7 @@ void TextField::setErrorState(std::string_view message) {
|
|||
clearSelectionRange();
|
||||
refreshBg();
|
||||
|
||||
m_errText.reset(new TextView(rootView().viewRes(), *this, rootView().viewRes().m_mainFont));
|
||||
m_errText = std::make_unique<TextView>(rootView().viewRes(), *this, rootView().viewRes().m_mainFont);
|
||||
m_errText->typesetGlyphs(message, rootView().themeData().uiText());
|
||||
|
||||
updateSize();
|
||||
|
|
|
@ -1,12 +1,15 @@
|
|||
#include "logvisor/logvisor.hpp"
|
||||
#include "specter/Toolbar.hpp"
|
||||
#include "specter/ViewResources.hpp"
|
||||
|
||||
#include "specter/RootView.hpp"
|
||||
#include "specter/ViewResources.hpp"
|
||||
|
||||
#include <boo/graphicsdev/IGraphicsCommandQueue.hpp>
|
||||
#include <logvisor/logvisor.hpp>
|
||||
|
||||
#define TOOLBAR_PADDING 10
|
||||
|
||||
namespace specter {
|
||||
static logvisor::Module Log("specter::Space");
|
||||
static logvisor::Module Log("specter::Toolbar");
|
||||
|
||||
static const zeus::RGBA32 Tex[] = {{{255, 255, 255, 64}}, {{255, 255, 255, 64}}, {{0, 0, 0, 64}}, {{0, 0, 0, 64}}};
|
||||
|
||||
|
@ -17,11 +20,9 @@ void Toolbar::Resources::init(boo::IGraphicsDataFactory::Context& ctx, const ITh
|
|||
Toolbar::Toolbar(ViewResources& res, View& parentView, Position tbPos, unsigned units)
|
||||
: View(res, parentView)
|
||||
, m_units(units)
|
||||
, m_children(units)
|
||||
, m_nomGauge(res.pixelFactor() * SPECTER_TOOLBAR_GAUGE * units)
|
||||
, m_padding(res.pixelFactor() * TOOLBAR_PADDING) {
|
||||
m_children.reserve(units);
|
||||
for (unsigned u = 0; u < units; ++u)
|
||||
m_children.emplace_back();
|
||||
commitResources(res, [&](boo::IGraphicsDataFactory::Context& ctx) -> bool {
|
||||
buildResources(ctx, res);
|
||||
m_tbBlockBuf = res.m_viewRes.m_bufPool.allocateBlock(res.m_factory);
|
||||
|
@ -112,11 +113,13 @@ void Toolbar::setVerticalVerts(int height) {
|
|||
}
|
||||
|
||||
void Toolbar::push_back(View* v, unsigned unit) {
|
||||
if (unit >= m_units)
|
||||
if (unit >= m_units) {
|
||||
Log.report(logvisor::Fatal, fmt("unit {} out of range {}"), unit, m_units);
|
||||
std::vector<ViewChild<View*>>& u = m_children[unit];
|
||||
u.emplace_back();
|
||||
u.back().m_view = v;
|
||||
}
|
||||
|
||||
std::vector<ViewChild<View*>>& children = m_children[unit];
|
||||
auto& child = children.emplace_back();
|
||||
child.m_view = v;
|
||||
}
|
||||
|
||||
void Toolbar::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub) {
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "specter/RootView.hpp"
|
||||
#include "specter/ViewResources.hpp"
|
||||
|
||||
#include <boo/graphicsdev/IGraphicsCommandQueue.hpp>
|
||||
|
||||
namespace specter {
|
||||
|
||||
#define TOOLTIP_MAX_WIDTH 316
|
||||
|
@ -22,8 +24,8 @@ Tooltip::Tooltip(ViewResources& res, View& parentView, std::string_view title, s
|
|||
});
|
||||
|
||||
for (int i = 0; i < 4; ++i) {
|
||||
m_cornersOutline[i].reset(new TextView(res, *this, res.m_curveFont, TextView::Alignment::Left, 1));
|
||||
m_cornersFilled[i].reset(new TextView(res, *this, res.m_curveFont, TextView::Alignment::Left, 1));
|
||||
m_cornersOutline[i] = std::make_unique<TextView>(res, *this, res.m_curveFont, TextView::Alignment::Left, 1);
|
||||
m_cornersFilled[i] = std::make_unique<TextView>(res, *this, res.m_curveFont, TextView::Alignment::Left, 1);
|
||||
}
|
||||
m_cornersOutline[0]->typesetGlyphs(L"\xF4F0");
|
||||
m_cornersFilled[0]->typesetGlyphs(L"\xF4F1", res.themeData().tooltipBackground());
|
||||
|
@ -34,9 +36,9 @@ Tooltip::Tooltip(ViewResources& res, View& parentView, std::string_view title, s
|
|||
m_cornersOutline[3]->typesetGlyphs(L"\xF4F6");
|
||||
m_cornersFilled[3]->typesetGlyphs(L"\xF4F7", res.themeData().tooltipBackground());
|
||||
|
||||
m_title.reset(new TextView(res, *this, res.m_heading14));
|
||||
m_title = std::make_unique<TextView>(res, *this, res.m_heading14);
|
||||
m_title->typesetGlyphs(m_titleStr);
|
||||
m_message.reset(new MultiLineTextView(res, *this, res.m_mainFont));
|
||||
m_message = std::make_unique<MultiLineTextView>(res, *this, res.m_mainFont);
|
||||
m_message->typesetGlyphs(m_messageStr, zeus::skWhite, int(TOOLTIP_MAX_TEXT_WIDTH * res.pixelFactor()));
|
||||
|
||||
float pf = res.pixelFactor();
|
||||
|
|
|
@ -5,11 +5,8 @@
|
|||
|
||||
#include <boo/System.hpp>
|
||||
#include <hecl/Pipeline.hpp>
|
||||
#include <logvisor/logvisor.hpp>
|
||||
|
||||
namespace specter {
|
||||
static logvisor::Module Log("specter::View");
|
||||
|
||||
zeus::CMatrix4f g_PlatformMatrix;
|
||||
|
||||
void View::Resources::init(boo::IGraphicsDataFactory::Context& ctx, const IThemeData& theme) {
|
||||
|
|
|
@ -1 +1 @@
|
|||
Subproject commit c5d90a5d5efe436d1a06568be911cfafa973dd83
|
||||
Subproject commit bf416af1edc715f73d3d363d0d9f40c33b657dc3
|
Loading…
Reference in New Issue