All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.swt.widgets.CoolBar Maven / Gradle / Ivy

Go to download

The osx x86_64 swt jar as available in the Eclipse 4.6 (Neon) release for OSX. It is suitable for use with jface and other dependencies available from maven central in the org.eclipse.scout.sdk.deps group. The sources is copied from swt-4.6-cocoa-macosx-x86_64.zip from http://download.eclipse.org/eclipse/downloads/drops4/R-4.6-201606061100/ and javadoc is generated from sources.

The newest version!
/*******************************************************************************
 * Copyright (c) 2000, 2016 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
 *******************************************************************************/
package org.eclipse.swt.widgets;


import org.eclipse.swt.*;
import org.eclipse.swt.graphics.*;

/**
 * Instances of this class provide an area for dynamically
 * positioning the items they contain.
 * 

* The item children that may be added to instances of this class * must be of type CoolItem. *

* Note that although this class is a subclass of Composite, * it does not make sense to add Control children to it, * or set a layout on it. *

*

*
Styles:
*
FLAT, HORIZONTAL, VERTICAL
*
Events:
*
(none)
*
*

* Note: Only one of the styles HORIZONTAL and VERTICAL may be specified. *

* IMPORTANT: This class is not intended to be subclassed. *

* * @see CoolBar snippets * @see SWT Example: ControlExample * @see Sample code and further information * @noextend This class is not intended to be subclassed by clients. */ public class CoolBar extends Composite { CoolItem[][] items = new CoolItem[0][0]; CoolItem[] originalItems = new CoolItem[0]; Cursor hoverCursor, dragCursor, cursor; CoolItem dragging = null; int mouseXOffset, itemXOffset; boolean isLocked = false; boolean inDispose = false; static final int ROW_SPACING = 2; static final int CLICK_DISTANCE = 3; static final int DEFAULT_COOLBAR_WIDTH = 0; static final int DEFAULT_COOLBAR_HEIGHT = 0; /** * Constructs a new instance of this class given its parent * and a style value describing its behavior and appearance. *

* The style value is either one of the style constants defined in * class SWT which is applicable to instances of this * class, or must be built by bitwise OR'ing together * (that is, using the int "|" operator) two or more * of those SWT style constants. The class description * lists the style constants that are applicable to the class. * Style bits are also inherited from superclasses. *

* * @param parent a composite control which will be the parent of the new instance (cannot be null) * @param style the style of control to construct * * @exception IllegalArgumentException
    *
  • ERROR_NULL_ARGUMENT - if the parent is null
  • *
* @exception SWTException
    *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent
  • *
  • ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass
  • *
* * @see SWT * @see SWT#FLAT * @see SWT#HORIZONTAL * @see SWT#VERTICAL * @see Widget#checkSubclass * @see Widget#getStyle */ public CoolBar (Composite parent, int style) { super (parent, checkStyle(style)); if ((style & SWT.VERTICAL) != 0) { this.style |= SWT.VERTICAL; hoverCursor = new Cursor(display, SWT.CURSOR_SIZENS); } else { this.style |= SWT.HORIZONTAL; hoverCursor = new Cursor(display, SWT.CURSOR_SIZEWE); } dragCursor = new Cursor(display, SWT.CURSOR_SIZEALL); Listener listener = new Listener() { @Override public void handleEvent(Event event) { switch (event.type) { case SWT.Dispose: onDispose(event); break; case SWT.MouseDown: onMouseDown(event); break; case SWT.MouseExit: onMouseExit(); break; case SWT.MouseMove: onMouseMove(event); break; case SWT.MouseUp: onMouseUp(event); break; case SWT.MouseDoubleClick: onMouseDoubleClick(event); break; case SWT.Paint: onPaint(event); break; case SWT.Resize: onResize(); break; } } }; int[] events = new int[] { SWT.Dispose, SWT.MouseDown, SWT.MouseExit, SWT.MouseMove, SWT.MouseUp, SWT.MouseDoubleClick, SWT.Paint, SWT.Resize }; for (int i = 0; i < events.length; i++) { addListener(events[i], listener); } } static int checkStyle (int style) { style |= SWT.NO_FOCUS; return (style | SWT.NO_REDRAW_RESIZE) & ~(SWT.V_SCROLL | SWT.H_SCROLL); } void _setCursor (Cursor cursor) { if (this.cursor != null) return; super.setCursor (cursor); } @Override protected void checkSubclass () { if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS); } @Override public Point computeSize (int wHint, int hHint, boolean changed) { checkWidget(); int width = 0, height = 0; wrapItems((style & SWT.VERTICAL) != 0 ? hHint : wHint); boolean flat = (style & SWT.FLAT) != 0; for (int row = 0; row < items.length; row++) { int rowWidth = 0, rowHeight = 0; for (int i = 0; i < items[row].length; i++) { CoolItem item = items[row][i]; rowWidth += item.preferredWidth; rowHeight = Math.max(rowHeight, item.preferredHeight); } height += rowHeight; if (!flat && row > 0) height += ROW_SPACING; width = Math.max(width, rowWidth); } wrapItems(getWidth()); if (width == 0) width = DEFAULT_COOLBAR_WIDTH; if (height == 0) height = DEFAULT_COOLBAR_HEIGHT; Point size = fixPoint(width, height); if (wHint != SWT.DEFAULT) size.x = wHint; if (hHint != SWT.DEFAULT) size.y = hHint; Rectangle trim = computeTrim(0, 0, size.x, size.y); return new Point(trim.width, trim.height); } CoolItem getGrabbedItem(int x, int y) { for (int row = 0; row < items.length; row++) { for (int i = 0; i < items[row].length; i++) { CoolItem item = items[row][i]; Rectangle bounds = item.internalGetBounds(); bounds.width = CoolItem.MINIMUM_WIDTH; if (bounds.x > x) break; if (bounds.y > y) return null; if (bounds.contains(x, y)) { return item; } } } return null; } /** * Returns the item that is currently displayed at the given, * zero-relative index. Throws an exception if the index is * out of range. * * @param index the visual index of the item to return * @return the item at the given visual index * * @exception IllegalArgumentException
    *
  • ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the list minus 1 (inclusive)
  • *
* @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
*/ public CoolItem getItem (int index) { checkWidget(); if (index < 0) error (SWT.ERROR_INVALID_RANGE); for (int row = 0; row < items.length; row++) { if (items[row].length > index) { return items[row][index]; } else { index -= items[row].length; } } error (SWT.ERROR_INVALID_RANGE); return null; } /** * Returns the number of items contained in the receiver. * * @return the number of items * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
*/ public int getItemCount () { checkWidget(); return originalItems.length; } /** * Returns an array of CoolItems in the order * in which they are currently being displayed. *

* Note: This is not the actual structure used by the receiver * to maintain its list of items, so modifying the array will * not affect the receiver. *

* * @return the receiver's items in their current visual order * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
*/ public CoolItem [] getItems () { checkWidget(); CoolItem [] result = new CoolItem [getItemCount()]; int offset = 0; for (int row = 0; row < items.length; row++) { System.arraycopy(items[row], 0, result, offset, items[row].length); offset += items[row].length; } return result; } Point findItem (CoolItem item) { for (int row = 0; row < items.length; row++) { for (int i = 0; i < items[row].length; i++) { if (items[row][i].equals(item)) return new Point(i, row); } } return new Point(-1, -1); } void fixEvent (Event event) { if ((style & SWT.VERTICAL) != 0) { int tmp = event.x; event.x = event.y; event.y = tmp; } } Rectangle fixRectangle (int x, int y, int width, int height) { if ((style & SWT.VERTICAL) != 0) { return new Rectangle(y, x, height, width); } return new Rectangle(x, y, width, height); } Point fixPoint (int x, int y) { if ((style & SWT.VERTICAL) != 0) { return new Point(y, x); } return new Point(x, y); } /** * Searches the receiver's items in the order they are currently * being displayed, starting at the first item (index 0), until * an item is found that is equal to the argument, and returns * the index of that item. If no item is found, returns -1. * * @param item the search item * @return the visual order index of the search item, or -1 if the item is not found * * @exception IllegalArgumentException
    *
  • ERROR_NULL_ARGUMENT - if the item is null
  • *
  • ERROR_INVALID_ARGUMENT - if the item is disposed
  • *
* @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
*/ public int indexOf (CoolItem item) { checkWidget(); if (item == null) error (SWT.ERROR_NULL_ARGUMENT); if (item.isDisposed()) error (SWT.ERROR_INVALID_ARGUMENT); int answer = 0; for (int row = 0; row < items.length; row++) { for (int i = 0; i < items[row].length; i++) { if (items[row][i].equals(item)) { return answer; } else { answer++; } } } return -1; } /** * Insert the item into the row. Adjust the x and width values * appropriately. */ boolean insertItemIntoRow(CoolItem item, int rowIndex, int x_root) { if (rowIndex < 0 || rowIndex >= items.length) { /* Create a new row for the item. */ boolean bottom = rowIndex >= items.length; CoolItem[][] newRows = new CoolItem[items.length + 1][]; System.arraycopy(items, 0, newRows, bottom ? 0 : 1, items.length); int row = bottom ? items.length : 0; newRows[row] = new CoolItem[1]; newRows[row][0] = item; items = newRows; item.wrap = true; return true; } int barWidth = getWidth(); Rectangle bounds = items[rowIndex][0].internalGetBounds(); int rowY = bounds.y; int oldRowHeight = bounds.height; int x = Math.max(0, Math.abs(x_root - toDisplay(new Point(0, 0)).x)); /* Find the insertion index and add the item. */ int index; for (index = 0; index < items[rowIndex].length; index++) { if (x < items[rowIndex][index].internalGetBounds().x) break; } if (index == 0) { item.wrap = true; items[rowIndex][0].wrap = false; } int oldLength = items[rowIndex].length; CoolItem[] newRow = new CoolItem[oldLength + 1]; System.arraycopy(items[rowIndex], 0, newRow, 0, index); newRow[index] = item; System.arraycopy(items[rowIndex], index, newRow, index + 1, oldLength - index); items[rowIndex] = newRow; /* Adjust the width of the item to the left. */ if (index > 0) { CoolItem left = items[rowIndex][index - 1]; Rectangle leftBounds = left.internalGetBounds(); int newWidth = x - leftBounds.x; if (newWidth < left.internalGetMinimumWidth()) { x += left.internalGetMinimumWidth() - newWidth; newWidth = left.internalGetMinimumWidth(); } left.setBounds(leftBounds.x, leftBounds.y, newWidth, leftBounds.height); left.requestedWidth = newWidth; } /* Set the item's bounds. */ int width = 0, height = item.preferredHeight; if (index < items[rowIndex].length - 1) { CoolItem right = items[rowIndex][index + 1]; width = right.internalGetBounds().x - x; if (width < right.internalGetMinimumWidth()) { moveRight(right, right.internalGetMinimumWidth() - width); width = right.internalGetBounds().x - x; } item.setBounds(x, rowY, width, height); if (width < item.internalGetMinimumWidth()) moveLeft(item, item.internalGetMinimumWidth() - width); } else { width = Math.max(item.internalGetMinimumWidth(), barWidth - x); item.setBounds(x, rowY, width, height); if (x + width > barWidth) moveLeft(item, x + width - barWidth); } bounds = item.internalGetBounds(); item.requestedWidth = bounds.width; internalRedraw(bounds.x, bounds.y, item.internalGetMinimumWidth(), bounds.height); return height > oldRowHeight; } void internalRedraw (int x, int y, int width, int height) { if ((style & SWT.VERTICAL) != 0) { redraw (y, x, height, width, false); } else { redraw (x, y, width, height, false); } } void createItem (CoolItem item, int index) { int itemCount = getItemCount(), row = 0; if (!(0 <= index && index <= itemCount)) error (SWT.ERROR_INVALID_RANGE); if (items.length == 0) { items = new CoolItem[1][1]; items[0][0] = item; } else { int i = index; /* find the row to insert into */ if (index < itemCount) { while (i > items[row].length) { i -= items[row].length; row++; } } else { row = items.length - 1; i = items[row].length; } // Set the last item in the row to the preferred size // and add the new one just to it's right int lastIndex = items[row].length - 1; CoolItem lastItem = items[row][lastIndex]; if (lastItem.ideal) { Rectangle bounds = lastItem.internalGetBounds(); bounds.width = lastItem.preferredWidth; bounds.height = lastItem.preferredHeight; lastItem.requestedWidth = lastItem.preferredWidth; lastItem.setBounds(bounds.x, bounds.y, bounds.width, bounds.height); } if (i == 0) { item.wrap = true; items[row][0].wrap = false; } int oldLength = items[row].length; CoolItem[] newRow = new CoolItem[oldLength + 1]; System.arraycopy(items[row], 0, newRow, 0, i); newRow[i] = item; System.arraycopy(items[row], i, newRow, i + 1, oldLength - i); items[row] = newRow; } item.requestedWidth = CoolItem.MINIMUM_WIDTH; int length = originalItems.length; CoolItem [] newOriginals = new CoolItem [length + 1]; System.arraycopy (originalItems, 0, newOriginals, 0, index); System.arraycopy (originalItems, index, newOriginals, index + 1, length - index); newOriginals [index] = item; originalItems = newOriginals; layoutItems(); } void destroyItem(CoolItem item) { if (inDispose) return; int row = findItem(item).y; if (row == -1) return; Rectangle bounds = item.internalGetBounds(); removeItemFromRow(item, row, true); int index = 0; while (index < originalItems.length) { if (originalItems [index] == item) break; index++; } int length = originalItems.length - 1; CoolItem [] newOriginals = new CoolItem [length]; System.arraycopy (originalItems, 0, newOriginals, 0, index); System.arraycopy (originalItems, index + 1, newOriginals, index, length - index); originalItems = newOriginals; internalRedraw(bounds.x, bounds.y, CoolItem.MINIMUM_WIDTH, bounds.height); relayout(); } void moveDown(CoolItem item, int x_root) { int oldRowIndex = findItem(item).y; if (items[oldRowIndex].length == 1) { /* If this is the only item in the bottom row, don't move it. */ if (oldRowIndex == items.length - 1) return; } int newRowIndex = (items[oldRowIndex].length == 1) ? oldRowIndex : oldRowIndex + 1; boolean resize = removeItemFromRow(item, oldRowIndex, false); Rectangle old = item.internalGetBounds(); internalRedraw(old.x, old.y, CoolItem.MINIMUM_WIDTH, old.height); resize |= insertItemIntoRow(item, newRowIndex, x_root); if (resize) { relayout(); } else { layoutItems(); } } void moveLeft(CoolItem item, int pixels) { Point point = findItem(item); int row = point.y; int index = point.x; if (index == 0) return; Rectangle bounds = item.internalGetBounds(); int minSpaceOnLeft = 0; for (int i = 0; i < index; i++) { minSpaceOnLeft += items[row][i].internalGetMinimumWidth(); } int x = Math.max(minSpaceOnLeft, bounds.x - pixels); CoolItem left = items[row][index - 1]; Rectangle leftBounds = left.internalGetBounds(); if (leftBounds.x + left.internalGetMinimumWidth() > x) { int shift = leftBounds.x + left.internalGetMinimumWidth() - x; moveLeft(left, shift); leftBounds = left.internalGetBounds(); } int leftWidth = Math.max(left.internalGetMinimumWidth(), leftBounds.width - pixels); left.setBounds(leftBounds.x, leftBounds.y, leftWidth, leftBounds.height); left.requestedWidth = leftWidth; int width = bounds.width + (bounds.x - x); item.setBounds(x, bounds.y, width, bounds.height); item.requestedWidth = width; int damagedWidth = bounds.x - x + CoolItem.MINIMUM_WIDTH; if (damagedWidth > CoolItem.MINIMUM_WIDTH) { internalRedraw(x, bounds.y, damagedWidth, bounds.height); } } void moveRight(CoolItem item, int pixels) { Point point = findItem(item); int row = point.y; int index = point.x; if (index == 0) return; Rectangle bounds = item.internalGetBounds(); int minSpaceOnRight = 0; for (int i = index; i < items[row].length; i++) { minSpaceOnRight += items[row][i].internalGetMinimumWidth(); } int max = getWidth() - minSpaceOnRight; int x = Math.min(max, bounds.x + pixels); int width = 0; if (index + 1 == items[row].length) { width = getWidth() - x; } else { CoolItem right = items[row][index + 1]; Rectangle rightBounds = right.internalGetBounds(); if (x + item.internalGetMinimumWidth() > rightBounds.x) { int shift = x + item.internalGetMinimumWidth() - rightBounds.x; moveRight(right, shift); rightBounds = right.internalGetBounds(); } width = rightBounds.x - x; } item.setBounds(x, bounds.y, width, bounds.height); item.requestedWidth = width; CoolItem left = items[row][index - 1]; Rectangle leftBounds = left.internalGetBounds(); int leftWidth = x - leftBounds.x; left.setBounds(leftBounds.x, leftBounds.y, leftWidth, leftBounds.height); left.requestedWidth = leftWidth; int damagedWidth = x - bounds.x + CoolItem.MINIMUM_WIDTH + CoolItem.MARGIN_WIDTH; if (x - bounds.x > 0) { internalRedraw(bounds.x - CoolItem.MARGIN_WIDTH, bounds.y, damagedWidth, bounds.height); } } void moveUp(CoolItem item, int x_root) { Point point = findItem(item); int oldRowIndex = point.y; if (items[oldRowIndex].length == 1) { /* If this is the only item in the top row, don't move it. */ if (oldRowIndex == 0) return; } boolean resize = removeItemFromRow(item, oldRowIndex, false); Rectangle old = item.internalGetBounds(); internalRedraw(old.x, old.y, CoolItem.MINIMUM_WIDTH, old.height); int newRowIndex = oldRowIndex - 1; resize |= insertItemIntoRow(item, newRowIndex, x_root); if (resize) { relayout(); } else { layoutItems(); } } void onDispose(Event event) { /* * Usually when an item is disposed, destroyItem will change the size of the items array * and reset the bounds of all the remaining cool items. * Since the whole cool bar is being disposed, this is not necessary. For speed * the inDispose flag is used to skip over this part of the item dispose. */ if (inDispose) return; inDispose = true; notifyListeners(SWT.Dispose, event); event.type = SWT.None; for (int i = 0; i < items.length; i++) { for (int j = 0; j < items[i].length; j++) { items[i][j].dispose(); } } hoverCursor.dispose(); dragCursor.dispose(); cursor = null; } void onMouseDown(Event event) { if (isLocked || event.button != 1) return; fixEvent(event); dragging = getGrabbedItem(event.x, event.y); if (dragging != null) { mouseXOffset = event.x; itemXOffset = mouseXOffset - dragging.internalGetBounds().x; _setCursor(dragCursor); } fixEvent(event); } void onMouseExit() { if (dragging == null) _setCursor(null); } void onMouseMove(Event event) { if (isLocked) return; fixEvent(event); CoolItem grabbed = getGrabbedItem(event.x, event.y); if (dragging != null) { int left_root = toDisplay(new Point(event.x - itemXOffset, event.y)).x; Rectangle bounds = dragging.internalGetBounds(); if (event.y < bounds.y) { moveUp(dragging, left_root); } else if (event.y > bounds.y + bounds.height){ moveDown(dragging, left_root); } else if (event.x < mouseXOffset) { int distance = Math.min(mouseXOffset, bounds.x + itemXOffset) - event.x; if (distance > 0) moveLeft(dragging, distance); } else if (event.x > mouseXOffset) { int distance = event.x - Math.max(mouseXOffset, bounds.x + itemXOffset); if (distance > 0) moveRight(dragging, distance); } mouseXOffset = event.x; } else { if (grabbed != null) { _setCursor(hoverCursor); } else { _setCursor(null); } } fixEvent(event); } void onMouseUp(Event event) { dragging = null; CoolItem grabbed = getGrabbedItem(event.x, event.y); if (grabbed != null) { _setCursor(hoverCursor); } else { _setCursor(null); } } void onMouseDoubleClick(Event event) { if (isLocked) return; dragging = null; fixEvent(event); CoolItem target = getGrabbedItem(event.x, event.y); if (target == null) { _setCursor(null); } else { Point location = findItem(target); int row = location.y; int index = location.x; if (items[row].length > 1) { Rectangle bounds = target.internalGetBounds(); int maxSize = getWidth (); for (int i = 0; i < items[row].length; i++) { if (i != index) { maxSize -= items[row][i].internalGetMinimumWidth(); } } if (bounds.width == maxSize) { /* The item is at its maximum width. It should be resized to its minimum width. */ int distance = bounds.width - target.internalGetMinimumWidth(); if (index + 1 < items[row].length) { /* There is an item to the right. Maximize it. */ CoolItem right = items[row][index + 1]; moveLeft(right, distance); } else { /* There is no item to the right. Move the item all the way right. */ moveRight(target, distance); } } else if (bounds.width < target.preferredWidth) { /* The item is less than its preferredWidth. Resize to preferredWidth. */ int distance = target.preferredWidth - bounds.width; if (index + 1 < items[row].length) { CoolItem right = items[row][index + 1]; moveRight(right, distance); distance = target.preferredWidth - target.internalGetBounds().width; } if (distance > 0) { moveLeft(target, distance); } } else { /* The item is at its minimum width. Maximize it. */ for (int i = 0; i < items[row].length; i++) { if (i != index) { CoolItem item = items[row][i]; item.requestedWidth = Math.max(item.internalGetMinimumWidth(), CoolItem.MINIMUM_WIDTH); } } target.requestedWidth = maxSize; layoutItems(); } _setCursor(hoverCursor); } } fixEvent(event); } void onPaint(Event event) { GC gc = event.gc; if (items.length == 0) return; Color shadowColor = display.getSystemColor(SWT.COLOR_WIDGET_NORMAL_SHADOW); Color highlightColor = display.getSystemColor(SWT.COLOR_WIDGET_HIGHLIGHT_SHADOW); boolean vertical = (style & SWT.VERTICAL) != 0; boolean flat = (style & SWT.FLAT) != 0; int stopX = getWidth(); Rectangle rect; Rectangle clipping = gc.getClipping(); for (int row = 0; row < items.length; row++) { Rectangle bounds = new Rectangle(0, 0, 0, 0); for (int i = 0; i < items[row].length; i++) { bounds = items[row][i].internalGetBounds(); rect = fixRectangle(bounds.x, bounds.y, bounds.width, bounds.height); if (!clipping.intersects(rect)) continue; boolean nativeGripper = false; /* Draw gripper. */ if (!isLocked) { rect = fixRectangle(bounds.x, bounds.y, CoolItem.MINIMUM_WIDTH, bounds.height); if (!flat) nativeGripper = drawGripper(gc, rect.x, rect.y, rect.width, rect.height, vertical); if (!nativeGripper) { int grabberTrim = 2; int grabberHeight = bounds.height - (2 * grabberTrim) - 1; gc.setForeground(shadowColor); rect = fixRectangle( bounds.x + CoolItem.MARGIN_WIDTH, bounds.y + grabberTrim, 2, grabberHeight); gc.drawRectangle(rect); gc.setForeground(highlightColor); rect = fixRectangle( bounds.x + CoolItem.MARGIN_WIDTH, bounds.y + grabberTrim + 1, bounds.x + CoolItem.MARGIN_WIDTH, bounds.y + grabberTrim + grabberHeight - 1); gc.drawLine(rect.x, rect.y, rect.width, rect.height); rect = fixRectangle( bounds.x + CoolItem.MARGIN_WIDTH, bounds.y + grabberTrim, bounds.x + CoolItem.MARGIN_WIDTH + 1, bounds.y + grabberTrim); gc.drawLine(rect.x, rect.y, rect.width, rect.height); } } /* Draw separator. */ if (!flat && !nativeGripper && i != 0) { gc.setForeground(shadowColor); rect = fixRectangle(bounds.x, bounds.y, bounds.x, bounds.y + bounds.height - 1); gc.drawLine(rect.x, rect.y, rect.width, rect.height); gc.setForeground(highlightColor); rect = fixRectangle(bounds.x + 1, bounds.y, bounds.x + 1, bounds.y + bounds.height - 1); gc.drawLine(rect.x, rect.y, rect.width, rect.height); } } if (!flat && row + 1 < items.length) { /* Draw row separator. */ int separatorY = bounds.y + bounds.height; gc.setForeground(shadowColor); rect = fixRectangle(0, separatorY, stopX, separatorY); gc.drawLine(rect.x, rect.y, rect.width, rect.height); gc.setForeground(highlightColor); rect = fixRectangle(0, separatorY + 1, stopX, separatorY + 1); gc.drawLine(rect.x, rect.y, rect.width, rect.height); } } } void onResize () { layoutItems (); } @Override void removeControl (Control control) { super.removeControl (control); CoolItem [] items = getItems (); for (int i=0; i 0) { CoolItem[] newRow = new CoolItem[newLength]; System.arraycopy(items[rowIndex], 0, newRow, 0, index); System.arraycopy(items[rowIndex], index + 1, newRow, index, newRow.length - index); items[rowIndex] = newRow; items[rowIndex][0].wrap = true; } else { CoolItem[][] newRows = new CoolItem[items.length - 1][]; System.arraycopy(items, 0, newRows, 0, rowIndex); System.arraycopy(items, rowIndex + 1, newRows, rowIndex, newRows.length - rowIndex); items = newRows; return true; } if (!disposed) { if (index == 0) { CoolItem first = items[rowIndex][0]; Rectangle bounds = first.internalGetBounds(); int width = bounds.x + bounds.width; first.setBounds(0, bounds.y, width, bounds.height); first.requestedWidth = width; internalRedraw(bounds.x, bounds.y, CoolItem.MINIMUM_WIDTH, bounds.height); } else { CoolItem previous = items[rowIndex][index - 1]; Rectangle bounds = previous.internalGetBounds(); int width = bounds.width + itemBounds.width; previous.setBounds(bounds.x, bounds.y, width, bounds.height); previous.requestedWidth = width; } } int newRowHeight = 0; for (int i = 0; i < newLength; i++) { newRowHeight = Math.max(newRowHeight, items[rowIndex][i].preferredHeight); } return newRowHeight != oldRowHeight; } /** * Return the height of the bar after it has * been properly laid out for the given width. */ int layoutItems () { int y = 0, width; if ((style&SWT.VERTICAL) != 0) { width = getClientArea().height; } else { width = getClientArea().width; } wrapItems(width); int rowSpacing = (style & SWT.FLAT) != 0 ? 0 : ROW_SPACING; for (int row = 0; row < items.length; row++) { int count = items[row].length; int x = 0; /* determine the height and the available width for the row */ int rowHeight = 0; int available = width; for (int i = 0; i < count; i++) { CoolItem item = items[row][i]; rowHeight = Math.max(rowHeight, item.preferredHeight); available -= item.internalGetMinimumWidth(); } if (row > 0) y += rowSpacing; /* lay the items out */ for (int i = 0; i < count; i++) { CoolItem child = items[row][i]; int newWidth = available + child.internalGetMinimumWidth(); if (i + 1 < count) { newWidth = Math.min(newWidth, child.requestedWidth); available -= (newWidth - child.internalGetMinimumWidth()); } Rectangle oldBounds = child.internalGetBounds(); Rectangle newBounds = new Rectangle(x, y, newWidth, rowHeight); if (!oldBounds.equals(newBounds)) { child.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height); Rectangle damage = new Rectangle(0, 0, 0, 0); /* Cases are in descending order from most area to redraw to least. */ if (oldBounds.y != newBounds.y) { damage = newBounds; damage.add(oldBounds); /* Redraw the row separator as well. */ damage.y -= rowSpacing; damage.height += 2 * rowSpacing; } else if (oldBounds.height != newBounds.height) { /* * Draw from the bottom of the gripper to the bottom of the new area. * (Bottom of the gripper is -3 from the bottom of the item). */ damage.y = newBounds.y + Math.min(oldBounds.height, newBounds.height) - 3; damage.height = newBounds.y + newBounds.height + rowSpacing; damage.x = oldBounds.x - CoolItem.MARGIN_WIDTH; damage.width = oldBounds.width + CoolItem.MARGIN_WIDTH; } else if (oldBounds.x != newBounds.x) { /* Redraw only the difference between the separators. */ damage.x = Math.min(oldBounds.x, newBounds.x); damage.width = Math.abs(oldBounds.x - newBounds.x) + CoolItem.MINIMUM_WIDTH; damage.y = oldBounds.y; damage.height = oldBounds.height; } internalRedraw(damage.x, damage.y, damage.width, damage.height); } x += newWidth; } y += rowHeight; } return y; } void relayout() { Point size = getSize(); int height = layoutItems(); if ((style & SWT.VERTICAL) != 0) { Rectangle trim = computeTrim (0, 0, height, 0); if (height != size.x) super.setSize(trim.width, size.y); } else { Rectangle trim = computeTrim (0, 0, 0, height); if (height != size.y) super.setSize(size.x, trim.height); } } /** * Returns an array of zero-relative ints that map * the creation order of the receiver's items to the * order in which they are currently being displayed. *

* Specifically, the indices of the returned array represent * the current visual order of the items, and the contents * of the array represent the creation order of the items. *

* Note: This is not the actual structure used by the receiver * to maintain its list of items, so modifying the array will * not affect the receiver. *

* * @return the current visual order of the receiver's items * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
*/ public int[] getItemOrder () { checkWidget (); int count = getItemCount (); int [] indices = new int [count]; count = 0; for (int i = 0; i < items.length; i++) { for (int j = 0; j < items[i].length; j++) { CoolItem item = items[i][j]; int index = 0; while (index= count) error (SWT.ERROR_INVALID_ARGUMENT); if (set [itemOrder [i]]) error (SWT.ERROR_INVALID_ARGUMENT); set [itemOrder [i]] = true; } CoolItem[] row = new CoolItem[count]; for (int i = 0; i < count; i++) { row[i] = originalItems[itemOrder[i]]; } items = new CoolItem[1][count]; items[0] = row; } /** * Returns an array of points whose x and y coordinates describe * the widths and heights (respectively) of the items in the receiver * in the order in which they are currently being displayed. * * @return the receiver's item sizes in their current visual order * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
*/ public Point[] getItemSizes () { checkWidget(); CoolItem[] items = getItems(); Point[] sizes = new Point[items.length]; for (int i = 0; i < items.length; i++) { sizes[i] = items[i].getSize(); } return sizes; } void setItemSizes (Point[] sizes) { if (sizes == null) error(SWT.ERROR_NULL_ARGUMENT); CoolItem[] items = getItems(); if (sizes.length != items.length) error(SWT.ERROR_INVALID_ARGUMENT); for (int i = 0; i < items.length; i++) { items[i].setSize(sizes[i]); } } /** * Returns whether or not the receiver is 'locked'. When a coolbar * is locked, its items cannot be repositioned. * * @return true if the coolbar is locked, false otherwise * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
* * @since 2.0 */ public boolean getLocked () { checkWidget (); return isLocked; } int getWidth () { if ((style & SWT.VERTICAL) != 0) return getSize().y; return getSize().x; } /** * Returns an array of ints that describe the zero-relative * indices of any item(s) in the receiver that will begin on * a new row. The 0th visible item always begins the first row, * therefore it does not count as a wrap index. * * @return an array containing the receiver's wrap indices, or an empty array if all items are in one row * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
*/ public int[] getWrapIndices () { checkWidget(); if (items.length <= 1) return new int[]{}; int[] wrapIndices = new int[items.length - 1]; int i = 0, nextWrap = items[0].length; for (int row = 1; row < items.length; row++) { if (items[row][0].wrap) wrapIndices[i++] = nextWrap; nextWrap += items[row].length; } if (i != wrapIndices.length) { int[] tmp = new int[i]; System.arraycopy(wrapIndices, 0, tmp, 0, i); return tmp; } return wrapIndices; } /** * Sets whether or not the receiver is 'locked'. When a coolbar * is locked, its items cannot be repositioned. * * @param locked lock the coolbar if true, otherwise unlock the coolbar * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
* * @since 2.0 */ public void setLocked (boolean locked) { checkWidget (); if (isLocked != locked) { redraw(); } isLocked = locked; } /** * Sets the indices of all item(s) in the receiver that will * begin on a new row. The indices are given in the order in * which they are currently being displayed. The 0th item * always begins the first row, therefore it does not count * as a wrap index. If indices is null or empty, the items * will be placed on one line. * * @param indices an array of wrap indices, or null * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
*/ public void setWrapIndices (int[] indices) { checkWidget(); if (indices == null) indices = new int[0]; int count = originalItems.length; for (int i=0; i= count) { error (SWT.ERROR_INVALID_ARGUMENT); } } for (int i=0; i index) { items[row][index].wrap = true; break; } else { index -= items[row].length; } } } relayout(); } @Override void reskinChildren (int flags) { if (items != null) { for (int row = 0; row < items.length; row++) { for (int i = 0; i < items[row].length; i++) { CoolItem item = items[row][i]; if (item != null) item.reskin (flags); } } } super.reskinChildren (flags); } @Override public void setCursor (Cursor cursor) { checkWidget (); super.setCursor (this.cursor = cursor); } /** * Sets the receiver's item order, wrap indices, and item sizes * all at once. This method is typically used to restore the * displayed state of the receiver to a previously stored state. *

* The item order is the order in which the items in the receiver * should be displayed, given in terms of the zero-relative ordering * of when the items were added. *

* The wrap indices are the indices of all item(s) in the receiver * that will begin on a new row. The indices are given in the order * specified by the item order. The 0th item always begins the first * row, therefore it does not count as a wrap index. If wrap indices * is null or empty, the items will be placed on one line. *

* The sizes are specified in an array of points whose x and y * coordinates describe the new widths and heights (respectively) * of the receiver's items in the order specified by the item order. *

* * @param itemOrder an array of indices that describe the new order to display the items in * @param wrapIndices an array of wrap indices, or null * @param sizes an array containing the new sizes for each of the receiver's items in visual order * * @exception SWTException
    *
  • ERROR_WIDGET_DISPOSED - if the receiver has been disposed
  • *
  • ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver
  • *
* @exception IllegalArgumentException
    *
  • ERROR_NULL_ARGUMENT - if item order or sizes is null
  • *
  • ERROR_INVALID_ARGUMENT - if item order or sizes is not the same length as the number of items
  • *
*/ public void setItemLayout (int[] itemOrder, int[] wrapIndices, Point[] sizes) { checkWidget(); setItemOrder(itemOrder); setWrapIndices(wrapIndices); setItemSizes(sizes); relayout(); } @Override public void setOrientation (int orientation) { super.setOrientation(orientation); for (int row = 0; row < items.length; row++) { for (int column = 0; column < items[row].length; column++) { CoolItem item = items[row][column]; if (item.arrowImage != null) { item.arrowImage.dispose(); item.arrowImage = null; } item.updateChevron(); } } } void wrapItems (int maxWidth) { int itemCount = originalItems.length; if (itemCount < 2) return; CoolItem[] itemsVisual = new CoolItem[itemCount]; int start = 0; for (int row = 0; row < items.length; row++) { System.arraycopy(items[row], 0, itemsVisual, start, items[row].length); start += items[row].length; } CoolItem[][] newItems = new CoolItem[itemCount][]; int rowCount = 0, rowWidth = 0; start = 0; for (int i = 0; i < itemCount; i++) { CoolItem item = itemsVisual[i]; int itemWidth = item.internalGetMinimumWidth(); if ((i > 0 && item.wrap) || (maxWidth != SWT.DEFAULT && rowWidth + itemWidth > maxWidth)) { if (i == start) { newItems[rowCount] = new CoolItem[1]; newItems[rowCount][0] = item; start = i + 1; rowWidth = 0; } else { int count = i - start; newItems[rowCount] = new CoolItem[count]; System.arraycopy(itemsVisual, start, newItems[rowCount], 0, count); start = i; rowWidth = itemWidth; } rowCount++; } else { rowWidth += itemWidth; } } if (start < itemCount) { int count = itemCount - start; newItems[rowCount] = new CoolItem[count]; System.arraycopy(itemsVisual, start, newItems[rowCount], 0, count); rowCount++; } if (newItems.length != rowCount) { CoolItem[][] tmp = new CoolItem[rowCount][]; System.arraycopy(newItems, 0, tmp, 0, rowCount); items = tmp; } else { items = newItems; } } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy