All Downloads are FREE. Search and download functionalities are using the official Maven repository.

eu.hansolo.medusa.skins.LcdClockSkin Maven / Gradle / Ivy

/*
 * Copyright (c) 2016 by Gerrit Grunwald
 *
 * 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 eu.hansolo.medusa.skins;

import eu.hansolo.medusa.Clock;
import eu.hansolo.medusa.Fonts;
import eu.hansolo.medusa.LcdDesign;
import eu.hansolo.medusa.LcdFont;
import eu.hansolo.medusa.tools.Helper;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
import java.time.format.TextStyle;
import java.util.Locale;
import javafx.geometry.Insets;
import javafx.geometry.VPos;
import javafx.scene.Group;
import javafx.scene.effect.BlurType;
import javafx.scene.effect.DropShadow;
import javafx.scene.effect.InnerShadow;
import javafx.scene.image.Image;
import javafx.scene.image.ImageView;
import javafx.scene.layout.Background;
import javafx.scene.layout.BackgroundFill;
import javafx.scene.layout.Border;
import javafx.scene.layout.BorderStroke;
import javafx.scene.layout.BorderStrokeStyle;
import javafx.scene.layout.BorderWidths;
import javafx.scene.layout.CornerRadii;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.paint.CycleMethod;
import javafx.scene.paint.LinearGradient;
import javafx.scene.paint.Paint;
import javafx.scene.paint.Stop;
import javafx.scene.shape.ClosePath;
import javafx.scene.shape.CubicCurveTo;
import javafx.scene.shape.FillRule;
import javafx.scene.shape.LineTo;
import javafx.scene.shape.MoveTo;
import javafx.scene.shape.Path;
import javafx.scene.shape.Rectangle;
import javafx.scene.text.Font;
import javafx.scene.text.Text;
import javafx.scene.text.TextAlignment;


/**
 * Created by hansolo on 28.01.16.
 */
public class LcdClockSkin extends ClockSkinBase {
    private static final double     PREFERRED_WIDTH    = 220;//190;
    private static final double     PREFERRED_HEIGHT   = 100;
    private static final Color      DARK_NOISE_COLOR   = Color.rgb(100, 100, 100, 0.10);
    private static final Color      BRIGHT_NOISE_COLOR = Color.rgb(200, 200, 200, 0.05);
    private static final DropShadow FOREGROUND_SHADOW  = new DropShadow();
    private static final double     ASPECT_RATIO       = 0.52631579;
    private double                  width;
    private double                  height;
    private Pane                    pane;
    private Paint                   lcdPaint;
    private Paint                   lcdFramePaint;
    private ImageView               crystalOverlay;
    private Image                   crystalImage;
    private Rectangle               crystalClip;
    private InnerShadow             mainInnerShadow0;
    private InnerShadow             mainInnerShadow1;
    private Text                    timeText;
    private Text                    backgroundTimeText;
    private Text                    secondText;
    private Text                    backgroundSecondText;
    private Text                    title;
    private Text                    dateText;
    private Text                    dayOfWeekText;
    private Path                    alarm;
    private DateTimeFormatter       dateFormat;
    private double                  digitalFontSizeFactor;
    private Font                    timeFont;
    private Font                    secondFont;
    private Font                    titleFont;
    private Font                    smallFont;
    private StringBuilder           backgroundTextBuilder;
    private Group                   shadowGroup;


    // ******************** Constructors **************************************
    public LcdClockSkin(Clock clock) {
        super(clock);
        digitalFontSizeFactor = 1.0;
        backgroundTextBuilder = new StringBuilder();
        FOREGROUND_SHADOW.setOffsetX(0);
        FOREGROUND_SHADOW.setOffsetY(1);
        FOREGROUND_SHADOW.setColor(Color.rgb(0, 0, 0, 0.5));
        FOREGROUND_SHADOW.setBlurType(BlurType.TWO_PASS_BOX);
        FOREGROUND_SHADOW.setRadius(2);
        adjustDateFormat();
        initGraphics();
        registerListeners();
    }


    // ******************** Initialization ************************************
    @Override protected void initGraphics() {
        // Set initial size
        if (Double.compare(clock.getPrefWidth(), 0.0) <= 0 || Double.compare(clock.getPrefHeight(), 0.0) <= 0 ||
            Double.compare(clock.getWidth(), 0.0) <= 0 || Double.compare(clock.getHeight(), 0.0) <= 0) {
            if (clock.getPrefWidth() > 0 && clock.getPrefHeight() > 0) {
                clock.setPrefSize(clock.getPrefWidth(), clock.getPrefHeight());
            } else {
                clock.setPrefSize(PREFERRED_WIDTH, PREFERRED_HEIGHT);
            }
        }

        mainInnerShadow0 = new InnerShadow();
        mainInnerShadow0.setOffsetX(0.0);
        mainInnerShadow0.setOffsetY(0.0);
        mainInnerShadow0.setRadius(3.0 / 132.0 * PREFERRED_WIDTH);
        mainInnerShadow0.setColor(Color.rgb(255, 255, 255, 0.5));
        mainInnerShadow0.setBlurType(BlurType.TWO_PASS_BOX);

        mainInnerShadow1 = new InnerShadow();
        mainInnerShadow1.setOffsetX(0.0);
        mainInnerShadow1.setOffsetY(1.0);
        mainInnerShadow1.setRadius(2.0 / 132.0 * PREFERRED_WIDTH);
        mainInnerShadow1.setColor(Color.rgb(0, 0, 0, 0.65));
        mainInnerShadow1.setBlurType(BlurType.TWO_PASS_BOX);
        mainInnerShadow1.setInput(mainInnerShadow0);

        crystalClip = new Rectangle(0, 0, PREFERRED_WIDTH, PREFERRED_HEIGHT);
        crystalClip.setArcWidth(5);
        crystalClip.setArcHeight(5);

        crystalImage   = Helper.createNoiseImage(PREFERRED_WIDTH, PREFERRED_HEIGHT, DARK_NOISE_COLOR, BRIGHT_NOISE_COLOR, 8);
        crystalOverlay = new ImageView(crystalImage);
        crystalOverlay.setClip(crystalClip);
        boolean crystalEnabled = clock.isLcdCrystalEnabled();
        crystalOverlay.setManaged(crystalEnabled);
        crystalOverlay.setVisible(crystalEnabled);

        boolean secondsVisible = clock.isSecondsVisible();

        backgroundTimeText = new Text("");
        backgroundTimeText.setFill(clock.getLcdDesign().lcdBackgroundColor);
        backgroundTimeText.setOpacity((LcdFont.LCD == clock.getLcdFont() || LcdFont.ELEKTRA == clock.getLcdFont()) ? 1 : 0);

        backgroundSecondText = new Text("");
        backgroundSecondText.setFill(clock.getLcdDesign().lcdBackgroundColor);
        backgroundSecondText.setOpacity((LcdFont.LCD == clock.getLcdFont() || LcdFont.ELEKTRA == clock.getLcdFont()) ? 1 : 0);
        backgroundSecondText.setManaged(secondsVisible);
        backgroundSecondText.setVisible(secondsVisible);

        timeText = new Text("");
        timeText.setFill(clock.getLcdDesign().lcdForegroundColor);

        secondText = new Text("");
        secondText.setFill(clock.getLcdDesign().lcdForegroundColor);
        secondText.setManaged(secondsVisible);
        secondText.setVisible(secondsVisible);

        title = new Text(clock.getTitle());
        title.setFill(clock.getLcdDesign().lcdForegroundColor);
        boolean titleVisible = clock.isTitleVisible();
        title.setManaged(titleVisible);
        title.setVisible(titleVisible);

        dateText = new Text(dateFormat.format(clock.getTime()));
        dateText.setFill(clock.getLcdDesign().lcdForegroundColor);
        boolean dateVisible = clock.isDateVisible();
        dateText.setManaged(dateVisible);
        dateText.setVisible(dateVisible);

        dayOfWeekText = new Text("");
        dayOfWeekText.setFill(clock.getLcdDesign().lcdForegroundColor);
        dayOfWeekText.setManaged(dateVisible);
        dayOfWeekText.setVisible(dateVisible);

        alarm = new Path();
        alarm.setFillRule(FillRule.EVEN_ODD);
        alarm.setStroke(null);
        boolean alarmVisible = clock.getAlarms().size() > 0;
        alarm.setManaged(alarmVisible);
        alarm.setVisible(alarmVisible);

        shadowGroup = new Group();
        shadowGroup.setEffect(clock.getShadowsEnabled() ? FOREGROUND_SHADOW : null);
        shadowGroup.getChildren().setAll(timeText,
                                         secondText,
                                         title,
                                         dateText,
                                         dayOfWeekText,
                                         alarm);

        pane = new Pane();
        pane.setEffect(clock.getShadowsEnabled() ? mainInnerShadow1 : null);
        pane.getChildren().setAll(crystalOverlay,
                                  backgroundTimeText,
                                  backgroundSecondText,
                                  shadowGroup);
        getChildren().setAll(pane);
    }

    @Override protected void registerListeners() {
        super.registerListeners();
    }


    // ******************** Methods *******************************************
    protected void handleEvents(final String EVENT_TYPE) {
        if ("REDRAW".equals(EVENT_TYPE)) {
            pane.setEffect(clock.getShadowsEnabled() ? mainInnerShadow1 : null);
            shadowGroup.setEffect(clock.getShadowsEnabled() ? FOREGROUND_SHADOW : null);
            updateLcdDesign(height);
            redraw();
        } else if ("RESIZE".equals(EVENT_TYPE)) {
            resize();
            redraw();
        } else if ("LCD".equals(EVENT_TYPE)) {
            updateLcdDesign(height);
        } else if ("VISIBILITY".equals(EVENT_TYPE)) {
            boolean crystalEnable = clock.isLcdCrystalEnabled();
            crystalOverlay.setManaged(crystalEnable);
            crystalOverlay.setVisible(crystalEnable);
            boolean secondsVisible = clock.isSecondsVisible();
            backgroundSecondText.setManaged(secondsVisible);
            backgroundSecondText.setVisible(secondsVisible);
            secondText.setManaged(secondsVisible);
            secondText.setVisible(secondsVisible);
            boolean dateVisible = clock.isDateVisible();
            dateText.setManaged(dateVisible);
            dateText.setVisible(dateVisible);
            dayOfWeekText.setManaged(dateVisible);
            dayOfWeekText.setVisible(dateVisible);
            boolean titleVisible = clock.isTitleVisible();
            title.setManaged(titleVisible);
            title.setVisible(titleVisible);
            boolean alarmVisible = clock.getAlarms().size() > 0;
            alarm.setManaged(alarmVisible);
            alarm.setVisible(alarmVisible);
            resize();
            redraw();
        } else if ("RECALC".equals(EVENT_TYPE)) {
            adjustDateFormat();
            redraw();
        }
    }


    // ******************** Private Methods ***********************************
    private String ensureTwoDigits(final int NUMBER) {
        if (NUMBER < 10) return "0" + NUMBER;
        return Integer.toString(NUMBER);
    }

    private void updateLcdDesign(final double HEIGHT) {
        LcdDesign lcdDesign = clock.getLcdDesign();
        Color[]   lcdColors = lcdDesign.getColors();

        lcdPaint = new LinearGradient(0, 1, 0, HEIGHT - 1,
                                      false, CycleMethod.NO_CYCLE,
                                      new Stop(0, lcdColors[0]),
                                      new Stop(0.03, lcdColors[1]),
                                      new Stop(0.5, lcdColors[2]),
                                      new Stop(0.5, lcdColors[3]),
                                      new Stop(1.0, lcdColors[4]));
        if (lcdDesign.name().startsWith("FLAT")) {
            lcdFramePaint = clock.getBorderPaint();

            lcdPaint      = clock.getBackgroundPaint();

            Color lcdForegroundColor = (Color) clock.getForegroundPaint();
            backgroundTimeText.setFill(Color.color(lcdForegroundColor.getRed(), lcdForegroundColor.getGreen(), lcdForegroundColor.getBlue(), 0.1));
            backgroundSecondText.setFill(Color.color(lcdForegroundColor.getRed(), lcdForegroundColor.getGreen(), lcdForegroundColor.getBlue(), 0.1));
            timeText.setFill(lcdForegroundColor);
            secondText.setFill(lcdForegroundColor);
            title.setFill(lcdForegroundColor);
            dateText.setFill(lcdForegroundColor);
            dayOfWeekText.setFill(lcdForegroundColor);
            alarm.setFill(lcdForegroundColor);
        } else {
            lcdFramePaint = new LinearGradient(0, 0.02083333 * height, 0, HEIGHT - 0.02083333 * HEIGHT,
                                               false, CycleMethod.NO_CYCLE,
                                               new Stop(0.0, Color.rgb(26, 26, 26)),
                                               new Stop(0.015, Color.rgb(77, 77, 77)),
                                               new Stop(0.985, Color.rgb(77, 77, 77)),
                                               new Stop(1.0, Color.rgb(221, 221, 221)));

            lcdPaint = new LinearGradient(0, 1, 0, HEIGHT - 1,
                                          false, CycleMethod.NO_CYCLE,
                                          new Stop(0, lcdColors[0]),
                                          new Stop(0.03, lcdColors[1]),
                                          new Stop(0.5, lcdColors[2]),
                                          new Stop(0.5, lcdColors[3]),
                                          new Stop(1.0, lcdColors[4]));

            backgroundTimeText.setFill(lcdDesign.lcdBackgroundColor);
            backgroundSecondText.setFill(lcdDesign.lcdBackgroundColor);
            timeText.setFill(lcdDesign.lcdForegroundColor);
            secondText.setFill(lcdDesign.lcdForegroundColor);
            title.setFill(lcdDesign.lcdForegroundColor);
            dateText.setFill(lcdDesign.lcdForegroundColor);
            dayOfWeekText.setFill(lcdDesign.lcdForegroundColor);
            alarm.setFill(lcdDesign.lcdForegroundColor);
        }

        pane.setBackground(new Background(new BackgroundFill(lcdPaint, new CornerRadii(0.10416667 * HEIGHT), Insets.EMPTY)));
        pane.setBorder(new Border(new BorderStroke(lcdFramePaint, BorderStrokeStyle.SOLID, new CornerRadii(0.05 * HEIGHT), new BorderWidths(0.02083333 * HEIGHT))));
    }

    private void adjustDateFormat() {
        Locale locale = clock.getLocale();
        if (Locale.US == locale) {
            dateFormat = DateTimeFormatter.ofPattern("MM/dd/YYYY");
        } else if (Locale.CHINA == locale) {
            dateFormat = DateTimeFormatter.ofPattern("YYYY.MM.dd");
        } else {
            dateFormat = DateTimeFormatter.ofPattern("dd.MM.YYYY");
        }
    }

    private void updateFonts() {
        digitalFontSizeFactor = 1.0;
        switch(clock.getLcdFont()) {
            case LCD:
                digitalFontSizeFactor = 1.05;
                timeFont   = Fonts.digital(0.675 * height);
                secondFont = Fonts.digital(0.2 * height);
                break;
            case DIGITAL:
                digitalFontSizeFactor = 0.7;
                timeFont   = Fonts.digitalReadout(0.7 * height);
                secondFont = Fonts.digitalReadout(0.2 * height);
                break;
            case DIGITAL_BOLD:
                digitalFontSizeFactor = 0.7;
                timeFont   = Fonts.digitalReadoutBold(0.7 * height);
                secondFont = Fonts.digitalReadoutBold(0.2 * height);
                break;
            case ELEKTRA:
                digitalFontSizeFactor = 0.8;
                timeFont   = Fonts.elektra(0.7 * height);
                secondFont = Fonts.elektra(0.186 * height);
                break;
            case STANDARD:
            default:
                digitalFontSizeFactor = 0.7;
                timeFont   = Fonts.robotoMedium(0.6 * height);
                secondFont = Fonts.robotoMedium(0.2 * height);
                break;
        }

        backgroundTimeText.setFont(timeFont);
        backgroundTimeText.setOpacity((LcdFont.LCD == clock.getLcdFont() ||
                                       LcdFont.DIGITAL == clock.getLcdFont() ||
                                       LcdFont.DIGITAL_BOLD == clock.getLcdFont() ||
                                       LcdFont.ELEKTRA == clock.getLcdFont()) ? 1 : 0);

        backgroundSecondText.setFont(secondFont);
        backgroundSecondText.setOpacity((LcdFont.LCD == clock.getLcdFont() ||
                                         LcdFont.DIGITAL == clock.getLcdFont() ||
                                         LcdFont.DIGITAL_BOLD == clock.getLcdFont() ||
                                         LcdFont.ELEKTRA == clock.getLcdFont()) ? 1 : 0);

        timeText.setFont(timeFont);
        titleFont = Fonts.latoBold(0.16 * height);
        smallFont = Fonts.latoBold(0.12 * height);
    }

    private void updateBackgroundText() {
        // Setup the semitransparent background timeText
        backgroundTimeText.setTextOrigin(VPos.BASELINE);
        backgroundTimeText.setTextAlignment(TextAlignment.RIGHT);

        backgroundSecondText.setTextOrigin(VPos.BASELINE);
        backgroundSecondText.setTextAlignment(TextAlignment.RIGHT);

        // Setup the semitransparent background timeText
        // Width of one time segment
        String backgroundSegment = "_";
        switch(clock.getLcdFont()) {
            case LCD         : backgroundSegment = "8"; break;
            case DIGITAL     :
            case DIGITAL_BOLD:
            case ELEKTRA     : backgroundSegment = "_"; break;
        }

        // Add segments to background timeText
        backgroundTextBuilder.setLength(0);
        backgroundTextBuilder.append(backgroundSegment);
        backgroundTextBuilder.append(backgroundSegment);
        backgroundTextBuilder.append(":");
        backgroundTextBuilder.append(backgroundSegment);
        backgroundTextBuilder.append(backgroundSegment);
        backgroundTimeText.setText(backgroundTextBuilder.toString());
        backgroundSecondText.setText(backgroundSegment + backgroundSegment);
    }

    private void updateTimePosition() {

        double secondsWidth = secondText.getLayoutBounds().getWidth();
        double secodsOffset = height * 0.03;
        double timeWidth    = timeText.getLayoutBounds().getWidth();
        double timeX        = ( clock.isSecondsVisible() )
                            ? ( width - 2 - timeWidth - secodsOffset - secondsWidth ) * 0.5
                            : ( width - 2 - timeWidth ) * 0.5;
        double timeY        = height - timeText.getLayoutBounds().getHeight() * digitalFontSizeFactor * 0.5;
        double secondsX     = timeX + 1 + timeWidth + secodsOffset;

        backgroundTimeText.setX(timeX);
        backgroundTimeText.setY(timeY);
        backgroundSecondText.setX(secondsX);
        backgroundSecondText.setY(timeY);

        timeText.setX(timeX);
        timeText.setY(timeY);
        secondText.setX(secondsX);
        secondText.setY(timeY);

    }

    @Override public void updateTime(final ZonedDateTime TIME) {
        timeText.setText(ensureTwoDigits(TIME.getHour()) + ":" + ensureTwoDigits(TIME.getMinute()));
        secondText.setText(ensureTwoDigits(TIME.getSecond()));

        updateBackgroundText();
        updateTimePosition();

        title.setText(clock.getTitle());
        title.setX((width - title.getLayoutBounds().getWidth()) * 0.5);

        dayOfWeekText.setText(TIME.getDayOfWeek().getDisplayName(TextStyle.FULL_STANDALONE, clock.getLocale()));
        dayOfWeekText.setX(0.0416666667 * height);

        dateText.setText(dateFormat.format(TIME));
        dateText.setX(width - dateText.getLayoutBounds().getWidth() - 0.0416666667 * height);
        dateText.setY(pane.getLayoutBounds().getMinY() + height - 3 - 0.0416666667 * height);
    }

    @Override public void updateAlarms() {}

    private void createAlarmIcon(final boolean ENABLED) {
        double iconSize = 0.16 * height;
        alarm.getElements().clear();
        if (ENABLED) {
            alarm.getElements().add(new MoveTo(0.65625 * iconSize, 0.875 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.6328125 * iconSize, 0.9453125 * iconSize,
                                                    0.5703125 * iconSize, iconSize,
                                                    0.5 * iconSize, iconSize));
            alarm.getElements().add(new CubicCurveTo(0.4296875 * iconSize, iconSize,
                                                    0.3671875 * iconSize, 0.9453125 * iconSize,
                                                    0.34375 * iconSize, 0.875 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.34375 * iconSize, 0.875 * iconSize,
                                                    0.65625 * iconSize, 0.875 * iconSize,
                                                    0.65625 * iconSize, 0.875 * iconSize));
            alarm.getElements().add(new ClosePath());
            alarm.getElements().add(new MoveTo(0.9921875 * iconSize, 0.7578125 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.65625 * iconSize, 0.53125 * iconSize,
                                                    0.90625 * iconSize, 0.0,
                                                    0.5 * iconSize, 0.0));
            alarm.getElements().add(new CubicCurveTo(0.5 * iconSize, 0.0,
                                                    0.5 * iconSize, 0.0,
                                                    0.5 * iconSize, 0.0));
            alarm.getElements().add(new CubicCurveTo(0.5 * iconSize, 0.0,
                                                    0.5 * iconSize, 0.0,
                                                    0.5 * iconSize, 0.0));
            alarm.getElements().add(new CubicCurveTo(0.09375 * iconSize, 0.0,
                                                    0.34375 * iconSize, 0.53125 * iconSize,
                                                    0.0078125 * iconSize, 0.7578125 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.0, 0.765625 * iconSize,
                                                    0.0, 0.7734375 * iconSize,
                                                    0.0, 0.78125 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.0, 0.78125 * iconSize,
                                                    0.0, 0.7890625 * iconSize,
                                                    0.0, 0.7890625 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.0078125 * iconSize, 0.8046875 * iconSize,
                                                    0.015625 * iconSize, 0.8125 * iconSize,
                                                    0.03125 * iconSize, 0.8125 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.03125 * iconSize, 0.8125 * iconSize,
                                                    0.5 * iconSize, 0.8125 * iconSize,
                                                    0.5 * iconSize, 0.8125 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.5 * iconSize, 0.8125 * iconSize,
                                                    0.96875 * iconSize, 0.8125 * iconSize,
                                                    0.96875 * iconSize, 0.8125 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.984375 * iconSize, 0.8125 * iconSize,
                                                    0.9921875 * iconSize, 0.8046875 * iconSize,
                                                    iconSize, 0.7890625 * iconSize));
            alarm.getElements().add(new CubicCurveTo(iconSize, 0.7890625 * iconSize,
                                                    iconSize, 0.78125 * iconSize,
                                                    iconSize, 0.78125 * iconSize));
            alarm.getElements().add(new CubicCurveTo(iconSize, 0.7734375 * iconSize,
                                                    iconSize, 0.765625 * iconSize,
                                                    0.9921875 * iconSize, 0.7578125 * iconSize));
            alarm.getElements().add(new ClosePath());
        } else {
            alarm.getElements().add(new MoveTo(0.0703125 * iconSize, 0.015625 * iconSize));
            alarm.getElements().add(new LineTo(0.015625 * iconSize, 0.0703125 * iconSize));
            alarm.getElements().add(new LineTo(0.9296875 * iconSize, 0.984375 * iconSize));
            alarm.getElements().add(new LineTo(0.984375 * iconSize, 0.9296875 * iconSize));
            alarm.getElements().add(new LineTo(0.0703125 * iconSize, 0.015625 * iconSize));
            alarm.getElements().add(new ClosePath());
            alarm.getElements().add(new MoveTo(0.65625 * iconSize, 0.875 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.65625 * iconSize, 0.875 * iconSize,
                                                    0.34375 * iconSize, 0.875 * iconSize,
                                                    0.34375 * iconSize, 0.875 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.3671875 * iconSize, 0.9453125 * iconSize,
                                                    0.4296875 * iconSize, iconSize,
                                                    0.5 * iconSize, iconSize));
            alarm.getElements().add(new CubicCurveTo(0.5703125 * iconSize, iconSize,
                                                    0.6328125 * iconSize, 0.9453125 * iconSize,
                                                    0.65625 * iconSize, 0.875 * iconSize));
            alarm.getElements().add(new ClosePath());
            alarm.getElements().add(new MoveTo(0.2265625 * iconSize, 0.3125 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.1953125 * iconSize, 0.46875 * iconSize,
                                                    0.171875 * iconSize, 0.6484375 * iconSize,
                                                    0.0078125 * iconSize, 0.7578125 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.0, 0.765625 * iconSize,
                                                    0.0, 0.7734375 * iconSize,
                                                    0.0, 0.78125 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.0, 0.78125 * iconSize,
                                                    0.0, 0.7890625 * iconSize,
                                                    0.0, 0.7890625 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.0078125 * iconSize, 0.8046875 * iconSize,
                                                    0.015625 * iconSize, 0.8125 * iconSize,
                                                    0.03125 * iconSize, 0.8125 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.03125 * iconSize, 0.8125 * iconSize,
                                                    0.5 * iconSize, 0.8125 * iconSize,
                                                    0.5 * iconSize, 0.8125 * iconSize));
            alarm.getElements().add(new LineTo(0.7265625 * iconSize, 0.8125 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.7265625 * iconSize, 0.8125 * iconSize,
                                                    0.2265625 * iconSize, 0.3125 * iconSize,
                                                    0.2265625 * iconSize, 0.3125 * iconSize));
            alarm.getElements().add(new ClosePath());
            alarm.getElements().add(new MoveTo(0.9921875 * iconSize, 0.7578125 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.65625 * iconSize, 0.53125 * iconSize,
                                                    0.90625 * iconSize, 0.0,
                                                    0.5 * iconSize, 0.0));
            alarm.getElements().add(new CubicCurveTo(0.3515625 * iconSize, 0.0,
                                                    0.2890625 * iconSize, 0.0703125 * iconSize,
                                                    0.2578125 * iconSize, 0.171875 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.2578125 * iconSize, 0.171875 * iconSize,
                                                    0.8984375 * iconSize, 0.8125 * iconSize,
                                                    0.8984375 * iconSize, 0.8125 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.8984375 * iconSize, 0.8125 * iconSize,
                                                    0.96875 * iconSize, 0.8125 * iconSize,
                                                    0.96875 * iconSize, 0.8125 * iconSize));
            alarm.getElements().add(new CubicCurveTo(0.984375 * iconSize, 0.8125 * iconSize,
                                                    0.9921875 * iconSize, 0.8046875 * iconSize,
                                                    iconSize, 0.7890625 * iconSize));
            alarm.getElements().add(new CubicCurveTo(iconSize, 0.7890625 * iconSize,
                                                    iconSize, 0.78125 * iconSize,
                                                    iconSize, 0.78125 * iconSize));
            alarm.getElements().add(new CubicCurveTo(iconSize, 0.7734375 * iconSize,
                                                    iconSize, 0.765625 * iconSize,
                                                    0.9921875 * iconSize, 0.7578125 * iconSize));
            alarm.getElements().add(new ClosePath());
        }
    }

    @Override protected void resize() {
        width  = clock.getWidth() - clock.getInsets().getLeft() - clock.getInsets().getRight();
        height = clock.getHeight() - clock.getInsets().getTop() - clock.getInsets().getBottom();

        if (ASPECT_RATIO * width > height) {
            width = 1 / (ASPECT_RATIO / height);
        } else if (1 / (ASPECT_RATIO / height) > width) {
            height = ASPECT_RATIO * width;
        }

        if (width > 0 && height > 0) {
            pane.setMaxSize(width, height);
            pane.relocate((clock.getWidth() - width) * 0.5, (clock.getHeight() - height) * 0.5);

            updateLcdDesign(height);

            mainInnerShadow0.setRadius(0.0625 * height);
            mainInnerShadow1.setRadius(0.04166667 * height);

            ZonedDateTime time = clock.getTime();

            if (crystalOverlay.isVisible()) {
                crystalClip.setWidth(width);
                crystalClip.setHeight(height);
                crystalOverlay.setImage(Helper.createNoiseImage(width, height, DARK_NOISE_COLOR, BRIGHT_NOISE_COLOR, 8));
                crystalOverlay.setCache(true);
            }

            updateFonts();

            updateBackgroundText();
            updateTimePosition();

            secondText.setFont(secondFont);
            secondText.setTextOrigin(VPos.BASELINE);
            secondText.setTextAlignment(TextAlignment.RIGHT);

            // Setup the font for the lcd title, number system, min measured, max measure and former value
            // Title
            title.setFont(titleFont);
            title.setTextOrigin(VPos.BASELINE);
            title.setTextAlignment(TextAlignment.CENTER);
            title.setText(time.getDayOfWeek().name());
            title.setX((width - title.getLayoutBounds().getWidth()) * 0.5);
            title.setY(pane.getLayoutBounds().getMinY() + title.getLayoutBounds().getHeight() - 0.04 * height + 2);

            // Date
            dateText.setFont(smallFont);
            dateText.setTextOrigin(VPos.BASELINE);
            dateText.setTextAlignment(TextAlignment.RIGHT);
            dateText.setText(dateFormat.format(time));
            dateText.setX(width - dateText.getLayoutBounds().getWidth() - 0.0416666667 * height);
            dateText.setY(pane.getLayoutBounds().getMinY() + height - 3 - 0.0416666667 * height);

            // Day of week
            dayOfWeekText.setFont(smallFont);
            dayOfWeekText.setTextOrigin(VPos.BASELINE);
            dayOfWeekText.setTextAlignment(TextAlignment.LEFT);
            dayOfWeekText.setX(0.0416666667 * height);
            dayOfWeekText.setY(pane.getLayoutBounds().getMinY() + height - 3 - 0.0416666667 * height);
        }
    }

    @Override protected void redraw() {
        updateBackgroundText();
        updateTimePosition();

        ZonedDateTime time = clock.getTime();
        timeText.setText(ensureTwoDigits(time.getHour()) + ":" + ensureTwoDigits(time.getMinute()));
        secondText.setText(ensureTwoDigits(time.getSecond()));

        title.setText(clock.getTitle());
        title.setX((width - title.getLayoutBounds().getWidth()) * 0.5);

        dateText.setText(dateFormat.format(time));
        dateText.setX(width - dateText.getLayoutBounds().getWidth() - 0.0416666667 * height);
        dateText.setY(pane.getLayoutBounds().getMinY() + height - 3 - 0.0416666667 * height);

        dayOfWeekText.setText(time.getDayOfWeek().getDisplayName(TextStyle.FULL_STANDALONE, clock.getLocale()));
        dayOfWeekText.setX(0.0416666667 * height);
        dayOfWeekText.setY(pane.getLayoutBounds().getMinY() + height - 3 - 0.0416666667 * height);

        createAlarmIcon(clock.isAlarmsEnabled());
        alarm.relocate(width * 0.885, height * 0.28);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy