001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.netbeans.modules.mobility.svgcore.composer.actions;
042:
043: import java.awt.AWTEvent;
044: import java.awt.Color;
045: import java.awt.Cursor;
046: import java.awt.Graphics;
047: import java.awt.event.ActionEvent;
048: import java.awt.event.MouseEvent;
049: import java.util.ArrayList;
050: import java.util.List;
051: import javax.microedition.m2g.SVGImage;
052: import javax.swing.Action;
053: import org.netbeans.modules.mobility.svgcore.composer.AbstractComposerAction;
054: import org.netbeans.modules.mobility.svgcore.composer.AbstractComposerActionFactory;
055: import org.netbeans.modules.mobility.svgcore.composer.ActionMouseCursor;
056: import org.netbeans.modules.mobility.svgcore.composer.ComposerAction;
057: import org.netbeans.modules.mobility.svgcore.composer.PerseusController;
058: import org.netbeans.modules.mobility.svgcore.composer.SVGObject;
059: import org.netbeans.modules.mobility.svgcore.composer.SVGObjectOutline;
060: import org.netbeans.modules.mobility.svgcore.composer.SceneManager;
061: import org.netbeans.modules.mobility.svgcore.view.svg.AbstractSVGAction;
062: import org.w3c.dom.svg.SVGLocatableElement;
063:
064: /**
065: *
066: * @author Pavel Benes
067: */
068: public final class MoveFocusActionFactory extends
069: AbstractComposerActionFactory {
070: private static final ActionMouseCursor ACTIVATE_MOUSE_CURSOR = new ActionMouseCursor(
071: Cursor.HAND_CURSOR, 3);
072:
073: private static final Color FOCUS_OUTLINE_COLOR = Color.GREEN;
074:
075: private final class ShowFocusAction extends AbstractComposerAction {
076: private final SVGObject m_focused;
077:
078: public ShowFocusAction(SVGObject focused) {
079: super (MoveFocusActionFactory.this );
080: m_focused = focused;
081: }
082:
083: public void paint(Graphics g, int x, int y, boolean isReadOnly) {
084: if (isReadOnly && !m_isCompleted) {
085: SVGObjectOutline outline = m_focused.getOutline();
086: outline.draw(g, x, y, FOCUS_OUTLINE_COLOR, false);
087: outline.setDirty();
088: }
089: }
090:
091: public void actionCompleted() {
092: m_focused.repaint(SVGObjectOutline.SELECTOR_OVERLAP);
093: super .actionCompleted();
094: }
095: }
096:
097: private final AbstractSVGAction m_focusNext = new AbstractSVGAction(
098: "svg_focus_next", false) { //NOI18N
099: public void actionPerformed(ActionEvent e) {
100: if (++m_focusedIdIndex > m_focusTargets.size() - 1) {
101: m_focusedIdIndex = 0;
102: }
103: focusElement();
104: }
105: };
106:
107: private final transient AbstractSVGAction m_focusPrevious = new AbstractSVGAction(
108: "svg_focus_previous", false) { //NOI18N
109: public void actionPerformed(ActionEvent e) {
110: if (--m_focusedIdIndex < 0) {
111: m_focusedIdIndex = m_focusTargets.size() - 1;
112: }
113: assert m_focusedIdIndex >= 0;
114: focusElement();
115: }
116: };
117:
118: private final transient AbstractSVGAction m_activateFocused = new AbstractSVGAction(
119: "svg_activate_focused", false) { //NOI18N
120: public void actionPerformed(ActionEvent e) {
121: SVGImage svgImg = m_sceneMgr.getSVGImage();
122: if (svgImg != null) {
123: svgImg.activate();
124: }
125: }
126: };
127:
128: private final List<String> m_focusTargets = new ArrayList<String>();
129: private int m_focusedIdIndex = -1;
130: private ShowFocusAction m_showFocusAction = null;
131:
132: public MoveFocusActionFactory(SceneManager sceneMgr) {
133: super (sceneMgr);
134: }
135:
136: private void focusElement() {
137: if (m_showFocusAction != null) {
138: m_showFocusAction.actionCompleted();
139: m_showFocusAction = null;
140: }
141:
142: SVGObject obj = null;
143: String id = m_focusTargets.get(m_focusedIdIndex);
144: if (id != null) {
145: obj = getPerseusController().getObjectById(id);
146: assert obj != null;
147: m_showFocusAction = new ShowFocusAction(obj);
148: m_sceneMgr.startAction(m_showFocusAction);
149: }
150: m_sceneMgr.getSVGImage().focusOn(
151: obj != null ? obj.getSVGElement() : null);
152: m_sceneMgr.getScreenManager().repaint();
153: }
154:
155: public synchronized ComposerAction startAction(AWTEvent e,
156: boolean isOutsideEvent) {
157: if (e.getID() == SceneManager.EVENT_ANIM_STARTED) {
158: ((PerseusController) e.getSource())
159: .getFocusableTargets(m_focusTargets);
160: m_focusedIdIndex = 0;
161: setActionseEnabled(true);
162: } else if (e.getID() == SceneManager.EVENT_ANIM_STOPPED) {
163: m_focusTargets.clear();
164: setActionseEnabled(false);
165: } else if (e.getID() == MouseEvent.MOUSE_CLICKED) {
166: MouseEvent me = (MouseEvent) e;
167: if (me.getButton() == MouseEvent.BUTTON1
168: && me.getClickCount() == 1) {
169: int index = getFocusTargetIdAt(me, isOutsideEvent);
170: if (index != -1) {
171: m_focusedIdIndex = index;
172: focusElement();
173: m_activateFocused.actionPerformed(null);
174: }
175: }
176: }
177: return null;
178: }
179:
180: public ActionMouseCursor getMouseCursor(MouseEvent me,
181: boolean isOutsideEvent) {
182: return me.getID() == MouseEvent.MOUSE_MOVED
183: && getFocusTargetIdAt(me, isOutsideEvent) != -1 ? ACTIVATE_MOUSE_CURSOR
184: : null;
185: }
186:
187: private int getFocusTargetIdAt(MouseEvent me, boolean isOutsideEvent) {
188: if (!isOutsideEvent && m_sceneMgr.isReadOnly()
189: && m_focusTargets.size() > 0) {
190: SVGLocatableElement elem = m_sceneMgr
191: .getPerseusController().findElementAt(me.getX(),
192: me.getY());
193: if (elem != null) {
194: String id = elem.getId();
195: if (id != null)
196: return m_focusTargets.indexOf(id);
197: {
198: }
199: }
200: }
201: return -1;
202: }
203:
204: public Action[] getMenuActions() {
205: return new Action[] { m_focusNext, m_focusPrevious,
206: m_activateFocused };
207: }
208:
209: private void setActionseEnabled(boolean enabled) {
210: m_activateFocused.setEnabled(enabled);
211: m_focusNext.setEnabled(enabled);
212: m_focusPrevious.setEnabled(enabled);
213: }
214: }
|