Source code: org/eclipse/swt/widgets/Group.java
1 /*******************************************************************************
2 * Copyright (c) 2000, 2004 IBM Corporation and others.
3 * All rights reserved. This program and the accompanying materials
4 * are made available under the terms of the Common Public License v1.0
5 * which accompanies this distribution, and is available at
6 * http://www.eclipse.org/legal/cpl-v10.html
7 *
8 * Contributors:
9 * IBM Corporation - initial API and implementation
10 *******************************************************************************/
11 package org.eclipse.swt.widgets;
12
13
14 import org.eclipse.swt.*;
15 import org.eclipse.swt.internal.*;
16 import org.eclipse.swt.internal.gtk.*;
17 import org.eclipse.swt.graphics.*;
18
19 /**
20 * Instances of this class provide an etched border
21 * with an optional title.
22 * <p>
23 * Shadow styles are hints and may not be honoured
24 * by the platform. To create a group with the
25 * default shadow style for the platform, do not
26 * specify a shadow style.
27 * <dl>
28 * <dt><b>Styles:</b></dt>
29 * <dd>SHADOW_ETCHED_IN, SHADOW_ETCHED_OUT, SHADOW_IN, SHADOW_OUT, SHADOW_NONE</dd>
30 * <dt><b>Events:</b></dt>
31 * <dd>(none)</dd>
32 * </dl>
33 * <p>
34 * Note: Only one of the above styles may be specified.
35 * </p><p>
36 * IMPORTANT: This class is <em>not</em> intended to be subclassed.
37 * </p>
38 */
39 public class Group extends Composite {
40 long /*int*/ clientHandle, labelHandle;
41 String text = "";
42
43 /**
44 * Constructs a new instance of this class given its parent
45 * and a style value describing its behavior and appearance.
46 * <p>
47 * The style value is either one of the style constants defined in
48 * class <code>SWT</code> which is applicable to instances of this
49 * class, or must be built by <em>bitwise OR</em>'ing together
50 * (that is, using the <code>int</code> "|" operator) two or more
51 * of those <code>SWT</code> style constants. The class description
52 * lists the style constants that are applicable to the class.
53 * Style bits are also inherited from superclasses.
54 * </p>
55 *
56 * @param parent a composite control which will be the parent of the new instance (cannot be null)
57 * @param style the style of control to construct
58 *
59 * @exception IllegalArgumentException <ul>
60 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li>
61 * </ul>
62 * @exception SWTException <ul>
63 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li>
64 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li>
65 * </ul>
66 *
67 * @see SWT#SHADOW_ETCHED_IN
68 * @see SWT#SHADOW_ETCHED_OUT
69 * @see SWT#SHADOW_IN
70 * @see SWT#SHADOW_OUT
71 * @see SWT#SHADOW_NONE
72 * @see Widget#checkSubclass
73 * @see Widget#getStyle
74 */
75 public Group (Composite parent, int style) {
76 super (parent, checkStyle (style));
77 }
78
79 static int checkStyle (int style) {
80 style |= SWT.NO_FOCUS;
81 /*
82 * Even though it is legal to create this widget
83 * with scroll bars, they serve no useful purpose
84 * because they do not automatically scroll the
85 * widget's client area. The fix is to clear
86 * the SWT style.
87 */
88 return style & ~(SWT.H_SCROLL | SWT.V_SCROLL);
89 }
90
91 long /*int*/ clientHandle () {
92 return clientHandle;
93 }
94
95
96 public Rectangle computeTrim (int x, int y, int width, int height) {
97 checkWidget();
98 int clientX = OS.GTK_WIDGET_X (clientHandle);
99 int clientY = OS.GTK_WIDGET_Y (clientHandle);
100 x -= clientX;
101 y -= clientY;
102 int oldWidth = OS.GTK_WIDGET_WIDTH (handle);
103 int oldHeight = OS.GTK_WIDGET_HEIGHT (handle);
104 OS.gtk_widget_set_size_request (handle, -1, -1);
105 GtkRequisition requisition = new GtkRequisition ();
106 OS.gtk_widget_size_request (handle, requisition);
107 OS.gtk_widget_set_size_request (handle, oldWidth, oldHeight);
108 width = Math.max (width + clientX + clientX, requisition.width);
109 height += clientX + clientY;
110 return new Rectangle (x, y, width, height);
111 }
112
113 void createHandle(int index) {
114 state |= HANDLE;
115 fixedHandle = OS.gtk_fixed_new ();
116 if (fixedHandle == 0) error (SWT.ERROR_NO_HANDLES);
117 OS.gtk_fixed_set_has_window (fixedHandle, true);
118 handle = OS.gtk_frame_new (null);
119 if (handle == 0) error (SWT.ERROR_NO_HANDLES);
120 labelHandle = OS.gtk_label_new (null);
121 if (labelHandle == 0) error (SWT.ERROR_NO_HANDLES);
122 OS.g_object_ref (labelHandle);
123 OS.gtk_object_sink (labelHandle);
124 clientHandle = OS.gtk_fixed_new();
125 if (clientHandle == 0) error (SWT.ERROR_NO_HANDLES);
126 OS.gtk_fixed_set_has_window (clientHandle, true);
127 long /*int*/ parentHandle = parent.parentingHandle ();
128 OS.gtk_container_add (parentHandle, fixedHandle);
129 OS.gtk_container_add (fixedHandle, handle);
130 OS.gtk_container_add (handle, clientHandle);
131 OS.gtk_widget_show (handle);
132 OS.gtk_widget_show (clientHandle);
133 OS.gtk_widget_show (labelHandle);
134 OS.gtk_widget_show (fixedHandle);
135 if ((style & SWT.SHADOW_IN) != 0) {
136 OS.gtk_frame_set_shadow_type (handle, OS.GTK_SHADOW_IN);
137 }
138 if ((style & SWT.SHADOW_OUT) != 0) {
139 OS.gtk_frame_set_shadow_type (handle, OS.GTK_SHADOW_OUT);
140 }
141 if ((style & SWT.SHADOW_ETCHED_IN) != 0) {
142 OS.gtk_frame_set_shadow_type (handle, OS.GTK_SHADOW_ETCHED_IN);
143 }
144 if ((style & SWT.SHADOW_ETCHED_OUT) != 0) {
145 OS.gtk_frame_set_shadow_type (handle, OS.GTK_SHADOW_ETCHED_OUT);
146 }
147 }
148
149 void deregister () {
150 super.deregister ();
151 display.removeWidget (clientHandle);
152 display.removeWidget (labelHandle);
153 }
154
155 void enableWidget (boolean enabled) {
156 OS.gtk_widget_set_sensitive (labelHandle, enabled);
157 }
158
159 long /*int*/ eventHandle () {
160 return fixedHandle;
161 }
162
163 void fixGroup () {
164 /*
165 * Force the container to allocate the size of its children.
166 */
167 int flags = OS.GTK_WIDGET_FLAGS (handle);
168 OS.GTK_WIDGET_SET_FLAGS (handle, OS.GTK_VISIBLE);
169 GtkRequisition requisition = new GtkRequisition ();
170 OS.gtk_widget_size_request (handle, requisition);
171 OS.gtk_container_resize_children (handle);
172 if ((flags & OS.GTK_VISIBLE) == 0) {
173 OS.GTK_WIDGET_UNSET_FLAGS (handle, OS.GTK_VISIBLE);
174 }
175 }
176
177 public Rectangle getClientArea () {
178 checkWidget();
179 int width = OS.GTK_WIDGET_WIDTH (clientHandle);
180 int height = OS.GTK_WIDGET_HEIGHT (clientHandle);
181 return new Rectangle (0, 0, width, height);
182 }
183
184 String getNameText () {
185 return getText ();
186 }
187
188 /**
189 * Returns the receiver's text, which is the string that the
190 * is used as the <em>title</em>. If the text has not previously
191 * been set, returns an empty string.
192 *
193 * @return the text
194 *
195 * @exception SWTException <ul>
196 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
197 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
198 * </ul>
199 */
200 public String getText () {
201 checkWidget();
202 return text;
203 }
204
205 void hookEvents () {
206 super.hookEvents();
207 if (labelHandle != 0) {
208 OS.g_signal_connect (labelHandle, OS.mnemonic_activate, display.windowProc3, MNEMONIC_ACTIVATE);
209 }
210 }
211
212 boolean mnemonicHit (char key) {
213 if (labelHandle == 0) return false;
214 boolean result = super.mnemonicHit (labelHandle, key);
215 if (result) setFocus ();
216 return result;
217 }
218
219 boolean mnemonicMatch (char key) {
220 if (labelHandle == 0) return false;
221 return mnemonicMatch (labelHandle, key);
222 }
223
224 long /*int*/ parentingHandle() {
225 return clientHandle;
226 }
227
228 void register () {
229 super.register ();
230 display.addWidget (clientHandle, this);
231 display.addWidget (labelHandle, this);
232 }
233
234 void releaseHandle () {
235 super.releaseHandle ();
236 clientHandle = labelHandle = 0;
237 }
238
239 void releaseWidget () {
240 super.releaseWidget ();
241 if (labelHandle != 0) OS.g_object_unref (labelHandle);
242 text = null;
243 }
244
245 void setBackgroundColor (GdkColor color) {
246 super.setBackgroundColor (color);
247 setBackgroundColor(fixedHandle, color);
248 }
249
250 void setFontDescription (long /*int*/ font) {
251 super.setFontDescription (font);
252 OS.gtk_widget_modify_font (labelHandle, font);
253 }
254
255 void setForegroundColor (GdkColor color) {
256 super.setForegroundColor (color);
257 OS.gtk_widget_modify_fg (labelHandle, OS.GTK_STATE_NORMAL, color);
258 }
259
260 void setOrientation () {
261 super.setOrientation ();
262 if ((style & SWT.RIGHT_TO_LEFT) != 0) {
263 OS.gtk_widget_set_direction (handle, OS.GTK_TEXT_DIR_RTL);
264 OS.gtk_widget_set_direction (labelHandle, OS.GTK_TEXT_DIR_RTL);
265 }
266 }
267
268 /**
269 * Sets the receiver's text, which is the string that will
270 * be displayed as the receiver's <em>title</em>, to the argument,
271 * which may not be null. The string may include the mnemonic character.
272 * </p>
273 * Mnemonics are indicated by an '&' that causes the next
274 * character to be the mnemonic. When the user presses a
275 * key sequence that matches the mnemonic, focus is assgned
276 * to the first child of the group. On most platforms, the
277 * mnemonic appears underlined but may be emphasised in a
278 * platform specific manner. The mnemonic indicator character
279 *'&' can be escaped by doubling it in the string, causing
280 * a single '&' to be displayed.
281 * </p>
282 * @param string the new text
283 *
284 * @exception IllegalArgumentException <ul>
285 * <li>ERROR_NULL_ARGUMENT - if the text is null</li>
286 * </ul>
287 * @exception SWTException <ul>
288 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li>
289 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li>
290 * </ul>
291 */
292 public void setText (String string) {
293 checkWidget();
294 if (string == null) error (SWT.ERROR_NULL_ARGUMENT);
295 text = string;
296 char [] chars = fixMnemonic (string);
297 byte [] buffer = Converter.wcsToMbcs (null, chars, true);
298 OS.gtk_label_set_text_with_mnemonic (labelHandle, buffer);
299 if (string.length () != 0) {
300 if (OS.gtk_frame_get_label_widget (handle) == 0) {
301 OS.gtk_frame_set_label_widget (handle, labelHandle);
302 }
303 } else {
304 OS.gtk_frame_set_label_widget (handle, 0);
305 }
306 fixGroup ();
307 }
308
309 }