All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.rpgframework.jfx.ChoiceManyDialog Maven / Gradle / Ivy

package de.rpgframework.jfx;

import java.lang.System.Logger;
import java.lang.System.Logger.Level;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import java.util.Locale;

import org.prelle.javafx.CloseType;
import org.prelle.javafx.ManagedDialog;
import org.prelle.javafx.OptionalNodePane;
import org.prelle.javafx.SymbolIcon;
import org.prelle.javafx.WindowMode;

import de.rpgframework.genericrpg.chargen.PartialController;
import de.rpgframework.genericrpg.chargen.RecommendationState;
import de.rpgframework.genericrpg.chargen.RecommendingController;
import de.rpgframework.genericrpg.data.Choice;
import de.rpgframework.genericrpg.data.DataItem;
import de.rpgframework.genericrpg.data.DataItemValue;
import de.rpgframework.genericrpg.data.Decision;
import javafx.collections.ListChangeListener;
import javafx.scene.control.Label;
import javafx.scene.control.ListCell;
import javafx.scene.control.ListView;
import javafx.scene.control.SelectionMode;
import javafx.scene.layout.Priority;
import javafx.scene.layout.VBox;

/**
 * Select one from a list of 2-3 choices
 * @author prelle
 *
 */
@SuppressWarnings("rawtypes")
public class ChoiceManyDialog extends ManagedDialog  {

	public final static Logger logger = System.getLogger(RPGFrameworkJFXConstants.BASE_LOGGER_NAME);

	private String modText;
	private DataItem decideFor;
	private Choice choice;
	private List options;
	private PartialController control;
	private OptionalNodePane pane;
	private GenericDescriptionVBox bxDescription;

	private ListView listView;
	private List selections;

	private Decision decision;

	//-------------------------------------------------------------------
	@SuppressWarnings("unchecked")
	public ChoiceManyDialog(DataItem decideFor, Choice choice, String modText, List options, PartialController control) {
		super("",null,CloseType.CANCEL, CloseType.OK);
		this.decideFor = decideFor;
		this.modText = modText;
		this.choice  = choice;
		this.options = (List) options;
		this.control = control;
		if (control==null) throw new NullPointerException();
		initComponents();
		initLayout();
		initInteractivity();

		buttonDisabledProperty().put(CloseType.OK, Boolean.FALSE);
		verifyOKButton();
	}

	//-------------------------------------------------------------------
	private void initComponents() {
		selections = new ArrayList();
		listView = new ListView<>();
		listView.getItems().addAll(options);
		if (choice.getCount()>1) {
			listView.getSelectionModel().setSelectionMode(SelectionMode.MULTIPLE);
		}

		bxDescription = new GenericDescriptionVBox(null, null);
		bxDescription.setStyle("-fx-max-width: 360px; -fx-min-width: 300px;");
	}

	//-------------------------------------------------------------------
	private void initLayout() {
		Label lbModText = new Label(modText);

		VBox layout = new VBox(5, lbModText, listView);
		listView.setMaxHeight(Double.MAX_VALUE);
		listView.setStyle("-fx-max-width: 360px; -fx-min-width: 300px");
		listView.setCellFactory( lv -> {
			return new ListCell<>() {
				public void updateItem(Object item, boolean empty) {
					super.updateItem(item, empty);
					if (empty) {
						setGraphic(null);
						setText(null);
					} else {
						SymbolIcon symbol = new SymbolIcon("outlinestar");
						RecommendingController recCtrl = control.getCharacterController().getRecommendingControllerFor(item);
						if (recCtrl!=null) {
							symbol.setManaged(true);
							RecommendationState state = recCtrl.getRecommendationState(item);
							if (state==null || state==RecommendationState.NEUTRAL) {
								symbol.setVisible(false);
							} else if (state==RecommendationState.RECOMMENDED) {
								symbol.setVisible(true);
								symbol.setSymbol("outlinestar");
							} else if (state==RecommendationState.STRONGLY_RECOMMENDED) {
								symbol.setVisible(true);
								symbol.setSymbol("favorite");
							}
						} else {
							symbol.setVisible(false);
							symbol.setManaged(false);
						}
						setGraphic(symbol);

						if (item instanceof DataItem) {
							setText(((DataItem)item).getName());
						} else if (item instanceof DataItemValue) {
							setText(((DataItemValue)item).getNameWithoutRating(Locale.getDefault()));
						} else if (item instanceof Enum) {
							try {
								Method method = item.getClass().getMethod("getName");
								setText((String)method.invoke(item));
							} catch (Exception e) {
								setText(String.valueOf(item));
							}
						} else {
							setText(String.valueOf(item));
						}
					}
				}
			};
		});
		VBox.setVgrow(listView, Priority.SOMETIMES);

		pane = new OptionalNodePane();
		pane.setThreshold(WindowMode.COMPACT);
		pane.setContentGrow(Priority.SOMETIMES);
		pane.setContent(layout);
		pane.setOptional(bxDescription);
		super.setContent(pane);
		super.setTitle(decideFor.getName());
	}

	//-------------------------------------------------------------------
	private void initInteractivity() {
		listView.getSelectionModel().getSelectedItems().addListener(new ListChangeListener() {
			public void onChanged(Change c) {
				logger.log(Level.WARNING, "Selection changed "+c);
				// Recalculate keys
				selections.clear();
				for (Object resolved : listView.getSelectionModel().getSelectedItems()) {
					String key = String.valueOf(resolved);
					if (resolved instanceof Enum) {
						key = ((Enum) resolved).name();
						if (resolved instanceof Enum) {
							try {
								Method method = resolved.getClass().getMethod("getName");
								bxDescription.setTitle((String)method.invoke(resolved));
							} catch (Exception e) {
								bxDescription.setTitle(String.valueOf(resolved));
							}
						}
					} else if (resolved instanceof DataItem) {
						bxDescription.setData((DataItem)resolved);
//						pane.setOptional(new GenericDescriptionVBox<>(null, (DataItem)resolved));
//						pane.setStyle("-fx-pref-width: 20em");
						key = ((DataItem) resolved).getId();
					} else if (resolved instanceof DataItemValue) {
						bxDescription.setData((DataItemValue)resolved);
//						pane.setOptional(new GenericDescriptionVBox<>(null, (DataItem)resolved));
//						pane.setStyle("-fx-pref-width: 20em");
						key = ((DataItemValue) resolved).getKey();
					}
					selections.add(key);
				}

				verifyOKButton();
			}});
	}

	//-------------------------------------------------------------------
	private void verifyOKButton() {
		boolean notGood = true;
		if (choice.getCount()>0) {
			notGood = selections.size()!=choice.getCount();
		}  else {
			notGood = selections.size()!=1;
		}
		logger.log(Level.INFO, "Choice count = "+choice.getCount()+"   notGood="+notGood);
		ChoiceManyDialog.this.buttonDisabledProperty().put(CloseType.OK,notGood);
	}

	//-------------------------------------------------------------------
	/**
	 * @see org.prelle.javafx.ManagedDialog#onClose(org.prelle.javafx.CloseType)
	 */
	@SuppressWarnings("unchecked")
	public void onClose(CloseType closeType) {
		if (closeType == CloseType.OK) {
			String decidedKeys = String.join(",", selections);
			logger.log(Level.INFO, "Closing with decided keys = " + decidedKeys);

			decision = new Decision(choice, decidedKeys);
			((PartialController) control).decide(decideFor, choice.getUUID(), decision);
		}
	}

	//-------------------------------------------------------------------
	/**
	 * Return the decision that has been already send to the controller
	 */
	public Decision getDecision() {
		return decision;
	}

}