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