package com.akjava.gwt.poseeditor.client;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import com.akjava.gwt.html5.client.file.File;
import com.akjava.gwt.html5.client.file.FileUploadForm;
import com.akjava.gwt.html5.client.file.FileUtils;
import com.akjava.gwt.html5.client.file.FileUtils.DataURLListener;
import com.akjava.gwt.lib.client.ExportUtils;
import com.akjava.gwt.lib.client.IStorageControler;
import com.akjava.gwt.lib.client.LogUtils;
import com.akjava.gwt.lib.client.StorageDataList;
import com.akjava.gwt.lib.client.StorageDataList.StorageExceptionListener;
import com.akjava.gwt.lib.client.StorageException;
import com.akjava.gwt.lib.client.ValueUtils;
import com.akjava.gwt.lib.client.datalist.SimpleTextData;
import com.akjava.gwt.poseeditor.client.resources.PoseEditorBundles;
import com.google.gwt.event.dom.client.ChangeEvent;
import com.google.gwt.event.dom.client.ChangeHandler;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.http.client.Request;
import com.google.gwt.http.client.RequestBuilder;
import com.google.gwt.http.client.RequestCallback;
import com.google.gwt.http.client.RequestException;
import com.google.gwt.http.client.Response;
import com.google.gwt.http.client.URL;
import com.google.gwt.json.client.JSONObject;
import com.google.gwt.json.client.JSONParser;
import com.google.gwt.json.client.JSONValue;
import com.google.gwt.user.client.Window;
import com.google.gwt.user.client.ui.Button;
import com.google.gwt.user.client.ui.FocusWidget;
import com.google.gwt.user.client.ui.HorizontalPanel;
import com.google.gwt.user.client.ui.Label;
import com.google.gwt.user.client.ui.ListBox;
import com.google.gwt.user.client.ui.VerticalPanel;
public class PreferenceTabPanel extends VerticalPanel {
private IStorageControler controler;
private PreferenceListener preferenceListener;
private Map<Integer, String> presetModelMap = new HashMap<Integer, String>();
private ListBox modelListBox;
private Label modelSelection;
private StorageDataList modelControler;
private StorageDataList textureControler;
public static final String KEY_MODEL_SELECTION="MODEL_SELECTION";
public static final String KEY_TEXTURE_SELECTION="TEXTURE_SELECTION";
private Button removeBt;
public PreferenceListener getListener() {
return preferenceListener;
}
public void setListener(PreferenceListener listener) {
this.preferenceListener = listener;
}
private void createModelControl(){
HorizontalPanel mPanel=new HorizontalPanel();
add(mPanel);
Label modelLabel=new Label("Model(three.json include bone)");
modelLabel.setWidth("150px");
mPanel.add(modelLabel);
Button modelUpdateBt=new Button("Update");
mPanel.add(modelUpdateBt);
modelUpdateBt.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
updateModelList();
}
});
final FileUploadForm modelUpload=FileUtils.createSingleTextFileUploadForm(new DataURLListener() {
@Override
public void uploaded(File file, String text) {
JSONValue lastJsonValue = JSONParser.parseStrict(text);
//TODO more validate
JSONObject object=lastJsonValue.isObject();
if(object==null){
Window.alert("invalid model");
return;
}
modelControler.setDataValue(file.getFileName(), text);
int id=modelControler.incrementId();
loadModel(new SimpleTextData(id, file.getFileName(), text));
modelListBox.addItem(file.getFileName(),""+id);
//LogUtils.log("preferenceDebug:6"+(modelListBox.getItemCount()-1));
modelListBox.setSelectedIndex(modelListBox.getItemCount()-1);
//LogUtils.log("preferenceDebug:7"+id);
updateModelButtons();
try {
controler.setValue(KEY_MODEL_SELECTION, modelListBox.getItemCount()-1);
} catch (StorageException e) {
PoseEditor.alert(e.getMessage());
}
//LogUtils.log("preferenceDebug:8"+id);
}
}, true);
add(modelUpload);
/*
modelUpload.getFileUpload().addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
JsArray<File> files = FileUtils.toFile(event.getNativeEvent());
final FileReader reader=FileReader.createFileReader();
final File file=files.get(0);
reader.setOnLoad(new FileHandler() {
@Override
public void onLoad() {
modelUpload.reset();
try{
String text=reader.getResultAsString();
JSONValue lastJsonValue = JSONParser.parseStrict(text);
//TODO more validate
JSONObject object=lastJsonValue.isObject();
if(object==null){
Window.alert("invalid model");
return;
}
LogUtils.log("preferenceDebug:1");
modelControler.setDataValue(file.getFileName(), text);
LogUtils.log("preferenceDebug:2");
int id=modelControler.incrementId();
LogUtils.log("preferenceDebug:3"+id);
loadModel(new HeaderAndValue(id, file.getFileName(), text));
LogUtils.log("preferenceDebug:4");
modelListBox.addItem(file.getFileName(),""+id);
LogUtils.log("preferenceDebug:5"+id);
LogUtils.log("preferenceDebug:6"+(modelListBox.getItemCount()-1));
modelListBox.setSelectedIndex(modelListBox.getItemCount()-1);
LogUtils.log("preferenceDebug:7"+id);
updateModelButtons();
controler.setValue(KEY_MODEL_SELECTION, modelListBox.getItemCount()-1);
LogUtils.log("preferenceDebug:8"+id);
}catch(Exception e){
PoseEditor.alert(e.getMessage());
}
}
});
reader.readAsText(file,"utf-8");
}
});
*/
modelControler=new StorageDataList(controler, "MODEL");
modelSelection = new Label();
add(modelSelection);
modelListBox = new ListBox();
modelListBox.setWidth("300px");
add(modelListBox);
modelListBox.setVisibleItemCount(5);
modelListBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
updateModelButtons();
}
});
updateModelList();
HorizontalPanel buttons = new HorizontalPanel();
add(buttons);
Button loadBt = new Button("Load");
buttons.add(loadBt);
loadBt.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
loadModelByListIndex(modelListBox
.getSelectedIndex());
}
});
removeBt = new Button("Remove");
buttons.add(removeBt);
removeBt.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
removeModelByListIndex(modelListBox
.getSelectedIndex());
}
});
}
String[] imageExtensions={".jpg",".png",".jpeg","webp"};
private boolean isImageFile(File file){
String name=file.getFileName().toLowerCase();
for(int i=0;i<imageExtensions.length;i++){
if(name.endsWith(imageExtensions[i])){
return true;
}
}
return false;
}
private ListBox textureListBox;
private Label textureSelection;
private FocusWidget removeTextureBt;
private Map<Integer, String> presetTextureMap = new HashMap<Integer, String>();
private void createTextureControl(){
add(new Label("Texture"));
final FileUploadForm textureUpload=FileUtils.createSingleFileUploadForm(new DataURLListener() {
public void uploaded(File file,String value){
if(!isImageFile(file)){
Window.alert("texture format support .jpg , .png or .webp");
return;
}
//TODO check image and validate it for size
try{
int id=textureControler.addData(file.getFileName(), value);
loadTexture(new SimpleTextData(id, file.getFileName(), value));
textureListBox.addItem(file.getFileName(),""+id);
textureListBox.setSelectedIndex(textureListBox.getItemCount()-1);
updateTextureButtons();
controler.setValue(KEY_TEXTURE_SELECTION, textureListBox.getItemCount()-1);//anyway select last one
}catch(Exception e){
LogUtils.log(e.getMessage());
//PoseEditor.alert(e.getMessage());
}
}
},true);
add(textureUpload);
/*
textureUpload.getFileUpload().addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
JsArray<File> files = FileUtils.toFile(event.getNativeEvent());
final FileReader reader=FileReader.createFileReader();
final File file=files.get(0);
reader.setOnLoad(new FileHandler() {
@Override
public void onLoad() {
textureUpload.reset();
String text=reader.getResultAsString();
if(!isImageFile(file)){
Window.alert("texture support .jpg or .png");
return;
}
try{
textureControler.setDataValue(file.getFileName(), text);
int id=textureControler.incrementId();
loadTexture(new HeaderAndValue(id, file.getFileName(), text));
textureListBox.addItem(file.getFileName(),""+id);
textureListBox.setSelectedIndex(textureListBox.getItemCount()-1);
updateTextureButtons();
controler.setValue(KEY_TEXTURE_SELECTION, textureListBox.getItemCount()-1);
}catch(Exception e){
PoseEditor.alert(e.getMessage());
}
}
});
reader.readAsDataURL(file);
}
});
*/
textureControler=new StorageDataList(controler, "TEXTURE");
textureControler.setExceptionListener(new StorageExceptionListener() {
@Override
public void onError(StorageException exception) {
PoseEditor.alert(exception.getMessage());
}
});
textureSelection = new Label();
add(textureSelection);
textureListBox = new ListBox();
textureListBox.setWidth("300px");
add(textureListBox);
textureListBox.setVisibleItemCount(5);
// read from
String textureText = PoseEditorBundles.INSTANCE.textureNames().getText();
String[][] mapV = ValueUtils.csvToArray(textureText);
for (int i = 0; i < mapV.length; i++) {
if (mapV[i].length == 2) {
String filePath = mapV[i][0];
String id = mapV[i][1];
String fileName = getFileNameWithoutExtension(filePath);
presetTextureMap.put(Integer.parseInt(id), filePath);
textureListBox.addItem(fileName, id);
}
}
List<SimpleTextData> textures=textureControler.getDataList();
for(int i=0;i<textures.size();i++){
textureListBox.addItem(textures.get(i).getName(),""+textures.get(i).getId());
}
textureListBox.addChangeHandler(new ChangeHandler() {
@Override
public void onChange(ChangeEvent event) {
updateTextureButtons();
}
});
int listBoxSelection;
try {
listBoxSelection = controler.getValue(KEY_TEXTURE_SELECTION, 0);
if(listBoxSelection>=textureListBox.getItemCount()){
LogUtils.log("warn texture index is invalid:"+listBoxSelection);
listBoxSelection=0;
}
textureListBox.setSelectedIndex(listBoxSelection);
} catch (StorageException e) {
LogUtils.log("get key_texture_selection faild");
}//default bone
HorizontalPanel buttons = new HorizontalPanel();
add(buttons);
Button loadBt = new Button("Load");
buttons.add(loadBt);
loadBt.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
loadTextureByListIndex(textureListBox
.getSelectedIndex());
}
});
removeTextureBt = new Button("Remove");
buttons.add(removeTextureBt);
removeTextureBt.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
removeTextureByListIndex(textureListBox
.getSelectedIndex());
}
});
Button exportBt = new Button("Export");
buttons.add(exportBt);
exportBt.addClickHandler(new ClickHandler() {
@Override
public void onClick(ClickEvent event) {
exportTextureByListIndex(textureListBox
.getSelectedIndex());
}
});
}
private void updateModelList(){
modelListBox.clear();
// read from resource
String modelText = PoseEditorBundles.INSTANCE.modelNames().getText();
String[][] mapV = ValueUtils.csvToArray(modelText);
for (int i = 0; i < mapV.length; i++) {
if (mapV[i].length == 2) {
String filePath = mapV[i][0];
String id = mapV[i][1];
String fileName = getFileNameWithoutExtension(filePath);
presetModelMap.put(Integer.parseInt(id), filePath);
modelListBox.addItem(fileName, id);
}
}
//update from storage
List<SimpleTextData> models=modelControler.getDataList();
for(int i=0;i<models.size();i++){
modelListBox.addItem(models.get(i).getName(),""+models.get(i).getId());
}
int listBoxSelection;
try {
listBoxSelection = controler.getValue(KEY_MODEL_SELECTION, 0);
if(listBoxSelection>=modelListBox.getItemCount()){
LogUtils.log("warn model index is invalid:"+listBoxSelection);
listBoxSelection=0;
}
modelListBox.setSelectedIndex(listBoxSelection);
} catch (StorageException e) {
LogUtils.log("load model selection faild");
e.printStackTrace();
}//default bone
}
public PreferenceTabPanel(IStorageControler cs,
PreferenceListener listener) {
this.controler = cs;
this.preferenceListener = listener;
createModelControl();
createTextureControl();
}
protected void updateModelButtons() {
//preset cant remove
String id = modelListBox.getValue(modelListBox.getSelectedIndex());
final int idIndex = Integer.parseInt(id);
if(idIndex<0){//preset cant delate
removeBt.setEnabled(false);
}else{
removeBt.setEnabled(true);
}
}
protected void updateTextureButtons() {
//preset cant remove
String id = textureListBox.getValue(textureListBox.getSelectedIndex());
final int idIndex = Integer.parseInt(id);
if(idIndex<0){
removeTextureBt.setEnabled(false);
}else{
removeTextureBt.setEnabled(true);
}
}
public void loadSelectionModel(){
loadModelByListIndex(modelListBox.getSelectedIndex());
}
public void loadSelectionTexture(){
loadTextureByListIndex(textureListBox.getSelectedIndex());
}
private void removeModelByListIndex(final int index) {
String id = modelListBox.getValue(index);
final String modelName=modelListBox.getItemText(index);
LogUtils.log(id+","+modelName);
final int idIndex = Integer.parseInt(id);
if (idIndex < 0) {
//never calld;
} else {
modelControler.clearData(idIndex);
int boxIndex=modelListBox.getSelectedIndex();
modelListBox.removeItem(boxIndex);
modelListBox.setSelectedIndex(boxIndex-1);
updateModelButtons();
loadSelectionModel();
}
}
private void removeTextureByListIndex(final int index) {
String id = textureListBox.getValue(index);
final String textureName=textureListBox.getItemText(index);
LogUtils.log(id+","+textureName);
final int idIndex = Integer.parseInt(id);
if (idIndex < 0) {
//never calld;
} else {
textureControler.clearData(idIndex);
int boxIndex=textureListBox.getSelectedIndex();
textureListBox.removeItem(boxIndex);
textureListBox.setSelectedIndex(boxIndex-1);
updateTextureButtons();
loadSelectionTexture();
}
}
private void loadModelByListIndex(final int index) {
String id = modelListBox.getValue(index);
final String modelName=modelListBox.getItemText(index);
LogUtils.log(id+","+modelName);
final int idIndex = Integer.parseInt(id);
if (idIndex < 0) {
String path = presetModelMap.get(idIndex);
if (path != null) {
RequestBuilder builder = new RequestBuilder(
RequestBuilder.GET, URL.encode(path));
try {
builder.sendRequest(null, new RequestCallback() {
@Override
public void onResponseReceived(Request request,
Response response) {
loadModel(new SimpleTextData(idIndex, modelName, response.getText()));
try {
controler.setValue(KEY_MODEL_SELECTION, index);
} catch (StorageException e) {
LogUtils.log("set KEY_MODEL_SELECTION faild");
e.printStackTrace();
}
}
@Override
public void onError(Request request,
Throwable exception) {
Window.alert("load faild:");
}
});
} catch (RequestException e) {
LogUtils.log(e.getMessage());
e.printStackTrace();
}
} else {
LogUtils.log("preset model not found" + idIndex);
}
} else {
// load from cache
SimpleTextData hv=modelControler.getDataValue(idIndex);
loadModel(hv);
try {
controler.setValue(KEY_MODEL_SELECTION, index);
} catch (StorageException e) {
LogUtils.log("set KEY_MODEL_SELECTION faild");
e.printStackTrace();
}
}
}
private void loadTextureByListIndex(final int index) {
String id = textureListBox.getValue(index);
final String textureName=textureListBox.getItemText(index);
LogUtils.log(id+","+textureName);
final int idIndex = Integer.parseInt(id);
if (idIndex < 0) {
String path = presetTextureMap.get(idIndex);
if (path != null) {
loadTexture(new SimpleTextData(idIndex, textureName, path));
try {
controler.setValue(KEY_TEXTURE_SELECTION, index);
} catch (StorageException e) {
LogUtils.log("set KEY_TEXTURE_SELECTION faild");
e.printStackTrace();
}
} else {
LogUtils.log("preset model not found" + idIndex);
}
} else {
// load from cache
SimpleTextData hv=textureControler.getDataValue(idIndex);
loadTexture(hv);
try {
controler.setValue(KEY_TEXTURE_SELECTION, index);
} catch (StorageException e) {
LogUtils.log("set KEY_TEXTURE_SELECTION faild");
e.printStackTrace();
}
}
}
private void exportTextureByListIndex(final int index) {
String id = textureListBox.getValue(index);
final String textureName=textureListBox.getItemText(index);
LogUtils.log(id+","+textureName);
final int idIndex = Integer.parseInt(id);
if (idIndex < 0) {
String path = presetTextureMap.get(idIndex);
if (path != null) {
//becareful app mode cant export iamge because of app has secret url
//blank uimage must be absolute path,or data url
//ExportUtils.openTabDataURLImage(GWT.getHostPageBaseURL()+path, textureName);
Window.open(path, textureName,null);
} else {
LogUtils.log("preset model not found" + idIndex);
}
} else {
// load from cache
SimpleTextData hv=textureControler.getDataValue(idIndex);
//LogUtils.log("texture:"+hv.getData());
//Window.open(hv.getData(), textureName, null);
ExportUtils.openTabAbsoluteURLImage(hv.getData(), textureName);
}
}
private void loadModel(SimpleTextData value) {
preferenceListener.modelChanged(value);
modelSelection.setText("Selection:"+value.getName());
}
private void loadTexture(SimpleTextData value) {
preferenceListener.textureChanged(value);
textureSelection.setText("Selection:"+value.getName());
}
public String getFileNameWithoutExtension(String name) {
int start = name.lastIndexOf("/");
if (start == -1) {
start = 0;
} else {
start++;
}
int end = name.lastIndexOf(".");
if (end == -1) {
end = name.length();
}
return name.substring(start, end);
}
public interface PreferenceListener {
public void modelChanged(SimpleTextData model);
public void textureChanged(SimpleTextData texture);
}
}