Cherish: Bring back icon shapes, icon packs, fonts customization

Signed-off-by: Pranav Vashi <neobuddy89@gmail.com>
Signed-off-by: Hưng Phan <phandinhhungvp2001@gmail.com>
This commit is contained in:
SagarMakhar
2021-12-29 16:58:56 +00:00
committed by Hưng Phan
parent 20b79ae45c
commit 773e46b857
17 changed files with 1044 additions and 17 deletions

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2019 The Android Open Source Project
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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item
android:state_activated="true"
android:color="?android:colorAccent" />
<item
android:state_activated="false"
android:alpha="0.24"
android:color="?android:colorAccent" />
<item
android:alpha="0.05"
android:color="@color/option_border_default"/>
</selector>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2017 AospExtended ROM Project
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.
-->
<shape
xmlns:android="http://schemas.android.com/apk/res/android"
android:shape="rectangle">
<corners android:radius="100dp" />
<solid android:color="#FFF" />
</shape>

View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?><!--
Copyright (C) 2019 The Android Open Source Project
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.
-->
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/shape">
<shape android:shape="rectangle">
<solid android:color="?android:attr/colorPrimary"/>
<corners android:radius="?android:dialogCornerRadius" />
</shape>
</item>
<item android:drawable="@drawable/option_border_edge_custom" />
</layer-list>

View File

@@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2019 The Android Open Source Project
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.
-->
<selector xmlns:android="http://schemas.android.com/apk/res/android">
<item android:state_activated="true">
<shape android:shape="rectangle">
<stroke
android:color="@color/option_border_color"
android:width="4dp" />
<corners android:radius="?android:dialogCornerRadius" />
</shape>
</item>
<item android:state_activated="false">
<shape android:shape="rectangle">
<stroke
android:color="@color/option_border_color"
android:width="4dp" />
<corners android:radius="?android:dialogCornerRadius" />
</shape>
</item>
</selector>

View File

@@ -0,0 +1,48 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2019 The Android Open Source Project
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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="7dp"
android:layout_gravity="center"
android:orientation="vertical">
<FrameLayout
android:id="@+id/option_tile"
android:layout_width="match_parent"
android:layout_height="75dp"
android:gravity="center"
android:layout_gravity="center"
android:paddingHorizontal="10dp"
android:paddingVertical="10dp"
android:background="@drawable/option_border_custom">
<TextView android:id="@+id/option_title"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:gravity="center"
android:textAppearance="@style/OptionTitleTextAppearance"/>
</FrameLayout>
<TextView
android:id="@+id/option_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textAppearance="@style/OptionTitleTextAppearance"/>
</LinearLayout>

View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2019 The Android Open Source Project
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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="10dp"
android:gravity="center"
android:orientation="vertical">
<LinearLayout
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_centerInParent="true"
android:gravity="center"
android:orientation="vertical"
android:paddingHorizontal="5dp"
android:paddingVertical="5dp"
android:background="@drawable/option_border_custom">
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/image1"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/icon_background"
android:backgroundTint="?android:attr/textColorSecondary"
android:tint="?android:attr/textColorPrimary" />
<ImageView
android:id="@+id/image2"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/icon_background"
android:backgroundTint="?android:attr/textColorSecondary"
android:tint="?android:attr/textColorPrimary" />
</LinearLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:orientation="horizontal">
<ImageView
android:id="@+id/image3"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/icon_background"
android:backgroundTint="?android:attr/textColorSecondary"
android:tint="?android:attr/textColorPrimary" />
<ImageView
android:id="@+id/image4"
android:layout_width="30dp"
android:layout_height="30dp"
android:background="@drawable/icon_background"
android:backgroundTint="?android:attr/textColorSecondary"
android:tint="?android:attr/textColorSecondary" />
</LinearLayout>
</LinearLayout>
<TextView
android:id="@+id/option_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textAppearance="@style/OptionTitleTextAppearance"/>
</LinearLayout>

View File

@@ -0,0 +1,42 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright (C) 2019 The Android Open Source Project
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.
-->
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:layout_margin="7dp"
android:layout_gravity="center"
android:orientation="vertical">
<FrameLayout
android:id="@+id/option_tile"
android:layout_width="100dp"
android:layout_height="100dp"
android:layout_gravity="center_horizontal"
android:paddingHorizontal="10dp"
android:paddingVertical="10dp"
android:background="@drawable/option_border_custom">
<ImageView
android:id="@+id/option_thumbnail"
android:layout_width="match_parent"
android:layout_height="match_parent"/>
</FrameLayout>
<TextView
android:id="@+id/option_label"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_horizontal"
android:textAppearance="@style/OptionTitleTextAppearance"/>
</LinearLayout>

17
res/layout/item_view.xml Normal file
View File

@@ -0,0 +1,17 @@
<?xml version="1.0" encoding="utf-8"?>
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingLeft="7dp"
android:paddingRight="7dp">
<androidx.recyclerview.widget.RecyclerView
android:id="@+id/recycler_view"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:scrollbars="none"
android:gravity="center"/>
</LinearLayout>

View File

@@ -536,11 +536,13 @@
<!-- [CHAR_LIMIT=NONE] Developer Settings: Title of the setting which enables overlays to customize the adaptive icon shape (e.g. launcher and quick settings icons). -->
<string name="theme_customization_icon_shape_title">Icon shape</string>
<!-- [CHAR_LIMIT=NONE] Developer Settings: Title of the setting which enables overlays to customize accent color. -->
<string name="theme_customization_accent_color_title">Accent color</string>
<string name="theme_customization_icon_shape_summary">Set system icon shape style</string>
<!-- [CHAR_LIMIT=NONE] Developer Settings: Title of the setting which enables overlays to customize headline and body fonts. -->
<string name="theme_customization_font_title">Headline / Body font</string>
<!-- [CHAR_LIMIT=NONE] Developer Settings: Title of the setting which enables overlays to customize the statusbar icon -->
<string name="theme_customization_sysui_icon_title">Statusbar icon</string>
<string name="theme_customization_font_summary">Set system font style</string>
<!-- [CHAR_LIMIT=NONE] Developer Settings: Title of the setting which enables overlays to customize the system wide icon pack. -->
<string name="theme_customization_icon_pack_title">Icon pack</string>
<string name="theme_customization_icon_pack_summary">Set custom icon pack style</string>
<!-- Custom Signal bar icons -->
<string name="custom_signal_bar_title">Signal</string>

View File

@@ -22,4 +22,5 @@
<dimen name="fod_picker_item_size">100dp</dimen>
<dimen name="fod_picker_item_padding">20dp</dimen>
<color name="option_border_default">#5f6368</color>
</resources>

21
res/values/colors.xml Normal file
View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2014-2016 The Dirty Unicorns Project
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/>.
-->
<resources>
<color name="google_grey700">#5f6368</color>
<color name="edit_background_base">@color/google_grey700</color>
<color name="option_border_default">@color/edit_background_base</color>
</resources>

21
res/values/styles.xml Normal file
View File

@@ -0,0 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Copyright (C) 2010 The Android Open Source Project
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.
-->
<resources>
<style name="OptionTitleTextAppearance" parent="@android:style/TextAppearance.DeviceDefault.Widget.ActionBar.Title">
<item name="android:textAlignment">center</item>
<item name="android:textSize">15sp</item>
<item name="android:lineHeight">15sp</item>
<item name="android:textColor">?android:attr/textColorSecondary</item>
</style>
</resources>

View File

@@ -28,17 +28,26 @@
android:fragment="com.android.settings.display.darkmode.DarkModeSettingsFragment"
settings:controller="com.android.settings.display.DarkUIPreferenceController" />
<ListPreference
<!-- Font style -->
<Preference
android:key="android.theme.customization.font"
android:title="@string/theme_customization_font_title"/>
android:title="@string/theme_customization_font_title"
android:summary="@string/theme_customization_font_summary"
android:fragment="com.cherish.settings.fragments.ui.FontsPicker"/>
<ListPreference
android:key="android.theme.customization.adaptive_icon_shape"
android:title="@string/theme_customization_icon_shape_title"/>
<ListPreference
<!-- Icon pack -->
<Preference
android:key="android.theme.customization.icon_pack"
android:title="@string/theme_customization_sysui_icon_title"/>
android:title="@string/theme_customization_icon_pack_title"
android:summary="@string/theme_customization_icon_pack_summary"
android:fragment="com.cherish.settings.fragments.ui.StatusbarIcons"/>
<!-- Adaptive icon shape -->
<Preference
android:key="android.theme.customization.adaptive_icon_shape"
android:title="@string/theme_customization_icon_shape_title"
android:summary="@string/theme_customization_icon_shape_summary"
android:fragment="com.cherish.settings.fragments.ui.IconShapes"/>
<ListPreference
android:key="android.theme.customization.signal_icon"

View File

@@ -96,12 +96,6 @@ public class ThemeSettings extends DashboardFragment implements OnPreferenceChan
Context context, Lifecycle lifecycle, Fragment fragment) {
final List<AbstractPreferenceController> controllers = new ArrayList<>();
controllers.add(new OverlayCategoryPreferenceController(context,
"android.theme.customization.font"));
controllers.add(new OverlayCategoryPreferenceController(context,
"android.theme.customization.adaptive_icon_shape"));
controllers.add(new OverlayCategoryPreferenceController(context,
"android.theme.customization.icon_pack"));
controllers.add(new OverlayCategoryPreferenceController(context,
"android.theme.customization.signal_icon"));
controllers.add(new OverlayCategoryPreferenceController(context,

View File

@@ -0,0 +1,224 @@
/*
* Copyright (C) 2020-22 The CherishOS Project
*
* 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 com.cherish.settings.fragments.ui;
import static android.os.UserHandle.USER_SYSTEM;
import static com.android.internal.util.cherish.ThemeUtils.FONT_KEY;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.Resources;
import android.graphics.Typeface;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.net.Uri;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.res.ResourcesCompat;
import androidx.preference.Preference.OnPreferenceChangeListener;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.PreferenceViewHolder;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import androidx.recyclerview.widget.RecyclerView;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.cherish.ThemeUtils;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settingslib.search.Indexable;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import org.json.JSONException;
import org.json.JSONObject;
public class FontsPicker extends SettingsPreferenceFragment {
private RecyclerView mRecyclerView;
private ThemeUtils mThemeUtils;
private String mCategory = FONT_KEY;
private List<String> mPkgs;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActivity().setTitle(R.string.theme_customization_font_title);
mThemeUtils = new ThemeUtils(getActivity());
mPkgs = mThemeUtils.getOverlayPackagesForCategory(mCategory, "android");
Collections.sort(mPkgs);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(
R.layout.item_view, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 1);
mRecyclerView.setLayoutManager(gridLayoutManager);
Adapter mAdapter = new Adapter(getActivity());
mRecyclerView.setAdapter(mAdapter);
return view;
}
@Override
public int getMetricsCategory() {
return MetricsEvent.CHERISH_SETTINGS;
}
@Override
public void onResume() {
super.onResume();
}
public class Adapter extends RecyclerView.Adapter<Adapter.CustomViewHolder> {
Context context;
String mSelectedPkg;
String mAppliedPkg;
public Adapter(Context context) {
this.context = context;
}
@Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.fonts_option, parent, false);
CustomViewHolder vh = new CustomViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(CustomViewHolder holder, final int position) {
String pkg = mPkgs.get(position);
String label = getLabel(holder.itemView.getContext(), pkg);
String currentPackageName = mThemeUtils.getOverlayInfos(mCategory).stream()
.filter(info -> info.isEnabled())
.map(info -> info.packageName)
.findFirst()
.orElse("android");
holder.title.setText("android".equals(pkg) ? "Default" : label);
holder.title.setTextSize(20);
holder.title.setTypeface(getTypeface(holder.title.getContext(), pkg));
holder.name.setVisibility(View.GONE);
if (currentPackageName.equals(pkg)) {
mAppliedPkg = pkg;
if (mSelectedPkg == null) {
mSelectedPkg = pkg;
}
}
holder.itemView.setActivated(pkg == mSelectedPkg);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
updateActivatedStatus(mSelectedPkg, false);
updateActivatedStatus(pkg, true);
mSelectedPkg = pkg;
enableOverlays(position);
}
});
}
@Override
public int getItemCount() {
return mPkgs.size();
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
TextView name;
TextView title;
public CustomViewHolder(View itemView) {
super(itemView);
title = (TextView) itemView.findViewById(R.id.option_title);
name = (TextView) itemView.findViewById(R.id.option_label);
}
}
private void updateActivatedStatus(String pkg, boolean isActivated) {
int index = mPkgs.indexOf(pkg);
if (index < 0) {
return;
}
RecyclerView.ViewHolder holder = mRecyclerView.findViewHolderForAdapterPosition(index);
if (holder != null && holder.itemView != null) {
holder.itemView.setActivated(isActivated);
}
}
}
public Typeface getTypeface(Context context, String pkg) {
try {
PackageManager pm = context.getPackageManager();
Resources res = pkg.equals("android") ? Resources.getSystem()
: pm.getResourcesForApplication(pkg);
return Typeface.create(res.getString(
res.getIdentifier("config_bodyFontFamily",
"string", pkg)), Typeface.NORMAL);
}
catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
public String getLabel(Context context, String pkg) {
PackageManager pm = context.getPackageManager();
try {
return pm.getApplicationInfo(pkg, 0)
.loadLabel(pm).toString();
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return pkg;
}
public void enableOverlays(int position) {
mThemeUtils.setOverlayEnabled(mCategory, mPkgs.get(position));
}
}

View File

@@ -0,0 +1,207 @@
/*
* Copyright (C) 2020-22 The CherishOS Projects
*
* 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 com.cherish.settings.fragments.ui;
import static com.android.internal.util.cherish.ThemeUtils.ICON_SHAPE_KEY;
import android.content.ContentResolver;
import android.content.Context;
import android.content.pm.PackageManager;
import android.content.res.ColorStateList;
import android.content.res.Resources;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.graphics.drawable.ShapeDrawable;
import android.net.Uri;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.text.TextUtils;
import android.view.Gravity;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup.LayoutParams;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.content.res.ResourcesCompat;
import androidx.core.graphics.ColorUtils;
import androidx.preference.Preference.OnPreferenceChangeListener;
import androidx.preference.Preference;
import androidx.preference.PreferenceScreen;
import androidx.preference.PreferenceViewHolder;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import androidx.recyclerview.widget.RecyclerView;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.internal.util.cherish.ThemeUtils;
import com.android.settings.R;
import com.android.settings.SettingsPreferenceFragment;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.Utils;
import com.android.settingslib.search.Indexable;
import com.bumptech.glide.Glide;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Arrays;
import org.json.JSONObject;
import org.json.JSONException;
public class IconShapes extends SettingsPreferenceFragment {
private RecyclerView mRecyclerView;
private ThemeUtils mThemeUtils;
private String mCategory = ICON_SHAPE_KEY;
private List<String> mPkgs;
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActivity().setTitle(R.string.theme_customization_icon_shape_title);
mThemeUtils = new ThemeUtils(getActivity());
mPkgs = mThemeUtils.getOverlayPackagesForCategory(mCategory, "android");
Collections.sort(mPkgs);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(
R.layout.item_view, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 3);
mRecyclerView.setLayoutManager(gridLayoutManager);
Adapter mAdapter = new Adapter(getActivity());
mRecyclerView.setAdapter(mAdapter);
return view;
}
@Override
public int getMetricsCategory() {
return MetricsEvent.CHERISH_SETTINGS;
}
@Override
public void onResume() {
super.onResume();
}
public class Adapter extends RecyclerView.Adapter<Adapter.CustomViewHolder> {
Context context;
String mSelectedPkg;
String mAppliedPkg;
public Adapter(Context context) {
this.context = context;
}
@Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.item_option, parent, false);
CustomViewHolder vh = new CustomViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(CustomViewHolder holder, final int position) {
String pkg = mPkgs.get(position);
holder.image.setBackgroundDrawable(mThemeUtils.createShapeDrawable(pkg));
String currentPackageName = mThemeUtils.getOverlayInfos(mCategory).stream()
.filter(info -> info.isEnabled())
.map(info -> info.packageName)
.findFirst()
.orElse("android");
holder.name.setText("android".equals(pkg) ? "Default" : getLabel(holder.name.getContext(), pkg));
final boolean isDefault = "android".equals(currentPackageName) && "android".equals(pkg);
final int color = ColorUtils.setAlphaComponent(
Utils.getColorAttrDefaultColor(getContext(), android.R.attr.colorAccent),
pkg.equals(currentPackageName) || isDefault ? 170 : 75);
holder.image.setBackgroundTintList(ColorStateList.valueOf(color));
holder.itemView.findViewById(R.id.option_tile).setBackgroundDrawable(null);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
enableOverlays(position);
}
});
}
@Override
public int getItemCount() {
return mPkgs.size();
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
TextView name;
ImageView image;
public CustomViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.option_label);
image = (ImageView) itemView.findViewById(R.id.option_thumbnail);
}
}
}
public Drawable getDrawable(Context context, String pkg, String drawableName) {
try {
PackageManager pm = context.getPackageManager();
Resources res = pkg.equals("android") ? Resources.getSystem()
: pm.getResourcesForApplication(pkg);
return res.getDrawable(res.getIdentifier(drawableName, "drawable", pkg));
}
catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
public String getLabel(Context context, String pkg) {
PackageManager pm = context.getPackageManager();
try {
return pm.getApplicationInfo(pkg, 0)
.loadLabel(pm).toString();
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return pkg;
}
public void enableOverlays(int position) {
mThemeUtils.setOverlayEnabled(mCategory, mPkgs.get(position));
}
}

View File

@@ -0,0 +1,257 @@
/*
* Copyright (C) 2020-22 The CherishOS Project
*
* 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 com.cherish.settings.fragments.ui;
import android.content.ContentResolver;
import android.content.Context;
import android.content.res.Resources;
import android.content.pm.PackageManager;
import android.graphics.drawable.AnimationDrawable;
import android.graphics.drawable.Drawable;
import android.os.Bundle;
import android.provider.SearchIndexableResource;
import android.provider.Settings;
import android.view.LayoutInflater;
import android.view.View;
import android.view.Gravity;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.FrameLayout;
import android.widget.TextView;
import android.widget.Toast;
import android.text.TextUtils;
import androidx.preference.PreferenceViewHolder;
import android.view.ViewGroup.LayoutParams;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.recyclerview.widget.GridLayoutManager;
import androidx.recyclerview.widget.RecyclerView.ViewHolder;
import androidx.recyclerview.widget.RecyclerView;
import android.net.Uri;
import androidx.core.content.res.ResourcesCompat;
import androidx.preference.Preference;
import androidx.preference.Preference.OnPreferenceChangeListener;
import androidx.preference.PreferenceScreen;
import com.android.internal.logging.nano.MetricsProto.MetricsEvent;
import com.android.settings.R;
import com.android.settings.search.BaseSearchIndexProvider;
import com.android.settingslib.search.Indexable;
import com.android.settings.SettingsPreferenceFragment;
import com.bumptech.glide.Glide;
import com.android.internal.util.cherish.ThemeUtils;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Arrays;
import org.json.JSONObject;
import org.json.JSONException;
public class StatusbarIcons extends SettingsPreferenceFragment {
private RecyclerView mRecyclerView;
private ThemeUtils mThemeUtils;
private String mCategory = "android.theme.customization.icon_pack.android";
private List<String> mPkgs;
Map<String, String> overlayMap = new HashMap<String, String>();
{
overlayMap.put("com.android.settings", "android.theme.customization.icon_pack.settings");
overlayMap.put("com.android.systemui", "android.theme.customization.icon_pack.systemui");
overlayMap.put("com.google.android.apps.nexuslauncher", "android.theme.customization.icon_pack.launcher");
overlayMap.put("com.google.android.apps.wallpaper", "android.theme.customization.icon_pack.themepicker");
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
getActivity().setTitle(R.string.theme_customization_icon_pack_title);
mThemeUtils = new ThemeUtils(getActivity());
mPkgs = mThemeUtils.getOverlayPackagesForCategory(mCategory, "android");
Collections.sort(mPkgs);
}
@Override
public View onCreateView(@NonNull LayoutInflater inflater, @Nullable ViewGroup container,
@Nullable Bundle savedInstanceState) {
View view = inflater.inflate(
R.layout.item_view, container, false);
mRecyclerView = (RecyclerView) view.findViewById(R.id.recycler_view);
GridLayoutManager gridLayoutManager = new GridLayoutManager(getActivity(), 3);
mRecyclerView.setLayoutManager(gridLayoutManager);
Adapter mAdapter = new Adapter(getActivity());
mRecyclerView.setAdapter(mAdapter);
return view;
}
@Override
public int getMetricsCategory() {
return MetricsEvent.CHERISH_SETTINGS;
}
@Override
public void onResume() {
super.onResume();
}
public class Adapter extends RecyclerView.Adapter<Adapter.CustomViewHolder> {
Context context;
String mSelectedPkg;
String mAppliedPkg;
public Adapter(Context context) {
this.context = context;
}
@Override
public CustomViewHolder onCreateViewHolder(ViewGroup parent, int viewType) {
View v = LayoutInflater.from(parent.getContext()).inflate(R.layout.icon_option, parent, false);
CustomViewHolder vh = new CustomViewHolder(v);
return vh;
}
@Override
public void onBindViewHolder(CustomViewHolder holder, final int position) {
String iconPkg = mPkgs.get(position);
holder.image1.setBackgroundDrawable(getDrawable(holder.image1.getContext(), iconPkg, "ic_wifi_signal_4"));
holder.image2.setBackgroundDrawable(getDrawable(holder.image2.getContext(), iconPkg, "ic_signal_cellular_4_4_bar"));
holder.image3.setBackgroundDrawable(getDrawable(holder.image3.getContext(), iconPkg, "ic_qs_airplane"));
holder.image4.setBackgroundDrawable(getDrawable(holder.image4.getContext(), iconPkg, "ic_qs_flashlight"));
String currentPackageName = mThemeUtils.getOverlayInfos(mCategory).stream()
.filter(info -> info.isEnabled())
.map(info -> info.packageName)
.findFirst()
.orElse("android");
holder.name.setText("android".equals(iconPkg) ? "Default" : getLabel(holder.name.getContext(), iconPkg));
if (currentPackageName.equals(iconPkg)) {
mAppliedPkg = iconPkg;
if (mSelectedPkg == null) {
mSelectedPkg = iconPkg;
}
}
holder.itemView.setActivated(iconPkg == mSelectedPkg);
holder.itemView.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
updateActivatedStatus(mSelectedPkg, false);
updateActivatedStatus(iconPkg, true);
mSelectedPkg = iconPkg;
enableOverlays(position);
}
});
}
@Override
public int getItemCount() {
return mPkgs.size();
}
public class CustomViewHolder extends RecyclerView.ViewHolder {
TextView name;
ImageView image1;
ImageView image2;
ImageView image3;
ImageView image4;
public CustomViewHolder(View itemView) {
super(itemView);
name = (TextView) itemView.findViewById(R.id.option_label);
image1 = (ImageView) itemView.findViewById(R.id.image1);
image2 = (ImageView) itemView.findViewById(R.id.image2);
image3 = (ImageView) itemView.findViewById(R.id.image3);
image4 = (ImageView) itemView.findViewById(R.id.image4);
}
}
private void updateActivatedStatus(String pkg, boolean isActivated) {
int index = mPkgs.indexOf(pkg);
if (index < 0) {
return;
}
RecyclerView.ViewHolder holder = mRecyclerView.findViewHolderForAdapterPosition(index);
if (holder != null && holder.itemView != null) {
holder.itemView.setActivated(isActivated);
}
}
}
public Drawable getDrawable(Context context, String pkg, String drawableName) {
try {
PackageManager pm = context.getPackageManager();
Resources res = pkg.equals("android") ? Resources.getSystem()
: pm.getResourcesForApplication(pkg);
int resId = res.getIdentifier(drawableName, "drawable", pkg);
if (resId == 0) {
return Resources.getSystem().getDrawable(
Resources.getSystem().getIdentifier(drawableName, "drawable", "android"));
}
return res.getDrawable(resId);
}
catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return null;
}
public String getLabel(Context context, String pkg) {
PackageManager pm = context.getPackageManager();
try {
return pm.getApplicationInfo(pkg, 0)
.loadLabel(pm).toString();
} catch (PackageManager.NameNotFoundException e) {
e.printStackTrace();
}
return pkg;
}
public void enableOverlays(int position) {
mThemeUtils.setOverlayEnabled(mCategory, mPkgs.get(position));
String pattern = "android".equals(mPkgs.get(position)) ? ""
: mPkgs.get(position).split("\\.")[4];
for (Map.Entry<String, String> entry : overlayMap.entrySet()) {
enableOverlay(entry.getValue(), entry.getKey(), pattern);
}
}
public void enableOverlay(String category, String target, String pattern) {
if (pattern.isEmpty()) {
mThemeUtils.setOverlayEnabled(category, "android");
return;
}
for (String pkg: mThemeUtils.getOverlayPackagesForCategory(category, target)) {
if (pkg.contains(pattern)) {
mThemeUtils.setOverlayEnabled(category, pkg);
}
}
}
}