/* * Copyright (C) 2014 AChep@xda <artemchep@gmail.com> * * This program 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 2 * of the License, or (at your option) any later version. * * This program 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 this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, * MA 02110-1301, USA. */ package com.achep.acdisplay.ui.components; import android.graphics.Bitmap; import android.support.annotation.NonNull; import android.support.annotation.Nullable; import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import com.achep.acdisplay.Config; import com.achep.acdisplay.ui.fragments.AcDisplayFragment; import com.achep.base.tests.Check; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; /** * Base of AcDisplay's widgets. * * @author Artem Chepurnoy */ public abstract class Widget { @NonNull private final AcDisplayFragment mFragment; @NonNull protected final Callback mCallback; private ViewGroup mView; private View mIconView; private boolean mAttached; private boolean mStarted; /** * Interface definition for a callback to the host fragment. */ public interface Callback { /** * Requests the fragment to update widget's dynamic background. * * @see #getBackground() * @see #getBackgroundMask() */ void requestBackgroundUpdate(@NonNull Widget widget); /** * Requests the fragment to restart the timeout. */ void requestTimeoutRestart(@NonNull Widget widget); /** * Requests the fragment to stick this widget and turn on the special timeout mode. */ void requestWidgetStick(@NonNull Widget widget); } public Widget(@NonNull Callback callback, @NonNull AcDisplayFragment fragment) { mCallback = callback; mFragment = fragment; } /** * {@inheritDoc} */ @Override public int hashCode() { return new HashCodeBuilder(23, 651) .append(mFragment) .append(mView) .append(mIconView) .append(mAttached) .append(mStarted) .toHashCode(); } /** * {@inheritDoc} */ @Override public boolean equals(Object o) { if (o == this) return true; if (!(o instanceof Widget)) return false; Widget widget = (Widget) o; return new EqualsBuilder() .append(mAttached, widget.mAttached) .append(mStarted, widget.mStarted) .append(mFragment, widget.mFragment) .append(mView, widget.mView) .append(mIconView, widget.mIconView) .isEquals(); } /** * @return the host fragment */ @NonNull public AcDisplayFragment getFragment() { return mFragment; } @NonNull public Config getConfig() { return mFragment.getConfig(); } //-- HOME WIDGET ---------------------------------------------------------- public boolean isHomeWidget() { return false; } public boolean hasClock() { return false; } //-- DISMISSING WIDGET ---------------------------------------------------- /** * @return {@code true} if the widget can be dismissed, {@code false} otherwise * @see #onDismiss() */ public boolean isDismissible() { return !isHomeWidget(); } /** * Called when widget is being dismissed. For example, here you need to dismiss * notification from system if it's notification widget. * * @see #isDismissible() */ public void onDismiss() { /* reserved for children */ } //-- READING WIDGET ------------------------------------------------------- /** * @return {@code true} if the widget can be read aloud, {@code false} otherwise * @see #getReadAloudText() */ public boolean isReadable() { return false; } /** * @return Text to be read aloud. * @see #isReadable() */ @Nullable public CharSequence getReadAloudText() { return null; } //-- DYNAMIC BACKGROUND --------------------------------------------------- /** * @return The bitmap to be used as background, {@code null} if no background. * @see #getBackgroundMask() */ @Nullable public Bitmap getBackground() { return null; } /** * @return The mask of widget's background, or {@code 0} to show background * not depending on any config. * @see Config#DYNAMIC_BG_ARTWORK_MASK * @see Config#DYNAMIC_BG_NOTIFICATION_MASK * @see #getBackground() */ public int getBackgroundMask() { return 0; } //-- LIFE CYCLE ----------------------------------------------------------- public final void start() { if (mStarted) return; mStarted = true; onStart(); } public final void stop() { if (!mStarted) return; mStarted = false; onStop(); } public final boolean isStarted() { return mStarted; } public void onStart() { /* empty */ } /** * This is called when the {@link #getView() view} is attached to host fragment. * Here you need to update view's content. * * @see #onViewDetached() * @see #isViewAttached() */ public void onViewAttached() { Check.getInstance().isFalse(mAttached); mAttached = true; } /** * This is called when the {@link #getView() view} is detached from host fragment. * * @see #onViewAttached() * @see #isViewAttached() */ public void onViewDetached() { Check.getInstance().isTrue(mAttached); mAttached = false; } public boolean isViewAttached() { return mAttached; } public void onStop() { /* empty */ } //-- VIEWS ---------------------------------------------------------------- /** * @return The icon of this widget. * @see #onCreateIconView(android.view.LayoutInflater, android.view.ViewGroup) */ public View getIconView() { return mIconView; } /** * Returns the view of widget. Please note, that this view can be reused by * other similar widgets. * * @return The main view of this widget. * @see #onViewAttached() * @see #onViewDetached() * @see #isViewAttached() * @see #onCreateView(android.view.LayoutInflater, android.view.ViewGroup, android.view.ViewGroup) */ public ViewGroup getView() { return mView; } public View createIconView(LayoutInflater inflater, ViewGroup container) { mIconView = onCreateIconView(inflater, container); return mIconView; } public ViewGroup createView(LayoutInflater inflater, ViewGroup container, ViewGroup view) { mView = onCreateView(inflater, container, view); return mView; } protected View onCreateIconView( @NonNull LayoutInflater inflater, @NonNull ViewGroup container) { return null; } protected ViewGroup onCreateView( @NonNull LayoutInflater inflater, @NonNull ViewGroup container, @Nullable ViewGroup view) { return null; } }