/*
* File : ServerBrowserGUI.java
* Created : 25.02.2006
* By : kahless
*
* GOIM - Gamers Own Instant Messenger
* Copyright (C) 2005-2006 Herbert Poul
* (JabberId: kahless@sphene.net / Email: herbert.poul@gmail.com)
* http://goim.sphene.net
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
package net.sphene.goim.serverbrowser.ui.browser;
import net.sphene.goim.rcp.GOIMPlugin;
import net.sphene.goim.rcp.beans.GOIMAbstractListEvent;
import net.sphene.goim.rcp.beans.GOIMGameItem;
import net.sphene.goim.rcp.beans.GOIMGameList;
import net.sphene.goim.rcp.extensionpoints.game.GameDestination;
import net.sphene.goim.serverbrowser.ServerBrowserPlugin;
import net.sphene.goim.serverbrowser.models.GameServer;
import net.sphene.goim.serverbrowser.models.GameServerListWrapper;
import net.sphene.goim.serverbrowser.models.MasterServer;
import net.sphene.goim.serverbrowser.models.MasterServerList;
import net.sphene.goim.serverbrowser.ui.wizard.addmasterserver.AddMasterServerWizardDialog;
import net.sphene.libs.SpheneEvent;
import net.sphene.libs.SpheneListener;
import org.eclipse.jface.viewers.DoubleClickEvent;
import org.eclipse.jface.viewers.IDoubleClickListener;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.ISelectionProvider;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.LabelProvider;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerSorter;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Listener;
import org.eclipse.swt.widgets.Menu;
import org.eclipse.swt.widgets.MenuItem;
import org.eclipse.swt.widgets.ToolBar;
import org.eclipse.swt.widgets.ToolItem;
import org.eclipse.swt.widgets.TreeColumn;
/**
* The base GUI for the server browser..
*/
public class ServerBrowserGUI {
Composite parent;
public Composite main;
MasterServerList masterServerList;
private TreeViewer viewer;
protected Menu serverContextMenu;
private Menu masterServerContextMenu;
private SpheneListener<SpheneEvent> gameServerListener;
public ServerBrowserGUI(Composite parent) {
this.parent = parent;
init();
}
protected void init() {
masterServerList = ServerBrowserPlugin
.getPreferenceObject(MasterServerList.class);
gameServerListener = new SpheneListener<SpheneEvent>() {
public void handleEvent(final SpheneEvent event) {
if(event.source instanceof GameServer) {
viewer.getTree().getDisplay().asyncExec(new Runnable() {
public void run() {
viewer.update(event.source,new String[] { "server" });
}
});
} else {
viewer.refresh();
}
}
};
for(MasterServer masterServer : masterServerList) {
masterServer.addGameServerListener(gameServerListener);
}
masterServerList.addChangeListener(new SpheneListener<SpheneEvent>() {
public void handleEvent(SpheneEvent event_) {
GOIMAbstractListEvent event = (GOIMAbstractListEvent) event_;
if(event.type == GOIMAbstractListEvent.TYPE_EDIT) {
} else {
if(event.type == GOIMAbstractListEvent.TYPE_ADD) {
((MasterServer)event.source).removeGameServerListener(gameServerListener);
} else if (event.type == GOIMAbstractListEvent.TYPE_DEL) {
((MasterServer)event.source).addGameServerListener(gameServerListener);
}
viewer.refresh();
}
}
});
main = new Composite(parent, SWT.NULL);
GridLayout gridLayout = new GridLayout(1, false);
main.setLayout(gridLayout);
createToolBar();
createServerTree();
}
protected void createToolBar() {
ToolBar bar = new ToolBar(main, SWT.NULL);
bar.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false));
ToolItem addMasterServer = new ToolItem(bar, SWT.PUSH);
addMasterServer.setText("Add Master Server");
ToolItem refreshList = new ToolItem(bar, SWT.PUSH);
refreshList.setText("Refresh");
refreshList.addListener(SWT.Selection,new Listener() {
public void handleEvent(Event event) {
refreshSelection(viewer.getSelection());
}
});
addMasterServer.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
new AddMasterServerWizardDialog(parent.getShell()).open();
}
});
}
/**
* Refreshes the selected item. Currently only MasterServer.
* @param selection
*/
protected void refreshSelection(ISelection selection) {
IStructuredSelection sel = (IStructuredSelection)selection;
Object obj = sel.getFirstElement();
if(obj instanceof MasterServer) {
((MasterServer)obj).getServerList(true);
}
}
protected void createServerTree() {
viewer = new TreeViewer(main, SWT.BORDER | SWT.FLAT);
viewer.getTree().setLayoutData(
new GridData(SWT.FILL, SWT.FILL, true, true));
GameServerBrowserLabelProvider labelProvider = new GameServerBrowserLabelProvider();
viewer.setLabelProvider(labelProvider);
GameServerBrowserContentProvider contentProvider = new GameServerBrowserContentProvider();
viewer.setContentProvider(contentProvider);
GameServerBrowserSorter sorter = new GameServerBrowserSorter();
viewer.setSorter(sorter);
viewer.getTree().setHeaderVisible(true);
TreeColumn name = new TreeColumn(viewer.getTree(), SWT.NULL);
name.setText("Server Name");
name.setWidth(200);
TreeColumn map = new TreeColumn(viewer.getTree(), SWT.NULL);
map.setText("Map");
map.setWidth(50);
TreeColumn ping = new TreeColumn(viewer.getTree(), SWT.NULL);
ping.setText("Ping");
ping.setWidth(70);
TreeColumn players = new TreeColumn(viewer.getTree(), SWT.NULL);
players.setText("Players");
players.setWidth(50);
viewer.getTree().setSortColumn(ping);
viewer.getTree().setSortDirection(SWT.UP);
createServerContextMenu();
createMasterServerContextMenu();
viewer.setInput("");
viewer.addDoubleClickListener(new IDoubleClickListener() {
public void doubleClick(DoubleClickEvent event) {
ISelection selection = event.getSelection();
joinSelectedServer(selection);
}
});
viewer.getTree().addListener(SWT.MouseDown, new Listener() {
public void handleEvent(Event event) {
if(event.button == 3) {
IStructuredSelection selection = (IStructuredSelection)viewer.getSelection();
Object obj = selection.getFirstElement();
if(obj instanceof GameServer) {
serverContextMenu.setVisible(true);
} else {
masterServerContextMenu.setVisible(true);
}
}
}
});
}
/**
* Creates the ServerContextMenu
*/
private void createServerContextMenu() {
serverContextMenu = new Menu(viewer.getTree());
MenuItem joinServer = new MenuItem(serverContextMenu, SWT.PUSH);
joinServer.setText("Join");
joinServer.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
joinSelectedServer(viewer.getSelection());
}
});
}
/**
* Creates the MasterServerContext Menu
*/
private void createMasterServerContextMenu() {
masterServerContextMenu = new Menu(viewer.getTree());
MenuItem removeMasterServer = new MenuItem(masterServerContextMenu, SWT.PUSH);
removeMasterServer.setText("Remove Master Server");
removeMasterServer.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
IStructuredSelection sel = (IStructuredSelection)viewer.getSelection();
Object obj = sel.getFirstElement();
if(!(obj instanceof MasterServer)) return;
masterServerList.remove(obj);
}
});
MenuItem refreshMasterServer = new MenuItem(masterServerContextMenu, SWT.PUSH);
refreshMasterServer.setText("Refresh");
refreshMasterServer.addListener(SWT.Selection, new Listener() {
public void handleEvent(Event event) {
refreshSelection(viewer.getSelection());
}
});
}
public static class GameServerBrowserLabelProvider extends LabelProvider
implements ITableLabelProvider {
public Image getColumnImage(Object element, int columnIndex) {
if (element instanceof GameServer) {
GameServer gameServer = (GameServer) element;
if (columnIndex == 0) {
return gameServer.getGameExtension().getIcon()
.createImage();
}
}
return null;
}
@Override
public boolean isLabelProperty(Object element, String property) {
return true;
}
public String getColumnText(Object element, int columnIndex) {
if (element instanceof MasterServer) {
MasterServer masterServer = (MasterServer) element;
switch (columnIndex) {
case 0:
return ("".equals(masterServer.name) ? masterServer.address
: masterServer.name);
default:
return null;
}
} else if (element instanceof GameServer) {
GameServer server = (GameServer) element;
switch (columnIndex) {
case 0:
return server.name;
case 1:
return server.mapname;
case 2:
return Integer.toString(server.ping);
case 3:
if(server.lastQuery == null) return "";
return server.lastQuery.playerCount + "/" + server.lastQuery.maxPlayerCount;
}
}
return null;
}
}
public class GameServerBrowserContentProvider implements
ITreeContentProvider {
public Object[] getChildren(Object parentElement) {
if (parentElement == null || "".equals(parentElement)) {
return masterServerList.toArray();
} else if (parentElement instanceof MasterServer) {
MasterServer masterServer = (MasterServer) parentElement;
GameServerListWrapper serverList = masterServer.getServerList(false);
serverList.refresh(false);
return serverList.getServerList();
}
return null;
}
public Object getParent(Object element) {
return null;
}
public boolean hasChildren(Object element) {
if (element instanceof MasterServer) {
return true;
}
return false;
}
public Object[] getElements(Object inputElement) {
return getChildren(inputElement);
}
public void dispose() {
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput) {
System.out.println("inputChanged");
}
}
public class GameServerBrowserSorter extends ViewerSorter {
@Override
public int compare(Viewer viewer, Object obj1, Object obj2) {
if (obj1 instanceof GameServer && obj2 instanceof GameServer) {
GameServer g1 = (GameServer) obj1;
GameServer g2 = (GameServer) obj2;
if (g1.ping < 0 && g2.ping < 0) {
return g2.ping - g1.ping;
}
if (g1.ping < 0)
return 1;
if (g2.ping < 0)
return -1;
return g1.ping - g2.ping;
}
return super.compare(viewer, obj1, obj2);
}
@Override
public boolean isSorterProperty(Object element, String property) {
if (element instanceof GameServer) {
return true;
}
return true;
}
}
private void joinServer(GameServer server) {
GOIMGameList gameList = GOIMPlugin
.getPreferenceObject(GOIMGameList.class);
GOIMGameItem game = gameList
.getGameItemForExtensionId(server.gameid);
if (game != null && server.getGameExtension() != null) {
server.getGameExtension().getDelegate().execute(game,
new GameDestination(game, server.address));
}
}
private void joinSelectedServer(ISelection selection) {
IStructuredSelection sel = (IStructuredSelection) selection;
Object obj = sel.getFirstElement();
if (obj != null && obj instanceof GameServer) {
GameServer server = (GameServer) obj;
joinServer(server);
}
}
public ISelectionProvider getSelectionProvider() {
return viewer;
}
}