1 package jp.sourceforge.gokigen.memoma;
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;
28 public class MeMoMaCanvasDrawer implements ICanvasDrawer, GestureDetector.OnGestureListener, ScaleGestureDetector.OnScaleGestureListener, SeekBar.OnSeekBarChangeListener
30 public static final float OBJECTLABEL_MARGIN = 8.0f;
31 public static final float OBJECTLABEL_MARGIN_WIDTH = 24.0f;
33 public static final int BACKGROUND_COLOR_DEFAULT = 0xff004000;
34 private int backgroundColor = BACKGROUND_COLOR_DEFAULT;
36 private MeMoMaObjectHolder.PositionObject selectedPosition = null;
37 private float tempPosX = Float.MIN_VALUE;
38 private float tempPosY = Float.MIN_VALUE;
39 private float downPosX = Float.MIN_VALUE;
40 private float downPosY = Float.MIN_VALUE;
42 // 以下の値は、MeMoMaListenerで初期値を設定する
43 private int objectStyle = MeMoMaObjectHolder.DRAWSTYLE_RECTANGLE;
45 private LineStyleHolder lineStyleHolder = null;
47 private float drawScale = 1.0f; // 表示の倍率
48 private float drawTransX = 0.0f; // 並行移動距離 (X)
49 private float drawTransY = 0.0f; // 並行移動距離 (Y)
50 private boolean onScaling = false; // ピンチイン・ピンチアウト操作しているかどうかを示す
51 private int currentScaleBar= 50; // 現在のピンチイン・ピンチアウト倍率
53 private boolean onGestureProcessed = false; // 長押し時の処理を行なっているかどうかを示す。
55 private float screenWidth = 0.0f; // 表示領域の幅
56 private float screenHeight = 0.0f; // 表示領域の高さ
58 private int displayObjectInformation = 1; // オブジェクトラベルの表示
60 private String backgroundBitmapUri = null;
61 private Bitmap backgroundBitmap = null;
63 private MeMoMaObjectHolder objectHolder = null;
64 private MeMoMaConnectLineHolder lineHolder = null;
65 private IObjectSelectionReceiver selectionReceiver = null;
67 private GestureDetector gestureDetector = null;
68 private ScaleGestureDetector scaleGestureDetector = null;
70 private Activity parent = null;
76 public MeMoMaCanvasDrawer(Activity argument, MeMoMaObjectHolder object, LineStyleHolder styleHolder, IObjectSelectionReceiver receiver)
78 objectHolder = object;
79 lineHolder = objectHolder.getConnectLineHolder();
80 selectionReceiver = receiver;
81 lineStyleHolder = styleHolder;
85 gestureDetector = new GestureDetector(argument, this);
86 scaleGestureDetector = new ScaleGestureDetector(argument, this);
89 restoreTranslateAndZoomScale();
94 * (ここで指定された形状のチェックを行っておく。)
98 public void setObjectStyle(int style)
102 case MeMoMaObjectHolder.DRAWSTYLE_OVAL:
103 case MeMoMaObjectHolder.DRAWSTYLE_ROUNDRECT:
104 case MeMoMaObjectHolder.DRAWSTYLE_RECTANGLE:
105 case MeMoMaObjectHolder.DRAWSTYLE_DIAMOND:
106 case MeMoMaObjectHolder.DRAWSTYLE_KEYBOARD:
107 case MeMoMaObjectHolder.DRAWSTYLE_PAPER:
108 case MeMoMaObjectHolder.DRAWSTYLE_DRUM:
109 case MeMoMaObjectHolder.DRAWSTYLE_PARALLELOGRAM:
110 case MeMoMaObjectHolder.DRAWSTYLE_HEXAGONAL:
111 case MeMoMaObjectHolder.DRAWSTYLE_CIRCLE:
112 case MeMoMaObjectHolder.DRAWSTYLE_NO_REGION:
113 case MeMoMaObjectHolder.DRAWSTYLE_LOOP_START:
114 case MeMoMaObjectHolder.DRAWSTYLE_LOOP_END:
115 case MeMoMaObjectHolder.DRAWSTYLE_LEFT_ARROW:
116 case MeMoMaObjectHolder.DRAWSTYLE_DOWN_ARROW:
117 case MeMoMaObjectHolder.DRAWSTYLE_UP_ARROW:
118 case MeMoMaObjectHolder.DRAWSTYLE_RIGHT_ARROW:
123 objectStyle = MeMoMaObjectHolder.DRAWSTYLE_RECTANGLE;
132 public void updateBackgroundBitmap(String uri, int width, int height)
135 backgroundBitmapUri = uri;
137 // とりあえず、背景画像をクリアしてガベコレする。
138 backgroundBitmap = null;
140 if (uri.isEmpty() == true)
142 // 背景画像の指定がなかったので、ここでリターンする。
147 // とりあえず設定する情報をログに残してみる
148 Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::updateBackgroundBitmap() : w:" + width + " , h:"+ height + " " + uri);
151 backgroundBitmap = ImageLoader.getBitmapFromUri(parent, ImageLoader.parseUri(uri), width, height);
155 Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::updateBackgroundBitmap() : " + uri + " , "+ ex.toString());
156 ex.printStackTrace();
157 backgroundBitmap = null;
158 backgroundBitmapUri = "";
169 public void setBackgroundUri(String uri)
171 backgroundBitmapUri = uri;
179 public void setBackgroundColor(String colorString)
183 backgroundColor = Color.parseColor(colorString);
189 //Log.v(Main.APP_IDENTIFIER, "Ex:" + ex.toString() + " " + ex.getMessage());
191 backgroundColor = BACKGROUND_COLOR_DEFAULT;
198 public void prepareToStart(int width, int height)
200 Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::prepareToStart() " + "x:" + width + " , " + "y:" + height);
203 //updateBackgroundBitmap(backgroundBitmapUri, width, height);
206 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
207 displayObjectInformation = Integer.parseInt(preferences.getString("objectPrintData", "1"));
211 * 画面の大きさが変わってしまった場合...
214 public void changedScreenProperty(int format, int width, int height)
217 updateBackgroundBitmap(backgroundBitmapUri, width, height);
221 screenHeight = height;
223 Log.v(Main.APP_IDENTIFIER, "changedScreenProperty() " + "x:" + width + " , " + "y:" + height);
228 * キャンバスにオブジェクト(と接続線)を表示する
231 public void drawOnCanvas(Canvas canvas)
233 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::drawOnCanvas()");
237 //canvas.drawColor(Color.argb(backgroundColorAlfa, backgroundColorRed, backgroundColorGreen, backgroundColorBlue), Mode.CLEAR);
238 canvas.drawColor(backgroundColor);
240 // 背景画像が設定されていた場合は、背景画像を描画する
241 if (backgroundBitmap != null)
243 canvas.drawBitmap(backgroundBitmap, 0, 0, new Paint());
247 canvas.translate(drawTransX, drawTransY);
250 canvas.scale(drawScale, drawScale);
252 // オブジェクト間の接続線をすべて表示する
253 drawConnectionLines(canvas, 0.0f, 0.0f);
256 drawObjects(canvas, 0.0f, 0.0f);
258 /** 移動中かどうかのチェックを行う。 **/
259 if (isFlicking(canvas) == true)
261 // 移動中の場合、フリック時の軌跡と現在位置を表示する
262 drawTrackAndPositions(canvas);
267 // 例外発生...でもそのときには何もしない
268 Log.v(Main.APP_IDENTIFIER, "drawOnCanvas() ex: " + ex.getMessage());
273 * オブジェクトをBitmapCanvas上に描く
276 public void drawOnBitmapCanvas(Canvas canvas, float offsetX, float offsetY)
280 Paint paint = new Paint();
283 canvas.drawColor(backgroundColor);
285 // 背景画像が設定されていた場合は、背景画像を描画する
286 if (backgroundBitmap != null)
288 canvas.drawBitmap(backgroundBitmap, offsetX, offsetY, paint);
291 // オブジェクト間の接続線をすべて表示する
292 drawConnectionLines(canvas, offsetX, offsetY);
295 drawObjects(canvas, offsetX, offsetY);
297 // タイトルとめもまのアイコンを表示する : 文字の色は黒でいいのかな...
298 Bitmap bitmap = BitmapFactory.decodeResource(parent.getResources(), R.drawable.icon1);
299 canvas.drawBitmap(bitmap, 2.0f, 2.0f, paint);
300 canvas.drawText(objectHolder.getDataTitle(), (bitmap.getWidth() + 10.0f), 32.0f, paint);
305 // 例外発生...でもそのときには何もしない
306 Log.v(Main.APP_IDENTIFIER, "drawOnBitmapCanvas() ex: " + ex.toString() + " " + ex.getMessage());
315 private void drawConnectionLines(Canvas canvas, float offsetX, float offsetY)
317 // オブジェクトの色と枠線を設定する (連続線用)
318 Paint paint = new Paint();
319 paint.setColor(Color.WHITE);
320 paint.setStyle(Paint.Style.STROKE);
322 // オブジェクトの色と枠線を設定する (点線用)
323 Paint dashLinePaint = new Paint();
324 dashLinePaint.setColor(Color.WHITE);
325 dashLinePaint.setStyle(Paint.Style.STROKE);
326 dashLinePaint.setPathEffect(new DashPathEffect(new float[]{ 5.0f, 5.0f }, 0));
328 // オブジェクトの描画 (保持しているものはすべて表示する)
329 Enumeration<Integer> keys = lineHolder.getLineKeys();
330 while (keys.hasMoreElements())
332 Integer key = keys.nextElement();
333 MeMoMaConnectLineHolder.ObjectConnector line = lineHolder.getLine(key);
337 drawLine(canvas, paint, dashLinePaint, line, offsetX, offsetY);
341 // ここは呼ばれないはず。。。消したはずのものが残っている
342 Log.v(Main.APP_IDENTIFIER, "DETECTED DELETED LINE");
354 public void drawLine(Canvas canvas, Paint paint, Paint dashPaint, MeMoMaConnectLineHolder.ObjectConnector line, float offsetX, float offsetY)
358 if ((objectHolder == null)||(canvas == null))
364 MeMoMaObjectHolder.PositionObject from = objectHolder.getPosition(line.fromObjectKey);
365 MeMoMaObjectHolder.PositionObject to = objectHolder.getPosition(line.toObjectKey);
366 if ((from == null)||(to == null))
373 paint.setStrokeWidth((float) line.lineThickness);
376 dashPaint.setStrokeWidth((float) line.lineThickness);
378 // ラインのスタイル(連続線 or 点線)を設定する
379 Paint linePaint = (line.lineShape == LineStyleHolder.LINESHAPE_DASH) ? dashPaint : paint;
381 // 初期値として、各オブジェクトの中心座標を設定する
382 float startX = from.rect.centerX() + offsetX;
383 float endX = to.rect.centerX() + offsetX;
384 float startY = from.rect.centerY() + offsetY;
385 float endY = to.rect.centerY() + offsetY;
388 if (from.rect.bottom < to.rect.top)
390 startY = from.rect.bottom + offsetY;
391 endY = to.rect.top + offsetY;
393 else if (from.rect.top > to.rect.bottom)
395 startY = from.rect.top + offsetY;
396 endY = to.rect.bottom + offsetY;
399 // X座標の線の位置を補正する (Y座標が補正されていないとき)
400 if ((startY != (from.rect.top + offsetY))&&(startY != (from.rect.bottom + offsetY)))
402 if (from.rect.right < to.rect.left)
404 startX = from.rect.right + offsetX;
405 endX = to.rect.left + offsetX;
407 else if (from.rect.left > to.rect.right)
409 startX = from.rect.left + offsetX;
410 endX = to.rect.right + offsetX;
414 if ((line.lineStyle == LineStyleHolder.LINESTYLE_TREESTYLE_NO_ARROW)||
415 (line.lineStyle == LineStyleHolder.LINESTYLE_TREESTYLE_L_ARROW)||
416 (line.lineStyle == LineStyleHolder.LINESTYLE_TREESTYLE_R_ARROW))
419 if (startX == (from.rect.centerX() + offsetX))
421 float middleY = (startY + endY) / 2;
422 canvas.drawLine(startX, startY, startX, middleY, linePaint);
423 canvas.drawLine(startX, middleY, endX, middleY, linePaint);
424 canvas.drawLine(endX, middleY, endX, endY, linePaint);
427 if (line.lineStyle == LineStyleHolder.LINESTYLE_TREESTYLE_L_ARROW)
430 ObjectShapeDrawer.drawArrowTree(canvas, paint, startX,startY, middleY, false);
432 else if (line.lineStyle == LineStyleHolder.LINESTYLE_TREESTYLE_R_ARROW)
435 ObjectShapeDrawer.drawArrowTree(canvas, paint, endX, endY, middleY, false);
440 float middleX = (startX + endX) / 2;
441 canvas.drawLine(startX, startY, middleX, startY, linePaint);
442 canvas.drawLine(middleX, startY, middleX, endY, linePaint);
443 canvas.drawLine(middleX, endY, endX, endY, linePaint);
445 /** やじるし(三角形)をつける処理 **/
446 if (line.lineStyle == LineStyleHolder.LINESTYLE_TREESTYLE_L_ARROW)
449 ObjectShapeDrawer.drawArrowTree(canvas, paint, startX, startY, middleX, true);
451 else if (line.lineStyle == LineStyleHolder.LINESTYLE_TREESTYLE_R_ARROW)
454 ObjectShapeDrawer.drawArrowTree(canvas, paint, endX,endY, middleX, true);
458 else if ((line.lineStyle == LineStyleHolder.LINESTYLE_CURVESTYLE_NO_ARROW)||
459 (line.lineStyle == LineStyleHolder.LINESTYLE_CURVESTYLE_L_ARROW)||
460 (line.lineStyle == LineStyleHolder.LINESTYLE_CURVESTYLE_R_ARROW))
463 float middleX = (startX + endX) / 2;
464 float middleY = (startY + endY) / 2;
465 float x1 = (startX + middleX) / 2;
467 float x2 = (middleX + endX) / 2;
470 Path pathLine = new Path();
471 pathLine.moveTo(startX, startY);
472 pathLine.cubicTo(x1, y1, x2, y2, endX, endY);
473 canvas.drawPath(pathLine, linePaint);
476 if (line.lineStyle == LineStyleHolder.LINESTYLE_CURVESTYLE_L_ARROW)
479 ObjectShapeDrawer.drawArrow(canvas, paint, startX, startY, endX, endY);
481 else if (line.lineStyle == LineStyleHolder.LINESTYLE_CURVESTYLE_R_ARROW)
484 ObjectShapeDrawer.drawArrow(canvas, paint, endX, endY, startX, startY);
487 else // if (line.lineStyle == MeMoMaConnectLineHolder.LINESTYLE_STRAIGHT)
490 canvas.drawLine(startX, startY, endX, endY, linePaint);
493 if (line.lineStyle == LineStyleHolder.LINESTYLE_STRAIGHT_L_ARROW)
496 ObjectShapeDrawer.drawArrow(canvas, paint, startX, startY, endX, endY);
498 else if (line.lineStyle == LineStyleHolder.LINESTYLE_STRAIGHT_R_ARROW)
501 ObjectShapeDrawer.drawArrow(canvas, paint, endX, endY, startX, startY);
508 Log.v(Main.APP_IDENTIFIER, "EXCEPTION :" + ex.toString());
513 * オブジェクトを動かしている最中かどうかの判定を行う。
516 * @return trueなら、動かしている最中
518 private boolean isFlicking(Canvas canvas)
520 //int width = canvas.getWidth();
521 //int height = canvas.getHeight();
522 if ((tempPosX == Float.MIN_VALUE)||(tempPosY == Float.MIN_VALUE))
534 private void drawTrackAndPositions(Canvas canvas)
537 float x = (tempPosX - drawTransX) / drawScale;
538 float y = (tempPosY - drawTransY) / drawScale;
540 Paint paint = new Paint();
541 paint.setStyle(Paint.Style.STROKE);
542 paint.setColor(Color.GRAY);
543 if (selectedPosition != null)
545 float objX = (selectedPosition.rect.right - selectedPosition.rect.left) / 2;
546 float objY = (selectedPosition.rect.bottom - selectedPosition.rect.top) / 2;
547 canvas.drawLine(selectedPosition.rect.centerX(), selectedPosition.rect.centerY(), x, y, paint);
548 canvas.drawRect((x - objX), (y - objY), (x + objX), (y + objY), paint);
551 drawObject(canvas, selectedPosition, true, 0.0f, 0.0f);
553 else // オブジェクト非選択時の表示
555 int data = selectionReceiver.touchedVacantArea();
556 if (data ==OperationModeHolder.OPERATIONMODE_MOVE)
558 // 移動モードのとき... (表示領域を移動させる)
559 drawTransX = (tempPosX - downPosX);
560 drawTransY = (tempPosY - downPosY);
563 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
564 SharedPreferences.Editor editor = preferences.edit();
565 editor.putFloat("drawTransX", drawTransX);
566 editor.putFloat("drawTransY", drawTransY);
572 paint.setColor(Color.YELLOW);
573 canvas.drawLine(((downPosX) / drawScale), ((downPosY) / drawScale), x, y, paint);
585 private void drawObject(Canvas canvas, MeMoMaObjectHolder.PositionObject object, boolean isMoving, float offsetX, float offsetY)
587 float label_offsetX = OBJECTLABEL_MARGIN;
588 float label_offsetY = 0.0f;
591 Paint paint = new Paint();
592 if (isMoving == true)
594 paint.setColor(Color.YELLOW);
595 paint.setStyle(Paint.Style.STROKE);
596 paint.setStrokeWidth(object.strokeWidth);
600 paint.setColor(object.objectColor);
601 paint.setStyle(Paint.Style.valueOf(object.paintStyle));
602 paint.setStrokeWidth(object.strokeWidth);
606 RectF objectShape = new RectF(object.rect);
607 objectShape.left = objectShape.left + offsetX;
608 objectShape.right = objectShape.right + offsetX;
609 objectShape.top = objectShape.top + offsetY;
610 objectShape.bottom = objectShape.bottom + offsetY;
612 if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_OVAL)
615 label_offsetY = ObjectShapeDrawer.drawObjectOval(canvas, objectShape, paint);
617 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_ROUNDRECT)
620 label_offsetY = ObjectShapeDrawer.drawObjectRoundRect(canvas, objectShape, paint);
622 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_DIAMOND)
625 label_offsetY = ObjectShapeDrawer.drawObjectDiamond(canvas, objectShape, paint);
626 label_offsetX = OBJECTLABEL_MARGIN;
628 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_KEYBOARD)
631 label_offsetY = ObjectShapeDrawer.drawObjectKeyboard(canvas, objectShape, paint);
633 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_PARALLELOGRAM)
636 label_offsetY = ObjectShapeDrawer.drawObjectParallelogram(canvas, objectShape, paint);
638 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_HEXAGONAL)
641 label_offsetY = ObjectShapeDrawer.drawObjectHexagonal(canvas, objectShape, paint);
643 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_PAPER)
646 label_offsetY = ObjectShapeDrawer.drawObjectPaper(canvas, objectShape, paint);
648 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_DRUM)
651 label_offsetY = ObjectShapeDrawer.drawObjectDrum(canvas, objectShape, paint, Paint.Style.valueOf(object.paintStyle));
653 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_CIRCLE)
656 label_offsetY = ObjectShapeDrawer.drawObjectCircle(canvas, objectShape, paint);
658 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_NO_REGION)
660 // 枠なしを描画(?)する ... なにもしない
661 if (object.label.length() == 0)
663 // 何も表示しないとわからないので、ラベルが無いときには枠を表示する
664 ObjectShapeDrawer.drawObjectNoRegion(canvas, objectShape, paint);
667 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_LOOP_START)
670 label_offsetY = ObjectShapeDrawer.drawObjectLoopStart(canvas, objectShape, paint);
672 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_LOOP_END)
675 label_offsetY = ObjectShapeDrawer.drawObjectLoopEnd(canvas, objectShape, paint);
677 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_LEFT_ARROW)
680 label_offsetY = ObjectShapeDrawer.drawObjectLeftArrow(canvas, objectShape, paint);
682 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_DOWN_ARROW)
685 label_offsetY = ObjectShapeDrawer.drawObjectDownArrow(canvas, objectShape, paint);
687 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_UP_ARROW)
690 label_offsetY = ObjectShapeDrawer.drawObjectUpArrow(canvas, objectShape, paint);
692 else if (object.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_RIGHT_ARROW)
695 label_offsetY = ObjectShapeDrawer.drawObjectRightArrow(canvas, objectShape, paint);
697 else // if (pos.drawStyle == MeMoMaObjectHolder.DRAWSTYLE_RECTANGLE)
700 label_offsetY = ObjectShapeDrawer.drawObjectRect(canvas, objectShape, paint);
704 paint.setTextSize(object.fontSize);
707 ObjectShapeDrawer.drawTextLabel(canvas, paint, object, objectShape, displayObjectInformation, label_offsetX, label_offsetY);
715 private void drawObjects(Canvas canvas , float offsetX, float offsetY)
717 // オブジェクトの描画 (保持しているものはすべて表示する)
718 Enumeration<Integer> keys = objectHolder.getObjectKeys();
719 while (keys.hasMoreElements())
721 Integer key = keys.nextElement();
722 MeMoMaObjectHolder.PositionObject pos = objectHolder.getPosition(key);
723 drawObject(canvas, pos, false, offsetX, offsetY);
732 private boolean onTouchDown(MotionEvent event)
735 downPosX = event.getX() - drawTransX;
736 downPosY = event.getY() - drawTransY;
738 // タッチ位置をオブジェクト画像の座標に変換する
739 float x = downPosX / drawScale;
740 float y = downPosY / drawScale;
742 // タッチ位置にオブジェクトが存在するか確認する
743 selectedPosition = checkSelectedObject(x, y);
744 if (selectedPosition == null)
746 // 最初にタップしたときの位置を selectedPositionに設定する
747 int data = selectionReceiver.touchedVacantArea();
748 if (data == OperationModeHolder.OPERATIONMODE_CREATE)
750 // オブジェクト作成モードのとき...オブジェクトを生成する
751 selectedPosition = objectHolder.createPosition(x, y, objectStyle);
753 // オブジェクトが生成されたことを通知する
754 selectionReceiver.objectCreated();
756 else if (data ==OperationModeHolder.OPERATIONMODE_MOVE)
760 else // if (data ==ChangeDrawMode.OPERATIONMODE_DELETE)
773 private boolean onTouchUp(MotionEvent event)
775 boolean longPress = false;
776 if (onGestureProcessed == true)
778 // ロングタッチ中だった場合...フラグを落とす
779 onGestureProcessed = false;
783 // タッチ位置をオブジェクト画像の座標に変換する
784 float x = (event.getX() - drawTransX) / drawScale;
785 float y = (event.getY() - drawTransY) / drawScale;
787 if (selectedPosition == null)
789 int data = selectionReceiver.touchUppedVacantArea();
790 if (data == OperationModeHolder.OPERATIONMODE_DELETE)
792 if ((tempPosX == Float.MIN_VALUE)||(tempPosY == Float.MIN_VALUE)||(downPosX == Float.MIN_VALUE)||(downPosY == Float.MIN_VALUE))
794 // タッチが2つ揃っていないので、何もしない。
795 Log.v(Main.APP_IDENTIFIER, "onTouchUp : (" + downPosX + "," + downPosY + ") [" + drawScale + "] (" + tempPosX + "," + tempPosY + ") [" + drawTransX + "," + drawTransY + "]");
799 // タッチが離された位置にオブジェクトがおらず、オブジェクトが非選択だった場合...オブジェクトが繋がっているラインを切断する
800 disconnectObjects((downPosX / drawScale) , (downPosY / drawScale), ((tempPosX - drawTransX) / drawScale), ((tempPosY - drawTransY) / drawScale));
803 tempPosX = Float.MIN_VALUE;
804 tempPosY = Float.MIN_VALUE;
805 downPosX = Float.MIN_VALUE;
806 downPosY = Float.MIN_VALUE;
811 tempPosX = Float.MIN_VALUE;
812 tempPosY = Float.MIN_VALUE;
813 downPosX = Float.MIN_VALUE;
814 downPosY = Float.MIN_VALUE;
818 if (selectedPosition.rect.contains(x, y) == true)
820 // タッチが離された位置がタッチしたオブジェクトと同じ位置だった場合......
823 float diffX = Math.abs(event.getX() - drawTransX - downPosX);
824 float diffY = Math.abs(event.getY() - drawTransY - downPosY);
826 // タッチが離された位置が動いていた場合、オブジェクト位置の微調整と判定する。
827 if (((diffX > 2.0f)||(diffY > 2.0f))||(longPress == true))
829 // タッチが離された場所にはオブジェクトがなかった場合...オブジェクトをその位置に移動させる
830 Log.v(Main.APP_IDENTIFIER, "MOVE OBJECT : (" + diffX + "," + diffY + ")");
831 moveObjectPosition(x, y);
835 // タッチが押された位置と離された位置が同じ位置だった場合......アイテムが選択された、と認識する。
836 Log.v(Main.APP_IDENTIFIER, " ITEM SELECTED :" + x + "," + y);
837 if (selectionReceiver != null)
840 boolean isDraw = selectionReceiver.objectSelected(selectedPosition.getKey());
843 tempPosX = Float.MIN_VALUE;
844 tempPosY = Float.MIN_VALUE;
849 // タッチが離された位置にオブジェクトがいるかどうかのチェック
850 MeMoMaObjectHolder.PositionObject position = checkSelectedObject(x, y);
851 if ((position != null)&&(longPress == false))
853 // 他のオブジェクトと重なるように操作した、この場合は、オブジェクト間を線をつなげる
854 // (ただし、ボタンを長押ししていなかったとき。)
855 lineHolder.setLines(selectedPosition.getKey(), position.getKey(), lineStyleHolder);
856 tempPosX = Float.MIN_VALUE;
857 tempPosY = Float.MIN_VALUE;
861 // タッチが離された場所にはオブジェクトがなかった場合...オブジェクトをその位置に移動させる
862 moveObjectPosition(x, y);
864 tempPosX = Float.MIN_VALUE;
865 tempPosY = Float.MIN_VALUE;
866 float positionX = alignPosition(x, (objectSizeX / 2) * (-1));
867 float positionY = alignPosition(y, (objectSizeY / 2) * (-1));
868 selectedPosition.rect = new android.graphics.RectF(positionX, positionY, (positionX + objectSizeX), (positionY + objectSizeY));
869 // selectedPosition.drawStyle = objectStyle; // 不要、最初に生成するときだけ必要
880 private void moveObjectPosition(float x, float y)
882 tempPosX = Float.MIN_VALUE;
883 tempPosY = Float.MIN_VALUE;
884 float sizeX = selectedPosition.rect.right - selectedPosition.rect.left;
885 float sizeY = selectedPosition.rect.bottom - selectedPosition.rect.top;
887 float positionX = alignPosition(x, (sizeX / 2) * (-1));
888 float positionY = alignPosition(y, (sizeY / 2) * (-1));
889 selectedPosition.rect = new android.graphics.RectF(positionX, positionY, (positionX + sizeX), (positionY + sizeY));
895 * onTouchEvent : 画面がタッチした時のイベント処理
896 * (true なら、画面描画を実施する)
898 public boolean onTouchEvent(MotionEvent event)
900 boolean isDraw = false;
902 /** スケールジェスチャ(マルチタッチのジェスチャ)を拾う **/
903 isDraw = scaleGestureDetector.onTouchEvent(event);
904 if ((onScaling == true)||(scaleGestureDetector.isInProgress() == true))
910 /** 先にジェスチャーを拾ってみよう... **/
911 isDraw = gestureDetector.onTouchEvent(event);
914 Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onTouchEvent() : isDraw == true");
918 int action = event.getAction();
920 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onTouchEvent() : " + action);
921 if (action == MotionEvent.ACTION_DOWN)
924 isDraw = onTouchDown(event);
926 else if (action == MotionEvent.ACTION_MOVE)
928 // タッチされたまま動かされたときの処理
929 tempPosX = event.getX();
930 tempPosY = event.getY();
933 else if (action == MotionEvent.ACTION_UP)
936 isDraw = onTouchUp(event);
943 * タテヨコ位置を合わせられるよう、調整する。
947 private float alignPosition(float pos, float offset)
950 return (pos + offset);
954 * 位置から判定し、選択したオブジェクトを応答する
955 * (オブジェクトが選択されていない場合には、nullを応答する)
960 private MeMoMaObjectHolder.PositionObject checkSelectedObject(float x, float y)
962 Enumeration<Integer> keys = objectHolder.getObjectKeys();
963 //Log.v(Main.APP_IDENTIFIER, "CHECK POS " + x + "," + y);
964 while (keys.hasMoreElements())
966 Integer key = keys.nextElement();
967 MeMoMaObjectHolder.PositionObject pos = objectHolder.getPosition(key);
968 if (pos.rect.contains(x, y) == true)
970 Log.v(Main.APP_IDENTIFIER, "SELECTED :" + pos.rect.centerX() + "," + pos.rect.centerY() + " KEY :" + key);
973 //Log.v(Main.APP_IDENTIFIER, "NOT MATCH :" + pos.rect.centerX() + "," + pos.rect.centerY());
975 //Log.v(Main.APP_IDENTIFIER, "RETURN NULL...");
980 * 線と交差するオブジェクト接続線をすべて削除する
987 private void disconnectObjects(float startX, float startY, float endX, float endY)
989 Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::disconnectObjects() [" + startX + "," + startY +"]-[" + endX + "," + endY + "]");
992 Enumeration<Integer> keys = lineHolder.getLineKeys();
993 while (keys.hasMoreElements())
995 Integer key = keys.nextElement();
996 MeMoMaConnectLineHolder.ObjectConnector line = lineHolder.getLine(key);
1000 MeMoMaObjectHolder.PositionObject from = objectHolder.getPosition(line.fromObjectKey);
1001 MeMoMaObjectHolder.PositionObject to = objectHolder.getPosition(line.toObjectKey);
1004 if (checkIntersection(startX, startY, endX, endY, from.rect.centerX(), from.rect.centerY(), to.rect.centerX(), to.rect.centerY()) == true)
1007 //Log.v(Main.APP_IDENTIFIER, "CUT LINE [" + from.rect.centerX() + "," + from.rect.centerY() +"]-[" + to.rect.centerX() + "," + to.rect.centerY() + "]");
1008 lineHolder.disconnectLines(line.key);
1013 catch (Exception ex)
1022 * @param x1 線1の始点 (X座標)
1023 * @param y1 線1の始点 (Y座標)
1024 * @param x2 線1の終点 (X座標)
1025 * @param y2 線1の終点 (Y座標)
1026 * @param x3 線2の始点 (X座標)
1027 * @param y3 線2の始点 (Y座標)
1028 * @param x4 線2の終点 (X座標)
1029 * @param y4 線2の終点 (Y座標)
1030 * @return true なら線が交差している
1032 private boolean checkIntersection(float x1, float y1, float x2, float y2, float x3, float y3, float x4, float y4)
1035 float denominator = (x2 - x1) * (y4 - y3) - (y2 - y1) * (x4 - x3);
1036 if (Math.abs(denominator) < 0.00001)
1042 float tempX = x3 - x1;
1043 float tempY = y3 - y1;
1044 float dR = (((y4 - y3) * tempX) - ((x4 - x3) * tempY)) / denominator;
1045 float dS = (((y2 - y1) * tempX) - ((x2 - x1) * tempY)) / denominator;
1048 //float crossX, crossY;
1049 //crossX = x1 + dR * (x2 - x1);
1050 //crossY = y1 + dR * (y2 - y1);
1052 // 交点が線分内にあるかどうかをチェックする
1053 if ((dR >= 0)&&(dR <= 1)&&(dS >= 0)&&(dS <= 1))
1061 * 並行移動・ズームのサイズをリセットする
1064 public void resetScaleAndLocation(SeekBar zoomBar)
1070 // プログレスバーの位置をリセットする
1072 zoomBar.setProgress(50);
1074 // preferenceに状態を記録する
1075 recordTranslateAndZoomScale(50);
1081 public void zoomScaleChanged(int progress)
1083 float val = ((float) progress - 50.0f) / 50.0f;
1086 float prevSizeWidth = screenWidth * drawScale;
1087 float prevSizeHeight = screenHeight * drawScale;
1089 // 表示倍率を変更し、倍率を画面に表示する
1090 drawScale = (float) Math.round(Math.pow(10.0, val) * 10.0) / 10.0f;
1091 TextView textview = (TextView) parent.findViewById(R.id.ZoomRate);
1092 textview.setText("x" + drawScale);
1095 float showSizeWidth = screenWidth * drawScale;
1096 float showSizeHeight = screenHeight * drawScale;
1098 // 倍率にあわせて並行移動する場所を調整する
1099 drawTransX = (prevSizeWidth - showSizeWidth) / 2.0f + drawTransX;
1100 drawTransY = (prevSizeHeight - showSizeHeight) / 2.0f + drawTransY;
1102 // preferenceに状態を記録する
1103 recordTranslateAndZoomScale(progress);
1110 private void recordTranslateAndZoomScale(int progress)
1112 //Log.v(Main.APP_IDENTIFIER, "recordTranslateAndZoomScale() : x" + drawScale + " X:" + drawTransX + " Y: " + drawTransY);
1113 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
1114 SharedPreferences.Editor editor = preferences.edit();
1115 editor.putFloat("drawScale", drawScale);
1116 editor.putFloat("drawTransX", drawTransX);
1117 editor.putFloat("drawTransY", drawTransY);
1118 editor.putInt("zoomProgress", progress);
1126 private void restoreTranslateAndZoomScale()
1128 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
1129 drawScale = preferences.getFloat("drawScale", 1.0f);
1130 drawTransX = preferences.getFloat("drawTransX", 0.0f);
1131 drawTransY = preferences.getFloat("drawTransY", 0.0f);
1132 Log.v(Main.APP_IDENTIFIER, "restoreTranslateAndZoomScale() : x" + drawScale + " X:" + drawTransX + " Y: " + drawTransY);
1136 * GestureDetector.OnGestureListener の実装
1138 public boolean onDown(MotionEvent event)
1140 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onDown() " + event.getX() + "," + event.getY());
1145 * GestureDetector.OnGestureListener の実装
1147 public boolean onFling(MotionEvent e1, MotionEvent e2, float velocityX, float velocityY)
1149 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onFling() " + velocityX + "," + velocityY);
1154 * GestureDetector.OnGestureListener の実装
1156 public void onLongPress(MotionEvent event)
1158 Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onLongPress() " + event.getX() + "," + event.getY());
1160 // タッチ位置をオブジェクト画像の座標に変換する
1161 float x = (event.getX() - drawTransX) / drawScale;
1162 float y = (event.getY() - drawTransY) / drawScale;
1164 // タッチ位置にオブジェクトが存在するか確認する
1165 MeMoMaObjectHolder.PositionObject position = checkSelectedObject(x, y);
1166 if (position != null)
1168 // 長押し処理を実施していることを記憶する
1169 onGestureProcessed = true;
1171 // タッチした場所にオブジェクトが存在した!!
1172 selectionReceiver.objectSelectedContext(position.getKey());
1177 * GestureDetector.OnGestureListener の実装
1179 public boolean onScroll(MotionEvent e1, MotionEvent e2, float distanceX, float distanceY)
1181 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onScroll() " + distanceX + "," + distanceY);
1186 * GestureDetector.OnGestureListener の実装
1188 public void onShowPress(MotionEvent event)
1190 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onShowPress() " + event.getX() + "," + event.getY());
1194 * GestureDetector.OnGestureListener の実装
1196 public boolean onSingleTapUp(MotionEvent event)
1198 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onSingleTapUp() " + event.getX() + "," + event.getY());
1204 * (SeekBar.OnSeekBarChangeListener の実装)
1206 public void onProgressChanged(SeekBar seekBar, int progress, boolean fromUser)
1209 zoomScaleChanged(progress);
1212 final GokigenSurfaceView surfaceView = (GokigenSurfaceView) parent.findViewById(R.id.GraphicView);
1213 surfaceView.doDraw();
1217 * SeekBar.OnSeekBarChangeListener の実装
1219 public void onStartTrackingTouch(SeekBar seekBar)
1225 * SeekBar.OnSeekBarChangeListener の実装
1227 public void onStopTrackingTouch(SeekBar seekBar)
1233 * (ScaleGestureDetector.OnScaleGestureListener の実装)
1238 public boolean onScale(ScaleGestureDetector detector)
1240 float scaleFactor = detector.getScaleFactor();
1241 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onScale() : " + scaleFactor + " (" + currentScaleBar + ")");
1243 /** 画面表示の倍率が変更された! x < 1 : 縮小、 1 < x : 拡大 **/
1244 if (scaleFactor < 1.0f)
1246 currentScaleBar = (currentScaleBar == 0) ? 0 : currentScaleBar - 1;
1248 else if (scaleFactor > 1.0f)
1250 currentScaleBar = (currentScaleBar == 100) ? 100 : currentScaleBar + 1;
1252 zoomScaleChanged(currentScaleBar);
1258 * (ScaleGestureDetector.OnScaleGestureListener の実装)
1262 public boolean onScaleBegin(ScaleGestureDetector detector)
1264 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onScaleBegin() ");
1265 SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(parent);
1266 currentScaleBar = preferences.getInt("zoomProgress", 50);
1272 * (ScaleGestureDetector.OnScaleGestureListener の実装)
1275 public void onScaleEnd(ScaleGestureDetector detector)
1277 //Log.v(Main.APP_IDENTIFIER, "MeMoMaCanvasDrawer::onScaleEnd() " + currentScaleBar);
1281 final SeekBar seekbar = (SeekBar) parent.findViewById(R.id.ZoomInOut);
1282 seekbar.setProgress(currentScaleBar);
1283 zoomScaleChanged(currentScaleBar);