Android ui upgrade (#1)

---------

Co-authored-by: intelligence <intelligence@debian.local>
Reviewed-on: #1
This commit was merged in pull request #1.
This commit is contained in:
jourintownandintelligence committed 2026-08-29 19:22:18 +02:00
1 parent 357edf9a2d
commit ca1437a4fa
11 files changed
+108 -51

No files matched your search

@@ -1,17 +1,34 @@
package io.github.transui.android;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.widget.ImageButton;
public final class PushToTalkButton extends ImageButton {
enum IconMode {
APPS,
STOP_CIRCLE
}
private final Paint iconPaint = new Paint(Paint.ANTI_ALIAS_FLAG);
private Runnable pressedAction;
private Runnable releasedAction;
private boolean trackingPress;
private IconMode iconMode = IconMode.STOP_CIRCLE;
public PushToTalkButton(Context context, AttributeSet attributes) {
super(context, attributes);
iconPaint.setColor(context.getColor(R.color.on_signal));
setImageDrawable(null);
}
void setIconMode(IconMode iconMode) {
this.iconMode = iconMode;
setImageDrawable(null);
invalidate();
}
void setPushToTalkActions(Runnable pressedAction, Runnable releasedAction) {
@@ -55,4 +72,48 @@ public final class PushToTalkButton extends ImageButton {
public boolean performClick() {
return super.performClick();
}
@Override
protected void onDraw(Canvas canvas) {
super.onDraw(canvas);
float contentWidth = getWidth() - getPaddingLeft() - getPaddingRight();
float contentHeight = getHeight() - getPaddingTop() - getPaddingBottom();
float size = Math.min(contentWidth, contentHeight);
float centerX = getWidth() / 2f;
float centerY = getHeight() / 2f;
if (iconMode == IconMode.APPS) {
drawAppsIcon(canvas, centerX, centerY, size);
} else {
drawStopCircleIcon(canvas, centerX, centerY, size);
}
}
private void drawAppsIcon(Canvas canvas, float centerX, float centerY, float size) {
iconPaint.setStyle(Paint.Style.FILL);
float spacing = size * 0.27f;
float radius = size * 0.09f;
for (int row = -1; row <= 1; row++) {
for (int column = -1; column <= 1; column++) {
canvas.drawCircle(
centerX + column * spacing,
centerY + row * spacing,
radius,
iconPaint);
}
}
}
private void drawStopCircleIcon(Canvas canvas, float centerX, float centerY, float size) {
iconPaint.setStyle(Paint.Style.STROKE);
iconPaint.setStrokeWidth(size * 0.12f);
canvas.drawCircle(centerX, centerY, size * 0.42f, iconPaint);
iconPaint.setStyle(Paint.Style.FILL);
float squareHalfSize = size * 0.17f;
canvas.drawRect(
centerX - squareHalfSize,
centerY - squareHalfSize,
centerX + squareHalfSize,
centerY + squareHalfSize,
iconPaint);
}
}
@@ -80,25 +80,29 @@ public final class SpeechRecognitionActivity extends Activity {
private void configureRecordButton() {
record.setAlpha(1);
resizeRecordButton(config.pushToTalk ? 80 : 64, config.pushToTalk ? 23 : 19);
if (config.pushToTalk) {
record.setImageResource(R.drawable.ic_mic);
record.setBackgroundResource(R.drawable.voice_pill_button);
resizeRecordButton(132, 64, 16);
record.setIconMode(PushToTalkButton.IconMode.APPS);
record.setContentDescription(getString(R.string.hold_to_talk));
record.setPushToTalkActions(this::startRecording, this::stopRecording);
} else {
record.setImageResource(R.drawable.ic_stop);
record.setBackgroundResource(R.drawable.voice_primary_button);
resizeRecordButton(64, 64, 19);
record.setIconMode(PushToTalkButton.IconMode.STOP_CIRCLE);
record.setContentDescription(getString(R.string.stop));
record.setOnClickListener(view -> stopRecording());
}
}
private void resizeRecordButton(int sizeDp, int paddingDp) {
private void resizeRecordButton(int widthDp, int heightDp, int paddingDp) {
float density = getResources().getDisplayMetrics().density;
int size = Math.round(sizeDp * density);
int width = Math.round(widthDp * density);
int height = Math.round(heightDp * density);
int padding = Math.round(paddingDp * density);
ViewGroup.LayoutParams parameters = record.getLayoutParams();
parameters.width = size;
parameters.height = size;
parameters.width = width;
parameters.height = height;
record.setLayoutParams(parameters);
record.setPadding(padding, padding, padding, padding);
}
@@ -194,7 +198,9 @@ public final class SpeechRecognitionActivity extends Activity {
public void onRecording() {
runOnUiThread(() -> {
status.setText(R.string.listening);
if (!config.pushToTalk) record.setImageResource(R.drawable.ic_stop);
if (!config.pushToTalk) {
record.setIconMode(PushToTalkButton.IconMode.STOP_CIRCLE);
}
recordingStartedAt = SystemClock.elapsedRealtime();
elapsed.setText(R.string.elapsed_zero);
handler.post(updateElapsed);
@@ -109,25 +109,29 @@ public final class TransuiInputMethodService extends InputMethodService {
record.setAlpha(1);
record.setOnClickListener(null);
record.setPushToTalkActions(null, null);
resizeRecordButton(config.pushToTalk ? 76 : 64, config.pushToTalk ? 22 : 19);
if (config.pushToTalk) {
record.setImageResource(R.drawable.ic_mic);
record.setBackgroundResource(R.drawable.voice_pill_button);
resizeRecordButton(132, 64, 16);
record.setIconMode(PushToTalkButton.IconMode.APPS);
record.setContentDescription(getString(R.string.hold_to_talk));
record.setPushToTalkActions(this::startRecording, this::stopRecording);
} else {
record.setImageResource(R.drawable.ic_stop);
record.setBackgroundResource(R.drawable.voice_primary_button);
resizeRecordButton(64, 64, 19);
record.setIconMode(PushToTalkButton.IconMode.STOP_CIRCLE);
record.setContentDescription(getString(R.string.stop));
record.setOnClickListener(view -> stopRecording());
}
}
private void resizeRecordButton(int sizeDp, int paddingDp) {
private void resizeRecordButton(int widthDp, int heightDp, int paddingDp) {
float density = getResources().getDisplayMetrics().density;
int size = Math.round(sizeDp * density);
int width = Math.round(widthDp * density);
int height = Math.round(heightDp * density);
int padding = Math.round(paddingDp * density);
ViewGroup.LayoutParams parameters = record.getLayoutParams();
parameters.width = size;
parameters.height = size;
parameters.width = width;
parameters.height = height;
record.setLayoutParams(parameters);
record.setPadding(padding, padding, padding, padding);
}
@@ -176,7 +180,9 @@ public final class TransuiInputMethodService extends InputMethodService {
public void onRecording() {
handler.post(() -> {
status.setText(R.string.listening);
if (!config.pushToTalk) record.setImageResource(R.drawable.ic_stop);
if (!config.pushToTalk) {
record.setIconMode(PushToTalkButton.IconMode.STOP_CIRCLE);
}
});
}
@@ -1,10 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path
android:fillColor="#FF000000"
android:pathData="M12,14c1.66,0 3,-1.34 3,-3V5c0,-1.66 -1.34,-3 -3,-3S9,3.34 9,5v6c0,1.66 1.34,3 3,3zM17,11c0,2.76 -2.24,5 -5,5s-5,-2.24 -5,-5H5c0,3.53 2.61,6.43 6,6.92V21h2v-3.08c3.39,-0.49 6,-3.39 6,-6.92h-2z" />
</vector>
@@ -1,8 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24">
<path android:fillColor="#FF000000" android:pathData="M6,6h12v12H6z" />
</vector>
@@ -0,0 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<ripple xmlns:android="http://schemas.android.com/apk/res/android"
android:color="@color/ripple_on_signal">
<item>
<shape android:shape="rectangle">
<solid android:color="@color/signal" />
<corners android:radius="18dp" />
</shape>
</item>
</ripple>
@@ -60,9 +60,7 @@
android:layout_marginTop="14dp"
android:background="@drawable/voice_primary_button"
android:contentDescription="@string/stop"
android:padding="16dp"
android:src="@drawable/ic_stop"
android:tint="@color/paper" />
android:padding="16dp" />
<Button
android:id="@+id/recognition_cancel"
@@ -75,8 +75,6 @@
android:layout_gravity="center"
android:background="@drawable/voice_primary_button"
android:contentDescription="@string/stop"
android:padding="21dp"
android:src="@drawable/ic_stop"
android:tint="@color/paper" />
android:padding="21dp" />
</FrameLayout>
</LinearLayout>
@@ -6,6 +6,7 @@
<color name="mist">#11191D</color>
<color name="paper">#192329</color>
<color name="line">#34444B</color>
<color name="on_signal">#142027</color>
<color name="ripple_on_signal">#3DFFFFFF</color>
<color name="ripple_signal">#3342C9C1</color>
</resources>
@@ -6,6 +6,7 @@
<color name="mist">#F2F6F7</color>
<color name="paper">#FFFFFF</color>
<color name="line">#D5E0E3</color>
<color name="on_signal">#FFFFFF</color>
<color name="ripple_on_signal">#3DFFFFFF</color>
<color name="ripple_signal">#33008D87</color>
</resources>