From 2b6e9ade075d9365ae5bc4092ee51e2845f8c8c5 Mon Sep 17 00:00:00 2001 From: Vincent Deville Date: Wed, 13 Jan 2021 17:08:35 +0100 Subject: [PATCH] ExtraKeysView: Handle multiple and popup SpecialButtons --- .../java/com/termux/app/ExtraKeysView.java | 83 +++++++++++++------ 1 file changed, 56 insertions(+), 27 deletions(-) diff --git a/app/src/main/java/com/termux/app/ExtraKeysView.java b/app/src/main/java/com/termux/app/ExtraKeysView.java index b5687033..7b875f75 100644 --- a/app/src/main/java/com/termux/app/ExtraKeysView.java +++ b/app/src/main/java/com/termux/app/ExtraKeysView.java @@ -6,6 +6,8 @@ import android.os.Build; import android.provider.Settings; import android.util.AttributeSet; +import java.util.ArrayList; +import java.util.List; import java.util.concurrent.Executors; import java.util.concurrent.TimeUnit; import java.util.concurrent.ScheduledExecutorService; @@ -13,6 +15,7 @@ import java.util.concurrent.ScheduledExecutorService; import java.util.Map; import java.util.HashMap; import java.util.Arrays; +import java.util.stream.Collectors; import android.view.Gravity; import android.view.HapticFeedbackConstants; @@ -129,15 +132,30 @@ public final class ExtraKeysView extends GridLayout { private static class SpecialButtonState { boolean isOn = false; - ToggleButton button = null; + boolean isActive = false; + List buttons = new ArrayList<>(); + + void toggle(boolean value) { + isActive = value; + buttons.forEach(button -> { + button.setChecked(value); + button.setTextColor(value ? INTERESTING_COLOR : TEXT_COLOR); + }); + } } - private Map specialButtons = new HashMap() {{ + private final Map specialButtons = new HashMap() {{ put(SpecialButton.CTRL, new SpecialButtonState()); put(SpecialButton.ALT, new SpecialButtonState()); put(SpecialButton.FN, new SpecialButtonState()); }}; + private final List specialButtonsKeys = specialButtons.keySet().stream().map(Enum::name).collect(Collectors.toList()); + + private boolean isSpecialButton(ExtraKeyButton button) { + return specialButtonsKeys.contains(button.getKey()); + } + private ScheduledExecutorService scheduledExecutor; private PopupWindow popupWindow; private int longPressCount; @@ -147,30 +165,40 @@ public final class ExtraKeysView extends GridLayout { if (state == null) throw new RuntimeException("Must be a valid special button (see source)"); - if (! state.isOn) + if (!state.isOn) return false; - if (state.button == null) { + if (!state.isActive) { return false; } - if (state.button.isPressed()) - return true; + state.toggle(false); - if (! state.button.isChecked()) - return false; - - state.button.setChecked(false); - state.button.setTextColor(TEXT_COLOR); return true; } - void popup(View view, String text) { + private ToggleButton createSpecialButton(String buttonKey, boolean needUpdate) { + SpecialButtonState state = specialButtons.get(SpecialButton.valueOf(buttonKey)); + state.isOn = true; + ToggleButton toggleButton = new ToggleButton(getContext(), null, android.R.attr.buttonBarButtonStyle); + toggleButton.setTextColor(state.isActive ? INTERESTING_COLOR : TEXT_COLOR); + if (needUpdate) { + state.buttons.add(toggleButton); + } + return toggleButton; + } + + void popup(View view, ExtraKeyButton extraButton) { int width = view.getMeasuredWidth(); int height = view.getMeasuredHeight(); - Button button = new Button(getContext(), null, android.R.attr.buttonBarButtonStyle); - button.setText(text); - button.setTextColor(TEXT_COLOR); + Button button; + if(isSpecialButton(extraButton)) { + button = createSpecialButton(extraButton.getKey(), false); + } else { + button = new Button(getContext(), null, android.R.attr.buttonBarButtonStyle); + button.setTextColor(TEXT_COLOR); + } + button.setText(extraButton.getDisplay()); button.setPadding(0, 0, 0, 0); button.setMinHeight(0); button.setMinWidth(0); @@ -219,7 +247,7 @@ public final class ExtraKeysView extends GridLayout { return; for(SpecialButtonState state : specialButtons.values()) - state.button = null; + state.buttons = new ArrayList<>(); removeAllViews(); @@ -233,10 +261,8 @@ public final class ExtraKeysView extends GridLayout { final ExtraKeyButton buttonInfo = buttons[row][col]; Button button; - if(Arrays.asList("CTRL", "ALT", "FN").contains(buttonInfo.getKey())) { - SpecialButtonState state = specialButtons.get(SpecialButton.valueOf(buttonInfo.getKey())); // for valueOf: https://stackoverflow.com/a/604426/1980630 - state.isOn = true; - button = state.button = new ToggleButton(getContext(), null, android.R.attr.buttonBarButtonStyle); + if(isSpecialButton(buttonInfo)) { + button = createSpecialButton(buttonInfo.getKey(), true); button.setClickable(true); } else { button = new Button(getContext(), null, android.R.attr.buttonBarButtonStyle); @@ -262,10 +288,9 @@ public final class ExtraKeysView extends GridLayout { } View root = getRootView(); - if (Arrays.asList("CTRL", "ALT", "FN").contains(buttonInfo.getKey())) { - ToggleButton self = (ToggleButton) finalButton; - self.setChecked(self.isChecked()); - self.setTextColor(self.isChecked() ? INTERESTING_COLOR : TEXT_COLOR); + if (isSpecialButton(buttonInfo)) { + SpecialButtonState state = specialButtons.get(SpecialButton.valueOf(buttonInfo.getKey())); + state.toggle(!state.isActive); } else { sendKey(root, buttonInfo); } @@ -295,8 +320,7 @@ public final class ExtraKeysView extends GridLayout { scheduledExecutor = null; } v.setBackgroundColor(BUTTON_COLOR); - String extraButtonDisplayedText = buttonInfo.getPopup().getDisplay(); - popup(v, extraButtonDisplayedText); + popup(v, buttonInfo.getPopup()); } if (popupWindow != null && event.getY() > 0) { v.setBackgroundColor(BUTTON_PRESSED_COLOR); @@ -325,7 +349,12 @@ public final class ExtraKeysView extends GridLayout { popupWindow.dismiss(); popupWindow = null; if (buttonInfo.getPopup() != null) { - sendKey(root, buttonInfo.getPopup()); + if (isSpecialButton(buttonInfo.getPopup())) { + SpecialButtonState state = specialButtons.get(SpecialButton.valueOf(buttonInfo.getPopup().getKey())); + state.toggle(!state.isActive); + } else { + sendKey(root, buttonInfo.getPopup()); + } } } else { v.performClick();