1 package jp.sourceforge.gokigen.memoma.drawers;
3 import java.util.Enumeration;
4 import android.app.Activity;
5 import android.content.SharedPreferences;
6 import android.graphics.Bitmap;
7 import android.graphics.BitmapFactory;
8 import android.graphics.Canvas;
9 import android.graphics.Color;
10 import android.graphics.DashPathEffect;
11 import android.graphics.Paint;
12 import android.graphics.Path;
13 import android.graphics.RectF;
14 import android.preference.PreferenceManager;
15 import android.util.Log;
16 import android.view.MotionEvent;
17 import android.view.GestureDetector;
18 import android.view.ScaleGestureDetector;
19 import android.widget.SeekBar;
20 import android.widget.TextView;
22 import jp.sourceforge.gokigen.memoma.GokigenSurfaceView;
23 import jp.sourceforge.gokigen.memoma.IObjectSelectionReceiver;
24 import jp.sourceforge.gokigen.memoma.fileio.ImageLoader;
25 import jp.sourceforge.gokigen.memoma.Main;
26 import jp.sourceforge.gokigen.memoma.R;
27 import jp.sourceforge.gokigen.memoma.holders.LineStyleHolder;
28 import jp.sourceforge.gokigen.memoma.holders.MeMoMaConnectLineHolder;
29 import jp.sourceforge.gokigen.memoma.holders.MeMoMaObjectHolder;
30 import jp.sourceforge.gokigen.memoma.holders.OperationModeHolder;
38 public class MeMoMaCanvasDrawer implements ICanvasDrawer, GestureDetector.OnGestureListener, ScaleGestureDetector.OnScaleGestureListener, SeekBar.OnSeekBarChangeListener
40 public static final float OBJECTLABEL_MARGIN = 8.0f;
41 public static final float OBJECTLABEL_MARGIN_WIDTH = 24.0f;
43 public static final int BACKGROUND_COLOR_DEFAULT = 0xff004000;
44 private int backgroundColor = BACKGROUND_COLOR_DEFAULT;
46 private MeMoMaObjectHolder.PositionObject selectedPosition = null;
47 private float tempPosX = Float.MIN_VALUE;
48 private float tempPosY = Float.MIN_VALUE;
49 private float downPosX = Float.MIN_VALUE;
50 private float downPosY = Float.MIN_VALUE;
52 // 以下の値は、MeMoMaListenerで初期値を設定する
53 private int objectStyle = MeMoMaObjectHolder.DRAWSTYLE_RECTANGLE;
55 private LineStyleHolder lineStyleHolder = null;
57 private float drawScale = 1.0f; // 表示の倍率
58 private float drawTransX = 0.0f; // 並行移動距離 (X)
59 private float drawTransY = 0.0f; // 並行移動距離 (Y)
60 private boolean onScaling = false; // ピンチイン・ピンチアウト操作しているかどうかを示す
61 private int currentScaleBar= 50; // 現在のピンチイン・ピンチアウト倍率
63 private boolean onGestureProcessed = false; // 長押し時の処理を行なっているかどうかを示す。
65 private float screenWidth = 0.0f; // 表示領域の幅
66 private float screenHeight = 0.0f; // 表示領域の高さ
68 private int displayObjectInformation = 1; // オブジェクトラベルの表示
70 private String backgroundBitmapUri = null;
71 private Bitmap backgroundBitmap = null;
73 private MeMoMaObjectHolder objectHolder = null;
74 private MeMoMaConnectLineHolder lineHolder = null;
75 private IObjectSelectionReceiver selectionReceiver = null;
77 private GestureDetector gestureDetector = null;
78 private ScaleGestureDetector scaleGestureDetector = null;
80 private Activity parent = null;
86 public MeMoMaCanvasDrawer(Activity argument, MeMoMaObjectHolder object, LineStyleHolder styleHolder, IObjectSelectionReceiver receiver)
88 objectHolder = object;
89 lineHolder = objectHolder.getConnectLineHolder();
90 selectionReceiver = receiver;
91 lineStyleHolder = styleHolder;
95 gestureDetector = new GestureDetector(argument, this);
96 scaleGestureDetector = new ScaleGestureDetector(argument, this);
99 restoreTranslateAndZoomScale();
104 * (ここで指定された形状のチェックを行っておく。)
108 public void setObjectStyle(int style)
112 case MeMoMaObjectHolder.DRAWSTYLE_OVAL:
113 case MeMoMaObjectHolder.DRAWSTYLE_ROUNDRECT:
114 case MeMoMaObjectHolder.DRAWSTYLE_RECTANGLE:
115 case MeMoMaObjectHolder.DRAWSTYLE_DIAMOND:
116 case MeMoMaObjectHolder.DRAWSTYLE_KEYBOARD:
117 case MeMoMaObjectHolder.DRAWSTYLE_PAPER:
118 case MeMoMaObjectHolder.DRAWSTYLE_DRUM:
119 case MeMoMaObjectHolder.DRAWSTYLE_PARALLELOGRAM:
120 case MeMoMaObjectHolder.DRAWSTYLE_HEXAGONAL:
121 case MeMoMaObjectHolder.DRAWSTYLE_CIRCLE:
122 case MeMoMaObjectHolder.DRAWSTYLE_NO_REGION:
123 case MeMoMaObjectHolder.DRAWSTYLE_LOOP_START:
124 case MeMoMaObjectHolder.DRAWSTYLE_LOOP_END:
125 case MeMoMaObjectHolder.DRAWSTYLE_LEFT_ARROW:
126 case MeMoMaObjectHolder.DRAWSTYLE_DOWN_ARROW:
127 case MeMoMaObjectHolder.DRAWSTYLE_UP_ARROW:
128 case MeMoMaObjectHolder.DRAWSTYLE_RIGHT_ARROW:
133 objectStyle = MeMoMaObjectHolder.DRAWSTYLE_RECTANGLE;
142 public void updateBackgroundBitmap(String uri, int width, int height)
145 backgroundBitmapUri = uri;
147 // とりあえず、背景画像をクリアしてガベコレする。
148 backgroundBitmap = null;
150 if (uri.isEmpty() == true)
152 // 背景画像の指定がなかったので、ここでリターンする。
157 // とりあえず設定する情報をログに残してみる
158 Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::updateBackgroundBitmap() : w:" + width + " , h:"+ height + " " + uri);
161 backgroundBitmap = ImageLoader.getBitmapFromUri(parent, ImageLoader.parseUri(uri), width, height);
165 Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::updateBackgroundBitmap() : " + uri + " , "+ ex.toString());
166 ex.printStackTrace();
167 backgroundBitmap = null;
168 backgroundBitmapUri = "";
179 public void setBackgroundUri(String uri)
181 backgroundBitmapUri = uri;
189 public void setBackgroundColor(String colorString)
193 backgroundColor = Color.parseColor(colorString);
199 //Log.v(Main.APP_IDENTIFIER, "Ex:" + ex.toString() + " " + ex.getMessage());
201 backgroundColor = BACKGROUND_COLOR_DEFAULT;
208 public void prepareToStart(int width, int height)
210 Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::prepareToStart() " + "x:" + width + " , " + "y:" + height);
213 //updateBackgroundBitmap(backgroundBitmapUri, width, height);
216 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
217 displayObjectInformation = Integer.parseInt(preferences.getString("objectPrintData", "1"));
221 * 画面の大きさが変わってしまった場合...
224 public void changedScreenProperty(int format, int width, int height)
227 updateBackgroundBitmap(backgroundBitmapUri, width, height);
231 screenHeight = height;
233 Log.v(Main.APP_IDENTIFIER, "changedScreenProperty() " + "x:" + width + " , " + "y:" + height);
238 * キャンバスにオブジェクト(と接続線)を表示する
241 public void drawOnCanvas(Canvas canvas)
243 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::drawOnCanvas()");
247 //canvas.drawColor(Color.argb(backgroundColorAlfa, backgroundColorRed, backgroundColorGreen, backgroundColorBlue), Mode.CLEAR);
248 canvas.drawColor(backgroundColor);
250 // 背景画像が設定されていた場合は、背景画像を描画する
251 if (backgroundBitmap != null)
253 canvas.drawBitmap(backgroundBitmap, 0, 0, new Paint());
257 canvas.translate(drawTransX, drawTransY);
260 canvas.scale(drawScale, drawScale);
262 // オブジェクト間の接続線をすべて表示する
263 drawConnectionLines(canvas, 0.0f, 0.0f);
266 drawObjects(canvas, 0.0f, 0.0f);
268 /** 移動中かどうかのチェックを行う。 **/
269 if (isFlicking(canvas) == true)
271 // 移動中の場合、フリック時の軌跡と現在位置を表示する
272 drawTrackAndPositions(canvas);
277 // 例外発生...でもそのときには何もしない
278 Log.v(Main.APP_IDENTIFIER, "drawOnCanvas() ex: " + ex.getMessage());
283 * オブジェクトをBitmapCanvas上に描く
286 public void drawOnBitmapCanvas(Canvas canvas, float offsetX, float offsetY)
290 Paint paint = new Paint();
293 canvas.drawColor(backgroundColor);
295 // 背景画像が設定されていた場合は、背景画像を描画する
296 if (backgroundBitmap != null)
298 canvas.drawBitmap(backgroundBitmap, offsetX, offsetY, paint);
301 // オブジェクト間の接続線をすべて表示する
302 drawConnectionLines(canvas, offsetX, offsetY);
305 drawObjects(canvas, offsetX, offsetY);
307 // タイトルとめもまのアイコンを表示する : 文字の色は黒でいいのかな...
308 Bitmap bitmap = BitmapFactory.decodeResource(parent.getResources(), R.drawable.icon1);
309 canvas.drawBitmap(bitmap, 2.0f, 2.0f, paint);
310 canvas.drawText(objectHolder.getDataTitle(), (bitmap.getWidth() + 10.0f), 32.0f, paint);
315 // 例外発生...でもそのときには何もしない
316 Log.v(Main.APP_IDENTIFIER, "drawOnBitmapCanvas() ex: " + ex.toString() + " " + ex.getMessage());
325 private void drawConnectionLines(Canvas canvas, float offsetX, float offsetY)
327 // オブジェクトの色と枠線を設定する (連続線用)
328 Paint paint = new Paint();
329 paint.setColor(Color.WHITE);
330 paint.setStyle(Paint.Style.STROKE);
332 // オブジェクトの色と枠線を設定する (点線用)
333 Paint dashLinePaint = new Paint();
334 dashLinePaint.setColor(Color.WHITE);
335 dashLinePaint.setStyle(Paint.Style.STROKE);
336 dashLinePaint.setPathEffect(new DashPathEffect(new float[]{ 5.0f, 5.0f }, 0));
338 // オブジェクトの描画 (保持しているものはすべて表示する)
339 Enumeration<Integer> keys = lineHolder.getLineKeys();
340 while (keys.hasMoreElements())
342 Integer key = keys.nextElement();
343 MeMoMaConnectLineHolder.ObjectConnector line = lineHolder.getLine(key);
347 drawLine(canvas, paint, dashLinePaint, line, offsetX, offsetY);
351 // ここは呼ばれないはず。。。消したはずのものが残っている
352 Log.v(Main.APP_IDENTIFIER, "DETECTED DELETED LINE");
364 public void drawLine(Canvas canvas, Paint paint, Paint dashPaint, MeMoMaConnectLineHolder.ObjectConnector line, float offsetX, float offsetY)
368 if ((objectHolder == null)||(canvas == null))
374 MeMoMaObjectHolder.PositionObject from = objectHolder.getPosition(line.fromObjectKey);
375 MeMoMaObjectHolder.PositionObject to = objectHolder.getPosition(line.toObjectKey);
376 if ((from == null)||(to == null))
383 paint.setStrokeWidth((float) line.lineThickness);
386 dashPaint.setStrokeWidth((float) line.lineThickness);
388 // ラインのスタイル(連続線 or 点線)を設定する
389 Paint linePaint = (line.lineShape == LineStyleHolder.LINESHAPE_DASH) ? dashPaint : paint;
391 // 初期値として、各オブジェクトの中心座標を設定する
392 float startX = from.rect.centerX() + offsetX;
393 float endX = to.rect.centerX() + offsetX;
394 float startY = from.rect.centerY() + offsetY;
395 float endY = to.rect.centerY() + offsetY;
398 if (from.rect.bottom < to.rect.top)
400 startY = from.rect.bottom + offsetY;
401 endY = to.rect.top + offsetY;
403 else if (from.rect.top > to.rect.bottom)
405 startY = from.rect.top + offsetY;
406 endY = to.rect.bottom + offsetY;
409 // X座標の線の位置を補正する (Y座標が補正されていないとき)
410 if ((startY != (from.rect.top + offsetY))&&(startY != (from.rect.bottom + offsetY)))
412 if (from.rect.right < to.rect.left)
414 startX = from.rect.right + offsetX;
415 endX = to.rect.left + offsetX;
417 else if (from.rect.left > to.rect.right)
419 startX = from.rect.left + offsetX;
420 endX = to.rect.right + offsetX;
424 if ((line.lineStyle == LineStyleHolder.LINESTYLE_TREESTYLE_NO_ARROW)||
425 (line.lineStyle == LineStyleHolder.LINESTYLE_TREESTYLE_L_ARROW)||
426 (line.lineStyle == LineStyleHolder.LINESTYLE_TREESTYLE_R_ARROW))
429 if (startX == (from.rect.centerX() + offsetX))
431 float middleY = (startY + endY) / 2;
432 canvas.drawLine(startX, startY, startX, middleY, linePaint);
433 canvas.drawLine(startX, middleY, endX, middleY, linePaint);
434 canvas.drawLine(endX, middleY, endX, endY, linePaint);
437 if (line.lineStyle == LineStyleHolder.LINESTYLE_TREESTYLE_L_ARROW)
440 ObjectShapeDrawer.drawArrowTree(canvas, paint, startX,startY, middleY, false);
442 else if (line.lineStyle == LineStyleHolder.LINESTYLE_TREESTYLE_R_ARROW)
445 ObjectShapeDrawer.drawArrowTree(canvas, paint, endX, endY, middleY, false);
450 float middleX = (startX + endX) / 2;
451 canvas.drawLine(startX, startY, middleX, startY, linePaint);
452 canvas.drawLine(middleX, startY, middleX, endY, linePaint);
453 canvas.drawLine(middleX, endY, endX, endY, linePaint);
455 /** やじるし(三角形)をつける処理 **/
456 if (line.lineStyle == LineStyleHolder.LINESTYLE_TREESTYLE_L_ARROW)
459 ObjectShapeDrawer.drawArrowTree(canvas, paint, startX, startY, middleX, true);
461 else if (line.lineStyle == LineStyleHolder.LINESTYLE_TREESTYLE_R_ARROW)
464 ObjectShapeDrawer.drawArrowTree(canvas, paint, endX,endY, middleX, true);
468 else if ((line.lineStyle == LineStyleHolder.LINESTYLE_CURVESTYLE_NO_ARROW)||
469 (line.lineStyle == LineStyleHolder.LINESTYLE_CURVESTYLE_L_ARROW)||
470 (line.lineStyle == LineStyleHolder.LINESTYLE_CURVESTYLE_R_ARROW))
473 float middleX = (startX + endX) / 2;
474 float middleY = (startY + endY) / 2;
475 float x1 = (startX + middleX) / 2;
477 float x2 = (middleX + endX) / 2;
480 Path pathLine = new Path();
481 pathLine.moveTo(startX, startY);
482 pathLine.cubicTo(x1, y1, x2, y2, endX, endY);
483 canvas.drawPath(pathLine, linePaint);
486 if (line.lineStyle == LineStyleHolder.LINESTYLE_CURVESTYLE_L_ARROW)
489 ObjectShapeDrawer.drawArrow(canvas, paint, startX, startY, endX, endY);
491 else if (line.lineStyle == LineStyleHolder.LINESTYLE_CURVESTYLE_R_ARROW)
494 ObjectShapeDrawer.drawArrow(canvas, paint, endX, endY, startX, startY);
497 else // if (line.lineStyle == MeMoMaConnectLineHolder.LINESTYLE_STRAIGHT)
500 canvas.drawLine(startX, startY, endX, endY, linePaint);
503 if (line.lineStyle == LineStyleHolder.LINESTYLE_STRAIGHT_L_ARROW)
506 ObjectShapeDrawer.drawArrow(canvas, paint, startX, startY, endX, endY);
508 else if (line.lineStyle == LineStyleHolder.LINESTYLE_STRAIGHT_R_ARROW)
511 ObjectShapeDrawer.drawArrow(canvas, paint, endX, endY, startX, startY);
518 Log.v(Main.APP_IDENTIFIER, "EXCEPTION :" + ex.toString());
523 * オブジェクトを動かしている最中かどうかの判定を行う。
526 * @return trueなら、動かしている最中
528 private boolean isFlicking(Canvas canvas)
530 //int width = canvas.getWidth();
531 //int height = canvas.getHeight();
532 if ((tempPosX == Float.MIN_VALUE)||(tempPosY == Float.MIN_VALUE))
544 private void drawTrackAndPositions(Canvas canvas)
547 float x = (tempPosX - drawTransX) / drawScale;
548 float y = (tempPosY - drawTransY) / drawScale;
550 Paint paint = new Paint();
551 paint.setStyle(Paint.Style.STROKE);
552 paint.setColor(Color.GRAY);
553 if (selectedPosition != null)
555 float objX = (selectedPosition.rect.right - selectedPosition.rect.left) / 2;
556 float objY = (selectedPosition.rect.bottom - selectedPosition.rect.top) / 2;
557 canvas.drawLine(selectedPosition.rect.centerX(), selectedPosition.rect.centerY(), x, y, paint);
558 canvas.drawRect((x - objX), (y - objY), (x + objX), (y + objY), paint);
561 drawObject(canvas, selectedPosition, true, 0.0f, 0.0f);
563 else // オブジェクト非選択時の表示
565 int data = selectionReceiver.touchedVacantArea();
566 if (data == OperationModeHolder.OPERATIONMODE_MOVE)
568 // 移動モードのとき... (表示領域を移動させる)
569 drawTransX = (tempPosX - downPosX);
570 drawTransY = (tempPosY - downPosY);
573 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
574 SharedPreferences.Editor editor = preferences.edit();
575 editor.putFloat("drawTransX", drawTransX);
576 editor.putFloat("drawTransY", drawTransY);
582 paint.setColor(Color.YELLOW);
583 canvas.drawLine(((downPosX) / drawScale), ((downPosY) / drawScale), x, y, paint);
592 private void drawObject(Canvas canvas, MeMoMaObjectHolder.PositionObject object, boolean isMoving, float offsetX, float offsetY)
594 float label_offsetX = OBJECTLABEL_MARGIN;
595 float label_offsetY = 0.0f;
598 Paint paint = new Paint();
599 if (isMoving == true)
601 paint.setColor(Color.YELLOW);
602 paint.setStyle(Paint.Style.STROKE);
603 paint.setStrokeWidth(object.strokeWidth);
607 paint.setColor(object.objectColor);
608 paint.setStyle(Paint.Style.valueOf(object.paintStyle));
609 paint.setStrokeWidth(object.strokeWidth);
613 RectF objectShape = new RectF(object.rect);
614 objectShape.left = objectShape.left + offsetX;
615 objectShape.right = objectShape.right + offsetX;
616 objectShape.top = objectShape.top + offsetY;
617 objectShape.bottom = objectShape.bottom + offsetY;
619 if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_OVAL)
622 label_offsetY = ObjectShapeDrawer.drawObjectOval(canvas, objectShape, paint);
624 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_ROUNDRECT)
627 label_offsetY = ObjectShapeDrawer.drawObjectRoundRect(canvas, objectShape, paint);
629 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_DIAMOND)
632 label_offsetY = ObjectShapeDrawer.drawObjectDiamond(canvas, objectShape, paint);
633 label_offsetX = OBJECTLABEL_MARGIN;
635 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_KEYBOARD)
638 label_offsetY = ObjectShapeDrawer.drawObjectKeyboard(canvas, objectShape, paint);
640 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_PARALLELOGRAM)
643 label_offsetY = ObjectShapeDrawer.drawObjectParallelogram(canvas, objectShape, paint);
645 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_HEXAGONAL)
648 label_offsetY = ObjectShapeDrawer.drawObjectHexagonal(canvas, objectShape, paint);
650 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_PAPER)
653 label_offsetY = ObjectShapeDrawer.drawObjectPaper(canvas, objectShape, paint);
655 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_DRUM)
658 label_offsetY = ObjectShapeDrawer.drawObjectDrum(canvas, objectShape, paint, Paint.Style.valueOf(object.paintStyle));
660 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_CIRCLE)
663 label_offsetY = ObjectShapeDrawer.drawObjectCircle(canvas, objectShape, paint);
665 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_NO_REGION)
667 // 枠なしを描画(?)する ... なにもしない
668 if (object.label.length() == 0)
670 // 何も表示しないとわからないので、ラベルが無いときには枠を表示する
671 ObjectShapeDrawer.drawObjectNoRegion(canvas, objectShape, paint);
674 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_LOOP_START)
677 label_offsetY = ObjectShapeDrawer.drawObjectLoopStart(canvas, objectShape, paint);
679 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_LOOP_END)
682 label_offsetY = ObjectShapeDrawer.drawObjectLoopEnd(canvas, objectShape, paint);
684 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_LEFT_ARROW)
687 label_offsetY = ObjectShapeDrawer.drawObjectLeftArrow(canvas, objectShape, paint);
689 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_DOWN_ARROW)
692 label_offsetY = ObjectShapeDrawer.drawObjectDownArrow(canvas, objectShape, paint);
694 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_UP_ARROW)
697 label_offsetY = ObjectShapeDrawer.drawObjectUpArrow(canvas, objectShape, paint);
699 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_RIGHT_ARROW)
702 label_offsetY = ObjectShapeDrawer.drawObjectRightArrow(canvas, objectShape, paint);
704 else // if (pos.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_RECTANGLE)
707 label_offsetY = ObjectShapeDrawer.drawObjectRect(canvas, objectShape, paint);
711 paint.setTextSize(object.fontSize);
714 ObjectShapeDrawer.drawTextLabel(canvas, paint, object, objectShape, displayObjectInformation, label_offsetX, label_offsetY);
722 private void drawObjects(Canvas canvas , float offsetX, float offsetY)
724 // オブジェクトの描画 (保持しているものはすべて表示する)
725 Enumeration<Integer> keys = objectHolder.getObjectKeys();
726 while (keys.hasMoreElements())
728 Integer key = keys.nextElement();
729 MeMoMaObjectHolder.PositionObject pos = objectHolder.getPosition(key);
730 drawObject(canvas, pos, false, offsetX, offsetY);
739 private boolean onTouchDown(MotionEvent event)
742 downPosX = event.getX() - drawTransX;
743 downPosY = event.getY() - drawTransY;
745 // タッチ位置をオブジェクト画像の座標に変換する
746 float x = downPosX / drawScale;
747 float y = downPosY / drawScale;
749 // タッチ位置にオブジェクトが存在するか確認する
750 selectedPosition = checkSelectedObject(x, y);
751 if (selectedPosition == null)
753 // 最初にタップしたときの位置を selectedPositionに設定する
754 int data = selectionReceiver.touchedVacantArea();
755 if (data == OperationModeHolder.OPERATIONMODE_CREATE)
757 // オブジェクト作成モードのとき...オブジェクトを生成する
758 selectedPosition = objectHolder.createPosition(x, y, objectStyle);
760 // オブジェクトが生成されたことを通知する
761 selectionReceiver.objectCreated();
763 else if (data ==OperationModeHolder.OPERATIONMODE_MOVE)
767 else // if (data ==ChangeDrawMode.OPERATIONMODE_DELETE)
780 private boolean onTouchUp(MotionEvent event)
782 boolean longPress = false;
783 if (onGestureProcessed == true)
785 // ロングタッチ中だった場合...フラグを落とす
786 onGestureProcessed = false;
790 // タッチ位置をオブジェクト画像の座標に変換する
791 float x = (event.getX() - drawTransX) / drawScale;
792 float y = (event.getY() - drawTransY) / drawScale;
794 if (selectedPosition == null)
796 int data = selectionReceiver.touchUppedVacantArea();
797 if (data == OperationModeHolder.OPERATIONMODE_DELETE)
799 if ((tempPosX == Float.MIN_VALUE)||(tempPosY == Float.MIN_VALUE)||(downPosX == Float.MIN_VALUE)||(downPosY == Float.MIN_VALUE))
801 // タッチが2つ揃っていないので、何もしない。
802 Log.v(Main.APP_IDENTIFIER, "onTouchUp : (" + downPosX + "," + downPosY + ") [" + drawScale + "] (" + tempPosX + "," + tempPosY + ") [" + drawTransX + "," + drawTransY + "]");
806 // タッチが離された位置にオブジェクトがおらず、オブジェクトが非選択だった場合...オブジェクトが繋がっているラインを切断する
807 disconnectObjects((downPosX / drawScale) , (downPosY / drawScale), ((tempPosX - drawTransX) / drawScale), ((tempPosY - drawTransY) / drawScale));
810 tempPosX = Float.MIN_VALUE;
811 tempPosY = Float.MIN_VALUE;
812 downPosX = Float.MIN_VALUE;
813 downPosY = Float.MIN_VALUE;
818 tempPosX = Float.MIN_VALUE;
819 tempPosY = Float.MIN_VALUE;
820 downPosX = Float.MIN_VALUE;
821 downPosY = Float.MIN_VALUE;
825 if (selectedPosition.rect.contains(x, y) == true)
827 // タッチが離された位置がタッチしたオブジェクトと同じ位置だった場合......
830 float diffX = Math.abs(event.getX() - drawTransX - downPosX);
831 float diffY = Math.abs(event.getY() - drawTransY - downPosY);
833 // タッチが離された位置が動いていた場合、オブジェクト位置の微調整と判定する。
834 if (((diffX > 2.0f)||(diffY > 2.0f))||(longPress == true))
836 // タッチが離された場所にはオブジェクトがなかった場合...オブジェクトをその位置に移動させる
837 Log.v(Main.APP_IDENTIFIER, "MOVE OBJECT : (" + diffX + "," + diffY + ")");
838 moveObjectPosition(x, y);
842 // タッチが押された位置と離された位置が同じ位置だった場合......アイテムが選択された、と認識する。
843 Log.v(Main.APP_IDENTIFIER, " ITEM SELECTED :" + x + "," + y);
844 if (selectionReceiver != null)
847 boolean isDraw = selectionReceiver.objectSelected(selectedPosition.getKey());
850 tempPosX = Float.MIN_VALUE;
851 tempPosY = Float.MIN_VALUE;
856 // タッチが離された位置にオブジェクトがいるかどうかのチェック
857 MeMoMaObjectHolder.PositionObject position = checkSelectedObject(x, y);
858 if ((position != null)&&(longPress == false))
860 // 他のオブジェクトと重なるように操作した、この場合は、オブジェクト間を線をつなげる
861 // (ただし、ボタンを長押ししていなかったとき。)
862 lineHolder.setLines(selectedPosition.getKey(), position.getKey(), lineStyleHolder);
863 tempPosX = Float.MIN_VALUE;
864 tempPosY = Float.MIN_VALUE;
868 // タッチが離された場所にはオブジェクトがなかった場合...オブジェクトをその位置に移動させる
869 moveObjectPosition(x, y);
871 tempPosX = Float.MIN_VALUE;
872 tempPosY = Float.MIN_VALUE;
873 float positionX = alignPosition(x, (objectSizeX / 2) * (-1));
874 float positionY = alignPosition(y, (objectSizeY / 2) * (-1));
875 selectedPosition.rect = new android.graphics.RectF(positionX, positionY, (positionX + objectSizeX), (positionY + objectSizeY));
876 // selectedPosition.drawStyle = objectStyle; // 不要、最初に生成するときだけ必要
887 private void moveObjectPosition(float x, float y)
889 tempPosX = Float.MIN_VALUE;
890 tempPosY = Float.MIN_VALUE;
891 float sizeX = selectedPosition.rect.right - selectedPosition.rect.left;
892 float sizeY = selectedPosition.rect.bottom - selectedPosition.rect.top;
894 float positionX = alignPosition(x, (sizeX / 2) * (-1));
895 float positionY = alignPosition(y, (sizeY / 2) * (-1));
896 selectedPosition.rect = new android.graphics.RectF(positionX, positionY, (positionX + sizeX), (positionY + sizeY));
902 * onTouchEvent : 画面がタッチした時のイベント処理
903 * (true なら、画面描画を実施する)
905 public boolean onTouchEvent(MotionEvent event)
907 boolean isDraw = false;
909 /** スケールジェスチャ(マルチタッチのジェスチャ)を拾う **/
910 isDraw = scaleGestureDetector.onTouchEvent(event);
911 if ((onScaling == true)||(scaleGestureDetector.isInProgress() == true))
917 /** 先にジェスチャーを拾ってみよう... **/
918 isDraw = gestureDetector.onTouchEvent(event);
921 Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onTouchEvent() : isDraw == true");
925 int action = event.getAction();
927 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onTouchEvent() : " + action);
928 if (action == MotionEvent.ACTION_DOWN)
931 isDraw = onTouchDown(event);
933 else if (action == MotionEvent.ACTION_MOVE)
935 // タッチされたまま動かされたときの処理
936 tempPosX = event.getX();
937 tempPosY = event.getY();
940 else if (action == MotionEvent.ACTION_UP)
943 isDraw = onTouchUp(event);
950 * タテヨコ位置を合わせられるよう、調整する。
954 private float alignPosition(float pos, float offset)
957 return (pos + offset);
961 * 位置から判定し、選択したオブジェクトを応答する
962 * (オブジェクトが選択されていない場合には、nullを応答する)
967 private MeMoMaObjectHolder.PositionObject checkSelectedObject(float x, float y)
969 Enumeration<Integer> keys = objectHolder.getObjectKeys();
970 //Log.v(Main.APP_IDENTIFIER, "CHECK POS " + x + "," + y);
971 while (keys.hasMoreElements())
973 Integer key = keys.nextElement();
974 MeMoMaObjectHolder.PositionObject pos = objectHolder.getPosition(key);
975 if (pos.rect.contains(x, y) == true)
977 Log.v(Main.APP_IDENTIFIER, "SELECTED :" + pos.rect.centerX() + "," + pos.rect.centerY() + " KEY :" + key);
980 //Log.v(Main.APP_IDENTIFIER, "NOT MATCH :" + pos.rect.centerX() + "," + pos.rect.centerY());
982 //Log.v(Main.APP_IDENTIFIER, "RETURN NULL...");
987 * 線と交差するオブジェクト接続線をすべて削除する
994 private void disconnectObjects(float startX, float startY, float endX, float endY)
996 Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::disconnectObjects() [" + startX + "," + startY +"]-[" + endX + "," + endY + "]");
999 Enumeration<Integer> keys = lineHolder.getLineKeys();
1000 while (keys.hasMoreElements())
1002 Integer key = keys.nextElement();
1003 MeMoMaConnectLineHolder.ObjectConnector line = lineHolder.getLine(key);
1007 MeMoMaObjectHolder.PositionObject from = objectHolder.getPosition(line.fromObjectKey);
1008 MeMoMaObjectHolder.PositionObject to = objectHolder.getPosition(line.toObjectKey);
1011 if (checkIntersection(startX, startY, endX, endY, from.rect.centerX(), from.rect.centerY(), to.rect.centerX(), to.rect.centerY()) == true)
1014 //Log.v(Main.APP_IDENTIFIER, "CUT LINE [" + from.rect.centerX() + "," + from.rect.centerY() +"]-[" + to.rect.centerX() + "," + to.rect.centerY() + "]");
1015 lineHolder.disconnectLines(line.key);
1020 catch (Exception ex)
1029 * @param x1 線1の始点 (X座標)
1030 * @param y1 線1の始点 (Y座標)
1031 * @param x2 線1の終点 (X座標)
1032 * @param y2 線1の終点 (Y座標)
1033 * @param x3 線2の始点 (X座標)
1034 * @param y3 線2の始点 (Y座標)
1035 * @param x4 線2の終点 (X座標)
1036 * @param y4 線2の終点 (Y座標)
1037 * @return true なら線が交差している
1039 private boolean checkIntersection(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
1042 float denominator = (x2 - x1) * (y4 - y3) - (y2 - y1) * (x4 - x3);
1043 if (Math.abs(denominator) < 0.00001)
1049 float tempX = x3 - x1;
1050 float tempY = y3 - y1;
1051 float dR = (((y4 - y3) * tempX) - ((x4 - x3) * tempY)) / denominator;
1052 float dS = (((y2 - y1) * tempX) - ((x2 - x1) * tempY)) / denominator;
1055 //float crossX, crossY;
1056 //crossX = x1 + dR * (x2 - x1);
1057 //crossY = y1 + dR * (y2 - y1);
1059 // 交点が線分内にあるかどうかをチェックする
1060 if ((dR >= 0)&&(dR <= 1)&&(dS >= 0)&&(dS <= 1))
1068 * 並行移動・ズームのサイズをリセットする
1071 public void resetScaleAndLocation(SeekBar zoomBar)
1077 // プログレスバーの位置をリセットする
1079 zoomBar.setProgress(50);
1081 // preferenceに状態を記録する
1082 recordTranslateAndZoomScale(50);
1088 public void zoomScaleChanged(int progress)
1090 float val = ((float) progress - 50.0f) / 50.0f;
1093 float prevSizeWidth = screenWidth * drawScale;
1094 float prevSizeHeight = screenHeight * drawScale;
1096 // 表示倍率を変更し、倍率を画面に表示する
1097 drawScale = (float) Math.round(Math.pow(10.0, val) * 10.0) / 10.0f;
1098 TextView textview = (TextView) parent.findViewById(R.id.ZoomRate);
1099 textview.setText("x" + drawScale);
1102 float showSizeWidth = screenWidth * drawScale;
1103 float showSizeHeight = screenHeight * drawScale;
1105 // 倍率にあわせて並行移動する場所を調整する
1106 drawTransX = (prevSizeWidth - showSizeWidth) / 2.0f + drawTransX;
1107 drawTransY = (prevSizeHeight - showSizeHeight) / 2.0f + drawTransY;
1109 // preferenceに状態を記録する
1110 recordTranslateAndZoomScale(progress);
1117 private void recordTranslateAndZoomScale(int progress)
1119 //Log.v(Main.APP_IDENTIFIER, "recordTranslateAndZoomScale() : x" + drawScale + " X:" + drawTransX + " Y: " + drawTransY);
1120 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
1121 SharedPreferences.Editor editor = preferences.edit();
1122 editor.putFloat("drawScale", drawScale);
1123 editor.putFloat("drawTransX", drawTransX);
1124 editor.putFloat("drawTransY", drawTransY);
1125 editor.putInt("zoomProgress", progress);
1133 private void restoreTranslateAndZoomScale()
1135 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
1136 drawScale = preferences.getFloat("drawScale", 1.0f);
1137 drawTransX = preferences.getFloat("drawTransX", 0.0f);
1138 drawTransY = preferences.getFloat("drawTransY", 0.0f);
1139 Log.v(Main.APP_IDENTIFIER, "restoreTranslateAndZoomScale() : x" + drawScale + " X:" + drawTransX + " Y: " + drawTransY);
1143 * GestureDetector.OnGestureListener の実装
1145 public boolean onDown(MotionEvent event)
1147 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onDown() " + event.getX() + "," + event.getY());
1152 * GestureDetector.OnGestureListener の実装
1154 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
1156 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onFling() " + velocityX + "," + velocityY);
1161 * GestureDetector.OnGestureListener の実装
1163 public void onLongPress(MotionEvent event)
1165 Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onLongPress() " + event.getX() + "," + event.getY());
1167 // タッチ位置をオブジェクト画像の座標に変換する
1168 float x = (event.getX() - drawTransX) / drawScale;
1169 float y = (event.getY() - drawTransY) / drawScale;
1171 // タッチ位置にオブジェクトが存在するか確認する
1172 MeMoMaObjectHolder.PositionObject position = checkSelectedObject(x, y);
1173 if (position != null)
1175 // 長押し処理を実施していることを記憶する
1176 onGestureProcessed = true;
1178 // タッチした場所にオブジェクトが存在した!!
1179 selectionReceiver.objectSelectedContext(position.getKey());
1184 * GestureDetector.OnGestureListener の実装
1186 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
1188 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onScroll() " + distanceX + "," + distanceY);
1193 * GestureDetector.OnGestureListener の実装
1195 public void onShowPress(MotionEvent event)
1197 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onShowPress() " + event.getX() + "," + event.getY());
1201 * GestureDetector.OnGestureListener の実装
1203 public boolean onSingleTapUp(MotionEvent event)
1205 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onSingleTapUp() " + event.getX() + "," + event.getY());
1211 * (SeekBar.OnSeekBarChangeListener の実装)
1213 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
1216 zoomScaleChanged(progress);
1219 final GokigenSurfaceView surfaceView = (GokigenSurfaceView) parent.findViewById(R.id.GraphicView);
1220 surfaceView.doDraw();
1224 * SeekBar.OnSeekBarChangeListener の実装
1226 public void onStartTrackingTouch(SeekBar seekBar)
1232 * SeekBar.OnSeekBarChangeListener の実装
1234 public void onStopTrackingTouch(SeekBar seekBar)
1240 * (ScaleGestureDetector.OnScaleGestureListener の実装)
1245 public boolean onScale(ScaleGestureDetector detector)
1247 float scaleFactor = detector.getScaleFactor();
1248 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onScale() : " + scaleFactor + " (" + currentScaleBar + ")");
1250 /** 画面表示の倍率が変更された! x < 1 : 縮小、 1 < x : 拡大 **/
1251 if (scaleFactor < 1.0f)
1253 currentScaleBar = (currentScaleBar == 0) ? 0 : currentScaleBar - 1;
1255 else if (scaleFactor > 1.0f)
1257 currentScaleBar = (currentScaleBar == 100) ? 100 : currentScaleBar + 1;
1259 zoomScaleChanged(currentScaleBar);
1265 * (ScaleGestureDetector.OnScaleGestureListener の実装)
1269 public boolean onScaleBegin(ScaleGestureDetector detector)
1271 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onScaleBegin() ");
1272 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
1273 currentScaleBar = preferences.getInt("zoomProgress", 50);
1279 * (ScaleGestureDetector.OnScaleGestureListener の実装)
1282 public void onScaleEnd(ScaleGestureDetector detector)
1284 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onScaleEnd() " + currentScaleBar);
1288 final SeekBar seekbar = (SeekBar) parent.findViewById(R.id.ZoomInOut);
1289 seekbar.setProgress(currentScaleBar);
1290 zoomScaleChanged(currentScaleBar);