diff --git a/Documentation/.gitignore b/Documentation/.gitignore new file mode 100644 index 0000000..1320f90 --- /dev/null +++ b/Documentation/.gitignore @@ -0,0 +1 @@ +site diff --git a/Documentation/docs/AnimationKit.Coordinator.md b/Documentation/docs/AnimationKit.Coordinator.md new file mode 100644 index 0000000..981c7c8 --- /dev/null +++ b/Documentation/docs/AnimationKit.Coordinator.md @@ -0,0 +1,31 @@ +# AnimationKit.Coordinator + +This class handles all the aspects of animation. Most users will never need to think about this class at all however. The coordinator can be subclassed to customize behaviors if necessary. + +The Run method of [AnimationKit.Task](AnimationKit.Task.md) will use an application-global coordinator if one is not passed in. This global coordinator can be referenced using the AnimationKit.SharedCoordinator method. + +## Events + +
Event TaskAdded (Task As AnimationKit.Task)
+Triggered after a task has been added to the animation queue.
+
+Event TaskRemoved (Task As AnimationKit.Task)
+Triggered after a task has been removed from the animation queue. This will happen for any of the following reasons:
+
+- Animation has completed
+- Animation was cancelled
+- Target has gone out of scope
+
+## Properties
+
+FramesPerSecond As Integer = 60
+Allows the developer to customize the performance of the animations. There is a logical maximum of 100 frames per second.
+
+## Methods
+
+Sub AddTask (Task As AnimationKit.Task)
+Adds a task to the coordinator and begins animating it.
+
+## See Also
+
+[AnimationKit.Task](AnimationKit.Task.md)
\ No newline at end of file
diff --git a/Documentation/docs/AnimationKit.Curve.md b/Documentation/docs/AnimationKit.Curve.md
new file mode 100644
index 0000000..70421f8
--- /dev/null
+++ b/Documentation/docs/AnimationKit.Curve.md
@@ -0,0 +1,73 @@
+# AnimationKit.Curve
+
+This class describes a cubic bézier curve which controls the timing of animation tasks. The values are identical to css easing animations, meaning you can use an [online generator](http://matthewlein.com/ceaser/) to experiment and generate your own curves.
+
+## Constructors
+
+P1 As Xojo.Core.Point, P2 As Xojo.Core.Point
+Creates a new curve with points P1 and P2. P0 is always {0, 0}, and P3 is always {1, 1}.
+
+P1X As Single, P1Y As Single, P2X As Single, P2Y As Single
+Alternate constructor which uses 4 singles instead of 2 Xojo.Core.Point objects.
+
+## Methods
+
+Function Evaluate (Time As Double, StartValue As Double, EndValue As Double) As Double
+Determine the value between StartValue and EndValue given a Time between 0 and 1.
+
+Function Reverse () As AnimationKit.Curve
+Returns a new curve whose with inverted control points.
+
+## Shared Methods
+
+Shared Function CreateEaseIn () As AnimationKit.Curve
+Returns a new curve using the EaseIn preset.
+
+Shared Function CreateEaseInOut () As AnimationKit.Curve
+Returns a new curve using the EaseInOut preset.
+
+Shared Function CreateEaseOut () As AnimationKit.Curve
+Returns a new curve using the EaseOut preset.
+
+Shared Function CreateFromPreset(Preset As AnimationKit.Curve.Presets) As AnimationKit.Curve
+Returns a new curve using the provided preset.
+
+Shared Function CreateLinear () As AnimationKit.Curve
+Returns a new curve using the Linear preset.
+
+## Enumerations
+
+Presets { + Linear = 0, + EaseIn, + EaseInBack, + EaseInCirc, + EaseInCubic, + EaseInExpo, + EaseInQuad, + EaseInQuart, + EaseInQuint, + EaseInSine, + EaseOut, + EaseOutBack, + EaseOutCirc, + EaseOutCubic, + EaseOutExpo, + EaseOutQuad, + EaseOutQuart, + EaseOutQuint, + EaseOutSine, + EaseInOut, + EaseInOutBack, + EaseInOutCirc, + EaseInOutCubic, + EaseInOutExpo, + EaseInOutQuad, + EaseInOutQuart, + EaseInOutQuint, + EaseInOutSine +}+ +## See Also + +[AnimationKit.MoveTask](AnimationKit.MoveTask.md), [AnimationKit.ScrollTask](AnimationKit.ScrollTask.md), [AnimationKit.ValueTask](AnimationKit.ValueTask.md) \ No newline at end of file diff --git a/Documentation/docs/AnimationKit.Frame.md b/Documentation/docs/AnimationKit.Frame.md new file mode 100644 index 0000000..a0e680d --- /dev/null +++ b/Documentation/docs/AnimationKit.Frame.md @@ -0,0 +1,26 @@ +# AnimationKit.Frame + +## Constructors + +
Image As iOSImage, RetinaImage As iOSImage
+Image As Picture, RetinaImage As Picture
+Creates a new frame with the provided graphic. If a retina version is provided (which it should be) it must match exactly 2x the width and height as the standard graphic.
+
+## Methods
+
+Function Dimensions () As Xojo.Core.Size
+Returns the width and height of the standard graphic.
+
+## Properties
+
+Image As iOSImage // Read Only
+Image As Picture // Read Only
+The standard resolution graphic.
+
+RetinaImage As iOSImage // Read Only
+RetinaImage As Picture // Read Only
+The double resolution graphic.
+
+## See Also
+
+[AnimationKit.FrameSet](AnimationKit.FrameSet.md), [AnimationKit.FrameTarget](AnimationKit.FrameTarget.md), [AnimationKit.FrameTask](AnimationKit.FrameTask.md)
\ No newline at end of file
diff --git a/Documentation/docs/AnimationKit.FrameSet.md b/Documentation/docs/AnimationKit.FrameSet.md
new file mode 100644
index 0000000..78955d1
--- /dev/null
+++ b/Documentation/docs/AnimationKit.FrameSet.md
@@ -0,0 +1,53 @@
+# AnimationKit.FrameSet
+
+Holds a set of [AnimationKit.Frame](AnimationKit.Frame.md) objects used to animate with a [AnimationKit.FrameTask](AnimationKit.FrameTask.md).
+
+This class supports multiple usage syntaxes. Developers can choose to use this as a class, like they would a [FolderItem](http://docs.xojo.com/index.php/FolderItem), or they can choose to use it as an array. Each of the following syntaxes are acceptable:
+
+For I As Integer = 0 To Set.Count - 1
Dim Frame As AnimationKit.Frame = Set.Frame(I)
// Do something
Next
For I As Integer = 0 To UBound(Set)
Dim Frame As AnimationKit.Frame = Set(I)
// Do something
Next
For Each Frame As AnimationKit.Frame In Set
// Do something
Next
+
+### Frame Dimensions
+
+All frames in a set must match their dimensions exactly. Only when the set is empty will the set accept an image of any size. Once the set has one or more frames, attempting to add a frame with different dimensions will trigger an UnsupportedOperationException.
+
+## Methods
+
+Sub Append (Frame As AnimationKit.Frame)
+Add a frame to the end the set.
+
+Function Count () As Integer
+Returns the number of items in the set.
+
+Function FirstFrame () As AnimationKit.Frame
+This is a shorthand for Frame(0).
+
+Function Frame (Index As Integer) As AnimationKit.Frame
+Returns the frame at the given 0-based index.
+
+Sub Frame (Index As Integer, Assigns Value As AnimationKit.Frame)
+Changes the frame at the give 0-based index.
+
+Function IndexOf (Frame As AnimationKit.Frame) As Integer
+Returns the index of the given frame, or -1 if not found.
+
+Sub Insert (Index As Integer, Frame As AnimationKit.Frame)
+Adds a new frame at the given index, increasing the index of each frame whose index is >= the given index.
+
+Function LastFrame () As AnimationKit.Frame
+This is a shorthand for Frame(Count - 1).
+
+Sub Remove (Index As Integer)
+Removes the frame at the given index.
+
+Function Reverse () As AnimationKit.FrameSet
+Returns a new frame set with the frames in reverse.
+
+## Shared Methods
+
+Shared Function CreateFromSpriteSheet (Sprites As iOSImage, RetinaSprites As iOSImage, CellWidth As Integer, CellHeight As Integer, Rows As Integer, Columns As Integer) As AnimationKit.FrameSet
+Shared Function CreateFromSpriteSheet (Sprites As Picture, RetinaSprites As Picture, CellWidth As Integer, CellHeight As Integer, Rows As Integer, Columns As Integer) As AnimationKit.FrameSet
+These methods take a sprite grid and create a frame set. Provide the size of each cell, as well as the number of rows and columns in the grid. The input graphic will be checked to ensure dimensions match the provided cell sizes, row count, and column count. The Retina graphic is very strongly recommended, but not required. To avoid supporting retina resolutions properly, pass Nil for the second parameter.
+
+## See Also
+
+[AnimationKit.Frame](AnimationKit.Frame.md), [AnimationKit.FrameTarget](AnimationKit.FrameTarget.md), [AnimationKit.FrameTask](AnimationKit.FrameTask.md)
\ No newline at end of file
diff --git a/Documentation/docs/AnimationKit.FrameTarget.md b/Documentation/docs/AnimationKit.FrameTarget.md
new file mode 100644
index 0000000..d06e633
--- /dev/null
+++ b/Documentation/docs/AnimationKit.FrameTarget.md
@@ -0,0 +1,16 @@
+# AnimationKit.FrameTarget
+
+## Interface Methods
+
+Sub AnimationStep (Identifier As Text, Frame As AnimationKit.Frame)
+This method is fired as often as necessary to run the animation, providing both the identifier and the new frame.
+
+## Example Class
+
+This is a very simple class that will display each frame given to it.
+
+Sub Paint (g As Graphics, areas() As REALbasic.Rect)
If Self.CurrentFrame <> Nil Then
G.DrawPicture(Self.CurrentFrame.Image, 0, 0)
End If
End Sub
Sub AnimationStep (Identifier As Text, Frame As AnimationKit.Frame)
// Part of the AnimationKit.FrameTarget interface.
Self.CurrentFrame = Frame
Self.Invalidate(Self.EraseBackground)
End Sub
Private CurrentFrame As AnimationKit.Frame
+
+## See Also
+
+[AnimationKit.Frame](AnimationKit.Frame.md), [AnimationKit.FrameSet](AnimationKit.FrameSet.md), [AnimationKit.FrameTask](AnimationKit.FrameTask.md)
\ No newline at end of file
diff --git a/Documentation/docs/AnimationKit.FrameTask.md b/Documentation/docs/AnimationKit.FrameTask.md
new file mode 100644
index 0000000..e3c5927
--- /dev/null
+++ b/Documentation/docs/AnimationKit.FrameTask.md
@@ -0,0 +1,38 @@
+# AnimationKit.FrameTask
+
+Inherits from [AnimationKit.Task](AnimationKit.Task.md).
+
+This task controls animations for implementors of the [AnimationKit.FrameTarget](AnimationKit.FrameTarget.md) interface.
+
+A frame task does no actual animation, instead providing a way for an implementor to animate using sprites. Frame tasks have an identifier property which is used by the implementor to determine which sprite the new frame is intended for.
+
+See the [AnimationKit.FrameTarget](AnimationKit.FrameTarget.md) interface for an example implementation and usage.
+
+## Constructors
+
+Target As AnimationKit.FrameTarget, Frames As AnimationKit.FrameSet
+Creates a task for Target with the provided set of frames. The frame set can be modified after the task is created, but before it is run.
+
+## Properties
+
+DurationInSeconds As Double = 1.0
+If the Looping property is true, this is the number of seconds required to complete one loop of the animation. If the Looping property is false, this is the number of seconds required to complete the animation.
+
+[AnimationKit.Coordinator.FramesPerSecond](AnimationKit.Coordinator.md#property.framespersecond) has minimal impact on the animation speed. The duration property fully determines the speed at which frames will be swapped. This means frames may be duplicated or dropped to match the intended duration.
+
+For example, assuming the default of 60 frames per second, a frame set of 30 frames, and a duration of 1 second, each frame in the set will be displayed for two animation frames.
+
+The implementor will only receive a change notification when the frame actually changes; duplicated frames will not trigger duplicate notifications.
+
+Frames As AnimationKit.FrameSet = New AnimationKit.FrameSet()
+The set of frames to play/loop through.
+
+Identifier As Text = ""
+The identifier is used to instruct the implementor which sprite the new frame is for.
+
+Looping As Boolean = False
+If true, the animation will never end.
+
+## See Also
+
+[AnimationKit.Frame](AnimationKit.Frame.md), [AnimationKit.FrameSet](AnimationKit.FrameSet.md), [AnimationKit.FrameTarget](AnimationKit.FrameTarget.md)
\ No newline at end of file
diff --git a/Documentation/docs/AnimationKit.MoveTask.md b/Documentation/docs/AnimationKit.MoveTask.md
new file mode 100644
index 0000000..27737e3
--- /dev/null
+++ b/Documentation/docs/AnimationKit.MoveTask.md
@@ -0,0 +1,77 @@
+# AnimationKit.MoveTask
+
+Inherits from [AnimationKit.Task](AnimationKit.Task.md). Only available to Desktop projects.
+
+This class is used for manipulating the size and position of windows and controls, probably the most used class in the framework.
+
+## Constructors
+
+Target As RectControl
+Creates the task with the specified control set to the Item property. The Left, Top, Width, and Height properties will be set to the control's current position.
+
+Target As Window
+Creates the task with the specified window set to the Item property. The Left, Top, Width, and Height properties will be set to window's current position.
+
+## Properties
+
+AnimateHeight As Boolean = False
+When true, the target's Height property will be animated.
+
+AnimateLeft As Boolean = False
+When true, the target's Left property will be animated.
+
+AnimateTop As Boolean = False
+When true, the target's Top property will be animated.
+
+AnimateWidth As Boolean = False
+When true, the target's Width property will be animated.
+
+Curve As AnimationKit.Curve = AnimationKit.Curve.CreateLinear()
+The timing curve to use for this animation.
+
+DurationInSeconds As Double = 1.0
+Number of seconds the animation will require to complete.
+
+Height As Double = Target.Height
+The final height of the target. Changing this value automatically sets AnimateHeight to True.
+
+Left As Double = Target.Left
+The final left position of the target. Changing this value automatically sets AnimateLeft to True.
+
+Top As Double = Target.Top
+The final top position of the target. Changing this value automatically sets AnimateTop to True.
+
+Width As Double = Target.Width
+The final width of the target. Changing this value automatically sets AnimateWidth to True.
+
+## Methods
+
+Sub EnableValues (ParamArray Keys() As UInt64)
+Pass one or more of the Key constants to enable property animations in bulk.
+
+Sub DisableValues (ParamArray Keys() As UInt64)
+Pass one or more of the Key constants to disable property animations in bulk.
+
+Function OriginalRect () As Xojo.Core.Rect
+Returns the starting rect of the target. May return Nil if the animation has not started.
+
+Sub SetDestination (Source As Xojo.Core.Rect)
+Sets the destination of the target using the provided rect. Also accepts a REALbasic.Rect in desktop projects. Only values which differ from the control's current position will be animated. Automatically sets the value of all four Animate properties accordingly.
+
+## Constants
+
+Const KeyHeight = 8
Const KeyLeft = 1
Const KeyTop = 2
Const KeyWidth = 4
+
+## iOS Projects
+
+This task has all the functionality necessary to support iOSControl animations, but the iOSControl cannot be moved. So the class is currently disabled on iOS despite being designed to work for iOS projects.
+
+The reason iOSControls cannot be moved is because of the auto layout system. Moving a control requires manipulating the restraints around it, which is not immediately practical. Support for iOSControl animations may come in the future.
+
+## Web Projects
+
+This task does not support WebControl due to the high latency of web communications. In its current form, the latency prohibits the animation from working in any reasonable manner. In the future, it may be possible to translate the task properties into a CSS animation so the browser can run the animation entirely client side.
+
+## See Also
+
+[AnimationKit.Curve](AnimationKit.Curve.md)
\ No newline at end of file
diff --git a/Documentation/docs/AnimationKit.ScrollTask.md b/Documentation/docs/AnimationKit.ScrollTask.md
new file mode 100644
index 0000000..1e97789
--- /dev/null
+++ b/Documentation/docs/AnimationKit.ScrollTask.md
@@ -0,0 +1,61 @@
+# AnimationKit.ScrollTask
+
+Inherits from [AnimationKit.Task](AnimationKit.Task.md).
+
+This class is used to animate scrolling behaviors for any class which implements the [AnimationKit.Scrollable](AnimationKit.Scrollable.md) interface. Delegate classes are built-in to support scrolling the [ScrollBar](http://docs.xojo.com/index.php/Scrollbar), [TextArea](http://docs.xojo.com/index.php/TextArea), and [Listbox](http://docs.xojo.com/index.php/Listbox) controls.
+
+## Constructors
+
+Target As AnimationKit.Scrollable
+Creates the task using a class which implements the AnimationKit.Scrollable interface.
+
+Target As Listbox
+Creates the task using using the provided Listbox. The Position property links to the Listbox.ScrollPosition property. Minimum and Maximum properties have no effect on Listbox controls.
+
+Target As ScrollBar
+Creates the task using using the provided Scrollbar. The Position property links to the ScrollBar.Value property.
+
+Target As TextArea
+Creates the task using using the provided TextArea. The Position property links to the TextArea.ScrollPosition property. Minimum and Maximum properties have no effect on TextArea controls.
+
+## Properties
+
+AnimateMaximum As Boolean = False
+When true, the target's Maximum property will be animated.
+
+AnimateMinimum As Boolean = False
+When true, the target's Minimum property will be animated.
+
+AnimatePosition As Boolean = False
+When true, the target's Position property will be animated.
+
+Curve As AnimationKit.Curve = AnimationKit.Curve.CreateLinear()
+The timing curve to use for this animation.
+
+DurationInSeconds As Double = 1.0
+Number of seconds the animation will require to complete.
+
+Maximum As Double = Target.Maximum
+The final scroll maximum of the target. Changing this value automatically sets AnimateMaximum to True.
+
+Minimum As Double = Target.Minimum
+The final scroll minimum of the target. Changing this value automatically sets AnimateMinimum to True.
+
+Position As Double = Target.Position
+The final scroll position of the target. Changing this value automatically sets AnimatePosition to True.
+
+## Methods
+
+Sub EnableValues (ParamArray Keys() As UInt64)
+Pass one or more of the Key constants to enable property animations in bulk.
+
+Sub DisableValues (ParamArray Keys() As UInt64)
+Pass one or more of the Key constants to disable property animations in bulk.
+
+## Constants
+
+Const KeyMaximum = 2
Const KeyMinimum = 1
Const KeyPosition = 4
+
+## See Also
+
+[AnimationKit.Scrollable](AnimationKit.Scrollable.md), [AnimationKit.Curve](AnimationKit.Curve.md)
\ No newline at end of file
diff --git a/Documentation/docs/AnimationKit.Scrollable.md b/Documentation/docs/AnimationKit.Scrollable.md
new file mode 100644
index 0000000..47c7889
--- /dev/null
+++ b/Documentation/docs/AnimationKit.Scrollable.md
@@ -0,0 +1,27 @@
+# AnimationKit.Scrollable
+
+This is an interface that can be implemented by custom classes which can be scrolled. It allows the class to be animated with the [AnimationKit.ScrollTask](AnimationKit.ScrollTask.md) class.
+
+## Interface Methods
+
+Function ScrollMaximum () As Double
+Return the current maximum scroll value.
+
+Sub ScrollMaximum (Assigns Value As Double)
+Set the new maximum scroll value.
+
+Function ScrollMinimum () As Double
+Return the current minimum scroll value.
+
+Sub ScrollMinimum (Assigns Value As Double)
+Set the new minimum scroll value.
+
+Function ScrollPosition () As Double
+Return the current scroll position.
+
+Sub ScrollPosition (Assigns Value As Double)
+Set the new scroll position.
+
+## See Also
+
+[AnimationKit.ScrollTask](AnimationKit.ScrollTask.md)
\ No newline at end of file
diff --git a/Documentation/docs/AnimationKit.Task.md b/Documentation/docs/AnimationKit.Task.md
new file mode 100644
index 0000000..96b2686
--- /dev/null
+++ b/Documentation/docs/AnimationKit.Task.md
@@ -0,0 +1,63 @@
+# AnimationKit.Task
+
+AnimationKit.Task is the parent class for all animations. It controls things like frame delays and general animation status information.
+
+## Events
+
+Event Completed ()
+When the task has finished executing, after the final Perform event, the `Completed` event will fire. Will not fire if the task was cancelled.
+
+Event Perform (Final As Boolean, Time As Double)
+The current state of the animation should be updated. Will not fire if the object referenced by the Item property has gone out of scope. If `Final` is true, this is the last `Perform` event that will be fired for this task.
+
+The `Time` parameter is a value returned by the Xojo `Microseconds` method used to coordinate the execution times of multiple animations. It is strongly recommended that developers calculate based on the `Time` parameter, and not by the value returned by `Microseconds`.
+
+Event Started ()
+The `Started` event triggers immediately before the first `Perform` event.
+
+## Properties
+
+Cancelled As Boolean // Read Only
+`Cancelled` will be true if either the `Cancel` method has been called, or the object referenced by the `Item` property has gone out of scope. The task can no longer execute, and no more `Perform` events will trigger. Chained tasks will not be started.
+
+Item As Object = Nil
+The target of the animation. This is a weak reference, so that when the target goes out of scope, the animation will automatically cancel.
+
+LastFrameTime As Double // Read Only
+The time in microseconds that the last `Perform` event was triggered.
+
+NextTask As AnimationKit.Task = Nil
+When this task has completed, automatically start the task referenced in this property. The new value will always be set to the end of the chain. To break the chain, set this property to `Nil`. To replace an item in the chain, rather than append, set this property to `Nil` first, then to the intended value.
+
+Started As Boolean // Read Only
+The animation has started.
+
+## Methods
+
+Sub Cancel ()
+Stops the animation where it is.
+
+Sub Completed ()
+Triggers an `UnsupportedOperationException`. Subclasses must override so the framework knows when a task is complete and can move on to the next task in the chain.
+
+Function ElapsedTime (Time As Double) As Double
+Amount of time in microseconds since `Time` that has elapsed since the task started execution.
+
+Sub Perform (Time As Double)
+Does some status checking and triggers the `Perform` event if necessary.
+
+Sub Run ()
+Begin the animation using the application global coordinator.
+
+Sub Run (Coordinator As AnimationKit.Coordinator)
+Begin the animation using the coordinator specified.
+
+## Subclassing
+
+Developers can create subclasses to implement new forms of animation.
+
+The `Completed` method must be overridden.
+
+## See Also
+
+[AnimationKit.Coordinator](AnimationKit.Coordinator.md), [AnimationKit.MoveTask](AnimationKit.MoveTask.md)
\ No newline at end of file
diff --git a/Documentation/docs/AnimationKit.ValueAnimator.md b/Documentation/docs/AnimationKit.ValueAnimator.md
new file mode 100644
index 0000000..f7bd5d3
--- /dev/null
+++ b/Documentation/docs/AnimationKit.ValueAnimator.md
@@ -0,0 +1,18 @@
+# AnimationKit.ValueAnimator
+
+This interface allows custom classes to implement simple animations. Anything numeric can be animated using this interface and the [AnimationKit.ValueTask](AnimationKit.ValueTask.md) task.
+
+## Interface Methods
+
+Sub AnimationStep (Identifier As Text, Value As Double)
+This method is fired as often as necessary to run the animation, providing both the identifier and current value.
+
+## Example Class
+
+The following class is a Label subclass which accepts an integer value and animates counting up/down to the new value. A reference to the last task is retained so the animation can be interrupted and changed to a new value.
+
+Class CountingLabel Inherits Label
Public Sub Add (Amount As Integer)
Self.Value = Self.Value + Amount
End Sub
Public Sub AnimationStep (Identifier As Text, Value As Double)
// Part of the AnimationKit.ValueAnimator interface.
Select Case Identifier
Case "Text"
Self.Text = Str(Round(Value), "-0")
End Select
End Sub
Public Sub Subtract (Amount As Integer)
Self.Value = Self.Value - Amount
End Sub
Public Function Value () As Integer
Return Val(Self.Text)
End Function
Public Sub Value (Assigns NewValue As Integer)
If Task <> Nil And Not (Task.Completed Or Task.Cancelled) Then
Task.Cancel
Task = Nil
End If
Task = New AnimationKit.ValueTask(Self, "Text", Self.Value, Value)
Task.DurationInSeconds = 1
Task.Curve = AnimationKit.Curve.CreateEaseOut
Task.Run
End Sub
Private Property Task As AnimationKit.ValueTask
End Class
+
+## See Also
+
+[AnimationKit.ValueTask](AnimationKit.ValueTask.md)
\ No newline at end of file
diff --git a/Documentation/docs/AnimationKit.ValueTask.md b/Documentation/docs/AnimationKit.ValueTask.md
new file mode 100644
index 0000000..7f4c9e6
--- /dev/null
+++ b/Documentation/docs/AnimationKit.ValueTask.md
@@ -0,0 +1,35 @@
+# AnimationKit.ValueTask
+
+This task is used to create simple animations for implementors of the [AnimationKit.ValueAnimator](AnimationKit.ValueAnimator.md) interface.
+
+A value task does no actual animation, instead providing a simple way for a custom class to implement their own animation without creating a custom [AnimationKit.Task](AnimationKit.Task.md) subclass.
+
+Value tasks have an identifier property which is used by the implementor to determine what actually needs to change. For example, if an implementor wants to animate an opacity change, the identifier might simply be "*opacity*".
+
+See the [AnimationKit.ValueAnimator](AnimationKit.ValueAnimator.md) interface for an example implementation and usage.
+
+## Constructors
+
+Target As AnimationKit.ValueAnimator, Identifier As Text, StartValue As Double, EndValue As Double
+Creates a task for Target with the provided identifier, start value, and end values.
+
+## Properties
+
+Curve As AnimationKit.Curve = AnimationKit.Curve.CreateLinear()
+The timing curve to use for this animation.
+
+DurationInSeconds As Double = 1.0
+Number of seconds the animation will require to complete.
+
+EndValue As Double
+The final value the task should animate to.
+
+Identifier As Text
+The identifier used to instruct the implementor what the value is used for.
+
+StartValue As Double
+The beginning value the task should animate from.
+
+## See Also
+
+[AnimationKit.ValueAnimator](AnimationKit.ValueAnimator.md)
\ No newline at end of file
diff --git a/Documentation/docs/History.md b/Documentation/docs/History.md
new file mode 100644
index 0000000..dd71cc3
--- /dev/null
+++ b/Documentation/docs/History.md
@@ -0,0 +1,5 @@
+# Version History
+
+Version 3.0 - March 28th, 2015
+
+- Initial 3.0 release.
\ No newline at end of file
diff --git a/Documentation/docs/Migrating.md b/Documentation/docs/Migrating.md
new file mode 100644
index 0000000..545c4af
--- /dev/null
+++ b/Documentation/docs/Migrating.md
@@ -0,0 +1,99 @@
+# Migrating from Animation Kit 2.5
+
+Animation Kit was originally released in late 2007. Version 2 was only a few months later in March 2008. Back then, Xojo was known as REALbasic. REALbasic evolved into REAL Studio, which evolved into Xojo.
+
+A lot has changed since then. Xojo has namespace support now, so prefixing classes with AK has become no longer necessary. AddHandler allows Animation Kit to eliminate the AKTimer subclass completely. And of course new ideas have been thought up. In order to push Animation Kit forward, the old framework had to be torn down.
+
+This guide is designed to help developers who want to transition to the new Animation Kit. Transitioning is recommended, as older versions had a potential referencing problem that could cause crashes or exceptions if a window is closed while an animation running.
+
+## Requirements
+
+Animation Kit 3 absolutely requires Xojo 2015 Release 1 or newer. This version was developed as a universal set of code compatible with all project types, and therefore makes extensive use of the New Xojo Framework.
+
+## AKCore
+
+AKCore is replaced by [AnimationKit.Coordinator](AnimationKit.Coordinator.md) but developers will not need to worry about the coordinator like they would the AKCore module.
+
+There is no replacement for AKCore.Start and AKCore.Stop. These jobs are handled automatically.
+
+AKCore.SplitGraphic has been replaced by the CreateFromSpriteSheet shared method on [AnimationKit.FrameSet](AnimationKit.FrameSet.md).
+
+The NewFrameTask and NewMoveTask extension methods should work exactly as-is.
+
+AKCore.ReverseFrames has been replaced by the Reverse method on [AnimationKit.FrameSet](AnimationKit.FrameSet.md).
+
+The ContentRect methods have no replacement. However, Xojo has a built in [Bounds property](http://docs.xojo.com/index.php/Window.Bounds) on Window which is similar.
+
+The Animate extension methods will work similarly, but move tasks will need to use a [curve](AnimationKit.Curve.md) instead of an easing constant, and frame tasks will require a [AnimationKit.FrameSet](AnimationKit.FrameSet.md) instead of an array of pictures.
+
+There is no AKCompletionDelegate anymore. Use the Completed event as part of [AnimationKit.Task](AnimationKit.Task.md) instead.
+
+## AKEasing
+
+The AKEasing module has been completely replaced by the [AnimationKit.Curve](AnimationKit.Curve.md) class. Nearly all of the easing methods are still available, but Bounce and Elastic had to be dropped due to limitations of cubic bezier curves.
+
+## AKTimer
+
+AKTimer is gone completely. Developers should not have been mucking with this class anyway.
+
+## AKTask
+
+The AKTask class has been replaced by [AnimationKit.Task](AnimationKit.Task.md).
+
+To solve crashing and memory leak problems brought on by improper reference handling, AnimationKit.Task uses weak references instead of AKTask's strong references.
+
+HasCompleted is now known as Completed.
+
+HasStarted is now known as Started.
+
+RunTime is now known as ElapsedTime.
+
+Start, StartTime, UniqueID, ConflictResolutionAction, and OnCompleteAction have been removed. OnCompleteAction can be replaced by the Completed event, but the others have no replacement.
+
+## AKFrameTask
+
+AKFrameTask has been replaced by [AnimationKit.FrameTask](AnimationKit.FrameTask.md).
+
+Duration is now known as DurationInSeconds.
+
+Frames is now a [AnimationKit.FrameSet](AnimationKit.FrameSet.md) object, however it can still be used as an array.
+
+CurrentFrame has been removed. Developers are encouraged to get the current frame from the AnimationStep method the [AnimationKit.FrameTarget](AnimationKit.FrameTarget.md) interface provides.
+
+## AKMoveTask and AKResizeTask
+
+Both AKMoveTask and AKResizeTask have been replaced by [AnimationKit.MoveTask](AnimationKit.MoveTask.md).
+
+AKMoveTask would always animate all four position properties: Left, Top, Width, and Height. For some animations, this would be a problem, as another animation might be trying to change a property that the original animation never intended to change. That's why AKResizeTask was introduced, so only the Width and Height would change. This was still somewhat limiting.
+
+Instead, AnimationKit.MoveTask has four properties: AnimateLeft, AnimateTop, AnimateWidth, and AnimateHeight. These are automatically set to true when the developer changes the Left, Top, Width, and Height values, respectively. For the most part, developers will not need to worry about manually controlling these four Animate properties, but they are available just in case.
+
+Delta, GetCurrentRect, and SetRectNow have been removed.
+
+Duration is now known as DurationInSeconds.
+
+EasingMethod has been replaced by Curve, and the type changed to [AnimationKit.Curve](AnimationKit.Curve.md).
+
+NewRect has been removed. Instead, developers can use the SetDestination method, which automatically sets the Animate properties according to the value differences. There are also Left, Top, Width, and Height properties to use.
+
+## AKScrollTask
+
+AKScrollTask has been replaced by [AnimationKit.ScrollTask](AnimationKit.ScrollTask.md).
+
+Value is now known as Position.
+
+Duration is now known as DurationInSeconds.
+
+EasingMethod has been replaced by Curve, and the type changed to [AnimationKit.Curve](AnimationKit.Curve.md).
+
+OriginalValue has been removed with no replacement.
+
+## AKFrameTarget
+
+AKFrameTarget has been replaced by [AnimationKit.FrameTarget](AnimationKit.FrameTarget.md).
+
+ChangeFrame is now known as AnimationStep. The method is given an identifier provided by the driving task and the new frame, instead of the frame index and picture.
+
+## AKAnimationCanvas
+
+AKAnimationCanvas has been removed. Developers can replace the class using the [AnimationKit.FrameTarget](AnimationKit.FrameTarget.md) interface with minimal effort.
\ No newline at end of file
diff --git a/Documentation/docs/index.md b/Documentation/docs/index.md
new file mode 100644
index 0000000..ea4888e
--- /dev/null
+++ b/Documentation/docs/index.md
@@ -0,0 +1,43 @@
+# The ZAZ Animation Kit Version 3
+
+Animation Kit is a powerful animation framework for Xojo projects. All animations are asynchronous and driven by time, rather than by a number of iterations or changes.
+
+Animation Kit includes task subclasses to power window and control movements and resizes, change scroll positions, and sequence sprites. Developer classes can implement an interface to allow their own light animations, or create custom task subclasses to provide any form of animation necessary.
+
+The framework is simple enough to execute animations with a single line of code, while being powerful enough to handle any animation the developer requires.
+
+## Requirements
+
+Animation Kit utilizes the new Xojo Framework made available in 2015 Release 1. All projects can compile and use the framework, but not every feature is supported in all projects.
+
+## Installation
+
+Download the Animation Kit project, open the `Animation Kit.xojo_binary_project` file, then copy the `AnimationKit` module into your project.
+
+## Getting Started
+
+Animation can be started with a simple `Animate` shorthand method.
+
+
+PushButton1.Animate(New Xojo.Core.Rect(PushButton1.Left, PushButton1.Top, 100, PushButton1.Height), 0.2)
+
+
+This will cause the button PushButton1 to adjust to 100 points wide. Since the Left, Top, and Height values do not change, those values will not be animated.
+
+The same job can be done more explicitly, which is also more flexible.
+
+
+Dim Task As New AnimationKit.MoveTask(PushButton1)
Task.DurationInSeconds = 0.25
Task.Width = 100
Task.Run
+
+
+Both variants will behave exactly the same.
+
+## Next Steps
+
+Explore the [AnimationKit.MoveTask](AnimationKit.MoveTask.md), [AnimationKit.ScrollTask](AnimationKit.ScrollTask.md), and [AnimationKit.Curve](AnimationKit.Curve.md) classes for more customizable animations.
+
+Custom control developers should explore the [AnimationKit.ValueAnimator](AnimationKit.ValueAnimator.md) and [AnimationKit.Scrollable](AnimationKit.Scrollable.md) interfaces.
+
+Developers interested in sprite-based animations should explore the [AnimationKit.Frame](AnimationKit.Frame.md), [AnimationKit.FrameSet](AnimationKit.FrameSet.md), and [AnimationKit.FrameTask](AnimationKit.FrameTask.md) classes.
+
+If you are upgrading from a previous version of Animation Kit, [see this migration guide](Migrating.md).
\ No newline at end of file
diff --git a/Documentation/mkdocs.yml b/Documentation/mkdocs.yml
new file mode 100644
index 0000000..7824fc5
--- /dev/null
+++ b/Documentation/mkdocs.yml
@@ -0,0 +1,25 @@
+site_name: Animation Kit
+pages:
+- Home: 'index.md'
+- Tasks: [
+{AnimationKit.Task: 'AnimationKit.Task.md'},
+{AnimationKit.MoveTask: 'AnimationKit.MoveTask.md'},
+{AnimationKit.ScrollTask: 'AnimationKit.ScrollTask.md'},
+{AnimationKit.FrameTask: 'AnimationKit.FrameTask.md'},
+{AnimationKit.ValueTask: 'AnimationKit.ValueTask.md'}
+]
+- Interfaces: [
+{AnimationKit.ValueAnimator: 'AnimationKit.ValueAnimator.md'},
+{AnimationKit.Scrollable: 'AnimationKit.Scrollable.md'},
+{AnimationKit.FrameTarget: 'AnimationKit.FrameTarget.md'}
+]
+- Classes: [
+{AnimationKit.Curve: 'AnimationKit.Curve.md'},
+{AnimationKit.Frame: 'AnimationKit.Frame.md'},
+{AnimationKit.FrameSet: 'AnimationKit.FrameSet.md'},
+{AnimationKit.Coordinator: 'AnimationKit.Coordinator.md'}
+]
+- Migrating: 'Migrating.md'
+- Version History: 'History.md'
+theme: mkdocs
+include_next_prev: false
\ No newline at end of file
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..543ff3f
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,22 @@
+The MIT License (MIT)
+
+Copyright (c) 2015 thommcgrath
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
diff --git a/Project/.gitignore b/Project/.gitignore
new file mode 100644
index 0000000..c5ad6c3
--- /dev/null
+++ b/Project/.gitignore
@@ -0,0 +1,6 @@
+*.xojo_uistate
+Builds - *
+*.debug.app
+*.debug
+*.tar.gz
+TempSaveFile*
diff --git a/Project/Animation Kit.xojo_project b/Project/Animation Kit.xojo_project
new file mode 100644
index 0000000..3dd7edb
--- /dev/null
+++ b/Project/Animation Kit.xojo_project
@@ -0,0 +1,58 @@
+Type=Desktop
+RBProjectVersion=2015.021
+MinIDEVersion=20070100
+Class=App;App.xojo_code;&h12F941C6;&h0;false
+Window=Window1;Window1.xojo_window;&h2A4D798B;&h0;false
+Window=SheetDemo;SheetDemo.xojo_window;&h389363E5;&h0;false
+MenuBar=MenuBar1;MenuBar1.xojo_menu;&h4466EC05;&h0;false
+BuildSteps=Build Automation;Build Automation.xojo_code;&h55629F41;&h0;false
+Module=AnimationKit;AnimationKit.xojo_code;&h116B320C;&h0;false
+Class=Coordinator;AnimationKit/Coordinator.xojo_code;&h58699DBA;&h116B320C;false
+Class=Task;AnimationKit/Task.xojo_code;&h15A23C5E;&h116B320C;false
+Class=MoveTask;AnimationKit/MoveTask.xojo_code;&h3D3A4A32;&h116B320C;false
+Class=Curve;AnimationKit/Curve.xojo_code;&h472F74AB;&h116B320C;false
+Class=ValueTask;AnimationKit/ValueTask.xojo_code;&h58F6D3C0;&h116B320C;false
+Interface=Scrollable;AnimationKit/Scrollable.xojo_code;&h667F2647;&h116B320C;false
+Class=ScrollTask;AnimationKit/ScrollTask.xojo_code;&h5E7D58A2;&h116B320C;false
+Class=ListboxScrollDelegate;AnimationKit/ListboxScrollDelegate.xojo_code;&h13E13B76;&h116B320C;false
+Class=TextAreaScrollDelegate;AnimationKit/TextAreaScrollDelegate.xojo_code;&h3510D36F;&h116B320C;false
+Class=ScrollBarScrollDelegate;AnimationKit/ScrollBarScrollDelegate.xojo_code;&h75F4A284;&h116B320C;false
+Class=FrameTask;AnimationKit/FrameTask.xojo_code;&hFDA0642;&h116B320C;false
+Class=FrameSet;AnimationKit/FrameSet.xojo_code;&h32D120D5;&h116B320C;false
+Interface=ValueAnimator;AnimationKit/ValueAnimator.xojo_code;&h11E39699;&h116B320C;false
+Class=Frame;AnimationKit/Frame.xojo_code;&h338B9627;&h116B320C;false
+Class=FrameSetIterator;AnimationKit/FrameSetIterator.xojo_code;&h2B877291;&h116B320C;false
+Interface=FrameTarget;AnimationKit/FrameTarget.xojo_code;&h21BF716E;&h116B320C;false
+DefaultWindow=Window1
+AppMenuBar=MenuBar1
+MajorVersion=1
+MinorVersion=0
+SubVersion=0
+NonRelease=0
+Release=0
+InfoVersion=
+LongVersion=
+ShortVersion=
+WinCompanyName=
+WinInternalName=
+WinProductName=
+WinFileDescription=
+AutoIncrementVersionInformation=False
+BuildFlags=&h4800
+BuildLanguage=&h0
+DebugLanguage=&h0
+Region=
+WindowsName=Animation Kit Demo.exe
+MacCarbonMachName=Animation Kit Demo
+LinuxX86Name=Animation Kit Demo
+MacCreator=
+MDI=0
+MDICaption=
+DefaultEncoding=&h0
+AppIcon=Animation Kit.xojo_resources;&h0
+OSXBundleID=com.thezaz.animkitdemo
+DebuggerCommandLine=
+UseGDIPlus=False
+UseBuildsFolder=True
+IsWebProject=False
+UseLLVM=False
diff --git a/Project/Animation Kit.xojo_resources b/Project/Animation Kit.xojo_resources
new file mode 100644
index 0000000..a6d4df6
Binary files /dev/null and b/Project/Animation Kit.xojo_resources differ
diff --git a/Project/AnimationKit.xojo_code b/Project/AnimationKit.xojo_code
new file mode 100644
index 0000000..51401ef
--- /dev/null
+++ b/Project/AnimationKit.xojo_code
@@ -0,0 +1,160 @@
+#tag Module
+Protected Module AnimationKit
+ #tag CompatibilityFlags = ( not TargetHasGUI and not TargetWeb and not TargetIOS ) or ( TargetWeb ) or ( TargetHasGUI ) or ( TargetIOS )
+ #tag Method, Flags = &h0
+ Sub Animate(Extends Target As AnimationKit.FrameTarget, Frames As AnimationKit.FrameSet, DurationInSeconds As Double, Looping As Boolean)
+ Dim Task As New AnimationKit.FrameTask(Target, Frames)
+ Task.DurationInSeconds = DurationInSeconds
+ Task.Looping = Looping
+ Task.Run
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Animate(Extends Target As AnimationKit.ValueAnimator, Identifier As Text, StartValue As Double, EndValue As Double, DurationInSeconds As Double, Curve As AnimationKit.Curve = Nil)
+ Dim Task As New AnimationKit.ValueTask(Target, Identifier, StartValue, EndValue)
+ Task.DurationInSeconds = DurationInSeconds
+ If Curve <> Nil Then
+ Task.Curve = Curve
+ End If
+ Task.Run
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0, CompatibilityFlags = (TargetHasGUI)
+ Sub Animate(Extends Target As RectControl, Destination As REALbasic.Rect, DurationInSeconds As Double, Curve As AnimationKit.Curve = Nil)
+ Dim Task As New AnimationKit.MoveTask(Target)
+ Task.DurationInSeconds = DurationInSeconds
+ Task.SetDestination(Destination)
+ If Curve <> Nil Then
+ Task.Curve = Curve
+ End If
+ Task.Run
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0, CompatibilityFlags = (TargetHasGUI)
+ Sub Animate(Extends Target As RectControl, Destination As Xojo.Core.Rect, DurationInSeconds As Double, Curve As AnimationKit.Curve = Nil)
+ Dim Task As New AnimationKit.MoveTask(Target)
+ Task.DurationInSeconds = DurationInSeconds
+ Task.SetDestination(Destination)
+ If Curve <> Nil Then
+ Task.Curve = Curve
+ End If
+ Task.Run
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0, CompatibilityFlags = (TargetHasGUI)
+ Sub Animate(Extends Target As Window, Destination As REALbasic.Rect, DurationInSeconds As Double, Curve As AnimationKit.Curve = Nil)
+ Dim Task As New AnimationKit.MoveTask(Target)
+ Task.DurationInSeconds = DurationInSeconds
+ Task.SetDestination(Destination)
+ If Curve <> Nil Then
+ Task.Curve = Curve
+ End If
+ Task.Run
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0, CompatibilityFlags = (TargetHasGUI)
+ Sub Animate(Extends Target As Window, Destination As Xojo.Core.Rect, DurationInSeconds As Double, Curve As AnimationKit.Curve = Nil)
+ Dim Task As New AnimationKit.MoveTask(Target)
+ Task.DurationInSeconds = DurationInSeconds
+ Task.SetDestination(Destination)
+ If Curve <> Nil Then
+ Task.Curve = Curve
+ End If
+ Task.Run
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Function CloneRect(Source As Xojo.Core.Rect) As Xojo.Core.Rect
+ Return New Xojo.Core.Rect(Source.Left, Source.Top, Source.Width, Source.Height)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function NewFrameTask(Extends Target As AnimationKit.FrameTarget) As AnimationKit.FrameTask
+ Return New AnimationKit.FrameTask(Target, New AnimationKit.FrameSet)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0, CompatibilityFlags = (TargetHasGUI)
+ Function NewMoveTask(Extends Target As RectControl) As AnimationKit.MoveTask
+ Return New AnimationKit.MoveTask(Target)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0, CompatibilityFlags = (TargetHasGUI)
+ Function NewMoveTask(Extends Target As Window) As AnimationKit.MoveTask
+ Return New AnimationKit.MoveTask(Target)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h1
+ Protected Function SharedCoordinator() As AnimationKit.Coordinator
+ If SharedCoordinatorRef = Nil Then
+ SharedCoordinatorRef = New AnimationKit.Coordinator
+ End If
+
+ Return SharedCoordinatorRef
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function UBound(Frames As AnimationKit.FrameSet) As Integer
+ Return Frames.UBound
+ End Function
+ #tag EndMethod
+
+
+ #tag Note, Name = Documentation
+ Documentation can be found at http://docs.thezaz.com/animationkit/3.0.0
+
+ #tag EndNote
+
+
+ #tag Property, Flags = &h21
+ Private SharedCoordinatorRef As AnimationKit.Coordinator
+ #tag EndProperty
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ InitialValue="-2147483648"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Module
+#tag EndModule
diff --git a/Project/AnimationKit/Coordinator.xojo_code b/Project/AnimationKit/Coordinator.xojo_code
new file mode 100644
index 0000000..c93fd7b
--- /dev/null
+++ b/Project/AnimationKit/Coordinator.xojo_code
@@ -0,0 +1,139 @@
+#tag Class
+Protected Class Coordinator
+ #tag CompatibilityFlags = ( not TargetHasGUI and not TargetWeb and not TargetIOS ) or ( TargetWeb ) or ( TargetHasGUI ) or ( TargetIOS )
+ #tag Method, Flags = &h0
+ Sub AddTask(Task As AnimationKit.Task)
+ Self.Tasks.Append(Task)
+ RaiseEvent TaskAdded(Task)
+
+ If Self.Animator.Mode = Xojo.Core.Timer.Modes.Off Then
+ Self.Animator.Mode = Xojo.Core.Timer.Modes.Multiple
+ End If
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Sub Animator_Action(Sender As Xojo.Core.Timer)
+ Dim AddedTasks(), RemovedTasks() As AnimationKit.Task
+ For I As Integer = UBound(Self.Tasks) DownTo 0
+ If Self.Tasks(I).Cancelled Then
+ RemovedTasks.Append(Self.Tasks(I))
+ Self.Tasks.Remove(I)
+ End If
+ Next
+
+ Dim Now As Double = Microseconds
+
+ For Each Task As AnimationKit.Task In Self.Tasks
+ If Task.Completed(Now) Or Now - Task.LastFrameTime >= Self.FramePeriod Then
+ Task.Perform(Now)
+ End If
+ Next
+
+ For I As Integer = UBound(Self.Tasks) DownTo 0
+ Dim Task As AnimationKit.Task = Self.Tasks(I)
+ If Task.Completed(Now) Then
+ RemovedTasks.Append(Task)
+ Self.Tasks.Remove(I)
+
+ If Task.NextTask <> Nil Then
+ Self.AddTask(Task.NextTask)
+ AddedTasks.Append(Task.NextTask)
+ End If
+ End If
+ Next
+
+ If UBound(Self.Tasks) = -1 Then
+ Sender.Mode = Xojo.Core.Timer.Modes.Off
+ End If
+
+ For Each Task As AnimationKit.Task In RemovedTasks
+ RaiseEvent TaskRemoved(Task)
+ Next
+ For Each Task As AnimationKit.Task In AddedTasks
+ RaiseEvent TaskAdded(Task)
+ Next
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Constructor()
+ Self.Animator = New Xojo.Core.Timer
+ Self.Animator.Mode = Xojo.Core.Timer.Modes.Off
+ Self.Animator.Period = 10
+ AddHandler Self.Animator.Action, WeakAddressOf Self.Animator_Action
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Function FramePeriod() As Double
+ return 1000000 / Self.FramesPerSecond
+ End Function
+ #tag EndMethod
+
+
+ #tag Hook, Flags = &h0
+ Event TaskAdded(Task As AnimationKit.Task)
+ #tag EndHook
+
+ #tag Hook, Flags = &h0
+ Event TaskRemoved(Task As AnimationKit.Task)
+ #tag EndHook
+
+
+ #tag Property, Flags = &h21
+ Private Animator As Xojo.Core.Timer
+ #tag EndProperty
+
+ #tag Property, Flags = &h0
+ FramesPerSecond As Integer = 60
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private Tasks() As AnimationKit.Task
+ #tag EndProperty
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="FramesPerSecond"
+ Group="Behavior"
+ InitialValue="60"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ InitialValue="-2147483648"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Class
+#tag EndClass
diff --git a/Project/AnimationKit/Curve.xojo_code b/Project/AnimationKit/Curve.xojo_code
new file mode 100644
index 0000000..cd7bb6b
--- /dev/null
+++ b/Project/AnimationKit/Curve.xojo_code
@@ -0,0 +1,240 @@
+#tag Class
+Protected Class Curve
+ #tag CompatibilityFlags = ( not TargetHasGUI and not TargetWeb and not TargetIOS ) or ( TargetWeb ) or ( TargetHasGUI ) or ( TargetIOS )
+ #tag Method, Flags = &h1
+ Protected Function B0(Time As Double) As Double
+ Return Time * Time * Time
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h1
+ Protected Function B1(Time As Double) As Double
+ Return 3 * Time * Time * (1 - Time)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h1
+ Protected Function B2(Time As Double) As Double
+ Return 3 * Time * (1 - Time) * (1 - Time)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h1
+ Protected Function B3(Time As Double) As Double
+ Return (1 - Time) * (1 - Time) * (1 - Time)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Constructor(P1X As Single, P1Y As Single, P2X As Single, P2Y As Single)
+ Self.Constructor(New Xojo.Core.Point(P1X, P1Y), New Xojo.Core.Point(P2X, P2Y))
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Constructor(P1 As Xojo.Core.Point, P2 As Xojo.Core.Point)
+ Self.C0 = New Xojo.Core.Point(0, 0)
+ Self.C1 = New Xojo.Core.Point(P1.X, P1.Y)
+ Self.C2 = New Xojo.Core.Point(P2.X, P2.Y)
+ Self.C3 = New Xojo.Core.Point(1, 1)
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Shared Function CreateEaseIn() As AnimationKit.Curve
+ Return CreateFromPreset(Presets.EaseIn)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Shared Function CreateEaseInOut() As AnimationKit.Curve
+ Return CreateFromPreset(Presets.EaseInOut)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Shared Function CreateEaseOut() As AnimationKit.Curve
+ Return CreateFromPreset(Presets.EaseOut)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Shared Function CreateFromPreset(Preset As AnimationKit.Curve.Presets) As AnimationKit.Curve
+ Select Case Preset
+ Case AnimationKit.Curve.Presets.Linear
+ Return New AnimationKit.Curve(0.250, 0.250, 0.750, 0.750)
+ Case AnimationKit.Curve.Presets.EaseIn
+ Return New AnimationKit.Curve(0.420, 0.000, 1.000, 1.000)
+ Case AnimationKit.Curve.Presets.EaseInBack
+ Return New AnimationKit.Curve(0.600, -0.280, 0.735, 0.045)
+ Case AnimationKit.Curve.Presets.EaseInCirc
+ Return New AnimationKit.Curve(0.600, 0.040, 0.980, 0.335)
+ Case AnimationKit.Curve.Presets.EaseInCubic
+ Return New AnimationKit.Curve(0.550, 0.055, 0.675, 0.190)
+ Case AnimationKit.Curve.Presets.EaseInExpo
+ Return New AnimationKit.Curve(0.950, 0.050, 0.795, 0.035)
+ Case AnimationKit.Curve.Presets.EaseInQuad
+ Return New AnimationKit.Curve(0.550, 0.085, 0.680, 0.530)
+ Case AnimationKit.Curve.Presets.EaseInQuart
+ Return New AnimationKit.Curve(0.895, 0.030, 0.685, 0.220)
+ Case AnimationKit.Curve.Presets.EaseInQuint
+ Return New AnimationKit.Curve(0.755, 0.050, 0.855, 0.060)
+ Case AnimationKit.Curve.Presets.EaseInSine
+ Return New AnimationKit.Curve(0.470, 0.000, 0.745, 0.715)
+ Case AnimationKit.Curve.Presets.EaseOut
+ Return New AnimationKit.Curve(0.000, 0.000, 0.580, 1.000)
+ Case AnimationKit.Curve.Presets.EaseOutBack
+ Return New AnimationKit.Curve(0.175, 0.885, 0.320, 1.275)
+ Case AnimationKit.Curve.Presets.EaseOutCirc
+ Return New AnimationKit.Curve(0.075, 0.820, 0.165, 1.000)
+ Case AnimationKit.Curve.Presets.EaseOutCubic
+ Return New AnimationKit.Curve(0.215, 0.610, 0.355, 1.000)
+ Case AnimationKit.Curve.Presets.EaseOutExpo
+ Return New AnimationKit.Curve(0.190, 1.000, 0.220, 1.000)
+ Case AnimationKit.Curve.Presets.EaseOutQuad
+ Return New AnimationKit.Curve(0.250, 0.460, 0.450, 0.940)
+ Case AnimationKit.Curve.Presets.EaseOutQuart
+ Return New AnimationKit.Curve(0.165, 0.840, 0.440, 1.000)
+ Case AnimationKit.Curve.Presets.EaseOutQuint
+ Return New AnimationKit.Curve(0.230, 1.000, 0.320, 1.000)
+ Case AnimationKit.Curve.Presets.EaseOutSine
+ Return New AnimationKit.Curve(0.390, 0.575, 0.565, 1.000)
+ Case AnimationKit.Curve.Presets.EaseInOut
+ Return New AnimationKit.Curve(0.420, 0.000, 0.580, 1.000)
+ Case AnimationKit.Curve.Presets.EaseInOutBack
+ Return New AnimationKit.Curve(0.680, -0.550, 0.265, 1.550)
+ Case AnimationKit.Curve.Presets.EaseInOutCirc
+ Return New AnimationKit.Curve(0.785, 0.135, 0.150, 0.860)
+ Case AnimationKit.Curve.Presets.EaseInOutCubic
+ Return New AnimationKit.Curve(0.645, 0.045, 0.355, 1.000)
+ Case AnimationKit.Curve.Presets.EaseInOutExpo
+ Return New AnimationKit.Curve(1.000, 0.000, 0.000, 1.000)
+ Case AnimationKit.Curve.Presets.EaseInOutQuad
+ Return New AnimationKit.Curve(0.455, 0.030, 0.515, 0.955)
+ Case AnimationKit.Curve.Presets.EaseInOutQuart
+ Return New AnimationKit.Curve(0.770, 0.000, 0.175, 1.000)
+ Case AnimationKit.Curve.Presets.EaseInOutQuint
+ Return New AnimationKit.Curve(0.860, 0.000, 0.070, 1.000)
+ Case AnimationKit.Curve.Presets.EaseInOutSine
+ Return New AnimationKit.Curve(0.445, 0.050, 0.550, 0.950)
+ End Select
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Shared Function CreateLinear() As AnimationKit.Curve
+ Return CreateFromPreset(Presets.Linear)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function Evaluate(Time As Double, StartValue As Double, EndValue As Double) As Double
+ If StartValue = EndValue Then
+ Return StartValue
+ End If
+
+ Time = 1 - Max(Min(Time, 1), 0)
+
+ Dim V0 As Double = Self.C0.Y * Self.B0(Time)
+ Dim V1 As Double = Self.C1.Y * Self.B1(Time)
+ Dim V2 As Double = Self.C2.Y * Self.B2(Time)
+ Dim V3 As Double = Self.C3.Y * Self.B3(Time)
+
+ Dim Y As Double = V0 + V1 + V2 + V3
+ Return StartValue + ((EndValue - StartValue) * Y)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function Reverse() As AnimationKit.Curve
+ Return New AnimationKit.Curve(1 - Self.C1.X, 1 - Self.C1.Y, 1 - Self.C2.X, 1 - Self.C2.Y)
+ End Function
+ #tag EndMethod
+
+
+ #tag Property, Flags = &h21
+ Private C0 As Xojo.Core.Point
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private C1 As Xojo.Core.Point
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private C2 As Xojo.Core.Point
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private C3 As Xojo.Core.Point
+ #tag EndProperty
+
+
+ #tag Enum, Name = Presets, Type = Integer, Flags = &h0
+ Linear
+ EaseIn
+ EaseInBack
+ EaseInCirc
+ EaseInCubic
+ EaseInExpo
+ EaseInQuad
+ EaseInQuart
+ EaseInQuint
+ EaseInSine
+ EaseOut
+ EaseOutBack
+ EaseOutCirc
+ EaseOutCubic
+ EaseOutExpo
+ EaseOutQuad
+ EaseOutQuart
+ EaseOutQuint
+ EaseOutSine
+ EaseInOut
+ EaseInOutBack
+ EaseInOutCirc
+ EaseInOutCubic
+ EaseInOutExpo
+ EaseInOutQuad
+ EaseInOutQuart
+ EaseInOutQuint
+ EaseInOutSine
+ #tag EndEnum
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ InitialValue="-2147483648"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Class
+#tag EndClass
diff --git a/Project/AnimationKit/Frame.xojo_code b/Project/AnimationKit/Frame.xojo_code
new file mode 100644
index 0000000..f8cdeba
--- /dev/null
+++ b/Project/AnimationKit/Frame.xojo_code
@@ -0,0 +1,160 @@
+#tag Class
+Protected Class Frame
+ #tag CompatibilityFlags = ( not TargetHasGUI and not TargetWeb and not TargetIOS ) or ( TargetWeb ) or ( TargetHasGUI ) or ( TargetIOS )
+ #tag Method, Flags = &h21
+ Private Sub Constructor()
+
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0, CompatibilityFlags = (TargetIOS)
+ Sub Constructor(Image As iOSImage, RetinaImage As iOSImage)
+ If Image = Nil Then
+ Dim Err As New UnsupportedOperationException
+ Err.Reason = "Cannot create a frame without an image."
+ Raise Err
+ End If
+
+ If RetinaImage <> Nil Then
+ If RetinaImage.Width <> Image.Width * 2 Or RetinaImage.Height <> Image.Height * 2 Then
+ Dim Err As New UnsupportedOperationException
+ Err.Reason = "Retina image must be exactly twice the dimensions of the standard image."
+ Raise Err
+ End If
+ End If
+
+ Self.Constructor()
+ Self.PrivateImage = Image
+ Self.PrivateRetinaImage = RetinaImage
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0, CompatibilityFlags = (TargetHasGUI)
+ Sub Constructor(Image As Picture, RetinaImage As Picture)
+ If Image = Nil Then
+ Dim Err As New UnsupportedOperationException
+ Err.Reason = "Cannot create a frame without an image."
+ Raise Err
+ End If
+
+ If RetinaImage <> Nil Then
+ If RetinaImage.Width <> Image.Width * 2 Or RetinaImage.Height <> Image.Height * 2 Then
+ Dim Err As New UnsupportedOperationException
+ Err.Reason = "Retina image must be exactly twice the dimensions of the standard image."
+ Raise Err
+ End If
+ End If
+
+ Self.Constructor()
+ Self.PrivateImage = Image
+ Self.PrivateRetinaImage = RetinaImage
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function Dimensions() As Xojo.Core.Size
+ Return New Xojo.Core.Size(Self.Image.Width, Self.Image.Height)
+ End Function
+ #tag EndMethod
+
+
+ #tag ComputedProperty, Flags = &h0, CompatibilityFlags = (TargetIOS)
+ #tag Getter
+ Get
+ Return Self.PrivateImage
+ End Get
+ #tag EndGetter
+ Image As iOSImage
+ #tag EndComputedProperty
+
+ #tag ComputedProperty, Flags = &h0, CompatibilityFlags = (not TargetHasGUI and not TargetWeb and not TargetIOS) or (TargetWeb) or (TargetHasGUI)
+ #tag Getter
+ Get
+ Return Self.PrivateImage
+ End Get
+ #tag EndGetter
+ Image As Picture
+ #tag EndComputedProperty
+
+ #tag Property, Flags = &h21, CompatibilityFlags = (TargetIOS)
+ Private PrivateImage As iOSImage
+ #tag EndProperty
+
+ #tag Property, Flags = &h21, CompatibilityFlags = (not TargetHasGUI and not TargetWeb and not TargetIOS) or (TargetWeb) or (TargetHasGUI)
+ Private PrivateImage As Picture
+ #tag EndProperty
+
+ #tag Property, Flags = &h21, CompatibilityFlags = (TargetIOS)
+ Private PrivateRetinaImage As iOSImage
+ #tag EndProperty
+
+ #tag Property, Flags = &h21, CompatibilityFlags = (not TargetHasGUI and not TargetWeb and not TargetIOS) or (TargetWeb) or (TargetHasGUI)
+ Private PrivateRetinaImage As Picture
+ #tag EndProperty
+
+ #tag ComputedProperty, Flags = &h0, CompatibilityFlags = (TargetIOS)
+ #tag Getter
+ Get
+ Return Self.PrivateRetinaImage
+ End Get
+ #tag EndGetter
+ RetinaImage As iOSImage
+ #tag EndComputedProperty
+
+ #tag ComputedProperty, Flags = &h0, CompatibilityFlags = (not TargetHasGUI and not TargetWeb and not TargetIOS) or (TargetWeb) or (TargetHasGUI)
+ #tag Getter
+ Get
+ Return Self.PrivateRetinaImage
+ End Get
+ #tag EndGetter
+ RetinaImage As Picture
+ #tag EndComputedProperty
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="Image"
+ Group="Behavior"
+ Type="Picture"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ InitialValue="-2147483648"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="RetinaImage"
+ Group="Behavior"
+ Type="Picture"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Class
+#tag EndClass
diff --git a/Project/AnimationKit/FrameSet.xojo_code b/Project/AnimationKit/FrameSet.xojo_code
new file mode 100644
index 0000000..b1b0fb9
--- /dev/null
+++ b/Project/AnimationKit/FrameSet.xojo_code
@@ -0,0 +1,290 @@
+#tag Class
+Protected Class FrameSet
+Implements xojo.Core.Iterable
+ #tag Method, Flags = &h0
+ Sub Append(Frame As AnimationKit.Frame)
+ Self.VerifyFrame(Frame)
+ Self.Frames.Append(Frame)
+ Self.CheckCurrentFrames()
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Sub CheckCurrentFrames()
+ Dim FirstFrame As AnimationKit.Frame
+ For I As Integer = 0 To UBound(Self.Frames)
+ If Self.Frames(I) <> Nil Then
+ FirstFrame = Self.Frames(I)
+ Exit For I
+ End If
+ Next
+
+ If FirstFrame = Nil Then
+ Self.Width = -1
+ Self.Height = -1
+ Else
+ Self.Width = FirstFrame.Dimensions.Width
+ Self.Height = FirstFrame.Dimensions.Height
+ End If
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Constructor()
+
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function Count() As Integer
+ Return UBound(Self.Frames) + 1
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0, CompatibilityFlags = (TargetIOS)
+ Shared Function CreateFromSpriteSheet(Sprites As iOSImage, RetinaSprites As iOSImage, CellWidth As Integer, CellHeight As Integer, Rows As Integer, Columns As Integer) As AnimationKit.FrameSet
+ Dim StandardCells() As iOSImage = SplitSprites(Sprites, CellWidth, CellHeight, Rows, Columns)
+ Dim RetinaCells() As iOSImage
+ If RetinaSprites <> Nil Then
+ RetinaCells = SplitSprites(RetinaSprites, CellWidth * 2, CellHeight * 2, Rows, Columns)
+ End If
+
+ Dim Set As New AnimationKit.FrameSet()
+ Redim Set(UBound(StandardCells))
+ For I As Integer = 0 To UBound(StandardCells)
+ If RetinaSprites <> Nil Then
+ Set(I) = New AnimationKit.Frame(StandardCells(I), RetinaCells(I))
+ Else
+ Set(I) = New AnimationKit.Frame(StandardCells(I), Nil)
+ End If
+ Next
+ Return Set
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0, CompatibilityFlags = (TargetHasGUI)
+ Shared Function CreateFromSpriteSheet(Sprites As Picture, RetinaSprites As Picture, CellWidth As Integer, CellHeight As Integer, Rows As Integer, Columns As Integer) As AnimationKit.FrameSet
+ Dim StandardCells() As Picture = SplitSprites(Sprites, CellWidth, CellHeight, Rows, Columns)
+ Dim RetinaCells() As Picture
+ If RetinaSprites <> Nil Then
+ RetinaCells = SplitSprites(RetinaSprites, CellWidth * 2, CellHeight * 2, Rows, Columns)
+ End If
+
+ Dim Set As New AnimationKit.FrameSet()
+ Redim Set(UBound(StandardCells))
+ For I As Integer = 0 To UBound(StandardCells)
+ If RetinaSprites <> Nil Then
+ Set(I) = New AnimationKit.Frame(StandardCells(I), RetinaCells(I))
+ Else
+ Set(I) = New AnimationKit.Frame(StandardCells(I), Nil)
+ End If
+ Next
+ Return Set
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function FirstFrame() As AnimationKit.Frame
+ If Self.Count > 0 Then
+ Return Self.Frames(0)
+ End If
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function Frame(Index As Integer) As AnimationKit.Frame
+ Return Self.Frames(Index)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Frame(Index As Integer, Assigns Value As AnimationKit.Frame)
+ Self.VerifyFrame(Value)
+ Self.Frames(Index) = Value
+ Self.CheckCurrentFrames()
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function GetIterator() As Xojo.Core.Iterator
+ // Part of the xojo.Core.Iterable interface.
+
+ Return New AnimationKit.FrameSetIterator(Self)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function IndexOf(Frame As AnimationKit.Frame) As Integer
+ For I As Integer = 0 To UBound(Self.Frames)
+ If Self.Frames(I) = Frame Then
+ Return I
+ End If
+ Next
+ Return -1
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Insert(Index As Integer, Frame As AnimationKit.Frame)
+ Self.VerifyFrame(Frame)
+ Self.Frames.Insert(Index, Frame)
+ Self.CheckCurrentFrames()
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function LastFrame() As AnimationKit.Frame
+ If Self.Count > 0 Then
+ Return Self.Frames(UBound(Self.Frames))
+ End If
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Operator_Redim(Bound As Integer)
+ Redim Self.Frames(Bound)
+ Self.CheckCurrentFrames()
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function Operator_Subscript(Index As Integer) As AnimationKit.Frame
+ Return Self.Frame(Index)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Operator_Subscript(Index As Integer, Assigns Frame As AnimationKit.Frame)
+ Self.Frame(Index) = Frame
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Remove(Index As Integer)
+ Self.Frames.Remove(Index)
+ Self.CheckCurrentFrames()
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function Reverse() As AnimationKit.FrameSet
+ Dim Set As New AnimationKit.FrameSet
+ For I As Integer = UBound(Self.Frames) DownTo 0
+ Set.Frames.Append(Self.Frames(I))
+ Next
+ Set.CheckCurrentFrames()
+ Return Set
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h21, CompatibilityFlags = (TargetIOS)
+ Private Shared Function SplitSprites(Sprites As iOSImage, Width As Integer, Height As Integer, Rows As Integer, Columns As Integer) As iOSImage()
+ If Sprites.Width <> (Rows + 1) * Width Or Sprites.Height <> (Columns + 1) * Height Then
+ Dim Err As New UnsupportedOperationException
+ Err.Reason = "Sprite sheet dimensions are not correct for the provided cell count."
+ Raise Err
+ End If
+
+ Dim Cells() As iOSImage
+ For Row As Integer = 0 To Rows - 1
+ For Column As Integer = 0 To Columns - 1
+ Dim Sprite As New iOSBitmap(Width, Height, Sprites.Scale)
+ Sprite.Graphics.DrawImage(Sprites, (Row * Column) * -1, (Column * Height) * -1)
+ Cells.Append(Sprite.Image)
+ Next
+ Next
+ Return Cells
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h21, CompatibilityFlags = (TargetHasGUI)
+ Private Shared Function SplitSprites(Sprites As Picture, Width As Integer, Height As Integer, Rows As Integer, Columns As Integer) As Picture()
+ If Sprites.Width <> (Rows + 1) * Width Or Sprites.Height <> (Columns + 1) * Height Then
+ Dim Err As New UnsupportedOperationException
+ Err.Reason = "Sprite sheet dimensions are not correct for the provided cell count."
+ Raise Err
+ End If
+
+ Dim Cells() As Picture
+ For Row As Integer = 0 To Rows - 1
+ For Column As Integer = 0 To Columns - 1
+ Dim Sprite As New Picture(Width, Height)
+ Sprite.Graphics.DrawPicture(Sprites, (Row * Column) * -1, (Column * Height) * -1)
+ Cells.Append(Sprite)
+ Next
+ Next
+ Return Cells
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function UBound() As Integer
+ Return UBound(Self.Frames)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Sub VerifyFrame(Frame As AnimationKit.Frame)
+ If Frame = Nil Or Self.Width = -1 Or Self.Height = -1 Then
+ Return
+ End If
+
+ If Frame.Dimensions.Width <> Self.Width Or Frame.Dimensions.Height <> Self.Height Then
+ Dim Err As New UnsupportedOperationException
+ Err.Reason = "Frame dimensions must match the set dimensions."
+ Raise Err
+ End If
+ End Sub
+ #tag EndMethod
+
+
+ #tag Property, Flags = &h21
+ Private Frames() As AnimationKit.Frame
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private Height As Integer = -1
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private Width As Integer = -1
+ #tag EndProperty
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ InitialValue="-2147483648"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Class
+#tag EndClass
diff --git a/Project/AnimationKit/FrameSetIterator.xojo_code b/Project/AnimationKit/FrameSetIterator.xojo_code
new file mode 100644
index 0000000..89a6cca
--- /dev/null
+++ b/Project/AnimationKit/FrameSetIterator.xojo_code
@@ -0,0 +1,75 @@
+#tag Class
+Private Class FrameSetIterator
+Implements xojo.Core.Iterator
+ #tag Method, Flags = &h0
+ Sub Constructor(Source As AnimationKit.FrameSet)
+ Self.Index = 0
+ Self.Frames = Source
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function MoveNext() As Boolean
+ // Part of the xojo.Core.Iterator interface.
+
+ If Self.Index < UBound(Self.Frames) Then
+ Self.Index = Self.Index + 1
+ Return True
+ End If
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function Value() As Auto
+ // Part of the xojo.Core.Iterator interface.
+
+ Return Self.Frames(Self.Index)
+ End Function
+ #tag EndMethod
+
+
+ #tag Property, Flags = &h21
+ Private Frames As AnimationKit.FrameSet
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private Index As Integer
+ #tag EndProperty
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Class
+#tag EndClass
diff --git a/Project/AnimationKit/FrameTarget.xojo_code b/Project/AnimationKit/FrameTarget.xojo_code
new file mode 100644
index 0000000..bc2c267
--- /dev/null
+++ b/Project/AnimationKit/FrameTarget.xojo_code
@@ -0,0 +1,46 @@
+#tag Interface
+Protected Interface FrameTarget
+ #tag Method, Flags = &h0
+ Sub AnimationStep(Identifier As Text, Frame As AnimationKit.Frame)
+
+ End Sub
+ #tag EndMethod
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ InitialValue="-2147483648"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Interface
+#tag EndInterface
diff --git a/Project/AnimationKit/FrameTask.xojo_code b/Project/AnimationKit/FrameTask.xojo_code
new file mode 100644
index 0000000..c22453c
--- /dev/null
+++ b/Project/AnimationKit/FrameTask.xojo_code
@@ -0,0 +1,147 @@
+#tag Class
+Protected Class FrameTask
+Inherits AnimationKit.Task
+ #tag Event
+ Sub Perform(Final As Boolean, Time As Double)
+ If Final Then
+ Self.CurrentFrame = UBound(Self.Frames)
+ AnimationKit.FrameTarget(Self.Item).AnimationStep(Self.Identifier, Self.Frames.LastFrame)
+ Return
+ End If
+
+ Dim Duration As Double = Self.DurationInSeconds * 1000000
+ Dim LoopElapsed As Double = Self.ElapsedTime(Time) Mod Duration
+ Dim PercentComplete As Double = LoopElapsed / Duration
+ Dim Frame As Integer = Round(Self.Frames.UBound * PercentComplete)
+
+ If Frame <> Self.CurrentFrame Then
+ Self.CurrentFrame = Frame
+ AnimationKit.FrameTarget(Self.Item).AnimationStep(Self.Identifier, Self.Frames(Frame))
+ End If
+ End Sub
+ #tag EndEvent
+
+ #tag Event
+ Sub Started()
+ //
+ End Sub
+ #tag EndEvent
+
+
+ #tag Method, Flags = &h0
+ Function Completed(Time As Double) As Boolean
+ If Self.Looping Then
+ Return False
+ Else
+ Return Self.ElapsedTime(Time) >= (Self.DurationInSeconds * 1000000)
+ End If
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h1021
+ Private Sub Constructor()
+ Self.Looping = True
+ Self.Frames = New AnimationKit.FrameSet()
+ Self.DurationInSeconds = 1
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h1000
+ Sub Constructor(Target As AnimationKit.FrameTarget, Frames As AnimationKit.FrameSet)
+ Self.Constructor()
+ Self.Item = Target
+ Self.Frames = Frames
+ End Sub
+ #tag EndMethod
+
+
+ #tag Property, Flags = &h21
+ Private CurrentFrame As Integer
+ #tag EndProperty
+
+ #tag Property, Flags = &h0
+ DurationInSeconds As Double = 1
+ #tag EndProperty
+
+ #tag Property, Flags = &h0
+ Frames As AnimationKit.FrameSet
+ #tag EndProperty
+
+ #tag Property, Flags = &h0
+ Identifier As Text
+ #tag EndProperty
+
+ #tag Property, Flags = &h0
+ Looping As Boolean
+ #tag EndProperty
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="Cancelled"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="DurationInSeconds"
+ Group="Behavior"
+ InitialValue="1"
+ Type="Double"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Identifier"
+ Group="Behavior"
+ Type="Text"
+ EditorType="MultiLineEditor"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ InitialValue="-2147483648"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="LastFrameTime"
+ Group="Behavior"
+ Type="Double"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Looping"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Started"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Class
+#tag EndClass
diff --git a/Project/AnimationKit/ListboxScrollDelegate.xojo_code b/Project/AnimationKit/ListboxScrollDelegate.xojo_code
new file mode 100644
index 0000000..1f4225d
--- /dev/null
+++ b/Project/AnimationKit/ListboxScrollDelegate.xojo_code
@@ -0,0 +1,111 @@
+#tag Class
+Private Class ListboxScrollDelegate
+Implements AnimationKit.Scrollable
+ #tag CompatibilityFlags = ( TargetHasGUI )
+ #tag Method, Flags = &h21
+ Private Sub Constructor()
+
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Constructor(Source As Listbox)
+ Self.TargetRef = Xojo.Core.WeakRef.Create(Source)
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function ScrollMaximum() As Double
+ If Self.Target <> Nil Then
+ Return Self.Target.ListCount
+ End If
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub ScrollMaximum(Assigns Value As Double)
+ // Ignored
+ #pragma Unused Value
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function ScrollMinimum() As Double
+ Return 0
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub ScrollMinimum(Assigns Value As Double)
+ // Ignored
+ #pragma Unused Value
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function ScrollPosition() As Double
+ If Self.Target <> Nil Then
+ Return Self.Target.ScrollPosition
+ End If
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub ScrollPosition(Assigns Value As Double)
+ If Self.Target <> Nil Then
+ Self.Target.ScrollPosition = Round(Value)
+ End If
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function Target() As Listbox
+ If TargetRef <> Nil And TargetRef.Value <> Nil Then
+ Return Listbox(TargetRef.Value)
+ End If
+ End Function
+ #tag EndMethod
+
+
+ #tag Property, Flags = &h21
+ Private TargetRef As Xojo.Core.WeakRef
+ #tag EndProperty
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ InitialValue="-2147483648"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Class
+#tag EndClass
diff --git a/Project/AnimationKit/MoveTask.xojo_code b/Project/AnimationKit/MoveTask.xojo_code
new file mode 100644
index 0000000..6565115
--- /dev/null
+++ b/Project/AnimationKit/MoveTask.xojo_code
@@ -0,0 +1,509 @@
+#tag Class
+Protected Class MoveTask
+Inherits AnimationKit.Task
+ #tag CompatibilityFlags = ( TargetHasGUI )
+ #tag Event
+ Sub Perform(Final As Boolean, Time As Double)
+ If Final Then
+ Self.ApplyRect(Self.EndBounds)
+ Return
+ End If
+
+ Dim Elapsed As Double = Self.ElapsedTime(Time)
+ Dim Duration As Double = Self.DurationInSeconds * 1000000
+ Dim RectTop As Double = Self.Curve.Evaluate(Elapsed / Duration, Self.StartBounds.Top, Self.EndBounds.Top)
+ Dim RectLeft As Double = Self.Curve.Evaluate(Elapsed / Duration, Self.StartBounds.Left, Self.EndBounds.Left)
+ Dim RectWidth As Double = Self.Curve.Evaluate(Elapsed / Duration, Self.StartBounds.Width, Self.EndBounds.Width)
+ Dim RectHeight As Double = Self.Curve.Evaluate(Elapsed / Duration, Self.StartBounds.Height, Self.EndBounds.Height)
+
+ Self.ApplyRect(New Xojo.Core.Rect(Floor(RectLeft), Floor(RectTop), Ceil(RectWidth), Ceil(RectHeight)))
+ End Sub
+ #tag EndEvent
+
+ #tag Event
+ Sub Started()
+ Self.StartBounds = Self.CurrentRect()
+ End Sub
+ #tag EndEvent
+
+
+ #tag Method, Flags = &h21, CompatibilityFlags = (TargetIOS)
+ Private Sub ApplyRect(Target As iOSControl, Rect As Xojo.Core.Rect)
+ // This is left in as a stub. iOSControl cannot move, so this entire
+ // task is useless on iOS.
+
+ If Self.AnimateLeft Then
+ Target.Left = Rect.Left
+ End If
+ If Self.AnimateTop Then
+ Target.Top = Rect.Top
+ End If
+ If Self.AnimateWidth Then
+ Target.Width = Rect.Width
+ End If
+ If Self.AnimateHeight Then
+ Target.Height = Rect.Height
+ End If
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21, CompatibilityFlags = (TargetHasGUI)
+ Private Sub ApplyRect(Target As RectControl, Rect As Xojo.Core.Rect)
+ If Self.AnimateLeft Then
+ Target.Left = Rect.Left
+ End If
+ If Self.AnimateTop Then
+ Target.Top = Rect.Top
+ End If
+ If Self.AnimateWidth Then
+ Target.Width = Rect.Width
+ End If
+ If Self.AnimateHeight Then
+ Target.Height = Rect.Height
+ End If
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21, CompatibilityFlags = (TargetHasGUI)
+ Private Sub ApplyRect(Target As Window, Rect As Xojo.Core.Rect)
+ If Self.AnimateLeft Then
+ Target.Left = Rect.Left
+ End If
+ If Self.AnimateTop Then
+ Target.Top = Rect.Top
+ End If
+ If Self.AnimateWidth Then
+ Target.Width = Rect.Width
+ End If
+ If Self.AnimateHeight Then
+ Target.Height = Rect.Height
+ End If
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21, CompatibilityFlags = (not TargetHasGUI and not TargetWeb and not TargetIOS) or (TargetWeb) or (TargetHasGUI) or (TargetIOS)
+ Private Sub ApplyRect(Rect As Xojo.Core.Rect)
+ Dim Item As Object = Self.Item
+
+ If Item = Nil Then
+ Return
+ End If
+
+ #if TargetDesktop
+ If Item IsA Window Then
+ Self.ApplyRect(Window(Item), Rect)
+ Return
+ ElseIf Item IsA RectControl Then
+ Self.ApplyRect(RectControl(Item), Rect)
+ Return
+ End If
+ #elseif TargetiOS
+ If Item IsA iOSControl Then
+ Self.ApplyRect(iOSControl(Item), Rect)
+ Return
+ End If
+ #endif
+
+ Dim Err As New UnsupportedOperationException
+ #if TargetDesktop
+ Err.Reason = "Item for AnimationKit.MoveTask must be a Window or RectControl."
+ #elseif TargetiOS
+ Err.Reason = "Item for AnimationKit.MoveTask must be an iOSControl."
+ #endif
+ Raise Err
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function Completed(Time As Double) As Boolean
+ Return Self.ElapsedTime(Time) >= (Self.DurationInSeconds * 1000000)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h1021
+ Private Sub Constructor()
+ Self.Curve = AnimationKit.Curve.CreateFromPreset(AnimationKit.Curve.Presets.Linear)
+ Self.DurationInSeconds = 1
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h1000, CompatibilityFlags = (TargetIOS)
+ Sub Constructor(Target As iOSControl)
+ Self.Constructor()
+ Self.StartBounds = Nil
+ Self.EndBounds = Self.CurrentRect(Target)
+ Self.Item = Target
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h1000, CompatibilityFlags = (TargetHasGUI)
+ Sub Constructor(Target As RectControl)
+ Self.Constructor()
+ Self.StartBounds = Nil
+ Self.EndBounds = Self.CurrentRect(Target)
+ Self.Item = Target
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h1000, CompatibilityFlags = (TargetHasGUI)
+ Sub Constructor(Target As Window)
+ Self.Constructor()
+ Self.StartBounds = Nil
+ Self.EndBounds = Self.CurrentRect(Target)
+ Self.Item = Target
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21, CompatibilityFlags = (not TargetHasGUI and not TargetWeb and not TargetIOS) or (TargetWeb) or (TargetHasGUI) or (TargetIOS)
+ Private Function CurrentRect() As Xojo.Core.Rect
+ Dim Item As Object = Self.Item
+
+ If Item = Nil Then
+ Return Nil
+ End If
+
+ #if TargetDesktop
+ If Item IsA Window Then
+ Return Self.CurrentRect(Window(Item))
+ ElseIf Item IsA RectControl Then
+ Return Self.CurrentRect(RectControl(Item))
+ End If
+ #elseif TargetiOS
+ If Item IsA iOSControl Then
+ Return Self.CurrentRect(iOSControl(Item))
+ End If
+ #endif
+
+ Dim Err As New UnsupportedOperationException
+ #if TargetDesktop
+ Err.Reason = "Item for AnimationKit.MoveTask must be a Window or RectControl."
+ #elseif TargetiOS
+ Err.Reason = "Item for AnimationKit.MoveTask must be an iOSControl."
+ #endif
+ Raise Err
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h21, CompatibilityFlags = (TargetIOS)
+ Private Function CurrentRect(Target As iOSControl) As Xojo.Core.Rect
+ Return New Xojo.Core.Rect(Target.Left, Target.Top, Target.Width, Target.Height)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h21, CompatibilityFlags = (TargetHasGUI)
+ Private Function CurrentRect(Target As RectControl) As Xojo.Core.Rect
+ Return New Xojo.Core.Rect(Target.Left, Target.Top, Target.Width, Target.Height)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h21, CompatibilityFlags = (TargetHasGUI)
+ Private Function CurrentRect(Target As Window) As Xojo.Core.Rect
+ Return New Xojo.Core.Rect(Target.Left, Target.Top, Target.Width, Target.Height)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub DisableValues(ParamArray Keys() As UInt64)
+ For Each Key As UInt8 In Keys
+ Self.AnimationKeys = (Self.AnimationKeys And (Not Key))
+ Next
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub EnableValues(ParamArray Keys() As UInt64)
+ For Each Key As UInt8 In Keys
+ Self.AnimationKeys = (Self.AnimationKeys Or Key)
+ Next
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0, CompatibilityFlags = (TargetHasGUI) or (TargetIOS)
+ Function OriginalRect() As Xojo.Core.Rect
+ If Self.StartBounds <> Nil Then
+ Return CloneRect(Self.StartBounds)
+ End If
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0, CompatibilityFlags = (TargetHasGUI)
+ Sub SetDestination(Source As REALbasic.Rect)
+ Self.SetDestination(New Xojo.Core.Rect(Source.Left, Source.Top, Source.Width, Source.Height))
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0, CompatibilityFlags = (TargetHasGUI) or (TargetIOS)
+ Sub SetDestination(Source As Xojo.Core.Rect)
+ Dim CurrentBounds As Xojo.Core.Rect = Self.CurrentRect()
+ Self.EndBounds = New Xojo.Core.Rect(Source.Left, Source.Top, Source.Width, Source.Height)
+ Self.AnimationKeys = 0
+ If Self.EndBounds.Left <> CurrentBounds.Left Then
+ Self.EnableValues(Self.KeyLeft)
+ End If
+ If Self.EndBounds.Top <> CurrentBounds.Top Then
+ Self.EnableValues(Self.KeyTop)
+ End If
+ If Self.EndBounds.Width <> CurrentBounds.Width Then
+ Self.EnableValues(Self.KeyWidth)
+ End If
+ If Self.EndBounds.Height <> CurrentBounds.Height Then
+ Self.EnableValues(Self.KeyHeight)
+ End If
+ End Sub
+ #tag EndMethod
+
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return (Self.AnimationKeys And Self.KeyHeight) = Self.KeyHeight
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ If Value Then
+ Self.EnableValues(Self.KeyHeight)
+ Else
+ Self.DisableValues(Self.KeyHeight)
+ End If
+ End Set
+ #tag EndSetter
+ AnimateHeight As Boolean
+ #tag EndComputedProperty
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return (Self.AnimationKeys And Self.KeyLeft) = Self.KeyLeft
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ If Value Then
+ Self.EnableValues(Self.KeyLeft)
+ Else
+ Self.DisableValues(Self.KeyLeft)
+ End If
+ End Set
+ #tag EndSetter
+ AnimateLeft As Boolean
+ #tag EndComputedProperty
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return (Self.AnimationKeys And Self.KeyTop) = Self.KeyTop
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ If Value Then
+ Self.EnableValues(Self.KeyTop)
+ Else
+ Self.DisableValues(Self.KeyTop)
+ End If
+ End Set
+ #tag EndSetter
+ AnimateTop As Boolean
+ #tag EndComputedProperty
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return (Self.AnimationKeys And Self.KeyWidth) = Self.KeyWidth
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ If Value Then
+ Self.EnableValues(Self.KeyWidth)
+ Else
+ Self.DisableValues(Self.KeyWidth)
+ End If
+ End Set
+ #tag EndSetter
+ AnimateWidth As Boolean
+ #tag EndComputedProperty
+
+ #tag Property, Flags = &h21
+ Private AnimationKeys As UInt64
+ #tag EndProperty
+
+ #tag Property, Flags = &h0
+ Curve As AnimationKit.Curve
+ #tag EndProperty
+
+ #tag Property, Flags = &h0
+ DurationInSeconds As Double = 1
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private EndBounds As Xojo.Core.Rect
+ #tag EndProperty
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return Self.EndBounds.Height
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ Self.EndBounds = New Xojo.Core.Rect(Self.EndBounds.Left, Self.EndBounds.Top, Self.EndBounds.Width, Value)
+ Self.EnableValues(Self.KeyHeight)
+ End Set
+ #tag EndSetter
+ Height As Integer
+ #tag EndComputedProperty
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return Self.EndBounds.Left
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ Self.EndBounds = New Xojo.Core.Rect(Value, Self.EndBounds.Top, Self.EndBounds.Width, Self.EndBounds.Height)
+ Self.EnableValues(Self.KeyLeft)
+ End Set
+ #tag EndSetter
+ Left As Integer
+ #tag EndComputedProperty
+
+ #tag Property, Flags = &h21
+ Private StartBounds As Xojo.Core.Rect
+ #tag EndProperty
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return Self.EndBounds.Top
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ Self.EndBounds = New Xojo.Core.Rect(Self.EndBounds.Left, Value, Self.EndBounds.Width, Self.EndBounds.Height)
+ Self.EnableValues(Self.KeyTop)
+ End Set
+ #tag EndSetter
+ Top As Integer
+ #tag EndComputedProperty
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return Self.EndBounds.Width
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ Self.EndBounds = New Xojo.Core.Rect(Self.EndBounds.Left, Self.EndBounds.Top, Value, Self.EndBounds.Height)
+ Self.EnableValues(Self.KeyWidth)
+ End Set
+ #tag EndSetter
+ Width As Integer
+ #tag EndComputedProperty
+
+
+ #tag Constant, Name = KeyHeight, Type = Double, Dynamic = False, Default = \"8", Scope = Public
+ #tag EndConstant
+
+ #tag Constant, Name = KeyLeft, Type = Double, Dynamic = False, Default = \"1", Scope = Public
+ #tag EndConstant
+
+ #tag Constant, Name = KeyTop, Type = Double, Dynamic = False, Default = \"2", Scope = Public
+ #tag EndConstant
+
+ #tag Constant, Name = KeyWidth, Type = Double, Dynamic = False, Default = \"4", Scope = Public
+ #tag EndConstant
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="AnimateHeight"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="AnimateLeft"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="AnimateTop"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="AnimateWidth"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Cancelled"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="DurationInSeconds"
+ Group="Behavior"
+ InitialValue="1"
+ Type="Double"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Height"
+ Group="Behavior"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ InitialValue="-2147483648"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="LastFrameTime"
+ Group="Behavior"
+ Type="Double"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Started"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Width"
+ Group="Behavior"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Class
+#tag EndClass
diff --git a/Project/AnimationKit/ScrollBarScrollDelegate.xojo_code b/Project/AnimationKit/ScrollBarScrollDelegate.xojo_code
new file mode 100644
index 0000000..cf17fad
--- /dev/null
+++ b/Project/AnimationKit/ScrollBarScrollDelegate.xojo_code
@@ -0,0 +1,115 @@
+#tag Class
+Private Class ScrollBarScrollDelegate
+Implements AnimationKit.Scrollable
+ #tag CompatibilityFlags = ( TargetHasGUI )
+ #tag Method, Flags = &h21
+ Private Sub Constructor()
+
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Constructor(Source As ScrollBar)
+ Self.TargetRef = Xojo.Core.WeakRef.Create(Source)
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function ScrollMaximum() As Double
+ If Self.Target <> Nil Then
+ Return Self.Target.Maximum
+ End If
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub ScrollMaximum(Assigns Value As Double)
+ If Self.Target <> Nil Then
+ Self.Target.Maximum = Value
+ End If
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function ScrollMinimum() As Double
+ If Self.Target <> Nil Then
+ Return Self.Target.Minimum
+ End If
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub ScrollMinimum(Assigns Value As Double)
+ If Self.Target <> Nil Then
+ Self.Target.Minimum = Value
+ End If
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function ScrollPosition() As Double
+ If Self.Target <> Nil Then
+ Return Self.Target.Value
+ End If
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub ScrollPosition(Assigns Value As Double)
+ If Self.Target <> Nil Then
+ Self.Target.Value = Value
+ End If
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function Target() As ScrollBar
+ If TargetRef <> Nil And TargetRef.Value <> Nil Then
+ Return ScrollBar(TargetRef.Value)
+ End If
+ End Function
+ #tag EndMethod
+
+
+ #tag Property, Flags = &h21
+ Private TargetRef As Xojo.Core.WeakRef
+ #tag EndProperty
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ InitialValue="-2147483648"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Class
+#tag EndClass
diff --git a/Project/AnimationKit/ScrollTask.xojo_code b/Project/AnimationKit/ScrollTask.xojo_code
new file mode 100644
index 0000000..8b36134
--- /dev/null
+++ b/Project/AnimationKit/ScrollTask.xojo_code
@@ -0,0 +1,352 @@
+#tag Class
+Protected Class ScrollTask
+Inherits AnimationKit.Task
+ #tag Event
+ Sub Perform(Final As Boolean, Time As Double)
+ Dim Item As Object = Self.Item
+ If Item = Nil Then
+ Return
+ End If
+
+ If Not (Item IsA AnimationKit.Scrollable) Then
+ Return
+ End If
+
+ Dim Target As AnimationKit.Scrollable = AnimationKit.Scrollable(Item)
+
+ If Final Then
+ Self.Apply(Target, Self.Minimum, Self.Maximum, Self.Position)
+ Return
+ End If
+
+ Dim Elapsed As Double = Self.ElapsedTime(Time)
+ Dim Duration As Double = Self.DurationInSeconds * 1000000
+ Dim Minimum As Double = Self.Curve.Evaluate(Elapsed / Duration, Self.StartMinimum, Self.Minimum)
+ Dim Maximum As Double = Self.Curve.Evaluate(Elapsed / Duration, Self.StartMaximum, Self.Maximum)
+ Dim Position As Double = Self.Curve.Evaluate(Elapsed / Duration, Self.StartPosition, Self.Position)
+ Self.Apply(Target, Minimum, Maximum, Position)
+ End Sub
+ #tag EndEvent
+
+ #tag Event
+ Sub Started()
+ Dim Item As Object = Self.Item
+ If Item = Nil Then
+ Return
+ End If
+
+ If Not (Item IsA AnimationKit.Scrollable) Then
+ Return
+ End If
+
+ Dim Target As AnimationKit.Scrollable = AnimationKit.Scrollable(Item)
+ Self.StartMinimum = Target.ScrollMinimum
+ Self.StartMaximum = Target.ScrollMaximum
+ Self.StartPosition = Target.ScrollPosition
+ End Sub
+ #tag EndEvent
+
+
+ #tag Method, Flags = &h21
+ Private Sub Apply(Target As AnimationKit.Scrollable, Minimum As Double, Maximum As Double, Position As Double)
+ If Self.AnimateMaximum Then
+ Target.ScrollMaximum = Maximum
+ End If
+ If Self.AnimateMinimum Then
+ Target.ScrollMinimum = Minimum
+ End If
+ If Self.AnimatePosition Then
+ Target.ScrollPosition = Position
+ End If
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h21
+ Private Sub Constructor()
+ Self.Curve = AnimationKit.Curve.CreateFromPreset(AnimationKit.Curve.Presets.Linear)
+ Self.DurationInSeconds = 1
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Constructor(Target As AnimationKit.Scrollable)
+ Self.Constructor()
+ Self.Item = Target
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0, CompatibilityFlags = (TargetHasGUI)
+ Sub Constructor(Target As Listbox)
+ Self.Retainer = New ListboxScrollDelegate(Target)
+ Self.Constructor(Self.Retainer)
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0, CompatibilityFlags = (TargetHasGUI)
+ Sub Constructor(Target As ScrollBar)
+ Self.Retainer = New ScrollBarScrollDelegate(Target)
+ Self.Constructor(Self.Retainer)
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0, CompatibilityFlags = (TargetHasGUI)
+ Sub Constructor(Target As TextArea)
+ Self.Retainer = New TextAreaScrollDelegate(Target)
+ Self.Constructor(Self.Retainer)
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub DisableValues(ParamArray Keys() As UInt64)
+ For Each Key As UInt8 In Keys
+ Self.AnimationKeys = (Self.AnimationKeys And (Not Key))
+ Next
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub EnableValues(ParamArray Keys() As UInt64)
+ For Each Key As UInt8 In Keys
+ Self.AnimationKeys = (Self.AnimationKeys Or Key)
+ Next
+ End Sub
+ #tag EndMethod
+
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return (Self.AnimationKeys And Self.KeyMaximum) = Self.KeyMaximum
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ If Value Then
+ Self.EnableValues(Self.KeyMaximum)
+ Else
+ Self.DisableValues(Self.KeyMaximum)
+ End If
+ End Set
+ #tag EndSetter
+ AnimateMaximum As Boolean
+ #tag EndComputedProperty
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return (Self.AnimationKeys And Self.KeyMinimum) = Self.KeyMinimum
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ If Value Then
+ Self.EnableValues(Self.KeyMinimum)
+ Else
+ Self.DisableValues(Self.KeyMinimum)
+ End If
+ End Set
+ #tag EndSetter
+ AnimateMinimum As Boolean
+ #tag EndComputedProperty
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return (Self.AnimationKeys And Self.KeyPosition) = Self.KeyPosition
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ If Value Then
+ Self.EnableValues(Self.KeyPosition)
+ Else
+ Self.DisableValues(Self.KeyPosition)
+ End If
+ End Set
+ #tag EndSetter
+ AnimatePosition As Boolean
+ #tag EndComputedProperty
+
+ #tag Property, Flags = &h21
+ Private AnimationKeys As UInt64
+ #tag EndProperty
+
+ #tag Property, Flags = &h0
+ Curve As AnimationKit.Curve
+ #tag EndProperty
+
+ #tag Property, Flags = &h0
+ DurationInSeconds As Double
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private EndMaximum As Double
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private EndMinimum As Double
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private EndPosition As Double
+ #tag EndProperty
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return Self.EndMaximum
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ Self.EndMaximum = Value
+ Self.EnableValues(Self.KeyMaximum)
+ End Set
+ #tag EndSetter
+ Maximum As Double
+ #tag EndComputedProperty
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return Self.EndMinimum
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ Self.EndMinimum = Value
+ Self.EnableValues(Self.KeyMinimum)
+ End Set
+ #tag EndSetter
+ Minimum As Double
+ #tag EndComputedProperty
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return Self.EndPosition
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ Self.EndPosition = Value
+ Self.EnableValues(Self.KeyPosition)
+ End Set
+ #tag EndSetter
+ Position As Double
+ #tag EndComputedProperty
+
+ #tag Property, Flags = &h21
+ Private Retainer As AnimationKit.Scrollable
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private StartMaximum As Double
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private StartMinimum As Double
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private StartPosition As Double
+ #tag EndProperty
+
+
+ #tag Constant, Name = KeyMaximum, Type = Double, Dynamic = False, Default = \"2", Scope = Public
+ #tag EndConstant
+
+ #tag Constant, Name = KeyMinimum, Type = Double, Dynamic = False, Default = \"1", Scope = Public
+ #tag EndConstant
+
+ #tag Constant, Name = KeyPosition, Type = Double, Dynamic = False, Default = \"4", Scope = Public
+ #tag EndConstant
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="AnimateMaximum"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="AnimateMinimum"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="AnimatePosition"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Cancelled"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="DurationInSeconds"
+ Group="Behavior"
+ Type="Double"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ InitialValue="-2147483648"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="LastFrameTime"
+ Group="Behavior"
+ Type="Double"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Maximum"
+ Group="Behavior"
+ Type="Double"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Minimum"
+ Group="Behavior"
+ Type="Double"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Position"
+ Group="Behavior"
+ Type="Double"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Started"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Class
+#tag EndClass
diff --git a/Project/AnimationKit/Scrollable.xojo_code b/Project/AnimationKit/Scrollable.xojo_code
new file mode 100644
index 0000000..e769d8e
--- /dev/null
+++ b/Project/AnimationKit/Scrollable.xojo_code
@@ -0,0 +1,76 @@
+#tag Interface
+Protected Interface Scrollable
+ #tag Method, Flags = &h0
+ Function ScrollMaximum() As Double
+
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub ScrollMaximum(Assigns Value As Double)
+
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function ScrollMinimum() As Double
+
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub ScrollMinimum(Assigns Value As Double)
+
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function ScrollPosition() As Double
+
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub ScrollPosition(Assigns Value As Double)
+
+ End Sub
+ #tag EndMethod
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ InitialValue="-2147483648"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Interface
+#tag EndInterface
diff --git a/Project/AnimationKit/Task.xojo_code b/Project/AnimationKit/Task.xojo_code
new file mode 100644
index 0000000..5a7a4eb
--- /dev/null
+++ b/Project/AnimationKit/Task.xojo_code
@@ -0,0 +1,217 @@
+#tag Class
+Protected Class Task
+ #tag Method, Flags = &h0
+ Sub Cancel()
+ Self.PrivateCancelled = True
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function Completed(Time As Double) As Boolean
+ #pragma Unused Time
+
+ Dim Err As New UnsupportedOperationException
+ Err.Reason = "Subclasses of AnimationKit.Task must override the Completed method."
+ Raise Err
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function ElapsedTime(Time As Double) As Double
+ Return Time - Self.StartTime
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Perform(Time As Double)
+ If Self.Item = Nil Then
+ Return
+ End If
+
+ If Not Self.Started Then
+ RaiseEvent Started()
+ Self.StartTime = Time
+ End If
+
+ Self.PrivateLastFrameTime = Time
+
+ Dim Final As Boolean = Self.Completed(Time)
+ RaiseEvent Perform(Final, Time)
+ If Final Then
+ RaiseEvent Completed
+ End If
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Run()
+ Self.Run(AnimationKit.SharedCoordinator)
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Run(Coordinator As AnimationKit.Coordinator)
+ Coordinator.AddTask(Self)
+ End Sub
+ #tag EndMethod
+
+
+ #tag Hook, Flags = &h0
+ Event Completed()
+ #tag EndHook
+
+ #tag Hook, Flags = &h0
+ Event Perform(Final As Boolean, Time As Double)
+ #tag EndHook
+
+ #tag Hook, Flags = &h0
+ Event Started()
+ #tag EndHook
+
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return Self.PrivateCancelled Or Self.Item = Nil
+ End Get
+ #tag EndGetter
+ Cancelled As Boolean
+ #tag EndComputedProperty
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ If Self.ItemRef <> Nil And Self.ItemRef.Value <> Nil Then
+ Return Self.ItemRef.Value
+ Else
+ Return Nil
+ End If
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ If Value = Nil Then
+ Self.ItemRef = Nil
+ Return
+ End If
+
+ Self.ItemRef = Xojo.Core.WeakRef.Create(Value)
+ End Set
+ #tag EndSetter
+ Item As Object
+ #tag EndComputedProperty
+
+ #tag Property, Flags = &h21
+ Private ItemRef As Xojo.Core.WeakRef
+ #tag EndProperty
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return Self.PrivateLastFrameTime
+ End Get
+ #tag EndGetter
+ LastFrameTime As Double
+ #tag EndComputedProperty
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return Self.PrivateNextTask
+ End Get
+ #tag EndGetter
+ #tag Setter
+ Set
+ If Value = Nil Then
+ Self.PrivateNextTask = Nil
+ Return
+ End If
+
+ If Self.PrivateNextTask = Nil Then
+ Self.PrivateNextTask = Value
+ Else
+ Self.PrivateNextTask.NextTask = Value
+ End If
+ End Set
+ #tag EndSetter
+ NextTask As AnimationKit.Task
+ #tag EndComputedProperty
+
+ #tag Property, Flags = &h21
+ Private PrivateCancelled As Boolean
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private PrivateLastFrameTime As Double
+ #tag EndProperty
+
+ #tag Property, Flags = &h21
+ Private PrivateNextTask As AnimationKit.Task
+ #tag EndProperty
+
+ #tag ComputedProperty, Flags = &h0
+ #tag Getter
+ Get
+ Return Self.PrivateLastFrameTime > 0
+ End Get
+ #tag EndGetter
+ Started As Boolean
+ #tag EndComputedProperty
+
+ #tag Property, Flags = &h21
+ Private StartTime As Double
+ #tag EndProperty
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="Cancelled"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ InitialValue="-2147483648"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="LastFrameTime"
+ Group="Behavior"
+ Type="Double"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Started"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Class
+#tag EndClass
diff --git a/Project/AnimationKit/TextAreaScrollDelegate.xojo_code b/Project/AnimationKit/TextAreaScrollDelegate.xojo_code
new file mode 100644
index 0000000..efc2e6d
--- /dev/null
+++ b/Project/AnimationKit/TextAreaScrollDelegate.xojo_code
@@ -0,0 +1,111 @@
+#tag Class
+Private Class TextAreaScrollDelegate
+Implements AnimationKit.Scrollable
+ #tag CompatibilityFlags = ( TargetHasGUI )
+ #tag Method, Flags = &h21
+ Private Sub Constructor()
+
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub Constructor(Source As TextArea)
+ Self.TargetRef = Xojo.Core.WeakRef.Create(Source)
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function ScrollMaximum() As Double
+ If Self.Target <> Nil Then
+ Return Self.Target.LineNumAtCharPos(Len(Self.Target.Text) - 1)
+ End If
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub ScrollMaximum(Assigns Value As Double)
+ // Ignored
+ #pragma Unused Value
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function ScrollMinimum() As Double
+ Return 0
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub ScrollMinimum(Assigns Value As Double)
+ // Ignored
+ #pragma Unused Value
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function ScrollPosition() As Double
+ If Self.Target <> Nil Then
+ Return Self.Target.ScrollPosition
+ End If
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Sub ScrollPosition(Assigns Value As Double)
+ If Self.Target <> Nil Then
+ Self.Target.ScrollPosition = Round(Value)
+ End If
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h0
+ Function Target() As TextArea
+ If TargetRef <> Nil And TargetRef.Value <> Nil Then
+ Return TextArea(TargetRef.Value)
+ End If
+ End Function
+ #tag EndMethod
+
+
+ #tag Property, Flags = &h21
+ Private TargetRef As Xojo.Core.WeakRef
+ #tag EndProperty
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ InitialValue="-2147483648"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Class
+#tag EndClass
diff --git a/Project/AnimationKit/ValueAnimator.xojo_code b/Project/AnimationKit/ValueAnimator.xojo_code
new file mode 100644
index 0000000..ee5f04f
--- /dev/null
+++ b/Project/AnimationKit/ValueAnimator.xojo_code
@@ -0,0 +1,46 @@
+#tag Interface
+Protected Interface ValueAnimator
+ #tag Method, Flags = &h0
+ Sub AnimationStep(Identifier As Text, Value As Double)
+
+ End Sub
+ #tag EndMethod
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ InitialValue="-2147483648"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Interface
+#tag EndInterface
diff --git a/Project/AnimationKit/ValueTask.xojo_code b/Project/AnimationKit/ValueTask.xojo_code
new file mode 100644
index 0000000..aa6159c
--- /dev/null
+++ b/Project/AnimationKit/ValueTask.xojo_code
@@ -0,0 +1,143 @@
+#tag Class
+Protected Class ValueTask
+Inherits AnimationKit.Task
+ #tag Event
+ Sub Perform(Final As Boolean, Time As Double)
+ If Final Then
+ AnimationKit.ValueAnimator(Self.Item).AnimationStep(Self.Identifier, Self.EndValue)
+ Return
+ End If
+
+ Dim Elapsed As Double = Self.ElapsedTime(Time)
+ Dim Duration As Double = Self.DurationInSeconds * 1000000
+ Dim Value As Double = Self.Curve.Evaluate(Elapsed / Duration, Self.StartValue, Self.EndValue)
+ AnimationKit.ValueAnimator(Self.Item).AnimationStep(Self.Identifier, Value)
+ End Sub
+ #tag EndEvent
+
+ #tag Event
+ Sub Started()
+ //
+ End Sub
+ #tag EndEvent
+
+
+ #tag Method, Flags = &h0
+ Function Completed(Time As Double) As Boolean
+ Return Self.ElapsedTime(Time) >= (Self.DurationInSeconds * 1000000)
+ End Function
+ #tag EndMethod
+
+ #tag Method, Flags = &h1021
+ Private Sub Constructor()
+ Self.Curve = AnimationKit.Curve.CreateFromPreset(AnimationKit.Curve.Presets.Linear)
+ Self.DurationInSeconds = 1
+ End Sub
+ #tag EndMethod
+
+ #tag Method, Flags = &h1000
+ Sub Constructor(Target As AnimationKit.ValueAnimator, Identifier As Text, StartValue As Double, EndValue As Double)
+ Self.Constructor()
+ Self.StartValue = StartValue
+ Self.EndValue = EndValue
+ Self.Item = Target
+ Self.Identifier = Identifier
+ End Sub
+ #tag EndMethod
+
+
+ #tag Property, Flags = &h0
+ Curve As AnimationKit.Curve
+ #tag EndProperty
+
+ #tag Property, Flags = &h0
+ DurationInSeconds As Double = 1
+ #tag EndProperty
+
+ #tag Property, Flags = &h0
+ EndValue As Double
+ #tag EndProperty
+
+ #tag Property, Flags = &h0
+ Identifier As Text
+ #tag EndProperty
+
+ #tag Property, Flags = &h0
+ StartValue As Double
+ #tag EndProperty
+
+
+ #tag ViewBehavior
+ #tag ViewProperty
+ Name="Cancelled"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="DurationInSeconds"
+ Group="Behavior"
+ InitialValue="1"
+ Type="Double"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="EndValue"
+ Group="Behavior"
+ Type="Double"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Identifier"
+ Group="Behavior"
+ Type="Text"
+ EditorType="MultiLineEditor"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Index"
+ Visible=true
+ Group="ID"
+ InitialValue="-2147483648"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="LastFrameTime"
+ Group="Behavior"
+ Type="Double"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Left"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Started"
+ Group="Behavior"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="StartValue"
+ Group="Behavior"
+ Type="Double"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Top"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag EndViewBehavior
+End Class
+#tag EndClass
diff --git a/Project/App.xojo_code b/Project/App.xojo_code
new file mode 100644
index 0000000..4b7d02a
--- /dev/null
+++ b/Project/App.xojo_code
@@ -0,0 +1,22 @@
+#tag Class
+Protected Class App
+Inherits Application
+ #tag Constant, Name = kEditClear, Type = String, Dynamic = False, Default = \"&Delete", Scope = Public
+ #Tag Instance, Platform = Windows, Language = Default, Definition = \"&Delete"
+ #Tag Instance, Platform = Linux, Language = Default, Definition = \"&Delete"
+ #tag EndConstant
+
+ #tag Constant, Name = kFileQuit, Type = String, Dynamic = False, Default = \"&Quit", Scope = Public
+ #Tag Instance, Platform = Windows, Language = Default, Definition = \"E&xit"
+ #tag EndConstant
+
+ #tag Constant, Name = kFileQuitShortcut, Type = String, Dynamic = False, Default = \"", Scope = Public
+ #Tag Instance, Platform = Mac OS, Language = Default, Definition = \"Cmd+Q"
+ #Tag Instance, Platform = Linux, Language = Default, Definition = \"Ctrl+Q"
+ #tag EndConstant
+
+
+ #tag ViewBehavior
+ #tag EndViewBehavior
+End Class
+#tag EndClass
diff --git a/Project/Build Automation.xojo_code b/Project/Build Automation.xojo_code
new file mode 100644
index 0000000..5e18874
--- /dev/null
+++ b/Project/Build Automation.xojo_code
@@ -0,0 +1,18 @@
+#tag BuildAutomation
+ Begin BuildStepList Linux
+ Begin BuildProjectStep Build
+ End
+ End
+ Begin BuildStepList Mac OS X
+ Begin BuildProjectStep Build
+ End
+ Begin IDEScriptBuildStep EnableRetina , AppliesTo = 0
+ Dim App As String = CurrentBuildLocation + "/""" + CurrentBuildAppName + ".app"""
+ Call DoShellCommand("/usr/bin/defaults write " + App + "/Contents/Info ""NSHighResolutionCapable"" YES")
+ End
+ End
+ Begin BuildStepList Windows
+ Begin BuildProjectStep Build
+ End
+ End
+#tag EndBuildAutomation
diff --git a/Project/MenuBar1.xojo_menu b/Project/MenuBar1.xojo_menu
new file mode 100644
index 0000000..4a412f8
--- /dev/null
+++ b/Project/MenuBar1.xojo_menu
@@ -0,0 +1,98 @@
+#tag Menu
+Begin Menu MenuBar1
+ Begin MenuItem FileMenu
+ SpecialMenu = 0
+ Text = "&File"
+ Index = -2147483648
+ AutoEnable = True
+ Visible = True
+ Begin QuitMenuItem FileQuit
+ SpecialMenu = 0
+ Text = "#App.kFileQuit"
+ Index = -2147483648
+ ShortcutKey = "#App.kFileQuitShortcut"
+ Shortcut = "#App.kFileQuitShortcut"
+ AutoEnable = True
+ Visible = True
+ End
+ End
+ Begin MenuItem EditMenu
+ SpecialMenu = 0
+ Text = "&Edit"
+ Index = -2147483648
+ AutoEnable = True
+ Visible = True
+ Begin MenuItem EditUndo
+ SpecialMenu = 0
+ Text = "&Undo"
+ Index = -2147483648
+ ShortcutKey = "Z"
+ Shortcut = "Cmd+Z"
+ MenuModifier = True
+ AutoEnable = True
+ Visible = True
+ End
+ Begin MenuItem UntitledMenu1
+ SpecialMenu = 0
+ Text = "-"
+ Index = -2147483648
+ AutoEnable = True
+ Visible = True
+ End
+ Begin MenuItem EditCut
+ SpecialMenu = 0
+ Text = "Cu&t"
+ Index = -2147483648
+ ShortcutKey = "X"
+ Shortcut = "Cmd+X"
+ MenuModifier = True
+ AutoEnable = True
+ Visible = True
+ End
+ Begin MenuItem EditCopy
+ SpecialMenu = 0
+ Text = "&Copy"
+ Index = -2147483648
+ ShortcutKey = "C"
+ Shortcut = "Cmd+C"
+ MenuModifier = True
+ AutoEnable = True
+ Visible = True
+ End
+ Begin MenuItem EditPaste
+ SpecialMenu = 0
+ Text = "&Paste"
+ Index = -2147483648
+ ShortcutKey = "V"
+ Shortcut = "Cmd+V"
+ MenuModifier = True
+ AutoEnable = True
+ Visible = True
+ End
+ Begin MenuItem EditClear
+ SpecialMenu = 0
+ Text = "#App.kEditClear"
+ Index = -2147483648
+ AutoEnable = True
+ Visible = True
+ End
+ Begin MenuItem UntitledMenu0
+ SpecialMenu = 0
+ Text = "-"
+ Index = -2147483648
+ AutoEnable = True
+ Visible = True
+ End
+ Begin MenuItem EditSelectAll
+ SpecialMenu = 0
+ Text = "Select &All"
+ Index = -2147483648
+ ShortcutKey = "A"
+ Shortcut = "Cmd+A"
+ MenuModifier = True
+ AutoEnable = True
+ Visible = True
+ End
+ End
+End
+#tag EndMenu
diff --git a/Project/SheetDemo.xojo_window b/Project/SheetDemo.xojo_window
new file mode 100644
index 0000000..6492708
--- /dev/null
+++ b/Project/SheetDemo.xojo_window
@@ -0,0 +1,142 @@
+#tag Window
+Begin Window SheetDemo
+ BackColor = &cFFFFFF00
+ Backdrop = 0
+ CloseButton = True
+ Compatibility = ""
+ Composite = False
+ Frame = 8
+ FullScreen = False
+ FullScreenButton= False
+ HasBackColor = False
+ Height = 88
+ ImplicitInstance= True
+ LiveResize = True
+ MacProcID = 0
+ MaxHeight = 32000
+ MaximizeButton = False
+ MaxWidth = 32000
+ MenuBar = 0
+ MenuBarVisible = True
+ MinHeight = 64
+ MinimizeButton = True
+ MinWidth = 64
+ Placement = 0
+ Resizeable = False
+ Title = "SheetDemo"
+ Visible = True
+ Width = 424
+ Begin Label StaticText1
+ AutoDeactivate = True
+ Bold = True
+ DataField = ""
+ DataSource = ""
+ Enabled = True
+ Height = 22
+ HelpTag = ""
+ Index = -2147483648
+ InitialParent = ""
+ Italic = False
+ Left = 50
+ LockBottom = False
+ LockedInPosition= False
+ LockLeft = True
+ LockRight = True
+ LockTop = True
+ Multiline = False
+ Scope = 0
+ Selectable = False
+ TabIndex = 0
+ TabPanelIndex = 0
+ TabStop = True
+ Text = "Some Content"
+ TextAlign = 0
+ TextColor = &c00000000
+ TextFont = "System"
+ TextSize = 0.0
+ TextUnit = 0
+ Top = 14
+ Transparent = False
+ Underline = False
+ Visible = True
+ Width = 354
+ End
+ Begin PushButton PushButton1
+ AutoDeactivate = True
+ Bold = False
+ ButtonStyle = "0"
+ Cancel = False
+ Caption = "Done"
+ Default = False
+ Enabled = True
+ Height = 20
+ HelpTag = ""
+ Index = -2147483648
+ InitialParent = ""
+ Italic = False
+ Left = 324
+ LockBottom = True
+ LockedInPosition= False
+ LockLeft = False
+ LockRight = True
+ LockTop = False
+ Scope = 0
+ TabIndex = 1
+ TabPanelIndex = 0
+ TabStop = True
+ TextFont = "System"
+ TextSize = 0.0
+ TextUnit = 0
+ Top = 48
+ Underline = False
+ Visible = True
+ Width = 80
+ End
+ Begin DisclosureTriangle DisclosureTriangle1
+ AcceptFocus = False
+ AutoDeactivate = True
+ Enabled = True
+ Facing = 0
+ Height = 18
+ HelpTag = ""
+ Index = -2147483648
+ InitialParent = ""
+ Left = 20
+ LockBottom = False
+ LockedInPosition= False
+ LockLeft = False
+ LockRight = False
+ LockTop = False
+ Scope = 0
+ TabIndex = 2
+ TabPanelIndex = 0
+ TabStop = True
+ Top = 16
+ Value = False
+ Visible = True
+ Width = 18
+ End
+End
+#tag EndWindow
+
+#tag WindowCode
+#tag EndWindowCode
+
+#tag Events PushButton1
+ #tag Event
+ Sub Action()
+ self.close
+ End Sub
+ #tag EndEvent
+#tag EndEvents
+#tag Events DisclosureTriangle1
+ #tag Event
+ Sub Action()
+ If Not Me.Value Then
+ Self.Animate(New Xojo.Core.Rect(Self.Left, Self.Top, Self.Width, Self.Height - 75), 0.25, Window1.Curve)
+ Else
+ Self.Animate(New Xojo.Core.Rect(Self.Left, Self.Top, Self.Width, Self.Height + 75), 0.25, Window1.Curve)
+ End If
+ End Sub
+ #tag EndEvent
+#tag EndEvents
diff --git a/Project/Window1.xojo_window b/Project/Window1.xojo_window
new file mode 100644
index 0000000..3a7a0d1
--- /dev/null
+++ b/Project/Window1.xojo_window
@@ -0,0 +1,561 @@
+#tag Window
+Begin Window Window1
+ BackColor = &cFFFFFF00
+ Backdrop = 0
+ CloseButton = True
+ Compatibility = ""
+ Composite = True
+ Frame = 0
+ FullScreen = False
+ FullScreenButton= False
+ HasBackColor = False
+ Height = 375
+ ImplicitInstance= True
+ LiveResize = True
+ MacProcID = 0
+ MaxHeight = 32000
+ MaximizeButton = False
+ MaxWidth = 32000
+ MenuBar = 1147595781
+ MenuBarVisible = True
+ MinHeight = 64
+ MinimizeButton = True
+ MinWidth = 64
+ Placement = 2
+ Resizeable = False
+ Title = "Animation Demo"
+ Visible = True
+ Width = 653
+ Begin PushButton PushButton1
+ AutoDeactivate = True
+ Bold = False
+ ButtonStyle = "0"
+ Cancel = False
+ Caption = "Sheet"
+ Default = False
+ Enabled = True
+ Height = 20
+ HelpTag = ""
+ Index = -2147483648
+ InitialParent = ""
+ Italic = False
+ Left = 20
+ LockBottom = False
+ LockedInPosition= False
+ LockLeft = False
+ LockRight = False
+ LockTop = False
+ Scope = 0
+ TabIndex = 0
+ TabPanelIndex = 0
+ TabStop = True
+ TextFont = "System"
+ TextSize = 0.0
+ TextUnit = 0
+ Top = 335
+ Underline = False
+ Visible = True
+ Width = 80
+ End
+ Begin TextField TextField1
+ AcceptTabs = False
+ Alignment = 0
+ AutoDeactivate = True
+ AutomaticallyCheckSpelling= False
+ BackColor = &cFFFFFF00
+ Bold = False
+ Border = True
+ CueText = ""
+ DataField = ""
+ DataSource = ""
+ Enabled = True
+ Format = ""
+ Height = 22
+ HelpTag = ""
+ Index = -2147483648
+ InitialParent = ""
+ Italic = False
+ Left = 20
+ LimitText = 0
+ LockBottom = False
+ LockedInPosition= False
+ LockLeft = True
+ LockRight = True
+ LockTop = False
+ Mask = ""
+ Password = False
+ ReadOnly = False
+ Scope = 0
+ TabIndex = 1
+ TabPanelIndex = 0
+ TabStop = True
+ Text = ""
+ TextColor = &c00000000
+ TextFont = "System"
+ TextSize = 0.0
+ TextUnit = 0
+ Top = 301
+ Underline = False
+ UseFocusRing = True
+ Visible = True
+ Width = 613
+ End
+ Begin ListBox ListBox1
+ AutoDeactivate = True
+ AutoHideScrollbars= True
+ Bold = False
+ Border = True
+ ColumnCount = 1
+ ColumnsResizable= False
+ ColumnWidths = ""
+ DataField = ""
+ DataSource = ""
+ DefaultRowHeight= -1
+ Enabled = True
+ EnableDrag = False
+ EnableDragReorder= False
+ GridLinesHorizontal= 0
+ GridLinesVertical= 0
+ HasHeading = False
+ HeadingIndex = -1
+ Height = 275
+ HelpTag = ""
+ Hierarchical = False
+ Index = -2147483648
+ InitialParent = ""
+ InitialValue = ""
+ Italic = False
+ Left = 20
+ LockBottom = False
+ LockedInPosition= False
+ LockLeft = False
+ LockRight = False
+ LockTop = False
+ RequiresSelection= False
+ Scope = 0
+ ScrollbarHorizontal= False
+ ScrollBarVertical= True
+ SelectionType = 0
+ TabIndex = 2
+ TabPanelIndex = 0
+ TabStop = True
+ TextFont = "System"
+ TextSize = 0.0
+ TextUnit = 0
+ Top = 14
+ Underline = False
+ UseFocusRing = True
+ Visible = True
+ Width = 613
+ _ScrollOffset = 0
+ _ScrollWidth = -1
+ End
+ Begin PushButton PushButton2
+ AutoDeactivate = True
+ Bold = False
+ ButtonStyle = "0"
+ Cancel = False
+ Caption = "Switch"
+ Default = False
+ Enabled = True
+ Height = 20
+ HelpTag = ""
+ Index = -2147483648
+ InitialParent = ""
+ Italic = False
+ Left = 112
+ LockBottom = False
+ LockedInPosition= False
+ LockLeft = False
+ LockRight = False
+ LockTop = False
+ Scope = 0
+ TabIndex = 3
+ TabPanelIndex = 0
+ TabStop = True
+ TextFont = "System"
+ TextSize = 0.0
+ TextUnit = 0
+ Top = 335
+ Underline = False
+ Visible = True
+ Width = 80
+ End
+ Begin PopupMenu AnimMethodMenu
+ AutoDeactivate = True
+ Bold = False
+ DataField = ""
+ DataSource = ""
+ Enabled = True
+ Height = 20
+ HelpTag = ""
+ Index = -2147483648
+ InitialParent = ""
+ InitialValue = ""
+ Italic = False
+ Left = 512
+ ListIndex = 1
+ LockBottom = True
+ LockedInPosition= False
+ LockLeft = False
+ LockRight = True
+ LockTop = False
+ Scope = 0
+ TabIndex = 4
+ TabPanelIndex = 0
+ TabStop = True
+ TextFont = "System"
+ TextSize = 0.0
+ TextUnit = 0
+ Top = 334
+ Underline = False
+ Visible = True
+ Width = 121
+ End
+ Begin Label StaticText1
+ AutoDeactivate = True
+ Bold = False
+ DataField = ""
+ DataSource = ""
+ Enabled = True
+ Height = 20
+ HelpTag = ""
+ Index = -2147483648
+ InitialParent = ""
+ Italic = False
+ Left = 376
+ LockBottom = True
+ LockedInPosition= False
+ LockLeft = False
+ LockRight = True
+ LockTop = False
+ Multiline = False
+ Scope = 0
+ Selectable = False
+ TabIndex = 5
+ TabPanelIndex = 0
+ TabStop = True
+ Text = "Animation Method:"
+ TextAlign = 2
+ TextColor = &c00000000
+ TextFont = "System"
+ TextSize = 0.0
+ TextUnit = 0
+ Top = 335
+ Transparent = False
+ Underline = False
+ Visible = True
+ Width = 124
+ End
+End
+#tag EndWindow
+
+#tag WindowCode
+ #tag Property, Flags = &h0
+ Curve As AnimationKit.Curve
+ #tag EndProperty
+
+
+#tag EndWindowCode
+
+#tag Events PushButton1
+ #tag Event
+ Sub Action()
+ SheetDemo.ShowWithin Self
+ End Sub
+ #tag EndEvent
+#tag EndEvents
+#tag Events PushButton2
+ #tag Event
+ Sub Action()
+ Dim ListboxTask, TextFieldTask As AnimationKit.MoveTask
+
+ ListboxTask = New AnimationKit.MoveTask(Listbox1)
+ ListboxTask.Curve = Self.Curve
+ ListboxTask.DurationInSeconds = 1
+
+ TextFieldTask = New AnimationKit.MoveTask(TextField1)
+ TextFieldTask.Curve = ListboxTask.Curve
+ TextFieldTask.DurationInSeconds = ListboxTask.DurationInSeconds
+
+ If Listbox1.Top = 14 Then
+ ListboxTask.Top = 48
+ TextFieldTask.Top = 14
+ Else
+ ListboxTask.Top = 14
+ TextFieldTask.Top = 301
+ End If
+
+ ListboxTask.Run
+ TextFieldTask.Run
+ End Sub
+ #tag EndEvent
+#tag EndEvents
+#tag Events AnimMethodMenu
+ #tag Event
+ Sub Open()
+ Me.AddRow("Linear")
+ Me.AddRow("EaseIn")
+ Me.AddRow("EaseInBack")
+ Me.AddRow("EaseInCirc")
+ Me.AddRow("EaseInCubic")
+ Me.AddRow("EaseInExpo")
+ Me.AddRow("EaseInQuad")
+ Me.AddRow("EaseInQuart")
+ Me.AddRow("EaseInQuint")
+ Me.AddRow("EaseInSine")
+ Me.AddRow("EaseOut")
+ Me.AddRow("EaseOutBack")
+ Me.AddRow("EaseOutCirc")
+ Me.AddRow("EaseOutCubic")
+ Me.AddRow("EaseOutExpo")
+ Me.AddRow("EaseOutQuad")
+ Me.AddRow("EaseOutQuart")
+ Me.AddRow("EaseOutQuint")
+ Me.AddRow("EaseOutSine")
+ Me.AddRow("EaseInOut")
+ Me.AddRow("EaseInOutBack")
+ Me.AddRow("EaseInOutCirc")
+ Me.AddRow("EaseInOutCubic")
+ Me.AddRow("EaseInOutExpo")
+ Me.AddRow("EaseInOutQuad")
+ Me.AddRow("EaseInOutQuart")
+ Me.AddRow("EaseInOutQuint")
+ Me.AddRow("EaseInOutSine")
+ Me.ListIndex = 0
+ End Sub
+ #tag EndEvent
+ #tag Event
+ Sub Change()
+ Dim Preset As AnimationKit.Curve.Presets = CType(Me.ListIndex, AnimationKit.Curve.Presets)
+ Self.Curve = AnimationKit.Curve.CreateFromPreset(Preset)
+ End Sub
+ #tag EndEvent
+#tag EndEvents
+#tag ViewBehavior
+ #tag ViewProperty
+ Name="BackColor"
+ Visible=true
+ Group="Appearance"
+ InitialValue="&hFFFFFF"
+ Type="Color"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Backdrop"
+ Visible=true
+ Group="Appearance"
+ Type="Picture"
+ EditorType="Picture"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="CloseButton"
+ Visible=true
+ Group="Appearance"
+ InitialValue="True"
+ Type="Boolean"
+ EditorType="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Composite"
+ Group="Appearance"
+ InitialValue="False"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Frame"
+ Visible=true
+ Group="Appearance"
+ InitialValue="0"
+ Type="Integer"
+ EditorType="Enum"
+ #tag EnumValues
+ "0 - Document"
+ "1 - Movable Modal"
+ "2 - Modal Dialog"
+ "3 - Floating Window"
+ "4 - Plain Box"
+ "5 - Shadowed Box"
+ "6 - Rounded Window"
+ "7 - Global Floating Window"
+ "8 - Sheet Window"
+ "9 - Metal Window"
+ "10 - Drawer Window"
+ "11 - Modeless Dialog"
+ #tag EndEnumValues
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="FullScreen"
+ Group="Appearance"
+ InitialValue="False"
+ Type="Boolean"
+ EditorType="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="FullScreenButton"
+ Visible=true
+ Group="Appearance"
+ InitialValue="False"
+ Type="Boolean"
+ EditorType="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="HasBackColor"
+ Visible=true
+ Group="Appearance"
+ InitialValue="False"
+ Type="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Height"
+ Visible=true
+ Group="Position"
+ InitialValue="400"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="ImplicitInstance"
+ Visible=true
+ Group="Appearance"
+ InitialValue="True"
+ Type="Boolean"
+ EditorType="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Interfaces"
+ Visible=true
+ Group="ID"
+ Type="String"
+ EditorType="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="LiveResize"
+ Visible=true
+ Group="Appearance"
+ InitialValue="True"
+ Type="Boolean"
+ EditorType="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="MacProcID"
+ Group="Appearance"
+ InitialValue="0"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="MaxHeight"
+ Visible=true
+ Group="Position"
+ InitialValue="32000"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="MaximizeButton"
+ Visible=true
+ Group="Appearance"
+ InitialValue="True"
+ Type="Boolean"
+ EditorType="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="MaxWidth"
+ Visible=true
+ Group="Position"
+ InitialValue="32000"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="MenuBar"
+ Visible=true
+ Group="Appearance"
+ Type="MenuBar"
+ EditorType="MenuBar"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="MenuBarVisible"
+ Group="Appearance"
+ InitialValue="True"
+ Type="Boolean"
+ EditorType="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="MinHeight"
+ Visible=true
+ Group="Position"
+ InitialValue="64"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="MinimizeButton"
+ Visible=true
+ Group="Appearance"
+ InitialValue="True"
+ Type="Boolean"
+ EditorType="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="MinWidth"
+ Visible=true
+ Group="Position"
+ InitialValue="64"
+ Type="Integer"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Name"
+ Visible=true
+ Group="ID"
+ Type="String"
+ EditorType="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Placement"
+ Visible=true
+ Group="Position"
+ InitialValue="0"
+ Type="Integer"
+ EditorType="Enum"
+ #tag EnumValues
+ "0 - Default"
+ "1 - Parent Window"
+ "2 - Main Screen"
+ "3 - Parent Window Screen"
+ "4 - Stagger"
+ #tag EndEnumValues
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Resizeable"
+ Visible=true
+ Group="Appearance"
+ InitialValue="True"
+ Type="Boolean"
+ EditorType="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Super"
+ Visible=true
+ Group="ID"
+ Type="String"
+ EditorType="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Title"
+ Visible=true
+ Group="Appearance"
+ InitialValue="Untitled"
+ Type="String"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Visible"
+ Visible=true
+ Group="Appearance"
+ InitialValue="True"
+ Type="Boolean"
+ EditorType="Boolean"
+ #tag EndViewProperty
+ #tag ViewProperty
+ Name="Width"
+ Visible=true
+ Group="Position"
+ InitialValue="600"
+ Type="Integer"
+ #tag EndViewProperty
+#tag EndViewBehavior
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..ee4bdc5
--- /dev/null
+++ b/README.md
@@ -0,0 +1,6 @@
+# Animation Kit
+Provides user interface animations to Xojo projects.
+
+## Building Documentation
+
+Documentation is powered by [MkDocs](http://www.mkdocs.org/). Simply `cd` into the Documentation directory and `mkdocs build` after installing MkDocs. Release builds will contain compiled documentation as well as hosted documentation.
\ No newline at end of file