338147 - Update CTabFolder tab management
diff --git a/bundles/org.eclipse.e4.ui.widgets/src/org/eclipse/e4/ui/widgets/CTabFolder.java b/bundles/org.eclipse.e4.ui.widgets/src/org/eclipse/e4/ui/widgets/CTabFolder.java
index 5cf1c95..10ab6c0 100644
--- a/bundles/org.eclipse.e4.ui.widgets/src/org/eclipse/e4/ui/widgets/CTabFolder.java
+++ b/bundles/org.eclipse.e4.ui.widgets/src/org/eclipse/e4/ui/widgets/CTabFolder.java
@@ -148,33 +148,32 @@
boolean showClose = false;
boolean showUnselectedClose = true;
- Rectangle chevronRect = new Rectangle(0, 0, 0, 0);
- int chevronImageState = SWT.NONE;
+ boolean showMin = false;
+ boolean minimized = false;
+ boolean showMax = false;
+ boolean maximized = false;
+ ToolBar minMaxTb;
+ ToolItem maxItem;
+ ToolItem minItem;
+ Image maxImage;
+ Image minImage;
+ Image restorImage;
+
boolean showChevron = false;
Menu showMenu;
-
- boolean showMin = false;
- Rectangle minRect = new Rectangle(0, 0, 0, 0);
- boolean minimized = false;
- int minImageState = SWT.NONE;
-
- boolean showMax = false;
- Rectangle maxRect = new Rectangle(0, 0, 0, 0);
- boolean maximized = false;
- int maxImageState = SWT.NONE;
+ ToolBar chevronTb;
+ ToolItem chevronItem;
+ Image chevronImage;
+ int chevronCount;
+ boolean chevronVisible = true;
Control topRight;
- Rectangle topRightRect = new Rectangle(0, 0, 0, 0);
int topRightAlignment = SWT.RIGHT;
-
- Image topRightImage;
boolean ignoreResize;
- ControlAdapter topRightResize = new ControlAdapter() {
- public void controlResized(ControlEvent e) {
- if (ignoreResize) return;
- if (updateItems()) redraw();
- }
- };
+ Control[] controls;
+ int[] controlAlignments;
+ Rectangle[] controlRects;
+ Image[] controlBkImages;
// when disposing CTabFolder, don't try to layout the items or
// change the selection as each child is destroyed.
@@ -195,10 +194,8 @@
static final int FOREGROUND = SWT.COLOR_WIDGET_FOREGROUND;
static final int BACKGROUND = SWT.COLOR_WIDGET_BACKGROUND;
- static final int CHEVRON_CHILD_ID = 0;
- static final int MINIMIZE_CHILD_ID = 1;
- static final int MAXIMIZE_CHILD_ID = 2;
- static final int EXTRA_CHILD_ID_COUNT = 3;
+ //TODO: add setter for spacing?
+ static final int SPACING = 3;
/**
* Constructs a new instance of this class given its parent
@@ -251,6 +248,10 @@
selectionForeground = display.getSystemColor(SELECTION_FOREGROUND);
selectionBackground = display.getSystemColor(SELECTION_BACKGROUND);
renderer = new CTabFolderRenderer(this);
+ controls = new Control[0];
+ controlAlignments = new int[0];
+ controlRects = new Rectangle[0];
+ controlBkImages = new Image[0];
updateTabHeight(false);
// Add all listeners
@@ -269,8 +270,9 @@
case SWT.MouseMove: onMouse(event); break;
case SWT.MouseUp: onMouse(event); break;
case SWT.Paint: onPaint(event); break;
- case SWT.Resize: onResize(); break;
+ case SWT.Resize: onResize(event); break;
case SWT.Traverse: onTraverse(event); break;
+ case SWT.Selection: onSelection(event); break;
}
}
};
@@ -422,6 +424,183 @@
addListener(SWT.DefaultSelection, typedListener);
}
+Rectangle[] computeControlBounds (Point size, boolean[][] position) {
+ if (controls == null || controls.length == 0) return new Rectangle[0];
+ Rectangle[] rects = new Rectangle[controls.length];
+ for (int i = 0; i < rects.length; i++) {
+ rects[i] = new Rectangle(0, 0, 0, 0);
+ }
+ Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
+ int borderRight = trim.width + trim.x;
+ int borderLeft = -trim.x;
+ int borderBottom = trim.height + trim.y;
+ int borderTop = -trim.y;
+
+ Point[] tabControlSize = new Point[controls.length];
+ boolean[] overflow = new boolean [controls.length];
+ //Left Control
+ int leftWidth = 0;
+ int x = borderLeft + SPACING;
+ int rightWidth = 0;
+ int allWidth = 0;
+ for (int i = 0; i < controls.length; i++) {
+ Point ctrlSize = tabControlSize[i] = controls[i].getVisible() ? controls[i].computeSize(SWT.DEFAULT, SWT.DEFAULT) : new Point(0,0);
+ int alignment = controlAlignments[i];
+ if ((alignment & SWT.LEAD) != 0) {
+ rects[i].width = ctrlSize.x;
+ rects[i].height = Math.max(tabHeight - 1, ctrlSize.y);
+ rects[i].x = x;
+ rects[i].y = getControlY(size, rects, borderBottom, borderTop, i);
+ x += ctrlSize.x;
+ leftWidth += ctrlSize.x;
+ } else {
+ if ((alignment & (SWT.FILL | SWT.WRAP)) == 0) {
+ rightWidth += ctrlSize.x;
+ }
+ allWidth += ctrlSize.x;
+ }
+ }
+ if (leftWidth > 0) leftWidth += SPACING * 2;
+
+ int itemWidth = 0;
+ for (int i = 0; i < items.length; i++) {
+ if (items[i].showing) itemWidth += items[i].width;
+ }
+
+ int maxWidth = size.x - borderLeft - leftWidth - borderRight;
+ int availableWidth = Math.max(0, maxWidth - itemWidth - rightWidth);
+ if (rightWidth > 0) availableWidth -= SPACING * 2;
+ x = size.x - borderRight - SPACING;
+ if (itemWidth + allWidth <= maxWidth) {
+ //Everything fits
+ for (int i = 0; i < controls.length; i++) {
+ int alignment = controlAlignments[i];
+ if ((alignment & SWT.TRAIL) != 0) {
+ Point ctrlSize = tabControlSize[i];
+ x -= ctrlSize.x;
+ rects[i].width = ctrlSize.x;
+ rects[i].height = Math.min(tabHeight - 1, ctrlSize.y);
+ rects[i].x = x;
+ rects[i].y = getControlY(size, rects, borderBottom, borderTop, i);
+ if ((alignment & (SWT.FILL | SWT.WRAP)) != 0) availableWidth -= ctrlSize.x;
+ }
+ }
+ } else {
+ for (int i = 0; i < controls.length; i++) {
+ int alignment = controlAlignments[i];
+ Point ctrlSize = tabControlSize[i];
+ if ((alignment & SWT.TRAIL) != 0) {
+ if ((alignment & (SWT.FILL | SWT.WRAP)) == 0) {
+ x -= ctrlSize.x;
+ rects[i].width = ctrlSize.x;
+ rects[i].height = Math.min(tabHeight - 1, ctrlSize.y);
+ rects[i].x = x;
+ rects[i].y = getControlY(size, rects, borderBottom, borderTop, i);
+ } else if (((alignment & (SWT.WRAP)) != 0 && ctrlSize.x < availableWidth)) {
+ x -= ctrlSize.x;
+ rects[i].width = ctrlSize.x;
+ rects[i].height = Math.min(tabHeight - 1, ctrlSize.y);
+ rects[i].x = x;
+ rects[i].y = getControlY(size, rects, borderBottom, borderTop, i);
+ availableWidth -= ctrlSize.x;
+ } else if ((alignment & (SWT.FILL)) != 0 && (alignment & (SWT.WRAP)) == 0) {
+ rects[i].width = 0;
+ rects[i].height = Math.min(tabHeight - 1, ctrlSize.y);
+ rects[i].x = x;
+ rects[i].y = getControlY(size, rects, borderBottom, borderTop, i);
+ } else {
+ if ((alignment & (SWT.WRAP)) != 0) {
+ overflow[i] = true;
+ }
+ }
+ }
+ }
+ }
+
+ //Any space, distribute amongst FILL
+ if (availableWidth > 0) {
+ int fillCount = 0;
+ for (int i = 0; i < controls.length; i++) {
+ int alignment = controlAlignments[i];
+ if ((alignment & SWT.TRAIL) != 0 && (alignment & SWT.FILL) != 0 && !overflow[i]) {
+ fillCount++;
+ }
+ }
+ if (fillCount != 0) {
+ int extraSpace = availableWidth/fillCount;
+ int addedSpace = 0;
+ for (int i = 0; i < controls.length; i++) {
+ int alignment = controlAlignments[i];
+ if ((alignment & SWT.TRAIL) != 0) {
+ if ((alignment & SWT.FILL) != 0 && !overflow[i]) {
+ rects[i].width += extraSpace;
+ addedSpace += extraSpace;
+ }
+ if (!overflow[i]) {
+ rects[i].x -= addedSpace;
+ }
+ }
+ }
+ }
+ }
+
+ //Go through overflow laying out all wrapped controls
+ Rectangle bodyTrim = renderer.computeTrim(CTabFolderRenderer.PART_BODY, SWT.NONE, 0, 0, 0, 0);
+ int bodyRight = bodyTrim.width + bodyTrim.x;
+ int bodyLeft = -bodyTrim.x;
+ int bodyWidth = size.x - bodyLeft - bodyRight;
+ x = size.x - bodyRight;
+ int y = -bodyTrim.y;
+ availableWidth = bodyWidth;
+ int maxHeight = 0;
+ for (int i = 0; i < controls.length; i++) {
+ if (overflow[i]) {
+ Point ctrlSize = tabControlSize[i];
+ if (availableWidth > ctrlSize.x) {
+ x -= ctrlSize.x;
+ rects[i].width = ctrlSize.x;
+ rects[i].y = y;
+ rects[i].height = ctrlSize.y;
+ rects[i].x = x;
+ availableWidth -= ctrlSize.x;
+ maxHeight = Math.max(maxHeight, ctrlSize.y);
+ } else {
+ x = size.x - bodyRight;
+ y += maxHeight;
+ maxHeight = 0;
+ availableWidth = bodyWidth;
+ if (availableWidth > ctrlSize.x) {
+ //Relayout this control in the next line
+ i--;
+ } else {
+ ctrlSize = controls[i].computeSize(bodyWidth, SWT.DEFAULT);
+ rects[i].width = bodyWidth;
+ rects[i].y = y;
+ rects[i].height = ctrlSize.y;
+ rects[i].x = size.x - ctrlSize.x - bodyRight;
+ y += ctrlSize.y;
+ }
+ }
+ }
+ }
+
+ if (showChevron) {
+ int i = 0, lastIndex = -1;
+ while (i < priority.length && items[priority[i]].showing) {
+ lastIndex = Math.max(lastIndex, priority[i++]);
+ }
+ if (lastIndex == -1) lastIndex = firstIndex;
+ if (lastIndex != -1) {
+ CTabItem lastItem = items[lastIndex];
+ int w = lastItem.x + lastItem.width + SPACING;
+ if (!simple && lastIndex == selectedIndex) w -= renderer.curveIndent;
+ rects[controls.length - 1].x = w;
+ }
+ }
+
+ if (position != null) position[0] = overflow;
+ return rects;
+}
/*
* This class was not intended to be subclassed but this restriction
* cannot be enforced without breaking backward compatibility.
@@ -436,17 +615,39 @@
public Rectangle computeTrim (int x, int y, int width, int height) {
checkWidget();
Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BODY, SWT.NONE, x, y, width, height);
- if (topRight != null && topRightAlignment == (SWT.RIGHT | SWT.WRAP)) {
- Rectangle bounds = topRight.getBounds();
- if (bounds.y >= getTabHeight()) {
- if (!onBottom) {
- trim.y -= bounds.height;
- }
- trim.height += bounds.height;
- }
+ Point size = new Point(width, height);
+ int wrapHeight = getWrappedHeight(size);
+ if (onBottom) {
+ trim.height += wrapHeight;
+ } else {
+ trim.y -= wrapHeight;
+ trim.height += wrapHeight;
}
return trim;
}
+Image createButtonImage(Display display, int button) {
+ Point size = renderer.computeSize(button, SWT.NONE, null, SWT.DEFAULT, SWT.DEFAULT);
+ Rectangle trim = renderer.computeTrim(button, SWT.NONE, 0, 0, 0, 0);
+ Image image = new Image (display, size.x - trim.width, size.y - trim.height);
+ GC gc = new GC (image);
+ RGB transparent;
+ if (button == CTabFolderRenderer.PART_CHEVRON_BUTTON) {
+ transparent = new RGB(0xFF, 0xFF, 0xFF);
+ } else {
+ transparent = new RGB(0xFD, 0, 0);
+ }
+ Color transColor = new Color(display, transparent);
+ gc.setBackground(transColor);
+ gc.fillRectangle(image.getBounds());
+ renderer.draw(button, SWT.NONE, new Rectangle(trim.x, trim.y, size.x, size.y), gc);
+ gc.dispose ();
+ transColor.dispose();
+ ImageData imageData = image.getImageData();
+ imageData.transparentPixel = imageData.palette.getPixel(transparent);
+ image.dispose();
+ image = new Image(display, imageData);
+ return image;
+}
void createItem (CTabItem item, int index) {
if (0 > index || index > getItemCount ())SWT.error (SWT.ERROR_INVALID_RANGE);
item.parent = this;
@@ -544,20 +745,48 @@
checkWidget();
return borderVisible;
}
+ToolBar getChevron() {
+ if (chevronTb == null) {
+ chevronTb = new ToolBar(this, SWT.NONE);
+ addTabControl(chevronTb, SWT.TRAIL, -1, false);
+ }
+ if (chevronItem == null) {
+ chevronItem = new ToolItem(chevronTb, SWT.PUSH);
+ chevronItem.setToolTipText(SWT.getMessage("SWT_ShowList"));
+ chevronItem.addListener(SWT.Selection, listener);
+ }
+ return chevronTb;
+}
+/**
+ * Returns <code>true</code> if the chevron button
+ * is visible when necessary.
+ *
+ * @return the visibility of the chevron button
+ *
+ * @exception SWTException <ul>
+ * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
+ * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
+ * </ul>
+ *
+ * @since 4.1
+ */
+public boolean getChevronVisible() {
+ checkWidget();
+ return chevronVisible;
+}
public Rectangle getClientArea() {
checkWidget();
+ //TODO: HACK - find a better way to get padding
Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BODY, SWT.FILL, 0, 0, 0, 0);
- if (topRight != null && topRightAlignment == (SWT.RIGHT | SWT.WRAP)) {
- Rectangle bounds = topRight.getBounds();
- if (bounds.y >= getTabHeight()) {
- if (!onBottom) {
- trim.y -= bounds.height;
- }
- trim.height += bounds.height;
- }
+ Point size = getSize();
+ int wrapHeight = getWrappedHeight(size);
+ if (onBottom) {
+ trim.height += wrapHeight;
+ } else {
+ trim.y -= wrapHeight;
+ trim.height += wrapHeight;
}
if (minimized) return new Rectangle(-trim.x, -trim.y, 0, 0);
- Point size = getSize();
int width = size.x - trim.width;
int height = size.y - trim.height;
return new Rectangle(-trim.x, -trim.y, width, height);
@@ -600,7 +829,6 @@
Point size = getSize();
Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
if (size.x <= trim.width) return null;
- if (showChevron && chevronRect.contains(pt)) return null;
for (int i = 0; i < priority.length; i++) {
CTabItem item = items[priority[i]];
Rectangle rect = item.getBounds();
@@ -638,7 +866,19 @@
System.arraycopy(items, 0, tabItems, 0, items.length);
return tabItems;
}
-
+int getLeftItemEdge (GC gc, int part){
+ Rectangle trim = renderer.computeTrim(part, SWT.NONE, 0, 0, 0, 0);
+ int x = -trim.x;
+ int width = 0;
+ for (int i = 0; i < controls.length; i++) {
+ if ((controlAlignments[i] & SWT.LEAD) != 0 && controls[i].getVisible()) {
+ width += controls[i].computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
+ }
+ }
+ if (width != 0) width += SPACING * 2;
+ x += width;
+ return Math.max(0, x);
+}
/*
* Return the lowercase of the first non-'&' character following
* an '&' character in the given string. If there are no '&'
@@ -803,14 +1043,17 @@
}
int getRightItemEdge (GC gc){
Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
- int x = getSize().x - (trim.width + trim.x) - 3; //TODO: add setter for spacing?
- if (showMin) x -= renderer.computeSize(CTabFolderRenderer.PART_MIN_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
- if (showMax) x -= renderer.computeSize(CTabFolderRenderer.PART_MAX_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
- if (showChevron) x -= renderer.computeSize(CTabFolderRenderer.PART_CHEVRON_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
- if (topRight != null && topRightAlignment == SWT.RIGHT) {
- Point rightSize = topRight.computeSize(SWT.DEFAULT, SWT.DEFAULT);
- x -= rightSize.x + 3;
+ int x = getSize().x - (trim.width + trim.x);
+ int width = 0;
+ for (int i = 0; i < controls.length; i++) {
+ int align = controlAlignments[i];
+ if ((align & SWT.WRAP) == 0 && (align & SWT.LEAD) == 0 && controls[i].getVisible()) {
+ Point rightSize = controls[i].computeSize(SWT.DEFAULT, SWT.DEFAULT);
+ width += rightSize.x;
+ }
}
+ if (width != 0) width += SPACING * 2;
+ x -= width;
return Math.max(0, x);
}
/**
@@ -941,14 +1184,6 @@
return onBottom ? SWT.BOTTOM : SWT.TOP;
}
/**
- * WARNING: Provisional API. This API is temporary and is not guaranteed to exist in
- * future releases.
- */
-public Control getTopControl (){
- checkWidget ();
- return topRight;
-}
-/**
* Returns the control in the top right corner of the tab folder.
* Typically this is a close button or a composite with a menu and close button.
*
@@ -1041,12 +1276,6 @@
int childID = e.childID;
if (childID >= 0 && childID < items.length) {
name = stripMnemonic(items[childID].getText());
- } else if (childID == items.length + CHEVRON_CHILD_ID) {
- name = SWT.getMessage("SWT_ShowList"); //$NON-NLS-1$
- } else if (childID == items.length + MINIMIZE_CHILD_ID) {
- name = minimized ? SWT.getMessage("SWT_Restore") : SWT.getMessage("SWT_Minimize"); //$NON-NLS-1$ //$NON-NLS-2$
- } else if (childID == items.length + MAXIMIZE_CHILD_ID) {
- name = maximized ? SWT.getMessage("SWT_Restore") : SWT.getMessage("SWT_Maximize"); //$NON-NLS-1$ //$NON-NLS-2$
}
e.result = name;
}
@@ -1089,18 +1318,10 @@
}
}
if (childID == ACC.CHILDID_NONE) {
- if (showChevron && chevronRect.contains(testPoint)) {
- childID = items.length + CHEVRON_CHILD_ID;
- } else if (showMin && minRect.contains(testPoint)) {
- childID = items.length + MINIMIZE_CHILD_ID;
- } else if (showMax && maxRect.contains(testPoint)) {
- childID = items.length + MAXIMIZE_CHILD_ID;
- } else {
- Rectangle location = getBounds();
- location.height = location.height - getClientArea().height;
- if (location.contains(testPoint)) {
- childID = ACC.CHILDID_SELF;
- }
+ Rectangle location = getBounds();
+ location.height = location.height - getClientArea().height;
+ if (location.contains(testPoint)) {
+ childID = ACC.CHILDID_SELF;
}
}
e.childID = childID;
@@ -1116,12 +1337,6 @@
} else {
if (childID >= 0 && childID < items.length && items[childID].isShowing()) {
location = items[childID].getBounds();
- } else if (showChevron && childID == items.length + CHEVRON_CHILD_ID) {
- location = chevronRect;
- } else if (showMin && childID == items.length + MINIMIZE_CHILD_ID) {
- location = minRect;
- } else if (showMax && childID == items.length + MAXIMIZE_CHILD_ID) {
- location = maxRect;
}
if (location != null) {
pt = toDisplay(location.x, location.y);
@@ -1136,7 +1351,7 @@
}
public void getChildCount(AccessibleControlEvent e) {
- e.detail = items.length + EXTRA_CHILD_ID_COUNT;
+ e.detail = items.length;
}
public void getDefaultAction(AccessibleControlEvent e) {
@@ -1145,7 +1360,7 @@
if (childID >= 0 && childID < items.length) {
action = SWT.getMessage ("SWT_Switch"); //$NON-NLS-1$
}
- if (childID >= items.length && childID < items.length + EXTRA_CHILD_ID_COUNT) {
+ if (childID >= items.length && childID < items.length) {
action = SWT.getMessage ("SWT_Press"); //$NON-NLS-1$
}
e.result = action;
@@ -1170,7 +1385,7 @@
role = ACC.ROLE_TABFOLDER;
} else if (childID >= 0 && childID < items.length) {
role = ACC.ROLE_TABITEM;
- } else if (childID >= items.length && childID < items.length + EXTRA_CHILD_ID_COUNT) {
+ } else if (childID >= items.length && childID < items.length) {
role = ACC.ROLE_PUSHBUTTON;
}
e.detail = role;
@@ -1196,18 +1411,12 @@
state |= ACC.STATE_FOCUSED;
}
}
- } else if (childID == items.length + CHEVRON_CHILD_ID) {
- state = showChevron ? ACC.STATE_NORMAL : ACC.STATE_INVISIBLE;
- } else if (childID == items.length + MINIMIZE_CHILD_ID) {
- state = showMin ? ACC.STATE_NORMAL : ACC.STATE_INVISIBLE;
- } else if (childID == items.length + MAXIMIZE_CHILD_ID) {
- state = showMax ? ACC.STATE_NORMAL : ACC.STATE_INVISIBLE;
}
e.detail = state;
}
public void getChildren(AccessibleControlEvent e) {
- int childIdCount = items.length + EXTRA_CHILD_ID_COUNT;
+ int childIdCount = items.length;
Object[] children = new Object[childIdCount];
for (int i = 0; i < childIdCount; i++) {
children[i] = new Integer(i);
@@ -1264,6 +1473,8 @@
index = visible [current + offset];
} else {
if (showChevron) {
+ Rectangle chevronRect = chevronItem.getBounds();
+ chevronRect = event.display.map(chevronTb, this, chevronRect);
CTabFolderEvent e = new CTabFolderEvent(this);
e.widget = this;
e.time = event.time;
@@ -1318,27 +1529,37 @@
selectionBackground = null;
selectionForeground = null;
- if (topRight != null && !topRight.isDisposed())
- topRight.removeControlListener(topRightResize);
+ if (controlBkImages != null) {
+ for (int i = 0; i < controlBkImages.length; i++) {
+ if (controlBkImages[i] != null) {
+ controlBkImages[i].dispose();
+ controlBkImages[i] = null;
+ }
+ }
+ controlBkImages = null;
+ }
+ controls = null;
+ controlAlignments = null;
+ controlRects = null;
- if (topRightImage != null) topRightImage.dispose();
- topRightImage = null;
+ if (maxImage != null) maxImage.dispose();
+ maxImage = null;
+
+ if (minImage != null) minImage.dispose();
+ minImage = null;
+
+ if (chevronImage != null) chevronImage.dispose();
+ chevronImage = null;
if (renderer != null) renderer.dispose();
renderer = null;
}
void onDragDetect(Event event) {
boolean consume = false;
- if (chevronRect.contains(event.x, event.y) ||
- minRect.contains(event.x, event.y) ||
- maxRect.contains(event.x, event.y)){
- consume = true;
- } else {
- for (int i = 0; i < items.length; i++) {
- if (items[i].closeRect.contains(event.x, event.y)) {
- consume = true;
- break;
- }
+ for (int i = 0; i < items.length; i++) {
+ if (items[i].closeRect.contains(event.x, event.y)) {
+ consume = true;
+ break;
}
}
if (consume) {
@@ -1392,18 +1613,6 @@
break;
}
case SWT.MouseExit: {
- if (minImageState != SWT.NONE) {
- minImageState = SWT.NONE;
- redraw(minRect.x, minRect.y, minRect.width, minRect.height, false);
- }
- if (maxImageState != SWT.NONE) {
- maxImageState = SWT.NONE;
- redraw(maxRect.x, maxRect.y, maxRect.width, maxRect.height, false);
- }
- if (chevronImageState != SWT.NONE) {
- chevronImageState = SWT.NONE;
- redraw(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, false);
- }
for (int i=0; i<items.length; i++) {
CTabItem item = items[i];
if (i != selectedIndex && item.closeImageState != SWT.BACKGROUND) {
@@ -1423,28 +1632,6 @@
}
case SWT.MouseDown: {
if (event.button != 1) return;
- if (minRect.contains(x, y)) {
- minImageState = SWT.SELECTED;
- redraw(minRect.x, minRect.y, minRect.width, minRect.height, false);
- update();
- return;
- }
- if (maxRect.contains(x, y)) {
- maxImageState = SWT.SELECTED;
- redraw(maxRect.x, maxRect.y, maxRect.width, maxRect.height, false);
- update();
- return;
- }
- if (chevronRect.contains(x, y)) {
- if (chevronImageState != SWT.HOT) {
- chevronImageState = SWT.HOT;
- } else {
- chevronImageState = SWT.SELECTED;
- }
- redraw(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, false);
- update();
- return;
- }
CTabItem item = null;
if (single) {
if (selectedIndex != -1) {
@@ -1483,40 +1670,7 @@
}
case SWT.MouseMove: {
_setToolTipText(event.x, event.y);
- boolean close = false, minimize = false, maximize = false, chevron = false;
- if (minRect.contains(x, y)) {
- minimize = true;
- if (minImageState != SWT.SELECTED && minImageState != SWT.HOT) {
- minImageState = SWT.HOT;
- redraw(minRect.x, minRect.y, minRect.width, minRect.height, false);
- }
- }
- if (maxRect.contains(x, y)) {
- maximize = true;
- if (maxImageState != SWT.SELECTED && maxImageState != SWT.HOT) {
- maxImageState = SWT.HOT;
- redraw(maxRect.x, maxRect.y, maxRect.width, maxRect.height, false);
- }
- }
- if (chevronRect.contains(x, y)) {
- chevron = true;
- if (chevronImageState != SWT.SELECTED && chevronImageState != SWT.HOT) {
- chevronImageState = SWT.HOT;
- redraw(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, false);
- }
- }
- if (minImageState != SWT.NONE && !minimize) {
- minImageState = SWT.NONE;
- redraw(minRect.x, minRect.y, minRect.width, minRect.height, false);
- }
- if (maxImageState != SWT.NONE && !maximize) {
- maxImageState = SWT.NONE;
- redraw(maxRect.x, maxRect.y, maxRect.width, maxRect.height, false);
- }
- if (chevronImageState != SWT.NONE && !chevron) {
- chevronImageState = SWT.NONE;
- redraw(chevronRect.x, chevronRect.y, chevronRect.width, chevronRect.height, false);
- }
+ boolean close = false;
for (int i=0; i<items.length; i++) {
CTabItem item = items[i];
close = false;
@@ -1555,59 +1709,6 @@
}
case SWT.MouseUp: {
if (event.button != 1) return;
- if (chevronRect.contains(x, y)) {
- boolean selected = chevronImageState == SWT.SELECTED;
- if (!selected) return;
- CTabFolderEvent e = new CTabFolderEvent(this);
- e.widget = this;
- e.time = event.time;
- e.x = chevronRect.x;
- e.y = chevronRect.y;
- e.width = chevronRect.width;
- e.height = chevronRect.height;
- e.doit = true;
- for (int i = 0; i < folderListeners.length; i++) {
- folderListeners[i].showList(e);
- }
- if (e.doit && !isDisposed()) {
- showList(chevronRect);
- }
- return;
- }
- if (minRect.contains(x, y)) {
- boolean selected = minImageState == SWT.SELECTED;
- minImageState = SWT.HOT;
- redraw(minRect.x, minRect.y, minRect.width, minRect.height, false);
- if (!selected) return;
- CTabFolderEvent e = new CTabFolderEvent(this);
- e.widget = this;
- e.time = event.time;
- for (int i = 0; i < folderListeners.length; i++) {
- if (minimized) {
- folderListeners[i].restore(e);
- } else {
- folderListeners[i].minimize(e);
- }
- }
- return;
- }
- if (maxRect.contains(x, y)) {
- boolean selected = maxImageState == SWT.SELECTED;
- maxImageState = SWT.HOT;
- redraw(maxRect.x, maxRect.y, maxRect.width, maxRect.height, false);
- if (!selected) return;
- CTabFolderEvent e = new CTabFolderEvent(this);
- e.widget = this;
- e.time = event.time;
- for (int i = 0; i < folderListeners.length; i++) {
- if (maximized) {
- folderListeners[i].restore(e);
- } else {
- folderListeners[i].maximize(e);
- }
- }
- return;
- }
CTabItem item = null;
if (single) {
if (selectedIndex != -1) {
@@ -1693,6 +1794,8 @@
index = visible [current + offset];
} else {
if (showChevron) {
+ Rectangle chevronRect = chevronItem.getBounds();
+ chevronRect = event.display.map(chevronTb, this, chevronRect);
CTabFolderEvent e = new CTabFolderEvent(this);
e.widget = this;
e.time = event.time;
@@ -1772,17 +1875,10 @@
gc.setFont(gcFont);
gc.setForeground(gcForeground);
gc.setBackground(gcBackground);
-
- renderer.draw(CTabFolderRenderer.PART_MAX_BUTTON, maxImageState, maxRect, gc);
- renderer.draw(CTabFolderRenderer.PART_MIN_BUTTON, minImageState, minRect, gc);
- renderer.draw(CTabFolderRenderer.PART_CHEVRON_BUTTON, chevronImageState, chevronRect, gc);
-
- gc.setFont(gcFont);
- gc.setForeground(gcForeground);
- gc.setBackground(gcBackground);
}
-void onResize() {
+void onResize(Event event) {
+ if (ignoreResize) return;
if (updateItems()) redrawTabs();
Point size = getSize();
@@ -1806,6 +1902,48 @@
}
oldSize = size;
}
+void onSelection(Event event) {
+ if (event.widget == maxItem) {
+ CTabFolderEvent e = new CTabFolderEvent(this);
+ e.widget = CTabFolder.this;
+ e.time = event.time;
+ for (int i = 0; i < folderListeners.length; i++) {
+ if (maximized) {
+ folderListeners[i].restore(e);
+ } else {
+ folderListeners[i].maximize(e);
+ }
+ }
+ } else if (event.widget == minItem) {
+ CTabFolderEvent e = new CTabFolderEvent(this);
+ e.widget = CTabFolder.this;
+ e.time = event.time;
+ for (int i = 0; i < folderListeners.length; i++) {
+ if (minimized) {
+ folderListeners[i].restore(e);
+ } else {
+ folderListeners[i].minimize(e);
+ }
+ }
+ } else if (event.widget == chevronItem) {
+ Rectangle chevronRect = chevronItem.getBounds();
+ chevronRect = event.display.map(chevronTb, this, chevronRect);
+ CTabFolderEvent e = new CTabFolderEvent(this);
+ e.widget = this;
+ e.time = event.time;
+ e.x = chevronRect.x;
+ e.y = chevronRect.y;
+ e.width = chevronRect.width;
+ e.height = chevronRect.height;
+ e.doit = true;
+ for (int i = 0; i < folderListeners.length; i++) {
+ folderListeners[i].showList(e);
+ }
+ if (e.doit && !isDisposed()) {
+ showList(chevronRect);
+ }
+ }
+}
void onTraverse (Event event) {
if (ignoreTraverse) return;
switch (event.detail) {
@@ -1964,7 +2102,7 @@
public void setBackground (Color color) {
super.setBackground(color);
renderer.createAntialiasColors(); //TODO: need better caching strategy
- updateTopRightBackground();
+ updateBkImages();
redraw();
}
/**
@@ -2118,205 +2256,85 @@
}
void setButtonBounds(GC gc) {
Point size = getSize();
- int oldX, oldY, oldWidth, oldHeight;
- Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
- int borderRight = trim.width + trim.x;
- int borderLeft = -trim.x;
- int borderBottom = trim.height + trim.y;
- int borderTop = -trim.y;
-
// max button
- oldX = maxRect.x;
- oldY = maxRect.y;
- oldWidth = maxRect.width;
- oldHeight = maxRect.height;
- maxRect.x = maxRect.y = maxRect.width = maxRect.height = 0;
+ Display display = getDisplay();
if (showMax) {
- Point maxSize = renderer.computeSize(CTabFolderRenderer.PART_MAX_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT);
- maxRect.x = size.x - borderRight - maxSize.x - 3;
- if (borderRight > 0) maxRect.x += 1;
- maxRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - maxSize.y)/2: borderTop + (tabHeight - maxSize.y)/2;
- maxRect.width = maxSize.x;
- maxRect.height = maxSize.y;
- }
- if (oldX != maxRect.x || oldWidth != maxRect.width ||
- oldY != maxRect.y || oldHeight != maxRect.height) {
- int left = Math.min(oldX, maxRect.x);
- int right = Math.max(oldX + oldWidth, maxRect.x + maxRect.width);
- int top = onBottom ? size.y - borderBottom - tabHeight: borderTop + 1;
- redraw(left, top, right - left, tabHeight, false);
- }
-
- // min button
- oldX = minRect.x;
- oldY = minRect.y;
- oldWidth = minRect.width;
- oldHeight = minRect.height;
- minRect.x = minRect.y = minRect.width = minRect.height = 0;
- if (showMin) {
- Point minSize = renderer.computeSize(CTabFolderRenderer.PART_MIN_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT);
- minRect.x = size.x - borderRight - maxRect.width - minSize.x - 3;
- if (borderRight > 0) minRect.x += 1;
- minRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - minSize.y)/2: borderTop + (tabHeight - minSize.y)/2;
- minRect.width = minSize.x;
- minRect.height = minSize.y;
- }
- if (oldX != minRect.x || oldWidth != minRect.width ||
- oldY != minRect.y || oldHeight != minRect.height) {
- int left = Math.min(oldX, minRect.x);
- int right = Math.max(oldX + oldWidth, minRect.x + minRect.width);
- int top = onBottom ? size.y - borderBottom - tabHeight: borderTop + 1;
- redraw(left, top, right - left, tabHeight, false);
- }
-
- // top right control
- oldX = topRightRect.x;
- oldY = topRightRect.y;
- oldWidth = topRightRect.width;
- oldHeight = topRightRect.height;
- topRightRect.x = topRightRect.y = topRightRect.width = topRightRect.height = 0;
- if (topRight != null) {
- switch (topRightAlignment) {
- case SWT.FILL: {
- int rightEdge = size.x - borderRight - 3 - maxRect.width - minRect.width;
- if (!simple && borderRight > 0 && !showMax && !showMin) rightEdge -= 2;
- if (single) {
- if (items.length == 0 || selectedIndex == -1) {
- topRightRect.x = borderLeft + 3;
- topRightRect.width = rightEdge - topRightRect.x;
- } else {
- // fill size is 0 if item compressed
- CTabItem item = items[selectedIndex];
- int chevronWidth = renderer.computeSize(CTabFolderRenderer.PART_CHEVRON_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
- if (item.x + item.width + 7 + chevronWidth >= rightEdge) break;
- topRightRect.x = item.x + item.width + 7 + chevronWidth;
- topRightRect.width = rightEdge - topRightRect.x;
- }
- } else {
- // fill size is 0 if chevron showing
- if (showChevron) break;
- if (items.length == 0) {
- topRightRect.x = borderLeft + 3;
- } else {
- int lastIndex = items.length - 1;
- CTabItem lastItem = items[lastIndex];
- topRightRect.x = lastItem.x + lastItem.width;
- }
- topRightRect.width = Math.max(0, rightEdge - topRightRect.x);
- }
- topRightRect.y = onBottom ? size.y - borderBottom - tabHeight: borderTop + 1;
- topRightRect.height = tabHeight - 1;
- break;
- }
- case SWT.RIGHT: {
- Point topRightSize = topRight.computeSize(SWT.DEFAULT, tabHeight, false);
- int rightEdge = size.x - borderRight - 3 - maxRect.width - minRect.width;
- if (!simple && borderRight > 0 && !showMax && !showMin) rightEdge -= 2;
- topRightRect.x = rightEdge - topRightSize.x;
- topRightRect.width = topRightSize.x;
- topRightRect.y = onBottom ? size.y - borderBottom - tabHeight: borderTop + 1;
- topRightRect.height = tabHeight - 1;
- break;
- }
- case SWT.RIGHT | SWT.WRAP: {
- Point topRightSize = topRight.computeSize(SWT.DEFAULT, tabHeight, false);
- int rightEdge = size.x - borderRight - 3 - maxRect.width - minRect.width;
- if (!simple && borderRight > 0 && !showMax && !showMin) rightEdge -= 2;
- int leftEdge = 0;
- if (items.length == 0) {
- leftEdge = borderLeft + 3;
- } else {
- int lastIndex = items.length - 1;
- CTabItem lastItem = items[lastIndex];
- leftEdge = lastItem.x + lastItem.width;
- }
-
- if (topRightSize.x <= rightEdge - leftEdge) {
- topRightRect.x = rightEdge - topRightSize.x;
- topRightRect.width = topRightSize.x;
- topRightRect.y = onBottom ? size.y - borderBottom - tabHeight: borderTop + 1;
- topRightRect.height = tabHeight - 1;
- } else {
- Rectangle bodyTrim = renderer.computeTrim(CTabFolderRenderer.PART_BODY, SWT.NONE, 0, 0, 0, 0);
- Point preferredSize = topRight.computeSize(SWT.DEFAULT, SWT.DEFAULT);
- int bodyRight = bodyTrim.width + bodyTrim.x;
- int bodyLeft = -bodyTrim.x;
- int compWidth = size.x - bodyLeft - bodyRight;
- if (compWidth > preferredSize.x) {
- topRightRect.width = preferredSize.x;
- topRightRect.y = -bodyTrim.y;
- topRightRect.height = preferredSize.y;
- topRightRect.x = size.x - preferredSize.x - bodyRight;
- } else {
- preferredSize = topRight.computeSize(compWidth, SWT.DEFAULT);
- topRightRect.width = compWidth;
- topRightRect.y = -bodyTrim.y;
- topRightRect.height = preferredSize.y;
- topRightRect.x = size.x - preferredSize.x - bodyRight;
- }
- }
- }
+ if (minMaxTb == null) {
+ minMaxTb = new ToolBar(this, SWT.NONE);
+ addTabControl(minMaxTb, SWT.TRAIL, 0, false);
}
- ignoreResize = true;
- topRight.setBounds(topRightRect);
- ignoreResize = false;
- }
- if (oldY != topRightRect.y || oldHeight != topRightRect.height) {
- updateTopRightBackground();
- }
- if (oldX != topRightRect.x || oldWidth != topRightRect.width ||
- oldY != topRightRect.y || oldHeight != topRightRect.height) {
- int left = Math.min(oldX, topRightRect.x);
- int right = Math.max(oldX + oldWidth, topRightRect.x + topRightRect.width);
- int top = onBottom ? size.y - borderBottom - tabHeight : borderTop + 1;
- redraw(left, top, right - left, tabHeight, false);
- }
-
- // chevron button
- oldX = chevronRect.x;
- oldY = chevronRect.y;
- oldWidth = chevronRect.width;
- oldHeight = chevronRect.height;
- chevronRect.x = chevronRect.y = chevronRect.height = chevronRect.width = 0;
- Point chevronSize = renderer.computeSize(CTabFolderRenderer.PART_CHEVRON_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT);
- if (single) {
- if (selectedIndex == -1 || items.length > 1) {
- chevronRect.width = chevronSize.x;
- chevronRect.height = chevronSize.y;
- chevronRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - chevronRect.height)/2 : borderTop + (tabHeight - chevronRect.height)/2;
- if (selectedIndex == -1) {
- chevronRect.x = size.x - borderRight - 3 - minRect.width - maxRect.width - topRightRect.width - chevronRect.width;
- } else {
- CTabItem item = items[selectedIndex];
- int w = size.x - borderRight - 3 - minRect.width - maxRect.width - chevronRect.width;
- if (topRightRect.width > 0) w -= topRightRect.width + 3;
- chevronRect.x = Math.min(item.x + item.width + 3, w);
+ if (maxItem == null) {
+ maxItem = new ToolItem(minMaxTb, SWT.PUSH);
+ if (maxImage == null) {
+ maxImage = createButtonImage(display, CTabFolderRenderer.PART_MAX_BUTTON);
}
- if (borderRight > 0) chevronRect.x += 1;
+ maxItem.setImage(maxImage);
+ maxItem.setToolTipText(maximized ? SWT.getMessage("SWT_Restore") : SWT.getMessage("SWT_Maximize")); //$NON-NLS-1$ //$NON-NLS-2$
+ maxItem.addListener(SWT.Selection, listener);
}
} else {
- if (showChevron) {
- chevronRect.width = chevronSize.x;
- chevronRect.height = chevronSize.y;
- int i = 0, lastIndex = -1;
- while (i < priority.length && items[priority[i]].showing) {
- lastIndex = Math.max(lastIndex, priority[i++]);
- }
- if (lastIndex == -1) lastIndex = firstIndex;
- CTabItem lastItem = items[lastIndex];
- int w = lastItem.x + lastItem.width + 3;
- if (!simple && lastIndex == selectedIndex) w -= renderer.curveIndent; //TODO: fix chevron position
- chevronRect.x = Math.min(w, getRightItemEdge(gc));
- chevronRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - chevronRect.height)/2 : borderTop + (tabHeight - chevronRect.height)/2;
+ //might need to remove it if already there
+ if (maxItem != null) {
+ maxItem.dispose();
+ maxItem = null;
}
}
- if (oldX != chevronRect.x || oldWidth != chevronRect.width ||
- oldY != chevronRect.y || oldHeight != chevronRect.height) {
- int left = Math.min(oldX, chevronRect.x);
- int right = Math.max(oldX + oldWidth, chevronRect.x + chevronRect.width);
- int top = onBottom ? size.y - borderBottom - tabHeight: borderTop + 1;
- redraw(left, top, right - left, tabHeight, false);
+ // min button
+ if (showMin) {
+ if (minMaxTb == null) {
+ minMaxTb = new ToolBar(this, SWT.NONE);
+ addTabControl(minMaxTb, SWT.TRAIL, 0, false);
+ }
+ if (minItem == null) {
+ minItem = new ToolItem(minMaxTb, SWT.PUSH, 0);
+ if (minImage == null) {
+ minImage = createButtonImage(display, CTabFolderRenderer.PART_MIN_BUTTON);
+ }
+ minItem.setImage(minImage);
+ minItem.setToolTipText(minimized ? SWT.getMessage("SWT_Restore") : SWT.getMessage("SWT_Minimize")); //$NON-NLS-1$ //$NON-NLS-2$
+ minItem.addListener(SWT.Selection, listener);
+ }
+ } else {
+ //might need to remove it if already there
+ if (minItem != null) {
+ minItem.dispose();
+ minItem = null;
+ }
}
+ if (minMaxTb != null && minMaxTb.getItemCount() == 0) {
+ removeTabControl(minMaxTb);
+ minMaxTb.dispose();
+ minMaxTb = null;
+ }
+ if (showChevron) {
+ int itemCount = items.length;
+ int count;
+ if (single) {
+ count = selectedIndex == -1 ? itemCount : itemCount - 1;
+ } else {
+ int showCount = 0;
+ while (showCount < priority.length && items[priority[showCount]].showing) {
+ showCount++;
+ }
+ count = itemCount - showCount;
+ }
+ if (count != chevronCount) {
+ chevronCount = count;
+ if (chevronImage != null) chevronImage.dispose();
+ chevronImage = createButtonImage(display, CTabFolderRenderer.PART_CHEVRON_BUTTON);
+ chevronItem.setImage(chevronImage);
+ }
+ }
+ Rectangle[] rects = computeControlBounds(size, null);
+ boolean changed = false;
+ ignoreResize = true;
+ for (int i = 0; i < controls.length; i++) {
+ controls[i].setBounds(rects[i]);
+ if (!changed && !rects[i].equals(controlRects[i])) changed = true;
+ }
+ ignoreResize = false;
+ controlRects = rects;
+ if (changed) updateBkImages();
}
public void setFont(Font font) {
checkWidget();
@@ -2376,12 +2394,12 @@
boolean changed = false;
if (items.length == 0) return false;
Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
- int borderLeft = -trim.x;
int borderBottom = trim.height + trim.y;
int borderTop = -trim.y;
Point size = getSize();
int y = onBottom ? Math.max(borderBottom, size.y - borderBottom - tabHeight) : borderTop;
Point closeButtonSize = renderer.computeSize(CTabFolderRenderer.PART_CLOSE_BUTTON, 0, gc, SWT.DEFAULT, SWT.DEFAULT);
+ int leftItemEdge = getLeftItemEdge(gc, CTabFolderRenderer.PART_BORDER);
if (single) {
int defaultX = getDisplay().getBounds().width + 10; // off screen
for (int i = 0; i < items.length; i++) {
@@ -2389,11 +2407,11 @@
if (i == selectedIndex) {
firstIndex = selectedIndex;
int oldX = item.x, oldY = item.y;
- item.x = borderLeft;
+ item.x = leftItemEdge;
item.y = y;
item.showing = true;
if (showClose || item.showClose) {
- item.closeRect.x = borderLeft - renderer.computeTrim(i, SWT.NONE, 0, 0, 0, 0).x;
+ item.closeRect.x = leftItemEdge - renderer.computeTrim(i, SWT.NONE, 0, 0, 0, 0).x;
item.closeRect.y = onBottom ? size.y - borderBottom - tabHeight + (tabHeight - closeButtonSize.y)/2: borderTop + (tabHeight - closeButtonSize.y)/2;
}
if (item.x != oldX || item.y != oldY) changed = true;
@@ -2404,14 +2422,14 @@
}
} else {
int rightItemEdge = getRightItemEdge(gc);
- int maxWidth = rightItemEdge - borderLeft;
+ int maxWidth = rightItemEdge - leftItemEdge;
int width = 0;
for (int i = 0; i < priority.length; i++) {
CTabItem item = items[priority[i]];
width += item.width;
item.showing = i == 0 ? true : item.width > 0 && width <= maxWidth;
}
- int x = -renderer.computeTrim(CTabFolderRenderer.PART_HEADER, SWT.NONE, 0, 0, 0, 0).x;
+ int x = getLeftItemEdge(gc, CTabFolderRenderer.PART_HEADER);
int defaultX = getDisplay().getBounds().width + 10; // off screen
firstIndex = items.length - 1;
for (int i = 0; i < items.length; i++) {
@@ -2477,18 +2495,18 @@
if (isDisposed()) return changed;
Point size = getSize();
if (size.x <= 0 || size.y <= 0) return changed;
-
- Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
- int borderRight = trim.width + trim.x;
- int borderLeft = -trim.x;
-
+ ToolBar chevron = getChevron();
+ if (chevron != null) chevron.setVisible(false);
showChevron = false;
if (single) {
- showChevron = true;
+ showChevron = chevronVisible && items.length > 1;
+ if (showChevron) {
+ chevron.setVisible(true);
+ }
if (selectedIndex != -1) {
CTabItem tab = items[selectedIndex];
int width = renderer.computeSize(selectedIndex, SWT.SELECTED, gc, SWT.DEFAULT, SWT.DEFAULT).x;
- width = Math.min(width, getRightItemEdge(gc) - borderLeft);
+ width = Math.min(width, getRightItemEdge(gc) - getLeftItemEdge(gc, CTabFolderRenderer.PART_BORDER));
if (tab.height != tabHeight || tab.width != width) {
changed = true;
tab.shortenedText = null;
@@ -2507,17 +2525,8 @@
}
if (items.length == 0) return changed;
-
int[] widths;
- int tabAreaWidth = size.x - borderLeft - borderRight - 3;
- if (showMin) tabAreaWidth -= renderer.computeSize(CTabFolderRenderer.PART_MIN_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
- if (showMax) tabAreaWidth -= renderer.computeSize(CTabFolderRenderer.PART_MAX_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
- if (topRightAlignment == SWT.RIGHT && topRight != null) {
- Point rightSize = topRight.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
- tabAreaWidth -= rightSize.x + 3;
- }
- tabAreaWidth = Math.max(0, tabAreaWidth);
-
+ int tabAreaWidth = Math.max(0, getRightItemEdge(gc) - getLeftItemEdge(gc, CTabFolderRenderer.PART_BORDER));
// First, try the minimum tab size at full compression.
int minWidth = 0;
int[] minWidths = new int[items.length];
@@ -2531,8 +2540,11 @@
}
if (minWidth > tabAreaWidth) {
// full compression required and a chevron
- showChevron = items.length > 1;
- if (showChevron) tabAreaWidth -= renderer.computeSize(CTabFolderRenderer.PART_CHEVRON_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
+ showChevron = chevronVisible && items.length > 1;
+ if (showChevron) {
+ tabAreaWidth -= chevron.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
+ chevron.setVisible(true);
+ }
widths = minWidths;
int index = selectedIndex != -1 ? selectedIndex : 0;
if (tabAreaWidth < widths[index]) {
@@ -2655,7 +2667,10 @@
if (this.maximized == maximize) return;
if (maximize && this.minimized) setMinimized(false);
this.maximized = maximize;
- redraw(maxRect.x, maxRect.y, maxRect.width, maxRect.height, false);
+ if (maxImage != null) maxImage.dispose();
+ maxImage = createButtonImage(getDisplay(), CTabFolderRenderer.PART_MAX_BUTTON);
+ maxItem.setImage(maxImage);
+ maxItem.setToolTipText(maximized ? SWT.getMessage("SWT_Restore") : SWT.getMessage("SWT_Maximize")); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
* Marks the receiver's minimize button as visible if the argument is <code>true</code>,
@@ -2695,7 +2710,10 @@
if (this.minimized == minimize) return;
if (minimize && this.maximized) setMaximized(false);
this.minimized = minimize;
- redraw(minRect.x, minRect.y, minRect.width, minRect.height, false);
+ if (minImage != null) minImage.dispose();
+ minImage = createButtonImage(getDisplay(), CTabFolderRenderer.PART_MIN_BUTTON);
+ minItem.setImage(minImage);
+ minItem.setToolTipText(minimized ? SWT.getMessage("SWT_Restore") : SWT.getMessage("SWT_Minimize")); //$NON-NLS-1$ //$NON-NLS-2$
}
/**
@@ -3148,6 +3166,11 @@
redraw();
}
}
+
+int getControlY(Point size, Rectangle[] rects, int borderBottom, int borderTop, int i) {
+ return onBottom ? size.y - 1 - borderBottom - tabHeight + (tabHeight - rects[i].height)/2 : 1 + borderTop + (tabHeight - rects[i].height)/2;
+}
+
/**
* Specify a fixed height for the tab items. If no height is specified,
* the default height is the height of the text or the image, whichever
@@ -3251,22 +3274,15 @@
if (control != null && control.getParent() != this) {
SWT.error(SWT.ERROR_INVALID_ARGUMENT);
}
-
- if (topRight != null && !topRight.isDisposed()) {
- topRight.removeControlListener(topRightResize);
- topRight.setBackground (null);
- topRight.setBackgroundImage (null);
- }
-
+ if (topRight == control && topRightAlignment == alignment) return;
+ if (topRight != null) removeTabControl(topRight, false);
topRight = control;
-
- if (topRight != null)
- topRight.addControlListener(topRightResize);
-
topRightAlignment = alignment;
+ alignment &= ~SWT.RIGHT;
+ if (control != null) addTabControl(control, SWT.TRAIL | alignment, -1, false);
updateTabHeight(false);
if (updateItems()) redraw();
- updateTopRightBackground();
+ updateBkImages();
}
@@ -3427,9 +3443,7 @@
// make sure selected item will be showing
int firstIndex = showIndex;
if (priority[0] < showIndex) {
- Rectangle trim = renderer.computeTrim(CTabFolderRenderer.PART_BORDER, SWT.NONE, 0, 0, 0, 0);
- int borderLeft = -trim.x;
- int maxWidth = getRightItemEdge(gc) - borderLeft;
+ int maxWidth = getRightItemEdge(gc) - getLeftItemEdge(gc, CTabFolderRenderer.PART_BORDER);
int width = 0;
int[] widths = new int[items.length];
for (int i = priority[0]; i <= showIndex; i++) {
@@ -3500,45 +3514,48 @@
GC gc = new GC(this);
tabHeight = renderer.computeSize(CTabFolderRenderer.PART_HEADER, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).y;
gc.dispose();
- if (fixedTabHeight == SWT.DEFAULT && topRight != null) {
- int topHeight = topRight.computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
- topHeight += renderer.computeTrim(CTabFolderRenderer.PART_HEADER, SWT.NONE, 0,0,0,0).height + 1;
- tabHeight = Math.max(topHeight, tabHeight);
+ if (fixedTabHeight == SWT.DEFAULT && controls != null && controls.length > 0) {
+ for (int i = 0; i < controls.length; i++) {
+ if ((controlAlignments[i] & SWT.WRAP) == 0 && controls[i].getVisible()) {
+ int topHeight = controls[i].computeSize(SWT.DEFAULT, SWT.DEFAULT).y;
+ topHeight += renderer.computeTrim(CTabFolderRenderer.PART_HEADER, SWT.NONE, 0,0,0,0).height + 1;
+ tabHeight = Math.max(topHeight, tabHeight);
+ }
+ }
}
if (!force && tabHeight == oldHeight) return false;
oldSize = null;
notifyListeners(SWT.Resize, new Event());
return true;
}
-void updateTopRightBackground() {
- if (topRightImage != null) {
- topRightImage.dispose();
- topRightImage = null;
- }
- if (topRight == null) return;
-
- Rectangle bounds = topRight.getBounds();
- if (topRight instanceof Composite) ((Composite) topRight).setBackgroundMode(SWT.INHERIT_DEFAULT);
- if (bounds.y > getTabHeight() || gradientColors == null) {
- topRight.setBackgroundImage(null);
- topRight.setBackground(getBackground());
- } else {
- bounds.width = 10;
- bounds.y = -bounds.y;
- bounds.height -= 2*bounds.y;
- bounds.x = 0;
- Image image = topRightImage = new Image(topRight.getDisplay(), bounds);
- GC gc = new GC(image);
- renderer.drawBackground(gc, bounds, 0);
- gc.dispose();
- topRight.setBackground(null);
- topRight.setBackgroundImage(image);
+
+void updateBkImages() {
+ if (controls != null && controls.length > 0) {
+ for (int i = 0; i < controls.length; i++) {
+ Control control = controls[i];
+ if (control instanceof Composite) ((Composite) control).setBackgroundMode(SWT.INHERIT_DEFAULT);
+ Rectangle bounds = control.getBounds();
+ if (bounds.y > getTabHeight() || gradientColors == null) {
+ control.setBackgroundImage(null);
+ control.setBackground(getBackground());
+ } else {
+ bounds.width = 10;
+ bounds.y = -bounds.y;
+ bounds.height -= 2*bounds.y - 1;
+ bounds.x = 0;
+ if (controlBkImages[i] != null) controlBkImages[i].dispose();
+ controlBkImages[i] = new Image(control.getDisplay(), bounds);
+ GC gc = new GC(controlBkImages[i]);
+ renderer.drawBackground(gc, bounds, 0);
+ gc.dispose();
+ control.setBackground(null);
+ control.setBackgroundImage(controlBkImages[i]);
+ }
+ }
+
}
}
String _getToolTip(int x, int y) {
- if (showMin && minRect.contains(x, y)) return minimized ? SWT.getMessage("SWT_Restore") : SWT.getMessage("SWT_Minimize"); //$NON-NLS-1$ //$NON-NLS-2$
- if (showMax && maxRect.contains(x, y)) return maximized ? SWT.getMessage("SWT_Restore") : SWT.getMessage("SWT_Maximize"); //$NON-NLS-1$ //$NON-NLS-2$
- if (showChevron && chevronRect.contains(x, y)) return SWT.getMessage("SWT_ShowList"); //$NON-NLS-1$
CTabItem item = getItem(new Point (x, y));
if (item == null) return null;
if (!item.showing) return null;
@@ -3604,16 +3621,71 @@
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
* <li>ERROR_INVALID_ARGUMENT - if the control is not a child of this CTabFolder</li>
* </ul>
-* @since 3.7
+* @since 4.1
*/
public void addTabControl(Control control, int flags) {
- SWT.error (SWT.ERROR_NOT_IMPLEMENTED, null, "");
+ checkWidget();
+ addTabControl(control, flags, -1, true);
}
-
+void addTabControl(Control control, int flags, int index, boolean update) {
+ switch (flags) {
+ case SWT.TRAIL:
+ case SWT.TRAIL | SWT.WRAP:
+ case SWT.TRAIL | SWT.FILL:
+ case SWT.TRAIL | SWT.FILL | SWT.WRAP:
+ case SWT.LEAD:
+ break;
+ default:
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ break;
+ }
+ if (control != null && control.getParent() != this) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ //check for duplicates
+ for (int i = 0; i < controls.length; i++) {
+ if (controls[i] == control) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ }
+ int length = controls.length;
+
+ control.addListener(SWT.Resize, listener);
+
+ //Grow all 4 arrays
+ Control[] newControls = new Control [length + 1];
+ System.arraycopy(controls, 0, newControls, 0, length);
+ controls = newControls;
+ int[] newAlignment = new int [length + 1];
+ System.arraycopy(controlAlignments, 0, newAlignment, 0, length);
+ controlAlignments = newAlignment;
+ Rectangle[] newRect = new Rectangle [length + 1];
+ System.arraycopy(controlRects, 0, newRect, 0, length);
+ controlRects = newRect;
+ Image[] newImage = new Image [length + 1];
+ System.arraycopy(controlBkImages, 0, newImage, 0, length);
+ controlBkImages = newImage;
+ if (index == -1) {
+ index = length;
+ if (chevronTb != null && control != chevronTb) index--;
+ }
+ System.arraycopy (controls, index, controls, index + 1, length - index);
+ System.arraycopy (controlAlignments, index, controlAlignments, index + 1, length - index);
+ System.arraycopy (controlRects, index, controlRects, index + 1, length - index);
+ System.arraycopy (controlBkImages, index, controlBkImages, index + 1, length - index);
+ controls[index] = control;
+ controlAlignments[index] = flags;
+ controlRects[index] = new Rectangle(0, 0, 0, 0);
+ if (update) {
+ updateTabHeight(false);
+ if (updateItems()) redraw();
+ updateBkImages();
+ }
+}
/**
-* Removes the control from the list of tab controls
+* Removes the control from the list of tab controls.
*
* @param control the control to be removed
*
@@ -3622,12 +3694,65 @@
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
* <li>ERROR_INVALID_ARGUMENT - if the control is not a child of this CTabFolder</li>
* </ul>
-* @since 3.7
+* @since 4.1
*/
public void removeTabControl (Control control) {
- SWT.error (SWT.ERROR_NOT_IMPLEMENTED, null, "");
+ checkWidget();
+ removeTabControl (control, true);
}
+void removeTabControl (Control control, boolean update) {
+ if (control != null && control.getParent() != this) {
+ SWT.error(SWT.ERROR_INVALID_ARGUMENT);
+ }
+ int index = -1;
+ for (int i = 0; i < controls.length; i++) {
+ if (controls[i] == control){
+ index = i;
+ break;
+ }
+ }
+ if (index == -1) return;
+
+ if (!control.isDisposed()) {
+ control.removeListener(SWT.Resize, listener);
+ control.setBackground (null);
+ control.setBackgroundImage (null);
+ if (control instanceof Composite) ((Composite) control).setBackgroundMode(SWT.INHERIT_NONE);
+ }
+
+ if (controlBkImages[index] != null && !controlBkImages[index].isDisposed()) controlBkImages[index].dispose();
+ if (controls.length == 1) {
+ controls = new Control[0];
+ controlAlignments = new int[0];
+ controlRects = new Rectangle[0];
+ controlBkImages = new Image[0];
+ } else {
+ Control[] newControls = new Control [controls.length - 1];
+ System.arraycopy(controls, 0, newControls, 0, index);
+ System.arraycopy(controls, index + 1, newControls, index, controls.length - index - 1);
+ controls = newControls;
+
+ int[] newAlignments = new int [controls.length];
+ System.arraycopy(controlAlignments, 0, newAlignments, 0, index);
+ System.arraycopy(controlAlignments, index + 1, newAlignments, index, controls.length - index);
+ controlAlignments = newAlignments;
+
+ Rectangle[] newRects = new Rectangle [controls.length];
+ System.arraycopy(controlRects, 0, newRects, 0, index);
+ System.arraycopy(controlRects, index + 1, newRects, index, controls.length - index);
+ controlRects = newRects;
+
+ Image[] newBkImages = new Image [controls.length];
+ System.arraycopy(controlBkImages, 0, newBkImages, 0, index);
+ System.arraycopy(controlBkImages, index + 1, newBkImages, index, controls.length - index);
+ controlBkImages = newBkImages;
+ }
+ if (update) {
+ updateItems();
+ redraw();
+ }
+}
/**
* Return the visible item for the specified flags.
@@ -3659,8 +3784,24 @@
return null;
}
+int getWrappedHeight (Point size) {
+ boolean[][] positions = new boolean[1][];
+ GC gc = new GC(this);
+ Rectangle[] rects = computeControlBounds(size, positions);
+ gc.dispose();
+ int minY = Integer.MAX_VALUE, maxY = 0, wrapHeight = 0;
+ for (int i = 0; i < rects.length; i++) {
+ if (positions[0][i]) {
+ minY = Math.min(minY, rects[i].y);
+ maxY = Math.max(maxY, rects[i].y + rects[i].height);
+ wrapHeight = maxY - minY;
+ }
+ }
+ return wrapHeight;
+}
+
/**
- * Show a chevron if there are more items to be displayed.
+ * Sets whether a chevron is shown when there are more items to be displayed.
*
* @exception IllegalArgumentException <ul>
* <li>ERROR_INVALID_RANGE - if the index is out of range</li>
@@ -3670,9 +3811,13 @@
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li>
* </ul>
*
- * @since 3.7
+ * @since 4.1
*/
public void setChevronVisible(boolean visible) {
- SWT.error (SWT.ERROR_NOT_IMPLEMENTED, null, "");
+ checkWidget();
+ if (chevronVisible == visible) return;
+ chevronVisible = visible;
+ updateItems();
+ redraw();
}
}
diff --git a/bundles/org.eclipse.e4.ui.widgets/src/org/eclipse/e4/ui/widgets/CTabFolderLayout.java b/bundles/org.eclipse.e4.ui.widgets/src/org/eclipse/e4/ui/widgets/CTabFolderLayout.java
index eb651c5..963847e 100644
--- a/bundles/org.eclipse.e4.ui.widgets/src/org/eclipse/e4/ui/widgets/CTabFolderLayout.java
+++ b/bundles/org.eclipse.e4.ui.widgets/src/org/eclipse/e4/ui/widgets/CTabFolderLayout.java
@@ -38,24 +38,44 @@
tabW += renderer.computeSize(i, state, gc, SWT.DEFAULT, SWT.DEFAULT).x;
}
}
- tabW += 3;
- if (folder.showMax) tabW += renderer.computeSize(CTabFolderRenderer.PART_MAX_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
- if (folder.showMin) tabW += renderer.computeSize(CTabFolderRenderer.PART_MIN_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
- if (folder.single) tabW += renderer.computeSize(CTabFolderRenderer.PART_CHEVRON_BUTTON, SWT.NONE, gc, SWT.DEFAULT, SWT.DEFAULT).x;
- int headerH = 0;
- if (folder.topRight != null) {
- Point pt = folder.topRight.computeSize(SWT.DEFAULT, folder.tabHeight, flushCache);
- if (wHint == SWT.DEFAULT || folder.topRightAlignment != (SWT.RIGHT | SWT.WRAP)) {
- tabW += 3 + pt.x;
- } else {
- if (wHint - tabW > pt.x) {
- tabW += 3 + pt.x;
+ int width = 0, wrapHeight = 0;
+ boolean leftControl = false, rightControl = false;
+ if (wHint == SWT.DEFAULT) {
+ for (int i = 0; i < folder.controls.length; i++) {
+ Control control = folder.controls[i];
+ if (control.getVisible()) {
+ if ((folder.controlAlignments[i] & SWT.LEAD) != 0) {
+ leftControl = true;
+ } else {
+ rightControl = true;
+ }
+ width += control.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
+ }
+ }
+ } else {
+ Point size = new Point (wHint, hHint);
+ boolean[][] positions = new boolean[1][];
+ Rectangle[] rects = folder.computeControlBounds(size, positions);
+ int minY = Integer.MAX_VALUE, maxY = 0;
+ for (int i = 0; i < rects.length; i++) {
+ if (positions[0][i]) {
+ minY = Math.min(minY, rects[i].y);
+ maxY = Math.max(maxY, rects[i].y + rects[i].height);
+ wrapHeight = maxY - minY;
} else {
- headerH += pt.y;
+ if ((folder.controlAlignments[i] & SWT.LEAD) != 0) {
+ leftControl = true;
+ } else {
+ rightControl = true;
+ }
+ width += rects[i].width;
}
}
}
+ if (leftControl) width += CTabFolder.SPACING * 2;
+ if (rightControl) width += CTabFolder.SPACING * 2;
+ tabW += width;
gc.dispose();
@@ -71,8 +91,8 @@
}
}
- int minWidth = Math.max(tabW, controlW);
- int minHeight = (folder.minimized) ? 0 : controlH + headerH;
+ int minWidth = Math.max(tabW, controlW + folder.marginWidth);
+ int minHeight = (folder.minimized) ? 0 : controlH + wrapHeight;
if (minWidth == 0) minWidth = CTabFolder.DEFAULT_WIDTH;
if (minHeight == 0) minHeight = CTabFolder.DEFAULT_HEIGHT;
diff --git a/bundles/org.eclipse.e4.ui.widgets/src/org/eclipse/e4/ui/widgets/CTabFolderRenderer.java b/bundles/org.eclipse.e4.ui.widgets/src/org/eclipse/e4/ui/widgets/CTabFolderRenderer.java
index 1912381..0a5afea 100644
--- a/bundles/org.eclipse.e4.ui.widgets/src/org/eclipse/e4/ui/widgets/CTabFolderRenderer.java
+++ b/bundles/org.eclipse.e4.ui.widgets/src/org/eclipse/e4/ui/widgets/CTabFolderRenderer.java
@@ -80,7 +80,8 @@
static final RGB CLOSE_FILL = new RGB(252, 160, 160);
- static final int BUTTON_SIZE = 18;
+ static final int BUTTON_SIZE = 16;
+ static final int BUTTON_TRIM = 1;
static final int BUTTON_BORDER = SWT.COLOR_WIDGET_DARK_SHADOW;
static final int BUTTON_FILL = SWT.COLOR_LIST_BACKGROUND;
@@ -350,6 +351,15 @@
case PART_HEADER:
//no trim
break;
+ case PART_MAX_BUTTON:
+ case PART_MIN_BUTTON:
+ case PART_CLOSE_BUTTON:
+ case PART_CHEVRON_BUTTON:
+ x -= BUTTON_TRIM;
+ y -= BUTTON_TRIM;
+ width += BUTTON_TRIM*2;
+ height += BUTTON_TRIM*2;
+ break;
case PART_BORDER:
x = x - borderLeft;
width = width + borderLeft + borderRight;
diff --git a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/CTabRendering.java b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/CTabRendering.java
index bb428b1..e66ae07 100644
--- a/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/CTabRendering.java
+++ b/bundles/org.eclipse.e4.ui.workbench.renderers.swt/src/org/eclipse/e4/ui/workbench/renderers/swt/CTabRendering.java
@@ -343,7 +343,9 @@
int circX = bounds.x + radius;
int circY = bounds.y - 1 + radius;
int selectionX1, selectionY1, selectionX2, selectionY2;
- if (itemIndex == 0) {
+ if (itemIndex == 0
+ && bounds.x == -computeTrim(CTabFolderRenderer.PART_HEADER,
+ SWT.NONE, 0, 0, 0, 0).x) {
circX -= 1;
points[index++] = circX - radius;
points[index++] = bounds.y + bounds.height;