package com.icystar.dicegenerator;
import java.util.Stack;
import android.content.Context;
import android.graphics.Rect;
import android.graphics.Typeface;
import android.text.TextPaint;
import android.util.AttributeSet;
import android.util.TypedValue;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.FrameLayout;
import android.widget.ImageButton;
import android.widget.ImageView.ScaleType;
import android.widget.TextView;
import com.icystar.dicegenerator.MainActivity.Drop;
public class ResizerFrameLayout extends FrameLayout {
public static class Measures {
public Typeface typeface;
public float indicatorFontSize;
public float numberFontSize;
public float buttonFontSize;
public int indicatorButtonSize;
public int historyItemWidth;
public int dicesItemWidth;
public int padding;
public float fitText(String text, TextPaint textPaint, int w, int h) {
float max = 100.f;
float min = 2.f;
float precision = 0.5f;
while (max - min > precision) {
float current = (max + min)/2.f;
textPaint.setTextSize(current);
Rect bounds = new Rect();
textPaint.getTextBounds(text, 0, text.length(), bounds);
int tw = Math.max(bounds.right, 0) - Math.min(bounds.left, 0);
int th = Math.max(bounds.bottom, 0) - Math.min(bounds.top, 0);
if (tw >= w || th >= h)
max = current;
else
min = current;
}
return min;
}
public float widthOfText(String text, TextPaint textPaint, float size) {
textPaint.setTextSize(size);
Rect bounds = new Rect();
textPaint.getTextBounds(text, 0, text.length(), bounds);
return Math.max(bounds.right, 0) - Math.min(bounds.left, 0);
}
public Measures(int width, int height, TextPaint textPaint) {
typeface = textPaint.getTypeface();
padding = width/40;
indicatorButtonSize = Math.min(width/6, height/5);
int indicatorWidth = width - indicatorButtonSize*2;
if (width > height && indicatorWidth > width/2) indicatorWidth = width/2;
int indicatorTextWidth = indicatorWidth - padding*2;
indicatorFontSize = fitText(Drop.template, textPaint, indicatorTextWidth, indicatorButtonSize/3);
int buttonWidth = Math.round((float)width/3.f/1.5f);
int buttonHeight = Math.round((float)(height-indicatorButtonSize)/4.f/3.f);
numberFontSize = fitText("0", textPaint, buttonWidth, buttonHeight);
buttonFontSize = fitText("Mmmm", textPaint, buttonWidth, buttonHeight);
historyItemWidth = Math.round(widthOfText(Drop.template, textPaint, indicatorFontSize)) + 1 + padding*2;
historyItemWidth = historyItemWidth > width ? width : width / (width/historyItemWidth) - 1;
dicesItemWidth = Math.round(widthOfText(Drop.diceTemplate, textPaint, indicatorFontSize)) + 1 + padding*3;
}
}
public int appliedWidth = 0;
public int appliedHeight = 0;
public boolean needLayout = false;
public TextPaint textPaint;
public Stack<Runnable> afterLayout = new Stack<Runnable>();
public Runnable requestLayoutPost;
public ResizerFrameLayout(Context context) {
super(context);
initialize();
}
public ResizerFrameLayout(Context context, AttributeSet attrs) {
super(context, attrs);
initialize();
}
public ResizerFrameLayout(Context context, AttributeSet attrs, int defStyle) {
super(context, attrs, defStyle);
initialize();
}
void initialize() {
requestLayoutPost = new Runnable() {
@Override
public void run() {
requestLayout();
}
};
TextView textView = new TextView(getContext());
textPaint = new TextPaint(textView.getPaint());
}
@Override
protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
super.onLayout(changed, left, top, right, bottom);
int w = right - left;
int h = bottom - top;
if (!isInEditMode() && (appliedWidth != w || appliedHeight != h)) {
appliedWidth = w;
appliedHeight = h;
setMeasures(this, new Measures(appliedWidth, appliedHeight, textPaint));
if (!isInEditMode()) post(requestLayoutPost);
} else {
if (!isInEditMode())
while (afterLayout.size() > 0)
post(afterLayout.pop());
}
}
void setMeasures(View view, Measures measures) {
String tag = view.getTag() == null ? "" : view.getTag().toString();
if (view instanceof ImageButton) {
ImageButton imageButton = (ImageButton)view;
imageButton.setMaxHeight(measures.indicatorButtonSize);
imageButton.setMaxWidth(measures.indicatorButtonSize);
imageButton.setMinimumWidth(measures.indicatorButtonSize);
imageButton.setMinimumHeight(measures.indicatorButtonSize);
imageButton.setScaleType(ScaleType.CENTER_INSIDE);
ViewGroup.LayoutParams layoutParams = imageButton.getLayoutParams();
layoutParams.width = measures.indicatorButtonSize;
layoutParams.height = measures.indicatorButtonSize;
imageButton.setLayoutParams(layoutParams);
} else
if (view instanceof Button) {
Button button = (Button)view;
button.setTypeface(measures.typeface);
if (tag.compareTo("historyActivityButton") == 0) {
button.setTextSize(TypedValue.COMPLEX_UNIT_PX, measures.indicatorFontSize);
} else
if (button.getText().length() == 1)
button.setTextSize(TypedValue.COMPLEX_UNIT_PX, measures.numberFontSize);
else
button.setTextSize(TypedValue.COMPLEX_UNIT_PX, measures.buttonFontSize);
} else
if (view instanceof TextView) {
TextView textView = (TextView)view;
if (tag.compareTo("indicator") == 0) {
textView.setMaxHeight(measures.indicatorButtonSize);
textView.setMinHeight(measures.indicatorButtonSize);
textView.setHeight(measures.indicatorButtonSize);
textView.setLineSpacing(0.f, 100.f);
} else
if (tag.compareTo("historyItem") == 0) {
textView.setMaxWidth(measures.historyItemWidth);
textView.setMinWidth(measures.historyItemWidth);
textView.setWidth(measures.historyItemWidth);
} else
if (tag.compareTo("dicesItem") == 0) {
textView.setMaxWidth(measures.dicesItemWidth);
textView.setMinWidth(measures.dicesItemWidth);
textView.setWidth(measures.dicesItemWidth);
}
textView.setTextSize(TypedValue.COMPLEX_UNIT_PX, measures.indicatorFontSize);
textView.setPadding(measures.padding, 0, measures.padding, 0);
textView.setTypeface(measures.typeface);
textView.requestLayout();
} else
if (view instanceof ViewGroup) {
ViewGroup viewGroup = (ViewGroup)view;
for(int i = 0; i < viewGroup.getChildCount(); i++)
setMeasures(viewGroup.getChildAt(i), measures);
}
}
}