43
43
* @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a>
44
44
* @noextend This class is not intended to be subclassed by clients.
45
45
*/
46
- public class Group extends Composite implements ICustomWidget {
46
+ public class Group extends Composite {
47
47
private String text = "" ;
48
- static final int CLIENT_INSET = 3 ;
48
+ private static final int CLIENT_INSET = 3 ;
49
49
private Listener listener ;
50
- private boolean enabled = true ;
51
50
private int orientation = SWT .LEFT_TO_RIGHT ;
52
- private static int DRAW_FLAGS = SWT .DRAW_MNEMONIC | SWT .DRAW_TAB | SWT .DRAW_TRANSPARENT | SWT .DRAW_DELIMITER ;
51
+ private static final int DRAW_FLAGS = SWT .DRAW_MNEMONIC | SWT .DRAW_TAB | SWT .DRAW_TRANSPARENT | SWT .DRAW_DELIMITER ;
52
+ private Point textExtent = new Point (0 , 0 );
53
53
54
54
/**
55
55
* Constructs a new instance of this class given its parent
@@ -97,48 +97,51 @@ public Group (Composite parent, int style) {
97
97
}
98
98
99
99
private void onPaint (Event event ) {
100
- if (isVisible ()) {
101
- Drawing .drawWithGC (this , event .gc , this ::doPaint );
102
- }
100
+ Drawing .drawWithGC (this , event .gc , this ::drawGroup );
103
101
}
104
102
105
- private void doPaint (GC gc ) {
106
- Rectangle bounds = getBounds ();
107
- if (bounds .width > 0 && bounds .height > 0 ) {
108
- drawGroup (gc , bounds .width , bounds .height );
109
- }
110
- }
103
+ private void drawGroup (GC gc ) {
111
104
112
- private void drawGroup (GC gc , int width , int height ) {
113
- int titleWidth = gc .textExtent (text ).x ;
114
- int titleHeight = gc .textExtent (text ).y ;
105
+ int width = getBounds ().width ;
106
+ int height = getBounds ().height ;
107
+ int titleWidth = textExtent .x ;
108
+ int titleHeight = textExtent .y ;
115
109
116
- int inset = 2 , groupInset = 8 , borderRadius = 6 ;
117
- int textX = inset + groupInset , textY = titleHeight ;
118
- int newWidth = width - (inset * 2 ), newHeight = height - (inset * 5 );
110
+ int inset = 2 ;
111
+ int groupInset = 8 ;
112
+ int borderRadius = 6 ;
113
+ int textX = inset + groupInset ;
114
+ int textY = titleHeight ;
115
+ int newWidth = width - (inset * 2 );
116
+ int newHeight = height - (inset * 5 );
119
117
120
118
// Set shadow color
121
119
gc .setForeground (getShadowColor ());
122
120
123
121
// Draw group border
124
122
gc .drawRoundRectangle (inset , textY / 2 , newWidth , newHeight , borderRadius , borderRadius );
125
123
126
- // Draw text background and text
124
+ // Draw text background (A fillRectangle to erase the part of the group border
125
+ // where text is drawn) and text
127
126
int textPosX = (orientation == SWT .RIGHT_TO_LEFT ) ? newWidth - groupInset - titleWidth : textX ;
128
127
gc .fillRectangle (textPosX , textY / 2 , titleWidth , gc .getLineWidth () + 1 );
129
128
gc .setForeground (getForeground ());
130
- gc .drawText (text , textPosX , 0 );
129
+ gc .drawText (text , textPosX , 0 , DRAW_FLAGS );
131
130
}
132
131
133
132
private Color getShadowColor () {
134
- if ((style & SWT .SHADOW_ETCHED_IN ) != 0 )
133
+ if ((style & SWT .SHADOW_ETCHED_IN ) != 0 ) {
135
134
return new Color (136 , 136 , 136 );
136
- if ((style & SWT .SHADOW_ETCHED_OUT ) != 0 )
135
+ }
136
+ if ((style & SWT .SHADOW_ETCHED_OUT ) != 0 ) {
137
137
return new Color (68 , 68 , 68 );
138
- if ((style & SWT .SHADOW_IN ) != 0 )
138
+ }
139
+ if ((style & SWT .SHADOW_IN ) != 0 ) {
139
140
return new Color (102 , 102 , 102 );
140
- if ((style & SWT .SHADOW_OUT ) != 0 )
141
+ }
142
+ if ((style & SWT .SHADOW_OUT ) != 0 ) {
141
143
return new Color (187 , 187 , 187 );
144
+ }
142
145
return getForeground ();
143
146
}
144
147
@@ -153,6 +156,9 @@ static int checkStyle (int style) {
153
156
style |= SWT .LEFT_TO_RIGHT ;
154
157
style &= ~SWT .RIGHT_TO_LEFT ;
155
158
}
159
+ if ((style & SWT .BORDER ) != 0 ) {
160
+ style |= SWT .SHADOW_IN ;
161
+ }
156
162
/*
157
163
* Even though it is legal to create this widget
158
164
* with scroll bars, they serve no useful purpose
@@ -169,32 +175,24 @@ protected void checkSubclass () {
169
175
}
170
176
171
177
@ Override
172
- public Point computeSizeInPixels (int wHint , int hHint , boolean changed ) {
178
+ public Point computeSize (int wHint , int hHint , boolean changed ) {
173
179
checkWidget ();
174
-
175
- Point size = DPIUtil .autoScaleUp (super .computeSizeInPixels (wHint , hHint , changed ));
180
+ Point size = DPIUtil .autoScaleUp (super .computeSize (wHint , hHint , changed ));
176
181
177
182
if (!changed && new Point (wHint , hHint ).equals (size )) {
178
183
return size ;
179
184
}
180
-
181
185
if (text == null || text .isEmpty ()) {
182
186
return size ;
183
187
}
184
-
185
- Point textExtent = Drawing .executeOnGC (this , gc -> {
186
- gc .setFont (getFont ());
187
- return gc .textExtent (text , DRAW_FLAGS );
188
- });
189
-
190
- Point layoutSize = (getLayout () != null ) ? getLayout ().computeSize (this , wHint , hHint , changed )
188
+ Layout layout = getLayout ();
189
+ Point layoutSize = (layout != null ) ? layout .computeSize (this , wHint , hHint , changed )
191
190
: computeChildrenSize (changed );
192
191
193
192
int width = Math .max (10 , Math .max (layoutSize .x + CLIENT_INSET * 2 , textExtent .x + CLIENT_INSET * 6 ));
194
193
int height = Math .max (10 , Math .max (layoutSize .y + CLIENT_INSET * 4 , textExtent .y + CLIENT_INSET * 4 ));
195
194
196
195
size = DPIUtil .autoScaleUp (new Point (wHint != SWT .DEFAULT ? wHint : width , hHint != SWT .DEFAULT ? hHint : height ));
197
-
198
196
return size ;
199
197
}
200
198
@@ -208,21 +206,14 @@ private Point computeChildrenSize(boolean changed) {
208
206
return size ;
209
207
}
210
208
211
-
212
209
@ Override
213
- public Rectangle computeTrimInPixels (int x , int y , int width , int height ) {
210
+ public Rectangle computeTrim (int x , int y , int width , int height ) {
214
211
checkWidget ();
215
- Rectangle trim = super .computeTrimInPixels (x , y , width , height );
212
+ Rectangle trim = super .computeTrim (x , y , width , height );
216
213
trim .width = width + CLIENT_INSET * 2 ;
217
214
trim .height = height + CLIENT_INSET * 2 ;
218
215
219
- int textHeight = Drawing .executeOnGC (this , gc -> {
220
- gc .setFont (getFont ());
221
- return gc .textExtent (text , DRAW_FLAGS ).y ;
222
- });
223
-
224
- trim .height += textHeight + CLIENT_INSET * 2 ;
225
-
216
+ trim .height += textExtent .y + CLIENT_INSET * 2 ;
226
217
return DPIUtil .autoScaleUp (trim );
227
218
}
228
219
@@ -235,32 +226,29 @@ public void setEnabled(boolean enabled) {
235
226
236
227
@ Override
237
228
void enableWidget (boolean enabled ) {
238
- this . enabled = enabled ;
239
- for ( Control child : getChildren ()) {
240
- child . setEnabled ( enabled );
241
- }
242
- if ( text != null && ! text . isEmpty () ) {
243
- redraw ();
244
- }
229
+ super . enableWidget ( enabled ) ;
230
+ }
231
+
232
+ @ Override
233
+ public boolean isEnabled ( ) {
234
+ checkWidget ();
235
+ return getEnabled () && parent . isEnabled ();
245
236
}
246
237
247
238
@ Override
248
- Rectangle getClientAreaInPixels () {
239
+ public Rectangle getClientArea () {
249
240
checkWidget ();
250
- Rectangle rect = super .getClientAreaInPixels ();
241
+ Rectangle rect = super .getClientArea ();
251
242
if (rect .isEmpty ())
252
243
return rect ;
253
244
254
245
int y = 5 ;
255
246
if (text != null && !text .isEmpty ()) {
256
- y = Drawing .executeOnGC (this , gc -> {
257
- gc .setFont (getFont ());
258
- return gc .textExtent (text , DRAW_FLAGS ).y - 5 ;
259
- });
247
+ y = textExtent .y - 5 ;
260
248
}
249
+ return new Rectangle (rect .x + CLIENT_INSET , y , Math .max (0 , rect .width - CLIENT_INSET * 2 ),
250
+ Math .max (0 , rect .height - CLIENT_INSET * 6 ));
261
251
262
- return DPIUtil .autoScaleUp (new Rectangle (CLIENT_INSET , y , Math .max (0 , rect .width - CLIENT_INSET * 2 ),
263
- Math .max (0 , rect .height - CLIENT_INSET * 5 )));
264
252
}
265
253
266
254
@ Override
@@ -298,90 +286,15 @@ boolean mnemonicMatch(char key) {
298
286
return Character .toUpperCase (key ) == Character .toUpperCase (mnemonic );
299
287
}
300
288
301
- //@Override
302
- //void printWidget (long hwnd, long hdc, GC gc) {
303
- // /*
304
- // * Bug in Windows. For some reason, PrintWindow()
305
- // * returns success but does nothing when it is called
306
- // * on a printer. The fix is to just go directly to
307
- // * WM_PRINT in this case.
308
- // */
309
- // boolean success = false;
310
- // NativeGC ngc = (NativeGC) gc.innerGC;
311
- // if (!(OS.GetDeviceCaps(ngc.handle, OS.TECHNOLOGY) == OS.DT_RASPRINTER)) {
312
- // int bits = OS.GetWindowLong (hwnd, OS.GWL_STYLE);
313
- // if ((bits & OS.WS_VISIBLE) == 0) {
314
- // OS.ShowWindow (hwnd, OS.SW_SHOW);
315
- // }
316
- // success = OS.PrintWindow (hwnd, hdc, 0);
317
- // if ((bits & OS.WS_VISIBLE) == 0) {
318
- // OS.ShowWindow (hwnd, OS.SW_HIDE);
319
- // }
320
- // }
321
- //
322
- // /*
323
- // * Bug in Windows. For some reason, PrintWindow() fails
324
- // * when it is called on a push button. The fix is to
325
- // * detect the failure and use WM_PRINT instead. Note
326
- // * that WM_PRINT cannot be used all the time because it
327
- // * fails for browser controls when the browser has focus.
328
- // */
329
- // if (!success) {
330
- // /*
331
- // * Bug in Windows. For some reason, WM_PRINT when called
332
- // * with PRF_CHILDREN will not draw the tool bar divider
333
- // * for tool bar children that do not have CCS_NODIVIDER.
334
- // * The fix is to draw the group box and iterate through
335
- // * the children, drawing each one.
336
- // */
337
- // int flags = OS.PRF_CLIENT | OS.PRF_NONCLIENT | OS.PRF_ERASEBKGND;
338
- // OS.SendMessage (hwnd, OS.WM_PRINT, hdc, flags);
339
- // int nSavedDC = OS.SaveDC (hdc);
340
- // Control [] children = _getChildren ();
341
- // Rectangle rect = getBoundsInPixels ();
342
- // OS.IntersectClipRect (hdc, 0, 0, rect.width, rect.height);
343
- // for (int i=children.length - 1; i>=0; --i) {
344
- // Point location = children [i].getLocationInPixels ();
345
- // int graphicsMode = OS.GetGraphicsMode(hdc);
346
- // if (graphicsMode == OS.GM_ADVANCED) {
347
- // float [] lpXform = {1, 0, 0, 1, location.x, location.y};
348
- // OS.ModifyWorldTransform(hdc, lpXform, OS.MWT_LEFTMULTIPLY);
349
- // } else {
350
- // OS.SetWindowOrgEx (hdc, -location.x, -location.y, null);
351
- // }
352
- // long topHandle = children [i].topHandle();
353
- // int bits = OS.GetWindowLong (topHandle, OS.GWL_STYLE);
354
- // if ((bits & OS.WS_VISIBLE) != 0) {
355
- // children [i].printWidget (topHandle, hdc, gc);
356
- // }
357
- // if (graphicsMode == OS.GM_ADVANCED) {
358
- // float [] lpXform = {1, 0, 0, 1, -location.x, -location.y};
359
- // OS.ModifyWorldTransform(hdc, lpXform, OS.MWT_LEFTMULTIPLY);
360
- // }
361
- // }
362
- // OS.RestoreDC (hdc, nSavedDC);
363
- // }
364
- //}
365
-
366
- //@Override
367
- //void releaseWidget () {
368
- // super.releaseWidget ();
369
- // text = null;
370
- //}
371
-
372
- //@Override
373
- //int resolveTextDirection () {
374
- // return BidiUtil.resolveTextDirection (text);
375
- //}
376
-
377
289
@ Override
378
290
public void setFont (Font font ) {
379
291
checkWidget ();
380
292
Rectangle oldRect = getClientAreaInPixels ();
381
293
super .setFont (font );
382
294
Rectangle newRect = getClientAreaInPixels ();
383
- if (!oldRect .equals (newRect ))
295
+ if (!oldRect .equals (newRect )) {
384
296
sendResize ();
297
+ }
385
298
}
386
299
387
300
/**
@@ -425,7 +338,15 @@ public void setText(String text) {
425
338
if (!text .equals (this .text )) {
426
339
this .text = text ;
427
340
redraw ();
341
+ textExtent = Drawing .executeOnGC (this , gc -> {
342
+ gc .setFont (getFont ());
343
+ return gc .textExtent (this .text , DRAW_FLAGS );
344
+ });
428
345
}
346
+ }
429
347
348
+ @ Override
349
+ void printWidget (long hwnd , long hdc , GC gc ) {
350
+ System .err .println ("printWidget of Group is not implemented yet." );
430
351
}
431
352
}
0 commit comments