package advancedsystemsmanager.flow.menus; import advancedsystemsmanager.api.network.IPacketSync; import advancedsystemsmanager.flow.FlowComponent; import advancedsystemsmanager.flow.elements.*; import advancedsystemsmanager.flow.setting.Setting; import advancedsystemsmanager.client.gui.GuiManager; import advancedsystemsmanager.helpers.CollisionHelper; import advancedsystemsmanager.network.ASMPacket; import advancedsystemsmanager.reference.Names; import advancedsystemsmanager.registry.ThemeHandler; import cpw.mods.fml.relauncher.Side; import cpw.mods.fml.relauncher.SideOnly; import net.minecraft.nbt.NBTTagCompound; import net.minecraft.nbt.NBTTagList; import java.util.ArrayList; import java.util.List; public abstract class MenuStuff<Type> extends Menu implements IPacketSync { public static final int RADIO_BUTTON_X_LEFT = 5; public static final int RADIO_BUTTON_X_RIGHT = 65; public static final int RADIO_BUTTON_Y = 5; public static final int ITEM_SIZE = 16; public static final int ITEM_SIZE_WITH_MARGIN = 20; public static final int ITEM_X = 5; public static final int SETTING_SRC_X = 0; public static final int SETTING_SRC_Y = 189; public static final int EDIT_ITEM_X = 5; public static final int EDIT_ITEM_Y = 5; public static final int BACK_SRC_X = 85; public static final int BACK_SRC_Y = 9; public static final int BACK_SIZE_W = 10; public static final int BACK_SIZE_H = 9; public static final int BACK_X = 108; public static final int BACK_Y = 57; public static final int DELETE_SRC_X = 0; public static final int DELETE_SRC_Y = 130; public static final int DELETE_SIZE_W = 32; public static final int DELETE_SIZE_H = 11; public static final int DELETE_X = 85; public static final int DELETE_Y = 3; public static final int DELETE_TEXT_Y = 3; public static final String NBT_RADIO_SELECTION = "FirstSelected"; public static final String NBT_SETTINGS = "Settings"; public static final String NBT_SETTING_ID = "Id"; public ScrollController<Type> scrollControllerSearch; public ScrollController<Setting<Type>> scrollControllerSelected; public List<Setting<Type>> settings; public List<Setting<Type>> externalSettings; public Setting<Type> selectedSetting; public boolean editSetting; public TextBoxNumberList numberTextBoxes; public RadioButtonList radioButtons; public CheckBoxList checkBoxes; private int id; public MenuStuff(FlowComponent parent) { super(parent); parent.registerSyncable(this); settings = new ArrayList<Setting<Type>>(); externalSettings = new ArrayList<Setting<Type>>(); for (int i = 0; i < getSettingCount(); i++) { Setting<Type> setting = getSetting(i); settings.add(setting); externalSettings.add(setting); } numberTextBoxes = new TextBoxNumberList(); radioButtons = new RadioButtonList(getParent()); initRadioButtons(); checkBoxes = new CheckBoxList(); if (settings.get(0).isAmountSpecific()) { checkBoxes.addCheckBox(new CheckBox(getParent(), Names.SPECIFY_AMOUNT, 5, 25) { @Override public void setValue(boolean val) { selectedSetting.setLimitedByAmount(val); if (!val) selectedSetting.setDefaultAmount(); } @Override public boolean getValue() { return selectedSetting.isLimitedByAmount(); } @Override public boolean readData(ASMPacket packet) { Setting<Type> setting = settings.get(packet.readByte()); setting.setLimitedByAmount(packet.readBoolean()); if (!setting.isLimitedByAmount()) setting.setDefaultAmount(); return false; } @Override public boolean writeData(ASMPacket packet) { packet.writeByte(selectedSetting.getId()); return super.writeData(packet); } }); } scrollControllerSearch = new ScrollController<Type>(getParent(), true) { @Override public List<Type> updateSearch(String search, boolean all) { if (search.equals("")) { return new ArrayList<Type>(); } return MenuStuff.this.updateSearch(search, all); } @Override public void onClick(Type o, int mX, int mY, int button) { selectedSetting.setContent(o); ASMPacket packet = getSyncPacket(); packet.writeByte(1); selectedSetting.writeContentData(packet); packet.sendServerPacket(); selectedSetting = null; updateScrolling(); } @Override public void draw(GuiManager gui, Type o, int x, int y, boolean hover) { drawResultObject(gui, o, x, y); } @Override public void drawMouseOver(GuiManager gui, Type o, int mX, int mY) { if (o != null) { gui.drawMouseOver(getResultObjectMouseOver(o), mX, mY); } } }; scrollControllerSelected = new ScrollController<Setting<Type>>(getParent(), false) { @Override public List<Setting<Type>> updateSearch(String search, boolean all) { return settings; } @Override public void onClick(Setting<Type> setting, int mX, int mY, int button) { selectedSetting = setting; editSetting = button == 1 && doAllowEdit(); if (editSetting && !selectedSetting.isValid()) { selectedSetting = null; editSetting = false; } else { if (editSetting) { updateTextBoxes(); } updateScrolling(); } } @Override public void draw(GuiManager gui, Setting<Type> setting, int x, int y, boolean hover) { if (setting.isValid()) { gui.drawColouredTexture(x, y, MenuContainer.INVENTORY_SRC_X, MenuContainer.INVENTORY_SRC_Y, MenuContainer.INVENTORY_SIZE, MenuContainer.INVENTORY_SIZE, ThemeHandler.theme.menus.checkboxes.getColour(false, hover)); drawSettingObject(gui, setting, x, y); } else { gui.drawColouredTexture(x, y, MenuContainer.INVENTORY_SRC_X - MenuContainer.INVENTORY_SIZE, MenuContainer.INVENTORY_SRC_Y, MenuContainer.INVENTORY_SIZE, MenuContainer.INVENTORY_SIZE, ThemeHandler.theme.menus.checkboxes.getColour(false, hover)); } } @Override public void drawMouseOver(GuiManager gui, Setting<Type> setting, int mX, int mY) { if (setting.isValid()) { gui.drawMouseOver(getSettingObjectMouseOver(setting), mX, mY); } } }; } public int getSettingCount() { return 30; } public abstract Setting<Type> getSetting(int id); public void initRadioButtons() { radioButtons.add(new RadioButton(RADIO_BUTTON_X_LEFT, RADIO_BUTTON_Y, Names.WHITE_LIST)); radioButtons.add(new RadioButton(RADIO_BUTTON_X_RIGHT, RADIO_BUTTON_Y, Names.BLACK_LIST)); } @SideOnly(Side.CLIENT) public abstract List<Type> updateSearch(String search, boolean showAll); protected ASMPacket getSyncPacket() { ASMPacket packet = parent.getSyncPacket(); packet.writeByte(this.id); packet.writeByte(selectedSetting.getId()); return packet; } @SideOnly(Side.CLIENT) public abstract void drawResultObject(GuiManager gui, Type obj, int x, int y); @SideOnly(Side.CLIENT) public abstract List<String> getResultObjectMouseOver(Type obj); public boolean doAllowEdit() { return true; } public abstract void updateTextBoxes(); @SideOnly(Side.CLIENT) public abstract void drawSettingObject(GuiManager gui, Setting<Type> setting, int x, int y); @SideOnly(Side.CLIENT) public abstract List<String> getSettingObjectMouseOver(Setting<Type> setting); @Override public void setId(int id) { this.id = id; } @Override public boolean readData(ASMPacket packet) { Setting<Type> setting = settings.get(packet.readByte()); int action = packet.readByte(); switch (action) { case 0: setting.clear(); selectedSetting = null; break; case 1: setting.readContentData(packet); if (isEditing()) { updateTextBoxes(); } break; default: return readSpecificData(packet, action, setting); } return false; } public boolean isEditing() { return selectedSetting != null && editSetting; } protected abstract boolean readSpecificData(ASMPacket packet, int action, Setting<Type> setting); public void writeRadioButtonRefreshState(ASMPacket dw, boolean value) { dw.writeBoolean(value); } @SideOnly(Side.CLIENT) @Override public void draw(GuiManager gui, int mX, int mY) { if (isEditing()) { checkBoxes.draw(gui, mX, mY); drawSettingObject(gui, selectedSetting, EDIT_ITEM_X, EDIT_ITEM_Y); numberTextBoxes.draw(gui, mX, mY); drawInfoMenuContent(gui, mX, mY); int srcDeleteY = inDeleteBounds(mX, mY) ? 1 : 0; //gui.drawTexture(DELETE_X, DELETE_Y, DELETE_SRC_X, DELETE_SRC_Y + srcDeleteY * DELETE_SIZE_H, DELETE_SIZE_W, DELETE_SIZE_H); gui.drawCenteredString(Names.DELETE, DELETE_X, DELETE_Y + DELETE_TEXT_Y, 0.7F, DELETE_SIZE_W, 0xBB4040); } else { if (!isSearching()) { radioButtons.draw(gui, mX, mY); } if (isListVisible()) { getScrollingList().draw(gui, mX, mY); } } if (selectedSetting != null) { int srcBackX = inBackBounds(mX, mY) ? 1 : 0; gui.drawColouredTexture(BACK_X, BACK_Y, BACK_SRC_X, BACK_SRC_Y, BACK_SIZE_W, BACK_SIZE_H, new int[] {255, 0, 0, 255}); } } @SideOnly(Side.CLIENT) public abstract void drawInfoMenuContent(GuiManager gui, int mX, int mY); public boolean inDeleteBounds(int mX, int mY) { return CollisionHelper.inBounds(DELETE_X, DELETE_Y, DELETE_SIZE_W, DELETE_SIZE_H, mX, mY); } public boolean isSearching() { return selectedSetting != null && !editSetting; } public boolean isListVisible() { return true; } public ScrollController getScrollingList() { return isSearching() ? scrollControllerSearch : scrollControllerSelected; } public boolean inBackBounds(int mX, int mY) { return CollisionHelper.inBounds(BACK_X, BACK_Y, BACK_SIZE_W, BACK_SIZE_H, mX, mY); } @SideOnly(Side.CLIENT) @Override public void drawMouseOver(GuiManager gui, int mX, int mY) { if (isEditing()) { if (CollisionHelper.inBounds(EDIT_ITEM_X, EDIT_ITEM_Y, ITEM_SIZE, ITEM_SIZE, mX, mY)) { scrollControllerSelected.drawMouseOver(gui, selectedSetting, mX, mY); } else if (inDeleteBounds(mX, mY)) { gui.drawMouseOver(Names.DELETE_ITEM_SELECTION, mX, mY); } } else if (isListVisible()) { getScrollingList().drawMouseOver(gui, mX, mY); } if (selectedSetting != null && inBackBounds(mX, mY)) { gui.drawMouseOver(isEditing() ? Names.GO_BACK : Names.CANCEL, mX, mY); } } @Override public void onClick(int mX, int mY, int button) { if (isEditing()) { checkBoxes.onClick(mX, mY); numberTextBoxes.onClick(mX, mY, button); if (inDeleteBounds(mX, mY)) { selectedSetting.delete(); sendClear(); selectedSetting = null; getScrollingList().updateScrolling(); } } else { if (!isSearching()) { radioButtons.onClick(mX, mY, button); } if (isListVisible()) { getScrollingList().onClick(mX, mY, button); } } if (selectedSetting != null && inBackBounds(mX, mY)) { selectedSetting = null; getScrollingList().updateScrolling(); } } protected void sendClear() { ASMPacket packet = getSyncPacket(); packet.writeByte(0); packet.sendServerPacket(); } @Override public void onRelease(int mX, int mY, int button, boolean isMenuOpen) { getScrollingList().onRelease(mX, mY); } @SideOnly(Side.CLIENT) @Override public boolean onKeyStroke(GuiManager gui, char c, int k) { return isSearching() && getScrollingList().onKeyStroke(gui, c, k) || isEditing() && numberTextBoxes.onKeyStroke(gui, c, k); } @Override public void copyFrom(Menu menu) { MenuStuff<Type> menuItem = (MenuStuff<Type>)menu; setFirstRadioButtonSelected(menuItem.isFirstRadioButtonSelected()); for (int i = 0; i < settings.size(); i++) { if (!menuItem.settings.get(i).isValid()) { settings.get(i).clear(); } else { settings.get(i).copyFrom(menuItem.settings.get(i)); if (settings.get(i).isAmountSpecific()) { settings.get(i).setLimitedByAmount(menuItem.settings.get(i).isLimitedByAmount()); settings.get(i).setAmount(menuItem.settings.get(i).getAmount()); } } } } @Override public void readFromNBT(NBTTagCompound nbtTagCompound, boolean pickup) { setFirstRadioButtonSelected(nbtTagCompound.getBoolean(NBT_RADIO_SELECTION)); NBTTagList settingTagList = nbtTagCompound.getTagList(NBT_SETTINGS, 10); for (int i = 0; i < settingTagList.tagCount(); i++) { NBTTagCompound settingTag = settingTagList.getCompoundTagAt(i); Setting setting = settings.get(settingTag.getByte(NBT_SETTING_ID)); setting.load(settingTag); } onSettingContentChange(); } public void onSettingContentChange() { } @Override public void writeToNBT(NBTTagCompound nbtTagCompound, boolean pickup) { nbtTagCompound.setBoolean(NBT_RADIO_SELECTION, isFirstRadioButtonSelected()); NBTTagList settingTagList = new NBTTagList(); for (Setting<Type> setting : settings) { if (setting.isValid()) { NBTTagCompound settingTag = new NBTTagCompound(); settingTag.setByte(NBT_SETTING_ID, (byte)setting.getId()); setting.save(settingTag); settingTagList.appendTag(settingTag); } } nbtTagCompound.setTag(NBT_SETTINGS, settingTagList); } @Override public void addErrors(List<String> errors) { if (useWhiteList()) { for (Setting setting : settings) { if (setting.isValid()) { return; } } errors.add(Names.EMPTY_WHITE_LIST_ERROR); } } @Override public void update(float partial) { if (isSearching()) { scrollControllerSearch.update(partial); } else if (!isEditing()) { scrollControllerSelected.update(partial); } } @Override public void doScroll(int scroll) { if (isSearching()) { scrollControllerSearch.doScroll(scroll); } else if (!isEditing()) { scrollControllerSelected.doScroll(scroll); } } public boolean useWhiteList() { return isFirstRadioButtonSelected(); } public boolean isFirstRadioButtonSelected() { return radioButtons.getSelectedOption() == 0; } public void setFirstRadioButtonSelected(boolean value) { radioButtons.setSelectedOption(value ? 0 : 1); } public List<Setting<Type>> getSettings() { return externalSettings; } public void setBlackList() { setFirstRadioButtonSelected(false); } }