Don't update the editbox styling when it hasn't changed

The syntax highlighting isn't especially slow, but the stylesneeded
event seems to be sent repeatedly until the styles aren't changed, so it
was pointlessly reparsing and restyling the text on every idle event.
This commit is contained in:
Thomas Goyne 2012-11-06 06:33:44 -08:00
parent f628f92747
commit 24c21dd425
2 changed files with 37 additions and 24 deletions

View file

@ -118,9 +118,9 @@ SubsTextEditCtrl::SubsTextEditCtrl(wxWindow* parent, wxSize wsize, long style, a
Bind(wxEVT_COMMAND_MENU_SELECTED, bind(&cmd::call, "edit/line/split/estimate", context), EDIT_MENU_SPLIT_ESTIMATE); Bind(wxEVT_COMMAND_MENU_SELECTED, bind(&cmd::call, "edit/line/split/estimate", context), EDIT_MENU_SPLIT_ESTIMATE);
} }
Bind(wxEVT_STC_STYLENEEDED, &SubsTextEditCtrl::UpdateCallTip, this); Bind(wxEVT_STC_STYLENEEDED, std::bind(&SubsTextEditCtrl::UpdateStyle, this));
Bind(wxEVT_CONTEXT_MENU, &SubsTextEditCtrl::OnContextMenu, this); Bind(wxEVT_CONTEXT_MENU, &SubsTextEditCtrl::OnContextMenu, this);
Bind(wxEVT_IDLE, std::bind(&SubsTextEditCtrl::UpdateCallTip, this));
OPT_SUB("Subtitle/Edit Box/Font Face", &SubsTextEditCtrl::SetStyles, this); OPT_SUB("Subtitle/Edit Box/Font Face", &SubsTextEditCtrl::SetStyles, this);
OPT_SUB("Subtitle/Edit Box/Font Size", &SubsTextEditCtrl::SetStyles, this); OPT_SUB("Subtitle/Edit Box/Font Size", &SubsTextEditCtrl::SetStyles, this);
@ -137,8 +137,7 @@ SubsTextEditCtrl::SubsTextEditCtrl(wxWindow* parent, wxSize wsize, long style, a
Subscribe("Karaoke Variable"); Subscribe("Karaoke Variable");
OPT_SUB("Subtitle/Highlight/Syntax", &SubsTextEditCtrl::UpdateStyle, this); OPT_SUB("Subtitle/Highlight/Syntax", &SubsTextEditCtrl::UpdateStyle, this);
static wxStyledTextEvent evt; OPT_SUB("App/Call Tips", &SubsTextEditCtrl::UpdateCallTip, this);
OPT_SUB("App/Call Tips", &SubsTextEditCtrl::UpdateCallTip, this, std::ref(evt));
} }
SubsTextEditCtrl::~SubsTextEditCtrl() { SubsTextEditCtrl::~SubsTextEditCtrl() {
@ -208,39 +207,43 @@ void SubsTextEditCtrl::SetStyles() {
} }
void SubsTextEditCtrl::UpdateStyle() { void SubsTextEditCtrl::UpdateStyle() {
{
std::string text = GetTextRaw().data();
if (text == line_text) return;
line_text = move(text);
}
tokenized_line = agi::ass::TokenizeDialogueBody(line_text);
cursor_pos = -1;
UpdateCallTip();
StartStyling(0,255); StartStyling(0,255);
std::string text = GetTextRaw().data();
if (!OPT_GET("Subtitle/Highlight/Syntax")->GetBool()) { if (!OPT_GET("Subtitle/Highlight/Syntax")->GetBool()) {
SetStyling(text.size(), 0); SetStyling(line_text.size(), 0);
return; return;
} }
if (text.empty()) return; if (line_text.empty()) return;
AssDialogue *diag = context ? context->selectionController->GetActiveLine() : 0; AssDialogue *diag = context ? context->selectionController->GetActiveLine() : 0;
bool template_line = diag && diag->Comment && diag->Effect.Lower().StartsWith("template"); bool template_line = diag && diag->Comment && diag->Effect.Lower().StartsWith("template");
auto tokens = agi::ass::TokenizeDialogueBody(text); for (auto const& style_range : agi::ass::SyntaxHighlight(line_text, tokenized_line, template_line, spellchecker.get()))
for (auto const& style_range : agi::ass::SyntaxHighlight(text, tokens, template_line, spellchecker.get()))
SetStyling(style_range.length, style_range.type); SetStyling(style_range.length, style_range.type);
} }
/// @brief Update call tip void SubsTextEditCtrl::UpdateCallTip() {
void SubsTextEditCtrl::UpdateCallTip(wxStyledTextEvent &) {
UpdateStyle();
if (!OPT_GET("App/Call Tips")->GetBool()) return; if (!OPT_GET("App/Call Tips")->GetBool()) return;
int pos = GetCurrentPos();
if (!pos == cursor_pos) return;
cursor_pos = pos;
if (!calltip_provider) if (!calltip_provider)
calltip_provider.reset(new agi::CalltipProvider); calltip_provider.reset(new agi::CalltipProvider);
std::string text = GetTextRaw().data(); agi::Calltip new_calltip = calltip_provider->GetCalltip(tokenized_line, line_text, pos);
auto tokens = agi::ass::TokenizeDialogueBody(text);
int pos = GetCurrentPos();
agi::Calltip new_calltip = calltip_provider->GetCalltip(tokens, text, GetCurrentPos());
if (new_calltip.text.empty()) { if (new_calltip.text.empty()) {
CallTipCancel(); CallTipCancel();
@ -256,15 +259,15 @@ void SubsTextEditCtrl::UpdateCallTip(wxStyledTextEvent &) {
CallTipSetHighlight(new_calltip.highlight_start, new_calltip.highlight_end); CallTipSetHighlight(new_calltip.highlight_start, new_calltip.highlight_end);
} }
void SubsTextEditCtrl::SetTextTo(wxString text) { void SubsTextEditCtrl::SetTextTo(wxString const& text) {
SetEvtHandlerEnabled(false); SetEvtHandlerEnabled(false);
Freeze(); Freeze();
int from=0,to=0; int from=0,to=0;
GetSelection(&from,&to); GetSelection(&from,&to);
line_text.clear();
SetText(text); SetText(text);
UpdateStyle();
// Restore selection // Restore selection
SetSelectionU(GetReverseUnicodePosition(from), GetReverseUnicodePosition(to)); SetSelectionU(GetReverseUnicodePosition(from), GetReverseUnicodePosition(to));
@ -290,7 +293,6 @@ void SubsTextEditCtrl::Paste() {
int sel_start = GetUnicodePosition(from + data.size()); int sel_start = GetUnicodePosition(from + data.size());
SetSelectionStart(sel_start); SetSelectionStart(sel_start);
SetSelectionEnd(sel_start); SetSelectionEnd(sel_start);
UpdateStyle();
} }
void SubsTextEditCtrl::OnContextMenu(wxContextMenuEvent &event) { void SubsTextEditCtrl::OnContextMenu(wxContextMenuEvent &event) {

View file

@ -47,6 +47,7 @@ namespace agi {
class CalltipProvider; class CalltipProvider;
class SpellChecker; class SpellChecker;
struct Context; struct Context;
namespace ass { struct DialogueToken; }
} }
/// @class SubsTextEditCtrl /// @class SubsTextEditCtrl
@ -82,6 +83,16 @@ class SubsTextEditCtrl : public ScintillaTextCtrl {
/// Position of the currently show calltip /// Position of the currently show calltip
size_t calltip_position; size_t calltip_position;
/// Cursor position which the current calltip is for
int cursor_pos;
/// The last seen line text, used to avoid reparsing the line for syntax
/// highlighting when possible
std::string line_text;
/// Tokenized version of line_text
std::vector<agi::ass::DialogueToken> tokenized_line;
void OnContextMenu(wxContextMenuEvent &); void OnContextMenu(wxContextMenuEvent &);
void OnAddToDictionary(wxCommandEvent &event); void OnAddToDictionary(wxCommandEvent &event);
void OnUseSuggestion(wxCommandEvent &event); void OnUseSuggestion(wxCommandEvent &event);
@ -94,7 +105,7 @@ class SubsTextEditCtrl : public ScintillaTextCtrl {
void Subscribe(std::string const& name); void Subscribe(std::string const& name);
void StyleSpellCheck(); void StyleSpellCheck();
void UpdateCallTip(wxStyledTextEvent &); void UpdateCallTip();
void SetStyles(); void SetStyles();
void UpdateStyle(); void UpdateStyle();
@ -115,7 +126,7 @@ public:
SubsTextEditCtrl(wxWindow* parent, wxSize size, long style, agi::Context *context); SubsTextEditCtrl(wxWindow* parent, wxSize size, long style, agi::Context *context);
~SubsTextEditCtrl(); ~SubsTextEditCtrl();
void SetTextTo(wxString text); void SetTextTo(wxString const& text);
void Paste(); void Paste();
DECLARE_EVENT_TABLE() DECLARE_EVENT_TABLE()