LineEdit improvements and fixes
This commit is contained in:
parent
f382367980
commit
dc67a81f9f
@ -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;
|
||||
}
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user