/*******************************************************************************
* Copyright (c) 2004, 2007 Composent, Inc. and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Composent, Inc. - initial API and implementation
******************************************************************************/
package org.eclipse.ecf.internal.example.collab.ui;
import org.eclipse.ecf.internal.example.collab.Messages;
import org.eclipse.ecf.ui.SharedImages;
import org.eclipse.jface.viewers.TableViewer;
import org.eclipse.jface.window.ApplicationWindow;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.events.*;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.widgets.*;
public class ChatWindow extends ApplicationWindow {
private static final long FLASH_INTERVAL = 600;
private final LineChatClientView view;
private final TableViewer table;
private final String initText;
private ChatComposite chat;
private Image image;
private Image blank;
private boolean flashing;
private final Runnable flipImage = new Runnable() {
public void run() {
final Shell shell = getShell();
if (shell != null && !shell.isDisposed())
if (blank == shell.getImage()) {
if (image != null && !image.isDisposed())
shell.setImage(image);
} else {
if (blank != null && !blank.isDisposed())
shell.setImage(blank);
}
}
};
private Flash flash;
public ChatWindow(LineChatClientView view, TableViewer table, String initText) {
super(null);
this.view = view;
this.table = table;
this.initText = initText;
addStatusLine();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.window.Window#configureShell(org.eclipse.swt.widgets.Shell)
*/
protected void configureShell(final Shell newShell) {
super.configureShell(newShell);
newShell.setText(NLS.bind(Messages.ChatWindow_SHELL_TEXT, view.name));
image = SharedImages.getImage(SharedImages.IMG_USER_AVAILABLE);
newShell.setImage(image);
final RGB[] colors = new RGB[2];
colors[0] = new RGB(0, 0, 0);
colors[1] = new RGB(255, 255, 255);
final ImageData data = new ImageData(16, 16, 1, new PaletteData(colors));
data.transparentPixel = 0;
blank = new Image(newShell.getDisplay(), data);
flash = new Flash(newShell.getDisplay());
new Thread(flash).start();
newShell.addDisposeListener(new DisposeListener() {
public void widgetDisposed(DisposeEvent e) {
if (flash != null)
flash.dispose();
if (blank != null)
blank.dispose();
}
});
newShell.addShellListener(new ShellAdapter() {
public void shellActivated(ShellEvent e) {
stopFlashing();
if (!chat.isDisposed())
chat.textinput.setFocus();
}
});
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.window.Window#createContents(org.eclipse.swt.widgets.Composite)
*/
protected Control createContents(Composite parent) {
chat = new ChatComposite(view, parent, table, initText, this);
chat.setLayoutData(new GridData(GridData.FILL_BOTH));
chat.setFont(parent.getFont());
return chat;
}
ChatComposite getChat() {
return chat;
}
boolean hasFocus() {
if (getShell().isDisposed())
return false;
else
return hasFocus(getShell());
}
private boolean hasFocus(Composite composite) {
if (composite.isFocusControl())
return true;
else {
final Control[] children = composite.getChildren();
for (int i = 0; i < children.length; ++i)
if (children[i] instanceof Composite && hasFocus((Composite) children[i]))
return true;
else if (children[i].isFocusControl())
return true;
}
return false;
}
void flash() {
synchronized (flash) {
if (!flashing) {
flashing = true;
flash.notify();
}
}
}
private void stopFlashing() {
synchronized (flash) {
if (flashing) {
flashing = false;
if (!getShell().isDisposed() && image != null && !image.isDisposed())
getShell().setImage(image);
}
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jface.window.Window#handleShellCloseEvent()
*/
protected void handleShellCloseEvent() {
if (!getShell().isDisposed())
getShell().setVisible(false);
}
private class Flash implements Runnable {
private final Display display;
private boolean disposed;
public Flash(Display display) {
this.display = display;
}
public synchronized void dispose() {
if (!disposed) {
disposed = true;
notify();
}
}
public void run() {
while (true) {
synchronized (this) {
try {
while (!flashing && !disposed)
wait();
} catch (final InterruptedException e) {
break;
}
}
if (disposed && display.isDisposed())
break;
display.syncExec(flipImage);
synchronized (this) {
try {
wait(FLASH_INTERVAL);
} catch (final InterruptedException e) {
break;
}
}
}
}
}
}