1
0
Fork 0

Settings Reorganization

All categories are now on separate screens

Added a 'Clear Unselected' dictionary option

The 'auto space' setting is now on by default

Reorganized the emoji and added 4 new ones
This commit is contained in:
Dimo Karaivanov 2023-02-20 12:51:42 +02:00
parent d7ead4ba06
commit 1178357b4a
27 changed files with 378 additions and 233 deletions

View file

@ -106,11 +106,20 @@ public class DictionaryDb {
}
public static void truncateWords(Handler handler) {
public static void deleteWords(Handler handler) {
deleteWords(handler, null);
}
public static void deleteWords(Handler handler, ArrayList<Integer> languageIds) {
new Thread() {
@Override
public void run() {
getInstance().clearAllTables();
if (languageIds == null) {
getInstance().clearAllTables();
} else if (languageIds.size() > 0) {
getInstance().wordsDao().deleteByLanguage(languageIds);
}
handler.sendEmptyMessage(0);
}
}.start();

View file

@ -5,6 +5,7 @@ import androidx.room.Insert;
import androidx.room.OnConflictStrategy;
import androidx.room.Query;
import java.util.ArrayList;
import java.util.List;
@Dao
@ -12,6 +13,9 @@ interface WordsDao {
@Query("SELECT COUNT(id) FROM words WHERE :langId < 0 OR lang = :langId")
int count(int langId);
@Query("DELETE FROM words WHERE LANG IN(:langIds)")
int deleteByLanguage(ArrayList<Integer> langIds);
@Query("SELECT COUNT(id) FROM words WHERE lang = :langId AND word = :word")
int doesWordExist(int langId, String word);

View file

@ -20,17 +20,21 @@ public class Characters {
));
final private static ArrayList<ArrayList<String>> Emoji = new ArrayList<>(Arrays.asList(
// smile -> frown
// positive
new ArrayList<>(Arrays.asList(
"🙂", "😀", "🤣", "😉", "😛", "😳", "😲", "😱", "😭", "😢", "🙁"
"🙂", "😀", "🤣", "🤓", "😎", "😛", "😉"
)),
// negative
new ArrayList<>(Arrays.asList(
"🙁", "😢", "😭", "😱", "😲", "😳", "😐", "😠"
)),
// hands
new ArrayList<>(Arrays.asList(
"👍", "👋", "✌️", "👏", "🤝", "💪", "🤘", "🖖", "👎"
"👍", "👋", "✌️", "👏", "🖖", "🤘", "🤝", "💪", "👎"
)),
// emotions
new ArrayList<>(Arrays.asList(
"", "🤗", "😍", "😘", "😇", "😈", "🎉", "🤓", "😎", "🤔", "🥶", "😬"
"", "🤗", "😍", "😘", "😇", "😈", "🍺", "🎉", "🥱", "🤔", "🥶", "😬"
))
));

View file

@ -7,14 +7,18 @@ import androidx.appcompat.app.ActionBar;
import androidx.appcompat.app.AppCompatActivity;
import androidx.appcompat.app.AppCompatDelegate;
import androidx.fragment.app.Fragment;
import androidx.fragment.app.FragmentTransaction;
import androidx.preference.Preference;
import androidx.preference.PreferenceFragmentCompat;
import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.db.DictionaryDb;
import io.github.sspanak.tt9.db.DictionaryLoader;
import io.github.sspanak.tt9.preferences.screens.MainSettingsScreen;
import io.github.sspanak.tt9.preferences.screens.AppearanceScreen;
import io.github.sspanak.tt9.preferences.screens.DictionariesScreen;
import io.github.sspanak.tt9.preferences.screens.HotkeysScreen;
import io.github.sspanak.tt9.preferences.screens.KeyPadScreen;
import io.github.sspanak.tt9.preferences.screens.MainSettingsScreen;
import io.github.sspanak.tt9.ui.DictionaryLoadingBar;
public class PreferencesActivity extends AppCompatActivity implements PreferenceFragmentCompat.OnPreferenceStartFragmentCallback {
@ -31,39 +35,68 @@ public class PreferencesActivity extends AppCompatActivity implements Preference
super.onCreate(savedInstanceState);
validateFunctionKeys();
buildScreen();
buildLayout();
}
@Override
public boolean onPreferenceStartFragment(@NonNull PreferenceFragmentCompat caller, @NonNull Preference pref) {
// instantiate the new Fragment
Fragment fragment;
if (pref.getFragment() != null && pref.getFragment().contains("Hotkeys")) {
fragment = new HotkeysScreen(this);
} else {
fragment = new MainSettingsScreen(this);
}
Fragment fragment = getScreen((getScreenName(pref)));
fragment.setArguments(pref.getExtras());
// replace the existing Fragment with the new Fragment
getSupportFragmentManager().beginTransaction()
.replace(R.id.preferences_container, fragment)
.addToBackStack(null)
.commit();
displayScreen(fragment, true);
return true;
}
private void applyTheme() {
AppCompatDelegate.setDefaultNightMode(
settings.getDarkTheme() ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO
);
/**
* getScreenName
* Determines the name of the screen for the given preference, as defined in the preference's "fragment" attribute.
* Expected format: "current.package.name.screens.SomeNameScreen"
*/
private String getScreenName(@NonNull Preference pref) {
String screenClassName = pref.getFragment();
return screenClassName != null ? screenClassName.replaceFirst("^.+?([^.]+)Screen$", "$1") : "";
}
private void buildScreen() {
/**
* getScreen
* Finds a screen fragment by name. If there is no fragment with such name, the main screen
* fragment will be returned.
*/
private Fragment getScreen(String name) {
switch (name) {
case "Appearance":
return new AppearanceScreen(this);
case "Dictionaries":
return new DictionariesScreen(this);
case "Hotkeys":
return new HotkeysScreen(this);
case "KeyPad":
return new KeyPadScreen(this);
default:
return new MainSettingsScreen(this);
}
}
/**
* displayScreen
* Replaces the currently displayed screen fragment with a new one.
*/
private void displayScreen(Fragment screen, boolean addToBackStack) {
FragmentTransaction transaction = getSupportFragmentManager().beginTransaction();
transaction.replace(R.id.preferences_container, screen);
if (addToBackStack) {
transaction.addToBackStack(screen.getClass().getSimpleName());
}
transaction.commit();
}
private void buildLayout() {
ActionBar actionBar = getSupportActionBar();
if (actionBar != null) {
actionBar.setDisplayShowHomeEnabled(true);
@ -71,10 +104,7 @@ public class PreferencesActivity extends AppCompatActivity implements Preference
}
setContentView(R.layout.preferences_container);
getSupportFragmentManager()
.beginTransaction()
.replace(R.id.preferences_container, new MainSettingsScreen(this))
.commit();
displayScreen(new MainSettingsScreen(this), false);
}
@ -87,6 +117,13 @@ public class PreferencesActivity extends AppCompatActivity implements Preference
}
private void applyTheme() {
AppCompatDelegate.setDefaultNightMode(
settings.getDarkTheme() ? AppCompatDelegate.MODE_NIGHT_YES : AppCompatDelegate.MODE_NIGHT_NO
);
}
private void validateFunctionKeys() {
if (!settings.areFunctionKeysSet()) {
settings.setDefaultKeys();

View file

@ -207,7 +207,7 @@ public class SettingsStore {
/************* typing settings *************/
public boolean getAutoSpace() { return prefs.getBoolean("auto_space", false); }
public boolean getAutoSpace() { return prefs.getBoolean("auto_space", true); }
public boolean getAutoTextCase() { return prefs.getBoolean("auto_text_case", true); }
public String getDoubleZeroChar() {
String character = prefs.getString("pref_double_zero_char", ".");

View file

@ -13,7 +13,7 @@ import io.github.sspanak.tt9.db.DictionaryLoader;
import io.github.sspanak.tt9.ui.UI;
public class ItemTruncateDictionary extends ItemClickable {
public class ItemTruncateAll extends ItemClickable {
public static final String NAME = "dictionary_truncate";
private final Context context;
@ -21,7 +21,7 @@ public class ItemTruncateDictionary extends ItemClickable {
private final ItemLoadDictionary loadItem;
public ItemTruncateDictionary(Preference item, ItemLoadDictionary loadItem, Context context, DictionaryLoader loader) {
public ItemTruncateAll(Preference item, ItemLoadDictionary loadItem, Context context, DictionaryLoader loader) {
super(item);
this.context = context;
this.loadItem = loadItem;
@ -42,7 +42,7 @@ public class ItemTruncateDictionary extends ItemClickable {
loadItem.changeToLoadButton();
}
DictionaryDb.truncateWords(onDictionaryTruncated);
DictionaryDb.deleteWords(onDictionaryTruncated);
return true;
}

View file

@ -0,0 +1,64 @@
package io.github.sspanak.tt9.preferences.items;
import android.content.Context;
import android.os.Handler;
import android.os.Looper;
import android.os.Message;
import androidx.preference.Preference;
import java.util.ArrayList;
import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.db.DictionaryDb;
import io.github.sspanak.tt9.db.DictionaryLoader;
import io.github.sspanak.tt9.languages.Language;
import io.github.sspanak.tt9.languages.LanguageCollection;
import io.github.sspanak.tt9.preferences.SettingsStore;
import io.github.sspanak.tt9.ui.UI;
public class ItemTruncateUnselected extends ItemClickable {
public static final String NAME = "dictionary_truncate_unselected";
private final Context context;
private final DictionaryLoader loader;
private final ItemLoadDictionary loadItem;
private final SettingsStore settings;
public ItemTruncateUnselected(Preference item, ItemLoadDictionary loadItem, Context context, SettingsStore settings, DictionaryLoader loader) {
super(item);
this.context = context;
this.loadItem = loadItem;
this.settings = settings;
this.loader = loader;
}
private final Handler onDictionaryTruncated = new Handler(Looper.getMainLooper()) {
@Override
public void handleMessage(Message msg) {
UI.toast(context, R.string.dictionary_truncated);
}
};
@Override
protected boolean onClick(Preference p) {
if (loader != null && loader.isRunning()) {
loader.stop();
loadItem.changeToLoadButton();
}
ArrayList<Integer> unselectedLanguageIds = new ArrayList<>();
ArrayList<Integer> selectedLanguageIds = settings.getEnabledLanguageIds();
for (Language lang : LanguageCollection.getAll(false)) {
if (!selectedLanguageIds.contains(lang.getId())) {
unselectedLanguageIds.add(lang.getId());
}
}
DictionaryDb.deleteWords(onDictionaryTruncated, unselectedLanguageIds);
return true;
}
}

View file

@ -0,0 +1,18 @@
package io.github.sspanak.tt9.preferences.screens;
import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.preferences.PreferencesActivity;
import io.github.sspanak.tt9.preferences.items.ItemToggleDarkTheme;
public class AppearanceScreen extends BaseScreenFragment {
public AppearanceScreen() { init(); }
public AppearanceScreen(PreferencesActivity activity) { init(activity); }
@Override protected int getTitle() { return R.string.pref_category_appearance; }
@Override protected int getXml() { return R.xml.prefs_screen_appearance; }
@Override
protected void onCreate() {
(new ItemToggleDarkTheme(findPreference(ItemToggleDarkTheme.NAME))).enableToggleHandler();
}
}

View file

@ -0,0 +1,51 @@
package io.github.sspanak.tt9.preferences.screens;
import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.preferences.PreferencesActivity;
import io.github.sspanak.tt9.preferences.items.ItemLoadDictionary;
import io.github.sspanak.tt9.preferences.items.ItemSelectLanguage;
import io.github.sspanak.tt9.preferences.items.ItemTruncateAll;
import io.github.sspanak.tt9.preferences.items.ItemTruncateUnselected;
public class DictionariesScreen extends BaseScreenFragment {
public DictionariesScreen() { init(); }
public DictionariesScreen(PreferencesActivity activity) { init(activity); }
@Override protected int getTitle() { return R.string.pref_choose_languages; }
@Override protected int getXml() { return R.xml.prefs_screen_dictionaries; }
@Override
protected void onCreate() {
ItemSelectLanguage multiSelect = new ItemSelectLanguage(
findPreference(ItemSelectLanguage.NAME),
activity.settings
);
multiSelect.populate().enableValidation();
ItemLoadDictionary loadItem = new ItemLoadDictionary(
findPreference(ItemLoadDictionary.NAME),
activity,
activity.settings,
activity.getDictionaryLoader(),
activity.getDictionaryProgressBar()
);
loadItem.enableClickHandler();
ItemTruncateAll truncateItem = new ItemTruncateAll(
findPreference(ItemTruncateAll.NAME),
loadItem,
activity,
activity.getDictionaryLoader()
);
truncateItem.enableClickHandler();
ItemTruncateUnselected truncateSelectedItem = new ItemTruncateUnselected(
findPreference(ItemTruncateUnselected.NAME),
loadItem,
activity,
activity.settings,
activity.getDictionaryLoader()
);
truncateSelectedItem.enableClickHandler();
}
}

View file

@ -10,33 +10,14 @@ import io.github.sspanak.tt9.preferences.PreferencesActivity;
import io.github.sspanak.tt9.preferences.items.SectionKeymap;
public class HotkeysScreen extends BaseScreenFragment {
public HotkeysScreen() {
init();
}
public HotkeysScreen() { init(); }
public HotkeysScreen(PreferencesActivity activity) { init(activity); }
public HotkeysScreen(PreferencesActivity activity) {
init(activity);
}
@Override
protected int getTitle() {
return R.string.pref_category_function_keys;
}
@Override
protected int getXml() {
return R.xml.prefs_screen_hotkeys;
}
@Override protected int getTitle() { return R.string.pref_category_function_keys; }
@Override protected int getXml() { return R.xml.prefs_screen_hotkeys; }
@Override
public void onCreate() {
createKeymapSection();
}
private void createKeymapSection() {
DropDownPreference[] dropDowns = {
findPreference(SectionKeymap.ITEM_ADD_WORD),
findPreference(SectionKeymap.ITEM_BACKSPACE),

View file

@ -0,0 +1,18 @@
package io.github.sspanak.tt9.preferences.screens;
import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.preferences.PreferencesActivity;
import io.github.sspanak.tt9.preferences.items.ItemSelectZeroKeyCharacter;
public class KeyPadScreen extends BaseScreenFragment {
public KeyPadScreen() { init(); }
public KeyPadScreen(PreferencesActivity activity) { init(activity); }
@Override protected int getTitle() { return R.string.pref_category_keypad; }
@Override protected int getXml() { return R.xml.prefs_screen_keypad; }
@Override
protected void onCreate() {
(new ItemSelectZeroKeyCharacter(findPreference(ItemSelectZeroKeyCharacter.NAME), activity)).populate().activate();
}
}

View file

@ -10,84 +10,25 @@ import java.util.regex.Pattern;
import io.github.sspanak.tt9.BuildConfig;
import io.github.sspanak.tt9.Logger;
import io.github.sspanak.tt9.R;
import io.github.sspanak.tt9.preferences.items.ItemLoadDictionary;
import io.github.sspanak.tt9.preferences.items.ItemSelectLanguage;
import io.github.sspanak.tt9.preferences.items.ItemSelectZeroKeyCharacter;
import io.github.sspanak.tt9.preferences.items.ItemToggleDarkTheme;
import io.github.sspanak.tt9.preferences.items.ItemTruncateDictionary;
import io.github.sspanak.tt9.preferences.PreferencesActivity;
public class MainSettingsScreen extends BaseScreenFragment {
private final Pattern releaseVersionRegex = Pattern.compile("^\\d+\\.\\d+$");
public MainSettingsScreen() {
init();
}
public MainSettingsScreen(PreferencesActivity activity) {
init(activity);
}
@Override
protected int getTitle() {
return R.string.app_settings;
}
@Override
protected int getXml() {
return R.xml.prefs;
}
public MainSettingsScreen() { init(); }
public MainSettingsScreen(PreferencesActivity activity) { init(activity); }
@Override protected int getTitle() { return R.string.app_settings;}
@Override protected int getXml() { return R.xml.prefs; }
@Override
public void onCreate() {
addHelpLink();
createAboutSection();
createAppearanceSection();
createDictionarySection();
createHelpSection();
createPredictiveModeSection();
}
private void createDictionarySection() {
ItemSelectLanguage multiSelect = new ItemSelectLanguage(
findPreference(ItemSelectLanguage.NAME),
activity.settings
);
multiSelect.populate().enableValidation();
ItemLoadDictionary loadItem = new ItemLoadDictionary(
findPreference(ItemLoadDictionary.NAME),
activity,
activity.settings,
activity.getDictionaryLoader(),
activity.getDictionaryProgressBar()
);
loadItem.enableClickHandler();
ItemTruncateDictionary truncateItem = new ItemTruncateDictionary(
findPreference(ItemTruncateDictionary.NAME),
loadItem,
activity,
activity.getDictionaryLoader()
);
truncateItem.enableClickHandler();
}
private void createAppearanceSection() {
(new ItemToggleDarkTheme(findPreference(ItemToggleDarkTheme.NAME))).enableToggleHandler();
}
private void createPredictiveModeSection() {
(new ItemSelectZeroKeyCharacter(findPreference(ItemSelectZeroKeyCharacter.NAME), activity)).populate().activate();
}
private void createHelpSection() {
private void addHelpLink() {
try {
if (!releaseVersionRegex.matcher(BuildConfig.VERSION_NAME).find()) {
throw new Exception("VERSION_NAME does not match: \\d+.\\d+");