Home | History | Annotate | Download | only in setup
      1 /*******************************************************************************
      2  * Copyright 2011 See AUTHORS file.
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *   http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  ******************************************************************************/
     16 
     17 package com.badlogic.gdx.setup;
     18 
     19 import static java.awt.GridBagConstraints.BOTH;
     20 import static java.awt.GridBagConstraints.CENTER;
     21 import static java.awt.GridBagConstraints.HORIZONTAL;
     22 import static java.awt.GridBagConstraints.NONE;
     23 import static java.awt.GridBagConstraints.NORTH;
     24 import static java.awt.GridBagConstraints.SOUTH;
     25 import static java.awt.GridBagConstraints.SOUTHEAST;
     26 
     27 import java.awt.Color;
     28 import java.awt.Desktop;
     29 import java.awt.GridBagConstraints;
     30 import java.awt.GridBagLayout;
     31 import java.awt.Insets;
     32 import java.awt.event.ActionEvent;
     33 import java.awt.event.ActionListener;
     34 import java.awt.event.MouseAdapter;
     35 import java.awt.event.MouseEvent;
     36 import java.io.IOException;
     37 import java.net.URI;
     38 import java.net.URISyntaxException;
     39 import java.util.ArrayList;
     40 import java.util.HashMap;
     41 import java.util.List;
     42 import java.util.Map;
     43 
     44 import javax.swing.BorderFactory;
     45 import javax.swing.JDialog;
     46 import javax.swing.JLabel;
     47 import javax.swing.JPanel;
     48 import javax.swing.JScrollPane;
     49 import javax.swing.JSeparator;
     50 import javax.swing.JTable;
     51 import javax.swing.event.TableModelEvent;
     52 import javax.swing.event.TableModelListener;
     53 import javax.swing.table.DefaultTableModel;
     54 import javax.xml.parsers.DocumentBuilder;
     55 import javax.xml.parsers.DocumentBuilderFactory;
     56 import javax.xml.parsers.ParserConfigurationException;
     57 
     58 import org.w3c.dom.Document;
     59 import org.w3c.dom.Element;
     60 import org.w3c.dom.Node;
     61 import org.w3c.dom.NodeList;
     62 import org.xml.sax.SAXException;
     63 
     64 import com.badlogic.gdx.setup.GdxSetupUI.SetupButton;
     65 
     66 public class ExternalExtensionsDialog extends JDialog implements TableModelListener {
     67 
     68 	private JPanel contentPane;
     69 	private SetupButton buttonOK;
     70 	private SetupButton buttonCancel;
     71 	private JPanel topPanel;
     72 	private ExtensionTableModel tableModel;
     73 	JTable table;
     74 	private JPanel bottomPanel;
     75 	private JPanel buttonPanel;
     76 	private JScrollPane scrollPane;
     77 
     78 	private JLabel warningNotice;
     79 	private JLabel warningNotice2;
     80 
     81 	private List<Dependency> mainDependenciesSnapshot = new ArrayList<Dependency>();
     82 	List<Dependency> mainDependencies;
     83 
     84 	public ExternalExtensionsDialog (List<Dependency> mainDependencies) {
     85 		this.mainDependencies = mainDependencies;
     86 
     87 		contentPane = new JPanel(new GridBagLayout());
     88 		setContentPane(contentPane);
     89 		setModal(true);
     90 		getRootPane().setDefaultButton(buttonOK);
     91 
     92 		uiLayout();
     93 		uiStyle();
     94 
     95 		buttonOK.addActionListener(new ActionListener() {
     96 			public void actionPerformed (ActionEvent e) {
     97 				onOK();
     98 			}
     99 		});
    100 		buttonCancel.addActionListener(new ActionListener() {
    101 			@Override
    102 			public void actionPerformed (ActionEvent e) {
    103 				onCancel();
    104 			}
    105 		});
    106 
    107 		setTitle("Third party external extensions");
    108 		setSize(600, 300);
    109 		setLocationRelativeTo(null);
    110 	}
    111 
    112 	public void showDialog () {
    113 		takeSnapshot();
    114 		setVisible(true);
    115 	}
    116 
    117 	private void uiLayout () {
    118 
    119 		topPanel = new JPanel(new GridBagLayout());
    120 		topPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    121 		warningNotice = new JLabel("List of third party extensions for LibGDX");
    122 		warningNotice2 = new JLabel("These are not maintained by the LibGDX team, please see the support links for info and help");
    123 		warningNotice.setHorizontalAlignment(JLabel.CENTER);
    124 		warningNotice2.setHorizontalAlignment(JLabel.CENTER);
    125 
    126 		topPanel.add(warningNotice, new GridBagConstraints(0, 0, 1, 1, 1, 0, NORTH, HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
    127 		topPanel.add(warningNotice2, new GridBagConstraints(0, 1, 1, 1, 1, 0, NORTH, HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
    128 
    129 		JSeparator separator = new JSeparator();
    130 		separator.setForeground(new Color(85, 85, 85));
    131 		separator.setBackground(new Color(85, 85, 85));
    132 
    133 		topPanel.add(separator, new GridBagConstraints(0, 2, 1, 1, 1, 1, NORTH, HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
    134 
    135 		tableModel = new ExtensionTableModel();
    136 		table = new JTable(tableModel) {
    137 			@Override
    138 			public String getToolTipText (MouseEvent e) {
    139 				return ((ExtensionTableModel)getModel()).getToolTip(e);
    140 			}
    141 		};
    142 		table.getColumnModel().getColumn(0).setPreferredWidth(10);
    143 		table.getColumnModel().getColumn(1).setPreferredWidth(50);
    144 		table.getColumnModel().getColumn(2).setPreferredWidth(100);
    145 		table.getColumnModel().getColumn(3).setPreferredWidth(20);
    146 		table.getColumnModel().getColumn(4).setPreferredWidth(30);
    147 
    148 		table.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
    149 
    150 		table.getTableHeader().setReorderingAllowed(false);
    151 		table.getModel().addTableModelListener(this);
    152 		table.addMouseListener(new MouseAdapter() {
    153 			public void mouseClicked (MouseEvent e) {
    154 				int row = table.getSelectedRow();
    155 				int column = table.getSelectedColumn();
    156 				if (column == 5) {
    157 					URI uri = ((ExtensionTableModel)table.getModel()).getURI(row, column);
    158 					if (uri != null) {
    159 						try {
    160 							Desktop.getDesktop().browse(uri);
    161 						} catch (IOException e1) {
    162 							e1.printStackTrace();
    163 						}
    164 					}
    165 				}
    166 			}
    167 		});
    168 
    169 		scrollPane = new JScrollPane(table);
    170 
    171 		bottomPanel = new JPanel(new GridBagLayout());
    172 
    173 		buttonPanel = new JPanel(new GridBagLayout());
    174 		buttonPanel.setBorder(BorderFactory.createEmptyBorder(5, 5, 5, 5));
    175 		buttonOK = new SetupButton("Save");
    176 		buttonCancel = new SetupButton("Cancel");
    177 		buttonPanel.add(buttonOK, new GridBagConstraints(0, 0, 1, 1, 0, 0, CENTER, HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
    178 		buttonPanel.add(buttonCancel, new GridBagConstraints(1, 0, 1, 1, 0, 0, CENTER, HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
    179 		bottomPanel.add(buttonPanel, new GridBagConstraints(3, 0, 1, 1, 1, 1, SOUTHEAST, NONE, new Insets(0, 0, 0, 0), 0, 0));
    180 
    181 		contentPane.add(topPanel, new GridBagConstraints(0, 0, 1, 1, 1, 0.1, NORTH, BOTH, new Insets(0, 0, 0, 0), 0, 0));
    182 		contentPane.add(scrollPane, new GridBagConstraints(0, 1, 1, 1, 1, 1, NORTH, BOTH, new Insets(0, 0, 0, 0), 0, 0));
    183 		contentPane.add(bottomPanel, new GridBagConstraints(0, 2, 1, 1, 1, 0, SOUTH, HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
    184 
    185 		try {
    186 			initData();
    187 		} catch (Exception e) {
    188 			e.printStackTrace();
    189 		}
    190 
    191 	}
    192 
    193 	private void initData () throws ParserConfigurationException, IOException, SAXException {
    194 		DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
    195 		DocumentBuilder builder = dbFactory.newDocumentBuilder();
    196 		Document doc = builder.parse(ExternalExtensionsDialog.class
    197 			.getResourceAsStream("/com/badlogic/gdx/setup/data/extensions.xml"));
    198 
    199 		doc.getDocumentElement().normalize();
    200 
    201 		NodeList nList = doc.getElementsByTagName("extension");
    202 
    203 		for (int i = 0; i < nList.getLength(); i++) {
    204 			Node nNode = nList.item(i);
    205 			if (nNode.getNodeType() == Node.ELEMENT_NODE) {
    206 
    207 				Element eElement = (Element)nNode;
    208 				String name = eElement.getElementsByTagName("name").item(0).getTextContent();
    209 				String description = eElement.getElementsByTagName("description").item(0).getTextContent();
    210 				String version = eElement.getElementsByTagName("version").item(0).getTextContent();
    211 				String compatibility = eElement.getElementsByTagName("compatibility").item(0).getTextContent();
    212 				String url = eElement.getElementsByTagName("website").item(0).getTextContent();
    213 
    214 				String[] gwtInherits = null;
    215 				NodeList inheritsNode = eElement.getElementsByTagName("inherit");
    216 				gwtInherits = new String[inheritsNode.getLength()];
    217 
    218 				for (int j = 0; j < inheritsNode.getLength(); j++)
    219 					gwtInherits[j] = inheritsNode.item(j).getTextContent();
    220 
    221 				final HashMap<String, List<ExternalExtensionDependency>> dependencies = new HashMap<String, List<ExternalExtensionDependency>>();
    222 
    223 				addToDependencyMapFromXML(dependencies, eElement, "core");
    224 				addToDependencyMapFromXML(dependencies, eElement, "desktop");
    225 				addToDependencyMapFromXML(dependencies, eElement, "android");
    226 				addToDependencyMapFromXML(dependencies, eElement, "ios");
    227 				addToDependencyMapFromXML(dependencies, eElement, "html");
    228 
    229 				URI uri = null;
    230 				try {
    231 					uri = new URI(url);
    232 				} catch (URISyntaxException e) {
    233 					e.printStackTrace();
    234 				}
    235 
    236 				if (uri != null) {
    237 					final ExternalExtension extension = new ExternalExtension(name, gwtInherits, description, version);
    238 					extension.setDependencies(dependencies);
    239 					tableModel.addExtension(extension, false, name, description, version, compatibility, uri);
    240 				}
    241 			}
    242 		}
    243 	}
    244 
    245 	private void uiStyle () {
    246 		contentPane.setBackground(new Color(36, 36, 36));
    247 
    248 		topPanel.setBackground(new Color(36, 36, 36));
    249 		topPanel.setForeground(new Color(255, 255, 255));
    250 		table.setBackground(new Color(46, 46, 46));
    251 		table.setForeground(new Color(255, 255, 255));
    252 		bottomPanel.setBackground(new Color(36, 36, 36));
    253 		bottomPanel.setForeground(new Color(255, 255, 255));
    254 		buttonPanel.setBackground(new Color(36, 36, 36));
    255 		buttonPanel.setForeground(new Color(255, 255, 255));
    256 
    257 		scrollPane.setBorder(BorderFactory.createEmptyBorder());
    258 		scrollPane.setBackground(new Color(36, 36, 36));
    259 		scrollPane.getViewport().setBackground(new Color(36, 36, 36));
    260 
    261 		warningNotice.setForeground(new Color(255, 20, 20));
    262 		warningNotice2.setForeground(new Color(255, 20, 20));
    263 	}
    264 
    265 	void onOK () {
    266 		setVisible(false);
    267 	}
    268 
    269 	void onCancel () {
    270 		setVisible(false);
    271 		restore();
    272 	}
    273 
    274 	private void takeSnapshot () {
    275 		mainDependenciesSnapshot.clear();
    276 		for (int i = 0; i < mainDependencies.size(); i++) {
    277 			mainDependenciesSnapshot.add(mainDependencies.get(i));
    278 		}
    279 	}
    280 
    281 	private void restore () {
    282 		mainDependencies.clear();
    283 		((ExtensionTableModel)table.getModel()).unselectAll();
    284 		for (int i = 0; i < mainDependenciesSnapshot.size(); i++) {
    285 			mainDependencies.add(mainDependenciesSnapshot.get(i));
    286 			String extensionName = mainDependenciesSnapshot.get(i).getName();
    287 			if (((ExtensionTableModel)table.getModel()).hasExtension(extensionName)) {
    288 				((ExtensionTableModel)table.getModel()).setSelected(extensionName, true);
    289 			} else {
    290 			}
    291 		}
    292 	}
    293 
    294 	private void addToDependencyMapFromXML (Map<String, List<ExternalExtensionDependency>> dependencies, Element eElement, String platform) {
    295 		if (eElement.getElementsByTagName(platform).item(0) != null) {
    296 			Element project = (Element)eElement.getElementsByTagName(platform).item(0);
    297 
    298 			ArrayList<ExternalExtensionDependency> deps = new ArrayList<ExternalExtensionDependency>();
    299 
    300 			if (project.getTextContent().trim().equals("")) {
    301 				// No dependencies required
    302 			} else if (project.getTextContent().trim().equals("null")) {
    303 				// Not supported
    304 				deps = null;
    305 			} else {
    306 				NodeList nList = project.getElementsByTagName("dependency");
    307 
    308 				for (int i = 0; i < nList.getLength(); i++) {
    309 					Node nNode = nList.item(i);
    310 					if (nNode.getNodeType() == Node.ELEMENT_NODE) {
    311 						Element dependencyNode = (Element)nNode;
    312 						boolean external = Boolean.parseBoolean(dependencyNode.getAttribute("external"));
    313 						deps.add(new ExternalExtensionDependency(dependencyNode.getTextContent(), external));
    314 					}
    315 
    316 				}
    317 			}
    318 
    319 			dependencies.put(platform, deps);
    320 		}
    321 	}
    322 
    323 	class ExtensionTableModel extends DefaultTableModel {
    324 
    325 		private HashMap<Integer, ExternalExtension> extensions = new HashMap<Integer, ExternalExtension>();
    326 		private int rowCount = 0;
    327 
    328 		public ExtensionTableModel () {
    329 			addColumn("Use");
    330 			addColumn("Extension");
    331 			addColumn("Description");
    332 			addColumn("Version");
    333 			addColumn("Compatibility");
    334 			addColumn("Support");
    335 		}
    336 
    337 		public ExternalExtension getExtension (int row) {
    338 			return extensions.get(row);
    339 		}
    340 
    341 		public URI getURI (int row, int column) {
    342 			if (column != 5) return null;
    343 			return (URI)getValueAt(row, column);
    344 		}
    345 
    346 		@Override
    347 		public Class getColumnClass (int column) {
    348 			if (column == 0) return Boolean.class;
    349 			if (column == 5) return URI.class;
    350 			return super.getColumnClass(column);
    351 		}
    352 
    353 		@Override
    354 		public boolean isCellEditable (int x, int y) {
    355 			return y == 0;
    356 		}
    357 
    358 		public String getToolTip (MouseEvent e) {
    359 			int row = table.rowAtPoint(e.getPoint());
    360 			int column = table.columnAtPoint(e.getPoint());
    361 
    362 			if (column == 5) {
    363 				return "Click me!";
    364 			} else if (column != 0) {
    365 				return getValueAt(row, column).toString();
    366 			} else {
    367 				return "Select if you want to use this extension!";
    368 			}
    369 		}
    370 
    371 		public void unselectAll () {
    372 			for (int row : extensions.keySet()) {
    373 				table.setValueAt(false, row, 0);
    374 			}
    375 		}
    376 
    377 		public boolean hasExtension (String extensionName) {
    378 			for (ExternalExtension extension : extensions.values()) {
    379 				if (extension.getName().equals(extensionName)) return true;
    380 			}
    381 			return false;
    382 		}
    383 
    384 		public void setSelected (String extensionName, boolean selected) {
    385 			int row = -1;
    386 			for (int i : extensions.keySet()) {
    387 				if (extensions.get(i).getName().equals(extensionName)) {
    388 					row = i;
    389 					break;
    390 				}
    391 			}
    392 			if (row != -1) table.setValueAt(selected, row, 0);
    393 		}
    394 
    395 		public void addExtension (ExternalExtension extension, Boolean checkbox, String name, String description, String version,
    396 			String compatibility, URI support) {
    397 			addRow(new Object[] {checkbox, name, description, version, compatibility, support});
    398 			extensions.put(rowCount++, extension);
    399 		}
    400 
    401 	}
    402 
    403 	@Override
    404 	public void tableChanged (TableModelEvent e) {
    405 		int row = e.getFirstRow();
    406 		int column = e.getColumn();
    407 
    408 		if (column == 0) {
    409 			ExternalExtension extension = ((ExtensionTableModel)table.getModel()).getExtension(row);
    410 			Dependency dep = extension.generateDependency();
    411 			boolean selected = (Boolean)table.getModel().getValueAt(row, 0);
    412 			if (selected) {
    413 				if (!mainDependencies.contains(dep)) {
    414 					mainDependencies.add(dep);
    415 				}
    416 			} else {
    417 				mainDependencies.remove(dep);
    418 			}
    419 		}
    420 	}
    421 
    422 }
    423