| 1 |
package org.libspark.gunyarapaint.ui.v1 |
|---|
| 2 |
{ |
|---|
| 3 |
import flash.display.BitmapData; |
|---|
| 4 |
import flash.events.EventPhase; |
|---|
| 5 |
import flash.events.MouseEvent; |
|---|
| 6 |
import flash.geom.Matrix; |
|---|
| 7 |
import flash.geom.Point; |
|---|
| 8 |
import flash.geom.Rectangle; |
|---|
| 9 |
import flash.utils.ByteArray; |
|---|
| 10 |
|
|---|
| 11 |
import mx.containers.TitleWindow; |
|---|
| 12 |
import mx.controls.HScrollBar; |
|---|
| 13 |
import mx.controls.VScrollBar; |
|---|
| 14 |
import mx.controls.scrollClasses.ScrollBar; |
|---|
| 15 |
import mx.core.Application; |
|---|
| 16 |
import mx.core.Container; |
|---|
| 17 |
import mx.events.FlexEvent; |
|---|
| 18 |
import mx.events.MoveEvent; |
|---|
| 19 |
import mx.events.ResizeEvent; |
|---|
| 20 |
import mx.events.ScrollEvent; |
|---|
| 21 |
|
|---|
| 22 |
import org.libspark.gunyarapaint.framework.Pen; |
|---|
| 23 |
import org.libspark.gunyarapaint.framework.ui.IApplication; |
|---|
| 24 |
import org.libspark.gunyarapaint.ui.utils.ComponentResizer; |
|---|
| 25 |
|
|---|
| 26 |
public class CanvasController extends TitleWindow implements IController |
|---|
| 27 |
{ |
|---|
| 28 |
public function CanvasController() |
|---|
| 29 |
{ |
|---|
| 30 |
m_contentContainer = new Container(); |
|---|
| 31 |
m_contentContainer.setStyle("borderStyle", "none"); |
|---|
| 32 |
m_contentContainer.horizontalScrollPolicy = "off"; |
|---|
| 33 |
m_contentContainer.verticalScrollPolicy = "off"; |
|---|
| 34 |
m_contentContainer.percentWidth = 100; |
|---|
| 35 |
m_contentContainer.percentHeight = 100; |
|---|
| 36 |
m_contentContainer.addEventListener(MouseEvent.CLICK, onClickContentContainer); |
|---|
| 37 |
m_canvasContainer = new Container(); |
|---|
| 38 |
m_canvasContainer.mouseEnabled = false; |
|---|
| 39 |
m_canvasContainer.setStyle("borderStyle", "none"); |
|---|
| 40 |
m_canvasContainer.horizontalScrollPolicy = "off"; |
|---|
| 41 |
m_canvasContainer.verticalScrollPolicy = "off"; |
|---|
| 42 |
m_hScrollBar = new HScrollBar(); |
|---|
| 43 |
m_vScrollBar = new VScrollBar(); |
|---|
| 44 |
m_hScrollBar.height = ScrollBar.THICKNESS; |
|---|
| 45 |
m_vScrollBar.width = ScrollBar.THICKNESS; |
|---|
| 46 |
m_hScrollBar.addEventListener(ScrollEvent.SCROLL, onScrollHorizontally); |
|---|
| 47 |
m_vScrollBar.addEventListener(ScrollEvent.SCROLL, onScrollVertically); |
|---|
| 48 |
m_hScrollBar.lineScrollSize = 1; |
|---|
| 49 |
m_vScrollBar.lineScrollSize = 1; |
|---|
| 50 |
m_statusDefault = _("Coordinates:(%s, %s) Opacity:%s Color:(%s,%s,%s)", 0, 0, 0, 0, 0, 0); |
|---|
| 51 |
m_preDegree = 0; |
|---|
| 52 |
super(); |
|---|
| 53 |
} |
|---|
| 54 |
|
|---|
| 55 |
public function init(app:IApplication):void |
|---|
| 56 |
{ |
|---|
| 57 |
setStyle("backgroundColor", 0x0); |
|---|
| 58 |
horizontalScrollPolicy = "off"; |
|---|
| 59 |
verticalScrollPolicy = "off"; |
|---|
| 60 |
addChild(m_contentContainer); |
|---|
| 61 |
validateNow(); // percentWidth/Height -> width/heightに更新 |
|---|
| 62 |
m_canvasContainer.width = m_contentContainer.width - m_vScrollBar.width; |
|---|
| 63 |
m_canvasContainer.height = m_contentContainer.height - m_hScrollBar.height; |
|---|
| 64 |
m_canvasWidth = app.canvasWidth; |
|---|
| 65 |
m_canvasHeight = app.canvasHeight; |
|---|
| 66 |
m_canvasX = m_canvasY = 0; |
|---|
| 67 |
m_canvasScaleX = m_canvasScaleY = 0.5; |
|---|
| 68 |
m_canvasScale = 1; |
|---|
| 69 |
m_canvas = new Canvas(app, this); |
|---|
| 70 |
m_canvasContainer.addChild(m_canvas); |
|---|
| 71 |
m_contentContainer.addChild(m_canvasContainer); |
|---|
| 72 |
m_contentContainer.addChild(m_hScrollBar); |
|---|
| 73 |
m_contentContainer.addChild(m_vScrollBar); |
|---|
| 74 |
m_initRectangle = new Rectangle(x, y, width, height); |
|---|
| 75 |
status = m_statusDefault; |
|---|
| 76 |
ComponentResizer.addResize(this, new Point(100, 100)); |
|---|
| 77 |
resize(); |
|---|
| 78 |
update(); |
|---|
| 79 |
addEventListener(MoveEvent.MOVE, onMove); |
|---|
| 80 |
addEventListener(ResizeEvent.RESIZE, onResize); |
|---|
| 81 |
} |
|---|
| 82 |
|
|---|
| 83 |
public function load(data:Object):void |
|---|
| 84 |
{ |
|---|
| 85 |
var rect:Object = data.rectangle; |
|---|
| 86 |
move(rect.x, rect.y); |
|---|
| 87 |
width = rect.width; |
|---|
| 88 |
height = rect.height; |
|---|
| 89 |
m_canvas.auxBoxVisible = data.auxBoxVisible; |
|---|
| 90 |
m_canvas.auxSkewVisible = data.auxSkewVisible; |
|---|
| 91 |
m_canvas.auxDivideCount = data.auxDivideCount; |
|---|
| 92 |
m_canvas.auxLineAlpha = data.auxLineAlpha; |
|---|
| 93 |
m_canvas.auxLineColor = data.auxLineColor; |
|---|
| 94 |
m_canvas.enableAuxPixel = data.enableAuxPixel; |
|---|
| 95 |
} |
|---|
| 96 |
|
|---|
| 97 |
public function save(data:Object):void |
|---|
| 98 |
{ |
|---|
| 99 |
data.rectangle = new Rectangle(x, y, width, height); |
|---|
| 100 |
data.auxBoxVisible = m_canvas.auxBoxVisible; |
|---|
| 101 |
data.auxSkewVisible = m_canvas.auxSkewVisible; |
|---|
| 102 |
data.auxDivideCount = m_canvas.auxDivideCount; |
|---|
| 103 |
data.auxLineAlpha = m_canvas.auxLineAlpha; |
|---|
| 104 |
data.auxLineColor = m_canvas.auxLineColor; |
|---|
| 105 |
data.enableAuxPixel = m_canvas.enableAuxPixel; |
|---|
| 106 |
} |
|---|
| 107 |
|
|---|
| 108 |
public function resetWindow():void |
|---|
| 109 |
{ |
|---|
| 110 |
move(m_initRectangle.x, m_initRectangle.y); |
|---|
| 111 |
width = m_initRectangle.width; |
|---|
| 112 |
height = m_initRectangle.height; |
|---|
| 113 |
rotate(0); |
|---|
| 114 |
transform.matrix = new Matrix( |
|---|
| 115 |
1, 0, 0, 1, m_initRectangle.x, m_initRectangle.y |
|---|
| 116 |
); |
|---|
| 117 |
} |
|---|
| 118 |
|
|---|
| 119 |
public function zoom(value:Number):void |
|---|
| 120 |
{ |
|---|
| 121 |
var magnification:Number = value >= 1 ? value : (1.0 / (-value + 2)); |
|---|
| 122 |
var maxX:Number = m_canvasWidth * magnification - m_canvasContainer.width; |
|---|
| 123 |
var maxY:Number = m_canvasHeight * magnification - m_canvasContainer.height; |
|---|
| 124 |
m_canvasX = m_canvasScaleX * maxX; |
|---|
| 125 |
m_canvasY = m_canvasScaleY * maxY; |
|---|
| 126 |
m_canvas.scaleX = m_canvas.scaleY = m_canvasScale = magnification; |
|---|
| 127 |
resize(); |
|---|
| 128 |
update(); |
|---|
| 129 |
} |
|---|
| 130 |
|
|---|
| 131 |
public function rotate(value:int):void |
|---|
| 132 |
{ |
|---|
| 133 |
var pb:Rectangle = transform.pixelBounds; |
|---|
| 134 |
var p:Point = new Point(pb.x + pb.width / 2, pb.y + pb.height / 2); |
|---|
| 135 |
var m:Matrix = transform.matrix; |
|---|
| 136 |
m.translate(-p.x, -p.y); |
|---|
| 137 |
m.rotate((value - m_preDegree) * (Math.PI / 180)); |
|---|
| 138 |
m.translate(p.x, p.y); |
|---|
| 139 |
transform.matrix = m; |
|---|
| 140 |
m_preDegree = value; |
|---|
| 141 |
if (value == 0) |
|---|
| 142 |
transform.matrix = new Matrix(1, 0, 0, 1, m.tx, m.ty); |
|---|
| 143 |
} |
|---|
| 144 |
|
|---|
| 145 |
public function scroll(x:Number, y:Number):void |
|---|
| 146 |
{ |
|---|
| 147 |
var maxX:Number = m_canvasWidth * m_canvasScale - m_canvasContainer.width; |
|---|
| 148 |
var maxY:Number = m_canvasHeight * m_canvasScale - m_canvasContainer.height; |
|---|
| 149 |
m_canvasScaleX = x / maxX; |
|---|
| 150 |
m_canvasScaleY = x / maxY; |
|---|
| 151 |
m_canvasX = x; |
|---|
| 152 |
m_canvasY = y; |
|---|
| 153 |
update(); |
|---|
| 154 |
} |
|---|
| 155 |
|
|---|
| 156 |
public function exportBitmapData():BitmapData |
|---|
| 157 |
{ |
|---|
| 158 |
var bitmapData:BitmapData = new BitmapData(m_canvasWidth, m_canvasHeight); |
|---|
| 159 |
bitmapData.draw(m_canvas); |
|---|
| 160 |
return bitmapData; |
|---|
| 161 |
} |
|---|
| 162 |
|
|---|
| 163 |
public function get canvasScrollPosition():Point |
|---|
| 164 |
{ |
|---|
| 165 |
return new Point(m_canvasX, m_canvasY); |
|---|
| 166 |
} |
|---|
| 167 |
|
|---|
| 168 |
public function get canvasScale():Number |
|---|
| 169 |
{ |
|---|
| 170 |
return m_canvasScale; |
|---|
| 171 |
} |
|---|
| 172 |
|
|---|
| 173 |
public function set auxBoxVisible(value:Boolean):void |
|---|
| 174 |
{ |
|---|
| 175 |
m_canvas.auxBoxVisible = value; |
|---|
| 176 |
m_canvas.updateAuxViews(); |
|---|
| 177 |
} |
|---|
| 178 |
|
|---|
| 179 |
public function set auxSkewVisible(value:Boolean):void |
|---|
| 180 |
{ |
|---|
| 181 |
m_canvas.auxSkewVisible = value; |
|---|
| 182 |
m_canvas.updateAuxViews(); |
|---|
| 183 |
} |
|---|
| 184 |
|
|---|
| 185 |
public function set auxDivideCount(value:uint):void |
|---|
| 186 |
{ |
|---|
| 187 |
m_canvas.auxDivideCount = value; |
|---|
| 188 |
m_canvas.updateAuxViews(); |
|---|
| 189 |
} |
|---|
| 190 |
|
|---|
| 191 |
public function set enableAuxPixel(value:Boolean):void |
|---|
| 192 |
{ |
|---|
| 193 |
m_canvas.enableAuxPixel = value; |
|---|
| 194 |
m_canvas.updateAuxViews(); |
|---|
| 195 |
} |
|---|
| 196 |
|
|---|
| 197 |
public function set enablePixelInfo(value:Boolean):void |
|---|
| 198 |
{ |
|---|
| 199 |
status = value ? m_statusDefault : ""; |
|---|
| 200 |
m_canvas.enablePixelInfo = value; |
|---|
| 201 |
} |
|---|
| 202 |
|
|---|
| 203 |
public function set statusText(value:String):void |
|---|
| 204 |
{ |
|---|
| 205 |
status = value; |
|---|
| 206 |
} |
|---|
| 207 |
|
|---|
| 208 |
private function onScrollHorizontally(event:ScrollEvent):void |
|---|
| 209 |
{ |
|---|
| 210 |
var maxX:Number = m_canvasWidth * m_canvasScale - m_canvasContainer.width; |
|---|
| 211 |
m_canvasX = m_hScrollBar.scrollPosition; |
|---|
| 212 |
m_canvasScaleX = m_canvasX / maxX; |
|---|
| 213 |
update(); |
|---|
| 214 |
} |
|---|
| 215 |
|
|---|
| 216 |
private function onScrollVertically(event:ScrollEvent):void |
|---|
| 217 |
{ |
|---|
| 218 |
var maxY:Number = m_canvasHeight * m_canvasScale - m_canvasContainer.height; |
|---|
| 219 |
m_canvasY = m_vScrollBar.scrollPosition; |
|---|
| 220 |
m_canvasScaleY = m_canvasY / maxY; |
|---|
| 221 |
update(); |
|---|
| 222 |
} |
|---|
| 223 |
|
|---|
| 224 |
private function onResize(event:ResizeEvent):void |
|---|
| 225 |
{ |
|---|
| 226 |
resize(); |
|---|
| 227 |
update(); |
|---|
| 228 |
} |
|---|
| 229 |
|
|---|
| 230 |
private function onMove(event:MoveEvent):void |
|---|
| 231 |
{ |
|---|
| 232 |
x = int(x); |
|---|
| 233 |
y = int(y); |
|---|
| 234 |
} |
|---|
| 235 |
|
|---|
| 236 |
private function onClickContentContainer(event:MouseEvent):void |
|---|
| 237 |
{ |
|---|
| 238 |
if (event.eventPhase == EventPhase.AT_TARGET && event.shiftKey) { |
|---|
| 239 |
var pen:Pen = IApplication(Application.application).pen; |
|---|
| 240 |
setStyle("backgroundColor", pen.color); |
|---|
| 241 |
m_canvas.auxLineColor = pen.color; |
|---|
| 242 |
m_canvas.auxLineAlpha = pen.alpha; |
|---|
| 243 |
m_canvas.updateAuxViews(); |
|---|
| 244 |
} |
|---|
| 245 |
} |
|---|
| 246 |
|
|---|
| 247 |
private function update():void |
|---|
| 248 |
{ |
|---|
| 249 |
var maxX:Number = m_canvasWidth * m_canvasScale - m_canvasContainer.width; |
|---|
| 250 |
var maxY:Number = m_canvasHeight * m_canvasScale - m_canvasContainer.height; |
|---|
| 251 |
m_canvasX = Math.floor(m_canvasX); |
|---|
| 252 |
m_canvasY = Math.floor(m_canvasY); |
|---|
| 253 |
// 移動位置及び最大範囲を調整する |
|---|
| 254 |
if (maxX <= 0) |
|---|
| 255 |
maxX = 0; |
|---|
| 256 |
if (maxY <= 0) |
|---|
| 257 |
maxY = 0; |
|---|
| 258 |
if (m_canvasX < 0) |
|---|
| 259 |
m_canvasX = 0; |
|---|
| 260 |
if (m_canvasY < 0) |
|---|
| 261 |
m_canvasY = 0; |
|---|
| 262 |
if (m_canvasX > maxX) |
|---|
| 263 |
m_canvasX = maxX; |
|---|
| 264 |
if (m_canvasY > maxY) |
|---|
| 265 |
m_canvasY = maxY; |
|---|
| 266 |
// スクロールバーを移動先の位置に設定する |
|---|
| 267 |
m_hScrollBar.scrollPosition = m_canvasX; |
|---|
| 268 |
m_vScrollBar.scrollPosition = m_canvasY; |
|---|
| 269 |
// 拡大率によってスクロール量を決定する(拡大率が大きい程スクロール量も大きくなる) |
|---|
| 270 |
m_hScrollBar.lineScrollSize = m_canvasScale; |
|---|
| 271 |
m_vScrollBar.lineScrollSize = m_canvasScale; |
|---|
| 272 |
// スクロールバーの大きさを決定する(拡大率が大きい程スクロールバーが小さくなる) |
|---|
| 273 |
m_hScrollBar.setScrollProperties(m_canvasContainer.width, 0, maxX); |
|---|
| 274 |
m_vScrollBar.setScrollProperties(m_canvasContainer.height, 0, maxY); |
|---|
| 275 |
// キャンバスを移動させる |
|---|
| 276 |
m_canvas.move(-m_canvasX, -m_canvasY); |
|---|
| 277 |
} |
|---|
| 278 |
|
|---|
| 279 |
private function resize():void |
|---|
| 280 |
{ |
|---|
| 281 |
// 仮にサイズを狭める |
|---|
| 282 |
m_canvasContainer.width = 0; |
|---|
| 283 |
m_canvasContainer.height = 0; |
|---|
| 284 |
m_hScrollBar.width = 0; |
|---|
| 285 |
m_vScrollBar.height = 0; |
|---|
| 286 |
// _contentContainerのサイズを更新 |
|---|
| 287 |
validateNow(); |
|---|
| 288 |
// それを使って再設定 |
|---|
| 289 |
var clientWidth:Number = m_contentContainer.width - m_vScrollBar.width; |
|---|
| 290 |
var clientHeight:Number = m_contentContainer.height - m_hScrollBar.height; |
|---|
| 291 |
m_hScrollBar.width = clientWidth; |
|---|
| 292 |
m_vScrollBar.height = clientHeight; |
|---|
| 293 |
// 拡大または縮小したキャンバスのサイズを求める |
|---|
| 294 |
var scaledCanvasWidth:Number = m_canvasWidth * m_canvasScale; |
|---|
| 295 |
var scaledCanvasHeight:Number = m_canvasHeight * m_canvasScale; |
|---|
| 296 |
// 拡大または縮小したキャンバスをキャンバスコンテナのサイズに収める必要がある |
|---|
| 297 |
m_canvasContainer.width = scaledCanvasWidth < clientWidth ? scaledCanvasWidth : clientWidth; |
|---|
| 298 |
m_canvasContainer.height = scaledCanvasHeight < clientHeight ? scaledCanvasHeight : clientHeight; |
|---|
| 299 |
// スクロールバーを所定の位置に移動 |
|---|
| 300 |
m_hScrollBar.move(0, clientHeight); |
|---|
| 301 |
m_vScrollBar.move(clientWidth, 0); |
|---|
| 302 |
// キャンバスを所定の位置に移動 |
|---|
| 303 |
m_canvasContainer.move( |
|---|
| 304 |
(clientWidth - m_canvasContainer.width) / 2, |
|---|
| 305 |
(clientHeight - m_canvasContainer.height) / 2 |
|---|
| 306 |
); |
|---|
| 307 |
} |
|---|
| 308 |
|
|---|
| 309 |
private var m_statusDefault:String; |
|---|
| 310 |
private var m_canvasContainer:Container; // GPCanvasを直接格納するコンテナ |
|---|
| 311 |
private var m_contentContainer:Container; // GPCanvasと背景、スクロールバーを持つコンテナ |
|---|
| 312 |
private var m_hScrollBar:HScrollBar; // 横スクロールバー |
|---|
| 313 |
private var m_vScrollBar:VScrollBar; // 縦スクロールバー |
|---|
| 314 |
private var m_initRectangle:Rectangle; // 初期位置 |
|---|
| 315 |
private var m_canvasWidth:Number; // キャンバスの幅 (IApplication#canvasWidth の値をキャッシュする) |
|---|
| 316 |
private var m_canvasHeight:Number; // キャンバスの高さ (IApplication#canvasHeight の値をキャッシュする) |
|---|
| 317 |
private var m_canvasX:Number; // キャンバスのスクロール位置 |
|---|
| 318 |
private var m_canvasY:Number; |
|---|
| 319 |
private var m_canvasScaleX:Number; // 拡大したキャンバスの幅に対する X 座標の相対率 |
|---|
| 320 |
private var m_canvasScaleY:Number; // 拡大したキャンバスの高さに対する Y 座標の相対率 |
|---|
| 321 |
private var m_canvasScale:Number; // キャンバスの倍率 |
|---|
| 322 |
private var m_preDegree:int; // 前の回転角度 |
|---|
| 323 |
private var m_scrollDragStartPoint:Point; |
|---|
| 324 |
private var m_canvas:Canvas; |
|---|
| 325 |
} |
|---|
| 326 |
} |
|---|