/******************************************************************************* * Copyright (c) 2007, 2014 compeople AG 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: * compeople AG - initial API and implementation *******************************************************************************/ package org.eclipse.riena.internal.ui.ridgets.swt; import java.util.ArrayList; import java.util.Arrays; import java.util.Iterator; import java.util.List; import org.eclipse.jface.action.ContributionManager; import org.eclipse.jface.action.IContributionItem; import org.eclipse.jface.internal.provisional.action.ToolBarContributionItem2; import org.eclipse.swt.SWT; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.CoolBar; import org.eclipse.swt.widgets.CoolItem; import org.eclipse.swt.widgets.ToolBar; import org.eclipse.swt.widgets.ToolItem; import org.eclipse.riena.ui.swt.lnf.LnfKeyConstants; import org.eclipse.riena.ui.swt.lnf.LnfManager; import org.eclipse.riena.ui.swt.utils.SwtUtilities; /** * This class has some utility functions to support scaling the menu items in sync with Windows scaling factors */ public class ToolItemScalingHelper { /** * Creates SeparatorContributions for every toolbar in the given list. * * @param toolBars */ public void createSeparatorContributionsForToolBars(final List<ToolBar> toolBars) { int coolItemIndex = 0; boolean needFirstSeparator = false; for (final ToolBar toolBar : toolBars) { //the first toolbar doesnt need an Separator at the beginning if (coolItemIndex > 0) { needFirstSeparator = true; } createContributionForToolBarSeparators(toolBar, coolItemIndex, needFirstSeparator); coolItemIndex++; } } /** * Create a new Contributions and add them to the toolbarManager. * * @param toolItem * the toolItem which to attach the contribution * @param index * the index where to add the contribution in the toolarManager */ private void createContributionForToolBarSeparators(final ToolBar toolbar, final int coolItemIndex, final boolean firstSeparatorNeeded) { final ContributionManager toolbarManager = getContributionManagerFromToolBar(toolbar, coolItemIndex); if (toolbarManager != null) { int indexCounter = 0; //Create and insert an ToolItemContribution at the beginning of the toolbar which is no Separator to avoid being kept of the cleanlist if (firstSeparatorNeeded && !(toolbarManager.getItems()[0] instanceof ToolbarItemContribution)) { final ToolbarItemContribution FirstSeparatorContribution = new ToolbarItemContribution(); FirstSeparatorContribution.setIsSeparator(false); toolbarManager.insert(indexCounter, FirstSeparatorContribution); } //Insert Contribution for TBManager to avoid being kicked off the cleanlist final Iterator<IContributionItem> iterator = Arrays.asList(toolbarManager.getItems()).iterator(); while (iterator.hasNext()) { indexCounter++; if (!(iterator.next() instanceof ToolbarItemContribution)) { toolbarManager.insert(indexCounter, new ToolbarItemContribution()); indexCounter++; } } //Add the contribution to the toolbarItem to avoid being kicked off the cleanlist for (int i = 0; i < toolbar.getItems().length; i++) { toolbar.getItem(i).setData("toolItemSeparatorContribution", new ToolbarItemContribution()); //$NON-NLS-1$ } } } /** * Adds a seperator to allow for smooth scaling of the spacing between menu items when changing the windows scaling. seperators are only created for scaling * greater than 100% * * @param toolbar * toolbar into which to add the menu item * @param toolItem * item to which the separator must be appended if scaling is greater than 100% * @param index * index at which the separator is added * @param width * width if fixed, -1 to calculate use scaling * @return a separator if scaling is needed. Returns null if scaling is not needed. */ public ToolItem createSeparatorForScaling(final ToolBar toolbar, final ToolItem toolItem, final int index, int width, final ToolbarItemContribution contribution) { if (needScaleBasedSpacing()) { if (width == -1) { width = calculateScalingBasedSpacing(); } final ToolItem separator = new ToolItem(toolbar, SWT.SEPARATOR, index); separator.setWidth(width); final Composite composite = new Composite(toolbar, SWT.NONE); // composite.setBackground(new Color(SwtUtilities.getDisplay(), 255, 0, 0)); composite.setData("Separator", "Separator Composite"); //$NON-NLS-1$ //$NON-NLS-2$ separator.setControl(composite); separator.setEnabled(false); if (contribution != null) { separator.setData(contribution); } toolItem.setData("Separator", separator); //$NON-NLS-1$ return toolItem; } return null; } /** * creates a new Separator on the given position. * * @param toolbar * the toolbar where we add the newly created Separator * @param toolItem * the toolitem where want to attach the separator * @param width * the width of the separator. If width == -1 the width of the separator will be automatically calculated. * @param index * the index where the separator is placed within the toolbar. * @return */ public ToolItem createSeparatorForScalingOnPosition(final ToolBar toolbar, final ToolItem toolItem, int width, final int index) { if (needScaleBasedSpacing()) { if (width == -1) { width = calculateScalingBasedSpacing(); } final ToolItem separator = new ToolItem(toolbar, SWT.SEPARATOR, index); separator.setWidth(width); final Composite composite = new Composite(toolbar, SWT.NONE); // composite.setBackground(new Color(SwtUtilities.getDisplay(), 255, 0, 0)); composite.setData("Separator", "Separator Composite"); //$NON-NLS-1$ //$NON-NLS-2$ separator.setControl(composite); separator.setEnabled(false); toolItem.setData("Separator", separator); //$NON-NLS-1$ return toolItem; } return null; } private ContributionManager getContributionManagerFromToolBar(final ToolBar toolbar, final int coolItemIndex) { final CoolBar manager = ((CoolBar) toolbar.getParent()); final ArrayList<CoolItem> coolItems = new ArrayList<CoolItem>(); coolItems.addAll(Arrays.asList(manager.getItems())); if (toolbar.getItemCount() != 0 && coolItems.size() > coolItemIndex) { final ToolBarContributionItem2 contributionItem = (ToolBarContributionItem2) coolItems.get(coolItemIndex).getData(); final ContributionManager toolbarManager = (ContributionManager) contributionItem.getToolBarManager(); return toolbarManager; } return null; } /** * Checks if windows scaling is greater than 100%. If scaling is greather than 100% scaling is needed. * * @return true if spacing is needed. Otherwise false. */ public Boolean needScaleBasedSpacing() { final float[] dpi = SwtUtilities.getDpiFactors(); final boolean needSpacing = (dpi[0] > 1.0) ? true : false; return needSpacing; } /** * Calculates the needed spacing between two menu items depending on the windows scaling * * @returns the spacing */ public int calculateScalingBasedSpacing() { final float[] dpiFactors = SwtUtilities.getDpiFactors(); final int separatorSpacing = (int) (dpiFactors[0] * LnfManager.getLnf().getIntegerSetting(LnfKeyConstants.MENUBAR_SPACING, 4)); return separatorSpacing; } /** * Calculates the needed spacing between two toolbars depending on the windows scaling * * @return the spacing */ public int calculateSclaingBasedSpacingBetweenToolBars() { final float[] dpiFactors = SwtUtilities.getDpiFactors(); final int separatorSpacing = (int) (dpiFactors[0] * LnfManager.getLnf().getIntegerSetting(LnfKeyConstants.TOOLBAR_SPACING, 8)); return separatorSpacing; } /** * Remove the separator created for scaling if menu item is disposed * * @param item * @since 6.2 */ public void disposeSeparatorForMenuItem(final ToolItem item) { final ToolItem sep = (ToolItem) item.getData("Separator"); //$NON-NLS-1$ if (sep != null) { sep.getControl().dispose(); sep.dispose(); } } /** * @param originalItem * @return */ public boolean itemHasSeparator(final ToolItem originalItem) { if (originalItem.getData("Separator") != null) { //$NON-NLS-1$ return true; } return false; } /** * @param originalItem * @return */ public boolean toolbaritemHasSeparator(final ToolItem originalItem) { if (originalItem.getData("toolItemSeparatorContribution") != null) { //$NON-NLS-1$ return true; } return false; } }