de.rpgframework.jfx.DataItemPane Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of rpgframework-javafx Show documentation
Show all versions of rpgframework-javafx Show documentation
JavaFX extensions for the RPGFramework
package de.rpgframework.jfx;
import java.lang.System.Logger.Level;
import java.util.Collection;
import java.util.List;
import java.util.ResourceBundle;
import java.util.function.BiConsumer;
import java.util.function.Function;
import java.util.stream.Collectors;
import org.prelle.javafx.ImageSpinningListView;
import org.prelle.javafx.JavaFXConstants;
import org.prelle.javafx.ListWithDetailsView;
import org.prelle.javafx.ListWithDetailsViewColumn;
import org.prelle.javafx.NodeWithTitle;
import org.prelle.javafx.ResponsiveControl;
import org.prelle.javafx.ResponsiveControlManager;
import org.prelle.javafx.WindowMode;
import de.rpgframework.ResourceI18N;
import de.rpgframework.genericrpg.data.Choice;
import de.rpgframework.genericrpg.data.ChoiceOrigin;
import de.rpgframework.genericrpg.data.ComplexDataItem;
import de.rpgframework.genericrpg.data.DataItem;
import de.rpgframework.genericrpg.data.Decision;
import de.rpgframework.genericrpg.data.DecisionContainer;
import de.rpgframework.genericrpg.data.GenericRPGTools;
import de.rpgframework.genericrpg.modification.DataItemModification;
import de.rpgframework.genericrpg.modification.Modification;
import de.rpgframework.genericrpg.modification.ModificationChoice;
import de.rpgframework.genericrpg.modification.ModifiedObjectType;
import de.rpgframework.genericrpg.requirements.Requirement;
import javafx.beans.property.BooleanProperty;
import javafx.beans.property.ObjectProperty;
import javafx.beans.property.ReadOnlyObjectProperty;
import javafx.beans.property.SimpleBooleanProperty;
import javafx.beans.property.SimpleObjectProperty;
import javafx.collections.FXCollections;
import javafx.geometry.Insets;
import javafx.geometry.Pos;
import javafx.scene.Node;
import javafx.scene.control.Button;
import javafx.scene.control.Label;
import javafx.scene.control.Tooltip;
import javafx.scene.image.Image;
import javafx.scene.layout.HBox;
import javafx.scene.layout.VBox;
import javafx.scene.text.Text;
import javafx.scene.text.TextFlow;
import javafx.util.Callback;
/**
* Provide a spinner to browse through a list of data items
* and add additional information
*
* @author prelle
*
*/
public class DataItemPane extends ListWithDetailsView implements ResponsiveControl {
final static ResourceBundle RES = ResourceBundle.getBundle(DataItemPane.class.getName());
private ObjectProperty> modifConverter = new SimpleObjectProperty<>();
private ObjectProperty> refTypeConverter = new SimpleObjectProperty<>();
private ObjectProperty> choiceConverter = new SimpleObjectProperty<>();
private DecisionContainer decisionContainer;
private ObjectProperty> decisionHandler = new SimpleObjectProperty<>();
private ObjectProperty> modDecisionHandler = new SimpleObjectProperty<>();
private ObjectProperty customNode1 = new SimpleObjectProperty<>();
private ObjectProperty layoutMode = new SimpleObjectProperty<>(WindowMode.EXPANDED);
private BooleanProperty showDecisionColumn = new SimpleBooleanProperty(true);
private BooleanProperty showStatsColumn = new SimpleBooleanProperty(true);
private BooleanProperty showModificationsInDescription = new SimpleBooleanProperty(true);
private transient Function reqR;
private transient Function modR;
private ImageSpinningListView selector;
private ListWithDetailsViewColumn colEffects;
private ListWithDetailsViewColumn colChoices;
private ListWithDetailsViewColumn colDescription;
//-------------------------------------------------------------------
public DataItemPane(Function reqR, Function modR) {
layoutMode.set(ResponsiveControlManager.getCurrentMode());
this.reqR = reqR;
this.modR = modR;
initComponents();
initInteractivity();
// selectedItemValue.addListener( (ov,o,n) -> selectedItem.set((n!=null)?n.getResolved():null));
}
//-------------------------------------------------------------------
private void initColumns() {
colEffects = new ListWithDetailsViewColumn<>(ResourceI18N.get(RES, "tab.effects"), item -> {
return getContentStats(item);
});
colChoices = new ListWithDetailsViewColumn<>(ResourceI18N.get(RES, "tab.choices"), item -> {
return getContentStats(item);
});
colDescription = new ListWithDetailsViewColumn<>(ResourceI18N.get(RES, "tab.description"), item -> {
GenericDescriptionVBox ret = new GenericDescriptionVBox(reqR,modR);
ret.setUseScrollPane(false);
ret.showModificationsInDescriptionProperty().bind(showModificationsInDescriptionProperty());
ret.setData(item);
return ret;
});
}
//-------------------------------------------------------------------
private void initComponents() {
initColumns();
// Configure image spinner
selector = new ImageSpinningListView();
getColumns().addAll(colChoices,colDescription);
setSelectorNode(selector);
}
//-------------------------------------------------------------------
private void initInteractivity() {
customNode1Property().addListener( (ov,o,n) -> {
getColumns().setAll(colChoices,colDescription);
if (n!=null) {
ListWithDetailsViewColumn custCol = new ListWithDetailsViewColumn<>(n.getTitle(), item -> {
return n.getContent();
});
getColumns().add(0, custCol);
}
});
}
// //-------------------------------------------------------------------
// public DataItemPane(Node node, ObjectProperty selected,Function reqR, Function modR) {
// this(reqR,modR);
// selectorNode.set(node);
// selectedItem.bind(selected);
// }
//
// //-------------------------------------------------------------------
// /**
// * @see javafx.scene.control.Control#createDefaultSkin()
// */
// @Override
// public Skin> createDefaultSkin() {
// return new DataItemPaneSkin(this, reqR, modR);
// }
//-------------------------------------------------------------------
public ReadOnlyObjectProperty selectedItemProperty() { return selector.getSelectionModel().selectedItemProperty();}
public T getSelectedItem() { return selector.getSelectionModel().getSelectedItem();}
public DataItemPane setSelectedItem(T value) {
RPGFrameworkJavaFX.logger.log(Level.ERROR, "setSelectedItem({0}) for {1}", value, getId());
selector.getSelectionModel().select(value);
return this;
}
//-------------------------------------------------------------------
public void setItems(Collection items) {
selector.setItems(FXCollections.observableArrayList(items));
selector.refreshNames();
}
// //-------------------------------------------------------------------
// public ObjectProperty> selectedItemValueProperty() { return selectedItemValue;}
// public DataItemValue getSelectedItemValue() { return selectedItemValue.get();}
// public DataItemPane setSelectedItemValue(DataItemValue value) { selectedItemValue.set(value); return this;}
//-------------------------------------------------------------------
public ObjectProperty> modificationConverterProperty() { return modifConverter;}
public Function getModificationConverter() { return modifConverter.get();}
public DataItemPane setModificationConverter(Function value) { modifConverter.set(value); return this; }
//-------------------------------------------------------------------
public ObjectProperty> referenceTypeConverterProperty() { return refTypeConverter;}
public Function getReferenceTypeConverter() { return refTypeConverter.get();}
public DataItemPane setReferenceTypeConverter(Function value) { refTypeConverter.set(value); return this; }
//-------------------------------------------------------------------
public ObjectProperty> choiceConverterProperty() { return choiceConverter;}
public Function getChoiceConverter() { return choiceConverter.get();}
public DataItemPane setChoiceConverter(Function value) { choiceConverter.set(value); return this; }
//-------------------------------------------------------------------
public void setUseForChoices(DecisionContainer value) {
this.decisionContainer = value;
}
//-------------------------------------------------------------------
public ObjectProperty> decisionHandlerProperty() { return decisionHandler;}
public BiConsumer getDecisionHandler() { return decisionHandler.get();}
public DataItemPane setDecisionHandler(BiConsumer value) { decisionHandler.set(value); return this; }
//-------------------------------------------------------------------
public ObjectProperty> modDecisionHandlerProperty() { return modDecisionHandler;}
public BiConsumer getModDecisionHandler() { return modDecisionHandler.get();}
public DataItemPane setModDecisionHandler(BiConsumer value) { modDecisionHandler.set(value); return this; }
//-------------------------------------------------------------------
public ObjectProperty customNode1Property() { return customNode1;}
public NodeWithTitle getCustomNode1() { return customNode1.get();}
public DataItemPane setCustomNode1(NodeWithTitle value) { customNode1.set(value); return this;}
//--------------------------------------------------------------------
public BooleanProperty showDecisionColumnProperty() { return showDecisionColumn; }
public Boolean isShowDecisionColumn() { return showDecisionColumn.get(); }
public DataItemPane setShowDecisionColumn(Boolean value) { showDecisionColumn.set(value); return this; }
//--------------------------------------------------------------------
public BooleanProperty showStatsColumnProperty() { return showStatsColumn; }
public Boolean isShowStatsColumn() { return showStatsColumn.get(); }
public DataItemPane setShowStatsColumn(Boolean value) { showStatsColumn.set(value); return this; }
//-------------------------------------------------------------------
public ObjectProperty layoutModeProperty() { return layoutMode;}
//--------------------------------------------------------------------
public BooleanProperty showModificationsInDescriptionProperty() { return showModificationsInDescription; }
public Boolean isShowModificationsInDescription() { return showModificationsInDescription.get(); }
public DataItemPane setShowModificationsInDescription(Boolean value) { showModificationsInDescription.set(value); return this; }
//-------------------------------------------------------------------
/**
* @see org.prelle.javafx.ResponsiveControl#setResponsiveMode(org.prelle.javafx.WindowMode)
*/
@Override
public void setResponsiveMode(WindowMode value) {
RPGFrameworkJavaFX.logger.log(Level.WARNING, getId()+": mode changed to "+value);
layoutMode.set(value);
}
//-------------------------------------------------------------------
public ObjectProperty> imageConverterProperty() { return selector.imageConverterProperty(); }
public Callback getImageConverter() { return selector.getImageConverter(); }
public DataItemPane setImageConverter(Callback value) { selector.setImageConverter(value); return this; }
//-------------------------------------------------------------------
public ObjectProperty> nameConverterProperty() { return selector.stringConverterProperty(); }
public Callback getNameConverter() { return selector.getStringConverter(); }
public DataItemPane setNameConverter(Callback value) { selector.setStringConverter(value); return this; }
//-------------------------------------------------------------------
private Node getContentStats(T raw) {
VBox contentStats = new VBox();
RPGFrameworkJavaFX.logger.log(Level.DEBUG, "getContentStats() for {0} using {1}", raw, getModificationConverter());
if (raw instanceof ComplexDataItem) {
ComplexDataItem item = (ComplexDataItem)raw;
ModifiedObjectType previousType = null;
Function modConv = getModificationConverter();
for (Modification m : item.getOutgoingModifications()) {
// Check if it is a new category
if (m.getReferenceType()!=previousType) {
String category = String.valueOf(m.getReferenceType());
if (getReferenceTypeConverter()!=null && m.getReferenceType()!=null)
category = getReferenceTypeConverter().apply(m.getReferenceType());
RPGFrameworkJavaFX.logger.log(Level.DEBUG, "RefTypeConv {0} converted {1} into {2}",getReferenceTypeConverter(), m.getReferenceType(), category);
if (category != null) {
Label head = new Label(category);
head.getStyleClass().add(JavaFXConstants.STYLE_HEADING5);
contentStats.getChildren().add(head);
VBox.setMargin(head, new Insets(5, 0, 0, 0));
}
}
previousType = m.getReferenceType();
// Create a (potentially wrapped line) per modification
Button button = null;
Tooltip tooltip = null;
String text = (modConv!=null)?modConv.apply(m):String.valueOf(m);
Text choiceText = new Text(text);
choiceText.setStyle("-fx-fill: -fx-text-base-color");
// Decision text
Text decText = new Text();
decText.getStyleClass().add(JavaFXConstants.STYLE_HEADING5);
if (m instanceof DataItemModification) {
DataItemModification mod = (DataItemModification)m;
if (mod.getConnectedChoice()!=null) {
RPGFrameworkJavaFX.logger.log(Level.DEBUG, "Determine decision text for "+mod+" and choice "+mod.getConnectedChoice()+" using "+decisionContainer);
if (decisionContainer.getDecision(mod.getConnectedChoice())!=null) {
updateChoice(mod, decText);
}
Choice choice = item.getChoice(mod.getConnectedChoice());
button = new Button((decText.getText().length()==0)?"?":"!");
button.setOnAction(ev -> {
getDecisionHandler().accept(getSelectedItem(), choice);
RPGFrameworkJavaFX.logger.log(Level.WARNING, "Decision dialog closed------------------updating choice");
updateChoice(mod, decText);
});
button.setUserData(choice);
} else if (mod.getResolvedKey()!=null && mod.getResolvedKey() instanceof DataItem) {
DataItem toShow = mod.getResolvedKey();
if (toShow!=null) {
tooltip = new Tooltip(toShow.getDescription());
tooltip.setWrapText(true);
tooltip.setMaxWidth(300);
}
}
} else if (m instanceof ModificationChoice) {
ModificationChoice mod = (ModificationChoice)m;
button = new Button((decText.getText().length()==0)?"?":"!");
button.setOnAction(ev -> {
if (getModDecisionHandler()==null) {
RPGFrameworkJavaFX.logger.log(Level.ERROR, "Missing modDecisionHandler");
} else {
getModDecisionHandler().accept(getSelectedItem(), mod);
RPGFrameworkJavaFX.logger.log(Level.WARNING, "Decision dialog closed------------------");
updateChoice(mod, decText);
}
});
button.setUserData(mod);
}
TextFlow label = new TextFlow(choiceText, decText);
if (button==null) {
contentStats.getChildren().add(label);
} else {
HBox box = new HBox(5, button, label);
box.setAlignment(Pos.CENTER_LEFT);
contentStats.getChildren().add(box);
}
}
}
return contentStats;
}
//-------------------------------------------------------------------
private void updateChoice(DataItemModification mod, Text decText) {
System.err.println("DataItemPane.updateChoice("+mod+") for "+getSelectedItem()+" with "+decisionContainer);
RPGFrameworkJavaFX.updateChoice(
decisionContainer,
(ChoiceOrigin)getSelectedItem(),
getModificationConverter(), mod, decText);
}
//-------------------------------------------------------------------
private void updateChoice(ModificationChoice mod, Text decText) {
Decision dec = decisionContainer.getDecision(mod.getUUID());
if (dec == null) {
decText.setText("");
} else {
List modList = GenericRPGTools.decisionToModifications(mod, dec);
List modListS = modList.stream().map(mb -> getModificationConverter().apply(mb))
.collect(Collectors.toList());
decText.setText(" (" + String.join(", ", modListS) + ")");
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy