Fireworksでpickした画像をそのままクリップボードへ(Flashパネル習作)

FireworksのFlashパネルの習作ClickColorPickerです。FireworksExecuteクラスをテストするために作成しました。

機能

  • Fireworks 上で動作する色をスポイトで取得してそのままクリップボードにコピーします。
  • 一度取得した色はドキュメント単位で管理され、ドキュメントを保存したときに一緒に保存されます。
  • ドキュメント単位または色単位の削除が可能です。
  • 選択/クリックした色を、線・塗りに反映するかどうかを選択できます。

通常のスポイトツールとの違いは、特に指定しない限りドキュメント上の塗り・ 線に取得した色がセットされることがありません。

スクリーンショット

tl_files/fireworks/clipcolorpicker.pngtl_files/fireworks/clipcolorpicker2.png

Extensionとして配布しませんので使いたい方は、こちらのURLを参考にCommand PanelsフォルダにFlashパネルのswfを設置してください。

※イベントはFlashパネルだけが受け取れます。そのため、コマンドではなく、パネルとして設置しないと正常に動作しないのでお気をつけください。

ActionScriptで処理している部分

このパネルは次のように処理をしています。

  1. ドキュメント切り替え時にカラーリストを変更する(アクティブドキュメントな変更イベントのcallback使用)
  2. jsfのカラーピッカーで色を取得
  3. TileListコンポーネントで表示
  4. チェックボックスで選択されている塗り・線の反映の有無を確認して、必要に応じて塗り・線に反映
  5. clearボタンをクリックした際、カラーリストを消去
  6. 単体をクリックした際、標準→カラーをコピー、特殊キーを押しながらクリック→カラーを削除

具体的なスクリプトは早めにアップする予定です。

以下は、ActionScript 3.0 から MMExecuteを簡単に使用するためのクラスです。使用の際には必ずas3corelibを入手してJSONクラスを使える用にして下さい。

デバッグモードをONにしたときには、trace文で全実行jsfを表示します。

FireworksExecuteクラス

/*
   FireworksExecute Class
   version 0.1.1

   Risa Yugucchi <risa.yuguchi@gmail.com>
   Twitter: http://twitter.com/risay
   
   history
   0.1		created
   
   todo
   - save file(jsf) function
   - create directory(jsf) function
   
   IMPORTANT: 
   You need the library "as3corelib" for using this class. 
   please get as3corelib on web (http://code.google.com/p/as3corelib/.)

The MIT License

Copyright (c) 2009 Risa Yuguchi

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

*/
package jp.rstudio.extension.fw 
{
	import adobe.utils.MMExecute;
	import com.adobe.serialization.json.JSON;
	import flash.errors.IllegalOperationError;
	import flash.errors.ScriptTimeoutError;
	import flash.net.SharedObject;
	import flash.utils.Dictionary;
	
	/**
	 * MMExecuteを使用してFireworks APIを利用するためのユーティリティクラス
	 * @author Risa Yuguchi <info@r-studio.jp>
	 */
	public class FireworksExecute extends Object
	{
		
		private static var _instance:FireworksExecute;
		
		private var _isCatchFwEvent:Boolean = false;
		private var _isDebugMode:Boolean = false;
		private var _fw_property:Dictionary;
		private var _isStoreScript:Boolean = false;
		private var _scripts:Array;
		private const ACTIVE_DOC:String = "fw.getDocumentDOM()";
		
		/**
		 * constructor
		 */
		public function FireworksExecute() 
		{
			if (_instance) {
				throw new IllegalOperationError("Don't make instance of this class");
			}
			_fw_property = new Dictionary();
			getJSFProperty('fw.userJsCommandsDir',true);
			getJSFProperty('fw.userSwfCommandsDir',true);
		}
		
		/**
		 * instanceの取得
		 * @return
		 */
		public static function getInstance():FireworksExecute {
			if (_instance == null) {
				_instance = new FireworksExecute();
			}
			return _instance;
		}
		
		/**
		 * MMExecute('alert(message)');のエミュレート
		 * @param	message 表示したいメッセージ
		 */
		public function alert(message:String):void {
			executeJSFMethod("alert","",[message]);
		}
		
		/**
		 * MMExecute('confirm(message)');のエミュレート
		 * @param	message
		 * @return
		 */
		public function confirm(message:String):Boolean {
			return eval(executeJSFMethod("confirm", "", [message])) as Boolean;
		}
		/**
		 * MMExecute('prompt("caption,txext");')のエミュレート
		 * @param	caption
		 * @param	text
		 * @return
		 */
		public function prompt(caption:String, text:String):String {
			return executeJSFMethod("prompt", "", [caption, text]);
		}
		
		/**
		 * MMExecuteの隠蔽用
		 * @param	str String. jsfで実行したい文字列
		 * @return String. 実行結果
		 */
		public function execute(str:String):String {
			if(_isDebugMode) trace('MMExecute:'+str);
			if (_isStoreScript) {
				_scripts.push(str);
				return "";
			} else {
				return MMExecute(str);
			}
		}
		
		//---------------------------------------------------------
		// jsfメソッド実行
		//---------------------------------------------------------
		
		/**
		 * jsfの実行専用
		 * @param	functionName String fireworksオブジェクトのメソッド名。fireworksオブジェクトはfw.methodName、functionNameをdom.methodと書ける
		 * @param	target String メソッドを持つクラス名、またはインスタンス名。fwとdomはfunctionNameに含められる
		 * @param	args Array メソッドに渡す引数
		 * @return String 実行後文字列
		 */
		public function executeJSFMethod(functionName:String, target:String="", args:Array = null):String {
			if (target != "") {
				functionName = target + "." + functionName;
			}
			if (functionName.indexOf(".") > 0) {
				functionName = functionName.replace(/^dom\./, ACTIVE_DOC + ".");		
			}
			args = args || [];
			args.forEach(function(element:*, index:int, arr:Array):void { arr[index] = serialize(element); } );
			var execString:String = functionName + "(" + args.join(",") + ");";
			return execute(execString);
		}
		
		//---------------------------------------------------------
		// 変数取得
		//---------------------------------------------------------
		
		/**
		 * jsfのPropertyを取得
		 * @param	propertyName  String. オブジェクト.プロパティの形で指定する。
		 * @param	isSave Boolean. 取得した値を蓄積するかどうか。
		 * @param	useCache Boolean. 既に取得した値があったときに使うかどうか。デフォルトはtrueの使用する
		 * @return	String. 結果文字列
		 */
		public function getJSFProperty(propertyName:String, isSave:Boolean = false, useCache:Boolean = true):String {
			var res:String;
			propertyName = propertyName.replace(/^dom\./, ACTIVE_DOC + ".");
			var execString:String = propertyName+';';
			var objKey:String = propertyName.replace(".", "_");
			if (_fw_property.hasOwnProperty(objKey) && useCache) {
				res = _fw_property[objKey];
			} else {
				res = execute(execString);
				trace("getProperty:" + res);
				if (isSave) {
					_fw_property[objKey] = res;
				}
			}
			//alert(execString+"\n"+res);
			return res;
		}
		
		/**
		 * jsfでプロパティを保存
		 * @param	propertyName String プロパティ名
		 * @param	value プロパティにセットする値
		 * @param	isObject Boolean 値がオブジェクトかどうか
		 * @param	isSave 蓄積しておくかどうか。デフォルトはfalseで蓄積しない。
		 */
		public function setJSFProperty(propertyName:String, value:String, isObject:Boolean = false, isSave:Boolean = false):void {
			if (!isObject) {
				value = "'" + value + "'";
			}
			propertyName = propertyName.replace(/^dom\./, ACTIVE_DOC + ".");
			var executeString:String = propertyName + '=' + value;
			execute(executeString);
			if (isSave) {
				var objKey:String = propertyName.replace(".", "_");
				_fw_property[objKey] = value;
			}
		}
		/**
		 * ドキュメントに結びついた変数の取得。
		 * @param	fieldName String 格納したい変数名
		 * @param	value String 格納したい値
		 * @param	isObject Boolean 値がオブジェクトかどうか
		 * @return	Boolean 保存できたかどうか
		 */
		public function setPngTextField(fieldName:String, value:Object, isObject:Boolean = true):Boolean {
			var res:String = getActiveDocument();
			if (res == "" || res == "null") return false;
			// JSON形式に戻して保存
			setJSFProperty(ACTIVE_DOC + ".pngText." + fieldName, serialize(value), isObject);
			return true;
		}
		
		/**
		 * pngTextの削除
		 * @param	fieldName
		 */
		public function deletePngTextField(fieldName:String):void {
			var res:String = getActiveDocument();
			if (res == "" || res == "null") return;
			execute(ACTIVE_DOC + ".pngText." + fieldName + "=null");
		}
		
		/**
		 * ドキュメントに結びついた変数の格納。格納後ユーザーがドキュメントを保存しないで閉じると無効になる
		 * @param	paramName String 格納した変数名
		 * @return	JSONデコード済みデータ
		 */
		public function getPngTextParam(paramName:String):* {
			var res:String = getActiveDocument();
			if (res == "" || res == "null") return false;
			res = getJSFProperty(ACTIVE_DOC + ".pngText." + paramName);
			return eval(res);
		}
		
		//---------------------------------------------------------
		// SharedObject
		//---------------------------------------------------------
		
		/**
		 * SharedObjectに設定を保存
		 * @param	keyName String
		 * @param	setting 保存したい設定オブジェクト
		 */
		public function savePanelSetting(keyName:String, setting:*) {
			var so:SharedObject = SharedObject.getLocal(keyName);
			so.data.setting = setting;
			so.flush();
		}
		/**
		 * SharedObjectからkeyNameで保存されている設定を取得
		 * @param	keyName String ShardObjectのキー
		 * @return	ロードした設定オブジェクト
		 */
		public function loadPanelSetting(keyName:String):* {
			var so:SharedObject = SharedObject.getLocal(keyName);
			return so.data.setting;
		}
		
		//---------------------------------------------------------
		// バッチ処理
		//---------------------------------------------------------
		
		/**
		 * endCasheがくるまでスクリプトを一切実行しないようにする
		 */
		public function startCache():void {
			_isStoreScript = true;
		}
		/**
		 * 現在キャッシュされているスクリプトを取得
		 * @return スクリプトの文字列
		 */
		public function getCacheScript():String {
			return _scripts.join("/n");
		}
		/**
		 * スクリプトのキャッシュを終了する
		 * @return
		 */
		public function endCache():String {
			_isStoreScript = false;
			return getCacheScript();
		}
		/**
		 * 現在キャッシュしているスクリプトを実行処理に移す。終了後キャッシュを空にする
		 */
		public function run():void {
			if (_isStoreScript) {
				_isStoreScript = false;
				execute(_scripts.join(""));
				_isStoreScript = true;
			} else {
				execute(_scripts.join(""));
			}
			_scripts = [];
		}
		
		//---------------------------------------------------------
		// ファイル操作
		//---------------------------------------------------------
		
		/**
		 * utf-8でテキストファイルを保存する
		 * @param	filepath
		 * @return
		 */
		/*public function writeFile(filepath:String, content:String ):Boolean {
			setJSFProperty("fw.textOutputEncoding", "utf-8");
			if (filepath.indexOf("/") < 0) filepath = getJSFProperty("fw.userSwfCommandsDir", true) + "/" + filepath;
			if (executeJSFMethod("exists", "File", filepath) as Boolean) {
				
			} else {
				
			}
		}*/
		
		//---------------------------------------------------------
		// 特殊用途
		//---------------------------------------------------------
		
		/**
		 * Javascriptファイルのinclude
		 * @param	fileName
		 */
		
		public function runScript(fileName:String):void {
			if (fileName.indexOf("/") >= 0) {
				executeJSFMethod("fw.runScript", "", [fileName]);
			} else {
				executeJSFMethod("fw.runScript", "", [_fw_property['fw_userJsCommandsDir']+"/"+fileName]);
			}
		}
		/**
		 * カラーピッカーを表示して色を受け取る
		 * @param	initialColor 初期カラー文字列#00000000形式で
		 * @param	allowTransparent 透過を許可するか
		 * @param	forceWeb216 Webセーフカラー216色に限定するか
		 * @return	取得した色の文字列
		 */
		public function showColorPickerWithPointer(initialColor:String, allowTransparent:Boolean=false, forceWeb216:Boolean=false):String {
			return executeJSFMethod("fw.popupColorPickerOverMouse", "", [initialColor, allowTransparent, forceWeb216]);
		}
		
		/**
		 * アクティブなオブジェクトがあるかを取得する
		 * @return String null または [Object Fw~]
		 */
		public function getActiveDocument():String {
			var res:String = execute('fw.getDocumentDOM().toString();');
			if (_isDebugMode) trace("getActiveDocument",res);
			return res;
		}
		
		//---------------------------------------------------------
		// シリアライズ
		//---------------------------------------------------------
		
		/**
		 * Fireworksのオブジェクト書式をJSONに変換して、データをデコードする。
		 * @param	script Fireworksから戻ってきた文字列
		 * @return デコードした結果オブジェクト
		 */
		public function eval(script:String = ""):* {
			if (script == "") return new Object();
			try {
				script = script.replace(/([{,\s]+)([a-zA-Z0-9_]+):/g, '$1"$2":');
				return JSON.decode(script);
				//return decode(script);
			} catch (e:Error) {
				trace(script + "はデコードできませんでした\n" + e.message);
			}
				return new Object();
		}
		
		public function serialize(val:*, repeat:int = 0):String
		{
			if (repeat > 5) {
				throw new Error("そんなに深い階層のオブジェクトは分解できません。");
			}
			if (val is Boolean) {
				return val;
			} else if (val is String) {
				return '"'+val+'"';
			} else if (val is Number || val is int || val is uint) {
				return val;
			} else if (val is Array) {
				(val as Array).forEach(function(element:*, index:int, arr:Array):void { arr[index] = serialize(element,repeat); } );
				return "[" + (val as Array).join(",") + "]";
			} else if (val is Object) {
				var dump:Array = [];
				for (var item:String in val) {
					dump.push('"' + item + '":' + serialize(val[item], repeat));
				}
				return '{' + dump.join(",") + "}";
			} else {
				throw new Error("そのオブジェクトは展開できません");
			}
		}

		
		/**
		 * デバッグモードかどうかを示す
		 */
		public function get isDebugMode():Boolean { return _isDebugMode; }
		
		public function set isDebugMode(value:Boolean):void 
		{
			_isDebugMode = value;
		}
	}
	
}

戻る