Add ui::Entry::Range to simplify code

This commit is contained in:
David Capello 2020-05-15 18:24:35 -03:00
parent fa187b35a8
commit f491a2a506
5 changed files with 54 additions and 55 deletions

2
laf

@ -1 +1 @@
Subproject commit 755ad130b9c5d55354fd5d8c4ce74bf24c012b09
Subproject commit 207de6662911e9471c01681fb16912b756646f07

View File

@ -1015,7 +1015,7 @@ public:
, m_y(pos.y)
, m_h(h)
{
m_widget->getEntryThemeInfo(&m_index, &m_caret, &m_state, &m_selbeg, &m_selend);
m_widget->getEntryThemeInfo(&m_index, &m_caret, &m_state, &m_range);
}
int index() const { return m_index; }
@ -1033,8 +1033,8 @@ public:
fg = colors.text();
// Selected
if ((m_index >= m_selbeg) &&
(m_index <= m_selend)) {
if ((m_index >= m_range.from) &&
(m_index < m_range.to)) {
if (m_widget->hasFocus())
bg = colors.selected();
else
@ -1093,8 +1093,7 @@ private:
int m_index;
int m_caret;
int m_state;
int m_selbeg;
int m_selend;
Entry::Range m_range;
gfx::Rect m_textBounds;
bool m_caretDrawn;
gfx::Color m_bg;

View File

@ -1,4 +1,4 @@
Copyright (C) 2018-2020 Igara Studio S.A.
Copyright (c) 2018-2020 Igara Studio S.A.
Copyright (c) 2001-2018 David Capello
Permission is hereby granted, free of charge, to any person obtaining

View File

@ -172,19 +172,28 @@ void Entry::deselectText()
std::string Entry::selectedText() const
{
int selbeg, selend;
getEntryThemeInfo(nullptr, nullptr, nullptr, &selbeg, &selend);
if (selbeg >= 0 && selend >= 0) {
ASSERT(selbeg < int(m_boxes.size()));
ASSERT(selend < int(m_boxes.size()));
return text().substr(m_boxes[selbeg].from,
m_boxes[selend].to - m_boxes[selbeg].from);
}
Range range = selectedRange();
if (!range.isEmpty())
return text().substr(m_boxes[range.from].from,
m_boxes[range.to-1].to - m_boxes[range.from].from);
else
return std::string();
}
Entry::Range Entry::selectedRange() const
{
Range range;
if ((m_select >= 0) &&
(m_caret != m_select)) {
range.from = std::min(m_caret, m_select);
range.to = std::max(m_caret, m_select);
ASSERT(range.from >= 0 && range.from < int(m_boxes.size()));
ASSERT(range.to >= 0 && range.to <= int(m_boxes.size()));
}
return range;
}
void Entry::setSuffix(const std::string& suffix)
{
if (m_suffix != suffix) {
@ -198,22 +207,12 @@ void Entry::setTranslateDeadKeys(bool state)
m_translate_dead_keys = state;
}
void Entry::getEntryThemeInfo(int* scroll, int* caret, int* state,
int* selbeg, int* selend) const
void Entry::getEntryThemeInfo(int* scroll, int* caret, int* state, Range* range) const
{
if (scroll) *scroll = m_scroll;
if (caret) *caret = m_caret;
if (state) *state = !m_hidden && m_state;
if ((m_select >= 0) &&
(m_caret != m_select)) {
*selbeg = std::min(m_caret, m_select);
*selend = std::max(m_caret, m_select)-1;
}
else {
*selbeg = -1;
*selend = -1;
}
if (range) *range = selectedRange();
}
gfx::Rect Entry::getEntryTextBounds() const
@ -545,9 +544,7 @@ int Entry::getCaretFromMouse(MouseMessage* mousemsg)
void Entry::executeCmd(EntryCmd cmd, int unicodeChar, bool shift_pressed)
{
std::string text = this->text();
int selbeg, selend;
getEntryThemeInfo(nullptr, nullptr, nullptr, &selbeg, &selend);
const Range range = selectedRange();
switch (cmd) {
@ -556,11 +553,8 @@ void Entry::executeCmd(EntryCmd cmd, int unicodeChar, bool shift_pressed)
case EntryCmd::InsertChar:
// delete the entire selection
if (selbeg >= 0) {
text.erase(m_boxes[selbeg].from,
m_boxes[selend].to - m_boxes[selbeg].from);
m_caret = selbeg;
if (!range.isEmpty()) {
deleteRange(range, text);
// We set the caret to the beginning of the erased selection,
// needed to show the first inserted character in case
@ -657,16 +651,13 @@ void Entry::executeCmd(EntryCmd cmd, int unicodeChar, bool shift_pressed)
case EntryCmd::DeleteForward:
case EntryCmd::Cut:
// delete the entire selection
if (selbeg >= 0) {
if (!range.isEmpty()) {
// *cut* text!
if (cmd == EntryCmd::Cut)
set_clipboard_text(selectedText());
// remove text
text.erase(m_boxes[selbeg].from,
m_boxes[selend].to - m_boxes[selbeg].from);
m_caret = selbeg;
deleteRange(range, text);
}
// delete the next character
else {
@ -682,11 +673,8 @@ void Entry::executeCmd(EntryCmd cmd, int unicodeChar, bool shift_pressed)
std::string clipboard;
if (get_clipboard_text(clipboard)) {
// delete the entire selection
if (selbeg >= 0) {
text.erase(m_boxes[selbeg].from,
m_boxes[selend].to - m_boxes[selbeg].from);
m_caret = selbeg;
if (!range.isEmpty()) {
deleteRange(range, text);
m_select = -1;
}
@ -711,17 +699,14 @@ void Entry::executeCmd(EntryCmd cmd, int unicodeChar, bool shift_pressed)
}
case EntryCmd::Copy:
if (selbeg >= 0)
if (!range.isEmpty())
set_clipboard_text(selectedText());
break;
case EntryCmd::DeleteBackward:
// delete the entire selection
if (selbeg >= 0) {
text.erase(m_boxes[selbeg].from,
m_boxes[selend].to - m_boxes[selbeg].from);
m_caret = selbeg;
if (!range.isEmpty()) {
deleteRange(range, text);
}
// delete the previous character
else {
@ -898,4 +883,11 @@ bool Entry::shouldStartTimer(bool hasFocus)
return (!m_hidden && hasFocus && isEnabled());
}
void Entry::deleteRange(const Range& range, std::string& text)
{
text.erase(m_boxes[range.from].from,
m_boxes[range.to-1].to - m_boxes[range.from].from);
m_caret = range.from;
}
} // namespace ui

View File

@ -1,5 +1,5 @@
// Aseprite UI Library
// Copyright (C) 2018 Igara Studio S.A.
// Copyright (C) 2018-2020 Igara Studio S.A.
// Copyright (C) 2001-2017 David Capello
//
// This file is released under the terms of the MIT license.
@ -19,6 +19,12 @@ namespace ui {
class Entry : public Widget {
public:
struct Range {
int from = -1, to = -1;
bool isEmpty() const { return from < 0; }
int size() const { return to - from; }
};
Entry(const int maxsize, const char *format, ...);
~Entry();
@ -35,10 +41,12 @@ namespace ui {
void setCaretPos(int pos);
void setCaretToEnd();
void selectText(int from, int to);
void selectAllText();
void deselectText();
std::string selectedText() const;
Range selectedRange() const;
void setSuffix(const std::string& suffix);
const std::string& getSuffix() { return m_suffix; }
@ -46,8 +54,7 @@ namespace ui {
void setTranslateDeadKeys(bool state);
// for themes
void getEntryThemeInfo(int* scroll, int* caret, int* state,
int* selbeg, int* selend) const;
void getEntryThemeInfo(int* scroll, int* caret, int* state, Range* range) const;
gfx::Rect getEntryTextBounds() const;
static gfx::Size sizeHintWithText(Entry* entry,
@ -95,6 +102,7 @@ namespace ui {
void showEditPopupMenu(const gfx::Point& pt);
void recalcCharBoxes(const std::string& text);
bool shouldStartTimer(const bool hasFocus);
void deleteRange(const Range& range, std::string& text);
class CalcBoxesTextDelegate;