/******************************************************************************* * Copyright 2012-present Pixate, Inc. * * Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. ******************************************************************************/ package com.pixate.freestyle.styling.adapters; import java.util.ArrayList; import java.util.List; import android.app.ActionBar; import android.content.Context; import android.content.res.TypedArray; import android.graphics.RectF; import android.util.DisplayMetrics; import android.view.WindowManager; import com.pixate.freestyle.PixateFreestyle; import com.pixate.freestyle.annotations.PXDocElement; import com.pixate.freestyle.styling.PXRuleSet; import com.pixate.freestyle.styling.stylers.PXFillStyler; import com.pixate.freestyle.styling.stylers.PXShapeStyler; import com.pixate.freestyle.styling.stylers.PXStyler; import com.pixate.freestyle.styling.stylers.PXStylerContext; import com.pixate.freestyle.styling.virtualStyleables.PXVirtualActionBarIcon; import com.pixate.freestyle.styling.virtualStyleables.PXVirtualActionBarLogo; import com.pixate.freestyle.styling.virtualStyleables.PXVirtualActionBarSplit; import com.pixate.freestyle.styling.virtualStyleables.PXVirtualActionBarStacked; import com.pixate.freestyle.util.PXDrawableUtil; /** * A style adapter for {@link ActionBar} * * @author Shalom Gibly */ @PXDocElement public class PXActionBarStyleAdapter extends PXStyleAdapter { private static String ELEMENT_NAME = "action-bar"; private static PXActionBarStyleAdapter instance; /** * Returns an instance of this {@link PXActionBarStyleAdapter} */ public static PXActionBarStyleAdapter getInstance() { synchronized (PXActionBarStyleAdapter.class) { if (instance == null) { instance = new PXActionBarStyleAdapter(); } } return instance; } protected PXActionBarStyleAdapter() { } /* * (non-Javadoc) * @see * com.pixate.freestyle.styling.adapters.PXImageViewStyleAdapter#getElementName * (java.lang.Object) */ @Override public String getElementName(Object object) { return ELEMENT_NAME; } @Override protected List<Object> getVirtualChildren(Object styleable) { List<Object> virtuals = new ArrayList<Object>(); virtuals.add(new PXVirtualActionBarStacked(styleable)); virtuals.add(new PXVirtualActionBarSplit(styleable)); virtuals.add(new PXVirtualActionBarIcon(styleable)); virtuals.add(new PXVirtualActionBarLogo(styleable)); // virtuals.add(new PXActionBarDivider(styleable)); return virtuals; } /* * (non-Javadoc) * @see com.pixate.freestyle.styling.adapters.PXStyleAdapter#createStylers() */ @Override protected List<PXStyler> createStylers() { // We only add stylers that update the context. None of these stylers // should update a View, as this adapter is a non-view adapter. List<PXStyler> stylers = new ArrayList<PXStyler>(); stylers.add(PXShapeStyler.getInstance()); stylers.add(PXFillStyler.getInstance()); return stylers; } /* * (non-Javadoc) * @see * com.pixate.freestyle.styling.adapters.PXStyleAdapter#getBounds(java.lang * .Object) */ @Override public RectF getBounds(Object styleable) { return getActionBarBounds((ActionBar) styleable); } /** * Compute the {@link ActionBar} bounds. The computation is taking the * action-bar height value from the theme (in case the ActionBar does not * hold height information), and the actual screen width, to compute and * return the bounds. * * @param ab An {@link ActionBar} * @return A {@link RectF} description of the {@link ActionBar} bounds * (dimensions) */ public static RectF getActionBarBounds(ActionBar ab) { float height = ab.getHeight(); if (height <= 0) { // Unfortunately, we have to compute the ActionBar dimensions. Even // the height we get from the ActionBar styleable instance via // getHeight() is returned as zero. We get the height value from the // theme, and the width value from the screen. final TypedArray styledAttributes = PixateFreestyle.getAppContext().getTheme() .obtainStyledAttributes(new int[] { android.R.attr.actionBarSize }); height = (int) styledAttributes.getDimension(0, 0); } // compute the width of the screen. Context context = PixateFreestyle.getAppContext(); WindowManager windowManager = (WindowManager) context .getSystemService(Context.WINDOW_SERVICE); DisplayMetrics dimension = new DisplayMetrics(); windowManager.getDefaultDisplay().getMetrics(dimension); return new RectF(0, 0, dimension.widthPixels, height); } /* * (non-Javadoc) * @see * com.pixate.freestyle.styling.adapters.PXStyleAdapter#updateStyle(java. * util.List, java.util.List) */ @Override public boolean updateStyle(List<PXRuleSet> ruleSets, List<PXStylerContext> contexts) { // For the default case where we style just the action-bar, with no // virtual child involved, we will generate and set a background // drawable that will act as the default background. if (!super.updateStyle(ruleSets, contexts)) { return false; } PXStylerContext context = contexts.get(0); ActionBar actionBar = (ActionBar) context.getStyleable(); // We just overwrite the exiting background. No states merging here. RectF bounds = getBounds(actionBar); actionBar.setBackgroundDrawable(PXDrawableUtil.createDrawable(bounds, context.getCombinedPaints())); return true; } }