package com.marshalchen.common.uimodule.tileView.tileview.markers;
import android.content.Context;
import android.graphics.Point;
import android.graphics.Rect;
import android.view.View;
import com.marshalchen.common.uimodule.tileView.layouts.TranslationLayout;
import com.marshalchen.common.uimodule.tileView.tileview.detail.DetailLevelEventListener;
import com.marshalchen.common.uimodule.tileView.tileview.detail.DetailManager;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map.Entry;
/*
* TODO: need to consolidate positioning logic - works as is, but does too many unnecessary and possibly messy calculations
* should work with adding at runtime, in response to user event, sliding, etc.
*/
public class MarkerManager extends TranslationLayout implements DetailLevelEventListener {
private DetailManager detailManager;
private HashMap<View, Rect> markerMap = new HashMap<View, Rect>();
private ArrayList<MarkerEventListener> listeners = new ArrayList<MarkerEventListener>();
public MarkerManager( Context context, DetailManager zm ) {
super( context );
detailManager = zm;
detailManager.addDetailLevelEventListener( this );
}
public View addMarker( View v, int x, int y ){
LayoutParams lp = new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, x, y );
return addMarker( v, lp );
}
public View addMarker( View v, int x, int y, float aX, float aY ) {
LayoutParams lp = new LayoutParams( LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT, x, y, aX, aY );
return addMarker( v, lp );
}
public View addMarker( View v, LayoutParams params ) {
addView( v, params );
markerMap.put( v, new Rect() );
requestLayout();
return v;
}
public void removeMarker( View v ) {
removeView( v );
markerMap.remove( v );
}
public void addMarkerEventListener( MarkerEventListener listener ) {
listeners.add( listener );
}
public void removeMarkerEventListener( MarkerEventListener listener ) {
listeners.remove( listener );
}
private View getViewFromTap( int x, int y ) {
Iterator<Entry<View, Rect>> iterator = markerMap.entrySet().iterator();
while (iterator.hasNext()) {
Entry<View, Rect> pairs = iterator.next();
Rect rect = (Rect) pairs.getValue();
if(rect.contains( x, y )){
View view = (View) pairs.getKey();
return view;
}
}
return null;
}
public void processHit ( Point point ) {
// fast-fail if no listeners
if( listeners.isEmpty() ){
return;
}
View view = getViewFromTap( point.x, point.y );
if( view != null ) {
for( MarkerEventListener listener : listeners ) {
listener.onMarkerTap( view, point.x, point.y );
}
}
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b) {
super.onLayout( changed, l, t, r, b );
for (int i = getChildCount() - 1; i >= 0; i--) {
View child = getChildAt(i);
if (child.getVisibility() != GONE) {
LayoutParams lp = (LayoutParams) child.getLayoutParams();
// get sizes
int w = child.getMeasuredWidth();
int h = child.getMeasuredHeight();
// get offset position
int scaledX = (int) (0.5 + (lp.x * scale));
int scaledY = (int) (0.5 + (lp.y * scale));
// user child's layout params anchor position if set, otherwise default to anchor position of layout
float aX = (lp.anchorX == null) ? anchorX : lp.anchorX;
float aY = (lp.anchorY == null) ? anchorY : lp.anchorY;
// apply anchor offset to position
int x = scaledX + (int) (w * aX);
int y = scaledY + (int) (h * aY);
// get and set the rect for the child
Rect rect = markerMap.get( child );
if( rect != null ) {
rect.set( x, y, x + w, y + h );
}
}
}
}
@Override
public void onDetailLevelChanged() {
}
@Override
public void onDetailScaleChanged( double scale ) {
setScale( scale );
}
}