/* * This file is part of Oekaki Mobile. * Copyright (C) 2013 Jeremy Lam * * 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/>. */ package idv.jlchntoz.oekakimobile; import java.util.*; import com.chibipaint.CPController; import com.chibipaint.engine.*; import com.chibipaint.util.CPColor; import android.annotation.SuppressLint; import android.content.Context; import android.graphics.*; import android.os.Handler; import android.os.Message; import android.view.View; import android.widget.*; import android.widget.AdapterView.OnItemSelectedListener; import android.widget.CompoundButton.OnCheckedChangeListener; import android.widget.SeekBar.OnSeekBarChangeListener; public class ColorTextureDrawerHandler implements OnSeekBarChangeListener, OnCheckedChangeListener, android.view.View.OnClickListener, OnItemSelectedListener, CPController.ICPColorListener, ColorPaletteSelector.OnSelectedListener { public final CPController controller; public final View drawerView; public final Context context; private final Spinner sptextures; private final ImageView imvpreview; private final CheckBox cbinvert, cbmirror; private final SeekBar sbbrightness, sbcontrast; private final TextView tvbrightness, tvcontrast; private final Button btnreset, btncolor; private final ColorPaletteSelector CPS; private List<HashMap<String, ?>> sptexturContent; private HashMapTextIconAdapter HMTIA; private ArrayList<CPGreyBmp> textures; private CPGreyBmp selectedTexture, processedTexture; private Bitmap previewBMP; private int targetRGB; public ColorTextureDrawerHandler(Context context, CPController controller, View drawerView) { this.context = context; this.controller = controller; this.drawerView = drawerView; sptextures = (Spinner) this.drawerView.findViewById(R.id.sptextures); imvpreview = (ImageView) this.drawerView.findViewById(R.id.imvpreview); cbinvert = (CheckBox) this.drawerView.findViewById(R.id.cbinvert); cbmirror = (CheckBox) this.drawerView.findViewById(R.id.cbmirror); sbbrightness = (SeekBar) this.drawerView.findViewById(R.id.sbbrightness); sbcontrast = (SeekBar) this.drawerView.findViewById(R.id.sbcontrast); tvbrightness = (TextView) this.drawerView.findViewById(R.id.tvbrightness); tvcontrast = (TextView) this.drawerView.findViewById(R.id.tvcontrast); btnreset = (Button) this.drawerView.findViewById(R.id.btnreset); btncolor = (Button) this.drawerView.findViewById(R.id.btnsetcolor); CPS = (ColorPaletteSelector) this.drawerView.findViewById(R.id.CPS); Integer[] paletteColors = ((MainActivity) context).getSettings() .getColors(); if (paletteColors != null) for (int i = 0; i < paletteColors.length; i++) if (paletteColors[i] != null && paletteColors[i] != Color.TRANSPARENT) CPS.setColor(i, paletteColors[i]); textures = new ArrayList<CPGreyBmp>(); createTextures(); sptexturContent = new ArrayList<HashMap<String, ?>>(); for (CPGreyBmp BMP : textures) { HashMap<String, Object> itm = new HashMap<String, Object>(); itm.put("name", ""); itm.put("icon", TextureFactory.createTextureImage(BMP, 64, 64, Color.WHITE)); sptexturContent.add(itm); } HMTIA = new HashMapTextIconAdapter(this.context, sptexturContent, R.layout.imagespinneritemlayout, new String[] { "name", "icon" }, new int[] { R.id.spinnertext, R.id.spinnerimage }); sptextures.setAdapter(HMTIA); sbbrightness.setMax(200); sbcontrast.setMax(200); sbbrightness.setProgress(100); sbcontrast.setProgress(100); sbbrightness.setOnSeekBarChangeListener(this); sbcontrast.setOnSeekBarChangeListener(this); cbinvert.setOnCheckedChangeListener(this); cbmirror.setOnCheckedChangeListener(this); btnreset.setOnClickListener(this); btncolor.setOnClickListener(this); sptextures.setOnItemSelectedListener(this); CPS.setListener(this); this.controller.addColorListener(this); targetRGB = controller.getCurColorRgb(); } @SuppressLint("HandlerLeak") private final Handler _h = new Handler() { @Override public void handleMessage(Message m) { switch (m.what) { case MainActivity.MSG_UPDATECOLOR: int r = Color.red(targetRGB), g = Color.green(targetRGB), b = Color.blue(targetRGB); btncolor.setBackgroundColor(0xFF << 24 | targetRGB); btncolor.setTextColor((r + g * 2 + b) / 3 > 128 ? Color.BLACK : Color.WHITE); break; } } }; private void createTextures() { CPGreyBmp texture = new CPGreyBmp(1, 1); texture.data[0] = (byte) 0; textures.add(texture); textures.add(TextureFactory.makeDotTexture(2)); textures.add(TextureFactory.makeDotTexture(3)); textures.add(TextureFactory.makeDotTexture(4)); textures.add(TextureFactory.makeDotTexture(6)); textures.add(TextureFactory.makeDotTexture(8)); textures.add(TextureFactory.makeVertLinesTexture(1, 2)); textures.add(TextureFactory.makeVertLinesTexture(2, 4)); textures.add(TextureFactory.makeHorizLinesTexture(1, 2)); textures.add(TextureFactory.makeHorizLinesTexture(2, 4)); textures.add(TextureFactory.makeCheckerBoardTexture(1)); textures.add(TextureFactory.makeCheckerBoardTexture(2)); textures.add(TextureFactory.makeCheckerBoardTexture(4)); textures.add(TextureFactory.makeCheckerBoardTexture(8)); textures.add(TextureFactory.makeCheckerBoardTexture(16)); } public void update() { if (sptextures.getSelectedItemPosition() != 0) selectedTexture = textures.get(sptextures.getSelectedItemPosition()); else selectedTexture = null; if (selectedTexture != null) { processedTexture = new CPGreyBmp(selectedTexture); if (cbmirror.isChecked()) processedTexture.mirrorHorizontally(); CPLookUpTable lut = new CPLookUpTable( sbbrightness.getProgress() / 200F - 1F, sbcontrast.getProgress() / 200F - 1F); if (cbinvert.isChecked()) lut.inverse(); processedTexture.applyLUT(lut); } else processedTexture = null; controller.artwork.brushManager.setTexture(processedTexture); previewBMP = TextureFactory.createTextureImage(processedTexture, previewBMP, 64, 64, targetRGB); imvpreview.setImageBitmap(previewBMP); controller.setCurColor(controller.getCurColor()); } public Bitmap getBitmap() { update(); return previewBMP; } @Override public void onClick(View view) { if (view == btnreset) { cbmirror.setChecked(false); cbinvert.setChecked(false); sbbrightness.setProgress(100); sbcontrast.setProgress(100); update(); } else if (view == btncolor) { ColorPickerDialog dlg = new ColorPickerDialog(context, targetRGB, new ColorPickerDialog.ColorPickerCallback() { @Override public void onCallback(ColorPickerDialog which, int color) { controller.setCurColorRgb(color); update(); } }); dlg.getDialog().show(); } } @Override public void onCheckedChanged(CompoundButton target, boolean user) { update(); } @Override public void onProgressChanged(SeekBar target, int amount, boolean user) { if (target == sbbrightness) { tvbrightness.setText(R.string.brightness); tvbrightness.append(": " + (amount - 100) + "%"); } else if (target == sbcontrast) { tvcontrast.setText(R.string.contrast); tvcontrast.append(": " + (amount - 100) + "%"); } update(); } @Override public void onStartTrackingTouch(SeekBar seekbar) { } @Override public void onStopTrackingTouch(SeekBar seekbar) { } @Override public void onItemSelected(AdapterView<?> a, View v, int i, long d) { update(); } @Override public void onNothingSelected(AdapterView<?> a) { } @Override public void newColor(CPColor color) { targetRGB = color.rgb; Message m = new Message(); m.what = MainActivity.MSG_UPDATECOLOR; _h.sendMessage(m); } @Override public void OnSelected(int index, int color) { controller.setCurColorRgb(color); update(); } @Override public int OnReplace(int index) { ((MainActivity) context).getSettings().saveColor(index, 0xFF << 24 | targetRGB); return 0xFF << 24 | targetRGB; } public final static class TextureFactory { public static CPGreyBmp makeDotTexture(int size) { CPGreyBmp texture = new CPGreyBmp(size, size); for (int i = 1; i < size * size; i++) texture.data[i] = (byte) 0xFF; return texture; } public static CPGreyBmp makeCheckerBoardTexture(int size) { int textureSize = 2 * size; CPGreyBmp texture = new CPGreyBmp(textureSize, textureSize); for (int i = 0; i < textureSize; i++) for (int j = 0; j < textureSize; j++) texture.data[i + j * textureSize] = (i / size + j / size) % 2 == 0 ? (byte) 0 : (byte) 0xFF; return texture; } public static CPGreyBmp makeVertLinesTexture(int lineSize, int size) { CPGreyBmp texture = new CPGreyBmp(size, size); for (int i = 0; i < size * size; i++) if (i % size >= lineSize) texture.data[i] = (byte) 0xFF; return texture; } public static CPGreyBmp makeHorizLinesTexture(int lineSize, int size) { CPGreyBmp texture = new CPGreyBmp(size, size); for (int i = 0; i < size * size; i++) if (i / size >= lineSize) texture.data[i] = (byte) 0xFF; return texture; } public static Bitmap createTextureImage(CPGreyBmp texture, int width, int height, int color) { Bitmap bmp = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); alterTextureImage(texture, bmp, color); return bmp; } public static Bitmap createTextureImage(CPGreyBmp texture, Bitmap bitmap, int width, int height, int color) { if (bitmap == null) return createTextureImage(texture, width, height, color); alterTextureImage(texture, bitmap, color); return bitmap; } public static void alterTextureImage(CPGreyBmp texture, Bitmap bitmap, int color) { if (bitmap == null) return; if (texture == null) { texture = new CPGreyBmp(1, 1); texture.data[0] = (byte) 0x00; } int red = Color.red(color), green = Color.green(color), blue = Color .blue(color); int width = bitmap.getWidth(), height = bitmap.getHeight(); int[] buffer = new int[width * height]; for (int i = 0; i < width * height; i++) { buffer[i] = ~texture.data[texture.getWidth() * (i / width % texture.getHeight()) + i % width % texture.getWidth()]; buffer[i] = (buffer[i] & 0xff) << 24 | red << 16 | green << 8 | blue; } bitmap.setPixels(buffer, 0, width, 0, 0, width, height); } } }