com.waz.zclient.views.menus.ConfirmationMenu.java Source code

Java tutorial

Introduction

Here is the source code for com.waz.zclient.views.menus.ConfirmationMenu.java

Source

/**
 * Wire
 * Copyright (C) 2016 Wire Swiss GmbH
 *
 * 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 3 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, see <http://www.gnu.org/licenses/>.
 */
package com.waz.zclient.views.menus;

import android.animation.Animator;
import android.animation.AnimatorListenerAdapter;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.graphics.drawable.Drawable;
import android.support.annotation.DrawableRes;
import android.support.v4.content.ContextCompat;
import android.text.TextUtils;
import android.util.AttributeSet;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import com.waz.zclient.R;
import com.waz.zclient.controllers.confirmation.ConfirmationCallback;
import com.waz.zclient.controllers.confirmation.ConfirmationRequest;
import com.waz.zclient.ui.animation.interpolators.penner.Expo;
import com.waz.zclient.ui.animation.interpolators.penner.Quart;
import com.waz.zclient.ui.text.GlyphTextView;
import com.waz.zclient.ui.theme.OptionsTheme;
import com.waz.zclient.ui.utils.ColorUtils;
import com.waz.zclient.ui.views.ZetaButton;
import com.waz.zclient.utils.LayoutSpec;
import com.waz.zclient.utils.ViewUtils;
import com.waz.zclient.views.CheckBoxView;

public class ConfirmationMenu extends LinearLayout {
    private static final int DEFAULT_COLOR = Color.BLUE;
    private String header;
    private String text;
    private String positiveButtonText;
    private String negativeButtonText;
    private boolean cancelVisible;
    private String checkboxLabelText;
    private boolean checkboxSelectedByDefault;
    private int headerIconRes;
    private int backgroundImage;

    private TextView headerTextView;
    private TextView contentTextView;
    private ZetaButton positiveButton;
    private GlyphTextView cancelButton;
    private ZetaButton negativeButton;
    private CheckBoxView checkBoxView;
    private ImageView headerIconView;
    private ImageView backgroundImageView;
    private View backgroundView;
    private View messageContainerView;
    private boolean confirmed;
    private boolean cancelled;
    private ConfirmationCallback callback;
    private OptionsTheme optionsTheme;
    private boolean noRoundBackground;

    public void setNoRoundBackground() {
        noRoundBackground = true;
    }

    private final OnClickListener onClickListener = new OnClickListener() {

        @Override
        public void onClick(View v) {
            if (callback == null) {
                return;
            }
            switch (v.getId()) {
            case R.id.positive:
                confirmed = true;
                boolean checkboxIsSelected = checkBoxView.getVisibility() == VISIBLE && checkBoxView.isSelected();
                animateToShow(false);
                callback.positiveButtonClicked(checkboxIsSelected);
                break;
            case R.id.negative:
                callback.negativeButtonClicked();
                animateToShow(false);
                break;
            case R.id.cancel:
                cancelled = true;
                callback.canceled();
                animateToShow(false);
            default:
                break;
            }
        }
    };

    public ConfirmationMenu(Context context, AttributeSet attrs, int defStyle) {
        super(context, attrs, defStyle);
        initAttributes(attrs);
        if (!isInEditMode()) {
            initViews();
        }
    }

    public ConfirmationMenu(Context context, AttributeSet attrs) {
        super(context, attrs);
        initAttributes(attrs);
        if (!isInEditMode()) {
            initViews();
        }
    }

    private void initAttributes(AttributeSet attrs) {
        TypedArray a = getContext().obtainStyledAttributes(attrs, R.styleable.ConfirmationMenu);
        header = a.getString(R.styleable.ConfirmationMenu_header);
        text = a.getString(R.styleable.ConfirmationMenu_text);
        negativeButtonText = a.getString(R.styleable.ConfirmationMenu_negative);
        positiveButtonText = a.getString(R.styleable.ConfirmationMenu_positive);
        cancelVisible = a.getBoolean(R.styleable.ConfirmationMenu_cancelVisible, false);
        checkboxLabelText = a.getString(R.styleable.ConfirmationMenu_checkboxLabel);
        checkboxSelectedByDefault = a.getBoolean(R.styleable.ConfirmationMenu_checkboxIsSelected, false);
        headerIconRes = a.getResourceId(R.styleable.ConfirmationMenu_headerIcon, 0);
        backgroundImage = a.getResourceId(R.styleable.ConfirmationMenu_backgroundImage, 0);
        a.recycle();
    }

    public void setHeader(String text) {
        updateText(headerTextView, text);
    }

    public void setText(String text) {
        updateText(contentTextView, text);
    }

    public void setNegativeButton(String text) {
        updateText(negativeButton, text);
        if (negativeButton.getVisibility() == GONE) {
            ViewUtils.setMarginLeft(positiveButton, 0);
        }
    }

    public void setCancelVisible(boolean visible) {
        cancelVisible = visible;
        cancelButton.setVisibility(cancelVisible ? VISIBLE : GONE);
    }

    public void setPositiveButton(String text) {
        updateText(positiveButton, text);
    }

    public void setCheckBox(String label, boolean selectedByDefault) {
        checkboxLabelText = label;
        checkboxSelectedByDefault = selectedByDefault;
        if (TextUtils.isEmpty(checkboxLabelText)) {
            checkBoxView.setVisibility(GONE);
        } else {
            checkBoxView.setVisibility(VISIBLE);
            checkBoxView.setLabelText(checkboxLabelText);
            checkBoxView.setSelected(checkboxSelectedByDefault);
        }
    }

    private void updateText(TextView view, String text) {
        view.setText(text);
        if (!TextUtils.isEmpty(text)) {
            view.setVisibility(VISIBLE);
        } else {
            view.setVisibility(GONE);
        }
    }

    public void setButtonColor(int color) {
        positiveButton.setIsFilled(true);
        positiveButton.setAccentColor(color);

        negativeButton.setIsFilled(false);
        negativeButton.setAccentColor(color);
        if (optionsTheme != null && optionsTheme.getType() == OptionsTheme.Type.LIGHT) {
            negativeButton.setTextColor(color);
        }

        backgroundImageView.setColorFilter(ColorUtils.injectAlpha(0.1f, color));
    }

    public void useModalBackground(boolean show) {
        backgroundView.setVisibility(show ? VISIBLE : GONE);
    }

    public void setIcon(@DrawableRes int icon) {
        this.headerIconRes = icon;
        headerIconView.setVisibility(icon == 0 ? GONE : VISIBLE);
        headerIconView.setImageResource(icon);
    }

    public void setBackgroundImage(@DrawableRes int imageId) {
        this.backgroundImage = imageId;
        if (imageId != 0) {
            backgroundImageView.setImageDrawable(ContextCompat.getDrawable(getContext(), imageId));
            backgroundImageView.setVisibility(VISIBLE);
        } else {
            backgroundImageView.setVisibility(GONE);
        }
    }

    public void animateToShow(boolean show) {
        if (show) {
            confirmed = false;
            cancelled = false;

            // Init views and post animations to get measured height of message container
            backgroundView.setAlpha(0);
            messageContainerView.setVisibility(INVISIBLE);
            setVisibility(VISIBLE);

            messageContainerView.post(new Runnable() {
                @Override
                public void run() {

                    ObjectAnimator showBackgroundAnimator = ObjectAnimator.ofFloat(backgroundView, View.ALPHA, 0,
                            1);
                    showBackgroundAnimator.setInterpolator(new Quart.EaseOut());
                    showBackgroundAnimator
                            .setDuration(getResources().getInteger(R.integer.framework_animation_duration_short));

                    ObjectAnimator showMessageAnimator = ObjectAnimator.ofFloat(messageContainerView,
                            View.TRANSLATION_Y, messageContainerView.getMeasuredHeight(), 0);
                    showMessageAnimator.setInterpolator(new Expo.EaseOut());
                    showMessageAnimator
                            .setDuration(getResources().getInteger(R.integer.framework_animation_duration_medium));
                    showMessageAnimator.setStartDelay(getResources()
                            .getInteger(R.integer.framework_animation__confirmation_menu__show_message_delay));
                    showMessageAnimator.addListener(new AnimatorListenerAdapter() {
                        @Override
                        public void onAnimationStart(Animator animation) {
                            messageContainerView.setVisibility(VISIBLE);
                        }
                    });

                    AnimatorSet showSet = new AnimatorSet();
                    showSet.playTogether(showBackgroundAnimator, showMessageAnimator);
                    showSet.setDuration(getResources()
                            .getInteger(R.integer.background_accent_color_transition_animation_duration));
                    showSet.start();
                }
            });
        } else {
            ObjectAnimator hideBackgroundAnimator = ObjectAnimator.ofFloat(backgroundView, View.ALPHA, 1, 0);
            hideBackgroundAnimator.setInterpolator(new Quart.EaseOut());
            hideBackgroundAnimator
                    .setDuration(getResources().getInteger(R.integer.framework_animation_duration_short));
            hideBackgroundAnimator.setStartDelay(getResources()
                    .getInteger(R.integer.framework_animation__confirmation_menu__hide_background_delay));
            hideBackgroundAnimator.addListener(new AnimatorListenerAdapter() {
                @Override
                public void onAnimationEnd(Animator animation) {
                    setVisibility(GONE);
                    boolean checkboxIsSelected = checkBoxView.getVisibility() == VISIBLE
                            && checkBoxView.isSelected();
                    if (callback != null) {
                        callback.onHideAnimationEnd(confirmed, cancelled, checkboxIsSelected);
                    }
                }
            });

            ObjectAnimator hideMessageAnimator = ObjectAnimator.ofFloat(messageContainerView, View.TRANSLATION_Y, 0,
                    messageContainerView.getMeasuredHeight());
            hideMessageAnimator.setInterpolator(new Expo.EaseIn());
            hideMessageAnimator
                    .setDuration(getResources().getInteger(R.integer.framework_animation_duration_medium));

            AnimatorSet hideSet = new AnimatorSet();
            hideSet.playTogether(hideMessageAnimator, hideBackgroundAnimator);
            hideSet.start();
        }
    }

    private void initViews() {
        LayoutInflater.from(getContext()).inflate(R.layout.confirmation_menu_light, this, true);

        backgroundView = ViewUtils.getView(this, R.id.fl__confirmation_dialog__background);
        messageContainerView = ViewUtils.getView(this, R.id.ll__confirmation_dialog__message_container);
        setVisibility(GONE);

        // header
        headerTextView = ViewUtils.getView(this, R.id.header);
        headerTextView.setText(header);
        if (header != null) {
            headerTextView.setVisibility(View.VISIBLE);
        }

        // text
        contentTextView = ViewUtils.getView(this, R.id.text);
        contentTextView.setText(text);
        if (text != null) {
            contentTextView.setVisibility(View.VISIBLE);
        }

        // Checkbox
        checkBoxView = ViewUtils.getView(this, R.id.ll_confirmation_menu__checkbox_container);
        if (TextUtils.isEmpty(checkboxLabelText)) {
            checkBoxView.setVisibility(GONE);
        } else {
            checkBoxView.setVisibility(VISIBLE);
            checkBoxView.setLabelText(checkboxLabelText);
            checkBoxView.setSelected(checkboxSelectedByDefault);
        }

        // buttons
        positiveButton = ViewUtils.getView(this, R.id.positive);
        positiveButton.setText(positiveButtonText);
        positiveButton.setOnClickListener(onClickListener);

        negativeButton = ViewUtils.getView(this, R.id.negative);
        negativeButton.setText(negativeButtonText);
        negativeButton.setOnClickListener(onClickListener);

        cancelButton = ViewUtils.getView(this, R.id.cancel);
        cancelButton.setVisibility(cancelVisible ? VISIBLE : GONE);
        cancelButton.setOnClickListener(onClickListener);

        headerIconView = ViewUtils.getView(this, R.id.icon);
        headerIconView.setVisibility(headerIconRes == 0 ? GONE : VISIBLE);
        headerIconView.setImageResource(headerIconRes);

        backgroundImageView = ViewUtils.getView(this, R.id.backgroundImage);
        setBackgroundImage(backgroundImage);

        // Consume all touch events
        setOnTouchListener(new OnTouchListener() {
            @Override
            public boolean onTouch(View view, MotionEvent motionEvent) {
                return true;
            }
        });
        setButtonColor(DEFAULT_COLOR);
    }

    public void setWireTheme(OptionsTheme optionsTheme) {
        this.optionsTheme = optionsTheme;
        headerTextView.setTextColor(optionsTheme.getTextColorPrimary());
        contentTextView.setTextColor(optionsTheme.getTextColorPrimary());
        cancelButton.setTextColor(optionsTheme.getIconButtonTextColor());
        cancelButton.setBackground(optionsTheme.getIconButtonBackground());
        checkBoxView.setOptionsTheme(optionsTheme);
        if (optionsTheme.getType() == OptionsTheme.Type.DARK) {
            negativeButton.setTextColor(optionsTheme.getTextColorPrimary());
        }
        setBackground(optionsTheme.getOverlayColor());
    }

    public void setBackground(int color) {
        if (LayoutSpec.isPhone(getContext())) {
            backgroundView.setBackgroundColor(color);
        } else {
            if (!noRoundBackground) {
                Drawable backgroundDrawable = ViewUtils.getRoundedRect(getContext().getResources()
                        .getDimensionPixelSize(R.dimen.background__picture__corner_radius), color);
                backgroundView.setBackground(backgroundDrawable);
            } else {
                backgroundView.setBackgroundColor(color);
            }
        }
    }

    public void onRequestConfirmation(ConfirmationRequest confirmationRequest) {
        setWireTheme(confirmationRequest.optionsTheme);
        callback = confirmationRequest.callback;
        setHeader(confirmationRequest.header);
        setText(confirmationRequest.message);
        setPositiveButton(confirmationRequest.positiveButton);
        setNegativeButton(confirmationRequest.negativeButton);
        setCancelVisible(confirmationRequest.cancelVisible);
        setIcon(confirmationRequest.headerIconRes);
        setBackgroundImage(confirmationRequest.backgroundImage);
        setCheckBox(confirmationRequest.checkboxLabel, confirmationRequest.checkboxSelectedByDefault);
        animateToShow(true);
    }

    public void setCallback(ConfirmationCallback callback) {
        this.callback = callback;
    }

    public void adjustLayout() {
        int topPadding = getResources().getDimensionPixelSize(R.dimen.framework_confirmation_menu_padding_top);
        int bottomPadding = getResources()
                .getDimensionPixelSize(R.dimen.framework_confirmation_menu_padding_bottom);
        int horizontalPadding = getResources()
                .getDimensionPixelSize(R.dimen.framework_confirmation_menu_horizontal_padding);
        messageContainerView.setPadding(horizontalPadding, topPadding, horizontalPadding, bottomPadding);
    }

    public void resetFullScreenPadding() {
        int padding = getResources().getDimensionPixelSize(R.dimen.wire__padding__big);
        messageContainerView.setPadding(padding, padding, padding, padding);

    }
}