Flex Builder + Ant Build + Debug + Console Output

April 24, 2008

Flex Builder, as opposed to Visual Studio, doesn't have post-build scripts that allow you to easily copy assets to the build folder.

If you need to do this Ant is a good alternative. There can be problems connecting the Ant build process to the debugger though.

The solution to this problem is to add a builder to the project (in Flex Builder):

  • Right-click on the Flex project and choose "Properties"
  • Click on "Builders" in the left panel
  • Click on the "New..." button on the right
  • Choose "Ant Builder" from the "Choose configuration type" window
  • Type "Ant Builder" in the "Name" field
  • Locate the build.xml in the "Main" tab
  • Go to the "Build Options" tab and check the "Allocate Console" option
  • Click "OK"
  • Uncheck "Flex" in the Builders dialogue and make sure "Ant Builder" is checked
  • Press F11 to build & debug your project ...

That's all there is to it ...

  1. 0 Comments/Trackbacks
  2. Section(s): Developer Tools, Flash/ActionScript, Flex 
 
 

Programmatic drawing with Silverlight 2 Part 3: Simple Animation

March 12, 2008
Silverlight Animation

This example shows you how you can make a simple line animation in Silverlight 2. There isn't much documentation about this yet, so it took some figuring out on how to do this correctly.

Basically these are the steps to create an animation:

  • Create a Storyboard object
  • Set the Storyboard's Duration property
  • Create a DoubleAnimation object
  • Set the DoubleAnimation object's Duration property
  • Add the DoubleAnimation object to the Storyboard object's children
  • Call the static SetTarget method on the Storyboard class and pass it the DoubleAnimation object and the object that will be animated.
  • Call the static SetTargetProperty method on the Storyboard class and pass it the DoubleAnimation object and the property of the object that will be animated.
  • Set the To property on the DoubleAnimation object. This is object's property that will be used to animate to.
  • Add the storyboard to the layout
  • Start the animation by calling Storyboard's Begin method.

Same steps in code:


Storyboard storyBoard = new Storyboard();
Duration duration = new Duration(TimeSpan.FromMilliseconds(600));
storyBoard.Duration = duration;

DoubleAnimation animation = new DoubleAnimation();
animation.Duration = duration;
storyBoard.Children.Add(animation);

Storyboard.SetTarget(animation, objectToBeAnimated);
Storyboard.SetTargetProperty(animation, "objectToBeAnimated's property");

animation.To = someValue;

LayoutRoot.Resources.Add(storyBoard);

storyBoard.Begin();

Take a look at this example that draws a sequence of lines. I've used another property of the DoubleAnimation class: BeginTime. This way all lines are drawn consecutively. The code for this example:


using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace LineAnimation
{
    public partial class Page : UserControl
    {
        private Storyboard storyBoard;

        public Page()
        {
            InitializeComponent();
            
            Loaded += new RoutedEventHandler(PageLoaded);
        }

        private void PageLoaded(object sender, RoutedEventArgs e)
        {
            CreateAnimation();
            storyBoard.Begin();
        }

        private void CreateAnimation()
        {
            Line[] lines = new Line[700];
            int durationMillis = 200;
            Duration duration = new Duration(TimeSpan.FromMilliseconds(durationMillis));
            double previousX = 0;
            double previousY = 0;
            int lineCount = 0;            

            storyBoard = new Storyboard();
            storyBoard.Duration = new Duration(TimeSpan.FromMilliseconds(durationMillis * 60));
            
            for (int i = 0; i < 700; i++)
            {
                double newX = Math.Sin(i*4) * 150;
                double newY = Math.Cos(i*4) * 150;
                newX += 200;
                newY += 200;

                if (i > 0)
                {
                    SolidColorBrush stroke = new SolidColorBrush();
                    stroke.Color = Colors.Black;

                    lines[lineCount] = new Line();
                    lines[lineCount].X1 = previousX;
                    lines[lineCount].Y1 = previousY;
                    lines[lineCount].X2 = previousX;
                    lines[lineCount].Y2 = previousY;
                    lines[lineCount].Stroke = stroke;

                    LayoutRoot.Children.Add(lines[lineCount]);

                    DoubleAnimation animationX = new DoubleAnimation();
                    DoubleAnimation animationY = new DoubleAnimation();

                    animationX.BeginTime = animationY.BeginTime = new TimeSpan(0, 0, 0, 0, lineCount * durationMillis);
                    animationX.Duration = animationY.Duration = duration;
                    storyBoard.Children.Add(animationX);
                    storyBoard.Children.Add(animationY);

                    Storyboard.SetTarget(animationX, lines[lineCount]);
                    Storyboard.SetTarget(animationY, lines[lineCount]);
                    Storyboard.SetTargetProperty(animationX, "X2");
                    Storyboard.SetTargetProperty(animationY, "Y2");

                    animationX.To = newX;
                    animationY.To = newY;

                    lineCount++;
                }
                previousX = newX;
                previousY = newY;
            }

            LayoutRoot.Resources.Add(storyBoard);
        }
    }
}

Read more about Silverlight & Animation

  1. 1 Comments/Trackbacks
  2. Section(s): C#, Silverlight 
 
 

Silverlight 2 Beta 1 C# Truchet Tiling

March 4, 2008
Truchet Tiling

Truchet Tiling is an easy way of creating random patterns. See what it looks like here.


using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace Truchet3
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();

            drawTiles(40, Colors.Black);
        }

        private void drawTiles(int numTilesHorizontal, Color color)
        {
            SolidColorBrush stroke = new SolidColorBrush();
            stroke.Color = Colors.Black;

            int tileSize = (int)(Width / (double)numTilesHorizontal);
            int numTilesVertical = (int)Math.Ceiling(Height / (double)tileSize);
            int seed = 0;

            for (int i = 0; i < numTilesHorizontal + 1; i++)
            {
                for (int j = 0; j < numTilesVertical + 1; j++)
                {
                    int x = i * tileSize;
                    int y = j * tileSize;

                    // -- create a time dependend seed
                    DateTime dateTime = new DateTime(1000);
                    dateTime = DateTime.Now;
                    seed += (int)(dateTime.Millisecond);
                    Random random = new Random(seed);
                    int randomNumber = random.Next(0, 2);

                    drawTile1(x, y, tileSize, randomNumber, color);
                }
            }
        }

        private void drawTile1(int x, int y, int tileSize, int randomNumber, Color color)
        {
            double ellipseSize = (double)tileSize;
            double ellipseRadius = ellipseSize * .5;

            double leftPos1 = 0 - ellipseRadius;
            double topPos1 = (randomNumber == 0) ? 0 - ellipseRadius : tileSize - ellipseRadius;

            double leftPos2 = tileSize - ellipseRadius;
            double topPos2 = (randomNumber == 0) ? tileSize - ellipseRadius : 0 - ellipseRadius;

            Canvas canvas = new Canvas();
            canvas.Width = canvas.Height = tileSize;
            canvas.SetValue(Canvas.LeftProperty, x);
            canvas.SetValue(Canvas.TopProperty, y);

            RectangleGeometry rectMask = new RectangleGeometry();
            Rect rect = new Rect();
            rect.Width = rect.Height = tileSize;
            rectMask.Rect = rect;
            canvas.Clip = rectMask;

            SolidColorBrush stroke1 = new SolidColorBrush();
            stroke1.Color = color;

            Ellipse ellipse1 = new Ellipse();
            ellipse1.Width = ellipse1.Height = ellipseSize;
            ellipse1.StrokeThickness = .5;
            ellipse1.Stroke = stroke1;
            ellipse1.SetValue(Canvas.LeftProperty, leftPos1);
            ellipse1.SetValue(Canvas.TopProperty, topPos1);

            canvas.Children.Add(ellipse1);
            Canvas layoutRoot = FindName("LayoutRoot") as Canvas;

            SolidColorBrush stroke2 = new SolidColorBrush();
            stroke2.Color = color;

            Ellipse ellipse2 = new Ellipse();
            ellipse2.Width = ellipse2.Height = ellipseSize;
            ellipse2.StrokeThickness = .5;
            ellipse2.Stroke = stroke2;
            ellipse2.SetValue(Canvas.LeftProperty, leftPos2);
            ellipse2.SetValue(Canvas.TopProperty, topPos2);

            canvas.Children.Add(ellipse2);

            layoutRoot.Children.Add(canvas);
        }
    }
}

  1. 2 Comments/Trackbacks
  2. Section(s): C#, Silverlight 
 
 

An essential AIR application for serious guitarists

March 4, 2008

I just finished the new version of my guitar scales application. When AIR was still Apollo I created a first rough version with a standard Flex look. Now that AIR 1.0 has been released it was time to do it properly.

Guitar Scales V2

This application lets you pick a scale and draws it on a virtual fretboard. You can change the number of strings & frets, the tuning, the visible intervals, pick scale chords and lots more. Give it a try!

  1. 8 Comments/Trackbacks
  2. Section(s): AIR, Flash/ActionScript, Flex 
 
 

Programmatic drawing with Silverlight Part 2: C#

March 3, 2008

In one of my previous posts I explored how programmatic drawing with Silverlight 1.0/JavaScript worked. It was done by constructing a XAML string and inserting it into the XAML hierarchy. Not a nice way of doing things, imho.

Fortunately Silverlight 1.1 alpha offers the possibility to use C#. This way there's no need to construct strings anymore because the drawing API can be used for drawing. This is the same code I used in my previous post, but ported to C#:

Note Some things have changed in Silverlight 2 Beta 1:

  • [Scriptable] on methods changed to [ScriptableMember()]
  • Removed [Scriptable] on the class
  • Changed the managed code scriptable object registration from WebApplication.Current.RegisterScriptableObject("basic", this);
    to
    HtmlPage.RegisterScriptableObject("basic", this);

using System;
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Windows.Browser;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using System.Net;

namespace Whirl2
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();

            HtmlPage.RegisterScriptableObject("basic", this);  

            drawWhirl(3);
        }

        [ScriptableMember()]
        public void drawWhirl(uint numSides)
        {
            double[] x = new double[numSides + 1];
            double[] y = new double[numSides + 1];
            DateTime startTime = DateTime.Now;
            uint scaleFactor = 275;
            uint centerX = 300;
            uint centerY = 300;
            uint numLinesDrawn = 0;
            double rotAngle = 0.05;
            double rotAngleSin = Math.Sin(rotAngle);
            double rotAngleCos = Math.Cos(rotAngle);
            double a = (Math.PI * (1 - 2 / (double)numSides));
            double c = Math.Sin(a) / (rotAngleSin + Math.Sin(a + rotAngle));
            Canvas layoutRoot = FindName("LayoutRoot") as Canvas;

            layoutRoot.Children.Clear();

            for (uint k = 0; k <= numSides; k++)
            {
                double t = (2 * k + 1) * Math.PI / (double)numSides;
                x[k] = Math.Sin(t);
                y[k] = Math.Cos(t);
            }

            for (uint n = 1; n < 64; n++)
            {
                Point previousPoint = new Point();
                previousPoint.X = (x[0] * scaleFactor) + centerX;
                previousPoint.Y = (y[0] * scaleFactor) + centerY;

                for (uint l = 0; l <= numSides; l++)
                {
                    Point newPoint = new Point();
                    newPoint.X = (x[l] * scaleFactor) + centerX;
                    newPoint.Y = (y[l] * scaleFactor) + centerY;

                    Line line = new Line();
                    line.X1 = previousPoint.X;
                    line.Y1 = previousPoint.Y;
                    line.X2 = newPoint.X;
                    line.Y2 = newPoint.Y;
                    line.StrokeThickness = 1;
                    SolidColorBrush stroke = new SolidColorBrush();
                    stroke.Color = Colors.Black;
                    line.Stroke = stroke;

                    layoutRoot.Children.Add(line);

                    numLinesDrawn++;

                    previousPoint = newPoint;
                }

                for (uint m = 0; m <= numSides; m++)
                {
                    double z = x[m];
                    x[m] = (x[m] * rotAngleCos - y[m] * rotAngleSin) * c;
                    y[m] = (z * rotAngleSin + y[m] * rotAngleCos) * c;
                }
            }

            HtmlElement divInfo = HtmlPage.Document.GetElementById("divInfo");

            divInfo.SetAttribute("innerHTML",
                "<strong>Number of sides:</strong> " + numSides + "<br>" +
                "<strong>Number of lines drawn:</strong> " + numLinesDrawn + "<br>" +
                "<strong>Time:</strong> " + ((DateTime.Now - startTime).Milliseconds) + " milliseconds");
        }
    }
}

Take a look and compare the performance to the JavaScript version. Not surprisingly, it's much faster.

  1. 1 Comments/Trackbacks
  2. Section(s): C#, Silverlight