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.TabItem; 14 15 import java.lang.all; 16 17 18 19 import org.eclipse.swt.SWT; 20 import org.eclipse.swt.SWTException; 21 import org.eclipse.swt.graphics.Image; 22 import org.eclipse.swt.graphics.Rectangle; 23 import org.eclipse.swt.internal.gtk.OS; 24 import org.eclipse.swt.widgets.Item; 25 import org.eclipse.swt.widgets.Control; 26 import org.eclipse.swt.widgets.TabFolder; 27 import org.eclipse.swt.widgets.ImageList; 28 29 /** 30 * Instances of this class represent a selectable user interface object 31 * corresponding to a tab for a page in a tab folder. 32 * <dl> 33 * <dt><b>Styles:</b></dt> 34 * <dd>(none)</dd> 35 * <dt><b>Events:</b></dt> 36 * <dd>(none)</dd> 37 * </dl> 38 * <p> 39 * IMPORTANT: This class is <em>not</em> intended to be subclassed. 40 * </p> 41 * 42 * @see <a href="http://www.eclipse.org/swt/snippets/#tabfolder">TabFolder, TabItem snippets</a> 43 * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> 44 */ 45 public class TabItem : Item { 46 47 alias Item.setForegroundColor setForegroundColor; 48 49 GtkWidget* labelHandle, imageHandle, pageHandle; 50 Control control; 51 TabFolder parent; 52 String toolTipText; 53 54 /** 55 * Constructs a new instance of this class given its parent 56 * (which must be a <code>TabFolder</code>) and a style value 57 * describing its behavior and appearance. The item is added 58 * to the end of the items maintained by its parent. 59 * <p> 60 * The style value is either one of the style constants defined in 61 * class <code>SWT</code> which is applicable to instances of this 62 * class, or must be built by <em>bitwise OR</em>'ing together 63 * (that is, using the <code>int</code> "|" operator) two or more 64 * of those <code>SWT</code> style constants. The class description 65 * lists the style constants that are applicable to the class. 66 * Style bits are also inherited from superclasses. 67 * </p> 68 * 69 * @param parent a composite control which will be the parent of the new instance (cannot be null) 70 * @param style the style of control to construct 71 * 72 * @exception IllegalArgumentException <ul> 73 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> 74 * </ul> 75 * @exception SWTException <ul> 76 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> 77 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> 78 * </ul> 79 * 80 * @see SWT 81 * @see Widget#checkSubclass 82 * @see Widget#getStyle 83 */ 84 public this (TabFolder parent, int style) { 85 super (parent, style); 86 this.parent = parent; 87 createWidget (parent.getItemCount ()); 88 } 89 90 /** 91 * Constructs a new instance of this class given its parent 92 * (which must be a <code>TabFolder</code>), a style value 93 * describing its behavior and appearance, and the index 94 * at which to place it in the items maintained by its parent. 95 * <p> 96 * The style value is either one of the style constants defined in 97 * class <code>SWT</code> which is applicable to instances of this 98 * class, or must be built by <em>bitwise OR</em>'ing together 99 * (that is, using the <code>int</code> "|" operator) two or more 100 * of those <code>SWT</code> style constants. The class description 101 * lists the style constants that are applicable to the class. 102 * Style bits are also inherited from superclasses. 103 * </p> 104 * 105 * @param parent a composite control which will be the parent of the new instance (cannot be null) 106 * @param style the style of control to construct 107 * @param index the zero-relative index to store the receiver in its parent 108 * 109 * @exception IllegalArgumentException <ul> 110 * <li>ERROR_NULL_ARGUMENT - if the parent is null</li> 111 * <li>ERROR_INVALID_RANGE - if the index is not between 0 and the number of elements in the parent (inclusive)</li> 112 * </ul> 113 * @exception SWTException <ul> 114 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> 115 * <li>ERROR_INVALID_SUBCLASS - if this class is not an allowed subclass</li> 116 * </ul> 117 * 118 * @see SWT 119 * @see Widget#checkSubclass 120 * @see Widget#getStyle 121 */ 122 public this (TabFolder parent, int style, int index) { 123 super (parent, style); 124 this.parent = parent; 125 createWidget (index); 126 } 127 128 protected override void checkSubclass () { 129 if (!isValidSubclass ()) error (SWT.ERROR_INVALID_SUBCLASS); 130 } 131 132 override void createWidget (int index) { 133 parent.createItem (this, index); 134 setOrientation (); 135 hookEvents (); 136 register (); 137 text = ""; 138 } 139 140 override void deregister() { 141 super.deregister (); 142 if (labelHandle !is null) display.removeWidget (labelHandle); 143 } 144 145 override void destroyWidget () { 146 parent.destroyItem (this); 147 releaseHandle (); 148 } 149 150 /** 151 * Returns a rectangle describing the receiver's size and location 152 * relative to its parent. 153 * 154 * @return the receiver's bounding rectangle 155 * 156 * @exception SWTException <ul> 157 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 158 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 159 * </ul> 160 * 161 * @since 3.4 162 */ 163 public Rectangle getBounds () { 164 checkWidget(); 165 int x = OS.GTK_WIDGET_X (handle); 166 int y = OS.GTK_WIDGET_Y (handle); 167 int width = (state & ZERO_WIDTH) !is 0 ? 0 : OS.GTK_WIDGET_WIDTH (handle); 168 int height = (state & ZERO_HEIGHT) !is 0 ? 0 : OS.GTK_WIDGET_HEIGHT (handle); 169 if ((parent.style & SWT.MIRRORED) !is 0) x = parent.getClientWidth () - width - x; 170 return new Rectangle (x, y, width, height); 171 } 172 173 /** 174 * Returns the control that is used to fill the client area of 175 * the tab folder when the user selects the tab item. If no 176 * control has been set, return <code>null</code>. 177 * <p> 178 * @return the control 179 * 180 * @exception SWTException <ul> 181 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 182 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 183 * </ul> 184 */ 185 public Control getControl () { 186 checkWidget (); 187 return control; 188 } 189 190 /** 191 * Returns the receiver's parent, which must be a <code>TabFolder</code>. 192 * 193 * @return the receiver's parent 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 TabFolder getParent () { 201 checkWidget (); 202 return parent; 203 } 204 205 /** 206 * Returns the receiver's tool tip text, or null if it has 207 * not been set. 208 * 209 * @return the receiver's tool tip text 210 * 211 * @exception SWTException <ul> 212 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 213 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 214 * </ul> 215 */ 216 public String getToolTipText () { 217 checkWidget (); 218 return toolTipText; 219 } 220 221 override int gtk_enter_notify_event (GtkWidget* widget, GdkEventCrossing* event) { 222 parent.gtk_enter_notify_event (widget, event); 223 return 0; 224 } 225 226 override int gtk_mnemonic_activate (GtkWidget* widget, ptrdiff_t arg1) { 227 return parent.gtk_mnemonic_activate (widget, arg1); 228 } 229 230 override void hookEvents () { 231 super.hookEvents (); 232 if (labelHandle !is null) OS.g_signal_connect_closure_by_id (labelHandle, display.signalIds [MNEMONIC_ACTIVATE], 0, display.closures [MNEMONIC_ACTIVATE], false); 233 OS.g_signal_connect_closure_by_id (handle, display.signalIds [ENTER_NOTIFY_EVENT], 0, display.closures [ENTER_NOTIFY_EVENT], false); 234 } 235 236 override void register () { 237 super.register (); 238 if (labelHandle !is null) display.addWidget (labelHandle, this); 239 } 240 241 override void releaseHandle () { 242 super.releaseHandle (); 243 pageHandle = labelHandle = imageHandle = null; 244 parent = null; 245 } 246 247 override void releaseParent () { 248 super.releaseParent (); 249 int index = parent.indexOf (this); 250 if (index is parent.getSelectionIndex ()) { 251 if (control !is null) control.setVisible (false); 252 } 253 } 254 255 /** 256 * Sets the control that is used to fill the client area of 257 * the tab folder when the user selects the tab item. 258 * <p> 259 * @param control the new control (or null) 260 * 261 * @exception IllegalArgumentException <ul> 262 * <li>ERROR_INVALID_ARGUMENT - if the control has been disposed</li> 263 * <li>ERROR_INVALID_PARENT - if the control is not in the same widget tree</li> 264 * </ul> 265 * @exception SWTException <ul> 266 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 267 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 268 * </ul> 269 */ 270 public void setControl (Control control) { 271 checkWidget (); 272 if (control !is null) { 273 if (control.isDisposed ()) error (SWT.ERROR_INVALID_ARGUMENT); 274 if (control.parent !is parent) error (SWT.ERROR_INVALID_PARENT); 275 } 276 Control oldControl = this.control, newControl = control; 277 this.control = control; 278 int index = parent.indexOf (this); 279 if (index !is parent.getSelectionIndex ()) { 280 if (newControl !is null) newControl.setVisible (false); 281 return; 282 } 283 if (newControl !is null) { 284 newControl.setBounds (parent.getClientArea ()); 285 newControl.setVisible (true); 286 } 287 if (oldControl !is null) oldControl.setVisible (false); 288 } 289 290 void setFontDescription (PangoFontDescription* font) { 291 OS.gtk_widget_modify_font (labelHandle, font); 292 OS.gtk_widget_modify_font (imageHandle, font); 293 } 294 295 void setForegroundColor (GdkColor* color) { 296 /* Don't set the color in vbox handle (it doesn't draw) */ 297 setForegroundColor (labelHandle, color); 298 setForegroundColor (imageHandle, color); 299 } 300 301 public override void setImage (Image image) { 302 checkWidget (); 303 super.setImage (image); 304 if (image !is null) { 305 ImageList imageList = parent.imageList; 306 if (imageList is null) imageList = parent.imageList = new ImageList (); 307 int imageIndex = imageList.indexOf (image); 308 if (imageIndex is -1) { 309 imageIndex = imageList.add (image); 310 } else { 311 imageList.put (imageIndex, image); 312 } 313 auto pixbuf = imageList.getPixbuf (imageIndex); 314 OS.gtk_image_set_from_pixbuf (imageHandle, pixbuf); 315 OS.gtk_widget_show (imageHandle); 316 } else { 317 OS.gtk_image_set_from_pixbuf (imageHandle, null); 318 OS.gtk_widget_hide (imageHandle); 319 } 320 } 321 322 override void setOrientation () { 323 if ((parent.style & SWT.RIGHT_TO_LEFT) !is 0) { 324 if (handle !is null) OS.gtk_widget_set_direction (handle, OS.GTK_TEXT_DIR_RTL); 325 if (labelHandle !is null) OS.gtk_widget_set_direction (labelHandle, OS.GTK_TEXT_DIR_RTL); 326 if (imageHandle !is null) OS.gtk_widget_set_direction (imageHandle, OS.GTK_TEXT_DIR_RTL); 327 if (pageHandle !is null) OS.gtk_widget_set_direction (pageHandle, OS.GTK_TEXT_DIR_RTL); 328 } 329 } 330 331 /** 332 * Sets the receiver's text. The string may include 333 * the mnemonic character. 334 * </p> 335 * <p> 336 * Mnemonics are indicated by an '&' that causes the next 337 * character to be the mnemonic. When the user presses a 338 * key sequence that matches the mnemonic, a selection 339 * event occurs. On most platforms, the mnemonic appears 340 * underlined but may be emphasised in a platform specific 341 * manner. The mnemonic indicator character '&' can be 342 * escaped by doubling it in the string, causing a single 343 * '&' to be displayed. 344 * </p> 345 * 346 * @param string the new text 347 * 348 * @exception SWTException <ul> 349 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 350 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 351 * </ul> 352 * 353 */ 354 public override void setText (String string) { 355 checkWidget (); 356 // SWT extension: allow null for zero length string 357 //if (string is null) error (SWT.ERROR_NULL_ARGUMENT); 358 super.setText (string); 359 char [] chars = fixMnemonic (string); 360 OS.gtk_label_set_text_with_mnemonic (labelHandle, chars.toStringzValidPtr() ); 361 if (string.length !is 0) { 362 OS.gtk_widget_show (labelHandle); 363 } else { 364 OS.gtk_widget_hide (labelHandle); 365 } 366 } 367 368 /** 369 * Sets the receiver's tool tip text to the argument, which 370 * may be null indicating that no tool tip text should be shown. 371 * 372 * @param string the new tool tip text (or null) 373 * 374 * @exception SWTException <ul> 375 * <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> 376 * <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> 377 * </ul> 378 */ 379 public void setToolTipText (String string) { 380 checkWidget (); 381 toolTipText = string; 382 } 383 384 }