/*
* ******************************************************************************
* * Copyright 2015 See AUTHORS file.
* *
* * 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.uwsoft.editor.view.ui.box;
import com.badlogic.ashley.core.Entity;
import com.badlogic.gdx.utils.reflect.ClassReflection;
import com.badlogic.gdx.utils.reflect.ReflectionException;
import com.commons.MsgAPI;
import com.puremvc.patterns.mediator.Mediator;
import com.puremvc.patterns.observer.Notification;
import com.uwsoft.editor.Overlap2DFacade;
import com.uwsoft.editor.controller.commands.AddComponentToItemCommand;
import com.uwsoft.editor.controller.commands.RemoveComponentFromItemCommand;
import com.uwsoft.editor.renderer.components.PolygonComponent;
import com.uwsoft.editor.renderer.components.ShaderComponent;
import com.uwsoft.editor.renderer.components.physics.PhysicsBodyComponent;
import com.uwsoft.editor.renderer.data.SceneVO;
import com.uwsoft.editor.renderer.factory.EntityFactory;
import com.uwsoft.editor.renderer.utils.ComponentRetriever;
import com.uwsoft.editor.utils.runtime.EntityUtils;
import com.uwsoft.editor.view.stage.Sandbox;
import com.uwsoft.editor.view.stage.SandboxMediator;
import com.uwsoft.editor.view.stage.tools.TextTool;
import com.uwsoft.editor.view.ui.properties.UIAbstractProperties;
import com.uwsoft.editor.view.ui.properties.UIAbstractPropertiesMediator;
import com.uwsoft.editor.view.ui.properties.panels.*;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Set;
import java.util.stream.Stream;
/**
* Created by azakhary on 4/15/2015.
*/
public class UIMultiPropertyBoxMediator extends PanelMediator<UIMultiPropertyBox> {
private static final String TAG = UIMultiPropertyBoxMediator.class.getCanonicalName();
public static final String NAME = TAG;
private HashMap<String, ArrayList<String>> classToMediatorMap;
private ArrayList<UIAbstractPropertiesMediator> currentRegisteredPropertyBoxes = new ArrayList<>();
public UIMultiPropertyBoxMediator() {
super(NAME, new UIMultiPropertyBox());
// TODO: shouldn't this be initialized by default?
facade = Overlap2DFacade.getInstance();
initMap();
}
private void initMap() {
classToMediatorMap = new HashMap<>();
classToMediatorMap.put(Entity.class.getName(), new ArrayList<>());
classToMediatorMap.get(Entity.class.getName()).add(UIBasicItemPropertiesMediator.NAME);
classToMediatorMap.put(SceneVO.class.getName(), new ArrayList<>());
classToMediatorMap.get(SceneVO.class.getName()).add(UIScenePropertiesMediator.NAME);
classToMediatorMap.put(TextTool.class.getName(), new ArrayList<>());
classToMediatorMap.get(TextTool.class.getName()).add(UITextToolPropertiesMediator.NAME);
}
private void initEntityProperties( ArrayList<String> mediatorNames, Entity entity) {
int entityType = EntityUtils.getType(entity);
if(entityType == EntityFactory.IMAGE_TYPE) {
mediatorNames.add(UIImageItemPropertiesMediator.NAME);
}
if(entityType == EntityFactory.COMPOSITE_TYPE) {
mediatorNames.add(UICompositeItemPropertiesMediator.NAME);
}
if(entityType == EntityFactory.LABEL_TYPE) {
mediatorNames.add(UILabelItemPropertiesMediator.NAME);
}
if(entityType == EntityFactory.SPRITE_TYPE) {
mediatorNames.add(UISpriteAnimationItemPropertiesMediator.NAME);
}
if(entityType == EntityFactory.SPINE_TYPE) {
mediatorNames.add(UISpineAnimationItemPropertiesMediator.NAME);
}
if(entityType == EntityFactory.LIGHT_TYPE) {
mediatorNames.add(UILightItemPropertiesMediator.NAME);
}
// optional panels based on components
PolygonComponent polygonComponent = ComponentRetriever.get(entity, PolygonComponent.class);
PhysicsBodyComponent physicsComponent = ComponentRetriever.get(entity, PhysicsBodyComponent.class);
ShaderComponent shaderComponent = ComponentRetriever.get(entity, ShaderComponent.class);
if(polygonComponent != null) {
mediatorNames.add(UIPolygonComponentPropertiesMediator.NAME);
}
if(physicsComponent != null) {
mediatorNames.add(UIPhysicsPropertiesMediator.NAME);
}
if(shaderComponent != null) {
mediatorNames.add(UIShaderPropertiesMediator.NAME);
}
}
@Override
public String[] listNotificationInterests() {
String[] parentNotifications = super.listNotificationInterests();
return Stream.of(parentNotifications, new String[]{
MsgAPI.SCENE_LOADED,
MsgAPI.EMPTY_SPACE_CLICKED,
MsgAPI.ITEM_DATA_UPDATED,
MsgAPI.ITEM_SELECTION_CHANGED,
MsgAPI.DELETE_ITEMS_COMMAND_DONE,
SandboxMediator.SANDBOX_TOOL_CHANGED,
AddComponentToItemCommand.DONE,
RemoveComponentFromItemCommand.DONE
}).flatMap(Stream::of).toArray(String[]::new);
}
@Override
public void handleNotification(Notification notification) {
super.handleNotification(notification);
switch (notification.getName()) {
case MsgAPI.SCENE_LOADED:
initAllPropertyBoxes(null);
break;
case MsgAPI.EMPTY_SPACE_CLICKED:
initAllPropertyBoxes(null);
break;
case MsgAPI.ITEM_SELECTION_CHANGED:
Set<Entity> selection = notification.getBody();
if(selection.size() == 1) {
initAllPropertyBoxes(selection.iterator().next());
}
break;
case RemoveComponentFromItemCommand.DONE:
initAllPropertyBoxes(notification.getBody());
break;
case AddComponentToItemCommand.DONE:
initAllPropertyBoxes(notification.getBody());
break;
case SandboxMediator.SANDBOX_TOOL_CHANGED:
initAllPropertyBoxes(notification.getBody());
break;
case MsgAPI.DELETE_ITEMS_COMMAND_DONE:
initAllPropertyBoxes(null);
break;
default:
break;
}
}
private void initAllPropertyBoxes(Object observable) {
if(observable == null) {
// if there is nothing to observe, always observe current scene
observable = Sandbox.getInstance().sceneControl.getCurrentSceneVO();
}
String mapName = observable.getClass().getName();
if(classToMediatorMap.get(mapName) == null) return;
// retrieve a list of property panels to show
ArrayList<String> mediatorNames = new ArrayList<>(classToMediatorMap.get(mapName));
// TODO: this is not uber cool, gotta think a new way to make this class know nothing about entities
if(observable instanceof Entity){
initEntityProperties(mediatorNames, (Entity) observable);
}
if(mediatorNames == null) return;
//clear all current enabled panels
viewComponent.clearAll();
//unregister all current mediators
for(UIAbstractPropertiesMediator mediator: currentRegisteredPropertyBoxes) {
facade.removeMediator(mediator.getMediatorName());
}
currentRegisteredPropertyBoxes.clear();
for (String mediatorName : mediatorNames) {
try {
facade.registerMediator((Mediator) ClassReflection.newInstance(ClassReflection.forName(mediatorName)));
UIAbstractPropertiesMediator<Object, UIAbstractProperties> propertyBoxMediator = facade.retrieveMediator(mediatorName);
currentRegisteredPropertyBoxes.add(propertyBoxMediator);
propertyBoxMediator.setItem(observable);
viewComponent.addPropertyBox(propertyBoxMediator.getViewComponent());
} catch (ReflectionException e) {
e.printStackTrace();
}
}
}
}