mirror of
https://github.com/Helium314/HeliBoard.git
synced 2025-04-20 14:19:08 +00:00
parent
c19441310d
commit
ab183c53d7
6 changed files with 195 additions and 2 deletions
|
@ -81,6 +81,7 @@ dependencies {
|
||||||
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
|
||||||
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.1"
|
implementation "org.jetbrains.kotlinx:kotlinx-serialization-json:1.6.1"
|
||||||
implementation 'com.github.martin-stone:hsv-alpha-color-picker-android:3.1.0'
|
implementation 'com.github.martin-stone:hsv-alpha-color-picker-android:3.1.0'
|
||||||
|
implementation 'androidx.autofill:autofill:1.1.0'
|
||||||
|
|
||||||
testImplementation 'junit:junit:4.13.2'
|
testImplementation 'junit:junit:4.13.2'
|
||||||
testImplementation 'org.mockito:mockito-core:5.7.0'
|
testImplementation 'org.mockito:mockito-core:5.7.0'
|
||||||
|
|
|
@ -16,7 +16,9 @@ import android.graphics.Color;
|
||||||
import android.inputmethodservice.InputMethodService;
|
import android.inputmethodservice.InputMethodService;
|
||||||
import android.media.AudioManager;
|
import android.media.AudioManager;
|
||||||
import android.os.Build;
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
import android.os.Debug;
|
import android.os.Debug;
|
||||||
|
import android.os.Handler;
|
||||||
import android.os.IBinder;
|
import android.os.IBinder;
|
||||||
import android.os.Message;
|
import android.os.Message;
|
||||||
import android.os.Process;
|
import android.os.Process;
|
||||||
|
@ -33,8 +35,12 @@ import android.view.Window;
|
||||||
import android.view.WindowManager;
|
import android.view.WindowManager;
|
||||||
import android.view.inputmethod.CompletionInfo;
|
import android.view.inputmethod.CompletionInfo;
|
||||||
import android.view.inputmethod.EditorInfo;
|
import android.view.inputmethod.EditorInfo;
|
||||||
|
import android.view.inputmethod.InlineSuggestion;
|
||||||
|
import android.view.inputmethod.InlineSuggestionsRequest;
|
||||||
|
import android.view.inputmethod.InlineSuggestionsResponse;
|
||||||
import android.view.inputmethod.InputMethodInfo;
|
import android.view.inputmethod.InputMethodInfo;
|
||||||
import android.view.inputmethod.InputMethodSubtype;
|
import android.view.inputmethod.InputMethodSubtype;
|
||||||
|
import android.widget.HorizontalScrollView;
|
||||||
|
|
||||||
import org.dslul.openboard.inputmethod.accessibility.AccessibilityUtils;
|
import org.dslul.openboard.inputmethod.accessibility.AccessibilityUtils;
|
||||||
import org.dslul.openboard.inputmethod.annotations.UsedForTesting;
|
import org.dslul.openboard.inputmethod.annotations.UsedForTesting;
|
||||||
|
@ -73,6 +79,7 @@ import org.dslul.openboard.inputmethod.latin.suggestions.SuggestionStripViewAcce
|
||||||
import org.dslul.openboard.inputmethod.latin.touchinputconsumer.GestureConsumer;
|
import org.dslul.openboard.inputmethod.latin.touchinputconsumer.GestureConsumer;
|
||||||
import org.dslul.openboard.inputmethod.latin.utils.ApplicationUtils;
|
import org.dslul.openboard.inputmethod.latin.utils.ApplicationUtils;
|
||||||
import org.dslul.openboard.inputmethod.latin.utils.ColorUtilKt;
|
import org.dslul.openboard.inputmethod.latin.utils.ColorUtilKt;
|
||||||
|
import org.dslul.openboard.inputmethod.latin.utils.InlineAutofillUtils;
|
||||||
import org.dslul.openboard.inputmethod.latin.utils.InputMethodPickerKt;
|
import org.dslul.openboard.inputmethod.latin.utils.InputMethodPickerKt;
|
||||||
import org.dslul.openboard.inputmethod.latin.utils.JniUtils;
|
import org.dslul.openboard.inputmethod.latin.utils.JniUtils;
|
||||||
import org.dslul.openboard.inputmethod.latin.utils.LeakGuardHandlerWrapper;
|
import org.dslul.openboard.inputmethod.latin.utils.LeakGuardHandlerWrapper;
|
||||||
|
@ -94,6 +101,7 @@ import static org.dslul.openboard.inputmethod.latin.common.Constants.ImeOption.N
|
||||||
|
|
||||||
import androidx.annotation.NonNull;
|
import androidx.annotation.NonNull;
|
||||||
import androidx.annotation.Nullable;
|
import androidx.annotation.Nullable;
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
import androidx.appcompat.app.AlertDialog;
|
import androidx.appcompat.app.AlertDialog;
|
||||||
import androidx.core.content.ContextCompat;
|
import androidx.core.content.ContextCompat;
|
||||||
|
|
||||||
|
@ -1342,6 +1350,43 @@ public class LatinIME extends InputMethodService implements KeyboardActionListen
|
||||||
updateSoftInputWindowLayoutParameters();
|
updateSoftInputWindowLayoutParameters();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.R)
|
||||||
|
public InlineSuggestionsRequest onCreateInlineSuggestionsRequest(@NonNull Bundle uiExtras) {
|
||||||
|
Log.d(TAG,"onCreateInlineSuggestionsRequest called");
|
||||||
|
|
||||||
|
// Revert to default behaviour if show_suggestions is disabled
|
||||||
|
// (Maybe there is a better way to do this)
|
||||||
|
if(!mSettings.getCurrent().isSuggestionsEnabledPerUserSettings()){
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return InlineAutofillUtils.createInlineSuggestionRequest(mDisplayContext);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.R)
|
||||||
|
public boolean onInlineSuggestionsResponse(InlineSuggestionsResponse response) {
|
||||||
|
Log.d(TAG,"onInlineSuggestionsResponse called");
|
||||||
|
|
||||||
|
final List<InlineSuggestion> inlineSuggestions = response.getInlineSuggestions();
|
||||||
|
|
||||||
|
if (inlineSuggestions.isEmpty()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
HorizontalScrollView view = InlineAutofillUtils.createView(inlineSuggestions, mDisplayContext);
|
||||||
|
|
||||||
|
// Delay required to show properly
|
||||||
|
new Handler().postDelayed(() -> {
|
||||||
|
mSuggestionStripView.clear();
|
||||||
|
mSuggestionStripView.hideKeys();
|
||||||
|
mSuggestionStripView.addSuggestionView(view);
|
||||||
|
}, 200);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
private void updateSoftInputWindowLayoutParameters() {
|
private void updateSoftInputWindowLayoutParameters() {
|
||||||
// Override layout parameters to expand {@link SoftInputWindow} to the entire screen.
|
// Override layout parameters to expand {@link SoftInputWindow} to the entire screen.
|
||||||
// See {@link InputMethodService#setinputView(View)} and
|
// See {@link InputMethodService#setinputView(View)} and
|
||||||
|
|
|
@ -264,6 +264,15 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
||||||
getContext(), mSuggestedWords, mSuggestionsStrip, this);
|
getContext(), mSuggestedWords, mSuggestionsStrip, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void addSuggestionView(final View view) {
|
||||||
|
mSuggestionsStrip.addView(view);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void hideKeys() {
|
||||||
|
mToolbarKey.setVisibility(GONE);
|
||||||
|
mPinnedKeys.setVisibility(GONE);
|
||||||
|
}
|
||||||
|
|
||||||
public void setMoreSuggestionsHeight(final int remainingHeight) {
|
public void setMoreSuggestionsHeight(final int remainingHeight) {
|
||||||
mLayoutHelper.setMoreSuggestionsHeight(remainingHeight);
|
mLayoutHelper.setMoreSuggestionsHeight(remainingHeight);
|
||||||
}
|
}
|
||||||
|
@ -278,6 +287,11 @@ public final class SuggestionStripView extends RelativeLayout implements OnClick
|
||||||
for (final TextView word : mWordViews) {
|
for (final TextView word : mWordViews) {
|
||||||
word.setOnTouchListener(null);
|
word.setOnTouchListener(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mToolbarKey.getVisibility() != VISIBLE || mPinnedKeys.getVisibility() != VISIBLE){
|
||||||
|
mToolbarKey.setVisibility(VISIBLE);
|
||||||
|
mPinnedKeys.setVisibility(VISIBLE);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void removeAllDebugInfoViews() {
|
private void removeAllDebugInfoViews() {
|
||||||
|
|
|
@ -0,0 +1,127 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2019 The Android Open Source Project
|
||||||
|
* modified
|
||||||
|
* SPDX-License-Identifier: Apache-2.0
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.dslul.openboard.inputmethod.latin.utils;
|
||||||
|
|
||||||
|
import static android.util.TypedValue.COMPLEX_UNIT_DIP;
|
||||||
|
|
||||||
|
import android.annotation.SuppressLint;
|
||||||
|
import android.content.Context;
|
||||||
|
import android.graphics.Color;
|
||||||
|
import android.graphics.drawable.Icon;
|
||||||
|
import android.os.Build;
|
||||||
|
import android.os.Bundle;
|
||||||
|
import android.util.Log;
|
||||||
|
import android.util.Size;
|
||||||
|
import android.util.TypedValue;
|
||||||
|
import android.view.ViewGroup;
|
||||||
|
import android.view.inputmethod.InlineSuggestion;
|
||||||
|
import android.view.inputmethod.InlineSuggestionsRequest;
|
||||||
|
import android.widget.HorizontalScrollView;
|
||||||
|
import android.widget.LinearLayout;
|
||||||
|
import android.widget.inline.InlinePresentationSpec;
|
||||||
|
|
||||||
|
import androidx.annotation.RequiresApi;
|
||||||
|
import androidx.autofill.inline.UiVersions;
|
||||||
|
import androidx.autofill.inline.common.ImageViewStyle;
|
||||||
|
import androidx.autofill.inline.common.TextViewStyle;
|
||||||
|
import androidx.autofill.inline.common.ViewStyle;
|
||||||
|
import androidx.autofill.inline.v1.InlineSuggestionUi;
|
||||||
|
|
||||||
|
import org.dslul.openboard.inputmethod.latin.R;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
// Modified code from https://android.googlesource.com/platform/development/+/master/samples/AutofillKeyboard/
|
||||||
|
@RequiresApi(api = Build.VERSION_CODES.R)
|
||||||
|
public class InlineAutofillUtils {
|
||||||
|
|
||||||
|
private static int toPixel(int dp, Context context) {
|
||||||
|
return (int) TypedValue.applyDimension(COMPLEX_UNIT_DIP, dp,
|
||||||
|
context.getResources().getDisplayMetrics());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static int getHeight(Context context) {
|
||||||
|
return context.getResources().getDimensionPixelSize(R.dimen.config_suggestions_strip_height);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static InlineSuggestionsRequest createInlineSuggestionRequest(Context context) {
|
||||||
|
|
||||||
|
UiVersions.StylesBuilder stylesBuilder = UiVersions.newStylesBuilder();
|
||||||
|
@SuppressLint("RestrictedApi") InlineSuggestionUi.Style style = InlineSuggestionUi.newStyleBuilder()
|
||||||
|
.setSingleIconChipStyle(
|
||||||
|
new ViewStyle.Builder()
|
||||||
|
.setBackground(
|
||||||
|
Icon.createWithResource(context,
|
||||||
|
androidx.autofill.R.drawable.autofill_inline_suggestion_chip_background))
|
||||||
|
.setPadding(0, 0, 0, 0)
|
||||||
|
.build())
|
||||||
|
.setChipStyle(
|
||||||
|
new ViewStyle.Builder()
|
||||||
|
.setBackground(
|
||||||
|
Icon.createWithResource(context,
|
||||||
|
androidx.autofill.R.drawable.autofill_inline_suggestion_chip_background))
|
||||||
|
.build())
|
||||||
|
.setStartIconStyle(new ImageViewStyle.Builder().setLayoutMargin(0, 0, 0, 0).build())
|
||||||
|
.setTitleStyle(
|
||||||
|
new TextViewStyle.Builder()
|
||||||
|
.setLayoutMargin(toPixel(4, context), 0, toPixel(4, context), 0)
|
||||||
|
.setTextColor(Color.parseColor("#FF202124"))
|
||||||
|
.setTextSize(12)
|
||||||
|
.build())
|
||||||
|
.setSubtitleStyle(
|
||||||
|
new TextViewStyle.Builder()
|
||||||
|
.setLayoutMargin(0, 0, toPixel(4, context), 0)
|
||||||
|
.setTextColor(Color.parseColor("#99202124"))
|
||||||
|
.setTextSize(10)
|
||||||
|
.build())
|
||||||
|
.setEndIconStyle(new ImageViewStyle.Builder().setLayoutMargin(0, 0, 0, 0).build())
|
||||||
|
.build();
|
||||||
|
stylesBuilder.addStyle(style);
|
||||||
|
|
||||||
|
Bundle stylesBundle = stylesBuilder.build();
|
||||||
|
|
||||||
|
Size min = new Size(100, getHeight(context));
|
||||||
|
Size max = new Size(740, getHeight(context));
|
||||||
|
|
||||||
|
final ArrayList<InlinePresentationSpec> presentationSpecs = new ArrayList<>();
|
||||||
|
presentationSpecs.add(new InlinePresentationSpec.Builder(min, max).setStyle(stylesBundle).build());
|
||||||
|
presentationSpecs.add(new InlinePresentationSpec.Builder(min, max).setStyle(stylesBundle).build());
|
||||||
|
presentationSpecs.add(new InlinePresentationSpec.Builder(min, max).setStyle(stylesBundle).build());
|
||||||
|
|
||||||
|
return new InlineSuggestionsRequest.Builder(presentationSpecs)
|
||||||
|
.setMaxSuggestionCount(6)
|
||||||
|
.build();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static HorizontalScrollView createView(List<InlineSuggestion> inlineSuggestions, Context context) {
|
||||||
|
|
||||||
|
final int totalSuggestionsCount = inlineSuggestions.size();
|
||||||
|
|
||||||
|
// A container to hold all views
|
||||||
|
LinearLayout container = new LinearLayout(context);
|
||||||
|
|
||||||
|
for (int i = 0; i < totalSuggestionsCount; i++) {
|
||||||
|
final InlineSuggestion inlineSuggestion = inlineSuggestions.get(i);
|
||||||
|
|
||||||
|
inlineSuggestion.inflate(context, new Size(ViewGroup.LayoutParams.WRAP_CONTENT,
|
||||||
|
ViewGroup.LayoutParams.WRAP_CONTENT), context.getMainExecutor(), (view) -> {
|
||||||
|
if (view != null)
|
||||||
|
container.addView(view);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
HorizontalScrollView view = new HorizontalScrollView(context);
|
||||||
|
view.setLayoutParams(new ViewGroup.LayoutParams(
|
||||||
|
ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.WRAP_CONTENT));
|
||||||
|
view.setHorizontalScrollBarEnabled(false);
|
||||||
|
|
||||||
|
view.addView(container);
|
||||||
|
|
||||||
|
return view;
|
||||||
|
}
|
||||||
|
}
|
|
@ -108,9 +108,12 @@
|
||||||
<!-- If IME doesn't have an applicable subtype, the first subtype will be used as a default
|
<!-- If IME doesn't have an applicable subtype, the first subtype will be used as a default
|
||||||
subtype.-->
|
subtype.-->
|
||||||
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
|
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:settingsActivity="org.dslul.openboard.inputmethod.latin.settings.SettingsActivity"
|
android:settingsActivity="org.dslul.openboard.inputmethod.latin.settings.SettingsActivity"
|
||||||
android:isDefault="@bool/im_is_default"
|
android:isDefault="@bool/im_is_default"
|
||||||
android:supportsSwitchingToNextInputMethod="true">
|
android:supportsSwitchingToNextInputMethod="true"
|
||||||
|
android:supportsInlineSuggestions="true"
|
||||||
|
tools:targetApi="r">
|
||||||
<subtype android:icon="@drawable/ic_ime_switcher"
|
<subtype android:icon="@drawable/ic_ime_switcher"
|
||||||
android:label="@string/subtype_generic"
|
android:label="@string/subtype_generic"
|
||||||
android:subtypeId="0xc9194f97"
|
android:subtypeId="0xc9194f97"
|
||||||
|
|
|
@ -15,9 +15,12 @@ We don't want the subtypes managed by the system because it doesn't allow for ni
|
||||||
the system picker crashes on some devices for unknown reasons.
|
the system picker crashes on some devices for unknown reasons.
|
||||||
-->
|
-->
|
||||||
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
|
<input-method xmlns:android="http://schemas.android.com/apk/res/android"
|
||||||
|
xmlns:tools="http://schemas.android.com/tools"
|
||||||
android:settingsActivity="org.dslul.openboard.inputmethod.latin.settings.SettingsActivity"
|
android:settingsActivity="org.dslul.openboard.inputmethod.latin.settings.SettingsActivity"
|
||||||
android:isDefault="@bool/im_is_default"
|
android:isDefault="@bool/im_is_default"
|
||||||
android:supportsSwitchingToNextInputMethod="true">
|
android:supportsSwitchingToNextInputMethod="true"
|
||||||
|
android:supportsInlineSuggestions="true"
|
||||||
|
tools:targetApi="r">
|
||||||
<subtype android:icon="@drawable/ic_ime_switcher"
|
<subtype android:icon="@drawable/ic_ime_switcher"
|
||||||
android:imeSubtypeExtraValue="dummy"
|
android:imeSubtypeExtraValue="dummy"
|
||||||
android:imeSubtypeMode="keyboard"
|
android:imeSubtypeMode="keyboard"
|
||||||
|
|
Loading…
Add table
Reference in a new issue