| /******************************************************************************* |
| * Copyright (c) 2000, 2004 IBM Corporation 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.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.ui.forms.widgets; |
| import org.eclipse.swt.SWT; |
| import org.eclipse.swt.accessibility.*; |
| import org.eclipse.swt.graphics.*; |
| import org.eclipse.swt.widgets.*; |
| import org.eclipse.ui.forms.events.*; |
| /** |
| * A custom selectable control that can be used to control areas that can be |
| * expanded or collapsed. |
| * <p> |
| * This is an abstract class. Subclasses are responsible for rendering the |
| * control using decoration and hover decoration color. Control should be |
| * rendered based on the current expansion state. |
| * |
| * @since 3.0 |
| */ |
| public abstract class ToggleHyperlink extends AbstractHyperlink { |
| protected int innerWidth; |
| protected int innerHeight; |
| protected boolean hover; |
| private boolean expanded; |
| private Color decorationColor; |
| private Color hoverColor; |
| /** |
| * Creates a control in a provided composite. |
| * |
| * @param parent |
| * the parent |
| * @param style |
| * the style |
| */ |
| public ToggleHyperlink(Composite parent, int style) { |
| super(parent, style); |
| Listener listener = new Listener() { |
| public void handleEvent(Event e) { |
| switch (e.type) { |
| case SWT.MouseEnter: |
| hover=true; |
| redraw(); |
| break; |
| case SWT.MouseExit: |
| hover = false; |
| redraw(); |
| break; |
| case SWT.KeyDown: |
| onKeyDown(e); |
| break; |
| } |
| } |
| }; |
| addListener(SWT.MouseEnter, listener); |
| addListener(SWT.MouseExit, listener); |
| addListener(SWT.KeyDown, listener); |
| addHyperlinkListener(new HyperlinkAdapter() { |
| public void linkActivated(HyperlinkEvent e) { |
| setExpanded(!isExpanded()); |
| } |
| }); |
| initAccessible(); |
| } |
| /** |
| * Sets the color of the decoration. |
| * |
| * @param decorationColor |
| */ |
| public void setDecorationColor(Color decorationColor) { |
| this.decorationColor = decorationColor; |
| } |
| /** |
| * Returns the color of the decoration. |
| * |
| * @return decoration color |
| */ |
| public Color getDecorationColor() { |
| return decorationColor; |
| } |
| /** |
| * Sets the hover color of decoration. Hover color will be used when mouse |
| * enters the decoration area. |
| * |
| * @param hoverColor |
| * the hover color to use |
| */ |
| public void setHoverDecorationColor(Color hoverColor) { |
| this.hoverColor = hoverColor; |
| } |
| /** |
| * Returns the hover color of the decoration. |
| * |
| * @return the hover color of the decoration. |
| * @since 3.1 |
| */ |
| public Color getHoverDecorationColor() { |
| return hoverColor; |
| } |
| |
| /** |
| * Returns the hover color of the decoration. |
| * |
| * @return the hover color of the decoration. |
| * @deprecated use <code>getHoverDecorationColor</code> |
| * @see #getHoverDecorationColor() |
| */ |
| public Color geHoverDecorationColor() { |
| return hoverColor; |
| } |
| /** |
| * Computes the size of the control. |
| * |
| * @param wHint |
| * width hint |
| * @param hHint |
| * height hint |
| * @param changed |
| * if true, flush any saved layout state |
| */ |
| public Point computeSize(int wHint, int hHint, boolean changed) { |
| int width, height; |
| /* |
| if (wHint != SWT.DEFAULT) |
| width = wHint; |
| else */ |
| width = innerWidth + 2 * marginWidth; |
| /* |
| if (hHint != SWT.DEFAULT) |
| height = hHint; |
| else */ |
| height = innerHeight + 2 * marginHeight; |
| return new Point(width, height); |
| } |
| /** |
| * Returns the expansion state of the toggle control. When toggle is in the |
| * normal (downward) state, the value is <samp>true </samp>. Collapsed |
| * control will return <samp>false </samp>. |
| * |
| * @return <samp>false </samp> if collapsed, <samp>true </samp> otherwise. |
| */ |
| public boolean isExpanded() { |
| return expanded; |
| } |
| /** |
| * Sets the expansion state of the twistie control |
| * |
| * @param expanded the expansion state |
| */ |
| public void setExpanded(boolean expanded) { |
| this.expanded = expanded; |
| redraw(); |
| } |
| private void initAccessible() { |
| getAccessible().addAccessibleListener(new AccessibleAdapter() { |
| public void getHelp(AccessibleEvent e) { |
| e.result = getToolTipText(); |
| } |
| public void getName(AccessibleEvent e) { |
| if (getParent() instanceof ExpandableComposite) { |
| String name = ((ExpandableComposite)getParent()).getText(); |
| int index = name.indexOf('&'); |
| if (index != -1) { |
| name = name.substring(0, index) + name.substring(index + 1); |
| } |
| e.result = name; |
| } |
| |
| } |
| public void getDescription(AccessibleEvent e) { |
| getName(e); |
| } |
| }); |
| getAccessible().addAccessibleControlListener( |
| new AccessibleControlAdapter() { |
| public void getChildAtPoint(AccessibleControlEvent e) { |
| Point testPoint = toControl(new Point(e.x, e.y)); |
| if (getBounds().contains(testPoint)) { |
| e.childID = ACC.CHILDID_SELF; |
| } |
| } |
| public void getLocation(AccessibleControlEvent e) { |
| Rectangle location = getBounds(); |
| Point pt = toDisplay(new Point(location.x, location.y)); |
| e.x = pt.x; |
| e.y = pt.y; |
| e.width = location.width; |
| e.height = location.height; |
| } |
| public void getChildCount(AccessibleControlEvent e) { |
| e.detail = 0; |
| } |
| public void getRole(AccessibleControlEvent e) { |
| e.detail = ACC.ROLE_TREE; |
| } |
| public void getState(AccessibleControlEvent e) { |
| e.detail = ToggleHyperlink.this.isExpanded() |
| ? ACC.STATE_EXPANDED |
| : ACC.STATE_COLLAPSED; |
| } |
| public void getValue(AccessibleControlEvent e) { |
| e.result = "0"; //$NON-NLS-1$ |
| } |
| }); |
| } |
| private void onKeyDown(Event e) { |
| if (e.keyCode==SWT.ARROW_RIGHT) { |
| // expand if collapsed |
| if (!isExpanded()) { |
| handleActivate(e); |
| } |
| e.doit=false; |
| } |
| else if (e.keyCode==SWT.ARROW_LEFT) { |
| // collapse if expanded |
| if (isExpanded()) { |
| handleActivate(e); |
| } |
| e.doit=false; |
| } |
| } |
| } |