/* * This file is part of FTB Launcher. * * Copyright © 2012-2016, FTB Launcher Contributors <https://github.com/Slowpoke101/FTBLaunch/> * FTB Launcher is licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package net.ftb.gui.panes; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Cursor; import java.awt.Dimension; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.ComponentAdapter; import java.awt.event.ComponentEvent; import java.awt.event.MouseAdapter; import java.awt.event.MouseEvent; import java.io.File; import java.util.ArrayList; import java.util.HashMap; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JEditorPane; import javax.swing.JLabel; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JTextArea; import javax.swing.SwingConstants; import javax.swing.SwingUtilities; import javax.swing.UIManager; import com.google.common.collect.Lists; import com.google.common.collect.Maps; import com.google.common.eventbus.Subscribe; import lombok.Getter; import lombok.Setter; import net.ftb.data.LauncherStyle; import net.ftb.data.ModPack; import net.ftb.data.Settings; import net.ftb.events.PackChangeEvent; import net.ftb.gui.LaunchFrame; import net.ftb.gui.dialogs.EditModPackDialog; import net.ftb.gui.dialogs.ModPackFilterDialog; import net.ftb.gui.dialogs.PrivatePackDialog; import net.ftb.locale.I18N; import net.ftb.util.DownloadUtils; import net.ftb.util.ErrorUtils; import net.ftb.util.OSUtils; import net.ftb.util.TrackerUtils; @SuppressWarnings("unchecked") public abstract class AbstractModPackPane extends JPanel { // container for packs. Upgraded by appPack() JPanel packs; // array to store packs. Upgraded by addPack public ArrayList<JPanel> packPanels; JLabel typeLbl; JButton filter, editModPack; JButton server; JButton privatePack; JComboBox version; boolean modPacksAdded = false; HashMap<ModPack, JPanel> panelByPack = Maps.newHashMap(); @Setter @Getter ModPack selectedPack; JEditorPane packInfo; @Getter protected JScrollPane packsScroll; @Getter protected ObjectInfoSplitPane splitPane; public String origin = I18N.getLocaleString("MAIN_ALL"), mcVersion = I18N.getLocaleString("MAIN_ALL"), avaliability = I18N.getLocaleString("MAIN_ALL"), searchString = ""; public boolean loaded = false; public AbstractModPackPane () { super(); setBorder(null); setLayout(new BorderLayout()); // Contains buttons/filter info/selection boxes along top of mod pack panes JPanel buttonsPanel = new JPanel(); buttonsPanel.setLayout(new GridLayout(1, 6)); buttonsPanel.setMinimumSize(new Dimension(420, 25)); add(buttonsPanel, BorderLayout.PAGE_START); packPanels = Lists.newArrayList(); filter = new JButton(I18N.getLocaleString("FILTER_SETTINGS")); filter.setMinimumSize(new Dimension(105, 25)); filter.addActionListener(new ActionListener() { @Override public void actionPerformed (ActionEvent e) { if (loaded) { ModPackFilterDialog filterDia = new ModPackFilterDialog(getThis()); filterDia.setVisible(true); } } }); buttonsPanel.add(filter); String filterTextColor = LauncherStyle.getColorAsString(LauncherStyle.getCurrentStyle().filterTextColor); String filterInnerTextColor = LauncherStyle.getColorAsString(LauncherStyle.getCurrentStyle().filterInnerTextColor); String typeLblText = "<html><body>"; typeLblText += "<strong><font color=rgb\"(" + filterTextColor + ")\">Filter: </strong></font>"; typeLblText += "<font color=rgb\"(" + filterInnerTextColor + ")\">" + avaliability + "</font>"; typeLblText += "<font color=rgb\"(" + filterTextColor + ")\"> / </font>"; typeLblText += "<font color=rgb\"(" + filterInnerTextColor + ")\">" + mcVersion + "</font>"; typeLblText += "</body></html>"; typeLbl = new JLabel(typeLblText); typeLbl.setMinimumSize(new Dimension(175, 25)); typeLbl.setHorizontalAlignment(SwingConstants.CENTER); buttonsPanel.add(typeLbl); editModPack = new JButton(I18N.getLocaleString("MODS_EDIT_PACK")); editModPack.setMinimumSize(new Dimension(110, 25)); editModPack.addActionListener(new ActionListener() { @Override public void actionPerformed (ActionEvent e) { if (packPanels.size() > 0) { // TODO: fix by rename EditModPackDialog empd = new EditModPackDialog(LaunchFrame.getInstance(), selectedPack); empd.setVisible(true); } } }); buttonsPanel.add(editModPack); // stub for a real wait message final JPanel p = new JPanel(); p.setBackground(Color.cyan);; p.setMinimumSize(new Dimension(420, 55)); JTextArea filler = new JTextArea(I18N.getLocaleString("MODS_WAIT_WHILE_LOADING")); filler.setBorder(null); filler.setEditable(false); filler.setForeground(LauncherStyle.getCurrentStyle().tabPaneForeground); filler.setBackground(LauncherStyle.getCurrentStyle().tabPaneBackground); // p.add(loadingImage); p.add(filler); splitPane = new ObjectInfoSplitPane(); packs = splitPane.getPacks(); packInfo = splitPane.getPackInfo(); infoScroll = splitPane.getInfoScroll(); packsScroll = splitPane.getPacksScroll(); add(splitPane, BorderLayout.CENTER); packs.add(p); server = new JButton(I18N.getLocaleString("DOWNLOAD_SERVER")); server.setMinimumSize(new Dimension(130, 25)); // TODO: check server.addActionListener(new ActionListener() { @Override public void actionPerformed (ActionEvent event) { String url; ModPack pack = selectedPack; if ((LaunchFrame.currentPane == LaunchFrame.Panes.MODPACK || LaunchFrame.currentPane == LaunchFrame.Panes.THIRDPARTY) && !pack.getServerUrl().isEmpty()) { if (packPanels.size() > 0) { if (!pack.getServerUrl().equals("") && pack.getServerUrl() != null) { String version = (Settings.getSettings().getPackVer().equalsIgnoreCase("recommended version") || Settings.getSettings().getPackVer().equalsIgnoreCase("newest version")) ? pack.getVersion().replace(".", "_") : Settings.getSettings().getPackVer().replace(".", "_"); if (pack.isPrivatePack()) { url = DownloadUtils.getCreeperhostLink("privatepacks/" + pack.getDir() + "/" + version + "/" + pack.getServerUrl()); } else { url = DownloadUtils.getCreeperhostLink("modpacks/" + pack.getDir() + "/" + version + "/" + pack.getServerUrl()); } OSUtils.browse(url); TrackerUtils.sendPageView(pack.getName() + " Server Download", "Server Download / " + pack.getName() + " / " + version); } } } } }); buttonsPanel.add(server); version = new JComboBox(new String[] {}); version.setMinimumSize(new Dimension(130, 25)); version.addActionListener(al); version.setToolTipText(I18N.getLocaleString("MODPACK_VERSIONS")); buttonsPanel.add(version); privatePack = new JButton(I18N.getLocaleString("PACK_CODES")); privatePack.setMinimumSize(new Dimension(120, 25)); privatePack.addActionListener(new ActionListener() { @Override public void actionPerformed (ActionEvent e) { PrivatePackDialog ap = new PrivatePackDialog(); ap.setVisible(true); } }); buttonsPanel.add(privatePack); // Resize scrollbar when center divider is moved packsScroll.addComponentListener(new ComponentAdapter() { @Override public void componentResized (ComponentEvent e) { int itemsPerWidth = packs.getWidth() / 420; if (itemsPerWidth < 1) { itemsPerWidth = 1; } packs.setMinimumSize(new Dimension(420, (packPanels.size() * (55 + ObjectInfoSplitPane.verticalItemPadding)) / itemsPerWidth)); packs.setPreferredSize(new Dimension(420, (packPanels.size() * (55 + ObjectInfoSplitPane.verticalItemPadding)) / itemsPerWidth)); } }); } JScrollPane infoScroll; final ActionListener al = new ActionListener() { @Override public void actionPerformed (ActionEvent arg0) { if (version.getItemCount() > 0) { Settings.getSettings().setPackVer((String.valueOf(version.getSelectedItem()).equalsIgnoreCase("recommended") ? "Recommended Version" : String.valueOf(version.getSelectedItem()))); Settings.getSettings().save(); } } }; /* * GUI Code to add a modpack to the selection */ public JPanel addPack (final ModPack pack) { if (!modPacksAdded) { modPacksAdded = true; packs.removeAll(); packs.repaint(); } final int packIndex = packPanels.size(); final JPanel p = new JPanel(); p.setPreferredSize(new Dimension(420, 55)); p.setLayout(null); JLabel logo = new JLabel(new ImageIcon(pack.getLogo())); logo.setBounds(6, 6, 42, 42); logo.setVisible(true); JTextArea filler = new JTextArea(pack.getName() + " (v" + pack.getVersion() + ") Minecraft Version " + pack.getMcVersion() + "\n" + "By " + pack.getAuthor()); filler.setBorder(null); filler.setEditable(false); filler.setForeground(LauncherStyle.getCurrentStyle().tabPaneForeground); filler.setBounds(58, 6, 362, 42); filler.setBackground(LauncherStyle.getCurrentStyle().tabPaneBackground); MouseAdapter lin = new MouseAdapter() { @Override public void mouseClicked (MouseEvent e) { if (e.getClickCount() == 2) { LaunchFrame.getInstance().doLaunch(); } } @Override public void mousePressed (MouseEvent e) { ModPack.setSelectedPack(pack); selectedPack = pack; updateInfoScreen(); } }; p.addMouseListener(lin); filler.addMouseListener(lin); logo.addMouseListener(lin); p.add(filler); p.add(logo); packPanels.add(p); packs.add(p); packs.setMinimumSize(new Dimension(420, (packPanels.size() * (55 + ObjectInfoSplitPane.verticalItemPadding)))); packs.setPreferredSize(new Dimension(420, (packPanels.size() * (55 + ObjectInfoSplitPane.verticalItemPadding)))); // packsScroll.revalidate(); if (pack.getDir().equalsIgnoreCase(getLastPack())) { selectedPack = pack; } return p; } // TODO handle changes & removals here as well!!! @Subscribe public void packChange (PackChangeEvent evt) { final PackChangeEvent event = evt; SwingUtilities.invokeLater(new Runnable() { public void run () { if (event.getType() == PackChangeEvent.TYPE.ADD) { filterPacks(); } else if (event.getType() == PackChangeEvent.TYPE.FILTER) { filterPacks(); } else if (event.getType() == PackChangeEvent.TYPE.REMOVE) { filterPacks(); } } }); } public void filterPacks () { // TODO add sorting. How, where? packPanels.clear(); packs.removeAll(); selectedPack = null; packInfo.setText(""); // all removed, repaint packs.repaint(); // not really needed // modPacksAdded = false; for(ModPack pack : ModPack.getPackArray()) { if (filterForTab(pack) && mcVersionCheck(pack) && avaliabilityCheck(pack) && textSearch(pack)) { JPanel p = addPack(pack); panelByPack.put(pack, p); } } updateInfoScreen(); } // WTF: this does not update packs!! // only updating info for selected pack. pulldown menus and info area! public void updateInfoScreen () { // make all colors and cursors normal in left side list for(JPanel p : panelByPack.values()) { p.setBackground(UIManager.getColor("control")); p.setCursor(Cursor.getPredefinedCursor(Cursor.HAND_CURSOR)); } ModPack pack = selectedPack; if (pack != null && panelByPack.get(selectedPack) != null) { String mods = ""; if (pack.getMods() != null) { mods += "<p>This pack contains the following mods by default:</p><ul>"; for(String name : pack.getMods()) { mods += "<li>" + name + "</li>"; } mods += "</ul>"; } panelByPack.get(selectedPack).setBackground(UIManager.getColor("control").darker().darker()); panelByPack.get(selectedPack).setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR)); File tempDir = new File(OSUtils.getCacheStorageLocation(), "ModPacks" + File.separator + pack.getDir()); packInfo.setText("<html><img src='file:///" + tempDir.getPath() + File.separator + pack.getImageName() + "' width=400 height=200></img> <br>" + pack.getInfo() + mods); packInfo.setCaretPosition(0); if (selectedPack.getServerUrl().equals("") || selectedPack.getServerUrl() == null) { server.setEnabled(false); } else { server.setEnabled(true); } String tempVer = Settings.getSettings().getPackVer(pack.getDir()); version.removeActionListener(al); version.removeAllItems(); version.addItem("Recommended"); if (pack.getOldVersions() != null) { for(String s : pack.getOldVersions()) { version.addItem(s); } version.setSelectedItem(tempVer); } version.addActionListener(al); } // } } public void updateFilterText () { String filterTextColor = LauncherStyle.getColorAsString(LauncherStyle.getCurrentStyle().filterTextColor); String filterInnerTextColor = LauncherStyle.getColorAsString(LauncherStyle.getCurrentStyle().filterInnerTextColor); String typeLblText = "<html><body>"; typeLblText += "<strong><font color=rgb\"(" + filterTextColor + ")\">Filter: </strong></font>"; typeLblText += "<font color=rgb\"(" + filterInnerTextColor + ")\">" + avaliability + "</font>"; typeLblText += "<font color=rgb\"(" + filterTextColor + ")\"> / </font>"; typeLblText += "<font color=rgb\"(" + filterInnerTextColor + ")\">" + mcVersion + "</font>"; typeLblText += "</body></html>"; typeLbl.setText(typeLblText); } public void updateFilter () { updateFilterText(); filterPacks(); LaunchFrame.getInstance().updateFooter(); } public void updateLocale () { origin = I18N.getLocaleString("MAIN_ALL"); mcVersion = I18N.getLocaleString("MAIN_ALL"); avaliability = I18N.getLocaleString("MAIN_ALL"); filter.setText(I18N.getLocaleString("FILTER_SETTINGS")); updateFilterText(); editModPack.setText(I18N.getLocaleString("MODS_EDIT_PACK")); if (I18N.currentLocale == I18N.Locale.deDE) { editModPack.setBounds(290, 5, 120, 25); typeLbl.setBounds(115, 5, 165, 25); } else { editModPack.setBounds(300, 5, 110, 25); typeLbl.setBounds(115, 5, 175, 25); } } boolean avaliabilityCheck (ModPack pack) { return (avaliability.equalsIgnoreCase(I18N.getLocaleString("MAIN_ALL"))) || (avaliability.equalsIgnoreCase(I18N.getLocaleString("FILTER_PUBLIC")) && !pack.isPrivatePack()) || (avaliability.equalsIgnoreCase(I18N.getLocaleString("FILTER_PRIVATE")) && pack.isPrivatePack()); } boolean mcVersionCheck (ModPack pack) { return (mcVersion.equalsIgnoreCase(I18N.getLocaleString("MAIN_ALL"))) || (mcVersion.equalsIgnoreCase(pack.getMcVersion())); } boolean textSearch (ModPack pack) { String s = searchString.toLowerCase(); return ((s.isEmpty()) || pack.getName().toLowerCase().contains(s) || pack.getAuthor().toLowerCase().contains(s)); } abstract boolean filterForTab (ModPack pack); abstract String getLastPack (); abstract String getPaneShortName (); abstract boolean isFTB (); abstract AbstractModPackPane getThis (); }