未验证 提交 7e6191de 编写于 作者: C Chris Bracken 提交者: GitHub

Separate mutators for text and selection (#21612)

Previously, TextInputModel's SetEditingState method was a 1:1 mapping of
the underlying protocol used on the text input channel between the
framework and the engine. This breaks it up into two methods, which
allows the selection to be updated independently of the text, and avoids
tying the API the the underlying protocol.

This will become more important when we add additional state to support
composing regions for multi-step input methods such as those used for
Japanese.

SetText resets the selection rather than making a best-efforts attempt
to preserve it. This choice was primarily to keep the code simple and
make the API easier to reason about. An alternative would have been to
make a best-effort attempt to preserve the selection, potentially
clamping one or both to the end of the new string. In all cases where an
embedder resets the string, it is expected that they also have the
selection, so can call SetSelection with an updated selection if needed.
上级 8842e502
......@@ -35,17 +35,20 @@ TextInputModel::TextInputModel()
TextInputModel::~TextInputModel() = default;
bool TextInputModel::SetEditingState(size_t selection_base,
size_t selection_extent,
const std::string& text) {
if (selection_base > text.size() || selection_extent > text.size()) {
return false;
}
void TextInputModel::SetText(const std::string& text) {
std::wstring_convert<std::codecvt_utf8_utf16<char16_t>, char16_t>
utf16_converter;
text_ = utf16_converter.from_bytes(text);
selection_base_ = text_.begin() + selection_base;
selection_extent_ = text_.begin() + selection_extent;
selection_base_ = text_.begin();
selection_extent_ = selection_base_;
}
bool TextInputModel::SetSelection(size_t base, size_t extent) {
if (base > text_.size() || extent > text_.size()) {
return false;
}
selection_base_ = text_.begin() + base;
selection_extent_ = text_.begin() + extent;
return true;
}
......
......@@ -17,13 +17,15 @@ class TextInputModel {
TextInputModel();
virtual ~TextInputModel();
// Attempts to set the text state.
// Sets the text.
//
// Returns false if the state is not valid (base or extent are out of
// bounds, or base is less than extent).
bool SetEditingState(size_t selection_base,
size_t selection_extent,
const std::string& text);
// Resets the selection base and extent.
void SetText(const std::string& text);
// Attempts to set the text selection.
//
// Returns false if the base or extent are out of bounds.
bool SetSelection(size_t base, size_t extent);
// Adds a Unicode code point.
//
......
......@@ -194,7 +194,8 @@ void TextInputPlugin::HandleMethodCall(
if (base == -1 && extent == -1) {
base = extent = 0;
}
active_model_->SetEditingState(base, extent, text->value.GetString());
active_model_->SetText(text->value.GetString());
active_model_->SetSelection(base, extent);
} else {
result->NotImplemented();
return;
......
......@@ -218,7 +218,8 @@ static FlMethodResponse* set_editing_state(FlTextInputPlugin* self,
selection_base = selection_extent = 0;
}
self->text_model->SetEditingState(selection_base, selection_extent, text);
self->text_model->SetText(text);
self->text_model->SetSelection(selection_base, selection_extent);
return FL_METHOD_RESPONSE(fl_method_success_response_new(nullptr));
}
......
......@@ -195,7 +195,8 @@ void TextInputPlugin::HandleMethodCall(
if (base == -1 && extent == -1) {
base = extent = 0;
}
active_model_->SetEditingState(base, extent, text->value.GetString());
active_model_->SetText(text->value.GetString());
active_model_->SetSelection(base, extent);
} else {
result->NotImplemented();
return;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册