1 15 package org.eclipse.ui.internal; 16 17 import java.util.ArrayList ; 18 19 import org.eclipse.core.runtime.Assert; 20 import org.eclipse.jface.util.Geometry; 21 import org.eclipse.swt.SWT; 22 import org.eclipse.swt.graphics.Point; 23 import org.eclipse.swt.graphics.Rectangle; 24 import org.eclipse.swt.widgets.Composite; 25 import org.eclipse.ui.ISizeProvider; 26 27 33 public class LayoutTree implements ISizeProvider { 34 35 LayoutTreeNode parent; 36 37 38 LayoutPart part; 39 40 private int cachedMinimumWidthHint = SWT.DEFAULT; 42 private int cachedMinimumWidth = SWT.DEFAULT; 43 private int cachedMinimumHeightHint = SWT.DEFAULT; 44 private int cachedMinimumHeight = SWT.DEFAULT; 45 private int cachedMaximumWidthHint = SWT.DEFAULT; 46 private int cachedMaximumWidth = SWT.DEFAULT; 47 private int cachedMaximumHeightHint = SWT.DEFAULT; 48 private int cachedMaximumHeight = SWT.DEFAULT; 49 50 private boolean sizeFlagsDirty = true; 52 private int widthSizeFlags = 0; 53 private int heightSizeFlags = 0; 54 55 public static int minCacheHits; 57 public static int minCacheMisses; 58 public static int maxCacheHits; 59 public static int maxCacheMisses; 60 61 private boolean forceLayout = true; 62 private Rectangle currentBounds = new Rectangle(0,0,0,0); 63 64 67 public LayoutTree(LayoutPart part) { 68 this.part = part; 69 } 70 71 75 public LayoutPart computeRelation(ArrayList relations) { 76 return part; 77 } 78 79 85 public LayoutPart findPart(Point toFind) { 86 return part; 87 } 88 89 92 public void disposeSashes() { 93 } 94 95 99 public LayoutTree find(LayoutPart child) { 100 if (part != child) { 101 return null; 102 } 103 return this; 104 } 105 106 111 public void findSashes(PartPane.Sashes sashes) { 112 if (getParent() == null) { 113 return; 114 } 115 getParent().findSashes(this, sashes); 116 } 117 118 121 public LayoutPart findBottomRight() { 122 return part; 123 } 124 125 129 public LayoutTreeNode findSash(LayoutPartSash sash) { 130 return null; 131 } 132 133 137 public final Rectangle getBounds() { 138 return Geometry.copy(currentBounds); 139 } 140 141 150 public static int subtract(int a, int b) { 151 Assert.isTrue(b >= 0 && b < INFINITE); 152 153 return add(a, -b); 154 } 155 156 164 public static int add(int a, int b) { 165 if (a == INFINITE || b == INFINITE) { 166 return INFINITE; 167 } 168 169 return a + b; 170 } 171 172 181 public static void assertValidSize(int toCheck) { 182 Assert.isTrue(toCheck >= 0 && (toCheck == INFINITE || toCheck < INFINITE / 2)); 183 } 184 185 194 public final int computePreferredSize(boolean width, int availableParallel, int availablePerpendicular, int preferredParallel) { 195 assertValidSize(availableParallel); 196 assertValidSize(availablePerpendicular); 197 assertValidSize(preferredParallel); 198 199 if (!isVisible()) { 200 return 0; 201 } 202 203 if (availableParallel == 0) { 204 return 0; 205 } 206 207 if (preferredParallel == 0) { 208 return Math.min(availableParallel, computeMinimumSize(width, availablePerpendicular)); 209 } else if (preferredParallel == INFINITE && availableParallel == INFINITE) { 210 return computeMaximumSize(width, availablePerpendicular); 211 } 212 213 if (!hasSizeFlag(width, SWT.FILL)) { 216 return preferredParallel; 217 } 218 219 int result = doComputePreferredSize(width, availableParallel, availablePerpendicular, preferredParallel); 220 221 return result; 222 } 223 224 232 protected int doGetSizeFlags(boolean width) { 233 return part.getSizeFlags(width); 234 } 235 236 243 protected int doComputePreferredSize(boolean width, int availableParallel, int availablePerpendicular, int preferredParallel) { 244 int result = Math.min(availableParallel, 245 part.computePreferredSize(width, availableParallel, availablePerpendicular, preferredParallel)); 246 247 assertValidSize(result); 248 return result; 249 } 250 251 264 public final int computeMinimumSize(boolean width, int availablePerpendicular) { 265 assertValidSize(availablePerpendicular); 266 267 if (!hasSizeFlag(width, SWT.MIN)) { 270 return 0; 271 } 272 273 if (!hasSizeFlag(width, SWT.WRAP)) { 278 availablePerpendicular = INFINITE; 279 } 280 281 if (width) { 282 if (cachedMinimumWidthHint == availablePerpendicular) { 285 minCacheHits++; 286 return cachedMinimumWidth; 287 } 288 289 291 minCacheMisses++; 292 293 int result = doComputeMinimumSize(width, availablePerpendicular); 294 cachedMinimumWidth = result; 295 cachedMinimumWidthHint = availablePerpendicular; 296 return result; 297 298 } else { 299 if (cachedMinimumHeightHint == availablePerpendicular) { 302 minCacheHits++; 303 return cachedMinimumHeight; 304 } 305 306 minCacheMisses++; 308 309 int result = doComputeMinimumSize(width, availablePerpendicular); 310 cachedMinimumHeight = result; 311 cachedMinimumHeightHint = availablePerpendicular; 312 return result; 313 } 314 } 315 316 322 public static void printCacheStatistics() { 323 System.out.println("minimize cache " + minCacheHits + " / " + (minCacheHits + minCacheMisses) + " hits " + minCacheHits * 100 / (minCacheHits + minCacheMisses) + "%"); System.out.println("maximize cache " + maxCacheHits + " / " + (maxCacheHits + maxCacheMisses) + " hits" + maxCacheHits * 100 / (maxCacheHits + maxCacheMisses) + "%"); } 328 329 public int doComputeMinimumSize(boolean width, int availablePerpendicular) { 330 int result = doComputePreferredSize(width, INFINITE, availablePerpendicular, 0); 331 assertValidSize(result); 332 return result; 333 } 334 335 public final int computeMaximumSize(boolean width, int availablePerpendicular) { 336 assertValidSize(availablePerpendicular); 337 338 if (!hasSizeFlag(width, SWT.MAX)) { 341 return INFINITE; 342 } 343 344 if (!hasSizeFlag(width, SWT.WRAP)) { 349 availablePerpendicular = INFINITE; 350 } 351 352 if (width) { 353 if (cachedMaximumWidthHint == availablePerpendicular) { 356 maxCacheHits++; 357 return cachedMaximumWidth; 358 } 359 360 maxCacheMisses++; 361 362 int result = doComputeMaximumSize(width, availablePerpendicular); 364 cachedMaximumWidth = result; 365 cachedMaximumWidthHint = availablePerpendicular; 366 return result; 367 368 } else { 369 if (cachedMaximumHeightHint == availablePerpendicular) { 371 maxCacheHits++; 372 return cachedMaximumHeight; 373 } 374 375 maxCacheMisses++; 376 377 int result = doComputeMaximumSize(width, availablePerpendicular); 379 cachedMaximumHeight = result; 380 cachedMaximumHeightHint = availablePerpendicular; 381 return result; 382 } 383 } 384 385 protected int doComputeMaximumSize(boolean width, int availablePerpendicular) { 386 return doComputePreferredSize(width, INFINITE, availablePerpendicular, INFINITE); 387 } 388 389 392 public void flushNode() { 393 394 cachedMinimumWidthHint = SWT.DEFAULT; 396 cachedMinimumWidth = SWT.DEFAULT; 397 cachedMinimumHeightHint = SWT.DEFAULT; 398 cachedMinimumHeight = SWT.DEFAULT; 399 cachedMaximumWidthHint = SWT.DEFAULT; 400 cachedMaximumWidth = SWT.DEFAULT; 401 cachedMaximumHeightHint = SWT.DEFAULT; 402 cachedMaximumHeight = SWT.DEFAULT; 403 404 sizeFlagsDirty = true; 406 407 forceLayout = true; 410 } 411 412 420 public void flushChildren() { 421 flushNode(); 422 } 423 424 430 public final void flushCache() { 431 flushNode(); 432 433 if (parent != null) { 434 parent.flushCache(); 435 } 436 } 437 438 public final int getSizeFlags(boolean width) { 439 if (sizeFlagsDirty) { 440 widthSizeFlags = doGetSizeFlags(true); 441 heightSizeFlags = doGetSizeFlags(false); 442 sizeFlagsDirty = false; 443 } 444 445 return width ? widthSizeFlags : heightSizeFlags; 446 } 447 448 451 public LayoutTreeNode getParent() { 452 return parent; 453 } 454 455 459 public LayoutTree insert(LayoutPart child, boolean left, 460 LayoutPartSash sash, LayoutPart relative) { 461 LayoutTree relativeChild = find(relative); 462 LayoutTreeNode node = new LayoutTreeNode(sash); 463 if (relativeChild == null) { 464 node.setChild(left, child); 466 node.setChild(!left, this); 467 return node; 468 } else { 469 LayoutTreeNode oldParent = relativeChild.getParent(); 470 node.setChild(left, child); 471 node.setChild(!left, relativeChild); 472 if (oldParent == null) { 473 return node; 475 } 476 oldParent.replaceChild(relativeChild, node); 477 return this; 478 } 479 } 480 481 485 public boolean isCompressible() { 486 return part.isCompressible(); 488 } 489 490 493 public boolean isVisible() { 494 return !(part instanceof PartPlaceholder); 495 } 496 497 500 public void recomputeRatio() { 501 } 502 503 508 public LayoutTree remove(LayoutPart child) { 509 LayoutTree tree = find(child); 510 if (tree == null) { 511 return this; 512 } 513 LayoutTreeNode oldParent = tree.getParent(); 514 if (oldParent == null) { 515 return null; 517 } 518 if (oldParent.getParent() == null) { 519 return oldParent.remove(tree); 520 } 521 522 oldParent.remove(tree); 523 return this; 524 } 525 526 534 public final void setBounds(Rectangle bounds) { 535 if (!bounds.equals(currentBounds) || forceLayout) { 536 currentBounds = Geometry.copy(bounds); 537 538 doSetBounds(currentBounds); 539 forceLayout = false; 540 } 541 } 542 543 546 protected void doSetBounds(Rectangle bounds) { 547 part.setBounds(bounds); 548 } 549 550 553 void setParent(LayoutTreeNode parent) { 554 this.parent = parent; 555 } 556 557 560 void setPart(LayoutPart part) { 561 this.part = part; 562 flushCache(); 563 } 564 565 568 public String toString() { 569 return "(" + part.toString() + ")"; } 571 572 579 public void createControl(Composite parent) { 580 } 581 582 595 public void describeLayout(StringBuffer buf) { 596 part.describeLayout(buf); 597 } 598 599 610 public final boolean hasSizeFlag(boolean width, int flag) { 611 return (getSizeFlags(width) & flag) != 0; 612 } 613 614 } 615 | Popular Tags |