File indexing completed on 2024-12-22 04:41:42

0001 /*
0002  * SPDX-FileCopyrightText: 2023 Albert Vaca Cintora <albertvaka@gmail.com>
0003  *
0004  * SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 package org.kde.kdeconnect.UserInterface;
0008 
0009 import android.content.Context;
0010 import android.util.TypedValue;
0011 import android.view.View;
0012 
0013 import androidx.annotation.NonNull;
0014 import androidx.preference.PreferenceViewHolder;
0015 import androidx.preference.SwitchPreference;
0016 
0017 import org.kde.kdeconnect.Device;
0018 import org.kde.kdeconnect.Plugins.Plugin;
0019 import org.kde.kdeconnect.Plugins.PluginFactory;
0020 import org.kde.kdeconnect_tp.R;
0021 
0022 public class PluginPreference extends SwitchPreference {
0023     private final Device device;
0024     private final String pluginKey;
0025     private final View.OnClickListener listener;
0026 
0027     public PluginPreference(@NonNull final Context context, @NonNull final String pluginKey,
0028                             @NonNull final Device device, @NonNull PluginPreferenceCallback callback) {
0029         super(context);
0030 
0031         setLayoutResource(R.layout.preference_with_button);
0032 
0033         this.device = device;
0034         this.pluginKey = pluginKey;
0035 
0036         PluginFactory.PluginInfo info = PluginFactory.getPluginInfo(pluginKey);
0037         setTitle(info.getDisplayName());
0038         setSummary(info.getDescription());
0039         setChecked(device.isPluginEnabled(pluginKey));
0040 
0041         if (info.hasSettings()) {
0042             this.listener = v -> {
0043                 Plugin plugin = device.getPluginIncludingWithoutPermissions(pluginKey);
0044                 if (plugin != null) {
0045                     callback.onStartPluginSettingsFragment(plugin);
0046                 } else { //Could happen if the device is not connected anymore
0047                     callback.onFinish();
0048                 }
0049             };
0050         } else {
0051             this.listener = null;
0052         }
0053     }
0054 
0055     @Override
0056     public void onBindViewHolder(@NonNull PreferenceViewHolder holder) {
0057         super.onBindViewHolder(holder);
0058 
0059         View.OnClickListener toggleListener = v -> {
0060             boolean newState = !device.isPluginEnabled(pluginKey);
0061             setChecked(newState); //It actually works on API<14
0062             onStateChanged(holder, newState);
0063             device.setPluginEnabled(pluginKey, newState);
0064         };
0065 
0066         View content = holder.findViewById(R.id.content);
0067         View widget = holder.findViewById(android.R.id.widget_frame);
0068         View parent = holder.itemView;
0069         content.setOnClickListener(listener);
0070         widget.setOnClickListener(toggleListener);
0071         parent.setOnClickListener(toggleListener);
0072 
0073         // Disable child backgrounds when known to be unneeded to prevent duplicate ripples
0074         int selectableItemBackground;
0075         if (listener == null) {
0076             selectableItemBackground = 0;
0077         } else {
0078             TypedValue value = new TypedValue();
0079             getContext().getTheme().resolveAttribute(android.R.attr.selectableItemBackground, value, true);
0080             selectableItemBackground = value.resourceId;
0081         }
0082         content.setBackgroundResource(selectableItemBackground);
0083         widget.setBackgroundResource(selectableItemBackground);
0084 
0085         onStateChanged(holder, isChecked());
0086     }
0087 
0088     private void onStateChanged(PreferenceViewHolder holder, boolean state) {
0089         View content = holder.findViewById(R.id.content);
0090         View divider = holder.findViewById(R.id.divider);
0091         View widget = holder.findViewById(android.R.id.widget_frame);
0092         View parent = holder.itemView;
0093 
0094         boolean hasDetails = state && listener != null;
0095 
0096         divider.setVisibility(hasDetails ? View.VISIBLE : View.GONE);
0097         content.setClickable(hasDetails);
0098         widget.setClickable(hasDetails);
0099         parent.setClickable(!hasDetails);
0100 
0101         if (hasDetails) {
0102             // Cancel duplicate ripple caused by pressed state of parent propagating down
0103             content.setPressed(false);
0104             content.getBackground().jumpToCurrentState();
0105             widget.setPressed(false);
0106             widget.getBackground().jumpToCurrentState();
0107         }
0108     }
0109 
0110     interface PluginPreferenceCallback {
0111         void onStartPluginSettingsFragment(Plugin plugin);
0112         void onFinish();
0113     }
0114 }