/*
* Copyright (C) 2012 Alex Kuiper
*
* This file is part of PageTurner
*
* PageTurner 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.
*
* PageTurner 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 PageTurner. If not, see <http://www.gnu.org/licenses/>.*
*
* Based on the AlphabetListView which can be found here:
*
* http://devtcg.blogspot.com/2008/03/custom-android-list-view-widget-to.html
*/
package net.nightwhistler.pageturner.view;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.widget.LinearLayout;
import android.widget.TextView;
import net.nightwhistler.pageturner.Configuration;
import net.nightwhistler.pageturner.Configuration.ColourProfile;
import net.nightwhistler.pageturner.R;
import roboguice.RoboGuice;
import java.util.ArrayList;
import java.util.List;
public class AlphabetBar extends LinearLayout
{
private static final String TAG = "AlphabetBar";
private List<Character> alphabet = new ArrayList<Character>();
private AlphabetCallback callback;
public AlphabetBar(Context context)
{
super(context);
init();
}
public AlphabetBar(Context context, AttributeSet attrs)
{
super(context, attrs);
ColourProfile profile = RoboGuice.getInjector(context).getInstance(Configuration.class)
.getColourProfile();
if ( profile == ColourProfile.DAY ) {
setBackgroundResource(R.drawable.alphabet_bar_bg);
} else {
setBackgroundResource(R.drawable.alphabet_bar_bg_dark);
}
init();
}
public void setAlphabet(List<Character> alphabet ) {
this.alphabet = alphabet;
updateLabels();
invalidate();
}
public void setCallback(AlphabetCallback callback) {
this.callback = callback;
}
private void updateLabels() {
removeAllViews();
for ( final Character currentChar: this.alphabet ) {
TextView label = new TextView(getContext());
label.setText(String.valueOf(currentChar));
label.setGravity(Gravity.CENTER_VERTICAL);
label.setClickable(true);
label.setFocusable(true);
label.setOnClickListener( v -> {
if ( callback != null ) {
callback.characterClicked(currentChar);
}
});
addView(label, new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.WRAP_CONTENT));
}
}
public void init()
{
setLayoutParams(new LinearLayout.LayoutParams(
LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
/* Not strictly necessary since we override onLayout and onMeasure with
* our custom logic, but it seems like good form to do this just to
* show how we're arranging the children. */
setOrientation(VERTICAL);
}
@Override
protected void onLayout(boolean changed, int l, int t, int r, int b)
{
super.onLayout(changed, l, t, r, b);
}
@Override
protected void onMeasure(int wSpec, int hSpec)
{
Log.d(TAG, "onMeasure(" + wSpec + ", " + hSpec + ")");
int count = getChildCount();
int hMode = MeasureSpec.getMode(hSpec);
int hSize = MeasureSpec.getSize(hSpec);
assert hMode == MeasureSpec.EXACTLY;
int maxWidth = 0;
int hSizeAdj = hSize - getPaddingTop() - getPaddingBottom();
float childHeight = 0f;
if ( count > 0 ) {
childHeight = hSizeAdj / count;
}
/* Calculate how many extra 1-pixel spaces we'll need in order to make
* childHeight align to integer heights. */
int variance = hSizeAdj - ((int)childHeight * count);
int paddingWidth = getPaddingLeft() + getPaddingRight();
for (int i = 0; i < count; i++)
{
TextView label = (TextView)getChildAt(i);
label.setTextSize(childHeight * 0.5F);
int thisHeight = (int)childHeight;
if (variance > 0)
{
thisHeight++;
variance--;
}
label.measure
(MeasureSpec.makeMeasureSpec(26, MeasureSpec.EXACTLY),
MeasureSpec.makeMeasureSpec(thisHeight, MeasureSpec.EXACTLY));
maxWidth = Math.max(maxWidth, label.getMeasuredWidth());
}
maxWidth += paddingWidth;
setMeasuredDimension(resolveSize(maxWidth, wSpec), hSize);
}
public static interface AlphabetCallback {
public void characterClicked( Character c );
}
}