/*******************************************************************************
* 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.virtualAdapters;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import android.annotation.TargetApi;
import android.graphics.drawable.Drawable;
import android.os.Build;
import android.widget.Spinner;
import com.pixate.freestyle.styling.PXRuleSet;
import com.pixate.freestyle.styling.adapters.PXStyleAdapter;
import com.pixate.freestyle.styling.cache.PXStyleInfo;
import com.pixate.freestyle.styling.stylers.PXFillStyler;
import com.pixate.freestyle.styling.stylers.PXSpinnerDropDownStyler;
import com.pixate.freestyle.styling.stylers.PXStyler;
import com.pixate.freestyle.styling.stylers.PXStylerContext;
import com.pixate.freestyle.styling.virtualStyleables.PXVirtualStyleable;
import com.pixate.freestyle.util.PXDrawableUtil;
import com.pixate.freestyle.util.PXLog;
/**
* Virtual drop-down adapter for {@link Spinner}<code>s</code>. Handles
* <code>dropdown-xxx</code> declarations.
*
* @author Shalom Gibly
*/
public class PXVirtualDropDownAdapter extends PXStyleAdapter {
private static String ELEMENT_NAME = "dropdown";
private static PXVirtualDropDownAdapter instance;
/**
* Returns a singleton instance of this class.
*
* @return An instance of {@link PXVirtualDropDownAdapter}
*/
public static PXVirtualDropDownAdapter getInstance() {
synchronized (PXVirtualDropDownAdapter.class) {
if (instance == null) {
instance = new PXVirtualDropDownAdapter();
}
}
return instance;
}
protected PXVirtualDropDownAdapter() {
}
/*
* (non-Javadoc)
* @see
* com.pixate.freestyle.styling.adapters.PXViewStyleAdapter#getElementName
* (java.lang.Object)
*/
@Override
public String getElementName(Object object) {
return ELEMENT_NAME;
}
@Override
public List<String> getSupportedPseudoClasses(Object styleable) {
// FIXME - Note that we return the entire list of possible pseudo
// classes,
// although only two can actually be used here ('default' and
// 'above-anchor'). Eventually we'll need to do a smarter map from the
// pseudo class name to the Android integer number for that state.
return new ArrayList<String>(PXDrawableUtil.getSupportedStates().keySet());
}
@Override
public String getDefaultPseudoClass(Object styleable) {
return PXStyleInfo.DEFAULT_STYLE;
}
/*
* (non-Javadoc)
* @see
* com.pixate.freestyle.styling.adapters.PXStyleAdapter#getParent(java.lang
* .Object)
*/
@Override
public Object getParent(Object styleable) {
// Make sure we return the virtual styleable parent, which is a 'real'
// view.
if (styleable instanceof PXVirtualStyleable) {
return ((PXVirtualStyleable) styleable).getParent();
}
return super.getParent(styleable);
}
/*
* (non-Javadoc)
* @see com.pixate.freestyle.styling.adapters.PXStyleAdapter#createStylers()
*/
@Override
protected List<PXStyler> createStylers() {
List<PXStyler> stylers = new ArrayList<PXStyler>();
stylers.add(PXFillStyler.getInstance());
stylers.add(PXSpinnerDropDownStyler.getInstance());
return stylers;
}
@Override
public boolean updateStyle(List<PXRuleSet> ruleSets, List<PXStylerContext> contexts) {
// The fill styler should read any background image to the context, so
// we are grabbing it to be used as the popup background.
if (!super.updateStyle(ruleSets, contexts)) {
return false;
}
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.JELLY_BEAN) {
setPopupBackgroundImage(ruleSets, contexts);
} else {
if (PXLog.isLogging()) {
PXLog.w(PXVirtualDropDownAdapter.class.getSimpleName(),
"Spinner's pop-up background image setting requires API 16");
}
}
return true;
}
/**
* Sets the popup window background image. Note that the size cannot be
* determined at this point, so it's also recommended to set the
* background-size in the CSS (batter scaling down from a bigger image than
* scale up from a default 32x32 image).
*
* @param ruleSets
* @param contexts
*/
@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
private void setPopupBackgroundImage(List<PXRuleSet> ruleSets, List<PXStylerContext> contexts) {
Spinner spinner = (Spinner) contexts.get(0).getStyleable();
// Get the spinner adapter. We'll use it to create the states, although
// its default implementation does not create any additional state-sets
// (which is fine).
PXStyleAdapter spinnerAdapter = PXStyleAdapter.getStyleAdapter(spinner);
Map<int[], Drawable> existingPopupStates = PXDrawableUtil.getExistingStates(spinner
.getPopupBackground());
Drawable newPopupBackground = null;
if (existingPopupStates == null || existingPopupStates.isEmpty()) {
// create a new background for the popup
newPopupBackground = PXDrawableUtil.createNewStateListDrawable(spinnerAdapter,
ruleSets, contexts);
} else {
// merge or replace the states with what we have in the CSS
newPopupBackground = PXDrawableUtil.createDrawable(spinnerAdapter,
existingPopupStates, ruleSets, contexts);
}
if (newPopupBackground != null) {
spinner.setPopupBackgroundDrawable(newPopupBackground);
}
}
}