-
-
Notifications
You must be signed in to change notification settings - Fork 46
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
broken down the SoftKey into smaller files
- Loading branch information
Showing
14 changed files
with
358 additions
and
323 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
169 changes: 169 additions & 0 deletions
169
app/src/main/java/io/github/sspanak/tt9/ui/main/keys/BaseClickableKey.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
package io.github.sspanak.tt9.ui.main.keys; | ||
|
||
import android.content.Context; | ||
import android.os.Handler; | ||
import android.os.Looper; | ||
import android.util.AttributeSet; | ||
import android.view.MotionEvent; | ||
import android.view.View; | ||
|
||
import io.github.sspanak.tt9.ime.TraditionalT9; | ||
import io.github.sspanak.tt9.preferences.settings.SettingsStore; | ||
import io.github.sspanak.tt9.ui.Vibration; | ||
import io.github.sspanak.tt9.util.Logger; | ||
|
||
public class BaseClickableKey extends com.google.android.material.button.MaterialButton implements View.OnTouchListener, View.OnLongClickListener { | ||
private final String LOG_TAG = getClass().getSimpleName(); | ||
|
||
protected TraditionalT9 tt9; | ||
protected Vibration vibration; | ||
|
||
private boolean hold = false; | ||
private boolean repeat = false; | ||
private long lastLongClickTime = 0; | ||
private final Handler repeatHandler = new Handler(Looper.getMainLooper()); | ||
|
||
private static int lastPressedKey = -1; | ||
private boolean ignoreLastPressedKey = false; | ||
|
||
|
||
public BaseClickableKey(Context context) { | ||
super(context); | ||
setHapticFeedbackEnabled(false); | ||
setOnTouchListener(this); | ||
setOnLongClickListener(this); | ||
} | ||
|
||
|
||
public BaseClickableKey(Context context, AttributeSet attrs) { | ||
super(context, attrs); | ||
setHapticFeedbackEnabled(false); | ||
setOnTouchListener(this); | ||
setOnLongClickListener(this); | ||
} | ||
|
||
|
||
public BaseClickableKey(Context context, AttributeSet attrs, int defStyleAttr) { | ||
super(context, attrs, defStyleAttr); | ||
setHapticFeedbackEnabled(false); | ||
setOnTouchListener(this); | ||
setOnLongClickListener(this); | ||
} | ||
|
||
|
||
public void setTT9(TraditionalT9 tt9) { | ||
this.tt9 = tt9; | ||
} | ||
|
||
|
||
protected boolean validateTT9Handler() { | ||
if (tt9 == null) { | ||
Logger.w(LOG_TAG, "Traditional T9 handler is not set. Ignoring key press."); | ||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
|
||
@Override | ||
public boolean onTouch(View view, MotionEvent event) { | ||
super.onTouchEvent(event); | ||
|
||
int action = (event.getAction() & MotionEvent.ACTION_MASK); | ||
|
||
if (action == MotionEvent.ACTION_DOWN) { | ||
return handlePress(); | ||
} else if (action == MotionEvent.ACTION_UP) { | ||
if (!repeat || hold) { | ||
hold = false; | ||
repeat = false; | ||
boolean result = handleRelease(); | ||
lastPressedKey = ignoreLastPressedKey ? -1 : getId(); | ||
return result; | ||
} | ||
repeat = false; | ||
} | ||
return false; | ||
} | ||
|
||
|
||
@Override | ||
public boolean onLongClick(View view) { | ||
// sometimes this gets called twice, so we debounce the call to the repeating function | ||
final long now = System.currentTimeMillis(); | ||
if (now - lastLongClickTime < SettingsStore.SOFT_KEY_DOUBLE_CLICK_DELAY) { | ||
return false; | ||
} | ||
|
||
hold = true; | ||
lastLongClickTime = now; | ||
repeatOnLongPress(); | ||
return true; | ||
} | ||
|
||
|
||
/** | ||
* repeatOnLongPress | ||
* Repeatedly calls "handleHold()" upon holding the respective SoftKey, to simulate physical keyboard behavior. | ||
*/ | ||
private void repeatOnLongPress() { | ||
if (hold) { | ||
repeat = true; | ||
handleHold(); | ||
lastPressedKey = ignoreLastPressedKey ? -1 : getId(); | ||
repeatHandler.removeCallbacks(this::repeatOnLongPress); | ||
repeatHandler.postDelayed(this::repeatOnLongPress, SettingsStore.SOFT_KEY_REPEAT_DELAY); | ||
} | ||
} | ||
|
||
|
||
/** | ||
* preventRepeat | ||
* Prevents "handleHold()" from being called repeatedly when the SoftKey is being held. | ||
*/ | ||
protected void preventRepeat() { | ||
hold = false; | ||
repeatHandler.removeCallbacks(this::repeatOnLongPress); | ||
} | ||
|
||
|
||
protected static int getLastPressedKey() { | ||
return lastPressedKey; | ||
} | ||
|
||
|
||
protected void ignoreLastPressedKey() { | ||
ignoreLastPressedKey = true; | ||
} | ||
|
||
|
||
protected boolean handlePress() { | ||
if (validateTT9Handler()) { | ||
vibrate(Vibration.getPressVibration(this)); | ||
} | ||
|
||
return false; | ||
} | ||
|
||
|
||
protected void handleHold() {} | ||
|
||
|
||
protected boolean handleRelease() { | ||
return false; | ||
} | ||
|
||
|
||
public boolean isHoldEnabled() { | ||
return true; | ||
} | ||
|
||
|
||
protected void vibrate(int vibrationType) { | ||
if (tt9 != null) { | ||
vibration = vibration == null ? new Vibration(tt9.getSettings(), this) : vibration; | ||
vibration.vibrate(vibrationType); | ||
} | ||
} | ||
} |
118 changes: 118 additions & 0 deletions
118
app/src/main/java/io/github/sspanak/tt9/ui/main/keys/BaseSoftKeyWithIcons.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
package io.github.sspanak.tt9.ui.main.keys; | ||
|
||
import android.content.Context; | ||
import android.graphics.Color; | ||
import android.graphics.drawable.Drawable; | ||
import android.util.AttributeSet; | ||
import android.view.View; | ||
import android.widget.ImageView; | ||
import android.widget.RelativeLayout; | ||
|
||
import androidx.annotation.Nullable; | ||
import androidx.appcompat.content.res.AppCompatResources; | ||
|
||
public class BaseSoftKeyWithIcons extends SoftKey { | ||
private Drawable icon = null; | ||
private Drawable holdIcon = null; | ||
|
||
|
||
public BaseSoftKeyWithIcons(Context context) { super(context); } | ||
public BaseSoftKeyWithIcons(Context context, AttributeSet attrs) { super(context, attrs); } | ||
public BaseSoftKeyWithIcons(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } | ||
|
||
|
||
/** | ||
* Returns the central icon resource ID. If the key does not have a central icon, return -1. The scale | ||
*/ | ||
protected int getCentralIcon() { return -1; } | ||
|
||
|
||
/** | ||
* A fail-safe method to get the central icon drawable. | ||
*/ | ||
private Drawable getCentralIconCompat() { | ||
if (icon == null && getCentralIcon() > 0) { | ||
icon = AppCompatResources.getDrawable(getContext(), getCentralIcon()); | ||
} else if (getCentralIcon() <= 0) { | ||
icon = null; | ||
} | ||
|
||
return icon; | ||
} | ||
|
||
|
||
/** | ||
* Same as getTitleScale(), but for keys that have icons instead of text. | ||
*/ | ||
protected float getCentralIconScale() { | ||
float keyboardSizeScale = Math.max(0.7f, Math.min(getTT9Width(), getTT9Height())); | ||
keyboardSizeScale = Math.min(1.15f, keyboardSizeScale); | ||
return keyboardSizeScale * Math.min(getScreenScaleX(), getScreenScaleY()); | ||
} | ||
|
||
|
||
/** | ||
* Returns the hold icon resource ID. If the key does not have a hold icon, return -1. The scale | ||
* is controlled by super.getHoldElementScale(). | ||
*/ | ||
protected int getHoldIcon() { return -1; } | ||
|
||
|
||
/** | ||
* A fail-safe method to get the hold icon drawable. | ||
*/ | ||
private Drawable getHoldIconCompat() { | ||
if (holdIcon == null && getHoldIcon() > 0) { | ||
holdIcon = AppCompatResources.getDrawable(getContext(), getHoldIcon()); | ||
} else if (getHoldIcon() <= 0) { | ||
holdIcon = null; | ||
} | ||
|
||
return holdIcon; | ||
} | ||
|
||
|
||
protected void resetIconCache() { | ||
icon = null; | ||
holdIcon = null; | ||
} | ||
|
||
|
||
/** | ||
* Renders one of the key icons. It could be either the central icon, in the place of the main title, | ||
* or a hold icon, displayed in the upper right corner. | ||
*/ | ||
private void renderOverlayDrawable(String elementTag, @Nullable Drawable drawable, float scale, boolean isEnabled) { | ||
if (overlay == null) { | ||
return; | ||
} | ||
|
||
View element = ((RelativeLayout) getParent()).findViewWithTag(elementTag); | ||
if (!(element instanceof ImageView el)) { | ||
return; | ||
} | ||
|
||
el.setImageDrawable(drawable); | ||
if (!isEnabled) { | ||
el.setColorFilter(Color.GRAY); | ||
} else { | ||
el.clearColorFilter(); | ||
} | ||
|
||
if (drawable != null) { | ||
el.setScaleX(scale); | ||
el.setScaleY(scale); | ||
} | ||
} | ||
|
||
|
||
public void render() { | ||
boolean isKeyEnabled = isEnabled(); | ||
|
||
getOverlayWrapper(); | ||
renderOverlayDrawable("overlay_icon", getCentralIconCompat(), getCentralIconScale(), isKeyEnabled); | ||
renderOverlayDrawable("overlay_hold_icon", getHoldIconCompat(), getHoldElementScale(), isKeyEnabled && isHoldEnabled()); | ||
|
||
super.render(); | ||
} | ||
} |
27 changes: 27 additions & 0 deletions
27
app/src/main/java/io/github/sspanak/tt9/ui/main/keys/BaseSoftKeyWithSideText.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
package io.github.sspanak.tt9.ui.main.keys; | ||
|
||
import android.content.Context; | ||
import android.util.AttributeSet; | ||
|
||
public class BaseSoftKeyWithSideText extends BaseSoftKeyWithIcons { | ||
public BaseSoftKeyWithSideText(Context context) { super(context); } | ||
public BaseSoftKeyWithSideText(Context context, AttributeSet attrs) { super(context, attrs); } | ||
public BaseSoftKeyWithSideText(Context context, AttributeSet attrs, int defStyleAttr) { super(context, attrs, defStyleAttr); } | ||
|
||
protected String getTopText() { return null; } | ||
protected String getRightText() { return null; } | ||
protected String getBottomText() { return null; } | ||
protected String getLeftText() { return null; } | ||
|
||
@Override | ||
public void render() { | ||
boolean isKeyEnabled = isEnabled(); | ||
|
||
getOverlayWrapper(); | ||
renderOverlayText("overlay_top_text", getTopText(), getHoldElementScale(), isKeyEnabled); | ||
renderOverlayText("overlay_right_text", getRightText(), getHoldElementScale(), isKeyEnabled); | ||
renderOverlayText("overlay_bottom_text", getBottomText(), getHoldElementScale(), isKeyEnabled); | ||
renderOverlayText("overlay_left_text", getLeftText(), getHoldElementScale(), isKeyEnabled); | ||
super.render(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.