Entries tagged with “mxp”.


Bienvenidos, en esta ocasión retomaremos el tema de los Paneles pero enfocado a su creación mediante Adobe Flex.

Antes o después de leer este tutorial sería interesante leer el este otro post sobre la introducción a la creación de Paneles.

INTRODUCCIÓN

La idea es crear un panel que nos ayude a modificar el fondo del documento FLA, pero más rápidamente, si, sé que cambiar el fondo del documento es muy fácil, pero soy un poco maniático y la verdad tener que abrir una ventana, seleccionar un color y luego dar click en aceptar son muchos pasos, me gustaría algo mucho más rápido, algo como hacer rollOver sobre un componente ColorPicker y listo.

DESARROLLO

Para ejecutar código JSFL en una película swf generada con Flex utilizaremos el método MMExecute que encontramos en el paquete adobe.utils por ejemplo:

import adobe.utils.MMExecute;
MMExecute("jsfl code");

El método MMExecute recibe un parámetro de tipo String en el cual indicaremos el código JSFL que deseamos ejecutar. Además devuelve un valor también de tipo String que es la representación en cadena del resultado de la ejecución del código.

Parte JSFL

Vale, ahora que sabemos como ejecutar código JSFL necesitamos saber que código ejecutar. Lo que queremos modificar es una propiedad del documento FLA, así es que antes que otra cosa debemos obtener una referencia al documento, esto lo hacemos con el siguiente código:

var oDoc = fl.getDocumentDOM();

Y para acceder y modificar el color de fondo utilizamos la propiedad backgroundColor que es de lectura y escritura:

oDoc.backgroundColor

Listo, por lo menos la parte de JSFL, ahora tenemos que integrar este código en una aplicación Flex.

Parte FLEX

Utilizaremos un componente ColorPicker este componente entre otras cosas emite los eventos:

  • change
  • close
  • itemRollOver
  • itemRollOut
  • open

Los que en nuestro caso nos interesan son los eventos change e itemRollOver así que como en cualquier otra aplicación utilizamos el siguiente código:

<mx:ColorPicker id="cpBackgroundColor" x="89" y="10" change="onChange(event);" itemRollOver="onItemRollOver(event);" />

Ahora simplemente en los métodos onChange y onItemRollOver es donde tendremos que utilizar el método MMExecute de la siguiente manera:

import mx.events.ColorPickerEvent;
import adobe.utils.MMExecute;

private function onChange(_oEvent:ColorPickerEvent):void
{
    if (this.isDocumentExists())
        MMExecute("fl.getDocumentDOM().backgroundColor = Number(" + _oEvent.color + ");");
}

private function onItemRollOver(_oEvent:ColorPickerEvent):void
{
    if (this.isDocumentExists())
        MMExecute("fl.getDocumentDOM().backgroundColor = Number(" + _oEvent.color + ");");
}

private function isDocumentExists():Boolean
{
    var ret:Boolean = false;
    if (MMExecute("fl.getDocumentDOM();") != "null")
        ret = true;

    return ret;
}

INSTALACIÓN

Listo, el resultado no lo podremos ver en ejecución a menos que llevemos el swf resultante a la carpeta de Paneles de Flash, es decir al directorio WindowSWF dentro del directorio Configuration de la instalación.

Según el sistema operativo:

Windows® VistaTM:

  • unidad de arranque\Users\nombre de usuario\Local Settings\Application Data\Adobe\Flash

CS4\idioma\Configuration\

Windows XP:

  • unidad de arranque\Documents and Settings\nombre de usuario\Local Settings\Application Data\Adobe\Flash CS4\idioma\Configuration\

Mac OS® X:

  • Macintosh HD/Usuarios/nombre de usuario/Librería/Application Support/Adobe/Flash

CS4/idioma/Configuration/

EJECUCIÓN

Para ejecutar el Panel debemos acceder al menú Ventana -> Otros paneles -> Change Background Color a continuación un ejemplo de como ejecutar y su funcionamiento:

Ver ejemplo

DESCARGAS

Como es habitual a continuación podéis descargar los fuentes y el instalador del Panel:

  • Fichero MXML de Flex por si te interesa ver el código.
  • Fichero SWF del Panel para instalar manualmente el Panel.
  • Instalador MXP del Panel para instalar automáticamente la extensión.

Saludos, cualquier duda o comentario será bienvenido.

Entradas relacionadas

lego briks

Este es un post que tenía pendiente desde hace tiempo, en esta ocasión voy a hablar sobre las herramientas (tools) de Flash y de como personalizarlas o como es nuestro caso crear una nueva herramienta con JSFL.

INTRODUCCIÓN

Recuerdo en los tiempos de Flash 4 que fué cuando empecé con Flash que por comodidad y sobre todo por desconocimiento de la aplicación, quería hacer tablas en Flash y por mucho que busqué no encontré una herramienta que me sirviera para esto, así que al final aprendí a utilizar las herramientas de dibujo y a través de cuadros y líneas con las herramientas rectángulo y trazo conseguí hacer las tablas que quería, luego con el tiempo descubrí el panel alineación y distribución y con eso perfeccioné la tarea y me fué más fácil hacer estas tablas.

Bueno, pues la idea es que vamos a crear una herramienta para crear tablas de una manera fácil como si de rectángulos se tratara.

DESARROLLO

JSFL nos permite extender la funcionalidad de la aplicación, como hemos hablado ya en otras ocasiones, lo podemos hacer con comandos y paneles, pero también existe otro modo de extender y automatizar procesos, me refiero a la creación de herramientas.

Las herramientas al igual que los comandos y paneles se programan con JSFL y se almacenan en las siguiente rutas respectivamente por sistema operativo:

  • Windows Vista

unidad de arranque\Users\nombre de usuario\Local Settings\Application Data\Adobe\Flash

CS4\idioma\Configuration\Tools

  • Windows XP

unidad de arranque\Documents and Settings\usuario\Local Settings\Application Data\Adobe\Flash

CS4\idioma\Configuration\Tools

  • Mac OS X

Macintosh HD/Usuarios/nombre de usuario/Librería/Application Support/Adobe/Flash

CS4/idioma/Configuration/Tools

A diferencia de los comandos y los paneles en las herramientas tenemos acceso a funciones y métodos de nivel superior que nos ayudan a desarrollar y controlar el estado de nuestra herramienta, las funciones disponibles son las siguiente:

  • activate()
  • configureTool()
  • deactivate()
  • keyDown()
  • keyUp()
  • mouseDoubleClick()
  • mouseDown()
  • mouseMove()
  • mouseUp()
  • notifySettingsChanged()
  • setCursor()

Las que utilizaremos para la creación de la herramienta tablas serán, activate que se dispara cuando la herramienta es seleccionada por el usuario, deactivate que se dispara cuando el usuario cambia a otra herramienta, notifySettingsChanged que se dispara cuando el usuario modifica las propiedades de nuestra herramienta, mouseDownmouseMove mouseUp que se disparan cuando el usuario hace lo que el nombre de la función dice :D. Esto con respecto a los eventos para controlar nuestra herramienta.

Pero ¿cómo accedemos a la herramienta?

Pues fácil, como todo en JSFL son objetos necesitamos obtener la referencia a la herramienta activa que será nuestra herramienta, esto lo hacemos con la propiedad activeTool del objeto tools, en el ejemplo siguiente se muestra como obtener una referencia a la herramienta.

theTool = fl.tools.activeTool;

Guay, ¿Y para qué quiero tener una referencia al objeto herramienta?

Pues para asignar a nuestra herramienta nombre, tooltip, icono, opciones, especificar el tipo para el inspector de propiedades por ejemplo y muchas más cosas. Como se muestra a continuación.

// Set the standard tool information
theTool = fl.tools.activeTool;
theTool.setToolName("Tablas");
theTool.setIcon("Tablas.png");
theTool.setMenuString("Herramienta Tablas");
theTool.setToolTip("Herramienta Tablas");
theTool.setOptionsFile("Tablas.xml");

// This tool uses the Shape property inspector
theTool.setPI( "shape" );

Vale, vale, ya me entero, pero ¿Cómo dibujo?

Ah, muy cierto, pues para pintar / dibujar debemos hacer una nota importante y es que tenemos dos momento de dibujo:

  • El momento de la previsualización
  • El momento del dibujo final

Para el momento de la pre-visualización utilizaremos el objeto drawingLayer y sus métodos moveTo y lineTo que son idénticos a los que utilizamos en la API de dibujo de ActionScript y los método beginFrame y endFrame para indicar el incio y el fin del dibujo de la pre-visualización. Por ejemplo, con el siguiente código dibujaríamos un cuadro de 20×20 en 0, 0:

fl.drawingLayer.beginFrame();
fl.drawingLayer.moveTo(0, 0);
fl.drawingLayer.lineTo(20, 0);
fl.drawingLayer.lineTo(20, 20);
fl.drawingLayer.lineTo(0, 20);
fl.drawingLayer.lineTo(0, 0);
fl.drawingLayer.endFrame();

Y para el momento del dibujo final utilizaremos también el objeto drawingLayer para crear un objeto path con el método newPath, luego utilizaremos los métodos addPoint y makeShape para crear nuestro dibujo. Por ejemplo:

var myPath = fl.drawingLayer.newPath();
myPath.addPoint(0, 20);
myPath.addPoint(20, 20);
myPath.addPoint(20, 0);
myPath.addPoint(0, 0);
myPath.makeShape(false, true);

Perfecto, y ahora ¿cómo modifico las propiedades de mi herramienta?

Vale, para esto debemos recordar que en un principio utilizamos el método setOptionsFile del objeto tool donde indicamos un fichero xml, este fichero xml contiene la definición de las propiedades que utilizaremos en la herramienta. Por ejemplo para la herramienta tabla, utilizo dos propiedades nColumns y nRows. Un ejemplo del fichero xml de configuración es el siguiente:

property name="Columnas: " variable="nColumns" min="1" max="100" defaultValue="3" type="Number"
property name="Filas: " variable="nRows" min="1" max="100" defaultValue="3" type="Number"

Cuando el usuario modifique estos valores en el panel de propiedades se nos notificará en el evento (la función) notifySettingsChanged. Un ejemplo de como utilizar los valores modificados es el siguiente:

function notifySettingsChanged()
{
	var theTool = fl.tools.activeTool;

	this.nColumns = theTool.nColumns;
	this.nRows = theTool.nRows;
}

Y listo, con esto ya tenemos controladas todas las fases del diseño de una herramienta.

EJEMPLOS

A continuación un par de ejemplos de lo que podemos conseguir de una manera sencilla con esta herramienta.

Ejemplo 1 Herramienta Tablas

Ejemplo 2 Herramienta Tablas

herramienta tablas

DESCARGAS

Tenemos dos tipos de descargas, para instalar simplemente la herramienta Tablas y para descargar el JSFL:

  • Extensión Herramienta Tablas (instalador mxp).
  • Paquete zip con la Herramienta Tablas (ficheros jsfl, xml y png).

INSTALACIÓN

Una vez que se haya instalado la extensión debemos asignarla a un grupo de herramienta desde el panel Personalizar panel de herramientas y listo ya se puede utilizar.

Personalizar panel herramientas

Dudas, sugerencias o comentarios, aquí estaré.

Saludos.

Entradas relacionadas

marquesina lego jsfl

Desde siempre me han llamado la atención las marquesinas. Quizá por las veo muy habitualmente en el tren que viajo todos los días para ir de la casa al trabajo y del trabajo a casa, aunque ya desde mucho antes me gustaban.

NOTA
Puede ser interesante leer antes o después este otro post de Introducción a Comandos para saber qué son, dónde van y cómo funcionan.

INTRODUCCIÓN

Bueno, pues con esa idea en la cabeza se me ocurrió hacer un comando que en si mismo no tiene una utilidad claro, sino más bien abstracta o artística, pero que me viene muy bien para explicar el Objeto Timeline de JSFL.

El comando Escribir palabra no tiene una utilidad clara, es decir, no se creó con el fin de resolver un problema, sencillamente se hizo porque una tarde con una visión muy al estilo matrix (puede ser por la película o por una matriz) y con la nostalgia de las marquesinas de leds en la mente (quizá influenciado por las pantallas de los trenes de cercanías), si hizo.

TUTORIAL

Primero utilizaremos el objeto Document para acceder a su biblioteca (library), creamos y editamos un MovieClip en ella y por último acceder a su línea de tiempo (Timeline).

var oDoc;
var oLib;
var oTimeline;

this.oDoc = fl.getDocumentDOM();
this.oLib = this.oDoc.library;
this.oLib.addNewItem("movie clip", "Nombre_MovieClip");
this.oLib.editItem("Nombre_MovieClip");
this.oTimeline = this.oDoc.getTimeline();

Una vez que tenemos una referencia al objeto Timeline podremos utilizar sus métodos y propiedades, en este caso vamos a utilizar el método addNewLayer para agregar tantas capas como necesitemos.

this.oTimeline.addNewLayer();

Luego seleccionamos los fotogramas con los que vamos a trabajar, esto lo hacemos con el método setSelectedFrames y los convertimos en fotogramas clave:

this.oTimeline.setSelectedFrames(INICIO, FIN, REMPLAZAR_SELECCIÓN);
this.oTimeline.convertToKeyframes();

Y listo lo siguiente es simplemente ir creando algo en cada fotograma en función de un patrón para que la línea de tiempo tenga forma. Una forma sencilla de hacer esto es dibujando un círculo en el escenario, de esta manera el fotograma dejará de estar vacío, para dibujar el círculo utilizamos el método addNewOval del objeto Document:

this.oDoc.addNewOval({left:0, top:0, right:10, bottom:10});

El resultado al que queremos llegar es el que se muestra en la siguiente imagen.

Quizá sea mejor verlo desde lejos, porque muy cerca de la pantalla cuesta un poco leerlo.

flash timeline jsfl

El código completo es el siguiente:

var oDoc;
var oLib;
var oTimeline;
var aLetters;
var aWord;

this.config();

function config()
{
	fl.showIdleMessage(false);
	fl.outputPanel.clear();

	if(fl.getDocumentDOM())
	{
		this.oDoc = fl.getDocumentDOM();
		this.oLib = this.oDoc.library;

		this.init();
	}
	else
	{
		alert("Debes tener un documento abierto.");
	}
}

function init()
{
	this.configLetters();
	this.configWord();

	var nTotalLetters = this.aWord.length;
	for(var i = 0; i < nTotalLetters; i++)
	{
		this.createLetter(this.aWord[i], i * 6);
	}
}

function configLetters()
{
	this.aLetters = new Array();

	this.aLetters[" "] = "0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0|0,0,0,0,0";
	this.aLetters["A"] = "0,1,1,1,0|1,0,0,0,1|1,0,0,0,1|1,1,1,1,1|1,0,0,0,1|1,0,0,0,1|1,0,0,0,1";
	this.aLetters["B"] = "1,1,1,1,0|1,0,0,0,1|1,0,0,0,1|1,1,1,1,0|1,0,0,0,1|1,0,0,0,1|1,1,1,1,0";
	this.aLetters["C"] = "0,1,1,1,0|1,0,0,0,1|1,0,0,0,0|1,0,0,0,0|1,0,0,0,0|1,0,0,0,1|0,1,1,1,0";
	this.aLetters["D"] = "1,1,1,1,0|1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|1,1,1,1,0";
	this.aLetters["E"] = "1,1,1,1,1|1,0,0,0,0|1,0,0,0,0|1,1,1,1,0|1,0,0,0,0|1,0,0,0,0|1,1,1,1,1";
	this.aLetters["F"] = "1,1,1,1,1|1,0,0,0,0|1,0,0,0,0|1,1,1,1,0|1,0,0,0,0|1,0,0,0,0|1,0,0,0,0";
	this.aLetters["G"] = "0,1,1,1,0|1,0,0,0,1|1,0,0,0,0|1,0,1,1,1|1,0,0,0,1|1,0,0,0,1|0,1,1,1,0";
	this.aLetters["H"] = "1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|1,1,1,1,1|1,0,0,0,1|1,0,0,0,1|1,0,0,0,1";
	this.aLetters["I"] = "0,1,1,1,0|0,0,1,0,0|0,0,1,0,0|0,0,1,0,0|0,0,1,0,0|0,0,1,0,0|0,1,1,1,0";
	this.aLetters["J"] = "0,0,0,0,1|0,0,0,0,1|0,0,0,0,1|0,0,0,0,1|0,0,0,0,1|1,0,0,0,1|0,1,1,1,0";
	this.aLetters["K"] = "1,0,0,0,1|1,0,0,1,0|1,0,1,0,0|1,1,0,0,0|1,0,1,0,0|1,0,0,1,0|1,0,0,0,1";
	this.aLetters["L"] = "1,0,0,0,0|1,0,0,0,0|1,0,0,0,0|1,0,0,0,0|1,0,0,0,0|1,0,0,0,0|1,1,1,1,1";
	this.aLetters["M"] = "1,0,0,0,1|1,1,0,1,1|1,0,1,0,1|1,0,1,0,1|1,0,0,0,1|1,0,0,0,1|1,0,0,0,1";
	this.aLetters["N"] = "1,0,0,0,1|1,0,0,0,1|1,1,0,0,1|1,0,1,0,1|1,0,0,1,1|1,0,0,0,1|1,0,0,0,1";
	this.aLetters["O"] = "0,1,1,1,0|1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|0,1,1,1,0";
	this.aLetters["P"] = "1,1,1,1,0|1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|1,1,1,1,0|1,0,0,0,0|1,0,0,0,0";
	this.aLetters["Q"] = "0,1,1,1,0|1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|1,0,0,1,1|0,1,1,1,1";
	this.aLetters["R"] = "1,1,1,1,0|1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|1,1,1,1,0|1,0,0,1,0|1,0,0,0,1";
	this.aLetters["S"] = "0,1,1,1,0|1,0,0,0,1|1,0,0,0,0|0,1,1,1,0|0,0,0,0,1|1,0,0,0,1|0,1,1,1,0";
	this.aLetters["T"] = "1,1,1,1,1|0,0,1,0,0|0,0,1,0,0|0,0,1,0,0|0,0,1,0,0|0,0,1,0,0|0,0,1,0,0";
	this.aLetters["U"] = "1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|0,1,1,1,0";
	this.aLetters["V"] = "1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|0,1,0,1,0|0,1,0,1,0|0,0,1,0,0";
	this.aLetters["W"] = "1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|1,0,1,0,1|1,0,1,0,1|1,1,0,1,1|1,0,0,0,1";
	this.aLetters["X"] = "1,0,0,0,1|1,0,0,0,1|0,1,0,1,0|0,0,1,0,0|0,1,0,1,0|1,0,0,0,1|1,0,0,0,1";
	this.aLetters["Y"] = "1,0,0,0,1|1,0,0,0,1|1,0,0,0,1|0,1,0,1,0|0,0,1,0,0|0,0,1,0,0|0,0,1,0,0";
	this.aLetters["Z"] = "1,1,1,1,1|0,0,0,0,1|0,0,0,1,0|0,0,1,0,0|0,1,0,0,0|1,0,0,0,0|1,1,1,1,1";
}

function configWord()
{
	sWord = prompt("Escribe una palabra.");

	this.aWord = new Array();
	var nWordLength = sWord.length;
	for(var i = 0; i < nWordLength; i++)
	{
		this.aWord.push(sWord.substring(i, i + 1));
	}

	this.createTimeline(sWord);
}

function createTimeline(_sWord)
{
	var sWordLengthInFrames = _sWord.length * 6;
	this.oLib.addNewItem("movie clip", _sWord);
	this.oLib.editItem(_sWord);
	this.oTimeline = this.oDoc.getTimeline();
	this.oTimeline.setSelectedFrames(0, sWordLengthInFrames, true);
	this.oTimeline.convertToKeyframes();
	for(var i = 0; i < 6; i++)
	{
		this.oTimeline.addNewLayer();
		this.oTimeline.setSelectedFrames(0, sWordLengthInFrames, true);
		this.oTimeline.convertToKeyframes();
	}
}

function createLetter(_sLetter, _nStartFrame)
{
	var sConfigLetter = this.aLetters[_sLetter];
	if(sConfigLetter)
	{
		var aConfigLetter = sConfigLetter.split("|");
		for(var i = 0; i < 7; i++) aConfigLetter[i] = aConfigLetter[i].split(",");

		for(var i = 0; i < 7; i++)
		{
			for(var j = 0; j < 5; j++)
			{
				if(aConfigLetter[i][j] == "1")
				{
					this.oTimeline.setSelectedLayers(i);
					this.oTimeline.setSelectedFrames(_nStartFrame + j, _nStartFrame + j + 1, true);
					this.oDoc.addNewOval({left:0, top:0, right:10, bottom:10});
				}
			}
		}
	}
	else
	{
		alert("No existe el caracter: " + _sLetter);
	}
}

DESCARGAS

Tenemos dos tipos de descargas, para instalar simplemente el comando y para descargar el JSFL:

  • Extensión Escribir palabra (instalador mxp).
  • Comando Escribir palabra (fichero jsfl).

Dudas, sugerencias o comentarios, aquí estaré.

Saludos.

Entradas relacionadas

document fla backup

Esta es la primera entrega de un grupo de dos tutoriales sobre una misma tarea, guardar una copia del documento Fla con el que se esta trabajando pero sin perder el documento actual en el IDE de Flash.

Introducción

Me explico mejor, existe la opción de Guardar como, pero esta opción lo que hace es abrir el cuadro de diálogo donde nos permite especificar la ruta y nombre del documento Fla, al hacer clic el guardar el documento que se queda en edición en el IDE de Flash es el nuevo. Pero, ¿que pasa si quiero trabajar sobre el mismo fichero?, porque lo que realmente quería hacer era una copia del documento, pues que tenemos que cerrar el documento nuevo y abrir el original.

Bueno para esto sirve el comando que vamos a hacer en este tutorial. En el siguiente tutorial vamos a hacer lo mismo pero lo haremos con un panel para ver las ventajas de un sistema sobre el otro.

NOTA
Puede ser interesante leer antes o después este otro post de Introducción a Comandos para saber qué son, dónde van y cómo funcionan.

Tutorial

Para hacer la tarea de guardar una copia debemos primeramente guardar el documento en edición, esto lo hacemos mediante el método save del objeto Document,

fl.getDocumentDOM().save(true);

Una vez guardado el documento procedemos a realizar una copia, para esto hacemos uso del método copy del objeto FLfile, éste método recibe dos parámetros:

  • Origen: La ruta del fichero que deseamos copia.
  • Destino: La ruta del fichero resultante.

NOTA:

Es importante destacar que las rutas deben estar expresadas en  file:///

Ya que las rutas las debemos especificar mediante  file:/// haremos uso de una de las novedades de Flash CS4, me refiero a la propiedad pathURI del objeto Document ya que esta propiedad nos devuelve precisamente la ruta del documento Fla en edición expresda en file:///.

NOTA:

En caso de que el documento no haya sido guardado todavía el valor de la propiedad pathURI será udefined con lo que podemos controlar esa situación.

El código que utilizaremos para hacer la copia sería el siguiente:

FLfile.copy(fl.getDocumentDOM().pathURI, NUEVO_NOMBRE);

El caso de que la copia se realice con éxito el método copy nos devolverá true, en caso contrario devolverá false, con lo cual también podemos controlar esa situación para informar al usuario.

command save copy

A continuación en código completo del commando:

var oDoc;

this.config();

function config()
{
	fl.showIdleMessage(false);
	fl.outputPanel.clear();

	if(fl.getDocumentDOM())
	{
		this.oDoc = fl.getDocumentDOM();

		this.init();
	}
	else
	{
		alert("Debes tener un documento abierto.");
	}
}

function init()
{
	if(this.oDoc.pathURI)
	{
		this.oDoc.save(true);
		var bResult = FLfile.copy(this.oDoc.pathURI, this.oDoc.pathURI.split(".fla")[0] + "_back.fla");
		if(bResult)
		{
			alert("La copia se ha guardado correctamente.");
		}
		else
		{
			alert("Error al guardar la copia.");
		}
	}
	else
	{
		alert("El documento no ha sido guradado.\nPara crear una copia debes guardar antes el documento.");
	}
}

Descargas

Dudas, sugerencias o comentarios, aquí estaré.

Saludos.

Entradas relacionadas

Memoria USB Lego

Bienvenido querido lector a la sección de tutoriales en nomeva, en esta ocasión vamos a crear con Flash mediante JSFL y ActionScript un Panel que realice la tarea de guardar automáticamente el documento Fla en edición.

NOTA
Puede ser interesante leer antes o después este otro post de Introducción a Paneles para saber qué son, dónde van y cómo funcionan.

Panel Autoguardado

Auto Save es un Panel (plugin) que en un principio(*) tiene una misión muy importante, guardar automáticamente el documento (fla) con el cual estamos trabajando.

(*)Digo en un principio porque al pensarlo bien, tal como funciona el IDE de Flash y sobre todo con la gran cantidad de fallos (bugs) que he encontrado en esta nueva versión de Adobe Flash CS4 Professional no estoy 100 % seguro si nos podrá ayudar o no. :D Con esto quiero decir que el uso de este Panel es bajo tu propio riesgo.

Ahora si, dicho todo lo anterior hablemos del Panel.

CONFIGURACIÓN Y USO

Es muy fácil de configurar el Panel, son únicamente tres valores:

  • Frecuencia: Como su nombre indica sirva para configurar la frecuencia el minutos del auto guardado.
  • Preguntar: Si está activado antes de guardar te preguntará si deseas guardar, pudiendo responder que no y seguir tranquilamente con tu trabajo.
  • Activo / Inactivo: Este es nuestro botón de encendido, con el cual indicamos que el auto guardado está activo o inactivo.

Y ya está, así de fácil es configurar el Panel de Auto guardado de documentos Fla. (Hola Gus!!!)

Uso

Para usar el Panel debemos abrirlo, desde el menú Ventana > Otros paneles > Auto save y configurarlo tal como indicamos arriba. Es importante mencionar que para que funcione debe estar visible, es decir, el Panel debe estar abierto. Tal como se muestra en la siguiente imagen.

Un poco de historia

Hablando con un amigo (Iván) me comentó una funcionalidad importantísima y es que recuerde la configuración porque sino sería un verdadero incordio tener que estar configurándolo cada vez que lo utilizas, así que SI, el Panel recuerda la configuración cada vez que lo cierras y lo abres e incluso si cierras el IDE de Flash.

Descarga

Para todo aquel que simplemente necesite el Panel Auto Save y no tenga interés en saber como funciona por dentro puede descargar aquí el instalador mxp.

A los que les interese saber como funciona sigan leyendo hasta el final que también hay otro enlace al instalador al final. ;D

Parte friki, tutorial, código y demás

Hasta ahora hemos hablado del Panel y sus beneficios (es verdad, también hemos hablado de las posibles no bondades :P), pero todavía no sabemos cómo funciona, qué engranes se mueven por dentro, dónde está la magia y demás historias que en realidad es lo que quiero contar de lo que trata este post.

Pues vamos allá, jejeje, es que realmente el funcionamiento interno de este Panel es realmente sencillo, únicamente utilizamos dos métodos de JSFL, uno para comprobar que exista un documento abierto y otro para guardar el documento, si, así de fácil.

Explicación

Para saber si existe un documento Fla abierto utilizamos el método fl.getDocumentDOM() que nos devolverá un Objeto de tipo Document en caso de existir, en caso contrario nos devolverá undefined, con lo cual podemos hacer las comprobaciones necesarias en nuestro código ActionScript.

Lo siguiente que tenemos que hacer en caso de que exista el documento y que las variables de configuración del Panel (Frecuencia, Preguntar y Activo) nos los permitan es guardarlo, haciendo uso del método fl.getDocumentDOM().save(true) y listo.

Resultado final

En esta ocasión es más código ActionScript que código JSFL, como en los anteriores post aquí también hacemos uso de la función MMExecute que nos permite ejecutar JSFL desde un fichero swf con ActionScript.

A continuación os pongo el código. Hay un par de cosas feas por ahí, así que tener en cuenta que lo programé el viernes por la mañana mientras iba en el tren hacia el trabajo, así que si alguién lo quiere modificar para dejarlo más bonito o añadir funcionalidad es libre de hacerlo siempre y cuando mencione el origen (y si no lo menciona también, total, lo que quiero es compartir).

import fl.controls.Button;
import fl.controls.CheckBox;
import fl.controls.Label;
import fl.controls.NumericStepper;
import flash.events.Event;

var nIntervalID:uint;
var nMinutesToAutoSave:uint;
var bCheckBoxAsk:Boolean;
var bActive:Boolean;

var comButtonOnOff:Button;
var comCheckBoxAsk:CheckBox;
var oLabel:Label;
var comNumericStepperFrecuency:NumericStepper;

var oSharedObject:SharedObject;

this.config();
this.init();

function config():void
{

	this.oSharedObject = SharedObject.getLocal("DATA_AUTOSAVE_SO");

	this.nMinutesToAutoSave = (this.oSharedObject.data.nMinutesToAutoSave != undefined) ? this.oSharedObject.data.nMinutesToAutoSave: this.comNumericStepperFrecuency.value;
	this.bCheckBoxAsk = (this.oSharedObject.data.bCheckBoxAsk != undefined) ? this.oSharedObject.data.bCheckBoxAsk: this.comCheckBoxAsk.selected;
	this.bActive = (this.oSharedObject.data.bActive != undefined) ? this.oSharedObject.data.bActive: false;

	this.comNumericStepperFrecuency.value = this.nMinutesToAutoSave;
	this.comCheckBoxAsk.selected = this.bCheckBoxAsk;
	if (this.bActive)
		this.comButtonOnOff.label = "On";
	else
		this.comButtonOnOff.label = "Off";

	this.comButtonOnOff.addEventListener(MouseEvent.CLICK, onClickButtonOnOff);
	this.comCheckBoxAsk.addEventListener(Event.CHANGE, onCheckBoxAskChange);
	this.comNumericStepperFrecuency.addEventListener(Event.CHANGE, onNumericStepperFrecuencyChange);

	this.saveSharedObject();
}

function saveSharedObject():void
{
	this.oSharedObject.data.nMinutesToAutoSave = this.nMinutesToAutoSave;
	this.oSharedObject.data.bCheckBoxAsk = this.bCheckBoxAsk;
	this.oSharedObject.data.bActive = this.bActive;

	this.oSharedObject.flush();
}

function onClickButtonOnOff(_oMouseEvent:MouseEvent):void
{
	if (this.bActive)
	{
		this.bActive = false;
		this.comButtonOnOff.label = "On";
	}
	else
	{
		this.bActive = true;
		this.comButtonOnOff.label = "Off";

		this.init();
	}

	this.saveSharedObject();
}

function onCheckBoxAskChange(_oEvent:Event):void
{
	this.bCheckBoxAsk = this.comCheckBoxAsk.selected;

	this.saveSharedObject();
}

function onNumericStepperFrecuencyChange(_oEvent:Event):void
{
	this.nMinutesToAutoSave = this.comNumericStepperFrecuency.value;

	this.init();

	this.saveSharedObject();
}

function init():void
{
	clearInterval(this.nIntervalID);
	this.nIntervalID = setInterval(autoSave, this.nMinutesToAutoSave * 60 * 1000);
}

function autoSave():void
{
	if (this.bActive && this.isDocument())
	{
		if (this.comCheckBoxAsk.selected)
		{
			var sCodeJSFL:String = "";
			var sResult:String = "";

			sCodeJSFL = "confirm(\"Quieres guardar\");";
			sResult = MMExecute(sCodeJSFL);

			if (sResult == "true")
			{
				this.saveDocument();
			}
		}
		else
		{
			this.saveDocument();
		}
	}
}

function isDocument():Boolean
{
	var bRet:Boolean;

	var sCodeJSFL:String = "";
	var sResult:String = "";
	sCodeJSFL = "fl.getDocumentDOM();";
	sResult = MMExecute(sCodeJSFL);
	bRet = (sResult != "undefined") ? true: false;

	return bRet;
}

function saveDocument():void
{
	var sCodeJSFL:String = "";
	var sResult:String = "";
	sCodeJSFL = "fl.getDocumentDOM().save(true);";
	sResult = MMExecute(sCodeJSFL);
}

Aquí tenéis los archivos de descarga.

Sugerencias, dudas, ideas o comentarios?

Saludos!!!

Entradas relacionadas:

Get Adobe Flash playerPlugin by wpburn.com wordpress themes