Mercurial > projects > dwt2
view org.eclipse.swt.gtk.linux.x86/src/org/eclipse/swt/layout/RowLayout.d @ 120:536e43f63c81
Comprehensive update for Win32/Linux32 dmd-2.053/dmd-1.068+Tango-r5661
===D2===
* added [Try]Immutable/Const/Shared templates to work with differenses in D1/D2 instead of version statements
used these templates to work with strict type storage rules of dmd-2.053
* com.ibm.icu now also compilable with D2, but not tested yet
* small fixes
Snippet288 - shared data is in TLS
===Phobos===
* fixed critical bugs in Phobos implemention
completely incorrect segfault prone fromStringz (Linux's port ruthless killer)
terrible, incorrect StringBuffer realization (StyledText killer)
* fixed small bugs as well
Snippet72 - misprint in the snippet
* implemented missed functionality for Phobos
ByteArrayOutputStream implemented (image loading available)
formatting correctly works for all DWT's cases
As a result, folowing snippets now works with Phobos (Snippet### - what is fixed):
Snippet24, 42, 111, 115, 130, 235, 276 - bad string formatting
Snippet48, 282 - crash on image loading
Snippet163, 189, 211, 213, 217, 218, 222 - crash on copy/cut in StyledText
Snippet244 - hang-up
===Tango===
* few changes for the latest Tango trunc-r5661
* few small performance improvments
===General===
* implMissing-s for only one version changed to implMissingInTango/InPhobos
* incorrect calls to Format in toString-s fixed
* fixed loading \uXXXX characters in ResourceBundle
* added good UTF-8 support for StyledText, TextLayout (Win32) and friends
UTF functions revised and tested. It is now in java.nonstandard.*Utf modules
StyledText and TextLayout (Win32) modules revised for UTF-8 support
* removed small diferences in most identical files in *.swt.* folders
*.swt.internal.image, *.swt.events and *.swt.custom are identical in Win32/Linux32
now 179 of 576 (~31%) files in *.swt.* folders are fully identical
* Win32: snippets now have right subsystem, pretty icons and native system style controls
* small fixes in snippets
Snippet44 - it's not Snippet44
Snippet212 - functions work with different images and offsets arrays
Win32: Snippet282 - crash on close if the button has an image
Snippet293 - setGrayed is commented
and others
Win32: As a result, folowing snippets now works
Snippet68 - color doesn't change
Snippet163, 189, 211, 213, 217, 218, 222 - UTF-8 issues (see above)
Snippet193 - no tabel headers
author | Denis Shelomovskij <verylonglogin.reg@gmail.com> |
---|---|
date | Sat, 09 Jul 2011 15:50:20 +0300 |
parents | c01d033c633a |
children |
line wrap: on
line source
/******************************************************************************* * Copyright (c) 2000, 2008 IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * IBM Corporation - initial API and implementation * Port to the D programming language: * Frank Benoit <benoit@tionex.de> *******************************************************************************/ module org.eclipse.swt.layout.RowLayout; import org.eclipse.swt.SWT; import org.eclipse.swt.graphics.Point; import org.eclipse.swt.graphics.Rectangle; import org.eclipse.swt.widgets.Control; import org.eclipse.swt.widgets.Layout; import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.layout.RowData; import java.lang.all; /** * Instances of this class determine the size and position of the * children of a <code>Composite</code> by placing them either in * horizontal rows or vertical columns within the parent <code>Composite</code>. * <p> * <code>RowLayout</code> aligns all controls in one row if the * <code>type</code> is set to horizontal, and one column if it is * set to vertical. It has the ability to wrap, and provides configurable * margins and spacing. <code>RowLayout</code> has a number of configuration * fields. In addition, the height and width of each control in a * <code>RowLayout</code> can be specified by setting a <code>RowData</code> * object into the control using <code>setLayoutData ()</code>. * </p> * <p> * The following example code creates a <code>RowLayout</code>, sets all * of its fields to non-default values, and then sets it into a * <code>Shell</code>. * <pre> * RowLayout rowLayout = new RowLayout(); * rowLayout.wrap = false; * rowLayout.pack = false; * rowLayout.justify = true; * rowLayout.type = SWT.VERTICAL; * rowLayout.marginLeft = 5; * rowLayout.marginTop = 5; * rowLayout.marginRight = 5; * rowLayout.marginBottom = 5; * rowLayout.spacing = 0; * shell.setLayout(rowLayout); * </pre> * If you are using the default field values, you only need one line of code: * <pre> * shell.setLayout(new RowLayout()); * </pre> * </p> * * @see RowData * @see <a href="http://www.eclipse.org/swt/snippets/#rowlayout">RowLayout snippets</a> * @see <a href="http://www.eclipse.org/swt/examples.php">SWT Example: LayoutExample</a> * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> */ public final class RowLayout : Layout { /** * type specifies whether the layout places controls in rows or * columns. * * The default value is HORIZONTAL. * * Possible values are: <ul> * <li>HORIZONTAL: Position the controls horizontally from left to right</li> * <li>VERTICAL: Position the controls vertically from top to bottom</li> * </ul> * * @since 2.0 */ public int type = SWT.HORIZONTAL; /** * marginWidth specifies the number of pixels of horizontal margin * that will be placed along the left and right edges of the layout. * * The default value is 0. * * @since 3.0 */ public int marginWidth = 0; /** * marginHeight specifies the number of pixels of vertical margin * that will be placed along the top and bottom edges of the layout. * * The default value is 0. * * @since 3.0 */ public int marginHeight = 0; /** * spacing specifies the number of pixels between the edge of one cell * and the edge of its neighbouring cell. * * The default value is 3. */ public int spacing = 3; /** * wrap specifies whether a control will be wrapped to the next * row if there is insufficient space on the current row. * * The default value is true. */ public bool wrap = true; /** * pack specifies whether all controls in the layout take * their preferred size. If pack is false, all controls will * have the same size which is the size required to accommodate the * largest preferred height and the largest preferred width of all * the controls in the layout. * * The default value is true. */ public bool pack = true; /** * fill specifies whether the controls in a row should be * all the same height for horizontal layouts, or the same * width for vertical layouts. * * The default value is false. * * @since 3.0 */ public bool fill = false; /** * center specifies whether the controls in a row should be * centered vertically in each cell for horizontal layouts, * or centered horizontally in each cell for vertical layouts. * * The default value is false. * * @since 3.4 */ public bool center = false; /** * justify specifies whether the controls in a row should be * fully justified, with any extra space placed between the controls. * * The default value is false. */ public bool justify = false; /** * marginLeft specifies the number of pixels of horizontal margin * that will be placed along the left edge of the layout. * * The default value is 3. */ public int marginLeft = 3; /** * marginTop specifies the number of pixels of vertical margin * that will be placed along the top edge of the layout. * * The default value is 3. */ public int marginTop = 3; /** * marginRight specifies the number of pixels of horizontal margin * that will be placed along the right edge of the layout. * * The default value is 3. */ public int marginRight = 3; /** * marginBottom specifies the number of pixels of vertical margin * that will be placed along the bottom edge of the layout. * * The default value is 3. */ public int marginBottom = 3; /** * Constructs a new instance of this class. */ public this () { } /** * Constructs a new instance of this class given the type. * * @param type the type of row layout * * @since 2.0 */ public this (int type) { this.type = type; } override protected Point computeSize (Composite composite, int wHint, int hHint, bool flushCache_) { Point extent; if (type is SWT.HORIZONTAL) { extent = layoutHorizontal (composite, false, (wHint !is SWT.DEFAULT) && wrap, wHint, flushCache_); } else { extent = layoutVertical (composite, false, (hHint !is SWT.DEFAULT) && wrap, hHint, flushCache_); } if (wHint !is SWT.DEFAULT) extent.x = wHint; if (hHint !is SWT.DEFAULT) extent.y = hHint; return extent; } Point computeSize (Control control, bool flushCache_) { int wHint = SWT.DEFAULT, hHint = SWT.DEFAULT; RowData data = cast(RowData) control.getLayoutData (); if (data !is null) { wHint = data.width; hHint = data.height; } return control.computeSize (wHint, hHint, flushCache_); } override protected bool flushCache (Control control) { return true; } String getName () { String string = this.classinfo.name; int index = string.lastIndexOf('.'); if (index is -1 ) return string; return string[ index + 1 .. string.length ]; } override protected void layout (Composite composite, bool flushCache_) { Rectangle clientArea = composite.getClientArea (); if (type is SWT.HORIZONTAL) { layoutHorizontal (composite, true, wrap, clientArea.width, flushCache_); } else { layoutVertical (composite, true, wrap, clientArea.height, flushCache_); } } Point layoutHorizontal (Composite composite, bool move, bool wrap, int width, bool flushCache_) { Control [] children = composite.getChildren (); int count = 0; for (int i=0; i<children.length; i++) { Control control = children [i]; RowData data = cast(RowData) control.getLayoutData (); if (data is null || !data.exclude) { children [count++] = children [i]; } } if (count is 0) { return new Point (marginLeft + marginWidth * 2 + marginRight, marginTop + marginHeight * 2 + marginBottom); } int childWidth = 0, childHeight = 0, maxHeight = 0; if (!pack) { for (int i=0; i<count; i++) { Control child = children [i]; Point size = computeSize (child, flushCache_); childWidth = Math.max (childWidth, size.x); childHeight = Math.max (childHeight, size.y); } maxHeight = childHeight; } int clientX = 0, clientY = 0; if (move) { Rectangle rect = composite.getClientArea (); clientX = rect.x; clientY = rect.y; } int [] wraps = null; bool wrapped = false; Rectangle [] bounds = null; if (move && (justify || fill || center)) { bounds = new Rectangle [count]; wraps = new int [count]; } int maxX = 0, x = marginLeft + marginWidth, y = marginTop + marginHeight; for (int i=0; i<count; i++) { Control child = children [i]; if (pack) { Point size = computeSize (child, flushCache_); childWidth = size.x; childHeight = size.y; } if (wrap && (i !is 0) && (x + childWidth > width)) { wrapped = true; if (move && (justify || fill || center)) wraps [i - 1] = maxHeight; x = marginLeft + marginWidth; y += spacing + maxHeight; if (pack) maxHeight = 0; } if (pack || fill || center) { maxHeight = Math.max (maxHeight, childHeight); } if (move) { int childX = x + clientX, childY = y + clientY; if (justify || fill || center) { bounds [i] = new Rectangle (childX, childY, childWidth, childHeight); } else { child.setBounds (childX, childY, childWidth, childHeight); } } x += spacing + childWidth; maxX = Math.max (maxX, x); } maxX = Math.max (clientX + marginLeft + marginWidth, maxX - spacing); if (!wrapped) maxX += marginRight + marginWidth; if (move && (justify || fill || center)) { int space = 0, margin = 0; if (!wrapped) { space = Math.max (0, (width - maxX) / (count + 1)); margin = Math.max (0, ((width - maxX) % (count + 1)) / 2); } else { if (fill || justify || center) { int last = 0; if (count > 0) wraps [count - 1] = maxHeight; for (int i=0; i<count; i++) { if (wraps [i] !is 0) { int wrapCount = i - last + 1; if (justify) { int wrapX = 0; for (int j=last; j<=i; j++) { wrapX += bounds [j].width + spacing; } space = Math.max (0, (width - wrapX) / (wrapCount + 1)); margin = Math.max (0, ((width - wrapX) % (wrapCount + 1)) / 2); } for (int j=last; j<=i; j++) { if (justify) bounds [j].x += (space * (j - last + 1)) + margin; if (fill) { bounds [j].height = wraps [i]; } else { if (center) { bounds [j].y += Math.max (0, (wraps [i] - bounds [j].height) / 2); } } } last = i + 1; } } } } for (int i=0; i<count; i++) { if (!wrapped) { if (justify) bounds [i].x += (space * (i + 1)) + margin; if (fill) { bounds [i].height = maxHeight; } else { if (center) { bounds [i].y += Math.max (0, (maxHeight - bounds [i].height) / 2); } } } children [i].setBounds (bounds [i]); } } return new Point (maxX, y + maxHeight + marginBottom + marginHeight); } Point layoutVertical (Composite composite, bool move, bool wrap, int height, bool flushCache_) { Control [] children = composite.getChildren (); int count = 0; for (int i=0; i<children.length; i++) { Control control = children [i]; RowData data = cast(RowData) control.getLayoutData (); if (data is null || !data.exclude) { children [count++] = children [i]; } } if (count is 0) { return new Point (marginLeft + marginWidth * 2 + marginRight, marginTop + marginHeight * 2 + marginBottom); } int childWidth = 0, childHeight = 0, maxWidth = 0; if (!pack) { for (int i=0; i<count; i++) { Control child = children [i]; Point size = computeSize (child, flushCache_); childWidth = Math.max (childWidth, size.x); childHeight = Math.max (childHeight, size.y); } maxWidth = childWidth; } int clientX = 0, clientY = 0; if (move) { Rectangle rect = composite.getClientArea (); clientX = rect.x; clientY = rect.y; } int [] wraps = null; bool wrapped = false; Rectangle [] bounds = null; if (move && (justify || fill || center)) { bounds = new Rectangle [count]; wraps = new int [count]; } int maxY = 0, x = marginLeft + marginWidth, y = marginTop + marginHeight; for (int i=0; i<count; i++) { Control child = children [i]; if (pack) { Point size = computeSize (child, flushCache_); childWidth = size.x; childHeight = size.y; } if (wrap && (i !is 0) && (y + childHeight > height)) { wrapped = true; if (move && (justify || fill || center)) wraps [i - 1] = maxWidth; x += spacing + maxWidth; y = marginTop + marginHeight; if (pack) maxWidth = 0; } if (pack || fill || center) { maxWidth = Math.max (maxWidth, childWidth); } if (move) { int childX = x + clientX, childY = y + clientY; if (justify || fill || center) { bounds [i] = new Rectangle (childX, childY, childWidth, childHeight); } else { child.setBounds (childX, childY, childWidth, childHeight); } } y += spacing + childHeight; maxY = Math.max (maxY, y); } maxY = Math.max (clientY + marginTop + marginHeight, maxY - spacing); if (!wrapped) maxY += marginBottom + marginHeight; if (move && (justify || fill || center)) { int space = 0, margin = 0; if (!wrapped) { space = Math.max (0, (height - maxY) / (count + 1)); margin = Math.max (0, ((height - maxY) % (count + 1)) / 2); } else { if (fill || justify || center) { int last = 0; if (count > 0) wraps [count - 1] = maxWidth; for (int i=0; i<count; i++) { if (wraps [i] !is 0) { int wrapCount = i - last + 1; if (justify) { int wrapY = 0; for (int j=last; j<=i; j++) { wrapY += bounds [j].height + spacing; } space = Math.max (0, (height - wrapY) / (wrapCount + 1)); margin = Math.max (0, ((height - wrapY) % (wrapCount + 1)) / 2); } for (int j=last; j<=i; j++) { if (justify) bounds [j].y += (space * (j - last + 1)) + margin; if (fill) { bounds [j].width = wraps [i]; } else { if (center) { bounds [j].x += Math.max (0, (wraps [i] - bounds [j].width) / 2); } } } last = i + 1; } } } } for (int i=0; i<count; i++) { if (!wrapped) { if (justify) bounds [i].y += (space * (i + 1)) + margin; if (fill) { bounds [i].width = maxWidth; } else { if (center) { bounds [i].x += Math.max (0, (maxWidth - bounds [i].width) / 2); } } } children [i].setBounds (bounds [i]); } } return new Point (x + maxWidth + marginRight + marginWidth, maxY); } /** * Returns a string containing a concise, human-readable * description of the receiver. * * @return a string representation of the layout */ override public String toString () { String string = getName ()~" {"; string ~= "type="~((type !is SWT.HORIZONTAL) ? "SWT.VERTICAL" : "SWT.HORIZONTAL")~" "; if (marginWidth !is 0) string ~= "marginWidth="~String_valueOf(marginWidth)~" "; if (marginHeight !is 0) string ~= "marginHeight="~String_valueOf(marginHeight)~" "; if (marginLeft !is 0) string ~= "marginLeft="~String_valueOf(marginLeft)~" "; if (marginTop !is 0) string ~= "marginTop="~String_valueOf(marginTop)~" "; if (marginRight !is 0) string ~= "marginRight="~String_valueOf(marginRight)~" "; if (marginBottom !is 0) string ~= "marginBottom="~String_valueOf(marginBottom)~" "; if (spacing !is 0) string ~= "spacing="~String_valueOf(spacing)~" "; string ~= "wrap="~String_valueOf(wrap)~" "; string ~= "pack="~String_valueOf(pack)~" "; string ~= "fill="~String_valueOf(fill)~" "; string ~= "justify="~String_valueOf(justify)~" "; string = string.trim(); string ~= "}"; return string; } }