1 11 package org.eclipse.ui.forms.widgets; 12 13 import java.util.List ; 14 15 import org.eclipse.jface.util.Geometry; 16 import org.eclipse.swt.SWT; 17 import org.eclipse.swt.graphics.Point; 18 import org.eclipse.swt.graphics.Rectangle; 19 import org.eclipse.swt.widgets.Button; 20 import org.eclipse.swt.widgets.Combo; 21 import org.eclipse.swt.widgets.Composite; 22 import org.eclipse.swt.widgets.Control; 23 import org.eclipse.swt.widgets.Label; 24 import org.eclipse.swt.widgets.Layout; 25 import org.eclipse.swt.widgets.ProgressBar; 26 import org.eclipse.swt.widgets.Sash; 27 import org.eclipse.swt.widgets.Scale; 28 import org.eclipse.swt.widgets.Scrollable; 29 import org.eclipse.swt.widgets.Slider; 30 import org.eclipse.swt.widgets.Text; 31 import org.eclipse.swt.widgets.ToolBar; 32 import org.eclipse.swt.widgets.Tree; 33 import org.eclipse.ui.internal.forms.widgets.FormUtil; 34 35 40 public class SizeCache { 41 private Control control; 42 43 private Point preferredSize; 44 45 private int cachedWidthQuery; 46 private int cachedWidthResult; 47 48 private int cachedHeightQuery; 49 private int cachedHeightResult; 50 51 private int minimumWidth; 52 private int heightAtMinimumWidth = -1; 53 private int maximumWidth; 54 55 58 private boolean flushChildren; 59 60 64 private boolean independentDimensions = false; 65 66 70 private boolean preferredWidthOrLargerIsMinimumHeight = false; 71 72 private int widthAdjustment = 0; 77 78 private int heightAdjustment = 0; 79 80 private int minimumHeight; 81 82 private int widthAtMinimumHeight = -1; 83 84 private Point dirtySize = null; 87 88 89 91 public SizeCache() { 92 this(null); 93 } 94 95 101 public SizeCache(Control control) { 102 setControl(control); 103 } 104 105 111 public void setControl(Control newControl) { 112 if (newControl != control) { 113 control = newControl; 114 if (control == null) { 115 independentDimensions = true; 116 preferredWidthOrLargerIsMinimumHeight = false; 117 widthAdjustment = 0; 118 heightAdjustment = 0; 119 } else { 120 independentDimensions = independentLengthAndWidth(control); 121 preferredWidthOrLargerIsMinimumHeight = isPreferredWidthMaximum(control); 122 computeHintOffset(control); 123 flush(); 124 } 125 } 126 } 127 128 133 public Control getControl() { 134 return control; 135 } 136 137 141 public void flush() { 142 flush(true); 143 } 144 145 public void flush(boolean recursive) { 146 preferredSize = null; 147 cachedWidthQuery = -1; 148 cachedWidthResult = -1; 149 cachedHeightQuery = -1; 150 cachedHeightResult = -1; 151 minimumWidth = -1; 152 maximumWidth = -1; 153 minimumHeight = -1; 154 heightAtMinimumWidth = -1; 155 widthAtMinimumHeight = -1; 156 157 if (recursive || dirtySize != null) { 158 if (control == null || control.isDisposed()) { 159 dirtySize = new Point(0,0); 160 control = null; 161 } else { 162 dirtySize = control.getSize(); 163 } 164 } 165 166 this.flushChildren = this.flushChildren || recursive; 167 } 168 169 private Point getPreferredSize() { 170 if (preferredSize == null) { 171 preferredSize = controlComputeSize(SWT.DEFAULT, SWT.DEFAULT); 172 } 173 174 return preferredSize; 175 } 176 177 184 public Point computeSize(int widthHint, int heightHint) { 185 if (control == null || control.isDisposed()) { 186 return new Point(0, 0); 187 } 188 189 int minWidth = computeMinimumWidth(); 191 192 if (widthHint != SWT.DEFAULT && widthHint + widthAdjustment < minWidth) { 193 if (heightHint == SWT.DEFAULT) { 194 return new Point(minWidth, computeHeightAtMinimumWidth()); 195 } 196 197 widthHint = minWidth - widthAdjustment; 198 } 199 200 int minHeight = computeMinimumHeight(); 202 203 if (heightHint != SWT.DEFAULT && heightHint + heightAdjustment < minHeight) { 204 if (widthHint == SWT.DEFAULT) { 205 return new Point(computeWidthAtMinimumHeight(), minHeight); 206 } 207 208 heightHint = minHeight - heightAdjustment; 209 } 210 211 if (widthHint != SWT.DEFAULT && heightHint != SWT.DEFAULT) { 213 return new Point(widthHint + widthAdjustment, heightHint + heightAdjustment); 214 } 215 216 if (widthHint == SWT.DEFAULT && heightHint == SWT.DEFAULT) { 218 return Geometry.copy(getPreferredSize()); 219 } 220 221 if (independentDimensions) { 224 Point result = Geometry.copy(getPreferredSize()); 225 226 if (widthHint != SWT.DEFAULT) { 227 result.x = widthHint + widthAdjustment; 228 } 229 230 if (heightHint != SWT.DEFAULT) { 231 result.y = heightHint + heightAdjustment; 232 } 233 234 return result; 235 } 236 237 if (heightHint == SWT.DEFAULT) { 239 if (preferredSize != null) { 241 if (widthHint + widthAdjustment == preferredSize.x) { 243 return Geometry.copy(preferredSize); 244 } 245 } 246 247 if (cachedHeightQuery != -1) { 249 if (cachedHeightQuery == widthHint) { 251 return new Point(widthHint + widthAdjustment, cachedHeightResult); 252 } 253 } 254 255 if (preferredWidthOrLargerIsMinimumHeight) { 259 getPreferredSize(); 261 262 if (widthHint + widthAdjustment >= preferredSize.x) { 265 return new Point(widthHint + widthAdjustment, preferredSize.y); 266 } 267 } 268 269 Point newHeight = controlComputeSize(widthHint - widthAdjustment, SWT.DEFAULT); 272 273 cachedHeightQuery = heightHint; 274 cachedHeightResult = newHeight.y; 275 276 return newHeight; 277 } 278 279 if (widthHint == SWT.DEFAULT) { 281 if (preferredSize != null) { 283 if (heightHint + heightAdjustment == preferredSize.y) { 285 return Geometry.copy(preferredSize); 286 } 287 } 288 289 if (cachedWidthQuery == heightHint) { 291 return new Point(cachedWidthResult, heightHint + heightAdjustment); 292 } 293 294 Point widthResult = controlComputeSize(SWT.DEFAULT, heightHint - heightAdjustment); 295 296 cachedWidthQuery = heightHint; 297 cachedWidthResult = widthResult.x; 298 299 return widthResult; 300 } 301 302 return controlComputeSize(widthHint, heightHint); 303 } 304 305 314 public Point computeAdjustedSize(int widthHint, int heightHint) { 315 int adjustedWidthHint = widthHint == SWT.DEFAULT ? SWT.DEFAULT : Math 316 .max(0, widthHint - widthAdjustment); 317 int adjustedHeightHint = heightHint == SWT.DEFAULT ? SWT.DEFAULT : Math 318 .max(0, heightHint - heightAdjustment); 319 320 Point result = computeSize(adjustedWidthHint, adjustedHeightHint); 321 322 325 return result; 326 } 327 328 344 static boolean independentLengthAndWidth(Control control) { 345 if (control == null || control.isDisposed()) { 346 return true; 347 } 348 349 if (control instanceof Button || control instanceof ProgressBar 350 || control instanceof Sash || control instanceof Scale 351 || control instanceof Slider || control instanceof List 352 || control instanceof Combo || control instanceof Tree) { 353 return true; 354 } 355 356 if (control instanceof Label || control instanceof Text) { 357 return (control.getStyle() & SWT.WRAP) == 0; 358 } 359 360 363 return false; 364 } 365 366 375 private void computeHintOffset(Control control) { 376 if (control instanceof Scrollable) { 377 Scrollable scrollable = (Scrollable) control; 379 Rectangle trim = scrollable.computeTrim(0, 0, 0, 0); 380 381 widthAdjustment = trim.width; 382 heightAdjustment = trim.height; 383 } else { 384 widthAdjustment = control.getBorderWidth() * 2; 386 heightAdjustment = widthAdjustment; 387 } 388 } 389 390 private Point controlComputeSize(int widthHint, int heightHint) { 391 Point result = control.computeSize(widthHint, heightHint, flushChildren); 392 flushChildren = false; 393 394 return result; 395 } 396 397 412 private static boolean isPreferredWidthMaximum(Control control) { 413 return (control instanceof ToolBar 414 || control instanceof Label); 416 } 417 418 public int computeMinimumWidth() { 419 if (minimumWidth == -1) { 420 if (control instanceof Composite) { 421 Layout layout = ((Composite)control).getLayout(); 422 if (layout instanceof ILayoutExtension) { 423 minimumWidth = ((ILayoutExtension)layout).computeMinimumWidth((Composite)control, flushChildren); 424 flushChildren = false; 425 } 426 } 427 } 428 429 if (minimumWidth == -1) { 430 Point minWidth = controlComputeSize(FormUtil.getWidthHint(5, control), SWT.DEFAULT); 431 minimumWidth = minWidth.x; 432 heightAtMinimumWidth = minWidth.y; 433 } 434 435 return minimumWidth; 436 } 437 438 public int computeMaximumWidth() { 439 if (maximumWidth == -1) { 440 if (control instanceof Composite) { 441 Layout layout = ((Composite)control).getLayout(); 442 if (layout instanceof ILayoutExtension) { 443 maximumWidth = ((ILayoutExtension)layout).computeMaximumWidth((Composite)control, flushChildren); 444 flushChildren = false; 445 } 446 } 447 } 448 449 if (maximumWidth == -1) { 450 maximumWidth = getPreferredSize().x; 451 } 452 453 return maximumWidth; 454 } 455 456 private int computeHeightAtMinimumWidth() { 457 int minimumWidth = computeMinimumWidth(); 458 459 if (heightAtMinimumWidth == -1) { 460 heightAtMinimumWidth = controlComputeSize(minimumWidth - widthAdjustment, SWT.DEFAULT).y; 461 } 462 463 return heightAtMinimumWidth; 464 } 465 466 private int computeWidthAtMinimumHeight() { 467 int minimumHeight = computeMinimumHeight(); 468 469 if (widthAtMinimumHeight == -1) { 470 widthAtMinimumHeight = controlComputeSize(SWT.DEFAULT, minimumHeight - heightAdjustment).x; 471 } 472 473 return widthAtMinimumHeight; 474 } 475 476 private int computeMinimumHeight() { 477 if (minimumHeight == -1) { 478 Point sizeAtMinHeight = controlComputeSize(SWT.DEFAULT, 0); 479 480 minimumHeight = sizeAtMinHeight.y; 481 widthAtMinimumHeight = sizeAtMinHeight.x; 482 } 483 484 return minimumHeight; 485 } 486 487 public Point computeMinimumSize() { 488 return new Point(computeMinimumWidth(), computeMinimumHeight()); 489 } 490 491 public void setSize(Point newSize) { 492 if (control != null) { 493 control.setSize(newSize); 494 } 495 496 layoutIfNecessary(); 497 } 498 499 public void setSize(int width, int height) { 500 if (control != null) { 501 control.setSize(width, height); 502 } 503 504 layoutIfNecessary(); 505 } 506 507 public void setBounds(int x, int y, int width, int height) { 508 if (control != null) { 509 control.setBounds(x, y, width, height); 510 } 511 512 layoutIfNecessary(); 513 } 514 515 public void setBounds(Rectangle bounds) { 516 if (control != null) { 517 control.setBounds(bounds); 518 } 519 520 layoutIfNecessary(); 521 } 522 523 public void layoutIfNecessary() { 524 if (dirtySize != null && control != null && control instanceof Composite) { 525 if (control.getSize().equals(dirtySize)) { 526 ((Composite)control).layout(flushChildren); 527 flushChildren = false; 528 } 529 } 530 dirtySize = null; 531 } 532 } 533 | Popular Tags |