├── .github
└── workflows
│ └── ci.yml
├── .gitignore
├── LICENSE
├── Overview.png
├── README.md
├── build.gradle
├── contributors.txt
├── gradle.properties
├── gradle
├── LICENSE_HEADER
└── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── images
├── AmpSkin.png
├── BarSkin.png
├── BatterySkin.png
├── BulletChartSkin.png
├── ChargeSkin.png
├── ClockSkin.png
├── DBClockSkin.png
├── DashboardSkin.png
├── DesignClockSkin.png
├── DigitalClockSkin.png
├── DigitalSkin.png
├── FatClockSkin.png
├── FlatSkin.png
├── GaugeDescription.png
├── GaugeSkin.png
├── HSkin.png
├── IndicatorSkin.png
├── IndustrialClockSkin.png
├── KpiSkin.png
├── LcdClockSkin.png
├── LcdSkin.png
├── LevelSkin.png
├── LinearSkin.png
├── MedusaJS_Overview.png
├── Medusa_0.fw.png
├── MinimalClockSkin.png
├── ModernSkin.png
├── Overview.png
├── PearClockSkin.png
├── PlainClockSkin.png
├── QuarterSkin.png
├── RoundLcdClockSkin.png
├── SectionSkin.png
├── SimpleDigitalSkin.png
├── SimpleSectionSkin.png
├── SimpleSkin.png
├── SlimClockSkin.png
├── SlimSkin.png
├── SpaceXSkin.png
├── TextClockSkin.png
├── TileClockSkin.png
├── TileKpiSkin.png
├── TileSparklineSkin.png
├── TileTextKpiSkin.png
├── TinySkin.png
├── VSkin.png
├── WhiteSkin.png
└── Yota2ClockSkin.png
├── license.txt
├── settings.gradle
└── src
└── main
├── java
├── eu
│ └── hansolo
│ │ └── medusa
│ │ ├── Alarm.java
│ │ ├── AlarmBuilder.java
│ │ ├── Clock.java
│ │ ├── ClockBuilder.java
│ │ ├── Command.java
│ │ ├── Demo.java
│ │ ├── DemoLauncher.java
│ │ ├── FGauge.java
│ │ ├── FGaugeBuilder.java
│ │ ├── Fonts.java
│ │ ├── Gauge.java
│ │ ├── GaugeBuilder.java
│ │ ├── GaugeDesign.java
│ │ ├── LcdDesign.java
│ │ ├── LcdFont.java
│ │ ├── Marker.java
│ │ ├── MarkerBuilder.java
│ │ ├── Needle.java
│ │ ├── Section.java
│ │ ├── SectionBuilder.java
│ │ ├── Test.java
│ │ ├── TestLauncher.java
│ │ ├── TickLabelLocation.java
│ │ ├── TickLabelOrientation.java
│ │ ├── TickMarkType.java
│ │ ├── TimeSection.java
│ │ ├── TimeSectionBuilder.java
│ │ ├── events
│ │ ├── AlarmEvent.java
│ │ ├── AlarmEventListener.java
│ │ ├── TimeEvent.java
│ │ ├── TimeEventListener.java
│ │ ├── UpdateEvent.java
│ │ └── UpdateEventListener.java
│ │ ├── skins
│ │ ├── AmpSkin.java
│ │ ├── BarSkin.java
│ │ ├── BatterySkin.java
│ │ ├── BulletChartSkin.java
│ │ ├── ChargeSkin.java
│ │ ├── ClockSkin.java
│ │ ├── ClockSkinBase.java
│ │ ├── DBClockSkin.java
│ │ ├── DashboardSkin.java
│ │ ├── DesignClockSkin.java
│ │ ├── DigitalClockSkin.java
│ │ ├── DigitalSkin.java
│ │ ├── FatClockSkin.java
│ │ ├── FlatSkin.java
│ │ ├── GaugeSkin.java
│ │ ├── GaugeSkinBase.java
│ │ ├── HSkin.java
│ │ ├── IndicatorSkin.java
│ │ ├── IndustrialClockSkin.java
│ │ ├── KpiSkin.java
│ │ ├── LcdClockSkin.java
│ │ ├── LcdSkin.java
│ │ ├── LevelSkin.java
│ │ ├── LinearSkin.java
│ │ ├── MinimalClockSkin.java
│ │ ├── ModernSkin.java
│ │ ├── MorphingClockSkin.java
│ │ ├── NasaSkin.java
│ │ ├── PearClockSkin.java
│ │ ├── PlainAmpSkin.java
│ │ ├── PlainClockSkin.java
│ │ ├── QuarterSkin.java
│ │ ├── RoundLcdClockSkin.java
│ │ ├── SectionSkin.java
│ │ ├── SimpleDigitalSkin.java
│ │ ├── SimpleSectionSkin.java
│ │ ├── SimpleSkin.java
│ │ ├── SlimClockSkin.java
│ │ ├── SlimSkin.java
│ │ ├── SpaceXSkin.java
│ │ ├── TextClockSkin.java
│ │ ├── TileClockSkin.java
│ │ ├── TileKpiSkin.java
│ │ ├── TileSparklineSkin.java
│ │ ├── TileTextKpiSkin.java
│ │ ├── TinySkin.java
│ │ ├── VSkin.java
│ │ └── WhiteSkin.java
│ │ └── tools
│ │ ├── AngleConicalGradient.java
│ │ ├── ConicalGradient.java
│ │ ├── Data.java
│ │ ├── GradientLookup.java
│ │ ├── Helper.java
│ │ ├── MarkerComparator.java
│ │ ├── MovingAverage.java
│ │ ├── SectionComparator.java
│ │ ├── Statistics.java
│ │ └── TimeSectionComparator.java
└── module-info.java
└── resources
└── eu
└── hansolo
└── medusa
├── Estricta-Medium.otf
├── Estricta-MediumItalic.otf
├── Estricta-Regular.otf
├── Estricta-RegularItalic.otf
├── Lato-Bol.otf
├── Lato-Lig.otf
├── Lato-Reg.otf
├── Roboto-Bold.ttf
├── Roboto-Light.ttf
├── Roboto-Medium.ttf
├── Roboto-Regular.ttf
├── Roboto-Thin.ttf
├── RobotoCondensed-Bold.ttf
├── RobotoCondensed-Light.ttf
├── RobotoCondensed-Regular.ttf
├── clock.css
├── digital.ttf
├── digitalreadout.ttf
├── digitalreadoutb.ttf
├── elektra.ttf
├── framed-gauge.css
└── gauge.css
/.github/workflows/ci.yml:
--------------------------------------------------------------------------------
1 | ---
2 | name: Java CI
3 |
4 | on: [push]
5 |
6 | jobs:
7 | test:
8 | runs-on: ${{ matrix.os }}
9 | strategy:
10 | matrix:
11 | os: [ubuntu-18.04, macOS-latest, windows-latest]
12 | java: [11, 11.0.3]
13 | fail-fast: false
14 | max-parallel: 4
15 | name: Test JDK ${{ matrix.java }}, ${{ matrix.os }}
16 |
17 | steps:
18 | - uses: actions/checkout@v1
19 | - name: Set up JDK
20 | uses: actions/setup-java@v1
21 | with:
22 | java-version: ${{ matrix.java }}
23 | - name: Build with Gradle
24 | run: ./gradlew build
25 |
26 | ...
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .idea
2 | medusa.iml
3 | build
4 | logos
5 | signing.properties
6 | cache.properties.lock
7 | fileHashes.bin
8 | fileSnapshots.bin
9 | outputFileStates.bin
10 | taskArtifacts.bin
11 | otherResources
12 | ._*
13 | .gradle
14 | .DS_Store
15 | /out
16 | /.nb-gradle/
17 | /src/main/java/eu/hansolo/medusa/MedusaTest.java
18 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "{}"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright {yyyy} {name of copyright owner}
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/Overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/Overview.png
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | ## Medusa
2 |
3 |
4 | A JavaFX library for Gauges. The main focus of this project is to provide Gauges that can be configured in multiple ways.
5 |
6 | Donations are welcome at [Paypal](https://paypal.me/hans0l0)
7 |
8 | ## Overview
9 | 
10 |
--------------------------------------------------------------------------------
/build.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 |
19 |
20 | /*
21 | * SPDX-License-Identifier: Apache-2.0
22 | *
23 | * Copyright 2016-2020 Gerrit Grunwald.
24 | *
25 | * Licensed under the Apache License, Version 2.0 (the "License");
26 | * you may not use this file except in compliance with the License.
27 | * You may obtain a copy of the License at
28 | *
29 | * https://www.apache.org/licenses/LICENSE-2.0
30 | *
31 | * Unless required by applicable law or agreed to in writing, software
32 | * distributed under the License is distributed on an "AS IS" BASIS,
33 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
34 | * See the License for the specific language governing permissions and
35 | * limitations under the License.
36 | */
37 |
38 | // Medusa main build file
39 | plugins {
40 | id 'idea'
41 | id 'java-library'
42 | id 'org.kordamp.gradle.java-project'
43 | id 'org.openjfx.javafxplugin'
44 | id 'biz.aQute.bnd.builder'
45 | }
46 |
47 |
48 | if (!project.hasProperty('bintrayUsername')) ext.bintrayUsername = '**undefined**'
49 | if (!project.hasProperty('bintrayApiKey')) ext.bintrayApiKey = '**undefined**'
50 | if (!project.hasProperty('sonatypeUsername')) ext.sonatypeUsername = '**undefined**'
51 | if (!project.hasProperty('sonatypePassword')) ext.sonatypePassword = '**undefined**'
52 |
53 | config {
54 | release = (rootProject.findProperty('release') ?: false).toBoolean()
55 |
56 | info {
57 | name = 'Medusa'
58 | description = 'Medusa is a JavaFX library containing gauges and clocks'
59 | vendor = 'Hansolo'
60 | inceptionYear = '2016'
61 | tags = ['javafx', 'gauges', 'clocks']
62 |
63 | links {
64 | website = 'https://github.com/HanSolo/Medusax/wiki'
65 | issueTracker = 'https://github.com/HanSolo/Medusa/issues'
66 | scm = 'https://github.com/HanSolo/Medusa.git'
67 | }
68 |
69 | people {
70 | person {
71 | id = 'HanSolo'
72 | name = 'Gerrit Grunwald'
73 | url = 'https://harmoniccode.blogspot.com/'
74 | roles = ['developer']
75 | }
76 | }
77 |
78 | credentials {
79 | sonatype {
80 | username = project.sonatypeUsername
81 | password = project.sonatypePassword
82 | }
83 | }
84 |
85 | repositories {
86 | repository {
87 | name = 'localRelease'
88 | url = "${project.rootProject.buildDir}/repos/local/release"
89 | }
90 | repository {
91 | name = 'localSnapshot'
92 | url = "${project.rootProject.buildDir}/repos/local/snapshot"
93 | }
94 | }
95 | }
96 |
97 | licensing {
98 | licenses {
99 | license {
100 | id = 'Apache-2.0'
101 | }
102 | }
103 | }
104 |
105 | bintray {
106 | enabled = true
107 | userOrg = 'hansolo'
108 | repo = 'Medusa'
109 | name = rootProject.name
110 | publish = config.release
111 | credentials {
112 | username = project.bintrayUsername
113 | password = project.bintrayApiKey
114 | }
115 | }
116 |
117 | publishing {
118 | signing = false
119 | releasesRepository = 'localRelease'
120 | snapshotsRepository = 'localSnapshot'
121 | }
122 |
123 | docs {
124 | javadoc {
125 | autoLinks {
126 | enabled = false
127 | }
128 | }
129 | }
130 | }
131 |
132 | normalization {
133 | runtimeClasspath {
134 | ignore('/META-INF/MANIFEST.MF')
135 | }
136 | }
137 |
138 | repositories {
139 | jcenter()
140 | mavenCentral()
141 | }
142 |
143 | javafx {
144 | version = javafxVersion
145 | modules = [ 'javafx.base', 'javafx.graphics', 'javafx.controls' ]
146 | }
147 |
148 | jar {
149 | manifest {
150 | attributes(
151 | 'Bundle-Name': project.name,
152 | 'Bundle-License': 'https://www.apache.org/licenses/LICENSE-2.0;description=Apache License Version 2.0;link=https://spdx.org/licenses/Apache-2.0.html',
153 | 'Bundle-Description': config.info.description,
154 | 'Bundle-SymbolicName': 'eu.hansolo',
155 | 'Export-Package': 'eu.hansolo.medusa,eu.hansolo.medusa.tools,eu.hansolo.medusa.skins,eu.hansolo.medusa.events'
156 | )
157 | }
158 | }
159 |
160 | // start the demo from gradle
161 | task Demo(type: JavaExec) {
162 | main = "eu.hansolo.medusa.DemoLauncher"
163 | classpath = sourceSets.main.runtimeClasspath
164 | }
165 |
166 | // Only used for internal test
167 | task Test(type: JavaExec) {
168 | main = "eu.hansolo.medusa.TestLauncher"
169 | classpath = sourceSets.main.runtimeClasspath
170 | }
171 |
172 | publishing {
173 | publications {
174 | main(MavenPublication) {
175 | pom.withXml {
176 | asNode().dependencies.'*'.findAll {
177 | it.groupId.text() == 'org.openjfx'
178 | }.each {
179 | it.remove(it.classifier)
180 | }
181 | }
182 | }
183 | }
184 | }
185 |
--------------------------------------------------------------------------------
/contributors.txt:
--------------------------------------------------------------------------------
1 | Gerrit Grunwald (han.solo.gg@gmail.com)
2 |
--------------------------------------------------------------------------------
/gradle.properties:
--------------------------------------------------------------------------------
1 | #
2 | # SPDX-License-Identifier: Apache-2.0
3 | #
4 | # Copyright 2016-2021 Gerrit Grunwald.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | sourceCompatibility = 11
20 | targetCompatibility = 11
21 |
22 | group = eu.hansolo
23 | version = 11.7
24 | javafxVersion = 11.0.1
--------------------------------------------------------------------------------
/gradle/LICENSE_HEADER:
--------------------------------------------------------------------------------
1 | SPDX-License-Identifier: Apache-2.0
2 |
3 | Copyright ${copyrightYear} ${author}.
4 |
5 | Licensed under the Apache License, Version 2.0 (the "License");
6 | you may not use this file except in compliance with the License.
7 | You may obtain a copy of the License at
8 |
9 | https://www.apache.org/licenses/LICENSE-2.0
10 |
11 | Unless required by applicable law or agreed to in writing, software
12 | distributed under the License is distributed on an "AS IS" BASIS,
13 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 | See the License for the specific language governing permissions and
15 | limitations under the License.
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/gradle/wrapper/gradle-wrapper.jar
--------------------------------------------------------------------------------
/gradle/wrapper/gradle-wrapper.properties:
--------------------------------------------------------------------------------
1 | #
2 | # SPDX-License-Identifier: Apache-2.0
3 | #
4 | # Copyright 2016-2020 Gerrit Grunwald.
5 | #
6 | # Licensed under the Apache License, Version 2.0 (the "License");
7 | # you may not use this file except in compliance with the License.
8 | # You may obtain a copy of the License at
9 | #
10 | # https://www.apache.org/licenses/LICENSE-2.0
11 | #
12 | # Unless required by applicable law or agreed to in writing, software
13 | # distributed under the License is distributed on an "AS IS" BASIS,
14 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | # See the License for the specific language governing permissions and
16 | # limitations under the License.
17 | #
18 |
19 | #Thu Dec 17 09:21:18 CET 2015
20 | distributionBase=GRADLE_USER_HOME
21 | distributionPath=wrapper/dists
22 | distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-bin.zip
23 | zipStoreBase=GRADLE_USER_HOME
24 | zipStorePath=wrapper/dists
25 |
--------------------------------------------------------------------------------
/gradlew:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | ##############################################################################
4 | ##
5 | ## Gradle start up script for UN*X
6 | ##
7 | ##############################################################################
8 |
9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
10 | DEFAULT_JVM_OPTS=""
11 |
12 | APP_NAME="Gradle"
13 | APP_BASE_NAME=`basename "$0"`
14 |
15 | # Use the maximum available, or set MAX_FD != -1 to use that value.
16 | MAX_FD="maximum"
17 |
18 | warn ( ) {
19 | echo "$*"
20 | }
21 |
22 | die ( ) {
23 | echo
24 | echo "$*"
25 | echo
26 | exit 1
27 | }
28 |
29 | # OS specific support (must be 'true' or 'false').
30 | cygwin=false
31 | msys=false
32 | darwin=false
33 | case "`uname`" in
34 | CYGWIN* )
35 | cygwin=true
36 | ;;
37 | Darwin* )
38 | darwin=true
39 | ;;
40 | MINGW* )
41 | msys=true
42 | ;;
43 | esac
44 |
45 | # For Cygwin, ensure paths are in UNIX format before anything is touched.
46 | if $cygwin ; then
47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
48 | fi
49 |
50 | # Attempt to set APP_HOME
51 | # Resolve links: $0 may be a link
52 | PRG="$0"
53 | # Need this for relative symlinks.
54 | while [ -h "$PRG" ] ; do
55 | ls=`ls -ld "$PRG"`
56 | link=`expr "$ls" : '.*-> \(.*\)$'`
57 | if expr "$link" : '/.*' > /dev/null; then
58 | PRG="$link"
59 | else
60 | PRG=`dirname "$PRG"`"/$link"
61 | fi
62 | done
63 | SAVED="`pwd`"
64 | cd "`dirname \"$PRG\"`/" >&-
65 | APP_HOME="`pwd -P`"
66 | cd "$SAVED" >&-
67 |
68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
69 |
70 | # Determine the Java command to use to start the JVM.
71 | if [ -n "$JAVA_HOME" ] ; then
72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
73 | # IBM's JDK on AIX uses strange locations for the executables
74 | JAVACMD="$JAVA_HOME/jre/sh/java"
75 | else
76 | JAVACMD="$JAVA_HOME/bin/java"
77 | fi
78 | if [ ! -x "$JAVACMD" ] ; then
79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
80 |
81 | Please set the JAVA_HOME variable in your environment to match the
82 | location of your Java installation."
83 | fi
84 | else
85 | JAVACMD="java"
86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
87 |
88 | Please set the JAVA_HOME variable in your environment to match the
89 | location of your Java installation."
90 | fi
91 |
92 | # Increase the maximum file descriptors if we can.
93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
94 | MAX_FD_LIMIT=`ulimit -H -n`
95 | if [ $? -eq 0 ] ; then
96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
97 | MAX_FD="$MAX_FD_LIMIT"
98 | fi
99 | ulimit -n $MAX_FD
100 | if [ $? -ne 0 ] ; then
101 | warn "Could not set maximum file descriptor limit: $MAX_FD"
102 | fi
103 | else
104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
105 | fi
106 | fi
107 |
108 | # For Darwin, add options to specify how the application appears in the dock
109 | if $darwin; then
110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
111 | fi
112 |
113 | # For Cygwin, switch paths to Windows format before running java
114 | if $cygwin ; then
115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"`
116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
117 |
118 | # We build the pattern for arguments to be converted via cygpath
119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
120 | SEP=""
121 | for dir in $ROOTDIRSRAW ; do
122 | ROOTDIRS="$ROOTDIRS$SEP$dir"
123 | SEP="|"
124 | done
125 | OURCYGPATTERN="(^($ROOTDIRS))"
126 | # Add a user-defined pattern to the cygpath arguments
127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then
128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
129 | fi
130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh
131 | i=0
132 | for arg in "$@" ; do
133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option
135 |
136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition
137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
138 | else
139 | eval `echo args$i`="\"$arg\""
140 | fi
141 | i=$((i+1))
142 | done
143 | case $i in
144 | (0) set -- ;;
145 | (1) set -- "$args0" ;;
146 | (2) set -- "$args0" "$args1" ;;
147 | (3) set -- "$args0" "$args1" "$args2" ;;
148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
154 | esac
155 | fi
156 |
157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
158 | function splitJvmOpts() {
159 | JVM_OPTS=("$@")
160 | }
161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
163 |
164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
165 |
--------------------------------------------------------------------------------
/gradlew.bat:
--------------------------------------------------------------------------------
1 | @if "%DEBUG%" == "" @echo off
2 | @rem ##########################################################################
3 | @rem
4 | @rem Gradle startup script for Windows
5 | @rem
6 | @rem ##########################################################################
7 |
8 | @rem Set local scope for the variables with windows NT shell
9 | if "%OS%"=="Windows_NT" setlocal
10 |
11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
12 | set DEFAULT_JVM_OPTS=
13 |
14 | set DIRNAME=%~dp0
15 | if "%DIRNAME%" == "" set DIRNAME=.
16 | set APP_BASE_NAME=%~n0
17 | set APP_HOME=%DIRNAME%
18 |
19 | @rem Find java.exe
20 | if defined JAVA_HOME goto findJavaFromJavaHome
21 |
22 | set JAVA_EXE=java.exe
23 | %JAVA_EXE% -version >NUL 2>&1
24 | if "%ERRORLEVEL%" == "0" goto init
25 |
26 | echo.
27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
28 | echo.
29 | echo Please set the JAVA_HOME variable in your environment to match the
30 | echo location of your Java installation.
31 |
32 | goto fail
33 |
34 | :findJavaFromJavaHome
35 | set JAVA_HOME=%JAVA_HOME:"=%
36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe
37 |
38 | if exist "%JAVA_EXE%" goto init
39 |
40 | echo.
41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
42 | echo.
43 | echo Please set the JAVA_HOME variable in your environment to match the
44 | echo location of your Java installation.
45 |
46 | goto fail
47 |
48 | :init
49 | @rem Get command-line arguments, handling Windowz variants
50 |
51 | if not "%OS%" == "Windows_NT" goto win9xME_args
52 | if "%@eval[2+2]" == "4" goto 4NT_args
53 |
54 | :win9xME_args
55 | @rem Slurp the command line arguments.
56 | set CMD_LINE_ARGS=
57 | set _SKIP=2
58 |
59 | :win9xME_args_slurp
60 | if "x%~1" == "x" goto execute
61 |
62 | set CMD_LINE_ARGS=%*
63 | goto execute
64 |
65 | :4NT_args
66 | @rem Get arguments from the 4NT Shell from JP Software
67 | set CMD_LINE_ARGS=%$
68 |
69 | :execute
70 | @rem Setup the command line
71 |
72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
73 |
74 | @rem Execute Gradle
75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
76 |
77 | :end
78 | @rem End local scope for the variables with windows NT shell
79 | if "%ERRORLEVEL%"=="0" goto mainEnd
80 |
81 | :fail
82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of
83 | rem the _cmd.exe /c_ return code!
84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1
85 | exit /b 1
86 |
87 | :mainEnd
88 | if "%OS%"=="Windows_NT" endlocal
89 |
90 | :omega
91 |
--------------------------------------------------------------------------------
/images/AmpSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/AmpSkin.png
--------------------------------------------------------------------------------
/images/BarSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/BarSkin.png
--------------------------------------------------------------------------------
/images/BatterySkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/BatterySkin.png
--------------------------------------------------------------------------------
/images/BulletChartSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/BulletChartSkin.png
--------------------------------------------------------------------------------
/images/ChargeSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/ChargeSkin.png
--------------------------------------------------------------------------------
/images/ClockSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/ClockSkin.png
--------------------------------------------------------------------------------
/images/DBClockSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/DBClockSkin.png
--------------------------------------------------------------------------------
/images/DashboardSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/DashboardSkin.png
--------------------------------------------------------------------------------
/images/DesignClockSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/DesignClockSkin.png
--------------------------------------------------------------------------------
/images/DigitalClockSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/DigitalClockSkin.png
--------------------------------------------------------------------------------
/images/DigitalSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/DigitalSkin.png
--------------------------------------------------------------------------------
/images/FatClockSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/FatClockSkin.png
--------------------------------------------------------------------------------
/images/FlatSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/FlatSkin.png
--------------------------------------------------------------------------------
/images/GaugeDescription.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/GaugeDescription.png
--------------------------------------------------------------------------------
/images/GaugeSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/GaugeSkin.png
--------------------------------------------------------------------------------
/images/HSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/HSkin.png
--------------------------------------------------------------------------------
/images/IndicatorSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/IndicatorSkin.png
--------------------------------------------------------------------------------
/images/IndustrialClockSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/IndustrialClockSkin.png
--------------------------------------------------------------------------------
/images/KpiSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/KpiSkin.png
--------------------------------------------------------------------------------
/images/LcdClockSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/LcdClockSkin.png
--------------------------------------------------------------------------------
/images/LcdSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/LcdSkin.png
--------------------------------------------------------------------------------
/images/LevelSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/LevelSkin.png
--------------------------------------------------------------------------------
/images/LinearSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/LinearSkin.png
--------------------------------------------------------------------------------
/images/MedusaJS_Overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/MedusaJS_Overview.png
--------------------------------------------------------------------------------
/images/Medusa_0.fw.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/Medusa_0.fw.png
--------------------------------------------------------------------------------
/images/MinimalClockSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/MinimalClockSkin.png
--------------------------------------------------------------------------------
/images/ModernSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/ModernSkin.png
--------------------------------------------------------------------------------
/images/Overview.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/Overview.png
--------------------------------------------------------------------------------
/images/PearClockSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/PearClockSkin.png
--------------------------------------------------------------------------------
/images/PlainClockSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/PlainClockSkin.png
--------------------------------------------------------------------------------
/images/QuarterSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/QuarterSkin.png
--------------------------------------------------------------------------------
/images/RoundLcdClockSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/RoundLcdClockSkin.png
--------------------------------------------------------------------------------
/images/SectionSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/SectionSkin.png
--------------------------------------------------------------------------------
/images/SimpleDigitalSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/SimpleDigitalSkin.png
--------------------------------------------------------------------------------
/images/SimpleSectionSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/SimpleSectionSkin.png
--------------------------------------------------------------------------------
/images/SimpleSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/SimpleSkin.png
--------------------------------------------------------------------------------
/images/SlimClockSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/SlimClockSkin.png
--------------------------------------------------------------------------------
/images/SlimSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/SlimSkin.png
--------------------------------------------------------------------------------
/images/SpaceXSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/SpaceXSkin.png
--------------------------------------------------------------------------------
/images/TextClockSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/TextClockSkin.png
--------------------------------------------------------------------------------
/images/TileClockSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/TileClockSkin.png
--------------------------------------------------------------------------------
/images/TileKpiSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/TileKpiSkin.png
--------------------------------------------------------------------------------
/images/TileSparklineSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/TileSparklineSkin.png
--------------------------------------------------------------------------------
/images/TileTextKpiSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/TileTextKpiSkin.png
--------------------------------------------------------------------------------
/images/TinySkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/TinySkin.png
--------------------------------------------------------------------------------
/images/VSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/VSkin.png
--------------------------------------------------------------------------------
/images/WhiteSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/WhiteSkin.png
--------------------------------------------------------------------------------
/images/Yota2ClockSkin.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/images/Yota2ClockSkin.png
--------------------------------------------------------------------------------
/license.txt:
--------------------------------------------------------------------------------
1 |
2 | Apache License
3 | Version 2.0, January 2004
4 | http://www.apache.org/licenses/
5 |
6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
7 |
8 | 1. Definitions.
9 |
10 | "License" shall mean the terms and conditions for use, reproduction,
11 | and distribution as defined by Sections 1 through 9 of this document.
12 |
13 | "Licensor" shall mean the copyright owner or entity authorized by
14 | the copyright owner that is granting the License.
15 |
16 | "Legal Entity" shall mean the union of the acting entity and all
17 | other entities that control, are controlled by, or are under common
18 | control with that entity. For the purposes of this definition,
19 | "control" means (i) the power, direct or indirect, to cause the
20 | direction or management of such entity, whether by contract or
21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
22 | outstanding shares, or (iii) beneficial ownership of such entity.
23 |
24 | "You" (or "Your") shall mean an individual or Legal Entity
25 | exercising permissions granted by this License.
26 |
27 | "Source" form shall mean the preferred form for making modifications,
28 | including but not limited to software source code, documentation
29 | source, and configuration files.
30 |
31 | "Object" form shall mean any form resulting from mechanical
32 | transformation or translation of a Source form, including but
33 | not limited to compiled object code, generated documentation,
34 | and conversions to other media types.
35 |
36 | "Work" shall mean the work of authorship, whether in Source or
37 | Object form, made available under the License, as indicated by a
38 | copyright notice that is included in or attached to the work
39 | (an example is provided in the Appendix below).
40 |
41 | "Derivative Works" shall mean any work, whether in Source or Object
42 | form, that is based on (or derived from) the Work and for which the
43 | editorial revisions, annotations, elaborations, or other modifications
44 | represent, as a whole, an original work of authorship. For the purposes
45 | of this License, Derivative Works shall not include works that remain
46 | separable from, or merely link (or bind by name) to the interfaces of,
47 | the Work and Derivative Works thereof.
48 |
49 | "Contribution" shall mean any work of authorship, including
50 | the original version of the Work and any modifications or additions
51 | to that Work or Derivative Works thereof, that is intentionally
52 | submitted to Licensor for inclusion in the Work by the copyright owner
53 | or by an individual or Legal Entity authorized to submit on behalf of
54 | the copyright owner. For the purposes of this definition, "submitted"
55 | means any form of electronic, verbal, or written communication sent
56 | to the Licensor or its representatives, including but not limited to
57 | communication on electronic mailing lists, source code control systems,
58 | and issue tracking systems that are managed by, or on behalf of, the
59 | Licensor for the purpose of discussing and improving the Work, but
60 | excluding communication that is conspicuously marked or otherwise
61 | designated in writing by the copyright owner as "Not a Contribution."
62 |
63 | "Contributor" shall mean Licensor and any individual or Legal Entity
64 | on behalf of whom a Contribution has been received by Licensor and
65 | subsequently incorporated within the Work.
66 |
67 | 2. Grant of Copyright License. Subject to the terms and conditions of
68 | this License, each Contributor hereby grants to You a perpetual,
69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
70 | copyright license to reproduce, prepare Derivative Works of,
71 | publicly display, publicly perform, sublicense, and distribute the
72 | Work and such Derivative Works in Source or Object form.
73 |
74 | 3. Grant of Patent License. Subject to the terms and conditions of
75 | this License, each Contributor hereby grants to You a perpetual,
76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
77 | (except as stated in this section) patent license to make, have made,
78 | use, offer to sell, sell, import, and otherwise transfer the Work,
79 | where such license applies only to those patent claims licensable
80 | by such Contributor that are necessarily infringed by their
81 | Contribution(s) alone or by combination of their Contribution(s)
82 | with the Work to which such Contribution(s) was submitted. If You
83 | institute patent litigation against any entity (including a
84 | cross-claim or counterclaim in a lawsuit) alleging that the Work
85 | or a Contribution incorporated within the Work constitutes direct
86 | or contributory patent infringement, then any patent licenses
87 | granted to You under this License for that Work shall terminate
88 | as of the date such litigation is filed.
89 |
90 | 4. Redistribution. You may reproduce and distribute copies of the
91 | Work or Derivative Works thereof in any medium, with or without
92 | modifications, and in Source or Object form, provided that You
93 | meet the following conditions:
94 |
95 | (a) You must give any other recipients of the Work or
96 | Derivative Works a copy of this License; and
97 |
98 | (b) You must cause any modified files to carry prominent notices
99 | stating that You changed the files; and
100 |
101 | (c) You must retain, in the Source form of any Derivative Works
102 | that You distribute, all copyright, patent, trademark, and
103 | attribution notices from the Source form of the Work,
104 | excluding those notices that do not pertain to any part of
105 | the Derivative Works; and
106 |
107 | (d) If the Work includes a "NOTICE" text file as part of its
108 | distribution, then any Derivative Works that You distribute must
109 | include a readable copy of the attribution notices contained
110 | within such NOTICE file, excluding those notices that do not
111 | pertain to any part of the Derivative Works, in at least one
112 | of the following places: within a NOTICE text file distributed
113 | as part of the Derivative Works; within the Source form or
114 | documentation, if provided along with the Derivative Works; or,
115 | within a display generated by the Derivative Works, if and
116 | wherever such third-party notices normally appear. The contents
117 | of the NOTICE file are for informational purposes only and
118 | do not modify the License. You may add Your own attribution
119 | notices within Derivative Works that You distribute, alongside
120 | or as an addendum to the NOTICE text from the Work, provided
121 | that such additional attribution notices cannot be construed
122 | as modifying the License.
123 |
124 | You may add Your own copyright statement to Your modifications and
125 | may provide additional or different license terms and conditions
126 | for use, reproduction, or distribution of Your modifications, or
127 | for any such Derivative Works as a whole, provided Your use,
128 | reproduction, and distribution of the Work otherwise complies with
129 | the conditions stated in this License.
130 |
131 | 5. Submission of Contributions. Unless You explicitly state otherwise,
132 | any Contribution intentionally submitted for inclusion in the Work
133 | by You to the Licensor shall be under the terms and conditions of
134 | this License, without any additional terms or conditions.
135 | Notwithstanding the above, nothing herein shall supersede or modify
136 | the terms of any separate license agreement you may have executed
137 | with Licensor regarding such Contributions.
138 |
139 | 6. Trademarks. This License does not grant permission to use the trade
140 | names, trademarks, service marks, or product names of the Licensor,
141 | except as required for reasonable and customary use in describing the
142 | origin of the Work and reproducing the content of the NOTICE file.
143 |
144 | 7. Disclaimer of Warranty. Unless required by applicable law or
145 | agreed to in writing, Licensor provides the Work (and each
146 | Contributor provides its Contributions) on an "AS IS" BASIS,
147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
148 | implied, including, without limitation, any warranties or conditions
149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
150 | PARTICULAR PURPOSE. You are solely responsible for determining the
151 | appropriateness of using or redistributing the Work and assume any
152 | risks associated with Your exercise of permissions under this License.
153 |
154 | 8. Limitation of Liability. In no event and under no legal theory,
155 | whether in tort (including negligence), contract, or otherwise,
156 | unless required by applicable law (such as deliberate and grossly
157 | negligent acts) or agreed to in writing, shall any Contributor be
158 | liable to You for damages, including any direct, indirect, special,
159 | incidental, or consequential damages of any character arising as a
160 | result of this License or out of the use or inability to use the
161 | Work (including but not limited to damages for loss of goodwill,
162 | work stoppage, computer failure or malfunction, or any and all
163 | other commercial damages or losses), even if such Contributor
164 | has been advised of the possibility of such damages.
165 |
166 | 9. Accepting Warranty or Additional Liability. While redistributing
167 | the Work or Derivative Works thereof, You may choose to offer,
168 | and charge a fee for, acceptance of support, warranty, indemnity,
169 | or other liability obligations and/or rights consistent with this
170 | License. However, in accepting such obligations, You may act only
171 | on Your own behalf and on Your sole responsibility, not on behalf
172 | of any other Contributor, and only if You agree to indemnify,
173 | defend, and hold each Contributor harmless for any liability
174 | incurred by, or claims asserted against, such Contributor by reason
175 | of your accepting any such warranty or additional liability.
176 |
177 | END OF TERMS AND CONDITIONS
178 |
179 | APPENDIX: How to apply the Apache License to your work.
180 |
181 | To apply the Apache License to your work, attach the following
182 | boilerplate notice, with the fields enclosed by brackets "[]"
183 | replaced with your own identifying information. (Don't include
184 | the brackets!) The text should be enclosed in the appropriate
185 | comment syntax for the file format. We also recommend that a
186 | file or class name and description of purpose be included on the
187 | same "printed page" as the copyright notice for easier
188 | identification within third-party archives.
189 |
190 | Copyright [yyyy] [name of copyright owner]
191 |
192 | Licensed under the Apache License, Version 2.0 (the "License");
193 | you may not use this file except in compliance with the License.
194 | You may obtain a copy of the License at
195 |
196 | http://www.apache.org/licenses/LICENSE-2.0
197 |
198 | Unless required by applicable law or agreed to in writing, software
199 | distributed under the License is distributed on an "AS IS" BASIS,
200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
201 | See the License for the specific language governing permissions and
202 | limitations under the License.
--------------------------------------------------------------------------------
/settings.gradle:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | pluginManagement {
19 | repositories {
20 | jcenter()
21 | gradlePluginPortal()
22 | }
23 | plugins {
24 | id 'com.gradle.enterprise' version '3.5'
25 | id 'org.kordamp.gradle.java-project' version '0.42.1'
26 | id 'org.openjfx.javafxplugin' version '0.0.9'
27 | id 'biz.aQute.bnd.builder' version '5.2.0'
28 | }
29 | }
30 |
31 | rootProject.name = 'Medusa'
32 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/Alarm.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa;
19 |
20 |
21 | import javafx.application.Platform;
22 | import javafx.beans.property.ObjectProperty;
23 | import javafx.beans.property.SimpleObjectProperty;
24 | import javafx.event.Event;
25 | import javafx.event.EventHandler;
26 | import javafx.event.EventTarget;
27 | import javafx.event.EventType;
28 | import javafx.scene.paint.Color;
29 |
30 | import java.time.ZonedDateTime;
31 | import java.time.temporal.ChronoUnit;
32 | import java.util.UUID;
33 |
34 |
35 | /**
36 | * Created by hansolo on 28.01.16.
37 | */
38 | public class Alarm {
39 | public enum Repetition { ONCE, HALF_HOURLY, HOURLY, DAILY, WEEKLY }
40 | public static final boolean ARMED = true;
41 | public static final boolean UNARMED = false;
42 |
43 | public final AlarmMarkerEvent ALARM_MARKER_PRESSED_EVENT = new AlarmMarkerEvent(Alarm.this, null, AlarmMarkerEvent.ALARM_MARKER_PRESSED);
44 | public final AlarmMarkerEvent ALARM_MARKER_RELEASED_EVENT = new AlarmMarkerEvent(Alarm.this, null, AlarmMarkerEvent.ALARM_MARKER_RELEASED);
45 |
46 | private Repetition repetition;
47 | private ZonedDateTime time;
48 | private boolean armed;
49 | private String text;
50 | private Command command;
51 | private Color color;
52 |
53 |
54 | // ******************** Constructors **************************************
55 | /**
56 | * Represents a point in time where something should be triggered.
57 | */
58 | public Alarm() {
59 | this(Repetition.ONCE, ZonedDateTime.now().plus(5, ChronoUnit.MINUTES), true, "", null, Clock.DARK_COLOR);
60 | }
61 | public Alarm(final ZonedDateTime TIME) {
62 | this(Repetition.ONCE, TIME, true, "", null, Clock.DARK_COLOR);
63 | }
64 | public Alarm(final ZonedDateTime TIME, final Color COLOR) {
65 | this(Repetition.ONCE, TIME, true, "", null, COLOR);
66 | }
67 | public Alarm(final Repetition REPETITION, final ZonedDateTime TIME) {
68 | this(REPETITION, TIME, true, "", null, Clock.DARK_COLOR);
69 | }
70 | public Alarm(final Repetition REPETITION, final ZonedDateTime TIME, final Color COLOR) {
71 | this(REPETITION, TIME, true, "", null, COLOR);
72 | }
73 | public Alarm(final Repetition REPETITION, final ZonedDateTime TIME, final boolean ARMED) {
74 | this(REPETITION, TIME, ARMED, "");
75 | }
76 | public Alarm(final Repetition REPETITION, final ZonedDateTime TIME, final boolean ARMED, final String TEXT) {
77 | this(REPETITION, TIME, ARMED, TEXT, null, Clock.DARK_COLOR);
78 | }
79 | public Alarm(final Repetition REPETITION, final ZonedDateTime TIME, final boolean ARMED, final String TEXT, final Command COMMAND) {
80 | this(REPETITION, TIME, ARMED, TEXT, COMMAND, Clock.DARK_COLOR);
81 | }
82 | public Alarm(final Repetition REPETITION, final ZonedDateTime TIME, final boolean ARMED, final String TEXT, final Command COMMAND, final Color COLOR) {
83 | repetition = REPETITION;
84 | time = TIME;
85 | armed = ARMED;
86 | text = TEXT;
87 | command = COMMAND;
88 | color = COLOR;
89 | }
90 |
91 |
92 | // ******************** Methods *******************************************
93 | /**
94 | * Returns the repetition rate of the alarm.
95 | * The values are ONCE, HALF_HOURLY, HOURLY, DAILY, WEEKLY
96 | * @return the repetition rate of the alarm
97 | */
98 | public Repetition getRepetition() { return repetition; }
99 | /**
100 | * Defines the repetition rate of the alarm.
101 | * The values are ONCE, HALF_HOURLY, HOURLY, DAILY, WEEKLY
102 | * @param REPETITION
103 | */
104 | public void setRepetition(final Repetition REPETITION) { repetition = REPETITION; }
105 |
106 | /**
107 | * Returns the time of the alarm.
108 | * @return the time of the alarm
109 | */
110 | public ZonedDateTime getTime() { return time; }
111 | /**
112 | * Defines the time of the alarm.
113 | * @param TIME
114 | */
115 | public void setTime(final ZonedDateTime TIME) { time = TIME; }
116 |
117 | /**
118 | * Returns true if the alarm is activated.
119 | * If an alarm is not armed it will be drawn gray translucent.
120 | * @return true if the alarm is activated
121 | */
122 | public boolean isArmed() { return armed; }
123 | /**
124 | * Defines if the alarm is activated.
125 | * If an alarm is not armed it will be drawn gray translucent.
126 | * @param ARMED
127 | */
128 | public void setArmed(final boolean ARMED) { armed = ARMED; }
129 |
130 | /**
131 | * Returns the text that was defined for the alarm.
132 | * The text will be shown in tooltips.
133 | * @return the text that was defined for the alarm
134 | */
135 | public String getText() { return text; }
136 | /**
137 | * Defines a text for the alarm.
138 | * The text will be shown in tooltips.
139 | * @param TEXT
140 | */
141 | public void setText(final String TEXT) { text = TEXT; }
142 |
143 | /**
144 | * Returns an instance of a class that implements the Command interface.
145 | * This interface only contains one method execute() which will be called
146 | * when the alarm is triggered. With this one could execute specific tasks
147 | * defined in separate classes.
148 | * @return an instance of a class that implements the Command interface
149 | */
150 | public Command getCommand() { return command; }
151 | /**
152 | * Defines a class that implements the Command interface and which execute()
153 | * method will be called when the alarm is triggered.
154 | * @param COMMAND
155 | */
156 | public void setCommand(final Command COMMAND) { command = COMMAND; }
157 | public void executeCommand() { if (null != command) command.execute(); }
158 |
159 | /**
160 | * Returns the color that will be used to colorize the alarm in a clock.
161 | * @return the color that will be used to colorize the alarm
162 | */
163 | public Color getColor() { return color; }
164 | /**
165 | * Defines the color that will be used to colorize the alarm
166 | * @param COLOR
167 | */
168 | public void setColor(final Color COLOR) { color = COLOR; }
169 |
170 | @Override public String toString() {
171 | return new StringBuilder()
172 | .append("{\n")
173 | .append("\"reptition\":\"").append(repetition.name()).append("\",\n")
174 | .append("\"time\":\"").append(time).append("\",\n")
175 | .append("\"armed\":").append(armed).append(",\n")
176 | .append("\"color\":\"").append(getColor().toString().substring(0,8).replace("0x", "#")).append("\",\n")
177 | .append("\"text\":\"").append(text).append("\"\n")
178 | .append("}")
179 | .toString();
180 | }
181 |
182 |
183 | // ******************** Event Handling ************************************
184 | public final ObjectProperty> onMarkerPressedProperty() { return onMarkerPressed; }
185 | public final void setOnMarkerPressed(EventHandler value) { onMarkerPressedProperty().set(value); }
186 | public final EventHandler getOnMarkerPressed() { return onMarkerPressedProperty().get(); }
187 | private ObjectProperty> onMarkerPressed = new SimpleObjectProperty<>(Alarm.this, "onMarkerPressed");
188 |
189 | public final ObjectProperty> onMarkerReleasedProperty() { return onMarkerReleased; }
190 | public final void setOnMarkerReleased(EventHandler value) { onMarkerReleasedProperty().set(value); }
191 | public final EventHandler getOnMarkerReleased() { return onMarkerReleasedProperty().get(); }
192 | private ObjectProperty> onMarkerReleased = new SimpleObjectProperty<>(Alarm.this, "onMarkerReleased");
193 |
194 | public void fireAlarmMarkerEvent(final AlarmMarkerEvent EVENT) {
195 | final EventHandler HANDLER;
196 | final EventType TYPE = EVENT.getEventType();
197 |
198 | if (AlarmMarkerEvent.ALARM_MARKER_PRESSED == TYPE) {
199 | HANDLER = getOnMarkerPressed();
200 | } else if (AlarmMarkerEvent.ALARM_MARKER_RELEASED == TYPE) {
201 | HANDLER = getOnMarkerReleased();
202 | } else {
203 | HANDLER = null;
204 | }
205 | if (null == HANDLER) return;
206 | Platform.runLater(() -> HANDLER.handle(EVENT));
207 | }
208 |
209 |
210 | // ******************** Inner Classes *************************************
211 | public static class AlarmMarkerEvent extends Event {;
212 | public static final EventType ALARM_MARKER_PRESSED = new EventType(ANY, "ALARM_MARKER_PRESSED" + UUID.randomUUID().toString());
213 | public static final EventType ALARM_MARKER_RELEASED = new EventType(ANY, "ALARM_MARKER_RELEASED" + UUID.randomUUID().toString());
214 |
215 |
216 | // ******************** Constructors **************************************
217 | public AlarmMarkerEvent(final Object SOURCE, final EventTarget TARGET, EventType TYPE) {
218 | super(SOURCE, TARGET, TYPE);
219 | }
220 | }
221 | }
222 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/AlarmBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa;
19 |
20 | import eu.hansolo.medusa.Alarm.AlarmMarkerEvent;
21 | import eu.hansolo.medusa.Alarm.Repetition;
22 | import javafx.beans.property.BooleanProperty;
23 | import javafx.beans.property.ObjectProperty;
24 | import javafx.beans.property.Property;
25 | import javafx.beans.property.SimpleBooleanProperty;
26 | import javafx.beans.property.SimpleObjectProperty;
27 | import javafx.beans.property.SimpleStringProperty;
28 | import javafx.beans.property.StringProperty;
29 | import javafx.event.EventHandler;
30 | import javafx.scene.paint.Color;
31 |
32 | import java.time.ZonedDateTime;
33 | import java.util.HashMap;
34 |
35 |
36 | /**
37 | * Created by hansolo on 31.01.16.
38 | */
39 | public class AlarmBuilder> {
40 | private HashMap properties = new HashMap<>();
41 |
42 |
43 | // ******************** Constructors **************************************
44 | protected AlarmBuilder() {}
45 |
46 |
47 | // ******************** Methods *******************************************
48 | public static final AlarmBuilder create() {
49 | return new AlarmBuilder();
50 | }
51 |
52 | public final B time(final ZonedDateTime DATE_TIME) {
53 | properties.put("time", new SimpleObjectProperty(DATE_TIME));
54 | return (B)this;
55 | }
56 |
57 | public final B repetition(final Repetition REPETITION) {
58 | properties.put("repetition", new SimpleObjectProperty(REPETITION));
59 | return (B)this;
60 | }
61 |
62 | public final B text(final String TEXT) {
63 | properties.put("text", new SimpleStringProperty(TEXT));
64 | return (B)this;
65 | }
66 |
67 | public final B armed(final boolean ARMED) {
68 | properties.put("armed", new SimpleBooleanProperty(ARMED));
69 | return (B)this;
70 | }
71 |
72 | public final B command(final Command COMMAND) {
73 | properties.put("command", new SimpleObjectProperty<>(COMMAND));
74 | return (B)this;
75 | }
76 |
77 | public final B color(final Color COLOR) {
78 | properties.put("color", new SimpleObjectProperty<>(COLOR));
79 | return (B)this;
80 | }
81 |
82 | public final B onAlarmMarkerPressed(final EventHandler HANDLER) {
83 | properties.put("onAlarmMarkerPressed", new SimpleObjectProperty<>(HANDLER));
84 | return (B)this;
85 | }
86 |
87 | public final B onAlarmMarkerReleased(final EventHandler HANDLER) {
88 | properties.put("onAlarmMarkerReleased", new SimpleObjectProperty<>(HANDLER));
89 | return (B)this;
90 | }
91 |
92 | public final Alarm build() {
93 | final Alarm ALARM = new Alarm();
94 | for (String key : properties.keySet()) {
95 | if ("time".equals(key)) {
96 | ALARM.setTime(((ObjectProperty) properties.get(key)).get());
97 | } else if("repetition".equals(key)) {
98 | ALARM.setRepetition(((ObjectProperty) properties.get(key)).get());
99 | } else if("text".equals(key)) {
100 | ALARM.setText(((StringProperty) properties.get(key)).get());
101 | } else if("armed".equals(key)) {
102 | ALARM.setArmed(((BooleanProperty) properties.get(key)).get());
103 | } else if ("command".equals(key)) {
104 | ALARM.setCommand(((ObjectProperty) properties.get(key)).get());
105 | } else if ("color".equals(key)) {
106 | ALARM.setColor(((ObjectProperty) properties.get(key)).get());
107 | } else if ("onAlarmMarkerPressed".equals(key)) {
108 | ALARM.setOnMarkerPressed(((ObjectProperty) properties.get(key)).get());
109 | } else if ("onAlarmMarkerReleased".equals(key)) {
110 | ALARM.setOnMarkerReleased(((ObjectProperty) properties.get(key)).get());
111 | }
112 | }
113 | return ALARM;
114 | }
115 | }
116 |
117 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/Command.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa;
19 |
20 | /**
21 | * Created by hansolo on 28.01.16.
22 | */
23 | @FunctionalInterface
24 | public interface Command {
25 | void execute();
26 | }
27 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/DemoLauncher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa;
19 |
20 | public class DemoLauncher {
21 | public static void main(final String[] args) {
22 | Demo.main(args);
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/FGauge.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa;
19 |
20 | import eu.hansolo.medusa.Gauge.SkinType;
21 | import eu.hansolo.medusa.GaugeDesign.GaugeBackground;
22 | import eu.hansolo.medusa.skins.GaugeSkin;
23 | import javafx.scene.control.Skin;
24 | import javafx.scene.effect.BlurType;
25 | import javafx.scene.effect.InnerShadow;
26 | import javafx.scene.layout.Region;
27 | import javafx.scene.paint.Color;
28 | import javafx.scene.paint.CycleMethod;
29 | import javafx.scene.paint.RadialGradient;
30 | import javafx.scene.paint.Stop;
31 | import javafx.scene.shape.Circle;
32 |
33 |
34 | /**
35 | * A Region that embeds a given Gauge control. Keep in mind that
36 | * this only works with the round Medusa Skins and not with
37 | * skins like BulletChartSkin and QuarterSkin.
38 | * Created by hansolo on 08.01.16.
39 | */
40 | public class FGauge extends Region {
41 | public static final double PREFERRED_WIDTH = 270;
42 | public static final double PREFERRED_HEIGHT = 270;
43 | public static final double MINIMUM_WIDTH = 50;
44 | public static final double MINIMUM_HEIGHT = 50;
45 | public static final double MAXIMUM_WIDTH = 1024;
46 | public static final double MAXIMUM_HEIGHT = 1024;
47 |
48 | // Model related
49 | private Gauge gauge;
50 |
51 | // View related
52 | private double size;
53 | private Region frame;
54 | private Circle background;
55 | private Circle foreground;
56 | private GaugeDesign gaugeDesign;
57 | private GaugeBackground gaugeBackground;
58 | private InnerShadow innerShadow;
59 |
60 |
61 | // ******************** Constructors **************************************
62 | public FGauge() {
63 | this(new Gauge(), GaugeDesign.BLACK_METAL, GaugeBackground.BEIGE);
64 | }
65 | public FGauge(final Gauge GAUGE, final GaugeDesign DESIGN) {
66 | this(GAUGE, DESIGN, GaugeBackground.DARK_GRAY);
67 | }
68 | public FGauge(final Gauge GAUGE, final GaugeDesign DESIGN, final GaugeBackground BACKGROUND) {
69 | getStylesheets().add(getClass().getResource("framed-gauge.css").toExternalForm());
70 | getStyleClass().setAll("framed-gauge");
71 | gauge = GAUGE;
72 | gaugeDesign = DESIGN;
73 | gaugeBackground = BACKGROUND;
74 |
75 | Skin skin = gauge.getSkin();
76 |
77 | if (null == skin) {
78 | throw new RuntimeException("Please use a valid Skin.");
79 | }
80 |
81 | init();
82 | initGraphics();
83 | registerListeners();
84 | }
85 |
86 |
87 | // ******************** Initialization ************************************
88 | private void init() {
89 | if (Double.compare(getWidth(), 0) <= 0 || Double.compare(getHeight(), 0) <= 0 ||
90 | Double.compare(getPrefWidth(), 0) <= 0 || Double.compare(getPrefHeight(), 0) <= 0) {
91 | setPrefSize(PREFERRED_WIDTH, PREFERRED_HEIGHT);
92 | }
93 | if (Double.compare(getMinWidth(), 0) <= 0 || Double.compare(getMinHeight(), 0) <= 0) {
94 | setMinSize(MINIMUM_WIDTH, MINIMUM_HEIGHT);
95 | }
96 | if (Double.compare(getMaxWidth(), 0) <= 0 || Double.compare(getMaxHeight(), 0) <= 0) {
97 | setMaxSize(MAXIMUM_WIDTH, MAXIMUM_HEIGHT);
98 | }
99 | }
100 |
101 | private void initGraphics() {
102 | innerShadow = new InnerShadow(BlurType.TWO_PASS_BOX, Color.rgb(0, 0, 0, 0.35), 20, 0.0, 0, 20);
103 |
104 | frame = new Region();
105 |
106 | background = new Circle();
107 | background.setEffect(innerShadow);
108 |
109 | foreground = new Circle();
110 | foreground.setMouseTransparent(true);
111 |
112 | getChildren().setAll(frame, background, gauge, foreground);
113 | }
114 |
115 | private void registerListeners() {
116 | widthProperty().addListener(o -> redraw());
117 | heightProperty().addListener(o -> redraw());
118 | }
119 |
120 |
121 | // ******************** Methods *******************************************
122 | public GaugeDesign getGaugeDesign() { return gaugeDesign; }
123 | public void setGaugeDesign(final GaugeDesign DESIGN) {
124 | gaugeDesign = DESIGN;
125 | redraw();
126 | }
127 |
128 | public GaugeBackground getGaugeBackground() { return gaugeBackground; }
129 | public void setGaugeBackground(final GaugeBackground BACKGROUND) {
130 | gaugeBackground = BACKGROUND;
131 | redraw();
132 | }
133 |
134 | public boolean isForegroundVisible() { return foreground.isVisible(); }
135 | public void setForegroundVisible(final boolean VISIBLE) {
136 | foreground.setVisible(VISIBLE);
137 | foreground.setManaged(VISIBLE);
138 | }
139 |
140 | public Gauge getGauge() { return gauge; }
141 | public void setGauge(final Gauge GAUGE) { gauge = GAUGE; }
142 |
143 |
144 | // ******************** Resizing ******************************************
145 | private void redraw() {
146 | double width = getWidth() - getInsets().getLeft() - getInsets().getRight();
147 | double height = getHeight() - getInsets().getTop() - getInsets().getBottom();
148 | size = width < height ? width : height;
149 |
150 | if (size > 0) {
151 | if (getWidth() > getHeight()) {
152 | setTranslateX(0.5 * (getWidth() - size));
153 | } else if (getHeight() > getWidth()) {
154 | setTranslateY(0.5 * (getHeight() - size));
155 | }
156 |
157 | frame.setPrefSize(size, size);
158 | frame.setBorder(gaugeDesign.getBorder(size));
159 |
160 | background.setCenterX(size * 0.5);
161 | background.setCenterY(size * 0.5);
162 | background.setRadius(size * 0.4375);
163 |
164 | background.setFill(gaugeBackground.getPaint(background.getLayoutBounds().getMinX(), background.getLayoutBounds().getMinY(),
165 | background.getLayoutBounds().getMaxX(), background.getLayoutBounds().getMaxY()));
166 |
167 | switch(gaugeDesign) {
168 | case NONE:
169 | frame.setVisible(false);
170 | foreground.setVisible(false);
171 | background.setVisible(false);
172 | break;
173 | case ENZO:
174 | background.setFill(Color.rgb(240, 240, 240));
175 | innerShadow.setRadius(0.07407407 * size);
176 | innerShadow.setOffsetX(0);
177 | innerShadow.setOffsetY(0.07407407 * size);
178 | innerShadow.setColor(Color.rgb(0, 0, 0, 0.35));
179 | foreground.setFill(Color.TRANSPARENT);
180 | foreground.setStroke(null);
181 | break;
182 | default:
183 | frame.setVisible(true);
184 | foreground.setVisible(true);
185 | background.setVisible(true);
186 | innerShadow.setColor(Color.rgb(0, 0, 0, 0.65));
187 | innerShadow.setRadius(0.08 * size);
188 | innerShadow.setOffsetX(0);
189 | innerShadow.setOffsetY(0.0 * size);
190 | foreground.setFill(new RadialGradient(0, 0, size * 0.5, size * gaugeDesign.FRAME_FACTOR * 0.5, size, false, CycleMethod.NO_CYCLE,
191 | new Stop(0, Color.rgb(255, 255, 255, 0.6)),
192 | new Stop(0.4, Color.TRANSPARENT)));
193 | foreground.setStroke(null);
194 | break;
195 | }
196 |
197 | gauge.setPrefSize(size * (1.0 - gaugeDesign.FRAME_FACTOR * 2.0), size * (1.0 - gaugeDesign.FRAME_FACTOR * 2.0));
198 | gauge.relocate(gaugeDesign.FRAME_FACTOR * size, gaugeDesign.FRAME_FACTOR * size);
199 |
200 | foreground.setCenterX(size * 0.5);
201 | foreground.setCenterY(size * 0.5);
202 | foreground.setRadius(size * 0.42);
203 | }
204 | }
205 | }
206 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/FGaugeBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa;
19 |
20 | import eu.hansolo.medusa.GaugeDesign.GaugeBackground;
21 | import eu.hansolo.medusa.skins.GaugeSkin;
22 | import javafx.beans.property.BooleanProperty;
23 | import javafx.beans.property.DoubleProperty;
24 | import javafx.beans.property.ObjectProperty;
25 | import javafx.beans.property.Property;
26 | import javafx.beans.property.SimpleBooleanProperty;
27 | import javafx.beans.property.SimpleDoubleProperty;
28 | import javafx.beans.property.SimpleObjectProperty;
29 | import javafx.geometry.Dimension2D;
30 | import javafx.scene.control.Skin;
31 |
32 | import java.util.HashMap;
33 |
34 |
35 | /**
36 | * Created by hansolo on 13.01.16.
37 | */
38 | public class FGaugeBuilder> {
39 | private HashMap properties = new HashMap<>();
40 |
41 |
42 | // ******************** Constructors **************************************
43 | protected FGaugeBuilder() {}
44 |
45 |
46 | // ******************** Methods *******************************************
47 | public static final FGaugeBuilder create() {
48 | return new FGaugeBuilder();
49 | }
50 |
51 | public final B gauge(final Gauge GAUGE) {
52 | properties.put("gauge", new SimpleObjectProperty<>(GAUGE));
53 | return (B)this;
54 | }
55 |
56 | public final B gaugeDesign(final GaugeDesign DESIGN) {
57 | properties.put("gaugeDesign", new SimpleObjectProperty<>(DESIGN));
58 | return (B)this;
59 | }
60 |
61 | public final B gaugeBackground(final GaugeBackground BACKGROUND) {
62 | properties.put("gaugeBackground", new SimpleObjectProperty<>(BACKGROUND));
63 | return (B)this;
64 | }
65 |
66 | public final B foregroundVisible(final boolean VISIBLE) {
67 | properties.put("foregroundVisible", new SimpleBooleanProperty(VISIBLE));
68 | return (B)this;
69 | }
70 |
71 | public final B prefSize(final double WIDTH, final double HEIGHT) {
72 | properties.put("prefSize", new SimpleObjectProperty<>(new Dimension2D(WIDTH, HEIGHT)));
73 | return (B)this;
74 | }
75 | public final B minSize(final double WIDTH, final double HEIGHT) {
76 | properties.put("minSize", new SimpleObjectProperty<>(new Dimension2D(WIDTH, HEIGHT)));
77 | return (B)this;
78 | }
79 | public final B maxSize(final double WIDTH, final double HEIGHT) {
80 | properties.put("maxSize", new SimpleObjectProperty<>(new Dimension2D(WIDTH, HEIGHT)));
81 | return (B)this;
82 | }
83 |
84 | public final B prefWidth(final double PREF_WIDTH) {
85 | properties.put("prefWidth", new SimpleDoubleProperty(PREF_WIDTH));
86 | return (B)this;
87 | }
88 | public final B prefHeight(final double PREF_HEIGHT) {
89 | properties.put("prefHeight", new SimpleDoubleProperty(PREF_HEIGHT));
90 | return (B)this;
91 | }
92 |
93 | public final B minWidth(final double MIN_WIDTH) {
94 | properties.put("minWidth", new SimpleDoubleProperty(MIN_WIDTH));
95 | return (B)this;
96 | }
97 | public final B minHeight(final double MIN_HEIGHT) {
98 | properties.put("minHeight", new SimpleDoubleProperty(MIN_HEIGHT));
99 | return (B)this;
100 | }
101 |
102 | public final B maxWidth(final double MAX_WIDTH) {
103 | properties.put("maxWidth", new SimpleDoubleProperty(MAX_WIDTH));
104 | return (B)this;
105 | }
106 | public final B maxHeight(final double MAX_HEIGHT) {
107 | properties.put("maxHeight", new SimpleDoubleProperty(MAX_HEIGHT));
108 | return (B)this;
109 | }
110 |
111 | public final B scaleX(final double SCALE_X) {
112 | properties.put("scaleX", new SimpleDoubleProperty(SCALE_X));
113 | return (B)this;
114 | }
115 | public final B scaleY(final double SCALE_Y) {
116 | properties.put("scaleY", new SimpleDoubleProperty(SCALE_Y));
117 | return (B)this;
118 | }
119 |
120 | public final B layoutX(final double LAYOUT_X) {
121 | properties.put("layoutX", new SimpleDoubleProperty(LAYOUT_X));
122 | return (B)this;
123 | }
124 | public final B layoutY(final double LAYOUT_Y) {
125 | properties.put("layoutY", new SimpleDoubleProperty(LAYOUT_Y));
126 | return (B)this;
127 | }
128 |
129 | public final B translateX(final double TRANSLATE_X) {
130 | properties.put("translateX", new SimpleDoubleProperty(TRANSLATE_X));
131 | return (B)this;
132 | }
133 | public final B translateY(final double TRANSLATE_Y) {
134 | properties.put("translateY", new SimpleDoubleProperty(TRANSLATE_Y));
135 | return (B)this;
136 | }
137 |
138 | public final FGauge build() {
139 | Gauge gauge = null == properties.get("gauge") ? new Gauge() : ((ObjectProperty) properties.get("gauge")).get();
140 | GaugeDesign design = null == properties.get("gaugeDesign") ? GaugeDesign.METAL : ((ObjectProperty) properties.get("gaugeDesign")).get();
141 | GaugeBackground background = null == properties.get("gaugeBackground") ? GaugeBackground.DARK_GRAY : ((ObjectProperty) properties.get("gaugeBackground")).get();
142 |
143 | Skin skin = gauge.getSkin();
144 | if (null != skin && gauge.getSkin().getClass() != GaugeSkin.class) {
145 | throw new RuntimeException("Please change Skin to GaugeSkin.");
146 | }
147 |
148 | final FGauge CONTROL = new FGauge(gauge, design, background);
149 | for (String key : properties.keySet()) {
150 | if ("prefSize".equals(key)) {
151 | Dimension2D dim = ((ObjectProperty) properties.get(key)).get();
152 | CONTROL.setPrefSize(dim.getWidth(), dim.getHeight());
153 | } else if("minSize".equals(key)) {
154 | Dimension2D dim = ((ObjectProperty) properties.get(key)).get();
155 | CONTROL.setPrefSize(dim.getWidth(), dim.getHeight());
156 | } else if("maxSize".equals(key)) {
157 | Dimension2D dim = ((ObjectProperty) properties.get(key)).get();
158 | CONTROL.setPrefSize(dim.getWidth(), dim.getHeight());
159 | } else if("prefWidth".equals(key)) {
160 | CONTROL.setPrefWidth(((DoubleProperty) properties.get(key)).get());
161 | } else if("prefHeight".equals(key)) {
162 | CONTROL.setPrefHeight(((DoubleProperty) properties.get(key)).get());
163 | } else if("minWidth".equals(key)) {
164 | CONTROL.setMinWidth(((DoubleProperty) properties.get(key)).get());
165 | } else if("minHeight".equals(key)) {
166 | CONTROL.setMinHeight(((DoubleProperty) properties.get(key)).get());
167 | } else if("maxWidth".equals(key)) {
168 | CONTROL.setMaxWidth(((DoubleProperty) properties.get(key)).get());
169 | } else if("maxHeight".equals(key)) {
170 | CONTROL.setMaxHeight(((DoubleProperty) properties.get(key)).get());
171 | } else if("scaleX".equals(key)) {
172 | CONTROL.setScaleX(((DoubleProperty) properties.get(key)).get());
173 | } else if("scaleY".equals(key)) {
174 | CONTROL.setScaleY(((DoubleProperty) properties.get(key)).get());
175 | } else if ("layoutX".equals(key)) {
176 | CONTROL.setLayoutX(((DoubleProperty) properties.get(key)).get());
177 | } else if ("layoutY".equals(key)) {
178 | CONTROL.setLayoutY(((DoubleProperty) properties.get(key)).get());
179 | } else if ("translateX".equals(key)) {
180 | CONTROL.setTranslateX(((DoubleProperty) properties.get(key)).get());
181 | } else if ("translateY".equals(key)) {
182 | CONTROL.setTranslateY(((DoubleProperty) properties.get(key)).get());
183 | } else if ("foregroundVisible".equals(key)) {
184 | CONTROL.setForegroundVisible(((BooleanProperty) properties.get(key)).get());
185 | }
186 | }
187 | return CONTROL;
188 | }
189 | }
190 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/Fonts.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa;
19 |
20 | import javafx.scene.text.Font;
21 |
22 |
23 | /**
24 | * Created by hansolo on 11.12.15.
25 | */
26 | public class Fonts {
27 | private static final String DIGITAL_NAME;
28 | private static final String DIGITAL_READOUT_NAME;
29 | private static final String DIGITAL_READOUT_BOLD_NAME;
30 | private static final String ELEKTRA_NAME;
31 | private static final String ROBOTO_THIN_NAME;
32 | private static final String ROBOTO_LIGHT_NAME;
33 | private static final String ROBOTO_REGULAR_NAME;
34 | private static final String ROBOTO_MEDIUM_NAME;
35 | private static final String ROBOTO_BOLD_NAME;
36 | private static final String ROBOTO_LIGHT_CONDENSED_NAME;
37 | private static final String ROBOTO_REGULAR_CONDENSED_NAME;
38 | private static final String ROBOTO_BOLD_CONDENSED_NAME;
39 | private static final String LATO_LIGHT_NAME;
40 | private static final String LATO_REGULAR_NAME;
41 | private static final String LATO_BOLD_NAME;
42 | private static final String ESTRICTA_REGULAR_NAME;
43 | private static final String ESTRICTA_REGULAR_ITALIC_NAME;
44 | private static final String ESTRICTA_MEDIUM_NAME;
45 | private static final String ESTRICTA_MEDIUM_ITALIC_NAME;
46 |
47 | private static String digitalName;
48 | private static String digitalReadoutName;
49 | private static String digitalReadoutBoldName;
50 | private static String elektraName;
51 |
52 | private static String robotoThinName;
53 | private static String robotoLightName;
54 | private static String robotoRegularName;
55 | private static String robotoMediumName;
56 | private static String robotoBoldName;
57 |
58 | private static String robotoLightCondensedName;
59 | private static String robotoRegularCondensedName;
60 | private static String robotoBoldCondensedName;
61 |
62 | private static String latoLightName;
63 | private static String latoRegularName;
64 | private static String latoBoldName;
65 |
66 | private static String estrictaRegularName;
67 | private static String estrictaRegularItalicName;
68 | private static String estrictaMediumName;
69 | private static String estrictaMediumItalicName;
70 |
71 |
72 | static {
73 | try {
74 | digitalName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/digital.ttf"), 10).getName();
75 | digitalReadoutName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/digitalreadout.ttf"), 10).getName();
76 | digitalReadoutBoldName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/digitalreadoutb.ttf"), 10).getName();
77 | elektraName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/elektra.ttf"), 10).getName();
78 | robotoThinName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/Roboto-Thin.ttf"), 10).getName();
79 | robotoLightName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/Roboto-Light.ttf"), 10).getName();
80 | robotoRegularName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/Roboto-Regular.ttf"), 10).getName();
81 | robotoMediumName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/Roboto-Medium.ttf"), 10).getName();
82 | robotoBoldName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/Roboto-Bold.ttf"), 10).getName();
83 | robotoLightCondensedName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/RobotoCondensed-Light.ttf"), 10).getName();
84 | robotoRegularCondensedName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/RobotoCondensed-Regular.ttf"), 10).getName();
85 | robotoBoldCondensedName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/RobotoCondensed-Bold.ttf"), 10).getName();
86 | latoLightName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/Lato-Lig.otf"), 10).getName();
87 | latoRegularName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/Lato-Reg.otf"), 10).getName();
88 | latoBoldName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/Lato-Bol.otf"), 10).getName();
89 | estrictaRegularName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/Estricta-Regular.otf"), 10).getName();
90 | estrictaRegularItalicName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/Estricta-RegularItalic.otf"), 10).getName();
91 | estrictaMediumName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/Estricta-Medium.otf"), 10).getName();
92 | estrictaMediumItalicName = Font.loadFont(Fonts.class.getResourceAsStream("/eu/hansolo/medusa/Estricta-MediumItalic.otf"), 10).getName();
93 | } catch (Exception exception) { }
94 | DIGITAL_NAME = digitalName;
95 | DIGITAL_READOUT_NAME = digitalReadoutName;
96 | DIGITAL_READOUT_BOLD_NAME = digitalReadoutBoldName;
97 | ELEKTRA_NAME = elektraName;
98 | ROBOTO_THIN_NAME = robotoThinName;
99 | ROBOTO_LIGHT_NAME = robotoLightName;
100 | ROBOTO_REGULAR_NAME = robotoRegularName;
101 | ROBOTO_MEDIUM_NAME = robotoMediumName;
102 | ROBOTO_BOLD_NAME = robotoBoldName;
103 | ROBOTO_LIGHT_CONDENSED_NAME = robotoLightCondensedName;
104 | ROBOTO_REGULAR_CONDENSED_NAME = robotoRegularCondensedName;
105 | ROBOTO_BOLD_CONDENSED_NAME = robotoBoldCondensedName;
106 | LATO_LIGHT_NAME = latoLightName;
107 | LATO_REGULAR_NAME = latoRegularName;
108 | LATO_BOLD_NAME = latoBoldName;
109 | ESTRICTA_REGULAR_NAME = estrictaRegularName;
110 | ESTRICTA_REGULAR_ITALIC_NAME = estrictaRegularItalicName;
111 | ESTRICTA_MEDIUM_NAME = estrictaMediumName;
112 | ESTRICTA_MEDIUM_ITALIC_NAME = estrictaMediumItalicName;
113 | }
114 |
115 |
116 | // ******************** Methods *******************************************
117 | public static Font digital(final double SIZE) { return new Font(DIGITAL_NAME, SIZE); }
118 |
119 | public static Font digitalReadout(final double SIZE) { return new Font(DIGITAL_READOUT_NAME, SIZE); }
120 | public static Font digitalReadoutBold(final double SIZE) { return new Font(DIGITAL_READOUT_BOLD_NAME, SIZE); }
121 |
122 | public static Font elektra(final double SIZE) { return new Font(ELEKTRA_NAME, SIZE); }
123 |
124 | public static Font robotoThin(final double SIZE) { return new Font(ROBOTO_THIN_NAME, SIZE); }
125 | public static Font robotoLight(final double SIZE) { return new Font(ROBOTO_LIGHT_NAME, SIZE); }
126 | public static Font robotoRegular(final double SIZE) { return new Font(ROBOTO_REGULAR_NAME, SIZE); }
127 | public static Font robotoMedium(final double SIZE) { return new Font(ROBOTO_MEDIUM_NAME, SIZE); }
128 | public static Font robotoBold(final double SIZE) { return new Font(ROBOTO_BOLD_NAME, SIZE); }
129 |
130 | public static Font robotoCondensedLight(final double SIZE) { return new Font(ROBOTO_LIGHT_CONDENSED_NAME, SIZE); }
131 | public static Font robotoCondensedRegular(final double SIZE) { return new Font(ROBOTO_REGULAR_CONDENSED_NAME, SIZE); }
132 | public static Font robotoCondensedBold(final double SIZE) { return new Font(ROBOTO_BOLD_CONDENSED_NAME, SIZE); }
133 |
134 | public static Font latoLight(final double SIZE) { return new Font(LATO_LIGHT_NAME, SIZE); }
135 | public static Font latoRegular(final double SIZE) { return new Font(LATO_REGULAR_NAME, SIZE); }
136 | public static Font latoBold(final double SIZE) { return new Font(LATO_BOLD_NAME, SIZE); }
137 |
138 | public static Font estrictaRegular(final double SIZE) { return new Font(ESTRICTA_REGULAR_NAME, SIZE); }
139 | public static Font estrictaRegularItalic(final double SIZE) { return new Font(ESTRICTA_REGULAR_ITALIC_NAME, SIZE); }
140 | public static Font estrictaMedium(final double SIZE) { return new Font(ESTRICTA_MEDIUM_NAME, SIZE); }
141 | public static Font estrictaMediumItalic(final double SIZE) { return new Font(ESTRICTA_MEDIUM_ITALIC_NAME, SIZE); }
142 | }
143 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/LcdDesign.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa;
19 |
20 | import javafx.scene.paint.Color;
21 |
22 |
23 | /**
24 | * Created by hansolo on 30.12.15.
25 | */
26 | public enum LcdDesign {
27 | BEIGE(Color.rgb(200, 200, 177), Color.rgb(241, 237, 207), Color.rgb(234, 230, 194), Color.rgb(225, 220, 183), Color.rgb(237, 232, 191), Color.BLACK, Color.rgb(0, 0, 0, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
28 | BLUE(Color.WHITE, Color.rgb(231, 246, 255), Color.rgb(170, 224, 255), Color.rgb(136, 212, 255), Color.rgb(192, 232, 255), Color.rgb(18, 69, 100), Color.rgb(18, 69, 100, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
29 | ORANGE(Color.WHITE, Color.rgb(255, 245, 225), Color.rgb(255, 217, 147), Color.rgb(255, 201, 104), Color.rgb(255, 227, 173), Color.rgb(80, 55, 0), Color.rgb(80, 55, 0, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
30 | RED(Color.WHITE, Color.rgb(255, 225, 225), Color.rgb(252, 114, 115), Color.rgb(252, 114, 115), Color.rgb(254, 178, 178), Color.rgb(79, 12, 14), Color.rgb(79, 12, 14, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
31 | YELLOW(Color.WHITE, Color.rgb(245, 255, 186), Color.rgb(158, 205, 0), Color.rgb(158, 205, 0), Color.rgb(210, 255, 0), Color.rgb(64, 83, 0), Color.rgb(64, 83, 0, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
32 | WHITE(Color.WHITE, Color.WHITE, Color.rgb(241, 246, 242), Color.rgb(229, 239, 244), Color.WHITE, Color.BLACK, Color.rgb(0, 0, 0, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
33 | GRAY(Color.rgb(65, 65, 65), Color.rgb(117, 117, 117), Color.rgb(87, 87, 87), Color.rgb(65, 65, 65), Color.rgb(81, 81, 81), Color.WHITE, Color.rgb(255, 255, 255, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
34 | BLACK(Color.rgb(65, 65, 65), Color.rgb(102, 102, 102), Color.rgb(51, 51, 51), Color.BLACK, Color.rgb(51, 51, 51), Color.rgb(204, 204, 204), Color.rgb(204, 204, 204, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
35 | GREEN(Color.rgb(33, 67, 67), Color.rgb(33, 67, 67), Color.rgb(29, 58, 58), Color.rgb(28, 57, 57), Color.rgb(23, 46, 46), Color.rgb(0, 185, 165), Color.rgb(0, 185, 165, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
36 | GREEN_DARKGREEN(Color.rgb(27, 41, 17), Color.rgb(70, 84, 58), Color.rgb(36, 60, 14), Color.rgb(24, 50, 1), Color.rgb(8, 10, 7), Color.rgb(152, 255, 74), Color.rgb(152, 255, 74, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
37 | BLUE2(Color.rgb(0, 68, 103), Color.rgb(8, 109, 165), Color.rgb(0, 72, 117), Color.rgb(0, 72, 117), Color.rgb(0, 68, 103), Color.rgb(111, 182, 228), Color.rgb(111, 182, 228, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
38 | BLUE_BLACK(Color.rgb(22, 125, 212), Color.rgb(3, 162, 254), Color.rgb(3, 162, 254), Color.rgb(3, 162, 254), Color.rgb(11, 172, 244), Color.BLACK, Color.rgb(0, 0, 0, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
39 | BLUE_DARKBLUE(Color.rgb(18, 33, 88), Color.rgb(18, 33, 88), Color.rgb(19, 30, 90), Color.rgb(17, 31, 94), Color.rgb(21, 25, 90), Color.rgb(23, 99, 221), Color.rgb(23, 99, 221, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
40 | BLUE_LIGHTBLUE(Color.rgb(88, 107, 132), Color.rgb(53, 74, 104), Color.rgb(27, 37, 65), Color.rgb(5, 12, 40), Color.rgb(32, 47, 79), Color.rgb(71, 178, 254), Color.rgb(71, 178, 254, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
41 | BLUE_GRAY(Color.rgb(135, 174, 255), Color.rgb(101, 159, 255), Color.rgb(44, 93, 255), Color.rgb(27, 65, 254), Color.rgb(12, 50, 255), Color.rgb(178, 180, 237), Color.rgb(178, 180, 237, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
42 | STANDARD(Color.rgb(131, 133, 119), Color.rgb(176, 183, 167), Color.rgb(165, 174, 153), Color.rgb(166, 175, 156), Color.rgb(175, 184, 165), Color.rgb(35, 42, 52), Color.rgb(35, 42, 52, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
43 | LIGHTGREEN(Color.rgb(194, 212, 188), Color.rgb(212, 234, 206), Color.rgb(205, 224, 194), Color.rgb(206, 225, 194), Color.rgb(214, 233, 206), Color.rgb(0, 12, 6), Color.rgb(0, 12, 6, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
44 | STANDARD_GREEN(Color.WHITE, Color.rgb(219, 230, 220), Color.rgb(179, 194, 178), Color.rgb(153, 176, 151), Color.rgb(114, 138, 109), Color.rgb(0, 12, 6), Color.rgb(0, 12, 6, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
45 | BLUE_BLUE(Color.rgb(100, 168, 253), Color.rgb(100, 168, 253), Color.rgb(95, 160, 250), Color.rgb(80, 144, 252), Color.rgb(74, 134, 255), Color.rgb(0, 44, 187), Color.rgb(0, 44, 187, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
46 | RED_DARKRED(Color.rgb(72, 36, 50), Color.rgb(185, 111, 110), Color.rgb(148, 66, 72), Color.rgb(83, 19, 20), Color.rgb(7, 6, 14), Color.rgb(254, 139, 146), Color.rgb(254, 139, 146, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
47 | DARKBLUE(Color.rgb(14, 24, 31), Color.rgb(46, 105, 144), Color.rgb(19, 64, 96), Color.rgb(6, 20, 29), Color.rgb(8, 9, 10), Color.rgb(61, 179, 255), Color.rgb(61, 179, 255, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
48 | PURPLE(Color.rgb(175, 164, 255), Color.rgb(188, 168, 253), Color.rgb(176, 159, 255), Color.rgb(174, 147, 252), Color.rgb(168, 136, 233), Color.rgb(7, 97, 72), Color.rgb(7, 97, 72, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
49 | BLACK_RED(Color.rgb(8, 12, 11), Color.rgb(10, 11, 13), Color.rgb(11, 10, 15), Color.rgb(7, 13, 9), Color.rgb(9, 13, 14), Color.rgb(181, 0, 38), Color.rgb(181, 0, 38, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
50 | DARKGREEN(Color.rgb(25, 85, 0), Color.rgb(47, 154, 0), Color.rgb(30, 101, 0), Color.rgb(30, 101, 0), Color.rgb(25, 85, 0), Color.rgb(35, 49, 35), Color.rgb(35, 49, 35, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
51 | AMBER(Color.rgb(182, 71, 0), Color.rgb(236, 155, 25), Color.rgb(212, 93, 5), Color.rgb(212, 93, 5), Color.rgb(182, 71, 0), Color.rgb(89, 58, 10), Color.rgb(89, 58, 10, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
52 | LIGHTBLUE(Color.rgb(125, 146, 184), Color.rgb(197, 212, 231), Color.rgb(138, 155, 194), Color.rgb(138, 155, 194), Color.rgb(125, 146, 184), Color.rgb(9, 0, 81), Color.rgb(9, 0, 81, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
53 | GREEN_BLACK(Color.rgb(1, 47, 0), Color.rgb(20, 106, 61), Color.rgb(33, 125, 84), Color.rgb(33, 125, 84), Color.rgb(33, 109, 63), Color.rgb(3, 15, 11), Color.rgb(3, 15, 11, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
54 | YELLOW_BLACK(Color.rgb(223, 248, 86), Color.rgb(222, 255, 28), Color.rgb(213, 245, 24), Color.rgb(213, 245, 24), Color.rgb(224, 248, 88), Color.rgb(9, 19, 0), Color.rgb(9, 19, 0, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
55 | BLACK_YELLOW(Color.rgb(43, 3, 3), Color.rgb(29, 0, 0), Color.rgb(26, 2, 2), Color.rgb(31, 5, 8), Color.rgb(30, 1, 3), Color.rgb(255, 254, 24), Color.rgb(255, 254, 24, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
56 | LIGHTGREEN_BLACK(Color.rgb(79, 121, 19), Color.rgb(96, 169, 0), Color.rgb(120, 201, 2), Color.rgb(118, 201, 0), Color.rgb(105, 179, 4), Color.rgb(0, 35, 0), Color.rgb(0, 35, 0, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
57 | DARKPURPLE(Color.rgb(35, 24, 75), Color.rgb(42, 20, 111), Color.rgb(40, 22, 103), Color.rgb(40, 22, 103), Color.rgb(41, 21, 111), Color.rgb(158, 167, 210), Color.rgb(158, 167, 210, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
58 | DARKAMBER(Color.rgb(134, 39, 17), Color.rgb(120, 24, 0), Color.rgb(83, 15, 12), Color.rgb(83, 15, 12), Color.rgb(120, 24, 0), Color.rgb(233, 140, 44), Color.rgb(233, 140, 44, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
59 | BLUE_LIGHTBLUE2(Color.rgb(15, 84, 151), Color.rgb(60, 103, 198), Color.rgb(67, 109, 209), Color.rgb(67, 109, 209), Color.rgb(64, 101, 190), Color.rgb(193, 253, 254), Color.rgb(193, 253, 254, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
60 | GRAY_PURPLE(Color.rgb(153, 164, 161), Color.rgb(203, 215, 213), Color.rgb(202, 212, 211), Color.rgb(202, 212, 211), Color.rgb(198, 209, 213), Color.rgb(99, 124, 204), Color.rgb(99, 124, 204, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
61 | YOCTOPUCE(Color.web("#0E181F"), Color.web("#232341"), Color.web("#1E1E3C"), Color.web("#1E1E3C"), Color.web("#191937"), Color.web("#99E5FF"), Color.rgb(153,229,255, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
62 | SECTIONS(Color.web("#B2B2B2"), Color.web("#FFFFFF"), Color.web("#C4C4C4"), Color.web("#C4C4C4"), Color.web("#B2B2B2"), Color.web("#000000"), Color.rgb(0, 0, 0, 0.1)) { @Override public Color[] getColors() { return this.COLORS; } },
63 | FLAT_CUSTOM(Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT, Color.TRANSPARENT, Color.WHITE, Color.TRANSPARENT) { @Override public Color[] getColors() { return this.COLORS; } };
64 |
65 |
66 | protected final Color[] COLORS;
67 | public Color lcdForegroundColor;
68 | public Color lcdBackgroundColor;
69 |
70 | public abstract Color[] getColors();
71 |
72 | LcdDesign(final Color BG0, final Color BG1, final Color BG2, final Color BG3, final Color BG4, final Color FG, final Color FGT) {
73 | COLORS = new Color[] {BG0, BG1, BG2, BG3, BG4, FG, FGT};
74 | lcdForegroundColor = FG;
75 | lcdBackgroundColor = FGT;
76 | }
77 | }
78 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/LcdFont.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa;
19 |
20 | /**
21 | * Created by hansolo on 28.01.16.
22 | */
23 | public enum LcdFont {
24 | STANDARD, LCD, DIGITAL, DIGITAL_BOLD, ELEKTRA
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/MarkerBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa;
19 |
20 | import eu.hansolo.medusa.Marker.MarkerType;
21 | import javafx.beans.property.DoubleProperty;
22 | import javafx.beans.property.ObjectProperty;
23 | import javafx.beans.property.Property;
24 | import javafx.beans.property.SimpleDoubleProperty;
25 | import javafx.beans.property.SimpleObjectProperty;
26 | import javafx.beans.property.SimpleStringProperty;
27 | import javafx.beans.property.StringProperty;
28 | import javafx.event.EventHandler;
29 | import javafx.scene.paint.Color;
30 |
31 | import java.util.HashMap;
32 |
33 |
34 | /**
35 | * Created by hansolo on 05.01.16.
36 | */
37 | public class MarkerBuilder> {
38 | private HashMap properties = new HashMap<>();
39 |
40 |
41 | // ******************** Constructors **************************************
42 | protected MarkerBuilder() {}
43 |
44 |
45 | // ******************** Methods *******************************************
46 | public static final MarkerBuilder create() {
47 | return new MarkerBuilder();
48 | }
49 |
50 | public final B value(final double VALUE) {
51 | properties.put("value", new SimpleDoubleProperty(VALUE));
52 | return (B)this;
53 | }
54 |
55 | public final B text(final String TEXT) {
56 | properties.put("text", new SimpleStringProperty(TEXT));
57 | return (B)this;
58 | }
59 |
60 | public final B color(final Color COLOR) {
61 | properties.put("color", new SimpleObjectProperty<>(COLOR));
62 | return (B)this;
63 | }
64 |
65 | public final B markerType(final MarkerType TYPE) {
66 | properties.put("markerType", new SimpleObjectProperty<>(TYPE));
67 | return (B)this;
68 | }
69 |
70 | public final B styleClass(final String STYLE_CLASS) {
71 | properties.put("styleClass", new SimpleStringProperty(STYLE_CLASS));
72 | return (B)this;
73 | }
74 |
75 | public final B onMarkerPressed(final EventHandler HANDLER) {
76 | properties.put("onMarkerPressed", new SimpleObjectProperty<>(HANDLER));
77 | return (B)this;
78 | }
79 |
80 | public final B onMarkerReleased(final EventHandler HANDLER) {
81 | properties.put("onMarkerReleased", new SimpleObjectProperty<>(HANDLER));
82 | return (B)this;
83 | }
84 |
85 | public final B onMarkerExceeded(final EventHandler HANDLER) {
86 | properties.put("onMarkerExceeded", new SimpleObjectProperty<>(HANDLER));
87 | return (B)this;
88 | }
89 |
90 | public final B onMarkerUnderrun(final EventHandler HANDLER) {
91 | properties.put("onMarkerUnderrun", new SimpleObjectProperty<>(HANDLER));
92 | return (B)this;
93 | }
94 |
95 | public final Marker build() {
96 | final Marker MARKER = new Marker();
97 | for (String key : properties.keySet()) {
98 | if ("value".equals(key)) {
99 | MARKER.setValue(((DoubleProperty) properties.get(key)).get());
100 | } else if("text".equals(key)) {
101 | MARKER.setText(((StringProperty) properties.get(key)).get());
102 | } else if ("color".equals(key)) {
103 | MARKER.setColor(((ObjectProperty) properties.get(key)).get());
104 | } else if ("markerType".equals(key)) {
105 | MARKER.setMarkerType(((ObjectProperty) properties.get(key)).get());
106 | } else if ("onMarkerPressed".equals(key)) {
107 | MARKER.setOnMarkerPressed(((ObjectProperty) properties.get(key)).get());
108 | } else if ("onMarkerReleased".equals(key)) {
109 | MARKER.setOnMarkerReleased(((ObjectProperty) properties.get(key)).get());
110 | } else if ("onMarkerExceeded".equals(key)) {
111 | MARKER.setOnMarkerExceeded(((ObjectProperty) properties.get(key)).get());
112 | } else if ("onMarkerUnderrun".equals(key)) {
113 | MARKER.setOnMarkerUnderrun(((ObjectProperty) properties.get(key)).get());
114 | } else if ("styleClass".equals(key)) {
115 | MARKER.setStyleClass(((StringProperty) properties.get(key)).get());
116 | }
117 | }
118 | return MARKER;
119 | }
120 | }
121 |
122 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/SectionBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa;
19 |
20 | import eu.hansolo.medusa.Section.SectionEvent;
21 | import javafx.beans.property.DoubleProperty;
22 | import javafx.beans.property.ObjectProperty;
23 | import javafx.beans.property.Property;
24 | import javafx.beans.property.SimpleDoubleProperty;
25 | import javafx.beans.property.SimpleObjectProperty;
26 | import javafx.beans.property.SimpleStringProperty;
27 | import javafx.beans.property.StringProperty;
28 | import javafx.event.EventHandler;
29 | import javafx.scene.image.Image;
30 | import javafx.scene.paint.Color;
31 |
32 | import java.util.HashMap;
33 |
34 |
35 | /**
36 | * Created by hansolo on 20.12.15.
37 | */
38 | public class SectionBuilder> {
39 | private HashMap properties = new HashMap<>();
40 |
41 |
42 | // ******************** Constructors **************************************
43 | protected SectionBuilder() {}
44 |
45 |
46 | // ******************** Methods *******************************************
47 | public static final SectionBuilder create() {
48 | return new SectionBuilder();
49 | }
50 |
51 | public final B start(final double VALUE) {
52 | properties.put("start", new SimpleDoubleProperty(VALUE));
53 | return (B)this;
54 | }
55 |
56 | public final B stop(final double VALUE) {
57 | properties.put("stop", new SimpleDoubleProperty(VALUE));
58 | return (B)this;
59 | }
60 |
61 | public final B text(final String TEXT) {
62 | properties.put("text", new SimpleStringProperty(TEXT));
63 | return (B)this;
64 | }
65 |
66 | public final B icon(final Image IMAGE) {
67 | properties.put("icon", new SimpleObjectProperty<>(IMAGE));
68 | return (B)this;
69 | }
70 |
71 | public final B color(final Color COLOR) {
72 | properties.put("color", new SimpleObjectProperty<>(COLOR));
73 | return (B)this;
74 | }
75 |
76 | public final B highlightColor(final Color COLOR) {
77 | properties.put("highlightColor", new SimpleObjectProperty<>(COLOR));
78 | return (B)this;
79 | }
80 |
81 | public final B textColor(final Color COLOR) {
82 | properties.put("textColor", new SimpleObjectProperty<>(COLOR));
83 | return (B)this;
84 | }
85 |
86 | public final B styleClass(final String STYLE_CLASS) {
87 | properties.put("styleClass", new SimpleStringProperty(STYLE_CLASS));
88 | return (B)this;
89 | }
90 |
91 | public final B onSectionEntered(final EventHandler HANDLER) {
92 | properties.put("onSectionEntered", new SimpleObjectProperty<>(HANDLER));
93 | return (B)this;
94 | }
95 |
96 | public final B onSectionLeft(final EventHandler HANDLER) {
97 | properties.put("onSectionLeft", new SimpleObjectProperty<>(HANDLER));
98 | return (B)this;
99 | }
100 |
101 | public final Section build() {
102 | final Section SECTION = new Section();
103 | for (String key : properties.keySet()) {
104 | if ("start".equals(key)) {
105 | SECTION.setStart(((DoubleProperty) properties.get(key)).get());
106 | } else if("stop".equals(key)) {
107 | SECTION.setStop(((DoubleProperty) properties.get(key)).get());
108 | } else if("text".equals(key)) {
109 | SECTION.setText(((StringProperty) properties.get(key)).get());
110 | } else if("icon".equals(key)) {
111 | SECTION.setIcon(((ObjectProperty) properties.get(key)).get());
112 | } else if ("color".equals(key)) {
113 | SECTION.setColor(((ObjectProperty) properties.get(key)).get());
114 | } else if ("highlightColor".equals(key)) {
115 | SECTION.setHighlightColor(((ObjectProperty) properties.get(key)).get());
116 | } else if ("textColor".equals(key)) {
117 | SECTION.setTextColor(((ObjectProperty) properties.get(key)).get());
118 | } else if ("onSectionEntered".equals(key)) {
119 | SECTION.setOnSectionEntered(((ObjectProperty) properties.get(key)).get());
120 | } else if ("onSectionLeft".equals(key)) {
121 | SECTION.setOnSectionLeft(((ObjectProperty) properties.get(key)).get());
122 | } else if ("styleClass".equals(key)) {
123 | SECTION.setStyleClass(((StringProperty) properties.get(key)).get());
124 | }
125 | }
126 | return SECTION;
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/Test.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa;
19 |
20 | import eu.hansolo.medusa.Clock.ClockSkinType;
21 | import eu.hansolo.medusa.Gauge.SkinType;
22 | import eu.hansolo.medusa.events.UpdateEvent;
23 | import eu.hansolo.medusa.events.UpdateEventListener;
24 | import eu.hansolo.medusa.tools.GradientLookup;
25 | import javafx.animation.AnimationTimer;
26 | import javafx.application.Application;
27 | import javafx.collections.ObservableList;
28 | import javafx.geometry.Insets;
29 | import javafx.geometry.Orientation;
30 | import javafx.scene.Group;
31 | import javafx.scene.Node;
32 | import javafx.scene.Parent;
33 | import javafx.scene.Scene;
34 | import javafx.scene.layout.Background;
35 | import javafx.scene.layout.BackgroundFill;
36 | import javafx.scene.layout.CornerRadii;
37 | import javafx.scene.layout.StackPane;
38 | import javafx.scene.paint.Color;
39 | import javafx.scene.paint.Stop;
40 | import javafx.stage.Stage;
41 |
42 | import java.util.Locale;
43 | import java.util.Random;
44 |
45 |
46 | public class Test extends Application {
47 | private static final Random RND = new Random();
48 | private static int noOfNodes = 0;
49 | private Gauge gauge;
50 | private long lastTimerCall;
51 | private AnimationTimer timer;
52 |
53 |
54 | @Override public void init() {
55 | gauge = GaugeBuilder.create()
56 | .skinType(SkinType.SIMPLE_DIGITAL)
57 | .prefSize(400, 400)
58 | .foregroundBaseColor(Color.web("#ebeefd"))
59 | .barBackgroundColor(Color.web("#262c49"))
60 | .decimals(2)
61 | .maxValue(200)
62 | .arcExtend(5)
63 | .gradientLookup(new GradientLookup(new Stop(0, Color.web("#8f62cb")),
64 | new Stop(0.25, Color.web("#7367f0")),
65 | new Stop(0.5, Color.web("#ad5ea5")),
66 | new Stop(0.75, Color.web("#e85456")),
67 | new Stop(1.0, Color.web("#e85456").brighter())))
68 | .gradientBarEnabled(true)
69 | .animated(true)
70 | .build();
71 |
72 | lastTimerCall = System.nanoTime();
73 | timer = new AnimationTimer() {
74 | @Override public void handle(final long now) {
75 | if (now > lastTimerCall + 2_000_000_000l) {
76 | double value = RND.nextDouble() * gauge.getRange() + gauge.getMinValue();
77 | gauge.setValue(value);
78 | lastTimerCall = now;
79 | }
80 | }
81 | };
82 | }
83 |
84 | @Override public void start(Stage stage) {
85 | StackPane pane = new StackPane(gauge);
86 | pane.setPadding(new Insets(10));
87 | pane.setBackground(new Background(new BackgroundFill(Color.web("#10163a"), CornerRadii.EMPTY, Insets.EMPTY)));
88 |
89 | Scene scene = new Scene(pane);
90 |
91 | stage.setTitle("Test");
92 | stage.setScene(scene);
93 | stage.show();
94 |
95 | // Calculate number of nodes
96 | calcNoOfNodes(pane);
97 | System.out.println(noOfNodes + " Nodes in SceneGraph");
98 |
99 | timer.start();
100 | }
101 |
102 | @Override public void stop() {
103 | System.exit(0);
104 | }
105 |
106 |
107 |
108 | // ******************** Misc **********************************************
109 | private static void calcNoOfNodes(Node node) {
110 | if (node instanceof Parent) {
111 | if (((Parent) node).getChildrenUnmodifiable().size() != 0) {
112 | ObservableList tempChildren = ((Parent) node).getChildrenUnmodifiable();
113 | noOfNodes += tempChildren.size();
114 | for (Node n : tempChildren) { calcNoOfNodes(n); }
115 | }
116 | }
117 | }
118 |
119 | public static void main(String[] args) {
120 | launch(args);
121 | }
122 | }
123 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/TestLauncher.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa;
19 |
20 | public class TestLauncher {
21 | /**
22 | *
23 | * This launcher starts the medusa test pane.
24 | *
25 | * Note: This launcher is required to make sure all openjfx java modules are linked via the classpath.
26 | *
27 | * @param args application arguments
28 | */
29 | public static void main(String[] args) {
30 | Test.main(args);
31 | }
32 | }
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/TickLabelLocation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa;
19 |
20 | /**
21 | * Created by hansolo on 28.01.16.
22 | */
23 | public enum TickLabelLocation {
24 | INSIDE, OUTSIDE
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/TickLabelOrientation.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa;
19 |
20 | /**
21 | * Created by hansolo on 28.01.16.
22 | */
23 | public enum TickLabelOrientation {
24 | ORTHOGONAL, HORIZONTAL, TANGENT
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/TickMarkType.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa;
19 |
20 | /**
21 | * Created by hansolo on 28.01.16.
22 | */
23 | public enum TickMarkType {
24 | LINE, DOT, TRAPEZOID, TRIANGLE, BOX, TICK_LABEL, PILL
25 | }
26 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/TimeSectionBuilder.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa;
19 |
20 | import eu.hansolo.medusa.TimeSection.TimeSectionEvent;
21 | import javafx.beans.property.ObjectProperty;
22 | import javafx.beans.property.Property;
23 | import javafx.beans.property.SimpleObjectProperty;
24 | import javafx.beans.property.SimpleStringProperty;
25 | import javafx.beans.property.StringProperty;
26 | import javafx.event.EventHandler;
27 | import javafx.scene.image.Image;
28 | import javafx.scene.paint.Color;
29 |
30 | import java.time.LocalTime;
31 | import java.util.HashMap;
32 |
33 |
34 | /**
35 | * Created by hansolo on 31.01.16.
36 | */
37 | public class TimeSectionBuilder> {
38 | private HashMap properties = new HashMap<>();
39 |
40 |
41 | // ******************** Constructors **************************************
42 | protected TimeSectionBuilder() {}
43 |
44 |
45 | // ******************** Methods *******************************************
46 | public static final TimeSectionBuilder create() {
47 | return new TimeSectionBuilder();
48 | }
49 |
50 | public final B start(final LocalTime VALUE) {
51 | properties.put("start", new SimpleObjectProperty<>(VALUE));
52 | return (B)this;
53 | }
54 |
55 | public final B stop(final LocalTime VALUE) {
56 | properties.put("stop", new SimpleObjectProperty<>(VALUE));
57 | return (B)this;
58 | }
59 |
60 | public final B text(final String TEXT) {
61 | properties.put("text", new SimpleStringProperty(TEXT));
62 | return (B)this;
63 | }
64 |
65 | public final B icon(final Image IMAGE) {
66 | properties.put("icon", new SimpleObjectProperty<>(IMAGE));
67 | return (B)this;
68 | }
69 |
70 | public final B color(final Color COLOR) {
71 | properties.put("color", new SimpleObjectProperty<>(COLOR));
72 | return (B)this;
73 | }
74 |
75 | public final B highlightColor(final Color COLOR) {
76 | properties.put("highlightColor", new SimpleObjectProperty<>(COLOR));
77 | return (B)this;
78 | }
79 |
80 | public final B textColor(final Color COLOR) {
81 | properties.put("textColor", new SimpleObjectProperty<>(COLOR));
82 | return (B)this;
83 | }
84 |
85 | public final B onTimeSectionEntered(final EventHandler HANDLER) {
86 | properties.put("onTimeSectionEntered", new SimpleObjectProperty<>(HANDLER));
87 | return (B)this;
88 | }
89 |
90 | public final B onTimeSectionLeft(final EventHandler HANDLER) {
91 | properties.put("onTimeSectionLeft", new SimpleObjectProperty<>(HANDLER));
92 | return (B)this;
93 | }
94 |
95 | public final TimeSection build() {
96 | final TimeSection SECTION = new TimeSection();
97 | for (String key : properties.keySet()) {
98 | if ("start".equals(key)) {
99 | SECTION.setStart(((ObjectProperty) properties.get(key)).get());
100 | } else if("stop".equals(key)) {
101 | SECTION.setStop(((ObjectProperty) properties.get(key)).get());
102 | } else if("text".equals(key)) {
103 | SECTION.setText(((StringProperty) properties.get(key)).get());
104 | } else if("icon".equals(key)) {
105 | SECTION.setIcon(((ObjectProperty) properties.get(key)).get());
106 | } else if ("color".equals(key)) {
107 | SECTION.setColor(((ObjectProperty) properties.get(key)).get());
108 | } else if ("highlightColor".equals(key)) {
109 | SECTION.setHighlightColor(((ObjectProperty) properties.get(key)).get());
110 | } else if ("textColor".equals(key)) {
111 | SECTION.setTextColor(((ObjectProperty) properties.get(key)).get());
112 | } else if ("onTimeSectionEntered".equals(key)) {
113 | SECTION.setOnTimeSectionEntered(((ObjectProperty) properties.get(key)).get());
114 | } else if ("onTimeSectionLeft".equals(key)) {
115 | SECTION.setOnTimeSectionLeft(((ObjectProperty) properties.get(key)).get());
116 | }
117 | }
118 | return SECTION;
119 | }
120 | }
121 |
122 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/events/AlarmEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.events;
19 |
20 | import eu.hansolo.medusa.Alarm;
21 |
22 | import java.util.EventObject;
23 |
24 |
25 | /**
26 | * Created by hansolo on 28.01.16.
27 | */
28 | public class AlarmEvent extends EventObject {
29 | public final Alarm ALARM;
30 |
31 |
32 | // ******************** Constructors **************************************
33 | public AlarmEvent(final Object SRC, final Alarm ALARM) {
34 | super(SRC);
35 | this.ALARM = ALARM;
36 | }
37 | }
38 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/events/AlarmEventListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.events;
19 |
20 | import java.util.EventListener;
21 |
22 |
23 | /**
24 | * Created by hansolo on 28.01.16.
25 | */
26 | @FunctionalInterface
27 | public interface AlarmEventListener extends EventListener {
28 | public void onAlarmEvent(final AlarmEvent EVENT);
29 | }
30 |
31 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/events/TimeEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.events;
19 |
20 | import java.time.ZonedDateTime;
21 | import java.util.EventObject;
22 |
23 |
24 | /**
25 | * Created by hansolo on 24.02.16.
26 | */
27 | public class TimeEvent extends EventObject {
28 | public enum TimeEventType { HOUR, MINUTE, SECOND };
29 | public final ZonedDateTime TIME;
30 | public final TimeEventType TYPE;
31 |
32 |
33 | // ******************** Constructors **************************************
34 | public TimeEvent(final Object SRC, final ZonedDateTime TIME, final TimeEventType TYPE) {
35 | super(SRC);
36 | this.TIME = TIME;
37 | this.TYPE = TYPE;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/events/TimeEventListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.events;
19 |
20 | import java.util.EventListener;
21 |
22 |
23 | /**
24 | * Created by hansolo on 24.02.16.
25 | */
26 | @FunctionalInterface
27 | public interface TimeEventListener extends EventListener {
28 | public void onTimeEvent(final TimeEvent EVENT);
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/events/UpdateEvent.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.events;
19 |
20 | import java.util.EventObject;
21 |
22 |
23 | /**
24 | * Created by hansolo on 05.01.16.
25 | */
26 | public class UpdateEvent extends EventObject {
27 | public enum EventType { RECALC, REDRAW, RESIZE, LED, LCD, VISIBILITY, INTERACTIVITY, FINISHED, SECTION, ALERT, VALUE };
28 | public final EventType eventType;
29 |
30 | public UpdateEvent(final Object SRC, final EventType EVENT_TYPE) {
31 | super(SRC);
32 | eventType = EVENT_TYPE;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/events/UpdateEventListener.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.events;
19 |
20 | import java.util.EventListener;
21 |
22 |
23 | /**
24 | * Created by hansolo on 05.01.16.
25 | */
26 | @FunctionalInterface
27 | public interface UpdateEventListener extends EventListener {
28 | public void onUpdateEvent(final UpdateEvent EVENT);
29 | }
30 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/skins/ChargeSkin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.skins;
19 |
20 | import eu.hansolo.medusa.Gauge;
21 | import javafx.application.Platform;
22 | import javafx.beans.InvalidationListener;
23 | import javafx.beans.value.ChangeListener;
24 | import javafx.geometry.Bounds;
25 | import javafx.geometry.Insets;
26 | import javafx.geometry.Pos;
27 | import javafx.scene.layout.Background;
28 | import javafx.scene.layout.BackgroundFill;
29 | import javafx.scene.layout.Border;
30 | import javafx.scene.layout.BorderStroke;
31 | import javafx.scene.layout.BorderStrokeStyle;
32 | import javafx.scene.layout.BorderWidths;
33 | import javafx.scene.layout.CornerRadii;
34 | import javafx.scene.layout.HBox;
35 | import javafx.scene.layout.Region;
36 | import javafx.scene.paint.Color;
37 | import javafx.scene.paint.CycleMethod;
38 | import javafx.scene.paint.LinearGradient;
39 | import javafx.scene.paint.Paint;
40 | import javafx.scene.paint.Stop;
41 |
42 |
43 | /**
44 | * Created by hansolo on 08.07.16.
45 | */
46 | public class ChargeSkin extends GaugeSkinBase {
47 | private enum BarColor {
48 | GRAY(Color.rgb(243, 243, 243), Color.rgb(143, 143, 143)),
49 | RED(Color.rgb(243, 0, 6), Color.rgb(143, 0, 9)),
50 | ORANGE(Color.rgb(253, 148, 21), Color.rgb(253, 97, 8)),
51 | GREEN(Color.rgb(110, 190, 5), Color.rgb(50, 177, 7));
52 |
53 | public final Color COLOR_FROM;
54 | public final Color COLOR_TO;
55 |
56 | BarColor(final Color COLOR_FROM, final Color COLOR_TO) {
57 | this.COLOR_FROM = COLOR_FROM;
58 | this.COLOR_TO = COLOR_TO;
59 | }
60 | }
61 | protected static final double PREFERRED_WIDTH = 306;
62 | protected static final double PREFERRED_HEIGHT = 66;
63 | protected static final double MINIMUM_WIDTH = 153;
64 | protected static final double MINIMUM_HEIGHT = 33;
65 | protected static final double MAXIMUM_WIDTH = 918;
66 | protected static final double MAXIMUM_HEIGHT = 198;
67 | private static double aspectRatio = PREFERRED_HEIGHT / PREFERRED_WIDTH;
68 | private Region[] bars;
69 | private Background[] barBackgrounds;
70 | private Border barBorder;
71 | private double width;
72 | private double height;
73 | private HBox pane;
74 | private Paint backgroundPaint;
75 | private Paint borderPaint;
76 | private double borderWidth;
77 | private InvalidationListener currentValueListener;
78 | private ChangeListener paneWidthListener;
79 |
80 |
81 | // ******************** Constructors **************************************
82 | public ChargeSkin(Gauge gauge) {
83 | super(gauge);
84 | backgroundPaint = Color.TRANSPARENT;
85 | borderPaint = Color.TRANSPARENT;
86 | borderWidth = 0;
87 | bars = new Region[12];
88 | barBackgrounds = new Background[24];
89 | currentValueListener = o -> handleEvents("VALUE");
90 | paneWidthListener = (o, ov, nv) -> { if (ov.intValue() == 0 && nv.intValue() > 0) Platform.runLater(() -> resize()); };
91 |
92 | initGraphics();
93 | registerListeners();
94 | }
95 |
96 |
97 | // ******************** Initialization ************************************
98 | private void initGraphics() {
99 | // Set initial size
100 | if (Double.compare(gauge.getPrefWidth(), 0.0) <= 0 || Double.compare(gauge.getPrefHeight(), 0.0) <= 0 ||
101 | Double.compare(gauge.getWidth(), 0.0) <= 0 || Double.compare(gauge.getHeight(), 0.0) <= 0) {
102 | if (gauge.getPrefWidth() > 0 && gauge.getPrefHeight() > 0) {
103 | gauge.setPrefSize(gauge.getPrefWidth(), gauge.getPrefHeight());
104 | } else {
105 | gauge.setPrefSize(PREFERRED_WIDTH, PREFERRED_HEIGHT);
106 | }
107 | }
108 |
109 | for (int i = 0 ; i < 12 ; i++) {
110 | Region bar = new Region();
111 | bar.setPrefSize(20, 20 + (i * 4));
112 | bars[i] = bar;
113 | }
114 |
115 | pane = new HBox(bars);
116 | pane.setSpacing(PREFERRED_WIDTH * 0.01960784);
117 | pane.setAlignment(Pos.BOTTOM_CENTER);
118 | pane.setFillHeight(false);
119 | pane.setBackground(new Background(new BackgroundFill(backgroundPaint, new CornerRadii(1024), Insets.EMPTY)));
120 | pane.setBorder(new Border(new BorderStroke(borderPaint, BorderStrokeStyle.SOLID, new CornerRadii(1024), new BorderWidths(borderWidth))));
121 |
122 | getChildren().setAll(pane);
123 | }
124 |
125 | @Override protected void registerListeners() {
126 | super.registerListeners();
127 | gauge.currentValueProperty().addListener(currentValueListener);
128 | pane.widthProperty().addListener(paneWidthListener);
129 | }
130 |
131 |
132 | // ******************** Methods *******************************************
133 | @Override public void layoutChildren(double x, double y, double w, double h) {
134 | super.layoutChildren(x, y, w, h);
135 | if(Double.compare(bars[0].getLayoutBounds().getWidth(), 0) == 0) resize();
136 | }
137 |
138 | @Override protected void handleEvents(final String EVENT_TYPE) {
139 | super.handleEvents(EVENT_TYPE);
140 | if ("VALUE".equals(EVENT_TYPE)) {
141 | redraw();
142 | }
143 | }
144 |
145 | @Override public void dispose() {
146 | gauge.currentValueProperty().removeListener(currentValueListener);
147 | pane.widthProperty().removeListener(paneWidthListener);
148 | super.dispose();
149 | }
150 |
151 |
152 | // ******************** Resizing ******************************************
153 | @Override protected void resize() {
154 | width = gauge.getWidth() - gauge.getInsets().getLeft() - gauge.getInsets().getRight();
155 | height = gauge.getHeight() - gauge.getInsets().getTop() - gauge.getInsets().getBottom();
156 |
157 | if (aspectRatio * width > height) {
158 | width = 1 / (aspectRatio / height);
159 | } else if (1 / (aspectRatio / height) > width) {
160 | height = aspectRatio * width;
161 | }
162 |
163 | if (width > 0 && height > 0) {
164 | pane.setMaxSize(width, height);
165 | pane.setPrefSize(width, height);
166 | pane.relocate((gauge.getWidth() - width) * 0.5, (gauge.getHeight() - height) * 0.5);
167 | pane.setSpacing(width * 0.01960784);
168 |
169 | double barWidth = 0;
170 | for (int i = 0 ; i < 12 ; i++) {
171 | bars[i].setPrefSize(0.3030303 * height, (0.3030303 * height + i * 0.06060606 * height));
172 | Bounds bounds = bars[i].getLayoutBounds();
173 | barWidth = bounds.getWidth();
174 | if (barWidth == 0) return;
175 |
176 | BarColor barColor;
177 | if (i < 2) {
178 | barColor = BarColor.RED;
179 | } else if (i < 9) {
180 | barColor = BarColor.ORANGE;
181 | } else {
182 | barColor = BarColor.GREEN;
183 | }
184 | barBackgrounds[i] = new Background(new BackgroundFill[] {
185 | new BackgroundFill(Color.WHITE, new CornerRadii(1024), Insets.EMPTY),
186 | new BackgroundFill(new LinearGradient(0, bounds.getMinY(), 0, bounds.getMaxY(), false, CycleMethod.NO_CYCLE, new Stop(0.0, barColor.COLOR_FROM), new Stop(1.0, barColor.COLOR_TO)), new CornerRadii(1024), new Insets(0.15 * barWidth))
187 | });
188 | barBackgrounds[i + 12] = new Background(new BackgroundFill[] {
189 | new BackgroundFill(Color.WHITE, new CornerRadii(1024), Insets.EMPTY),
190 | new BackgroundFill(new LinearGradient(0, bounds.getMinY(), 0, bounds.getMaxY(), false, CycleMethod.NO_CYCLE, new Stop(0.0, BarColor.GRAY.COLOR_FROM), new Stop(1.0, BarColor.GRAY.COLOR_TO)), new CornerRadii(1024), new Insets(0.15 * barWidth))
191 | });
192 | }
193 | barBorder = new Border(new BorderStroke(Color.rgb(102, 102, 102), BorderStrokeStyle.SOLID, new CornerRadii(1024), new BorderWidths(0.05 * barWidth)));
194 | }
195 | redraw();
196 | }
197 |
198 | @Override protected void redraw() {
199 | int chargedBars = (int) (gauge.getCurrentValue() * 13);
200 | for (int i = 0 ; i < 12 ; i++) {
201 | bars[i].setBackground(i < chargedBars ? barBackgrounds[i] : barBackgrounds[i + 12]);
202 | bars[i].setBorder(barBorder);
203 | }
204 | }
205 | }
206 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/skins/ClockSkinBase.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.skins;
19 |
20 | import eu.hansolo.medusa.Alarm;
21 | import eu.hansolo.medusa.Clock;
22 | import eu.hansolo.medusa.events.UpdateEventListener;
23 | import javafx.beans.InvalidationListener;
24 | import javafx.collections.ListChangeListener;
25 | import javafx.scene.control.Skin;
26 | import javafx.scene.control.SkinBase;
27 |
28 | import java.time.Instant;
29 | import java.time.ZoneId;
30 | import java.time.ZonedDateTime;
31 |
32 |
33 | /**
34 | * Created by hansolo on 20.01.17.
35 | */
36 | public abstract class ClockSkinBase extends SkinBase implements Skin {
37 | protected static final double PREFERRED_WIDTH = 250;
38 | protected static final double PREFERRED_HEIGHT = 250;
39 | protected static final double MINIMUM_WIDTH = 50;
40 | protected static final double MINIMUM_HEIGHT = 50;
41 | protected static final double MAXIMUM_WIDTH = 1024;
42 | protected static final double MAXIMUM_HEIGHT = 1024;
43 |
44 | protected Clock clock;
45 | protected InvalidationListener sizeListener;
46 | protected UpdateEventListener updateEventListener;
47 | protected InvalidationListener currentTimeListener;
48 | protected InvalidationListener timeListener;
49 | protected ListChangeListener alarmListener;
50 |
51 |
52 | // ******************** Constructors **************************************
53 | public ClockSkinBase(final Clock CLOCK) {
54 | super(CLOCK);
55 |
56 | clock = CLOCK;
57 | sizeListener = o -> handleEvents("RESIZE");
58 | updateEventListener = e -> handleEvents(e.eventType.name());
59 | currentTimeListener = o -> updateTime(ZonedDateTime.ofInstant(Instant.ofEpochSecond(clock.getCurrentTime()), ZoneId.of(ZoneId.systemDefault().getId())));
60 | timeListener = o -> updateTime(clock.getTime());
61 | alarmListener = c -> {
62 | updateAlarms();
63 | redraw();
64 | };
65 | }
66 |
67 |
68 | // ******************** Initialization ************************************
69 | protected abstract void initGraphics();
70 |
71 | protected void registerListeners() {
72 | clock.widthProperty().addListener(sizeListener);
73 | clock.heightProperty().addListener(sizeListener);
74 | clock.setOnUpdate(updateEventListener);
75 | if (clock.isAnimated()) {
76 | clock.currentTimeProperty().addListener(currentTimeListener);
77 | } else {
78 | clock.timeProperty().addListener(timeListener);
79 | }
80 | clock.getAlarms().addListener(alarmListener);
81 | }
82 |
83 |
84 | // ******************** Methods *******************************************
85 | @Override protected double computeMinWidth(final double HEIGHT, final double TOP, final double RIGHT, final double BOTTOM, final double LEFT) { return MINIMUM_WIDTH; }
86 | @Override protected double computeMinHeight(final double WIDTH, final double TOP, final double RIGHT, final double BOTTOM, final double LEFT) { return MINIMUM_HEIGHT; }
87 | @Override protected double computePrefWidth(final double HEIGHT, final double TOP, final double RIGHT, final double BOTTOM, final double LEFT) { return super.computePrefWidth(HEIGHT, TOP, RIGHT, BOTTOM, LEFT); }
88 | @Override protected double computePrefHeight(final double WIDTH, final double TOP, final double RIGHT, final double BOTTOM, final double LEFT) { return super.computePrefHeight(WIDTH, TOP, RIGHT, BOTTOM, LEFT); }
89 | @Override protected double computeMaxWidth(final double HEIGHT, final double TOP, final double RIGHT, final double BOTTOM, final double LEFT) { return MAXIMUM_WIDTH; }
90 | @Override protected double computeMaxHeight(final double WIDTH, final double TOP, final double RIGHT, final double BOTTOM, final double LEFT) { return MAXIMUM_HEIGHT; }
91 |
92 | protected void handleEvents(final String EVENT_TYPE) {
93 | if ("RESIZE".equals(EVENT_TYPE)) {
94 | resize();
95 | redraw();
96 | } else if ("REDRAW".equals(EVENT_TYPE)) {
97 | redraw();
98 | }
99 | }
100 |
101 | @Override public void dispose() {
102 | clock.widthProperty().removeListener(sizeListener);
103 | clock.heightProperty().removeListener(sizeListener);
104 | clock.removeUpdateEventListener(updateEventListener);
105 | if (clock.isAnimated()) {
106 | clock.currentTimeProperty().removeListener(currentTimeListener);
107 | } else {
108 | clock.timeProperty().removeListener(timeListener);
109 | }
110 | clock.getAlarms().removeListener(alarmListener);
111 | clock = null;
112 | }
113 |
114 |
115 | // ******************** Graphics ******************************************
116 | public abstract void updateTime(final ZonedDateTime TIME);
117 |
118 | public abstract void updateAlarms();
119 |
120 |
121 | // ******************** Resizing ******************************************
122 | protected abstract void resize();
123 |
124 | protected abstract void redraw();
125 | }
126 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/skins/DigitalClockSkin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.skins;
19 |
20 | import eu.hansolo.medusa.Clock;
21 | import eu.hansolo.medusa.Fonts;
22 | import eu.hansolo.medusa.tools.Helper;
23 | import javafx.geometry.Insets;
24 | import javafx.geometry.VPos;
25 | import javafx.scene.canvas.Canvas;
26 | import javafx.scene.canvas.GraphicsContext;
27 | import javafx.scene.layout.Background;
28 | import javafx.scene.layout.BackgroundFill;
29 | import javafx.scene.layout.Border;
30 | import javafx.scene.layout.BorderStroke;
31 | import javafx.scene.layout.BorderStrokeStyle;
32 | import javafx.scene.layout.BorderWidths;
33 | import javafx.scene.layout.CornerRadii;
34 | import javafx.scene.layout.Pane;
35 | import javafx.scene.paint.Color;
36 | import javafx.scene.text.TextAlignment;
37 |
38 | import java.time.ZonedDateTime;
39 | import java.time.format.DateTimeFormatter;
40 | import java.util.Locale;
41 |
42 |
43 | /**
44 | * Created by hansolo on 11.08.16.
45 | */
46 | public class DigitalClockSkin extends ClockSkinBase {
47 | protected static final double PREFERRED_WIDTH = 250;
48 | protected static final double PREFERRED_HEIGHT = 100;
49 | protected static final double MINIMUM_WIDTH = 50;
50 | protected static final double MINIMUM_HEIGHT = 20;
51 | protected static final double MAXIMUM_WIDTH = 1024;
52 | protected static final double MAXIMUM_HEIGHT = 1024;
53 | private static final DateTimeFormatter HHMM_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");
54 | private static final DateTimeFormatter HHMMSS_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");
55 | private static final DateTimeFormatter AMPM_HHMM_FORMATTER = DateTimeFormatter.ofPattern("hh:mm a");
56 | private static final DateTimeFormatter AMPM_HHMMSS_FORMATTER = DateTimeFormatter.ofPattern("hh:mm:ss a");
57 | private double aspectRatio = 0.4;
58 | private double width;
59 | private double height;
60 | private double centerX;
61 | private double centerY;
62 | private DateTimeFormatter dateFormat;
63 | private Pane pane;
64 | private Canvas canvas;
65 | private GraphicsContext ctx;
66 | private Color textColor;
67 | private Color dateColor;
68 | private Color alarmColor;
69 |
70 |
71 | // ******************** Constructors **************************************
72 | public DigitalClockSkin(Clock clock) {
73 | super(clock);
74 | textColor = clock.getTextColor();
75 | dateColor = clock.getDateColor();
76 | alarmColor = clock.getAlarmColor();
77 | dateFormat = Helper.getDateFormat(clock.getLocale());
78 |
79 | initGraphics();
80 | registerListeners();
81 | }
82 |
83 |
84 | // ******************** Initialization ************************************
85 | @Override protected void initGraphics() {
86 | // Set initial size
87 | if (Double.compare(clock.getPrefWidth(), 0.0) <= 0 || Double.compare(clock.getPrefHeight(), 0.0) <= 0 ||
88 | Double.compare(clock.getWidth(), 0.0) <= 0 || Double.compare(clock.getHeight(), 0.0) <= 0) {
89 | if (clock.getPrefWidth() > 0 && clock.getPrefHeight() > 0) {
90 | clock.setPrefSize(clock.getPrefWidth(), clock.getPrefHeight());
91 | } else {
92 | clock.setPrefSize(PREFERRED_WIDTH, PREFERRED_HEIGHT);
93 | }
94 | }
95 |
96 | canvas = new Canvas(PREFERRED_WIDTH, PREFERRED_HEIGHT);
97 | ctx = canvas.getGraphicsContext2D();
98 |
99 | pane = new Pane(canvas);
100 | pane.setBorder(new Border(new BorderStroke(clock.getBorderPaint(), BorderStrokeStyle.SOLID, CornerRadii.EMPTY, new BorderWidths(clock.getBorderWidth()))));
101 | pane.setBackground(new Background(new BackgroundFill(clock.getBackgroundPaint(), CornerRadii.EMPTY, Insets.EMPTY)));
102 |
103 | getChildren().setAll(pane);
104 | }
105 |
106 | @Override protected void registerListeners() {
107 | super.registerListeners();
108 | }
109 |
110 |
111 | // ******************** Methods *******************************************
112 | @Override protected void handleEvents(final String EVENT_TYPE) {
113 | super.handleEvents(EVENT_TYPE);
114 | if ("VISIBILITY".equals(EVENT_TYPE)) {
115 |
116 | } else if ("SECTION".equals(EVENT_TYPE)) {
117 | redraw();
118 | }
119 | }
120 |
121 |
122 | // ******************** Canvas ********************************************
123 | private void drawTime(final ZonedDateTime TIME) {
124 | ctx.clearRect(0, 0, width, height);
125 |
126 | // draw the time
127 | if (clock.isTextVisible()) {
128 | ctx.setFill(textColor);
129 | ctx.setTextBaseline(VPos.CENTER);
130 | ctx.setTextAlign(TextAlignment.CENTER);
131 | if (Locale.US == clock.getLocale()) {
132 | ctx.setFont(Fonts.digital(0.5 * height));
133 | ctx.fillText(clock.isSecondsVisible() ? AMPM_HHMMSS_FORMATTER.format(TIME) : AMPM_HHMM_FORMATTER.format(TIME), centerX, clock.isDateVisible() ? height * 0.35 : centerY);
134 | } else {
135 | ctx.setFont(Fonts.digital(0.6 * height));
136 | ctx.fillText(clock.isSecondsVisible() ? HHMMSS_FORMATTER.format(TIME) : HHMM_FORMATTER.format(TIME), centerX, clock.isDateVisible() ? height * 0.3 : centerY);
137 | }
138 | }
139 |
140 | // draw the date
141 | if (clock.isDateVisible()) {
142 | ctx.setFill(dateColor);
143 | ctx.setFont(Fonts.digital(0.34 * height));
144 | ctx.fillText(dateFormat.format(TIME), centerX, height * 0.77);
145 | }
146 |
147 | // draw the alarmOn icon
148 | if (clock.isAlarmsEnabled() && clock.getAlarms().size() > 0) { ctx.setFill(alarmColor); }
149 |
150 | }
151 |
152 | @Override public void updateTime(final ZonedDateTime TIME) {
153 | drawTime(TIME);
154 | }
155 |
156 | @Override public void updateAlarms() {}
157 |
158 |
159 | // ******************** Resizing ******************************************
160 | @Override protected void resize() {
161 | width = clock.getWidth() - clock.getInsets().getLeft() - clock.getInsets().getRight();
162 | height = clock.getHeight() - clock.getInsets().getTop() - clock.getInsets().getBottom();
163 |
164 | if (aspectRatio * width > height) {
165 | width = 1 / (aspectRatio / height);
166 | } else if (1 / (aspectRatio / height) > width) {
167 | height = aspectRatio * width;
168 | }
169 |
170 | centerX = width * 0.5;
171 | centerY = height * 0.5;
172 |
173 | if (width > 0 && height > 0) {
174 | pane.setMaxSize(width, height);
175 | pane.relocate((clock.getWidth() - height) * 0.5, (clock.getHeight() - height) * 0.5);
176 |
177 | canvas.setWidth(width);
178 | canvas.setHeight(height);
179 | }
180 | }
181 |
182 | @Override protected void redraw() {
183 | pane.setBorder(new Border(new BorderStroke(clock.getBorderPaint(), BorderStrokeStyle.SOLID, CornerRadii.EMPTY, new BorderWidths(clock.getBorderWidth() / PREFERRED_WIDTH * height))));
184 | pane.setBackground(new Background(new BackgroundFill(clock.getBackgroundPaint(), CornerRadii.EMPTY, Insets.EMPTY)));
185 | ZonedDateTime time = clock.getTime();
186 |
187 | textColor = clock.getTextColor();
188 | dateColor = clock.getDateColor();
189 | alarmColor = clock.getAlarmColor();
190 |
191 | drawTime(time);
192 | }
193 | }
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/skins/GaugeSkinBase.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.skins;
19 |
20 | import eu.hansolo.medusa.Gauge;
21 | import eu.hansolo.medusa.events.UpdateEventListener;
22 | import javafx.beans.InvalidationListener;
23 | import javafx.scene.control.Skin;
24 | import javafx.scene.control.SkinBase;
25 |
26 |
27 | /**
28 | * Created by hansolo on 20.01.17.
29 | */
30 | public abstract class GaugeSkinBase extends SkinBase implements Skin {
31 | protected static final double PREFERRED_WIDTH = 250;
32 | protected static final double PREFERRED_HEIGHT = 250;
33 | protected static final double MINIMUM_WIDTH = 50;
34 | protected static final double MINIMUM_HEIGHT = 50;
35 | protected static final double MAXIMUM_WIDTH = 1024;
36 | protected static final double MAXIMUM_HEIGHT = 1024;
37 | protected Gauge gauge;
38 | protected InvalidationListener sizeListener;
39 | protected UpdateEventListener updateEventListener;
40 |
41 |
42 | protected GaugeSkinBase(final Gauge GAUGE) {
43 | super(GAUGE);
44 | gauge = GAUGE;
45 | sizeListener = o -> handleEvents("RESIZE");
46 | updateEventListener = e -> handleEvents(e.eventType.name());
47 | }
48 |
49 | protected void registerListeners() {
50 | getSkinnable().widthProperty().addListener(sizeListener);
51 | getSkinnable().heightProperty().addListener(sizeListener);
52 | getSkinnable().setOnUpdate(updateEventListener);
53 | }
54 |
55 | protected void handleEvents(final String EVENT_TYPE) {
56 | if ("RESIZE".equals(EVENT_TYPE)) {
57 | resize();
58 | redraw();
59 | } else if ("REDRAW".equals(EVENT_TYPE)) {
60 | redraw();
61 | }
62 | }
63 |
64 |
65 | // ******************** Methods *******************************************
66 | @Override protected double computeMinWidth(final double HEIGHT, final double TOP, final double RIGHT, final double BOTTOM, final double LEFT) { return MINIMUM_WIDTH; }
67 | @Override protected double computeMinHeight(final double WIDTH, final double TOP, final double RIGHT, final double BOTTOM, final double LEFT) { return MINIMUM_HEIGHT; }
68 | @Override protected double computePrefWidth(final double HEIGHT, final double TOP, final double RIGHT, final double BOTTOM, final double LEFT) { return super.computePrefWidth(HEIGHT, TOP, RIGHT, BOTTOM, LEFT); }
69 | @Override protected double computePrefHeight(final double WIDTH, final double TOP, final double RIGHT, final double BOTTOM, final double LEFT) { return super.computePrefHeight(WIDTH, TOP, RIGHT, BOTTOM, LEFT); }
70 | @Override protected double computeMaxWidth(final double HEIGHT, final double TOP, final double RIGHT, final double BOTTOM, final double LEFT) { return MAXIMUM_WIDTH; }
71 | @Override protected double computeMaxHeight(final double WIDTH, final double TOP, final double RIGHT, final double BOTTOM, final double LEFT) { return MAXIMUM_HEIGHT; }
72 |
73 | @Override public void dispose() {
74 | gauge.widthProperty().removeListener(sizeListener);
75 | gauge.heightProperty().removeListener(sizeListener);
76 | gauge.removeUpdateEventListener(updateEventListener);
77 | }
78 |
79 | protected void resize() {}
80 |
81 | protected void redraw() {}
82 | }
83 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/skins/SlimClockSkin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.skins;
19 |
20 | import eu.hansolo.medusa.Clock;
21 | import eu.hansolo.medusa.Fonts;
22 | import eu.hansolo.medusa.tools.Helper;
23 | import javafx.geometry.Insets;
24 | import javafx.scene.layout.Background;
25 | import javafx.scene.layout.BackgroundFill;
26 | import javafx.scene.layout.Border;
27 | import javafx.scene.layout.BorderStroke;
28 | import javafx.scene.layout.BorderStrokeStyle;
29 | import javafx.scene.layout.BorderWidths;
30 | import javafx.scene.layout.CornerRadii;
31 | import javafx.scene.layout.Pane;
32 | import javafx.scene.shape.Arc;
33 | import javafx.scene.shape.Circle;
34 | import javafx.scene.shape.StrokeLineCap;
35 | import javafx.scene.shape.StrokeType;
36 | import javafx.scene.text.Text;
37 |
38 | import java.time.ZonedDateTime;
39 | import java.time.format.DateTimeFormatter;
40 | import java.time.temporal.ChronoField;
41 |
42 |
43 | /**
44 | * Created by hansolo on 11.02.16.
45 | */
46 | public class SlimClockSkin extends ClockSkinBase {
47 | private static final DateTimeFormatter HOUR_FORMATTER = DateTimeFormatter.ofPattern("HH");
48 | private static final DateTimeFormatter MINUTE_FORMATTER = DateTimeFormatter.ofPattern("mm");
49 | private DateTimeFormatter dateTextFormatter;
50 | private DateTimeFormatter dateNumberFormatter;
51 | private double size;
52 | private Circle secondBackgroundCircle;
53 | private Text dateText;
54 | private Text dateNumbers;
55 | private Text hour;
56 | private Text minute;
57 | private Arc secondArc;
58 | private Pane pane;
59 |
60 |
61 | // ******************** Constructors **************************************
62 | public SlimClockSkin(Clock clock) {
63 | super(clock);
64 |
65 | dateTextFormatter = DateTimeFormatter.ofPattern("cccc", clock.getLocale());
66 | dateNumberFormatter = Helper.getLocalizedDateFormat(clock.getLocale());
67 |
68 | initGraphics();
69 | registerListeners();
70 | }
71 |
72 |
73 | // ******************** Initialization ************************************
74 | @Override protected void initGraphics() {
75 | // Set initial size
76 | if (Double.compare(clock.getPrefWidth(), 0.0) <= 0 || Double.compare(clock.getPrefHeight(), 0.0) <= 0 ||
77 | Double.compare(clock.getWidth(), 0.0) <= 0 || Double.compare(clock.getHeight(), 0.0) <= 0) {
78 | if (clock.getPrefWidth() > 0 && clock.getPrefHeight() > 0) {
79 | clock.setPrefSize(clock.getPrefWidth(), clock.getPrefHeight());
80 | } else {
81 | clock.setPrefSize(PREFERRED_WIDTH, PREFERRED_HEIGHT);
82 | }
83 | }
84 |
85 | ZonedDateTime time = clock.getTime();
86 |
87 | secondBackgroundCircle = new Circle(PREFERRED_WIDTH * 0.5, PREFERRED_HEIGHT * 0.5, PREFERRED_WIDTH * 0.48);
88 | secondBackgroundCircle.setStrokeWidth(PREFERRED_WIDTH * 0.008);
89 | secondBackgroundCircle.setStrokeType(StrokeType.CENTERED);
90 | secondBackgroundCircle.setStrokeLineCap(StrokeLineCap.ROUND);
91 | secondBackgroundCircle.setFill(null);
92 | secondBackgroundCircle.setStroke(Helper.getTranslucentColorFrom(clock.getSecondColor(), 0.2));
93 | secondBackgroundCircle.setVisible(clock.isSecondsVisible());
94 | secondBackgroundCircle.setManaged(clock.isSecondsVisible());
95 |
96 | dateText = new Text(dateTextFormatter.format(time));
97 | dateText.setVisible(clock.isDayVisible());
98 | dateText.setManaged(clock.isDayVisible());
99 |
100 | dateNumbers = new Text(dateNumberFormatter.format(time));
101 | dateNumbers.setVisible(clock.isDateVisible());
102 | dateNumbers.setManaged(clock.isDateVisible());
103 |
104 | hour = new Text(HOUR_FORMATTER.format(time));
105 | hour.setFill(clock.getHourColor());
106 |
107 | minute = new Text(MINUTE_FORMATTER.format(time));
108 | minute.setFill(clock.getMinuteColor());
109 |
110 | secondArc = new Arc(PREFERRED_WIDTH * 0.5, PREFERRED_HEIGHT * 0.5, PREFERRED_WIDTH * 0.96, PREFERRED_WIDTH * 0.48, 90, (-6 * clock.getTime().getSecond()));
111 | secondArc.setStrokeWidth(PREFERRED_WIDTH * 0.008);
112 | secondArc.setStrokeType(StrokeType.CENTERED);
113 | secondArc.setStrokeLineCap(StrokeLineCap.ROUND);
114 | secondArc.setFill(null);
115 | secondArc.setStroke(clock.getSecondColor());
116 | secondArc.setVisible(clock.isSecondsVisible());
117 | secondArc.setManaged(clock.isSecondsVisible());
118 |
119 | pane = new Pane(secondBackgroundCircle, dateText, dateNumbers, hour, minute, secondArc);
120 | pane.setBorder(new Border(new BorderStroke(clock.getBorderPaint(), BorderStrokeStyle.SOLID, new CornerRadii(1024), new BorderWidths(clock.getBorderWidth()))));
121 | pane.setBackground(new Background(new BackgroundFill(clock.getBackgroundPaint(), new CornerRadii(1024), Insets.EMPTY)));
122 |
123 | getChildren().setAll(pane);
124 | }
125 |
126 | @Override protected void registerListeners() {
127 | super.registerListeners();
128 | }
129 |
130 |
131 | // ******************** Methods *******************************************
132 | @Override protected void handleEvents(final String EVENT_TYPE) {
133 | super.handleEvents(EVENT_TYPE);
134 | if ("VISIBILITY".equals(EVENT_TYPE)) {
135 | boolean isDateVisible = clock.isDateVisible();
136 | boolean isDayVisible = clock.isDayVisible();
137 | dateText.setVisible(isDayVisible);
138 | dateText.setManaged(isDayVisible);
139 | dateNumbers.setVisible(isDateVisible);
140 | dateNumbers.setManaged(isDateVisible);
141 | boolean isSecondsVisible = clock.isSecondsVisible();
142 | secondBackgroundCircle.setVisible(isSecondsVisible);
143 | secondBackgroundCircle.setManaged(isSecondsVisible);
144 | secondArc.setVisible(isSecondsVisible);
145 | secondArc.setManaged(isSecondsVisible);
146 | } else if ("FINISHED".equals(EVENT_TYPE)) {
147 |
148 | }
149 | }
150 |
151 |
152 | // ******************** Graphics ******************************************
153 | @Override public void updateTime(final ZonedDateTime TIME) {
154 | if (dateText.isVisible()) {
155 | dateText.setText(dateTextFormatter.format(TIME));
156 | Helper.adjustTextSize(dateText, 0.6 * size, size * 0.08);
157 | dateText.relocate((size - dateText.getLayoutBounds().getWidth()) * 0.5, size * 0.22180451);
158 | }
159 | if (dateNumbers.isVisible()) {
160 | dateNumbers.setText(dateNumberFormatter.format(TIME));
161 | Helper.adjustTextSize(dateNumbers, 0.6 * size, size * 0.08);
162 | dateNumbers.relocate((size -dateNumbers.getLayoutBounds().getWidth()) * 0.5, size * 0.68984962);
163 | }
164 |
165 | hour.setText(HOUR_FORMATTER.format(TIME));
166 | Helper.adjustTextSize(hour, 0.4 * size, 0.328 * size);
167 | hour.relocate(0.136 * size, (size - hour.getLayoutBounds().getHeight()) * 0.5);
168 |
169 | minute.setText(MINUTE_FORMATTER.format(TIME));
170 | Helper.adjustTextSize(minute, 0.4 * size, 0.328 * size);
171 | minute.relocate(0.544 * size, (size - minute.getLayoutBounds().getHeight()) * 0.5);
172 |
173 | if (secondBackgroundCircle.isVisible()) {
174 | secondArc.setLength((-6 * TIME.getSecond()));
175 | if (clock.isDiscreteSeconds()) {
176 | secondArc.setLength((-6 * TIME.getSecond()));
177 | } else {
178 | secondArc.setLength((-6 * TIME.getSecond() -TIME.get(ChronoField.MILLI_OF_SECOND) * 0.006));
179 | }
180 | }
181 | }
182 |
183 | @Override public void updateAlarms() {
184 |
185 | }
186 |
187 |
188 | // ******************** Resizing ******************************************
189 | @Override protected void resize() {
190 | double width = clock.getWidth() - clock.getInsets().getLeft() - clock.getInsets().getRight();
191 | double height = clock.getHeight() - clock.getInsets().getTop() - clock.getInsets().getBottom();
192 | size = width < height ? width : height;
193 |
194 | if (size > 0) {
195 | double center = size * 0.5;
196 |
197 | pane.setMaxSize(size, size);
198 | pane.relocate((clock.getWidth() - size) * 0.5, (clock.getHeight() - size) * 0.5);
199 |
200 | secondBackgroundCircle.setCenterX(center);
201 | secondBackgroundCircle.setCenterY(center);
202 | secondBackgroundCircle.setRadius(size * 0.48590226);
203 | secondBackgroundCircle.setStrokeWidth(size * 0.02819549);
204 |
205 | secondArc.setCenterX(center);
206 | secondArc.setCenterY(center);
207 | secondArc.setRadiusX(size * 0.48590226);
208 | secondArc.setRadiusY(size * 0.48590226);
209 | secondArc.setStrokeWidth(size * 0.02819549);
210 |
211 | dateText.setFont(Fonts.robotoLight(size * 0.08082707));
212 | dateNumbers.setFont(Fonts.robotoLight(size * 0.08082707));
213 |
214 | hour.setFont(Fonts.robotoMedium(size * 0.328));
215 | minute.setFont(Fonts.robotoThin(size * 0.328));
216 | }
217 | }
218 |
219 | @Override protected void redraw() {
220 | pane.setBorder(new Border(new BorderStroke(clock.getBorderPaint(), BorderStrokeStyle.SOLID, new CornerRadii(1024), new BorderWidths(clock.getBorderWidth() / 250 * size))));
221 | pane.setBackground(new Background(new BackgroundFill(clock.getBackgroundPaint(), new CornerRadii(1024), Insets.EMPTY)));
222 |
223 | secondBackgroundCircle.setStroke(Helper.getTranslucentColorFrom(clock.getSecondColor(), 0.2));
224 | secondArc.setStroke(clock.getSecondColor());
225 |
226 | hour.setFill(clock.getHourColor());
227 | minute.setFill(clock.getMinuteColor());
228 |
229 | dateText.setFill(clock.getDateColor());
230 | dateNumbers.setFill(clock.getDateColor());
231 |
232 | hour.setFill(clock.getHourColor());
233 | minute.setFill(clock.getMinuteColor());
234 |
235 | ZonedDateTime time = clock.getTime();
236 | updateTime(time);
237 | }
238 | }
239 |
240 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/skins/TextClockSkin.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.skins;
19 |
20 | import eu.hansolo.medusa.Clock;
21 | import eu.hansolo.medusa.Fonts;
22 | import eu.hansolo.medusa.tools.Helper;
23 | import javafx.geometry.Insets;
24 | import javafx.geometry.VPos;
25 | import javafx.scene.layout.Background;
26 | import javafx.scene.layout.BackgroundFill;
27 | import javafx.scene.layout.Border;
28 | import javafx.scene.layout.BorderStroke;
29 | import javafx.scene.layout.BorderStrokeStyle;
30 | import javafx.scene.layout.BorderWidths;
31 | import javafx.scene.layout.CornerRadii;
32 | import javafx.scene.layout.Pane;
33 | import javafx.scene.paint.Color;
34 | import javafx.scene.text.Font;
35 | import javafx.scene.text.Text;
36 |
37 | import java.time.ZonedDateTime;
38 | import java.time.format.DateTimeFormatter;
39 | import java.util.Locale;
40 |
41 |
42 | /**
43 | * Created by hansolo on 29.09.16.
44 | */
45 | public class TextClockSkin extends ClockSkinBase {
46 | protected static final double PREFERRED_WIDTH = 250;
47 | protected static final double PREFERRED_HEIGHT = 100;
48 | protected static final double MINIMUM_WIDTH = 50;
49 | protected static final double MINIMUM_HEIGHT = 20;
50 | protected static final double MAXIMUM_WIDTH = 1024;
51 | protected static final double MAXIMUM_HEIGHT = 1024;
52 | private static final DateTimeFormatter HHMM_FORMATTER = DateTimeFormatter.ofPattern("HH:mm");
53 | private static final DateTimeFormatter HHMMSS_FORMATTER = DateTimeFormatter.ofPattern("HH:mm:ss");
54 | private static final DateTimeFormatter AMPM_HHMM_FORMATTER = DateTimeFormatter.ofPattern("hh:mm a");
55 | private static final DateTimeFormatter AMPM_HHMMSS_FORMATTER = DateTimeFormatter.ofPattern("hh:mm:ss a");
56 | private double aspectRatio = 0.4;
57 | private double width;
58 | private double height;
59 | private DateTimeFormatter dateFormat;
60 | private Text timeText;
61 | private Text dateText;
62 | private Pane pane;
63 | private Color textColor;
64 | private Color dateColor;
65 | private Font customFont;
66 |
67 |
68 | // ******************** Constructors **************************************
69 | public TextClockSkin(Clock clock) {
70 | super(clock);
71 | textColor = clock.getTextColor();
72 | dateColor = clock.getDateColor();
73 | dateFormat = Helper.getDateFormat(clock.getLocale());
74 | customFont = clock.getCustomFont();
75 |
76 | initGraphics();
77 | registerListeners();
78 | }
79 |
80 |
81 | // ******************** Initialization ************************************
82 | @Override protected void initGraphics() {
83 | // Set initial size
84 | if (Double.compare(clock.getPrefWidth(), 0.0) <= 0 || Double.compare(clock.getPrefHeight(), 0.0) <= 0 ||
85 | Double.compare(clock.getWidth(), 0.0) <= 0 || Double.compare(clock.getHeight(), 0.0) <= 0) {
86 | if (clock.getPrefWidth() > 0 && clock.getPrefHeight() > 0) {
87 | clock.setPrefSize(clock.getPrefWidth(), clock.getPrefHeight());
88 | } else {
89 | clock.setPrefSize(PREFERRED_WIDTH, PREFERRED_HEIGHT);
90 | }
91 | }
92 |
93 | timeText = new Text();
94 | timeText.setTextOrigin(VPos.CENTER);
95 | timeText.setFill(textColor);
96 |
97 | dateText = new Text();
98 | dateText.setTextOrigin(VPos.CENTER);
99 | dateText.setFill(dateColor);
100 |
101 | pane = new Pane(timeText, dateText);
102 | pane.setBorder(new Border(new BorderStroke(clock.getBorderPaint(), BorderStrokeStyle.SOLID, CornerRadii.EMPTY, new BorderWidths(clock.getBorderWidth()))));
103 | pane.setBackground(new Background(new BackgroundFill(clock.getBackgroundPaint(), CornerRadii.EMPTY, Insets.EMPTY)));
104 |
105 | getChildren().setAll(pane);
106 | }
107 |
108 | @Override protected void registerListeners() {
109 | super.registerListeners();
110 | }
111 |
112 |
113 | // ******************** Methods *******************************************
114 | @Override protected void handleEvents(final String EVENT_TYPE) {
115 | super.handleEvents(EVENT_TYPE);
116 | if ("VISIBILITY".equals(EVENT_TYPE)) {
117 |
118 | } else if ("SECTION".equals(EVENT_TYPE)) {
119 | redraw();
120 | }
121 | }
122 |
123 |
124 | // ******************** Canvas ********************************************
125 | private void drawTime(final ZonedDateTime TIME) {
126 | // draw the time
127 | if (clock.isTextVisible()) {
128 | if (Locale.US == clock.getLocale()) {
129 | timeText.setText(clock.isSecondsVisible() ? AMPM_HHMMSS_FORMATTER.format(TIME) : AMPM_HHMM_FORMATTER.format(TIME));
130 | } else {
131 | timeText.setText(clock.isSecondsVisible() ? HHMMSS_FORMATTER.format(TIME) : HHMM_FORMATTER.format(TIME));
132 | }
133 | timeText.setX((width - timeText.getLayoutBounds().getWidth()) * 0.5);
134 | }
135 |
136 | // draw the date
137 | if (clock.isDateVisible()) {
138 | dateText.setText(dateFormat.format(TIME));
139 | dateText.setX((width - dateText.getLayoutBounds().getWidth()) * 0.5);
140 | }
141 | }
142 |
143 | @Override public void updateTime(final ZonedDateTime TIME) {
144 | drawTime(TIME);
145 | }
146 |
147 | @Override public void updateAlarms() {}
148 |
149 |
150 | // ******************** Resizing ******************************************
151 | @Override protected void resize() {
152 | width = clock.getWidth() - clock.getInsets().getLeft() - clock.getInsets().getRight();
153 | height = clock.getHeight() - clock.getInsets().getTop() - clock.getInsets().getBottom();
154 |
155 | if (aspectRatio * width > height) {
156 | width = 1 / (aspectRatio / height);
157 | } else if (1 / (aspectRatio / height) > width) {
158 | height = aspectRatio * width;
159 | }
160 |
161 | if (width > 0 && height > 0) {
162 | pane.setMaxSize(width, height);
163 | pane.relocate((clock.getWidth() - height) * 0.5, (clock.getHeight() - height) * 0.5);
164 |
165 | if (clock.isTextVisible()) {
166 | if (null == customFont) {
167 | timeText.setFont(Locale.US == clock.getLocale() ? Fonts.robotoLight(0.5 * height) : Fonts.robotoLight(0.6 * height));
168 | } else {
169 | timeText.setFont(Locale.US == clock.getLocale() ? new Font(customFont.getName(), 0.5 * height) : new Font(customFont.getName(), 0.6 * height));
170 | }
171 | timeText.setX((width - timeText.getLayoutBounds().getWidth()) * 0.5);
172 | if (clock.isDateVisible()) {
173 | timeText.setY(height * 0.3);
174 | } else {
175 | timeText.setY(height * 0.5);
176 | }
177 | }
178 | if (clock.isDateVisible()) {
179 | if (null == customFont) {
180 | dateText.setFont(Fonts.robotoLight(0.3 * height));
181 | } else {
182 | dateText.setFont(new Font(customFont.getName(), 0.3 * height));
183 | }
184 | dateText.setX((width - dateText.getLayoutBounds().getWidth()) * 0.5);
185 | dateText.setY(height * 0.8);
186 | }
187 | }
188 | }
189 |
190 | @Override protected void redraw() {
191 | pane.setBorder(new Border(new BorderStroke(clock.getBorderPaint(), BorderStrokeStyle.SOLID, CornerRadii.EMPTY, new BorderWidths(clock.getBorderWidth() / PREFERRED_WIDTH * height))));
192 | pane.setBackground(new Background(new BackgroundFill(clock.getBackgroundPaint(), CornerRadii.EMPTY, Insets.EMPTY)));
193 | ZonedDateTime time = clock.getTime();
194 |
195 | dateFormat = Helper.getDateFormat(clock.getLocale());
196 |
197 | textColor = clock.getTextColor();
198 | timeText.setFill(textColor);
199 |
200 | dateColor = clock.getDateColor();
201 | dateText.setFill(dateColor);
202 |
203 | drawTime(time);
204 | }
205 | }
206 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/tools/AngleConicalGradient.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.tools;
19 |
20 | import eu.hansolo.medusa.Gauge.ScaleDirection;
21 | import javafx.geometry.Point2D;
22 | import javafx.scene.image.Image;
23 | import javafx.scene.paint.Color;
24 | import javafx.scene.paint.ImagePattern;
25 | import javafx.scene.paint.Stop;
26 | import javafx.scene.shape.Rectangle;
27 | import javafx.scene.shape.Shape;
28 |
29 | import java.util.ArrayList;
30 | import java.util.List;
31 | import java.util.Map;
32 |
33 |
34 | /**
35 | * Created by hansolo on 21.12.15.
36 | */
37 | public class AngleConicalGradient {
38 | private ConicalGradient gradient;
39 |
40 | public AngleConicalGradient(final Map ANGLE_STOP_MAP, final ScaleDirection DIRECTION) {
41 | this(0, 0, ANGLE_STOP_MAP, DIRECTION);
42 | }
43 | public AngleConicalGradient(final double CENTER_X, final double CENTER_Y, final Map ANGLE_STOP_MAP, final ScaleDirection DIRECTION) {
44 | this(CENTER_X, CENTER_Y, 0.0, ANGLE_STOP_MAP, DIRECTION);
45 | }
46 | public AngleConicalGradient(final double CENTER_X, final double CENTER_Y, final double OFFSET_ANGLE, final Map ANGLE_STOP_MAP, final ScaleDirection DIRECTION) {
47 | final double ANGLE_FACTOR = 1.0 / 360.0;
48 | double offset = Helper.clamp(0, 1, (OFFSET_ANGLE % 360.0) * ANGLE_FACTOR);
49 | List stops = new ArrayList<>();
50 | for (double fraction : ANGLE_STOP_MAP.keySet()) {
51 | stops.add(new Stop(Helper.clamp(0, 1, (fraction % 360.0) * ANGLE_FACTOR), ANGLE_STOP_MAP.get(fraction)));
52 | }
53 | gradient = new ConicalGradient(CENTER_X, CENTER_Y, offset, DIRECTION, stops);
54 | }
55 |
56 | public void recalculateWithAngle(final double ANGLE) { gradient.recalculateWithAngle(ANGLE); }
57 |
58 | public List getStops() { return gradient.getStops(); }
59 |
60 | public double[] getCenter() { return gradient.getCenter(); }
61 | public Point2D getCenterPoint() { return gradient.getCenterPoint(); }
62 |
63 | public Image getImage(final double WIDTH, final double HEIGHT) { return gradient.getImage(WIDTH, HEIGHT); }
64 | public Image getRoundImage(final double SIZE) { return gradient.getRoundImage(SIZE); }
65 |
66 | public ImagePattern apply(final Shape SHAPE) { return gradient.apply(SHAPE); }
67 |
68 | public ImagePattern getImagePattern(final Rectangle BOUNDS) { return gradient.getImagePattern(BOUNDS); }
69 | }
70 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/tools/Data.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.tools;
19 |
20 | import java.time.Instant;
21 |
22 |
23 | /**
24 | * Created by hansolo on 01.11.16.
25 | */
26 | public class Data {
27 | private final Instant timestamp;
28 | private final double value;
29 |
30 |
31 | // ******************** Constructors **************************************
32 | public Data(final double VALUE) {
33 | value = VALUE;
34 | timestamp = Instant.now();
35 | }
36 |
37 |
38 | // ******************** Methods *******************************************
39 | public double getValue() { return value; }
40 |
41 | public Instant getTimestamp() { return timestamp; }
42 |
43 | @Override public String toString() {
44 | return new StringBuilder().append("{\n")
45 | .append(" \"timestamp\":").append(timestamp.getEpochSecond()).append(",\n")
46 | .append(" \"value\":").append(value).append(",\n")
47 | .append("}")
48 | .toString();
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/tools/GradientLookup.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.tools;
19 |
20 | import javafx.scene.paint.Color;
21 | import javafx.scene.paint.Stop;
22 |
23 | import java.util.ArrayList;
24 | import java.util.Arrays;
25 | import java.util.Collections;
26 | import java.util.List;
27 | import java.util.Map;
28 | import java.util.TreeMap;
29 |
30 |
31 | /**
32 | * Created by hansolo on 21.12.15.
33 | */
34 | public class GradientLookup {
35 | private Map stops;
36 |
37 |
38 | // ******************** Constructors **************************************
39 | public GradientLookup () {
40 | this(new Stop[]{});
41 | }
42 | public GradientLookup(final Stop... STOPS) {
43 | this(Arrays.asList(STOPS));
44 | }
45 | public GradientLookup(final List STOPS) {
46 | stops = new TreeMap<>();
47 | for (Stop stop : STOPS) { stops.put(stop.getOffset(), stop); }
48 | init();
49 | }
50 |
51 |
52 | // ******************** Initialization ************************************
53 | private void init() {
54 | if (stops.isEmpty()) return;
55 |
56 | double minFraction = Collections.min(stops.keySet());
57 | double maxFraction = Collections.max(stops.keySet());
58 |
59 | if (Double.compare(minFraction, 0) > 0) { stops.put(0.0, new Stop(0.0, stops.get(minFraction).getColor())); }
60 | if (Double.compare(maxFraction, 1) < 0) { stops.put(1.0, new Stop(1.0, stops.get(maxFraction).getColor())); }
61 | }
62 |
63 |
64 | // ******************** Methods *******************************************
65 | public Color getColorAt(final double POSITION_OF_COLOR) {
66 | if (stops.isEmpty()) return Color.BLACK;
67 |
68 | final double POSITION = Helper.clamp(0.0, 1.0, POSITION_OF_COLOR);
69 | final Color COLOR;
70 | if (stops.size() == 1) {
71 | final Map ONE_ENTRY = (Map) stops.entrySet().iterator().next();
72 | COLOR = stops.get(ONE_ENTRY.keySet().iterator().next()).getColor();
73 | } else {
74 | Stop lowerBound = stops.get(0.0);
75 | Stop upperBound = stops.get(1.0);
76 | for (Double fraction : stops.keySet()) {
77 | if (Double.compare(fraction,POSITION) < 0) {
78 | lowerBound = stops.get(fraction);
79 | }
80 | if (Double.compare(fraction, POSITION) > 0) {
81 | upperBound = stops.get(fraction);
82 | break;
83 | }
84 | }
85 | COLOR = interpolateColor(lowerBound, upperBound, POSITION);
86 | }
87 | return COLOR;
88 | }
89 |
90 | public List getStops() { return new ArrayList<>(stops.values()); }
91 | public void setStops(final Stop... STOPS) { setStops(Arrays.asList(STOPS)); }
92 | public void setStops(final List STOPS) {
93 | stops.clear();
94 | for (Stop stop : STOPS) { stops.put(stop.getOffset(), stop); }
95 | init();
96 | }
97 |
98 | private Color interpolateColor(final Stop LOWER_BOUND, final Stop UPPER_BOUND, final double POSITION) {
99 | final double POS = (POSITION - LOWER_BOUND.getOffset()) / (UPPER_BOUND.getOffset() - LOWER_BOUND.getOffset());
100 |
101 | final double DELTA_RED = (UPPER_BOUND.getColor().getRed() - LOWER_BOUND.getColor().getRed()) * POS;
102 | final double DELTA_GREEN = (UPPER_BOUND.getColor().getGreen() - LOWER_BOUND.getColor().getGreen()) * POS;
103 | final double DELTA_BLUE = (UPPER_BOUND.getColor().getBlue() - LOWER_BOUND.getColor().getBlue()) * POS;
104 | final double DELTA_OPACITY = (UPPER_BOUND.getColor().getOpacity() - LOWER_BOUND.getColor().getOpacity()) * POS;
105 |
106 | double red = Helper.clamp(0.0, 1.0, (LOWER_BOUND.getColor().getRed() + DELTA_RED));
107 | double green = Helper.clamp(0.0, 1.0, (LOWER_BOUND.getColor().getGreen() + DELTA_GREEN));
108 | double blue = Helper.clamp(0.0, 1.0, (LOWER_BOUND.getColor().getBlue() + DELTA_BLUE));
109 | double opacity = Helper.clamp(0.0, 1.0, (LOWER_BOUND.getColor().getOpacity() + DELTA_OPACITY));
110 |
111 | return Color.color(red, green, blue, opacity);
112 | }
113 | }
114 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/tools/MarkerComparator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.tools;
19 |
20 | import eu.hansolo.medusa.Marker;
21 |
22 | import java.io.Serializable;
23 | import java.util.Comparator;
24 |
25 |
26 | /**
27 | * Created by hansolo on 26.01.16.
28 | */
29 | public class MarkerComparator implements Comparator, Serializable {
30 | @Override public int compare(final Marker MARKER_1, final Marker MARKER_2) {
31 | return MARKER_1.compareTo(MARKER_2);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/tools/MovingAverage.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.tools;
19 |
20 | import java.time.Duration;
21 | import java.time.Instant;
22 | import java.util.LinkedList;
23 | import java.util.Queue;
24 | import java.util.concurrent.ConcurrentLinkedQueue;
25 |
26 |
27 | /**
28 | * Created by hansolo on 01.11.16.
29 | */
30 | public class MovingAverage {
31 | public static final int MAX_PERIOD = 2_073_600; // 24h in seconds
32 | private static final int DEFAULT_PERIOD = 10;
33 | private final Queue window;
34 | private int period;
35 | private double sum;
36 |
37 |
38 | // ******************** Constructors **************************************
39 | public MovingAverage() {
40 | this(DEFAULT_PERIOD);
41 | }
42 | public MovingAverage(final int PERIOD) {
43 | period = Helper.clamp(0, MAX_PERIOD, PERIOD);
44 | window = new ConcurrentLinkedQueue<>();
45 | }
46 |
47 |
48 | // ******************** Methods *******************************************
49 | public void addData(final Data DATA) {
50 | sum += DATA.getValue();
51 | window.add(DATA);
52 | if (window.size() > period) {
53 | sum -= window.remove().getValue();
54 | }
55 | }
56 | public void addValue(final double VALUE) {
57 | addData(new Data(VALUE));
58 | }
59 |
60 | public Queue getWindow() { return new LinkedList<>(window); }
61 |
62 | public double getAverage() {
63 | if (window.isEmpty()) return 0; // technically the average is undefined
64 | return (sum / window.size());
65 | }
66 |
67 | public double getTimeBasedAverageOf(final Duration DURATION) {
68 | assert !DURATION.isNegative() : "Time period must be positive";
69 | Instant now = Instant.now();
70 | return window.stream()
71 | .filter(v -> v.getTimestamp().isAfter(now.minus(DURATION)))
72 | .mapToDouble(Data::getValue)
73 | .average()
74 | .getAsDouble();
75 | }
76 |
77 | public int getPeriod() { return period; }
78 | public void setPeriod(final int PERIOD) {
79 | period = Helper.clamp(0, MAX_PERIOD, PERIOD);
80 | reset();
81 | }
82 |
83 | public boolean isFilling() { return window.size() < period; }
84 |
85 | public void reset() { window.clear(); }
86 | }
87 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/tools/SectionComparator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.tools;
19 |
20 | import eu.hansolo.medusa.Section;
21 |
22 | import java.io.Serializable;
23 | import java.util.Comparator;
24 |
25 |
26 | /**
27 | * Created by hansolo on 26.01.16.
28 | */
29 | public class SectionComparator implements Comparator, Serializable {
30 | @Override public int compare(final Section SECTION_1, final Section SECTION_2) {
31 | return SECTION_1.compareTo(SECTION_2);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/tools/Statistics.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.tools;
19 |
20 | import java.util.Collections;
21 | import java.util.List;
22 |
23 |
24 | /**
25 | * Created by hansolo on 06.12.16.
26 | */
27 | public class Statistics {
28 |
29 |
30 | // ******************** Methods *******************************************
31 | public static double getMean(final List DATA) { return DATA.stream().mapToDouble(v -> v).sum() / DATA.size(); }
32 |
33 | public static double getVariance(final List DATA) {
34 | double mean = getMean(DATA);
35 | double temp = 0;
36 | for (double a : DATA) { temp += ((a - mean) * (a - mean)); }
37 | return temp / DATA.size();
38 | }
39 |
40 | public static double getStdDev(final List DATA) { return Math.sqrt(getVariance(DATA)); }
41 |
42 | public static double getMedian(final List DATA) {
43 | int size = DATA.size();
44 | Collections.sort(DATA);
45 | return size % 2 == 0 ? (DATA.get((size / 2) - 1) + DATA.get(size / 2)) / 2.0 : DATA.get(size / 2);
46 | }
47 |
48 | public static double getMin(final List DATA) { return DATA.stream().mapToDouble(v -> v).min().orElse(0); }
49 |
50 | public static double getMax(final List DATA) { return DATA.stream().mapToDouble(v -> v).max().orElse(0); }
51 | }
52 |
--------------------------------------------------------------------------------
/src/main/java/eu/hansolo/medusa/tools/TimeSectionComparator.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | package eu.hansolo.medusa.tools;
19 |
20 | import eu.hansolo.medusa.TimeSection;
21 |
22 | import java.io.Serializable;
23 | import java.util.Comparator;
24 |
25 |
26 | /**
27 | * Created by hansolo on 31.01.16.
28 | */
29 | public class TimeSectionComparator implements Comparator, Serializable {
30 | @Override public int compare(final TimeSection SECTION_1, final TimeSection SECTION_2) {
31 | return SECTION_1.compareTo(SECTION_2);
32 | }
33 | }
34 |
35 |
--------------------------------------------------------------------------------
/src/main/java/module-info.java:
--------------------------------------------------------------------------------
1 | /*
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | module eu.hansolo.medusa {
19 |
20 | // Java
21 | requires java.base;
22 |
23 | // Java-FX
24 | requires transitive javafx.base;
25 | requires transitive javafx.graphics;
26 | requires transitive javafx.controls;
27 |
28 | exports eu.hansolo.medusa;
29 | exports eu.hansolo.medusa.skins;
30 | exports eu.hansolo.medusa.events;
31 | exports eu.hansolo.medusa.tools;
32 | }
33 |
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/Estricta-Medium.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/Estricta-Medium.otf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/Estricta-MediumItalic.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/Estricta-MediumItalic.otf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/Estricta-Regular.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/Estricta-Regular.otf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/Estricta-RegularItalic.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/Estricta-RegularItalic.otf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/Lato-Bol.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/Lato-Bol.otf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/Lato-Lig.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/Lato-Lig.otf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/Lato-Reg.otf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/Lato-Reg.otf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/Roboto-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/Roboto-Bold.ttf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/Roboto-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/Roboto-Light.ttf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/Roboto-Medium.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/Roboto-Medium.ttf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/Roboto-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/Roboto-Regular.ttf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/Roboto-Thin.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/Roboto-Thin.ttf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/RobotoCondensed-Bold.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/RobotoCondensed-Bold.ttf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/RobotoCondensed-Light.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/RobotoCondensed-Light.ttf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/RobotoCondensed-Regular.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/RobotoCondensed-Regular.ttf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/clock.css:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | /******************************************************************************
19 | * CLOCK class *
20 | *****************************************************************************/
21 | .clock {
22 |
23 | }
24 |
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/digital.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/digital.ttf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/digitalreadout.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/digitalreadout.ttf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/digitalreadoutb.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/digitalreadoutb.ttf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/elektra.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/HanSolo/medusa/51b560b5a11db6bc4835e934f3df2f273561bc6c/src/main/resources/eu/hansolo/medusa/elektra.ttf
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/framed-gauge.css:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | .framed-gauge {
19 |
20 | }
21 |
22 | .steel-series-frame {
23 | -outer-border : rgb(132,132,132);
24 | -inner-border : linear-gradient(to bottom, rgb(254,254,254) 0%, rgb(210,210,210) 7%, rgb(179,179,179) 12%, rgb(213,213,213) 100%);
25 | -body : linear-gradient(to bottom, rgb(0,0,0) 0%, rgb(50,50,50) 39%, rgb(51,51,51) 40%, rgb(153,153,153) 100%);
26 | -fx-background-color : -outer-border, -inner-border, -body;
27 | -fx-background-radius: 1024;
28 | }
29 |
30 | .enzo-frame {
31 | -outer-border : linear-gradient(to bottom, rgb(224,224,224) 0%, rgb(133,133,133) 26%, rgb(84,84,84) 100%);
32 | -highlight-border : linear-gradient(to bottom, rgb(255,255,255) 0%, rgb(146,146,147) 50%, rgb(135,136,138) 100%);
33 | -inner-border : linear-gradient(to bottom, rgb(71,72,72) 0%, rgb(110,106,107) 50%, rgb(186,185,187) 100%);
34 | -body : rgb(240,240,240);
35 | -fx-background-color : -outer-border, -highlight-border, -inner-border, -body;
36 | -fx-background-radius: 1024;
37 | -fx-effect : innershadow(two-pass-box, rgba(0, 0, 0, 0.3), 20, 0.0, 0, 20);
38 | }
39 |
--------------------------------------------------------------------------------
/src/main/resources/eu/hansolo/medusa/gauge.css:
--------------------------------------------------------------------------------
1 | /**
2 | * SPDX-License-Identifier: Apache-2.0
3 | *
4 | * Copyright 2016-2021 Gerrit Grunwald.
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License");
7 | * you may not use this file except in compliance with the License.
8 | * You may obtain a copy of the License at
9 | *
10 | * https://www.apache.org/licenses/LICENSE-2.0
11 | *
12 | * Unless required by applicable law or agreed to in writing, software
13 | * distributed under the License is distributed on an "AS IS" BASIS,
14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 | * See the License for the specific language governing permissions and
16 | * limitations under the License.
17 | */
18 | /******************************************************************************
19 | * GAUGE class *
20 | *****************************************************************************/
21 | .gauge {
22 |
23 | }
24 |
--------------------------------------------------------------------------------