Thursday, September 24, 2009

Failure Doesn't Preclude Success

This is a brilliant video on how failure doesn't preclude future success:



Tuesday, September 22, 2009

Touch Demo Part I

Over the next few posts I am going to walk you through building one of the touch demos I used in my CodeRage 4 Session. This demo demonstrates using Direct2D and the WM_TOUCH message. Before we get started here is a brief explanation of these two technologies.

Since Windows Vista GDI has become a legacy drawing API supported with software rendering on top of Direct3D. Direct3D is great but it is very raw. This is where Direct2D shines for applications. Direct2D has all the performance benefits of Direct3D and adds support for bitmaps and text and support for GDI Interop all with a much simpler API. And Delphi 2010 has made it even simpler by wrapping it up with a TDirect2DCanvas that is very similar to TCanvas. Direct2D supports remote rendering through Remote Desktop which is very cool.

WM_TOUCH is the raw multi-touch message that provides various states of contact with the input digitizer for hot sizzling touch applications.

Now that we got that out of the way, create yourself a VCL Application. We want to start painting with Direct2D so add Direct2D and D2D1 to the uses and a TDirect2DCanvas property to your form like this:


private
FCanvas: TDirect2DCanvas;
...
public
constructor Create(AOwner: TComponent); override;
destructor Destroy; override;

property Canvas: TDirect2DCanvas read FCanvas
write FCanvas;
end;
...
constructor TTouchForm.Create(AOwner: TComponent);
begin
inherited;
FCanvas := TDirect2DCanvas.Create(Handle);
end;

destructor TTouchForm.Destroy;
begin
FCanvas.Free;
inherited;
end;

This creates a Direct2D surface (TDirect2DCanvas) that we can draw to instead of the traditional GDI surface (TCanvas).

Depending on the type of application you build you may experience some flicker. To avoid this handle the message WM_ERASEBKGND and returns true.

procedure TTouchForm.WMEraseBkgnd(
var Message: TWMEraseBkgnd);
begin
Message.Result := 1;
end;

Next override Paint and just draw a line:

procedure TTouchForm.Paint;
begin
Canvas.BeginDraw;
try
Canvas.Pen.Color := clRed;
Canvas.MoveTo(10, 10);
Canvas.LineTo(40, 40);
finally
Canvas.EndDraw;
end;
end;

If you run your application at this point and resize the form you will noticed that the line changes size. This is because the view port is resizing to scale to the window and your line will do the same. To prevent this override the Resize method and add the following:

procedure TTouchForm.Resize;
var
HwndTarget: ID2D1HwndRenderTarget;
begin
inherited;
if Supports(Canvas.RenderTarget,
ID2D1HwndRenderTarget, HwndTarget) then
HwndTarget.Resize(D2D1SizeU(ClientWidth, ClientHeight));
Invalidate;
end;

Now you have a form that renders everything drawn to the Canvas through a Direct2D surface.

UPDATE: Added Invalidate to Resize because when resizing the window larger it will force a redraw but smaller will not because typically a redraw isn't required.

Delphi 2010 - Touch and Pen added to TShiftState

While we were researching adding Touch and Gesturing to VCL we quickly realized it was important to detect what type of input produced the mouse messages. So we introduced some new elements to TShiftState: ssTouch and ssPen:


TShiftState = set of (ssShift, ssAlt, ssCtrl,
ssLeft, ssRight, ssMiddle, ssDouble, ssTouch, ssPen);

One of the key reasons this is so important is when handling WM_TOUCH messages the mouse messages are also fired. Chances are you only want to handle one of them. On a non-touch machine you want to handle the mouse. So this allows input to be filtered and handled independently.

Wednesday, September 16, 2009

September Photo of the Month



This is a photo of Cottonwood Lake in Inyo National Forest. This photo is a panorama stitched from 14 photos! And one of the most beautiful mornings I've ever had the pleasure to see.

Tuesday, September 15, 2009

Interactive Gestures 101

As promised at my CodeRage 4 session I will be blogging about Gestures and the Touch feature of Delphi 2010. So here is a quick set of steps to use interactive gestures. It will require a multi-touch system such as I described here (the mouse will not work here) and some context by watching my CodeRage 4 session from here.

1. File | New VCL Application
2. Drop a TPanel on your form (there is a known bug using interactive gestures on the form)
3. Select Panel1 and expand the Touch property
4. Check igoPanSinglerFingerHorizontal, and check igPan. I also like to turn off toPressandHold
5. Go to events and add the following code to the OnGesture event:


if EventInfo.GestureID = igiPan then
Caption := IntToStr(EventInfo.Location.X);

Now run the application and move your finger left and right on the panel.

Note: Interactive Gestures don't require a TGestureManage. Only Gestures require the Gesture Manager.

Update: Fixed the code and added links for touch hardware and my CodeRage 4 session.

Wednesday, September 2, 2009

CodeRage 4



Register for CodeRage4 and come check out the sessions. It's all free so why not, it should be a lot of fun.

I'll be at three talks answering questions:

Building Awesome Touch Enabled Applications by Chris Bensen
Tuesday, September 8, 2009 -- 11:00am - 11:45am PDT
Wednesday, September 9, 2009 -- 9:00am - 9:45am PDT

Hands-On: Gestures in the VCL by Seppy Bloom
Tuesday, September 8, 2009 -- 4:00pm - 4:45pm PDT

What's New in the VCL *
Tuesday, September 8, 2009 -- 3:00pm - 3:45pm PDT
Thursday, September 10, 2009 -- 8:00am - 8:45am PDT (I won't be here because I'll be on vacation!)