Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.
View | Details | Raw Unified | Return to bug 123257 | Differences between
and this patch

Collapse All | Expand All

(-)plugin.xml (-3 / +4 lines)
Lines 46-54 Link Here
46
            class="org.eclipse.ui.examples.presentation.wrappedtabs.WrappedTabsPresentationFactory"
46
            class="org.eclipse.ui.examples.presentation.wrappedtabs.WrappedTabsPresentationFactory"
47
            name="Wrapped tabs presentation"
47
            name="Wrapped tabs presentation"
48
            id="org.eclipse.ui.examples.presentation.wrappedtabs"/>
48
            id="org.eclipse.ui.examples.presentation.wrappedtabs"/>
49
   </extension>
50
      <extension
51
         point="org.eclipse.ui.presentationFactories">
52
      <factory
49
      <factory
53
            class="org.eclipse.ui.internal.presentations.defaultpresentation.NativePresentationFactory"
50
            class="org.eclipse.ui.internal.presentations.defaultpresentation.NativePresentationFactory"
54
            name="Native Tabs"
51
            name="Native Tabs"
Lines 61-66 Link Here
61
            class="org.eclipse.ui.examples.presentation.sidewinder.SideWinderPresentationFactory"
58
            class="org.eclipse.ui.examples.presentation.sidewinder.SideWinderPresentationFactory"
62
            id="org.eclipse.ui.examples.presentation.factory2"
59
            id="org.eclipse.ui.examples.presentation.factory2"
63
            name="Side Winder"/>
60
            name="Side Winder"/>
61
      <factory
62
            class="org.eclipse.ui.examples.presentation.customtoolbar.CustomToolBarPresentationFactory"
63
            id="org.eclipse.ui.examples.presentation.customtoolbar"
64
            name="Custom Toolbar"/>
64
   </extension>
65
   </extension>
65
66
66
<!-- =================================================================================== -->
67
<!-- =================================================================================== -->
(-)src/org/eclipse/ui/examples/presentation/customtoolbar/widgets/HannoverGlobalCoolBarSkin.java (+200 lines)
Added Link Here
1
package org.eclipse.ui.examples.presentation.customtoolbar.widgets;
2
3
import org.eclipse.swt.SWT;
4
import org.eclipse.swt.graphics.Color;
5
import org.eclipse.swt.graphics.Font;
6
import org.eclipse.swt.graphics.GC;
7
import org.eclipse.swt.graphics.Image;
8
import org.eclipse.swt.graphics.Point;
9
import org.eclipse.swt.graphics.Rectangle;
10
import org.eclipse.swt.widgets.Display;
11
12
public class HannoverGlobalCoolBarSkin implements Skin {
13
14
	// border colors
15
	Color borderTopColor = new Color(null, 255, 255, 255);
16
	Color borderBottomColor = new Color(null, 144, 161, 181);
17
	Color borderLeftRightColor = new Color(null, 255, 255, 255);
18
	Color draggerLineColor = new Color(null, 168, 191, 197);
19
	Color draggerLineColor2 = new Color(null, 255, 255, 255);
20
	
21
	// background colors
22
	Color shadowColor = new Color(null, 109, 131, 180);
23
	Color backgroundTopColor = new Color(null, 247, 247, 247);
24
	Color backgroundBottomColor = new Color(null, 189, 198, 216);
25
	Color hoverItemBackgroundColor = new Color(null, 224, 233, 237);
26
	Color pressedItemBackgroundColor = new Color(null, 231, 231, 231);
27
	
28
	// arrows and text colors
29
	Color arrowColor = Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);
30
	Color textColor = new Color(null, 43,73,111);
31
	Color hoverTextColor = new Color(null, 20, 38, 54);
32
33
	// gripper
34
	private final static int GRIPPER_DOT_HEIGHT = 3;
35
	private final static int GRIPPER_DOT_COUNT = 3;
36
37
	Color[] gripperColors = {
38
				new Color(null,213,218,225),new Color(null,174,186,197),new Color(null,214,219,225),
39
				new Color(null,246,246,243),new Color(null,247,248,246),new Color(null,245,246,242),
40
				new Color(null,247,248,248),new Color(null,249,249,249),new Color(null,247,248,248),
41
				new Color(null,208,241,222),new Color(null,173,184,197),new Color(null,208,214,222),
42
				new Color(null,246,247,245),new Color(null,247,248,246),new Color(null,246,247,245),
43
				new Color(null,240,241,244),new Color(null,247,248,247),new Color(null,240,242,244),
44
				new Color(null,200,208,217),new Color(null,171,183,196),new Color(null,200,208,217),
45
				new Color(null,244,245,244),new Color(null,247,248,246),new Color(null,244,245,244),
46
				new Color(null,232,235,239),new Color(null,246,247,246),new Color(null,232,235,240)
47
	};
48
49
	public HannoverGlobalCoolBarSkin() {
50
		super();
51
	}
52
	
53
	public Rectangle getInsets(int type, int state) {
54
		return null;
55
	}
56
57
	public Point getSize(int type, int state) {
58
		if (type == Skin.TYPE_DECORATION_GRIPPER) {
59
			return new Point(6, SWT.DEFAULT);
60
		} else if (type == Skin.TYPE_ITEM_MIN_MAX_HEIGHT) {
61
			return new Point(26, SWT.DEFAULT);
62
		} else if (type == Skin.TYPE_ITEM_MIN_MAX_WIDTHS) {
63
			return new Point(26, SWT.DEFAULT);
64
		}
65
		return null;
66
	}
67
68
	public Font getFont(int type, int state) {
69
		return null;
70
	}
71
72
	public Rectangle getMargins(int type, int state) {
73
		return new Rectangle(0,0,0,0);
74
	}
75
76
	public Rectangle getRect(int type, int state) {
77
		if (type == Skin.TYPE_ITEM_BORDER) {
78
			/*
79
			 * x - border on left of cool item (does not include gripper decorator.
80
			 * y - border on top of cool item
81
			 * width - border on right of cool item
82
			 * height - border on bottom of cool item
83
			 */
84
			return new Rectangle(0, 0, 2, 0);
85
		} else if (type == Skin.TYPE_BORDER) {
86
			/*
87
			 * x - border on left of coolbar
88
			 * y - border on top of coolbar
89
			 * width - border on right of coolbar
90
			 * height - border on bottom of coolbar
91
			 */
92
			return new Rectangle(1, 0, 1, 0);
93
		}
94
		return null;
95
	}
96
97
	public void drawBorder(GC gc, Rectangle rect, SWidget widget, int type, int state) {
98
		if (type == Skin.TYPE_BORDER) {
99
			// left/right edge
100
			gc.setForeground(borderLeftRightColor);
101
			gc.drawLine(rect.x, rect.y, rect.x, rect.y+rect.height-1);
102
			gc.drawLine(rect.x+rect.width-1, rect.y, rect.x+rect.width-1, rect.y+rect.height-1);
103
104
			// top edge
105
			gc.setForeground(borderTopColor);
106
			gc.drawLine(rect.x, rect.y, rect.x + rect.width -1, rect.y);
107
			// bottom edge
108
			gc.setForeground(borderBottomColor);
109
			gc.drawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width -1, rect.y + rect.height - 1);
110
		} else if (type == Skin.TYPE_ITEM_BORDER) {
111
			// top edge
112
			gc.setForeground(borderTopColor);
113
			gc.drawLine(rect.x, rect.y, rect.x + rect.width -1, rect.y);
114
			// bottom edge
115
			gc.setForeground(borderBottomColor);
116
			gc.drawLine(rect.x, rect.y + rect.height - 1, rect.x + rect.width -1, rect.y + rect.height - 1);
117
118
			// Right edge.
119
			gc.setForeground(draggerLineColor);
120
			gc.drawLine(rect.x + rect.width -2, rect.y, rect.x + rect.width -2, rect.y + rect.height - 2);
121
			gc.setForeground(draggerLineColor2);			
122
			gc.drawLine(rect.x + rect.width -1, rect.y, rect.x + rect.width -1, rect.y + rect.height - 2);
123
		}
124
	}
125
126
	public void drawBackground(GC gc, Rectangle rect, SWidget widget, int type, int state) {
127
		
128
		if (type == Skin.TYPE_BACKGROUND) {
129
			gc.setForeground(backgroundTopColor); 
130
			gc.setBackground(backgroundBottomColor); 
131
			gc.fillGradientRectangle(rect.x, rect.y, rect.width, rect.height, true); 
132
		} 
133
	}
134
135
	public void drawDecoration(GC gc, Rectangle rect, SWidget widget, int type, int state) {
136
		if (type == Skin.TYPE_DECORATION_GRIPPER) {
137
			drawGripper(gc, rect, widget, type, state);
138
		}
139
	}
140
141
	public void drawText(GC gc, Rectangle rect, String text, int style, SWidget widget, int type, int state) {
142
	}
143
144
	public void drawImage(GC gc, Rectangle rect, Image image, SWidget widget, int type, int state) {
145
	}
146
147
	public void dispose() {
148
		if (borderTopColor != null && borderTopColor.isDisposed() == false)
149
			borderTopColor.dispose();
150
		if (draggerLineColor != null && draggerLineColor.isDisposed() == false)
151
			draggerLineColor.dispose();
152
153
		if (shadowColor != null && shadowColor.isDisposed() == false)
154
			shadowColor.dispose();
155
		if (backgroundTopColor != null && backgroundTopColor.isDisposed() == false)
156
			backgroundTopColor.dispose();
157
		if (backgroundBottomColor != null && backgroundBottomColor.isDisposed() == false)
158
			backgroundBottomColor.dispose();
159
		if (hoverItemBackgroundColor != null && hoverItemBackgroundColor.isDisposed() == false)
160
			hoverItemBackgroundColor.dispose();
161
		if (pressedItemBackgroundColor != null && pressedItemBackgroundColor.isDisposed() == false)
162
			pressedItemBackgroundColor.dispose();
163
		
164
		if (arrowColor != null && arrowColor.isDisposed() == false)
165
			arrowColor.dispose();
166
		if (textColor != null && textColor.isDisposed() == false)
167
			textColor.dispose();
168
		if (hoverTextColor != null && hoverTextColor.isDisposed() == false)
169
			hoverTextColor.dispose();
170
		
171
		for (int i = 0; i < gripperColors.length; i++) {
172
			if (gripperColors[i] != null && gripperColors[i].isDisposed() == false)
173
				gripperColors[i].dispose();
174
		}
175
	}
176
	
177
	private void drawGripper(GC gc, Rectangle rect, SWidget widget, int type, int state) {
178
179
		int dotGap = GRIPPER_DOT_HEIGHT;
180
		int gripperImageHeight = GRIPPER_DOT_HEIGHT * GRIPPER_DOT_COUNT + dotGap * (GRIPPER_DOT_COUNT-1);
181
		int left = rect.x + rect.width - 3;
182
		int top = rect.y + (rect.height - gripperImageHeight) / 2;
183
		
184
		int x = left;
185
		int y = top;
186
		for (int i = 0; i < gripperColors.length; i++) {
187
			if (i != 0 && i % 9 == 0) {
188
				x = left;
189
				y += dotGap+1;
190
			} else if (i != 0 && i % 3 == 0) {
191
				x = left;
192
				y++;
193
			}
194
			gc.setForeground(gripperColors[i]); 
195
			gc.drawPoint(x,y);
196
			x++;
197
		}
198
	}
199
200
}
(-)src/org/eclipse/ui/examples/presentation/customtoolbar/widgets/SWidget.java (+31 lines)
Added Link Here
1
package org.eclipse.ui.examples.presentation.customtoolbar.widgets;
2
3
import org.eclipse.swt.widgets.Canvas;
4
import org.eclipse.swt.widgets.Composite;
5
6
public abstract class SWidget extends Canvas {
7
	
8
	public static final int HOVER = 1 << 1;
9
	public static final int SELECTED = 1 << 2;
10
	public static final int PRESSED = 1 << 3;
11
	
12
	private Skin skin;
13
14
	public SWidget(Composite parent, int style) {
15
		super(parent, style);
16
	}
17
	
18
	public void setSkin(Skin skin) {
19
		if (this.skin != null) {
20
			this.skin.dispose();
21
			this.skin = null;
22
		}
23
24
		this.skin = skin;
25
	}
26
27
	public Skin getSkin() {
28
		return skin;
29
	}
30
	
31
}
(-)src/org/eclipse/ui/examples/presentation/customtoolbar/widgets/SCoolBar.java (+411 lines)
Added Link Here
1
package org.eclipse.ui.examples.presentation.customtoolbar.widgets;
2
3
import java.util.ArrayList;
4
5
import org.eclipse.swt.SWT;
6
import org.eclipse.swt.graphics.GC;
7
import org.eclipse.swt.graphics.Point;
8
import org.eclipse.swt.graphics.Rectangle;
9
import org.eclipse.swt.widgets.Composite;
10
import org.eclipse.swt.widgets.Event;
11
import org.eclipse.swt.widgets.Listener;
12
13
14
public class SCoolBar extends SWidget {
15
	
16
	private ArrayList items = new ArrayList();
17
18
	static final int DEFAULT_WIDTH	= 64;
19
	static final int DEFAULT_HEIGHT	= 64;
20
	static final int ITEM_INSET_TOP = 0;
21
	static final int ITEM_INSET_BOTTOM = 0;
22
	static final int LEFT_MARGIN = 6;
23
	static final int SHADOW_SIZE = 4;
24
25
	public SCoolBar(Composite parent, int style) {
26
		super(parent, checkStyle(style));
27
28
		Listener listener = new Listener() {
29
			public void handleEvent(Event event) {
30
				switch (event.type) {
31
					case SWT.Dispose:      		
32
						onDispose(event);
33
						break;
34
					case SWT.MouseDown:
35
						onMouseDown(event);
36
						break;
37
					case SWT.MouseExit:
38
						onMouseExit(event);
39
						break;
40
					case SWT.MouseMove:
41
						onMouseMove(event);
42
						break;
43
					case SWT.MouseUp:
44
						onMouseUp(event);
45
						break;
46
					case SWT.MouseDoubleClick:
47
						onMouseDoubleClick(event);
48
						break;
49
					case SWT.Paint:
50
						onPaint(event);
51
						break;
52
					case SWT.Resize:
53
						onResize(event);
54
						break;
55
				}
56
			}
57
		};
58
		int[] events = new int[] { 
59
			SWT.Dispose, 
60
			SWT.MouseDown,
61
			SWT.MouseExit, 
62
			SWT.MouseMove, 
63
			SWT.MouseUp, 
64
			SWT.MouseDoubleClick,
65
			SWT.Paint,
66
			SWT.Resize
67
		};
68
		for (int i = 0; i < events.length; i++) {
69
			addListener(events[i], listener);	
70
		}
71
	}
72
73
	private static int checkStyle(int style) {
74
		return style;
75
	}
76
77
	public Point computeSize(int wHint, int hHint) {
78
		return computeSize(wHint, hHint, true);
79
	}
80
	
81
	public Point computeSize(int wHint, int hHint, boolean changed) {
82
		checkWidget();
83
		int width = 0;
84
		int height = 0;
85
		int rowWidth = 0;
86
		int rowHeight = 0;
87
		for (int i = 0; i < items.size(); i++) {
88
			SCoolItem item = (SCoolItem)items.get(i);
89
			Point pt = item.getPreferredSize();
90
			if (i != 0 && item.wrap == true) {
91
				width = Math.max(rowWidth, width);
92
				height += rowHeight;
93
				rowWidth = 0;
94
				rowHeight = 0;
95
			}
96
			rowWidth += pt.x;
97
			rowHeight = Math.max(pt.y, rowHeight);
98
		}
99
		width = Math.max(rowWidth, width);
100
		height += rowHeight;
101
		if (wHint == 0) { 
102
			width = DEFAULT_WIDTH;
103
		}
104
		if (hHint == 0) {
105
			height = DEFAULT_HEIGHT;
106
		}
107
		
108
		Skin skin = getSkin();
109
		Rectangle borders = null;
110
		
111
		if (skin != null) {
112
			borders = skin.getRect(Skin.TYPE_BORDER, Skin.NORMAL);
113
		} 
114
		if (borders == null) {
115
			borders = new Rectangle(0, 0, 0, 0);
116
		}
117
		
118
		width += borders.x + borders.width;
119
		height += borders.y + borders.height;
120
		
121
		if (wHint != SWT.DEFAULT) {
122
			width = wHint;
123
		}
124
		if (hHint != SWT.DEFAULT) {
125
			height = hHint;
126
		}
127
		Rectangle trim = computeTrim(0, 0, width, height);
128
		Point pt = new Point(trim.width, trim.height);;
129
130
		return pt;
131
	}
132
133
	void createItem (SCoolItem item, int index) {
134
		int itemCount = getItemCount();
135
		if (!(0 <= index && index <= itemCount))
136
			SWT.error (SWT.ERROR_INVALID_RANGE);
137
		items.add(index, item);
138
		layout();
139
	}
140
	
141
	/**
142
	 * @return
143
	 */
144
	public int[] getAlignmentIndices () {
145
		checkWidget ();
146
		int itemCount = items.size();
147
		int[] indices = new int[itemCount];
148
		int count = 0;
149
		for (int i = 0; i < itemCount; i++) {
150
			SCoolItem item = (SCoolItem)items.get(i);
151
			if (item.alignment) {
152
				indices[count++] = i;
153
			}
154
		}
155
		int[] result = new int[count];
156
		System.arraycopy (indices, 0, result, 0, count);
157
		return result;		
158
	}
159
	
160
	public SCoolItem getItem(int index) {
161
		checkWidget();
162
		SCoolItem item = (SCoolItem)items.get(index);
163
		return item;
164
	}
165
	
166
	public int getItemCount() {
167
		checkWidget();
168
		return items.size();
169
	}
170
	
171
	public SCoolItem[] getItems() {
172
		checkWidget();
173
		if (items.size() == 0)
174
			return new SCoolItem[0];
175
		return (SCoolItem[])items.toArray(new SCoolItem[1]);
176
	}
177
178
	public boolean getLocked() {
179
		return false;
180
	}
181
	
182
	/**
183
	 * 
184
	 * @return
185
	 */
186
	public int[] getWrapIndices () {
187
		checkWidget ();
188
		int itemCount = items.size();
189
		int[] indices = new int[itemCount];
190
		int count = 0;
191
		for (int i = 0; i < itemCount; i++) {
192
			SCoolItem item = (SCoolItem)items.get(i);
193
			if (item.wrap) {
194
				indices[count++] = i;
195
			}
196
		}
197
		int[] result = new int[count];
198
		System.arraycopy (indices, 0, result, 0, count);
199
		return result;
200
	}
201
	
202
	public int indexOf(SCoolItem item) {
203
		checkWidget();
204
		if (item == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
205
		if (item.isDisposed()) SWT.error (SWT.ERROR_INVALID_ARGUMENT);
206
		return items.indexOf(item);
207
	}
208
	
209
	protected void onDispose(Event event) {
210
		// TODO Auto-generated method stub
211
		
212
	}
213
214
	protected void onMouseDown(Event event) {
215
		// TODO Auto-generated method stub
216
		
217
	}
218
219
	protected void onMouseExit(Event event) {
220
		// TODO Auto-generated method stub
221
		
222
	}
223
224
	protected void onMouseMove(Event event) {
225
		// TODO Auto-generated method stub
226
		
227
	}
228
229
	protected void onMouseUp(Event event) {
230
		// TODO Auto-generated method stub
231
		
232
	}
233
234
	protected void onMouseDoubleClick(Event event) {
235
		// TODO Auto-generated method stub
236
		
237
	}
238
239
	protected void onPaint(Event event) {
240
		Skin skin = getSkin();
241
		GC gc = event.gc;
242
		
243
		if (skin == null)
244
			return;
245
				
246
		Rectangle rect = getClientArea();
247
		if (rect.width == 0 || rect.height == 0)
248
			return;
249
		
250
		int state = Skin.NORMAL;
251
		
252
		// paint background
253
		skin.drawBackground(gc, rect, this, Skin.TYPE_BACKGROUND, state);
254
		
255
		// paint border
256
		skin.drawBorder(gc, rect, this, Skin.TYPE_BORDER, state);
257
258
		// paint each item
259
		for (int i = 0; i < items.size(); i++) {
260
			SCoolItem item = getItem(i);
261
			if (item != null) {
262
				item.paint(gc, state);
263
			}
264
		}
265
	}
266
267
	protected void onResize(Event event) {
268
		layout();
269
	}
270
	
271
	/**
272
	 * Sets the indices of all item(s) in the receiver 
273
	 * that will begin right alignment on each row.
274
	 * For example, if indice contains 2, 
275
	 * that mean all the items from item2 to the end row are right aligned. 
276
	 *  
277
	 * @param indices
278
	 */
279
	public void setAlignmentIndices(int[] indices) {
280
		checkWidget();
281
		if (indices == null) 
282
			indices = new int[0];
283
		int count = items.size();
284
//		for (int i = 0; i< indices.length; i++) {
285
//			if (indices[i] < 0 || indices[i] >= count) {
286
//				SWT.error (SWT.ERROR_INVALID_ARGUMENT);
287
//			}
288
//		}
289
		for (int i = 0; i < items.size(); i++) {
290
			((SCoolItem)items.get(i)).alignment = false;
291
		}
292
		for (int i = 0; i < indices.length; i++) {
293
			int index = indices[i];
294
			if (index < items.size()) {
295
				((SCoolItem)items.get(index)).alignment = true;
296
			}
297
		}
298
		layout();
299
	}
300
301
	public void setBounds(int x, int y, int width, int height) {
302
		super.setBounds(x, y, width, height);
303
	}
304
	
305
	public void setBounds(Rectangle rect) {
306
		super.setBounds(rect);
307
	}
308
	
309
	public void setSize(int width, int height) {
310
		super.setSize(width, height);
311
	}
312
	 
313
	
314
	public void setLocked(boolean locked) {
315
		// TODO Auto-generated method stub
316
	}
317
318
	public void setWrapIndices(int[] wrapIndices) {
319
		// TODO Auto-generated method stub
320
	}
321
322
	public void layout(boolean changed) {
323
		int x = 1;
324
		int y = 0;
325
		int rowHeight = 0;
326
		int maxHeightInRow = 0;
327
		int maxWidth;
328
		int i;
329
		Skin skin = getSkin();
330
		Rectangle borders = null;
331
		
332
		if (skin != null) {
333
			borders = skin.getRect(Skin.TYPE_BORDER, Skin.NORMAL);
334
		} 
335
		if (borders == null) {
336
			borders = new Rectangle(0, 0, 0, 0);
337
		}
338
339
		maxWidth = getClientArea().width;
340
		if (maxWidth == 0)
341
			return;
342
		
343
		x = borders.x;
344
		
345
		for (i = 0; i < items.size(); i++) {
346
			SCoolItem item = (SCoolItem)items.get(i);
347
			Point itemSize = item.computeSize(SWT.DEFAULT, SWT.DEFAULT);
348
			maxHeightInRow = Math.max(itemSize.y, maxHeightInRow);
349
		}
350
351
		for (i = 0; i < items.size(); i++) {
352
			
353
			// TODO: multiple row support
354
			
355
			// calc max height in row
356
//			if (i == 0 || ((SCoolItem)items.get(i)).wrap) {
357
//				rowHeight = maxHeightInRow;
358
//				maxHeightInRow = 0;
359
//				for (int j = i; j < items.size(); j++) {
360
//					SCoolItem item = (SCoolItem)items.get(j);
361
//					if (j != 0 && item.wrap)
362
//						break;
363
//					Point itemSize = item.computeSize(SWT.DEFAULT, SWT.DEFAULT);
364
//					maxHeightInRow = Math.max(itemSize.y, maxHeightInRow);
365
//				}
366
//			}
367
			
368
			// layout item
369
			SCoolItem item = (SCoolItem)items.get(i);
370
			Point itemSize = item.computeSize(SWT.DEFAULT, SWT.DEFAULT);
371
			Rectangle oldBounds = item.getBounds();
372
			if (i != 0 && item.wrap) {
373
				x = borders.x;
374
				y += rowHeight;
375
			} else if (item.alignment) {
376
				// right align from this item till the last item in the row
377
				
378
				int rightAlignWidth = 0;
379
				for (int j = i; j < items.size(); j++) {
380
					SCoolItem rightItem = (SCoolItem)items.get(j);
381
					int itemWidth = rightItem.computeSize(SWT.DEFAULT, SWT.DEFAULT).x;
382
					rightAlignWidth += itemWidth; 
383
					if (rightItem.wrap == true)
384
						break;
385
				}
386
				int prevx = x;
387
				x = maxWidth - rightAlignWidth;	 // new x position after right alingn
388
				if (i > 0 && prevx != x) {
389
					// change the previous item width wider
390
					SCoolItem prevItem = (SCoolItem)items.get(i-1);
391
					Point pt = prevItem.computeSize(SWT.DEFAULT, SWT.DEFAULT);
392
					Rectangle r = prevItem.getBounds();
393
					prevItem.setBounds(r.x, r.y, pt.x + x - prevx, pt.y);
394
					//prevItem.setBounds(r.x, r.y, r.width + x - prevx, r.height);
395
				}
396
			}		
397
			if (x + itemSize.x > maxWidth) {
398
				itemSize.x -= (x + itemSize.x - maxWidth); 
399
			}
400
			Rectangle newBounds = new Rectangle(x, y, itemSize.x, maxHeightInRow);
401
			if (!oldBounds.equals(newBounds)) {
402
				item.setBounds(newBounds.x, newBounds.y, newBounds.width, newBounds.height);	
403
			}
404
			x += newBounds.width;
405
		}
406
		y += maxHeightInRow;
407
	}
408
409
410
	
411
}
(-)src/org/eclipse/ui/examples/presentation/customtoolbar/widgets/SCoolBarManager.java (+1037 lines)
Added Link Here
1
package org.eclipse.ui.examples.presentation.customtoolbar.widgets;
2
3
import java.util.ArrayList;
4
import java.util.HashMap;
5
import java.util.Iterator;
6
import java.util.List;
7
import java.util.ListIterator;
8
9
import org.eclipse.jface.action.ContributionManager;
10
import org.eclipse.jface.action.IContributionItem;
11
import org.eclipse.jface.action.ICoolBarManager;
12
import org.eclipse.jface.action.IMenuManager;
13
import org.eclipse.jface.action.IToolBarManager;
14
import org.eclipse.jface.action.MenuManager;
15
import org.eclipse.jface.action.Separator;
16
import org.eclipse.jface.action.ToolBarContributionItem;
17
import org.eclipse.jface.util.Assert;
18
import org.eclipse.jface.util.Policy;
19
import org.eclipse.swt.SWT;
20
import org.eclipse.swt.widgets.Composite;
21
import org.eclipse.swt.widgets.Control;
22
import org.eclipse.swt.widgets.CoolBar;
23
import org.eclipse.swt.widgets.Menu;
24
25
public class SCoolBarManager extends ContributionManager implements ICoolBarManager {
26
27
    /**
28
     * A separator created by the end user.
29
     */
30
    public final static String USER_SEPARATOR = "UserSeparator"; //$NON-NLS-1$
31
32
    /**
33
     * The original creation order of the contribution items.
34
     */
35
    private ArrayList cbItemsCreationOrder = new ArrayList();
36
37
    /**
38
     * MenuManager for cool bar pop-up menu, or null if none.
39
     */
40
    private MenuManager contextMenuManager = null;
41
42
    /**
43
     * The cool bar control; <code>null</code> before creation and after
44
     * disposal.
45
     */
46
    private SCoolBar coolBar = null;
47
48
    /**
49
     * The cool bar items style; <code>SWT.NONE</code> by default.
50
     */
51
    private int itemStyle = SWT.NONE;
52
53
    /**
54
     * Creates a new cool bar manager with the default style. Equivalent to
55
     * <code>CoolBarManager(SWT.NONE)</code>.
56
     */
57
    public SCoolBarManager() {
58
        // do nothing
59
    }
60
61
    /**
62
     * Creates a cool bar manager for an existing cool bar control. This
63
     * manager becomes responsible for the control, and will dispose of it when
64
     * the manager is disposed.
65
     * 
66
     * @param coolBar
67
     *            the cool bar control
68
     */
69
    public SCoolBarManager(SCoolBar coolBar) {
70
        this();
71
        Assert.isNotNull(coolBar);
72
        this.coolBar = coolBar;
73
        itemStyle = coolBar.getStyle();
74
    }
75
76
    /**
77
     * Creates a cool bar manager with the given SWT style. Calling <code>createControl</code>
78
     * will create the cool bar control.
79
     * 
80
     * @param style
81
     *            the cool bar item style; see
82
     *            {@link org.eclipse.swt.widgets.CoolBar CoolBar}for for valid
83
     *            style bits
84
     */
85
    public SCoolBarManager(int style) {
86
        itemStyle = style;
87
    }
88
89
    /*
90
     * (non-Javadoc)
91
     * 
92
     * @see org.eclipse.jface.action.ICoolBarManager#add(org.eclipse.jface.action.IToolBarManager)
93
     */
94
    public void add(IToolBarManager toolBarManager) {
95
        Assert.isNotNull(toolBarManager);
96
        SToolBarContributionItem2 toolBarContributionItem = null;
97
        if (toolBarContributionItem == null)
98
        	toolBarContributionItem = new SToolBarContributionItem2(toolBarManager);
99
        super.add(toolBarContributionItem);
100
    }
101
    
102
    public void add(IContributionItem item) {
103
    	super.add(item);
104
    }
105
106
    /**
107
     * Collapses consecutive separators and removes a separator from the
108
     * beginning and end of the list.
109
     * 
110
     * @param contributionList
111
     *            the list of contributions; must not be <code>null</code>.
112
     * @return The contribution list provided with extraneous separators
113
     *         removed; this value is never <code>null</code>, but may be
114
     *         empty.
115
     */
116
    private ArrayList adjustContributionList(ArrayList contributionList) {
117
        IContributionItem item;
118
        // Fist remove a separator if it is the first element of the list
119
        if (contributionList.size() != 0) {
120
            item = (IContributionItem) contributionList.get(0);
121
            if (item.isSeparator()) {
122
                contributionList.remove(0);
123
            }
124
125
            ListIterator iterator = contributionList.listIterator();
126
            // collapse consecutive separators
127
            while (iterator.hasNext()) {
128
                item = (IContributionItem) iterator.next();
129
                if (item.isSeparator()) {
130
                    while (iterator.hasNext()) {
131
                        item = (IContributionItem) iterator.next();
132
                        if (item.isSeparator()) {
133
                            iterator.remove();
134
                        } else {
135
                            break;
136
                        }
137
                    }
138
139
                }
140
            }
141
            // Now check last element to see if there is a separator
142
            item = (IContributionItem) contributionList.get(contributionList
143
                    .size() - 1);
144
            if (item.isSeparator()) {
145
                contributionList.remove(contributionList.size() - 1);
146
            }
147
        }
148
        return contributionList;
149
150
    }
151
152
    /* (non-Javadoc)
153
     * @see org.eclipse.jface.action.ContributionManager#checkDuplication(org.eclipse.jface.action.IContributionItem)
154
     */
155
    protected boolean allowItem(IContributionItem itemToAdd) {
156
        /* We will allow as many null entries as they like, though there should
157
         * be none.
158
         */
159
        if (itemToAdd == null) {
160
            return true;
161
        }
162
163
        /* Null identifiers can be expected in generic contribution items.
164
         */
165
        String firstId = itemToAdd.getId();
166
        if (firstId == null) {
167
            return true;
168
        }
169
170
        // Cycle through the current list looking for duplicates.
171
        IContributionItem[] currentItems = getItems();
172
        for (int i = 0; i < currentItems.length; i++) {
173
            IContributionItem currentItem = currentItems[i];
174
175
            // We ignore null entries.
176
            if (currentItem == null) {
177
                continue;
178
            }
179
180
            String secondId = currentItem.getId();
181
            if (firstId.equals(secondId)) {
182
                if (Policy.TRACE_TOOLBAR) { //$NON-NLS-1$
183
                    System.out.println("Trying to add a duplicate item."); //$NON-NLS-1$
184
                    new Exception().printStackTrace(System.out);
185
                    System.out.println("DONE --------------------------"); //$NON-NLS-1$
186
                }
187
                return false;
188
            }
189
        }
190
191
        return true;
192
    }
193
194
    /**
195
     * Positions the list iterator to the end of all the separators. Calling
196
     * <code>next()</code> the iterator should return the immediate object
197
     * following the last separator.
198
     * 
199
     * @param iterator
200
     *            the list iterator.
201
     */
202
    private void collapseSeparators(ListIterator iterator) {
203
204
        while (iterator.hasNext()) {
205
            IContributionItem item = (IContributionItem) iterator.next();
206
            if (!item.isSeparator()) {
207
                iterator.previous();
208
                return;
209
            }
210
        }
211
    }
212
213
    /**
214
     * Returns whether the cool bar control has been created and not yet
215
     * disposed.
216
     * 
217
     * @return <code>true</code> if the control has been created and not yet
218
     *         disposed, <code>false</code> otherwise
219
     */
220
    private boolean coolBarExist() {
221
        return coolBar != null && !coolBar.isDisposed();
222
    }
223
224
    /**
225
     * Creates and returns this manager's cool bar control. Does not create a
226
     * new control if one already exists.
227
     * 
228
     * @param parent
229
     *            the parent control
230
     * @return the cool bar control
231
     */
232
    public Control createControl2(Composite parent) {
233
        Assert.isNotNull(parent);
234
        if (!coolBarExist()) {
235
       		coolBar = new SCoolBar(parent, itemStyle);
236
       		((SCoolBar)coolBar).setSkin(new HannoverGlobalCoolBarSkin());
237
            coolBar.setMenu(getContextMenuControl());
238
            coolBar.setLocked(false);
239
            coolBar.setSkin(new HannoverGlobalCoolBarSkin());
240
            update(false);
241
        }
242
        return coolBar;
243
    }
244
245
    /**
246
     * Disposes of this cool bar manager and frees all allocated SWT resources.
247
     * Notifies all contribution items of the dispose. Note that this method
248
     * does not clean up references between this cool bar manager and its
249
     * associated contribution items. Use <code>removeAll</code> for that
250
     * purpose.
251
     */
252
    public void dispose() {
253
        if (coolBarExist()) {
254
            IContributionItem[] items = getItems();
255
            for (int i = 0; i < items.length; i++) {
256
                // Disposes of the contribution item.
257
                // If Contribution Item is a toolbar then it will dispose of
258
                // all the nested
259
                // contribution items.
260
                items[i].dispose();
261
            }
262
            coolBar.dispose();
263
            coolBar = null;
264
        }
265
        // If a context menu existed then dispose of it.
266
        if (contextMenuManager != null) {
267
            contextMenuManager.dispose();
268
            contextMenuManager = null;
269
        }
270
271
    }
272
273
    /**
274
     * Disposes the given cool item.
275
     * 
276
     * @param item
277
     *            the cool item to dispose
278
     */
279
    private void dispose(SCoolItem item) {
280
        if ((item != null) && !item.isDisposed()) {
281
282
            item.setData(null);
283
            Control control = item.getControl();
284
            // if the control is already disposed, setting the coolitem
285
            // control to null will cause an SWT exception, workaround
286
            // for 19630
287
            if ((control != null) && !control.isDisposed()) {
288
                item.setControl(null);
289
            }
290
            item.dispose();
291
        }
292
    }
293
294
    /**
295
     * Finds the cool item associated with the given contribution item.
296
     * 
297
     * @param item
298
     *            the contribution item
299
     * @return the associated cool item, or <code>null</code> if not found
300
     */
301
    private SCoolItem findCoolItem(IContributionItem item) {
302
        if (coolBar == null)
303
            return null;
304
        SCoolItem[] items = coolBar.getItems();
305
        for (int i = 0; i < items.length; i++) {
306
            SCoolItem coolItem = items[i];
307
            IContributionItem data = (IContributionItem) coolItem.getData();
308
            if (data != null && data.equals(item))
309
                return coolItem;
310
        }
311
        return null;
312
    }
313
314
    /**
315
     * Return a consistent set of wrap indices. The return value will always
316
     * include at least one entry and the first entry will always be zero.
317
     * CoolBar.getWrapIndices() is inconsistent in whether or not it returns an
318
     * index for the first row.
319
     * 
320
     * @param wraps
321
     *            the wrap indicies from the cool bar widget
322
     * @return the adjusted wrap indicies.
323
     */
324
    private int[] getAdjustedWrapIndices(int[] wraps) {
325
        int[] adjustedWrapIndices;
326
        if (wraps.length == 0) {
327
            adjustedWrapIndices = new int[] { 0 };
328
        } else {
329
            if (wraps[0] != 0) {
330
                adjustedWrapIndices = new int[wraps.length + 1];
331
                adjustedWrapIndices[0] = 0;
332
                for (int i = 0; i < wraps.length; i++) {
333
                    adjustedWrapIndices[i + 1] = wraps[i];
334
                }
335
            } else {
336
                adjustedWrapIndices = wraps;
337
            }
338
        }
339
        return adjustedWrapIndices;
340
    }
341
342
    /**
343
     * Returns the control of the Menu Manager. If the menu manager does not
344
     * have a control then one is created.
345
     * 
346
     * @return menu control associated with manager, or null if none
347
     */
348
    private Menu getContextMenuControl() {
349
        if ((contextMenuManager != null) && (coolBar != null)) {
350
            Menu menuWidget = contextMenuManager.getMenu();
351
            if ((menuWidget == null) || (menuWidget.isDisposed())) {
352
                menuWidget = contextMenuManager.createContextMenu(coolBar);
353
            }
354
            return menuWidget;
355
        }
356
        return null;
357
    }
358
359
    /*
360
     * (non-Javadoc)
361
     * 
362
     * @see org.eclipse.jface.action.ICoolBarManager#isLayoutLocked()
363
     */
364
    public IMenuManager getContextMenuManager() {
365
        return contextMenuManager;
366
    }
367
368
    /**
369
     * Returns the cool bar control for this manager.
370
     * 
371
     * @return the cool bar control, or <code>null</code> if none
372
     */
373
    public CoolBar getControl() {
374
        return null;
375
    }
376
377
    /**
378
     * Returns an array list of all the contribution items in the manager.
379
     * 
380
     * @return an array list of contribution items.
381
     */
382
    private ArrayList getItemList() {
383
        IContributionItem[] cbItems = getItems();
384
        ArrayList list = new ArrayList(cbItems.length);
385
        for (int i = 0; i < cbItems.length; i++) {
386
            list.add(cbItems[i]);
387
        }
388
        return list;
389
    }
390
391
    /*
392
     * (non-Javadoc)
393
     * 
394
     * @see org.eclipse.jface.action.ICoolBarManager#isLayoutLocked()
395
     */
396
    public boolean getLockLayout() {
397
        if (!coolBarExist()) {
398
            return false;
399
        }
400
        return coolBar.getLocked();
401
    }
402
403
    /**
404
     * Returns the number of rows that should be displayed visually.
405
     * 
406
     * @param items
407
     *            the array of contributin items
408
     * @return the number of rows
409
     */
410
    private int getNumRows(IContributionItem[] items) {
411
        int numRows = 1;
412
        boolean separatorFound = false;
413
        for (int i = 0; i < items.length; i++) {
414
            if (items[i].isSeparator()) {
415
                separatorFound = true;
416
            }
417
            if ((separatorFound) && (items[i].isVisible())
418
                    && (!items[i].isGroupMarker()) && (!items[i].isSeparator())) {
419
                numRows++;
420
                separatorFound = false;
421
            }
422
        }
423
        return numRows;
424
    }
425
426
    /*
427
     * (non-Javadoc)
428
     * 
429
     * @see org.eclipse.jface.action.ICoolBarManager#getStyle()
430
     */
431
    public int getStyle() {
432
        return itemStyle;
433
    }
434
435
    /**
436
     * Subclasses may extend this <code>ContributionManager</code> method,
437
     * but must call <code>super.itemAdded</code>.
438
     * 
439
     * @see org.eclipse.jface.action.ContributionManager#itemAdded(org.eclipse.jface.action.IContributionItem)
440
     */
441
    protected void itemAdded(IContributionItem item) {
442
        Assert.isNotNull(item);
443
        super.itemAdded(item);
444
        int insertedAt = indexOf(item);
445
        boolean replaced = false;
446
        final int size = cbItemsCreationOrder.size();
447
        for (int i = 0; i < size; i++) {
448
            IContributionItem created = (IContributionItem) cbItemsCreationOrder
449
                    .get(i);
450
            if (created.getId() != null && created.getId().equals(item.getId())) {
451
                cbItemsCreationOrder.set(i, item);
452
                replaced = true;
453
                break;
454
            }
455
        }
456
457
        if (!replaced) {
458
            cbItemsCreationOrder.add(Math.min(Math.max(insertedAt, 0),
459
                    cbItemsCreationOrder.size()), item);
460
        }
461
    }
462
463
    /**
464
     * Subclasses may extend this <code>ContributionManager</code> method,
465
     * but must call <code>super.itemRemoved</code>.
466
     * 
467
     * @see org.eclipse.jface.action.ContributionManager#itemRemoved(org.eclipse.jface.action.IContributionItem)
468
     */
469
    protected void itemRemoved(IContributionItem item) {
470
        Assert.isNotNull(item);
471
        super.itemRemoved(item);
472
        SCoolItem coolItem = findCoolItem(item);
473
        if (coolItem != null) {
474
            coolItem.setData(null);
475
        }
476
    }
477
478
    /**
479
     * Positions the list iterator to the starting of the next row. By calling
480
     * next on the returned iterator, it will return the first element of the
481
     * next row.
482
     * 
483
     * @param iterator
484
     *            the list iterator of contribution items
485
     * @param ignoreCurrentItem
486
     *            Whether the current item in the iterator should be considered
487
     *            (as well as subsequent items).
488
     */
489
    private void nextRow(ListIterator iterator, boolean ignoreCurrentItem) {
490
491
        IContributionItem currentElement = null;
492
        if (!ignoreCurrentItem && iterator.hasPrevious()) {
493
            currentElement = (IContributionItem) iterator.previous();
494
            iterator.next();
495
        }
496
497
        if ((currentElement != null) && (currentElement.isSeparator())) {
498
            collapseSeparators(iterator);
499
            return;
500
        } else {
501
            //Find next separator
502
            while (iterator.hasNext()) {
503
                IContributionItem item = (IContributionItem) iterator.next();
504
                if (item.isSeparator()) {
505
                    // we we find a separator, collapse any consecutive
506
                    // separators
507
                    // and return
508
                    collapseSeparators(iterator);
509
                    return;
510
                }
511
            }
512
        }
513
    }
514
515
    /*
516
     * Used for debuging. Prints all the items in the internal structures.
517
     */
518
    //    private void printContributions(ArrayList contributionList) {
519
    //        int index = 0;
520
    //        System.out.println("----------------------------------\n"); //$NON-NLS-1$
521
    //        for (Iterator i = contributionList.iterator(); i.hasNext(); index++) {
522
    //            IContributionItem item = (IContributionItem) i.next();
523
    //            if (item.isSeparator()) {
524
    //                System.out.println("Separator"); //$NON-NLS-1$
525
    //            } else {
526
    //                System.out.println(index + ". Item id: " + item.getId() //$NON-NLS-1$
527
    //                        + " - is Visible: " //$NON-NLS-1$
528
    //                        + item.isVisible());
529
    //            }
530
    //        }
531
    //    }
532
    /**
533
     * Synchronizes the visual order of the cool items in the control with this
534
     * manager's internal data structures. This method should be called before
535
     * requesting the order of the contribution items to ensure that the order
536
     * is accurate.
537
     * <p>
538
     * Note that <code>update()</code> and <code>refresh()</code> are
539
     * converses: <code>update()</code> changes the visual order to match the
540
     * internal structures, and <code>refresh</code> changes the internal
541
     * structures to match the visual order.
542
     * </p>
543
     */
544
    public void refresh() {
545
        if (!coolBarExist()) {
546
            return;
547
        }
548
549
        // Retreives the list of contribution items as an array list
550
        ArrayList contributionList = getItemList();
551
552
        // Check the size of the list
553
        if (contributionList.size() == 0)
554
            return;
555
556
        // The list of all the cool items in their visual order
557
        SCoolItem[] coolItems = coolBar.getItems();
558
        // The wrap indicies of the coolbar
559
        int[] wrapIndicies = getAdjustedWrapIndices(coolBar.getWrapIndices());
560
561
        int row = 0;
562
        int coolItemIndex = 0;
563
564
        // Traverse through all cool items in the coolbar add them to a new
565
        // data structure
566
        // in the correct order
567
        ArrayList displayedItems = new ArrayList(coolBar.getItemCount());
568
        for (int i = 0; i < coolItems.length; i++) {
569
            SCoolItem coolItem = coolItems[i];
570
            if (coolItem.getData() instanceof IContributionItem) {
571
                IContributionItem cbItem = (IContributionItem) coolItem
572
                        .getData();
573
                displayedItems.add(Math.min(i, displayedItems.size()), cbItem);
574
            }
575
        }
576
577
        // Add separators to the displayed Items data structure
578
        int offset = 0;
579
        for (int i = 1; i < wrapIndicies.length; i++) {
580
            int insertAt = wrapIndicies[i] + offset;
581
            displayedItems.add(insertAt, new Separator(USER_SEPARATOR));
582
            offset++;
583
        }
584
585
        // Determine which rows are invisible
586
        ArrayList existingVisibleRows = new ArrayList(4);
587
        ListIterator rowIterator = contributionList.listIterator();
588
        collapseSeparators(rowIterator);
589
        int numRow = 0;
590
        while (rowIterator.hasNext()) {
591
            // Scan row
592
            while (rowIterator.hasNext()) {
593
                IContributionItem cbItem = (IContributionItem) rowIterator
594
                        .next();
595
                if (displayedItems.contains(cbItem)) {
596
                    existingVisibleRows.add(new Integer(numRow));
597
                    break;
598
                }
599
                if (cbItem.isSeparator()) {
600
                    break;
601
                }
602
            }
603
            nextRow(rowIterator, false);
604
            numRow++;
605
        }
606
607
        Iterator existingRows = existingVisibleRows.iterator();
608
        // Adjust row number to the first visible
609
        if (existingRows.hasNext()) {
610
            row = ((Integer) existingRows.next()).intValue();
611
        }
612
613
        HashMap itemLocation = new HashMap();
614
        for (ListIterator locationIterator = displayedItems.listIterator(); locationIterator
615
                .hasNext();) {
616
            IContributionItem item = (IContributionItem) locationIterator
617
                    .next();
618
            if (item.isSeparator()) {
619
                if (existingRows.hasNext()) {
620
                    Integer value = (Integer) existingRows.next();
621
                    row = value.intValue();
622
                } else {
623
                    row++;
624
                }
625
            } else {
626
                itemLocation.put(item, new Integer(row));
627
            }
628
629
        }
630
631
        // Insert the contribution items in their correct location
632
        for (ListIterator iterator = displayedItems.listIterator(); iterator
633
                .hasNext();) {
634
            IContributionItem cbItem = (IContributionItem) iterator.next();
635
            if (cbItem.isSeparator()) {
636
                coolItemIndex = 0;
637
            } else {
638
                relocate(cbItem, coolItemIndex, contributionList, itemLocation);
639
                cbItem.saveWidgetState();
640
                coolItemIndex++;
641
            }
642
        }
643
644
        if (contributionList.size() != 0) {
645
            contributionList = adjustContributionList(contributionList);
646
            IContributionItem[] array = new IContributionItem[contributionList
647
                    .size() - 1];
648
            array = (IContributionItem[]) contributionList.toArray(array);
649
            internalSetItems(array);
650
        }
651
652
    }
653
654
    /**
655
     * Relocates the given contribution item to the specified index.
656
     * 
657
     * @param cbItem
658
     *            the conribution item to relocate
659
     * @param index
660
     *            the index to locate this item
661
     * @param contributionList
662
     *            the current list of conrtributions
663
     * @param itemLocation
664
     */
665
    private void relocate(IContributionItem cbItem, int index,
666
            ArrayList contributionList, HashMap itemLocation) {
667
668
        if (!(itemLocation.get(cbItem) instanceof Integer))
669
            return;
670
        int targetRow = ((Integer) itemLocation.get(cbItem)).intValue();
671
672
        int cbInternalIndex = contributionList.indexOf(cbItem);
673
674
        //	by default add to end of list
675
        int insertAt = contributionList.size();
676
        // Find the row to place this item in.
677
        ListIterator iterator = contributionList.listIterator();
678
        // bypass any separators at the begining
679
        collapseSeparators(iterator);
680
        int currentRow = -1;
681
        while (iterator.hasNext()) {
682
683
            currentRow++;
684
            if (currentRow == targetRow) {
685
                // We found the row to insert the item
686
                int virtualIndex = 0;
687
                insertAt = iterator.nextIndex();
688
                // first check the position of the current element (item)
689
                // then get the next element
690
                while (iterator.hasNext()) {
691
                    IContributionItem item = (IContributionItem) iterator
692
                            .next();
693
                    Integer itemRow = (Integer) itemLocation.get(item);
694
                    if (item.isSeparator())
695
                        break;
696
                    // if the item has an associate widget
697
                    if ((itemRow != null) && (itemRow.intValue() == targetRow)) {
698
                        // if the next element is the index we are looking for
699
                        // then break
700
                        if (virtualIndex >= index)
701
                            break;
702
                        virtualIndex++;
703
704
                    }
705
                    insertAt++;
706
                }
707
                // If we don't need to move it then we return
708
                if (cbInternalIndex == insertAt)
709
                    return;
710
                break;
711
            }
712
            nextRow(iterator, true);
713
        }
714
        contributionList.remove(cbItem);
715
716
        // Adjust insertAt index
717
        if (cbInternalIndex < insertAt) {
718
            insertAt--;
719
        }
720
721
        // if we didn't find the row then add a new row
722
        if (currentRow != targetRow) {
723
            contributionList.add(new Separator(USER_SEPARATOR));
724
            insertAt = contributionList.size();
725
        }
726
        insertAt = Math.min(insertAt, contributionList.size());
727
        contributionList.add(insertAt, cbItem);
728
729
    }
730
731
    /**
732
     * Restores the canonical order of this cool bar manager. The canonical
733
     * order is the order in which the contribution items where added.
734
     */
735
    public void resetItemOrder() {
736
        for (ListIterator iterator = cbItemsCreationOrder.listIterator(); iterator
737
                .hasNext();) {
738
            IContributionItem item = (IContributionItem) iterator.next();
739
            // if its a user separator then do not include in original order.
740
            if ((item.getId() != null) && (item.getId().equals(USER_SEPARATOR))) {
741
                iterator.remove();
742
            }
743
        }
744
        IContributionItem[] itemsToSet = new IContributionItem[cbItemsCreationOrder
745
                .size()];
746
        cbItemsCreationOrder.toArray(itemsToSet);
747
        setItems(itemsToSet);
748
    }
749
750
    /*
751
     * (non-Javadoc)
752
     * 
753
     * @see org.eclipse.jface.action.ICoolBarManager#setContextMenuManager(org.eclipse.jface.action.IMenuManager)
754
     */
755
    public void setContextMenuManager(IMenuManager contextMenuManager) {
756
        this.contextMenuManager = (MenuManager) contextMenuManager;
757
        if (coolBar != null) {
758
            coolBar.setMenu(getContextMenuControl());
759
        }
760
    }
761
762
    /**
763
     * Replaces the current items with the given items.
764
     * Forces an update.
765
     * 
766
     * @param newItems the items with which to replace the current items
767
     */
768
    public void setItems(IContributionItem[] newItems) {
769
        // dispose of all the cool items on the cool bar manager
770
/* FIXME TFS
771
 *	This is disposing of the coolItems but references are still hanging around. Might
772
 *	be a problem with SCoolBar and or SCoolItem. [Terry Smith 12/9/2005]
773
 * 
774
        if (coolBar != null) {
775
            SCoolItem[] coolItems = coolBar.getItems();
776
           for (int i = 0; i < coolItems.length; i++) {
777
              dispose(coolItems[i]);
778
            }
779
        }
780
        // Set the internal structure to this order
781
        internalSetItems(newItems);
782
*/
783
        // Force and update
784
        update(true);
785
    }
786
787
    /*
788
     * (non-Javadoc)
789
     * 
790
     * @see org.eclipse.jface.action.ICoolBarManager#lockLayout(boolean)
791
     */
792
    public void setLockLayout(boolean value) {
793
        if (!coolBarExist()) {
794
            return;
795
        }
796
        coolBar.setLocked(value);
797
    }
798
799
    /**
800
     * Subclasses may extend this <code>IContributionManager</code> method,
801
     * but must call <code>super.update</code>.
802
     * 
803
     * @see org.eclipse.jface.action.IContributionManager#update(boolean)
804
     */
805
    public void update(boolean force) {
806
        if ((!isDirty() && !force) || (!coolBarExist())) {
807
            return;
808
        }
809
810
        boolean relock = false;
811
        boolean changed = false;
812
813
        try {
814
            coolBar.setRedraw(false);
815
816
            // Refresh the widget data with the internal data structure.
817
            refresh();
818
819
            if (coolBar.getLocked()) {
820
                coolBar.setLocked(false);
821
                relock = true;
822
            }
823
824
            /*
825
             * Make a list of items including only those items that are
826
             * visible. Separators should stay because they mark line breaks in
827
             * a cool bar.
828
             */
829
            final IContributionItem[] items = getItems();
830
            final List visibleItems = new ArrayList(items.length);
831
            for (int i = 0; i < items.length; i++) {
832
                final IContributionItem item = items[i];
833
                if (item.isVisible()) {
834
                    visibleItems.add(item);
835
                }
836
            }
837
838
            /*
839
             * Make a list of CoolItem widgets in the cool bar for which there
840
             * is no current visible contribution item. These are the widgets
841
             * to be disposed. Dynamic items are also removed.
842
             */
843
            SCoolItem[] coolItems = coolBar.getItems();
844
            final ArrayList coolItemsToRemove = new ArrayList(coolItems.length);
845
            for (int i = 0; i < coolItems.length; i++) {
846
                final Object data = coolItems[i].getData();
847
                if ((data == null)
848
                        || (!visibleItems.contains(data))
849
                        || ((data instanceof IContributionItem) && ((IContributionItem) data)
850
                                .isDynamic())) {
851
                    coolItemsToRemove.add(coolItems[i]);
852
                }
853
            }
854
855
            // Dispose of any items in the list to be removed.
856
            for (int i = coolItemsToRemove.size() - 1; i >= 0; i--) {
857
                SCoolItem coolItem = (SCoolItem) coolItemsToRemove.get(i);
858
                if (!coolItem.isDisposed()) {
859
                    Control control = coolItem.getControl();
860
                    if (control != null) {
861
                        coolItem.setControl(null);
862
                        control.dispose();
863
                    }
864
                    coolItem.dispose();
865
                }
866
            }
867
868
            // Add any new items by telling them to fill.
869
            coolItems = coolBar.getItems();
870
            IContributionItem sourceItem;
871
            IContributionItem destinationItem;
872
            int sourceIndex = 0;
873
            int destinationIndex = 0;
874
            final Iterator visibleItemItr = visibleItems.iterator();
875
            while (visibleItemItr.hasNext()) {
876
                sourceItem = (IContributionItem) visibleItemItr.next();
877
878
                // Retrieve the corresponding contribution item from SWT's
879
                // data.
880
                if (sourceIndex < coolItems.length) {
881
                    destinationItem = (IContributionItem) coolItems[sourceIndex]
882
                            .getData();
883
                } else {
884
                    destinationItem = null;
885
                }
886
887
                // The items match is they are equal or both separators.
888
                if (destinationItem != null) {
889
                    if (sourceItem.equals(destinationItem)) {
890
                        sourceIndex++;
891
                        destinationIndex++;
892
                        sourceItem.update();
893
                        continue;
894
895
                    } else if ((destinationItem.isSeparator())
896
                            && (sourceItem.isSeparator())) {
897
                        coolItems[sourceIndex].setData(sourceItem);
898
                        sourceIndex++;
899
                        destinationIndex++;
900
                        sourceItem.update();
901
                        continue;
902
903
                    }
904
                }
905
906
                // Otherwise, a new item has to be added.
907
                final int start = coolBar.getItemCount();
908
                if (sourceItem instanceof ISContributionItem)
909
                	((ISContributionItem)sourceItem).fill(coolBar, destinationIndex);
910
                final int newItems = coolBar.getItemCount() - start;
911
                for (int i = 0; i < newItems; i++) {
912
                    coolBar.getItem(destinationIndex++).setData(sourceItem);
913
                }
914
                changed = true;
915
            }
916
917
            // Remove any old widgets not accounted for.
918
            for (int i = coolItems.length - 1; i >= sourceIndex; i--) {
919
                final SCoolItem item = coolItems[i];
920
                if (!item.isDisposed()) {
921
                    Control control = item.getControl();
922
                    if (control != null) {
923
                        item.setControl(null);
924
                        control.dispose();
925
                    }
926
                    item.dispose();
927
                    changed = true;
928
                }
929
            }
930
931
            // Update wrap indices.
932
            updateWrapIndices();
933
934
            // Update the sizes.
935
            for (int i = 0; i < items.length; i++) {
936
                IContributionItem item = items[i];
937
                item.update(SIZE);
938
            }
939
940
            // if the coolBar was previously locked then lock it
941
            if (relock) {
942
                coolBar.setLocked(true);
943
            }
944
945
            if (changed) {
946
                updateTabOrder();
947
            }
948
949
            // We are no longer dirty.
950
            setDirty(false);
951
        } finally {
952
            coolBar.setRedraw(true);
953
        }
954
    }
955
956
    /**
957
     * Sets the tab order of the coolbar to the visual order of its items.
958
     */
959
    /* package */void updateTabOrder() {
960
        if (coolBar != null) {
961
            SCoolItem[] items = coolBar.getItems();
962
            if (items != null) {
963
                ArrayList children = new ArrayList(items.length);
964
                for (int i = 0; i < items.length; i++) {
965
                    if ((items[i].getControl() != null)
966
                            && (!items[i].getControl().isDisposed())) {
967
                        children.add(items[i].getControl());
968
                    }
969
                }
970
                // Convert array
971
                Control[] childrenArray = new Control[0];
972
                childrenArray = (Control[]) children.toArray(childrenArray);
973
974
                if (childrenArray != null) {
975
                    coolBar.setTabList(childrenArray);
976
                }
977
978
            }
979
        }
980
    }
981
982
    /**
983
     * Updates the indices at which the cool bar should wrap.
984
     */
985
    private void updateWrapIndices() {
986
        final IContributionItem[] items = getItems();
987
        final int numRows = getNumRows(items) - 1;
988
989
        // Generate the list of wrap indices.
990
        final int[] wrapIndices = new int[numRows];
991
        boolean foundSeparator = false;
992
        int j = 0;
993
        for (int i = 0; i < items.length; i++) {
994
            IContributionItem item = items[i];
995
            SCoolItem coolItem = findCoolItem(item);
996
            if (item.isSeparator()) {
997
                foundSeparator = true;
998
            }
999
            if ((!item.isSeparator()) && (!item.isGroupMarker())
1000
                    && (item.isVisible()) && (coolItem != null)
1001
                    && (foundSeparator)) {
1002
                wrapIndices[j] = coolBar.indexOf(coolItem);
1003
                j++;
1004
                foundSeparator = false;
1005
            }
1006
        }
1007
1008
        /*
1009
         * Check to see if these new wrap indices are different than the old
1010
         * ones.
1011
         */
1012
        final int[] oldIndices = coolBar.getWrapIndices();
1013
        boolean shouldUpdate = false;
1014
        if (oldIndices.length == wrapIndices.length) {
1015
            for (int i = 0; i < oldIndices.length; i++) {
1016
                if (oldIndices[i] != wrapIndices[i]) {
1017
                    shouldUpdate = true;
1018
                    break;
1019
                }
1020
            }
1021
        } else {
1022
            shouldUpdate = true;
1023
        }
1024
1025
        if (shouldUpdate) {
1026
            coolBar.setWrapIndices(wrapIndices);
1027
        }
1028
    }
1029
1030
	public CoolBar createControl(Composite parent) {
1031
		return null;
1032
	}
1033
1034
	public Control getControl2() {
1035
		return coolBar;
1036
	}
1037
}
(-)src/org/eclipse/ui/examples/presentation/customtoolbar/widgets/Skin.java (+94 lines)
Added Link Here
1
package org.eclipse.ui.examples.presentation.customtoolbar.widgets;
2
3
import org.eclipse.swt.graphics.Font;
4
import org.eclipse.swt.graphics.GC;
5
import org.eclipse.swt.graphics.Image;
6
import org.eclipse.swt.graphics.Point;
7
import org.eclipse.swt.graphics.Rectangle;
8
9
public interface Skin {
10
11
	// states
12
	public static final int NORMAL = 0;
13
	public static final int HOVER = 1 << 1;
14
	public static final int SELECTED = 1 << 2;
15
	public static final int PRESSED = 1 << 3;
16
	public static final int DISABLED = 1 << 4;
17
	public static final int COLLAPSED = 1 << 5;
18
	
19
	// decorations
20
	public final static int TYPE_DECORATION_CLOSE = 1;
21
	public final static int TYPE_DECORATION_SEPARATOR = 2;
22
	public final static int TYPE_DECORATION_FOCUS = 3;
23
	public final static int TYPE_DECORATION_ARROW = 4;
24
	public final static int TYPE_DECORATION_CHEVRON = 5;
25
	public final static int TYPE_DECORATION_DROPDOWN_BUTTON = 6;
26
	public final static int TYPE_DECORATION_COLLAPSE_BUTTON = 7;
27
	public final static int TYPE_DECORATION_EXPAND_BUTTON = 8;
28
	public final static int TYPE_DECORATION_GRIPPER = 9;
29
	public final static int TYPE_DECORATION_INTERNAL_SEPARATOR = 10;
30
	
31
	// borders
32
	public final static int TYPE_ITEM_MENU_BORDER = 11;
33
	public final static int TYPE_ITEM_AREA_BORDER = 12;
34
	public final static int TYPE_ITEM_BORDER = 13;
35
	public final static int TYPE_BORDER = 14;
36
	public final static int TYPE_GROUP_ITEM_BORDER = 15;
37
	public final static int TYPE_GROUP_BORDER = 16;
38
	public final static int TYPE_HEADER_ITEM_BORDER = 17;
39
	public final static int TYPE_HEADER_BORDER = 18;
40
	
41
	// backgrounds
42
	public final static int TYPE_ITEM_MENU_BACKGROUND = 19;
43
	public final static int TYPE_ITEM_AREA_BACKGROUND = 20;
44
	public final static int TYPE_ITEM_BACKGROUND = 21;
45
	public final static int TYPE_BACKGROUND = 22;
46
	public final static int TYPE_GROUP_ITEM_BACKGROUND = 23;
47
	public final static int TYPE_HEADER_ITEM_BACKGROUND = 24;
48
	public final static int TYPE_HEADER_BACKGROUND = 25;
49
50
	// fonts
51
	public final static int TYPE_ITEM_MENU_FONT = 26;
52
	public final static int TYPE_ITEM_FONT = 27;
53
	public final static int TYPE_FONT = 28;
54
	
55
	// text
56
	public final static int TYPE_ITEM_MENU_TEXT = 29;
57
	public final static int TYPE_ITEM_TEXT = 30;
58
	public final static int TYPE_TEXT= 31;
59
	public final static int TYPE_GROUP_ITEM_TEXT = 32;				
60
	public final static int TYPE_HEADER_ITEM_TEXT = 33;				
61
	
62
	// images
63
	public final static int TYPE_ITEM_IMAGE = 34;
64
	public final static int TYPE_IMAGE = 35;
65
	
66
	// properties
67
	public final static int TYPE_MARGINS = 36;
68
	public final static int TYPE_INSETS = 37;
69
	public final static int TYPE_ITEM_MARGINS = 38;
70
	public final static int TYPE_ITEM_INSETS = 39;
71
	public final static int TYPE_ITEM_AREA_MARGINS = 40;
72
	public final static int TYPE_ITEM_AREA_INSETS = 41;
73
	public final static int TYPE_ITEM_MENU_MARGINS = 42;
74
	public final static int TYPE_ITEM_MENU_INSETS = 43;	
75
	public final static int TYPE_DECORATION_CLOSE_INSETS = 44;
76
	public final static int TYPE_ITEM_MIN_MAX_WIDTHS = 45;
77
	public final static int TYPE_ITEM_ICON_SIZE = 46;
78
	public final static int TYPE_ITEM_MIN_MAX_HEIGHT = 47;
79
	
80
	abstract public Rectangle getInsets(int type, int state);
81
	abstract public Point getSize(int type, int state);
82
	abstract public Font getFont(int type, int state);
83
	abstract public Rectangle getMargins(int type, int state);
84
	abstract public Rectangle getRect(int type, int state);
85
86
	public abstract void drawBorder(GC gc, Rectangle rect, SWidget widget, int type, int state);
87
	public abstract void drawBackground(GC gc, Rectangle rect, SWidget widget, int type, int state);
88
	public abstract void drawDecoration(GC gc, Rectangle rect, SWidget widget, int type, int state);
89
	public abstract void drawText(GC gc, Rectangle rect, String text, int style, SWidget widget, int type, int state);
90
	public abstract void drawImage(GC gc, Rectangle rect, Image image, SWidget widget, int type, int state);
91
92
	abstract public void dispose();
93
94
}
(-)src/org/eclipse/ui/examples/presentation/customtoolbar/widgets/SToolItem.java (+731 lines)
Added Link Here
1
/*
2
*	Copyright IBM Corporation 2003, 2005
3
*	All rights reserved.
4
*	US Government Users Restricted Rights - Use, duplication or disclosure
5
*	restricted by GS ADP Schedule Contract with IBM Corp.
6
*/
7
package org.eclipse.ui.examples.presentation.customtoolbar.widgets;
8
9
import org.eclipse.swt.SWT;
10
import org.eclipse.swt.events.SelectionListener;
11
import org.eclipse.swt.graphics.FontMetrics;
12
import org.eclipse.swt.graphics.GC;
13
import org.eclipse.swt.graphics.Image;
14
import org.eclipse.swt.graphics.Point;
15
import org.eclipse.swt.graphics.Rectangle;
16
import org.eclipse.swt.widgets.Control;
17
import org.eclipse.swt.widgets.Event;
18
import org.eclipse.swt.widgets.Item;
19
import org.eclipse.swt.widgets.TypedListener;
20
 
21
public class SToolItem extends Item {
22
	SToolBar parent;
23
	Control control;
24
	int index;
25
	String toolTipText;
26
	Image disabledImage;
27
	Image hotImage;
28
	Image pressedImage;
29
	boolean enabled = true;
30
	boolean selected;
31
	int separatorWidth;
32
	int width = -1;
33
	Point arrowSize = new Point(5, 5);
34
	int state;
35
	int arrowState;
36
37
	/** the alignment. Either CENTER, RIGHT, LEFT. Default is LEFT */
38
	private int align = SWT.LEFT;
39
40
	Rectangle itemRect = new Rectangle(0,0,0,0);
41
	Rectangle arrowRect;
42
43
	/**
44
	 * @param parent
45
	 * @param style
46
	 */
47
	public SToolItem(SToolBar parent, int style) {
48
		super(parent, style);
49
		this.parent = parent;
50
		parent.createItem(this, parent.getItemCount());
51
	}
52
53
	/**
54
	 * @param parent
55
	 * @param style
56
	 * @param index
57
	 */
58
	public SToolItem(SToolBar parent, int style, int index) {
59
		super(parent, style, index);
60
		this.parent = parent;
61
		parent.createItem(this, index);
62
	}
63
64
	public void addSelectionListener(SelectionListener listener) {
65
		checkWidget();
66
		if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
67
		TypedListener typedListener = new TypedListener (listener);
68
		addListener (SWT.Selection, typedListener);
69
		addListener (SWT.DefaultSelection, typedListener);
70
	}
71
	
72
	public Point computeSize(int wHint, int hHint, boolean changed) {
73
		checkWidget();
74
		Skin skin = parent.getSkin();
75
		
76
		Rectangle insets = skin.getRect(Skin.TYPE_ITEM_INSETS, Skin.NORMAL);
77
		if (insets == null) {
78
			insets = new Rectangle(0, 0, 0, 0);
79
		}
80
		
81
		Point size = null;
82
		String t = getText();
83
		if (t != null && t.length() == 0) {
84
			t = null;
85
		}
86
87
		if (control == null && (getStyle() & SWT.SEPARATOR) == SWT.SEPARATOR && 
88
				t == null) {
89
			size = skin.getSize(Skin.TYPE_DECORATION_SEPARATOR, Skin.NORMAL);
90
		}
91
		else {
92
			size = getContentSize(getImage(), getText());
93
		}
94
		if (size == null) {
95
			size = new Point(0, 0);
96
		}
97
		
98
		if (wHint == SWT.DEFAULT) {
99
			size.x += (insets.x + insets.width);
100
		} else {
101
			size.x = wHint;
102
		}
103
		if (hHint == SWT.DEFAULT) {
104
			if (size.y != SWT.DEFAULT) {
105
				if (getControl() == null) {
106
					size.y += (insets.y + insets.height);
107
				}
108
			}
109
		} else {
110
			size.y = hHint;
111
		}
112
113
		//
114
		// Everything gets measured for a min/max width and height except if 
115
		// it is exclusively a SEPARATOR or if it is a separator with a control. 
116
		//
117
		boolean measureMinMax = true;
118
		if ((getStyle() & SWT.SEPARATOR) == SWT.SEPARATOR) {
119
			if (control != null || t == null) { 
120
				measureMinMax = false;
121
			}
122
		}
123
		
124
		if (measureMinMax) {
125
			Point minMax = skin.getSize(Skin.TYPE_ITEM_MIN_MAX_WIDTHS, Skin.NORMAL);
126
			if (minMax != null) {
127
				if (minMax.x > size.x && minMax.x != SWT.DEFAULT) {
128
					size.x = minMax.x;
129
				}
130
				if (minMax.y < size.x && minMax.y != SWT.DEFAULT) {
131
					size.x = minMax.y;
132
				}
133
			}
134
	
135
			minMax = skin.getSize(Skin.TYPE_ITEM_MIN_MAX_HEIGHT, Skin.NORMAL);
136
			if (minMax != null) {
137
				if (minMax.x > size.y && minMax.x != SWT.DEFAULT) {
138
					size.y = minMax.x;
139
				}
140
				if (minMax.y < size.y && minMax.y != SWT.DEFAULT) {
141
					size.y = minMax.y;
142
				}
143
			}
144
		}
145
		
146
		return size;
147
	}
148
	
149
	public void dispose() {
150
		if (isDisposed ()) return;
151
		parent.destroyItem(this);
152
		super.dispose();
153
	}
154
155
	/**
156
	 * @return
157
	 */
158
	public Rectangle getBounds() {
159
		return itemRect;
160
	}
161
162
	/**
163
	 * @return
164
	 */
165
	public Control getControl() {
166
		return control;
167
	}
168
169
	Skin getSkin() {
170
		Skin skin = parent.getSkin();
171
		return skin;
172
	}
173
	
174
	/**
175
	 * @return
176
	 */
177
	public Image getDisabledImage() {
178
		return disabledImage;
179
	}
180
181
	/**
182
	 * @return
183
	 */
184
	public boolean getEnabled() {
185
		return enabled;
186
	}
187
	
188
	/**
189
	 * @return
190
	 */
191
	public Image getHotImage() {
192
		return hotImage;
193
	}
194
195
	/**
196
	 * @return pressed image.
197
	 */
198
	public Image getPressedImage() {
199
		return pressedImage;
200
	}
201
	
202
	/**
203
	 * @return
204
	 */
205
	public SToolBar getParent() {
206
		return this.parent;
207
	}
208
	
209
	/**
210
	 * @return
211
	 */
212
	public boolean getSelection() {
213
		return selected;
214
	}
215
216
	private int getState() {
217
		return state;
218
	}
219
	
220
	private int getArrowState() {
221
		return arrowState;
222
	}
223
	
224
	/**
225
	 * Compute the minimum size.
226
	 */
227
	private Point getContentSize(Image image, String text) {
228
		Point size = new Point(0, 0);
229
		Skin skin = getSkin();
230
		
231
		Control control = getControl();
232
		if (control != null) {
233
			size = control.computeSize(SWT.DEFAULT, SWT.DEFAULT);
234
			if (width != -1)
235
				size.x = width;
236
			return size;
237
		}
238
239
		if (image != null) {
240
			Rectangle r;
241
			Point imageSize = skin.getSize(Skin.TYPE_ITEM_ICON_SIZE, state);
242
			if (imageSize != null && imageSize.y != SWT.DEFAULT) {
243
				r = new Rectangle(0, 0, imageSize.x, imageSize.y);
244
			} else {
245
				r = image.getBounds();
246
			}
247
			size.x += r.width;
248
			size.y += r.height;
249
		}
250
251
		if (skin != null) {
252
			Rectangle margins = skin.getRect(Skin.TYPE_ITEM_MARGINS, Skin.NORMAL);
253
			if (margins == null) {
254
				margins = new Rectangle(0, 0, 0, 0);
255
			}
256
			
257
			if (text != null && text.length() > 0) {
258
				GC gc = new GC(this.getParent());
259
				gc.setFont(skin.getFont(Skin.TYPE_ITEM_FONT, Skin.NORMAL));
260
				FontMetrics fm = gc.getFontMetrics();
261
				Point e = gc.textExtent(text, SWT.DRAW_TRANSPARENT);
262
				size.x += e.x;
263
				size.y = Math.max(size.y, fm.getAscent());
264
				if (image != null) {
265
					size.x += margins.x;
266
				}
267
				gc.dispose();
268
			} 
269
	
270
			if ((getStyle() & SWT.DROP_DOWN) != 0) {
271
				Point hinkySize = skin.getSize(Skin.TYPE_DECORATION_ARROW, Skin.NORMAL);
272
				if (hinkySize == null) {
273
					hinkySize = new Point(0, 0);
274
				}
275
				size.x += hinkySize.x + margins.y;
276
				
277
				if ((getStyle() & SWT.SIMPLE) != SWT.SIMPLE) {
278
					Point separatorSize = skin.getSize(Skin.TYPE_DECORATION_INTERNAL_SEPARATOR, Skin.NORMAL);
279
					if (separatorSize == null) {
280
						separatorSize = new Point(0, 0);
281
					}
282
					size.x += separatorSize.x;
283
				}
284
			}
285
		}
286
		
287
		return size;
288
	}
289
	
290
	/**
291
	 * @return
292
	 */
293
	public String getToolTipText() {
294
		return toolTipText;
295
	}
296
	
297
	/**
298
	 * @return
299
	 */
300
	public int getWidth() {
301
		return itemRect.width;
302
	}
303
	
304
	public Rectangle getArrowRect() {
305
		return arrowRect;
306
	}
307
	
308
	/**
309
	 * @return
310
	 */
311
	public boolean isEnabled() {
312
		return enabled;
313
	}
314
	
315
	/**
316
	 * 
317
	 */
318
	void onDispose() {
319
		// TODO Auto-generated method stub
320
	}
321
	
322
	/**
323
	 * @param event
324
	 */
325
	void onFocus(Event event) {
326
		// TODO Auto-generated method stub
327
	}
328
329
	/**
330
	 * @param event
331
	 */
332
	void onMouseDoubleClick(Event event) {		
333
	}
334
	
335
	/**
336
	 * @param event
337
	 */
338
	void onMouseDown(Event event) {
339
		if (arrowRect != null) {
340
			if (arrowRect.contains(event.x, event.y)) {
341
				setArrowPressed(true);
342
			}
343
		}
344
		if ((arrowState & Skin.PRESSED) == 0) {
345
			setPressed(true);
346
		}
347
		notifyListeners(SWT.MouseDown, event);
348
		
349
		if ((getStyle() & SWT.RADIO) == SWT.RADIO) {
350
			Event e = new Event();
351
			e.button = event.button;
352
			e.character = event.character;
353
			e.count = event.count;
354
			e.data = event.data;
355
			e.detail = event.detail;
356
			e.display = event.display;
357
			e.doit = event.doit;
358
			e.end = event.end;
359
			e.gc = event.gc;
360
			e.height = event.height;
361
			e.item = event.item;
362
			e.keyCode = event.keyCode;
363
			e.start = event.start;
364
			e.stateMask = event.stateMask;
365
			e.text = event.text;
366
			e.time = event.time;
367
			e.widget = event.widget;
368
			e.width = event.width;
369
			e.x = event.x;
370
			e.y = event.y;
371
			
372
			e.type = SWT.Selection;
373
			notifyListeners(SWT.Selection, e);
374
			setSelected(true);
375
		}
376
	}
377
378
	/**
379
	 * @param event
380
	 */
381
	void onMouseExit(Event event) {
382
	}
383
384
	/**
385
	 * @param event
386
	 */
387
	void onMouseHover(Event event) {
388
		notifyListeners(SWT.MouseHover, event);
389
	}
390
	
391
	void setHot(boolean hot) {
392
		if (hot)
393
			state |= Skin.HOVER;
394
		else if ((state & Skin.HOVER) != 0) 
395
			state = (state & ~Skin.HOVER);
396
	}
397
398
	void setArrowHot(boolean hot) {
399
		if (hot) {
400
			arrowState |= Skin.HOVER;
401
		} else if ((arrowState & Skin.HOVER) == Skin.HOVER) {
402
			arrowState = (arrowState & ~Skin.HOVER);
403
		}
404
	}
405
	
406
	void setPressed(boolean pressed) {
407
		if (pressed)
408
			state |= Skin.PRESSED;
409
		else if ((state & Skin.PRESSED) != 0) 
410
			state = (state & ~Skin.PRESSED);
411
	}
412
	
413
	void setArrowPressed(boolean pressed) {
414
		if (pressed)
415
			arrowState |= Skin.PRESSED;
416
		else if ((arrowState & Skin.PRESSED) == Skin.PRESSED) 
417
			arrowState = (arrowState & ~Skin.PRESSED);
418
	}
419
420
	public void setSelected(boolean selected) {
421
		if (selected) {
422
			/* Clear all adjacent selected radio buttons */
423
			int itemIndex = parent.indexOf(this);
424
			int i;
425
			SToolItem item;
426
			
427
			for (i = itemIndex -1; i > 0; i--) {
428
				item = parent.getItem(i);
429
				if ((item.getStyle() & SWT.RADIO) == SWT.RADIO) {
430
					item.setSelected(false);
431
				} else {
432
					break;
433
				}
434
			}
435
			for (i = itemIndex +1; i < parent.getItemCount(); i++) {
436
				item = parent.getItem(i);
437
				if ((item.getStyle() & SWT.RADIO) == SWT.RADIO) {
438
					item.setSelected(false);
439
				} else {
440
					break;
441
				}
442
			}
443
			state |= Skin.SELECTED;
444
		} else if ((state & Skin.SELECTED) == Skin.SELECTED) { 
445
			state = (state & ~Skin.SELECTED);
446
		}
447
	}
448
	
449
	/**
450
	 * @param event
451
	 */
452
	void onMouseMove(Event event) {
453
	}
454
455
	/**
456
	 * @param event
457
	 */
458
	void onMouseUp(Event event) {
459
		setPressed(false);
460
		
461
		Event e = new Event();
462
		e.type = SWT.MouseUp;
463
		e.widget = this;
464
		e.gc = event.gc;
465
		e.x = event.x;
466
		e.y = event.y;
467
		notifyListeners(SWT.MouseUp, event);
468
469
		if ((getStyle() & SWT.RADIO) != SWT.RADIO) {
470
			e = new Event();
471
			e.type = SWT.Selection;
472
			e.widget = this;
473
			e.gc = event.gc;
474
			e.x = event.x;
475
			e.y = event.y;
476
			if (arrowRect != null && arrowRect.contains(event.x, event.y))
477
				e.detail |= SWT.ARROW;
478
			notifyListeners(SWT.Selection, e);
479
		}
480
	}
481
		
482
	
483
	/*
484
	 * Process the paint event
485
	 */
486
	void onPaint(GC gc) {
487
		Skin skin = parent.getSkin();
488
		String t = getText();
489
		if (t != null && t.length() == 0) {
490
			t = null;
491
		}
492
		Image img = null;
493
494
		int state = getState();
495
496
		/*
497
		 * A separator with text will just draw static text rather than a line separator
498
		 * so always keep the state normal so it doesn't behave like a button. 
499
		 */
500
		if (control == null && (getStyle() & SWT.SEPARATOR) == SWT.SEPARATOR && t != null) {
501
			state = Skin.NORMAL;
502
		}
503
504
		if (isEnabled() == false) {
505
			img = getDisabledImage();
506
		} else if ((state & Skin.PRESSED) == Skin.PRESSED) {
507
			img = getPressedImage();
508
		} else if ((state & Skin.HOVER) == Skin.HOVER) {
509
			img = getHotImage();
510
		}
511
		
512
		if (img == null) {
513
			img = getImage();
514
		}
515
		
516
		Rectangle insets = skin.getRect(Skin.TYPE_ITEM_INSETS, state);
517
		if (insets == null) {
518
			insets = new Rectangle(0, 0, 0, 0);
519
		}
520
		gc.setFont(skin.getFont(Skin.TYPE_ITEM_FONT, state));
521
522
		Rectangle rect = getBounds();
523
		if (rect.width == 0 || rect.height == 0)
524
			return;
525
		
526
		int availableWidth = rect.width - (insets.x + insets.width);
527
		Point extent = getContentSize(img, t);
528
		if (extent.x > availableWidth) {
529
			img = null;
530
			extent = getContentSize(img, t);
531
		}
532
533
		// determine horizontal position
534
		int x = (rect.x + insets.x);
535
		if (align == SWT.CENTER) {
536
			x = (rect.width - extent.x) / 2;
537
		}
538
		else if (align == SWT.RIGHT) {
539
			x = rect.width - extent.x - insets.width;
540
		}
541
//gc.setForeground(getDisplay().getSystemColor(SWT.COLOR_RED));
542
//gc.drawRectangle(rect);
543
		if (control == null && (getStyle() & SWT.SEPARATOR) == SWT.SEPARATOR && t == null) {
544
			state = (state & ~(Skin.PRESSED));
545
			skin.drawDecoration(gc, rect, parent, Skin.TYPE_DECORATION_SEPARATOR, state);
546
			return;
547
		}
548
		
549
		// paint background
550
		skin.drawBackground(gc, rect, parent, Skin.TYPE_ITEM_BACKGROUND, state);
551
		
552
		// paint border
553
		skin.drawBorder(gc, rect, parent, Skin.TYPE_ITEM_BORDER, state);
554
		
555
		Rectangle itemMargins = skin.getRect(Skin.TYPE_ITEM_MARGINS, state);
556
		if (itemMargins == null) {
557
			itemMargins = new Rectangle(0, 0, 0, 0);
558
		}
559
		
560
		// draw the image
561
		
562
		if (img != null) {
563
			Rectangle imageRect;
564
			Point imageSize = skin.getSize(Skin.TYPE_ITEM_ICON_SIZE, state);
565
			if (imageSize != null && imageSize.y != SWT.DEFAULT) {
566
				imageRect = new Rectangle(0, 0, imageSize.x, imageSize.y);
567
			} else {
568
				imageRect = img.getBounds();
569
			}
570
571
			imageRect = new Rectangle(x, rect.y + ((rect.height - imageRect.height) / 2),
572
					imageRect.width, imageRect.height);
573
			skin.drawImage(gc, imageRect, img, parent, Skin.TYPE_ITEM_IMAGE, state);
574
			
575
			x += imageRect.width + itemMargins.x;
576
		}
577
		
578
		// draw the text
579
		if (t != null) {
580
			FontMetrics fm = gc.getFontMetrics();
581
			int textHeight = fm.getAscent();
582
			int textWidth = gc.textExtent(getText(), SWT.DRAW_TRANSPARENT  | SWT.DRAW_MNEMONIC).x;
583
			int y = rect.y;
584
			int availableHeight = rect.height;
585
			y = y + ((availableHeight / 2) - (textHeight / 2));
586
			Rectangle textRect = new Rectangle(x, y, textWidth, textHeight);
587
//Used for debugging text rect rendering.
588
//			gc.setBackground(getDisplay().getSystemColor(SWT.COLOR_GREEN));
589
//			gc.fillRectangle(textRect);
590
			/* Don't include leading so top of text lines up when expected in the drawing rect. */
591
			textRect.y -= fm.getLeading();
592
			skin.drawText(gc, textRect, getText(), SWT.DRAW_TRANSPARENT | SWT.DRAW_MNEMONIC, parent, Skin.TYPE_ITEM_TEXT, state);
593
			/* Add leading back in to get the "text rect" that the text is actually rendered in. */
594
			textRect.y += fm.getLeading();
595
			x += textRect.width + itemMargins.y;
596
		}
597
598
		// draw the hinky and text/hinky separator
599
		if ((getStyle() & SWT.DROP_DOWN) != 0) {
600
			Point hinkySize = skin.getSize(Skin.TYPE_DECORATION_ARROW, state);
601
			if (hinkySize == null) {
602
				hinkySize = new Point(0, 0);
603
			}
604
			int myX = x;
605
			int myY = rect.y + ((rect.height /2) - ((hinkySize.y == SWT.DEFAULT ? 0 : hinkySize.y) / 2));
606
			Point separatorSize = skin.getSize(Skin.TYPE_DECORATION_INTERNAL_SEPARATOR, state);
607
			if (separatorSize == null) {
608
				separatorSize = new Point(0, 0);
609
			}
610
			int sepLineX = myX -2;
611
612
			int arrowState = state;
613
			// separator
614
			Rectangle sepLineRectangle = null;
615
			if ((getStyle() & SWT.SIMPLE) != SWT.SIMPLE) {
616
				int y = rect.y + (((rect.height / 2) - ((separatorSize.y == SWT.DEFAULT ? rect.height : separatorSize.y)) / 2));
617
				sepLineRectangle = new Rectangle(sepLineX, y, separatorSize.x, (separatorSize.y == SWT.DEFAULT ? rect.height : separatorSize.y));
618
				skin.drawDecoration(gc, sepLineRectangle, parent, Skin.TYPE_DECORATION_INTERNAL_SEPARATOR, state);
619
				myX += separatorSize.x;
620
				/* Since it is separate, use the arrow state to draw the hinky below. */
621
				arrowState = getArrowState();
622
			}
623
			
624
			// hinky
625
			int height = (hinkySize.y == SWT.DEFAULT ? rect.height : hinkySize.y); 
626
			Rectangle arrowImageRect = new Rectangle(myX, myY, hinkySize.x, height);
627
			skin.drawDecoration(gc, arrowImageRect, parent, Skin.TYPE_DECORATION_ARROW, arrowState);
628
			
629
			if (sepLineRectangle != null)
630
				arrowRect = new Rectangle(sepLineRectangle.x, 0, myX, rect.height);
631
			else
632
				arrowRect = null;
633
		}
634
	}
635
636
	public void removeSelectionListener (SelectionListener listener) {
637
		checkWidget();
638
		if (listener == null) SWT.error (SWT.ERROR_NULL_ARGUMENT);
639
		removeListener(SWT.Selection, listener);
640
		removeListener(SWT.DefaultSelection,listener);	
641
	}
642
	
643
	/**
644
	 * @param control
645
	 */
646
	public void setControl(Control control) {
647
		this.control = control;
648
		if (control != null) {
649
			Point pt = control.computeSize(SWT.DEFAULT, SWT.DEFAULT);
650
			itemRect = new Rectangle(0, 0, pt.x, pt.y);
651
			control.setBounds(itemRect);
652
			parent.itemChanged(this);
653
		}
654
	}
655
	
656
	/**
657
	 * @param image
658
	 */
659
	public void setDisabledImage(Image image) {
660
		this.disabledImage = image;
661
		parent.itemChanged(this);
662
	}
663
	
664
	/**
665
	 * @param enabled
666
	 */
667
	public void setEnabled(boolean enabled) {
668
		this.enabled = enabled;
669
		parent.itemChanged(this);
670
	}
671
	
672
	/**
673
	 * @param image
674
	 */
675
	public void setHotImage(Image image) {
676
		this.hotImage = image;
677
		parent.itemChanged(this);
678
	}
679
	
680
	/**
681
	 * @param pressed image
682
	 */
683
	public void setPressedImage(Image image) {
684
		this.pressedImage = image;
685
		parent.itemChanged(this);
686
	}
687
	
688
	/* (non-Javadoc)
689
	 * @see org.eclipse.swt.widgets.Item#setImage(org.eclipse.swt.graphics.Image)
690
	 */
691
	public void setImage(Image image) {
692
		if ((getStyle() & SWT.SEPARATOR) != 0)
693
			return;
694
		super.setImage(image);
695
		parent.itemChanged(this);
696
	}
697
698
	/**
699
	 * @param selected
700
	 */
701
	public void setSelection(boolean selected) {
702
		this.selected = selected;
703
		parent.itemChanged(this);
704
	}
705
	
706
	/* (non-Javadoc)
707
	 * @see org.eclipse.swt.widgets.Item#setText(java.lang.String)
708
	 */
709
	public void setText(String string) {
710
		super.setText(string);
711
		parent.itemChanged(this);
712
	}
713
	
714
	/**
715
	 * @param string
716
	 */
717
	public void setToolTipText(String string) {
718
		toolTipText = string;
719
		parent.itemChanged(this);
720
	}
721
	
722
	public void setWidth(int width) {
723
		this.width = width;
724
		if (control != null) {
725
			Point size = control.getSize();
726
			size.x = width;
727
			control.setSize(size);
728
		}
729
	}
730
731
}
(-)src/org/eclipse/ui/examples/presentation/customtoolbar/widgets/SToolBar.java (+504 lines)
Added Link Here
1
/*
2
*	Copyright IBM Corporation 2003, 2005
3
*	All rights reserved.
4
*	US Government Users Restricted Rights - Use, duplication or disclosure
5
*	restricted by GS ADP Schedule Contract with IBM Corp.
6
*/
7
package org.eclipse.ui.examples.presentation.customtoolbar.widgets;
8
9
import java.util.ArrayList;
10
11
import org.eclipse.swt.SWT;
12
import org.eclipse.swt.graphics.GC;
13
import org.eclipse.swt.graphics.Image;
14
import org.eclipse.swt.graphics.ImageData;
15
import org.eclipse.swt.graphics.PaletteData;
16
import org.eclipse.swt.graphics.Point;
17
import org.eclipse.swt.graphics.Rectangle;
18
import org.eclipse.swt.widgets.Composite;
19
import org.eclipse.swt.widgets.Control;
20
import org.eclipse.swt.widgets.Event;
21
import org.eclipse.swt.widgets.Listener;
22
23
public class SToolBar extends SWidget {
24
	
25
	private ArrayList items = new ArrayList();
26
	private SToolItem hoverItem;
27
	private SToolItem mouseDownItem;
28
	
29
	private Point offscreenImageSize = new Point(-1, -1);
30
	private Image offscreenImage = null;
31
	private GC offscreenGc = null;
32
	
33
	static final int ITEM_INSET_TOP = 3;
34
	static final int ITEM_INSET_BOTTOM = 4;
35
	static final int LEFT_MARGIN = 6;
36
	static final int SHADOW_SIZE = 4;
37
	
38
	/**
39
	 * @param parent
40
	 * @param style
41
	 */
42
	public SToolBar(Composite parent, int style) {
43
		super(parent, checkStyle(style));
44
45
		// Add all listeners
46
		Listener listener = new Listener() {
47
			public void handleEvent(Event event) {
48
				switch (event.type) {
49
					case SWT.Dispose:          onDispose(); break;
50
					case SWT.FocusIn:          onFocus(event);	break;
51
					case SWT.FocusOut:         onFocus(event);	break;
52
					case SWT.MouseDoubleClick: onMouseDoubleClick(event); break;
53
					case SWT.MouseDown:        onMouseDown(event);	break;
54
					case SWT.MouseExit:        onMouseExit(event);	break;
55
					case SWT.MouseHover:       onMouseHover(event); break;
56
					case SWT.MouseMove:        onMouseMove(event); break;
57
					case SWT.MouseUp:          onMouseUp(event); break;
58
					case SWT.Paint:            onPaint(event);	break;
59
					case SWT.Traverse:         onTraverse(event); break;
60
				}
61
			}
62
		};
63
64
		int[] toolBarEvents = new int[]{
65
66
			SWT.Dispose,
67
			SWT.FocusIn, 
68
			SWT.FocusOut, 
69
			SWT.KeyDown,
70
			SWT.MouseDoubleClick, 
71
			SWT.MouseDown,
72
			SWT.MouseExit,
73
			SWT.MouseHover, 
74
			SWT.MouseMove,
75
			SWT.MouseUp,
76
			SWT.Paint,
77
			SWT.Resize,  
78
			SWT.Traverse
79
		};
80
		for (int i = 0; i < toolBarEvents.length; i++) {
81
			addListener(toolBarEvents[i], listener);
82
		}
83
	}
84
	
85
	private static int checkStyle(int style) {
86
		return SWT.NO_BACKGROUND;
87
	}
88
89
	void createItem(SToolItem item, int index) {
90
		if (!(0 <= index && index <= items.size()))
91
			SWT.error(SWT.ERROR_INVALID_RANGE);
92
		items.add(index, item);
93
		redraw();
94
	}
95
96
	public Point computeSize(int wHint, int hHint, boolean changed) {
97
		if (getLayout() != null) {
98
			return super.computeSize (wHint, hHint, changed);
99
		}
100
		
101
		Skin skin = getSkin();
102
		Rectangle itemAreaInsets = null; 
103
		Rectangle itemMargins = null;
104
		if (skin != null) {
105
			itemAreaInsets = skin.getRect(Skin.TYPE_ITEM_AREA_INSETS, Skin.NORMAL);
106
			itemMargins = skin.getRect(Skin.TYPE_ITEM_AREA_MARGINS, Skin.NORMAL);
107
		}
108
		if (itemAreaInsets == null) {
109
			itemAreaInsets = new Rectangle(0, 0, 0, 0);
110
		}
111
		if (itemMargins == null) {
112
			itemMargins = new Rectangle(0, 0, 0, 0);
113
		}
114
115
		int x;
116
		int y;
117
		Point size = getSize();
118
		int length = (items != null) ? items.size() : 0;
119
		if ((getStyle() & SWT.VERTICAL) == SWT.VERTICAL) {
120
			x = 0;
121
			y = itemAreaInsets.x + itemMargins.x;
122
			for (int i = 0; i < length; i++) {
123
				SToolItem item = (SToolItem)items.get(i);
124
				Point pt = item.computeSize(wHint, hHint, changed);
125
				x = (pt.x > x) ? pt.x : x;
126
				y += (pt.y + itemMargins.x);
127
			}
128
			x += itemAreaInsets.y + itemAreaInsets.height;
129
			y += itemAreaInsets.width;
130
		} else {
131
			x = itemAreaInsets.x + itemMargins.x;
132
			y = 0;
133
			for (int i = 0; i < length; i++) {
134
				SToolItem item = (SToolItem)items.get(i);
135
				Point pt = item.computeSize(wHint, hHint, changed);
136
				x += (pt.x + itemMargins.x);
137
				y = (pt.y > y) ? pt.y : y;
138
			}
139
			y += itemAreaInsets.y + itemAreaInsets.height;
140
			x += itemAreaInsets.width;
141
		}
142
		
143
		if (wHint != SWT.DEFAULT && wHint >= x)
144
			x = wHint;
145
		if (hHint != SWT.DEFAULT && hHint >= y)
146
			y = hHint;
147
		// TODO: to be refactored. we should not use the value from getSize(). 
148
		// Otherwise toolbar cannot be smaller.
149
		//if (wHint == SWT.DEFAULT && size.x > x)
150
		//	x = size.x; 
151
		if (hHint == SWT.DEFAULT && size.y > y)
152
			y = size.y; 
153
		return new Point(x, y);
154
	}
155
	
156
	public Rectangle computeTrim(int x, int y, int width, int height) {
157
		return new Rectangle(x+SHADOW_SIZE, y+SHADOW_SIZE, 
158
				width-(SHADOW_SIZE*2), height-(SHADOW_SIZE*2));
159
	}
160
161
	void destroyItem(SToolItem item) {
162
		if (items.contains(item))
163
			items.remove(item);
164
	}
165
	
166
	public SToolItem getItem(int index) {
167
		return (SToolItem)items.get(index);
168
	}
169
	
170
	public SToolItem getItem(Point point) {
171
		return null;
172
	}
173
	
174
	public int getItemCount() {
175
		return items.size();
176
	}
177
	
178
	public SToolItem[] getItems() {
179
		return (SToolItem[])items.toArray(new SToolItem[0]);
180
	}
181
	
182
	public int getRowCount() {
183
		return 0;
184
	}
185
	
186
	public int indexOf(SToolItem item) {
187
		return items.indexOf(item);
188
	}
189
190
	void itemChanged(SToolItem item) {
191
		updateItems();
192
		redraw();
193
	}
194
	
195
	/**
196
	 * 
197
	 */
198
	protected void onDispose() {
199
		Skin skin = getSkin();
200
		if (skin != null)
201
			skin.dispose();
202
	}
203
	
204
	/**
205
	 * @param event
206
	 */
207
	protected void onFocus(Event event) {
208
		// TODO Auto-generated method stub
209
	}
210
211
	/**
212
	 * @param event
213
	 */
214
	protected void onMouseDoubleClick(Event event) {
215
		// TODO Auto-generated method stub
216
	}
217
	
218
	/**
219
	 * @param event
220
	 */
221
	protected void onMouseDown(Event event) {
222
		SToolItem item = findToolItem(event.x, event.y);
223
		if (item != null) {
224
			item.onMouseDown(event);
225
			mouseDownItem = item;
226
			redraw();
227
		}
228
	}
229
230
	/**
231
	 * @param event
232
	 */
233
	protected void onMouseExit(Event event) {
234
		boolean needsRedraw = false;
235
		if (hoverItem != null) {
236
			hoverItem.setHot(false);
237
			hoverItem.setArrowHot(false);
238
			hoverItem = null;
239
			needsRedraw = true;
240
		}
241
		if (mouseDownItem != null) {
242
			mouseDownItem.setPressed(false);
243
			mouseDownItem.setArrowPressed(false);
244
			mouseDownItem = null;
245
			needsRedraw = true;
246
		}
247
		if (needsRedraw)
248
			redraw();
249
	}
250
251
	/**
252
	 * @param event
253
	 */
254
	protected void onMouseHover(Event event) {
255
		// TODO Auto-generated method stub
256
	}
257
	
258
	/**
259
	 * @param event
260
	 */
261
	protected void onMouseMove(Event event) {
262
		SToolItem item = findToolItem(event.x, event.y);
263
		if (item != null) {
264
			if (hoverItem != item) {
265
				item.setHot(true);
266
				Rectangle arrowRect = item.getArrowRect();
267
				if (arrowRect != null) {
268
					if (arrowRect.contains(event.x, event.y)) {
269
						item.setArrowHot(true);
270
					}
271
				}
272
				
273
				if (hoverItem != null) {
274
					hoverItem.setHot(false);
275
					hoverItem.setArrowHot(false);
276
				}
277
				
278
				hoverItem = item;
279
				redraw();
280
			}
281
		} else if (hoverItem != null) {
282
			hoverItem.setHot(false);
283
			hoverItem.setArrowHot(false);
284
			hoverItem = null;
285
			redraw();
286
		}
287
	}
288
289
	/**
290
	 * @param event
291
	 */
292
	protected void onMouseUp(Event event) {
293
		boolean needsRedraw = false;
294
		
295
		try {
296
			SToolItem item = findToolItem(event.x, event.y);
297
			if (item != null && item == mouseDownItem) {
298
				needsRedraw = true;
299
				item.onMouseUp(event);
300
			} else if (mouseDownItem != null) {
301
				needsRedraw = true;
302
				mouseDownItem.setPressed(false);
303
				mouseDownItem.setArrowPressed(false);
304
			}
305
		} finally {
306
			if (needsRedraw)
307
				redraw();
308
		}
309
	}
310
	
311
	
312
	/**
313
	 * @param event
314
	 */
315
	protected void onPaint(Event event) {
316
		Point size = getSize();
317
		GC gc = event.gc;
318
		
319
		try {
320
			if (offscreenImageSize.x != size.x || offscreenImageSize.y != size.y) {
321
				if (offscreenImage != null) {
322
					offscreenImage.dispose();
323
					offscreenImage = null;
324
				}
325
				if (offscreenGc != null) {
326
					offscreenGc.dispose();
327
					offscreenGc = null;
328
				}
329
				PaletteData offscreenImagePalette = new PaletteData(0x0000FF00, 0x00FF0000, 0xFF000000);
330
				ImageData offscreenImageData = new ImageData(size.x, size.y, 32, offscreenImagePalette);
331
				offscreenImageData.type = SWT.BITMAP;
332
				offscreenImage = new Image(null, offscreenImageData);
333
				offscreenGc = new GC(offscreenImage, getStyle());
334
				offscreenImageSize.x = size.x;
335
				offscreenImageSize.y = size.y;
336
			}
337
		} finally {
338
			if (offscreenGc != null) {
339
				offscreenGc.setForeground(event.gc.getForeground());
340
				offscreenGc.setBackground(event.gc.getBackground());
341
				offscreenGc.fillRectangle(0, 0, size.x, size.y);
342
				gc = offscreenGc;
343
			}
344
		}
345
		
346
		updateItems();
347
		Skin skin = getSkin();
348
		
349
		if (skin == null)
350
			return;
351
				
352
		Rectangle rect = getClientArea();
353
		if (rect.width == 0 || rect.height == 0)
354
			return;
355
		
356
		int state = Skin.NORMAL;
357
		
358
		// paint background
359
		skin.drawBackground(gc, rect, this, Skin.TYPE_BACKGROUND, state);
360
		
361
		// paint tool items
362
		for (int i = 0; i < items.size(); i++) {
363
			SToolItem item = this.getItem(i);
364
			item.onPaint(gc);
365
		}
366
367
		// paint border
368
		skin.drawBorder(gc, rect, this, Skin.TYPE_BORDER, state);
369
		
370
		// draw the offscreen image
371
		if (gc == offscreenGc)
372
			event.gc.drawImage(offscreenImage, 0, 0);
373
	
374
	}
375
	
376
	/**
377
	 * @param event
378
	 */
379
	protected void onTraverse(Event event) {
380
		// TODO Auto-generated method stub
381
	}
382
383
	private SToolItem findToolItem(int x, int y) {
384
		SToolItem item = null;
385
		for (int i=0; i<items.size(); i++) {
386
			Rectangle bounds = ((SToolItem)items.get(i)).getBounds();
387
			if (bounds.contains(x, y)){
388
				item = (SToolItem)items.get(i);
389
			}
390
		}
391
		return item;
392
	}
393
	
394
	public void setSkin(Skin skin) {
395
		super.setSkin(skin);
396
	}
397
	
398
	boolean setItemLocation() {
399
		if (items.size() == 0)
400
			return false;
401
		
402
		Skin skin = getSkin();
403
		Rectangle itemAreaInsets = null; 
404
		Rectangle itemMargins = null;
405
		if (skin != null) {
406
			itemAreaInsets = skin.getRect(Skin.TYPE_ITEM_AREA_INSETS, Skin.NORMAL);
407
			itemMargins = skin.getRect(Skin.TYPE_ITEM_AREA_MARGINS, Skin.NORMAL);
408
		}
409
		if (itemAreaInsets == null) {
410
			itemAreaInsets = new Rectangle(0, 0, 0, 0);
411
		}
412
		if (itemMargins == null) {
413
			itemMargins = new Rectangle(0, 0, 0, 0);
414
		}
415
416
		/*
417
		 * TODO Handle vertical toolbars.
418
		 */
419
		
420
		Rectangle barBounds = getBounds();
421
		int height = 0;
422
		if (barBounds != null) {
423
			height = barBounds.height;
424
		}
425
426
		boolean changed = false;
427
		int x = itemAreaInsets.x + itemMargins.x;
428
		int y;
429
		for (int i = 0; i < items.size(); i++) {
430
			SToolItem item = (SToolItem)items.get(i);
431
			if (item.itemRect.x != x) {
432
				item.itemRect.x = x;
433
				changed = true;
434
			}
435
436
			/*
437
			 * Center vertically.
438
			 */
439
			y = itemAreaInsets.y + (((height - itemAreaInsets.y - itemAreaInsets.height) / 2) - (item.itemRect.height / 2));
440
441
			if (item.itemRect.y != y) {
442
				item.itemRect.y = y;
443
				changed = true;
444
			}
445
			if (changed == true) {
446
				Control control = item.getControl(); 
447
				if (control != null) {
448
					Rectangle r = control.getBounds();
449
					r.x = item.itemRect.x + (item.itemRect.width - r.width) / 2;
450
					r.y = item.itemRect.y + (item.itemRect.height - r.height) / 2;
451
					control.setLocation(r.x, r.y);
452
				}
453
			}
454
			x += (item.itemRect.width + itemMargins.x);
455
		}
456
		return changed;
457
	}
458
459
	boolean setItemSize() {
460
		if (items.size() == 0)
461
			return false;
462
		
463
		boolean changed = false;
464
465
		Skin skin = getSkin();
466
		Rectangle itemAreaInsets = null; 
467
		if (skin != null) {
468
			itemAreaInsets = skin.getRect(Skin.TYPE_ITEM_AREA_INSETS, Skin.NORMAL);
469
		}
470
		if (itemAreaInsets == null) {
471
			itemAreaInsets = new Rectangle(0, 0, 0, 0);
472
		}
473
474
		for (int i = 0; i < items.size(); i++) {
475
			SToolItem item = (SToolItem)items.get(i);
476
			Point pt = item.computeSize(SWT.DEFAULT, SWT.DEFAULT, false);
477
			
478
			if (pt.y == SWT.DEFAULT) {
479
				if ((getStyle() & SWT.VERTICAL) == SWT.VERTICAL) {
480
					pt.y = pt.x;
481
					pt.x = getSize().x - (itemAreaInsets.y + itemAreaInsets.height);
482
				} else {
483
					pt.y = getSize().y - (itemAreaInsets.y + itemAreaInsets.height);
484
				}
485
			}
486
			
487
			if (pt.x != item.itemRect.width) {
488
				item.itemRect.width = pt.x;
489
				changed = true;
490
			}
491
		    if (pt.y != item.itemRect.height) {
492
		    	item.itemRect.height = pt.y;
493
				changed = true;
494
		    }
495
		}
496
		return changed;
497
	}
498
	
499
	void updateItems() {
500
		setItemSize();
501
		setItemLocation();
502
	}
503
504
}
(-)src/org/eclipse/ui/examples/presentation/customtoolbar/widgets/SToolBarContributionItem2.java (+709 lines)
Added Link Here
1
package org.eclipse.ui.examples.presentation.customtoolbar.widgets;
2
3
import java.util.ArrayList;
4
import java.util.Iterator;
5
6
import org.eclipse.jface.action.ActionContributionItem;
7
import org.eclipse.jface.action.IContributionItem;
8
import org.eclipse.jface.action.ICoolBarManager;
9
import org.eclipse.jface.action.IToolBarManager;
10
import org.eclipse.jface.action.MenuManager;
11
import org.eclipse.jface.action.Separator;
12
import org.eclipse.jface.action.SubContributionItem;
13
import org.eclipse.jface.action.ToolBarContributionItem;
14
import org.eclipse.jface.action.ToolBarManager;
15
import org.eclipse.jface.util.Assert;
16
import org.eclipse.jface.util.Policy;
17
import org.eclipse.swt.SWT;
18
import org.eclipse.swt.events.DisposeEvent;
19
import org.eclipse.swt.events.DisposeListener;
20
import org.eclipse.swt.events.SelectionAdapter;
21
import org.eclipse.swt.events.SelectionEvent;
22
import org.eclipse.swt.graphics.Point;
23
import org.eclipse.swt.graphics.Rectangle;
24
import org.eclipse.swt.widgets.Control;
25
import org.eclipse.swt.widgets.CoolBar;
26
import org.eclipse.swt.widgets.CoolItem;
27
import org.eclipse.swt.widgets.Event;
28
import org.eclipse.swt.widgets.Listener;
29
import org.eclipse.swt.widgets.Menu;
30
import org.eclipse.swt.widgets.ToolBar;
31
import org.eclipse.swt.widgets.ToolItem;
32
33
public class SToolBarContributionItem2 extends ToolBarContributionItem implements ISContributionItem {
34
35
    /**
36
     * A constant used by <code>setMinimumItemsToShow</code> and <code>getMinimumItemsToShow</code>
37
     * to indicate that all tool items should be shown in the cool item.
38
     */
39
    public static final int SHOW_ALL_ITEMS = -1;
40
41
    /**
42
     * The pull down menu used to list all hidden tool items if the current
43
     * size is less than the preffered size.
44
     */
45
    private MenuManager chevronMenuManager = null;
46
47
    /**
48
     * The widget created for this item; <code>null</code> before creation
49
     * and after disposal.
50
     */
51
    private SCoolItem coolItem = null;
52
53
    /**
54
     * Current height of cool item
55
     */
56
    private int currentHeight = -1;
57
58
    /**
59
     * Current width of cool item.
60
     */
61
    private int currentWidth = -1;
62
63
    /**
64
     * A flag indicating that this item has been disposed. This prevents future
65
     * method invocations from doing things they shouldn't.
66
     */
67
    private boolean disposed = false;
68
69
    /**
70
     * Mininum number of tool items to show in the cool item widget.
71
     */
72
    private int minimumItemsToShow = SHOW_ALL_ITEMS;
73
74
    /**
75
     * The tool bar manager used to manage the tool items contained in the cool
76
     * item widget.
77
     */
78
    private IToolBarManager toolBarManager = null;
79
80
    /**
81
     * Enable/disable chevron support.
82
     */
83
    private boolean useChevron = true;
84
85
	private String id;
86
87
    /**
88
     * Convenience method equivalent to <code>ToolBarContributionItem(new ToolBarManager(), null)</code>.
89
     */
90
    public SToolBarContributionItem2() {
91
        this(new SToolBarManager2(), (String)null);
92
    }
93
    
94
    /**
95
     * Convenience method equivalent to <code>ToolBarContributionItem(toolBarManager, null)</code>.
96
     * 
97
     * @param toolBarManager
98
     *            the tool bar manager
99
     */
100
    public SToolBarContributionItem2(IToolBarManager toolBarManager) {
101
        this(toolBarManager, (String)null);
102
    }
103
104
    /**
105
     * Creates a tool bar contribution item.
106
     * 
107
     * @param toolBarManager
108
     *            the tool bar manager to wrap
109
     * @param id
110
     *            the contribution item id, or <code>null</code> if none
111
     */
112
    public SToolBarContributionItem2(IToolBarManager toolBarManager, String id) {
113
        super();
114
        this.toolBarManager = toolBarManager;
115
        this.id = id;
116
    }
117
    
118
    /**
119
     * Checks whether this contribution item has been disposed. If it has, and
120
     * the tracing options are active, then it prints some debugging
121
     * information.
122
     * 
123
     * @return <code>true</code> if the item is disposed; <code>false</code>
124
     *         otherwise.
125
     *  
126
     */
127
    private final boolean checkDisposed() {
128
        if (disposed) {
129
            if (Policy.TRACE_TOOLBAR) { //$NON-NLS-1$
130
                System.out
131
                        .println("Method invocation on a disposed tool bar contribution item."); //$NON-NLS-1$
132
                new Exception().printStackTrace(System.out);
133
            }
134
135
            return true;
136
        }
137
138
        return false;
139
    }
140
141
    /*
142
     * (non-Javadoc)
143
     * 
144
     * @see org.eclipse.jface.action.IContributionItem#dispose()
145
     */
146
    public void dispose() {
147
        // Dispose of the ToolBar and all its contributions
148
        if (toolBarManager != null) {
149
        	// TODO: handle dispose
150
        	if (toolBarManager instanceof ToolBarManager)
151
        		((ToolBarManager)toolBarManager).dispose();
152
        	else if (toolBarManager instanceof SToolBarManager2)
153
        		((SToolBarManager2)toolBarManager).dispose();
154
            toolBarManager = null;
155
        }
156
157
        /*
158
         * We need to dispose the cool item or we might be left holding a cool
159
         * item with a disposed control.
160
         */
161
        if ((coolItem != null) && (!coolItem.isDisposed())) {
162
            coolItem.dispose();
163
            coolItem = null;
164
        }
165
166
        // Mark this item as disposed.
167
        disposed = true;
168
    }
169
170
    /*
171
     * (non-Javadoc)
172
     * 
173
     * @see org.eclipse.jface.action.IContributionItem#fill(org.eclipse.swt.widgets.CoolBar,
174
     *      int)
175
     */
176
    public void fill(CoolBar coolBar, int index) {
177
    	// do nothing
178
    }
179
    
180
    /**
181
     * Returns a consistent set of wrap indices. The return value will always
182
     * include at least one entry and the first entry will always be zero.
183
     * CoolBar.getWrapIndices() is inconsistent in whether or not it returns an
184
     * index for the first row.
185
     */
186
    private int[] getAdjustedWrapIndices(int[] wraps) {
187
        int[] adjustedWrapIndices;
188
        if (wraps.length == 0) {
189
            adjustedWrapIndices = new int[] { 0 };
190
        } else {
191
            if (wraps[0] != 0) {
192
                adjustedWrapIndices = new int[wraps.length + 1];
193
                adjustedWrapIndices[0] = 0;
194
                for (int i = 0; i < wraps.length; i++) {
195
                    adjustedWrapIndices[i + 1] = wraps[i];
196
                }
197
            } else {
198
                adjustedWrapIndices = wraps;
199
            }
200
        }
201
        return adjustedWrapIndices;
202
    }
203
204
    /**
205
     * Returns the current height of the corresponding cool item.
206
     * 
207
     * @return the current height
208
     */
209
    public int getCurrentHeight() {
210
        if (checkDisposed()) {
211
            return -1;
212
        }
213
        return currentHeight;
214
    }
215
216
    /**
217
     * Returns the current width of the corresponding cool item.
218
     * 
219
     * @return the current size
220
     */
221
    public int getCurrentWidth() {
222
        if (checkDisposed()) {
223
            return -1;
224
        }
225
        return currentWidth;
226
    }
227
228
    /*
229
     *  (non-Javadoc)
230
     * @see org.eclipse.jface.action.IContributionItem#getId()
231
     */
232
    public String getId() {
233
    	return this.id;
234
    }
235
    
236
    /**
237
     * Returns the minimum number of tool items to show in the cool item.
238
     * 
239
     * @return the minimum number of tool items to show, or <code>SHOW_ALL_ITEMS</code>
240
     *         if a value was not set
241
     * @see #setMinimumItemsToShow(int)
242
     */
243
    public int getMinimumItemsToShow() {
244
        if (checkDisposed()) {
245
            return -1;
246
        }
247
        return minimumItemsToShow;
248
    }
249
250
    /**
251
     * Returns the internal tool bar manager of the contribution item.
252
     * 
253
     * @return the tool bar manager, or <code>null</code> if one is not
254
     *         defined.
255
     * @see IToolBarManager
256
     */
257
    public IToolBarManager getToolBarManager() {
258
        if (checkDisposed()) {
259
            return null;
260
        }
261
        return toolBarManager;
262
    }
263
264
    /**
265
     * Returns whether chevron support is enabled.
266
     * 
267
     * @return <code>true</code> if chevron support is enabled, <code>false</code>
268
     *         otherwise
269
     */
270
    public boolean getUseChevron() {
271
        if (checkDisposed()) {
272
            return false;
273
        }
274
        return useChevron;
275
    }
276
277
    /**
278
     * Create and display the chevron menu.
279
     */
280
    private void handleChevron(SelectionEvent event) {
281
        CoolItem item = (CoolItem) event.widget;
282
        Control control = item.getControl();
283
        if ((control instanceof ToolBar) == false) {
284
            return;
285
        }
286
        CoolBar coolBar = item.getParent();
287
        ToolBar toolBar = (ToolBar) control;
288
        Rectangle toolBarBounds = toolBar.getBounds();
289
        ToolItem[] items = toolBar.getItems();
290
        ArrayList hidden = new ArrayList();
291
        for (int i = 0; i < items.length; ++i) {
292
            Rectangle itemBounds = items[i].getBounds();
293
            if (!((itemBounds.x + itemBounds.width <= toolBarBounds.width) && (itemBounds.y
294
                    + itemBounds.height <= toolBarBounds.height))) {
295
                hidden.add(items[i]);
296
            }
297
        }
298
299
        // Create a pop-up menu with items for each of the hidden buttons.
300
        if (chevronMenuManager != null) {
301
            chevronMenuManager.dispose();
302
        }
303
        chevronMenuManager = new MenuManager();
304
        for (Iterator i = hidden.iterator(); i.hasNext();) {
305
            ToolItem toolItem = (ToolItem) i.next();
306
            IContributionItem data = (IContributionItem) toolItem.getData();
307
            if (data instanceof ActionContributionItem) {
308
                ActionContributionItem contribution = new ActionContributionItem(
309
                        ((ActionContributionItem) data).getAction());
310
                chevronMenuManager.add(contribution);
311
            } else if (data instanceof SubContributionItem) {
312
                IContributionItem innerData = ((SubContributionItem) data)
313
                        .getInnerItem();
314
                if (innerData instanceof ActionContributionItem) {
315
                    ActionContributionItem contribution = new ActionContributionItem(
316
                            ((ActionContributionItem) innerData).getAction());
317
                    chevronMenuManager.add(contribution);
318
                }
319
            } else if (data.isSeparator()) {
320
                chevronMenuManager.add(new Separator());
321
            }
322
        }
323
        Menu popup = chevronMenuManager.createContextMenu(coolBar);
324
        Point chevronPosition = coolBar.toDisplay(event.x, event.y);
325
        popup.setLocation(chevronPosition.x, chevronPosition.y);
326
        popup.setVisible(true);
327
    }
328
329
    /**
330
     * Handles the event when the toobar item does not have its own context
331
     * menu.
332
     * 
333
     * @param event
334
     *            the event object
335
     */
336
    private void handleContextMenu(Event event) {
337
        Control toolBar = null;
338
        if (toolBarManager instanceof SToolBarManager2)
339
        	toolBar = ((SToolBarManager2)toolBarManager).getControl();
340
        else if (toolBarManager instanceof ToolBarManager)
341
        	toolBar = ((ToolBarManager)toolBarManager).getControl();
342
        else
343
        	return;
344
        // If parent has a menu then use that one
345
        Menu parentMenu = toolBar.getParent().getMenu();
346
        if ((parentMenu != null) && (!parentMenu.isDisposed())) {
347
            toolBar.setMenu(parentMenu);
348
            // Hook listener to remove menu once it has disapeared
349
            parentMenu.addListener(SWT.Hide, new Listener() {
350
351
                public void handleEvent(Event innerEvent) {
352
                    Control innerToolBar = null;
353
                    if (toolBarManager instanceof ToolBarManager)
354
                    	innerToolBar = ((ToolBarManager)toolBarManager).getControl();
355
                    else if (toolBarManager instanceof SToolBarManager2)
356
                    	innerToolBar = ((SToolBarManager2)toolBarManager).getControl();
357
                    if (innerToolBar != null) {
358
                        innerToolBar.setMenu(null);
359
                        Menu innerParentMenu = innerToolBar.getParent()
360
                                .getMenu();
361
                        if (innerParentMenu != null) {
362
                            innerParentMenu.removeListener(SWT.Hide, this);
363
                        }
364
                    }
365
                }
366
            });
367
        }
368
    }
369
370
    /**
371
     * Handles the disposal of the widget.
372
     * 
373
     * @param event
374
     *            the event object
375
     */
376
    private void handleWidgetDispose(DisposeEvent event) {
377
        coolItem = null;
378
    }
379
380
    /**
381
     * A contribution item is visible iff its internal state is visible <em>or</em>
382
     * the tool bar manager contains something other than group markers and
383
     * separators.
384
     * 
385
     * @return <code>true</code> if the tool bar manager contains something
386
     *         other than group marks and separators, and the internal state is
387
     *         set to be visible.
388
     */
389
    public boolean isVisible() {
390
        if (checkDisposed()) {
391
            return false;
392
        }
393
394
        boolean visibleItem = false;
395
        if (toolBarManager != null) {
396
            IContributionItem[] contributionItems = toolBarManager.getItems();
397
            for (int i = 0; i < contributionItems.length; i++) {
398
                IContributionItem contributionItem = contributionItems[i];
399
                if ((!contributionItem.isGroupMarker())
400
                        && (!contributionItem.isSeparator())) {
401
                    visibleItem = true;
402
                    break;
403
                }
404
            }
405
        }
406
407
        return (visibleItem || super.isVisible());
408
    }
409
410
    /*
411
     * (non-Javadoc)
412
     * 
413
     * @see org.eclipse.jface.action.IContributionItem#saveWidgetState()
414
     */
415
    public void saveWidgetState() {
416
        if (checkDisposed()) {
417
            return;
418
        }
419
        if (coolItem == null)
420
            return;
421
422
        //1. Save current size
423
        SCoolBar coolBar = (SCoolBar)coolItem.getParent();
424
        boolean isLastOnRow = false;
425
        int lastIndex = coolBar.getItemCount() - 1;
426
        int coolItemIndex = coolBar.indexOf(coolItem);
427
        int[] wrapIndicies = getAdjustedWrapIndices(coolBar.getWrapIndices());
428
        // Traverse through all wrap indicies backwards
429
        for (int row = wrapIndicies.length - 1; row >= 0; row--) {
430
            if (wrapIndicies[row] <= coolItemIndex) {
431
432
                int nextRow = row + 1;
433
                int nextRowStartIndex;
434
                if (nextRow > (wrapIndicies.length - 1)) {
435
                    nextRowStartIndex = lastIndex + 1;
436
                } else {
437
                    nextRowStartIndex = wrapIndicies[nextRow];
438
                }
439
440
                // Check to see if its the last item on the row
441
                if (coolItemIndex == (nextRowStartIndex - 1)) {
442
                    isLastOnRow = true;
443
                }
444
                break;
445
            }
446
        }
447
448
        // Save the preferred size as actual size for the last item on a row
449
        int nCurrentWidth;
450
        if (isLastOnRow) {
451
            nCurrentWidth = coolItem.getPreferredSize().x;
452
        } else {
453
            nCurrentWidth = coolItem.getSize().x;
454
        }
455
        setCurrentWidth(nCurrentWidth);
456
        setCurrentHeight(coolItem.getSize().y);
457
    }
458
459
    /**
460
     * Sets the current height of the cool item. Update(SIZE) should be called
461
     * to adjust the widget.
462
     * 
463
     * @param currentHeight
464
     *            the current height to set
465
     */
466
    public void setCurrentHeight(int currentHeight) {
467
        if (checkDisposed()) {
468
            return;
469
        }
470
        this.currentHeight = currentHeight;
471
    }
472
473
    /**
474
     * Sets the current width of the cool item. Update(SIZE) should be called
475
     * to adjust the widget.
476
     * 
477
     * @param currentWidth
478
     *            the current width to set
479
     */
480
    public void setCurrentWidth(int currentWidth) {
481
        if (checkDisposed()) {
482
            return;
483
        }
484
        this.currentWidth = currentWidth;
485
    }
486
487
    /**
488
     * Sets the minimum number of tool items to show in the cool item. If this
489
     * number is less than the total tool items, a chevron will appear and the
490
     * hidden tool items appear in a drop down menu. By default, all the tool
491
     * items are shown in the cool item.
492
     * 
493
     * @param minimumItemsToShow
494
     *            the minimum number of tool items to show.
495
     * @see #getMinimumItemsToShow()
496
     * @see #setUseChevron(boolean)
497
     */
498
    public void setMinimumItemsToShow(int minimumItemsToShow) {
499
        if (checkDisposed()) {
500
            return;
501
        }
502
        this.minimumItemsToShow = minimumItemsToShow;
503
    }
504
505
    /**
506
     * Enables or disables chevron support for the cool item. By default,
507
     * chevron support is enabled.
508
     * 
509
     * @param value
510
     *            <code>true</code> to enable chevron support, <code>false</code>
511
     *            otherwise.
512
     */
513
    public void setUseChevron(boolean value) {
514
        if (checkDisposed()) {
515
            return;
516
        }
517
        useChevron = value;
518
    }
519
520
    /*
521
     * (non-Javadoc)
522
     * 
523
     * @see org.eclipse.jface.action.IContributionItem#update(java.lang.String)
524
     */
525
    public void update(String propertyName) {
526
        if (checkDisposed()) {
527
            return;
528
        }
529
        if (coolItem != null) {
530
            IToolBarManager manager = getToolBarManager();
531
            if (manager != null) {
532
                manager.update(true);
533
            }
534
535
            if ((propertyName == null)
536
                    || propertyName.equals(ICoolBarManager.SIZE)) {
537
                updateSize(true);
538
            }
539
        }
540
    }
541
542
    /**
543
     * Updates the cool items' preferred, minimum, and current size. The
544
     * preferred size is calculated based on the tool bar size and extra trim.
545
     * 
546
     * @param changeCurrentSize
547
     *            <code>true</code> if the current size should be changed to
548
     *            the preferred size, <code>false</code> to not change the
549
     *            current size
550
     */
551
    private void updateSize(boolean changeCurrentSize) {
552
        if (checkDisposed()) {
553
            return;
554
        }
555
        // cannot set size if coolItem is null
556
        if (coolItem == null || coolItem.isDisposed()) {
557
            return;
558
        }
559
        boolean locked = false;
560
        SCoolBar coolBar = (SCoolBar)coolItem.getParent();
561
        try {
562
            // Fix odd behaviour with locked tool bars
563
            if (coolBar != null) {
564
                if (coolBar.getLocked()) {
565
                    coolBar.setLocked(false);
566
                    locked = true;
567
                }
568
            }
569
            SToolBar toolBar = (SToolBar) coolItem.getControl();
570
            if ((toolBar == null) || (toolBar.isDisposed())
571
                    || (toolBar.getItemCount() <= 0)) {
572
                // if the toolbar does not contain any items then dispose of
573
                // coolItem
574
                coolItem.setData(null);
575
                Control control = coolItem.getControl();
576
                if ((control != null) && !control.isDisposed()) {
577
                    control.dispose();
578
                    coolItem.setControl(null);
579
                }
580
                if (!coolItem.isDisposed()) {
581
                    coolItem.dispose();
582
                }
583
            } else {
584
                // If the toolbar item exists then adjust the size of the cool
585
                // item
586
                Point toolBarSize = toolBar.computeSize(SWT.DEFAULT,
587
                        SWT.DEFAULT);
588
                // Set the preffered size to the size of the toolbar plus trim
589
/* FIXME TFS Why is this needed? For repositioning..???
590
 * 		Oh well. Interferring with the LS build so commenting out.              
591
 * 				Point preferredSize = coolItem.computeSize(toolBarSize.x,
592
                        toolBarSize.y);
593
                coolItem.setPreferredSize(preferredSize);
594
*/                // note setMinimumSize must be called before setSize, see PR
595
                // 15565
596
                // Set minimum size
597
                if (getMinimumItemsToShow() != SHOW_ALL_ITEMS) {
598
                    int toolItemWidth = toolBar.getItems()[0].getWidth();
599
                    int minimumWidth = toolItemWidth * getMinimumItemsToShow();
600
                    coolItem.setMinimumSize(minimumWidth, toolBarSize.y);
601
                } else {
602
                    coolItem.setMinimumSize(toolBarSize.x, toolBarSize.y);
603
                }
604
/* FIXME TFS See the fixme above. 
605
 *                if (changeCurrentSize) {
606
                    // Set current size to preferred size
607
                    coolItem.setSize(preferredSize);
608
                }
609
*/            }
610
        } finally {
611
            // If the cool bar was locked, then set it back to locked
612
            if ((locked) && (coolBar != null)) {
613
                coolBar.setLocked(true);
614
            }
615
        }
616
    }
617
618
    public void fill(SCoolBar coolBar, int index) {
619
        if (checkDisposed()) {
620
            return;
621
        }
622
623
        if (coolItem == null && coolBar != null) {
624
            Control oldToolBar = null;
625
            Control toolBar = null;
626
            if (toolBarManager instanceof ToolBarManager) {
627
                oldToolBar = ((ToolBarManager)toolBarManager).getControl();
628
                toolBar = ((ToolBarManager)toolBarManager).createControl(coolBar);
629
            } else if (toolBarManager instanceof SToolBarManager2) {
630
                oldToolBar = ((SToolBarManager2)toolBarManager).getControl();
631
                toolBar = ((SToolBarManager2)toolBarManager).createControl(coolBar);
632
            }
633
            if ((oldToolBar != null) && (oldToolBar.equals(toolBar))) {
634
                // We are using an old tool bar, so we need to update.
635
                toolBarManager.update(true);
636
            }
637
638
            // Do not create a coolItem if the toolbar is empty
639
            if (toolBar instanceof ToolBar) {
640
                if (((ToolBar)toolBar).getItemCount() < 1)
641
                    return;
642
            } else if (toolBar instanceof SToolBar) {
643
                if (((SToolBar)toolBar).getItemCount() < 1)
644
                    return;
645
            }
646
            int flags = SWT.DROP_DOWN;
647
            if (index >= 0) {
648
                coolItem = new SCoolItem(coolBar, flags, index);
649
            } else {
650
                coolItem = new SCoolItem(coolBar, flags);
651
            }
652
            // sets the back reference
653
            coolItem.setData(this);
654
            // Add the toolbar to the CoolItem widget
655
            coolItem.setControl(toolBar);
656
657
            // Handle Context Menu
658
            // ToolBarManager.createControl can actually return a pre-existing control.
659
            // Only add the listener if the toolbar was newly created (bug 62097).
660
            if (oldToolBar != toolBar) {
661
	            toolBar.addListener(SWT.MenuDetect, new Listener() {
662
	
663
	                public void handleEvent(Event event) {
664
	                    // if the toolbar does not have its own context menu then
665
	                    // handle the event
666
	                    if (toolBarManager instanceof ToolBarManager) {
667
		                    if (((ToolBarManager)toolBarManager).getContextMenuManager() == null) {
668
		                        handleContextMenu(event);
669
		                    }
670
	                    } else if (toolBarManager instanceof SToolBarManager2) {
671
		                    if (((SToolBarManager2)toolBarManager).getContextMenuManager() == null) {
672
		                        handleContextMenu(event);
673
		                    }
674
	                    }
675
	                }
676
	            });
677
            }
678
679
            // Handle for chevron clicking
680
            if (getUseChevron()) {
681
                // Chevron Support
682
                coolItem.addSelectionListener(new SelectionAdapter() {
683
684
                    public void widgetSelected(SelectionEvent event) {
685
                        if (event.detail == SWT.ARROW) {
686
                            handleChevron(event);
687
                        }
688
                    }
689
                });
690
            }
691
692
            // Handle for disposal
693
            coolItem.addDisposeListener(new DisposeListener() {
694
695
                public void widgetDisposed(DisposeEvent event) {
696
                    handleWidgetDispose(event);
697
                }
698
            });
699
700
            // Sets the size of the coolItem
701
            updateSize(true);
702
        }
703
    }
704
705
	public void fill(SToolBar parent, int index) {
706
		// Do nothing
707
	}
708
709
}
(-)src/org/eclipse/ui/examples/presentation/customtoolbar/widgets/HannoverGlobalToolBarSkin.java (+207 lines)
Added Link Here
1
package org.eclipse.ui.examples.presentation.customtoolbar.widgets;
2
3
import org.eclipse.swt.SWT;
4
import org.eclipse.swt.graphics.Color;
5
import org.eclipse.swt.graphics.Font;
6
import org.eclipse.swt.graphics.FontData;
7
import org.eclipse.swt.graphics.GC;
8
import org.eclipse.swt.graphics.Image;
9
import org.eclipse.swt.graphics.Point;
10
import org.eclipse.swt.graphics.Rectangle;
11
import org.eclipse.swt.widgets.Control;
12
import org.eclipse.swt.widgets.Display;
13
14
public class HannoverGlobalToolBarSkin implements Skin {
15
	
16
	// border colors
17
	Color borderTopColor = new Color(null, 255, 255, 255);
18
	Color borderBottomColor = new Color(null, 144, 161, 181);
19
	Color borderColor = new Color(null, 132, 132, 132);
20
	Color borderLeftRightColor = new Color(null, 255, 255, 255);
21
	Color itemBorderColor = new Color(null, 180, 180, 180);
22
	
23
	// background colors
24
	Color shadowColor = new Color(null, 109, 131, 180);
25
	Color backgroundTopColor = new Color(null, 247, 247, 247);
26
	Color backgroundBottomColor = new Color(null, 189, 198, 216);
27
	Color hoverItemBackgroundColor = new Color(null, 224, 233, 237);
28
	Color pressedItemBackgroundColor = new Color(null, 231, 231, 231);
29
	
30
	// arrows and text colors
31
	Color arrowColor = Display.getCurrent().getSystemColor(SWT.COLOR_BLACK);
32
	Color textColor = new Color(null, 43,73,111);
33
	Color hoverTextColor = new Color(null, 20, 38, 54);
34
	
35
	Color separatorColor = new Color(null, 168, 181, 197);
36
	Font textFont;
37
	
38
	public HannoverGlobalToolBarSkin() {
39
		super();
40
		FontData fd = new FontData("Tahoma", 9, SWT.NORMAL);
41
		textFont = new Font(null, fd);
42
	}
43
44
	/**
45
	 * @deprecated use getRect() instead.
46
	 */
47
	public Rectangle getInsets(int type, int state) {
48
		return null;
49
	}
50
51
	/**
52
	 * @deprecated use getRect() instead.
53
	 */
54
	public Rectangle getMargins(int type, int state) {
55
		return new Rectangle(0,0,0,0);
56
	}
57
58
	public Font getFont(int type, int state) {
59
		return textFont;
60
	}
61
62
	public Point getSize(int type, int state) {
63
		if (type == Skin.TYPE_ITEM_MIN_MAX_HEIGHT) {
64
			return new Point(SWT.DEFAULT, SWT.DEFAULT);
65
		} else if (type == Skin.TYPE_ITEM_MIN_MAX_WIDTHS) {
66
			return new Point(SWT.DEFAULT, SWT.DEFAULT);
67
		} else if (type == Skin.TYPE_DECORATION_ARROW) {
68
			return new Point(5, 3);
69
		} else if (type == Skin.TYPE_DECORATION_SEPARATOR) {
70
			return new Point(3, SWT.DEFAULT);
71
		} else if (type == Skin.TYPE_ITEM_ICON_SIZE) {
72
			return new Point(20, 20);
73
		}
74
		return null;
75
	}
76
77
	public Rectangle getRect(int type, int state) {
78
		if (type == Skin.TYPE_ITEM_AREA_INSETS) {
79
			/*
80
			 * x - leading space before first item.
81
			 * y - space between top of toolbar and top of item
82
			 * width - trailing space after last item
83
			 * height - space between bottom of toolbar and bottom of item.
84
			 */
85
			return new Rectangle(1, 3, 1, 3);
86
		} else if (type == Skin.TYPE_ITEM_AREA_MARGINS) {
87
			/*
88
			 * x - space between items
89
			 * y - undefined
90
			 * width - undefined;
91
			 * height - undefined;
92
			 */
93
			return new Rectangle(5, 0, 0, 0);
94
		} else if (type == Skin.TYPE_ITEM_MARGINS) {
95
			/*
96
			 * x = horizontal space between image and text.
97
			 * y = horizontal space between image or text and hinky.
98
			 * width = undefined 
99
			 * height = undefined 
100
			 */
101
			return new Rectangle(3, 2, 0, 0);
102
		} else if (type == Skin.TYPE_ITEM_INSETS) {
103
			/* 
104
			 * x = left edge of tool item to left edge of image or text
105
			 * y = top edge of tool item to top edge of image or text
106
			 * width = right edge of last internal element and right edge of tool item.
107
			 * height = bottom edge of last internal element and bottom edge of tool item.
108
			 */
109
			return new Rectangle(0, 0, 0, 0);
110
		}
111
		
112
		return new Rectangle(0, 0, 0, 0);
113
	}
114
115
	public void drawBorder(GC gc, Rectangle rect, SWidget widget, int type, int state) {
116
		if (type == Skin.TYPE_BORDER) {
117
			// top edge
118
			gc.setForeground(borderTopColor);
119
			gc.drawLine(rect.x, rect.y, rect.x+rect.width, rect.y);
120
			// bottom edge
121
			gc.setForeground(borderBottomColor);
122
			gc.drawLine(rect.x, rect.y+rect.height-1, rect.x+rect.width, rect.y+rect.height-1);
123
		}
124
		
125
	}
126
127
	public void drawBackground(GC gc, Rectangle rect, SWidget widget, int type, int state) {
128
		if (type == Skin.TYPE_BACKGROUND) {
129
			if (widget instanceof Control) {
130
				gc.setForeground(backgroundTopColor); 
131
				gc.setBackground(backgroundBottomColor); 
132
				gc.fillGradientRectangle(rect.x, rect.y-1, rect.width, rect.height+1, true);
133
			}
134
		}
135
	}
136
137
	public void drawDecoration(GC gc, Rectangle rect, SWidget widget, int type, int state) {
138
		if (type == Skin.TYPE_DECORATION_ARROW) {
139
			int delta = 0;
140
			if ((state & Skin.PRESSED) == Skin.PRESSED) {
141
				delta = 1;
142
			}
143
			gc.setForeground(arrowColor);
144
			gc.drawLine(rect.x + delta, rect.y + delta, rect.x + rect.width -1 + delta, rect.y + delta);
145
			gc.drawLine(rect.x + 1 + delta, rect.y + 1 + delta, rect.x + rect.width -2 + delta, rect.y + 1 + delta);
146
			gc.drawPoint(rect.x + 2 + delta, rect.y + 2 + delta);
147
		} else if (type == Skin.TYPE_DECORATION_SEPARATOR) {
148
			gc.setForeground(separatorColor);
149
			gc.drawLine(rect.x + (rect.width /2), rect.y, rect.x + (rect.width /2), rect.y + rect.height - 1);
150
		}
151
	}
152
153
	public void drawText(GC gc, Rectangle rect, String text, int style, SWidget widget, int type, int state) {
154
		int delta = 0;
155
		if ((state & Skin.PRESSED) == Skin.PRESSED) {
156
			delta = 1;
157
			gc.setForeground(textColor);
158
		} 
159
		else if ((state & Skin.HOVER) == Skin.HOVER) {
160
			gc.setForeground(textColor);
161
		} 
162
		else {
163
			gc.setForeground(textColor);
164
		}
165
		gc.drawText(text, rect.x + delta, rect.y + delta, style);
166
	}
167
168
	public void drawImage(GC gc, Rectangle rect, Image image, SWidget widget, int type, int state) {
169
		Rectangle imageRect = image.getBounds();
170
		gc.drawImage(image, imageRect.x, imageRect.y, imageRect.width, imageRect.height,
171
					 rect.x, rect.y, rect.width, rect.height);
172
	}
173
174
	public void dispose() {
175
		if (borderColor != null && borderColor.isDisposed() == false)
176
			borderColor.dispose();
177
		if (itemBorderColor != null && itemBorderColor.isDisposed() == false)
178
			itemBorderColor.dispose();
179
180
		if (shadowColor != null && shadowColor.isDisposed() == false)
181
			shadowColor.dispose();
182
		if (backgroundTopColor != null && backgroundTopColor.isDisposed() == false)
183
			backgroundTopColor.dispose();
184
		if (backgroundBottomColor != null && backgroundBottomColor.isDisposed() == false)
185
			backgroundBottomColor.dispose();
186
		if (hoverItemBackgroundColor != null && hoverItemBackgroundColor.isDisposed() == false)
187
			hoverItemBackgroundColor.dispose();
188
		if (pressedItemBackgroundColor != null && pressedItemBackgroundColor.isDisposed() == false)
189
			pressedItemBackgroundColor.dispose();
190
		
191
		if (arrowColor != null && arrowColor.isDisposed() == false)
192
			arrowColor.dispose();
193
		if (textColor != null && textColor.isDisposed() == false)
194
			textColor.dispose();
195
		if (hoverTextColor != null && hoverTextColor.isDisposed() == false)
196
			hoverTextColor.dispose();
197
		
198
		if (separatorColor != null) {
199
			separatorColor.dispose();
200
		}
201
		
202
		if (textFont != null) {
203
			textFont.dispose();
204
			textFont = null;
205
		}
206
	}
207
}
(-)src/org/eclipse/ui/examples/presentation/customtoolbar/CustomToolBarPresentation.java (+48 lines)
Added Link Here
1
package org.eclipse.ui.examples.presentation.customtoolbar;
2
3
import org.eclipse.jface.action.ICoolBarManager;
4
import org.eclipse.jface.action.IToolBarManager;
5
import org.eclipse.jface.action.IToolBarManager2;
6
import org.eclipse.swt.widgets.Composite;
7
import org.eclipse.swt.widgets.Control;
8
import org.eclipse.ui.examples.presentation.customtoolbar.widgets.SCoolBarManager;
9
import org.eclipse.ui.examples.presentation.customtoolbar.widgets.SToolBarManager2;
10
import org.eclipse.ui.presentations.ActionBarPresentation;
11
12
/**
13
 * Demonstrates how to customize the tool bars in an RCP application.
14
 *
15
 */
16
class CustomToolBarPresentation extends ActionBarPresentation {
17
			
18
	/* (non-Javadoc)
19
	 * @see org.eclipse.ui.presentations.ToolBarPresentation#createCoolBarManager(int)
20
	 */
21
	public ICoolBarManager createCoolBarManager(int style) {
22
		SCoolBarManager coolBarManager = new SCoolBarManager(style);
23
		return coolBarManager;
24
	}
25
	
26
	/* (non-Javadoc)
27
	 * @see org.eclipse.ui.presentations.ToolBarPresentation#createToolBarManager(int)
28
	 */
29
	public IToolBarManager createToolBarManager(int style) {
30
		SToolBarManager2 toolBarManager = new SToolBarManager2(style);
31
		return toolBarManager;
32
	}
33
34
	/* (non-Javadoc)
35
	 * @see org.eclipse.ui.presentations.ToolBarPresentation#createCoolBarControl(org.eclipse.jface.action.ICoolBarManager, org.eclipse.swt.widgets.Composite)
36
	 */
37
	public Control createCoolBarControl(ICoolBarManager coolBarManager, Composite parent) {
38
		return super.createCoolBarControl(coolBarManager, parent);
39
	}
40
41
	/* (non-Javadoc)
42
	 * @see org.eclipse.ui.presentations.ToolBarPresentation#createToolBarControl(org.eclipse.jface.action.IToolBarManager2, org.eclipse.swt.widgets.Composite)
43
	 */
44
	public Control createToolBarControl(IToolBarManager2 toolBarManager, Composite parent) {
45
		return super.createToolBarControl(toolBarManager, parent);
46
	}
47
		
48
}
(-)src/org/eclipse/ui/examples/presentation/customtoolbar/widgets/SToolBarManager2.java (+411 lines)
Added Link Here
1
/**
2
 * 
3
 */
4
package org.eclipse.ui.examples.presentation.customtoolbar.widgets;
5
6
import java.util.ArrayList;
7
import java.util.Iterator;
8
9
import org.eclipse.jface.action.ActionContributionItem;
10
import org.eclipse.jface.action.ContributionManager;
11
import org.eclipse.jface.action.IAction;
12
import org.eclipse.jface.action.IContributionItem;
13
import org.eclipse.jface.action.IToolBarManager;
14
import org.eclipse.jface.action.MenuManager;
15
import org.eclipse.jface.action.Separator;
16
import org.eclipse.swt.SWT;
17
import org.eclipse.swt.accessibility.ACC;
18
import org.eclipse.swt.accessibility.AccessibleAdapter;
19
import org.eclipse.swt.accessibility.AccessibleEvent;
20
import org.eclipse.swt.accessibility.AccessibleListener;
21
import org.eclipse.swt.widgets.Composite;
22
import org.eclipse.swt.widgets.Control;
23
import org.eclipse.swt.widgets.Menu;
24
import org.eclipse.swt.widgets.ToolBar;
25
import org.eclipse.swt.widgets.ToolItem;
26
27
public class SToolBarManager2 extends ContributionManager implements IToolBarManager {
28
29
	/**
30
	 * The tool bar items style; <code>SWT.NONE</code> by default.
31
	 */
32
	private int itemStyle = SWT.NONE;
33
34
	/**
35
	 * The tool bat control; <code>null</code> before creation and after
36
	 * disposal.
37
	 */
38
	private Control toolBar = null;
39
40
	/**
41
	 * The menu manager to the context menu associated with the toolbar.
42
	 * 
43
	 * @since 3.0
44
	 */
45
	private MenuManager contextMenuManager = null;
46
47
	/**
48
	 * Creates a new tool bar manager with the default SWT button style. Use the
49
	 * <code>createControl</code> method to create the tool bar control.
50
	 */
51
	public SToolBarManager2() {
52
		//Do nothing if there are no parameters
53
	}
54
55
	/**
56
	 * Creates a tool bar manager with the given SWT button style. Use the
57
	 * <code>createControl</code> method to create the tool bar control.
58
	 * 
59
	 * @param style
60
	 *            the tool bar item style
61
	 * @see org.eclipse.swt.widgets.ToolBar for valid style bits
62
	 */
63
	public SToolBarManager2(int style) {
64
		itemStyle = style;
65
	}
66
67
	/**
68
	 * Creates a tool bar manager for an existing tool bar control. This manager
69
	 * becomes responsible for the control, and will dispose of it when the
70
	 * manager is disposed.
71
	 * 
72
	 * @param toolbar
73
	 *            the tool bar control
74
	 */
75
	public SToolBarManager2(ToolBar toolbar) {
76
		this();
77
		this.toolBar = toolbar;
78
	}
79
80
    public void add(IAction action) {
81
        super.add(new SActionContributionItem(action));
82
    }
83
84
    public void add(IContributionItem item) {
85
    	if (item instanceof Separator) {
86
    		Separator separator = (Separator)item;
87
    		String label = separator.getGroupName();
88
    		SActionContributionItem sItem = new SActionContributionItem();
89
    		IAction action = sItem.getAction();
90
    		action.setText(label);
91
    		item = sItem;
92
    	}
93
    	if (item instanceof ActionContributionItem) {
94
    		SActionContributionItem proxyItem = 
95
    			new SActionContributionItem(((ActionContributionItem)item).getAction());
96
    		item = proxyItem;
97
    	}
98
        super.add(item);
99
    }
100
101
	/**
102
	 * Creates and returns this manager's tool bar control. Does not create a
103
	 * new control if one already exists.
104
	 * 
105
	 * @param parent
106
	 *            the parent control
107
	 * @return the tool bar control
108
	 */
109
	public Control createControl(Composite parent) {
110
		if (!toolBarExist() && parent != null) {
111
			toolBar = new SToolBar(parent, itemStyle);
112
			((SToolBar)toolBar).setSkin(new HannoverGlobalToolBarSkin());
113
			toolBar.setMenu(getContextMenuControl());
114
			update(false);
115
			
116
			toolBar.getAccessible().addAccessibleListener(getAccessibleListener());
117
		}
118
		return toolBar;
119
	}
120
121
	/**
122
	 * Get the accessible listener for the tool bar.
123
	 * 
124
	 * @return AccessibleListener
125
	 * 
126
	 * @since 3.1
127
	 */
128
	private AccessibleListener getAccessibleListener() {
129
		return new AccessibleAdapter() {
130
			public void getName(AccessibleEvent e) {
131
				if (e.childID != ACC.CHILDID_SELF) {
132
					SToolItem item = ((SToolBar)toolBar).getItem(e.childID);
133
					if (item != null) {
134
						String toolTip = item.getToolTipText();
135
						if (toolTip != null) {
136
							e.result = toolTip;
137
						}
138
					}
139
				}
140
			}
141
		};
142
143
	}
144
145
	/**
146
	 * Disposes of this tool bar manager and frees all allocated SWT resources.
147
	 * Notifies all contribution items of the dispose. Note that this method
148
	 * does not clean up references between this tool bar manager and its
149
	 * associated contribution items. Use <code>removeAll</code> for that
150
	 * purpose.
151
	 */
152
	public void dispose() {
153
154
		if (toolBarExist()) {
155
			toolBar.dispose();
156
		}
157
		toolBar = null;
158
159
		IContributionItem[] items = getItems();
160
		for (int i = 0; i < items.length; i++) {
161
			items[i].dispose();
162
		}
163
164
		if (getContextMenuManager() != null) {
165
			getContextMenuManager().dispose();
166
			setContextMenuManager(null);
167
		}
168
	}
169
170
	/**
171
	 * Returns the tool bar control for this manager.
172
	 * 
173
	 * @return the tool bar control, or <code>null</code> if none (before
174
	 *         creating or after disposal)
175
	 */
176
	public Control getControl() {
177
		return toolBar;
178
	}
179
180
	/**
181
	 * Re-lays out the tool bar.
182
	 * <p>
183
	 * The default implementation of this framework method re-lays out the
184
	 * parent when the number of items crosses the zero threshold. Subclasses
185
	 * should override this method to implement their own re-layout strategy
186
	 * 
187
	 * @param layoutBar
188
	 *            the tool bar control
189
	 * @param oldCount
190
	 *            the old number of items
191
	 * @param newCount
192
	 *            the new number of items
193
	 */
194
	protected void relayout(SToolBar layoutBar, int oldCount, int newCount) {
195
		if ((oldCount == 0) != (newCount == 0))
196
			layoutBar.getParent().layout();
197
	}
198
199
	/**
200
	 * Returns whether the tool bar control is created and not disposed.
201
	 * 
202
	 * @return <code>true</code> if the control is created and not disposed,
203
	 *         <code>false</code> otherwise
204
	 */
205
	private boolean toolBarExist() {
206
		return toolBar != null && !toolBar.isDisposed();
207
	}
208
209
	/*
210
	 * (non-Javadoc) Method declared on IContributionManager.
211
	 */
212
	public void update(boolean force) {
213
214
		//	long startTime= 0;
215
		//	if (DEBUG) {
216
		//		dumpStatistics();
217
		//		startTime= (new Date()).getTime();
218
		//	}
219
220
		if (isDirty() || force) {
221
222
			if (toolBarExist()) {
223
224
				int oldCount = ((SToolBar)toolBar).getItemCount();
225
226
				// clean contains all active items without double separators
227
				IContributionItem[] items = getItems();
228
				ArrayList clean = new ArrayList(items.length);
229
				IContributionItem separator = null;
230
				//			long cleanStartTime= 0;
231
				//			if (DEBUG) {
232
				//				cleanStartTime= (new Date()).getTime();
233
				//			}
234
				for (int i = 0; i < items.length; ++i) {
235
					IContributionItem ci = items[i];
236
					if (!ci.isVisible())
237
						continue;
238
					if (ci.isSeparator()) {
239
						// delay creation until necessary
240
						// (handles both adjacent separators, and separator at
241
						// end)
242
						separator = ci;
243
					} else {
244
						if (separator != null) {
245
							if (clean.size() > 0) // no separator if first item
246
								clean.add(separator);
247
							separator = null;
248
						}
249
						clean.add(ci);
250
					}
251
				}
252
				//			if (DEBUG) {
253
				//				System.out.println(" Time needed to build clean vector: " +
254
				// ((new Date()).getTime() - cleanStartTime));
255
				//			}
256
257
				// determine obsolete items (removed or non active)
258
				SToolItem[] mi = ((SToolBar)toolBar).getItems();
259
				ArrayList toRemove = new ArrayList(mi.length);
260
				for (int i = 0; i < mi.length; i++) {
261
					Object data = mi[i].getData();
262
					if (data == null
263
							|| !clean.contains(data)
264
							|| (data instanceof IContributionItem && ((IContributionItem) data)
265
									.isDynamic())) {
266
						toRemove.add(mi[i]);
267
					}
268
				}
269
270
				// Turn redraw off if the number of items to be added
271
				// is above a certain threshold, to minimize flicker,
272
				// otherwise the toolbar can be seen to redraw after each item.
273
				// Do this before any modifications are made.
274
				// We assume each contribution item will contribute at least one
275
				// toolbar item.
276
				boolean useRedraw = (clean.size() - (mi.length - toRemove
277
						.size())) >= 3;
278
                try {
279
                    if (useRedraw) {
280
                        toolBar.setRedraw(false);
281
                    }
282
283
                    // remove obsolete items
284
                    for (int i = toRemove.size(); --i >= 0;) {
285
                        ToolItem item = (ToolItem) toRemove.get(i);
286
                        if (!item.isDisposed()) {
287
                            Control ctrl = item.getControl();
288
                            if (ctrl != null) {
289
                                item.setControl(null);
290
                                ctrl.dispose();
291
                            }
292
                            item.dispose();
293
                        }
294
                    }
295
296
                    // add new items
297
                    IContributionItem src, dest;
298
                    mi = ((SToolBar)toolBar).getItems();
299
                    int srcIx = 0;
300
                    int destIx = 0;
301
                    for (Iterator e = clean.iterator(); e.hasNext();) {
302
                        src = (IContributionItem) e.next();
303
304
                        // get corresponding item in SWT widget
305
                        if (srcIx < mi.length)
306
                            dest = (IContributionItem) mi[srcIx].getData();
307
                        else
308
                            dest = null;
309
310
                        if (dest != null && src.equals(dest)) {
311
                            srcIx++;
312
                            destIx++;
313
                            continue;
314
                        }
315
316
                        if (dest != null && dest.isSeparator()
317
                                && src.isSeparator()) {
318
                            mi[srcIx].setData(src);
319
                            srcIx++;
320
                            destIx++;
321
                            continue;
322
                        }
323
324
                        int start = ((SToolBar)toolBar).getItemCount();
325
                       	((ISContributionItem)src).fill(((SToolBar)toolBar), destIx);
326
                        int newItems = ((SToolBar)toolBar).getItemCount() - start;
327
                        for (int i = 0; i < newItems; i++) {
328
                            SToolItem item = ((SToolBar)toolBar).getItem(destIx++);
329
                            item.setData(src);
330
                        }
331
                    }
332
333
                    // remove any old tool items not accounted for
334
                    for (int i = mi.length; --i >= srcIx;) {
335
                        SToolItem item = mi[i];
336
                        if (!item.isDisposed()) {
337
                            Control ctrl = item.getControl();
338
                            if (ctrl != null) {
339
                                item.setControl(null);
340
                                ctrl.dispose();
341
                            }
342
                            item.dispose();
343
                        }
344
                    }
345
346
                    setDirty(false);
347
348
                    // turn redraw back on if we turned it off above
349
                } finally {
350
                    if (useRedraw) {
351
                        toolBar.setRedraw(true);
352
                    }
353
                }
354
355
				int newCount = ((SToolBar)toolBar).getItemCount();
356
				relayout((SToolBar)toolBar, oldCount, newCount);
357
			}
358
359
		}
360
361
		//	if (DEBUG) {
362
		//		System.out.println(" Time needed for update: " + ((new
363
		// Date()).getTime() - startTime));
364
		//		System.out.println();
365
		//	}
366
	}
367
368
	/**
369
	 * Returns the control of the Menu Manager. If the menu manager does not
370
	 * have a control then one is created.
371
	 * 
372
	 * @return menu widget associated with manager
373
	 */
374
	private Menu getContextMenuControl() {
375
		if ((contextMenuManager != null) && (toolBar != null)) {
376
			Menu menuWidget = contextMenuManager.getMenu();
377
			if ((menuWidget == null) || (menuWidget.isDisposed())) {
378
				menuWidget = contextMenuManager.createContextMenu(toolBar);
379
			}
380
			return menuWidget;
381
		}
382
		return null;
383
	}
384
385
	/**
386
	 * Returns the context menu manager for this tool bar manager.
387
	 * 
388
	 * @return the context menu manager, or <code>null</code> if none
389
	 * @since 3.0
390
	 */
391
	public MenuManager getContextMenuManager() {
392
		return contextMenuManager;
393
	}
394
395
	/**
396
	 * Sets the context menu manager for this tool bar manager to the given menu
397
	 * manager. If the tool bar control exists, it also adds the menu control to
398
	 * the tool bar.
399
	 * 
400
	 * @param contextMenuManager
401
	 *            the context menu manager, or <code>null</code> if none
402
	 * @since 3.0
403
	 */
404
	public void setContextMenuManager(MenuManager contextMenuManager) {
405
		this.contextMenuManager = contextMenuManager;
406
		if (toolBar != null) {
407
			toolBar.setMenu(getContextMenuControl());
408
		}
409
	}
410
	
411
}
(-)src/org/eclipse/ui/examples/presentation/customtoolbar/widgets/SActionContributionItem.java (+627 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.ui.examples.presentation.customtoolbar.widgets;
12
13
import org.eclipse.jface.action.Action;
14
import org.eclipse.jface.action.ActionContributionItem;
15
import org.eclipse.jface.action.ExternalActionManager;
16
import org.eclipse.jface.action.IAction;
17
import org.eclipse.jface.action.IContributionManagerOverrides;
18
import org.eclipse.jface.action.IMenuCreator;
19
import org.eclipse.jface.resource.ImageDescriptor;
20
import org.eclipse.jface.resource.JFaceResources;
21
import org.eclipse.jface.resource.LocalResourceManager;
22
import org.eclipse.jface.resource.ResourceManager;
23
import org.eclipse.jface.util.IPropertyChangeListener;
24
import org.eclipse.jface.util.Policy;
25
import org.eclipse.jface.util.PropertyChangeEvent;
26
import org.eclipse.swt.SWT;
27
import org.eclipse.swt.graphics.Point;
28
import org.eclipse.swt.graphics.Rectangle;
29
import org.eclipse.swt.widgets.Composite;
30
import org.eclipse.swt.widgets.CoolBar;
31
import org.eclipse.swt.widgets.Display;
32
import org.eclipse.swt.widgets.Event;
33
import org.eclipse.swt.widgets.Item;
34
import org.eclipse.swt.widgets.Listener;
35
import org.eclipse.swt.widgets.Menu;
36
import org.eclipse.swt.widgets.ToolBar;
37
import org.eclipse.swt.widgets.Widget;
38
39
/**
40
 * A contribution item which delegates to an action.
41
 * <p>
42
 * This class may be instantiated; it is not intended to be subclassed.
43
 * </p>
44
 */
45
public class SActionContributionItem extends ActionContributionItem implements ISContributionItem {
46
47
	ActionContributionItem actionContributionItem = null;
48
49
	private boolean isSeparator;
50
	
51
	/**
52
     * The listener for changes to the text of the action contributed by an
53
     * external source.
54
     */
55
    private final IPropertyChangeListener actionTextListener = new IPropertyChangeListener() {
56
57
        /**
58
         * @see IPropertyChangeListener#propertyChange(PropertyChangeEvent)
59
         */
60
        public void propertyChange(PropertyChangeEvent event) {
61
            update(event.getProperty());
62
        }
63
    };
64
65
    /**
66
     * Remembers all images in use by this contribution item
67
     */
68
    private LocalResourceManager imageManager;
69
70
    private boolean isWidgetSet = false;
71
    
72
    /**
73
     * Listener for SWT tool item widget events.
74
     */
75
    private Listener toolItemListener;
76
    
77
    /**
78
     * The widget created for this item; <code>null</code>
79
     * before creation and after disposal.
80
     */
81
    private Widget widget = null;
82
    
83
    /**
84
     * Listener for action property change notifications.
85
     */
86
    private final IPropertyChangeListener propertyListener = new IPropertyChangeListener() {
87
        public void propertyChange(PropertyChangeEvent event) {
88
            actionPropertyChange(event);
89
        }
90
    };
91
	
92
	public SActionContributionItem() {
93
		this(new ActionContributionItem(new Action() {public void run() {}}));
94
		this.isSeparator = true;
95
	}
96
	
97
    /**
98
     * @param action
99
     */
100
    public SActionContributionItem(IAction action) {
101
		this(new ActionContributionItem(action));
102
	}
103
    
104
    /**
105
     * 
106
     * @param action
107
     */
108
    public SActionContributionItem(ActionContributionItem actionContributionItem) {
109
		super(actionContributionItem.getAction());
110
		this.actionContributionItem = actionContributionItem;
111
    }
112
113
	public boolean isSeparator() {
114
		return isSeparator;
115
	}
116
117
    /**
118
     * Handles a property change event on the action (forwarded by nested listener).
119
     */
120
    private void actionPropertyChange(final PropertyChangeEvent e) {
121
        // This code should be removed. Avoid using free asyncExec
122
123
        if (isVisible() && widget != null) {
124
            Display display = widget.getDisplay();
125
            if (display.getThread() == Thread.currentThread()) {
126
                update(e.getProperty());
127
            } else {
128
                display.asyncExec(new Runnable() {
129
                    public void run() {
130
                        update(e.getProperty());
131
                    }
132
                });
133
            }
134
135
        }
136
    }
137
	
138
    /**
139
     * Dispose any images allocated for this contribution item
140
     */
141
    private void disposeOldImages() {
142
        if (imageManager != null) {
143
            imageManager.dispose();
144
            imageManager = null;
145
        }
146
    }
147
    
148
	/* (non-Javadoc)
149
	 * @see org.eclipse.jface.action.ActionContributionItem#fill(org.eclipse.swt.widgets.Composite)
150
	 */
151
	public void fill(Composite parent) {
152
		isWidgetSet = true;
153
		actionContributionItem.fill(parent);
154
	}
155
156
	/* (non-Javadoc)
157
	 * @see org.eclipse.jface.action.ContributionItem#fill(org.eclipse.swt.widgets.CoolBar, int)
158
	 */
159
	public void fill(CoolBar parent, int index) {
160
		if (widget instanceof SToolItem)
161
			return;
162
		isWidgetSet = true;
163
		actionContributionItem.fill(parent, index);
164
	}
165
	
166
	/* (non-Javadoc)
167
	 * @see org.eclipse.jface.action.ActionContributionItem#fill(org.eclipse.swt.widgets.Menu, int)
168
	 */
169
	public void fill(Menu parent, int index) {
170
		if (widget instanceof SToolItem)
171
			return;
172
		isWidgetSet = true;
173
		actionContributionItem.fill(parent, index);
174
	}
175
176
	/* (non-Javadoc)
177
	 * @see org.eclipse.jface.action.ActionContributionItem#fill(org.eclipse.swt.widgets.ToolBar, int)
178
	 */
179
	public void fill(ToolBar parent, int index) {
180
		if (widget instanceof SToolItem)
181
			return;
182
		isWidgetSet = true;
183
		actionContributionItem.fill(parent, index);
184
	}
185
    
186
	public void fill(SCoolBar parent, int index) {
187
		// do nothing
188
	}
189
190
	public void fill(SToolBar parent, int index) {
191
        if (isWidgetSet == false && widget == null && parent != null) {
192
            int flags = SWT.PUSH;
193
            IAction action = getAction();
194
            if (action != null) {
195
				if (isSeparator) {
196
					flags = SWT.SEPARATOR;
197
				} else {
198
	                int style = action.getStyle();
199
	                if (style == IAction.AS_CHECK_BOX)
200
	                    flags = SWT.CHECK;
201
	                else if (style == IAction.AS_RADIO_BUTTON)
202
	                    flags = SWT.RADIO;
203
	                else if (style == IAction.AS_DROP_DOWN_MENU)
204
	                    flags = SWT.DROP_DOWN;
205
				}
206
            }
207
208
            Item ti = null;
209
            if (index >= 0)
210
                ti = new SToolItem(parent, flags, index);
211
            else
212
                ti = new SToolItem(parent, flags);
213
            ti.setData(this);
214
            ti.addListener(SWT.Selection, getToolItemListener());
215
            ti.addListener(SWT.Dispose, getToolItemListener());
216
217
            widget = ti;
218
219
            update(null);
220
221
            // Attach some extra listeners.
222
            action.addPropertyChangeListener(propertyListener);
223
            if (action != null) {
224
                String commandId = action.getActionDefinitionId();
225
                ExternalActionManager.ICallback callback = ExternalActionManager
226
                        .getInstance().getCallback();
227
228
                if ((callback != null) && (commandId != null)) {
229
                    callback.addPropertyChangeListener(commandId,
230
                            actionTextListener);
231
                }
232
            }
233
        }
234
	}
235
	
236
    private Listener getToolItemListener() {
237
        if (toolItemListener == null) {
238
            toolItemListener = new Listener() {
239
                public void handleEvent(Event event) {
240
                    switch (event.type) {
241
                    case SWT.Dispose:
242
                        handleWidgetDispose(event);
243
                        break;
244
                    case SWT.Selection:
245
                        Widget ew = event.widget;
246
                        if (ew != null) {
247
                            handleWidgetSelection(event, ((SToolItem) ew)
248
                                    .getSelection());
249
                        }
250
                        break;
251
                    }
252
                }
253
            };
254
        }
255
        return toolItemListener;
256
    }
257
    
258
    /**
259
     * Handles a widget dispose event for the widget corresponding to this item.
260
     */
261
    private void handleWidgetDispose(Event e) {
262
        // Check if our widget is the one being disposed.
263
        if (e.widget == widget) {
264
            IAction action = getAction();
265
            // Dispose of the menu creator.
266
            if (action.getStyle() == IAction.AS_DROP_DOWN_MENU) {
267
                IMenuCreator mc = action.getMenuCreator();
268
                if (mc != null) {
269
                    mc.dispose();
270
                }
271
            }
272
273
            // Unhook all of the listeners.
274
            action.removePropertyChangeListener(propertyListener);
275
            if (action != null) {
276
                String commandId = action.getActionDefinitionId();
277
                ExternalActionManager.ICallback callback = ExternalActionManager
278
                        .getInstance().getCallback();
279
280
                if ((callback != null) && (commandId != null)) {
281
                    callback.removePropertyChangeListener(commandId,
282
                            actionTextListener);
283
                }
284
            }
285
286
            // Clear the widget field.
287
            widget = null;
288
            
289
            disposeOldImages();
290
        }
291
    }
292
293
    /**
294
     * Handles a widget selection event.
295
     */
296
    private void handleWidgetSelection(Event e, boolean selection) {
297
298
        Widget item = e.widget;
299
        if (item != null) {
300
            int style = item.getStyle();
301
            IAction action = getAction();
302
303
            if ((style & (SWT.TOGGLE | SWT.CHECK)) != 0) {
304
                if (action.getStyle() == IAction.AS_CHECK_BOX) {
305
                    action.setChecked(selection);
306
                }
307
            } else if ((style & SWT.RADIO) != 0) {
308
                if (action.getStyle() == IAction.AS_RADIO_BUTTON) {
309
                    action.setChecked(selection);
310
                }
311
            } else if ((style & SWT.DROP_DOWN) != 0) {
312
                if (e.detail == 4) { // on drop-down button
313
                    if (action.getStyle() == IAction.AS_DROP_DOWN_MENU) {
314
                        IMenuCreator mc = action.getMenuCreator();
315
                        SToolItem ti = (SToolItem) item;
316
                        // we create the menu as a sub-menu of "dummy" so that we can use
317
                        // it in a cascading menu too.
318
                        // If created on a SWT control we would get an SWT error...
319
                        //Menu dummy= new Menu(ti.getParent());
320
                        //Menu m= mc.getMenu(dummy);
321
                        //dummy.dispose();
322
                        if (mc != null) {
323
                            Menu m = mc.getMenu(ti.getParent());
324
                            if (m != null) {
325
                                // position the menu below the drop down item
326
                                Rectangle b = ti.getBounds();
327
                                Point p = ti.getParent().toDisplay(
328
                                        new Point(b.x, b.y + b.height));
329
                                m.setLocation(p.x, p.y); // waiting for SWT 0.42
330
                                m.setVisible(true);
331
                                return; // we don't fire the action
332
                            }
333
                        }
334
                    }
335
                }
336
            }
337
            // Ensure action is enabled first.
338
            // See 1GAN3M6: ITPUI:WINNT - Any IAction in the workbench can be executed while disabled.
339
            if (action.isEnabled()) {
340
                boolean trace = Policy.TRACE_ACTIONS;
341
342
                long ms = System.currentTimeMillis();
343
                if (trace)
344
                    System.out.println("Running action: " + action.getText()); //$NON-NLS-1$
345
346
                action.runWithEvent(e);
347
348
                if (trace)
349
                    System.out.println((System.currentTimeMillis() - ms)
350
                            + " ms to run action: " + action.getText()); //$NON-NLS-1$
351
            }
352
        }
353
    }
354
    
355
    /**
356
     * Returns whether the given action has any images.
357
     * 
358
     * @param actionToCheck the action
359
     * @return <code>true</code> if the action has any images, <code>false</code> if not
360
     */
361
    private boolean hasImages(IAction actionToCheck) {
362
        return actionToCheck.getImageDescriptor() != null
363
                || actionToCheck.getHoverImageDescriptor() != null
364
                || actionToCheck.getDisabledImageDescriptor() != null;
365
    }
366
    
367
    /**
368
     * Synchronizes the UI with the given property.
369
     *
370
     * @param propertyName the name of the property, or <code>null</code> meaning all applicable
371
     *   properties 
372
     */
373
    public void update(String propertyName) {
374
    	
375
        if (widget instanceof SToolItem) {
376
        	
377
            // determine what to do
378
        	IAction action = getAction();
379
            boolean textChanged = propertyName == null
380
                    || propertyName.equals(IAction.TEXT);
381
            boolean imageChanged = propertyName == null
382
                    || propertyName.equals(IAction.IMAGE);
383
            boolean tooltipTextChanged = propertyName == null
384
                    || propertyName.equals(IAction.TOOL_TIP_TEXT);
385
            boolean enableStateChanged = propertyName == null
386
                    || propertyName.equals(IAction.ENABLED)
387
                    || propertyName
388
                            .equals(IContributionManagerOverrides.P_ENABLED);
389
            boolean checkChanged = (action.getStyle() == IAction.AS_CHECK_BOX || action
390
                    .getStyle() == IAction.AS_RADIO_BUTTON)
391
                    && (propertyName == null || propertyName
392
                            .equals(IAction.CHECKED));
393
394
            if (widget instanceof SToolItem) {
395
                SToolItem ti = (SToolItem) widget;
396
                String text = action.getText();
397
                // the set text is shown only if there is no image or if forced by MODE_FORCE_TEXT
398
                boolean showText = text != null
399
                        && ((getMode() & MODE_FORCE_TEXT) != 0 || !hasImages(action));
400
401
                // only do the trimming if the text will be used
402
                if (showText && text != null) {
403
                    text = Action.removeAcceleratorText(text);
404
                    text = Action.removeMnemonics(text);
405
                }
406
407
                if (textChanged) {
408
                    String textToSet = showText ? text : ""; //$NON-NLS-1$
409
                    boolean rightStyle = (ti.getParent().getStyle() & SWT.RIGHT) != 0;
410
                    if (rightStyle || !ti.getText().equals(textToSet)) {
411
                        // In addition to being required to update the text if it
412
                        // gets nulled out in the action, this is also a workaround 
413
                        // for bug 50151: Using SWT.RIGHT on a ToolBar leaves blank space
414
                        ti.setText(textToSet);
415
                    }
416
                }
417
418
                if (imageChanged) {
419
                    // only substitute a missing image if it has no text
420
                    updateImages(!showText);
421
                }
422
423
                if (tooltipTextChanged || textChanged) {
424
                    String toolTip = action.getToolTipText();
425
                    // if the text is showing, then only set the tooltip if different
426
                    if (!showText || toolTip != null && !toolTip.equals(text)) {
427
                        ti.setToolTipText(toolTip);
428
                    } else {
429
                        ti.setToolTipText(null);
430
                    }
431
                }
432
433
/* FIXME TFS -- Need to keep the buttons enabled for now so they actually look like they work.
434
 * 			[Terry Smith 12/9/2005].
435
 *                 if (enableStateChanged) {
436
                    boolean shouldBeEnabled = action.isEnabled()
437
                            && isEnabledAllowed();
438
439
                    if (ti.getEnabled() != shouldBeEnabled)
440
                       ti.setEnabled(shouldBeEnabled);
441
                }
442
*/
443
                if (checkChanged) {
444
                    boolean bv = action.isChecked();
445
446
                    if (ti.getSelection() != bv)
447
                        ti.setSelection(bv);
448
                }
449
                return;
450
            }
451
        } else {
452
       		actionContributionItem.update(propertyName);
453
        }
454
    }
455
456
    /**
457
     * Updates the images for this action.
458
     *
459
     * @param forceImage <code>true</code> if some form of image is compulsory,
460
     *  and <code>false</code> if it is acceptable for this item to have no image
461
     * @return <code>true</code> if there are images for this action, <code>false</code> if not
462
     */
463
    private boolean updateImages(boolean forceImage) {
464
465
        ResourceManager parentResourceManager = JFaceResources.getResources();
466
        
467
        if (widget instanceof SToolItem) {
468
        	IAction action = getAction();
469
            if (getUseColorIconsInToolbars()) {
470
                ImageDescriptor imageDesc = action.getImageDescriptor();
471
                ImageDescriptor hoverImageDesc = action.getHoverImageDescriptor();
472
                ImageDescriptor disabledImageDesc = action.getDisabledImageDescriptor();
473
                ImageDescriptor pressedImageDesc = null;
474
                                
475
                if (imageDesc == null && forceImage) {
476
                    imageDesc = ImageDescriptor.getMissingImageDescriptor();
477
                }
478
                
479
//                if (disabledImageDesc == null && imageDesc != null) {
480
//               	disabledImageDesc = ImageDescriptor.createWithFlags(imageDesc, SWT.IMAGE_GRAY); 
481
//                }
482
483
                LocalResourceManager localManager = new LocalResourceManager(parentResourceManager);
484
                
485
                // performance: more efficient in SWT to set disabled and hot image before regular image
486
                ((SToolItem) widget).setDisabledImage(disabledImageDesc != null ? localManager.createImageWithDefault(disabledImageDesc) : null);
487
                ((SToolItem) widget).setHotImage(hoverImageDesc != null ? localManager.createImageWithDefault(hoverImageDesc) : null);
488
                ((SToolItem) widget).setImage(imageDesc != null ? localManager.createImageWithDefault(imageDesc) : null);
489
                disposeOldImages();
490
                imageManager = localManager;
491
492
                return imageDesc != null;
493
/* TODO TFS Old Crap             	
494
                ImageDescriptor image = action.getHoverImageDescriptor();
495
                if (image == null) {
496
                    image = action.getImageDescriptor();
497
                }
498
                ImageDescriptor disabledImage = action.getDisabledImageDescriptor();
499
500
                // Make sure there is a valid image.
501
                if (image == null && forceImage) {
502
                    image = ImageDescriptor.getMissingImageDescriptor();
503
                }
504
        
505
                LocalResourceManager localManager = new LocalResourceManager(parentResourceManager);
506
                
507
                // performance: more efficient in SWT to set disabled and hot image before regular image
508
                ((SToolItem) widget).setDisabledImage(disabledImage == null ? null : localManager.createImageWithDefault(disabledImage));
509
                ((SToolItem) widget).setImage(image == null ? null : localManager.createImageWithDefault(image));
510
511
                disposeOldImages();
512
                imageManager = localManager;
513
                
514
                return image != null;
515
*/
516
            }
517
            ImageDescriptor image = action.getImageDescriptor();
518
            ImageDescriptor hoverImage = action
519
                    .getHoverImageDescriptor();
520
            ImageDescriptor disabledImage = action
521
                    .getDisabledImageDescriptor();
522
523
            // If there is no regular image, but there is a hover image,
524
            // convert the hover image to gray and use it as the regular image.
525
            if (image == null && hoverImage != null) {
526
                image = ImageDescriptor.createWithFlags(action.getHoverImageDescriptor(), SWT.IMAGE_GRAY); 
527
            } else {
528
                // If there is no hover image, use the regular image as the hover image,
529
                // and convert the regular image to gray
530
                if (hoverImage == null && image != null) {
531
                    hoverImage = image;
532
                    image = ImageDescriptor.createWithFlags(action.getImageDescriptor(), SWT.IMAGE_GRAY);
533
                }
534
            }
535
536
            // Make sure there is a valid image.
537
            if (hoverImage == null && image == null && forceImage) {
538
                image = ImageDescriptor.getMissingImageDescriptor();
539
            }
540
541
            // Create a local resource manager to remember the images we've allocated for this tool item
542
            LocalResourceManager localManager = new LocalResourceManager(parentResourceManager);
543
            
544
            // performance: more efficient in SWT to set disabled and hot image before regular image
545
            ((SToolItem) widget).setDisabledImage(disabledImage == null? null : localManager.createImageWithDefault(disabledImage));
546
            ((SToolItem) widget).setHotImage(hoverImage == null? null : localManager.createImageWithDefault(hoverImage));
547
            ((SToolItem) widget).setImage(image == null? null : localManager.createImageWithDefault(image));
548
549
            // Now that we're no longer referencing the old images, clear them out.
550
            disposeOldImages();
551
            imageManager = localManager;
552
            
553
            return image != null;
554
        }
555
        return false;
556
    }
557
558
	/* (non-Javadoc)
559
	 * @see org.eclipse.jface.action.ActionContributionItem#equals(java.lang.Object)
560
	 */
561
	public boolean equals(Object o) {
562
		
563
        if (!(o instanceof ActionContributionItem)) {
564
            return false;
565
        }
566
        return actionContributionItem.getAction().equals(((ActionContributionItem) o).getAction());
567
	}
568
569
	/* (non-Javadoc)
570
	 * @see org.eclipse.jface.action.ActionContributionItem#getAction()
571
	 */
572
	public IAction getAction() {
573
		return actionContributionItem.getAction();
574
	}
575
576
	/* (non-Javadoc)
577
	 * @see org.eclipse.jface.action.ActionContributionItem#getMode()
578
	 */
579
	public int getMode() {
580
		return actionContributionItem.getMode();
581
	}
582
583
	/* (non-Javadoc)
584
	 * @see org.eclipse.jface.action.ActionContributionItem#hashCode()
585
	 */
586
	public int hashCode() {
587
		return actionContributionItem.hashCode();
588
	}
589
590
	/* (non-Javadoc)
591
	 * @see org.eclipse.jface.action.ActionContributionItem#isDynamic()
592
	 */
593
	public boolean isDynamic() {
594
		return actionContributionItem.isDynamic();
595
	}
596
597
	/* (non-Javadoc)
598
	 * @see org.eclipse.jface.action.ActionContributionItem#isEnabled()
599
	 */
600
	public boolean isEnabled() {
601
		return actionContributionItem.isEnabled();
602
	}
603
604
	/* (non-Javadoc)
605
	 * @see org.eclipse.jface.action.ActionContributionItem#isEnabledAllowed()
606
	 */
607
	protected boolean isEnabledAllowed() {
608
        if (actionContributionItem.getParent() == null)
609
            return true;
610
        Boolean value = actionContributionItem.getParent().getOverrides().getEnabled(this);
611
        return (value == null) ? true : value.booleanValue();
612
	}
613
614
	/* (non-Javadoc)
615
	 * @see org.eclipse.jface.action.ActionContributionItem#isVisible()
616
	 */
617
	public boolean isVisible() {
618
		return actionContributionItem.isVisible();
619
	}
620
621
	/* (non-Javadoc)
622
	 * @see org.eclipse.jface.action.ActionContributionItem#setMode(int)
623
	 */
624
	public void setMode(int mode) {
625
		actionContributionItem.setMode(mode);
626
	}
627
}
(-)src/org/eclipse/ui/examples/presentation/customtoolbar/widgets/ISContributionItem.java (+8 lines)
Added Link Here
1
package org.eclipse.ui.examples.presentation.customtoolbar.widgets;
2
3
import org.eclipse.jface.action.IContributionItem;
4
5
public interface ISContributionItem extends IContributionItem {
6
	public void fill(SCoolBar parent, int index);
7
	public void fill(SToolBar parent, int index);
8
}
(-)src/org/eclipse/ui/examples/presentation/customtoolbar/widgets/SCoolItem.java (+322 lines)
Added Link Here
1
package org.eclipse.ui.examples.presentation.customtoolbar.widgets;
2
3
import org.eclipse.swt.SWT;
4
import org.eclipse.swt.events.SelectionAdapter;
5
import org.eclipse.swt.graphics.GC;
6
import org.eclipse.swt.graphics.Image;
7
import org.eclipse.swt.graphics.Point;
8
import org.eclipse.swt.graphics.Rectangle;
9
import org.eclipse.swt.widgets.Control;
10
import org.eclipse.swt.widgets.Item;
11
12
public class SCoolItem extends Item {
13
	Control control;
14
	int preferredHeight = -1;
15
	int preferredWidth = -1;
16
	int width = -1;
17
	int height = -1;
18
	//int hIndent = 8;
19
	int hIndent = 0;
20
	//int vIndent = 8;
21
	int vIndent = 0;
22
	Rectangle itemBounds = new Rectangle(0, 0, 0, 0);
23
	boolean wrap = false;  // true if the item should be moved onto the next row.
24
	boolean alignment = false;  // true if the item and (the items following the items) should be right-aligned. 
25
	Image arrowImage = null;
26
	private SCoolBar parent = null;
27
	
28
	public SCoolItem(SCoolBar parent, int style) {
29
		this(parent, style, parent.getItemCount());
30
	}
31
32
	public SCoolItem(SCoolBar parent, int style, int index) {
33
		super(parent, style);
34
		this.parent = parent;
35
		parent.createItem (this, index);
36
	}
37
38
	public void addSelectionListener(SelectionAdapter adapter) {
39
		// TODO Auto-generated method stub
40
	}
41
42
	public Point computeSize(int wHint, int hHint) {
43
		return computeSize(wHint, hHint, true);
44
	}
45
	
46
	public Point computeSize(int wHint, int hHint, boolean changed) {
47
		checkWidget();
48
49
		Skin skin = parent.getSkin();
50
		int width = wHint;
51
		int height = hHint;
52
		
53
		if (control != null && (width == SWT.DEFAULT || height == SWT.DEFAULT)) {
54
			Point size = control.computeSize(width, height);
55
			if (width == SWT.DEFAULT) {
56
				width = size.x;
57
			}
58
			if (height == SWT.DEFAULT) {
59
				height = size.y;
60
			}
61
			
62
			size = null;
63
			if (skin != null) {
64
				size = skin.getSize(Skin.TYPE_DECORATION_GRIPPER, Skin.NORMAL);
65
			} 
66
			if (size == null) {
67
				size = new Point(0, 0);
68
			}
69
			if ((parent.getStyle() & SWT.VERTICAL) == SWT.VERTICAL) {
70
				height += size.x;
71
				if (size.y != SWT.DEFAULT) {
72
					width = Math.max(width, size.y);
73
				}
74
			} else {
75
				width += size.x;
76
				if (size.y != SWT.DEFAULT) {
77
					height = Math.max(height, size.y);
78
				}
79
			}
80
		} else {
81
			Point minMax = null;
82
			if (skin != null) {
83
				minMax = skin.getSize(Skin.TYPE_ITEM_MIN_MAX_HEIGHT, Skin.NORMAL);
84
			} 
85
			if (minMax == null) {
86
				minMax = new Point(SWT.DEFAULT, SWT.DEFAULT);
87
			}
88
			
89
			if (height == SWT.DEFAULT) {
90
				if (minMax.x != SWT.DEFAULT) {
91
					height = minMax.x;
92
				} else {
93
					height = 0;
94
				}
95
			}
96
97
			minMax = null;
98
			if (skin != null) {
99
				minMax = skin.getSize(Skin.TYPE_ITEM_MIN_MAX_HEIGHT, Skin.NORMAL);
100
			} 
101
			if (minMax == null) {
102
				minMax = new Point(SWT.DEFAULT, SWT.DEFAULT);
103
			}
104
			if (width == SWT.DEFAULT) {
105
				if (minMax.x != SWT.DEFAULT) {
106
					width = minMax.x;
107
				} else {
108
					width = 0;
109
				}
110
			}
111
		}
112
113
		Rectangle borders = null;
114
		if (skin != null) {
115
			borders = skin.getRect(Skin.TYPE_ITEM_BORDER, Skin.NORMAL);
116
		} 
117
		if (borders == null) {
118
			borders = new Rectangle(0, 0, 0, 0);
119
		}
120
		
121
		width += borders.x + borders.width;
122
		height += borders.y + borders.height;
123
		
124
		return new Point(width, height);
125
	}
126
127
	public Rectangle getBounds() {
128
		return itemBounds;
129
	}
130
	
131
	public Control getControl() {
132
		return control;
133
	}
134
135
	public Control getParent() {
136
		return this.parent;
137
	}
138
	
139
	public Point getPreferredSize() {
140
		checkWidget();
141
		int width = preferredWidth;
142
		int height = preferredHeight;
143
		if (control != null && (width == SWT.DEFAULT || height == SWT.DEFAULT)) {
144
			Point size = control.computeSize(width, height);
145
			if (width == SWT.DEFAULT) {
146
				width = size.x;
147
			}
148
			if (height == SWT.DEFAULT) {
149
				height = size.y;
150
			}
151
			
152
			Skin skin = parent.getSkin();
153
			size = null;
154
			if (skin != null) {
155
				size = skin.getSize(Skin.TYPE_DECORATION_GRIPPER, Skin.NORMAL);
156
			} 
157
			if (size == null) {
158
				size = new Point(0, 0);
159
			}
160
			if ((parent.getStyle() & SWT.VERTICAL) == SWT.VERTICAL) {
161
				height += size.x;
162
				if (size.y != SWT.DEFAULT) {
163
					width = Math.max(width, size.y);
164
				}
165
			} else {
166
				width += size.x;
167
				if (size.y != SWT.DEFAULT) {
168
					height = Math.max(height, size.y);
169
				}
170
			}
171
172
			Rectangle borders = null;
173
			if (skin != null) {
174
				borders = skin.getRect(Skin.TYPE_ITEM_BORDER, Skin.NORMAL);
175
			} 
176
			if (borders == null) {
177
				borders = new Rectangle(0, 0, 0, 0);
178
			}
179
			
180
			width += borders.x + borders.width;
181
			height += borders.y + borders.height;
182
		}
183
		
184
		return new Point(width, height);
185
	}
186
187
	public Point getSize() {
188
		checkWidget();
189
		if (itemBounds == null)
190
			itemBounds = new Rectangle(0,0,0,0);
191
		return new Point(itemBounds.width, itemBounds.height);
192
	}
193
	
194
	public void setBounds(int x, int y, int width, int height) {
195
		itemBounds.x = x;
196
		itemBounds.y = y;
197
		itemBounds.width = width;
198
		itemBounds.height = height;
199
200
		if (control != null) {
201
			Skin skin = parent.getSkin();
202
			Point size = null;
203
			if (skin != null) {
204
				size = skin.getSize(Skin.TYPE_DECORATION_GRIPPER, Skin.NORMAL);
205
			} 
206
			if (size == null) {
207
				size = new Point(0, 0);
208
			}
209
210
			if (width > size.x) {
211
				width -= size.x;
212
			} else {
213
				width = size.x;
214
			}
215
216
			Rectangle borders = null;
217
			if (skin != null) {
218
				borders = skin.getRect(Skin.TYPE_ITEM_BORDER, Skin.NORMAL);
219
			} 
220
			if (borders == null) {
221
				borders = new Rectangle(0, 0, 0, 0);
222
			}
223
			
224
			width -= (borders.x + borders.width);
225
			height -= (borders.y + borders.height);
226
227
			Rectangle controlRect = new Rectangle(itemBounds.x + size.x, y, width - size.x, height);
228
			control.setBounds(controlRect);
229
		}
230
	}
231
232
	public void setControl(Control control) {
233
		if (control != null) {
234
			if (control.isDisposed()) 
235
				SWT.error (SWT.ERROR_INVALID_ARGUMENT);
236
			if (control.getParent() != parent) 
237
				SWT.error (SWT.ERROR_INVALID_PARENT);
238
		}
239
		this.control = control;
240
		
241
		parent.layout();
242
	}
243
	
244
	public void setMinimumSize(int width, int height) {
245
		// TODO Auto-generated method stub
246
	}
247
	
248
	public void setPreferredSize(Point preferredSize) {
249
		setPreferredSize(preferredSize.x, preferredSize.y);
250
	}
251
252
	public void setPreferredSize (int width, int height) {
253
		preferredWidth = width;
254
		preferredHeight = height;
255
	}
256
257
	public void setSize(int width, int height) {
258
		checkWidget();
259
		itemBounds.width = width;
260
		itemBounds.height = height;
261
		
262
		if (preferredWidth == -1)
263
			preferredWidth = width;
264
		if (preferredHeight == -1)
265
			preferredHeight = height;
266
		
267
//		if (control != null) {
268
//			control.setSize(width - SCoolBar.GRIPPER_AREA_WIDTH, height);
269
//		}
270
//	TFS - parent.layout()?
271
	}
272
	
273
	public void setSize(Point pt) {
274
		checkWidget();
275
		if (pt == null) {
276
			SWT.error (SWT.ERROR_NULL_ARGUMENT);
277
		}
278
		setSize(pt.x, pt.y);
279
	}
280
281
	public void paint(GC gc, int state) {
282
		Skin skin = parent.getSkin();
283
284
		if (skin == null) {
285
			return;
286
		}
287
288
		skin.drawBackground(gc, itemBounds, parent, Skin.TYPE_ITEM_BACKGROUND, state);
289
		skin.drawBorder(gc, itemBounds, parent, Skin.TYPE_ITEM_BORDER, state);
290
291
		Point size = skin.getSize(Skin.TYPE_DECORATION_GRIPPER, state);
292
		if (size == null) {
293
			return;
294
		}
295
296
		if ((parent.getStyle() & SWT.VERTICAL) == SWT.VERTICAL) {
297
			if (size.y == SWT.DEFAULT) {
298
				size.y = 0;
299
			}
300
			if (size.x == SWT.DEFAULT) {
301
				size.x = itemBounds.width;
302
			}
303
			
304
		} else {
305
			if (size.x == SWT.DEFAULT) {
306
				size.x = 0;
307
			}
308
			if (size.y == SWT.DEFAULT) {
309
				size.y = itemBounds.height;
310
			}
311
		}
312
		
313
		if (size.x == 0 || size.y == 0) {
314
			return;
315
		}
316
		
317
		Rectangle gripperRect = new Rectangle(itemBounds.x, itemBounds.y, size.x, size.y);
318
		skin.drawDecoration(gc, gripperRect, parent, Skin.TYPE_DECORATION_GRIPPER, state);
319
320
	}
321
322
}
(-)src/org/eclipse/ui/examples/presentation/customtoolbar/CustomToolBarPresentationFactory.java (+13 lines)
Added Link Here
1
package org.eclipse.ui.examples.presentation.customtoolbar;
2
3
import org.eclipse.ui.IWorkbenchWindow;
4
import org.eclipse.ui.presentations.ActionBarPresentation;
5
import org.eclipse.ui.presentations.WorkbenchPresentationFactory;
6
7
public class CustomToolBarPresentationFactory extends WorkbenchPresentationFactory {
8
9
	public ActionBarPresentation createToolBarPresentation(IWorkbenchWindow window) {
10
		return new CustomToolBarPresentation();
11
	}
12
	
13
}

Return to bug 123257