add palettes

This commit is contained in:
Vologhat
2022-12-02 18:48:22 +03:00
parent 045daeea47
commit 810e5c72c1
10 changed files with 3919 additions and 0 deletions
@@ -0,0 +1,26 @@
package ru.vtosters.lite.themes.items;
public class VTLColor {
public String resName;
public int id;
public int color;
public VTLColor(int id, int color) {
this.id = id;
this.color = color;
}
public VTLColor(String resName, int id, int color) {
this.resName = resName;
this.id = id;
this.color = color;
}
public static VTLColor create(int id, int color) {
return new VTLColor(id, color);
}
public static VTLColor create(String resName, int id, int color) {
return new VTLColor(resName, id, color);
}
}
@@ -0,0 +1,94 @@
package ru.vtosters.lite.themes.items;
import android.graphics.Color;
import org.json.JSONException;
import org.json.JSONObject;
import java.util.ArrayList;
import java.util.List;
public class VTLPalette {
public String id;
public String name;
public String author;
public List<VTLColor> colors = new ArrayList<>();
public VTLPalette() {
}
public VTLPalette(String id, String name, String author, List<VTLColor> colors) {
this.id = id;
this.name = name;
this.author = author;
this.colors = colors;
}
public VTLPalette setId(String id) {
this.id = id;
return this;
}
public VTLPalette setName(String name) {
this.name = name;
return this;
}
public VTLPalette setAuthor(String author) {
this.author = author;
return this;
}
public VTLPalette setColors(List<VTLColor> colors) {
this.colors = colors;
return this;
}
public VTLPalette setColor(String name, int color) {
this.colors.add(new VTLColor(name, 0, color));
return this;
}
public int getColor(String name) {
for (var item : colors)
if (name.equals(item.resName))
return item.color;
return -1;
}
public static VTLPalette fromJson(JSONObject json) throws JSONException {
var palette = new VTLPalette()
.setId(json.optString("palette_id"))
.setName(json.optString("name"))
.setAuthor(json.optString("author"));
var paletteNode = json.getJSONArray("palette");
for (int i = 0; i < paletteNode.length(); i++) {
var colorNode = paletteNode.getJSONObject(i);
var name = colorNode.getString("name");
if (colorNode.has("colors")) {
var colorsNode = colorNode.getJSONArray("colors");
for (int j = 0; j < colorsNode.length(); j++) {
var subColorNode = colorsNode.getJSONObject(j);
var index = subColorNode.getString("index");
var subColor = subColorNode.getString("color");
if (!subColor.startsWith("#")) subColor = "#" + subColor;
palette.setColor(name + " " + index, Color.parseColor(subColor));
}
} else {
var color = colorNode.getString("color");
if (!color.startsWith("#")) color = "#" + color;
palette.setColor(name, Color.parseColor(color));
}
}
return palette;
}
public static VTLPalette valuesOf(String id, String name, String author, List<VTLColor> colors) {
return new VTLPalette()
.setId(id)
.setName(name)
.setAuthor(author)
.setColors(colors);
}
}
@@ -0,0 +1,98 @@
package ru.vtosters.lite.themes.palettes;
import android.os.Environment;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import org.json.JSONException;
import org.json.JSONObject;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import ru.vtosters.lite.themes.items.VTLPalette;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.IOUtils;
public class PalettesManager {
private final static File PALETTES_DIR = new File(Environment.getExternalStorageDirectory(), "VTL/palettes");
private final static String ASSETS_DIR = "vtl_themes/palettes/";
private static PalettesManager sInstance;
private final List<VTLPalette> mPalettes = new ArrayList<>();
public static PalettesManager getInstance() {
if (sInstance == null)
sInstance = new PalettesManager();
return sInstance;
}
public PalettesManager() {
load();
}
public void load() {
mPalettes.clear();
if (!PALETTES_DIR.exists())
PALETTES_DIR.mkdirs();
final var palettes = PALETTES_DIR.listFiles((dir, name) -> name.endsWith(".json"));
if (palettes == null || palettes.length == 0)
copyPaletteFromAssets();
parsePalettes();
}
private boolean copyPaletteFromAssets() {
try {
final var manager = AndroidUtils.getGlobalContext().getAssets();
final var assets = manager.list(ASSETS_DIR);
if (assets == null || assets.length == 0) return false;
for (var asset : assets) {
try {
IOUtils.copyFile(manager.open(ASSETS_DIR + asset), new File(PALETTES_DIR, asset));
} catch (IOException e) {
e.printStackTrace();
}
}
return true;
} catch (IOException e) {
e.printStackTrace();
}
return false;
}
private void parsePalettes() {
var arr = PALETTES_DIR.listFiles((dir, name) -> name.endsWith(".json"));
if (arr == null || arr.length == 0)
throw new RuntimeException("Can't load palettes");
for (var file : arr) {
try {
var json = new JSONObject(IOUtils.readAllLines(file));
mPalettes.add(VTLPalette.fromJson(json));
} catch (IOException | JSONException e) {
e.printStackTrace();
}
}
}
@Nullable
public VTLPalette getPalette(String id) {
for (var palette : mPalettes)
if (id.equals(palette.id))
return palette;
return null;
}
@NonNull
public VTLPalette getPalette(int i) {
return mPalettes.get(i);
}
public int getPalettesCount() {
return mPalettes.size();
}
}
@@ -0,0 +1,81 @@
package ru.vtosters.lite.ui.adapters;
import android.graphics.Color;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.FrameLayout;
import android.widget.TextView;
import androidx.annotation.NonNull;
import androidx.recyclerview.widget.RecyclerView;
import com.vk.core.drawable.BorderDrawable;
import com.vk.core.util.Screen;
import com.vk.stories.view.StoryCircleImageView;
import java.util.List;
import ru.vtosters.lite.themes.items.VTLColor;
import ru.vtosters.lite.utils.AndroidUtils;
import ru.vtosters.lite.utils.ThemesUtils;
public class ColorPickerAdapter extends RecyclerView.Adapter<ColorPickerAdapter.ColorPickerViewHolder> {
private List<VTLColor> mColors;
private OnColorSelectListener mSelectListener;
public ColorPickerAdapter(List<VTLColor> colors, OnColorSelectListener selectListener) {
this.mColors = colors;
this.mSelectListener = selectListener;
}
@NonNull
@Override
public ColorPickerViewHolder onCreateViewHolder(@NonNull ViewGroup parent, int viewType) {
var container = LayoutInflater.from(parent.getContext())
.inflate(AndroidUtils.getIdentifier("color_picker_item", "layout"), parent, false);
return new ColorPickerViewHolder(container);
}
@Override
public void onBindViewHolder(@NonNull ColorPickerViewHolder holder, int pos) {
holder.bind(mColors.get(pos));
}
@Override
public int getItemCount() {
return mColors.size();
}
public class ColorPickerViewHolder extends RecyclerView.ViewHolder {
private View mContainer;
private FrameLayout mColorPreviewBorder;
private StoryCircleImageView mColorPreview;
private TextView mColorName;
private TextView mColorValue;
public ColorPickerViewHolder(@NonNull View view) {
super(view);
mContainer = view;
mColorPreviewBorder = view.findViewById(AndroidUtils.getIdentifier("color_preview_border", "id"));
mColorPreview = view.findViewById(AndroidUtils.getIdentifier("color_preview", "id"));
mColorName = view.findViewById(AndroidUtils.getIdentifier("color_name", "id"));
mColorValue = view.findViewById(AndroidUtils.getIdentifier("color_value", "id"));
}
public void bind(VTLColor item) {
mContainer.setOnClickListener(v -> mSelectListener.onColorSelected(ColorPickerAdapter.this, item));
mColorPreviewBorder.setBackground(new BorderDrawable(ThemesUtils.isDarkTheme() ? Color.WHITE : Color.BLACK, Screen.c(24.0f), Screen.c(1.0f)));
mColorPreview.setPlaceholderColor(item.color);
mColorName.setText(item.resName);
mColorValue.setText("#" + Integer.toHexString(item.color).toUpperCase());
}
}
public interface OnColorSelectListener {
void onColorSelected(ColorPickerAdapter adapter, VTLColor vtlcolor);
}
}
@@ -0,0 +1,22 @@
package ru.vtosters.lite.ui.dialogs;
import android.app.Activity;
import ru.vtosters.lite.themes.items.VTLPalette;
import ru.vtosters.lite.ui.adapters.ColorPickerAdapter;
public class PalettesBottomSheetDialog {
private static final String TAG = "palettes_copy_color";
public static void create(Activity activity, VTLPalette palette, ColorPickerAdapter.OnColorSelectListener action) {
var instance = new VTColorPickerBottomSheetDialog(activity);
var colorPickerAdapter = new ColorPickerAdapter(palette.colors, (adapter, vtlcolor) -> {
action.onColorSelected(adapter, vtlcolor);
instance.dismiss();
});
instance.setTitle(palette.name)
.setAdapter(colorPickerAdapter, true)
.show(TAG, true);
}
}
@@ -0,0 +1,41 @@
package ru.vtosters.lite.ui.dialogs;
import android.app.Activity;
import android.widget.LinearLayout;
import androidx.recyclerview.widget.LinearLayoutManager;
import androidx.recyclerview.widget.RecyclerView;
import ru.vtosters.lite.ui.adapters.ColorPickerAdapter;
import ru.vtosters.lite.ui.vkui.ModalBottomSheetWrapper;
import ru.vtosters.lite.utils.LayoutUtils;
public class VTColorPickerBottomSheetDialog extends ModalBottomSheetWrapper<VTColorPickerBottomSheetDialog> {
private Activity mActivity;
private LinearLayout mContainer;
public VTColorPickerBottomSheetDialog(Activity activity) {
super(activity);
this.mActivity = activity;
mContainer = new LinearLayout(mActivity);
mContainer.setLayoutParams(LayoutUtils.createLinear(-1, -1));
mContainer.setOrientation(LinearLayout.VERTICAL);
}
public VTColorPickerBottomSheetDialog setAdapter(ColorPickerAdapter adapter, boolean searchMode) {
var recyclerView = new RecyclerView(mActivity);
recyclerView.setAdapter(adapter);
recyclerView.setHasFixedSize(true);
recyclerView.setLayoutManager(new LinearLayoutManager(mActivity));
var recyclerViewParams = LayoutUtils.createLinear(-1, -1);
mContainer.addView(recyclerView, recyclerViewParams);
mBuilder.a(mContainer);
return setView(mContainer);
}
public LinearLayout getContainer() {
return mContainer;
}
}
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+48
View File
@@ -0,0 +1,48 @@
<?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:orientation="horizontal"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:gravity="center_vertical"
android:background="?attr/selectableItemBackground"
android:paddingStart="12dp"
android:paddingTop="5dp"
android:paddingEnd="12dp"
android:paddingBottom="5dp">
<FrameLayout
android:id="@id/color_preview_border"
android:layout_width="48dp"
android:layout_height="48dp">
<com.vk.stories.view.StoryCircleImageView
android:id="@id/color_preview"
android:layout_width="40dp"
android:layout_height="40dp"
android:layout_gravity="center" />
</FrameLayout>
<LinearLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="16dp"
android:orientation="vertical">
<TextView
android:id="@id/color_name"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?attr/text_primary"
android:textSize="16sp"
android:maxLines="1" />
<TextView
android:id="@id/color_value"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="?attr/text_secondary" />
</LinearLayout>
</LinearLayout>
+4
View File
@@ -6867,6 +6867,10 @@
<public type="font" name="vk_sans_text_light" id="0x7f09001a" />
<public type="font" name="vk_sans_text_medium" id="0x7f09001b" />
<public type="font" name="vk_sans_text_regular" id="0x7f09001c" />
<public name="color_preview" id="0x7f0a1021" type="id" />
<public name="color_name" id="0x7f0a1022" type="id" />
<public name="color_value" id="0x7f0a1023" type="id" />
<public name="color_preview_border" id="0x7f0a1024" type="id" />
<public type="id" name="ALT" id="0x7f0a0000" />
<public type="id" name="CIRCLE" id="0x7f0a0001" />
<public type="id" name="CTRL" id="0x7f0a0002" />