Mercurial > projects > dwt-addons
view dwtx/novocode/ishell/internal/TitleBar.d @ 192:c3583c6ec027
Added missing default cases for switch statements
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Mon, 03 Nov 2008 22:52:26 +0100 |
parents | df4e66472aff |
children |
line wrap: on
line source
/******************************************************************************* * 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 *******************************************************************************/ module dwtx.novocode.ishell.internal.TitleBar; import dwt.dwthelper.utils; import dwt.dwthelper.Runnable; import dwtx.dwtxhelper.Timer; import dwtx.dwtxhelper.TimerTask; import dwt.DWT; import dwt.graphics.Color; import dwt.graphics.Font; import dwt.graphics.FontData; import dwt.graphics.GC; import dwt.graphics.Image; import dwt.graphics.ImageData; import dwt.graphics.PaletteData; import dwt.graphics.Point; import dwt.graphics.Rectangle; import dwt.graphics.RGB; import dwt.widgets.Canvas; import dwt.widgets.Display; import dwt.widgets.Event; import dwt.widgets.Listener; import dwt.widgets.Menu; import dwt.widgets.MenuItem; import dwt.widgets.Shell; import dwtx.novocode.ishell.DesktopForm; import dwtx.novocode.ishell.InternalShell; import dwt.dwthelper.utils; /** * A title bar for an InternalShell. * * @author Stefan Zeiger (szeiger@novocode.com) * @since Jan 21, 2005 * @version $Id: TitleBar.java 342 2005-07-09 20:37:13 +0000 (Sat, 09 Jul 2005) szeiger $ */ class TitleBar : Canvas { private static const long UPDATE_DELAY = 25; private static const int MINIMUM_GRAB_AREA = 2; private static const String ELLIPSIS = "..."; private static const int LEFT_PADDING = 2; private static const int RIGHT_PADDING = 2; private static const int IMAGE_SIZE = 16; private static const int TOOL_SIZE = 14; private static const int TOP_PADDING = 1; private static const int BOTTOM_PADDING = 1; private int mouseDownOffsetX, mouseDownOffsetY, snapBackX, snapBackY; private bool cancelled; private /**volatile*/ long lastUpdate; private Timer timer; private TimerTask timerTask; private InternalShell ishell; private DesktopForm desktop; private String text; private Image image; private bool styleClose, styleMax, styleTool, styleMin; private Image closeImage, restoreImage, maximizeImage, minimizeImage; private MenuItem restoreItem, closeItem, maximizeItem; private Menu defaultPopup; private Point minGrabSize; private Shell shell; private Color gradStartColor, gradEndColor, textColor, inactiveGradStartColor, inactiveGradEndColor, inactiveTextColor; private Listener activateListener, deactivateListener; this(InternalShell parent, int style) { super(parent, checkStyle(style)); this.timer = new Timer(true); this.minGrabSize = new Point(MINIMUM_GRAB_AREA, MINIMUM_GRAB_AREA); this.ishell = parent; this.desktop = cast(DesktopForm)ishell.getParent(); this.styleClose = (style & DWT.CLOSE) !is 0; this.styleMax = (style & DWT.MAX) !is 0; this.styleMin = (style & DWT.MIN) !is 0; this.styleTool = (style & DWT.TOOL) !is 0; Display display = getDisplay(); shell = getShell(); gradStartColor = display.getSystemColor(DWT.COLOR_TITLE_BACKGROUND); gradEndColor = display.getSystemColor(DWT.COLOR_TITLE_BACKGROUND_GRADIENT); textColor = display.getSystemColor(DWT.COLOR_TITLE_FOREGROUND); inactiveGradStartColor = display.getSystemColor(DWT.COLOR_TITLE_INACTIVE_BACKGROUND); inactiveGradEndColor = display.getSystemColor(DWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT); inactiveTextColor = display.getSystemColor(DWT.COLOR_TITLE_INACTIVE_FOREGROUND); GC gc = new GC(this); int imgHeight = gc.getFontMetrics().getHeight()-1; if(imgHeight%2 is 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, DWT.PUSH); restoreItem.setText("&Restore"); restoreItem.setImage(restoreImage); restoreItem.addListener(DWT.Selection, dgListener(&restoreListener)); MenuItem minimizeItem = new MenuItem(defaultPopup, DWT.PUSH); minimizeItem.setText("Mi&nimize"); minimizeItem.setEnabled(styleMin); minimizeItem.setImage(minimizeImage); minimizeItem.addListener(DWT.Selection, dgListener(&minimizeListener)); maximizeItem = new MenuItem(defaultPopup, DWT.PUSH); maximizeItem.setText("Ma&ximize"); maximizeItem.setImage(maximizeImage); maximizeItem.addListener(DWT.Selection, dgListener(&maximizeListener)); new MenuItem(defaultPopup, DWT.SEPARATOR); closeItem = new MenuItem(defaultPopup, DWT.PUSH); closeItem.setText("&Close"); closeItem.setEnabled(styleClose); closeItem.setImage(closeImage); closeItem.addListener(DWT.Selection, dgListener(&closeListener)); addListener(DWT.Paint, dgListener(&onPaint)); addListener(DWT.MouseDown, dgListener(&onMouseDown)); addListener(DWT.MenuDetect, dgListener(&onMenuDetect)); addListener(DWT.MouseDoubleClick, dgListener(&onMouseDoubleClick)); addListener(DWT.MouseMove, dgListener(&onMouseMove)); addListener(DWT.MouseUp, dgListener(&onMouseUp)); activateListener = dgListener(&onActivateListener); deactivateListener = dgListener(&onDeactivateListener); shell.addListener(DWT.Activate, activateListener); shell.addListener(DWT.Deactivate, deactivateListener); addListener(DWT.Dispose, dgListener(&onDispose)); } private void restoreListener(Event event) { ishell.setMaximized(false); } private void minimizeListener(Event event) { ishell.setMinimized(true); } private void maximizeListener(Event event) { ishell.setMaximized(true); } private void closeListener(Event event) { ishell.close(); } private void onPaint(Event event) { Rectangle r = getClientArea(); if(r.width is 0 || r.height is 0) return; bool active = (shell is 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 !is 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 !is null && text.length() > 0) { gc.setForeground(active ? textColor : inactiveTextColor); String s = text; int availableWidth = r.width - textLeftPadding - RIGHT_PADDING; if(gc.textExtent(s, DWT.DRAW_TRANSPARENT).x > availableWidth) { int ellipsisWidth = gc.textExtent(ELLIPSIS, DWT.DRAW_TRANSPARENT).x; while(s.length() > 0) { s = s.substring(0, s.length()-1); if(gc.textExtent(s, DWT.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); } private void onMouseDown(Event event) { if(event.button is 1) { if(image !is 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 is 3) { if((event.stateMask & DWT.BUTTON1) !is 0 && snapBackX !is Integer.MIN_VALUE && snapBackY !is Integer.MIN_VALUE) { ishell.setLocation(snapBackX, snapBackY); snapBackX = Integer.MIN_VALUE; snapBackY = Integer.MIN_VALUE; cancelled = true; } else { } } } private void onMenuDetect(Event event) { event.doit = false; Menu m = getMenu(); if(m is null || m.isDisposed()) { m = defaultPopup; instrumentDefaultPopup(false); } m.setLocation(event.x, event.y); m.setVisible(true); } private void onMouseDoubleClick(Event event) { if(event.button is 1) { if(image !is null && event.x < LEFT_PADDING + IMAGE_SIZE) { if(styleClose) ishell.close(); } else { if(styleMax) ishell.setMaximized(!ishell.getMaximized()); } cancelled = true; } } private void onMouseMove(Event event) { if(!cancelled && (event.stateMask & DWT.BUTTON1) !is 0 && !ishell.getMaximized()) { if(timerTask !is null) { timerTask.cancel(); timerTask = null; } long now = System.currentTimeMillis(); if(lastUpdate + UPDATE_DELAY < now) { performMove(event); lastUpdate = now; } else { timerTask = new class() TimerTask { public void run() { TimerTask executingTask = this; event.display.asyncExec(new class() Runnable { public void run() { if(executingTask !is timerTask) return; performMove(event); } }); } }; timer.schedule(timerTask, UPDATE_DELAY); } } } private void onMouseUp(Event event) { if(ishell.getMaximized()) return; if(image is null || event.x >= LEFT_PADDING + IMAGE_SIZE) { if(timerTask !is null) { timerTask.cancel(); timerTask = null; } if(!cancelled && (event.stateMask & DWT.BUTTON1) !is 0) { performMove(event); } } } private void onActivateListener(Event event) { redraw(); } private void onDeactivateListener(Event event) { redraw(); } private void onDispose(Event event) { timer.cancel(); shell.removeListener(DWT.Activate, activateListener); shell.removeListener(DWT.Deactivate, deactivateListener); closeImage.dispose(); maximizeImage.dispose(); restoreImage.dispose(); minimizeImage.dispose(); defaultPopup.dispose(); } private void performMove(Event event) { Point p = ishell.getLocation(); int newX = p.x + event.x - mouseDownOffsetX; int newY = p.y + event.y - mouseDownOffsetY; // Make sure that the minimum grab area stays visible Rectangle deskCA = desktop.getClientArea(); Rectangle bounds = getBounds(); newX = Math.min(Math.max(newX, deskCA.x-bounds.x-bounds.width+MINIMUM_GRAB_AREA), deskCA.x-bounds.x+deskCA.width-minGrabSize.x); newY = Math.min(Math.max(newY, deskCA.y-bounds.y-bounds.height+MINIMUM_GRAB_AREA), deskCA.y-bounds.y+deskCA.height-MINIMUM_GRAB_AREA); if(newX !is p.x || newY !is p.y) ishell.setLocation(newX, newY); } public Point getMinGrabSize() { return minGrabSize; } public Point computeSize(int wHint, int hHint, bool changed) { checkWidget(); if(wHint is DWT.DEFAULT) wHint = 50; if(hHint is DWT.DEFAULT) { GC gc = new GC(this); hHint = gc.getFontMetrics().getHeight(); hHint = Math.max(hHint, styleTool ? TOOL_SIZE : IMAGE_SIZE); hHint += TOP_PADDING + BOTTOM_PADDING; gc.dispose(); } return new Point(wHint, hHint); } private static int checkStyle(int style) { //int mask = DWT.SHADOW_IN | DWT.FLAT; //style &= mask; style = DWT.NO_FOCUS; return style; } public bool setFocus() { checkWidget(); return false; } public bool isReparentable () { checkWidget(); return false; } public void setText(String text) { checkWidget(); this.text = text; redraw(); } public String getText() { return text; } public void setImage(Image image) { checkWidget(); if(styleTool) return; this.image = image; minGrabSize.x = MINIMUM_GRAB_AREA; if(image !is null) minGrabSize.x += LEFT_PADDING + IMAGE_SIZE; redraw(); } public Image getImage() { return image; } private Font createTitleFont(Font f, bool tool) { FontData[] fds = f.getFontData(); foreach(fd; fds) { fd.setStyle(fd.getStyle() | DWT.BOLD); if(tool) fd.setHeight(cast(int)(fd.getHeight()*0.9)); } return new Font(getDisplay(), fds); } private void instrumentDefaultPopup(bool onImage) { restoreItem.setEnabled(styleMax && ishell.getMaximized()); maximizeItem.setEnabled(styleMax && !ishell.getMaximized()); MenuItem def = null; if(onImage) { if(styleClose) def = closeItem; } else if(styleMax) { def = ishell.getMaximized() ? restoreItem : maximizeItem; } defaultPopup.setDefaultItem(def); } private static const int IMAGE_TYPE_CLOSE = 1; private static const int IMAGE_TYPE_MAXIMIZE = 2; private static const int IMAGE_TYPE_RESTORE = 3; private static const int IMAGE_TYPE_MINIMIZE = 4; private Image createMenuImage(int type, int height) { final Point size = new Point(height, height); final int imgWidth = height + height/2; final Color fg = getForeground(); final Color white = getDisplay().getSystemColor(DWT.COLOR_WHITE); final RGB blackRGB = new RGB(0,0,0); ImageData id = new ImageData(imgWidth, size.y, 1, new PaletteData([ blackRGB, fg.getRGB() ])); ImageData maskid = new ImageData(imgWidth, size.y, 1, new PaletteData([ blackRGB, white.getRGB() ])); Image img = new Image(getDisplay(), id); GC gc = new GC(img); gc.setForeground(fg); drawMenuImage(gc, size, type); gc.dispose(); Image maskimg = new Image(getDisplay(), maskid); gc = new GC(maskimg); gc.setForeground(white); drawMenuImage(gc, size, type); gc.dispose(); Image transp = new Image(getDisplay(), img.getImageData(), maskimg.getImageData()); img.dispose(); maskimg.dispose(); return transp; } private void drawMenuImage(GC gc, Point size, int type) { switch(type) { case IMAGE_TYPE_CLOSE: gc.drawLine(1, 1, size.x-2, size.y-2); gc.drawLine(2, 1, size.x-2, size.y-3); gc.drawLine(1, 2, size.x-3, size.y-2); gc.drawLine(1, size.y-2, size.x-2, 1); gc.drawLine(1, size.y-3, size.x-3, 1); gc.drawLine(2, size.y-2, size.x-2, 2); break; case IMAGE_TYPE_RESTORE: gc.drawRectangle(0, 4, size.x-4, size.y-6); gc.drawLine(1, 5, size.x-5, 5); gc.drawLine(2, 1, size.x-2, 1); gc.drawLine(2, 2, size.x-2, 2); gc.drawPoint(2, 3); gc.drawLine(size.x-2, 3, size.x-2, size.y-5); gc.drawPoint(size.x-3, size.y-5); break; case IMAGE_TYPE_MAXIMIZE: gc.drawRectangle(0, 0, size.x-2, size.y-2); gc.drawLine(1, 1, size.x-3, 1); break; case IMAGE_TYPE_MINIMIZE: gc.drawLine(1, size.y-2, size.x-4, size.y-2); gc.drawLine(1, size.y-3, size.x-4, size.y-3); break; default: } } }