/* Copyright (C) 2014,2015 Björn Stelter, Jan Müller
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
package de.hu_berlin.informatik.spws2014.mapever.entzerrung;
import android.content.Context;
import android.graphics.Point;
import android.graphics.PointF;
import android.util.Log;
import de.hu_berlin.informatik.spws2014.mapever.R;
import de.hu_berlin.informatik.spws2014.mapever.Settings;
import de.hu_berlin.informatik.spws2014.mapever.largeimageview.LargeImageView;
import de.hu_berlin.informatik.spws2014.mapever.largeimageview.OverlayIcon;
public class CornerIcon extends OverlayIcon {
// Resource des zu verwendenden Bildes
private static int cornerImageResource = R.drawable.entzerrung_corner;
// Context der Activity
private Context context;
// Bildkoordinaten des Eckpunktes
private Point cornerPosition;
// Bildkoordinaten vor einem Drag-Vorgang (zwecks Drag-Abbruch)
private Point cornerPosition_preDrag = null;
// Offset des Angriffspunkt für Drag-Event (an welcher Stelle des Icons wird es gezogen?)
private float dragOriginOffsetX = 0;
private float dragOriginOffsetY = 0;
// ////////////////////////////////////////////////////////////////////////
// //////////// CONSTRUCTORS
// ////////////////////////////////////////////////////////////////////////
/**
* Erstelle Eckpunkt an bestimmter Position.
*
* @param parentEView die EntzerrungsView
* @param position Bildkoordinaten des Punktes
*/
public CornerIcon(EntzerrungsView parentEView, Point position) {
// Superkonstruktor, registriert Icon bei der LIV
super((LargeImageView) parentEView);
// Save activity context for later...
context = parentEView.getContext();
// Appresource als Bild setzen
setDrawable(parentEView.getResources().getDrawable(cornerImageResource));
// Setze Position
setPosition(position);
}
// ////////////////////////////////////////////////////////////////////////
// //////////// OVERLAYICON PROPERTY OVERRIDES
// ////////////////////////////////////////////////////////////////////////
@Override
protected int getImagePositionX() {
return cornerPosition == null ? 0 : cornerPosition.x;
}
@Override
protected int getImagePositionY() {
return cornerPosition == null ? 0 : cornerPosition.y;
}
@Override
protected int getImageOffsetX() {
return -getWidth() / 2;
}
@Override
protected int getImageOffsetY() {
return -getHeight() / 2;
}
// ////////////////////////////////////////////////////////////////////////
// //////////// PROPERTIES
// ////////////////////////////////////////////////////////////////////////
/**
* Gibt Bildkoordinaten des Eckpunktes als Point zurück.
*/
public Point getPosition() {
return cornerPosition;
}
/**
* Setze Bildkoordinaten des Eckpunktes.
*
* @param position neue Position
*/
public void setPosition(Point position) {
cornerPosition = position;
// Koordinaten auf Bildgröße beschränken
if (cornerPosition.x < 0)
cornerPosition.x = 0;
else if (cornerPosition.x >= getParentLIV().getImageWidth())
cornerPosition.x = getParentLIV().getImageWidth() - 1;
if (cornerPosition.y < 0)
cornerPosition.y = 0;
else if (cornerPosition.y >= getParentLIV().getImageHeight())
cornerPosition.y = getParentLIV().getImageHeight() - 1;
// Darstellung aktualisieren
update();
}
/**
* Setze Bildkoordinaten des Eckpunktes.
*
* @param position neue Position als OpenCV-Point (double-basiert)
*/
public void setPosition(org.opencv.core.Point position) {
setPosition(new Point((int) position.x, (int) position.y));
}
// ////////////////////////////////////////////////////////////////////////
// //////////// EVENT HANDLERS
// ////////////////////////////////////////////////////////////////////////
// ////// DRAG AND DROP
@Override
public boolean onDragDown(int pointerID, float screenX, float screenY) {
Log.d("CornerIcon/onDragDown", "[" + cornerPosition + "] start drag pointerID " + pointerID + ", screen pos " + screenX + "/" + screenY);
// Falls Multitouch nicht aktiviert ist und bereits ein Icon gedraggt wird, keinen weiteren Drag-Vorgang
// starten und alle laufenden abbrechen.
if (!Settings.getPreference_livMultitouch(context) && getParentLIV().isCurrentlyDragging()) {
getParentLIV().cancelAllDragging();
return true;
}
// Bildschirmkoordinaten in Bildkoordinaten umwandeln
PointF imagePos = getParentLIV().screenToImagePosition(screenX, screenY);
// Merke den Angriffspunkt des Drags als Offset (wenn man den Eckpunkt nicht mittig sondern an der Seite
// anfässt, dann zieht man den Eckpunkt auch an der Seite, statt dass er automatisch auf die Fingerposition
// zentriert wird).
dragOriginOffsetX = imagePos.x - getImagePositionX();
dragOriginOffsetY = imagePos.y - getImagePositionY();
// Alte Position des Eckpunkts merken, um sie im Falle eines Drag-Abbruchs zurückzusetzen
cornerPosition_preDrag = cornerPosition;
// Starte Drag-Vorgang (merke Pointer-ID, um onDragMove's zu erhalten)
startDrag(pointerID);
// Event wurde behandelt.
return true;
}
@Override
public boolean onDragMove(float screenX, float screenY) {
Log.d("CornerIcon/onDragMove", "[" + cornerPosition + "] dragging (pointer " + getDragPointerID() + ") on screen pos " + screenX + "/" + screenY);
// Bildschirmkoordinaten in Bildkoordinaten umwandeln
PointF imagePos = getParentLIV().screenToImagePosition(screenX, screenY);
// Neue Position des Eckpunktes setzen
setPosition(new Point(
(int) (imagePos.x - dragOriginOffsetX),
(int) (imagePos.y - dragOriginOffsetY)));
// Eckpunkte sortieren lassen
((EntzerrungsView) getParentLIV()).sortCorners();
// Event wurde behandelt.
return true;
}
@Override
public void onDragUp(float screenX, float screenY) {
Log.d("CornerIcon/onDragUp", "[" + cornerPosition + "] stop dragging (pointer " + getDragPointerID() + ") on screen pos " + screenX + "/" + screenY);
// Stoppe Drag-Vorgang (um keine onDragMove's mehr zu erhalten)
stopDrag();
// Im Falle eines Drag-Abbruchs (screenX = screenY = Float.NaN), Iconposition zurücksetzen
if (Float.isNaN(screenX) || Float.isNaN(screenY)) {
setPosition(cornerPosition_preDrag);
cornerPosition_preDrag = null;
}
// Angriffspunkt des Drags zurücksetzen
dragOriginOffsetX = dragOriginOffsetY = 0;
}
}