mirror of
https://github.com/Julow/Unexpected-Keyboard.git
synced 2025-06-22 10:42:43 +02:00
Refactor: Compute appearance values before onDraw
This moves some computations that used to be done during onDraw into the new Theme.Computed class. This also removes Paint objects from the Theme class, making it data-only. This is a requirement for making some keys render differently.
This commit is contained in:
parent
bd5c815a6f
commit
653c598a1c
@ -47,6 +47,7 @@ public class Keyboard2View extends View
|
||||
private float _marginBottom;
|
||||
|
||||
private Theme _theme;
|
||||
private Theme.Computed _tc;
|
||||
|
||||
private static RectF _tmpRect = new RectF();
|
||||
|
||||
@ -303,6 +304,7 @@ public class Keyboard2View extends View
|
||||
_marginRight = Math.max(_config.horizontal_margin, insets_right);
|
||||
_marginBottom = _config.margin_bottom + insets_bottom;
|
||||
_keyWidth = (width - _marginLeft - _marginRight) / _keyboard.keysWidth;
|
||||
_tc = new Theme.Computed(_theme, _config, _keyWidth);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -340,34 +342,27 @@ public class Keyboard2View extends View
|
||||
{
|
||||
// Set keyboard background opacity
|
||||
getBackground().setAlpha(_config.keyboardOpacity);
|
||||
// Set keys opacity
|
||||
_theme.keyBgPaint.setAlpha(_config.keyOpacity);
|
||||
_theme.keyDownBgPaint.setAlpha(_config.keyActivatedOpacity);
|
||||
_theme.keyBorderPaint.setAlpha(_config.keyOpacity);
|
||||
float key_vertical_margin = _config.key_vertical_margin * _config.keyHeight;
|
||||
float key_horizontal_margin = _config.key_horizontal_margin * _keyWidth;
|
||||
// Add half of the key margin on the left and on the top as it's then added
|
||||
// on the right and on the bottom of every keys.
|
||||
float y = _config.marginTop + key_vertical_margin / 2;
|
||||
float y = _tc.margin_top;
|
||||
for (KeyboardData.Row row : _keyboard.rows)
|
||||
{
|
||||
y += row.shift * _config.keyHeight;
|
||||
float x = _marginLeft + key_horizontal_margin / 2;
|
||||
float keyH = row.height * _config.keyHeight - key_vertical_margin;
|
||||
float x = _marginLeft + _tc.margin_left;
|
||||
float keyH = row.height * _config.keyHeight - _tc.vertical_margin;
|
||||
for (KeyboardData.Key k : row.keys)
|
||||
{
|
||||
x += k.shift * _keyWidth;
|
||||
float keyW = _keyWidth * k.width - key_horizontal_margin;
|
||||
float keyW = _keyWidth * k.width - _tc.horizontal_margin;
|
||||
boolean isKeyDown = _pointers.isKeyDown(k);
|
||||
drawKeyFrame(canvas, x, y, keyW, keyH, isKeyDown);
|
||||
Theme.Computed.Key tc_key = isKeyDown ? _tc.key_activated : _tc.key;
|
||||
drawKeyFrame(canvas, x, y, keyW, keyH, tc_key);
|
||||
if (k.keys[0] != null)
|
||||
drawLabel(canvas, k.keys[0], keyW / 2f + x, y, keyH, isKeyDown);
|
||||
drawLabel(canvas, k.keys[0], keyW / 2f + x, y, keyH, isKeyDown, tc_key);
|
||||
for (int i = 1; i < 9; i++)
|
||||
{
|
||||
if (k.keys[i] != null)
|
||||
drawSubLabel(canvas, k.keys[i], x, y, keyW, keyH, i, isKeyDown);
|
||||
drawSubLabel(canvas, k.keys[i], x, y, keyW, keyH, i, isKeyDown, tc_key);
|
||||
}
|
||||
drawIndication(canvas, k, x, y, keyW, keyH);
|
||||
drawIndication(canvas, k, x, y, keyW, keyH, _tc);
|
||||
x += _keyWidth * k.width;
|
||||
}
|
||||
y += row.height * _config.keyHeight;
|
||||
@ -382,42 +377,32 @@ public class Keyboard2View extends View
|
||||
|
||||
/** Draw borders and background of the key. */
|
||||
void drawKeyFrame(Canvas canvas, float x, float y, float keyW, float keyH,
|
||||
boolean isKeyDown)
|
||||
Theme.Computed.Key tc)
|
||||
{
|
||||
float r = _theme.keyBorderRadius;
|
||||
if (_config.borderConfig)
|
||||
r = _config.customBorderRadius * _keyWidth;
|
||||
float w = (_config.borderConfig) ? _config.customBorderLineWidth : _theme.keyBorderWidth;
|
||||
float r = tc.border_radius;
|
||||
float w = tc.border_width;
|
||||
float padding = w / 2.f;
|
||||
if (isKeyDown)
|
||||
w = _theme.keyBorderWidthActivated;
|
||||
_tmpRect.set(x + padding, y + padding, x + keyW - padding, y + keyH - padding);
|
||||
canvas.drawRoundRect(_tmpRect, r, r,
|
||||
isKeyDown ? _theme.keyDownBgPaint : _theme.keyBgPaint);
|
||||
canvas.drawRoundRect(_tmpRect, r, r, tc.bg_paint);
|
||||
if (w > 0.f)
|
||||
{
|
||||
_theme.keyBorderPaint.setStrokeWidth(w);
|
||||
float overlap = r - r * 0.85f + w; // sin(45°)
|
||||
drawBorder(canvas, x, y, x + overlap, y + keyH, _theme.keyBorderColorLeft);
|
||||
drawBorder(canvas, x + keyW - overlap, y, x + keyW, y + keyH, _theme.keyBorderColorRight);
|
||||
drawBorder(canvas, x, y, x + keyW, y + overlap, _theme.keyBorderColorTop);
|
||||
drawBorder(canvas, x, y + keyH - overlap, x + keyW, y + keyH, _theme.keyBorderColorBottom);
|
||||
drawBorder(canvas, x, y, x + overlap, y + keyH, tc.border_left_paint, tc);
|
||||
drawBorder(canvas, x + keyW - overlap, y, x + keyW, y + keyH, tc.border_right_paint, tc);
|
||||
drawBorder(canvas, x, y, x + keyW, y + overlap, tc.border_top_paint, tc);
|
||||
drawBorder(canvas, x, y + keyH - overlap, x + keyW, y + keyH, tc.border_bottom_paint, tc);
|
||||
}
|
||||
}
|
||||
|
||||
/** Clip to draw a border at a time. This allows to call [drawRoundRect]
|
||||
several time with the same parameters but a different Paint. */
|
||||
void drawBorder(Canvas canvas, float clipl, float clipt, float clipr,
|
||||
float clipb, int color)
|
||||
float clipb, Paint paint, Theme.Computed.Key tc)
|
||||
{
|
||||
Paint p = _theme.keyBorderPaint;
|
||||
float r = _theme.keyBorderRadius;
|
||||
if (_config.borderConfig)
|
||||
r = _config.customBorderRadius * _keyWidth;
|
||||
float r = tc.border_radius;
|
||||
canvas.save();
|
||||
canvas.clipRect(clipl, clipt, clipr, clipb);
|
||||
p.setColor(color);
|
||||
canvas.drawRoundRect(_tmpRect, r, r, p);
|
||||
canvas.drawRoundRect(_tmpRect, r, r, paint);
|
||||
canvas.restore();
|
||||
}
|
||||
|
||||
@ -442,21 +427,21 @@ public class Keyboard2View extends View
|
||||
return sublabel ? _theme.subLabelColor : _theme.labelColor;
|
||||
}
|
||||
|
||||
private void drawLabel(Canvas canvas, KeyValue kv, float x, float y, float keyH, boolean isKeyDown)
|
||||
private void drawLabel(Canvas canvas, KeyValue kv, float x, float y,
|
||||
float keyH, boolean isKeyDown, Theme.Computed.Key tc)
|
||||
{
|
||||
kv = modifyKey(kv, _mods);
|
||||
if (kv == null)
|
||||
return;
|
||||
float textSize = scaleTextSize(kv, _config.labelTextSize, keyH);
|
||||
Paint p = _theme.labelPaint(kv.hasFlagsAny(KeyValue.FLAG_KEY_FONT));
|
||||
Paint p = tc.label_paint(kv.hasFlagsAny(KeyValue.FLAG_KEY_FONT), textSize);
|
||||
p.setColor(labelColor(kv, isKeyDown, false));
|
||||
p.setAlpha(_config.labelBrightness);
|
||||
p.setTextSize(textSize);
|
||||
canvas.drawText(kv.getString(), x, (keyH - p.ascent() - p.descent()) / 2f + y, p);
|
||||
}
|
||||
|
||||
private void drawSubLabel(Canvas canvas, KeyValue kv, float x, float y,
|
||||
float keyW, float keyH, int sub_index, boolean isKeyDown)
|
||||
float keyW, float keyH, int sub_index, boolean isKeyDown,
|
||||
Theme.Computed.Key tc)
|
||||
{
|
||||
Paint.Align a = LABEL_POSITION_H[sub_index];
|
||||
Vertical v = LABEL_POSITION_V[sub_index];
|
||||
@ -464,10 +449,8 @@ public class Keyboard2View extends View
|
||||
if (kv == null)
|
||||
return;
|
||||
float textSize = scaleTextSize(kv, _config.sublabelTextSize, keyH);
|
||||
Paint p = _theme.subLabelPaint(kv.hasFlagsAny(KeyValue.FLAG_KEY_FONT), a);
|
||||
Paint p = tc.sublabel_paint(kv.hasFlagsAny(KeyValue.FLAG_KEY_FONT), textSize, a);
|
||||
p.setColor(labelColor(kv, isKeyDown, true));
|
||||
p.setAlpha(_config.labelBrightness);
|
||||
p.setTextSize(textSize);
|
||||
float subPadding = _config.keyPadding;
|
||||
if (v == Vertical.CENTER)
|
||||
y += (keyH - p.ascent() - p.descent()) / 2f;
|
||||
@ -486,12 +469,11 @@ public class Keyboard2View extends View
|
||||
}
|
||||
|
||||
private void drawIndication(Canvas canvas, KeyboardData.Key k, float x,
|
||||
float y, float keyW, float keyH)
|
||||
float y, float keyW, float keyH, Theme.Computed tc)
|
||||
{
|
||||
if (k.indication == null || k.indication.equals(""))
|
||||
return;
|
||||
Paint p = _theme.indicationPaint(false);
|
||||
p.setColor(_theme.subLabelColor);
|
||||
Paint p = tc.indication_paint;
|
||||
p.setTextSize(keyH * _config.sublabelTextSize * _config.characterSize);
|
||||
canvas.drawText(k.indication, 0, k.indication.length(),
|
||||
x + keyW / 2f, (keyH - p.ascent() - p.descent()) * 4/5 + y, p);
|
||||
|
@ -9,9 +9,11 @@ import android.util.AttributeSet;
|
||||
|
||||
public class Theme
|
||||
{
|
||||
public final Paint keyBgPaint = new Paint();
|
||||
public final Paint keyDownBgPaint = new Paint();
|
||||
public final Paint keyBorderPaint = new Paint();
|
||||
// Key colors
|
||||
public final int colorKey;
|
||||
public final int colorKeyActivated;
|
||||
|
||||
// Label colors
|
||||
public final int lockedColor;
|
||||
public final int activatedColor;
|
||||
public final int labelColor;
|
||||
@ -19,6 +21,7 @@ public class Theme
|
||||
public final int secondaryLabelColor;
|
||||
public final int greyedLabelColor;
|
||||
|
||||
// Key borders
|
||||
public final float keyBorderRadius;
|
||||
public final float keyBorderWidth;
|
||||
public final float keyBorderWidthActivated;
|
||||
@ -30,19 +33,12 @@ public class Theme
|
||||
public final int colorNavBar;
|
||||
public final boolean isLightNavBar;
|
||||
|
||||
private final Paint _keyLabelPaint;
|
||||
private final Paint _specialKeyLabelPaint;
|
||||
private final Paint _keySubLabelPaint;
|
||||
private final Paint _specialKeySubLabelPaint;
|
||||
private final Paint _indicationPaint;
|
||||
private final Paint _specialIndicationPaint;
|
||||
|
||||
public Theme(Context context, AttributeSet attrs)
|
||||
{
|
||||
getKeyFont(context); // _key_font will be accessed
|
||||
TypedArray s = context.getTheme().obtainStyledAttributes(attrs, R.styleable.keyboard, 0, 0);
|
||||
int colorKey = s.getColor(R.styleable.keyboard_colorKey, 0);
|
||||
keyBgPaint.setColor(colorKey);
|
||||
keyDownBgPaint.setColor(s.getColor(R.styleable.keyboard_colorKeyActivated, 0));
|
||||
colorKey = s.getColor(R.styleable.keyboard_colorKey, 0);
|
||||
colorKeyActivated = s.getColor(R.styleable.keyboard_colorKeyActivated, 0);
|
||||
// colorKeyboard = s.getColor(R.styleable.keyboard_colorKeyboard, 0);
|
||||
colorNavBar = s.getColor(R.styleable.keyboard_navigationBarColor, 0);
|
||||
isLightNavBar = s.getBoolean(R.styleable.keyboard_windowLightNavigationBar, false);
|
||||
@ -57,37 +53,11 @@ public class Theme
|
||||
keyBorderRadius = s.getDimension(R.styleable.keyboard_keyBorderRadius, 0);
|
||||
keyBorderWidth = s.getDimension(R.styleable.keyboard_keyBorderWidth, 0);
|
||||
keyBorderWidthActivated = s.getDimension(R.styleable.keyboard_keyBorderWidthActivated, 0);
|
||||
keyBorderPaint.setStyle(Paint.Style.STROKE);
|
||||
keyBorderColorLeft = s.getColor(R.styleable.keyboard_keyBorderColorLeft, colorKey);
|
||||
keyBorderColorTop = s.getColor(R.styleable.keyboard_keyBorderColorTop, colorKey);
|
||||
keyBorderColorRight = s.getColor(R.styleable.keyboard_keyBorderColorRight, colorKey);
|
||||
keyBorderColorBottom = s.getColor(R.styleable.keyboard_keyBorderColorBottom, colorKey);
|
||||
s.recycle();
|
||||
_keyLabelPaint = initLabelPaint(Paint.Align.CENTER, null);
|
||||
_keySubLabelPaint = initLabelPaint(Paint.Align.LEFT, null);
|
||||
Typeface specialKeyFont = getKeyFont(context);
|
||||
_specialKeyLabelPaint = initLabelPaint(Paint.Align.CENTER, specialKeyFont);
|
||||
_specialKeySubLabelPaint = initLabelPaint(Paint.Align.LEFT, specialKeyFont);
|
||||
_indicationPaint = initLabelPaint(Paint.Align.CENTER, null);
|
||||
_specialIndicationPaint = initLabelPaint(Paint.Align.CENTER, specialKeyFont);
|
||||
}
|
||||
|
||||
public Paint labelPaint(boolean special_font)
|
||||
{
|
||||
Paint p = special_font ? _specialKeyLabelPaint : _keyLabelPaint;
|
||||
return p;
|
||||
}
|
||||
|
||||
public Paint subLabelPaint(boolean special_font, Paint.Align align)
|
||||
{
|
||||
Paint p = special_font ? _specialKeySubLabelPaint : _keySubLabelPaint;
|
||||
p.setTextAlign(align);
|
||||
return p;
|
||||
}
|
||||
|
||||
public Paint indicationPaint(boolean special_font)
|
||||
{
|
||||
return special_font ? _specialIndicationPaint : _indicationPaint;
|
||||
}
|
||||
|
||||
/** Interpolate the 'value' component toward its opposite by 'alpha'. */
|
||||
@ -100,7 +70,7 @@ public class Theme
|
||||
return Color.HSVToColor(hsv);
|
||||
}
|
||||
|
||||
Paint initLabelPaint(Paint.Align align, Typeface font)
|
||||
Paint initIndicationPaint(Paint.Align align, Typeface font)
|
||||
{
|
||||
Paint paint = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
paint.setTextAlign(align);
|
||||
@ -117,4 +87,104 @@ public class Theme
|
||||
_key_font = Typeface.createFromAsset(context.getAssets(), "special_font.ttf");
|
||||
return _key_font;
|
||||
}
|
||||
|
||||
public static final class Computed
|
||||
{
|
||||
public final float vertical_margin;
|
||||
public final float horizontal_margin;
|
||||
public final float margin_top;
|
||||
public final float margin_left;
|
||||
public final Paint indication_paint;
|
||||
|
||||
public final Key key;
|
||||
public final Key key_activated;
|
||||
|
||||
public Computed(Theme theme, Config config, float keyWidth)
|
||||
{
|
||||
vertical_margin = config.key_vertical_margin * config.keyHeight;
|
||||
horizontal_margin = config.key_horizontal_margin * keyWidth;
|
||||
// Add half of the key margin on the left and on the top as it's also
|
||||
// added on the right and on the bottom of every keys.
|
||||
margin_top = config.marginTop + vertical_margin / 2;
|
||||
margin_left = horizontal_margin / 2;
|
||||
key = new Key(theme, config, keyWidth, false);
|
||||
key_activated = new Key(theme, config, keyWidth, true);
|
||||
indication_paint = init_label_paint(config, null);
|
||||
indication_paint.setColor(theme.subLabelColor);
|
||||
}
|
||||
|
||||
public static final class Key
|
||||
{
|
||||
public final Paint bg_paint = new Paint();
|
||||
public final Paint border_left_paint;
|
||||
public final Paint border_top_paint;
|
||||
public final Paint border_right_paint;
|
||||
public final Paint border_bottom_paint;
|
||||
public final float border_width;
|
||||
public final float border_radius;
|
||||
final Paint _label_paint;
|
||||
final Paint _special_label_paint;
|
||||
final Paint _sublabel_paint;
|
||||
final Paint _special_sublabel_paint;
|
||||
|
||||
public Key(Theme theme, Config config, float keyWidth, boolean activated)
|
||||
{
|
||||
bg_paint.setColor(activated ? theme.colorKeyActivated : theme.colorKey);
|
||||
if (config.borderConfig)
|
||||
{
|
||||
border_radius = config.customBorderRadius * keyWidth;
|
||||
border_width = config.customBorderLineWidth;
|
||||
}
|
||||
else
|
||||
{
|
||||
border_radius = theme.keyBorderRadius;
|
||||
border_width = activated ? theme.keyBorderWidthActivated : theme.keyBorderWidth;
|
||||
}
|
||||
bg_paint.setAlpha(activated ? config.keyActivatedOpacity : config.keyOpacity);
|
||||
border_left_paint = init_border_paint(config, border_width, theme.keyBorderColorLeft);
|
||||
border_top_paint = init_border_paint(config, border_width, theme.keyBorderColorTop);
|
||||
border_right_paint = init_border_paint(config, border_width, theme.keyBorderColorRight);
|
||||
border_bottom_paint = init_border_paint(config, border_width, theme.keyBorderColorBottom);
|
||||
_label_paint = init_label_paint(config, null);
|
||||
_special_label_paint = init_label_paint(config, _key_font);
|
||||
_sublabel_paint = init_label_paint(config, null);
|
||||
_special_sublabel_paint = init_label_paint(config, _key_font);
|
||||
}
|
||||
|
||||
public Paint label_paint(boolean special_font, float text_size)
|
||||
{
|
||||
Paint p = special_font ? _special_label_paint : _label_paint;
|
||||
p.setTextSize(text_size);
|
||||
return p;
|
||||
}
|
||||
|
||||
public Paint sublabel_paint(boolean special_font, float text_size, Paint.Align align)
|
||||
{
|
||||
Paint p = special_font ? _special_sublabel_paint : _sublabel_paint;
|
||||
p.setTextSize(text_size);
|
||||
p.setTextAlign(align);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
|
||||
static Paint init_border_paint(Config config, float border_width, int color)
|
||||
{
|
||||
Paint p = new Paint();
|
||||
p.setAlpha(config.keyOpacity);
|
||||
p.setStyle(Paint.Style.STROKE);
|
||||
p.setStrokeWidth(border_width);
|
||||
p.setColor(color);
|
||||
return p;
|
||||
}
|
||||
|
||||
static Paint init_label_paint(Config config, Typeface font)
|
||||
{
|
||||
Paint p = new Paint(Paint.ANTI_ALIAS_FLAG);
|
||||
p.setTextAlign(Paint.Align.CENTER);
|
||||
p.setAlpha(config.labelBrightness);
|
||||
if (font != null)
|
||||
p.setTypeface(font);
|
||||
return p;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user