/*
The contents of this file are subject to the Mozilla Public License
Version 1.1 (the "License"); you may not use this file except in
compliance with the License. You may obtain a copy of the License at
http://www.mozilla.org/MPL/
Software distributed under the License is distributed on an "AS IS"
basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
License for the specific language governing rights and limitations
under the License.
The Original Code is collection of files collectively known as Open Camera.
The Initial Developer of the Original Code is Almalence Inc.
Portions created by Initial Developer are Copyright (C) 2013
by Almalence Inc. All Rights Reserved.
*/
package com.almalence.plugins.processing.groupshot;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Paint.Style;
import android.graphics.Rect;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
public class HorizontalGalleryView extends View
{
private static int BORDER_SIZE = 4;
public interface SequenceListener
{
public void onSequenceChanged(int selectedIndex);
}
private Bitmap[] images = null;
private boolean[] enabled = null;
private int selected = 0;
private int[] indexes = null;
private final Rect inRect = new Rect();
private final RectF outRect = new RectF();
private int width;
private int height;
private int touchedIndex = -1;
private float touchedX;
private float touchedY;
private float touchingX;
private final Paint paint = new Paint();
private SequenceListener listener = null;
public HorizontalGalleryView(final Context context)
{
super(context);
this.init();
}
public HorizontalGalleryView(final Context context, final AttributeSet attrs)
{
super(context, attrs);
this.init();
}
public HorizontalGalleryView(final Context context, final AttributeSet attrs, final int defStyle)
{
super(context, attrs, defStyle);
this.init();
}
private void init()
{
this.paint.setStrokeWidth(BORDER_SIZE);
this.paint.setStyle(Style.STROKE);
this.paint.setAntiAlias(true);
}
@Override
protected void onDraw(final Canvas canvas)
{
if (this.indexes != null)
{
final int imageWidth = this.getImageWidth();
int touched = -1;
for (int i = 0; i < this.indexes.length; i++)
{
if (this.indexes[i] != selected)
{
final int actualIndex = this.indexes[i];
this.inRect.left = 0;
this.inRect.top = 0;
this.inRect.right = this.images[actualIndex].getWidth() - 1;
this.inRect.bottom = this.images[actualIndex].getHeight() - 1;
final float imageHeight = Math.min(this.height, this.images[actualIndex].getHeight() * imageWidth
/ (float) this.images[actualIndex].getWidth());
this.outRect.left = i * imageWidth;
this.outRect.top = this.height - imageHeight;
this.outRect.right = (i + 1) * imageWidth - 1;
this.outRect.bottom = this.height - 1;
canvas.drawBitmap(this.images[actualIndex], this.inRect, this.outRect, null);
this.paint.setColor(Color.WHITE);
canvas.drawRect(this.outRect.left + BORDER_SIZE / 2.0f, this.outRect.top + BORDER_SIZE / 2.0f,
this.outRect.right - BORDER_SIZE / 2.0f, this.outRect.bottom - BORDER_SIZE / 2.0f,
this.paint);
} else
{
touched = i;
}
}
if (touched >= 0)
{
this.inRect.left = 0;
this.inRect.top = 0;
this.inRect.right = this.images[selected].getWidth() - 1;
this.inRect.bottom = this.images[selected].getHeight() - 1;
final float imageHeight = Math.min(this.height, this.images[selected].getHeight() * imageWidth
/ (float) this.images[selected].getWidth());
this.outRect.left = touched * imageWidth + this.touchingX - this.touchedX;
this.outRect.top = this.height - imageHeight;
this.outRect.right = this.outRect.left + imageWidth;
this.outRect.bottom = this.height - 1;
canvas.drawBitmap(this.images[selected], this.inRect, this.outRect, null);
this.paint.setColor(Color.rgb(0, 160, 255));
canvas.drawRect(this.outRect.left + BORDER_SIZE / 2.0f, this.outRect.top + BORDER_SIZE / 2.0f,
this.outRect.right - BORDER_SIZE / 2.0f, this.outRect.bottom - BORDER_SIZE / 2.0f, this.paint);
}
}
}
@Override
protected void onMeasure(final int widthMeasureSpec, final int heightMeasureSpec)
{
this.setMeasuredDimension(MeasureSpec.getSize(widthMeasureSpec), MeasureSpec.getSize(heightMeasureSpec));
}
@Override
protected void onSizeChanged(final int w, final int h, final int oldw, final int oldh)
{
this.width = w;
this.height = h;
super.onSizeChanged(w, h, oldw, oldh);
}
@Override
public boolean onTouchEvent(final MotionEvent event)
{
if (!this.isEnabled())
{
return true;
}
switch (event.getAction())
{
case MotionEvent.ACTION_UP:
{
touchedX = event.getX();
this.touchedY = event.getY();
this.touchingX = event.getX();
final int touch_pos = (int) (this.touchedX / this.getImageWidth());
touchedIndex = this.indexes[Math.min(Math.max(touch_pos, 0), this.indexes.length - 1)];
if (touchedIndex != -1)
{
if(touchedIndex != selected)
{
selected = touchedIndex;
this.notifyListener();
}
}
this.touchedIndex = -1;
}
break;
default:
break;
}
this.invalidate();
this.requestLayout();
return true;
}
public void setContent(final Bitmap[] images, final SequenceListener listener)
{
if (images != null)
{
this.listener = listener;
this.images = new Bitmap[images.length];
System.arraycopy(images, 0, this.images, 0, images.length);
this.initIndexes();
}
}
private void notifyListener()
{
if (this.listener != null)
{
this.listener.onSequenceChanged(selected);
}
}
private void initIndexes()
{
if (this.images != null)
{
this.indexes = new int[this.images.length];
for (int i = 0; i < this.images.length; i++)
{
this.indexes[i] = i;
}
this.enabled = new boolean[this.images.length];
for (int i = 0; i < this.images.length; i++)
{
this.enabled[i] = true;
}
} else
{
throw new RuntimeException();
}
}
private int getImageWidth()
{
return (this.width / this.images.length);
}
}