📄 borderstyler.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.ui;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jface.resource.JFaceResources;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.MouseAdapter;
import org.eclipse.swt.events.MouseEvent;
import org.eclipse.swt.events.MouseListener;
import org.eclipse.swt.events.MouseMoveListener;
import org.eclipse.swt.events.MouseTrackAdapter;
import org.eclipse.swt.events.PaintEvent;
import org.eclipse.swt.events.PaintListener;
import org.eclipse.swt.graphics.Color;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.Point;
import org.eclipse.swt.graphics.Rectangle;
import org.eclipse.swt.layout.FormAttachment;
import org.eclipse.swt.layout.FormData;
import org.eclipse.swt.layout.FormLayout;
import org.eclipse.swt.layout.GridData;
import org.eclipse.swt.layout.GridLayout;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Control;
import org.eclipse.swt.widgets.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import edu.tsinghua.lumaqq.LumaQQ;
import edu.tsinghua.lumaqq.resource.Colors;
import edu.tsinghua.lumaqq.resource.Resources;
/**
* 用来给一个窗口加上自定义边框
*
* @author luma
*/
public class BorderStyler implements IBorderControlProvider {
private Resources res;
private Display display;
private Composite center;
private MainShell main;
private int downX, downY;
private boolean isMove;
private boolean hideWhenMinimize;
private boolean resizable;
private boolean showMaxButton;
private boolean showMinButton;
private boolean showPlusButton;
private boolean checkMinimizeWhenClose;
private boolean maximizeWhenDoubleClick;
private MouseListener plusMouseListener;
public static final String STYLER = "styler";
private Label top;
private Label left;
private Label right;
private Label bottom;
private Shell shell;
private List<MouseListener> mouseListeners;
private Composite topDown;
private Rectangle oldBound;
private Label lblMax;
private int minWidth, minHeight;
/**
* 构造函数
*
* @param main
*/
public BorderStyler(MainShell main) {
this.main = main;
display = main.getDisplay();
initializeVariables();
}
/**
* 构造函数
*/
public BorderStyler() {
display = Display.getCurrent();
initializeVariables();
}
/**
* 初始化变量
*/
protected void initializeVariables() {
res = Resources.getInstance();
hideWhenMinimize = true;
resizable = true;
showMaxButton = false;
showMinButton = true;
showPlusButton = false;
checkMinimizeWhenClose = false;
maximizeWhenDoubleClick = true;
minWidth = minHeight = 100;
}
public void addMouseListener(MouseListener ml) {
if(mouseListeners == null)
mouseListeners = new ArrayList<MouseListener>();
mouseListeners.add(ml);
}
/**
* 重画标题条
*/
public void repaintTitleBar() {
topDown.redraw();
}
/**
* 设置窗口位置和大小,提供最小尺寸检查
*
* @param bound
*/
private void setShellBound(Rectangle bound) {
bound.width = Math.max(minWidth, bound.width);
bound.height = Math.max(minHeight, bound.height);
shell.setBounds(bound);
}
/**
* 设置窗口大小,提供最小尺寸检查
*
* @param size
*/
private void setShellSize(Point size) {
size.x = Math.max(minWidth, size.x);
size.y = Math.max(minHeight, size.y);
shell.setSize(size);
}
/**
* 装饰一个shell
*
* @param shell
* @return
* 内容区容器
*/
public Composite decorateShell(Shell s) {
shell = s;
shell.setData(STYLER, this);
// 设置layout
GridLayout layout = new GridLayout(3, false);
layout.marginHeight = layout.marginWidth = layout.verticalSpacing = layout.horizontalSpacing = 0;
shell.setLayout(layout);
Composite leftTop = new Composite(shell, SWT.NONE | SWT.NO_BACKGROUND);
if(resizable)
leftTop.setCursor(display.getSystemCursor(SWT.CURSOR_SIZENWSE));
GridData gd = new GridData();
gd.widthHint = gd.heightHint = 5;
leftTop.setLayoutData(gd);
leftTop.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
Rectangle bound = ((Control) e.getSource()).getBounds();
int i = 0;
for(Color c : Colors.MAINSHELL_BORDERS) {
e.gc.setForeground(c);
e.gc.drawLine(i, i, bound.width, i);
e.gc.drawLine(i, i, i, bound.height);
i++;
}
}
});
if(resizable) {
leftTop.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
Control control = (Control)e.getSource();
Point loc = control.toDisplay(e.x, e.y);
downX = loc.x;
downY = loc.y;
}
@Override
public void mouseUp(MouseEvent e) {
Control control = (Control)e.getSource();
Point loc = control.toDisplay(e.x, e.y);
int dx = downX - loc.x;
int dy = downY - loc.y;
if(dx == 0 && dy == 0)
return;
Rectangle bound = shell.getBounds();
bound.x -= dx;
bound.y -= dy;
bound.width += dx;
bound.height += dy;
setShellBound(bound);
}
});
}
top = new Label(shell, SWT.LEFT);
if(resizable)
top.setCursor(display.getSystemCursor(SWT.CURSOR_SIZENS));
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.heightHint = 5;
top.setLayoutData(gd);
top.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
Rectangle bound = ((Control) e.getSource()).getBounds();
int i = 0;
for(Color c : Colors.MAINSHELL_BORDERS) {
e.gc.setForeground(c);
e.gc.drawLine(0, i, bound.width, i);
i++;
}
}
});
if(resizable) {
top.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
Control control = (Control)e.getSource();
downY = control.toDisplay(e.x, e.y).y;
}
@Override
public void mouseUp(MouseEvent e) {
Control control = (Control)e.getSource();
int newY = control.toDisplay(e.x, e.y).y;
int dy = downY - newY;
if(dy == 0)
return;
Rectangle bound = shell.getBounds();
bound.y -= dy;
bound.height += dy;
setShellBound(bound);
}
});
}
Composite rightTop = new Composite(shell, SWT.NONE | SWT.NO_BACKGROUND);
if(resizable)
rightTop.setCursor(display.getSystemCursor(SWT.CURSOR_SIZENESW));
gd = new GridData();
gd.widthHint = gd.heightHint = 5;
rightTop.setLayoutData(gd);
rightTop.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
Rectangle bound = ((Control) e.getSource()).getBounds();
int i = 0;
for(Color c : Colors.MAINSHELL_BORDERS) {
e.gc.setForeground(c);
e.gc.drawLine(bound.width - i - 1, i, 0, i);
e.gc.drawLine(bound.width - i - 1, i, bound.width - i - 1, bound.height);
i++;
}
}
});
if(resizable) {
rightTop.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
Control control = (Control)e.getSource();
Point loc = control.toDisplay(e.x, e.y);
downX = loc.x;
downY = loc.y;
}
@Override
public void mouseUp(MouseEvent e) {
Control control = (Control)e.getSource();
Point loc = control.toDisplay(e.x, e.y);
int dx = loc.x - downX;
int dy = downY - loc.y;
if(dx == 0 && dy == 0)
return;
Rectangle bound = shell.getBounds();
bound.y -= dy;
bound.width += dx;
bound.height += dy;
setShellBound(bound);
}
});
}
left = new Label(shell, SWT.LEFT);
gd = new GridData(GridData.FILL_VERTICAL);
gd.widthHint = 5;
gd.verticalSpan = 2;
left.setLayoutData(gd);
if(resizable)
left.setCursor(display.getSystemCursor(SWT.CURSOR_SIZEWE));
left.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
Rectangle bound = ((Control) e.getSource()).getBounds();
int i = 0;
for(Color c : Colors.MAINSHELL_BORDERS) {
e.gc.setForeground(c);
e.gc.drawLine(i, 0, i, bound.height);
i++;
}
}
});
if(resizable) {
left.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
Control control = (Control)e.getSource();
downX = control.toDisplay(e.x, e.y).x;
}
@Override
public void mouseUp(MouseEvent e) {
Control control = (Control)e.getSource();
int newX = control.toDisplay(e.x, e.y).x;
int dx = downX - newX;
if(dx == 0)
return;
Rectangle bound = shell.getBounds();
bound.x -= dx;
bound.width += dx;
setShellBound(bound);
}
});
}
topDown = new Composite(shell, SWT.LEFT);
gd = new GridData(GridData.FILL_HORIZONTAL);
gd.heightHint = 23;
topDown.setLayoutData(gd);
topDown.addPaintListener(new PaintListener() {
public void paintControl(PaintEvent e) {
Rectangle bound = ((Control)e.getSource()).getBounds();
e.gc.setForeground(Colors.MAINSHELL_TITLE_TOP);
e.gc.setBackground(Colors.MAINSHELL_TITLE_BOTTOM);
e.gc.fillGradientRectangle(0, 0, bound.width, bound.height, true);
e.gc.setForeground(Colors.MAINSHELL_TITLE_SEPARATOR_TOP);
e.gc.drawLine(2, 19, bound.width - 2, 19);
e.gc.setForeground(Colors.MAINSHELL_TITLE_SEPARATOR_BOTTOM);
e.gc.drawLine(2, 20, bound.width - 2, 20);
Image image = shell.getImage();
Rectangle imgBound = (image == null) ? new Rectangle(0, 0, 16, 16) : image.getBounds();
if(image != null) {
e.gc.drawImage(image, 2, (18 - imgBound.height) >> 1);
}
String text = shell.getText();
if(text != null) {
String name = JFaceResources.getDefaultFont().getFontData()[0].getName();
e.gc.setForeground(Colors.WHITE);
e.gc.setFont(JFaceResources.getFontRegistry().getBold(name));
Point extent = e.gc.textExtent(text);
e.gc.drawString(text, imgBound.width + 7, (18 - extent.y) >> 1, true);
}
}
});
topDown.setLayout(new FormLayout());
topDown.addMouseListener(new MouseListener() {
public void mouseDown(MouseEvent e) {
downX = e.x;
downY = e.y;
isMove = true;
fireMouseDownEvent(e);
}
public void mouseUp(MouseEvent e) {
isMove = false;
fireMouseUpEvent(e);
}
public void mouseDoubleClick(MouseEvent e) {
if(maximizeWhenDoubleClick && showMaxButton)
doMaximize();
}
});
topDown.addMouseMoveListener(new MouseMoveListener() {
public void mouseMove(MouseEvent e) {
if (isMove) {
Point loc = shell.getLocation();
int x = loc.x + e.x - downX;
int y = loc.y + e.y - downY;
shell.setLocation(x, y);
}
}
});
// 关闭按钮
Label lblClose = new Label(topDown, SWT.CENTER);
lblClose.setImage(res.getImage(Resources.bmpCloseNormal));
FormData fd = new FormData();
fd.top = new FormAttachment(0, 0);
fd.bottom = new FormAttachment(0, 16);
fd.right = new FormAttachment(100, -2);
fd.left = new FormAttachment(100, -19);
lblClose.setLayoutData(fd);
lblClose.addMouseTrackListener(new MouseTrackAdapter() {
@Override
public void mouseEnter(MouseEvent e) {
Label lbl = (Label)e.getSource();
lbl.setImage(res.getImage(Resources.bmpCloseHover));
}
@Override
public void mouseExit(MouseEvent e) {
Label lbl = (Label)e.getSource();
lbl.setImage(res.getImage(Resources.bmpCloseNormal));
}
});
lblClose.addMouseListener(new MouseAdapter() {
@Override
public void mouseDown(MouseEvent e) {
Label lbl = (Label)e.getSource();
lbl.setImage(res.getImage(Resources.bmpCloseDown));
}
@Override
public void mouseUp(MouseEvent e) {
if(checkMinimizeWhenClose && main != null) {
if(main.getOptionHelper().isMinimizeWhenClose()) {
Label lbl = (Label)e.getSource();
lbl.setImage(res.getImage(Resources.bmpCloseHover));
shell.setMinimized(true);
shell.setVisible(false);
} else
shell.close();
} else
shell.close();
}
});
Label referenceLabel = lblClose;
// 最大化按钮
if(showMaxButton) {
lblMax = new Label(topDown, SWT.CENTER);
lblMax.setImage(res.getImage(Resources.bmpMaxNormal));
fd = new FormData();
fd.top = new FormAttachment(0, 0);
fd.bottom = new FormAttachment(0, 16);
fd.right = new FormAttachment(referenceLabel, 0, SWT.LEFT);
fd.left = new FormAttachment(referenceLabel, -17, SWT.LEFT);
lblMax.setLayoutData(fd);
lblMax.addMouseTrackListener(new MouseTrackAdapter() {
@Override
public void mouseEnter(MouseEvent e) {
Label lbl = (Label)e.getSource();
lbl.setImage(shell.getMaximized() ? res.getImage(Resources.bmpRestoreHover) : res.getImage(Resources.bmpMaxHover));
}
@Override
public void mouseExit(MouseEvent e) {
Label lbl = (Label)e.getSource();
lbl.setImage(shell.getMaximized() ? res.getImage(Resources.bmpRestoreNormal) : res.getImage(Resources.bmpMaxNormal));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -