Silverlight Analog/Retro Flip Numbers

I’m not sure what to call these exactly. I’ve created a relatively simple Silverlight 4 control that emulates the old mechanical flip style numbers (or letters) displays found at airports and in old clock-radios.

image

I call it the RetroFlipper.

It’s easy to use (at least for my needs). Declare an instance of the control in XAML:

xmlns:wpcontrols="clr-namespace:WiredPrairie.Controls;assembly=WiredPrairie.RetroFlipperControl"             

 

        <wpcontrols:RetroFlipper Margin="5,20" 
                                 x:Name="numberFlip100" Grid.RowSpan="1" Grid.Column="1"/>

And then respond to the “Flipped” event and set the “Text” property as needed.

            numberFlip0.Flipped += new EventHandler(numberFlip1_Flipped);
            numberFlip0.Text = "0"; //(0, 0);

The default animation speed can be adjusted:

numberFlip0.AnimationSpeed = 1;

It’s a percentage – 1.0 is the default. If you want the animation of the flip to be half speed for example, just set it to .5.

The class that drives the demo is really simple:

public partial class MainPage : UserControl
{
    private DispatcherTimer _timer;
    private int _inc = 0;

    public MainPage()
    {
        InitializeComponent();
        numberFlip0.Text = "0"; //(0, 0);
        numberFlip0.AnimationSpeed = 1;
        numberFlip10.Text = "0"; //(0, 0);
        numberFlip10.AnimationSpeed = .7;
        numberFlip100.Text = "0"; //(0, 0);
        numberFlip100.AnimationSpeed = .4;
        _timer = new DispatcherTimer();
        _timer.Interval = TimeSpan.FromSeconds(.5);
        _timer.Tick += new EventHandler(_timer_Tick); 
        
    }

    void _timer_Tick(object sender, EventArgs e)
    {
        int current = _inc;
        int next = ++_inc;
        if (next % 10 == 0)
        {
            numberFlip10.Text = Math.Floor(next / 10 % 10).ToString(); 
        }
        if (next % 100 == 0)
        {
            numberFlip100.Text = Math.Floor(next / 100 % 100).ToString(); 
        }

        numberFlip0.Text = (next % 10).ToString();            
    }

    private void Button_Click(object sender, System.Windows.RoutedEventArgs e)
    {
        _timer.Start();
    }
}

(And no, it doesn’t handle numbers > 1000).

Building the control required a few tricks.

The most interesting was that I decided to use 4 layers to actually represent and animate the flip cards:

image

Using a few OpacityMasks

<Border.OpacityMask>
    <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
        <GradientStop Color="Transparent" Offset="0.5"/>
        <GradientStop Color="Black" Offset="1"/>
        <GradientStop Color="Black" Offset="0.5"/>
        <GradientStop Color="Transparent"/>
    </LinearGradientBrush>
</Border.OpacityMask>

and some creative PlaneProjection and animations,

<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Projection).(PlaneProjection.RotationX)" Storyboard.TargetName="backBottom">
    <EasingDoubleKeyFrame KeyTime="0:0:0.17" Value="270"/>
    <EasingDoubleKeyFrame KeyTime="0:0:0.27" Value="180"/>
    <EasingDoubleKeyFrame KeyTime="0:0:0.30" Value="220"/>
    <EasingDoubleKeyFrame KeyTime="0:0:0.32" Value="180"/>
</DoubleAnimationUsingKeyFrames>

it’s possible to create the illusion of the mechanical parts moving.

Any text may be set into the Text property – it’s automatically sized to fill. So, it could be words, double digits, anything you’d like, as long as it’s text.

In any case, the demo is here.

The source code, licensed under BSD, is here.

Enjoy.

Visual Studio 2010 Crashes

Visual Studio 2010 crashes a lot while doing WPF and Silverlight development for me. Anyone else having that same problem? It happens frequently after resuming my PC from ‘sleep’ or ‘hibernation’ …, but that could be a coincidence.

Microsoft Visual Studio 2010 has stopped working

Interestingly, one of the functions in the stack trace is a PNG encoder. PNG’s are my image file of choice in Silverlight and web applications. I know the project that was currently loaded contains several PNG files. Maybe there’s no connection.

     ntdll.dll!_RtlReportCriticalFailure@8()  + 0x57 bytes   
     ntdll.dll!_RtlpReportHeapFailure@4()  + 0x21 bytes   
     ntdll.dll!_RtlpLogHeapFailure@24()  + 0xa1 bytes   
     ntdll.dll!_RtlFreeHeap@12()  + 0x4ffeb bytes   
     kernel32.dll!_HeapFree@12()  + 0x14 bytes   
     WindowsCodecs.dll!WPF::ProcessHeapImpl::Free()  + 0x1c bytes   
>    WindowsCodecs.dll!DynArrayImpl<0>::~DynArrayImpl<0>()  + 0x104f bytes   
     WindowsCodecs.dll!CPngFrameEncode::~CPngFrameEncode()  + 0x66 bytes   
     WindowsCodecs.dll!CPngFrameEncode::`vector deleting destructor'()  + 0xd bytes   
     WindowsCodecs.dll!CMILCOMBase::InternalRelease()  + 0x24 bytes   
     WindowsCodecs.dll!CResetStream::Release()  + 0xe bytes   
     wpfgfx_v0400.dll!MILRelease()  + 0xe bytes   
     PresentationCore.ni.dll!5e74f2b1()    
     [Frames below may be incorrect and/or missing, no symbols loaded for PresentationCore.ni.dll]   
     PresentationCore.ni.dll!5e74f2b1()    
     PresentationCore.ni.dll!5e74f2fe()    
     clr.dll!_CallDescrWorker@20()  + 0x33 bytes   
     clr.dll!_CallDescrWorkerWithHandler@24()  + 0x8a bytes   
     clr.dll!MethodDesc::CallDescr()  + 0x148 bytes   
     clr.dll!MethodDesc::CallTargetWorker()  + 0x21 bytes   
     clr.dll!SafeHandle::RunReleaseMethod()  + 0xc7 bytes   
     clr.dll!SafeHandle::Release()  + 0x7b257 bytes   
     clr.dll!SafeHandle::Dispose()  + 0x2d bytes   
     clr.dll!SafeHandle::Finalize()  + 0xb0 bytes   
     mscorlib.ni.dll!617b913b()    
     mscorlib.ni.dll!617b90b2()    
     clr.dll!MethodTable::SetObjCreateDelegate()  – 0x1fc874 bytes   
     clr.dll!MethodTable::CallFinalizer()  + 0x75 bytes   
     clr.dll!WKS::CallFinalizer()  + 0x80 bytes   
     clr.dll!WKS::GCHeap::TraceGCSegments()  – 0x1f9fc6 bytes   
     clr.dll!WKS::GCHeap::TraceGCSegments()  – 0x1fa08a bytes   
     clr.dll!WKS::GCHeap::FinalizerThreadWorker()  + 0xb1 bytes   
     clr.dll!Thread::DoExtraWorkForFinalizer()  – 0xc291e bytes   
     clr.dll!Thread::ShouldChangeAbortToUnload()  + 0x1251e bytes   
     clr.dll!Thread::ShouldChangeAbortToUnload()  + 0x125d9 bytes   
     clr.dll!ManagedThreadBase_NoADTransition()  + 0x35 bytes   
     clr.dll!ManagedThreadBase::FinalizerBase()  + 0xf bytes   
     clr.dll!WKS::GCHeap::FinalizerThreadStart()  + 0xfb bytes   
     clr.dll!Thread::intermediateThreadProc()  + 0x48 bytes   
     kernel32.dll!@BaseThreadInitThunk@12()  + 0x12 bytes   
     ntdll.dll!___RtlUserThreadStart@8()  + 0x27 bytes   
     ntdll.dll!__RtlUserThreadStart@8()  + 0x1b bytes   

How to embed and use the Google Web Fonts in Silverlight

There are a few steps necessary to using one of the Google Web Fonts in Silverlight.

Step 1

Go to the directory of web fonts here.

  image

Step 2

Pick your favorite font and click the embed link:

SNAGHTML5af9c8a9

Step 3

Verify the license is acceptable to your needs.

SNAGHTML5afad2c6

Step 4

Click the “Get the code” tab:

image

Copy the location of the CSS and open it in your favorite editor. I just paste it into a new tab in Chrome. But you could open it in Visual Studio if you’d like for example (just File > Open).

Step 5

Grab the font URL from the CSS (copy the link to the clipboard).

image

Step 6

From the same tab in Chrome, I paste in that value which prompts me to download the file:

Give the font a file name and save it locally.

image

Step 7

In Windows 7, installing Fonts is easy (as easy as it should have been for years). For other operating systems, consult your OS docs.

SNAGHTML5aff9164

In Windows 7, simply click the image button.

Step 8-Blend 4 (RC)

In Blend 4, to use the font, you’ll need to select it once as a Font choice:

 image

Click the “Embed” checkbox to include it in your XAP file.

image

Step 8-Visual Studio 2010

In Visual Studio 2010, copy the font file to a new folder (suggest something like Fonts). Set the build action to Resource:

image

Step 9

Then, to use the font, set the FontFamily to be the Path/FileName.ext#FontName as shown here:

image

<Button Content="Login" Height="54" Margin="21,156,16,0" 
                x:Name="button1" 
                VerticalAlignment="Top" Click="button1_Click" Grid.Row="1" Grid.Column="1" 
                FontFamily="FONTS/INCONSOLATA.TTF#Inconsolata" />

 

Step 10

Sit back and enjoy the new font.

Impressive LiveCycle Data Services Numbers

My knowledge of Adobe’s LiveCycle Data Services platform is very limited as I’ve experimented with it only once. However, I’m impressed with the ability of the LiveCycle Data Services (LCDS) to push what seems like a massive amount of messages per second to client machines running Adobe Flash/AIR applications.

http://www.dcooper.org/blog/client/index.cfm?mode=entry&entry=084D6DDA-4E22-1671-5EFB301D42924692

LCDS in their scenario was able to push 400,000 messages to 500 concurrent clients with an average latency of less than 15 milliseconds on a single dual-processor Intel machine.

I know there were some big improvements in the network stack and polling API in Silverlight 4 (in particular the http stack added multiple messages per poll) – but I don’t know how it compares from a performance perspective to the Adobe options.

Anyone know of any real-world comparisons?

Apple Says: Safari Only!

I was browsing around in Chrome, looking at some examples of different JavaScript frameworks that Apple has created in the past few years and hit this:

Safari Only

“To access One to One, you must use a supported browser. Please download and install Safari 3.”

Harsh.

(And it hasn’t been updated to reflect the current version of Safari).