add palettes
This commit is contained in:
@@ -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
@@ -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>
|
||||
@@ -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" />
|
||||
|
||||
Reference in New Issue
Block a user