package ru.ltst.u2020mvp.ui.debug;
import android.content.Context;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.LinearLayout;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import ru.ltst.u2020mvp.R;
import timber.log.Timber;
public class ContextualDebugActions implements ViewGroup.OnHierarchyChangeListener {
public static abstract class DebugAction<T extends View> {
private final Class<T> viewClass;
protected DebugAction(Class<T> viewClass) {
this.viewClass = viewClass;
}
/** Invoked when the action has been added as available to run. */
public void added() {}
/** Invoked when the action has been removed as available to run. */
public void removed() {}
/** Return true if action is applicable. Called each time the target view is added. */
public boolean enabled() {
return true;
}
/** Human-readable action name. Displayed in debug drawer. */
public abstract String name();
/** Perform this action using the specified view. */
public abstract void run(T view);
}
private final Map<DebugAction<? extends View>, View> buttonMap;
private final Map<Class<? extends View>, List<DebugAction<? extends View>>> actionMap;
private final Context drawerContext;
private final View contextualTitleView;
private final LinearLayout contextualListView;
private View.OnClickListener clickListener;
public ContextualDebugActions(DebugView debugView, Set<DebugAction<?>> debugActions) {
buttonMap = new LinkedHashMap<>();
actionMap = new LinkedHashMap<>();
drawerContext = debugView.getContext();
contextualTitleView = debugView.contextualTitleView;
contextualListView = debugView.contextualListView;
for (DebugAction<?> debugAction : debugActions) {
Class cls = debugAction.viewClass;
Timber.d("Adding %s action for %s.", debugAction.getClass().getSimpleName(), cls.getSimpleName());
List<DebugAction<? extends View>> actionList = actionMap.get(cls);
if (actionList == null) {
actionList = new ArrayList<>(2);
actionMap.put(cls, actionList);
}
actionList.add(debugAction);
}
}
public void setActionClickListener(View.OnClickListener clickListener) {
this.clickListener = clickListener;
}
@Override public void onChildViewAdded(View parent, View child) {
List<DebugAction<? extends View>> actions = actionMap.get(child.getClass());
if (actions != null) {
for (DebugAction<? extends View> action : actions) {
if (!action.enabled()) {
continue;
}
Timber.d("Adding debug action \"%s\" for %s.", action.name(),
child.getClass().getSimpleName());
View button = createButton(action, child);
buttonMap.put(action, button);
contextualListView.addView(button);
action.added();
}
updateContextualVisibility();
}
}
@Override public void onChildViewRemoved(View parent, View child) {
List<DebugAction<? extends View>> actions = actionMap.get(child.getClass());
if (actions != null) {
for (DebugAction<? extends View> action : actions) {
Timber.d("Removing debug action \"%s\" for %s.", action.name(),
child.getClass().getSimpleName());
View buttonView = buttonMap.remove(action);
if (buttonView != null) {
contextualListView.removeView(buttonView);
action.removed();
}
}
updateContextualVisibility();
}
}
private Button createButton(final DebugAction action, final View child) {
Button button = (Button) LayoutInflater.from(drawerContext)
.inflate(R.layout.debug_drawer_contextual_action, contextualListView, false);
button.setText(action.name());
button.setOnClickListener(view -> {
if (clickListener != null) {
clickListener.onClick(view);
}
action.run(child);
});
return button;
}
private void updateContextualVisibility() {
int visibility = contextualListView.getChildCount() > 0 ? View.VISIBLE : View.GONE;
contextualTitleView.setVisibility(visibility);
contextualListView.setVisibility(visibility);
}
}