[go: nahoru, domu]

blob: 8f19ae4caacc8ec25f06e7b18d890e9791321a3a [file] [log] [blame]
/*
* Copyright 2021 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package androidx.wear.watchface.samples.minimal.complications;
import static androidx.wear.watchface.samples.minimal.complications.WatchFaceService.COMPLICATION_BOUNDS;
import android.content.res.Resources;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Align;
import android.graphics.Paint.Style;
import android.graphics.PorterDuff.Mode;
import android.graphics.PorterDuffXfermode;
import android.graphics.Rect;
import android.view.SurfaceHolder;
import androidx.annotation.NonNull;
import androidx.annotation.Px;
import androidx.wear.watchface.CanvasType;
import androidx.wear.watchface.ComplicationSlot;
import androidx.wear.watchface.ComplicationSlotsManager;
import androidx.wear.watchface.RenderParameters.HighlightLayer;
import androidx.wear.watchface.RenderParameters.HighlightedElement;
import androidx.wear.watchface.Renderer;
import androidx.wear.watchface.WatchState;
import androidx.wear.watchface.style.CurrentUserStyleRepository;
import java.time.ZonedDateTime;
import java.util.concurrent.TimeUnit;
class WatchFaceRenderer extends Renderer.CanvasRenderer {
private static final long UPDATE_DELAY_MILLIS = TimeUnit.SECONDS.toMillis(1);
private static final char[] DIGITS = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
/** Turn this on to debug the highlight layer. */
private static final boolean HIGHLIGHT_DEBUG = false;
private final ComplicationSlotsManager mComplicationSlotsManager;
private final Paint mPaint;
private final Paint mHighlightPaint;
private final Paint mHighlightFocusPaint;
@Px
private final float mHighlightExtraRadius;
private final char[] mTime = new char[5];
private Bitmap mHighlightBitmap;
WatchFaceRenderer(
@NonNull Resources resources,
@NonNull SurfaceHolder surfaceHolder,
@NonNull CurrentUserStyleRepository userStyleRepository,
@NonNull WatchState watchState,
@NonNull ComplicationSlotsManager complicationSlotsManager) {
super(surfaceHolder,
userStyleRepository,
watchState,
CanvasType.HARDWARE,
UPDATE_DELAY_MILLIS,
/* clearWithBackgroundTintBeforeRenderingHighlightLayer= */ true);
mComplicationSlotsManager = complicationSlotsManager;
mPaint = new Paint();
mPaint.setTextAlign(Align.CENTER);
mPaint.setTextSize(64f);
mHighlightPaint = new Paint();
mHighlightPaint.setTextAlign(Align.CENTER);
mHighlightPaint.setStyle(Style.STROKE);
mHighlightPaint.setStrokeWidth(resources.getDimension(R.dimen.highlight_stroke_width));
mHighlightExtraRadius = resources.getDimension(R.dimen.highlight_extra_radius);
mHighlightFocusPaint = new Paint();
mHighlightFocusPaint.setXfermode(new PorterDuffXfermode(Mode.CLEAR));
}
@Override
public void render(@NonNull Canvas canvas, @NonNull Rect rect,
@NonNull ZonedDateTime zonedDateTime) {
mPaint.setColor(Color.BLACK);
canvas.drawRect(rect, mPaint);
for (ComplicationSlot complication :
mComplicationSlotsManager.getComplicationSlots().values()) {
if (complication.isEnabled()) {
complication.render(canvas, zonedDateTime, getRenderParameters());
}
}
mPaint.setColor(Color.WHITE);
int hour = zonedDateTime.getHour() % 12;
int minute = zonedDateTime.getMinute();
int second = zonedDateTime.getSecond();
mTime[0] = DIGITS[hour / 10];
mTime[1] = DIGITS[hour % 10];
mTime[2] = second % 2 == 0 ? ':' : ' ';
mTime[3] = DIGITS[minute / 10];
mTime[4] = DIGITS[minute % 10];
canvas.drawText(mTime, 0, 5, rect.centerX(), rect.centerY(), mPaint);
if (HIGHLIGHT_DEBUG) {
HighlightLayer highlightLayerParams =
new HighlightLayer(
new HighlightedElement.ComplicationSlot(0), Color.MAGENTA, 0x10000000);
if (mHighlightBitmap == null
|| mHighlightBitmap.getWidth() != rect.width()
|| mHighlightBitmap.getHeight() != rect.height()) {
mHighlightBitmap =
Bitmap.createBitmap(rect.width(), rect.height(), Config.ARGB_8888);
}
renderHighlightLayer(
new Canvas(mHighlightBitmap), rect, zonedDateTime, highlightLayerParams);
canvas.drawBitmap(mHighlightBitmap, rect.left, rect.top, mPaint);
}
}
@Override
public void renderHighlightLayer(
@NonNull Canvas canvas, @NonNull Rect rect, @NonNull ZonedDateTime zonedDateTime) {
renderHighlightLayer(canvas, rect, zonedDateTime,
getRenderParameters().getHighlightLayer());
}
private void renderHighlightLayer(
@NonNull Canvas canvas,
@NonNull Rect rect,
@SuppressWarnings("UnusedVariable") @NonNull ZonedDateTime zonedDateTime,
HighlightLayer params) {
// There is no style defined, so the only options are rendering the highlight for the
// only complication or for all complications, which is essentially the same.
mHighlightPaint.setColor(params.getHighlightTint());
mHighlightFocusPaint.setColor(params.getBackgroundTint());
float complicationSlotRadius = COMPLICATION_BOUNDS.width() * rect.width() / 2f;
float highlightRadius = complicationSlotRadius + mHighlightExtraRadius;
float centerX = COMPLICATION_BOUNDS.centerX() * rect.width();
float centerY = COMPLICATION_BOUNDS.centerY() * rect.height();
canvas.drawCircle(centerX, centerY, highlightRadius, mHighlightFocusPaint);
canvas.drawCircle(centerX, centerY, highlightRadius, mHighlightPaint);
}
}