/* ****************************************************************************** * 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.editor; import org.eclipse.jface.action.ContributionItem; import org.eclipse.jface.action.GroupMarker; import org.eclipse.jface.action.IAction; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.action.IContributionManager; import org.eclipse.jface.action.IToolBarManager; import org.eclipse.jface.action.Separator; import org.eclipse.jface.viewers.IBaseLabelProvider; import org.eclipse.jface.viewers.IContentProvider; import org.eclipse.jface.viewers.IOpenListener; import org.eclipse.jface.viewers.ISelection; import org.eclipse.jface.viewers.ISelectionChangedListener; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.LabelProvider; import org.eclipse.jface.viewers.OpenEvent; import org.eclipse.jface.viewers.SelectionChangedEvent; import org.eclipse.jface.viewers.StructuredSelection; import org.eclipse.jface.viewers.Viewer; import org.eclipse.swt.SWT; import org.eclipse.swt.custom.CLabel; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; import org.eclipse.ui.IWorkbenchActionConstants; import org.xmind.gef.EditDomain; import org.xmind.gef.GEF; import org.xmind.gef.IGraphicalViewer; import org.xmind.gef.IZoomListener; import org.xmind.gef.Request; import org.xmind.gef.ZoomManager; import org.xmind.gef.ZoomObject; import org.xmind.gef.ui.actions.EditorAction; import org.xmind.gef.ui.editor.IGraphicalEditor; import org.xmind.gef.ui.editor.IGraphicalEditorPage; import org.xmind.gef.ui.editor.IMiniBar; import org.xmind.gef.ui.editor.MiniBarContributor; import org.xmind.ui.internal.MindMapMessages; import org.xmind.ui.internal.actions.ActionConstants; import org.xmind.ui.internal.actions.VisibleSeparator; import org.xmind.ui.mindmap.IMindMapImages; import org.xmind.ui.mindmap.MindMapUI; import org.xmind.ui.viewers.ISliderContentProvider; import org.xmind.ui.viewers.SliderViewer; public class MindMapMiniBarContributor extends MiniBarContributor implements IZoomListener { public static final String VALUE = "value"; //$NON-NLS-1$ public static final String ACTIVE_PAGE = "activePage"; //$NON-NLS-1$ protected static final int SLIDER_WIDTH = 88; private class ZoomValueItem extends ContributionItem { private CLabel label; public void fill(ToolBar parent, int index) { if (label == null || label.isDisposed()) { ToolItem placeHolder; if (index >= 0) { placeHolder = new ToolItem(parent, SWT.SEPARATOR, index); } else { placeHolder = new ToolItem(parent, SWT.SEPARATOR); } label = new CLabel(parent, SWT.NONE); label.setText("000%"); // set initial text for computing size //$NON-NLS-1$ placeHolder.setControl(label); placeHolder.setWidth(label.computeSize(SWT.DEFAULT, SWT.DEFAULT, true).x + 10); label.setText(""); //$NON-NLS-1$ update(); } } public void update() { super.update(); update(null); } public void update(String id) { super.update(id); if (label != null && !label.isDisposed()) { boolean valueChanged = id == null || VALUE.equals(id); if (valueChanged) { if (zoomManager != null) { double scale = zoomManager.getScale(); int s = (int) Math.round(scale * 100); label.setText(String.format("%d%%", s)); //$NON-NLS-1$ } else { label.setText(""); //$NON-NLS-1$ } } } } } private class ZoomSliderItem extends ContributionItem implements ISelectionChangedListener, IOpenListener { private class ZoomSliderContentProvider implements ISliderContentProvider { private final double center = 1.0; private double min = 0.5; private double max = 2.0; public double getRatio(Object input, Object value) { if (value instanceof Double) { return calcPortion(((Double) value).doubleValue()); } return center; } private double calcPortion(double v) { if (v == center) return 0.5; if (v < min) return 0; if (v > max) return 1.0; if (v < center) { double d = center - min; if (d == 0) return min; return (v - min) * 0.5 / d; } double d = max - center; if (d == 0) return max; return (v - center) * 0.5 / d + 0.5; } public Object getValue(Object input, double ratio) { return Double.valueOf(calcValue(ratio)); } private double calcValue(double ratio) { if (ratio > 0.45 && ratio < 0.52) return center; if (ratio < 0.5) return ((center - min) * ratio / 0.5 + min); return ((max - center) * (ratio - 0.5) / 0.5 + center); } // public Object[] getValues(Object input) { // return new Double[] { min, center, max }; // } public void inputChanged(Viewer viewer, Object oldInput, Object newInput) { if (newInput != null && newInput instanceof ZoomManager) { ZoomManager zm = (ZoomManager) newInput; min = zm.getMin(); max = zm.getMax(); } else { min = 0.5; max = 2.0; } } public void dispose() { } } private class ZoomSliderLabelProvider extends LabelProvider { public String getText(Object element) { if (element instanceof Double) { double scale = ((Double) element).doubleValue(); return String.format("%.0f%%", Double.valueOf(scale * 100)); //$NON-NLS-1$ } return super.getText(element); } } private SliderViewer slider; private boolean updating = false; private boolean sendingRequest = false; private IContentProvider contentProvider = new ZoomSliderContentProvider(); private IBaseLabelProvider labelProvider = new ZoomSliderLabelProvider(); public void fill(ToolBar parent, int index) { if (slider == null || slider.getControl().isDisposed()) { ToolItem placeHolder; if (index >= 0) { placeHolder = new ToolItem(parent, SWT.SEPARATOR, index); } else { placeHolder = new ToolItem(parent, SWT.SEPARATOR); } slider = new SliderViewer(parent, SWT.HORIZONTAL); slider.setContentProvider(contentProvider); slider.setLabelProvider(labelProvider); slider.addSelectionChangedListener(this); slider.addOpenListener(this); placeHolder.setControl(slider.getControl()); placeHolder.setWidth(SLIDER_WIDTH); update(); } } public void update() { update(null); } public void update(String id) { super.update(id); if (slider != null && !slider.getControl().isDisposed() && !sendingRequest) { boolean zoomObjectChanged = id == null || ACTIVE_PAGE.equals(id); boolean valueChanged = id == null || VALUE.equals(id); if (zoomObjectChanged) { slider.setInput(zoomManager); slider.getControl().setEnabled(zoomManager != null); } if (valueChanged) { double value; if (zoomManager != null) { value = zoomManager.getScale(); } else { value = 1.0d; } updating = true; slider.setSelection(new StructuredSelection(Double .valueOf(value))); updating = false; } } } public void selectionChanged(SelectionChangedEvent event) { if (updating) return; ISelection selection = event.getSelection(); if (!selection.isEmpty() && selection instanceof IStructuredSelection) { IStructuredSelection ss = (IStructuredSelection) selection; Object element = ss.getFirstElement(); if (element != null && element instanceof Double) { double value = ((Double) element).doubleValue(); IGraphicalEditorPage page = getActivePage(); if (page != null) { EditDomain domain = page.getEditDomain(); if (domain != null) { sendingRequest = true; sendZoomRequest(domain, value); sendingRequest = false; } } } } } private void sendZoomRequest(EditDomain domain, double value) { Request request = new Request(GEF.REQ_ZOOM); request.setViewer(getActivePage().getViewer()); request.setParameter(GEF.PARAM_ZOOM_SCALE, Double.valueOf(value)); domain.handleRequest(request); } public void open(OpenEvent event) { IGraphicalEditorPage page = getActivePage(); if (page != null) { EditDomain domain = page.getEditDomain(); if (domain != null) { sendZoomRequest(domain, 1.0d); } } } } private static class MiniZoomInAction extends EditorAction { public MiniZoomInAction(IGraphicalEditor editor) { super(editor); setToolTipText(MindMapMessages.ZoomIn_text); setImageDescriptor(MindMapUI.getImages().get( IMindMapImages.ZOOMIN_SMALL, true)); setDisabledImageDescriptor(MindMapUI.getImages().get( IMindMapImages.ZOOMIN_SMALL, false)); } public void run() { if (isDisposed()) return; performRequest(GEF.REQ_ZOOMIN); } } private static class MiniZoomOutAction extends EditorAction { public MiniZoomOutAction(IGraphicalEditor editor) { super(editor); setToolTipText(MindMapMessages.ZoomOut_text); setImageDescriptor(MindMapUI.getImages().get( IMindMapImages.ZOOMOUT_SMALL, true)); setDisabledImageDescriptor(MindMapUI.getImages().get( IMindMapImages.ZOOMOUT_SMALL, false)); } public void run() { if (isDisposed()) return; performRequest(GEF.REQ_ZOOMOUT); } } private static class MiniActualSizeAction extends EditorAction { public MiniActualSizeAction(IGraphicalEditor editor) { super(editor); setToolTipText(MindMapMessages.ActualSize_text); setImageDescriptor(MindMapUI.getImages().get( IMindMapImages.ACTUAL_SIZE_SMALL, true)); setDisabledImageDescriptor(MindMapUI.getImages().get( IMindMapImages.ACTUAL_SIZE_SMALL, false)); } public void run() { if (isDisposed()) return; performRequest(GEF.REQ_ACTUALSIZE); } } public static final int PREF_HEIGHT = 12; private ZoomManager zoomManager = null; private ZoomValueItem zoomValueItem; private ZoomSliderItem zoomSliderItem; private MiniZoomInAction zoomInAction; private MiniZoomOutAction zoomOutAction; private MiniActualSizeAction actualSizeAction; public void init(IMiniBar bar) { zoomValueItem = new ZoomValueItem(); zoomSliderItem = new ZoomSliderItem(); zoomInAction = new MiniZoomInAction(getEditor()); zoomOutAction = new MiniZoomOutAction(getEditor()); actualSizeAction = new MiniActualSizeAction(getEditor()); super.init(bar); } public void contributeToToolBar(IToolBarManager toolBar) { super.contributeToToolBar(toolBar); toolBar.add(new GroupMarker(IWorkbenchActionConstants.MB_ADDITIONS)); toolBar.add(new GroupMarker(ActionConstants.GROUP_ZOOM)); toolBar.add(new VisibleSeparator()); add(toolBar, zoomValueItem); toolBar.add(new Separator()); add(toolBar, zoomOutAction); toolBar.add(zoomSliderItem); add(toolBar, zoomInAction); add(toolBar, actualSizeAction); } protected void add(IContributionManager manager, IAction action) { if (manager == null || action == null) return; manager.add(action); } protected void add(IContributionManager manager, IContributionItem item) { if (manager == null || item == null) return; manager.add(item); } public void dispose() { super.dispose(); zoomValueItem = null; zoomSliderItem = null; if (zoomInAction != null) { zoomInAction.dispose(); zoomInAction = null; } if (zoomOutAction != null) { zoomOutAction.dispose(); zoomOutAction = null; } if (actualSizeAction != null) { actualSizeAction.dispose(); actualSizeAction = null; } } protected void updateZoomContributionItems() { update(zoomValueItem); update(zoomSliderItem); } protected void update(IContributionItem item) { if (item != null) item.update(); } protected void pageChanged(IGraphicalEditorPage page) { super.pageChanged(page); setZoomManager(getZoomManager(page)); } private ZoomManager getZoomManager(IGraphicalEditorPage page) { if (page == null) return null; IGraphicalViewer viewer = page.getViewer(); if (viewer == null) return null; return viewer.getZoomManager(); } protected void setZoomManager(ZoomManager zoomManager) { if (zoomManager == this.zoomManager) return; if (this.zoomManager != null) { unhookZoomManager(this.zoomManager); } this.zoomManager = zoomManager; if (zoomManager != null) { hookZoomManager(zoomManager); } updateZoomContributionItems(); } protected void hookZoomManager(ZoomManager zoomManager) { zoomManager.addZoomListener(this); } protected void unhookZoomManager(ZoomManager zoomManager) { zoomManager.removeZoomListener(this); } public void scaleChanged(ZoomObject source, double oldValue, double newValue) { updateZoomContributionItems(); } }