mirror of
https://github.com/fcitx5-android/fcitx5-android.git
synced 2026-08-02 04:44:35 +08:00
Send candidate list tab actions on input panel update
This commit is contained in:
parent
87bde649ed
commit
873c08255c
@ -65,10 +65,22 @@ public:
|
||||
|
||||
void updateInputPanel() {
|
||||
const InputPanel &ip = inputPanel();
|
||||
std::vector<CandidateActionEntity> tabs;
|
||||
auto list = ip.candidateList();
|
||||
if (list) {
|
||||
auto tabbed = ip.candidateList()->toTabbed();
|
||||
if (tabbed) {
|
||||
auto tabActions = tabbed->tabActions();
|
||||
for (const auto &a: tabActions) {
|
||||
tabs.emplace_back(a);
|
||||
}
|
||||
}
|
||||
}
|
||||
frontend_->updateInputPanel(
|
||||
filterText(ip.preedit()),
|
||||
filterText(ip.auxUp()),
|
||||
filterText(ip.auxDown())
|
||||
filterText(ip.auxDown()),
|
||||
tabs
|
||||
);
|
||||
}
|
||||
|
||||
@ -237,6 +249,18 @@ public:
|
||||
}
|
||||
}
|
||||
|
||||
void triggerTabAction(const int idx) {
|
||||
const auto &list = inputPanel().candidateList();
|
||||
if (!list) return;
|
||||
const auto &tabbed = list->toTabbed();
|
||||
if (!tabbed) return;
|
||||
try {
|
||||
tabbed->triggerTabAction(idx);
|
||||
} catch (const std::exception &e) {
|
||||
FCITX_WARN() << "triggerTabAction(" << idx << ") failed:" << e.what();
|
||||
}
|
||||
}
|
||||
|
||||
void offsetCandidatePage(int delta) {
|
||||
if (delta == 0) {
|
||||
return;
|
||||
@ -360,8 +384,8 @@ void AndroidFrontend::updateClientPreedit(const Text &clientPreedit) {
|
||||
preeditCallback(clientPreedit);
|
||||
}
|
||||
|
||||
void AndroidFrontend::updateInputPanel(const Text &preedit, const Text &auxUp, const Text &auxDown) {
|
||||
inputPanelCallback(preedit, auxUp, auxDown);
|
||||
void AndroidFrontend::updateInputPanel(const Text &preedit, const Text &auxUp, const Text &auxDown, const std::vector<CandidateActionEntity> &tabs) {
|
||||
inputPanelCallback(preedit, auxUp, auxDown, tabs);
|
||||
}
|
||||
|
||||
void AndroidFrontend::releaseInputContext(const int uid) {
|
||||
@ -387,6 +411,11 @@ void AndroidFrontend::triggerCandidateAction(const int idx, const int actionIdx)
|
||||
activeIC_->triggerCandidateAction(idx, actionIdx);
|
||||
}
|
||||
|
||||
void AndroidFrontend::triggerTabAction(const int idx) {
|
||||
if (!activeIC_) return;
|
||||
activeIC_->triggerTabAction(idx);
|
||||
}
|
||||
|
||||
bool AndroidFrontend::isInputPanelEmpty() {
|
||||
if (!activeIC_) return true;
|
||||
return activeIC_->inputPanel().empty();
|
||||
@ -475,6 +504,11 @@ void AndroidFrontend::offsetCandidatePage(int delta) {
|
||||
activeIC_->offsetCandidatePage(delta);
|
||||
}
|
||||
|
||||
void AndroidFrontend::triggerCandidateListTabAction(int id) {
|
||||
if (!activeIC_) return;
|
||||
activeIC_->triggerTabAction(id);
|
||||
}
|
||||
|
||||
void AndroidFrontend::setCommitStringCallback(const CommitStringCallback &callback) {
|
||||
commitStringCallback = callback;
|
||||
}
|
||||
@ -483,7 +517,7 @@ void AndroidFrontend::setPreeditCallback(const ClientPreeditCallback &callback)
|
||||
preeditCallback = callback;
|
||||
}
|
||||
|
||||
void AndroidFrontend::setInputPanelAuxCallback(const InputPanelCallback &callback) {
|
||||
void AndroidFrontend::setInputPanelCallback(const InputPanelCallback &callback) {
|
||||
inputPanelCallback = callback;
|
||||
}
|
||||
|
||||
|
||||
@ -26,7 +26,7 @@ public:
|
||||
void updateCandidateList(const std::vector<CandidateEntity> &candidates, int total);
|
||||
void commitString(const std::string &str, int cursor);
|
||||
void updateClientPreedit(const Text &clientPreedit);
|
||||
void updateInputPanel(const Text &preedit, const Text &auxUp, const Text &auxDown);
|
||||
void updateInputPanel(const Text &preedit, const Text &auxUp, const Text &auxDown, const std::vector<CandidateActionEntity> &tabs);
|
||||
void releaseInputContext(int uid);
|
||||
void updatePagedCandidate(const PagedCandidateEntity &paged);
|
||||
|
||||
@ -44,14 +44,16 @@ public:
|
||||
std::vector<CandidateEntity> getCandidates(int offset, int limit);
|
||||
std::vector<CandidateActionEntity> getCandidateActions(int idx);
|
||||
void triggerCandidateAction(int idx, int actionIdx);
|
||||
void triggerTabAction(int idx);
|
||||
void deleteSurrounding(int before, int after);
|
||||
void showToast(const std::string &s);
|
||||
void setCandidatePagingMode(int mode);
|
||||
void offsetCandidatePage(int delta);
|
||||
void triggerCandidateListTabAction(int id);
|
||||
void setCandidateListCallback(const CandidateListCallback &callback);
|
||||
void setCommitStringCallback(const CommitStringCallback &callback);
|
||||
void setPreeditCallback(const ClientPreeditCallback &callback);
|
||||
void setInputPanelAuxCallback(const InputPanelCallback &callback);
|
||||
void setInputPanelCallback(const InputPanelCallback &callback);
|
||||
void setKeyEventCallback(const KeyEventCallback &callback);
|
||||
void setInputMethodChangeCallback(const InputMethodChangeCallback &callback);
|
||||
void setStatusAreaUpdateCallback(const StatusAreaUpdateCallback &callback);
|
||||
@ -74,13 +76,15 @@ private:
|
||||
FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, getCandidates);
|
||||
FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, getCandidateActions);
|
||||
FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, triggerCandidateAction);
|
||||
FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, triggerTabAction);
|
||||
FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, showToast);
|
||||
FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, setCandidatePagingMode);
|
||||
FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, offsetCandidatePage);
|
||||
FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, triggerCandidateListTabAction);
|
||||
FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, setCandidateListCallback);
|
||||
FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, setCommitStringCallback);
|
||||
FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, setPreeditCallback);
|
||||
FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, setInputPanelAuxCallback);
|
||||
FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, setInputPanelCallback);
|
||||
FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, setKeyEventCallback);
|
||||
FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, setInputMethodChangeCallback);
|
||||
FCITX_ADDON_EXPORT_FUNCTION(AndroidFrontend, setStatusAreaUpdateCallback);
|
||||
@ -99,7 +103,7 @@ private:
|
||||
CandidateListCallback candidateListCallback = [](const std::vector<CandidateEntity> &, const int) {};
|
||||
CommitStringCallback commitStringCallback = [](const std::string &, const int) {};
|
||||
ClientPreeditCallback preeditCallback = [](const Text &) {};
|
||||
InputPanelCallback inputPanelCallback = [](const fcitx::Text &, const fcitx::Text &, const Text &) {};
|
||||
InputPanelCallback inputPanelCallback = [](const fcitx::Text &, const fcitx::Text &, const Text &, const std::vector<CandidateActionEntity> &) {};
|
||||
KeyEventCallback keyEventCallback = [](const int, const uint32_t, const uint32_t, const bool, const int) {};
|
||||
InputMethodChangeCallback imChangeCallback = [](const InputMethodStatus &) {};
|
||||
StatusAreaUpdateCallback statusAreaUpdateCallback = [](const std::vector<ActionEntity> &, const InputMethodStatus &) {};
|
||||
|
||||
@ -15,7 +15,7 @@
|
||||
typedef std::function<void(const std::vector<CandidateEntity> &, const int)> CandidateListCallback;
|
||||
typedef std::function<void(const std::string &, const int)> CommitStringCallback;
|
||||
typedef std::function<void(const fcitx::Text &)> ClientPreeditCallback;
|
||||
typedef std::function<void(const fcitx::Text &, const fcitx::Text &, const fcitx::Text &)> InputPanelCallback;
|
||||
typedef std::function<void(const fcitx::Text &, const fcitx::Text &, const fcitx::Text &, const std::vector<CandidateActionEntity> &)> InputPanelCallback;
|
||||
typedef std::function<void(const int, const uint32_t, const uint32_t, const bool, const int)> KeyEventCallback;
|
||||
typedef std::function<void(const InputMethodStatus &)> InputMethodChangeCallback;
|
||||
typedef std::function<void(const std::vector<ActionEntity> &, const InputMethodStatus &)> StatusAreaUpdateCallback;
|
||||
@ -63,6 +63,9 @@ FCITX_ADDON_DECLARE_FUNCTION(AndroidFrontend, getCandidateActions,
|
||||
FCITX_ADDON_DECLARE_FUNCTION(AndroidFrontend, triggerCandidateAction,
|
||||
void(const int, const int))
|
||||
|
||||
FCITX_ADDON_DECLARE_FUNCTION(AndroidFrontend, triggerTabAction,
|
||||
void(const int))
|
||||
|
||||
FCITX_ADDON_DECLARE_FUNCTION(AndroidFrontend, showToast,
|
||||
void(const std::string &))
|
||||
|
||||
@ -72,6 +75,9 @@ FCITX_ADDON_DECLARE_FUNCTION(AndroidFrontend, setCandidatePagingMode,
|
||||
FCITX_ADDON_DECLARE_FUNCTION(AndroidFrontend, offsetCandidatePage,
|
||||
void(int))
|
||||
|
||||
FCITX_ADDON_DECLARE_FUNCTION(AndroidFrontend, triggerCandidateListTabAction,
|
||||
void(int))
|
||||
|
||||
FCITX_ADDON_DECLARE_FUNCTION(AndroidFrontend, setCandidateListCallback,
|
||||
void(const CandidateListCallback &))
|
||||
|
||||
@ -81,7 +87,7 @@ FCITX_ADDON_DECLARE_FUNCTION(AndroidFrontend, setCommitStringCallback,
|
||||
FCITX_ADDON_DECLARE_FUNCTION(AndroidFrontend, setPreeditCallback,
|
||||
void(const ClientPreeditCallback &))
|
||||
|
||||
FCITX_ADDON_DECLARE_FUNCTION(AndroidFrontend, setInputPanelAuxCallback,
|
||||
FCITX_ADDON_DECLARE_FUNCTION(AndroidFrontend, setInputPanelCallback,
|
||||
void(const InputPanelCallback &))
|
||||
|
||||
FCITX_ADDON_DECLARE_FUNCTION(AndroidFrontend, setKeyEventCallback,
|
||||
|
||||
@ -434,6 +434,10 @@ public:
|
||||
return p_frontend->call<fcitx::IAndroidFrontend::offsetCandidatePage>(delta);
|
||||
}
|
||||
|
||||
void triggerCandidateListTabAction(int id) {
|
||||
return p_frontend->call<fcitx::IAndroidFrontend::triggerCandidateListTabAction>(id);
|
||||
}
|
||||
|
||||
void save() {
|
||||
p_instance->save();
|
||||
}
|
||||
@ -614,12 +618,18 @@ Java_org_fcitx_fcitx5_android_core_Fcitx_startupFcitx(
|
||||
env->SetObjectArrayElement(vararg, 0, fcitxTextToJObject(env, clientPreedit));
|
||||
env->CallStaticVoidMethod(GlobalRef->Fcitx, GlobalRef->HandleFcitxEvent, 2, *vararg);
|
||||
};
|
||||
auto inputPanelAuxCallback = [](const fcitx::Text &preedit, const fcitx::Text &auxUp, const fcitx::Text &auxDown) {
|
||||
auto inputPanelCallback = [](const fcitx::Text &preedit, const fcitx::Text &auxUp, const fcitx::Text &auxDown, const std::vector<CandidateActionEntity> &tabs) {
|
||||
auto env = GlobalRef->AttachEnv();
|
||||
auto vararg = JRef<jobjectArray>(env, env->NewObjectArray(3, GlobalRef->FormattedText, nullptr));
|
||||
auto vararg = JRef<jobjectArray>(env, env->NewObjectArray(4, GlobalRef->Object, nullptr));
|
||||
env->SetObjectArrayElement(vararg, 0, fcitxTextToJObject(env, preedit));
|
||||
env->SetObjectArrayElement(vararg, 1, fcitxTextToJObject(env, auxUp));
|
||||
env->SetObjectArrayElement(vararg, 2, fcitxTextToJObject(env, auxDown));
|
||||
auto tabsArray = JRef<jobjectArray>(env, env->NewObjectArray(static_cast<int>(tabs.size()), GlobalRef->CandidateAction, nullptr));
|
||||
int i = 0;
|
||||
for (const auto &tab: tabs) {
|
||||
env->SetObjectArrayElement(tabsArray, i++, fcitxCandidateActionToObject(env, tab));
|
||||
}
|
||||
env->SetObjectArrayElement(vararg, 3, *tabsArray);
|
||||
env->CallStaticVoidMethod(GlobalRef->Fcitx, GlobalRef->HandleFcitxEvent, 3, *vararg);
|
||||
};
|
||||
auto readyCallback = []() {
|
||||
@ -713,7 +723,7 @@ Java_org_fcitx_fcitx5_android_core_Fcitx_startupFcitx(
|
||||
androidfrontend->template call<fcitx::IAndroidFrontend::setCandidateListCallback>(candidateListCallback);
|
||||
androidfrontend->template call<fcitx::IAndroidFrontend::setCommitStringCallback>(commitStringCallback);
|
||||
androidfrontend->template call<fcitx::IAndroidFrontend::setPreeditCallback>(preeditCallback);
|
||||
androidfrontend->template call<fcitx::IAndroidFrontend::setInputPanelAuxCallback>(inputPanelAuxCallback);
|
||||
androidfrontend->template call<fcitx::IAndroidFrontend::setInputPanelCallback>(inputPanelCallback);
|
||||
androidfrontend->template call<fcitx::IAndroidFrontend::setKeyEventCallback>(keyEventCallback);
|
||||
androidfrontend->template call<fcitx::IAndroidFrontend::setInputMethodChangeCallback>(imChangeCallback);
|
||||
androidfrontend->template call<fcitx::IAndroidFrontend::setStatusAreaUpdateCallback>(statusAreaUpdateCallback);
|
||||
@ -1096,6 +1106,13 @@ Java_org_fcitx_fcitx5_android_core_Fcitx_offsetFcitxCandidatePage(JNIEnv *env, j
|
||||
Fcitx::Instance().offsetCandidatePage(delta);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_fcitx_fcitx5_android_core_Fcitx_triggerFcitxCandidateListTabAction(JNIEnv *env, jclass clazz, jint id) {
|
||||
RETURN_IF_NOT_RUNNING
|
||||
Fcitx::Instance().triggerCandidateListTabAction(id);
|
||||
}
|
||||
|
||||
extern "C"
|
||||
JNIEXPORT void JNICALL
|
||||
Java_org_fcitx_fcitx5_android_core_Fcitx_loopOnce(JNIEnv *env, jclass clazz) {
|
||||
|
||||
@ -194,6 +194,9 @@ class Fcitx(private val context: Context) : FcitxAPI, FcitxLifecycleOwner {
|
||||
override suspend fun offsetCandidatePage(delta: Int) =
|
||||
withFcitxContext { offsetFcitxCandidatePage(delta) }
|
||||
|
||||
override suspend fun triggerCandidateListTabAction(id: Int) =
|
||||
withFcitxContext { triggerFcitxCandidateListTabAction(id) }
|
||||
|
||||
init {
|
||||
if (lifecycle.currentState != FcitxLifecycle.State.STOPPED)
|
||||
throw IllegalAccessException("Fcitx5 has already been created!")
|
||||
@ -378,6 +381,9 @@ class Fcitx(private val context: Context) : FcitxAPI, FcitxLifecycleOwner {
|
||||
@JvmStatic
|
||||
external fun offsetFcitxCandidatePage(delta: Int)
|
||||
|
||||
@JvmStatic
|
||||
external fun triggerFcitxCandidateListTabAction(id: Int)
|
||||
|
||||
@JvmStatic
|
||||
external fun loopOnce()
|
||||
|
||||
|
||||
@ -108,4 +108,6 @@ interface FcitxAPI {
|
||||
suspend fun setCandidatePagingMode(mode: Int)
|
||||
suspend fun offsetCandidatePage(delta: Int)
|
||||
|
||||
suspend fun triggerCandidateListTabAction(id: Int)
|
||||
|
||||
}
|
||||
@ -61,9 +61,37 @@ sealed class FcitxEvent<T>(open val data: T) {
|
||||
data class Data(
|
||||
val preedit: FormattedText,
|
||||
val auxUp: FormattedText,
|
||||
val auxDown: FormattedText
|
||||
val auxDown: FormattedText,
|
||||
val tabs: Array<CandidateAction>
|
||||
) {
|
||||
constructor() : this(FormattedText.Empty, FormattedText.Empty, FormattedText.Empty)
|
||||
constructor() : this(
|
||||
FormattedText.Empty,
|
||||
FormattedText.Empty,
|
||||
FormattedText.Empty,
|
||||
emptyArray()
|
||||
)
|
||||
|
||||
override fun equals(other: Any?): Boolean {
|
||||
if (this === other) return true
|
||||
if (javaClass != other?.javaClass) return false
|
||||
|
||||
other as Data
|
||||
|
||||
if (preedit != other.preedit) return false
|
||||
if (auxUp != other.auxUp) return false
|
||||
if (auxDown != other.auxDown) return false
|
||||
if (!tabs.contentEquals(other.tabs)) return false
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
override fun hashCode(): Int {
|
||||
var result = preedit.hashCode()
|
||||
result = 31 * result + auxUp.hashCode()
|
||||
result = 31 * result + auxDown.hashCode()
|
||||
result = 31 * result + tabs.contentHashCode()
|
||||
return result
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -261,7 +289,8 @@ sealed class FcitxEvent<T>(open val data: T) {
|
||||
InputPanelEvent.Data(
|
||||
params[0] as FormattedText,
|
||||
params[1] as FormattedText,
|
||||
params[2] as FormattedText
|
||||
params[2] as FormattedText,
|
||||
params[3] as Array<CandidateAction>
|
||||
)
|
||||
)
|
||||
EventType.Ready -> ReadyEvent()
|
||||
|
||||
@ -1 +1 @@
|
||||
Subproject commit 940b3b3db521a6fcb14e4d67ea522217cf244c3b
|
||||
Subproject commit 3a94a96006f8e67665fa9bb1b9ef4602415ddd04
|
||||
@ -1 +1 @@
|
||||
Subproject commit e5809953e5c2d31c285f8b0c182e219962a12d4f
|
||||
Subproject commit 52978aa88b4979c057fe94d68291883d9c27085f
|
||||
@ -1 +1 @@
|
||||
Subproject commit ac7a6b937d69acf812a58eea6926182ceb3e502c
|
||||
Subproject commit 04eff1334eb2eab45245c492bf5b85be4c4eda6b
|
||||
@ -1 +1 @@
|
||||
Subproject commit c16d4e52c21d98ae71ffce355b395631a05acc42
|
||||
Subproject commit 7197ff04d43e192a87da157bebaaf386cf98ed3c
|
||||
Loading…
x
Reference in New Issue
Block a user