Working from Home

For the last week and a half I’ve been lucky enough to take some leave and work on some of my own (unpaid) projects. Here’s a few simple observations from that experience…

The view from my study window is better than the view from my third floor city office.

DSC09528-34 Stitch

The coffee is better, closer and comes with snacks.

DSC09503

No background chatter, instead I have the rare opportunity to really crank up the music – awesome boost to developer productivity!

Play List

No 2+ hour commute. On the surface this would seem to be a huge benefit, but it does come with drawbacks. My daily commute normally involves walking 4km and I get precious little other daily exercise these days. Also, commute time via bus is my allocated reading and podcast listening time – so I’ve been getting a little behind there.

I also got to watch my son participate in his first Grand Prix event – priceless!

DSC09535

Overall a great experience. I thoroughly recommend it!

I wonder if they’d notice at work if I took a couple more weeks off?

Desk Calendar UserControl – Source Code

I had to remove the source code from my previous post because it was doing weird things to my RSS feed. For those that may be interested though a sample project file can be found here. Note that its far from a finished control – the animation that happens when you click on it was just me messing around with Blend and the intention is for it to allow full navigation and selection.

XBAP demo (27kb) can be launched from here – note that XBAP version doesn’t have any drop shadows.

HTC Touch Diamond2

HTC Touch Diamond2 - Front I’m on an insane spending spree at the moment. Its a combination of the fast approaching end of the financial year and a series of routine mishaps/malfunctions – reversing into the garage roller door (no I wasn’t driving), faulty speaker on my 4 year old i-Mate JAM, grossly overpriced kitchen appliances, attending conferences etc.

Inspired by what I saw at Remix regarding the launch of Windows Mobile 6.5 I figured that since my phone is on the fritz now must be the time to get a new one. For me the phone has to be a Windows Mobile device and by all the reviews I’ve looked at in the last couple of days the HTC devices seem to be the most well thought of.

So the order is placed. I should be getting an unlocked HTC Touch Diamond2 in the next few days. Cooked ROMS running Windows Mobile 6.5 are already available and I already have the WM6.5 SDK installed on my dev box.

Desk Calendar UserControl

I had a lot of fun late this afternoon putting together a Desk Calendar UserControl. The idea was triggered by me using a screenshot of the Vista Calendar Gadget in my last post. Also I’m working on a project at the moment that could use a nice date/calendar display and my previous WinForms attempts never looked that great.


Believing that imitation is the greatest form of flattery – here is my new Desk Calendar UserControl in all its glory. Of course being WPF its fully zoomable – no nasty bitmaps here – click the image to see it at higher res.


DeskCalendar


For the moment the control is read-only, although I did start working on a “flip page” animation. The layout was done exclusively in Blend (v3 Preview) hence the mark-up has some redundant elements and over-precise co-ords. In general though I was really happy with how easy this was to put together using Blend – the product has certainly matured well.

[Edit: Source code and XBAP demo can be found on subsequent post here.]

CodeCampSA 2009

CodeCampSA 2009 - DatesCodeCampSA organised by the Adelaide .NET User Group (ADNUG) is on again this year on the weekend of 18-19th July. Same venue as last year at Uni SA “City West” campus. For more details about the venue and to keep up to date on who will be speaking (and what they’ll be speaking about) visit the new website at www.codecampsa.com. Kudos go to David Gardiner for putting the site together!

So if you are in Adelaide make sure you take some time out of your weekend to come along. I’ll be amongst those presenting but don’t let that deter you!

Box Layout Panel

Here’s another quick WPF custom control derived from Panel. This one is a cross between a StackPanel and a WrapPanel. It supports two modes of layout – Inline and Block.


Inline elements are wrapped left to right much as the same as a WrapPanel with the default Orientation = Horizontal.


Block elements are stacked as per a StackPanel with the default Orientation = Vertical.


The benefit of combining (a simplified version) of this logic into one layout control is that an attached property can then be used on a per child basis to determine the layout (LayoutMode = Block or Inline). This is even more convenient when the property is set via an implicit style, e.g. all TextBlocks set to Inline by default, all Buttons as Block.


I also added some dependency properties for Padding (space between edge and top/left/right/bottom-most controls) and InternalPadding (the vertical and horizontal spacing between wrapped/stacked controls).

<panels:BoxPanel Height=”Auto” Background=”PaleGreen” InternalPadding=”4,2″ Padding=”50,8,8,8″>
<
TextBlock>Some inline text.</TextBlock
>
<
TextBlock>Followed by some more inline text.</TextBlock
>
<
TextBlock>Followed by yet some more inline text.</TextBlock
>
<
TextBlock panels:BoxPanel.LayoutMode=”Block”>A new paragraph.</TextBlock
>
<
Button panels:BoxPanel.LayoutMode=”Block”>A Button</Button
>
<
TextBlock>Below are three buttons in a line</TextBlock
>
<
Button panels:BoxPanel.LayoutMode=”Inline”>One</Button
>
<
Button panels:BoxPanel.LayoutMode=”Inline”>Two</Button
>
<
Button panels:BoxPanel.LayoutMode=”Inline”>Three</Button
>
<
panels:BoxPanel Background=”LightYellow” Padding=”10,2″ InternalPadding
=”4,0″>
<
TextBlock>The</TextBlock
>
<
Image Source=”Passport_Photo_with_blue_background_half_size.png” Width
=”24″/>
<
TextBlock>End.</TextBlock
>
</
panels:BoxPanel
>
</
panels:BoxPanel>

BoxPanel - Layout Measures


 


Sound a bit obscure? Trust me, I had a reason .

VS2010 Intellisense and refactoring

I’ve been spending a little more time recently with Visual Studio 2010 Beta 1. In particular building a solution from the ground up (including TFS integration) and doing a fair bit of prototyping. Some of the new editor improvements in VS2010 are really pretty neat.

One of the first changes that you notice in the editor of course is the changes to intellisense. It now includes auto-filtering, but not just by a “starts-with” search but using more of a “contains” approach. This includes the ability to search for multi-word names using abbreviations, e.g. “AQN” to match “AssemblyQualifiedName.“ Personally I think the filtering works particularly well. Having used Resharper’s intellisense filtering I wasn’t to keen on the idea, I find that implementation to be slow and it somehow feels invasive. The VS2010 implementation IMHO is much better.

VS2010 Filtered Intellisense

I’ve started using the “consume-first” toggle, which is a great way to prevent Visual Studio from being over-zealous with auto-completion. This is useful when you’re building code against a set of yet-to-be-written APIs (i.e. consuming the API first).

VS2010 Consume First Mode

Just press the Ctrl+Alt+Space combination and auto-completion is suspended.

VS2010 Consume First Not Yet Created Class

The code generation options have also had a tweak with the “Generate other…” dialog.

VS2010 Generate Class

Lots of good options here – particularly being able to specify in which project to create the new file.

VS2010 Generate Other

(Refer here for more VS2010 code-focused changes).

{sigh} It’s getting harder and harder to go back to Visual Studio 2008.

Circular Layout Panel v2

On the flight to Remix09 last week I had fun putting together a simple WPF Circular Layout Panel. Today I decided that a nice “extra” feature would be to have the child elements optionally rotated so that they are normalised with the centre of the layout panel.


So after adding a new attached dependency property, IsNormalised I updated my sample clock and fan menu. The following XAML…

<Window x:Class=”PanelTest.Window1″
xmlns
=”http://schemas.microsoft.com/winfx/2006/xaml/presentation”
xmlns:x
=”http://schemas.microsoft.com/winfx/2006/xaml”
Title=”Circular Panel Examples” Height=”405″ Width
=”383″
xmlns:local
=”clr-namespace: PanelTest”
xmlns:panels=”clr-namespace:Spencen.Panels;assembly=Spencen.Panels”
>
<
DockPanel
>
<
DockPanel.Resources
>
<!– Stuff to make buttons pretty –>
</DockPanel.Resources
>
<Ellipse Fill=”LightYellow” Stroke=”LightGray” StrokeThickness=”1″ StrokeDashArray
=”0,1,1,0″ />
<panels:CircularPanel StartAngle=”-90″ EndAngle=”630″
TextBlock.FontSize=”24pt”>
<
TextBlock panels:CircularPanel.IsNormalised=”True”>XII</TextBlock
>
<
TextBlock panels:CircularPanel.IsNormalised=”True”>I</TextBlock
>
<
TextBlock panels:CircularPanel.IsNormalised=”True”>II</TextBlock
>
<
TextBlock panels:CircularPanel.IsNormalised=”True”>III</TextBlock
>
<
TextBlock panels:CircularPanel.IsNormalised=”True”>IV</TextBlock
>
<
TextBlock panels:CircularPanel.IsNormalised=”True”>V</TextBlock
>
<
TextBlock panels:CircularPanel.IsNormalised=”True”>VI</TextBlock
>
<
TextBlock panels:CircularPanel.IsNormalised=”True”>VII</TextBlock
>
<
TextBlock panels:CircularPanel.IsNormalised=”True”>VIII</TextBlock
>
<
TextBlock panels:CircularPanel.IsNormalised=”True”>IX</TextBlock
>
<
TextBlock panels:CircularPanel.IsNormalised=”True”>X</TextBlock
>
<
TextBlock panels:CircularPanel.IsNormalised=”True”>XI</TextBlock
>
<
Ellipse Width=”5″ Height=”5″ Fill=”Black”
panels:CircularPanel.RadiusScaleX=”0.9″ panels:CircularPanel.RadiusScaleY
=”0.9″/>
<
Ellipse Width=”5″ Height=”5″ Fill=”Black”
panels:CircularPanel.RadiusScaleX=”0.9″ panels:CircularPanel.RadiusScaleY
=”0.9″/>
<
Ellipse Width=”5″ Height=”5″ Fill=”Black”
panels:CircularPanel.RadiusScaleX=”0.9″ panels:CircularPanel.RadiusScaleY
=”0.9″/>
<
Ellipse Width=”5″ Height=”5″ Fill=”Black”
panels:CircularPanel.RadiusScaleX=”0.9″ panels:CircularPanel.RadiusScaleY
=”0.9″/>
<
Ellipse Width=”5″ Height=”5″ Fill=”Black”
panels:CircularPanel.RadiusScaleX=”0.9″ panels:CircularPanel.RadiusScaleY
=”0.9″/>
<
Ellipse Width=”5″ Height=”5″ Fill=”Black”
panels:CircularPanel.RadiusScaleX=”0.9″ panels:CircularPanel.RadiusScaleY
=”0.9″/>
<
Ellipse Width=”5″ Height=”5″ Fill=”Black”
panels:CircularPanel.RadiusScaleX=”0.9″ panels:CircularPanel.RadiusScaleY
=”0.9″/>
<
Ellipse Width=”5″ Height=”5″ Fill=”Black”
panels:CircularPanel.RadiusScaleX=”0.9″ panels:CircularPanel.RadiusScaleY=”0.9″/>
<
Ellipse Width=”5″ Height=”5″ Fill=”Black”
panels:CircularPanel.RadiusScaleX=”0.9″ panels:CircularPanel.RadiusScaleY
=”0.9″/>
<
Ellipse Width=”5″ Height=”5″ Fill=”Black”
panels:CircularPanel.RadiusScaleX=”0.9″ panels:CircularPanel.RadiusScaleY
=”0.9″/>
<
Ellipse Width=”5″ Height=”5″ Fill=”Black”
panels:CircularPanel.RadiusScaleX=”0.9″ panels:CircularPanel.RadiusScaleY
=”0.9″/>
<
Ellipse Width=”5″ Height=”5″ Fill=”Black”
panels:CircularPanel.RadiusScaleX=”0.9″ panels:CircularPanel.RadiusScaleY
=”0.9″/>




<
Line x:Name=”secondHand” Fill=”Black” X1=”0″ X2=”0″ Y1=”0″ Y2=”100″
Stroke=”Red” StrokeThickness=”1″ StrokeStartLineCap=”Triangle” StrokeEndLineCap
=”Round”
panels:CircularPanel.FixedAngle
=”-90″
panels:CircularPanel.RadiusScaleX
=”0.4″
panels:CircularPanel.RadiusScaleY
=”0.4″
panels:CircularPanel.IsNormalised
=”True”/>
<
Line x:Name=”minuteHand” Fill=”Black” X1=”2″ X2=”2″ Y1=”0″ Y2=”70″
Stroke=”Black” StrokeThickness=”5″ StrokeStartLineCap=”Triangle” StrokeEndLineCap
=”Round”
panels:CircularPanel.FixedAngle
=”-60″
panels:CircularPanel.RadiusScaleX
=”0.3″
panels:CircularPanel.RadiusScaleY
=”0.3″
panels:CircularPanel.IsNormalised
=”True”/>
<
Line x:Name=”hourHand” Fill=”Black” X1=”5″ X2=”5″ Y1=”0″ Y2=”50″
Stroke=”Black” StrokeThickness=”10″ StrokeStartLineCap=”Triangle” StrokeEndLineCap
=”Round”
panels:CircularPanel.FixedAngle
=”-180″
panels:CircularPanel.RadiusScaleX
=”0.2″
panels:CircularPanel.RadiusScaleY
=”0.2″
panels:CircularPanel.IsNormalised
=”True”/>
<
Ellipse Fill
=”Black”
panels:CircularPanel.FixedAngle
=”0″
panels:CircularPanel.RadiusScaleX
=”0″
panels:CircularPanel.RadiusScaleY=”0″ Width=”30″ Height
=”30″ />
<
panels:CircularPanel.Triggers
>
<
EventTrigger RoutedEvent
=”Loaded”>
<
BeginStoryboard
>
<
Storyboard
>
<
DoubleAnimation Duration=”0:1:0″ By=”360″ RepeatBehavior=”Forever”
Storyboard.TargetName=”secondHand”
Storyboard.TargetProperty
=”(panels:CircularPanel.FixedAngle)”/>
<
DoubleAnimation Duration=”1:0:0″ By=”360″ RepeatBehavior=”Forever”
Storyboard.TargetName=”minuteHand”
Storyboard.TargetProperty
=”(panels:CircularPanel.FixedAngle)”/>
<
DoubleAnimation Duration=”12:0:0″ By=”360″ RepeatBehavior=”Forever”
Storyboard.TargetName=”hourHand”
Storyboard.TargetProperty
=”(panels:CircularPanel.FixedAngle)”/>
</
Storyboard
>
</
BeginStoryboard
>
</
EventTrigger
>
</
panels:CircularPanel.Triggers
>
</
panels:CircularPanel
>
<
panels:CircularPanel Padding=”45″ StartAngle=”-90″ EndAngle=”-90″
>
<
Button panels:CircularPanel.IsNormalised=”true”>1</Button
>
<
Button panels:CircularPanel.IsNormalised=”true”>2</Button
>
<
Button panels:CircularPanel.IsNormalised=”true”>3</Button
>
<
Button panels:CircularPanel.IsNormalised=”true”>4</Button
>
<
Button Panel.ZIndex=”1″ Background=”Gray”>Menu</Button
>
<
Button panels:CircularPanel.IsNormalised=”true”>5</Button
>
<
Button panels:CircularPanel.IsNormalised=”true”>6</Button
>
<
Button panels:CircularPanel.IsNormalised=”true”>7</Button
>
<
Button panels:CircularPanel.IsNormalised=”true”>8</Button
>
<
panels:CircularPanel.Triggers
>
<
EventTrigger RoutedEvent
=”MouseEnter”>
<
BeginStoryboard
>
<
Storyboard
>
<
DoubleAnimation To=”-180″ Storyboard.TargetProperty
=”StartAngle”>
<
DoubleAnimation.EasingFunction
>
<
ElasticEase Springiness=”10″ Oscillations
=”2″/>
</
DoubleAnimation.EasingFunction
>
</
DoubleAnimation
>
<
DoubleAnimation To=”0″ Storyboard.TargetProperty
=”EndAngle”>
<
DoubleAnimation.EasingFunction
>
<
ElasticEase Springiness=”10″ Oscillations
=”2″/>
</
DoubleAnimation.EasingFunction
>
</
DoubleAnimation
>
</
Storyboard
>
</
BeginStoryboard
>
</
EventTrigger
>
<
EventTrigger RoutedEvent
=”MouseLeave”>
<
BeginStoryboard
>
<
Storyboard
>
<
DoubleAnimation To=”-90″ AccelerationRatio=”0.5″ DecelerationRatio=”0.5″
Storyboard.TargetProperty
=”StartAngle”/>
<
DoubleAnimation To=”-90″ AccelerationRatio=”0.5″ DecelerationRatio=”0.5″
Storyboard.TargetProperty
=”EndAngle”/>
</
Storyboard
>
</
BeginStoryboard
>
</
EventTrigger
>
</
panels:CircularPanel.Triggers
>
</
panels:CircularPanel
>
</DockPanel
>
</
Window>

Now produces…


 CircularPanel - Normalised


For reference this is so much easier than doing the same thing in WinForms. Custom layout panels really were quite a pain.


Updated source code for CircularPanel is here.

Remix09 Recap

Remix09 Last year I went to Remix08 in Melbourne (scaled down aussie version of Mix08). One of the main attractions was the fact they were giving away a copy of Expression Suite 2 to every attendee – not bad for the $199 entry fee!

This year I decided to go to Remix09 not for software bargains, but because of the quality of last year’s event. Presumably the GFC meant that the event was only held in Sydney this year. Here’s my take on the conference this year.

GoodWindows Mobile 6.5 Development

  • Keynote was packed with lots of good Aussie demos.
  • Matt Morphett on design prototyping and Sketchflow – for me he was the outstanding presenter of the day. [Make sure you check out the video when it comes online late next week.]
  • Silverlight 3 and Expression 3 demos – behaviours, blend visual state manager support, animation easing, 2.5D, shaders etc.
  • Windows Mobile 6.5 was demoed along with plans for the Australian launch and overview of the “Marketplace” to compete with “fruit phone”. Check out the Australian dev centre.
  • Virtual Earth Live Bing Maps for Silverlight. Some nice demos – I liked the GIS integration.

Bad

  • Internet connections. Its a shame that every time I attend a Microsoft conference in Australia the available internet connection sucks. It’s bad enough that the delegates get WiFi that drops out and 3G/NextG saturation, but when the presenters can’t get a reliable/performant connection if really affects demos.
  • Seating was a bit quishy in Ballroom 3. OK – if that’s all I’ve got to complain about I’m thinking this must have been a pretty good day .

Remix10?

There seems to be a question mark around having a Remix conference at all next year. I for one would be disappointed not to see the event return.