root/as3/gunyarapaint/trunk/gunyarapaint/src/gunyarapaint.as

リビジョン 1740, 13.6 kB (コミッタ: tasuku, コミット時期: 5 年 前)

fixed bug in dotButton and Ctrl shortcut

Line 
1 private const DEBUG:Boolean = false;
2
3 import flash.events.Event;
4 import flash.events.KeyboardEvent;
5 import flash.geom.Point;
6 import flash.ui.Keyboard;
7 import flash.utils.ByteArray;
8
9 import mx.controls.Alert;
10 import mx.core.UIComponent;
11 import mx.events.FlexEvent;
12 import mx.events.NumericStepperEvent;
13 import mx.events.SliderEvent;
14 import mx.managers.PopUpManager;
15
16 import org.libspark.gunyarapaint.controls.GPPasswordWindowControl;
17 import org.libspark.gunyarapaint.entities.GPLogger;
18 import org.libspark.gunyarapaint.entities.GPPen;
19 import org.libspark.nicopedia.Com;
20
21 private var basex:uint, basey:uint, baseWidth:uint, baseHeight:uint;
22
23 private var oekakiId:uint;
24 private var redirectUrl:String;
25
26 private var _logger:GPLogger;
27
28 private const ALERT_TITLE:String = 'お絵カキコ';
29 private const MAX_CANVAS_WIDTH:uint = 500;
30 private const MAX_CANVAS_HEIGHT:uint = 500;
31 private const MIN_CANVAS_WIDTH:uint = 16;
32 private const MIN_CANVAS_HEIGHT:uint = 16;
33
34 // ポップアップの初期位置
35 private var initCanvasWindowPos:Point;
36 private var initPenDetailWindowPos:Point;
37 private var initGPLayerWindowPos:Point;
38 private var initCanvasWindowSize:Point;
39
40 public function init():void {
41   var width:uint, height:uint, undoBufferSize:uint;
42
43   if (DEBUG) {
44     versionLabel.text += 'debug';
45     /*
46     parameters['oekakiId'] = 23724;
47     parameters['baseImgUrl'] = 'http://dic.nicovideo.jp/oekaki_layers/23724';
48     parameters['baseImgInfoUrl'] = 'http://dic.nicovideo.jp/oekaki_info/23724';
49     */
50     parameters['postUrl'] = 'http://dic.dev.nicovideo.jp/'
51     parameters['cookie'] = 'cookie'
52     parameters['magic'] = 'magic'
53     parameters['redirectUrl'] = 'http://dic.dev.nicovideo.jp/'
54     parameters['undoBufferSize'] = 16;
55     parameters['canvasWidth'] = 500;
56     parameters['canvasHeight'] = 500;
57     // debug buttons
58     logPlayButton.addEventListener(FlexEvent.BUTTON_DOWN, playLogHandler);
59     logPlayButton.visible = true;
60     checkPngButton.visible = true;
61   }
62
63   this.enabled = false;
64   gpCanvasWindow.enabled = false;
65   penDetailWindow.enabled = false;
66   gpLayerWindow.enabled = false;
67
68   // キャンバス回転スライダ
69   canvasZoom.addEventListener(SliderEvent.CHANGE, canvasZoomHandler);
70   canvasZoom.addEventListener(SliderEvent.THUMB_DRAG, canvasZoomHandler);
71   canvasRotate.addEventListener(SliderEvent.CHANGE, canvasRotateHandler);
72   canvasRotate.addEventListener(SliderEvent.THUMB_DRAG, canvasRotateHandler);
73   zoomResetButton.addEventListener(FlexEvent.BUTTON_DOWN, zoomResetButtonHandler);
74   rotateResetButton.addEventListener(FlexEvent.BUTTON_DOWN, rotateResetButtonHandler);
75  
76   // アンドゥ・リドゥ
77   undoButton.addEventListener(FlexEvent.BUTTON_DOWN, undoButtonHandler);
78   redoButton.addEventListener(FlexEvent.BUTTON_DOWN, redoButtonHandler);
79    
80   // 補助線
81   additionalNumberStepper.addEventListener(NumericStepperEvent.CHANGE, additionalNumberStepperHandler);
82   additionalBoxCheckBox.addEventListener(Event.CHANGE, additionalBoxCheckBoxHandler);
83   additionalSkewCheckBox.addEventListener(Event.CHANGE, additionalSkewCheckBoxHandler);
84  
85   // 投稿
86   postOekakiButton.addEventListener(FlexEvent.BUTTON_DOWN, postOekakiButtonHandler);
87
88   // window状態
89   windowsResetButton.addEventListener(FlexEvent.BUTTON_DOWN, windowsResetButtonHandler);
90   // ふっかつのじゅもん
91   passwordButton.addEventListener(FlexEvent.BUTTON_DOWN, passwordButtonHandler);
92
93   // ポップアップさせて、そいつらの初期位置を覚える
94
95   PopUpManager.addPopUp(gpCanvasWindow, this);
96   PopUpManager.addPopUp(penDetailWindow, this);
97   PopUpManager.addPopUp(gpLayerWindow, this);
98   initCanvasWindowPos = new Point(gpCanvasWindow.x, gpCanvasWindow.y);
99   initPenDetailWindowPos = new Point(penDetailWindow.x, penDetailWindow.y);
100   initGPLayerWindowPos = new Point(gpLayerWindow.x, gpLayerWindow.y);
101   initCanvasWindowSize = new Point(gpCanvasWindow.width, gpCanvasWindow.height);
102
103   if (parameters['postUrl'] && parameters['cookie'] && parameters['magic'] && parameters['redirectUrl']) {
104     postOekakiButton.enabled = true;
105     redirectUrl = parameters['redirectUrl'];
106   }
107   if (parameters['undoBufferSize']) {
108     undoBufferSize = int(parameters['undoBufferSize']);
109     if (undoBufferSize < 0) {
110       Alert.show('最大アンドゥ回数が少なすぎます。', ALERT_TITLE);     
111     }
112     if (undoBufferSize > 32) {
113       Alert.show('最大アンドゥ回数が多すぎます。', ALERT_TITLE);     
114     }
115   } else {
116     return;
117   }
118   if (parameters['oekakiId'] && parameters['baseImgUrl']) {
119     oekakiId = uint(parameters['oekakiId']);
120     new Com().loadURL(parameters['baseImgUrl'], getBaseImgHandler);
121   } else {
122     if (parameters['canvasWidth'] && parameters['canvasHeight']) {
123       width = int(parameters['canvasWidth']);
124       height = int(parameters['canvasHeight']);
125       if (width < MIN_CANVAS_WIDTH || height < MIN_CANVAS_HEIGHT) {
126         Alert.show('キャンバスサイズが小さすぎます。', ALERT_TITLE);
127         return;
128       }
129       if (width > MAX_CANVAS_WIDTH || height > MAX_CANVAS_HEIGHT) {
130         Alert.show('キャンバスサイズが大きすぎます。', ALERT_TITLE);
131         return;
132       }
133     } else {
134       return;
135     }
136     _logger = GPLogger.createForDraw(width, height, undoBufferSize, null, null);
137     initGunyaraPaintCanvas();
138   }
139 }
140
141 // ふっかつのじゅもんからの復活
142
143 public function deserialize(s:String):void {
144   // TODO: 実装
145   // var log:GPLogger = GPLogger.deserialize(s);
146 }
147
148 private function windowsResetButtonHandler(evt:FlexEvent):void {
149   gpCanvasWindow.move(initCanvasWindowPos.x, initCanvasWindowPos.y);
150   setRotate(0);
151   penDetailWindow.move(initPenDetailWindowPos.x, initPenDetailWindowPos.y);
152   gpLayerWindow.move(initGPLayerWindowPos.x, initGPLayerWindowPos.y);
153   gpCanvasWindow.width = initCanvasWindowSize.x;
154   gpCanvasWindow.height = initCanvasWindowSize.y;
155 }
156
157 private function passwordButtonHandler(evt:FlexEvent):void {
158   var w:GPPasswordWindowControl = new GPPasswordWindowControl();
159   mx.managers.PopUpManager.addPopUp(w, this, true);
160   // w.password = gpCanvas.logger.password;
161 }
162
163 private function appComplete():void {
164   stage.addEventListener(KeyboardEvent.KEY_DOWN, shortCutKeyDownHandler); 
165   stage.addEventListener(KeyboardEvent.KEY_UP, shortCutKeyUpHandler); 
166   stage.addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
167   stage.addEventListener(MouseEvent.MOUSE_OUT, mouseUpHandler); // これを入れるとマズい。
168 }
169
170 // canvasでの外のmouseUpをcanvasに通知 
171 private function mouseUpHandler(evt:MouseEvent):void {
172   if (_logger) {
173     _logger.extMouseUp(evt);
174   }
175 }
176 private function set allEnabled(value:Boolean):void {
177   this.enabled = value;
178   gpCanvasWindow.enabled = value;
179   penDetailWindow.enabled = value;
180   gpLayerWindow.enabled = value;
181 }
182 private function initGunyaraPaintCanvas():void {
183   toolCanvas.x = (this.width - toolCanvas.width) / 2;
184   allEnabled = true;
185 }
186
187 // TODO: もう本当に汚い… これのスコープを短くする。
188 private var baseImg:BitmapData;
189
190 private function getBaseImgHandler(com:Com):void {
191   baseImg = Bitmap(com.content).bitmapData;
192   if (parameters['baseImgInfoUrl']) {
193     new Com().sendGetUrlRequest(parameters['baseImgInfoUrl'], getBaseImgInfoHandler);
194   } else {
195     // 画像のサイズがそのままwidth/height
196     // このロジックは通らなくなっているはずだが、移行措置のため残してある。
197     // 消してもよい。
198     baseImgToCanvas(baseImg.width, baseImg.height, parameters['undoBufferSize'], null);
199   }
200 }
201
202 private function getBaseImgInfoHandler(com:Com):void {
203   var info:Object = com.jsonObject;
204   if (!info) {
205     info = {'width': baseImg.width, 'height': baseImg.height};
206   }
207   baseImgToCanvas(info['width'], info['height'], parameters['undoBufferSize'], info);
208 }
209
210 private function baseImgToCanvas(width:uint, height:uint, undoBufferSize:uint, baseInfo:Object):void {
211     _logger = GPLogger.createForDraw(width, height, undoBufferSize,
212                                      baseImg, baseInfo);
213     gpCanvasWindow.logger = _logger;
214     initGunyaraPaintCanvas();
215     this.enabled = true; 
216 }
217
218 private function canvasZoomHandler(evt:SliderEvent):void {
219   gpCanvasWindow.zoomCanvas(evt.value);
220 }
221
222 private function canvasRotateHandler(evt:SliderEvent):void {
223   gpCanvasWindow.rotateCanvas(evt.value);
224 }
225
226 private function undoButtonHandler(evt:FlexEvent):void {
227   _logger.eventUndo();
228 }
229 private function redoButtonHandler(evt:FlexEvent):void {
230   _logger.eventRedo();
231 }
232 private function additionalNumberStepperHandler(evt:NumericStepperEvent):void {
233   _logger.eventSetAdditionalNumber(evt.value);
234 }
235 private function additionalBoxCheckBoxHandler(evt:Event):void {
236   _logger.eventSetAdditionalBox(evt.target.selected);
237 }
238 private function additionalSkewCheckBoxHandler(evt:Event):void {
239   _logger.eventSetAdditionalSkew(evt.target.selected);
240 }
241 public function changeUndoRedoHandler(undoCount:uint, redoCount:uint):void {
242   if (undoCount > 0) {
243     undoButton.label = 'アンドゥ (' + undoCount + ')';
244     undoButton.enabled = true;
245   } else {
246     undoButton.label = 'アンドゥ';
247     undoButton.enabled = false;
248   }
249   if (redoCount > 0) {
250     redoButton.label = 'リドゥ (' + redoCount + ')';
251     redoButton.enabled = true;
252   } else {
253     redoButton.label = 'リドゥ';
254     redoButton.enabled = false;
255   }
256 }
257
258 private function commCompleteHandler(com:Com):void {
259   try {
260     if (com.errStr) {
261       // error
262       Alert.show(com.errStr, ALERT_TITLE);
263     } else if (com.data.toString() != '') {
264       Alert.show(com.data.toString(), ALERT_TITLE);
265     } else {
266       // redirect
267       Com.redirect(redirectUrl);
268       return;
269     }
270   } catch (e:Error) {
271     Alert.show('何かしらのエラーが起きました…再投稿お願いいたします。', ALERT_TITLE);
272   }
273   allEnabled = true;
274   extChangeAlertOnUnload(true);
275 }
276
277 private function postOekakiButtonHandler(evt:Event):void {
278   if (messageTextArea.text == '') {
279     Alert.show('書き込みが空です。絵のタイトルなどの情報を書き込んでください。', ALERT_TITLE);
280     return;
281   }
282   if (_logger.logCount == 0) {
283     Alert.show('絵が描かれていません。お絵かきしてください。', ALERT_TITLE);
284     return;
285   }
286   try {
287     allEnabled = false;
288     extChangeAlertOnUnload(false);
289     var com:Com = new Com();
290     com.postOekaki(this,
291                    parameters['postUrl'],
292                    parameters['magic'],
293                    parameters['cookie'],
294                    fromTextInput.text,
295                    messageTextArea.text,
296                    oekakiId,
297                    _logger.dataForPost,
298                    commCompleteHandler
299                   );
300   } catch (e:Error) {
301     allEnabled = true;
302     extChangeAlertOnUnload(true);
303     Alert.show(e.message, ALERT_TITLE);
304   }
305 }
306
307 private function rotateResetButtonHandler(evt:Event):void {
308   setRotate(0);
309 }
310
311 private function zoomResetButtonHandler(evt:Event):void {
312   setZoom(1);
313 }
314
315 private function setRotate(v:Number):void {
316   canvasRotate.value = v;
317   gpCanvasWindow.rotateCanvas(canvasRotate.value);
318 }
319
320 private function setZoom(v:Number):void {
321   canvasZoom.value = v;
322   gpCanvasWindow.zoomCanvas(canvasZoom.value); 
323 }
324
325 private function shortCutKeyDownHandler(evt:KeyboardEvent):void {
326   if (evt.target == this.fromTextInput ||
327       evt.target == this.messageTextArea) {
328     return;
329   }
330   switch (evt.keyCode) {
331   case Keyboard.CONTROL:
332     penDetailWindow.penDetail.setTool(GPPen.PEN_MODE_DROPPER, null, true);
333     break;
334   case Keyboard.SHIFT:
335     break;
336   case Keyboard.SPACE:
337     penDetailWindow.penDetail.setTool(GPPen.PEN_MODE_HANDTOOL, null, true);
338     break;
339   case 48: // 0
340   case 96: // ten-key 0
341     if (evt.shiftKey) {
342       setRotate(0);
343     } else {
344       setZoom(1);
345     }
346     break;
347   case 89: // y
348     _logger.eventRedo();
349     break;
350   case 90: // z
351     _logger.eventUndo();
352     break;
353   case 107: // ten key +
354     // +
355     setZoom(canvasZoom.value + 1);
356     break;
357   case 109: // ten key -
358     // -
359     setZoom(canvasZoom.value - 1);
360     break;
361   case 187:
362     if (evt.shiftKey) {
363       // +
364       setZoom(canvasZoom.value + 1);
365     }
366     break;
367   case 189:
368     // -
369     setZoom(canvasZoom.value - 1);
370     break;
371   default:
372     // Alert('' + evt.keyCode);
373     break;
374   }
375 }
376
377 private function shortCutKeyUpHandler(evt:KeyboardEvent):void {
378   if (evt.target == this.fromTextInput ||
379       evt.target == this.messageTextArea) {
380     return;
381   }
382   switch (evt.keyCode) {
383   case Keyboard.CONTROL:
384     penDetailWindow.penDetail.resetPenTool();
385     break;
386   case Keyboard.SPACE:
387     penDetailWindow.penDetail.resetPenTool();
388     break;
389   return;
390   }
391 }
392
393 /* for debug */
394
395 private var _debugLogger:GPLogger;
396 private function playLogHandler(evt:FlexEvent):void {
397   var lb:ByteArray = _logger.compressedLog;
398   lb.uncompress();
399   _debugLogger = GPLogger.createFromByteArray(lb, false, null, null);
400
401   var tui:UIComponent = new UIComponent();
402   tui.graphics.beginFill(0xFFFFFF);
403   tui.graphics.drawRect(0, 0, _debugLogger.canvasWidth, _debugLogger.canvasHeight);
404   tui.addChild(_debugLogger.layerArray.view);
405   this.addChild(tui);
406
407   // this.rawChildren.addChild(_debugLogger.layerArray.view);
408   _debugLogger.play(1000, function ():void {});
409 }
410
411 private function extChangeAlertOnUnload(b:Boolean):void {
412   if (ExternalInterface.available) {
413     try {
414       ExternalInterface.call("changeAlertOnUnload", b);
415     } catch (e:SecurityError) {
416     } catch (e:Error) {
417     }
418   }
419 }
Note: リポジトリブラウザについてのヘルプは TracBrowser を参照してください。