Mercurial > projects > dwt-mac
diff dwt/widgets/TreeColumn.d @ 45:d8635bb48c7c
Merge with SWT 3.5
author | Jacob Carlborg <doob@me.com> |
---|---|
date | Mon, 01 Dec 2008 17:07:00 +0100 |
parents | e831403a80a9 |
children | 6c56264306a6 |
line wrap: on
line diff
--- a/dwt/widgets/TreeColumn.d Tue Oct 21 15:20:04 2008 +0200 +++ b/dwt/widgets/TreeColumn.d Mon Dec 01 17:07:00 2008 +0100 @@ -1,5 +1,5 @@ -/******************************************************************************* - * Copyright (c) 2000, 2007 IBM Corporation and others. +/******************************************************************************* + * 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 @@ -18,9 +18,21 @@ import dwt.events.ControlListener; import dwt.events.SelectionEvent; import dwt.events.SelectionListener; +import dwt.graphics.GC; import dwt.graphics.Image; +import dwt.internal.cocoa.NSAffineTransform; +import dwt.internal.cocoa.NSAttributedString; +import dwt.internal.cocoa.NSGraphicsContext; +import dwt.internal.cocoa.NSMutableDictionary; +import dwt.internal.cocoa.NSMutableParagraphStyle; +import dwt.internal.cocoa.NSOutlineView; +import dwt.internal.cocoa.NSRect; +import dwt.internal.cocoa.NSSize; import dwt.internal.cocoa.NSString; import dwt.internal.cocoa.NSTableColumn; +import dwt.internal.cocoa.NSTableHeaderCell; +import dwt.internal.cocoa.NSTableHeaderView; +import dwt.internal.cocoa.NSView; import dwt.internal.cocoa.OS; /** @@ -36,13 +48,18 @@ * </p><p> * IMPORTANT: This class is <em>not</em> intended to be subclassed. * </p> + * + * @see <a href="http://www.eclipse.org/swt/snippets/#tree">Tree, TreeItem, TreeColumn snippets</a> + * @see <a href="http://www.eclipse.org/swt/">Sample code and further information</a> * * @since 3.1 */ public class TreeColumn : Item { NSTableColumn nsColumn; Tree parent; - String toolTipText; + String toolTipText, displayText; + + static final int MARGIN = 2; /** * Constructs a new instance of this class given its parent @@ -79,7 +96,7 @@ public this (Tree parent, int style) { super (parent, checkStyle (style)); this.parent = parent; - parent.createItem (this, parent.getColumnCount ()); + parent.createItem (this, parent.columnCount); } /** @@ -96,7 +113,10 @@ * lists the style constants that are applicable to the class. * Style bits are also inherited from superclasses. * </p> - * + * <p> + * Note that due to a restriction on some platforms, the first column + * is always left aligned. + * </p> * @param parent a composite control which will be the parent of the new instance (cannot be null) * @param style the style of control to construct * @param index the zero-relative index to store the receiver in its parent @@ -189,11 +209,110 @@ if (!isValidSubclass ()) error (DWT.ERROR_INVALID_SUBCLASS); } +void deregister () { + super.deregister (); + display.removeWidget (nsColumn.headerCell()); +} + void destroyWidget () { parent.destroyItem (this); releaseHandle (); } +void drawInteriorWithFrame_inView (int /*long*/ id, int /*long*/ sel, int /*long*/ cellFrame, int /*long*/ view) { + NSRect cellRect = new NSRect (); + OS.memmove (cellRect, cellFrame, NSRect.sizeof); + + /* + * Feature in Cocoa. When the last column in a tree does not reach the + * rightmost edge of the tree view, the cell that draws the rightmost- + * column's header is also invoked to draw the header space between its + * right edge and the tree's right edge. If this case is detected then + * nothing should be drawn. + */ + NSOutlineView outlineView = (NSOutlineView)parent.view; + int columnIndex = (int)/*64*/outlineView.columnWithIdentifier (nsColumn); + NSRect headerRect = parent.headerView.headerRectOfColumn (columnIndex); + if (headerRect.x !is cellRect.x || headerRect.width !is cellRect.width) return; + + NSGraphicsContext context = NSGraphicsContext.currentContext (); + context.saveGraphicsState (); + + int contentWidth = 0; + NSSize stringSize = null, imageSize = null; + NSAttributedString attrString = null; + NSTableHeaderCell headerCell = nsColumn.headerCell (); + if (displayText !is null) { + NSMutableDictionary dict = NSMutableDictionary.dictionaryWithCapacity(4); + dict.setObject (headerCell.font (), OS.NSFontAttributeName); + NSMutableParagraphStyle paragraphStyle = (NSMutableParagraphStyle)new NSMutableParagraphStyle ().alloc ().init (); + paragraphStyle.autorelease (); + paragraphStyle.setLineBreakMode (OS.NSLineBreakByClipping); + dict.setObject (paragraphStyle, OS.NSParagraphStyleAttributeName); + NSString string = NSString.stringWith (displayText); + attrString = ((NSAttributedString)new NSAttributedString ().alloc ()).initWithString (string, dict); + stringSize = attrString.size (); + contentWidth += Math.ceil (stringSize.width); + if (image !is null) contentWidth += MARGIN; /* space between image and text */ + } + if (image !is null) { + imageSize = image.handle.size (); + contentWidth += Math.ceil (imageSize.width); + } + + if (parent.sortColumn is this && parent.sortDirection !is DWT.NONE) { + bool ascending = parent.sortDirection is DWT.UP; + headerCell.drawSortIndicatorWithFrame (cellRect, new NSView(view), ascending, 0); + /* remove the arrow's space from the available drawing width */ + NSRect sortRect = headerCell.sortIndicatorRectForBounds (cellRect); + cellRect.width = Math.max (0, sortRect.x - cellRect.x); + } + + int drawX = 0; + if ((style & DWT.CENTER) !is 0) { + drawX = (int)(cellRect.x + Math.max (MARGIN, ((cellRect.width - contentWidth) / 2))); + } else if ((style & DWT.RIGHT) !is 0) { + drawX = (int)(cellRect.x + Math.max (MARGIN, cellRect.width - contentWidth - MARGIN)); + } else { + drawX = (int)cellRect.x + MARGIN; + } + + if (image !is null) { + NSRect destRect = new NSRect (); + destRect.x = drawX; + destRect.y = cellRect.y; + destRect.width = Math.min (imageSize.width, cellRect.width - 2 * MARGIN); + destRect.height = Math.min (imageSize.height, cellRect.height); + bool isFlipped = new NSView (view).isFlipped(); + if (isFlipped) { + context.saveGraphicsState (); + NSAffineTransform transform = NSAffineTransform.transform (); + transform.scaleXBy (1, -1); + transform.translateXBy (0, -(destRect.height + 2 * destRect.y)); + transform.concat (); + } + NSRect sourceRect = new NSRect (); + sourceRect.width = destRect.width; + sourceRect.height = destRect.height; + image.handle.drawInRect (destRect, sourceRect, OS.NSCompositeSourceOver, 1f); + if (isFlipped) context.restoreGraphicsState (); + drawX += destRect.width; + } + + if (displayText !is null && displayText.length () > 0) { + if (image !is null) drawX += MARGIN; /* space between image and text */ + NSRect destRect = new NSRect (); + destRect.x = drawX; + destRect.y = cellRect.y; + destRect.width = Math.min (stringSize.width, cellRect.x + cellRect.width - MARGIN - drawX); + destRect.height = Math.min (stringSize.height, cellRect.height); + attrString.drawInRect (destRect); + attrString.release (); + } + + context.restoreGraphicsState (); +} + /** * Returns a value which describes the position of the * text or image in the receiver. The value will be one of @@ -324,21 +443,59 @@ */ public void pack () { checkWidget (); -// GC gc = new GC (parent); -// int width = gc.stringExtent (text).x; - //TODO extra header -// int index = parent.indexOf (this); -// width = Math.max (width, calculateWidth (parent.childIds, index, gc, width)); -// -// gc.dispose (); -// setWidth (width + parent.getInsetWidth (id, true)); - //TODO this only takes care of the header - nsColumn.sizeToFit(); + + int width = 0; + + /* compute header width */ + if (displayText !is null) { + NSMutableDictionary dict = NSMutableDictionary.dictionaryWithCapacity (4); + NSTableHeaderCell headerCell = nsColumn.headerCell (); + dict.setObject (headerCell.font (), OS.NSFontAttributeName); + NSString string = NSString.stringWith (displayText); + NSAttributedString attrString = ((NSAttributedString)new NSAttributedString ().alloc ()).initWithString (string, dict); + NSSize stringSize = attrString.size (); + attrString.release (); + width += Math.ceil (stringSize.width); + if (image !is null) width += MARGIN; /* space between image and text */ + } + if (image !is null) { + NSSize imageSize = image.handle.size (); + width += Math.ceil (imageSize.width); + } + if (parent.sortColumn is this && parent.sortDirection !is DWT.NONE) { + NSTableHeaderCell headerCell = nsColumn.headerCell (); + NSRect rect = new NSRect (); + rect.width = rect.height = Float.MAX_VALUE; + NSSize cellSize = headerCell.cellSizeForBounds (rect); + rect.height = cellSize.height; + NSRect sortRect = headerCell.sortIndicatorRectForBounds (rect); + width += Math.ceil (sortRect.width); + } + + /* compute item widths down column */ + GC gc = new GC (parent); + int index = parent.indexOf (this); + for (int i=0; i<parent.itemCount; i++) { + TreeItem item = parent.items [i]; + if (item !is null && !item.isDisposed () && item.cached) { + width = Math.max (width, item.calculateWidth (index, gc, true, true)); + if (isDisposed ()) { + gc.dispose (); + return; + } + if (gc.isDisposed ()) gc = new GC (parent); + } + } + gc.dispose (); + setWidth (width + parent.getInsetWidth ()); } void releaseHandle () { super.releaseHandle (); - if (nsColumn !is null) nsColumn.release(); + if (nsColumn !is null) { + nsColumn.headerCell ().release (); + nsColumn.release (); + } nsColumn = null; parent = null; } @@ -404,7 +561,10 @@ * Controls how text and images will be displayed in the receiver. * The argument should be one of <code>LEFT</code>, <code>RIGHT</code> * or <code>CENTER</code>. - * + * <p> + * Note that due to a restriction on some platforms, the first column + * is always left aligned. + * </p> * @param alignment the new alignment * * @exception DWTException <ul> @@ -419,7 +579,14 @@ if (index is -1 || index is 0) return; style &= ~(DWT.LEFT | DWT.RIGHT | DWT.CENTER); style |= alignment & (DWT.LEFT | DWT.RIGHT | DWT.CENTER); - //TODO + NSOutlineView outlineView = ((NSOutlineView) parent.view); + NSTableHeaderView headerView = outlineView.headerView (); + if (headerView is null) return; + index = (int)/*64*/outlineView.columnWithIdentifier (nsColumn); + NSRect rect = headerView.headerRectOfColumn (index); + headerView.setNeedsDisplayInRect (rect); + rect = outlineView.rectOfColumn (index); + parent.view.setNeedsDisplayInRect (rect); } public void setImage (Image image) { @@ -427,19 +594,12 @@ if (image !is null && image.isDisposed ()) { error (DWT.ERROR_INVALID_ARGUMENT); } -// int index = parent.indexOf (this); -// if (index is -1) return; -// if (iconRef !is 0) { -// OS.ReleaseIconRef (iconRef); -// iconRef = 0; -// } -// super.setImage (image); -// if (image !is null) { -// if (OS.VERSION < 0x1040) { -// iconRef = createIconRef (image); -// } -// } -// updateHeader (); + super.setImage (image); + NSTableHeaderView headerView = ((NSOutlineView) parent.view).headerView (); + if (headerView is null) return; + int /*long*/ index = ((NSOutlineView)parent.view).columnWithIdentifier (nsColumn); + NSRect rect = headerView.headerRectOfColumn (index); + headerView.setNeedsDisplayInRect (rect); } /** @@ -465,6 +625,10 @@ */ public void setMoveable (bool moveable) { checkWidget (); + // TODO how to make only some columns movable? And handle moveable is false. + if (moveable) { + ((NSOutlineView)parent.view).setAllowsColumnReordering (true); + } // int [] flags = new int [1]; // OS.GetDataBrowserPropertyFlags (parent.handle, id, flags); // if (moveable) { @@ -499,7 +663,14 @@ char [] buffer = new char [text.length ()]; text.getChars (0, buffer.length, buffer, 0); int length = fixMnemonic (buffer); - nsColumn.headerCell().setTitle(NSString.stringWithCharacters(buffer, length)); + displayText = new String (buffer, 0, length); + NSString title = NSString.stringWith (displayText); + nsColumn.headerCell ().setTitle (title); + NSTableHeaderView headerView = ((NSOutlineView) parent.view).headerView (); + if (headerView is null) return; + int /*long*/ index = ((NSOutlineView)parent.view).columnWithIdentifier (nsColumn); + NSRect rect = headerView.headerRectOfColumn (index); + headerView.setNeedsDisplayInRect (rect); } /**