12f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian/*
22f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * Copyright (C) 2017 The Android Open Source Project
32f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian *
42f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * Licensed under the Apache License, Version 2.0 (the "License");
52f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * you may not use this file except in compliance with the License.
62f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * You may obtain a copy of the License at
72f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian *
82f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian *      http://www.apache.org/licenses/LICENSE-2.0
92f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian *
102f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * Unless required by applicable law or agreed to in writing, software
112f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * distributed under the License is distributed on an "AS IS" BASIS,
122f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
132f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * See the License for the specific language governing permissions and
142f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * limitations under the License
152f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian */
162f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
172f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianpackage com.android.dialershared.bubble;
182f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
192f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.content.Context;
202f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.support.v4.view.AccessibilityDelegateCompat;
212f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.support.v4.view.ViewCompat;
222f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.support.v4.view.accessibility.AccessibilityEventCompat;
232f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
242f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.support.v7.widget.AppCompatImageButton;
252f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.util.AttributeSet;
262f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.view.View;
272f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.view.accessibility.AccessibilityEvent;
282f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianimport android.widget.Checkable;
292f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
302f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian/**
312f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * An {@link android.widget.ImageButton ImageButton} that implements {@link Checkable} and
322f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian * propagates the checkable state
332f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian */
342f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanianpublic class CheckableImageButton extends AppCompatImageButton implements Checkable {
352f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
362f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  // Copied without modification from AppCompat library
372f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
382f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  private static final int[] DRAWABLE_STATE_CHECKED = new int[] {android.R.attr.state_checked};
392f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
402f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  private boolean mChecked;
412f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
422f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  public CheckableImageButton(Context context) {
432f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    this(context, null);
442f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  }
452f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
462f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  public CheckableImageButton(Context context, AttributeSet attrs) {
472f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    this(context, attrs, android.R.attr.imageButtonStyle);
482f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  }
492f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
502f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  public CheckableImageButton(Context context, AttributeSet attrs, int defStyleAttr) {
512f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    super(context, attrs, defStyleAttr);
522f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
532f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    ViewCompat.setAccessibilityDelegate(
542f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian        this,
552f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian        new AccessibilityDelegateCompat() {
562f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian          @Override
572f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian          public void onInitializeAccessibilityEvent(View host, AccessibilityEvent event) {
582f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian            super.onInitializeAccessibilityEvent(host, event);
592f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian            event.setChecked(isChecked());
602f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian          }
612f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
622f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian          @Override
632f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian          public void onInitializeAccessibilityNodeInfo(
642f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian              View host, AccessibilityNodeInfoCompat info) {
652f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian            super.onInitializeAccessibilityNodeInfo(host, info);
662f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian            info.setCheckable(true);
672f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian            info.setChecked(isChecked());
682f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian          }
692f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian        });
702f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  }
712f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
722f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  @Override
732f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  public void setChecked(boolean checked) {
742f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    if (mChecked != checked) {
752f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      mChecked = checked;
762f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      refreshDrawableState();
772f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      sendAccessibilityEvent(AccessibilityEventCompat.TYPE_WINDOW_CONTENT_CHANGED);
782f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    }
792f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  }
802f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
812f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  @Override
822f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  public boolean isChecked() {
832f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    return mChecked;
842f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  }
852f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
862f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  @Override
872f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  public void toggle() {
882f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    setChecked(!mChecked);
892f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  }
902f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian
912f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  @Override
922f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  public int[] onCreateDrawableState(int extraSpace) {
932f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    if (mChecked) {
942f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      return mergeDrawableStates(
952f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian          super.onCreateDrawableState(extraSpace + DRAWABLE_STATE_CHECKED.length),
962f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian          DRAWABLE_STATE_CHECKED);
972f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    } else {
982f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian      return super.onCreateDrawableState(extraSpace);
992f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian    }
1002f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian  }
1012f1c7586bcce334ca69022eb8dc6d8965ceb6a05Eric Erfanian}
102