package net.mcft.copy.backpacks.client.config;
import java.util.List;
import java.util.Objects;
import net.minecraft.client.renderer.GlStateManager;
import net.minecraftforge.common.config.ConfigElement;
import net.minecraftforge.fml.client.config.GuiConfig;
import net.minecraftforge.fml.client.config.GuiConfigEntries;
import net.minecraftforge.fml.client.config.HoverChecker;
import net.minecraftforge.fml.client.config.GuiConfigEntries.ListEntryBase;
import net.minecraftforge.fml.relauncher.Side;
import net.minecraftforge.fml.relauncher.SideOnly;
import net.mcft.copy.backpacks.WearableBackpacks;
import net.mcft.copy.backpacks.client.GuiTextureResource;
import net.mcft.copy.backpacks.config.Setting;
@SideOnly(Side.CLIENT)
public abstract class EntrySetting<T> extends ListEntryBase {
private static final GuiTextureResource CONFIG_ICONS =
new GuiTextureResource("config_icons", 16, 16);
public final Setting<T> setting;
protected T value;
private final HoverChecker _hintHoverChecker;
private List<String> _hintTooltip = null;
@SuppressWarnings("unchecked")
public EntrySetting(GuiConfig owningScreen, GuiConfigEntries owningEntryList, Setting<?> setting) {
super(owningScreen, owningEntryList, new ConfigElement(setting.getProperty().setLanguageKey(
"config." + WearableBackpacks.MOD_ID + "." + setting.getFullName())));
this.setting = (Setting<T>)setting;
this.setting.setEntry(this);
value = this.setting.get();
_hintHoverChecker = new HoverChecker(0, 0, 0, 0, 400);
}
@SuppressWarnings("unchecked")
public static <T> EntrySetting<T> Create(GuiConfig owningScreen, GuiConfigEntries owningEntryList, Setting<T> setting) {
String entryClassName = setting.getConfigEntryClass();
if (entryClassName == null) throw new RuntimeException(
"Setting '" + setting.getFullName() + "' has no entry class defined");
try {
EntrySetting<T> entry = (EntrySetting<T>)Class.forName(entryClassName)
.getConstructor(GuiConfig.class, GuiConfigEntries.class, Setting.class)
.newInstance(owningScreen, owningEntryList, setting);
entry.onValueChanged(); // Ugly hack to call onValueChanged after entry (and
return entry; // associated controls) have been fully constructed.
} catch (Exception ex) { throw new RuntimeException(
"Exception while instanciating setting entry for '" +
setting.getFullName() + "' (entry class '" + entryClassName + "')", ex); }
}
@Override
public void drawEntry(int slotIndex, int x, int y, int listWidth, int slotHeight,
int mouseX, int mouseY, boolean isSelected) {
super.drawEntry(slotIndex, x, y, listWidth, slotHeight, mouseX, mouseY, isSelected);
// Update the tooltip bounds slighty to not include the space left of the label ...
tooltipHoverChecker.updateBounds(y, y + slotHeight,
owningScreen.entryList.labelX - 2,
owningScreen.entryList.controlX - 8);
// ... because we need space for the recommendation hint icon.
_hintHoverChecker.updateBounds(y, y + 16,
owningScreen.entryList.labelX - 20,
owningScreen.entryList.labelX - 4);
_hintTooltip = setting.getRecommendationHint();
if (_hintTooltip != null) {
GlStateManager.color(1, 1, 1);
CONFIG_ICONS.bind();
CONFIG_ICONS.drawQuad(owningScreen.entryList.labelX - 20, y, 0, 0, 16, 16);
}
}
@Override
public void drawToolTip(int mouseX, int mouseY) {
super.drawToolTip(mouseX, mouseY);
if ((_hintTooltip != null) && _hintHoverChecker.checkHover(mouseX, mouseY))
owningScreen.drawToolTip(_hintTooltip, mouseX, mouseY);
}
/** Returns the height used for this list entry. */
public int getSlotHeight() { return 20; }
/** Gets the entry's current internal value. */
public T getValue() { return value; }
/** Sets the entry's current internal value and calls onValueUpdated. */
public void setValue(T value) { this.value = value; onValueChanged(); }
/** Called when the entry's value is changed.
* Overriden by implementing classes to update the control. */
public void onValueChanged() { }
@Override
public boolean enabled() { return super.enabled() && setting.isEnabledConfig(); }
@Override
public boolean isDefault() { return Objects.equals(value, setting.getDefault()); }
@Override
public void setToDefault() { if (!enabled()) return; setValue(setting.getDefault()); }
@Override
public boolean isChanged() { return !Objects.equals(value, setting.get()); }
@Override
public void undoChanges() { if (!enabled()) return; setValue(setting.get()); }
@Override
public boolean saveConfigElement() {
if (!enabled() || !isChanged()) return false;
setting.set(value);
boolean reqRestart = setting.requiresMinecraftRestart();
if (!reqRestart) setting.update();
return reqRestart;
}
@Override
public Object getCurrentValue() { return Objects.toString(value); }
@Override
public Object[] getCurrentValues() { return new Object[] { getCurrentValue() }; }
}