/* ****************************************************************************** * Copyright (c) 2006-2012 XMind Ltd. and others. * * This file is a part of XMind 3. XMind releases 3 and * above are dual-licensed under the Eclipse Public License (EPL), * which is available at http://www.eclipse.org/legal/epl-v10.html * and the GNU Lesser General Public License (LGPL), * which is available at http://www.gnu.org/licenses/lgpl.html * See http://www.xmind.net/license.html for details. * * Contributors: * XMind Ltd. - initial API and implementation *******************************************************************************/ package org.xmind.ui.gallery; import org.eclipse.draw2d.AbstractBorder; import org.eclipse.draw2d.ColorConstants; import org.eclipse.draw2d.Figure; import org.eclipse.draw2d.Graphics; import org.eclipse.draw2d.IFigure; import org.eclipse.draw2d.Layer; import org.eclipse.draw2d.LayoutManager; import org.eclipse.draw2d.PositionConstants; import org.eclipse.draw2d.geometry.Insets; import org.eclipse.draw2d.geometry.Rectangle; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.Pattern; import org.eclipse.swt.widgets.Display; import org.xmind.gef.draw2d.AdvancedToolbarLayout; import org.xmind.gef.draw2d.ITextFigure; import org.xmind.gef.draw2d.RotatableWrapLabel; import org.xmind.gef.draw2d.graphics.GradientPattern; import org.xmind.gef.draw2d.graphics.GraphicsUtils; import org.xmind.gef.draw2d.graphics.Path; import org.xmind.ui.resources.ColorUtils; /** * @author Frank Shaka */ public class FrameFigure extends Figure { private static final int FLAG_SELECTED = MAX_FLAG << 1; private static final int FLAG_PRESELECTED = MAX_FLAG << 2; private static final int FLAG_HIDE_TITLE = MAX_FLAG << 3; private static final int FLAG_FLAT = MAX_FLAG << 4; static { MAX_FLAG = FLAG_FLAT; } protected static final Color ColorSelected = ColorUtils.getColor("#0070d8"); //$NON-NLS-1$ protected static final Color ColorSelectedPreselected = ColorUtils .getColor("#2088e0"); //$NON-NLS-1$ protected static final Color ColorInactive = ColorUtils.gray(ColorSelected); private class FocusBorder extends AbstractBorder { private Insets insets = new Insets(6); public void paint(IFigure figure, Graphics graphics, Insets insets) { boolean selected = isSelected(); boolean preselected = isPreselected(); if (!preselected && !selected) return; boolean selectedPreselected = preselected && selected; boolean lighter = preselected && !selected; graphics.setAntialias(SWT.ON); graphics.setLineWidth(1); graphics.setLineStyle(SWT.LINE_SOLID); tempRect.setBounds(getPaintRectangle(figure, insets)); tempRect.shrink(1, 1); graphics .setForegroundColor(selectedPreselected ? ColorSelectedPreselected : ColorSelected); graphics.setAlpha(lighter ? 0x80 : 0xf0); Path p = new Path(Display.getCurrent()); p.addRoundedRectangle(tempRect.x, tempRect.y, tempRect.width, tempRect.height, 3); graphics.drawPath(p); p.dispose(); } public Insets getInsets(IFigure figure) { return insets; } } private RotatableWrapLabel title; private IFigure titleContainer; private ShadowedLayer contentLayer; private int titlePlacement = PositionConstants.TOP; /** * */ public FrameFigure() { setBorder(new FocusBorder()); FrameBorderLayout layout = new FrameBorderLayout(); layout.setVerticalSpacing(2); layout.setHorizontalSpacing(2); super.setLayoutManager(layout); titleContainer = new Layer(); AdvancedToolbarLayout titleContainerLayout = new AdvancedToolbarLayout(); titleContainerLayout.setStretchMinorAxis(true); titleContainer.setLayoutManager(titleContainerLayout); add(titleContainer, FrameBorderLayout.TOP); title = new RotatableWrapLabel(RotatableWrapLabel.NORMAL) { protected void paintFigure(Graphics graphics) { if (isSelected()) { graphics.setForegroundColor(ColorConstants.white); } super.paintFigure(graphics); } }; title.setTextAlignment(PositionConstants.CENTER); title.setAbbreviated(true); titleContainer.add(title, FrameBorderLayout.TOP); contentLayer = new ShadowedLayer(); contentLayer.setBorderColor(ColorConstants.gray); add(contentLayer, FrameBorderLayout.CENTER); } public void setLayoutManager(LayoutManager manager) { // Prevent external layout manager to be set. } public void paint(Graphics graphics) { GraphicsUtils.fixGradientBugForCarbon(graphics, this); super.paint(graphics); } @Override protected void paintFigure(Graphics graphics) { boolean preselected = isPreselected(); boolean selected = isSelected(); if (preselected && selected) { paintBackground(graphics, ColorSelectedPreselected, 0xf0); } else if (preselected) { paintBackground(graphics, ColorSelected, 0x80); } else if (selected) { paintBackground(graphics, ColorSelected, 0xf0); } super.paintFigure(graphics); } private void paintBackground(Graphics graphics, Color color, int alpha) { Rectangle b = new Rectangle(getBounds()).shrink(1, 1); graphics.setAntialias(SWT.ON); graphics.setAlpha(alpha); graphics.pushState(); try { switch (getTitlePlacement()) { case PositionConstants.LEFT: paintHorizontalBackground(graphics, 0, b, color, alpha, ColorUtils.gradientLighter(color), alpha); break; case PositionConstants.RIGHT: paintHorizontalBackground(graphics, 0, b, ColorUtils .gradientLighter(color), alpha, color, alpha); break; case PositionConstants.BOTTOM: paintVerticalBackground(graphics, 0, b, ColorUtils .gradientLighter(color), alpha, color, alpha); break; case PositionConstants.TOP: paintVerticalBackground(graphics, 0, b, color, alpha, ColorUtils.gradientLighter(color), alpha); break; } } finally { graphics.popState(); } } private void paintVerticalBackground(Graphics graphics, int start, Rectangle r, Color color1, int alpha1, Color color2, int alpha2) { int length = r.height; start += r.y; Pattern p = new GradientPattern(Display.getCurrent(), r.x, start, r.x, start + length, color1, alpha1, color2, alpha2); graphics.setBackgroundPattern(p); Path s = new Path(Display.getCurrent()); s.addRoundedRectangle(r.x, start, r.width, length, 3); graphics.fillPath(s); s.dispose(); p.dispose(); } private void paintHorizontalBackground(Graphics graphics, int start, Rectangle r, Color color, int alpha1, Color color2, int alpha2) { int length = r.width; start += r.x; Pattern p = new GradientPattern(Display.getCurrent(), start, r.y, start + length, r.y, color, alpha1, color2, alpha2); graphics.setBackgroundPattern(p); Path s = new Path(Display.getCurrent()); s.addRoundedRectangle(start, r.y, length, r.height, 3); graphics.fillPath(s); s.dispose(); p.dispose(); } /** * @return the slide */ public ShadowedLayer getContentPane() { return contentLayer; } public ITextFigure getTitle() { return title; } /** * * @return one of {@link PositionConstants#TOP}, * {@link PositionConstants#BOTTOM}, {@link PositionConstants#LEFT}, * {@link PositionConstants#RIGHT} */ public int getTitlePlacement() { return titlePlacement; } /** * * @param textPlacement * one of {@link PositionConstants#TOP}, * {@link PositionConstants#BOTTOM}, * {@link PositionConstants#LEFT}, * {@link PositionConstants#RIGHT} */ public void setTitlePlacement(int textPlacement) { if (textPlacement == getTitlePlacement()) return; this.titlePlacement = textPlacement; updateTitlePlacement(textPlacement); } private void updateTitlePlacement(int textPlacement) { Object constraint = null; switch (textPlacement) { case PositionConstants.LEFT: constraint = FrameBorderLayout.LEFT; title.setTextAlignment(PositionConstants.RIGHT); break; case PositionConstants.RIGHT: constraint = FrameBorderLayout.RIGHT; title.setTextAlignment(PositionConstants.LEFT); break; case PositionConstants.TOP: constraint = FrameBorderLayout.TOP; title.setTextAlignment(PositionConstants.CENTER); break; case PositionConstants.BOTTOM: constraint = FrameBorderLayout.BOTTOM; title.setTextAlignment(PositionConstants.CENTER); break; } if (constraint != null && titleContainer.getParent() == this) { setConstraint(titleContainer, constraint); } } public boolean isSelected() { return getFlag(FLAG_SELECTED); } public void setSelected(boolean selected) { if (selected == isSelected()) return; setFlag(FLAG_SELECTED, selected); repaint(); } public void setPreselected(boolean preselected) { if (preselected == isPreselected()) return; setFlag(FLAG_PRESELECTED, preselected); repaint(); } public boolean isPreselected() { return getFlag(FLAG_PRESELECTED); } public boolean isPressed() { return contentLayer.isPressed(); } public void setPressed(boolean pressed) { if (isFlat()) return; contentLayer.setPressed(pressed); } public void press() { if (isFlat()) return; contentLayer.press(); } public void unpress() { if (isFlat()) return; contentLayer.unpress(); } public void togglePressed() { if (isFlat()) return; contentLayer.togglePressed(); } public boolean isHideTitle() { return getFlag(FLAG_HIDE_TITLE); } public boolean isFlat() { return getFlag(FLAG_FLAT); } public void setFlat(boolean flat) { if (flat == isFlat()) return; setFlag(FLAG_FLAT, flat); if (flat) { contentLayer.setDepths(0); } else { contentLayer.setDepths(3); } } public void setHideTitle(boolean hideTitle) { boolean oldHideTitle = isHideTitle(); if (hideTitle == oldHideTitle) return; setFlag(FLAG_HIDE_TITLE, hideTitle); if (hideTitle) { remove(titleContainer); } else { add(titleContainer); updateTitlePlacement(getTitlePlacement()); } } }