⬆️ ⬇️

We attach Flex-components to the project on a clean Actionscript

Introduction



This article is intended more for beginners who have just begun to create FlashPlayer applications using only free development tools, and can be considered as a mini-tutorial on this topic, telling about my personal rake, which I sincerely wish not to step on the same way as I mastering programming in ActionScript.



As an example, HelloWorld will be used rather simple project, written in pure ActionScript 3.0 without using commercial development tools from Adobe.

I develop FlashPlayer applications using FlashDevelop on Windows, and vim (less convenient, but cheap and cheerful) on GNU / Linux.



Naturally, flex3 sdk is needed both there and there, which contains mxmlc - a compiler that accepts * .mxml (flex-layout) or * .as (actionscript) as input - and creates a swf file - an application for FlashPlayer 9/10 (the version is configured in the compiler configuration) output. The latter is a bytecode executed by the FlashPlayer or Adobe AIR virtual machine.



Task



As promised, consider a simple example.

So suppose we conceived to write an interactive flash application that should allow the user to draw colored rectangles, drag them and set their color (see the figure).

image

The color change is the second part of the task, and since the bar for entry into ActionScript3 is extremely low, we sit down and within the hour (or a couple of hours maximum) we code the first part, i.e. drawing and dragging rectangles. The result comes down to two classes: RectContainer and Rect. In the code, you can look at the simplest examples of implementing event handling, drawing graphics, dragging objects. The main file is RectContainer.as - it should be pushed into the mxmlc compiler or marked as Always Compile in the project tree in the FlashDevelop IDE.

')

RectContainer.as:


package {

import flash.events.*;

import flash.display.*;

public class RectContainer extends Sprite {

private var currentRect:Rect;

public var isDragging:Boolean;



public function RectContainer() {

stage.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);

stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);

stage.addEventListener(MouseEvent.MOUSE_UP,onMouseUp);

stage.scaleMode = StageScaleMode.NO_SCALE;

stage.addChild(this);

}



private function onMouseDown(evt:MouseEvent):void {

if (!isDragging) {

currentRect = new Rect();

currentRect.container = this;

currentRect.x = evt.stageX;

currentRect.y = evt.stageY;

addChild(currentRect);

}

}



private function onMouseUp(evt:MouseEvent):void {

if (null != currentRect) {

currentRect = null;

}

}



private function onMouseMove(evt:MouseEvent):void {

if (evt.buttonDown && !isDragging) {

var dX:Number = evt.stageX - currentRect.x;

var dY:Number = evt.stageY - currentRect.y;

if (dX>0 && dY>0)

currentRect.draw(dX,dY);

}

}



}

}





Rect.as:


package {

import flash.events.*;

import flash.display.*;

public class Rect extends Sprite {

public var color:uint = 0xff00ff;

public var container:RectContainer;



public function Rect() {

addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);

addEventListener(MouseEvent.MOUSE_UP,onMouseUp);

addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);

}



public function draw(width:int,height:int):void {

graphics.clear();

graphics.lineStyle(1);

graphics.beginFill(color);

graphics.drawRect(0,0,width,height);

graphics.endFill();

}



private function onMouseMove(evt:MouseEvent):void {



}



private function onMouseUp(evt:MouseEvent):void {

this.stopDrag();

container.isDragging = false;

}



private function onMouseDown(evt:MouseEvent):void {

container.isDragging = true;

this.startDrag();

}

}

}





The more difficult part of the task is to make the choice of color possible. Naturally you need a small component, allowing the user to interactively choose a color. After a brief googling, it becomes clear that it’s not so easy for us to download a light, simple and free ColorPicker, but we know that there is a Flex framework containing, among other things, what we need - a component of ColorPicker. The task is seemingly simple: screw the ColorPicker to our project.



Search solutions



1. Solution to the forehead


Immediately try the obvious way: we try to create an instance of this component directly in the Rect constructor.



import mx.controls.ColorPicker;

...

var colorPicker:ColorPicker = new ColorPicker();

addChild(colorPicker);





and when creating the next rectangle, contrary to expectations, there is no visual indication of the appearance of the color-picker.

After a hard googling, it becomes clear that the standard use case for Flex components is static positioning in an interactive form that contains other Flex components and is expressed by mxml markup. This way of solution does not suit us, since we even do not want to see any static mxml form in the project.



2. It took another half an hour googling


It was naturally initially clear that each tag describing an instance of a Flex component in mxml corresponds to a certain class in the Flex framework, but it’s just not clear how to use them in pure ActionScript. Adobe states only that this is certainly possible, but it doesn’t explain, because apparently it is not commercially profitable, why then Flex Builder, etc.? There are also bloggers who have thought closely about this issue and even created a few examples using Flex-like button components, which I honestly couldn’t use for the color picker.



3. And the casket just opened


So in Google-Despair, I came across somewhere (sorry, I lost this link, but I think the technique is common and is quoted in many sources), creating an mx: Application container using the simplest mxml and then dynamically creating objects inside this container using the ActionScript class hung on the applicationComplete event.



Looking at the class hierarchy for mx.core.UIComponent, it becomes clear that they inherit from flash.display.Sprite and overload the addChild method, and our “solution to the forehead” becomes obvious at once — for how you can add the Flex component ColorPicker by child of a simple Sprite, not a UIComponent, which is higher in the inheritance hierarchy. So, the solution (see the code below) is to create the simplest FlexContainer.mxml file, which we, by the way, will now add to the mxml compiler. FlexMain.main () is a method that adds to our container an instance of the RectContainer class, which, like Rect, is now inherited from the UIComponent, and not from Sprite, and accordingly the stage object in the RectContainer constructor is taken directly from the Application instance. application. Now ColorPicker is added as a native to our rectangles and moves along with them with a bang.



FlexContainer.mxml:


<?xml version="1.0" encoding="utf-8"?>

<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml"

layout="absolute" applicationComplete="FlexMain.main()">

</mx:Application>





FlexMain.as:


package {

import mx.controls.*;

import mx.core.*;

public class FlexMain {

public static function main ():void {

Application.application.addChild(new RectContainer());

}

}

}





RectContainer.as:


package {

import flash.events.*;

import flash.display.*;

import mx.core.Application;

import mx.core.UIComponent;

public class RectContainer extends UIComponent {

private var currentRect:Rect;

public var isDragging:Boolean;



public function RectContainer() {

var stage:Stage = Application.application.stage;

stage.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);

stage.addEventListener(MouseEvent.MOUSE_DOWN, onMouseDown);

stage.addEventListener(MouseEvent.MOUSE_UP,onMouseUp);

stage.scaleMode = StageScaleMode.NO_SCALE;

stage.addChild(this);

}

// RectContainer.as





Rect.as:


package {

import flash.events.*;

import flash.display.*;

import mx.core.UIComponent;

import mx.controls.ColorPicker;

import mx.events.ColorPickerEvent;



public class Rect extends UIComponent {

public var color:uint = 0xff00ff;

public var container:RectContainer;

public var colorPicker:ColorPicker = new ColorPicker();

public var _width:Number;

public var _height:Number;



public function Rect() {

addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);

addEventListener(MouseEvent.MOUSE_UP,onMouseUp);

addEventListener(MouseEvent.MOUSE_DOWN,onMouseDown);

colorPicker.visible = false;

colorPicker.x = 0;

colorPicker.y = 0;

colorPicker.selectedColor = color;

addChild(colorPicker);

colorPicker.addEventListener(ColorPickerEvent.CHANGE,onColorChanged);

}



public function draw(width:int,height:int):void {

_width = width;

_height = height;

graphics.clear();

graphics.lineStyle(1);

graphics.beginFill(color);

graphics.drawRect(0,0,_width,_height);

graphics.endFill();

const minSize:Number = 15;

if (width>minSize && height > minSize) {

colorPicker.visible = true;

colorPicker.setActualSize(minSize,minSize);

}

}



private function onMouseMove(evt:MouseEvent):void {



}



private function onMouseUp(evt:MouseEvent):void {

this.stopDrag();

container.isDragging = false;

}



private function onMouseDown(evt:MouseEvent):void {

container.isDragging = true;

this.startDrag();

}



private function onColorChanged(evt:ColorPickerEvent):void {

color = evt.color;

draw(_width,_height);

}

}

}





All code and compiled applications can be downloaded here :



Thanks for reading, I hope the article was helpful.

Source: https://habr.com/ru/post/91468/



All Articles