修复滚轮事件不是窗口内位置,新增slot可以覆盖控件的visibility
This commit is contained in:
parent
fb46da91d4
commit
fbf6e7e716
@ -18,7 +18,7 @@ int main(int argc, char* argv[]) {
|
||||
manager.add_font(L"C:/Windows/Fonts/seguiemj.ttf");
|
||||
|
||||
const auto& text_block = std::make_shared<mtext_block>();
|
||||
text_block->set_text(U"Hello, World! 你好,世界!\n换行测试1111,测试测试测试测试,测试测试😀🐵🙏");
|
||||
text_block->set_text(U"Hello, World! 你好,世界!\n换行测试1111,测试测试测试测试,测试测试😀🐵🙏 😃🐵🙏");
|
||||
|
||||
const auto& text_block2 = std::make_shared<mtext_block>();
|
||||
text_block2->set_text(U"Hello, World!");
|
||||
@ -26,12 +26,14 @@ int main(int argc, char* argv[]) {
|
||||
const auto button = mnew(mbutton)
|
||||
mslot(mbutton)
|
||||
.margin({10})
|
||||
.visibility(visibility_t::visible)
|
||||
[
|
||||
text_block
|
||||
];
|
||||
|
||||
const auto button2 = mnew(mbutton)
|
||||
mslot(mbutton)
|
||||
.visibility(visibility_t::visible)
|
||||
[
|
||||
text_block2
|
||||
];
|
||||
|
@ -23,12 +23,12 @@ void platform_window::handle_mouse_button_up(const Eigen::Vector2f& in_window_po
|
||||
on_mouse_button_up_delegate.broadcast(in_window_pos, in_button);
|
||||
}
|
||||
|
||||
void platform_window::handle_mouse_dbl_click(const Eigen::Vector2f& pos, mouse_button button) {
|
||||
on_mouse_button_dbl_delegate.broadcast(pos, button);
|
||||
void platform_window::handle_mouse_dbl_click(const Eigen::Vector2f& in_window_pos, mouse_button button) {
|
||||
on_mouse_button_dbl_delegate.broadcast(in_window_pos, button);
|
||||
}
|
||||
|
||||
void platform_window::handle_mouse_wheel(const Eigen::Vector2f& pos, wheel_event delta) {
|
||||
on_mouse_wheel_delegate.broadcast(pos, delta);
|
||||
void platform_window::handle_mouse_wheel(const Eigen::Vector2f& in_window_pos, wheel_event delta) {
|
||||
on_mouse_wheel_delegate.broadcast(in_window_pos, delta);
|
||||
}
|
||||
|
||||
void platform_window::handle_mouse_leave() {
|
||||
|
@ -179,17 +179,17 @@ public:
|
||||
|
||||
/**
|
||||
* @brief 处理鼠标双击事件
|
||||
* @param pos 窗口位置
|
||||
* @param in_window_pos 窗口位置
|
||||
* @param button 按下的按钮
|
||||
*/
|
||||
void handle_mouse_dbl_click(const Eigen::Vector2f& pos, mouse_button button);
|
||||
void handle_mouse_dbl_click(const Eigen::Vector2f& in_window_pos, mouse_button button);
|
||||
|
||||
/**
|
||||
* @brief 处理鼠标滚轮事件
|
||||
* @param pos 窗口位置
|
||||
* @param in_window_pos 窗口位置
|
||||
* @param delta 滚轮事件
|
||||
*/
|
||||
void handle_mouse_wheel(const Eigen::Vector2f& pos, wheel_event delta);
|
||||
void handle_mouse_wheel(const Eigen::Vector2f& in_window_pos, wheel_event delta);
|
||||
|
||||
/**
|
||||
* @brief 处理光标移出窗口事件
|
||||
|
@ -98,8 +98,15 @@ LRESULT CALLBACK WindowProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
const int x = LOWORD(lParam);
|
||||
const int y = HIWORD(lParam);
|
||||
const Eigen::Vector2f pos(static_cast<float>(x), static_cast<float>(y));
|
||||
POINT screen_point = { x, y };
|
||||
ScreenToClient(hwnd, &screen_point);
|
||||
|
||||
// 现在 screen_point.x 和 screen_point.y 包含相对于窗口客户区的坐标
|
||||
const Eigen::Vector2f client_pos(static_cast<float>(screen_point.x), static_cast<float>(screen_point.y));
|
||||
|
||||
// 计算滚轮事件的增量
|
||||
const auto delta = platform_event_to_wheel_event(uMsg, wParam, lParam);
|
||||
window->handle_mouse_wheel(pos, delta);
|
||||
window->handle_mouse_wheel(client_pos, delta);
|
||||
}
|
||||
processed = true;
|
||||
}
|
||||
|
@ -273,7 +273,7 @@ void render_elements::make_image(const Eigen::Vector2f& in_pos, const Eigen::Vec
|
||||
void render_elements::make_text(const text_layout_t& in_layout, const Eigen::Vector2f& in_pos,
|
||||
const Eigen::Vector2f& in_size, const geometry_t& in_geometry, const draw_effect& in_effect, const rect_color& in_color,
|
||||
float in_rotation_radians, const Eigen::Vector2f& in_pivot, const Eigen::Vector2f& in_scale) {
|
||||
const auto& glyph_sampler = texture_sampler_builder::get_sampler(sampler_type::anisotropic);
|
||||
const auto& glyph_sampler = texture_sampler_builder::get_sampler(sampler_type::pixel_art);
|
||||
const auto& emoji_sampler = texture_sampler_builder::get_sampler(sampler_type::anisotropic);
|
||||
|
||||
for (const auto& position : in_layout.glyphs) {
|
||||
|
@ -66,14 +66,6 @@ void mbutton::on_mouse_leave() {
|
||||
invalidate(invalidate_reason::paint);
|
||||
}
|
||||
|
||||
hit_test_handle mbutton::on_mouse_move(const Eigen::Vector2f& in_position) {
|
||||
mborder::on_mouse_move(in_position);
|
||||
// std::cout << this << ": Mouse moved!" << in_position.x() << ", " << in_position.y() << std::endl;
|
||||
color_ = {1, 1, 0, 1};
|
||||
invalidate(invalidate_reason::paint);
|
||||
return hit_test_handle::handled();
|
||||
}
|
||||
|
||||
hit_test_handle mbutton::on_mouse_button_down(const Eigen::Vector2f& in_position, mouse_button in_button) {
|
||||
mborder::on_mouse_button_down(in_position, in_button);
|
||||
std::cout << this << ": Mouse pressed!" << in_position.x() << ", " << in_position.y() << std::endl;
|
||||
@ -89,11 +81,3 @@ hit_test_handle mbutton::on_mouse_button_up(const Eigen::Vector2f& in_position,
|
||||
invalidate(invalidate_reason::paint);
|
||||
return hit_test_handle::handled();
|
||||
}
|
||||
|
||||
hit_test_handle mbutton::on_mouse_wheel(const Eigen::Vector2f& in_position, const wheel_event& in_delta) {
|
||||
mborder::on_mouse_wheel(in_position, in_delta);
|
||||
std::cout << this << ": Mouse wheeled!" << in_position.x() << ", " << in_position.y() << std::endl;
|
||||
color_ = {0, 1, 1, 1};
|
||||
invalidate(invalidate_reason::paint);
|
||||
return hit_test_handle::handled();
|
||||
}
|
||||
|
@ -12,10 +12,8 @@ public:
|
||||
virtual void on_double_click(const Eigen::Vector2f& in_position, mouse_button in_button) override;
|
||||
virtual void on_mouse_enter() override;
|
||||
virtual void on_mouse_leave() override;
|
||||
virtual hit_test_handle on_mouse_move(const Eigen::Vector2f& in_position) override;
|
||||
virtual hit_test_handle on_mouse_button_down(const Eigen::Vector2f& in_position, mouse_button in_button) override;
|
||||
virtual hit_test_handle on_mouse_button_up(const Eigen::Vector2f& in_position, mouse_button in_button) override;
|
||||
virtual hit_test_handle on_mouse_wheel(const Eigen::Vector2f& in_position, const wheel_event& in_delta) override;
|
||||
private:
|
||||
linear_color color_;
|
||||
};
|
||||
|
@ -20,6 +20,13 @@ auto mtext_block::compute_desired_size(float in_layout_scale_multiplier) const -
|
||||
return layout_.total_size;
|
||||
}
|
||||
|
||||
hit_test_handle mtext_block::on_mouse_wheel(const Eigen::Vector2f& in_position, const wheel_event& in_delta) {
|
||||
font_size_ += in_delta.delta_y;
|
||||
update_layout();
|
||||
return mleaf_widget::on_mouse_wheel(in_position, in_delta);
|
||||
}
|
||||
|
||||
void mtext_block::update_layout() {
|
||||
layout_ = font_manager::instance().layout_text(text_, font_, font_size_, max_width_, line_spacing_);
|
||||
invalidate(invalidate_reason::layout);
|
||||
}
|
||||
|
@ -39,7 +39,9 @@ public:
|
||||
auto get_line_spacing() const { return line_spacing_; }
|
||||
auto get_max_width() const { return max_width_; }
|
||||
|
||||
hit_test_handle on_mouse_move(const Eigen::Vector2f& in_position) override { return hit_test_handle::handled(); }
|
||||
auto compute_desired_size(float in_layout_scale_multiplier) const -> Eigen::Vector2f override;
|
||||
hit_test_handle on_mouse_wheel(const Eigen::Vector2f& in_position, const wheel_event& in_delta) override;
|
||||
private:
|
||||
void update_layout();
|
||||
|
||||
|
@ -37,6 +37,7 @@ struct mcompound_widget_slot {
|
||||
SLOT_CONTENT()
|
||||
SLOT_ATTRIBUTE(horizontal_alignment_t, h_alignment)
|
||||
SLOT_ATTRIBUTE(vertical_alignment_t, v_alignment)
|
||||
SLOT_OPTIONAL(visibility_t, visibility)
|
||||
};
|
||||
|
||||
/**
|
||||
@ -71,6 +72,9 @@ public:
|
||||
slot.set(in_widget);
|
||||
in_widget->init();
|
||||
in_widget->set_parent(shared_this);
|
||||
if (slot_.has_visibility()) {
|
||||
in_widget->set_visibility(slot_.visibility());
|
||||
}
|
||||
return slot;
|
||||
}
|
||||
auto& push_slot(const SlotType& in_slot) {
|
||||
@ -84,6 +88,9 @@ public:
|
||||
slot_.slot_owner = shared_this;
|
||||
child_widget->init();
|
||||
child_widget->set_parent(shared_this);
|
||||
if (slot_.has_visibility()) {
|
||||
child_widget->set_visibility(slot_.visibility());
|
||||
}
|
||||
return slot_;
|
||||
}
|
||||
|
||||
|
@ -34,6 +34,8 @@ struct mpanel_widget_slot {
|
||||
|
||||
// 插槽功能宏 - 定义内容管理
|
||||
SLOT_CONTENT()
|
||||
|
||||
SLOT_OPTIONAL(visibility_t, visibility)
|
||||
};
|
||||
|
||||
/**
|
||||
@ -79,6 +81,9 @@ public:
|
||||
const auto& child_widget = slot.get();
|
||||
child_widget->init();
|
||||
child_widget->set_parent(shared_this);
|
||||
if (slot.has_visibility()) {
|
||||
child_widget->set_visibility(slot.visibility());
|
||||
}
|
||||
invalidate(invalidate_reason::all);
|
||||
return slot;
|
||||
}
|
||||
@ -93,6 +98,9 @@ public:
|
||||
const auto& child_widget = slot.get();
|
||||
child_widget->init();
|
||||
child_widget->set_parent(shared_this);
|
||||
if (slot.has_visibility()) {
|
||||
child_widget->set_visibility(slot.visibility());
|
||||
}
|
||||
invalidate(invalidate_reason::all);
|
||||
return slot;
|
||||
}
|
||||
@ -105,6 +113,9 @@ public:
|
||||
const auto& child_widget = slot.get();
|
||||
child_widget->init();
|
||||
child_widget->set_parent(shared_this);
|
||||
if (slot.has_visibility()) {
|
||||
child_widget->set_visibility(slot.visibility());
|
||||
}
|
||||
invalidate(invalidate_reason::all);
|
||||
return slot;
|
||||
}
|
||||
|
@ -1,4 +1,5 @@
|
||||
#pragma once
|
||||
#include <optional>
|
||||
|
||||
#define SLOT_ME() auto& me() { return static_cast<T&>(*this) }
|
||||
|
||||
@ -12,6 +13,17 @@
|
||||
protected: \
|
||||
type name##_{};
|
||||
|
||||
#define SLOT_OPTIONAL(type, name) \
|
||||
public: \
|
||||
auto& name(type in_##name) { \
|
||||
name##_ = in_##name; \
|
||||
return me(); \
|
||||
} \
|
||||
const auto& name() const { return name##_.value(); } \
|
||||
auto has_##name() const { return name##_.has_value(); } \
|
||||
protected: \
|
||||
std::optional<type> name##_; \
|
||||
|
||||
#define SLOT_CONTENT() \
|
||||
public: \
|
||||
auto& set(const std::shared_ptr<mwidget>& in_widget) { \
|
||||
@ -26,22 +38,6 @@
|
||||
protected: \
|
||||
std::shared_ptr<mwidget> widget_{};
|
||||
|
||||
#define SLOT_OPTIONAL_ATTRIBUTE(type, name) \
|
||||
public: \
|
||||
auto& name(type in_##name) { \
|
||||
name##_ = in_##name; \
|
||||
return me(); \
|
||||
} \
|
||||
const auto& name() const { return name##_; } \
|
||||
auto& has_##name(bool in_has_##name) { \
|
||||
has_##name##_ = in_has_##name; \
|
||||
return me(); \
|
||||
} \
|
||||
const auto& has_##name() const { return has_##name##_; } \
|
||||
protected: \
|
||||
type name##_; \
|
||||
bool has_##name##_{};
|
||||
|
||||
#define SLOT_SIZE() \
|
||||
public: \
|
||||
auto& stretch(float in_stretch = 1.f) { \
|
||||
|
@ -84,6 +84,14 @@ void mwindow::invalidate_all() {
|
||||
pimpl_->invalidate_all();
|
||||
}
|
||||
|
||||
void mwindow::invalidate(invalidate_reason in_reason) {
|
||||
mwidget::invalidate(in_reason);
|
||||
// 如果窗口的布局发生变化,标记为需要重绘
|
||||
if (has_any_flag(in_reason, invalidate_reason::layout)) {
|
||||
invalidate(invalidate_reason::paint);
|
||||
}
|
||||
}
|
||||
|
||||
void mwindow::invalidate_rect(const Eigen::Vector2f& rect) {
|
||||
pimpl_->invalidate_rect(rect);
|
||||
}
|
||||
|
@ -113,6 +113,8 @@ public:
|
||||
*/
|
||||
void invalidate_all();
|
||||
|
||||
void invalidate(invalidate_reason in_reason) override;
|
||||
|
||||
/**
|
||||
* @brief 标记矩形区域需要重绘
|
||||
* @param rect 需要重绘的区域
|
||||
|
@ -185,7 +185,7 @@ public:
|
||||
return content_widget_;
|
||||
}
|
||||
|
||||
// 失效处理
|
||||
// 失效处理
|
||||
void invalidate_all() {
|
||||
invalidate_recursive(owner_, invalidate_reason::all);
|
||||
render_state_.needs_repaint = true;
|
||||
@ -367,10 +367,9 @@ public:
|
||||
}
|
||||
|
||||
void process_mouse_wheel(const Eigen::Vector2f& window_pos, wheel_event wheel_event) {
|
||||
std::shared_ptr<mwidget> hover_widget = mouse_.hover_widget.lock();
|
||||
if (hover_widget) {
|
||||
hover_widget->on_mouse_wheel(window_pos, wheel_event);
|
||||
}
|
||||
const auto& result = perform_hit_test(window_pos, [&](mwidget* widget, const Eigen::Vector2f& local_pos) {
|
||||
return widget->on_mouse_wheel(local_pos, wheel_event);
|
||||
});
|
||||
}
|
||||
|
||||
void process_mouse_leave() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user