aboutsummaryrefslogtreecommitdiff
path: root/src/gui/guiEditBoxWithScrollbar.cpp
diff options
context:
space:
mode:
authorLoïc Blot <nerzhul@users.noreply.github.com>2021-01-07 13:21:12 +0100
committerGitHub <noreply@github.com>2021-01-07 13:21:12 +0100
commit5fcc78a1feeffbc1a4fdd1cfffb49451694786d3 (patch)
treecd42adacba88ea4d99816a2f13f4c44593d89d7c /src/gui/guiEditBoxWithScrollbar.cpp
parent58a709096ef8ff17644cf201f25b1831d9506514 (diff)
downloadminetest-5fcc78a1feeffbc1a4fdd1cfffb49451694786d3.tar.gz
minetest-5fcc78a1feeffbc1a4fdd1cfffb49451694786d3.tar.bz2
minetest-5fcc78a1feeffbc1a4fdd1cfffb49451694786d3.zip
Refactor/gui editbox (#10787)
Diffstat (limited to 'src/gui/guiEditBoxWithScrollbar.cpp')
-rw-r--r--src/gui/guiEditBoxWithScrollbar.cpp690
1 files changed, 2 insertions, 688 deletions
diff --git a/src/gui/guiEditBoxWithScrollbar.cpp b/src/gui/guiEditBoxWithScrollbar.cpp
index 7f9fdafd7..707dbb7db 100644
--- a/src/gui/guiEditBoxWithScrollbar.cpp
+++ b/src/gui/guiEditBoxWithScrollbar.cpp
@@ -26,14 +26,8 @@ numerical
GUIEditBoxWithScrollBar::GUIEditBoxWithScrollBar(const wchar_t* text, bool border,
IGUIEnvironment* environment, IGUIElement* parent, s32 id,
const core::rect<s32>& rectangle, bool writable, bool has_vscrollbar)
- : GUIEditBox(environment, parent, id, rectangle), m_mouse_marking(false),
- m_border(border), m_background(true), m_mark_begin(0), m_mark_end(0), m_last_break_font(0),
- m_operator(0), m_blink_start_time(0), m_cursor_pos(0), m_hscroll_pos(0), m_vscroll_pos(0), m_max(0),
- m_passwordbox(false),
- m_passwordchar(L'*'), m_halign(EGUIA_UPPERLEFT), m_valign(EGUIA_CENTER),
- m_current_text_rect(0, 0, 1, 1), m_frame_rect(rectangle),
- m_scrollbar_width(0), m_vscrollbar(NULL), m_writable(writable),
- m_bg_color_used(false)
+ : GUIEditBox(environment, parent, id, rectangle, border, writable),
+ m_background(true), m_bg_color_used(false)
{
#ifdef _DEBUG
setDebugName("GUIEditBoxWithScrollBar");
@@ -63,24 +57,6 @@ GUIEditBoxWithScrollBar::GUIEditBoxWithScrollBar(const wchar_t* text, bool borde
setWritable(writable);
}
-
-//! destructor
-GUIEditBoxWithScrollBar::~GUIEditBoxWithScrollBar()
-{
- if (m_operator)
- m_operator->drop();
-
- if (m_vscrollbar)
- m_vscrollbar->drop();
-}
-
-
-//! Turns the border on or off
-void GUIEditBoxWithScrollBar::setDrawBorder(bool border)
-{
- m_border = border;
-}
-
//! Sets whether to draw the background
void GUIEditBoxWithScrollBar::setDrawBackground(bool draw)
{
@@ -100,466 +76,6 @@ void GUIEditBoxWithScrollBar::updateAbsolutePosition()
}
-void GUIEditBoxWithScrollBar::setPasswordBox(bool password_box, wchar_t password_char)
-{
- m_passwordbox = password_box;
- if (m_passwordbox) {
- m_passwordchar = password_char;
- setMultiLine(false);
- setWordWrap(false);
- m_broken_text.clear();
- }
-}
-
-
-bool GUIEditBoxWithScrollBar::isPasswordBox() const
-{
- return m_passwordbox;
-}
-
-
-//! Sets text justification
-void GUIEditBoxWithScrollBar::setTextAlignment(EGUI_ALIGNMENT horizontal, EGUI_ALIGNMENT vertical)
-{
- m_halign = horizontal;
- m_valign = vertical;
-}
-
-
-//! called if an event happened.
-bool GUIEditBoxWithScrollBar::OnEvent(const SEvent& event)
-{
- if (isEnabled()) {
- switch (event.EventType)
- {
- case EET_GUI_EVENT:
- if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST) {
- if (event.GUIEvent.Caller == this) {
- m_mouse_marking = false;
- setTextMarkers(0, 0);
- }
- }
- break;
- case EET_KEY_INPUT_EVENT:
- if (processKey(event))
- return true;
- break;
- case EET_MOUSE_INPUT_EVENT:
- if (processMouse(event))
- return true;
- break;
- default:
- break;
- }
- }
-
- return IGUIElement::OnEvent(event);
-}
-
-
-bool GUIEditBoxWithScrollBar::processKey(const SEvent& event)
-{
- if (!m_writable) {
- return false;
- }
-
- if (!event.KeyInput.PressedDown)
- return false;
-
- bool text_changed = false;
- s32 new_mark_begin = m_mark_begin;
- s32 new_mark_end = m_mark_end;
-
- // control shortcut handling
-
- if (event.KeyInput.Control) {
-
- // german backlash '\' entered with control + '?'
- if (event.KeyInput.Char == '\\') {
- inputChar(event.KeyInput.Char);
- return true;
- }
-
- switch (event.KeyInput.Key) {
- case KEY_KEY_A:
- // select all
- new_mark_begin = 0;
- new_mark_end = Text.size();
- break;
- case KEY_KEY_C:
- // copy to clipboard
- if (!m_passwordbox && m_operator && m_mark_begin != m_mark_end)
- {
- const s32 realmbgn = m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end;
- const s32 realmend = m_mark_begin < m_mark_end ? m_mark_end : m_mark_begin;
-
- core::stringc s;
- s = Text.subString(realmbgn, realmend - realmbgn).c_str();
- m_operator->copyToClipboard(s.c_str());
- }
- break;
- case KEY_KEY_X:
- // cut to the clipboard
- if (!m_passwordbox && m_operator && m_mark_begin != m_mark_end) {
- const s32 realmbgn = m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end;
- const s32 realmend = m_mark_begin < m_mark_end ? m_mark_end : m_mark_begin;
-
- // copy
- core::stringc sc;
- sc = Text.subString(realmbgn, realmend - realmbgn).c_str();
- m_operator->copyToClipboard(sc.c_str());
-
- if (isEnabled())
- {
- // delete
- core::stringw s;
- s = Text.subString(0, realmbgn);
- s.append(Text.subString(realmend, Text.size() - realmend));
- Text = s;
-
- m_cursor_pos = realmbgn;
- new_mark_begin = 0;
- new_mark_end = 0;
- text_changed = true;
- }
- }
- break;
- case KEY_KEY_V:
- if (!isEnabled())
- break;
-
- // paste from the clipboard
- if (m_operator) {
- const s32 realmbgn = m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end;
- const s32 realmend = m_mark_begin < m_mark_end ? m_mark_end : m_mark_begin;
-
- // add new character
- const c8* p = m_operator->getTextFromClipboard();
- if (p) {
- if (m_mark_begin == m_mark_end) {
- // insert text
- core::stringw s = Text.subString(0, m_cursor_pos);
- s.append(p);
- s.append(Text.subString(m_cursor_pos, Text.size() - m_cursor_pos));
-
- if (!m_max || s.size() <= m_max) // thx to Fish FH for fix
- {
- Text = s;
- s = p;
- m_cursor_pos += s.size();
- }
- } else {
- // replace text
-
- core::stringw s = Text.subString(0, realmbgn);
- s.append(p);
- s.append(Text.subString(realmend, Text.size() - realmend));
-
- if (!m_max || s.size() <= m_max) // thx to Fish FH for fix
- {
- Text = s;
- s = p;
- m_cursor_pos = realmbgn + s.size();
- }
- }
- }
-
- new_mark_begin = 0;
- new_mark_end = 0;
- text_changed = true;
- }
- break;
- case KEY_HOME:
- // move/highlight to start of text
- if (event.KeyInput.Shift) {
- new_mark_end = m_cursor_pos;
- new_mark_begin = 0;
- m_cursor_pos = 0;
- } else {
- m_cursor_pos = 0;
- new_mark_begin = 0;
- new_mark_end = 0;
- }
- break;
- case KEY_END:
- // move/highlight to end of text
- if (event.KeyInput.Shift) {
- new_mark_begin = m_cursor_pos;
- new_mark_end = Text.size();
- m_cursor_pos = 0;
- } else {
- m_cursor_pos = Text.size();
- new_mark_begin = 0;
- new_mark_end = 0;
- }
- break;
- default:
- return false;
- }
- }
- // default keyboard handling
- else
- switch (event.KeyInput.Key) {
- case KEY_END:
- {
- s32 p = Text.size();
- if (m_word_wrap || m_multiline) {
- p = getLineFromPos(m_cursor_pos);
- p = m_broken_text_positions[p] + (s32)m_broken_text[p].size();
- if (p > 0 && (Text[p - 1] == L'\r' || Text[p - 1] == L'\n'))
- p -= 1;
- }
-
- if (event.KeyInput.Shift) {
- if (m_mark_begin == m_mark_end)
- new_mark_begin = m_cursor_pos;
-
- new_mark_end = p;
- } else {
- new_mark_begin = 0;
- new_mark_end = 0;
- }
- m_cursor_pos = p;
- m_blink_start_time = porting::getTimeMs();
- }
- break;
- case KEY_HOME:
- {
-
- s32 p = 0;
- if (m_word_wrap || m_multiline) {
- p = getLineFromPos(m_cursor_pos);
- p = m_broken_text_positions[p];
- }
-
- if (event.KeyInput.Shift) {
- if (m_mark_begin == m_mark_end)
- new_mark_begin = m_cursor_pos;
- new_mark_end = p;
- } else {
- new_mark_begin = 0;
- new_mark_end = 0;
- }
- m_cursor_pos = p;
- m_blink_start_time = porting::getTimeMs();
- }
- break;
- case KEY_RETURN:
- if (m_multiline) {
- inputChar(L'\n');
- } else {
- calculateScrollPos();
- sendGuiEvent(EGET_EDITBOX_ENTER);
- }
- return true;
- case KEY_LEFT:
-
- if (event.KeyInput.Shift) {
- if (m_cursor_pos > 0) {
- if (m_mark_begin == m_mark_end)
- new_mark_begin = m_cursor_pos;
-
- new_mark_end = m_cursor_pos - 1;
- }
- } else {
- new_mark_begin = 0;
- new_mark_end = 0;
- }
-
- if (m_cursor_pos > 0)
- m_cursor_pos--;
- m_blink_start_time = porting::getTimeMs();
- break;
-
- case KEY_RIGHT:
- if (event.KeyInput.Shift) {
- if (Text.size() > (u32)m_cursor_pos) {
- if (m_mark_begin == m_mark_end)
- new_mark_begin = m_cursor_pos;
-
- new_mark_end = m_cursor_pos + 1;
- }
- } else {
- new_mark_begin = 0;
- new_mark_end = 0;
- }
-
- if (Text.size() > (u32)m_cursor_pos)
- m_cursor_pos++;
- m_blink_start_time = porting::getTimeMs();
- break;
- case KEY_UP:
- if (m_multiline || (m_word_wrap && m_broken_text.size() > 1)) {
- s32 lineNo = getLineFromPos(m_cursor_pos);
- s32 mb = (m_mark_begin == m_mark_end) ? m_cursor_pos : (m_mark_begin > m_mark_end ? m_mark_begin : m_mark_end);
- if (lineNo > 0) {
- s32 cp = m_cursor_pos - m_broken_text_positions[lineNo];
- if ((s32)m_broken_text[lineNo - 1].size() < cp)
- m_cursor_pos = m_broken_text_positions[lineNo - 1] + core::max_((u32)1, m_broken_text[lineNo - 1].size()) - 1;
- else
- m_cursor_pos = m_broken_text_positions[lineNo - 1] + cp;
- }
-
- if (event.KeyInput.Shift) {
- new_mark_begin = mb;
- new_mark_end = m_cursor_pos;
- } else {
- new_mark_begin = 0;
- new_mark_end = 0;
- }
- } else {
- return false;
- }
- break;
- case KEY_DOWN:
- if (m_multiline || (m_word_wrap && m_broken_text.size() > 1)) {
- s32 lineNo = getLineFromPos(m_cursor_pos);
- s32 mb = (m_mark_begin == m_mark_end) ? m_cursor_pos : (m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end);
- if (lineNo < (s32)m_broken_text.size() - 1)
- {
- s32 cp = m_cursor_pos - m_broken_text_positions[lineNo];
- if ((s32)m_broken_text[lineNo + 1].size() < cp)
- m_cursor_pos = m_broken_text_positions[lineNo + 1] + core::max_((u32)1, m_broken_text[lineNo + 1].size()) - 1;
- else
- m_cursor_pos = m_broken_text_positions[lineNo + 1] + cp;
- }
-
- if (event.KeyInput.Shift) {
- new_mark_begin = mb;
- new_mark_end = m_cursor_pos;
- } else {
- new_mark_begin = 0;
- new_mark_end = 0;
- }
-
- } else {
- return false;
- }
- break;
-
- case KEY_BACK:
- if (!isEnabled())
- break;
-
- if (Text.size()) {
- core::stringw s;
-
- if (m_mark_begin != m_mark_end) {
- // delete marked text
- const s32 realmbgn = m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end;
- const s32 realmend = m_mark_begin < m_mark_end ? m_mark_end : m_mark_begin;
-
- s = Text.subString(0, realmbgn);
- s.append(Text.subString(realmend, Text.size() - realmend));
- Text = s;
-
- m_cursor_pos = realmbgn;
- } else {
- // delete text behind cursor
- if (m_cursor_pos > 0)
- s = Text.subString(0, m_cursor_pos - 1);
- else
- s = L"";
- s.append(Text.subString(m_cursor_pos, Text.size() - m_cursor_pos));
- Text = s;
- --m_cursor_pos;
- }
-
- if (m_cursor_pos < 0)
- m_cursor_pos = 0;
- m_blink_start_time = porting::getTimeMs(); // os::Timer::getTime();
- new_mark_begin = 0;
- new_mark_end = 0;
- text_changed = true;
- }
- break;
- case KEY_DELETE:
- if (!isEnabled())
- break;
-
- if (Text.size() != 0) {
- core::stringw s;
-
- if (m_mark_begin != m_mark_end) {
- // delete marked text
- const s32 realmbgn = m_mark_begin < m_mark_end ? m_mark_begin : m_mark_end;
- const s32 realmend = m_mark_begin < m_mark_end ? m_mark_end : m_mark_begin;
-
- s = Text.subString(0, realmbgn);
- s.append(Text.subString(realmend, Text.size() - realmend));
- Text = s;
-
- m_cursor_pos = realmbgn;
- } else {
- // delete text before cursor
- s = Text.subString(0, m_cursor_pos);
- s.append(Text.subString(m_cursor_pos + 1, Text.size() - m_cursor_pos - 1));
- Text = s;
- }
-
- if (m_cursor_pos > (s32)Text.size())
- m_cursor_pos = (s32)Text.size();
-
- m_blink_start_time = porting::getTimeMs(); // os::Timer::getTime();
- new_mark_begin = 0;
- new_mark_end = 0;
- text_changed = true;
- }
- break;
-
- case KEY_ESCAPE:
- case KEY_TAB:
- case KEY_SHIFT:
- case KEY_F1:
- case KEY_F2:
- case KEY_F3:
- case KEY_F4:
- case KEY_F5:
- case KEY_F6:
- case KEY_F7:
- case KEY_F8:
- case KEY_F9:
- case KEY_F10:
- case KEY_F11:
- case KEY_F12:
- case KEY_F13:
- case KEY_F14:
- case KEY_F15:
- case KEY_F16:
- case KEY_F17:
- case KEY_F18:
- case KEY_F19:
- case KEY_F20:
- case KEY_F21:
- case KEY_F22:
- case KEY_F23:
- case KEY_F24:
- // ignore these keys
- return false;
-
- default:
- inputChar(event.KeyInput.Char);
- return true;
- }
-
- // Set new text markers
- setTextMarkers(new_mark_begin, new_mark_end);
-
- // break the text if it has changed
- if (text_changed) {
- breakText();
- calculateScrollPos();
- sendGuiEvent(EGET_EDITBOX_CHANGED);
- }
- else
- {
- calculateScrollPos();
- }
-
- return true;
-}
-
-
//! draws the element and its children
void GUIEditBoxWithScrollBar::draw()
{
@@ -748,115 +264,6 @@ void GUIEditBoxWithScrollBar::draw()
}
-//! Sets the new caption of this element.
-void GUIEditBoxWithScrollBar::setText(const wchar_t* text)
-{
- Text = text;
- if (u32(m_cursor_pos) > Text.size())
- m_cursor_pos = Text.size();
- m_hscroll_pos = 0;
- breakText();
-}
-
-
-//! Gets the area of the text in the edit box
-//! \return Returns the size in pixels of the text
-core::dimension2du GUIEditBoxWithScrollBar::getTextDimension()
-{
- core::rect<s32> ret;
-
- setTextRect(0);
- ret = m_current_text_rect;
-
- for (u32 i = 1; i < m_broken_text.size(); ++i) {
- setTextRect(i);
- ret.addInternalPoint(m_current_text_rect.UpperLeftCorner);
- ret.addInternalPoint(m_current_text_rect.LowerRightCorner);
- }
-
- return core::dimension2du(ret.getSize());
-}
-
-
-//! Sets the maximum amount of characters which may be entered in the box.
-//! \param max: Maximum amount of characters. If 0, the character amount is
-//! infinity.
-void GUIEditBoxWithScrollBar::setMax(u32 max)
-{
- m_max = max;
-
- if (Text.size() > m_max && m_max != 0)
- Text = Text.subString(0, m_max);
-}
-
-
-//! Returns maximum amount of characters, previously set by setMax();
-u32 GUIEditBoxWithScrollBar::getMax() const
-{
- return m_max;
-}
-
-
-bool GUIEditBoxWithScrollBar::processMouse(const SEvent& event)
-{
- switch (event.MouseInput.Event)
- {
- case irr::EMIE_LMOUSE_LEFT_UP:
- if (Environment->hasFocus(this)) {
- m_cursor_pos = getCursorPos(event.MouseInput.X, event.MouseInput.Y);
- if (m_mouse_marking) {
- setTextMarkers(m_mark_begin, m_cursor_pos);
- }
- m_mouse_marking = false;
- calculateScrollPos();
- return true;
- }
- break;
- case irr::EMIE_MOUSE_MOVED:
- {
- if (m_mouse_marking) {
- m_cursor_pos = getCursorPos(event.MouseInput.X, event.MouseInput.Y);
- setTextMarkers(m_mark_begin, m_cursor_pos);
- calculateScrollPos();
- return true;
- }
- }
- break;
- case EMIE_LMOUSE_PRESSED_DOWN:
-
- if (!Environment->hasFocus(this)) {
- m_blink_start_time = porting::getTimeMs();
- m_mouse_marking = true;
- m_cursor_pos = getCursorPos(event.MouseInput.X, event.MouseInput.Y);
- setTextMarkers(m_cursor_pos, m_cursor_pos);
- calculateScrollPos();
- return true;
- } else {
- if (!AbsoluteClippingRect.isPointInside(
- core::position2d<s32>(event.MouseInput.X, event.MouseInput.Y))) {
- return false;
- } else {
- // move cursor
- m_cursor_pos = getCursorPos(event.MouseInput.X, event.MouseInput.Y);
-
- s32 newMarkBegin = m_mark_begin;
- if (!m_mouse_marking)
- newMarkBegin = m_cursor_pos;
-
- m_mouse_marking = true;
- setTextMarkers(newMarkBegin, m_cursor_pos);
- calculateScrollPos();
- return true;
- }
- }
- default:
- break;
- }
-
- return false;
-}
-
-
s32 GUIEditBoxWithScrollBar::getCursorPos(s32 x, s32 y)
{
IGUIFont* font = getActiveFont();
@@ -1075,21 +482,6 @@ void GUIEditBoxWithScrollBar::setTextRect(s32 line)
}
-s32 GUIEditBoxWithScrollBar::getLineFromPos(s32 pos)
-{
- if (!m_word_wrap && !m_multiline)
- return 0;
-
- s32 i = 0;
- while (i < (s32)m_broken_text_positions.size()) {
- if (m_broken_text_positions[i] > pos)
- return i - 1;
- ++i;
- }
- return (s32)m_broken_text_positions.size() - 1;
-}
-
-
void GUIEditBoxWithScrollBar::inputChar(wchar_t c)
{
if (!isEnabled())
@@ -1259,30 +651,6 @@ void GUIEditBoxWithScrollBar::calculateFrameRect()
updateVScrollBar();
}
-//! set text markers
-void GUIEditBoxWithScrollBar::setTextMarkers(s32 begin, s32 end)
-{
- if (begin != m_mark_begin || end != m_mark_end) {
- m_mark_begin = begin;
- m_mark_end = end;
- sendGuiEvent(EGET_EDITBOX_MARKING_CHANGED);
- }
-}
-
-//! send some gui event to parent
-void GUIEditBoxWithScrollBar::sendGuiEvent(EGUI_EVENT_TYPE type)
-{
- if (Parent) {
- SEvent e;
- e.EventType = EET_GUI_EVENT;
- e.GUIEvent.Caller = this;
- e.GUIEvent.Element = 0;
- e.GUIEvent.EventType = type;
-
- Parent->OnEvent(e);
- }
-}
-
//! create a vertical scroll bar
void GUIEditBoxWithScrollBar::createVScrollBar()
{
@@ -1302,61 +670,7 @@ void GUIEditBoxWithScrollBar::createVScrollBar()
m_vscrollbar->setLargeStep(1);
}
-void GUIEditBoxWithScrollBar::updateVScrollBar()
-{
- if (!m_vscrollbar) {
- return;
- }
-
- // OnScrollBarChanged(...)
- if (m_vscrollbar->getPos() != m_vscroll_pos) {
- s32 deltaScrollY = m_vscrollbar->getPos() - m_vscroll_pos;
- m_current_text_rect.UpperLeftCorner.Y -= deltaScrollY;
- m_current_text_rect.LowerRightCorner.Y -= deltaScrollY;
-
- s32 scrollymax = getTextDimension().Height - m_frame_rect.getHeight();
- if (scrollymax != m_vscrollbar->getMax()) {
- // manage a newline or a deleted line
- m_vscrollbar->setMax(scrollymax);
- m_vscrollbar->setPageSize(s32(getTextDimension().Height));
- calculateScrollPos();
- } else {
- // manage a newline or a deleted line
- m_vscroll_pos = m_vscrollbar->getPos();
- }
- }
-
- // check if a vertical scrollbar is needed ?
- if (getTextDimension().Height > (u32) m_frame_rect.getHeight()) {
- m_frame_rect.LowerRightCorner.X -= m_scrollbar_width;
-
- s32 scrollymax = getTextDimension().Height - m_frame_rect.getHeight();
- if (scrollymax != m_vscrollbar->getMax()) {
- m_vscrollbar->setMax(scrollymax);
- m_vscrollbar->setPageSize(s32(getTextDimension().Height));
- }
-
- if (!m_vscrollbar->isVisible()) {
- m_vscrollbar->setVisible(true);
- }
- } else {
- if (m_vscrollbar->isVisible())
- {
- m_vscrollbar->setVisible(false);
- m_vscroll_pos = 0;
- m_vscrollbar->setPos(0);
- m_vscrollbar->setMax(1);
- m_vscrollbar->setPageSize(s32(getTextDimension().Height));
- }
- }
-}
-
-//! set true if this editbox is writable
-void GUIEditBoxWithScrollBar::setWritable(bool writable)
-{
- m_writable = writable;
-}
//! Change the background color
void GUIEditBoxWithScrollBar::setBackgroundColor(const video::SColor &bg_color)