/******************************************************************************* * Copyright (c) 2006 Chris Gross. 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: schtoo@schtoo.com * (Chris Gross) - initial API and implementation ******************************************************************************/ package org.eclipse.nebula.widgets.pgroup; import org.eclipse.nebula.widgets.pgroup.internal.GraphicUtils; import org.eclipse.nebula.widgets.pgroup.internal.TextUtils; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.GC; import org.eclipse.swt.graphics.Image; import org.eclipse.swt.graphics.Pattern; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.RGB; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.graphics.Region; /** * FormGroupStrategy makes a PGroup mimic the look and feel of an Eclipse Form * Section. * * @since 1.0 * @author chris */ public class FormGroupStrategy extends AbstractGroupStrategy { private Color initialBackColor; private Color initialBorderColor; private int titleTextMargin = 2; private int betweenSpacing = 6; private int margin = 0; private int vMargin = 2; private int hMargin = 6; private Color borderColor; private int titleHeight; private int textWidth; private int fontHeight; private Rectangle toolItemArea; /* * (non-Javadoc) * * @see com.swtplus.widgets.AbstractGroupStrategy#initialize(com.swtplus.widgets.PGroup) */ public void initialize(PGroup sg) { super.initialize(sg); RGB borderRGB = GraphicUtils.blend(getGroup().getDisplay() .getSystemColor(SWT.COLOR_TITLE_INACTIVE_BACKGROUND_GRADIENT).getRGB(), getGroup() .getDisplay().getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB(), 100); initialBorderColor = new Color(getGroup().getDisplay(), borderRGB); borderColor = initialBorderColor; RGB backRGB = GraphicUtils.blend(getGroup().getDisplay() .getSystemColor(SWT.COLOR_TITLE_BACKGROUND_GRADIENT).getRGB(), getGroup().getDisplay() .getSystemColor(SWT.COLOR_LIST_BACKGROUND).getRGB(), 40); initialBackColor = new Color(getGroup().getDisplay(), backRGB); } /** * Creates a FormGroupStrategy with the given toggle and style. * * @param toggle * @param style */ public FormGroupStrategy() { super(); } /* * (non-Javadoc) * * @see com.swtplus.widgets.AbstractGroupStrategy#paintGroup(org.eclipse.swt.graphics.GC) */ public void paint(GC gc) { Color back = getGroup().internalGetBackground(); if (back != null) { gc.fillRectangle(0,0,getGroup().getSize().x,getGroup().getSize().y); Region reg = new Region(); reg.add(0, 0, 5, 1); reg.add(0, 1, 3, 1); reg.add(0, 2, 2, 1); reg.add(0, 3, 1, 1); reg.add(0, 4, 1, 1); reg.add(getGroup().getSize().x - 5, 0, 5, 1); reg.add(getGroup().getSize().x - 3, 1, 3, 1); reg.add(getGroup().getSize().x - 2, 2, 2, 1); reg.add(getGroup().getSize().x - 1, 3, 1, 1); reg.add(getGroup().getSize().x - 1, 4, 1, 1); gc.setClipping(reg); getGroup().drawBackground(gc, 0, 0, getGroup().getSize().x,5); gc.setClipping((Region)null); reg.dispose(); } Point imagePoint = new Point(0, 0); if (getGroup().getToggleRenderer() != null) { Point p = getGroup().getToggleRenderer().getSize(); int toggleY = 0; toggleY = (titleHeight - p.y) / 2; int toggleX = 0; if ((getGroup().getTogglePosition() & SWT.LEAD) != 0) { toggleX = hMargin; } else { toggleX = getGroup().getSize().x - hMargin - p.x; } getGroup().getToggleRenderer().setLocation(new Point(toggleX, toggleY)); } Region reg = new Region(getGroup().getDisplay()); reg.add(0, 0, getGroup().getSize().x, titleHeight); reg.subtract(0, 0, 5, 1); reg.subtract(0, 1, 3, 1); reg.subtract(0, 2, 2, 1); reg.subtract(0, 3, 1, 1); reg.subtract(0, 4, 1, 1); reg.subtract(getGroup().getSize().x - 5, 0, 5, 1); reg.subtract(getGroup().getSize().x - 3, 1, 3, 1); reg.subtract(getGroup().getSize().x - 2, 2, 2, 1); reg.subtract(getGroup().getSize().x - 1, 3, 1, 1); reg.subtract(getGroup().getSize().x - 1, 4, 1, 1); gc.setClipping(reg); back = gc.getBackground(); Color fore = gc.getForeground(); gc.setForeground(initialBackColor); gc.setBackground(getGroup().getParent().getBackground()); Pattern p = new Pattern(getGroup().getDisplay(), 0, 0, 0, titleHeight, initialBackColor, 255, getGroup().getBackground(), 0); gc.setBackgroundPattern(p); gc.fillRectangle(0, 0, getGroup().getSize().x, titleHeight); p.dispose(); gc.setBackgroundPattern(null); if (getGroup().getExpanded() && getGroup().getSize().x > 1) { reg.subtract(1,titleHeight -1,getGroup().getSize().x -2,1); gc.setClipping(reg); } gc.setForeground(borderColor); GraphicUtils.drawRoundRectangle(gc, 0, 0, getGroup().getSize().x - 1, titleHeight, null, true, false); reg.dispose(); gc.setClipping((Region)null); gc.setForeground(getGroup().getParent().getBackground()); // if (getGroup().getExpanded()) // gc.fillRectangle(1, titleHeight - 1, getGroup().getSize().x - 2, 1); gc.setBackground(back); gc.setForeground(fore); Image image = getGroup().getImage(); if (image != null) { imagePoint.x = hMargin; if ((getGroup().getImagePosition() & SWT.LEAD) != 0) { if (getGroup().getToggleRenderer() != null) { if ((getGroup().getTogglePosition() & SWT.LEAD) != 0) { imagePoint.x += getGroup().getToggleRenderer().getSize().x + betweenSpacing; } } } else { if (getGroup().getToggleRenderer() != null) { if ((getGroup().getTogglePosition() & SWT.LEAD) != 0) { imagePoint.x = getGroup().getSize().x - (hMargin + image.getBounds().width); } else { imagePoint.x = getGroup().getSize().x - (hMargin + image.getBounds().width + getGroup().getToggleRenderer().getSize().x + betweenSpacing); } } else { imagePoint.x = getGroup().getSize().x - (hMargin + image.getBounds().width); } } imagePoint.y = ((titleHeight - image.getBounds().height) / 2); gc.drawImage(image, imagePoint.x, imagePoint.y); } Rectangle textBounds = getTextBounds(); String shortened = TextUtils.getShortString(gc, getGroup().getText(), textBounds.width); if( getGroup().getToolItems().length > 0 && getGroup().getToolItemRenderer() != null ) { PGroupToolItem[] items = getGroup().getToolItems(); AbstractToolItemRenderer renderer = getGroup().getToolItemRenderer(); Point size = new Point(0, 0); Point minSize = new Point(0, 0); int spacing = 3; for(int i = 0; i < items.length; i++ ) { PGroupToolItem item = items[i]; Point s0 = renderer.computeSize(gc, item, AbstractToolItemRenderer.DEFAULT); Point s1 = renderer.computeSize(gc, item, AbstractToolItemRenderer.MIN); size.x += s0.x + spacing; minSize.x += s1.x + spacing; } boolean min = false; if( shortened.length() != getGroup().getText().length() ) { textBounds.width -= minSize.x; min = true; } else { if( ! TextUtils.getShortString(gc, getGroup().getText(), textBounds.width - size.x).equals(getGroup().getText()) ) { textBounds.width -= minSize.x; min = true; } else { textBounds.width -= size.x; } } shortened = TextUtils.getShortString(gc, getGroup().getText(), textBounds.width); int x = textBounds.x + textBounds.width; if( min ) { toolItemArea = new Rectangle(x, 2, minSize.x, titleHeight - 4); } else { toolItemArea = new Rectangle(x, 2, size.x, titleHeight - 4); } } gc.drawText(TextUtils.getShortString(gc, getGroup().getText(), textBounds.width), textBounds.x, textBounds.y, true); } public Rectangle getToolItemArea() { return toolItemArea; } /** * {@inheritDoc} */ public boolean isToggleLocation(int x, int y) { if (super.isToggleLocation(x, y)) return true; if (getGroup().getToggleRenderer() == null) return false; Rectangle textBounds = getTextBounds(); textBounds.width = Math.min(textWidth,textBounds.width); if (textBounds.contains(x, y)) return true; return false; } private Rectangle getTextBounds() { Point textPoint = new Point(0, 0); textPoint.x = hMargin; textPoint.y = (titleHeight - fontHeight) / 2; if (getGroup().getImage() != null) { if ((getGroup().getImagePosition() & SWT.LEAD) != 0) { textPoint.x += getGroup().getImage().getBounds().width + betweenSpacing; } } if (getGroup().getToggleRenderer() != null) { if ((getGroup().getTogglePosition() & SWT.LEAD) != 0) { textPoint.x += getGroup().getToggleRenderer().getSize().x + betweenSpacing; } } int textWidth = getGroup().getSize().x - (hMargin * 2); if (getGroup().getImage() != null) { textWidth -= (getGroup().getImage().getBounds().width + betweenSpacing); } if (getGroup().getToggleRenderer() != null) { textWidth -= getGroup().getToggleRenderer().getSize().x + betweenSpacing; } return new Rectangle(textPoint.x, textPoint.y, textWidth, fontHeight); } /** * {@inheritDoc} */ public Rectangle getClientArea() { Rectangle area = getGroup().getBounds(); area.x = margin; area.y = titleHeight; area.width -= (2 * margin); area.height -= titleHeight + margin; return area; } /** * {@inheritDoc} */ public Rectangle computeTrim(int x, int y, int width, int height) { Rectangle area = new Rectangle(x, y, width, height); area.x -= margin; area.y -= titleHeight; area.width += (2 * margin); area.height += titleHeight + margin; return area; } /* * (non-Javadoc) * * @see com.swtplus.widgets.IGroupStrategy#dispose() */ public void dispose() { if (initialBackColor != null) initialBackColor.dispose(); if (initialBorderColor != null) initialBorderColor.dispose(); } /** * @return Returns the borderColor. */ public Color getBorderColor() { return borderColor; } /** * @param borderColor The borderColor to set. */ public void setBorderColor(Color borderColor) { this.borderColor = borderColor; } public void update() { GC gc = new GC(getGroup()); titleHeight = 0; if (getGroup().getImage() != null) titleHeight = getGroup().getImage().getBounds().height + (2 * vMargin); if (getGroup().getToggleRenderer() != null) { int toggleHeight = getGroup().getToggleRenderer().getSize().y; titleHeight = Math.max(toggleHeight + (2 * vMargin), titleHeight); } titleHeight = Math.max(gc.getFontMetrics().getHeight() + (2 * titleTextMargin) + (2 * vMargin), titleHeight); textWidth = gc.stringExtent(getGroup().getText()).x; fontHeight = gc.getFontMetrics().getHeight(); gc.dispose(); } }