175 lines
8.0 KiB
Plaintext
175 lines
8.0 KiB
Plaintext
output file "Rosetta Code Clock"
|
|
|
|
_window = 1
|
|
begin enum 1
|
|
_clockView
|
|
_one
|
|
_two
|
|
_three
|
|
_four
|
|
_five
|
|
_six
|
|
_seven
|
|
_eight
|
|
_nine
|
|
_ten
|
|
_eleven
|
|
_twelve
|
|
end enum
|
|
|
|
local fn BuildWindow
|
|
CALayerRef layer, hoursLayer, minutesLayer, secondsLayer
|
|
CAShapeLayerRef shapeLayer, hubLayer
|
|
CATextLayerRef textLayer
|
|
BezierPathRef circle, hub
|
|
CGPoint pt
|
|
CGRect r, frame
|
|
CFDateRef dt
|
|
CFTimeInterval ti
|
|
CGFloat h, m, s, ha, ma, sa
|
|
NSUInteger i
|
|
CFStringRef num
|
|
CABasicAnimationRef secondsAnimation, minutesAnimation, hoursAnimation
|
|
|
|
// Window
|
|
r = fn CGRectMake( 0, 0, 500, 500 )
|
|
window _window, @"FutureBasic Rosetta Code Clock", r
|
|
WindowSetBackgroundColor( _window, fn ColorBlack )
|
|
|
|
// View to hold clock layers
|
|
view _clockView, r, _window
|
|
ViewSetWantsLayer( _clockView, YES )
|
|
layer = fn ViewLayer( _clockView )
|
|
frame = fn ViewFrame( _clockView )
|
|
|
|
// Blank clock face
|
|
shapeLayer = fn CAShapeLayerInit
|
|
circle = fn BezierPathWithOvalInRect( fn CGRectInset( r, 35, 35 ) )
|
|
CAShapeLayerSetPath( shapeLayer, circle )
|
|
CAShapeLayerSetLineWidth( shapeLayer, 6.5 )
|
|
CAShapeLayerSetLineCap( shapeLayer, kCALineCapRound )
|
|
CAShapeLayerSetFillColor( shapeLayer, fn ColorDarkGray )
|
|
CAShapeLayerSetStrokeColor( shapeLayer, fn ColorWithRGB( 0.711, 0.533, 0.258, 1.0 ) )
|
|
CALayerAddSublayer( layer, shapeLayer )
|
|
|
|
// Clock numerals
|
|
for i = _one to _twelve
|
|
if i = _one then pt = fn CGPointMake( frame.size.width / 2 + 95, frame.size.height / 2 + 115 ) : num = @"1"
|
|
if i = _two then pt = fn CGPointMake( frame.size.width / 2 + 160, frame.size.height / 2 + 45 ) : num = @"2"
|
|
if i = _three then pt = fn CGPointMake( frame.size.width / 2 + 180, frame.size.height / 2 - 40 ) : num = @"3"
|
|
if i = _four then pt = fn CGPointMake( frame.size.width / 2 + 155, frame.size.height / 2 - 125 ) : num = @"4"
|
|
if i = _five then pt = fn CGPointMake( frame.size.width / 2 + 90, frame.size.height / 2 - 190 ) : num = @"5"
|
|
if i = _six then pt = fn CGPointMake( frame.size.width / 2, frame.size.height / 2 - 215 ) : num = @"6"
|
|
if i = _seven then pt = fn CGPointMake( frame.size.width / 2 - 90, frame.size.height / 2 - 190 ) : num = @"7"
|
|
if i = _eight then pt = fn CGPointMake( frame.size.width / 2 - 155, frame.size.height / 2 - 125 ) : num = @"8"
|
|
if i = _nine then pt = fn CGPointMake( frame.size.width / 2 - 185, frame.size.height / 2 - 40 ) : num = @"9"
|
|
if i = _ten then pt = fn CGPointMake( frame.size.width / 2 - 155, frame.size.height / 2 + 45 ) : num = @"10"
|
|
if i = _eleven then pt = fn CGPointMake( frame.size.width / 2 - 90, frame.size.height / 2 + 115 ) : num = @"11"
|
|
if i = _twelve then pt = fn CGPointMake( frame.size.width / 2, frame.size.height / 2 + 145 ) : num = @"12"
|
|
textLayer = fn CATextLayerInit
|
|
CATextLayerSetString( textLayer, num )
|
|
CATextLayerSetFont( textLayer, @"Times" )
|
|
CATextLayerSetFontSize( textLayer, 50.0 )
|
|
CATextLayerSetForegroundColor( textLayer, fn ColorGreen )
|
|
CALayerSetAnchorPoint( textLayer, fn CGPointMake( 0.5, 0 ) )
|
|
CATextLayerSetAlignmentMode( textLayer, kCAAlignmentCenter )
|
|
CALayerSetPosition( textLayer, pt )
|
|
CALayerSetBounds( textLayer, fn CGRectMake( 0, 0, 70, 65 ) )
|
|
CALayerAddSublayer( layer, textLayer )
|
|
next
|
|
|
|
// Hours layer
|
|
hoursLayer = fn CALayerInit
|
|
CALayerSetBackgroundColor( hoursLayer, fn ColorWhite )
|
|
CALayerSetAnchorPoint( hoursLayer, fn CGPointMake( 0.5, 0 ) )
|
|
CALayerSetPosition( hoursLayer, fn CGPointMake( frame.size.width / 2, frame.size.height / 2 ) )
|
|
CALayerSetBounds( hoursLayer, fn CGRectMake( 0, 0, 10, frame.size.width / 2 -90 ) )
|
|
CALayerSetCornerRadius( hoursLayer, 4.0 )
|
|
CALayerAddSublayer( layer, hoursLayer )
|
|
|
|
// Minutes layer
|
|
minutesLayer = fn CALayerInit
|
|
CALayerSetBackgroundColor( minutesLayer, fn ColorWhite )
|
|
CALayerSetAnchorPoint( minutesLayer, fn CGPointMake( 0.5, 0 ) )
|
|
CALayerSetPosition( minutesLayer, fn CGPointMake( frame.size.width / 2, frame.size.height / 2 ) )
|
|
CALayerSetBounds( minutesLayer, fn CGRectMake( 0, 0, 6, frame.size.width / 2 -45 ) )
|
|
CALayerSetCornerRadius( minutesLayer, 3.0 )
|
|
CALayerAddSublayer( layer, minutesLayer )
|
|
|
|
// Seconds layer
|
|
secondsLayer = fn CALayerInit
|
|
CALayerSetBackgroundColor( secondsLayer, fn ColorWithRGB( 0.502, 0.000, 0.251, 1.0 ) )
|
|
CALayerSetAnchorPoint( secondsLayer, fn CGPointMake( 0.5, 0 ) )
|
|
CALayerSetPosition( secondsLayer, fn CGPointMake( frame.size.width / 2, frame.size.height / 2 ) )
|
|
CALayerSetBounds( secondsLayer, fn CGRectMake( 0, 0, 3, frame.size.width / 2 -35 ) )
|
|
CALayerAddSublayer( layer, secondsLayer )
|
|
|
|
// Timing functions and calculations
|
|
dt = fn CalendarStartOfDayForDate( fn CalendarCurrent, fn DateInit )
|
|
ti = fn DateTimeIntervalSinceDate( fn DateInit, dt )
|
|
|
|
h = ti / 3600.0
|
|
m = ( h - int(h) ) * 60.0
|
|
s = ( m - int(m) ) * 60.0
|
|
|
|
ha = h / 12.0 * 360.0
|
|
ma = m / 60.0 * 360.0
|
|
sa = s / 60.0 * 360.0
|
|
|
|
// Rotation calculation
|
|
CALayerSetTransform( secondsLayer, fn CATransform3DMakeRotation( sa / 180.0 * PI, 0, 0, 1 ) )
|
|
CALayerSetTransform( minutesLayer, fn CATransform3DMakeRotation( ma / 180.0 * PI, 0, 0, 1 ) )
|
|
CALayerSetTransform( hoursLayer, fn CATransform3DMakeRotation( ha / 180.0 * PI, 0, 0, 1 ) )
|
|
|
|
// Animations for each clock hand
|
|
secondsAnimation = fn CABasicAnimationWithKeyPath( @"transform.rotation.z" )
|
|
CAMediaTimingSetRepeatCount( secondsAnimation, INFINITY )
|
|
CAMediaTimingSetDuration( secondsAnimation, 60 )
|
|
CAAnimationSetRemovedOnCompletion( secondsAnimation, NO )
|
|
CABasicAnimationSetFromValue( secondsAnimation, @( -sa * PI / 180 ) )
|
|
CABasicAnimationSetByValue( secondsAnimation, @( -2 * PI ) )
|
|
CAAnimationSetTimingFunction( secondsAnimation, fn CAMediaTimingFunctionWithName( kCAMediaTimingFunctionLinear ) )
|
|
CALayerAddAnimation( secondsLayer, secondsAnimation, @"SecondAnimationKey" )
|
|
|
|
minutesAnimation = fn CABasicAnimationWithKeyPath( @"transform.rotation.z" )
|
|
CAMediaTimingSetRepeatCount( minutesAnimation, INFINITY )
|
|
CAMediaTimingSetDuration( minutesAnimation, 60 * 60 )
|
|
CAAnimationSetRemovedOnCompletion( minutesAnimation, NO )
|
|
CABasicAnimationSetFromValue( minutesAnimation, @( -ma * PI / 180 ) )
|
|
CABasicAnimationSetByValue( minutesAnimation, @( -2 * PI ) )
|
|
CAAnimationSetTimingFunction( minutesAnimation, fn CAMediaTimingFunctionWithName( kCAMediaTimingFunctionLinear ) )
|
|
CALayerAddAnimation( minutesLayer, minutesAnimation, @"MinutesAnimationKey" )
|
|
|
|
hoursAnimation = fn CABasicAnimationWithKeyPath( @"transform.rotation.z" )
|
|
CAMediaTimingSetRepeatCount( hoursAnimation, INFINITY )
|
|
CAMediaTimingSetDuration( hoursAnimation, 60 * 60 * 12 )
|
|
CAAnimationSetRemovedOnCompletion( hoursAnimation, NO )
|
|
CABasicAnimationSetFromValue( hoursAnimation, @( -ha * PI / 180 ) )
|
|
CABasicAnimationSetByValue( hoursAnimation, @( -2 * PI ) )
|
|
CAAnimationSetTimingFunction( hoursAnimation, fn CAMediaTimingFunctionWithName( kCAMediaTimingFunctionLinear ) )
|
|
CALayerAddAnimation( hoursLayer, hoursAnimation, @"HoursAnimationKey" )
|
|
|
|
// Center hub
|
|
hubLayer = fn CAShapeLayerInit
|
|
r = fn CGRectMake( 244, 242, 16, 16 )
|
|
hub = fn BezierPathWithOvalInRect( r )
|
|
CAShapeLayerSetPath( hubLayer, hub )
|
|
CAShapeLayerSetLineWidth( hubLayer, 1.5 )
|
|
CAShapeLayerSetFillColor( hubLayer, fn ColorBlack )
|
|
CALayerAddSublayer( layer, hubLayer )
|
|
end fn
|
|
|
|
|
|
local fn DoDialog( ev as long, tag as long )
|
|
select ( ev )
|
|
case _viewWantsUpdateLayer : DialogEventSetBool(YES)
|
|
case _windowWillClose : end
|
|
end select
|
|
end fn
|
|
|
|
on dialog fn DoDialog
|
|
|
|
fn BuildWindow
|
|
|
|
HandleEvents
|