/*
* ConnectBot: simple, powerful, open-source SSH client for Android
* Copyright 2016 Kenny Root, Jeffrey Sharkey
*
* 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 org.connectbot.views;
import java.util.List;
import org.connectbot.R;
import android.content.Context;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Rect;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.support.annotation.DrawableRes;
import android.support.annotation.StringRes;
import android.support.graphics.drawable.VectorDrawableCompat;
import android.support.v4.view.ViewCompat;
import android.support.v4.view.accessibility.AccessibilityEventCompat;
import android.support.v4.view.accessibility.AccessibilityNodeInfoCompat;
import android.support.v4.widget.ExploreByTouchHelper;
import android.support.v7.widget.SwitchCompat;
import android.util.AttributeSet;
import android.view.View;
import android.view.accessibility.AccessibilityEvent;
import android.widget.CompoundButton;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TextView;
/**
* Created by kenny on 5/31/16.
*/
public class CheckableMenuItem extends RelativeLayout {
private static final String ACCESSIBILITY_EVENT_CLASS_NAME = "android.widget.Switch";
private final Rect mPlaceHolderRect = new Rect(0, 0, 1, 1);
private static final String PLACEHOLDER_STRING = "";
private final View mRootView;
private final TextView mTitle;
private final TextView mSummary;
private final SwitchCompat mSwitch;
private final ExploreByTouchHelper mAccessHelper;
public CheckableMenuItem(Context context, AttributeSet attrs) {
this(context, attrs, 0);
}
public CheckableMenuItem(Context context, AttributeSet attrs, int defStyleAttr) {
super(context, attrs, defStyleAttr);
mRootView = inflate(context, R.layout.view_checkablemenuitem, this);
mTitle = (TextView) mRootView.findViewById(R.id.title);
mSummary = (TextView) mRootView.findViewById(R.id.summary);
mSwitch = (SwitchCompat) findViewById(R.id.checkbox_switch);
setFocusable(true);
mAccessHelper = new ExploreByTouchHelper(this) {
private final Rect mTmpRect = new Rect();
@Override
protected int getVirtualViewAt(float x, float y) {
return HOST_ID;
}
@Override
protected void getVisibleVirtualViews(List<Integer> virtualViewIds) {
}
@Override
protected void onPopulateEventForVirtualView(int virtualViewId, AccessibilityEvent event) {
if (virtualViewId != HOST_ID) {
// TODO(kroot): remove this when the bug is fixed.
event.setContentDescription(PLACEHOLDER_STRING);
return;
}
event.setContentDescription(mTitle.getText() + " " + mSummary.getText());
event.setClassName(ACCESSIBILITY_EVENT_CLASS_NAME);
event.setChecked(isChecked());
}
@Override
protected void onPopulateNodeForVirtualView(int virtualViewId, AccessibilityNodeInfoCompat node) {
if (virtualViewId != HOST_ID) {
// TODO(kroot): remove this when the bug is fixed.
node.setBoundsInParent(mPlaceHolderRect);
node.setContentDescription(PLACEHOLDER_STRING);
return;
}
mTmpRect.set(0, 0, CheckableMenuItem.this.getWidth(), CheckableMenuItem.this.getHeight());
node.setBoundsInParent(mTmpRect);
node.addAction(AccessibilityNodeInfoCompat.ACTION_CLICK);
node.setClassName(ACCESSIBILITY_EVENT_CLASS_NAME);
node.setCheckable(true);
node.setChecked(isChecked());
node.addChild(mTitle);
node.addChild(mSummary);
}
@Override
protected boolean onPerformActionForVirtualView(int virtualViewId, int action, Bundle arguments) {
if (virtualViewId != HOST_ID) {
return false;
}
if (action == AccessibilityNodeInfoCompat.ACTION_CLICK) {
mSwitch.toggle();
sendAccessibilityEvent(mRootView,
AccessibilityEventCompat.CONTENT_CHANGE_TYPE_UNDEFINED);
return true;
}
return false;
}
};
ViewCompat.setAccessibilityDelegate(mRootView, mAccessHelper);
setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
mSwitch.toggle();
}
});
if (attrs != null) {
TypedArray typedArray = getContext().obtainStyledAttributes(
attrs, R.styleable.CheckableMenuItem, 0, 0);
@DrawableRes int iconRes = typedArray.getResourceId(
R.styleable.CheckableMenuItem_android_icon, 0);
@StringRes int titleRes = typedArray.getResourceId(
R.styleable.CheckableMenuItem_android_title, 0);
@StringRes int summaryRes = typedArray.getResourceId(
R.styleable.CheckableMenuItem_summary, 0);
typedArray.recycle();
ImageView icon = (ImageView) mRootView.findViewById(R.id.icon);
mTitle.setText(titleRes);
if (iconRes != 0) {
Resources resources = context.getResources();
Resources.Theme theme = context.getTheme();
Drawable iconDrawable = VectorDrawableCompat.create(resources, iconRes, theme);
icon.setImageDrawable(iconDrawable);
}
if (summaryRes != 0) {
mSummary.setText(summaryRes);
}
}
}
public boolean isChecked() {
return mSwitch.isChecked();
}
public void setChecked(boolean checked) {
mAccessHelper.sendAccessibilityEvent(mRootView,
AccessibilityEventCompat.CONTENT_CHANGE_TYPE_UNDEFINED);
mSwitch.setChecked(checked);
}
public void toggle() {
mAccessHelper.sendAccessibilityEvent(mRootView,
AccessibilityEventCompat.CONTENT_CHANGE_TYPE_UNDEFINED);
mSwitch.toggle();
}
public void setOnCheckedChangeListener(CompoundButton.OnCheckedChangeListener listener) {
mSwitch.setOnCheckedChangeListener(listener);
}
}