⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 imageselectshell.java

📁 类似于MSN
💻 JAVA
字号:
/*
* LumaQQ - Java QQ Client
*
* Copyright (C) 2004 luma <stubma@163.com>
*
* 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package edu.tsinghua.lumaqq.shells;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.Properties;

import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.ShellAdapter;
import org.eclipse.swt.events.ShellEvent;
import org.eclipse.swt.events.ShellListener;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.widgets.Canvas;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.ScrollBar;
import org.eclipse.swt.widgets.Shell;

import edu.tsinghua.lumaqq.IconHolder;

/**
 * 显示一些图像,让用户选择的shell,这些图像必须有相同的长宽
 * 
 * @author 马若劼
 */
public class ImageSelectShell extends ShellAdapter {	
	private Shell shell;
	private Display display;
	// 选择的图像代码列表
	private List selectedImageCodes;
	// IconHolder
	private IconHolder icons = IconHolder.getInstance();
	// dimension
	private Point dimension;
	// layout参数
	private int horizontalSpacing, verticalSpacing, marginHeight, marginWidth;
	// 垂直卷滚条
	private ScrollBar vBar;
	// 目前共有的image行数
	private int lines;
	// 容器类,用来实现滚动
	private Canvas canvas;
	// 是否运行在连续输入模式,连续输入模式是指按住ctrl键不放,可以连续点击输入图像
	//     比如在聊天输入框中要输入多个图像时比较有用。缺省为false
	private boolean continuous;
	// 图像的长宽
	private int imageWidth, imageHeight;
	// 保存图像和图像码的数组
	private List codes, images;
	// 当前卷滚条所对应的第一行索引,从0开始
	private int row;
	// 上一次鼠标在哪个图像上,这是绝对索引,-1表示没有
	private int oldIndex;
	// 当前鼠标在哪个图像上
	private int curIndex;
	// 旧图像和新图像的起始坐标
	private int oldImageX, oldImageY, curImageX, curImageY;
	
	/**
	 * 构造函数
	 * @param parent
	 */
	public ImageSelectShell(Shell parent) {
		display = parent.getDisplay();
		shell = new Shell(parent, SWT.NO_TRIM | SWT.V_SCROLL);
		shell.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
		shell.setLayout(new FormLayout());
		shell.addShellListener(this);
		
		// 添加canvas
		marginHeight = marginWidth = 0;
		verticalSpacing = horizontalSpacing = 5;
		canvas = new Canvas(shell, SWT.NONE);
		FormData fd = new FormData();
		fd.left = fd.top = new FormAttachment(0, marginWidth);
		fd.right = fd.bottom = new FormAttachment(100, -marginWidth);
		canvas.setLayoutData(fd);
		canvas.setBackground(display.getSystemColor(SWT.COLOR_WHITE));
		canvas.addPaintListener(
			new PaintListener() {
				public void paintControl(PaintEvent e) {
					// x, y: 绘图起始坐标,image:当前要画的image数组索引
					int x = 0, y = 0, image = row * dimension.x;
					int size = images.size();
					for(int i = 0; i < dimension.y && image < size; i++) {
						for(int j = 0; j < dimension.x && image < size; j++) {
							e.gc.drawImage((Image)images.get(image), x, y);
							image++;
							x += imageWidth + horizontalSpacing;
						}
						y += imageHeight + verticalSpacing;
						x = 0;
					}					
					// 在当前图像上画矩形
					if(curIndex != -1 && curIndex < images.size())
						e.gc.drawRectangle(curImageX, curImageY, imageWidth - 1, imageHeight - 1);								
					// 重设oldIndex
					oldIndex = curIndex;	
				}				
			}
		);
		canvas.addMouseMoveListener(
			new MouseMoveListener() {
				public void mouseMove(MouseEvent e) {
					// 判断现在的鼠标在哪个图像上
					int curXIndex = e.x / (imageWidth + horizontalSpacing);
					int curYIndex = e.y / (imageHeight + verticalSpacing);
					// 得到当前图像的绝对索引
					curIndex = dimension.x * (row + curYIndex) + curXIndex;
					// 如果旧图像不为-1,则重画
					if(oldIndex != -1) {
						oldImageX = (oldIndex % dimension.x) * (imageWidth + horizontalSpacing);
						oldImageY = (oldIndex / dimension.x - row) * (imageHeight + verticalSpacing);
					}					
					// 如何新旧索引相等,直接返回
					if(oldIndex == curIndex) return;
					// 重画新图像
					curImageX = e.x - e.x % (imageWidth + horizontalSpacing);
					curImageY = e.y - e.y % (imageHeight + verticalSpacing);	
					canvas.redraw();
				}				
			}
		);
		canvas.addMouseListener(
			new MouseAdapter() {
				public void mouseUp(MouseEvent e) {
					int xIndex = e.x / (imageWidth + horizontalSpacing);
					int yIndex = e.y / (imageHeight + verticalSpacing);
					// 这下面是判断鼠标是否是在空白地区
					if(e.x - xIndex * (imageWidth + horizontalSpacing) > imageWidth ||
							e.y - yIndex * (imageHeight + verticalSpacing) > imageHeight)
						return;
					// 如果不是,那就是在图像之上了,得到图像索引
					int image = (row + yIndex) * dimension.x + xIndex;
					// 如果图像索引超过了图像总数,也退出
					if(image >= images.size()) return;
					// 条件都符合,则保存图像代码
					selectedImageCodes.add(codes.get(image));
					boolean ctrlDown = (e.stateMask & SWT.CTRL) != 0;
					if(!(continuous && ctrlDown))
						shell.close();
				}
			}
		);
		
		// 初始化变量
		selectedImageCodes = new ArrayList();
		codes = new ArrayList();
		images = new ArrayList();
		continuous = false;
		oldIndex = curIndex = -1;
		dimension = new Point(6, 6);
		lines = 0;
		vBar = shell.getVerticalBar();
		vBar.setMaximum(lines);
		vBar.setMinimum(0);
		vBar.setIncrement(1);
		vBar.addSelectionListener(
			new SelectionAdapter() {
				public void widgetSelected(SelectionEvent e) {
					row = vBar.getSelection();
					curIndex = -1;
					canvas.redraw();
				}
			}
		);
		
		setDimension(6, 6);
	}

	/**
	 * 设置显示几行几列的图标
	 * @param x
	 * @param y
	 */
	public void setDimension(int x, int y) {
		dimension.x = x;
		dimension.y = y;
		setSize();
	}
	
	// 设置shell的size
	private void setSize() {
		Point barSize = vBar.getSize();
		
		shell.setSize(imageWidth * dimension.x + barSize.x + marginWidth * 2 + horizontalSpacing * (dimension.x - 1), imageHeight * dimension.y + marginHeight * 2 + verticalSpacing * (dimension.y - 1));
	}
	
	/**
	 * 添加一个图像
	 * @param image
	 * @param code
	 */
	public void addImage(Image image, int code) {
		codes.add(new Integer(code));
		images.add(image);
	}
	
	/**
	 * 刷新当前显示,使添加的图片都显示出来
	 */
	public void refresh() {
		lines = (images.size() + dimension.x - 1) / dimension.x;
		setSize();
		vBar.setMaximum(lines);
		vBar.setThumb(dimension.y);
	}
	
	/**
	 * 添加所有的头像
	 */
	public void addAllFace() {
		for(int i = 0; i < 253; i += 3) {
			addImage(icons.getFace(i), i);
		}
	}
	
	/**
	 * 添加所有的群头像
	 */
	public void addAllClusterFace() {
		for(int i = 1; i < 7; i++) {
			addImage(icons.getClusterFace(i), i);
		}
	}
	
	/**
	 * 添加所有的表情
	 */
	public void addAllSmiley() {
		Properties p = new Properties();
    	try {
			p.load(this.getClass().getResourceAsStream("/face_r.properties"));
		} catch (IOException e) {
			return;
		}
		for(int i = 0; i <= 95; i++) {
			String _code = p.getProperty(String.valueOf(i));
			if(_code == null)
				continue;
			int code = Integer.parseInt(_code);
			addImage(icons.getSmiley(code), code);
		}
	}
	
	// 打开shell
	public void open()	{
		// 打开shell
		shell.layout();
		shell.open();
	}
	
	/**
	 * 设置窗口位置
	 * @param x
	 * @param y
	 */
	public void setLocation(Point p) {
		shell.setLocation(p);
	}
	
	/**
	 * 返回选择的图像代码
	 * @return 图像代码,这个代码不能改动,由系统处理映射关系
	 */
	public int getSelectedImageCode() {
		if(selectedImageCodes.size() == 0) return -1;
		else return ((Integer)selectedImageCodes.get(0)).intValue();
	}
	
	/**
	 * 返回第index个选择的图像代码
	 * @param index
	 * @return 图像代码,这个代码不能改动,由系统处理映射关系
	 */
	public int getSelectedImageCode(int index) {
		return ((Integer)selectedImageCodes.get(index)).intValue();
	}
	
	/**
	 * @return 用户点击输入的图像个数
	 */
	public int getSelectedSize() {
		if(continuous)
			return selectedImageCodes.size();
		else 
			return 1;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.swt.events.ShellListener#shellDeactivated(org.eclipse.swt.events.ShellEvent)
	 */
	public void shellDeactivated(ShellEvent e) {
		shell.close();
	}
	
	/**
	 * @return true如果窗口已经被disposed
	 */
	public boolean isDisposed() {
		return shell.isDisposed();
	}
	
	/**
	 * 添加shell listener
	 * @param listener
	 */
	public void addShellListener(ShellListener listener) {
		shell.addShellListener(listener);
	}
	
	/**
	 * @param horizontalSpacing The horizontalSpacing to set.
	 */
	public void setHorizontalSpacing(int horizontalSpacing) {
		this.horizontalSpacing = horizontalSpacing;
	}
	
	/**
	 * @param marginHeight The marginHeight to set.
	 */
	public void setMarginHeight(int marginHeight) {
		this.marginHeight = marginHeight;
	}
	
	/**
	 * @param marginWidth The marginWidth to set.
	 */
	public void setMarginWidth(int marginWidth) {
		this.marginWidth = marginWidth;
		FormData fd = (FormData)canvas.getLayoutData();
		fd.left.offset = marginWidth;
	}
	
	/**
	 * @param verticalSpacing The verticalSpacing to set.
	 */
	public void setVerticalSpacing(int verticalSpacing) {
		this.verticalSpacing = verticalSpacing;
	}
	
	/**
	 * @return Returns the continuous.
	 */
	public boolean isContinuous() {
		return continuous;
	}
	
	/**
	 * @param continuous The continuous to set.
	 */
	public void setContinuous(boolean continuous) {
		this.continuous = continuous;
	}
	
	/**
	 * @return Returns the imageHeight.
	 */
	public int getImageHeight() {
		return imageHeight;
	}
	
	/**
	 * @param imageHeight The imageHeight to set.
	 */
	public void setImageHeight(int imageHeight) {
		this.imageHeight = imageHeight;
	}
	
	/**
	 * @return Returns the imageWidth.
	 */
	public int getImageWidth() {
		return imageWidth;
	}
	
	/**
	 * @param imageWidth The imageWidth to set.
	 */
	public void setImageWidth(int imageWidth) {
		this.imageWidth = imageWidth;
	}
	
	/**
	 * 设置要显示的图片的统一显示尺寸
	 * @param x
	 * @param y
	 */
	public void setImageSize(int x, int y) {
		imageWidth = x;
		imageHeight = y;
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -