significantly simpler language change dialog (no Activity hack)
This commit is contained in:
parent
32b172827e
commit
18c2ab8440
9 changed files with 71 additions and 119 deletions
|
|
@ -170,7 +170,7 @@ abstract public class CommandHandler extends TextEditingHandler {
|
|||
protected void changeLang() {
|
||||
suggestionOps.cancelDelayedAccept();
|
||||
stopVoiceInput();
|
||||
ChangeLanguageDialog.show(this, mInputMode.getSequence(), textField.getComposingText());
|
||||
new ChangeLanguageDialog(getFinalContext(), this::setLang).show();
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11,7 +11,6 @@ import android.view.inputmethod.EditorInfo;
|
|||
import android.view.inputmethod.InputConnection;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import io.github.sspanak.tt9.R;
|
||||
import io.github.sspanak.tt9.db.DataStore;
|
||||
|
|
@ -21,7 +20,6 @@ import io.github.sspanak.tt9.ime.modes.InputModeKind;
|
|||
import io.github.sspanak.tt9.languages.LanguageCollection;
|
||||
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
|
||||
import io.github.sspanak.tt9.ui.UI;
|
||||
import io.github.sspanak.tt9.ui.dialogs.ChangeLanguageDialog;
|
||||
import io.github.sspanak.tt9.ui.dialogs.PopupDialog;
|
||||
import io.github.sspanak.tt9.ui.dialogs.RequestPermissionDialog;
|
||||
import io.github.sspanak.tt9.util.Logger;
|
||||
|
|
@ -122,12 +120,6 @@ public class TraditionalT9 extends MainViewHandler {
|
|||
|
||||
if (!message.isEmpty()) {
|
||||
UI.toastLong(this, message);
|
||||
} else if (ChangeLanguageDialog.INTENT_SET_LANGUAGE.equals(intent.getStringExtra(ChangeLanguageDialog.INTENT_SET_LANGUAGE))) {
|
||||
onResume(
|
||||
intent.getStringExtra(ChangeLanguageDialog.PARAMETER_LANGUAGE),
|
||||
intent.getStringExtra(ChangeLanguageDialog.PARAMETER_SEQUENCE),
|
||||
intent.getStringExtra(ChangeLanguageDialog.PARAMETER_WORD)
|
||||
);
|
||||
}
|
||||
|
||||
return result;
|
||||
|
|
@ -184,24 +176,6 @@ public class TraditionalT9 extends MainViewHandler {
|
|||
}
|
||||
|
||||
|
||||
private void onResume(@Nullable String langStringId, @Nullable String sequence, @Nullable String word) {
|
||||
int languageId;
|
||||
try {
|
||||
langStringId = langStringId == null ? "(null)" : langStringId;
|
||||
languageId = Integer.parseInt(langStringId);
|
||||
} catch (NumberFormatException e) {
|
||||
Logger.e(LOG_TAG, "Can not resume typing. Failed to parse language ID '" + langStringId + "'. " + e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (word != null && !word.isEmpty() && sequence != null && !sequence.isEmpty()) {
|
||||
mInputMode.setSequence(sequence);
|
||||
}
|
||||
|
||||
setLang(languageId);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected void onStop() {
|
||||
stopVoiceInput();
|
||||
|
|
|
|||
|
|
@ -5,12 +5,18 @@ import android.app.Dialog;
|
|||
import android.content.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.view.View;
|
||||
import android.view.Window;
|
||||
import android.view.WindowManager;
|
||||
|
||||
import com.google.android.material.dialog.MaterialAlertDialogBuilder;
|
||||
|
||||
import io.github.sspanak.tt9.ui.main.MainView;
|
||||
import io.github.sspanak.tt9.util.Logger;
|
||||
import io.github.sspanak.tt9.util.sys.DeviceInfo;
|
||||
|
||||
public class PopupBuilder {
|
||||
private static final String LOG_TAG = PopupBuilder.class.getSimpleName();
|
||||
|
||||
private final Context context;
|
||||
private MaterialAlertDialogBuilder builder12;
|
||||
private AlertDialog.Builder builderLegacy;
|
||||
|
|
@ -112,4 +118,35 @@ public class PopupBuilder {
|
|||
public Dialog show() {
|
||||
return DeviceInfo.AT_LEAST_ANDROID_12 ? builder12.show() : builderLegacy.show();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* In IME context, it is not that easy to show a popup dialog. We need to make it "valid" using
|
||||
* the hacks below. Made possible thanks to:
|
||||
* <a href="https://stackoverflow.com/questions/51906586/display-dialog-from-input-method-service-in-android-9-android-pie">Philipp</a>
|
||||
* <a href="https://stackoverflow.com/questions/3494476/android-ime-how-to-show-a-pop-up-dialog/3508462#3508462">Maher Abuthraa</a>
|
||||
*/
|
||||
public Dialog showFromIme(MainView main) {
|
||||
if (main == null || main.getView() == null) {
|
||||
Logger.e(LOG_TAG, "Cannot show a popup dialog. Main view is null.");
|
||||
return null;
|
||||
}
|
||||
|
||||
Dialog dialog = DeviceInfo.AT_LEAST_ANDROID_12 ? builder12.create() : builderLegacy.create();
|
||||
|
||||
Window window = dialog.getWindow();
|
||||
if (window == null) {
|
||||
Logger.e(LOG_TAG, "Cannot show a popup dialog. AlertDialog generated a Dialog with NULL Window.");
|
||||
return null;
|
||||
}
|
||||
|
||||
WindowManager.LayoutParams layout = window.getAttributes();
|
||||
layout.token = main.getView().getWindowToken();
|
||||
layout.type = WindowManager.LayoutParams.TYPE_APPLICATION_ATTACHED_DIALOG;
|
||||
window.setAttributes(layout);
|
||||
window.addFlags(WindowManager.LayoutParams.FLAG_ALT_FOCUSABLE_IM);
|
||||
dialog.show();
|
||||
|
||||
return dialog;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,13 +57,13 @@ public class AddWordDialog extends ThemedPopupDialog {
|
|||
|
||||
|
||||
@Override
|
||||
void render() {
|
||||
void show() {
|
||||
if (message == null || word == null || word.isEmpty()) {
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
super.render(this::onOK);
|
||||
super.show(this::onOK);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ public class AutoUpdateMonolog extends PopupDialog {
|
|||
|
||||
|
||||
@Override
|
||||
void render() {
|
||||
void show() {
|
||||
if (language != null) {
|
||||
DictionaryLoader.load(context, language);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,65 +2,55 @@ package io.github.sspanak.tt9.ui.dialogs;
|
|||
|
||||
import android.app.Dialog;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
import android.inputmethodservice.InputMethodService;
|
||||
import android.view.KeyEvent;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.widget.LinearLayout;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import io.github.sspanak.tt9.R;
|
||||
import io.github.sspanak.tt9.ime.TraditionalT9;
|
||||
import io.github.sspanak.tt9.ime.helpers.Key;
|
||||
import io.github.sspanak.tt9.languages.Language;
|
||||
import io.github.sspanak.tt9.languages.LanguageCollection;
|
||||
import io.github.sspanak.tt9.preferences.settings.SettingsStore;
|
||||
import io.github.sspanak.tt9.ui.LanguageRadioButton;
|
||||
import io.github.sspanak.tt9.ui.PopupBuilder;
|
||||
import io.github.sspanak.tt9.ui.main.MainView;
|
||||
import io.github.sspanak.tt9.util.ConsumerCompat;
|
||||
import io.github.sspanak.tt9.util.sys.DeviceInfo;
|
||||
|
||||
public class ChangeLanguageDialog extends ThemedPopupDialog {
|
||||
public static final String TYPE = "tt9.popup_dialog.change_language";
|
||||
public static final String INTENT_SET_LANGUAGE = "tt9.popup_dialog.command.set_language";
|
||||
public static final String PARAMETER_LANGUAGE = "tt9.popup_dialog.parameter.language";
|
||||
public static final String PARAMETER_SEQUENCE = "tt9.popup_dialog.parameter.sequence";
|
||||
public static final String PARAMETER_WORD = "tt9.popup_dialog.parameter.word";
|
||||
|
||||
private final ConsumerCompat<HashMap<String, String>> activityFinisher;
|
||||
private final LayoutInflater inflater;
|
||||
private final ArrayList<Language> languages;
|
||||
private final MainView mainView;
|
||||
private final SettingsStore settings;
|
||||
private final String currentSequence;
|
||||
private final String currentWord;
|
||||
|
||||
private final ArrayList<LanguageRadioButton> radioButtonsCache = new ArrayList<>();
|
||||
private final ConsumerCompat<Integer> onLanguageChanged;
|
||||
private Dialog popup;
|
||||
private final ArrayList<LanguageRadioButton> radioButtonsCache = new ArrayList<>();
|
||||
|
||||
|
||||
ChangeLanguageDialog(@NonNull AppCompatActivity context, @NonNull Intent intent, ConsumerCompat<HashMap<String, String>> activityFinisher) {
|
||||
super(context, null, R.style.TTheme_AddWord);
|
||||
public ChangeLanguageDialog(@NonNull TraditionalT9 tt9, @Nullable ConsumerCompat<Integer> changeHandler) {
|
||||
super(tt9, null, R.style.TTheme_AddWord);
|
||||
|
||||
this.activityFinisher = activityFinisher;
|
||||
title = context.getResources().getString(R.string.language_popup_title);
|
||||
title = tt9.getResources().getString(R.string.language_popup_title);
|
||||
OKLabel = null;
|
||||
|
||||
inflater = context.getLayoutInflater();
|
||||
settings = new SettingsStore(context);
|
||||
mainView = tt9.getMainView();
|
||||
settings = tt9.getSettings();
|
||||
languages = LanguageCollection.getAll(settings.getEnabledLanguageIds(), true);
|
||||
|
||||
currentSequence = intent.getStringExtra(PARAMETER_SEQUENCE);
|
||||
currentWord = intent.getStringExtra(PARAMETER_WORD);
|
||||
onLanguageChanged = changeHandler;
|
||||
}
|
||||
|
||||
|
||||
private void onClick(View button) {
|
||||
changeLanguage(button.getId());
|
||||
if (onLanguageChanged != null) {
|
||||
onLanguageChanged.accept(button.getId());
|
||||
}
|
||||
close();
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -85,7 +75,10 @@ public class ChangeLanguageDialog extends ThemedPopupDialog {
|
|||
return false;
|
||||
}
|
||||
|
||||
changeLanguage(languageId);
|
||||
if (onLanguageChanged != null) {
|
||||
onLanguageChanged.accept(languageId);
|
||||
}
|
||||
close();
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -113,25 +106,6 @@ public class ChangeLanguageDialog extends ThemedPopupDialog {
|
|||
popup.dismiss();
|
||||
popup = null;
|
||||
}
|
||||
activityFinisher.accept(null);
|
||||
}
|
||||
|
||||
|
||||
private void changeLanguage(int languageId) {
|
||||
detachRadioButtons();
|
||||
if (popup != null) {
|
||||
popup.dismiss();
|
||||
popup = null;
|
||||
}
|
||||
|
||||
if (activityFinisher != null) {
|
||||
HashMap<String, String> messages = new HashMap<>();
|
||||
messages.put(INTENT_SET_LANGUAGE, INTENT_SET_LANGUAGE);
|
||||
messages.put(PARAMETER_LANGUAGE, String.valueOf(languageId));
|
||||
messages.put(PARAMETER_SEQUENCE, currentSequence);
|
||||
messages.put(PARAMETER_WORD, currentWord);
|
||||
activityFinisher.accept(messages);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -148,7 +122,7 @@ public class ChangeLanguageDialog extends ThemedPopupDialog {
|
|||
|
||||
private View generateRadioButtons() {
|
||||
final int currentLanguageId = settings.getInputLanguage();
|
||||
final View view = inflater.inflate(R.layout.popup_language_select, null);
|
||||
final View view = View.inflate(context, R.layout.popup_language_select, null);
|
||||
final LinearLayout radioGroup = view.findViewById(R.id.language_select_list);
|
||||
|
||||
radioButtonsCache.clear();
|
||||
|
|
@ -169,31 +143,14 @@ public class ChangeLanguageDialog extends ThemedPopupDialog {
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
void render() {
|
||||
public void show() {
|
||||
popup = new PopupBuilder(context)
|
||||
.setCancelable(false)
|
||||
.setCancelable(true)
|
||||
.setTitle(title)
|
||||
.setMessage(message)
|
||||
.setNegativeButton(true, this::close)
|
||||
.setOnKeyListener(this)
|
||||
.setView(generateRadioButtons())
|
||||
.show();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Open a popup dialog containing a list of the enabled languages. After a language is selected,
|
||||
* "currentSequence" and "currentWord" are passed back to the IME, in case it wants to recompose them.
|
||||
*/
|
||||
public static void show(InputMethodService ims, String currentSequence, String currentWord) {
|
||||
Intent intent = new Intent(ims, PopupDialogActivity.class);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_MULTIPLE_TASK);
|
||||
intent.addFlags(Intent.FLAG_ACTIVITY_RESET_TASK_IF_NEEDED);
|
||||
intent.putExtra(PARAMETER_DIALOG_TYPE, TYPE);
|
||||
intent.putExtra(PARAMETER_SEQUENCE, currentSequence);
|
||||
intent.putExtra(PARAMETER_WORD, currentWord);
|
||||
ims.startActivity(intent);
|
||||
.showFromIme(mainView);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ abstract public class PopupDialog implements DialogInterface.OnKeyListener {
|
|||
return false;
|
||||
}
|
||||
|
||||
protected void render(Runnable OKAction) {
|
||||
protected void show(Runnable OKAction) {
|
||||
new PopupBuilder(context)
|
||||
.setCancelable(false)
|
||||
.setTitle(title)
|
||||
|
|
@ -47,5 +47,5 @@ abstract public class PopupDialog implements DialogInterface.OnKeyListener {
|
|||
.show();
|
||||
}
|
||||
|
||||
abstract void render();
|
||||
abstract void show();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,8 +6,6 @@ import android.os.Bundle;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.appcompat.app.AppCompatActivity;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
import io.github.sspanak.tt9.ime.TraditionalT9;
|
||||
import io.github.sspanak.tt9.util.Logger;
|
||||
|
||||
|
|
@ -20,7 +18,7 @@ public class PopupDialogActivity extends AppCompatActivity {
|
|||
super.onCreate(savedData);
|
||||
PopupDialog dialog = getDialog();
|
||||
if (dialog != null) {
|
||||
dialog.render();
|
||||
dialog.show();
|
||||
} else {
|
||||
onDialogClose("");
|
||||
}
|
||||
|
|
@ -36,7 +34,6 @@ public class PopupDialogActivity extends AppCompatActivity {
|
|||
return switch (popupType) {
|
||||
case AddWordDialog.TYPE -> new AddWordDialog(this, i, this::onDialogClose);
|
||||
case AutoUpdateMonolog.TYPE -> new AutoUpdateMonolog(this, i, this::onDialogClose);
|
||||
case ChangeLanguageDialog.TYPE -> new ChangeLanguageDialog(this, i, this::onDialogClose);
|
||||
default -> {
|
||||
Logger.w(LOG_TAG, "Unknown popup type: '" + popupType + "'. Not displaying anything.");
|
||||
yield null;
|
||||
|
|
@ -53,23 +50,10 @@ public class PopupDialogActivity extends AppCompatActivity {
|
|||
startService(intent);
|
||||
}
|
||||
|
||||
private void onDialogClose(HashMap<String, String> messages) {
|
||||
finish();
|
||||
Intent intent = new Intent(this, TraditionalT9.class);
|
||||
if (messages != null) {
|
||||
intent.putExtra(PopupDialog.INTENT_CLOSE, "");
|
||||
for (String key : messages.keySet()) {
|
||||
intent.putExtra(key, messages.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
startService(intent);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void onRequestPermissionsResult(int requestCode, @NonNull String[] permissions, @NonNull int[] grantResults) {
|
||||
super.onRequestPermissionsResult(requestCode, permissions, grantResults);
|
||||
onDialogClose((String) null);
|
||||
onDialogClose(null);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -37,8 +37,8 @@
|
|||
</style>
|
||||
|
||||
<style name="TTheme.LanguageSelect.RadioButton.Label">
|
||||
<item name="android:paddingTop">0dp</item>
|
||||
<item name="android:paddingBottom">0dp</item>
|
||||
<item name="android:paddingTop">12dp</item>
|
||||
<item name="android:paddingBottom">12dp</item>
|
||||
<item name="android:paddingStart">0dp</item>
|
||||
<item name="android:paddingEnd">0dp</item>
|
||||
<item name="android:textAppearance">@style/TextAppearance.AppCompat.Widget.PopupMenu.Large</item>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue