mirror of https://github.com/odrling/Aegisub
Lua: Functions to set text selection and cursor
Putting this logic for delaying changes in the TextSelectionController isn't the cleanest, but all attempts at saving this state somewhere in the Lua API instead turned out even worse. Also, the logic for inverted selections probably does belong in there.
This commit is contained in:
parent
8336c7d97c
commit
c0fa794e45
|
@ -51,6 +51,7 @@
|
|||
#include "selection_controller.h"
|
||||
#include "subs_controller.h"
|
||||
#include "video_controller.h"
|
||||
#include "text_selection_controller.h"
|
||||
#include "utils.h"
|
||||
|
||||
#include <libaegisub/dispatch.h>
|
||||
|
@ -285,6 +286,39 @@ namespace {
|
|||
return 0;
|
||||
}
|
||||
|
||||
int lua_get_text_cursor(lua_State *L)
|
||||
{
|
||||
push_value(L, get_context(L)->textSelectionController->GetStagedInsertionPoint() + 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int lua_set_text_cursor(lua_State *L)
|
||||
{
|
||||
int point = lua_tointeger(L, -1) - 1;
|
||||
lua_pop(L, 1);
|
||||
get_context(L)->textSelectionController->StageSetInsertionPoint(point);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int lua_get_text_selection(lua_State *L)
|
||||
{
|
||||
const agi::Context *c = get_context(L);
|
||||
int start = c->textSelectionController->GetStagedSelectionStart() + 1;
|
||||
int end = c->textSelectionController->GetStagedSelectionEnd() + 1;
|
||||
push_value(L, start <= end ? start : end);
|
||||
push_value(L, start <= end ? end : start);
|
||||
return 2;
|
||||
}
|
||||
|
||||
int lua_set_text_selection(lua_State *L)
|
||||
{
|
||||
int start = lua_tointeger(L, -2) - 1;
|
||||
int end = lua_tointeger(L, -1) - 1;
|
||||
lua_pop(L, 2);
|
||||
get_context(L)->textSelectionController->StageSetSelection(start, end);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int project_properties(lua_State *L)
|
||||
{
|
||||
const agi::Context *c = get_context(L);
|
||||
|
@ -489,6 +523,12 @@ namespace {
|
|||
set_field<project_properties>(L, "project_properties");
|
||||
set_field<lua_get_audio_selection>(L, "get_audio_selection");
|
||||
set_field<lua_set_status_text>(L, "set_status_text");
|
||||
lua_createtable(L, 0, 4);
|
||||
set_field<lua_get_text_cursor>(L, "get_cursor");
|
||||
set_field<lua_set_text_cursor>(L, "set_cursor");
|
||||
set_field<lua_get_text_selection>(L, "get_selection");
|
||||
set_field<lua_set_text_selection>(L, "set_selection");
|
||||
lua_setfield(L, -2, "gui");
|
||||
|
||||
// store aegisub table to globals
|
||||
lua_settable(L, LUA_GLOBALSINDEX);
|
||||
|
@ -786,6 +826,7 @@ namespace {
|
|||
|
||||
void LuaCommand::operator()(agi::Context *c)
|
||||
{
|
||||
c->textSelectionController->DropStagedChanges();
|
||||
LuaStackcheck stackcheck(L);
|
||||
set_context(L, c);
|
||||
stackcheck.check_stack(0);
|
||||
|
@ -883,6 +924,7 @@ namespace {
|
|||
new_active = *new_sel.begin();
|
||||
c->selectionController->SetSelectionAndActive(std::move(new_sel), new_active);
|
||||
}
|
||||
c->textSelectionController->CommitStagedChanges();
|
||||
|
||||
stackcheck.check_stack(0);
|
||||
}
|
||||
|
|
|
@ -73,3 +73,18 @@ void TextSelectionController::SetSelection(int start, int end) {
|
|||
changing = false;
|
||||
AnnounceSelectionChanged();
|
||||
}
|
||||
|
||||
|
||||
void TextSelectionController::CommitStagedChanges() {
|
||||
if (has_staged_selection) {
|
||||
if (staged_selection_start <= staged_selection_end) {
|
||||
SetSelection(staged_selection_start, staged_selection_end);
|
||||
} else {
|
||||
// commit some crimes to get this to work in all cases
|
||||
SetInsertionPoint(staged_selection_end == 0 ? staged_selection_start : 0);
|
||||
SetSelection(staged_selection_start, staged_selection_start);
|
||||
SetInsertionPoint(staged_selection_end);
|
||||
}
|
||||
has_staged_selection = false;
|
||||
}
|
||||
}
|
|
@ -25,6 +25,10 @@ class TextSelectionController {
|
|||
int insertion_point = 0;
|
||||
bool changing = false;
|
||||
|
||||
int staged_selection_start = 0;
|
||||
int staged_selection_end = 0;
|
||||
bool has_staged_selection = false;
|
||||
|
||||
wxStyledTextCtrl *ctrl = nullptr;
|
||||
|
||||
void UpdateUI(wxStyledTextEvent &evt);
|
||||
|
@ -35,10 +39,23 @@ public:
|
|||
void SetSelection(int start, int end);
|
||||
void SetInsertionPoint(int point);
|
||||
|
||||
// This set of functions allows staging changes to the selection or insertion points, which can then be applied later.
|
||||
// This is useful when one is still waiting on other changes to be applied, but already listening for changes to the
|
||||
// selection in the eventually visible text.
|
||||
// They also provide a wrapper for setting a selection whose insertion point is on the left side.
|
||||
void StageSetSelection(int start, int end) { staged_selection_start = start; staged_selection_end = end; has_staged_selection = true; };
|
||||
void StageSetInsertionPoint(int point) { StageSetSelection(point, point); };
|
||||
void CommitStagedChanges();
|
||||
void DropStagedChanges() { has_staged_selection = false; };
|
||||
|
||||
int GetSelectionStart() const { return selection_start; }
|
||||
int GetSelectionEnd() const { return selection_end; }
|
||||
int GetInsertionPoint() const { return insertion_point; }
|
||||
|
||||
int GetStagedSelectionStart() const { return has_staged_selection ? staged_selection_start : selection_start; }
|
||||
int GetStagedSelectionEnd() const { return has_staged_selection ? staged_selection_end : selection_end; }
|
||||
int GetStagedInsertionPoint() const { return has_staged_selection ? staged_selection_end : insertion_point; }
|
||||
|
||||
void SetControl(wxStyledTextCtrl *ctrl);
|
||||
~TextSelectionController();
|
||||
|
||||
|
|
Loading…
Reference in New Issue