LineEdit improvements and fixes

This commit is contained in:
mrkubax10 2024-01-30 18:09:34 +01:00
parent f382367980
commit dc67a81f9f
2 changed files with 30 additions and 46 deletions

View File

@ -46,7 +46,6 @@ LineEdit::LineEdit(engine::Engine* engine, Constraint* x, Constraint* y, Constra
m_text_texture(engine->get_master_renderer()->create_texture()),
m_text_buffer(),
m_text_offset_x(0),
m_text_offset(0),
m_glyph_info(),
m_prev_cursor_change(),
m_render_cursor(false),
@ -68,7 +67,6 @@ LineEdit::LineEdit(engine::Engine* engine, xml::XMLNode* node) :
m_text_texture(engine->get_master_renderer()->create_texture()),
m_text_buffer(),
m_text_offset_x(0),
m_text_offset(0),
m_glyph_info(),
m_prev_cursor_change(),
m_render_cursor(false),
@ -94,6 +92,9 @@ LineEdit::~LineEdit() {
void LineEdit::set_text(const std::string& text) {
m_text_buffer = text;
m_text_offset_x = 0;
m_cursor_x = 0;
m_cursor_offset = 0;
update_text_texture();
}
@ -101,9 +102,9 @@ void LineEdit::render(renderer::GUIRenderer* renderer) {
const float width = std::min(m_parent->get_right(), get_right())-get_x();
const float height = std::min(m_parent->get_bottom(), get_bottom())-get_y();
renderer->render_cropped_texture(math::Vector2f{get_x()+3, get_y()+height-m_text_texture->get_height()-3}, m_text_texture, math::Vector2f{1, 1},
math::Rect(m_text_offset, 0, width-2, m_text_texture->get_adapted_height()*2));
math::Rect(m_text_offset_x, 0, width-3, m_text_texture->get_adapted_height()*2));
if(m_render_cursor)
renderer->fill_rect(math::Vector2f{get_x()+3+m_cursor_x, get_y()+1}, math::Vector2f{2, height-3}, math::RGBAColor{0, 0, 0, 255});
renderer->fill_rect(math::Vector2f{get_x()+3+m_cursor_x-m_text_offset_x, get_y()+1}, math::Vector2f{2, height-3}, math::RGBAColor{0, 0, 0, 255});
if(m_highlighted && std::chrono::steady_clock::now()-m_prev_cursor_change>=std::chrono::duration<double>(0.5)) {
m_render_cursor = !m_render_cursor;
@ -121,7 +122,7 @@ void LineEdit::set_highlighted(bool highlighted) {
}
bool LineEdit::update(const window::Event& event) {
const float width = std::min(m_parent->get_right(), get_right()+1)-get_x();
const float width = std::min(m_parent->get_right(), get_right()+1)-get_x()-3;
const float height = std::min(m_parent->get_bottom(), get_bottom()+1)-get_y();
switch(event.m_type) {
case window::EventType::EVENT_TYPE_KEY_DOWN:
@ -134,12 +135,13 @@ bool LineEdit::update(const window::Event& event) {
m_text_buffer.erase(m_text_buffer.begin()+(--m_cursor_offset));
update_text_texture();
update_cursor_x();
LOG_VERBOSE("%d",m_cursor_offset);
}
break;
case window::KeyCode::KEY_HOME:
m_cursor_offset = 0;
m_cursor_x = 0;
m_text_offset = 0;
m_text_offset_x = 0;
break;
case window::KeyCode::KEY_DELETE:
if(m_cursor_offset<m_text_buffer.size()) {
@ -153,7 +155,6 @@ bool LineEdit::update(const window::Event& event) {
case window::KeyCode::KEY_END:
m_cursor_offset = m_text_buffer.size();
update_cursor_x();
m_text_offset = m_text_texture->get_width()-width;
break;
case window::KeyCode::KEY_LEFT:
if(m_cursor_offset>0) {
@ -173,6 +174,7 @@ bool LineEdit::update(const window::Event& event) {
default:
break;
}
return true;
}
break;
case window::EventType::EVENT_TYPE_TEXT_ENTER:
@ -191,29 +193,15 @@ bool LineEdit::update(const window::Event& event) {
event.m_data.m_mouse_event.m_button==window::MouseButton::MOUSE_BUTTON_LEFT) {
if(!m_highlighted)
m_engine->get_gui_master().request_highlight(this);
const int mouse_x = m_engine->get_window()->get_mouse_x();
if(m_engine->get_window()->is_mouse_inside_area(math::Vector2f{get_x()+3, get_y()}, math::Vector2f{static_cast<float>(m_text_texture->get_width()), height})) {
const int local_mouse_x = mouse_x-get_x()-3;
for(size_t i = 0; i<m_glyph_info.size(); i++) {
const renderer::Font::GlyphMetrics& glyph = m_glyph_info[i];
const int local_glyph_x = static_cast<int>(glyph.m_x-m_text_offset);
if(local_mouse_x>=local_glyph_x && local_mouse_x<local_glyph_x+static_cast<int>(glyph.m_width)/2) {
m_cursor_x = local_glyph_x;
update_cursor_offset(i);
}
else if(local_mouse_x>=local_glyph_x+static_cast<int>(glyph.m_width)/2 && local_mouse_x<=local_glyph_x+static_cast<int>(glyph.m_width)) {
m_cursor_x = local_glyph_x+glyph.m_width;
update_cursor_offset(i+1);
}
}
}
else if(mouse_x<get_x()+3) {
if(!m_text_buffer.empty()) {
const int local_mouse_x = m_engine->get_window()->get_mouse_x()-get_x()-3+m_text_offset_x;
size_t current_glyph = 0;
m_cursor_x = 0;
m_cursor_offset = 0;
}
else {
m_cursor_x = m_text_texture->get_width()-m_text_offset;
m_cursor_offset = m_text_buffer.size();
while(current_glyph<m_glyph_info.size() && m_cursor_x<local_mouse_x-static_cast<int>(m_glyph_info[current_glyph].m_width/2)) {
m_cursor_x = m_glyph_info[current_glyph].m_x+m_glyph_info[current_glyph].m_width;
current_glyph++;
}
update_cursor_offset(current_glyph);
}
return true;
}
@ -236,6 +224,10 @@ void LineEdit::update_text_texture() {
void LineEdit::update_cursor_offset(size_t glyph_index) {
// to understand following code please learn about Unicode Transformation Format 8 (UTF-8)
if(glyph_index>=m_glyph_info.size()) {
m_cursor_offset = m_text_buffer.size();
return;
}
size_t temp_index = 0;
for(size_t i = 0; i<m_text_buffer.size(); i++) {
if(is_utf8_multibyte_continuation(m_text_buffer[i]))
@ -251,9 +243,10 @@ void LineEdit::update_cursor_offset(size_t glyph_index) {
void LineEdit::update_cursor_x() {
if(m_cursor_offset==0) {
m_cursor_x = 0;
m_text_offset_x = 0;
return;
}
const float width = std::min(m_parent->get_right(), get_right()+1)-get_x();
const float width = std::min(m_parent->get_right(), get_right()+1)-get_x()-3;
size_t glyph_index = 0;
size_t i = 0;
do {
@ -264,17 +257,9 @@ void LineEdit::update_cursor_x() {
}
while(i<m_cursor_offset);
const renderer::Font::GlyphMetrics& glyph = m_glyph_info[glyph_index-1];
m_cursor_x = glyph.m_x+glyph.m_width-m_text_offset;
if(m_cursor_x>width-5) {
m_text_offset+=glyph.m_width;
m_cursor_x = width-5;
}
else if(glyph.m_x<m_text_offset) {
m_text_offset-=glyph.m_width;
m_cursor_x = 0;
}
if(m_text_offset>m_text_texture->get_width())
m_text_offset = 0;
if(m_text_offset>0 && m_text_offset+width>m_text_texture->get_width())
m_text_offset = m_text_texture->get_width()-width-2;
m_cursor_x = glyph.m_x+glyph.m_width;
if(m_cursor_x-m_text_offset_x>width)
m_text_offset_x = m_cursor_x-width;
else if(m_cursor_x<m_text_offset_x)
m_text_offset_x = m_cursor_x;
}

View File

@ -66,12 +66,11 @@ namespace polygun::gui {
LineEditProp m_properties;
renderer::Texture* m_text_texture;
std::string m_text_buffer;
unsigned m_text_offset_x;
size_t m_text_offset;
int m_text_offset_x;
std::vector<renderer::Font::GlyphMetrics> m_glyph_info;
std::chrono::time_point<std::chrono::steady_clock> m_prev_cursor_change;
bool m_render_cursor;
unsigned m_cursor_x;
int m_cursor_x;
size_t m_cursor_offset;
private: