Skip to content

Commit

Permalink
refactor(text): reduce redundant code and normalize variable names
Browse files Browse the repository at this point in the history
  • Loading branch information
WhiredPlanck authored and Bambooin committed Oct 23, 2021
1 parent 902d400 commit b2580d9
Showing 1 changed file with 104 additions and 124 deletions.
228 changes: 104 additions & 124 deletions app/src/main/java/com/osfans/trime/ime/symbol/TabView.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,19 @@

import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.PaintDrawable;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup.LayoutParams;

import androidx.annotation.NonNull;

import com.osfans.trime.ime.core.Trime;
import com.osfans.trime.ime.enums.SymbolKeyboardType;
import com.osfans.trime.setup.Config;
Expand All @@ -42,115 +46,103 @@ public class TabView extends View {
private static final int CANDIDATE_TOUCH_OFFSET = -12;

private int highlightIndex;
private TabTag[] candidates;
private int num_candidates;

private Drawable candidateHighlight, candidateSeparator;
private final Paint paintCandidate;
private final Paint paintSymbol;
private final Paint paintComment;
private Typeface tfCandidate;
private Typeface tfHanB;
private Typeface tfLatin;
private int candidate_text_color, hilited_candidate_text_color;
private int candidate_view_height, comment_height, candidate_spacing, candidate_padding;
private final boolean show_comment = true;
private boolean comment_on_top;
private boolean candidate_use_cursor;

private final Rect[] candidateRect = new Rect[MAX_CANDIDATE_COUNT + 2];
private TabTag[] tabTags;

private PaintDrawable candidateHighlight;
private final Paint separatorPaint;
private final Paint candidatePaint;
private Typeface candidateFont;
private Typeface hanBFont;
private Typeface latinFont;
private int candidateTextColor, hilitedCandidateTextColor;
private int candidateViewHeight, commentHeight, candidateSpacing, candidatePadding;
private final boolean shouldShowComment = true;
private boolean isCommentOnTop;
private boolean shouldCandidateUseCursor;

private final Rect[] tabGeometries = new Rect[MAX_CANDIDATE_COUNT + 2];

public void reset(Context context) {
Config config = Config.get(context);
candidateHighlight = new PaintDrawable(config.getColor("hilited_candidate_back_color"));
((PaintDrawable) candidateHighlight).setCornerRadius(config.getFloat("layout/round_corner"));
candidateSeparator = new PaintDrawable(config.getColor("candidate_separator_color"));
candidate_spacing = config.getPixel("candidate_spacing");
candidate_padding = config.getPixel("candidate_padding");

candidate_text_color = config.getColor("candidate_text_color");
hilited_candidate_text_color = config.getColor("hilited_candidate_text_color");

comment_height = config.getPixel("comment_height");

int candidate_text_size = config.getPixel("candidate_text_size");
int comment_text_size = config.getPixel("comment_text_size");
candidate_view_height = config.getPixel("candidate_view_height");

tfCandidate = config.getFont("candidate_font");
tfLatin = config.getFont("latin_font");
tfHanB = config.getFont("hanb_font");
Typeface tfComment = config.getFont("comment_font");
Typeface tfSymbol = config.getFont("symbol_font");

paintCandidate.setTextSize(candidate_text_size);
paintCandidate.setTypeface(tfCandidate);
paintSymbol.setTextSize(candidate_text_size);
paintSymbol.setTypeface(tfSymbol);
paintComment.setTextSize(comment_text_size);
paintComment.setTypeface(tfComment);

comment_on_top = config.getBoolean("comment_on_top");
candidate_use_cursor = config.getBoolean("candidate_use_cursor");
candidateHighlight.setCornerRadius(config.getFloat("layout/round_corner"));

separatorPaint.setColor(config.getColor("candidate_separator_color"));

candidateSpacing = config.getPixel("candidate_spacing");
candidatePadding = config.getPixel("candidate_padding");

candidateTextColor = config.getColor("candidate_text_color");
hilitedCandidateTextColor = config.getColor("hilited_candidate_text_color");

commentHeight = config.getPixel("comment_height");

int candidateTextSize = config.getPixel("candidate_text_size");
candidateViewHeight = config.getPixel("candidate_view_height");

candidateFont = config.getFont("candidate_font");
latinFont = config.getFont("latin_font");
hanBFont = config.getFont("hanb_font");

candidatePaint.setTextSize(candidateTextSize);
candidatePaint.setTypeface(candidateFont);

isCommentOnTop = config.getBoolean("comment_on_top");
shouldCandidateUseCursor = config.getBoolean("candidate_use_cursor");
invalidate();
}

public TabView(Context context, AttributeSet attrs) {
super(context, attrs);
paintCandidate = new Paint();
paintCandidate.setAntiAlias(true);
paintCandidate.setStrokeWidth(0);
paintSymbol = new Paint();
paintSymbol.setAntiAlias(true);
paintSymbol.setStrokeWidth(0);
paintComment = new Paint();
paintComment.setAntiAlias(true);
paintComment.setStrokeWidth(0);
candidatePaint = new Paint();
candidatePaint.setAntiAlias(true);
candidatePaint.setStrokeWidth(0);

separatorPaint = new Paint();
separatorPaint.setColor(Color.BLACK);

reset(context);

setWillNotDraw(false);
}

private boolean isHighlighted(int i) {
return candidate_use_cursor && i >= 0 && i == highlightIndex;
return shouldCandidateUseCursor && i >= 0 && i == highlightIndex;
}

private void drawHighlight(Canvas canvas) {
if (isHighlighted(highlightIndex)) {
candidateHighlight.setBounds(candidateRect[highlightIndex]);
candidateHighlight.setBounds(tabGeometries[highlightIndex]);
candidateHighlight.draw(canvas);
}
}

public int getHightlightLeft() {
return candidateRect[highlightIndex].left;
return tabGeometries[highlightIndex].left;
}

public int getHightlightRight() {
return candidateRect[highlightIndex].right;
return tabGeometries[highlightIndex].right;
}

private Typeface getFont(int codepoint, Typeface font) {
if (tfHanB != Typeface.DEFAULT && Character.isSupplementaryCodePoint(codepoint)) return tfHanB;
if (tfLatin != Typeface.DEFAULT && codepoint < 0x2e80) return tfLatin;
if (hanBFont != Typeface.DEFAULT && Character.isSupplementaryCodePoint(codepoint)) return hanBFont;
if (latinFont != Typeface.DEFAULT && codepoint < 0x2e80) return latinFont;
return font;
}

private void drawText(
String s, Canvas canvas, Paint paint, Typeface font, float center, float y) {
if (s == null) return;
int length = s.length();
if (length == 0) return;
int points = s.codePointCount(0, length);
if (TextUtils.isEmpty(s)) return;
int codePoints = s.codePointCount(0, s.length());
float x = center - measureText(s, paint, font) / 2;
if (tfLatin != Typeface.DEFAULT || (tfHanB != Typeface.DEFAULT && length > points)) {
if (latinFont != Typeface.DEFAULT || (hanBFont != Typeface.DEFAULT && s.length() > codePoints)) {
int offset = 0;
while (offset < length) {
int codepoint = s.codePointAt(offset);
int charCount = Character.charCount(codepoint);
while (offset < s.length()) {
int codePoint = s.codePointAt(offset);
int charCount = Character.charCount(codePoint);
int end = offset + charCount;
paint.setTypeface(getFont(codepoint, font));
paint.setTypeface(getFont(codePoint, font));
canvas.drawText(s, offset, end, x, y, paint);
x += paint.measureText(s, offset, end);
offset = end;
Expand All @@ -162,28 +154,27 @@ private void drawText(
}

private void drawCandidates(Canvas canvas) {
if (candidates == null) return;

float x, y;
int i = 0;
if (tabTags == null) return;

y = candidateRect[0].centerY() - (paintCandidate.ascent() + paintCandidate.descent()) / 2;
if (show_comment && comment_on_top) y += (float) comment_height / 2;
float y = tabGeometries[0].centerY() - (candidatePaint.ascent() + candidatePaint.descent()) / 2;
if (shouldShowComment && isCommentOnTop) y += (float) commentHeight / 2;

while (i < num_candidates) {
int i = 0;
while (i < tabTags.length) {
// Calculate a position where the text could be centered in the rectangle.
x = candidateRect[i].centerX();
float x = tabGeometries[i].centerX();

paintCandidate.setColor(
isHighlighted(i) ? hilited_candidate_text_color : candidate_text_color);
drawText(getCandidate(i), canvas, paintCandidate, tfCandidate, x, y);
candidatePaint.setColor(
isHighlighted(i) ? hilitedCandidateTextColor : candidateTextColor);
drawText(getTabText(i), canvas, candidatePaint, candidateFont, x, y);
// Draw the separator at the right edge of each candidate.
candidateSeparator.setBounds(
candidateRect[i].right - candidateSeparator.getIntrinsicWidth(),
candidateRect[i].top,
candidateRect[i].right + candidate_spacing,
candidateRect[i].bottom);
candidateSeparator.draw(canvas);
canvas.drawRect(
tabGeometries[i].right - candidateSpacing,
tabGeometries[i].top,
tabGeometries[i].right + candidateSpacing,
tabGeometries[i].bottom,
separatorPaint
);
i++;
}
}
Expand All @@ -200,25 +191,19 @@ protected void onDraw(Canvas canvas) {
}

public void updateCandidateWidth() {
final int top = 0;
final int bottom = getHeight();
int i;
int x = 0;

candidates = TabManager.get().getTabCandidates();
tabTags = TabManager.get().getTabCandidates();
highlightIndex = TabManager.get().getSelected();
num_candidates = candidates.length;

for (i = 0; i < num_candidates; i++) {
candidateRect[i] = new Rect(x, top, x += getCandidateWidth(i), bottom);
x += candidate_spacing;
int x = 0;
for (int i = 0; i < tabTags.length; i++) {
tabGeometries[i] = new Rect(x, 0, x += getTabWidth(i), getHeight());
x += candidateSpacing;
}
LayoutParams params = getLayoutParams();
Timber.i("update, from Height=" + params.height + " width=" + params.width);
params.width = x;
params.height = candidate_view_height;
if (show_comment && comment_on_top) params.height += comment_height;
Timber.i("update, to Height=" + candidate_view_height + " width=" + x);
params.height = (shouldShowComment && isCommentOnTop) ? candidateViewHeight + commentHeight : candidateViewHeight;
Timber.i("update, to Height=" + candidateViewHeight + " width=" + x);
setLayoutParams(params);
params = getLayoutParams();
Timber.i("update, reload Height=" + params.height + " width=" + params.width);
Expand All @@ -241,23 +226,22 @@ public boolean performClick() {
long time0;

@Override
public boolean onTouchEvent(MotionEvent me) {
int action = me.getAction();
public boolean onTouchEvent(@NonNull MotionEvent me) {
int x = (int) me.getX();
int y = (int) me.getY();

switch (action) {
switch (me.getActionMasked()) {
case MotionEvent.ACTION_DOWN:
x0 = x;
y0 = y;
time0 = System.currentTimeMillis();
// updateHighlight(x, y);
break;
case MotionEvent.ACTION_MOVE:
if (x - x0 > 100 || x0 - x > 100) time0 = 0;
if (Math.abs(x - x0) > 100) time0 = 0;
break;
case MotionEvent.ACTION_UP:
int i = getCandidateIndex(x, y);
int i = getTabIndex(x, y);
if (i > -1) {
performClick();
TabTag tag = TabManager.getTag(i);
Expand All @@ -279,7 +263,7 @@ public boolean onTouchEvent(MotionEvent me) {
invalidate();
Trime.getService().selectLiquidKeyboard(i);
}
Timber.d("index=" + i + " length=" + candidates.length);
Timber.d("index=" + i + " length=" + tabTags.length);
}
break;
}
Expand All @@ -293,36 +277,34 @@ public boolean onTouchEvent(MotionEvent me) {
* @param y 觸摸點縱座標
* @return {@code >=0}: 觸摸點 (x, y) 處候選項序號,從0開始編號; {@code -1}: 觸摸點 (x, y) 處無候選項;
*/
private int getCandidateIndex(int x, int y) {
private int getTabIndex(int x, int y) {
Rect r = new Rect();

int j = 0;
for (int i = 0; i < num_candidates; i++) {
for (int i = 0; i < tabTags.length; i++) {
// Enlarge the rectangle to be more responsive to user clicks.
r.set(candidateRect[j++]);
r.set(tabGeometries[j++]);
r.inset(0, CANDIDATE_TOUCH_OFFSET);
if (r.contains(x, y)) {
// Returns -1 if there is no candidate in the hitting rectangle.
return (i < num_candidates) ? i : -1;
return (i < tabTags.length) ? i : -1;
}
}
return -1;
}

private String getCandidate(int i) {
if (candidates != null && i >= 0) return candidates[i].text;
private String getTabText(int i) {
if (tabTags != null && i >= 0) return tabTags[i].text;
return "-1";
}

private float measureText(String s, Paint paint, Typeface font) {
if (TextUtils.isEmpty(s)) return 0;
float x = 0;
if (s == null) return x;
int length = s.length();
if (length == 0) return x;
int points = s.codePointCount(0, length);
if (tfLatin != Typeface.DEFAULT || (tfHanB != Typeface.DEFAULT && length > points)) {
int codePoints = s.codePointCount(0, s.length());
if (latinFont != Typeface.DEFAULT || (hanBFont != Typeface.DEFAULT && s.length() > codePoints)) {
int offset = 0;
while (offset < length) {
while (offset < s.length()) {
int codepoint = s.codePointAt(offset);
int charCount = Character.charCount(codepoint);
int end = offset + charCount;
Expand All @@ -338,10 +320,8 @@ private float measureText(String s, Paint paint, Typeface font) {
return x;
}

private float getCandidateWidth(int i) {
String s = getCandidate(i);
float x = 2 * candidate_padding;
if (s != null) x += measureText(s, paintCandidate, tfCandidate);
return x;
private float getTabWidth(int i) {
String s = getTabText(i);
return s != null ? 2 * candidatePadding + measureText(s, candidatePaint, candidateFont) : 2 * candidatePadding;
}
}

0 comments on commit b2580d9

Please sign in to comment.