Tag Archives: flex

Flex Accepted by Apache Software Foundation

In case you did not see the post on the Flex Team blog on Dec. 31st, it was announced that Flex has officially been accepted by the Apache Software Foundation.   You can view the Apache Flex proposal on the Apache incubator wiki at http://wiki.apache.org/incubator/FlexProposal.

Apache Flex allows developers to target a variety of platforms, initially Apple iOS, Google Android, RIM BlackBerry, Microsoft Windows, and Mac OS X with a single codebase. Flex provides a compiler, skinnable user-interface components and managers to handle styling, skinning, layout, localization, animation, module-loading and user interaction management.

Just a bit of extra detail for you, all of which is available through Apache:

Initial goals of the Apache Flex incubation project:

  • Donate all Adobe Flex SDK source code and documentation to the Apache Software Foundation.
  • Setup and standardize the open governance of the Apache Flex project.
  • Rename all assets from Adobe Flex SDK to Apache Flex in project source code, docs, tests and related infrastructure.

Capturing User Signatures in Mobile Applications

One growing trend that I have seen in mobile & tablet applications is the creation of tools that enable your workforce to perform their job better. This can be in the case of mobile data retrieval, streamlined sales process with apps for door-to-door sales, mobile business process efficiency, etc…

One of the topics that comes up is how do you capture a signature and store it within your application? This might be for validation that the signer is who they say they are, or for legal/contractual reasons. Imagine a few scenarios:

  • Your cable TV can’t be installed until you sign the digital form on the installation tech’s tablet device
  • You agree to purchase a service from a sales person (door to door, or in-store kiosk) – your signature is required to make this legally binding.
  • Your signature is required to accept an agreement before confidential data is presented to you.

These are just a few random scenarios, I’m sure there are many more.   In this post, I will focus on 2 (yes, I said two) cross-platform solutions to handle this task – one built with Adobe Flex & AIR, and one built with HTML5 Canvas & PhoneGap.  

Source for both solutions is available at: https://github.com/triceam/Mobile-Signature-Capture

Watch the video below to see this in action, then we’ll dig into the code that makes it work.

The basic flow of the application is that you enter an email address, sign the interface, then click the green “check” button to submit to the signature to a ColdFusion server.  The server then sends a multi-part email to the email address that you provided, containing text elements as well as the signature that was just captured.

If you’d like to jump straight to specific code portions, use the links below:


The Server Solution

Let’s first examine the server component of the sample application.   The server side is powered by ColdFusion. There’s just a single CFC that is utilized by both the Flex/AIR and HTML/PhoneGap front-end applications.   The CFC exposes a single service that accepts two parameters: the email address, and a base-64 encoded string of the captured image data.

[cf]<cffunction name="submitSignature" access="remote" returntype="boolean">
<cfargument name="email" type="string" required="yes">
<cfargument name="signature" type="string" required="yes">

<cfmail SUBJECT ="Signature"
FROM="#noReplyAddress#"
TO="#email#"
username="#emailLoginUsername#"
password="#emailLoginPassword#"
server="#mailServer#"
type="HTML" >

<p>This completes the form transaction for <strong>#email#</strong>.</p>

<p>You may view your signature below:</p>
<p><img src="cid:signature" /></p>

<p>Thank you for your participation.</p>

<cfmailparam
file="signature"
content="#toBinary( signature )#"
contentid="signature"
disposition="inline" />

</cfmail>

<cfreturn true />
</cffunction>[/cf]

Note: I used base-64 encoded image data so that it can be a single server component for both user interfaces. In Flex/AIR you can also serialize the data as a binary byte array, however binary serialization isn’t quite as easy with HTML/JS… read on to learn more.


The Flex/AIR Solution

The main user interface for the Flex/AIR solution is a simple UI with some form elements. In that UI there is an instance of my SignatureCapture user interface component. This is a basic component that is built on top of UIComponent (the base class for all Flex visual components), which encapsulates all logic for capturing the user signature. The component captures input based on mouse events (single touch events are handled as mouse events in air). The mouse input is then used to manipulate the graphics content of the component using the drawing API. I like to think of the drawing API as a language around the childhood game “connect the dots”. In this case, you are just drawing lines from one point to another.

When the form is submitted, the graphical content is converted to a base-64 encoded string using the Flex ImageSnapshot class/API, before passing it to the server.

You can check out a browser-based Flex version of this in action at http://tricedesigns.com/portfolio/sigCaptureFlex/ – Just enter a valid email address and use your mouse to sign within the signature area. When this is submitted, it will send an email to you containing the signature.

You can check out the SignatureCapture component code below, or check out the full project at https://github.com/triceam/Mobile-Signature-Capture/tree/master/flex%20client. This class will also work in desktop AIR or browser/based Flex applications. The main application workflow and UI is contained with Main.mxml.

[as3]package
{
import flash.display.DisplayObject;
import flash.display.Graphics;
import flash.display.Sprite;
import flash.events.MouseEvent;
import flash.geom.Point;

import mx.core.UIComponent;
import mx.graphics.ImageSnapshot;
import mx.managers.IFocusManagerComponent;

import spark.primitives.Graphic;

public class SignatureCapture extends UIComponent
{
private var captureMask : Sprite;
private var drawSurface : UIComponent;
private var lastMousePosition : Point;

private var backgroundColor : int = 0xEEEEEE;
private var borderColor : int = 0x888888;
private var borderSize : int = 2;
private var cornerRadius :int = 25;
private var strokeColor : int = 0;
private var strokeSize : int = 2;

public function SignatureCapture()
{
lastMousePosition = new Point();
super();
}

override protected function createChildren():void
{
super.createChildren();

captureMask = new Sprite();
drawSurface = new UIComponent();
this.mask = captureMask;
addChild( drawSurface );
addChild( captureMask );

this.addEventListener( MouseEvent.MOUSE_DOWN, onMouseDown );
}

protected function onMouseDown( event : MouseEvent ) : void
{
lastMousePosition = globalToLocal( new Point( stage.mouseX, stage.mouseY ) );
stage.addEventListener( MouseEvent.MOUSE_MOVE, onMouseMove );
stage.addEventListener( MouseEvent.MOUSE_UP, onMouseUp );
}

protected function onMouseMove( event : MouseEvent ) : void
{
updateSegment();
}

protected function onMouseUp( event : MouseEvent ) : void
{
updateSegment();
stage.removeEventListener( MouseEvent.MOUSE_MOVE, onMouseMove );
stage.removeEventListener( MouseEvent.MOUSE_UP, onMouseUp );
}

protected function updateSegment() : void
{
var nextMousePosition : Point = globalToLocal( new Point( stage.mouseX, stage.mouseY ) );
renderSegment( lastMousePosition, nextMousePosition );
lastMousePosition = nextMousePosition;
}

public function clear() : void
{
drawSurface.graphics.clear();
}

override public function toString() : String
{
var snapshot : ImageSnapshot = ImageSnapshot.captureImage( drawSurface );
return ImageSnapshot.encodeImageAsBase64( snapshot );
}

override protected function updateDisplayList(w:Number, h:Number):void
{
super.updateDisplayList(w,h);

drawSurface.width = w;
drawSurface.height = h;

var g : Graphics = this.graphics;

//draw rectangle for mouse hit area
g.clear();
g.lineStyle( borderSize, borderColor, 1, true );
g.beginFill( backgroundColor, 1 );
g.drawRoundRect( 0,0,w,h, cornerRadius, cornerRadius );

//fill mask
g.clear();
g = captureMask.graphics;
g.beginFill( 0, 1 );
g.drawRoundRect( 0,0,w,h, cornerRadius, cornerRadius );
}

protected function renderSegment( from : Point, to : Point ) : void
{
var g : Graphics = drawSurface.graphics;
g.lineStyle( strokeSize, strokeColor, 1 );
g.moveTo( from.x, from.y );
g.lineTo( to.x, to.y );
}
}
}[/as3]


The HTML5/PhoneGap Solution

The main user interface for the HTML5/PhoneGap solution is also a simple UI with some form elements. In that UI there is a Canvas element that is used to render the signature. I created a SignatureCapture JavaScript class that encapsulates all logic for capturing the user signature. In browsers that support touch events (mobile browsers), this is based on the touchstart, touchmove and touchend events. In browsers that don’t support touch (aka desktop browsers), the signature input is based on mousedown, mousemove and mouseup events. The component captures input based on touch or mouse events, and that input is used to manipulate the graphics content of the Canvas tag instance. The canvas tag also supports a drawing API that is similar to the ActionScript drawing API. To read up on Canvas programmatic drawing basics, check out the tutorials at http://www.adobe.com/devnet/html5/html5-canvas.html

When the form is submitted, the graphical content is converted to a base-64 encoded string using the Canvas’s toDataURL() method. The toDataURL() method returns a base-64 encoded string value of the image content, prefixed with “data:image/png,”. Since I’ll be passing this back to the server, I don’t need this prefix, so it is stripped, then sent to the server for content within the email.

You can check out a browser-based version of this using the HTML5 Canvas in action at http://tricedesigns.com/portfolio/sigCapture/ – Again, just enter a valid email address and use your mouse to sign within the signature area. When this is submitted, it will send an email to you containing the signature. However, this example requires that your browser supports the HTML5 Canvas tag.

You can check out the SignatureCapture code below, or check out the full project at https://github.com/triceam/Mobile-Signature-Capture/tree/master/html%20client. This class will also work in desktop browser applications that support the HTML5 canvas. I used Modernizr to determine whether touch events are supported within the client container (PhoneGap or desktop browser). The main application workflow is within application.js.

Also a note for Android users, the Canvas toDataURL() method does not work in Android versions earlier than 3.0. However, you can implement your own toDataURL() method for use in older OS versions using the technique in this link: http://jimdoescode.blogspot.com/2011/11/trials-and-tribulations-with-html5.html (I did not update this example to support older Android OS versions.)

[js]function SignatureCapture( canvasID ) {
this.touchSupported = Modernizr.touch;
this.canvasID = canvasID;
this.canvas = $("#"+canvasID);
this.context = this.canvas.get(0).getContext("2d");
this.context.strokeStyle = "#000000";
this.context.lineWidth = 1;
this.lastMousePoint = {x:0, y:0};

this.canvas[0].width = this.canvas.parent().innerWidth();

if (this.touchSupported) {
this.mouseDownEvent = "touchstart";
this.mouseMoveEvent = "touchmove";
this.mouseUpEvent = "touchend";
}
else {
this.mouseDownEvent = "mousedown";
this.mouseMoveEvent = "mousemove";
this.mouseUpEvent = "mouseup";
}

this.canvas.bind( this.mouseDownEvent, this.onCanvasMouseDown() );
}

SignatureCapture.prototype.onCanvasMouseDown = function () {
var self = this;
return function(event) {
self.mouseMoveHandler = self.onCanvasMouseMove()
self.mouseUpHandler = self.onCanvasMouseUp()

$(document).bind( self.mouseMoveEvent, self.mouseMoveHandler );
$(document).bind( self.mouseUpEvent, self.mouseUpHandler );

self.updateMousePosition( event );
self.updateCanvas( event );
}
}

SignatureCapture.prototype.onCanvasMouseMove = function () {
var self = this;
return function(event) {

self.updateCanvas( event );
event.preventDefault();
return false;
}
}

SignatureCapture.prototype.onCanvasMouseUp = function (event) {
var self = this;
return function(event) {

$(document).unbind( self.mouseMoveEvent, self.mouseMoveHandler );
$(document).unbind( self.mouseUpEvent, self.mouseUpHandler );

self.mouseMoveHandler = null;
self.mouseUpHandler = null;
}
}

SignatureCapture.prototype.updateMousePosition = function (event) {
var target;
if (this.touchSupported) {
target = event.originalEvent.touches[0]
}
else {
target = event;
}

var offset = this.canvas.offset();
this.lastMousePoint.x = target.pageX – offset.left;
this.lastMousePoint.y = target.pageY – offset.top;

}

SignatureCapture.prototype.updateCanvas = function (event) {

this.context.beginPath();
this.context.moveTo( this.lastMousePoint.x, this.lastMousePoint.y );
this.updateMousePosition( event );
this.context.lineTo( this.lastMousePoint.x, this.lastMousePoint.y );
this.context.stroke();
}

SignatureCapture.prototype.toString = function () {

var dataString = this.canvas.get(0).toDataURL("image/png");
var index = dataString.indexOf( "," )+1;
dataString = dataString.substring( index );

return dataString;
}

SignatureCapture.prototype.clear = function () {

var c = this.canvas[0];
this.context.clearRect( 0, 0, c.width, c.height );
}[/js]


Source for the ColdFusion server, as well as Flex/AIR and HTML5/PhoneGap clients is available at: https://github.com/triceam/Mobile-Signature-Capture

Flex 4.6 is Available AND I’m on TV!

(Adobe TV, that is)

In case you had not seen on the Flex team blog, twitter or through some other medium, Flex SDK 4.6 and Flash Builder 4.6 were released today!  Go get them, if you have not done so already.  Flex 4.6 marks a huge advancement for the Flex SDK, especially regarding mobile applications.

Flash Builder 4.6 is a FREE update for Flash Builder 4.5 users. From the Flex team blog:

A lot is included in this update, so much so that we couldn’t deliver it in the Adobe Application Manager. This means Flash Builder 4.5 users won’t automatically be notified about the update and will have to download the full Flash Builder 4.6 installer and enter their Flash Builder 4.5 serial number.

You can download the open source Flex SDK at: http://opensource.adobe.com/wiki/display/flexsdk/Download+Flex+4.6.

Or, you can download Flash Builder 4.6 from: https://www.adobe.com/cfusion/tdrc/index.cfm?product=flash_builder.  Flash Builder 4.6 release notes are available at http://kb2.adobe.com/cps/921/cpsid_92180.html

Note: you must uninstall Flash Builder 4.5.1 to install Flash Builder 4.6.  

You can read specifics about what’s new in Flash Builder 4.6 on the Adobe Developer Connection at: http://www.adobe.com/devnet/flash-builder/articles/whatsnew-flashbuilder-46.html, and what’s new in Flex SDK 4.6 at: http://www.adobe.com/devnet/flex/articles/introducing-flex46sdk.html

Coinciding with the Flex & Flash Builder releases, new content around Flex and Flash Builder 4.6 have been posted on Adobe TV.   There is a bunch of great new content worth checking out, including fellow evangelist Michael Chaize’s adaptive UI for different platforms and device form factors.   In addition, here I am speaking out the new Captive Runtime feature introduced in AIR 3…

Captive Runtime for Mobile

Captive Runtime for Desktop

More on the Future of Flex & Flash

Late last week, Adobe released official statements and a FAQ to address the recent confusion around the Flex, the Flash/AIR platforms and mobile.    You can read the official statement at:

http://www.adobe.com/devnet/flashplatform/articles/recent-updates.html

You can read the FAQ at:

http://www.adobe.com/devnet/flex/articles/flex-announcements.html

Here are a few excerpts from the official statement:

Adobe Flash Player on desktop
Adobe reaffirmed its commitment to the Adobe Flash Player in desktop browsers, and its role of enabling functionality on the web that is not otherwise possible. Flash Player 11 for PC browsers just introduced dozens of new features, including hardware accelerated 3D graphics for console-quality gaming and premium HD video with content protection.

Adobe AIR for mobile
Adobe reaffirmed its commitment to Adobe AIR for mobile devices, which allows developers and designers to create standalone applications using Adobe Flash technologies that can be deployed across mobile operating systems, including Apple iOS, Google Android and RIM BlackBerry Tablet OS.

Adobe AIR for desktop
Adobe reconfirmed its commitment for its continued support for Adobe AIR applications running on the desktop. Adobe is actively working on the next version of Adobe AIR for the desktop.

Adobe Flex
Adobe announced its intention to contribute the Adobe Flex SDK open source project to the Apache Software Foundation for future governance.

No, Flex & Flash Are Not Dead

Last week Adobe announced information about the company’s evolution and future plans of Flex. It was also announced that Adobe Flex would be contributed to an open source software foundation. The result of which, was mass speculation, fear, uncertainty, and doubt.   Rest assured, Flash is not dead, nor is Flex.

Andrew and Deepa from the Flex team have posted some questions and answers raised by these conversations. I highly recommend reading these in their entirety, as they will answer a lot of the questions about the future of Flex. Key takeaways:

Is Adobe still committed to Flash Builder?

Yes. Flash Builder will continue to be developed and Adobe will work to ensure Flex developers can use Flash Builder as their development tool with future releases of Flex SDK.

Will Adobe continue to support customers using Flex?

Yes. Adobe will continue to honor existing Flex support contracts.

What specifically is Adobe proposing?

We are preparing two proposals for incubating Flex SDK and BlazeDS at the Apache Software Foundation.

In addition to contributing the core Flex SDK (including automation and advanced data visualization components), Adobe also plans to donate the following:

  • Complete, but yet-to-be-released, Spark components, including ViewStack, Accordion, DateField, DateChooser and an enhanced DataGrid.
  • BlazeDS, the server-based Java remoting and web messaging technology that enables developers to easily connect to back-end distributed data and push data in real-time to Flex applications.
  • Falcon, the next-generation MXML and ActionScript compiler that is currently under development (this will be contributed when complete in 2012)
  • Falcon JS, an experimental cross-compiler from MXML and ActionScript to HTML and JavaScript.
  • Flex testing tools, as used previously by Adobe, so as to ensure successful continued development of Flex with high quality

Isn’t Adobe just abandoning Flex SDK and putting it out to Apache to die? 

Absolutely not – we are incredibly proud of what we’ve achieved with Flex and know that it will continue to provide significant value for many years to come. We expect active and on-going contributions from the Apache community. To be clear, Adobe plans on steadily contributing to the projects and we are working with the Flex community to make them contributors as well.

Flex has been open source since the release of Flex 3 SDK. What’s so different about what you are announcing now?

Since Flex 3, customers have primarily used the Flex source code to debug underlying issues in the Flex framework, rather than to actively develop new features or fix bugs and contribute them back to the SDK.

With Friday’s announcement, Adobe will no longer be the owner of the ongoing roadmap. Instead, the project will be in Apache and governed according to its well-established community rules. In this model, Apache community members will provide project leadership. We expect project management to include both Adobe engineers as well as key community leaders. Together, they will jointly operate in a meritocracy to define new features and enhancements for future versions of the Flex SDK. The Apache model has proven to foster a vibrant community, drive development forward, and allow for continuous commits from active developers.

What guarantees can Adobe make in relation to Flex applications continuing to run on Flash Player and Adobe AIR?

Adobe will continue to support applications built with Flex, as well as all future versions of the SDK running in PC browsers with Adobe Flash Player and as mobile apps with Adobe AIR indefinitely on Apple iOS, Google Android and RIM BlackBerry Tablet OS.

http://blogs.adobe.com/flex/2011/11/your-questions-about-flex.html

Adobe’s Mike Chambers has also posted information explaining a bit more detail, and providing insight into the future of Flash and AIR.   Key takeaways:

Adobe AIR

We are continuing to develop Adobe AIR for both the desktop and mobile devices. Indeed, we have seen wide adoption of Adobe AIR for creating mobile applications and there have been a number of blockbuster mobile applications created using Adobe AIR.

Flash Player for Desktop Browsers

We feel that Flash continues to play a vital role of enabling features and functionality on the web that are not otherwise possible. As such, we have a long term commitment to the Flash Player on desktops, and are actively working on the next Flash Player version.

http://www.mikechambers.com/blog/2011/11/11/clarifications-on-flash-player-for-mobile-browsers-the-flash-platform-and-the-future-of-flash/