Mercurial > projects > dwt-addons
view dwtx/jface/action/CoolBarManager.d @ 90:7ffeace6c47f
Update 3.4M7 to 3.4
author | Frank Benoit <benoit@tionex.de> |
---|---|
date | Sun, 06 Jul 2008 23:30:07 +0200 |
parents | 46a6e0e6ccd4 |
children | 04b47443bb01 |
line wrap: on
line source
/******************************************************************************* * Copyright (c) 2003, 2008 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 * Port to the D programming language: * Frank Benoit <benoit@tionex.de> *******************************************************************************/ module dwtx.jface.action.CoolBarManager; import dwtx.jface.action.ToolBarContributionItem; import dwtx.jface.action.Separator; import dwtx.jface.action.ContributionManager; import dwtx.jface.action.IContributionManager; import dwtx.jface.action.IContributionItem; import dwtx.jface.action.ICoolBarManager; import dwtx.jface.action.IToolBarManager; import dwtx.jface.action.IMenuManager; import dwtx.jface.action.MenuManager; import tango.util.collection.ArraySeq; import tango.util.collection.HashMap; import tango.util.collection.model.Iterator; // import java.util.HashMap; // import java.util.Iterator; // import java.util.List; // import java.util.ListIterator; import dwt.DWT; import dwt.widgets.Composite; import dwt.widgets.Control; import dwt.widgets.CoolBar; import dwt.widgets.CoolItem; import dwt.widgets.Menu; import dwtx.core.runtime.Assert; import dwtx.jface.util.Policy; import dwt.dwthelper.utils; import tango.io.Stdout; /** * A cool bar manager is a contribution manager which realizes itself and its * items in a cool bar control. * <p> * This class may be instantiated; it may also be subclassed. * </p> * * @since 3.0 */ public class CoolBarManager : ContributionManager, ICoolBarManager { alias ContributionManager.add add; class ListIterator { ArraySeq!(Object) c; int i; this( ArraySeq!(Object) c ){ this.c = c; } Object next(){ return c.get(++i); } Object previous(){ return c.get(--i); } bool hasNext(){ return i+1 < c.size(); } bool hasPrevious(){ return i > 0; } void remove(){ c.removeAt(i); if( i is c.size() ) i--; } int nextIndex(){ return i+1; } } /** * A separator created by the end user. */ public final static String USER_SEPARATOR = "UserSeparator"; //$NON-NLS-1$ /** * The original creation order of the contribution items. */ private ArraySeq!(Object) cbItemsCreationOrder; /** * MenuManager for cool bar pop-up menu, or null if none. */ private MenuManager contextMenuManager = null; /** * The cool bar control; <code>null</code> before creation and after * disposal. */ private CoolBar coolBar = null; /** * The cool bar items style; <code>DWT.NONE</code> by default. */ private int itemStyle = DWT.NONE; /** * Creates a new cool bar manager with the default style. Equivalent to * <code>CoolBarManager(DWT.NONE)</code>. */ public this() { cbItemsCreationOrder = new ArraySeq!(Object); // do nothing } /** * Creates a cool bar manager for an existing cool bar control. This * manager becomes responsible for the control, and will dispose of it when * the manager is disposed. * * @param coolBar * the cool bar control */ public this(CoolBar coolBar) { this(); Assert.isNotNull(coolBar); this.coolBar = coolBar; itemStyle = coolBar.getStyle(); } /** * Creates a cool bar manager with the given DWT style. Calling <code>createControl</code> * will create the cool bar control. * * @param style * the cool bar item style; see * {@link dwt.widgets.CoolBar CoolBar}for for valid * style bits */ public this(int style) { cbItemsCreationOrder = new ArraySeq!(Object); itemStyle = style; } /* * (non-Javadoc) * * @see dwtx.jface.action.ICoolBarManager#add(dwtx.jface.action.IToolBarManager) */ public void add(IToolBarManager toolBarManager) { Assert.isNotNull(cast(Object)toolBarManager); super.add(new ToolBarContributionItem(toolBarManager)); } /** * Collapses consecutive separators and removes a separator from the * beginning and end of the list. * * @param contributionList * the list of contributions; must not be <code>null</code>. * @return The contribution list provided with extraneous separators * removed; this value is never <code>null</code>, but may be * empty. */ private ArraySeq!(Object) adjustContributionList(ArraySeq!(Object) contributionList) { IContributionItem item; // Fist remove a separator if it is the first element of the list if (contributionList.size() !is 0) { item = cast(IContributionItem) contributionList.get(0); if (item.isSeparator()) { contributionList.removeAt(0); } auto iterator = new ListIterator( contributionList ); // collapse consecutive separators while (iterator.hasNext()) { item = cast(IContributionItem) iterator.next(); if (item.isSeparator()) { while (iterator.hasNext()) { item = cast(IContributionItem) iterator.next(); if (item.isSeparator()) { iterator.remove(); } else { break; } } } } // Now check last element to see if there is a separator item = cast(IContributionItem) contributionList.get(contributionList .size() - 1); if (item.isSeparator()) { contributionList.removeAt(contributionList.size() - 1); } } return contributionList; } /* (non-Javadoc) * @see dwtx.jface.action.ContributionManager#checkDuplication(dwtx.jface.action.IContributionItem) */ protected override bool allowItem(IContributionItem itemToAdd) { /* We will allow as many null entries as they like, though there should * be none. */ if (itemToAdd is null) { return true; } /* Null identifiers can be expected in generic contribution items. */ String firstId = itemToAdd.getId(); if (firstId is null) { return true; } // Cycle through the current list looking for duplicates. IContributionItem[] currentItems = getItems(); for (int i = 0; i < currentItems.length; i++) { IContributionItem currentItem = currentItems[i]; // We ignore null entries. if (currentItem is null) { continue; } String secondId = currentItem.getId(); if (firstId.equals(secondId)) { if (Policy.TRACE_TOOLBAR) { Stdout.formatln("Trying to add a duplicate item."); //$NON-NLS-1$ ExceptionPrintStackTrace(new Exception(null), Stdout ); Stdout.formatln("DONE --------------------------"); //$NON-NLS-1$ } return false; } } return true; } /** * Positions the list iterator to the end of all the separators. Calling * <code>next()</code> the iterator should return the immediate object * following the last separator. * * @param iterator * the list iterator. */ private void collapseSeparators(ListIterator iterator) { while (iterator.hasNext()) { IContributionItem item = cast(IContributionItem) iterator.next(); if (!item.isSeparator()) { iterator.previous(); return; } } } /** * Returns whether the cool bar control has been created and not yet * disposed. * * @return <code>true</code> if the control has been created and not yet * disposed, <code>false</code> otherwise */ private bool coolBarExist() { return coolBar !is null && !coolBar.isDisposed(); } /** * Creates and returns this manager's cool bar control. Does not create a * new control if one already exists. * * @param parent * the parent control * @return the cool bar control */ public CoolBar createControl(Composite parent) { Assert.isNotNull(parent); if (!coolBarExist()) { coolBar = new CoolBar(parent, itemStyle); coolBar.setMenu(getContextMenuControl()); coolBar.setLocked(false); update(false); } return coolBar; } /** * Disposes of this cool bar manager and frees all allocated DWT resources. * Notifies all contribution items of the dispose. Note that this method * does not clean up references between this cool bar manager and its * associated contribution items. Use <code>removeAll</code> for that * purpose. */ public void dispose() { if (coolBarExist()) { coolBar.dispose(); coolBar = null; } IContributionItem[] items = getItems(); for (int i = 0; i < items.length; i++) { // Disposes of the contribution item. // If Contribution Item is a toolbar then it will dispose of // all the nested // contribution items. items[i].dispose(); } // If a context menu existed then dispose of it. if (contextMenuManager !is null) { contextMenuManager.dispose(); contextMenuManager = null; } } /** * Disposes the given cool item. * * @param item * the cool item to dispose */ private void dispose(CoolItem item) { if ((item !is null) && !item.isDisposed()) { item.setData(null); Control control = item.getControl(); // if the control is already disposed, setting the coolitem // control to null will cause an DWT exception, workaround // for 19630 if ((control !is null) && !control.isDisposed()) { item.setControl(null); } item.dispose(); } } /** * Finds the cool item associated with the given contribution item. * * @param item * the contribution item * @return the associated cool item, or <code>null</code> if not found */ private CoolItem findCoolItem(IContributionItem item) { CoolItem[] coolItems = (coolBar is null) ? null : coolBar.getItems(); return findCoolItem(coolItems, item); } private CoolItem findCoolItem(CoolItem[] items, IContributionItem item) { if (items is null) { return null; } for (int i = 0; i < items.length; i++) { CoolItem coolItem = items[i]; IContributionItem data = cast(IContributionItem) coolItem.getData(); if (data !is null && (cast(Object)data).opEquals(cast(Object)item)) { return coolItem; } } return null; } /** * Return a consistent set of wrap indices. The return value will always * include at least one entry and the first entry will always be zero. * CoolBar.getWrapIndices() is inconsistent in whether or not it returns an * index for the first row. * * @param wraps * the wrap indicies from the cool bar widget * @return the adjusted wrap indicies. */ private int[] getAdjustedWrapIndices(int[] wraps) { int[] adjustedWrapIndices; if (wraps.length is 0) { adjustedWrapIndices = [ 0 ]; } else { if (wraps[0] !is 0) { adjustedWrapIndices = new int[wraps.length + 1]; adjustedWrapIndices[0] = 0; for (int i = 0; i < wraps.length; i++) { adjustedWrapIndices[i + 1] = wraps[i]; } } else { adjustedWrapIndices = wraps; } } return adjustedWrapIndices; } /** * Returns the control of the Menu Manager. If the menu manager does not * have a control then one is created. * * @return menu control associated with manager, or null if none */ private Menu getContextMenuControl() { if ((contextMenuManager !is null) && (coolBar !is null)) { Menu menuWidget = contextMenuManager.getMenu(); if ((menuWidget is null) || (menuWidget.isDisposed())) { menuWidget = contextMenuManager.createContextMenu(coolBar); } return menuWidget; } return null; } /* * (non-Javadoc) * * @see dwtx.jface.action.ICoolBarManager#isLayoutLocked() */ public IMenuManager getContextMenuManager() { return contextMenuManager; } /** * Returns the cool bar control for this manager. * * @return the cool bar control, or <code>null</code> if none */ public CoolBar getControl() { return coolBar; } /** * Returns an array list of all the contribution items in the manager. * * @return an array list of contribution items. */ private ArraySeq!(Object) getItemList() { IContributionItem[] cbItems = getItems(); ArraySeq!(Object) list = new ArraySeq!(Object); list.capacity(cbItems.length); for (int i = 0; i < cbItems.length; i++) { list.append( cast(Object) cbItems[i]); } return list; } /* * (non-Javadoc) * * @see dwtx.jface.action.ICoolBarManager#isLayoutLocked() */ public bool getLockLayout() { if (!coolBarExist()) { return false; } return coolBar.getLocked(); } /** * Returns the number of rows that should be displayed visually. * * @param items * the array of contributin items * @return the number of rows */ private int getNumRows(IContributionItem[] items) { int numRows = 1; bool separatorFound = false; for (int i = 0; i < items.length; i++) { if (items[i].isSeparator()) { separatorFound = true; } if ((separatorFound) && (items[i].isVisible()) && (!items[i].isGroupMarker()) && (!items[i].isSeparator())) { numRows++; separatorFound = false; } } return numRows; } /* * (non-Javadoc) * * @see dwtx.jface.action.ICoolBarManager#getStyle() */ public int getStyle() { return itemStyle; } /** * Subclasses may extend this <code>ContributionManager</code> method, * but must call <code>super.itemAdded</code>. * * @see dwtx.jface.action.ContributionManager#itemAdded(dwtx.jface.action.IContributionItem) */ protected override void itemAdded(IContributionItem item) { Assert.isNotNull(cast(Object)item); super.itemAdded(item); int insertedAt = indexOf(item); bool replaced = false; final int size = cbItemsCreationOrder.size(); for (int i = 0; i < size; i++) { IContributionItem created = cast(IContributionItem) cbItemsCreationOrder .get(i); if (created.getId() !is null && created.getId().equals(item.getId())) { cbItemsCreationOrder.replaceAt(i, cast(Object) item); replaced = true; break; } } if (!replaced) { cbItemsCreationOrder.addAt(Math.min(Math.max(insertedAt, 0), cbItemsCreationOrder.size()), cast(Object) item); } } /** * Subclasses may extend this <code>ContributionManager</code> method, * but must call <code>super.itemRemoved</code>. * * @see dwtx.jface.action.ContributionManager#itemRemoved(dwtx.jface.action.IContributionItem) */ protected override void itemRemoved(IContributionItem item) { Assert.isNotNull(cast(Object)item); super.itemRemoved(item); CoolItem coolItem = findCoolItem(item); if (coolItem !is null) { coolItem.setData(null); } } /** * Positions the list iterator to the starting of the next row. By calling * next on the returned iterator, it will return the first element of the * next row. * * @param iterator * the list iterator of contribution items * @param ignoreCurrentItem * Whether the current item in the iterator should be considered * (as well as subsequent items). */ private void nextRow(ListIterator iterator, bool ignoreCurrentItem) { IContributionItem currentElement = null; if (!ignoreCurrentItem && iterator.hasPrevious()) { currentElement = cast(IContributionItem) iterator.previous(); iterator.next(); } if ((currentElement !is null) && (currentElement.isSeparator())) { collapseSeparators(iterator); return; } //Find next separator while (iterator.hasNext()) { IContributionItem item = cast(IContributionItem) iterator.next(); if (item.isSeparator()) { // we we find a separator, collapse any consecutive // separators // and return collapseSeparators(iterator); return; } } } /* * Used for debuging. Prints all the items in the internal structures. */ // private void printContributions(ArrayList contributionList) { // int index = 0; // System.out.println("----------------------------------\n"); //$NON-NLS-1$ // for (Iterator i = contributionList.iterator(); i.hasNext(); index++) { // IContributionItem item = (IContributionItem) i.next(); // if (item.isSeparator()) { // System.out.println("Separator"); //$NON-NLS-1$ // } else { // System.out.println(index + ". Item id: " + item.getId() //$NON-NLS-1$ // + " - is Visible: " //$NON-NLS-1$ // + item.isVisible()); // } // } // } /** * Synchronizes the visual order of the cool items in the control with this * manager's internal data structures. This method should be called before * requesting the order of the contribution items to ensure that the order * is accurate. * <p> * Note that <code>update()</code> and <code>refresh()</code> are * converses: <code>update()</code> changes the visual order to match the * internal structures, and <code>refresh</code> changes the internal * structures to match the visual order. * </p> */ public void refresh() { if (!coolBarExist()) { return; } // Retreives the list of contribution items as an array list auto contributionList = getItemList(); // Check the size of the list if (contributionList.size() is 0) { return; } // The list of all the cool items in their visual order CoolItem[] coolItems = coolBar.getItems(); // The wrap indicies of the coolbar int[] wrapIndicies = getAdjustedWrapIndices(coolBar.getWrapIndices()); int row = 0; int coolItemIndex = 0; // Traverse through all cool items in the coolbar add them to a new // data structure // in the correct order auto displayedItems = new ArraySeq!(Object); displayedItems.capacity(coolBar.getItemCount()); for (int i = 0; i < coolItems.length; i++) { CoolItem coolItem = coolItems[i]; if ( auto cbItem = cast(IContributionItem) coolItem.getData() ) { displayedItems.addAt(Math.min(i, displayedItems.size()), cast(Object) cbItem); } } // Add separators to the displayed Items data structure int offset = 0; for (int i = 1; i < wrapIndicies.length; i++) { int insertAt = wrapIndicies[i] + offset; displayedItems.addAt(insertAt, new Separator(USER_SEPARATOR)); offset++; } // Determine which rows are invisible auto existingVisibleRows = new ArraySeq!(Object); existingVisibleRows.capacity(4); ListIterator rowIterator = new ListIterator( contributionList ); collapseSeparators(rowIterator); int numRow = 0; while (rowIterator.hasNext()) { // Scan row while (rowIterator.hasNext()) { IContributionItem cbItem = cast(IContributionItem) rowIterator .next(); if (displayedItems.contains(cast(Object) cbItem)) { existingVisibleRows.append(new Integer(numRow)); break; } if (cbItem.isSeparator()) { break; } } nextRow(rowIterator, false); numRow++; } auto existingRows = new ListIterator( existingVisibleRows ); // Adjust row number to the first visible if (existingRows.hasNext()) { row = (cast(Integer) existingRows.next()).intValue(); } auto itemLocation = new HashMap!(Object,Object); foreach( key; displayedItems ){ IContributionItem item = cast(IContributionItem)key; if (item.isSeparator()) { if (existingRows.hasNext()) { Integer value = cast(Integer) existingRows.next(); row = value.intValue(); } else { row++; } } else { itemLocation.add(cast(Object)item, new Integer(row)); } } // Insert the contribution items in their correct location foreach( key; displayedItems ){ IContributionItem cbItem = cast(IContributionItem) key; if (cbItem.isSeparator()) { coolItemIndex = 0; } else { relocate(cbItem, coolItemIndex, contributionList, itemLocation); cbItem.saveWidgetState(); coolItemIndex++; } } if (contributionList.size() !is 0) { contributionList = adjustContributionList(contributionList); auto array = arraycast!(IContributionItem)( contributionList.toArray() ); internalSetItems(array); } } /** * Relocates the given contribution item to the specified index. * * @param cbItem * the conribution item to relocate * @param index * the index to locate this item * @param contributionList * the current list of conrtributions * @param itemLocation */ private void relocate(IContributionItem cbItem, int index, ArraySeq!(Object) contributionList, HashMap!(Object,Object) itemLocation) { if (!(cast(Integer)itemLocation.get(cast(Object)cbItem) )) { return; } int targetRow = (cast(Integer) itemLocation.get(cast(Object)cbItem)).intValue(); int cbInternalIndex = -1; int idx; foreach( el; contributionList ){ if( el == cast(Object)cbItem){ cbInternalIndex = idx; break; } idx++; } // by default add to end of list int insertAt = contributionList.size(); // Find the row to place this item in. auto iterator = new ListIterator( contributionList ); // bypass any separators at the begining collapseSeparators(iterator); int currentRow = -1; while (iterator.hasNext()) { currentRow++; if (currentRow is targetRow) { // We found the row to insert the item int virtualIndex = 0; insertAt = iterator.nextIndex(); // first check the position of the current element (item) // then get the next element while (iterator.hasNext()) { IContributionItem item = cast(IContributionItem) iterator .next(); Integer itemRow = cast(Integer) itemLocation.get( cast(Object) item); if (item.isSeparator()) { break; } // if the item has an associate widget if ((itemRow !is null) && (itemRow.intValue() is targetRow)) { // if the next element is the index we are looking for // then break if (virtualIndex >= index) { break; } virtualIndex++; } insertAt++; } // If we don't need to move it then we return if (cbInternalIndex is insertAt) { return; } break; } nextRow(iterator, true); } contributionList.remove(cast(Object) cbItem); // Adjust insertAt index if (cbInternalIndex < insertAt) { insertAt--; } // if we didn't find the row then add a new row if (currentRow !is targetRow) { contributionList.append(new Separator(USER_SEPARATOR)); insertAt = contributionList.size(); } insertAt = Math.min(insertAt, contributionList.size()); contributionList.addAt(insertAt, cast(Object) cbItem); } /** * Restores the canonical order of this cool bar manager. The canonical * order is the order in which the contribution items where added. */ public void resetItemOrder() { auto iterator = new ListIterator( cbItemsCreationOrder ); while( iterator.hasNext() ){ IContributionItem item = cast(IContributionItem) iterator.next(); // if its a user separator then do not include in original order. if ((item.getId() !is null) && (item.getId().equals(USER_SEPARATOR))) { iterator.remove(); } } setItems( arraycast!(IContributionItem)(cbItemsCreationOrder.toArray)); } /* * (non-Javadoc) * * @see dwtx.jface.action.ICoolBarManager#setContextMenuManager(dwtx.jface.action.IMenuManager) */ public void setContextMenuManager(IMenuManager contextMenuManager) { this.contextMenuManager = cast(MenuManager) contextMenuManager; if (coolBar !is null) { coolBar.setMenu(getContextMenuControl()); } } /** * Replaces the current items with the given items. * Forces an update. * * @param newItems the items with which to replace the current items */ public void setItems(IContributionItem[] newItems) { // dispose of all the cool items on the cool bar manager if (coolBar !is null) { CoolItem[] coolItems = coolBar.getItems(); for (int i = 0; i < coolItems.length; i++) { dispose(coolItems[i]); } } // Set the internal structure to this order internalSetItems(newItems); // Force and update update(true); } /* * (non-Javadoc) * * @see dwtx.jface.action.ICoolBarManager#lockLayout(bool) */ public void setLockLayout(bool value) { if (!coolBarExist()) { return; } coolBar.setLocked(value); } /** * Subclasses may extend this <code>IContributionManager</code> method, * but must call <code>super.update</code>. * * @see dwtx.jface.action.IContributionManager#update(bool) */ public void update(bool force) { if ((!isDirty() && !force) || (!coolBarExist())) { return; } bool relock = false; bool changed = false; try { coolBar.setRedraw(false); // Refresh the widget data with the internal data structure. refresh(); if (coolBar.getLocked()) { coolBar.setLocked(false); relock = true; } /* * Make a list of items including only those items that are * visible. Separators should stay because they mark line breaks in * a cool bar. */ IContributionItem[] items = getItems(); auto visibleItems = new ArraySeq!(Object); visibleItems.capacity(items.length); for (int i = 0; i < items.length; i++) { IContributionItem item = items[i]; if (item.isVisible()) { visibleItems.append(cast(Object)item); } } /* * Make a list of CoolItem widgets in the cool bar for which there * is no current visible contribution item. These are the widgets * to be disposed. Dynamic items are also removed. */ CoolItem[] coolItems = coolBar.getItems(); auto coolItemsToRemove = new ArraySeq!(Object); coolItemsToRemove.capacity(coolItems.length); for (int i = 0; i < coolItems.length; i++) { Object data = coolItems[i].getData(); if ((data is null) || (!visibleItems.contains(data)) || ((cast(IContributionItem)data ) && (cast(IContributionItem) data) .isDynamic())) { coolItemsToRemove.append(coolItems[i]); } } // Dispose of any items in the list to be removed. for (int i = coolItemsToRemove.size() - 1; i >= 0; i--) { CoolItem coolItem = cast(CoolItem) coolItemsToRemove.get(i); if (!coolItem.isDisposed()) { Control control = coolItem.getControl(); if (control !is null) { coolItem.setControl(null); control.dispose(); } coolItem.dispose(); } } // Add any new items by telling them to fill. coolItems = coolBar.getItems(); IContributionItem sourceItem; IContributionItem destinationItem; int sourceIndex = 0; int destinationIndex = 0; auto visibleItemItr = new ListIterator( visibleItems ); while (visibleItemItr.hasNext()) { sourceItem = cast(IContributionItem) visibleItemItr.next(); // Retrieve the corresponding contribution item from DWT's // data. if (sourceIndex < coolItems.length) { destinationItem = cast(IContributionItem) coolItems[sourceIndex] .getData(); } else { destinationItem = null; } // The items match is they are equal or both separators. if (destinationItem !is null) { if ((cast(Object)sourceItem).opEquals(cast(Object)destinationItem)) { sourceIndex++; destinationIndex++; sourceItem.update(); continue; } else if ((destinationItem.isSeparator()) && (sourceItem.isSeparator())) { coolItems[sourceIndex].setData(cast(Object)sourceItem); sourceIndex++; destinationIndex++; sourceItem.update(); continue; } } // Otherwise, a new item has to be added. int start = coolBar.getItemCount(); sourceItem.fill(coolBar, destinationIndex); int newItems = coolBar.getItemCount() - start; for (int i = 0; i < newItems; i++) { coolBar.getItem(destinationIndex++).setData(cast(Object)sourceItem); } changed = true; } // Remove any old widgets not accounted for. for (int i = coolItems.length - 1; i >= sourceIndex; i--) { final CoolItem item = coolItems[i]; if (!item.isDisposed()) { Control control = item.getControl(); if (control !is null) { item.setControl(null); control.dispose(); } item.dispose(); changed = true; } } // Update wrap indices. updateWrapIndices(); // Update the sizes. for (int i = 0; i < items.length; i++) { IContributionItem item = items[i]; item.update(SIZE); } // if the coolBar was previously locked then lock it if (relock) { coolBar.setLocked(true); } if (changed) { updateTabOrder(); } // We are no longer dirty. setDirty(false); } finally { coolBar.setRedraw(true); } } /** * Sets the tab order of the coolbar to the visual order of its items. */ /* package */void updateTabOrder() { if (coolBar !is null) { CoolItem[] items = coolBar.getItems(); if (items !is null) { auto children = new ArraySeq!(Object); children.capacity(items.length); for (int i = 0; i < items.length; i++) { if ((items[i].getControl() !is null) && (!items[i].getControl().isDisposed())) { children.append(items[i].getControl()); } } // Convert array Control[] childrenArray; childrenArray = arraycast!(Control)(children.toArray()); if (childrenArray !is null) { coolBar.setTabList(childrenArray); } } } } /** * Updates the indices at which the cool bar should wrap. */ private void updateWrapIndices() { final IContributionItem[] items = getItems(); final int numRows = getNumRows(items) - 1; // Generate the list of wrap indices. final int[] wrapIndices = new int[numRows]; bool foundSeparator = false; int j = 0; CoolItem[] coolItems = (coolBar is null) ? null : coolBar.getItems(); for (int i = 0; i < items.length; i++) { IContributionItem item = items[i]; CoolItem coolItem = findCoolItem(coolItems, item); if (item.isSeparator()) { foundSeparator = true; } if ((!item.isSeparator()) && (!item.isGroupMarker()) && (item.isVisible()) && (coolItem !is null) && (foundSeparator)) { wrapIndices[j] = coolBar.indexOf(coolItem); j++; foundSeparator = false; } } /* * Check to see if these new wrap indices are different than the old * ones. */ final int[] oldIndices = coolBar.getWrapIndices(); bool shouldUpdate = false; if (oldIndices.length is wrapIndices.length) { for (int i = 0; i < oldIndices.length; i++) { if (oldIndices[i] !is wrapIndices[i]) { shouldUpdate = true; break; } } } else { shouldUpdate = true; } if (shouldUpdate) { coolBar.setWrapIndices(wrapIndices); } } }