完成config方便获取值
TODO DPI缩放
This commit is contained in:
@@ -66,6 +66,7 @@ int main(int argc, char* argv[]) {
|
||||
const auto& config_info_str = utf8::utf8to32(ss.str());
|
||||
|
||||
const auto& window = mwindow::create({ 800, 600 }, L"Hello, World!");
|
||||
window->show();
|
||||
window->set_content(
|
||||
mnew(mv_box)
|
||||
[
|
||||
@@ -107,6 +108,7 @@ int main(int argc, char* argv[]) {
|
||||
);
|
||||
|
||||
const auto& window2 = mwindow::create({800, 600}, L"Hello, World!");
|
||||
window2->show();
|
||||
window2->set_content(
|
||||
mnew(moverlay)
|
||||
[
|
||||
|
||||
@@ -14,19 +14,11 @@
|
||||
#include <stop_token>
|
||||
|
||||
namespace config_convert {
|
||||
// 对于一般类型,返回原值
|
||||
template<typename T> requires (!std::is_pointer_v<std::decay_t<T>> || !std::is_same_v<
|
||||
std::remove_cv_t<std::remove_pointer_t<std::decay_t<T>>>, char>)
|
||||
decltype(auto) convert(T&& in) noexcept { return std::forward<T>(in); }
|
||||
|
||||
// 对于 const char* 和 char*
|
||||
template<typename T> requires std::is_pointer_v<std::decay_t<T>> && std::is_same_v<
|
||||
std::remove_cv_t<std::remove_pointer_t<std::decay_t<T>>>, char>
|
||||
std::string convert(T&& in) { return in ? std::string(in) : std::string{}; }
|
||||
|
||||
// 对于字符数组
|
||||
template<size_t N>
|
||||
std::string convert(const char (&in)[N]) { return std::string(in); }
|
||||
// 概念:检查是否是字符串类型
|
||||
template<typename U>
|
||||
concept StringLike = std::is_same_v<std::decay_t<U>, const char*> ||
|
||||
(std::is_array_v<std::remove_reference_t<U>> &&
|
||||
std::is_same_v<std::remove_extent_t<std::remove_reference_t<U>>, char>);
|
||||
}
|
||||
|
||||
struct config_options_t {
|
||||
@@ -41,8 +33,6 @@ public:
|
||||
using callback_t = std::function<void(const toml::table&)>;
|
||||
using clock_t = std::chrono::steady_clock;
|
||||
|
||||
|
||||
|
||||
[[nodiscard]] static auto& get() {
|
||||
static T instance;
|
||||
return instance;
|
||||
@@ -118,43 +108,42 @@ public:
|
||||
// 线程安全的带默认值获取
|
||||
template<typename T_Value, typename... Ks>
|
||||
requires (std::convertible_to<Ks, std::string_view> && ...)
|
||||
[[nodiscard]] auto get_or(const T_Value& default_value, const Ks&... keys) const
|
||||
-> decltype(config_convert::convert(default_value)) {
|
||||
[[nodiscard]] auto get_or(const T_Value& default_value, const Ks&... keys) const {
|
||||
std::shared_lock lock(mutex_);
|
||||
|
||||
using return_t = decltype(config_convert::convert(default_value));
|
||||
|
||||
if (auto node = get_unlocked(keys...)) {
|
||||
// 其他类型正常处理
|
||||
if (auto value = node->template value<return_t>()) {
|
||||
return config_convert::convert(*value);
|
||||
if constexpr (config_convert::StringLike<T_Value>) {
|
||||
// 字符串类型,从TOML获取std::string
|
||||
if (auto value = node->template value<std::string>()) { return *value; }
|
||||
return std::string(default_value);
|
||||
}
|
||||
else {
|
||||
// 其他类型
|
||||
if (auto value = node->template value<T_Value>()) { return *value; }
|
||||
return default_value;
|
||||
}
|
||||
}
|
||||
|
||||
return config_convert::convert(default_value);
|
||||
// 返回默认值
|
||||
if constexpr (config_convert::StringLike<T_Value>) { return std::string(default_value); }
|
||||
else { return default_value; }
|
||||
}
|
||||
|
||||
// 线程安全的类型获取
|
||||
template<typename T_Value, typename... Ks> requires (std::convertible_to<Ks, std::string_view> && ...)
|
||||
[[nodiscard]] auto get_as(
|
||||
const Ks&... keys) const noexcept {
|
||||
template<typename T_Value, typename... Ks>
|
||||
requires (std::convertible_to<Ks, std::string_view> && ...)
|
||||
[[nodiscard]] auto get_as(const Ks&... keys) const
|
||||
-> std::optional<std::conditional_t<config_convert::StringLike<T_Value>, std::string, T_Value>> {
|
||||
|
||||
std::shared_lock lock(mutex_);
|
||||
|
||||
if constexpr (std::is_same_v<T_Value, const char[]>) {
|
||||
// 对于 const char*,返回 std::optional<std::string>
|
||||
if (auto node = get_unlocked(keys...)) {
|
||||
return node->template value<std::string>();
|
||||
if constexpr (config_convert::StringLike<T_Value>) { return node->template value<std::string>(); }
|
||||
else { return node->template value<T_Value>(); }
|
||||
}
|
||||
|
||||
return std::nullopt;
|
||||
}
|
||||
else {
|
||||
// 其他类型保持原有逻辑
|
||||
if (auto node = get_unlocked(keys...)) {
|
||||
return node->template value<T_Value>();
|
||||
}
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
// 便捷的字符串获取方法
|
||||
template<typename... Ks> requires (std::convertible_to<Ks, std::string_view> && ...)
|
||||
|
||||
2
src/mirage_config/third_party/tomlplusplus
vendored
2
src/mirage_config/third_party/tomlplusplus
vendored
Submodule src/mirage_config/third_party/tomlplusplus updated: fea1d905f2...2f35c28a52
Submodule src/mirage_render/font/freetype_font/freetype updated: 82090e67c2...42a649be49
Submodule src/mirage_render/font/freetype_font/harfbuzz updated: 9f83bbbe64...e1dcc454f1
@@ -44,7 +44,7 @@ bool freetype_interface::supports_color_emoji() const {
|
||||
return FT_HAS_COLOR(face_) || FT_HAS_SBIX(face_) || FT_HAS_SVG(face_);
|
||||
}
|
||||
|
||||
font_v_metrics_t freetype_interface::get_metrics() const {
|
||||
font_v_metrics_t freetype_interface::get_metrics_impl() const {
|
||||
font_v_metrics_t metrics{};
|
||||
// 使用当前字体大小下的度量信息
|
||||
metrics.ascent = face_->size->metrics.ascender >> 6;
|
||||
|
||||
@@ -7,7 +7,7 @@ public:
|
||||
[[nodiscard]] std::string get_font_family() const override;
|
||||
[[nodiscard]] std::string get_font_style() const override;
|
||||
[[nodiscard]] bool supports_color_emoji() const override;
|
||||
[[nodiscard]] font_v_metrics_t get_metrics() const override;
|
||||
[[nodiscard]] font_v_metrics_t get_metrics_impl() const override;
|
||||
[[nodiscard]] std::shared_ptr<image_heap_t> get_glyph_image(int32_t in_glyph_id) const override;
|
||||
[[nodiscard]] std::shared_ptr<image_heap_t> get_emoji_image(int32_t in_glyph_id) const override;
|
||||
[[nodiscard]] uint32_t find_glyph_index(uint32_t in_unicode_codepoint) const override;
|
||||
|
||||
@@ -106,7 +106,16 @@ Eigen::Vector2i platform_window::get_window_frame_size() const {
|
||||
return { 0, 0 };
|
||||
}
|
||||
|
||||
float platform_window::get_window_dpi_scale() const { return 1.f; }
|
||||
float platform_window::get_window_dpi_scale() const {
|
||||
// 获取窗口 DPI 缩放比例
|
||||
if (HDC hdc = GetDC(WINDOW_HANDLE)) {
|
||||
int dpiX = GetDeviceCaps(hdc, LOGPIXELSX);
|
||||
int dpiY = GetDeviceCaps(hdc, LOGPIXELSY);
|
||||
ReleaseDC(WINDOW_HANDLE, hdc);
|
||||
return static_cast<float>(dpiX) / 96.0f; // 96 DPI 是标准 DPI
|
||||
}
|
||||
return 1.0f; // 默认 DPI 缩放比例
|
||||
}
|
||||
|
||||
Eigen::Vector2i platform_window::get_window_position() const {
|
||||
RECT rect;
|
||||
|
||||
@@ -294,11 +294,12 @@ void meditable_text_box::update_layout(const geometry_t& in_geometry, bool in_la
|
||||
invalidate(invalidate_reason::layout);
|
||||
}
|
||||
|
||||
layout_.set_font_size(font_size_ * get_dpi_scale());
|
||||
layout_.clear();
|
||||
layout_.push_str(temp_text_);
|
||||
|
||||
text_layout_t temp_layout{};
|
||||
temp_layout.set_font_size(font_size_);
|
||||
temp_layout.set_font_size(font_size_ * get_dpi_scale());
|
||||
temp_layout.set_primary_font(font_);
|
||||
temp_layout.set_line_spacing(line_spacing_);
|
||||
temp_layout.set_max_width(max_width);
|
||||
|
||||
@@ -57,7 +57,7 @@ private:
|
||||
size_t cursor_y_ = 0; // 行索引
|
||||
|
||||
text_layout_t layout_{};
|
||||
std::u32string text_; // 最终显示的文本
|
||||
std::u32string temp_text_; // 当前输入的文本
|
||||
std::u32string text_{}; // 最终显示的文本
|
||||
std::u32string temp_text_{}; // 当前输入的文本
|
||||
font_face_ptr font_;
|
||||
};
|
||||
|
||||
@@ -12,7 +12,6 @@ void mtext_block::setup_widget(const text_block_args& in_args) {
|
||||
font_size_ = in_args.font_size();
|
||||
line_spacing_ = in_args.line_spacing();
|
||||
warp_text_ = in_args.warp_text();
|
||||
update_no_wrap_size();
|
||||
}
|
||||
|
||||
void mtext_block::on_paint(mirage_paint_context& in_context) {
|
||||
@@ -39,20 +38,22 @@ void mtext_block::arrange_children(const geometry_t& in_allotted_geometry) {
|
||||
return;
|
||||
}
|
||||
max_width = current_width;
|
||||
invalidate(invalidate_reason::layout);
|
||||
}
|
||||
|
||||
layout_.set_font_size(font_size_);
|
||||
update_no_wrap_size();
|
||||
layout_.set_font_size(font_size_ * get_dpi_scale());
|
||||
layout_.set_primary_font(font_);
|
||||
layout_.set_line_spacing(line_spacing_);
|
||||
layout_.set_max_width(max_width);
|
||||
layout_.clear();
|
||||
layout_.push_str(text_);
|
||||
|
||||
invalidate(invalidate_reason::layout);
|
||||
}
|
||||
|
||||
void mtext_block::update_no_wrap_size() {
|
||||
text_layout_t temp_layout{};
|
||||
temp_layout.set_font_size(font_size_);
|
||||
temp_layout.set_font_size(font_size_ * get_dpi_scale());
|
||||
temp_layout.set_primary_font(font_);
|
||||
temp_layout.set_line_spacing(line_spacing_);
|
||||
temp_layout.push_str(text_);
|
||||
@@ -61,5 +62,5 @@ void mtext_block::update_no_wrap_size() {
|
||||
// 如果没有任何内容, 将大小设置为0
|
||||
if (no_warp_size_.x() == 0)
|
||||
no_warp_size_.y() = 0;
|
||||
invalidate(invalidate_reason::layout);
|
||||
// invalidate(invalidate_reason::layout);
|
||||
}
|
||||
|
||||
@@ -58,7 +58,6 @@ public:
|
||||
auto& push_slot(const SlotType& in_slot) {
|
||||
const auto& child_widget = in_slot.get();
|
||||
on_set_content(child_widget);
|
||||
this->invalidate(invalidate_reason::layout);
|
||||
auto shared_this = this->shared_from_this();
|
||||
|
||||
slot_ = in_slot;
|
||||
@@ -69,6 +68,8 @@ public:
|
||||
if (slot_.has_visibility()) {
|
||||
child_widget->set_visibility(slot_.visibility());
|
||||
}
|
||||
child_widget->on_into_window();
|
||||
this->invalidate(invalidate_reason::all);
|
||||
return slot_;
|
||||
}
|
||||
auto operator[](const SlotType& in_slot) {
|
||||
|
||||
@@ -84,6 +84,7 @@ public:
|
||||
if (slot.has_visibility()) {
|
||||
child_widget->set_visibility(slot.visibility());
|
||||
}
|
||||
child_widget->on_into_window();
|
||||
this->invalidate(invalidate_reason::all);
|
||||
return slot;
|
||||
}
|
||||
@@ -101,6 +102,7 @@ public:
|
||||
if (slot.has_visibility()) {
|
||||
child_widget->set_visibility(slot.visibility());
|
||||
}
|
||||
child_widget->on_into_window();
|
||||
this->invalidate(invalidate_reason::all);
|
||||
return slot;
|
||||
}
|
||||
@@ -116,6 +118,7 @@ public:
|
||||
if (slot.has_visibility()) {
|
||||
child_widget->set_visibility(slot.visibility());
|
||||
}
|
||||
child_widget->on_into_window();
|
||||
this->invalidate(invalidate_reason::all);
|
||||
return slot;
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ public:
|
||||
}
|
||||
|
||||
virtual void init() {}
|
||||
|
||||
virtual void on_into_window() {}
|
||||
virtual void on_tick(const duration_type& in_delta) {}
|
||||
virtual void on_paint(mirage_paint_context& in_context) = 0;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user