| /******************************************************************************* |
| * Copyright (c) 2000, 2006 IBM Corporation and others. |
| * |
| * This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License 2.0 |
| * which accompanies this distribution, and is available at |
| * https://www.eclipse.org/legal/epl-2.0/ |
| * |
| * SPDX-License-Identifier: EPL-2.0 |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| package org.eclipse.swt.custom; |
| |
| import org.eclipse.swt.*; |
| import org.eclipse.swt.graphics.*; |
| import org.eclipse.swt.widgets.*; |
| |
| /** |
| * This class provides the layout for CBanner |
| * |
| * @see CBanner |
| */ |
| class CBannerLayout extends Layout { |
| |
| @Override |
| protected Point computeSize(Composite composite, int wHint, int hHint, boolean flushCache) { |
| CBanner banner = (CBanner)composite; |
| Control left = banner.left; |
| Control right = banner.right; |
| Control bottom = banner.bottom; |
| boolean showCurve = left != null && right != null; |
| int height = hHint; |
| int width = wHint; |
| |
| // Calculate component sizes |
| Point bottomSize = new Point(0, 0); |
| if (bottom != null) { |
| int trim = computeTrim(bottom); |
| int w = wHint == SWT.DEFAULT ? SWT.DEFAULT : Math.max(0, width - trim); |
| bottomSize = computeChildSize(bottom, w, SWT.DEFAULT, flushCache); |
| } |
| Point rightSize = new Point(0, 0); |
| if (right != null) { |
| int trim = computeTrim(right); |
| int w = SWT.DEFAULT; |
| if (banner.rightWidth != SWT.DEFAULT) { |
| w = banner.rightWidth - trim; |
| if (left != null) { |
| w = Math.min(w, width - banner.curve_width + 2* banner.curve_indent - CBanner.MIN_LEFT - trim); |
| } |
| w = Math.max(0, w); |
| } |
| rightSize = computeChildSize(right, w, SWT.DEFAULT, flushCache); |
| if (wHint != SWT.DEFAULT) { |
| width -= rightSize.x + banner.curve_width - 2* banner.curve_indent; |
| } |
| } |
| Point leftSize = new Point(0, 0); |
| if (left != null) { |
| int trim = computeTrim(left); |
| int w = wHint == SWT.DEFAULT ? SWT.DEFAULT : Math.max(0, width - trim); |
| leftSize = computeChildSize(left, w, SWT.DEFAULT, flushCache); |
| } |
| |
| // Add up sizes |
| width = leftSize.x + rightSize.x; |
| height = bottomSize.y; |
| if (bottom != null && (left != null || right != null)) { |
| height += CBanner.BORDER_STRIPE + 2; |
| } |
| if (left != null) { |
| if (right == null) { |
| height += leftSize.y; |
| } else { |
| height += Math.max(leftSize.y, banner.rightMinHeight == SWT.DEFAULT ? rightSize.y : banner.rightMinHeight); |
| } |
| } else { |
| height += rightSize.y; |
| } |
| if (showCurve) { |
| width += banner.curve_width - 2*banner.curve_indent; |
| height += CBanner.BORDER_TOP + CBanner.BORDER_BOTTOM + 2*CBanner.BORDER_STRIPE; |
| } |
| |
| if (wHint != SWT.DEFAULT) width = wHint; |
| if (hHint != SWT.DEFAULT) height = hHint; |
| |
| return new Point(width, height); |
| } |
| Point computeChildSize(Control control, int wHint, int hHint, boolean flushCache) { |
| Object data = control.getLayoutData(); |
| if (data == null || !(data instanceof CLayoutData)) { |
| data = new CLayoutData(); |
| control.setLayoutData(data); |
| } |
| return ((CLayoutData)data).computeSize(control, wHint, hHint, flushCache); |
| } |
| int computeTrim(Control c) { |
| if (c instanceof Scrollable) { |
| Rectangle rect = ((Scrollable) c).computeTrim (0, 0, 0, 0); |
| return rect.width; |
| } |
| return c.getBorderWidth () * 2; |
| } |
| @Override |
| protected boolean flushCache(Control control) { |
| Object data = control.getLayoutData(); |
| if (data != null && data instanceof CLayoutData) ((CLayoutData)data).flushCache(); |
| return true; |
| } |
| @Override |
| protected void layout(Composite composite, boolean flushCache) { |
| CBanner banner = (CBanner)composite; |
| Control left = banner.left; |
| Control right = banner.right; |
| Control bottom = banner.bottom; |
| |
| Point size = banner.getSize(); |
| boolean showCurve = left != null && right != null; |
| int width = size.x - 2*banner.getBorderWidth(); |
| int height = size.y - 2*banner.getBorderWidth(); |
| |
| Point bottomSize = new Point(0, 0); |
| if (bottom != null) { |
| int trim = computeTrim(bottom); |
| int w = Math.max(0, width - trim); |
| bottomSize = computeChildSize(bottom, w, SWT.DEFAULT, flushCache); |
| height -= bottomSize.y + CBanner.BORDER_STRIPE + 2; |
| } |
| if (showCurve) height -= CBanner.BORDER_TOP + CBanner.BORDER_BOTTOM + 2*CBanner.BORDER_STRIPE; |
| height = Math.max(0, height); |
| Point rightSize = new Point(0,0); |
| if (right != null) { |
| int trim = computeTrim(right); |
| int w = SWT.DEFAULT; |
| if (banner.rightWidth != SWT.DEFAULT) { |
| w = banner.rightWidth - trim; |
| if (left != null) { |
| w = Math.min(w, width - banner.curve_width + 2* banner.curve_indent - CBanner.MIN_LEFT - trim); |
| } |
| w = Math.max(0, w); |
| } |
| rightSize = computeChildSize(right, w, SWT.DEFAULT, flushCache); |
| width = width - (rightSize.x - banner.curve_indent + banner.curve_width - banner.curve_indent); |
| } |
| Point leftSize = new Point(0, 0); |
| if (left != null) { |
| int trim = computeTrim(left); |
| int w = Math.max(0, width - trim); |
| leftSize = computeChildSize(left, w, SWT.DEFAULT, flushCache); |
| } |
| |
| int x = 0; |
| int y = 0; |
| int oldStart = banner.curveStart; |
| Rectangle leftRect = null; |
| Rectangle rightRect = null; |
| Rectangle bottomRect = null; |
| if (bottom != null) { |
| bottomRect = new Rectangle(x, y+size.y-bottomSize.y, bottomSize.x, bottomSize.y); |
| } |
| if (showCurve) y += CBanner.BORDER_TOP + CBanner.BORDER_STRIPE; |
| if(left != null) { |
| leftRect = new Rectangle(x, y, leftSize.x, leftSize.y); |
| banner.curveStart = x + leftSize.x - banner.curve_indent; |
| x += leftSize.x - banner.curve_indent + banner.curve_width - banner.curve_indent; |
| } |
| if (right != null) { |
| if (left != null) { |
| rightSize.y = Math.max(leftSize.y, banner.rightMinHeight == SWT.DEFAULT ? rightSize.y : banner.rightMinHeight); |
| } |
| rightRect = new Rectangle(x, y, rightSize.x, rightSize.y); |
| } |
| if (banner.curveStart < oldStart) { |
| banner.redraw(banner.curveStart - CBanner.CURVE_TAIL, 0, oldStart + banner.curve_width - banner.curveStart + CBanner.CURVE_TAIL + 5, size.y, false); |
| } |
| if (banner.curveStart > oldStart) { |
| banner.redraw(oldStart - CBanner.CURVE_TAIL, 0, banner.curveStart + banner.curve_width - oldStart + CBanner.CURVE_TAIL + 5, size.y, false); |
| } |
| /* |
| * The paint events must be flushed in order to make the curve draw smoothly |
| * while the user drags the divider. |
| * On Windows, it is necessary to flush the paints before the children are |
| * resized because otherwise the children (particularly toolbars) will flash. |
| */ |
| banner.update(); |
| banner.curveRect = new Rectangle(banner.curveStart, 0, banner.curve_width, size.y); |
| if (bottomRect != null) bottom.setBounds(bottomRect); |
| if (rightRect != null) right.setBounds(rightRect); |
| if (leftRect != null) left.setBounds(leftRect); |
| } |
| } |