/* Copyright (C) 2011 monte This file is part of PSP NetParty. PSP NetParty 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 3 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, see <http://www.gnu.org/licenses/>. */ package pspnetparty.client.swt; import java.net.MalformedURLException; import java.net.URL; import java.util.ArrayList; import java.util.Set; import org.eclipse.jface.resource.ImageDescriptor; import org.eclipse.swt.SWT; import org.eclipse.swt.SWTException; import org.eclipse.swt.events.DisposeEvent; import org.eclipse.swt.events.DisposeListener; import org.eclipse.swt.events.ShellEvent; import org.eclipse.swt.events.ShellListener; import org.eclipse.swt.graphics.Font; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.ImageData; import org.eclipse.swt.layout.GridData; import org.eclipse.swt.layout.GridLayout; import org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.program.Program; import org.eclipse.swt.widgets.Button; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Event; import org.eclipse.swt.widgets.Label; import org.eclipse.swt.widgets.Link; import org.eclipse.swt.widgets.Listener; import org.eclipse.swt.widgets.Shell; import org.eclipse.swt.widgets.Text; import pspnetparty.client.swt.config.IniAppData; import pspnetparty.lib.LobbyUser; import pspnetparty.lib.Utility; public class UserProfileWindow { private static final int ICON_SIZE = 96; private PlayClient application; private Shell shell; private Composite dataContainer; private Label iconPlaceHolder; private Label userName; private Link url; private Text profileText; private Composite circleContainer; private Label circleLabel; private Label circleLabelSuffix; private ArrayList<Button> circleList = new ArrayList<Button>(); private Button privateMessage; private Button closeWindow; private LobbyUser myself; private LobbyUser currentUser; public UserProfileWindow(PlayClient application, Shell parentShell, LobbyUser myself) { this.application = application; this.myself = myself; shell = new Shell(parentShell, SWT.SHELL_TRIM | SWT.TOOL); shell.setText("ユーザープロフィール"); try { shell.setImages(application.getShellImages()); } catch (RuntimeException e) { e.printStackTrace(); } GridLayout gridLayout; GridData gridData; gridLayout = new GridLayout(1, false); gridLayout.marginHeight = 0; gridLayout.marginWidth = 0; gridLayout.verticalSpacing = 3; shell.setLayout(gridLayout); dataContainer = new Composite(shell, SWT.NONE); dataContainer.setLayoutData(new GridData(SWT.FILL, SWT.TOP, true, false)); gridLayout = new GridLayout(2, false); gridLayout.marginHeight = 1; gridLayout.marginWidth = 1; gridLayout.marginTop = 3; gridLayout.horizontalSpacing = 10; dataContainer.setLayout(gridLayout); iconPlaceHolder = new Label(dataContainer, SWT.BORDER); gridData = new GridData(SWT.LEFT, SWT.TOP, false, false, 1, 3); gridData.heightHint = gridData.widthHint = ICON_SIZE; iconPlaceHolder.setLayoutData(gridData); Font font = new Font(SwtUtils.DISPLAY, SwtUtils.DISPLAY.getSystemFont().getFontData()[0].getName(), 14, SWT.BOLD); userName = new Label(dataContainer, SWT.NONE); userName.setLayoutData(new GridData(SWT.LEFT, SWT.TOP, true, false)); userName.setFont(font); url = new Link(dataContainer, SWT.NONE); gridData = new GridData(SWT.LEFT, SWT.TOP, true, false); gridData.verticalIndent = 2; url.setLayoutData(gridData); circleContainer = new Composite(dataContainer, SWT.NONE); gridData = new GridData(SWT.FILL, SWT.TOP, true, false); gridData.verticalIndent = 4; circleContainer.setLayoutData(gridData); RowLayout rowLayout = new RowLayout(); rowLayout.center = true; rowLayout.marginLeft = 0; circleContainer.setLayout(rowLayout); circleLabel = new Label(circleContainer, SWT.NONE); circleLabelSuffix = new Label(circleContainer, SWT.NONE); Label profileLabel = new Label(shell, SWT.NONE); profileLabel.setText("プロフィール"); gridData = new GridData(SWT.LEFT, SWT.CENTER, false, false); gridData.verticalIndent = 1; gridData.horizontalIndent = 2; profileLabel.setLayoutData(gridData); profileText = new Text(shell, SWT.MULTI | SWT.READ_ONLY | SWT.BORDER | SWT.V_SCROLL | SWT.H_SCROLL); application.initControl(profileText); profileText.setLayoutData(new GridData(SWT.FILL, SWT.FILL, true, true)); Composite controlContainer = new Composite(shell, SWT.NONE); gridData = new GridData(SWT.FILL, SWT.CENTER, true, false); gridData.verticalIndent = 7; controlContainer.setLayoutData(gridData); gridLayout = new GridLayout(2, false); controlContainer.setLayout(gridLayout); url.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { try { new URL(event.text); Program.launch(event.text); } catch (MalformedURLException e) { } } }); privateMessage = new Button(controlContainer, SWT.PUSH); privateMessage.setText("プライベートメッセージを送る"); privateMessage.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { if (currentUser == null) return; UserProfileWindow.this.application.getArenaWindow().openPrivateMessageDialog(currentUser); } }); closeWindow = new Button(controlContainer, SWT.PUSH); closeWindow.setText("閉じる"); gridData = new GridData(SWT.RIGHT, SWT.CENTER, true, false); gridData.widthHint = 80; closeWindow.setLayoutData(gridData); closeWindow.addListener(SWT.Selection, new Listener() { @Override public void handleEvent(Event event) { setVisible(false); } }); shell.addShellListener(new ShellListener() { @Override public void shellClosed(ShellEvent e) { e.doit = false; shell.setVisible(false); } @Override public void shellIconified(ShellEvent e) { } @Override public void shellDeiconified(ShellEvent e) { } @Override public void shellDeactivated(ShellEvent e) { } @Override public void shellActivated(ShellEvent e) { } }); shell.addDisposeListener(new DisposeListener() { @Override public void widgetDisposed(DisposeEvent e) { IniAppData appData = UserProfileWindow.this.application.getAppData(); appData.storeUserProfilegWindow(shell.getBounds()); } }); shell.setMinimumSize(450, 300); application.getAppData().restoreUserProfileWindow(shell); } public void switchProfile(final LobbyUser user) { currentUser = user; privateMessage.setEnabled(user != null && user != myself); Image oldImage = iconPlaceHolder.getBackgroundImage(); iconPlaceHolder.setBackgroundImage(null); if (oldImage != null) oldImage.dispose(); if (user == null || Utility.isEmpty(user.getName())) { userName.setText(""); url.setText(""); profileText.setText(""); updateCircleList(null); return; } userName.setText(user.getName()); if (!Utility.isEmpty(user.getIconUrl())) { application.execute(new Runnable() { @Override public void run() { try { URL url = new URL(user.getIconUrl()); ImageDescriptor desc = ImageDescriptor.createFromURL(url); setImage(desc); } catch (MalformedURLException ex) { } } private void setImage(final ImageDescriptor desc) { Image origImage = null; Image scaledImage = null; try { if (SwtUtils.isNotUIThread()) { SwtUtils.DISPLAY.asyncExec(new Runnable() { public void run() { setImage(desc); } }); return; } origImage = desc.createImage(); ImageData origImageData = origImage.getImageData(); if (origImageData.width == ICON_SIZE && origImageData.height == ICON_SIZE) { scaledImage = origImage; } else { scaledImage = new Image(SwtUtils.DISPLAY, origImageData.scaledTo(ICON_SIZE, ICON_SIZE)); origImage.dispose(); } iconPlaceHolder.setBackgroundImage(scaledImage); return; } catch (SWTException e) { } catch (RuntimeException e) { } if (origImage != null && !origImage.isDisposed()) origImage.dispose(); if (scaledImage != null && !scaledImage.isDisposed()) scaledImage.dispose(); iconPlaceHolder.setBackgroundImage(null); } }); } else { } if (Utility.isEmpty(user.getUrl())) url.setText(""); else url.setText("<a>" + user.getUrl() + "</a>"); if (Utility.isEmpty(user.getProfile())) profileText.setText(""); else profileText.setText(user.getProfile()); updateCircleList(user); dataContainer.layout(); } private Listener circleButtonListener = new Listener() { @Override public void handleEvent(Event event) { Button button = (Button) event.widget; String circle = button.getText(); if (button.getSelection()) { application.getArenaWindow().requestCircleJoin(circle); } else { application.getArenaWindow().requestCircleLeave(circle); } } }; private void updateCircleList(LobbyUser user) { for (Button circle : circleList) { circle.dispose(); } circleList.clear(); if (user == null) { circleLabel.setText(""); circleLabelSuffix.setText(""); } else { circleLabel.setText("所属サークル"); Set<String> myCircles = myself.getCircles(); for (String circle : user.getCircles()) { Button button = new Button(circleContainer, SWT.TOGGLE); button.setText(circle); button.setSelection(myCircles.contains(circle)); button.addListener(SWT.Selection, circleButtonListener); circleList.add(button); } circleLabelSuffix.setText(circleList.isEmpty() ? ": なし" : ""); } shell.layout(true, true); } public void profileRefreshed(LobbyUser user) { if (currentUser != user) return; switchProfile(user); } public void circlesRefreshed(LobbyUser user) { if (currentUser != user) return; updateCircleList(user); } public void userLoggedOut(LobbyUser user) { if (currentUser != user) return; switchProfile(null); } public void reflectApperance() { shell.layout(true, true); } public void setVisible(boolean visible) { shell.setVisible(visible); } }