michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this file, michael@0: * You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: package org.mozilla.gecko.toolbar; michael@0: michael@0: import org.mozilla.gecko.GeckoApplication; michael@0: import org.mozilla.gecko.LightweightTheme; michael@0: import org.mozilla.gecko.LightweightThemeDrawable; michael@0: import org.mozilla.gecko.R; michael@0: import org.mozilla.gecko.widget.ThemedImageButton; michael@0: michael@0: import android.content.Context; michael@0: import android.content.res.TypedArray; michael@0: import android.graphics.Canvas; michael@0: import android.graphics.Path; michael@0: import android.graphics.PorterDuff.Mode; michael@0: import android.graphics.drawable.Drawable; michael@0: import android.graphics.drawable.StateListDrawable; michael@0: import android.util.AttributeSet; michael@0: michael@0: public class ShapedButton extends ThemedImageButton michael@0: implements CanvasDelegate.DrawManager { michael@0: protected final LightweightTheme mTheme; michael@0: michael@0: private final Path mPath; michael@0: private final CurveTowards mSide; michael@0: michael@0: protected final CanvasDelegate mCanvasDelegate; michael@0: michael@0: private enum CurveTowards { NONE, LEFT, RIGHT }; michael@0: michael@0: public ShapedButton(Context context, AttributeSet attrs) { michael@0: super(context, attrs); michael@0: mTheme = ((GeckoApplication) context.getApplicationContext()).getLightweightTheme(); michael@0: michael@0: TypedArray a = context.obtainStyledAttributes(attrs, R.styleable.BrowserToolbarCurve); michael@0: int curveTowards = a.getInt(R.styleable.BrowserToolbarCurve_curveTowards, 0x00); michael@0: a.recycle(); michael@0: michael@0: if (curveTowards == 0x00) michael@0: mSide = CurveTowards.NONE; michael@0: else if (curveTowards == 0x01) michael@0: mSide = CurveTowards.LEFT; michael@0: else michael@0: mSide = CurveTowards.RIGHT; michael@0: michael@0: // Path is clipped. michael@0: mPath = new Path(); michael@0: mCanvasDelegate = new CanvasDelegate(this, Mode.DST_IN); michael@0: michael@0: setWillNotDraw(false); michael@0: } michael@0: michael@0: @Override michael@0: public void onMeasure(int widthMeasureSpec, int heightMeasureSpec) { michael@0: super.onMeasure(widthMeasureSpec, heightMeasureSpec); michael@0: michael@0: if (mSide == CurveTowards.NONE) michael@0: return; michael@0: michael@0: final int width = getMeasuredWidth(); michael@0: final int height = getMeasuredHeight(); michael@0: final int curve = (int) (height * 1.125f); michael@0: michael@0: mPath.reset(); michael@0: michael@0: if (mSide == CurveTowards.RIGHT) { michael@0: mPath.moveTo(0, 0); michael@0: mPath.cubicTo(curve * 0.75f, 0, michael@0: curve * 0.25f, height, michael@0: curve, height); michael@0: mPath.lineTo(width, height); michael@0: mPath.lineTo(width, 0); michael@0: mPath.lineTo(0, 0); michael@0: } else if (mSide == CurveTowards.LEFT) { michael@0: mPath.moveTo(width, 0); michael@0: mPath.cubicTo((width - (curve * 0.75f)), 0, michael@0: (width - (curve * 0.25f)), height, michael@0: (width - curve), height); michael@0: mPath.lineTo(0, height); michael@0: mPath.lineTo(0, 0); michael@0: } michael@0: } michael@0: michael@0: @Override michael@0: public void draw(Canvas canvas) { michael@0: if (mCanvasDelegate != null && mSide != CurveTowards.NONE) michael@0: mCanvasDelegate.draw(canvas, mPath, getWidth(), getHeight()); michael@0: else michael@0: defaultDraw(canvas); michael@0: } michael@0: michael@0: @Override michael@0: public void defaultDraw(Canvas canvas) { michael@0: super.draw(canvas); michael@0: } michael@0: michael@0: // The drawable is constructed as per @drawable/shaped_button. michael@0: @Override michael@0: public void onLightweightThemeChanged() { michael@0: final int background = getResources().getColor(R.color.background_tabs); michael@0: final LightweightThemeDrawable lightWeight = mTheme.getColorDrawable(this, background); michael@0: michael@0: if (lightWeight == null) michael@0: return; michael@0: michael@0: lightWeight.setAlpha(34, 34); michael@0: michael@0: final StateListDrawable stateList = new StateListDrawable(); michael@0: stateList.addState(PRESSED_ENABLED_STATE_SET, getColorDrawable(R.color.highlight_shaped)); michael@0: stateList.addState(FOCUSED_STATE_SET, getColorDrawable(R.color.highlight_shaped_focused)); michael@0: stateList.addState(PRIVATE_STATE_SET, getColorDrawable(R.color.background_tabs)); michael@0: stateList.addState(EMPTY_STATE_SET, lightWeight); michael@0: michael@0: setBackgroundDrawable(stateList); michael@0: } michael@0: michael@0: @Override michael@0: public void onLightweightThemeReset() { michael@0: setBackgroundResource(R.drawable.shaped_button); michael@0: } michael@0: michael@0: @Override michael@0: public void setBackgroundDrawable(Drawable drawable) { michael@0: if (getBackground() == null || drawable == null) { michael@0: super.setBackgroundDrawable(drawable); michael@0: return; michael@0: } michael@0: michael@0: int[] padding = new int[] { getPaddingLeft(), michael@0: getPaddingTop(), michael@0: getPaddingRight(), michael@0: getPaddingBottom() michael@0: }; michael@0: drawable.setLevel(getBackground().getLevel()); michael@0: super.setBackgroundDrawable(drawable); michael@0: michael@0: setPadding(padding[0], padding[1], padding[2], padding[3]); michael@0: } michael@0: michael@0: @Override michael@0: public void setBackgroundResource(int resId) { michael@0: setBackgroundDrawable(getResources().getDrawable(resId)); michael@0: } michael@0: }