Skip to content

Commit

Permalink
Allow using wxTextCtrl as subtitle edit box
Browse files Browse the repository at this point in the history
Fix #81
  • Loading branch information
wangqr committed Apr 3, 2021
1 parent 3d7b8c4 commit c39d3c5
Show file tree
Hide file tree
Showing 5 changed files with 187 additions and 39 deletions.
1 change: 1 addition & 0 deletions src/command/edit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1261,6 +1261,7 @@ struct edit_insert_original final : public Command {

line->Text = line->Text.get().substr(0, sel_start) + c->initialLineState->GetInitialText() + line->Text.get().substr(sel_end);
c->ass->Commit(_("insert original"), AssFile::COMMIT_DIAG_TEXT, -1, line);
c->textSelectionController->SetSelection(sel_start, sel_start + c->initialLineState->GetInitialText().length());
}
};

Expand Down
125 changes: 106 additions & 19 deletions src/subs_edit_box.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -213,18 +213,41 @@ SubsEditBox::SubsEditBox(wxWindow *parent, agi::Context *context)
main_sizer->Add(middle_right_sizer, wxSizerFlags().Expand().Border(wxLEFT | wxRIGHT | wxBOTTOM, 3));

// Text editor
edit_ctrl_stc = new SubsTextEditCtrl(this, wxDefaultSize, wxBORDER_SUNKEN, c);
edit_ctrl_stc->Bind(wxEVT_CHAR_HOOK, &SubsEditBox::OnKeyDown, this);
#ifdef WITH_WXSTC
if (use_stc) {
edit_ctrl_stc = new SubsTextEditCtrl(this, wxDefaultSize, wxBORDER_SUNKEN, c);
edit_ctrl_stc->Bind(wxEVT_CHAR_HOOK, &SubsEditBox::OnKeyDown, this);
}
else {
#endif
edit_ctrl_tc = new wxTextCtrl(this, wxID_ANY, wxEmptyString, wxDefaultPosition, wxDefaultSize, wxBORDER_SUNKEN | wxTE_MULTILINE);
edit_ctrl_tc->Bind(wxEVT_CHAR_HOOK, &SubsEditBox::OnKeyDown, this);
#ifdef WITH_WXSTC
}
#endif

secondary_editor = new wxTextCtrl(this, -1, "", wxDefaultPosition, wxDefaultSize, wxBORDER_SUNKEN | wxTE_MULTILINE | wxTE_READONLY);
// Here we use the height of secondary_editor as the initial size of edit_ctrl_stc,
// which is more reasonable than the default given by wxWidgets.
// See: https://trac.wxwidgets.org/ticket/18471#ticket
// https://github.com/wangqr/Aegisub/issues/4
edit_ctrl_stc->SetInitialSize(secondary_editor->GetSize());
#ifdef WITH_WXSTC
if (use_stc) {
// Here we use the height of secondary_editor as the initial size of edit_ctrl_stc,
// which is more reasonable than the default given by wxWidgets.
// See: https://trac.wxwidgets.org/ticket/18471#ticket
// https://github.com/wangqr/Aegisub/issues/4
edit_ctrl_stc->SetInitialSize(secondary_editor->GetSize());
}
#endif

main_sizer->Add(secondary_editor, wxSizerFlags(1).Expand().Border(wxLEFT | wxRIGHT | wxBOTTOM, 3));
main_sizer->Add(edit_ctrl_stc, wxSizerFlags(1).Expand().Border(wxLEFT | wxRIGHT | wxBOTTOM, 3));
#ifdef WITH_WXSTC
if (use_stc) {
main_sizer->Add(edit_ctrl_stc, wxSizerFlags(1).Expand().Border(wxLEFT | wxRIGHT | wxBOTTOM, 3));
}
else {
#endif
main_sizer->Add(edit_ctrl_tc, wxSizerFlags(1).Expand().Border(wxLEFT | wxRIGHT | wxBOTTOM, 3));
#ifdef WITH_WXSTC
}
#endif
main_sizer->Hide(secondary_editor);

bottom_sizer = new wxBoxSizer(wxHORIZONTAL);
Expand All @@ -237,8 +260,17 @@ SubsEditBox::SubsEditBox(wxWindow *parent, agi::Context *context)

SetSizerAndFit(main_sizer);

edit_ctrl_stc->Bind(wxEVT_STC_MODIFIED, &SubsEditBox::OnChange, this);
edit_ctrl_stc->SetModEventMask(wxSTC_MOD_INSERTTEXT | wxSTC_MOD_DELETETEXT | wxSTC_STARTACTION);
#ifdef WITH_WXSTC
if (use_stc) {
edit_ctrl_stc->Bind(wxEVT_STC_MODIFIED, &SubsEditBox::OnChangeStc, this);
edit_ctrl_stc->SetModEventMask(wxSTC_MOD_INSERTTEXT | wxSTC_MOD_DELETETEXT | wxSTC_STARTACTION);
}
else {
#endif
edit_ctrl_tc->Bind(wxEVT_TEXT, &SubsEditBox::OnChangeTc, this);
#ifdef WITH_WXSTC
}
#endif

Bind(wxEVT_TEXT, &SubsEditBox::OnLayerEnter, this, layer->GetId());
Bind(wxEVT_SPINCTRL, &SubsEditBox::OnLayerEnter, this, layer->GetId());
Expand All @@ -259,8 +291,18 @@ SubsEditBox::SubsEditBox(wxWindow *parent, agi::Context *context)
context->initialLineState->AddChangeListener(&SubsEditBox::OnLineInitialTextChanged, this),
});

context->textSelectionController->SetControl(edit_ctrl_stc);
edit_ctrl_stc->SetFocus();
#ifdef WITH_WXSTC
if (use_stc) {
context->textSelectionController->SetControl(edit_ctrl_stc);
edit_ctrl_stc->SetFocus();
}
else {
#endif
context->textSelectionController->SetControl(edit_ctrl_tc);
edit_ctrl_tc->SetFocus();
#ifdef WITH_WXSTC
}
#endif

bool show_original = OPT_GET("Subtitle/Show Original")->GetBool();
if (show_original) {
Expand All @@ -270,7 +312,7 @@ SubsEditBox::SubsEditBox(wxWindow *parent, agi::Context *context)
}

SubsEditBox::~SubsEditBox() {
c->textSelectionController->SetControl(nullptr);
c->textSelectionController->SetControl((wxTextCtrl*)nullptr);
}

wxTextCtrl *SubsEditBox::MakeMarginCtrl(wxString const& tooltip, int margin, wxString const& commit_msg) {
Expand Down Expand Up @@ -384,7 +426,16 @@ void SubsEditBox::UpdateFields(int type, bool repopulate_lists) {
}

if (type & AssFile::COMMIT_DIAG_TEXT) {
edit_ctrl_stc->SetTextTo(line->Text);
#ifdef WITH_WXSTC
if (use_stc) {
edit_ctrl_stc->SetTextTo(line->Text);
}
else {
#endif
edit_ctrl_tc->SetValue(to_wx(line->Text));
#ifdef WITH_WXSTC
}
#endif
UpdateCharacterCount(line->Text);
}

Expand Down Expand Up @@ -470,14 +521,23 @@ void SubsEditBox::OnKeyDown(wxKeyEvent &event) {
hotkey::check("Subtitle Edit Box", c, event);
}

void SubsEditBox::OnChange(wxStyledTextEvent &event) {
#ifdef WITH_WXSTC
void SubsEditBox::OnChangeStc(wxStyledTextEvent &event) {
if (line && edit_ctrl_stc->GetTextRaw().data() != line->Text.get()) {
if (event.GetModificationType() & wxSTC_STARTACTION)
commit_id = -1;
CommitText(_("modify text"));
UpdateCharacterCount(line->Text);
}
}
#endif

void SubsEditBox::OnChangeTc(wxCommandEvent& event) {
if (line && edit_ctrl_tc->GetValue().utf8_str() != line->Text.get()) {
CommitText(_("modify text"));
UpdateCharacterCount(line->Text);
}
}

void SubsEditBox::Commit(wxString const& desc, int type, bool amend, AssDialogue *line) {
file_changed_slot.Block();
Expand Down Expand Up @@ -508,8 +568,17 @@ void SubsEditBox::SetSelectedRows(T AssDialogueBase::*field, wxString const& val
}

void SubsEditBox::CommitText(wxString const& desc) {
auto data = edit_ctrl_stc->GetTextRaw();
SetSelectedRows(&AssDialogue::Text, boost::flyweight<std::string>(data.data(), data.length()), desc, AssFile::COMMIT_DIAG_TEXT, true);
#ifdef WITH_WXSTC
if (use_stc) {
auto data = edit_ctrl_stc->GetTextRaw();
SetSelectedRows(&AssDialogue::Text, boost::flyweight<std::string>(data.data(), data.length()), desc, AssFile::COMMIT_DIAG_TEXT, true);
}
else {
#endif
SetSelectedRows(&AssDialogue::Text, boost::flyweight<std::string>(edit_ctrl_tc->GetValue().utf8_str()), desc, AssFile::COMMIT_DIAG_TEXT, true);
#ifdef WITH_WXSTC
}
#endif
}

void SubsEditBox::CommitTimes(TimeField field) {
Expand Down Expand Up @@ -608,7 +677,16 @@ void SubsEditBox::SetControlsState(bool state) {
Enable(state);
if (!state) {
wxEventBlocker blocker(this);
edit_ctrl_stc->SetTextTo("");
#ifdef WITH_WXSTC
if (use_stc) {
edit_ctrl_stc->SetTextTo("");
}
else {
#endif
edit_ctrl_tc->Clear();
#ifdef WITH_WXSTC
}
#endif
}
}

Expand Down Expand Up @@ -659,7 +737,16 @@ void SubsEditBox::OnCommentChange(wxCommandEvent &evt) {

void SubsEditBox::CallCommand(const char *cmd_name) {
cmd::call(cmd_name, c);
edit_ctrl_stc->SetFocus();
#ifdef WITH_WXSTC
if (use_stc) {
edit_ctrl_stc->SetFocus();
}
else {
#endif
edit_ctrl_tc->SetFocus();
#ifdef WITH_WXSTC
}
#endif
}

void SubsEditBox::UpdateCharacterCount(std::string const& text) {
Expand Down
5 changes: 4 additions & 1 deletion src/subs_edit_box.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,10 @@ class SubsEditBox final : public wxPanel {
wxComboBox *MakeComboBox(wxString const& initial_text, int style, void (SubsEditBox::*handler)(wxCommandEvent&), wxString const& tooltip);
wxRadioButton *MakeRadio(wxString const& text, bool start, wxString const& tooltip);

void OnChange(wxStyledTextEvent &event);
#ifdef WITH_WXSTC
void OnChangeStc(wxStyledTextEvent &event);
#endif
void OnChangeTc(wxCommandEvent& event);
void OnKeyDown(wxKeyEvent &event);

void OnActiveLineChanged(AssDialogue *new_line);
Expand Down
91 changes: 74 additions & 17 deletions src/text_selection_controller.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,8 @@ void TextSelectionController::SetControl(wxTextCtrl* ctrl) {
this->ctrl_te = ctrl;
this->ctrl_ctl = ctrl;
if (ctrl) {
ctrl->Bind(wxEVT_KEY_DOWN, &TextSelectionController::UpdateUI, this);
ctrl->Bind(wxEVT_LEFT_DOWN, &TextSelectionController::UpdateUI, this);
ctrl->Bind(wxEVT_KEY_UP, &TextSelectionController::UpdateUI, this);
ctrl->Bind(wxEVT_LEFT_UP, &TextSelectionController::UpdateUI, this);
}
#ifdef WITH_WXSTC
use_stc = false;
Expand All @@ -56,45 +56,102 @@ TextSelectionController::~TextSelectionController() {
#endif
}

#define GET(var, new_value) do { \
int tmp = new_value; \
if (tmp != var) { \
var = tmp; \
changed = true; \
} \
} while(false)

void TextSelectionController::UpdateUI(wxEvent& evt) {
evt.Skip();
if (changing) return;

bool changed = false;
GET(insertion_point, ctrl_te->GetInsertionPoint());
long tmp_start, tmp_end;
long tmp_insertion, tmp_start, tmp_end;
tmp_insertion = ctrl_te->GetInsertionPoint();
ctrl_te->GetSelection(&tmp_start, &tmp_end);
if (tmp_start != selection_start || tmp_end != selection_end) {
#ifdef WITH_WXSTC
if (!use_stc) {
#endif
// GetSelection returned by wxTextCtrl is the index of Unicode codepoint position
// We need to convert it to UTF-8 location
tmp_insertion = ctrl_te->GetRange(0, tmp_insertion).utf8_str().length();
tmp_start = ctrl_te->GetRange(0, tmp_start).utf8_str().length();
tmp_end = ctrl_te->GetRange(0, tmp_end).utf8_str().length();
#ifdef WITH_WXSTC
}
#endif
if (tmp_insertion != insertion_point || tmp_start != selection_start || tmp_end != selection_end) {
insertion_point = tmp_insertion;
selection_start = tmp_start;
selection_end = tmp_end;
changed = true;
}
if (changed) AnnounceSelectionChanged();
}

void TextSelectionController::SetInsertionPoint(int position) {
void TextSelectionController::SetInsertionPoint(long position) {
changing = true;
if (insertion_point != position) {
insertion_point = position;
if (ctrl_te) ctrl_te->SetInsertionPoint(position);
if (ctrl_te) {
long tmp_position = 0;
#ifdef WITH_WXSTC
if (use_stc) {
tmp_position = position;
}
else {
#endif
// Convert UTF-8 position to wxTextEdit position
long last_position = ctrl_te->GetLastPosition();
for (; tmp_position < last_position; ++tmp_position) {
if (ctrl_te->GetRange(0, tmp_position).utf8_str().length() >= position) {
break;
}
}
#ifdef WITH_WXSTC
}
#endif
ctrl_te->SetInsertionPoint(tmp_position);
}
}
changing = false;
AnnounceSelectionChanged();
}

void TextSelectionController::SetSelection(int start, int end) {
void TextSelectionController::SetSelection(long start, long end) {
changing = true;
if (selection_start != start || selection_end != end) {
selection_start = start;
selection_end = end;
if (ctrl_te) ctrl_te->SetSelection(start, end);
if (ctrl_te) {
long tmp_start = -1, tmp_end = -1;
#ifdef WITH_WXSTC
if (use_stc) {
tmp_start = start;
tmp_end = end;
}
else {
#endif
// Convert UTF-8 position to wxTextEdit position
long last_position = ctrl_te->GetLastPosition();
for (long pos = 0; pos < last_position; ++pos) {
size_t pos_utf8 = ctrl_te->GetRange(0, pos).utf8_str().length();
if (tmp_start == -1 && pos_utf8 >= start) {
tmp_start = pos;
}
if (tmp_end == -1 && pos_utf8 >= end) {
tmp_end = pos;
}
if (tmp_start != -1 && tmp_end != -1) {
break;
}
}
if (tmp_start == -1) {
tmp_start = last_position;
}
if (tmp_end == -1) {
tmp_end = last_position;
}
#ifdef WITH_WXSTC
}
#endif
ctrl_te->SetSelection(tmp_start, tmp_end);
}
}
changing = false;
AnnounceSelectionChanged();
Expand Down
4 changes: 2 additions & 2 deletions src/text_selection_controller.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,8 +36,8 @@ class TextSelectionController {
agi::signal::Signal<> AnnounceSelectionChanged;

public:
void SetSelection(int start, int end);
void SetInsertionPoint(int point);
void SetSelection(long start, long end);
void SetInsertionPoint(long point);

long GetSelectionStart() const { return selection_start; }
long GetSelectionEnd() const { return selection_end; }
Expand Down

0 comments on commit c39d3c5

Please sign in to comment.