/* NSFormCell.m The cell class for the NSForm control Copyright (C) 1996, 1999 Free Software Foundation, Inc. Author: Ovidiu Predescu Date: March 1997 Author: Nicola Pero Date: November 1999 This file is part of the GNUstep GUI Library. This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include #include #include #include #include #include static NSColor *shadowCol; @interface NSFormCell (PrivateColor) + (void) _systemColorsChanged: (NSNotification*)n; @end @implementation NSFormCell (PrivateColor) + (void) _systemColorsChanged: (NSNotification*)n { ASSIGN(shadowCol, [NSColor controlDarkShadowColor]); } @end @implementation NSFormCell + (void) initialize { if (self == [NSFormCell class]) { [self setVersion: 1]; [[NSNotificationCenter defaultCenter] addObserver: self selector: @selector(_systemColorsChanged:) name: NSSystemColorsDidChangeNotification object: nil]; [self _systemColorsChanged: nil]; } } /* The title attributes are those inherited from the NSActionCell class. */ - init { return [self initTextCell: @"Field:"]; } - initTextCell: (NSString *)aString { self = [super initTextCell: @""]; _cell.is_bezeled = YES; _cell.text_align = NSLeftTextAlignment; _cell.is_editable = YES; _titleCell = [[NSCell alloc] initTextCell: aString]; [_titleCell setAlignment: NSRightTextAlignment]; _formcell_auto_title_width = YES; _displayedTitleWidth = -1; return self; } - (void)dealloc { [_titleCell release]; [super dealloc]; } - (BOOL)isOpaque { return [_titleCell isOpaque] && [super isOpaque]; } - (void)setTitle: (NSString*)aString { [_titleCell setStringValue: aString]; if (_formcell_auto_title_width) { // Invalidates title width _displayedTitleWidth = -1; // Update the control(s) [[NSNotificationCenter defaultCenter] postNotificationName: _NSFormCellDidChangeTitleWidthNotification object: self]; } } - (void)setTitleAlignment:(NSTextAlignment)mode { [_titleCell setAlignment: mode]; } - (void)setTitleFont: (NSFont*)fontObject { [_titleCell setFont: fontObject]; if (_formcell_auto_title_width) { // Invalidates title width _displayedTitleWidth = -1; // Update the control(s) [[NSNotificationCenter defaultCenter] postNotificationName: _NSFormCellDidChangeTitleWidthNotification object: self]; } } - (void)setTitleWidth: (float)width { if (width >= 0) { _formcell_auto_title_width = NO; _displayedTitleWidth = width; } else { _formcell_auto_title_width = YES; _displayedTitleWidth = -1; } // TODO: Don't updated the control if nothing changed. // Update the control(s) [[NSNotificationCenter defaultCenter] postNotificationName: _NSFormCellDidChangeTitleWidthNotification object: self]; } - (NSString*)title { return [_titleCell stringValue]; } - (NSTextAlignment)titleAlignment { return [_titleCell alignment]; } - (NSFont*)titleFont { return [_titleCell font]; } // // Warning: this method returns the width of the title; the width the // title would have if the cell was the only cell in the form. This // is used by NSForm to align all the cells in its form. This is to // say that this title width is *not* what you are going to see on the // screen if more than one cell is present. Setting a titleWidth // manually with setTitleWidth: disables any alignment with other // cells. // - (float)titleWidth { if (_formcell_auto_title_width == NO) return _displayedTitleWidth; else return [[_titleCell font] widthOfString: [_titleCell stringValue]]; } - (float)titleWidth: (NSSize)size { // Minor TODO -- what is this supposed to do? return 0; } // Updates the title width. The width of aRect is the new title width // to display. Invoked by NSForm to align the editable parts of the // cells. - (void) calcDrawInfo: (NSRect)aRect { if (_formcell_auto_title_width == NO) return; _displayedTitleWidth = aRect.size.width; } - (NSSize)cellSize { NSSize returnedSize; NSSize titleSize = [_titleCell cellSize]; NSSize textSize; if (_contents) textSize = [super cellSize]; else { ASSIGN (_contents, @"minimum"); textSize = [super cellSize]; RELEASE (_contents); _contents = nil; } returnedSize.width = titleSize.width + 3 + textSize.width; if (titleSize.height > textSize.height) returnedSize.height = titleSize.height; else returnedSize.height = textSize.height; return returnedSize; } - (NSRect) drawingRectForBounds: (NSRect)theRect { // Safety check if (_displayedTitleWidth == -1) _displayedTitleWidth = [self titleWidth]; theRect.origin.x += _displayedTitleWidth + 3; theRect.size.width -= _displayedTitleWidth + 3; return [super drawingRectForBounds: theRect]; } - (void) drawWithFrame: (NSRect)cellFrame inView: (NSView*)controlView { NSRect titleFrame = cellFrame; NSRect borderedFrame = cellFrame; // Save last view drawn to if (_control_view != controlView) _control_view = controlView; // do nothing if cell's frame rect is zero if (NSIsEmptyRect(cellFrame)) return; // Safety check if (_displayedTitleWidth == -1) _displayedTitleWidth = [self titleWidth]; // // Draw title // titleFrame.size.width = _displayedTitleWidth; [_titleCell drawWithFrame: titleFrame inView: controlView]; // // Leave unfilled the space between titlecell and editable text. // // // Draw border // borderedFrame.origin.x += _displayedTitleWidth + 3; borderedFrame.size.width -= _displayedTitleWidth + 3; if (NSIsEmptyRect(borderedFrame)) return; [controlView lockFocus]; if (_cell.is_bordered) { [shadowCol set]; NSFrameRect(borderedFrame); } else if (_cell.is_bezeled) { NSDrawWhiteBezel(borderedFrame, NSZeroRect); } [controlView unlockFocus]; // // Draw interior // [self drawInteriorWithFrame: cellFrame inView: controlView]; } - (void) encodeWithCoder: (NSCoder*)aCoder { BOOL tmp; [super encodeWithCoder: aCoder]; tmp = _formcell_auto_title_width; [aCoder encodeValueOfObjCType: @encode(BOOL) at: &tmp]; [aCoder encodeValueOfObjCType: @encode(float) at: &_displayedTitleWidth]; [aCoder encodeObject: _titleCell]; } - (id) initWithCoder: (NSCoder*)aDecoder { BOOL tmp; [super initWithCoder: aDecoder]; [aDecoder decodeValueOfObjCType: @encode(BOOL) at: &tmp]; _formcell_auto_title_width = tmp; [aDecoder decodeValueOfObjCType: @encode(float) at: &_displayedTitleWidth]; [aDecoder decodeValueOfObjCType: @encode(id) at: &_titleCell]; return self; } @end