Fix selection background of formatted labels

The metrics of the rectangles comprising the selection background
were calculated based on the selected range and the unformatted
text, so these rectangles would be off when the formatted text
was different (i.e. had any formatting).
This commit is contained in:
Tamás Bálint Misius
2019-07-19 11:26:33 +02:00
parent 34b4665d4b
commit 8223e06670
5 changed files with 41 additions and 41 deletions

View File

@@ -102,11 +102,11 @@ Controls
Command Line Command Line
--------------------------------------------------------------------------- ---------------------------------------------------------------------------
| Command | Description | Example | | Command | Description | Example |
| ---------------------- | ------------------------------------------------ | ---------------------------------------------------- | | --------------------- | ------------------------------------------------ | --------------------------------- |
| `scale:SIZE` | Change window scale factor | `scale:2` | | `scale:SIZE` | Change window scale factor | `scale:2` |
| `kiosk` | Fullscreen mode | | | `kiosk` | Fullscreen mode | |
| `proxy:SERVER[:PORT]` | Proxy server to use | `proxy:wwwcache.lancs.ac.uk:8080` | | `proxy:SERVER[:PORT]` | Proxy server to use | `proxy:wwwcache.lancs.ac.uk:8080` |
| `open FILE` | Opens the file as a stamp or game save | | | `open FILE` | Opens the file as a stamp or game save | |
| `ddir DIRECTORY` | Directory used for saving stamps and preferences | | | `ddir DIRECTORY` | Directory used for saving stamps and preferences | |
| `ptsave:SAVEID[#NAME]` | Open online save, used by ptsave: URLs | `ptsave:2198#Destroyable_city_5_wth_metro~dima-gord` | | `ptsave:SAVEID` | Open online save, used by ptsave: URLs | `ptsave:2198` |

View File

@@ -204,8 +204,10 @@ void Label::updateSelection()
displayTextWithSelection = displayTextWrapper.WrappedText(); displayTextWithSelection = displayTextWrapper.WrappedText();
if (HasSelection()) if (HasSelection())
{ {
displayTextWithSelection.Insert(displayTextWrapper.Clear2Index(selectionIndexL.clear_index).wrapped_index, "\x01"); auto indexL = displayTextWrapper.Clear2Index(selectionIndexL.clear_index);
displayTextWithSelection.Insert(displayTextWrapper.Clear2Index(selectionIndexH.clear_index).wrapped_index + 1, "\x01"); auto indexH = displayTextWrapper.Clear2Index(selectionIndexH.clear_index);
displayTextWithSelection.Insert(indexL.wrapped_index , "\x01");
displayTextWithSelection.Insert(indexH.wrapped_index + 1, "\x01");
} }
} }
@@ -229,13 +231,16 @@ void Label::Draw(const Point& screenPos)
} }
Graphics *g = GetGraphics(); Graphics *g = GetGraphics();
auto indexL = displayTextWrapper.Clear2Index(selectionIndexL.clear_index);
auto indexH = displayTextWrapper.Clear2Index(selectionIndexH.clear_index);
int selectionXL; int selectionXL;
int selectionYL; int selectionYL;
int selectionLineL = displayTextWrapper.Index2Point(selectionIndexL, selectionXL, selectionYL); int selectionLineL = displayTextWrapper.Index2Point(indexL, selectionXL, selectionYL);
int selectionXH; int selectionXH;
int selectionYH; int selectionYH;
int selectionLineH = displayTextWrapper.Index2Point(selectionIndexH, selectionXH, selectionYH); int selectionLineH = displayTextWrapper.Index2Point(indexH, selectionXH, selectionYH);
if (HasSelection()) if (HasSelection())
{ {

View File

@@ -20,6 +20,7 @@ namespace ui
int raw_index; int raw_index;
int clear_index; int clear_index;
bool wraps; bool wraps;
bool may_eat_space;
}; };
int line_width = 0; int line_width = 0;
std::vector<wrap_record> records; std::vector<wrap_record> records;
@@ -38,7 +39,8 @@ namespace ui
0, // width; fools the clickmap generator into not seeing this newline 0, // width; fools the clickmap generator into not seeing this newline
0, // position; the clickmap generator is fooled, this can be anything 0, // position; the clickmap generator is fooled, this can be anything
0, 0,
true // signal the end of the line to the clickmap generator true, // signal the end of the line to the clickmap generator
true // allow record to eat the following space
}); });
line_width = 0; line_width = 0;
lines += 1; lines += 1;
@@ -62,15 +64,22 @@ namespace ui
{ {
// add more supported spaces here // add more supported spaces here
case ' ': case ' ':
if (!wrap_if_needed(line_width)) wrap_if_needed(line_width);
if (records.size() && records.back().may_eat_space)
{ {
// this is in the non-wrapping branch to make spaces immediately records.back().may_eat_space = false;
// following newline characters inserted by the wrapper disappear }
else
{
// this is pushed only if the previous record isn't a wrapping one
// to make spaces immediately following newline characters inserted
// by the wrapper disappear
records.push_back(wrap_record{ records.push_back(wrap_record{
*it, *it,
char_width, char_width,
(int)(it - text.begin()), (int)(it - text.begin()),
clear_count, clear_count,
false,
false false
}); });
line_width += char_width; line_width += char_width;
@@ -86,7 +95,8 @@ namespace ui
max_width - line_width, // width; make it span all the way to the end max_width - line_width, // width; make it span all the way to the end
(int)(it - text.begin()), // position; so the clickmap generator knows where *it is (int)(it - text.begin()), // position; so the clickmap generator knows where *it is
clear_count, clear_count,
true // signal the end of the line to the clickmap generator true, // signal the end of the line to the clickmap generator
false
}); });
lines += 1; lines += 1;
line_width = 0; line_width = 0;
@@ -109,7 +119,8 @@ namespace ui
0, // width; fools the clickmap generator into not seeing this sequence 0, // width; fools the clickmap generator into not seeing this sequence
0, // position; the clickmap generator is fooled, this can be anything 0, // position; the clickmap generator is fooled, this can be anything
0, 0,
false // signal nothing to the clickmap generator false, // signal nothing to the clickmap generator
false
}); });
} }
--it; --it;
@@ -152,7 +163,8 @@ namespace ui
char_width, // width; make it span all the way to the end char_width, // width; make it span all the way to the end
(int)(it - text.begin()), // position; so the clickmap generator knows where *it is (int)(it - text.begin()), // position; so the clickmap generator knows where *it is
clear_count, clear_count,
false // signal nothing to the clickmap generator false, // signal nothing to the clickmap generator
false
}); });
word_width += char_width; word_width += char_width;
line_width += char_width; line_width += char_width;
@@ -269,22 +281,6 @@ namespace ui
return regions[index.wrapped_index].pos_line; return regions[index.wrapped_index].pos_line;
} }
TextWrapper::Index TextWrapper::Raw2Index(int raw_index) const
{
if (raw_index < 0)
{
return IndexBegin();
}
for (auto const &region : regions)
{
if (region.index.raw_index >= raw_index)
{
return region.index;
}
}
return IndexEnd();
}
TextWrapper::Index TextWrapper::Clear2Index(int clear_index) const TextWrapper::Index TextWrapper::Clear2Index(int clear_index) const
{ {
if (clear_index < 0) if (clear_index < 0)

View File

@@ -32,7 +32,6 @@ namespace ui
public: public:
int Update(String const &text, bool do_wrapping, int max_width); int Update(String const &text, bool do_wrapping, int max_width);
Index Raw2Index(int raw_index) const;
Index Clear2Index(int clear_index) const; Index Clear2Index(int clear_index) const;
Index Point2Index(int x, int y) const; Index Point2Index(int x, int y) const;
int Index2Point(Index index, int &x, int &y) const; int Index2Point(Index index, int &x, int &y) const;

View File

@@ -77,7 +77,7 @@ void Textbox::SetText(String newText)
if(cursor) if(cursor)
{ {
textWrapper.Index2Point(textWrapper.Raw2Index(cursor), cursorPositionX, cursorPositionY); textWrapper.Index2Point(textWrapper.Clear2Index(cursor), cursorPositionX, cursorPositionY);
} }
else else
{ {
@@ -128,7 +128,7 @@ void Textbox::OnContextMenuAction(int item)
void Textbox::resetCursorPosition() void Textbox::resetCursorPosition()
{ {
textWrapper.Index2Point(textWrapper.Raw2Index(cursor), cursorPositionX, cursorPositionY); textWrapper.Index2Point(textWrapper.Clear2Index(cursor), cursorPositionX, cursorPositionY);
} }
void Textbox::TabFocus() void Textbox::TabFocus()
@@ -175,7 +175,7 @@ void Textbox::cutSelection()
if(cursor) if(cursor)
{ {
textWrapper.Index2Point(textWrapper.Raw2Index(cursor), cursorPositionX, cursorPositionY); textWrapper.Index2Point(textWrapper.Clear2Index(cursor), cursorPositionX, cursorPositionY);
} }
else else
{ {
@@ -245,7 +245,7 @@ void Textbox::pasteIntoSelection()
if(cursor) if(cursor)
{ {
textWrapper.Index2Point(textWrapper.Raw2Index(cursor), cursorPositionX, cursorPositionY); textWrapper.Index2Point(textWrapper.Clear2Index(cursor), cursorPositionX, cursorPositionY);
} }
else else
{ {
@@ -463,7 +463,7 @@ void Textbox::AfterTextChange(bool changed)
if(cursor) if(cursor)
{ {
textWrapper.Index2Point(textWrapper.Raw2Index(cursor), cursorPositionX, cursorPositionY); textWrapper.Index2Point(textWrapper.Clear2Index(cursor), cursorPositionX, cursorPositionY);
} }
else else
{ {