package com.ss.editor.ui.control.property.impl; import com.jme3.scene.Geometry; import com.ss.editor.Messages; import com.ss.editor.annotation.FromAnyThread; import com.ss.editor.annotation.FxThread; import com.ss.editor.model.undo.editor.ChangeConsumer; import com.ss.editor.ui.control.property.PropertyControl; import com.ss.editor.ui.css.CssClasses; import com.ss.rlib.common.util.ObjectUtils; import com.ss.rlib.fx.util.FxControlUtils; import com.ss.rlib.fx.util.FxUtils; import javafx.scene.control.ComboBox; import javafx.scene.control.ListCell; import javafx.scene.layout.HBox; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; /** * The implementation of the {@link PropertyControl} to edit the LOD levels. * * @author JavaSaBr */ public class LodLevelPropertyControl<C extends ChangeConsumer> extends PropertyControl<C, Geometry, Integer> { private class LodLevelCell extends ListCell<Integer> { @Override protected void updateItem(@Nullable Integer level, boolean empty) { super.updateItem(level, empty); var geometry = getEditObject(); var mesh = geometry.getMesh(); if (level == null || mesh == null) { setText("None"); return; } int elements; if (level < mesh.getNumLodLevels()) { var lodLevel = mesh.getLodLevel(level); elements = lodLevel.getNumElements(); } else { elements = mesh.getTriangleCount(); } setText(Messages.MODEL_PROPERTY_LEVEL + ": " + level + " (" + elements + " " + Messages.MODEL_PROPERTY_TRIANGLE_COUNT + ")"); } } /** * The lod level combobox. */ @Nullable private ComboBox<Integer> levelComboBox; public LodLevelPropertyControl( @Nullable Integer element, @NotNull String paramName, @NotNull C changeConsumer ) { super(element, paramName, changeConsumer); } @Override @FromAnyThread protected boolean isSingleRow() { return true; } @Override @FxThread protected void createComponents(@NotNull HBox container) { super.createComponents(container); levelComboBox = new ComboBox<>(); levelComboBox.setCellFactory(param -> new LodLevelCell()); levelComboBox.setButtonCell(new LodLevelCell()); levelComboBox.setEditable(false); levelComboBox.prefWidthProperty() .bind(widthProperty().multiply(CONTROL_WIDTH_PERCENT)); FxControlUtils.onSelectedItemChange(levelComboBox, this::updateLevel); FxUtils.addClass(levelComboBox, CssClasses.PROPERTY_CONTROL_COMBO_BOX); FxUtils.addChild(container, levelComboBox); } /** * Update lod level. * * @param newValue the new level. */ @FxThread private void updateLevel(@Nullable Integer newValue) { if (isIgnoreListener()) return; changed(ObjectUtils.ifNull(newValue, 0), getPropertyValue()); } @Override @FxThread public @NotNull Integer getPropertyValue() { return ObjectUtils.ifNull(super.getPropertyValue(), 0); } /** * Get the level combo box. * * @return The lod level combo box. */ @FxThread protected @NotNull ComboBox<Integer> getLevelComboBox() { return ObjectUtils.notNull(levelComboBox); } @Override @FxThread protected void reload() { if (!hasEditObject()) { return; } var geometry = getEditObject(); var mesh = geometry.getMesh(); if (mesh == null) { return; } var element = getPropertyValue(); var levelComboBox = getLevelComboBox(); var items = levelComboBox.getItems(); items.clear(); var numLodLevels = mesh.getNumLodLevels(); for (var i = 0; i < numLodLevels; i++) { items.add(i); } if (items.isEmpty()) { items.add(0); } levelComboBox.getSelectionModel() .select(element); } }