Skip to content

Commit 9a181f6

Browse files
committed
Init
0 parents  commit 9a181f6

File tree

8 files changed

+229
-0
lines changed

8 files changed

+229
-0
lines changed

.classpath

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<classpath>
2+
<classpathentry output="target\scala-2.10\classes" path="src\main\scala" kind="src"></classpathentry>
3+
<classpathentry output="target\scala-2.10\classes" path="src\main\java" kind="src"></classpathentry>
4+
<classpathentry output="target\scala-2.10\test-classes" path="src\test\scala" kind="src"></classpathentry>
5+
<classpathentry output="target\scala-2.10\test-classes" path="src\test\java" kind="src"></classpathentry>
6+
<classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_CONTAINER"></classpathentry>
7+
<classpathentry path="C:\Users\Collin\.ivy2\cache\org.scalaj\scalaj-http_2.10\jars\scalaj-http_2.10-0.3.10.jar" kind="lib"></classpathentry>
8+
<classpathentry path="C:\Users\Collin\.ivy2\cache\net.liftweb\lift-json_2.10\jars\lift-json_2.10-2.5.1.jar" kind="lib"></classpathentry>
9+
<classpathentry path="C:\Users\Collin\.ivy2\cache\org.scala-lang\scalap\jars\scalap-2.10.0.jar" kind="lib"></classpathentry>
10+
<classpathentry kind="con" path="org.scala-ide.sdt.launching.SCALA_COMPILER_CONTAINER"></classpathentry>
11+
<classpathentry path="C:\Users\Collin\.ivy2\cache\org.scala-lang\scala-reflect\jars\scala-reflect-2.10.2.jar" kind="lib"></classpathentry>
12+
<classpathentry path="C:\Users\Collin\.ivy2\cache\com.thoughtworks.paranamer\paranamer\jars\paranamer-2.4.1.jar" kind="lib"></classpathentry>
13+
<classpathentry path="C:\Users\Collin\.ivy2\cache\org.scala-lang\scala-swing\jars\scala-swing-2.10.2.jar" kind="lib"></classpathentry>
14+
<classpathentry path="org.eclipse.jdt.launching.JRE_CONTAINER" kind="con"></classpathentry>
15+
<classpathentry path="bin" kind="output"></classpathentry>
16+
</classpath>

.gitignore

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
target/
2+
.worksheet/*
3+
.cache

.project

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<projectDescription>
2+
<name>Tyme</name>
3+
<buildSpec>
4+
<buildCommand>
5+
<name>org.scala-ide.sdt.core.scalabuilder</name>
6+
</buildCommand>
7+
</buildSpec>
8+
<natures>
9+
<nature>org.scala-ide.sdt.core.scalanature</nature>
10+
<nature>org.eclipse.jdt.core.javanature</nature>
11+
</natures>
12+
<linkedResources> </linkedResources>
13+
</projectDescription>

build.sbt

+12
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
name := "Tyme"
2+
3+
version := "0.0.1"
4+
5+
scalaVersion := "2.10.2"
6+
7+
// Dependencies
8+
libraryDependencies += "org.scalaj" % "scalaj-http_2.10" % "0.3.10"
9+
10+
libraryDependencies += "net.liftweb" % "lift-json_2.10" % "2.5.1"
11+
12+
libraryDependencies += "org.scala-lang" % "scala-swing" % "2.10.2"
+147
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
package org.collinm.tyme
2+
3+
import scala.swing.SwingApplication
4+
import scala.swing.MainFrame
5+
import java.awt.Color
6+
import scala.swing.BoxPanel
7+
import scala.swing.Orientation
8+
import java.awt.Graphics2D
9+
import java.awt.geom.Ellipse2D
10+
import java.awt.BasicStroke
11+
import scala.swing.event.Event
12+
import scala.swing.Publisher
13+
import java.awt.Dimension
14+
import java.awt.RenderingHints
15+
import java.awt.geom.Line2D
16+
import org.collinm.tyme.utils.Geometry
17+
import org.collinm.tyme.utils.Time
18+
19+
/** Main runtime */
20+
object Clock extends SwingApplication {
21+
22+
def startup(args: Array[String]) = {
23+
val frame = new ClockFrame()
24+
frame.visible = true
25+
//frame.peer.setUndecorated(true) // Remove title bar
26+
}
27+
}
28+
29+
/** The main window frame that houses the clock.
30+
*
31+
* Creates and owns the clock and it's refresh timer. Automatically maximizes
32+
* itself on creation and instantiates a clock that fits nicely inside the frame
33+
* (centered).
34+
*/
35+
class ClockFrame extends MainFrame {
36+
this.maximize()
37+
val clock = new ElegantClockPanel(this.toolkit.getScreenSize())
38+
val timer = new ClockTimer(30)
39+
40+
listenTo(timer)
41+
reactions += {
42+
case rt: RedrawTime => clock.repaint
43+
}
44+
45+
contents = clock
46+
timer.start()
47+
}
48+
49+
/** The Panel component that draws the clock.
50+
*
51+
* @param dimension
52+
* The area the clock should fit in (with a border)
53+
*/
54+
class ElegantClockPanel(dimension: Dimension) extends BoxPanel(Orientation.Horizontal) {
55+
var staticItemsPainted = false
56+
var lastStaticPaintSec = 0.0
57+
// Minimum dimension will always be height after the window is maximized
58+
// Figure out the basic measurements of the clock: diameter and border size for X and Y axis
59+
val yOffset = dimension.getHeight() * 0.1
60+
val diameter = dimension.getHeight() * 0.8
61+
val xOffset = (dimension.getWidth() - diameter) / 2
62+
63+
// Create the edge of the clock and the hour and minute ticks
64+
val outline = new Ellipse2D.Double(xOffset, yOffset, diameter, diameter)
65+
val origin = (xOffset + diameter/2, yOffset + diameter/2)
66+
def getCircleTick(percent: Double, origin: (Double, Double), distFromOrigin: Double, diameter: Double) = {
67+
val (x, y) = Geometry.getPointOnCircle(percent, origin, distFromOrigin)
68+
new Ellipse2D.Double(x - (diameter/2), y - (diameter/2), diameter, diameter)
69+
}
70+
val majorTickWidth = 10
71+
val minorTickWidth = 2
72+
val majorTicks = Range(1, 13).map(hr => getCircleTick(hr/12.0, origin, (diameter/2)*0.88, majorTickWidth))
73+
val minorTicks = Range(1, 61).map(min => getCircleTick(min/60.0, origin, (diameter/2)*0.88, minorTickWidth))
74+
75+
// Instantiate the Stokes used to dra the edge and hands
76+
background = Color.black
77+
val outlineStroke = new BasicStroke(10)
78+
val minHrStroke = new BasicStroke(5, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)
79+
val secStroke = new BasicStroke(2, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND)
80+
81+
override def paintComponent(g: Graphics2D): Unit = {
82+
// Rendering hints for anti-aliasing
83+
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
84+
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BICUBIC)
85+
super.paintComponent(g)
86+
87+
g.setColor(Color.LIGHT_GRAY)
88+
if (!staticItemsPainted) {
89+
// Draw edge of clock
90+
g.setStroke(outlineStroke)
91+
g.draw(outline)
92+
93+
// Draw ticks
94+
majorTicks.map(tick => g.fill(tick))
95+
minorTicks.map(tick => g.fill(tick))
96+
97+
staticItemsPainted = true
98+
}
99+
100+
// Draw hands
101+
val (hours, minutes, seconds) = Time.getTime()
102+
g.setStroke(minHrStroke)
103+
g.draw( getHand(hours/12, origin, (diameter/2)*0.4) )
104+
g.draw( getHand(minutes/60, origin, (diameter/2)*0.6472) )
105+
g.setStroke(secStroke)
106+
g.draw( getHand(seconds/60, origin, (diameter/2)*0.8) )
107+
108+
if (minutes > lastStaticPaintSec+5) staticItemsPainted = false
109+
}
110+
111+
/** Get a clock hand (line).
112+
*
113+
* @param percent
114+
* decimal representing where on the edge of the clock the hand should be pointing
115+
* 0 = 12, 0.25 = 3, 0.5 = 6, 0.75 = 9
116+
* @param origin
117+
* 2-tuple for the center of the clock
118+
* @param length
119+
* how long the hand should be
120+
* @return A Line2D for the clock hand
121+
*/
122+
def getHand(percent: Double, origin: (Double, Double), length: Double) = {
123+
val point = Geometry.getPointOnCircle(percent, origin, length)
124+
new Line2D.Double(origin._1, origin._2, point._1, point._2)
125+
}
126+
}
127+
128+
/** Update timer for a clock
129+
*
130+
* Fires a RedrawTime Event every n milliseconds, where n results in
131+
* the desired refresh rate.
132+
*
133+
* @param fps
134+
* target frames per second (refresh rate)
135+
*/
136+
class ClockTimer(fps: Int) extends Publisher {
137+
val delay = 1000/fps
138+
// Custom action to that fires our desired event, so we can use a Swing Timer
139+
val timeout = new javax.swing.AbstractAction() { def actionPerformed(e: java.awt.event.ActionEvent) = publish(RedrawTime()) }
140+
val timer = new javax.swing.Timer(delay, timeout) // Fire "timeout" ever "delay" milliseconds
141+
timer.setRepeats(true)
142+
143+
def start() = timer.start()
144+
def stop() = timer.stop()
145+
}
146+
147+
case class RedrawTime() extends Event
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.collinm.tyme.utils
2+
3+
import scala.math.{Pi, cos, sin}
4+
5+
object Geometry {
6+
7+
def getPointOnCircle(percent: Double, origin: (Double, Double), radius: Double): (Double, Double) = {
8+
val radians = (percent * 2*Pi) - Pi/2
9+
(origin._1 + (radius * cos(radians)), origin._2 + radius * sin(radians))
10+
}
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.collinm.tyme.utils
2+
3+
import java.util.GregorianCalendar
4+
import java.text.SimpleDateFormat
5+
6+
object Time {
7+
val hourFormat = new SimpleDateFormat("hh")
8+
val minuteFormat = new SimpleDateFormat("mm")
9+
val secondFormat = new SimpleDateFormat("ss.SSS")
10+
11+
/** Get the double-valued time for hours, minutes, and seconds.
12+
*
13+
* @return 3-tuple of Double's: hours, minutes, seconds
14+
*/
15+
def getTime(): (Double, Double, Double) = {
16+
val time = new GregorianCalendar().getTime()
17+
val seconds = secondFormat.format(time).toDouble
18+
val minutes = minuteFormat.format(time).toDouble + seconds/60
19+
val hours = hourFormat.format(time).toDouble + minutes/60
20+
(hours, minutes, seconds)
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package org.collinm.tyme.widgets
2+
3+
class WUnderground(key: String) {
4+
5+
}

0 commit comments

Comments
 (0)