2020-12-05 13:08:24 +01:00
|
|
|
|
#include "stdafx.h"
|
2021-05-26 20:29:03 +02:00
|
|
|
|
#include "overlay_edit_text.hpp"
|
2019-05-16 22:48:05 +02:00
|
|
|
|
|
|
|
|
|
|
namespace rsx
|
|
|
|
|
|
{
|
|
|
|
|
|
namespace overlays
|
|
|
|
|
|
{
|
2020-12-18 08:39:54 +01:00
|
|
|
|
static usz get_line_start(const std::u32string& text, usz pos)
|
2020-07-02 09:06:37 +02:00
|
|
|
|
{
|
|
|
|
|
|
if (pos == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
2020-12-18 08:39:54 +01:00
|
|
|
|
const usz line_start = text.rfind('\n', pos - 1);
|
2020-07-02 09:06:37 +02:00
|
|
|
|
if (line_start == std::string::npos)
|
|
|
|
|
|
{
|
|
|
|
|
|
return 0;
|
|
|
|
|
|
}
|
|
|
|
|
|
return line_start + 1;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-12-18 08:39:54 +01:00
|
|
|
|
static usz get_line_end(const std::u32string& text, usz pos)
|
2020-07-02 09:06:37 +02:00
|
|
|
|
{
|
2020-12-18 08:39:54 +01:00
|
|
|
|
const usz line_end = text.find('\n', pos);
|
2020-07-02 09:06:37 +02:00
|
|
|
|
if (line_end == std::string::npos)
|
|
|
|
|
|
{
|
|
|
|
|
|
return text.length();
|
|
|
|
|
|
}
|
|
|
|
|
|
return line_end;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-05-16 22:48:05 +02:00
|
|
|
|
void edit_text::move_caret(direction dir)
|
|
|
|
|
|
{
|
2021-03-09 20:40:14 +01:00
|
|
|
|
m_reset_caret_pulse = true;
|
|
|
|
|
|
|
2019-05-16 22:48:05 +02:00
|
|
|
|
switch (dir)
|
|
|
|
|
|
{
|
2020-09-02 16:20:29 +02:00
|
|
|
|
case direction::left:
|
2019-05-16 22:48:05 +02:00
|
|
|
|
{
|
|
|
|
|
|
if (caret_position)
|
|
|
|
|
|
{
|
|
|
|
|
|
caret_position--;
|
|
|
|
|
|
refresh();
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-09-02 16:20:29 +02:00
|
|
|
|
case direction::right:
|
2019-05-16 22:48:05 +02:00
|
|
|
|
{
|
2021-04-12 15:14:13 +02:00
|
|
|
|
if (caret_position < value.length())
|
2019-05-16 22:48:05 +02:00
|
|
|
|
{
|
|
|
|
|
|
caret_position++;
|
|
|
|
|
|
refresh();
|
|
|
|
|
|
}
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-09-02 16:20:29 +02:00
|
|
|
|
case direction::up:
|
2020-07-02 09:06:37 +02:00
|
|
|
|
{
|
2021-04-12 15:14:13 +02:00
|
|
|
|
const usz current_line_start = get_line_start(value, caret_position);
|
2020-07-02 09:06:37 +02:00
|
|
|
|
if (current_line_start == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
// This is the first line, so caret moves to the very beginning
|
|
|
|
|
|
caret_position = 0;
|
|
|
|
|
|
refresh();
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-12-18 08:39:54 +01:00
|
|
|
|
const usz caret_pos_in_line = caret_position - current_line_start;
|
|
|
|
|
|
const usz prev_line_end = current_line_start - 1;
|
2021-04-12 15:14:13 +02:00
|
|
|
|
const usz prev_line_start = get_line_start(value, prev_line_end);
|
2020-07-02 09:06:37 +02:00
|
|
|
|
// TODO : Save caret position to some kind of buffer, so after switching back and forward, caret would be on initial position
|
|
|
|
|
|
caret_position = std::min(prev_line_end, prev_line_start + caret_pos_in_line);
|
|
|
|
|
|
|
|
|
|
|
|
refresh();
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-09-02 16:20:29 +02:00
|
|
|
|
case direction::down:
|
2020-07-02 09:06:37 +02:00
|
|
|
|
{
|
2021-04-12 15:14:13 +02:00
|
|
|
|
const usz current_line_end = get_line_end(value, caret_position);
|
|
|
|
|
|
if (current_line_end == value.length())
|
2020-07-02 09:06:37 +02:00
|
|
|
|
{
|
|
|
|
|
|
// This is the last line, so caret moves to the very end
|
|
|
|
|
|
caret_position = current_line_end;
|
|
|
|
|
|
refresh();
|
|
|
|
|
|
break;
|
|
|
|
|
|
}
|
2021-04-12 15:14:13 +02:00
|
|
|
|
const usz current_line_start = get_line_start(value, caret_position);
|
2020-12-18 08:39:54 +01:00
|
|
|
|
const usz caret_pos_in_line = caret_position - current_line_start;
|
|
|
|
|
|
const usz next_line_start = current_line_end + 1;
|
2021-04-12 15:14:13 +02:00
|
|
|
|
const usz next_line_end = get_line_end(value, next_line_start);
|
2020-07-02 09:06:37 +02:00
|
|
|
|
// TODO : Save caret position to some kind of buffer, so after switching back and forward, caret would be on initial position
|
|
|
|
|
|
caret_position = std::min(next_line_end, next_line_start + caret_pos_in_line);
|
|
|
|
|
|
|
|
|
|
|
|
refresh();
|
2019-05-16 22:48:05 +02:00
|
|
|
|
break;
|
|
|
|
|
|
}
|
2020-07-02 09:06:37 +02:00
|
|
|
|
}
|
2019-05-16 22:48:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-04-12 15:14:13 +02:00
|
|
|
|
void edit_text::set_text(const std::string& text)
|
|
|
|
|
|
{
|
|
|
|
|
|
set_unicode_text(utf8_to_u32string(text));
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void edit_text::set_unicode_text(const std::u32string& text)
|
|
|
|
|
|
{
|
|
|
|
|
|
value = text;
|
|
|
|
|
|
|
|
|
|
|
|
if (value.empty())
|
|
|
|
|
|
{
|
|
|
|
|
|
overlay_element::set_unicode_text(placeholder);
|
|
|
|
|
|
}
|
2021-04-12 19:28:39 +02:00
|
|
|
|
else if (password_mode)
|
|
|
|
|
|
{
|
|
|
|
|
|
overlay_element::set_unicode_text(std::u32string(value.size(), U"*"[0]));
|
|
|
|
|
|
}
|
2021-04-12 15:14:13 +02:00
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
overlay_element::set_unicode_text(value);
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void edit_text::set_placeholder(const std::u32string& placeholder_text)
|
|
|
|
|
|
{
|
|
|
|
|
|
placeholder = placeholder_text;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2020-02-24 17:03:19 +01:00
|
|
|
|
void edit_text::insert_text(const std::u32string& str)
|
2019-05-16 22:48:05 +02:00
|
|
|
|
{
|
|
|
|
|
|
if (caret_position == 0)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Start
|
2021-04-12 15:14:13 +02:00
|
|
|
|
value = str + text;
|
2019-05-16 22:48:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
else if (caret_position == text.length())
|
|
|
|
|
|
{
|
|
|
|
|
|
// End
|
2021-04-12 15:14:13 +02:00
|
|
|
|
value += str;
|
2019-05-16 22:48:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
// Middle
|
2021-04-12 15:14:13 +02:00
|
|
|
|
value.insert(caret_position, str);
|
2019-05-16 22:48:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
2021-09-02 19:00:30 +02:00
|
|
|
|
caret_position += str.length();
|
2021-03-09 20:40:14 +01:00
|
|
|
|
m_reset_caret_pulse = true;
|
2021-04-12 15:14:13 +02:00
|
|
|
|
set_unicode_text(value);
|
2019-05-16 22:48:05 +02:00
|
|
|
|
refresh();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void edit_text::erase()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!caret_position)
|
|
|
|
|
|
{
|
|
|
|
|
|
return;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (caret_position == 1)
|
|
|
|
|
|
{
|
2021-04-12 15:14:13 +02:00
|
|
|
|
value = value.length() > 1 ? value.substr(1) : U"";
|
2019-05-16 22:48:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
else if (caret_position == text.length())
|
|
|
|
|
|
{
|
2021-04-12 15:14:13 +02:00
|
|
|
|
value = value.substr(0, caret_position - 1);
|
2019-05-16 22:48:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
2021-04-12 15:14:13 +02:00
|
|
|
|
value = value.substr(0, caret_position - 1) + value.substr(caret_position);
|
2019-05-16 22:48:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
caret_position--;
|
2021-03-09 20:40:14 +01:00
|
|
|
|
m_reset_caret_pulse = true;
|
2021-04-12 15:14:13 +02:00
|
|
|
|
set_unicode_text(value);
|
2019-05-16 22:48:05 +02:00
|
|
|
|
refresh();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
compiled_resource& edit_text::get_compiled()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (!is_compiled)
|
|
|
|
|
|
{
|
|
|
|
|
|
auto& compiled = label::get_compiled();
|
|
|
|
|
|
|
|
|
|
|
|
overlay_element caret;
|
|
|
|
|
|
auto renderer = get_font();
|
2021-05-22 20:46:10 +02:00
|
|
|
|
const auto caret_loc = renderer->get_char_offset(text.c_str(), caret_position, clip_text ? w : -1, wrap_text);
|
2019-05-16 22:48:05 +02:00
|
|
|
|
|
2021-04-12 22:23:24 +02:00
|
|
|
|
caret.set_pos(static_cast<u16>(caret_loc.first) + padding_left + x, static_cast<u16>(caret_loc.second) + padding_top + y);
|
|
|
|
|
|
caret.set_size(1, static_cast<u16>(renderer->get_size_px() + 2));
|
2019-05-16 22:48:05 +02:00
|
|
|
|
caret.fore_color = fore_color;
|
|
|
|
|
|
caret.back_color = fore_color;
|
|
|
|
|
|
caret.pulse_effect_enabled = true;
|
|
|
|
|
|
|
2021-03-09 20:40:14 +01:00
|
|
|
|
if (m_reset_caret_pulse)
|
|
|
|
|
|
{
|
|
|
|
|
|
// Reset the pulse slightly below 1 rising on each user interaction
|
|
|
|
|
|
caret.set_sinus_offset(1.6f);
|
|
|
|
|
|
m_reset_caret_pulse = false;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2019-05-16 22:48:05 +02:00
|
|
|
|
compiled.add(caret.get_compiled());
|
|
|
|
|
|
|
|
|
|
|
|
for (auto& cmd : compiled.draw_commands)
|
|
|
|
|
|
{
|
|
|
|
|
|
// TODO: Scrolling by using scroll offset
|
|
|
|
|
|
cmd.config.clip_region = true;
|
2021-04-12 22:23:24 +02:00
|
|
|
|
cmd.config.clip_rect = {static_cast<f32>(x), static_cast<f32>(y), static_cast<f32>(x + w), static_cast<f32>(y + h)};
|
2019-05-16 22:48:05 +02:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
is_compiled = true;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return compiled_resources;
|
|
|
|
|
|
}
|
|
|
|
|
|
} // namespace overlays
|
|
|
|
|
|
} // namespace rsx
|