📄 titlebar.java
字号:
/*******************************************************************************
* Copyright (c) 2005 Stefan Zeiger 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.novocode.com/legal/epl-v10.html
*
* Contributors:
* Stefan Zeiger (szeiger@novocode.com) - initial API and implementation
*******************************************************************************/
package com.novocode.naf.swt.custom.ishell.internal;
import java.util.Timer;
import java.util.TimerTask;
import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.*;
import org.eclipse.swt.widgets.*;
import com.novocode.naf.swt.custom.ishell.DesktopForm;
import com.novocode.naf.swt.custom.ishell.InternalShell;
/**
* A title bar for an InternalShell.
*
* @author Stefan Zeiger (szeiger@novocode.com)
* @since Jan 21, 2005
* @version $Id: TitleBar.java,v 1.5 2005/07/09 20:37:13 szeiger Exp $
*/
public final class TitleBar extends Canvas
{
private static final long UPDATE_DELAY = 25;
private static final int MINIMUM_GRAB_AREA = 2;
private static final String ELLIPSIS = "...";
private static final int LEFT_PADDING = 2;
private static final int RIGHT_PADDING = 2;
private static final int IMAGE_SIZE = 16;
private static final int TOOL_SIZE = 14;
private static final int TOP_PADDING = 1;
private static final int BOTTOM_PADDING = 1;
private int mouseDownOffsetX, mouseDownOffsetY, snapBackX, snapBackY;
private boolean cancelled;
private volatile long lastUpdate;
private Timer timer = new Timer(true);
private TimerTask timerTask;
private final InternalShell ishell;
private final DesktopForm desktop;
private String text;
private Image image;
private final boolean styleClose, styleMax, styleTool, styleMin;
private final Image closeImage, restoreImage, maximizeImage, minimizeImage;
private final MenuItem restoreItem, closeItem, maximizeItem;
private final Menu defaultPopup;
private final Point minGrabSize = new Point(MINIMUM_GRAB_AREA, MINIMUM_GRAB_AREA);
public TitleBar(InternalShell parent, int style)
{
super(parent, checkStyle(style));
this.ishell = parent;
this.desktop = (DesktopForm)ishell.getParent();
this.styleClose = (style & SWT.CLOSE) != 0;
this.styleMax = (style & SWT.MAX) != 0;
this.styleMin = (style & SWT.MIN) != 0;
this.styleTool = (style & SWT.TOOL) != 0;
final Display display = getDisplay();
final Shell shell = getShell();
final Color gradStartColor = display.getSystemColor(SWT.COLOR_TITLE_BACKGROUND);
final Color gradEndColor = display.getSystemColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT);
final Color textColor = display.getSystemColor(SWT.COLOR_TITLE_FOREGROUND);
final Color inactiveGradStartColor = display.getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND);
final Color inactiveGradEndColor = display.getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT);
final Color inactiveTextColor = display.getSystemColor(SWT.COLOR_TITLE_INACTIVE_FOREGROUND);
GC gc = new GC(this);
int imgHeight = gc.getFontMetrics().getHeight()-1;
if(imgHeight%2 == 0) imgHeight--;
gc.dispose();
closeImage = createMenuImage(IMAGE_TYPE_CLOSE, imgHeight);
restoreImage = createMenuImage(IMAGE_TYPE_RESTORE, imgHeight);
maximizeImage = createMenuImage(IMAGE_TYPE_MAXIMIZE, imgHeight);
minimizeImage = createMenuImage(IMAGE_TYPE_MINIMIZE, imgHeight);
setFont(createTitleFont(getFont(), styleTool));
defaultPopup = new Menu(this);
restoreItem = new MenuItem(defaultPopup, SWT.PUSH);
restoreItem.setText(LocalizedStrings.get(LocalizedStrings.POPUP_RESTORE));
restoreItem.setImage(restoreImage);
restoreItem.addListener(SWT.Selection, new Listener()
{
public void handleEvent(Event event)
{
ishell.setMaximized(false);
}
});
MenuItem minimizeItem = new MenuItem(defaultPopup, SWT.PUSH);
minimizeItem.setText(LocalizedStrings.get(LocalizedStrings.POPUP_MINIMIZE));
minimizeItem.setEnabled(styleMin);
minimizeItem.setImage(minimizeImage);
minimizeItem.addListener(SWT.Selection, new Listener()
{
public void handleEvent(Event event)
{
ishell.setMinimized(true);
}
});
maximizeItem = new MenuItem(defaultPopup, SWT.PUSH);
maximizeItem.setText(LocalizedStrings.get(LocalizedStrings.POPUP_MAXIMIZE));
maximizeItem.setImage(maximizeImage);
maximizeItem.addListener(SWT.Selection, new Listener()
{
public void handleEvent(Event event)
{
ishell.setMaximized(true);
}
});
new MenuItem(defaultPopup, SWT.SEPARATOR);
closeItem = new MenuItem(defaultPopup, SWT.PUSH);
closeItem.setText(LocalizedStrings.get(LocalizedStrings.POPUP_CLOSE));
closeItem.setEnabled(styleClose);
closeItem.setImage(closeImage);
closeItem.addListener(SWT.Selection, new Listener()
{
public void handleEvent(Event event)
{
ishell.close();
}
});
addListener(SWT.Paint, new Listener()
{
public void handleEvent(Event event)
{
Rectangle r = getClientArea();
if(r.width == 0 || r.height == 0) return;
boolean active = (shell == display.getActiveShell() && ishell.isActiveShell());
GC gc = event.gc;
gc.setForeground(active ? gradStartColor : inactiveGradStartColor);
gc.setBackground(active ? gradEndColor : inactiveGradEndColor);
gc.fillGradientRectangle(r.x, r.y, r.width, r.height, false);
int textLeftPadding = LEFT_PADDING;
if(image != null)
{
Rectangle imageBounds = image.getBounds();
if(imageBounds.width > IMAGE_SIZE || imageBounds.height > IMAGE_SIZE)
gc.drawImage(image, 0, 0, imageBounds.width, imageBounds.height, LEFT_PADDING, TOP_PADDING, IMAGE_SIZE, IMAGE_SIZE);
else
gc.drawImage(image, LEFT_PADDING + (IMAGE_SIZE-imageBounds.width)/2, (r.height-imageBounds.height)/2);
textLeftPadding += IMAGE_SIZE + LEFT_PADDING;
}
if(text != null && text.length() > 0)
{
gc.setForeground(active ? textColor : inactiveTextColor);
String s = text;
int availableWidth = r.width - textLeftPadding - RIGHT_PADDING;
if(gc.textExtent(s, SWT.DRAW_TRANSPARENT).x > availableWidth)
{
int ellipsisWidth = gc.textExtent(ELLIPSIS, SWT.DRAW_TRANSPARENT).x;
while(s.length() > 0)
{
s = s.substring(0, s.length()-1);
if(gc.textExtent(s, SWT.DRAW_TRANSPARENT).x + ellipsisWidth <= availableWidth)
{
s += ELLIPSIS;
break;
}
}
setToolTipText(text);
}
else setToolTipText(null);
if(s.length() > 0) gc.drawString(s, textLeftPadding, (r.height-gc.getFontMetrics().getHeight())/2, true);
}
else setToolTipText(null);
}
});
addListener(SWT.MouseDown, new Listener()
{
public void handleEvent(Event event)
{
if(event.button == 1)
{
if(image != null && event.x < LEFT_PADDING + IMAGE_SIZE)
{
cancelled = true;
// left-clicking on the image always shows the default popup menu
instrumentDefaultPopup(true);
defaultPopup.setLocation(toDisplay(0, getSize().y));
defaultPopup.setVisible(true);
}
else
{
mouseDownOffsetX = event.x;
mouseDownOffsetY = event.y;
Point p = ishell.getLocation();
snapBackX = p.x;
snapBackY = p.y;
cancelled = false;
}
}
else if(event.button == 3)
{
if((event.stateMask & SWT.BUTTON1) != 0 && snapBackX != Integer.MIN_VALUE && snapBackY != Integer.MIN_VALUE)
{
ishell.setLocation(snapBackX, snapBackY);
snapBackX = Integer.MIN_VALUE;
snapBackY = Integer.MIN_VALUE;
cancelled = true;
}
else
{
}
}
}
});
addListener(SWT.MenuDetect, new Listener()
{
public void handleEvent(Event event)
{
event.doit = false;
Menu m = getMenu();
if(m == null || m.isDisposed())
{
m = defaultPopup;
instrumentDefaultPopup(false);
}
m.setLocation(event.x, event.y);
m.setVisible(true);
}
});
addListener(SWT.MouseDoubleClick, new Listener()
{
public void handleEvent(Event event)
{
if(event.button == 1)
{
if(image != null && event.x < LEFT_PADDING + IMAGE_SIZE)
{
if(styleClose) ishell.close();
}
else
{
if(styleMax) ishell.setMaximized(!ishell.getMaximized());
}
cancelled = true;
}
}
});
addListener(SWT.MouseMove, new Listener()
{
public void handleEvent(final Event event)
{
if(!cancelled && (event.stateMask & SWT.BUTTON1) != 0 && !ishell.getMaximized())
{
if(timerTask != null)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -