mirror of
https://github.com/zhenyan121/Cubed.git
synced 2026-08-09 02:07:04 +08:00
feat(ui): add TextField widget with UTF-8 text input support
This commit is contained in:
@@ -36,5 +36,8 @@ protected:
|
||||
return false;
|
||||
}
|
||||
virtual bool handle_key_event(const KeyEvent&) { return false; }
|
||||
virtual bool handle_text_input_event(const TextInputEvent&) {
|
||||
return false;
|
||||
}
|
||||
};
|
||||
} // namespace Cubed
|
||||
41
include/Cubed/tools/text_tools.hpp
Normal file
41
include/Cubed/tools/text_tools.hpp
Normal file
@@ -0,0 +1,41 @@
|
||||
#pragma once
|
||||
#include <cstdint>
|
||||
#include <string>
|
||||
namespace Cubed {
|
||||
inline std::string codepoint_to_utf8(uint32_t cp) {
|
||||
std::string out;
|
||||
|
||||
if (cp <= 0x7F) {
|
||||
out.push_back(static_cast<char>(cp));
|
||||
} else if (cp <= 0x7FF) {
|
||||
out.push_back(static_cast<char>(0xC0 | (cp >> 6)));
|
||||
out.push_back(static_cast<char>(0x80 | (cp & 0x3F)));
|
||||
} else if (cp <= 0xFFFF) {
|
||||
out.push_back(static_cast<char>(0xE0 | (cp >> 12)));
|
||||
out.push_back(static_cast<char>(0x80 | ((cp >> 6) & 0x3F)));
|
||||
out.push_back(static_cast<char>(0x80 | (cp & 0x3F)));
|
||||
} else {
|
||||
out.push_back(static_cast<char>(0xF0 | (cp >> 18)));
|
||||
out.push_back(static_cast<char>(0x80 | ((cp >> 12) & 0x3F)));
|
||||
out.push_back(static_cast<char>(0x80 | ((cp >> 6) & 0x3F)));
|
||||
out.push_back(static_cast<char>(0x80 | (cp & 0x3F)));
|
||||
}
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
inline void utf8_pop_back(std::string& str) {
|
||||
if (str.empty()) {
|
||||
return;
|
||||
}
|
||||
|
||||
std::size_t i = str.size() - 1;
|
||||
|
||||
while (i > 0 && (static_cast<unsigned char>(str[i]) & 0xC0) == 0x80) {
|
||||
--i;
|
||||
}
|
||||
|
||||
str.erase(i);
|
||||
}
|
||||
|
||||
} // namespace Cubed
|
||||
65
include/Cubed/ui/text_field.hpp
Normal file
65
include/Cubed/ui/text_field.hpp
Normal file
@@ -0,0 +1,65 @@
|
||||
#pragma once
|
||||
|
||||
#include "Cubed/ui/image.hpp"
|
||||
#include "Cubed/ui/label.hpp"
|
||||
#include "Cubed/ui/widget.hpp"
|
||||
namespace Cubed {
|
||||
class TextField : public Widget {
|
||||
public:
|
||||
TextField(const TextField&) = delete;
|
||||
TextField(TextField&&) = delete;
|
||||
TextField& operator=(const TextField&) = delete;
|
||||
TextField& operator=(TextField&&) = delete;
|
||||
TextField(Widget* parent);
|
||||
|
||||
TextField& set_scale(float scale);
|
||||
|
||||
float width() const override;
|
||||
float height() const override;
|
||||
|
||||
TextField& set_width(float width);
|
||||
TextField& set_height(float height);
|
||||
TextField& set_show_text(const std::string& text);
|
||||
TextField& set_background_image(const std::string& path,
|
||||
TextureManager& texture_manager);
|
||||
TextField& set_default_image(TextureManager& texture_manager);
|
||||
TextField& set_auto_scale(bool auto_scale);
|
||||
bool handle_mouse_move_event(const MouseMoveEvent& e) override;
|
||||
bool handle_mouse_button_event(const MouseButtonEvent& e) override;
|
||||
bool handle_text_input_event(const TextInputEvent& e) override;
|
||||
bool handle_key_event(const KeyEvent& e) override;
|
||||
|
||||
const std::string& input_text() const;
|
||||
|
||||
template <typename F> TextField& set_on_finish(F&& f) {
|
||||
m_on_finished = std::forward<F>(f);
|
||||
return *this;
|
||||
}
|
||||
|
||||
private:
|
||||
static constexpr float PADDING = 5.0f;
|
||||
static constexpr float DEFAULT_SCALE = 3.0f;
|
||||
static constexpr float TEXT_SCALE = 0.6f;
|
||||
|
||||
static constexpr const char* DEFAULT_TEXT_FIELD_IMAGE =
|
||||
"texture/ui/textfield001.png";
|
||||
std::unique_ptr<Image> m_background;
|
||||
std::unique_ptr<Label> m_foreground;
|
||||
bool m_inside = false;
|
||||
bool m_typing = false;
|
||||
bool m_auto_scale = false;
|
||||
|
||||
float m_width = NORMAL_TEXTFIELD_WIDTH;
|
||||
float m_height = NORMAL_TEXTFIELD_HEIGHT;
|
||||
float m_scale = DEFAULT_SCALE;
|
||||
|
||||
std::string m_input_text;
|
||||
std::string m_show_text;
|
||||
|
||||
std::function<void()> m_on_finished;
|
||||
void update_text_scale();
|
||||
void on_render(Renderer& renderer) override;
|
||||
void on_update(float dt) override;
|
||||
void update_show_text();
|
||||
};
|
||||
} // namespace Cubed
|
||||
@@ -26,6 +26,7 @@ public:
|
||||
virtual bool handle_window_resize_event(const WindowResizeEvent& e);
|
||||
virtual bool handle_mouse_wheel_event(const MouseWheelEvent& e);
|
||||
virtual bool handle_key_event(const KeyEvent& e);
|
||||
virtual bool handle_text_input_event(const TextInputEvent& e);
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Widget> m_root_widget;
|
||||
|
||||
@@ -12,10 +12,16 @@ constexpr float NORMAL_BUTTON_WIDTH = 225.0f;
|
||||
constexpr float NORMAL_BUTTON_HEIGHT = 20.0f;
|
||||
constexpr float NORMAL_SLIDER_WIDTH = 225.0f;
|
||||
constexpr float NORMAL_SLIDER_HEIGHT = 20.0f;
|
||||
|
||||
constexpr float NORMAL_TEXTFIELD_WIDTH = 225.0f;
|
||||
constexpr float NORMAL_TEXTFIELD_HEIGHT = 20.0f;
|
||||
class Widget {
|
||||
|
||||
public:
|
||||
Widget(const Widget&) = delete;
|
||||
Widget(Widget&&) = delete;
|
||||
Widget& operator=(const Widget&) = delete;
|
||||
Widget& operator=(Widget&&) = delete;
|
||||
|
||||
Widget(const std::string& id, Widget* parent);
|
||||
Widget(Widget* parent);
|
||||
virtual ~Widget() = default;
|
||||
@@ -35,7 +41,7 @@ public:
|
||||
virtual bool handle_mouse_wheel_event(const MouseWheelEvent& e);
|
||||
virtual bool handle_window_resize_event(const WindowResizeEvent& e);
|
||||
virtual bool handle_mouse_move_event(const MouseMoveEvent& e);
|
||||
|
||||
virtual bool handle_text_input_event(const TextInputEvent& e);
|
||||
template <typename T, typename... Args> T& add_child(Args&&... args) {
|
||||
auto widget = std::make_unique<T>(std::forward<Args>(args)..., this);
|
||||
T& ref = *widget;
|
||||
|
||||
Reference in New Issue
Block a user