/* ****************************************************************************** * 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.internal.mindmap; import org.eclipse.swt.widgets.Display; import org.xmind.gef.GEF; import org.xmind.gef.part.IGraphicalEditPart; import org.xmind.gef.part.IPartStatus; import org.xmind.gef.service.IFeedback; import org.xmind.gef.service.IFeedbackService; import org.xmind.gef.status.IStatusListener; import org.xmind.gef.status.StatusEvent; import org.xmind.gef.status.StatusMachine2; import org.xmind.ui.mindmap.ISelectionFeedbackHelper; public class SelectionFeedbackHelper implements ISelectionFeedbackHelper, IStatusListener { private IGraphicalEditPart host; private IFeedbackService feedbackService = null; private IFeedback currentFeedback = null; private int lastStatus = 0; private boolean updating = false; private int overrideStatus = -1; private int overrideMask = -1; public void setHost(IGraphicalEditPart host) { if (host == this.host) return; if (this.host != null) { this.host.getStatus().removeStatusListener(this); } this.host = host; if (host != null) { host.getStatus().addStatusListener(this); } } protected IGraphicalEditPart getHost() { return host; } public void setFeedbackService(IFeedbackService feedbackService) { if (feedbackService == this.feedbackService) return; if (this.feedbackService != null) { removeAllFeedback(this.feedbackService); } this.feedbackService = feedbackService; if (feedbackService != null) update(feedbackService); } protected IFeedbackService getFeedbackService() { return feedbackService; } protected int getCalculatedSelectionStatus() { if (overrideMask >= 0) { return (overrideStatus & overrideMask) | (getRealSelectionStatus() & ~overrideMask); } return getRealSelectionStatus(); } protected int getRealSelectionStatus() { if (getHost() == null) return 0; IPartStatus status = getHost().getStatus(); if (status instanceof StatusMachine2) { return ((StatusMachine2) status).getStatus() & GEF.PART_SEL_MASK; } return calcSelectionStatus(status.isPreSelected(), status.isSelected(), status.isFocused()); } public void forceFeedback(int key, boolean value) { if (overrideMask < 0) overrideMask = 0; overrideMask |= key; if (overrideStatus < 0) overrideStatus = 0; if (value) { overrideStatus |= key; } else { overrideStatus &= ~key; } updateFeedback(true); } public void resetFeedback(int key) { overrideMask &= ~key; updateFeedback(true); } public void resetAllFeedback() { overrideMask = -1; overrideStatus = -1; updateFeedback(true); } public void updateFeedback(boolean async) { if (async) { asyncUpdate(); } else { update(); } } protected void asyncUpdate() { if (updating) return; Display.getCurrent().asyncExec(new Runnable() { public void run() { update(); updating = false; } }); } private void update() { if (getHost() == null || !getHost().getStatus().isActive()) return; if (feedbackService != null && !feedbackService.isDisposed()) { update(feedbackService); } } private void update(IFeedbackService feedbackService) { IFeedback newFeedback = (IFeedback) getHost().getAdapter( IFeedback.class); if (newFeedback != currentFeedback) { if (currentFeedback != null) { feedbackService.removeFeedback(currentFeedback); } currentFeedback = newFeedback; } int newStatus = getCalculatedSelectionStatus(); if (newStatus != lastStatus) { if (currentFeedback != null) { if (lastStatus == 0 && newStatus > 0) { feedbackService.addFeedback(currentFeedback); } else if (lastStatus > 0 && newStatus == 0) { feedbackService.removeFeedback(currentFeedback); } } lastStatus = newStatus; } if (currentFeedback != null) { updateFeedback(currentFeedback, newStatus); currentFeedback.update(); } updateOtherFeedback(feedbackService, newStatus); } protected void updateFeedback(IFeedback feedback, int newStatus) { } protected void updateOtherFeedback(IFeedbackService feedbackService, int newStatus) { } private void removeAllFeedback(IFeedbackService feedbackService) { if (currentFeedback != null) { feedbackService.removeFeedback(currentFeedback); } removeOtherFeedback(feedbackService); } protected void removeOtherFeedback(IFeedbackService feedbackService) { } public void statusChanged(StatusEvent event) { if ((event.key & GEF.PART_SEL_MASK) != 0) { updateFeedback(true); } } private static int calcSelectionStatus(boolean preselected, boolean selected, boolean focused) { int s = 0; if (preselected) s |= GEF.PART_PRESELECTED; if (selected) s |= GEF.PART_SELECTED; if (focused) s |= GEF.PART_FOCUSED; return s; } }