1
0
Fork 0

Codechange: Use std::string_view in IME input handling.

pull/14172/head
frosch 2025-04-30 12:07:58 +02:00 committed by frosch
parent 6db13df3b5
commit 66733e2a50
13 changed files with 59 additions and 54 deletions

View File

@ -317,7 +317,7 @@ struct IConsoleWindow : Window
return ES_HANDLED;
}
void InsertTextString(WidgetID, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end) override
void InsertTextString(WidgetID, std::string_view str, bool marked, std::optional<size_t> caret, std::optional<size_t> insert_location, std::optional<size_t> replacement_end) override
{
if (_iconsole_cmdline.InsertString(str, marked, caret, insert_location, replacement_end)) {
_iconsole_tab_completion.Reset();
@ -340,7 +340,7 @@ struct IConsoleWindow : Window
return pt;
}
Rect GetTextBoundingRect(const char *from, const char *to) const override
Rect GetTextBoundingRect(size_t from, size_t to) const override
{
int delta = std::min<int>(this->width - this->line_offset - _iconsole_cmdline.pixels - ICON_RIGHT_BORDERWIDTH, 0);

View File

@ -70,7 +70,9 @@ extern Palette _cur_palette; ///< Current palette
void HandleToolbarHotkey(int hotkey);
void HandleKeypress(uint keycode, char32_t key);
void HandleTextInput(const char *str, bool marked = false, const char *caret = nullptr, const char *insert_location = nullptr, const char *replacement_end = nullptr);
void HandleTextInput(std::string_view str, bool marked = false,
std::optional<size_t> caret = std::nullopt,
std::optional<size_t> insert_location = std::nullopt, std::optional<size_t> replacement_end = std::nullopt);
void HandleCtrlChanged();
void HandleMouseEvents();
void UpdateWindows();

View File

@ -418,15 +418,14 @@ void Layouter::ReduceLineCache()
* Get the leading corner of a character in a single-line string relative
* to the start of the string.
* @param str String containing the character.
* @param ch Pointer to the character in the string.
* @param pos Index to the character in the string.
* @param start_fontsize Font size to start the text with.
* @return Upper left corner of the glyph associated with the character.
*/
ParagraphLayouter::Position GetCharPosInString(std::string_view str, const char *ch, FontSize start_fontsize)
ParagraphLayouter::Position GetCharPosInString(std::string_view str, size_t pos, FontSize start_fontsize)
{
/* Ensure "ch" is inside "str" or at the exact end. */
assert(ch >= str.data() && (ch - str.data()) <= static_cast<ptrdiff_t>(str.size()));
auto it_ch = str.begin() + (ch - str.data());
assert(pos <= str.size());
auto it_ch = str.begin() + pos;
Layouter layout(str, INT32_MAX, start_fontsize);
return layout.GetCharPosition(it_ch);

View File

@ -197,7 +197,7 @@ public:
static void ReduceLineCache();
};
ParagraphLayouter::Position GetCharPosInString(std::string_view str, const char *ch, FontSize start_fontsize = FS_NORMAL);
ParagraphLayouter::Position GetCharPosInString(std::string_view str, size_t pos, FontSize start_fontsize = FS_NORMAL);
ptrdiff_t GetCharAtPosition(std::string_view str, int x, FontSize start_fontsize = FS_NORMAL);
#endif /* GFX_LAYOUT_H */

View File

@ -813,7 +813,7 @@ Point QueryString::GetCaretPosition(const Window *w, WidgetID wid) const
* @param to End of the string range.
* @return Rectangle encompassing the string range, relative to the window.
*/
Rect QueryString::GetBoundingRect(const Window *w, WidgetID wid, const char *from, const char *to) const
Rect QueryString::GetBoundingRect(const Window *w, WidgetID wid, size_t from, size_t to) const
{
const NWidgetLeaf *wi = w->GetWidget<NWidgetLeaf>(wid);

View File

@ -45,7 +45,7 @@ public:
void HandleEditBox(Window *w, WidgetID wid);
Point GetCaretPosition(const Window *w, WidgetID wid) const;
Rect GetBoundingRect(const Window *w, WidgetID wid, const char *from, const char *to) const;
Rect GetBoundingRect(const Window *w, WidgetID wid, size_t from, size_t to) const;
ptrdiff_t GetCharAtPosition(const Window *w, WidgetID wid, const Point &pt) const;
};

View File

@ -154,21 +154,21 @@ bool Textbuf::InsertChar(char32_t key)
* @param replacement_end Replace all characters from #insert_location up to this location with the new string.
* @return True on successful change of Textbuf, or false otherwise.
*/
bool Textbuf::InsertString(const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end)
bool Textbuf::InsertString(std::string_view str, bool marked, std::optional<size_t> caret, std::optional<size_t> insert_location, std::optional<size_t> replacement_end)
{
uint16_t insertpos = (marked && this->marklength != 0) ? this->markpos : this->caretpos;
if (insert_location != nullptr) {
insertpos = insert_location - this->buf.data();
if (insert_location.has_value()) {
insertpos = static_cast<uint16_t>(*insert_location);
if (insertpos >= this->buf.size()) return false;
if (replacement_end != nullptr) {
this->DeleteText(insertpos, replacement_end - this->buf.data(), str == nullptr);
if (replacement_end.has_value()) {
this->DeleteText(insertpos, static_cast<uint16_t>(*replacement_end), str.empty());
}
} else {
if (marked) this->DiscardMarkedText(str == nullptr);
if (marked) this->DiscardMarkedText(str.empty());
}
if (str == nullptr) return false;
if (str.empty()) return false;
uint16_t chars = 0;
uint16_t bytes;
@ -192,7 +192,7 @@ bool Textbuf::InsertString(const char *str, bool marked, const char *caret, cons
if (bytes == 0) return false;
/* Move caret if needed. */
if (str <= caret && caret <= str + bytes) this->caretpos = insertpos + (caret - str);
if (caret.has_value()) this->caretpos = insertpos + static_cast<uint16_t>(*caret);
if (marked) {
this->markpos = insertpos;
@ -202,7 +202,7 @@ bool Textbuf::InsertString(const char *str, bool marked, const char *caret, cons
this->buf.insert(insertpos, str, bytes);
this->chars += chars;
if (!marked && caret == nullptr) this->caretpos += bytes;
if (!marked && !caret.has_value()) this->caretpos += bytes;
assert(this->buf.size() < this->max_bytes);
assert(this->chars <= this->max_chars);
@ -225,7 +225,7 @@ bool Textbuf::InsertClipboard()
auto contents = GetClipboardContents();
if (!contents.has_value()) return false;
return this->InsertString(contents.value().c_str(), false);
return this->InsertString(contents.value(), false);
}
/**
@ -303,7 +303,7 @@ void Textbuf::UpdateWidth()
/** Update pixel position of the caret. */
void Textbuf::UpdateCaretPosition()
{
const auto pos = GetCharPosInString(this->buf, &this->buf[this->caretpos], FS_NORMAL);
const auto pos = GetCharPosInString(this->buf, this->caretpos, FS_NORMAL);
this->caretxoffs = _current_text_dir == TD_LTR ? pos.left : pos.right;
}
@ -311,8 +311,8 @@ void Textbuf::UpdateCaretPosition()
void Textbuf::UpdateMarkedText()
{
if (this->markend != 0) {
const auto pos = GetCharPosInString(this->buf, &this->buf[this->markpos], FS_NORMAL);
const auto end = GetCharPosInString(this->buf, &this->buf[this->markend], FS_NORMAL);
const auto pos = GetCharPosInString(this->buf, this->markpos, FS_NORMAL);
const auto end = GetCharPosInString(this->buf, this->markend, FS_NORMAL);
this->markxoffs = std::min(pos.left, end.left);
this->marklength = std::max(pos.right, end.right) - this->markxoffs;
} else {

View File

@ -49,7 +49,9 @@ struct Textbuf {
bool InsertClipboard();
bool InsertChar(char32_t key);
bool InsertString(const char *str, bool marked, const char *caret = nullptr, const char *insert_location = nullptr, const char *replacement_end = nullptr);
bool InsertString(std::string_view str, bool marked,
std::optional<size_t> caret = std::nullopt,
std::optional<size_t> insert_location = std::nullopt, std::optional<size_t> replacement_end = std::nullopt);
bool DeleteChar(uint16_t keycode);
bool MovePos(uint16_t keycode);

View File

@ -247,7 +247,7 @@ void VideoDriver_Cocoa::EditBoxLostFocus()
{
[ [ this->cocoaview inputContext ] performSelectorOnMainThread:@selector(discardMarkedText) withObject:nil waitUntilDone:[ NSThread isMainThread ] ];
/* Clear any marked string from the current edit box. */
HandleTextInput(nullptr, true);
HandleTextInput({}, true);
}
/**

View File

@ -115,9 +115,9 @@ static NSUInteger CountUtf16Units(std::string_view str)
* Advance an UTF-8 string by a number of equivalent UTF-16 code points.
* @param str UTF-8 string.
* @param count Number of UTF-16 code points to advance the string by.
* @return Advanced string pointer.
* @return Position inside str.
*/
static const char *Utf8AdvanceByUtf16Units(std::string_view str, NSUInteger count)
static size_t Utf8AdvanceByUtf16Units(std::string_view str, NSUInteger count)
{
Utf8View view(str);
auto it = view.begin();
@ -125,7 +125,7 @@ static const char *Utf8AdvanceByUtf16Units(std::string_view str, NSUInteger coun
for (NSUInteger i = 0; it != end && i < count; ++it) {
i += *it < 0x10000 ? 1 : 2; // Watch for surrogate pairs.
}
return str.data() + it.GetByteOffset();
return it.GetByteOffset();
}
/**
@ -940,16 +940,17 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
NSString *s = [ aString isKindOfClass:[ NSAttributedString class ] ] ? [ aString string ] : (NSString *)aString;
const char *insert_point = nullptr;
const char *replace_range = nullptr;
std::optional<size_t> insert_point;
std::optional<size_t> replace_range;
if (replacementRange.location != NSNotFound) {
/* Calculate the part to be replaced. */
insert_point = Utf8AdvanceByUtf16Units(_focused_window->GetFocusedTextbuf()->GetText(), replacementRange.location);
replace_range = Utf8AdvanceByUtf16Units(insert_point, replacementRange.length);
std::string_view focused_text{_focused_window->GetFocusedTextbuf()->GetText()};
insert_point = Utf8AdvanceByUtf16Units(focused_text, replacementRange.location);
replace_range = *insert_point + Utf8AdvanceByUtf16Units(focused_text.substr(*insert_point), replacementRange.length);
}
HandleTextInput(nullptr, true);
HandleTextInput([ s UTF8String ], false, nullptr, insert_point, replace_range);
HandleTextInput({}, true);
HandleTextInput([ s UTF8String ], false, std::nullopt, insert_point, replace_range);
}
/** Insert the given text at the caret. */
@ -967,17 +968,18 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
const char *utf8 = [ s UTF8String ];
if (utf8 != nullptr) {
const char *insert_point = nullptr;
const char *replace_range = nullptr;
std::optional<size_t> insert_point;
std::optional<size_t> replace_range;
if (replacementRange.location != NSNotFound) {
/* Calculate the part to be replaced. */
NSRange marked = [ self markedRange ];
insert_point = Utf8AdvanceByUtf16Units(_focused_window->GetFocusedTextbuf()->GetText(), replacementRange.location + (marked.location != NSNotFound ? marked.location : 0u));
replace_range = Utf8AdvanceByUtf16Units(insert_point, replacementRange.length);
std::string_view focused_text{_focused_window->GetFocusedTextbuf()->GetText()};
insert_point = Utf8AdvanceByUtf16Units(focused_text, replacementRange.location + (marked.location != NSNotFound ? marked.location : 0u));
replace_range = *insert_point + Utf8AdvanceByUtf16Units(focused_text.substr(*insert_point), replacementRange.length);
}
/* Convert caret index into a pointer in the UTF-8 string. */
const char *selection = Utf8AdvanceByUtf16Units(utf8, selRange.location);
size_t selection = Utf8AdvanceByUtf16Units(utf8, selRange.location);
HandleTextInput(utf8, true, selection, insert_point, replace_range);
}
@ -992,7 +994,7 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
/** Unmark the current marked text. */
- (void)unmarkText
{
HandleTextInput(nullptr, true);
HandleTextInput({}, true);
}
/** Get the caret position. */
@ -1084,8 +1086,8 @@ void CocoaDialog(std::string_view title, std::string_view message, std::string_v
std::string_view focused_text = _focused_window->GetFocusedTextbuf()->GetText();
/* Convert range to UTF-8 string pointers. */
const char *start = Utf8AdvanceByUtf16Units(focused_text, aRange.location);
const char *end = aRange.length != 0 ? Utf8AdvanceByUtf16Units(focused_text, aRange.location + aRange.length) : start;
size_t start = Utf8AdvanceByUtf16Units(focused_text, aRange.location);
size_t end = start + Utf8AdvanceByUtf16Units(focused_text.substr(start), aRange.length);
/* Get the bounding rect for the text range.*/
Rect r = _focused_window->GetTextBoundingRect(start, end);

View File

@ -346,8 +346,8 @@ static LRESULT HandleIMEComposition(HWND hwnd, WPARAM wParam, LPARAM lParam)
/* Transmit text to windowing system. */
if (len > 0) {
HandleTextInput(nullptr, true); // Clear marked string.
HandleTextInput(FS2OTTD(str).c_str());
HandleTextInput({}, true); // Clear marked string.
HandleTextInput(FS2OTTD(str));
}
SetCompositionPos(hwnd);
@ -380,9 +380,9 @@ static LRESULT HandleIMEComposition(HWND hwnd, WPARAM wParam, LPARAM lParam)
++caret;
}
HandleTextInput(utf8_buf, true, utf8_buf + caret.GetByteOffset());
HandleTextInput(utf8_buf, true, caret.GetByteOffset());
} else {
HandleTextInput(nullptr, true);
HandleTextInput({}, true);
}
lParam &= ~(GCS_COMPSTR | GCS_COMPATTR | GCS_COMPCLAUSE | GCS_CURSORPOS | GCS_DELTASTART);
@ -400,7 +400,7 @@ static void CancelIMEComposition(HWND hwnd)
if (hIMC != nullptr) ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0);
ImmReleaseContext(hwnd, hIMC);
/* Clear any marked string from the current edit box. */
HandleTextInput(nullptr, true);
HandleTextInput({}, true);
}
static bool IsDarkModeEnabled()
@ -597,7 +597,7 @@ LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
case WM_IME_ENDCOMPOSITION:
/* Clear any pending composition string. */
HandleTextInput(nullptr, true);
HandleTextInput({}, true);
if (DrawIMECompositionString()) return 0;
break;

View File

@ -390,7 +390,7 @@ void Window::UpdateQueryStringSize()
* @param to End of the string range.
* @return Rectangle encompassing the string range, relative to the window.
*/
/* virtual */ Rect Window::GetTextBoundingRect(const char *from, const char *to) const
/* virtual */ Rect Window::GetTextBoundingRect(size_t from, size_t to) const
{
if (this->nested_focus != nullptr && this->nested_focus->type == WWT_EDITBOX) {
return this->GetQueryString(this->nested_focus->GetIndex())->GetBoundingRect(this, this->nested_focus->GetIndex(), from, to);
@ -2647,7 +2647,7 @@ void HandleCtrlChanged()
* @param wid Edit box widget.
* @param str Text string to insert.
*/
/* virtual */ void Window::InsertTextString(WidgetID wid, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end)
/* virtual */ void Window::InsertTextString(WidgetID wid, std::string_view str, bool marked, std::optional<size_t> caret, std::optional<size_t> insert_location, std::optional<size_t> replacement_end)
{
QueryString *query = this->GetQueryString(wid);
if (query == nullptr) return;
@ -2664,7 +2664,7 @@ void HandleCtrlChanged()
* @param marked Is the input a marked composition string from an IME?
* @param caret Move the caret to this point in the insertion string.
*/
void HandleTextInput(const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end)
void HandleTextInput(std::string_view str, bool marked, std::optional<size_t> caret, std::optional<size_t> insert_location, std::optional<size_t> replacement_end)
{
if (!EditBoxInGlobalFocus()) return;

View File

@ -342,7 +342,7 @@ public:
virtual const struct Textbuf *GetFocusedTextbuf() const;
virtual Point GetCaretPosition() const;
virtual Rect GetTextBoundingRect(const char *from, const char *to) const;
virtual Rect GetTextBoundingRect(size_t from, size_t to) const;
virtual ptrdiff_t GetTextCharacterAtPosition(const Point &pt) const;
void InitNested(WindowNumber number = 0);
@ -497,7 +497,7 @@ public:
bool SetFocusedWidget(WidgetID widget_index);
EventState HandleEditBoxKey(WidgetID wid, char32_t key, uint16_t keycode);
virtual void InsertTextString(WidgetID wid, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end);
virtual void InsertTextString(WidgetID wid, std::string_view str, bool marked, std::optional<size_t> caret, std::optional<size_t> insert_location, std::optional<size_t> replacement_end);
void HandleButtonClick(WidgetID widget);
int GetRowFromWidget(int clickpos, WidgetID widget, int padding, int line_height = -1) const;