homeへのリンクです。

flashでAmazonECS 6

2006年05月20日

レイアウトについてよく考える。

30カテゴリぐらいあるようなので、6x5のグリッドで初期画面を作る。

columnは移動可能で並び順を変更できる。

今の所、このようになっている。

view.html

コンポーネントは使わないつもりだったが、とりあえずウィンドウは、わりとすぐに出てくるようだったので、使ってみた。

mx.containers.Windowなのだが、どうも、clickイベントしか拾えない。

ドラッグされているウィンドウの判定に一苦労と言った感じ。

クラスの構造は以下のようになっているので、とりあえず、後からウィンドウ部分を差し替えることも可能。

classes/column/Column
classes/column/WindowColumn
classes/layout/DataGridLayout
classes/layout/GridLayout
classes/layout/Layout
classes/layout/LayoutManager
classes/loadbar/LoadBar
classes/main/Main
classes/util/ColumnConstructor
classes/util/LayoutConstructor
classes/xml/LoadAmazonXML
classes/xml/ParseAmazonXML

今回主に手を入れたのは、GridLayoutクラス。

import classes.layout.*;
import classes.column.*;
import classes.util.*;
import mx.containers.*;
class GridLayout extends Layout{
	private var mytimeline:MovieClip;//columnを貼り付ける場所
	private var ctype:String="windowcolumn";//columnのタイプ
	private var myclist:Array=new Array();//columnのリスト
	private var pressx:Number;//columnをプレスし始めたときのx座標
	private var pressy:Number;//columnをプレスし始めたときのy座標
	private var xchklist:Array=new Array();//column入れ替えx座標チェック用リスト
	private var ychklist:Array=new Array();//column入れ替えy座標チェック用リスト
	private var xnum:Number;//1行に入れるcolumn数
	private var ynum:Number;//何列表示させるか
	private var centerx:Number;//columnの中央x;
	private var centery:Number;//columnの中央y;
	private var columnw:Number;//columnの幅
	private var columnh:Number;//columnの高さ
	public function GridLayout(tm:MovieClip,datanum:Number){
		mytimeline=tm;
		var margin:Number=5;//columnの外側の間隔
		var stagewidth:Number=mytimeline._width-margin;
		var stageheight:Number=mytimeline._height-margin;
		xnum=6;
		ynum=Math.ceil(datanum/xnum);
		columnw=stagewidth/xnum-margin;
		columnh=stageheight/ynum-margin;
		centerx=columnw/2;
		centery=columnh/2;
		var columncons:ColumnConstructor=new ColumnConstructor();
		for(var i:Number=0;i<datanum;i++){
			var xid:Number=i%xnum;//横並びの順番
			var yid:Number=Math.floor(i/(ynum+1));//縦並びの順番
			var posx:Number=xid*columnw+margin*(xid+1);//X座標上のポジション
			var posy:Number=yid*columnh+margin*(yid+1);//Y座標上のポジション
			xchklist[i]=posx;
			ychklist[i]=posy;
			myclist[i]=columncons.makeClass(ctype,mytimeline,posx,posy,columnw,columnh);
		}
		mytimeline.grdlyt=this;
		mytimeline.onMouseDown=function():Void{
			pressx=this._xmouse;
			pressy=this._ymouse;
		}
		mytimeline.onMouseUp=function():Void{
			if(pressx!=this._xmouse||pressy!=this._ymouse){//columnが動いているとき、場所入れ替えの処理をする。
				this.grdlyt.chkPos(this.grdlyt.chkTarget());
			}
		}
	}
	private function chkTarget():Number{
		for(var i:Number=0;i<myclist.length;i++){
			if(myclist[i].currentx!=myclist[i].startx||myclist[i].currenty!=myclist[i].starty){//どれが動いているかを突き止める
				return i;
			}
		}
	}
	private function chkPos(idx:Number):Void{
		//x座標の変更位置確認
		var chkx:Number=myclist[idx].currentx+centerx;
		for(var i:Number=0;i<xnum;i++){//列数分だけチェックする
			if(xchklist[i]+columnw>chkx){
				//var targetx:Number=xchklist[i];
				var targetxidx:Number=i;
				i=xnum;//loopを終了させる
			}
		}
		//y座標の変更位置確認
		var chky:Number=myclist[idx].currenty+centery;
		for(var i:Number=0;i<ychklist.length;i+=xnum){
			if(ychklist[i]+columnh>chky){//行数文だけチェックする
				//var targety:Number=ychklist[i];
				var targetyidx:Number=i/xnum;
				i=ychklist.length;//loopを終了させる
			}
		}
		var chgtgtidx:Number=targetyidx*xnum+targetxidx;//入れ替えターゲットのインデックス確定
		if(chgtgtidx>=myclist.length){//末尾の余白部分にはドロップさせない
			chgtgtidx=myclist.length-1;
		}
		var targetx:Number=xchklist[chgtgtidx];//移動位置確定
		var targety:Number=ychklist[chgtgtidx];
		//並び替え処理
		var tgtc:Column=myclist[idx];//入れ替え用にキープ
		if(chgtgtidx>idx){//前に詰める
			for(var i:Number=idx+1;i<=chgtgtidx;i++){//実際に動かす
				myclist[i].moveColumn(myclist[i-1].startx,myclist[i-1].starty);
			}
			for(var i:Number=idx+1;i<=chgtgtidx;i++){//リストの並び、start位置を変更する
				myclist[i-1]=myclist[i];
				myclist[i-1].startx=myclist[i-1].currentx;
				myclist[i-1].starty=myclist[i-1].currenty;
			}
		}else if(chgtgtidx<idx){//後ろに詰める
			for(var i:Number=idx-1;i>=chgtgtidx;i--){
				myclist[i].moveColumn(myclist[i+1].startx,myclist[i+1].starty);
			}
			for(var i:Number=idx-1;i>=chgtgtidx;i--){//リストの並び、start位置を変更する
				myclist[i+1]=myclist[i];
				myclist[i+1].startx=myclist[i+1].currentx;
				myclist[i+1].starty=myclist[i+1].currenty;
			}
		}
		tgtc.moveColumn(targetx,targety);//実際の移動処理
		myclist[chgtgtidx]=tgtc;//リストの並び、start位置を変更する
		myclist[chgtgtidx].startx=tgtc.currentx;
		myclist[chgtgtidx].starty=tgtc.currenty;
		for(var i:Number=0;i<myclist.length;i++){
			trace("y : "+myclist[i].starty+" , x : "+myclist[i].startx);
		}
	}
	public function setName(nlist:Array):Void{
		for(var i:Number=0;i<nlist.length;i++){
			myclist[i].setName(nlist[i]);//カテゴリー名の設定
		}
	}
	public function setID(idlist:Array):Void{
		for(var i:Number=0;i<idlist.length;i++){
			myclist[i].setID(idlist[i]);//ノードID設定
		}
	}
}

配列に入れているオブジェクトがオリジナルのクラスだとsortOnメソッドも使えないらしい。

単純に配列にウィンドウの参照を入れておいて、移動したら、配列のデータを参照しながら位置と情報をずらしていくだけ。


コンポーネントの表示待ちの時まで、ローディングバーを表示したままにできるようにしたい。

カテゴリーを色分けしたい。

ウィンドウサイズとステージサイズを可変にしたい。

サブカテゴリをウィンドウ内に表示させなければならない。