| 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 dwt.custom.CTabFolder; |
|---|
| 14 |
|
|---|
| 15 |
import dwt.DWT; |
|---|
| 16 |
import dwt.DWTException; |
|---|
| 17 |
import dwt.accessibility.ACC; |
|---|
| 18 |
import dwt.accessibility.Accessible; |
|---|
| 19 |
import dwt.accessibility.AccessibleAdapter; |
|---|
| 20 |
import dwt.accessibility.AccessibleControlAdapter; |
|---|
| 21 |
import dwt.accessibility.AccessibleControlEvent; |
|---|
| 22 |
import dwt.accessibility.AccessibleEvent; |
|---|
| 23 |
import dwt.events.SelectionAdapter; |
|---|
| 24 |
import dwt.events.SelectionEvent; |
|---|
| 25 |
import dwt.events.SelectionListener; |
|---|
| 26 |
import dwt.graphics.Color; |
|---|
| 27 |
import dwt.graphics.Font; |
|---|
| 28 |
import dwt.graphics.FontData; |
|---|
| 29 |
import dwt.graphics.GC; |
|---|
| 30 |
import dwt.graphics.Image; |
|---|
| 31 |
import dwt.graphics.Point; |
|---|
| 32 |
import dwt.graphics.RGB; |
|---|
| 33 |
import dwt.graphics.Rectangle; |
|---|
| 34 |
import dwt.graphics.Region; |
|---|
| 35 |
import dwt.widgets.Composite; |
|---|
| 36 |
import dwt.widgets.Control; |
|---|
| 37 |
import dwt.widgets.Display; |
|---|
| 38 |
import dwt.widgets.Event; |
|---|
| 39 |
import dwt.widgets.Layout; |
|---|
| 40 |
import dwt.widgets.Listener; |
|---|
| 41 |
import dwt.widgets.Menu; |
|---|
| 42 |
import dwt.widgets.MenuItem; |
|---|
| 43 |
import dwt.widgets.TypedListener; |
|---|
| 44 |
import dwt.custom.CTabItem; |
|---|
| 45 |
import dwt.custom.CTabFolder2Listener; |
|---|
| 46 |
import dwt.custom.CTabFolderListener; |
|---|
| 47 |
import dwt.custom.CTabFolderLayout; |
|---|
| 48 |
import dwt.custom.CTabFolderEvent; |
|---|
| 49 |
|
|---|
| 50 |
import dwt.dwthelper.utils; |
|---|
| 51 |
import tango.util.Convert; |
|---|
| 52 |
static import tango.text.convert.Utf; |
|---|
| 53 |
|
|---|
| 54 |
/** |
|---|
| 55 |
* |
|---|
| 56 |
* Instances of this class implement the notebook user interface |
|---|
| 57 |
* metaphor. It allows the user to select a notebook page from |
|---|
| 58 |
* set of pages. |
|---|
| 59 |
* <p> |
|---|
| 60 |
* The item children that may be added to instances of this class |
|---|
| 61 |
* must be of type <code>CTabItem</code>. |
|---|
| 62 |
* <code>Control</code> children are created and then set into a |
|---|
| 63 |
* tab item using <code>CTabItem#setControl</code>. |
|---|
| 64 |
* </p><p> |
|---|
| 65 |
* Note that although this class is a subclass of <code>Composite</code>, |
|---|
| 66 |
* it does not make sense to set a layout on it. |
|---|
| 67 |
* </p><p> |
|---|
| 68 |
* <dl> |
|---|
| 69 |
* <dt><b>Styles:</b></dt> |
|---|
| 70 |
* <dd>CLOSE, TOP, BOTTOM, FLAT, BORDER, SINGLE, MULTI</dd> |
|---|
| 71 |
* <dt><b>Events:</b></dt> |
|---|
| 72 |
* <dd>Selection</dd> |
|---|
| 73 |
* <dd>"CTabFolder2"</dd> |
|---|
| 74 |
* </dl> |
|---|
| 75 |
* <p> |
|---|
| 76 |
* Note: Only one of the styles TOP and BOTTOM |
|---|
| 77 |
* may be specified. |
|---|
| 78 |
* </p><p> |
|---|
| 79 |
* IMPORTANT: This class is <em>not</em> intended to be subclassed. |
|---|
| 80 |
* </p> |
|---|
| 81 |
* |
|---|
| 82 |
* @see <a href="http://www.eclipse.org/swt/snippets/#ctabfolder">CTabFolder, CTabItem snippets</a> |
|---|
| 83 |
* @see <a href="http://www.eclipse.org/swt/examples.php">DWT Example: CustomControlExample</a> |
|---|
| 84 |
* @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> |
|---|
| 85 |
*/ |
|---|
| 86 |
|
|---|
| 87 |
public class CTabFolder : Composite { |
|---|
| 88 |
|
|---|
| 89 |
/** |
|---|
| 90 |
* marginWidth specifies the number of pixels of horizontal margin |
|---|
| 91 |
* that will be placed along the left and right edges of the form. |
|---|
| 92 |
* |
|---|
| 93 |
* The default value is 0. |
|---|
| 94 |
*/ |
|---|
| 95 |
public int marginWidth = 0; |
|---|
| 96 |
/** |
|---|
| 97 |
* marginHeight specifies the number of pixels of vertical margin |
|---|
| 98 |
* that will be placed along the top and bottom edges of the form. |
|---|
| 99 |
* |
|---|
| 100 |
* The default value is 0. |
|---|
| 101 |
*/ |
|---|
| 102 |
public int marginHeight = 0; |
|---|
| 103 |
|
|---|
| 104 |
/** |
|---|
| 105 |
* A multiple of the tab height that specifies the minimum width to which a tab |
|---|
| 106 |
* will be compressed before scrolling arrows are used to navigate the tabs. |
|---|
| 107 |
* |
|---|
| 108 |
* NOTE This field is badly named and can not be fixed for backwards compatibility. |
|---|
| 109 |
* It should not be capitalized. |
|---|
| 110 |
* |
|---|
| 111 |
* @deprecated This field is no longer used. See setMinimumCharacters(int) |
|---|
| 112 |
*/ |
|---|
| 113 |
public int MIN_TAB_WIDTH = 4; |
|---|
| 114 |
|
|---|
| 115 |
/** |
|---|
| 116 |
* Color of innermost line of drop shadow border. |
|---|
| 117 |
* |
|---|
| 118 |
* NOTE This field is badly named and can not be fixed for backwards compatibility. |
|---|
| 119 |
* It should be capitalized. |
|---|
| 120 |
* |
|---|
| 121 |
* @deprecated drop shadow border is no longer drawn in 3.0 |
|---|
| 122 |
*/ |
|---|
| 123 |
public static RGB borderInsideRGB; |
|---|
| 124 |
/** |
|---|
| 125 |
* Color of middle line of drop shadow border. |
|---|
| 126 |
* |
|---|
| 127 |
* NOTE This field is badly named and can not be fixed for backwards compatibility. |
|---|
| 128 |
* It should be capitalized. |
|---|
| 129 |
* |
|---|
| 130 |
* @deprecated drop shadow border is no longer drawn in 3.0 |
|---|
| 131 |
*/ |
|---|
| 132 |
public static RGB borderMiddleRGB; |
|---|
| 133 |
/** |
|---|
| 134 |
* Color of outermost line of drop shadow border. |
|---|
| 135 |
* |
|---|
| 136 |
* NOTE This field is badly named and can not be fixed for backwards compatibility. |
|---|
| 137 |
* It should be capitalized. |
|---|
| 138 |
* |
|---|
| 139 |
* @deprecated drop shadow border is no longer drawn in 3.0 |
|---|
| 140 |
*/ |
|---|
| 141 |
public static RGB borderOutsideRGB; |
|---|
| 142 |
|
|---|
| 143 |
/* sizing, positioning */ |
|---|
| 144 |
int xClient, yClient; |
|---|
| 145 |
bool onBottom = false; |
|---|
| 146 |
bool single = false; |
|---|
| 147 |
bool simple = true; |
|---|
| 148 |
int fixedTabHeight = DWT.DEFAULT; |
|---|
| 149 |
int tabHeight; |
|---|
| 150 |
int minChars = 20; |
|---|
| 151 |
|
|---|
| 152 |
/* item management */ |
|---|
| 153 |
CTabItem items[]; |
|---|
| 154 |
int firstIndex = -1; // index of the left most visible tab. |
|---|
| 155 |
int selectedIndex = -1; |
|---|
| 156 |
int[] priority; |
|---|
| 157 |
bool mru = false; |
|---|
| 158 |
Listener listener; |
|---|
| 159 |
|
|---|
| 160 |
/* External Listener management */ |
|---|
| 161 |
CTabFolder2Listener[] folderListeners; |
|---|
| 162 |
// support for deprecated listener mechanism |
|---|
| 163 |
CTabFolderListener[] tabListeners; |
|---|
| 164 |
|
|---|
| 165 |
/* Selected item appearance */ |
|---|
| 166 |
Image selectionBgImage; |
|---|
| 167 |
Color[] selectionGradientColors; |
|---|
| 168 |
int[] selectionGradientPercents; |
|---|
| 169 |
bool selectionGradientVertical; |
|---|
| 170 |
Color selectionForeground; |
|---|
| 171 |
Color selectionBackground; //selection fade end |
|---|
| 172 |
Color selectionFadeStart; |
|---|
| 173 |
|
|---|
| 174 |
Color selectionHighlightGradientBegin = null; //null is no highlight |
|---|
| 175 |
//Although we are given new colours all the time to show different states (active, etc), |
|---|
| 176 |
//some of which may have a highlight and some not, we'd like to retain the highlight colours |
|---|
| 177 |
//as a cache so that we can reuse them if we're again told to show the highlight. |
|---|
| 178 |
//We are relying on the fact that only one tab state usually gets a highlight, so only |
|---|
| 179 |
//a single cache is required. If that happens to not be true, cache simply becomes less effective, |
|---|
| 180 |
//but we don't leak colours. |
|---|
| 181 |
Color[] selectionHighlightGradientColorsCache = null; //null is a legal value, check on access |
|---|
| 182 |
|
|---|
| 183 |
/* Unselected item appearance */ |
|---|
| 184 |
Image bgImage; |
|---|
| 185 |
Color[] gradientColors; |
|---|
| 186 |
int[] gradientPercents; |
|---|
| 187 |
bool gradientVertical; |
|---|
| 188 |
bool showUnselectedImage = true; |
|---|
| 189 |
|
|---|
| 190 |
static Color borderColor; |
|---|
| 191 |
|
|---|
| 192 |
// close, min/max and chevron buttons |
|---|
| 193 |
bool showClose = false; |
|---|
| 194 |
bool showUnselectedClose = true; |
|---|
| 195 |
|
|---|
| 196 |
Rectangle chevronRect; |
|---|
| 197 |
int chevronImageState = NORMAL; |
|---|
| 198 |
bool showChevron = false; |
|---|
| 199 |
Menu showMenu; |
|---|
| 200 |
|
|---|
| 201 |
bool showMin = false; |
|---|
| 202 |
Rectangle minRect; |
|---|
| 203 |
bool minimized = false; |
|---|
| 204 |
int minImageState = NORMAL; |
|---|
| 205 |
|
|---|
| 206 |
bool showMax = false; |
|---|
| 207 |
Rectangle maxRect; |
|---|
| 208 |
bool maximized = false; |
|---|
| 209 |
int maxImageState = NORMAL; |
|---|
| 210 |
|
|---|
| 211 |
Control topRight; |
|---|
| 212 |
Rectangle topRightRect; |
|---|
| 213 |
int topRightAlignment = DWT.RIGHT; |
|---|
| 214 |
|
|---|
| 215 |
// borders and shapes |
|---|
| 216 |
int borderLeft = 0; |
|---|
| 217 |
int borderRight = 0; |
|---|
| 218 |
int borderTop = 0; |
|---|
| 219 |
int borderBottom = 0; |
|---|
| 220 |
|
|---|
| 221 |
int highlight_margin = 0; |
|---|
| 222 |
int highlight_header = 0; |
|---|
| 223 |
|
|---|
| 224 |
int[] curve; |
|---|
| 225 |
int[] topCurveHighlightStart; |
|---|
| 226 |
int[] topCurveHighlightEnd; |
|---|
| 227 |
int curveWidth = 0; |
|---|
| 228 |
int curveIndent = 0; |
|---|
| 229 |
|
|---|
| 230 |
// when disposing CTabFolder, don't try to layout the items or |
|---|
| 231 |
// change the selection as each child is destroyed. |
|---|
| 232 |
bool inDispose = false; |
|---|
| 233 |
|
|---|
| 234 |
// keep track of size changes in order to redraw only affected area |
|---|
| 235 |
// on Resize |
|---|
| 236 |
Point oldSize; |
|---|
| 237 |
Font oldFont; |
|---|
| 238 |
|
|---|
| 239 |
// internal constants |
|---|
| 240 |
static const int DEFAULT_WIDTH = 64; |
|---|
| 241 |
static const int DEFAULT_HEIGHT = 64; |
|---|
| 242 |
static const int BUTTON_SIZE = 18; |
|---|
| 243 |
|
|---|
| 244 |
static const int[] TOP_LEFT_CORNER = [0,6, 1,5, 1,4, 4,1, 5,1, 6,0]; |
|---|
| 245 |
|
|---|
| 246 |
//TOP_LEFT_CORNER_HILITE is laid out in reverse (ie. top to bottom) |
|---|
| 247 |
//so can fade in same direction as right swoop curve |
|---|
| 248 |
static const int[] TOP_LEFT_CORNER_HILITE = [5,2, 4,2, 3,3, 2,4, 2,5, 1,6]; |
|---|
| 249 |
|
|---|
| 250 |
static const int[] TOP_RIGHT_CORNER = [-6,0, -5,1, -4,1, -1,4, -1,5, 0,6]; |
|---|
| 251 |
static const int[] BOTTOM_LEFT_CORNER = [0,-6, 1,-5, 1,-4, 4,-1, 5,-1, 6,0]; |
|---|
| 252 |
static const int[] BOTTOM_RIGHT_CORNER = [-6,0, -5,-1, -4,-1, -1,-4, -1,-5, 0,-6]; |
|---|
| 253 |
|
|---|
| 254 |
static const int[] SIMPLE_TOP_LEFT_CORNER = [0,2, 1,1, 2,0]; |
|---|
| 255 |
static const int[] SIMPLE_TOP_RIGHT_CORNER = [-2,0, -1,1, 0,2]; |
|---|
| 256 |
static const int[] SIMPLE_BOTTOM_LEFT_CORNER = [0,-2, 1,-1, 2,0]; |
|---|
| 257 |
static const int[] SIMPLE_BOTTOM_RIGHT_CORNER = [-2,0, -1,-1, 0,-2]; |
|---|
| 258 |
static const int[] SIMPLE_UNSELECTED_INNER_CORNER = [0,0]; |
|---|
| 259 |
|
|---|
| 260 |
static const int[] TOP_LEFT_CORNER_BORDERLESS = [0,6, 1,5, 1,4, 4,1, 5,1, 6,0]; |
|---|
| 261 |
static const int[] TOP_RIGHT_CORNER_BORDERLESS = [-7,0, -6,1, -5,1, -2,4, -2,5, -1,6]; |
|---|
| 262 |
static const int[] BOTTOM_LEFT_CORNER_BORDERLESS = [0,-6, 1,-6, 1,-5, 2,-4, 4,-2, 5,-1, 6,-1, 6,0]; |
|---|
| 263 |
static const int[] BOTTOM_RIGHT_CORNER_BORDERLESS = [-7,0, -7,-1, -6,-1, -5,-2, -3,-4, -2,-5, -2,-6, -1,-6]; |
|---|
| 264 |
|
|---|
| 265 |
static const int[] SIMPLE_TOP_LEFT_CORNER_BORDERLESS = [0,2, 1,1, 2,0]; |
|---|
| 266 |
static const int[] SIMPLE_TOP_RIGHT_CORNER_BORDERLESS= [-3,0, -2,1, -1,2]; |
|---|
| 267 |
static const int[] SIMPLE_BOTTOM_LEFT_CORNER_BORDERLESS = [0,-3, 1,-2, 2,-1, 3,0]; |
|---|
| 268 |
static const int[] SIMPLE_BOTTOM_RIGHT_CORNER_BORDERLESS = [-4,0, -3,-1, -2,-2, -1,-3]; |
|---|
| 269 |
|
|---|
| 270 |
static const int SELECTION_FOREGROUND = DWT.COLOR_LIST_FOREGROUND; |
|---|
| 271 |
static const int SELECTION_BACKGROUND = DWT.COLOR_LIST_BACKGROUND; |
|---|
| 272 |
static const int BORDER1_COLOR = DWT.COLOR_WIDGET_NORMAL_SHADOW; |
|---|
| 273 |
static const int FOREGROUND = DWT.COLOR_WIDGET_FOREGROUND; |
|---|
| 274 |
static const int BACKGROUND = DWT.COLOR_WIDGET_BACKGROUND; |
|---|
| 275 |
static const int BUTTON_BORDER = DWT.COLOR_WIDGET_DARK_SHADOW; |
|---|
| 276 |
static const int BUTTON_FILL = DWT.COLOR_LIST_BACKGROUND; |
|---|
| 277 |
|
|---|
| 278 |
static const int NONE = 0; |
|---|
| 279 |
static const int NORMAL = 1; |
|---|
| 280 |
static const int HOT = 2; |
|---|
| 281 |
static const int SELECTED = 3; |
|---|
| 282 |
static const RGB CLOSE_FILL; |
|---|
| 283 |
|
|---|
| 284 |
static const int CHEVRON_CHILD_ID = 0; |
|---|
| 285 |
static const int MINIMIZE_CHILD_ID = 1; |
|---|
| 286 |
static const int MAXIMIZE_CHILD_ID = 2; |
|---|
| 287 |
static const int EXTRA_CHILD_ID_COUNT = 3; |
|---|
| 288 |
|
|---|
| 289 |
static this(){ |
|---|
| 290 |
borderInsideRGB = new RGB (132, 130, 132); |
|---|
| 291 |
borderMiddleRGB = new RGB (143, 141, 138); |
|---|
| 292 |
borderOutsideRGB = new RGB (171, 168, 165); |
|---|
| 293 |
CLOSE_FILL = new RGB(252, 160, 160); |
|---|
| 294 |
} |
|---|
| 295 |
|
|---|
| 296 |
/** |
|---|
| 297 |
* Constructs a new instance of this class given its parent |
|---|
| 298 |
* and a style value describing its behavior and appearance. |
|---|
| 299 |
* <p> |
|---|
| 300 |
* The style value is either one of the style constants defined in |
|---|
| 301 |
* class <code>DWT</code> which is applicable to instances of this |
|---|
| 302 |
* class, or must be built by <em>bitwise OR</em>'ing together |
|---|
| 303 |
* (that is, using the <code>int</code> "|" operator) two or more |
|---|
| 304 |
* of those <code>DWT</code> style constants. The class description |
|---|
| 305 |
* lists the style constants that are applicable to the class. |
|---|
| 306 |
* Style bits are also inherited from superclasses. |
|---|
| 307 |
* </p> |
|---|
| 308 |
* |
|---|
| 309 |
* @param parent a widget which will be the parent of the new instance (cannot be null) |
|---|
| 310 |
* @param style the style of widget to construct |
|---|
| 311 |
* |
|---|
| 312 |
* @exception IllegalArgumentException <ul> |
|---|
| 313 |
* <li>ERROR_NULL_ARGUMENT - if the parent is null</li> |
|---|
| 314 |
* </ul> |
|---|
| 315 |
* @exception DWTException <ul> |
|---|
| 316 |
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the parent</li> |
|---|
| 317 |
* </ul> |
|---|
| 318 |
* |
|---|
| 319 |
* @see DWT#TOP |
|---|
| 320 |
* @see DWT#BOTTOM |
|---|
| 321 |
* @see DWT#FLAT |
|---|
| 322 |
* @see DWT#BORDER |
|---|
| 323 |
* @see DWT#SINGLE |
|---|
| 324 |
* @see DWT#MULTI |
|---|
| 325 |
* @see #getStyle() |
|---|
| 326 |
*/ |
|---|
| 327 |
public this(Composite parent, int style) { |
|---|
| 328 |
chevronRect = new Rectangle(0, 0, 0, 0); |
|---|
| 329 |
minRect = new Rectangle(0, 0, 0, 0); |
|---|
| 330 |
maxRect = new Rectangle(0, 0, 0, 0); |
|---|
| 331 |
topRightRect = new Rectangle(0, 0, 0, 0); |
|---|
| 332 |
super(parent, checkStyle (parent, style)); |
|---|
| 333 |
super.setLayout(new CTabFolderLayout()); |
|---|
| 334 |
int style2 = super.getStyle(); |
|---|
| 335 |
oldFont = getFont(); |
|---|
| 336 |
onBottom = (style2 & DWT.BOTTOM) !is 0; |
|---|
| 337 |
showClose = (style2 & DWT.CLOSE) !is 0; |
|---|
| 338 |
// showMin = (style2 & DWT.MIN) !is 0; - conflicts with DWT.TOP |
|---|
| 339 |
// showMax = (style2 & DWT.MAX) !is 0; - conflicts with DWT.BOTTOM |
|---|
| 340 |
single = (style2 & DWT.SINGLE) !is 0; |
|---|
| 341 |
borderLeft = borderRight = (style & DWT.BORDER) !is 0 ? 1 : 0; |
|---|
| 342 |
borderTop = onBottom ? borderLeft : 0; |
|---|
| 343 |
borderBottom = onBottom ? 0 : borderLeft; |
|---|
| 344 |
highlight_header = (style & DWT.FLAT) !is 0 ? 1 : 3; |
|---|
| 345 |
highlight_margin = (style & DWT.FLAT) !is 0 ? 0 : 2; |
|---|
| 346 |
//set up default colors |
|---|
| 347 |
Display display = getDisplay(); |
|---|
| 348 |
selectionForeground = display.getSystemColor(SELECTION_FOREGROUND); |
|---|
| 349 |
selectionBackground = display.getSystemColor(SELECTION_BACKGROUND); |
|---|
| 350 |
borderColor = display.getSystemColor(BORDER1_COLOR); |
|---|
| 351 |
updateTabHeight(false); |
|---|
| 352 |
|
|---|
| 353 |
initAccessible(); |
|---|
| 354 |
|
|---|
| 355 |
// Add all listeners |
|---|
| 356 |
listener = new class() Listener { |
|---|
| 357 |
public void handleEvent(Event event) { |
|---|
| 358 |
switch (event.type) { |
|---|
| 359 |
case DWT.Dispose: onDispose(event); break; |
|---|
| 360 |
case DWT.DragDetect: onDragDetect(event); break; |
|---|
| 361 |
case DWT.FocusIn: onFocus(event); break; |
|---|
| 362 |
case DWT.FocusOut: onFocus(event); break; |
|---|
| 363 |
case DWT.KeyDown: onKeyDown(event); break; |
|---|
| 364 |
case DWT.MouseDoubleClick: onMouseDoubleClick(event); break; |
|---|
| 365 |
case DWT.MouseDown: onMouse(event); break; |
|---|
| 366 |
case DWT.MouseEnter: onMouse(event); break; |
|---|
| 367 |
case DWT.MouseExit: onMouse(event); break; |
|---|
| 368 |
case DWT.MouseMove: onMouse(event); break; |
|---|
| 369 |
case DWT.MouseUp: onMouse(event); break; |
|---|
| 370 |
case DWT.Paint: onPaint(event); break; |
|---|
| 371 |
case DWT.Resize: onResize(); break; |
|---|
| 372 |
case DWT.Traverse: onTraverse(event); break; |
|---|
| 373 |
default: |
|---|
| 374 |
} |
|---|
| 375 |
} |
|---|
| 376 |
}; |
|---|
| 377 |
|
|---|
| 378 |
int[] folderEvents = [ |
|---|
| 379 |
DWT.Dispose, |
|---|
| 380 |
DWT.DragDetect, |
|---|
| 381 |
DWT.FocusIn, |
|---|
| 382 |
DWT.FocusOut, |
|---|
| 383 |
DWT.KeyDown, |
|---|
| 384 |
DWT.MouseDoubleClick, |
|---|
| 385 |
DWT.MouseDown, |
|---|
| 386 |
DWT.MouseEnter, |
|---|
| 387 |
DWT.MouseExit, |
|---|
| 388 |
DWT.MouseMove, |
|---|
| 389 |
DWT.MouseUp, |
|---|
| 390 |
DWT.Paint, |
|---|
| 391 |
DWT.Resize, |
|---|
| 392 |
DWT.Traverse, |
|---|
| 393 |
]; |
|---|
| 394 |
for (int i = 0; i < folderEvents.length; i++) { |
|---|
| 395 |
addListener(folderEvents[i], listener); |
|---|
| 396 |
} |
|---|
| 397 |
} |
|---|
| 398 |
static int checkStyle (Composite parent, int style) { |
|---|
| 399 |
int mask = DWT.CLOSE | DWT.TOP | DWT.BOTTOM | DWT.FLAT | DWT.LEFT_TO_RIGHT | DWT.RIGHT_TO_LEFT | DWT.SINGLE | DWT.MULTI; |
|---|
| 400 |
style = style & mask; |
|---|
| 401 |
// TOP and BOTTOM are mutually exclusive. |
|---|
| 402 |
// TOP is the default |
|---|
| 403 |
if ((style & DWT.TOP) !is 0) style = style & ~DWT.BOTTOM; |
|---|
| 404 |
// SINGLE and MULTI are mutually exclusive. |
|---|
| 405 |
// MULTI is the default |
|---|
| 406 |
if ((style & DWT.MULTI) !is 0) style = style & ~DWT.SINGLE; |
|---|
| 407 |
// reduce the flash by not redrawing the entire area on a Resize event |
|---|
| 408 |
style |= DWT.NO_REDRAW_RESIZE; |
|---|
| 409 |
//TEMPORARY CODE |
|---|
| 410 |
/* |
|---|
| 411 |
* The default background on carbon and some GTK themes is not a solid color |
|---|
| 412 |
* but a texture. To show the correct default background, we must allow |
|---|
| 413 |
* the operating system to draw it and therefore, we can not use the |
|---|
| 414 |
* NO_BACKGROUND style. The NO_BACKGROUND style is not required on platforms |
|---|
| 415 |
* that use double buffering which is true in both of these cases. |
|---|
| 416 |
*/ |
|---|
| 417 |
String platform = DWT.getPlatform(); |
|---|
| 418 |
if ("carbon"==platform || "gtk"==platform) return style; //$NON-NLS-1$ //$NON-NLS-2$ |
|---|
| 419 |
|
|---|
| 420 |
//TEMPORARY CODE |
|---|
| 421 |
/* |
|---|
| 422 |
* In Right To Left orientation on Windows, all GC calls that use a brush are drawing |
|---|
| 423 |
* offset by one pixel. This results in some parts of the CTabFolder not drawing correctly. |
|---|
| 424 |
* To alleviate some of the appearance problems, allow the OS to draw the background. |
|---|
| 425 |
* This does not draw correctly but the result is less obviously wrong. |
|---|
| 426 |
*/ |
|---|
| 427 |
if ((style & DWT.RIGHT_TO_LEFT) !is 0) return style; |
|---|
| 428 |
if ((parent.getStyle() & DWT.MIRRORED) !is 0 && (style & DWT.LEFT_TO_RIGHT) is 0) return style; |
|---|
| 429 |
|
|---|
| 430 |
return style | DWT.NO_BACKGROUND; |
|---|
| 431 |
} |
|---|
| 432 |
static void fillRegion(GC gc, Region region) { |
|---|
| 433 |
// NOTE: region passed in to this function will be modified |
|---|
| 434 |
Region clipping = new Region(); |
|---|
| 435 |
gc.getClipping(clipping); |
|---|
| 436 |
region.intersect(clipping); |
|---|
| 437 |
gc.setClipping(region); |
|---|
| 438 |
gc.fillRectangle(region.getBounds()); |
|---|
| 439 |
gc.setClipping(clipping); |
|---|
| 440 |
clipping.dispose(); |
|---|
| 441 |
} |
|---|
| 442 |
/** |
|---|
| 443 |
* |
|---|
| 444 |
* Adds the listener to the collection of listeners who will |
|---|
| 445 |
* be notified when a tab item is closed, minimized, maximized, |
|---|
| 446 |
* restored, or to show the list of items that are not |
|---|
| 447 |
* currently visible. |
|---|
| 448 |
* |
|---|
| 449 |
* @param listener the listener which should be notified |
|---|
| 450 |
* |
|---|
| 451 |
* @exception IllegalArgumentException <ul> |
|---|
| 452 |
* <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
|---|
| 453 |
* </ul> |
|---|
| 454 |
* |
|---|
| 455 |
* @exception DWTException <ul> |
|---|
| 456 |
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li> |
|---|
| 457 |
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li> |
|---|
| 458 |
* </ul> |
|---|
| 459 |
* |
|---|
| 460 |
* @see CTabFolder2Listener |
|---|
| 461 |
* @see #removeCTabFolder2Listener(CTabFolder2Listener) |
|---|
| 462 |
* |
|---|
| 463 |
* @since 3.0 |
|---|
| 464 |
*/ |
|---|
| 465 |
public void addCTabFolder2Listener(CTabFolder2Listener listener) { |
|---|
| 466 |
checkWidget(); |
|---|
| 467 |
if (listener is null) DWT.error (DWT.ERROR_NULL_ARGUMENT); |
|---|
| 468 |
// add to array |
|---|
| 469 |
CTabFolder2Listener[] newListeners = new CTabFolder2Listener[folderListeners.length + 1]; |
|---|
| 470 |
SimpleType!(CTabFolder2Listener).arraycopy(folderListeners, 0, newListeners, 0, folderListeners.length); |
|---|
| 471 |
folderListeners = newListeners; |
|---|
| 472 |
folderListeners[folderListeners.length - 1] = listener; |
|---|
| 473 |
} |
|---|
| 474 |
/** |
|---|
| 475 |
* Adds the listener to the collection of listeners who will |
|---|
| 476 |
* be notified when a tab item is closed. |
|---|
| 477 |
* |
|---|
| 478 |
* @param listener the listener which should be notified |
|---|
| 479 |
* |
|---|
| 480 |
* @exception IllegalArgumentException <ul> |
|---|
| 481 |
* <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
|---|
| 482 |
* </ul> |
|---|
| 483 |
* @exception DWTException <ul> |
|---|
| 484 |
* <li>ERROR_THREAD_INVALID_ACCESS when called from the wrong thread</li> |
|---|
| 485 |
* <li>ERROR_WIDGET_DISPOSED when the widget has been disposed</li> |
|---|
| 486 |
* </ul> |
|---|
| 487 |
* |
|---|
| 488 |
* @see CTabFolderListener |
|---|
| 489 |
* @see #removeCTabFolderListener(CTabFolderListener) |
|---|
| 490 |
* |
|---|
| 491 |
* @deprecated use addCTabFolder2Listener(CTabFolder2Listener) |
|---|
| 492 |
*/ |
|---|
| 493 |
public void addCTabFolderListener(CTabFolderListener listener) { |
|---|
| 494 |
checkWidget(); |
|---|
| 495 |
if (listener is null) DWT.error (DWT.ERROR_NULL_ARGUMENT); |
|---|
| 496 |
// add to array |
|---|
| 497 |
CTabFolderListener[] newTabListeners = new CTabFolderListener[tabListeners.length + 1]; |
|---|
| 498 |
SimpleType!(CTabFolderListener).arraycopy(tabListeners, 0, newTabListeners, 0, tabListeners.length); |
|---|
| 499 |
tabListeners = newTabListeners; |
|---|
| 500 |
tabListeners[tabListeners.length - 1] = listener; |
|---|
| 501 |
// display close button to be backwards compatible |
|---|
| 502 |
if (!showClose) { |
|---|
| 503 |
showClose = true; |
|---|
| 504 |
updateItems(); |
|---|
| 505 |
redraw(); |
|---|
| 506 |
} |
|---|
| 507 |
} |
|---|
| 508 |
/** |
|---|
| 509 |
* Adds the listener to the collection of listeners who will |
|---|
| 510 |
* be notified when the user changes the receiver's selection, by sending |
|---|
| 511 |
* it one of the messages defined in the <code>SelectionListener</code> |
|---|
| 512 |
* interface. |
|---|
| 513 |
* <p> |
|---|
| 514 |
* <code>widgetSelected</code> is called when the user changes the selected tab. |
|---|
| 515 |
* <code>widgetDefaultSelected</code> is not called. |
|---|
| 516 |
* </p> |
|---|
| 517 |
* |
|---|
| 518 |
* @param listener the listener which should be notified when the user changes the receiver's selection |
|---|
| 519 |
* |
|---|
| 520 |
* @exception IllegalArgumentException <ul> |
|---|
| 521 |
* <li>ERROR_NULL_ARGUMENT - if the listener is null</li> |
|---|
| 522 |
* </ul> |
|---|
| 523 |
* @exception DWTException <ul> |
|---|
| 524 |
* <li>ERROR_WIDGET_DISPOSED - if the receiver has been disposed</li> |
|---|
| 525 |
* <li>ERROR_THREAD_INVALID_ACCESS - if not called from the thread that created the receiver</li> |
|---|
| 526 |
* </ul> |
|---|
| 527 |
* |
|---|
| 528 |
* @see SelectionListener |
|---|
| 529 |
* @see #removeSelectionListener |
|---|
| 530 |
* @see SelectionEvent |
|---|
| 531 |
*/ |
|---|
| 532 |
public void addSelectionListener(SelectionListener listener) { |
|---|
| 533 |
checkWidget(); |
|---|
| 534 |
if (listener is null) { |
|---|
| 535 |
DWT.error(DWT.ERROR_NULL_ARGUMENT); |
|---|
| 536 |
} |
|---|
| 537 |
TypedListener typedListener = new TypedListener(listener); |
|---|
| 538 |
addListener(DWT.Selection, typedListener); |
|---|
| 539 |
addListener(DWT.DefaultSelection, typedListener); |
|---|
| 540 |
} |
|---|
| 541 |
void antialias (int[] shape, RGB lineRGB, RGB innerRGB, RGB outerRGB, GC gc){ |
|---|
| 542 |
// Don't perform anti-aliasing on Mac and WPF because the platform |
|---|
| 543 |
// already does it. The simple style also does not require anti-aliasing. |
|---|
| 544 |
if (simple || "carbon".equals(DWT.getPlatform()) || "wpf".equals(DWT.getPlatform())) return; //$NON-NLS-1$ |
|---|
| 545 |
// Don't perform anti-aliasing on low resolution displays |
|---|
| 546 |
if (getDisplay().getDepth() < 15) return; |
|---|
| 547 |
if (outerRGB !is null) { |
|---|
| 548 |
int index = 0; |
|---|
| 549 |
bool left = true; |
|---|
| 550 |
int oldY = onBottom ? 0 : getSize().y; |
|---|
| 551 |
int[] outer = new int[shape.length]; |
|---|
| 552 |
for (int i = 0; i < shape.length/2; i++) { |
|---|
| 553 |
if (left && (index + 3 < shape.length)) { |
|---|
| 554 |
left = onBottom ? oldY <= shape[index+3] : oldY >= shape[index+3]; |
|---|
| 555 |
oldY = shape[index+1]; |
|---|
| 556 |
} |
|---|
| 557 |
outer[index] = shape[index] + (left ? -1 : +1); |
|---|
| 558 |
index++; |
|---|
| 559 |
outer[index] = shape[index]; |
|---|
| 560 |
index++; |
|---|
| 561 |
} |
|---|
| 562 |
RGB from = lineRGB; |
|---|
| 563 |
RGB to = outerRGB; |
|---|
| 564 |
int red = from.red + 2*(to.red - from.red)/3; |
|---|
| 565 |
int green = from.green + 2*(to.green - from.green)/3; |
|---|
| 566 |
int blue = from.blue + 2*(to.blue - from.blue)/3; |
|---|
| 567 |
Color color = new Color(getDisplay(), red, green, blue); |
|---|
| 568 |
gc.setForeground(color); |
|---|