2001-12-17 16:51:51 +00:00
|
|
|
/** <title>NSComboBoxCell</title>
|
1999-09-09 20:06:52 +00:00
|
|
|
|
|
|
|
Copyright (C) 1999 Free Software Foundation, Inc.
|
|
|
|
|
|
|
|
Author: Gerrit van Dyk <gerritvd@decillion.net>
|
|
|
|
Date: 1999
|
2004-05-29 13:17:21 +00:00
|
|
|
Author: Quentin Mathe <qmathe@club-internet.fr>
|
|
|
|
Date: 2004
|
1999-09-09 20:06:52 +00:00
|
|
|
|
|
|
|
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.
|
|
|
|
*/
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
#include <Foundation/NSNotification.h>
|
|
|
|
#include <Foundation/NSString.h>
|
|
|
|
#include <Foundation/NSArray.h>
|
2002-11-10 17:11:49 +00:00
|
|
|
#include <Foundation/NSRunLoop.h>
|
|
|
|
#include <Foundation/NSException.h>
|
|
|
|
#include <Foundation/NSAutoreleasePool.h>
|
2004-05-29 13:17:21 +00:00
|
|
|
#include <Foundation/NSValue.h>
|
2003-06-13 15:01:12 +00:00
|
|
|
#include "AppKit/NSApplication.h"
|
|
|
|
#include "AppKit/NSBox.h"
|
|
|
|
#include "AppKit/NSBrowser.h"
|
|
|
|
#include "AppKit/NSBrowserCell.h"
|
|
|
|
#include "AppKit/NSButtonCell.h"
|
|
|
|
#include "AppKit/NSComboBox.h"
|
|
|
|
#include "AppKit/NSComboBoxCell.h"
|
|
|
|
#include "AppKit/NSGraphicsContext.h"
|
|
|
|
#include "AppKit/NSImage.h"
|
|
|
|
#include "AppKit/NSMatrix.h"
|
|
|
|
#include "AppKit/NSPanel.h"
|
|
|
|
#include "AppKit/NSScreen.h"
|
|
|
|
#include "AppKit/NSScroller.h"
|
2004-05-29 13:17:21 +00:00
|
|
|
#include "AppKit/NSScrollView.h"
|
|
|
|
#include "AppKit/NSTableColumn.h"
|
|
|
|
#include "AppKit/NSTableView.h"
|
|
|
|
#include "AppKit/NSTextView.h"
|
2002-11-10 17:11:49 +00:00
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
static NSNotificationCenter *nc;
|
|
|
|
static const BOOL ForceBrowser = NO;
|
|
|
|
static const BOOL ForceArrowIcon = NO;
|
|
|
|
|
|
|
|
|
|
|
|
@interface GSFirstMouseTableView : NSTableView
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation GSFirstMouseTableView
|
|
|
|
- (BOOL) acceptsFirstMouse: (NSEvent *)event
|
2002-11-10 17:11:49 +00:00
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
@end
|
2002-11-10 17:11:49 +00:00
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
@interface GSComboWindow : NSPanel
|
|
|
|
{
|
|
|
|
NSBrowser *_browser;
|
|
|
|
GSFirstMouseTableView *_tableView;
|
2002-11-10 17:11:49 +00:00
|
|
|
NSComboBoxCell *_cell;
|
2004-05-29 13:17:21 +00:00
|
|
|
BOOL _stopped;
|
|
|
|
BOOL _localSelection;
|
2002-11-10 17:11:49 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
+ (GSComboWindow *)defaultPopUp;
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
- (void) layoutWithComboBoxCell:(NSComboBoxCell *)comboBoxCell;
|
|
|
|
- (void) positionWithComboBoxCell:(NSComboBoxCell *)comboBoxCell;
|
|
|
|
- (void) popUpForComboBoxCell: (NSComboBoxCell *)comboBoxCell;
|
|
|
|
- (void) runModalPopUpWithComboBoxCell:(NSComboBoxCell *)comboBoxCell;
|
|
|
|
- (void) runLoopWithComboBoxCell:(NSComboBoxCell *)comboBoxCell;
|
|
|
|
- (void) onWindowEdited: (NSNotification *)notification;
|
2002-12-23 23:21:43 +00:00
|
|
|
- (void) reloadData;
|
|
|
|
- (void) noteNumberOfItemsChanged;
|
|
|
|
- (void) scrollItemAtIndexToTop: (int)index;
|
|
|
|
- (void) scrollItemAtIndexToVisible: (int)index;
|
|
|
|
- (void) selectItemAtIndex: (int)index;
|
|
|
|
- (void) deselectItemAtIndex: (int)index;
|
2004-05-29 13:17:21 +00:00
|
|
|
- (void) moveUpSelection;
|
|
|
|
- (void) moveDownSelection;
|
|
|
|
- (void) validateSelection;
|
2002-11-10 17:11:49 +00:00
|
|
|
|
|
|
|
@end
|
2001-06-09 23:36:23 +00:00
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
@interface NSComboBoxCell (GNUstepPrivate)
|
2002-12-23 23:21:43 +00:00
|
|
|
- (NSString *) _stringValueAtIndex: (int)index;
|
2004-05-29 13:17:21 +00:00
|
|
|
- (void) _performClickWithFrame: (NSRect)cellFrame inView: (NSView *)controlView;
|
|
|
|
- (void) _didClickWithinButton: (id)sender;
|
|
|
|
- (BOOL) _isWantedEvent: (NSEvent *)event;
|
2001-06-09 23:36:23 +00:00
|
|
|
- (GSComboWindow *) _popUp;
|
2004-05-29 13:17:21 +00:00
|
|
|
- (NSRect) _textCellFrame;
|
|
|
|
- (void) _setSelectedItem: (int)index;
|
1999-09-09 20:06:52 +00:00
|
|
|
@end
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
// ---
|
|
|
|
|
|
|
|
static GSComboWindow *gsWindow = nil;
|
2002-11-10 17:11:49 +00:00
|
|
|
|
|
|
|
@implementation GSComboWindow
|
|
|
|
|
|
|
|
+ (GSComboWindow *) defaultPopUp
|
|
|
|
{
|
|
|
|
if (!gsWindow)
|
2004-05-29 13:17:21 +00:00
|
|
|
gsWindow = [[self alloc] initWithContentRect: NSMakeRect(0,0,200,200)
|
|
|
|
styleMask: NSBorderlessWindowMask
|
|
|
|
backing: NSBackingStoreNonretained // NSBackingStoreBuffered
|
|
|
|
defer: YES];
|
2002-11-10 17:11:49 +00:00
|
|
|
return gsWindow;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initWithContentRect: (NSRect)contentRect
|
|
|
|
styleMask: (unsigned int)aStyle
|
|
|
|
backing: (NSBackingStoreType)bufferingType
|
|
|
|
defer: (BOOL)flag
|
|
|
|
{
|
|
|
|
NSBox *box;
|
2004-05-29 13:17:21 +00:00
|
|
|
NSScrollView *scrollView;
|
|
|
|
NSRect borderRect;
|
2002-11-10 17:11:49 +00:00
|
|
|
|
|
|
|
self = [super initWithContentRect: contentRect
|
2004-05-29 13:17:21 +00:00
|
|
|
styleMask: aStyle
|
|
|
|
backing: bufferingType
|
|
|
|
defer: flag];
|
2002-12-23 23:21:43 +00:00
|
|
|
[self setLevel: NSPopUpMenuWindowLevel];
|
|
|
|
[self setBecomesKeyOnlyIfNeeded: YES];
|
2004-05-29 13:17:21 +00:00
|
|
|
|
|
|
|
_localSelection = NO;
|
|
|
|
|
2002-11-10 17:11:49 +00:00
|
|
|
box = [[NSBox alloc] initWithFrame: contentRect];
|
|
|
|
[box setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
|
|
|
|
[box setBorderType: NSLineBorder];
|
|
|
|
[box setTitlePosition: NSNoTitle];
|
2004-05-29 13:17:21 +00:00
|
|
|
[box setContentViewMargins: NSMakeSize(0, 0)];
|
2002-12-23 23:21:43 +00:00
|
|
|
[self setContentView: box];
|
2004-05-29 13:17:21 +00:00
|
|
|
borderRect = contentRect;
|
2002-11-10 17:11:49 +00:00
|
|
|
RELEASE(box);
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
if (!ForceBrowser)
|
|
|
|
{
|
|
|
|
_tableView = [[GSFirstMouseTableView alloc] initWithFrame: NSMakeRect(0, 0, 100, 100)];
|
|
|
|
[_tableView setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
|
|
|
|
//[_tableView setBackgroundColor: [NSColor whiteColor]];
|
|
|
|
[_tableView setDrawsGrid: NO];
|
|
|
|
[_tableView setAllowsEmptySelection: YES];
|
|
|
|
[_tableView setAllowsMultipleSelection: NO];
|
|
|
|
[_tableView setAutoresizesAllColumnsToFit: YES];
|
|
|
|
[_tableView setHeaderView: nil];
|
|
|
|
[_tableView setCornerView: nil];
|
|
|
|
[_tableView addTableColumn: [[NSTableColumn alloc] initWithIdentifier: @"content"]];
|
|
|
|
[[_tableView tableColumnWithIdentifier:@"content"] setDataCell: [[NSCell alloc] initTextCell: @""]];
|
|
|
|
[_tableView setDataSource: self];
|
|
|
|
[_tableView setDelegate: self];
|
|
|
|
|
|
|
|
scrollView = [[NSScrollView alloc] initWithFrame: NSMakeRect(borderRect.origin.x,
|
|
|
|
borderRect.origin.y,
|
|
|
|
borderRect.size.width,
|
|
|
|
borderRect.size.height)];
|
|
|
|
[scrollView setHasVerticalScroller: YES];
|
|
|
|
[scrollView setDocumentView: _tableView];
|
|
|
|
[box setContentView: scrollView];
|
|
|
|
|
|
|
|
[_tableView reloadData];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_browser = [[NSBrowser alloc] initWithFrame: NSMakeRect(borderRect.origin.x,
|
|
|
|
borderRect.origin.y,
|
|
|
|
borderRect.size.width,
|
|
|
|
borderRect.size.height)];
|
|
|
|
[_browser setMaxVisibleColumns: 1];
|
|
|
|
[_browser setTitled: NO];
|
|
|
|
[_browser setHasHorizontalScroller: NO];
|
|
|
|
[_browser setTarget: self];
|
|
|
|
[_browser setAction: @selector(selectItem:)];
|
|
|
|
[_browser setDelegate: self];
|
|
|
|
[_browser setAutoresizingMask: NSViewWidthSizable | NSViewHeightSizable];
|
|
|
|
[_browser setAllowsEmptySelection: YES];
|
|
|
|
[_browser setAllowsMultipleSelection: NO];
|
|
|
|
[_browser setReusesColumns: YES];
|
|
|
|
// Create an empty matrix
|
|
|
|
[_browser loadColumnZero];
|
|
|
|
[box setContentView: _browser];
|
|
|
|
}
|
|
|
|
|
2002-11-10 17:11:49 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2002-12-23 23:21:43 +00:00
|
|
|
- (BOOL) canBecomeKeyWindow { return YES; }
|
|
|
|
|
2002-11-10 17:11:49 +00:00
|
|
|
- (void)dealloc
|
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
// browser, table view and scroll view were not retained so don't release them
|
2002-11-10 17:11:49 +00:00
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
- (void) layoutWithComboBoxCell: (NSComboBoxCell *)comboBoxCell
|
2002-11-10 17:11:49 +00:00
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
NSMatrix *matrix = [_browser matrixInColumn: 0];
|
2002-12-23 23:21:43 +00:00
|
|
|
NSSize bsize = _sizeForBorderType(NSLineBorder);
|
2004-05-29 13:17:21 +00:00
|
|
|
NSSize size;
|
2002-11-10 17:11:49 +00:00
|
|
|
float itemHeight;
|
2004-05-29 13:17:21 +00:00
|
|
|
float textCellWidth;
|
|
|
|
NSSize intercellSpacing;
|
|
|
|
int num = [comboBoxCell numberOfItems];
|
|
|
|
int max = [comboBoxCell numberOfVisibleItems];
|
|
|
|
|
|
|
|
// Manage table view or browser cells height
|
|
|
|
|
|
|
|
itemHeight = [comboBoxCell itemHeight];
|
2002-11-10 17:11:49 +00:00
|
|
|
if (itemHeight <= 0)
|
2002-12-23 23:21:43 +00:00
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
// FIX ME : raise NSException
|
|
|
|
if (!ForceBrowser)
|
|
|
|
{
|
|
|
|
itemHeight = [_tableView rowHeight];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2002-12-23 23:21:43 +00:00
|
|
|
itemHeight = [matrix cellSize].height;
|
2004-05-29 13:17:21 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
size.height = itemHeight;
|
|
|
|
|
|
|
|
// Manage table view or browser cells width
|
|
|
|
|
|
|
|
textCellWidth = [comboBoxCell _textCellFrame].size.width;
|
|
|
|
if ([comboBoxCell hasVerticalScroller])
|
|
|
|
{
|
|
|
|
size.width = textCellWidth - [NSScroller scrollerWidth] - bsize.width;
|
2002-12-23 23:21:43 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
size.width = textCellWidth - bsize.width;
|
|
|
|
}
|
|
|
|
if (size.width < 0)
|
|
|
|
{
|
|
|
|
size.width = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!ForceBrowser)
|
|
|
|
{
|
|
|
|
[_tableView setRowHeight: size.height];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
[matrix setCellSize: size];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Just check intercell spacing
|
|
|
|
|
|
|
|
intercellSpacing = [comboBoxCell intercellSpacing];
|
|
|
|
if (intercellSpacing.height <= 0)
|
|
|
|
{
|
|
|
|
// FIX ME : raise NSException
|
|
|
|
if (!ForceBrowser)
|
2002-12-23 23:21:43 +00:00
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
intercellSpacing.height = [_tableView intercellSpacing].height;
|
|
|
|
}
|
|
|
|
else
|
2002-12-23 23:21:43 +00:00
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
intercellSpacing.height = [matrix intercellSpacing].height;
|
2002-12-23 23:21:43 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2004-05-29 13:17:21 +00:00
|
|
|
{
|
|
|
|
if (!ForceBrowser)
|
|
|
|
{
|
|
|
|
[_tableView setIntercellSpacing: intercellSpacing];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
[matrix setIntercellSpacing: intercellSpacing];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (num > max)
|
|
|
|
num = max;
|
|
|
|
|
|
|
|
[self setFrame: NSMakeRect(0, 0, textCellWidth,
|
|
|
|
2 * bsize.height + (itemHeight + intercellSpacing.height) * (num - 1)
|
|
|
|
+ itemHeight) display: NO];
|
2002-11-10 17:11:49 +00:00
|
|
|
}
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
- (void) positionWithComboBoxCell: (NSComboBoxCell *)comboBoxCell
|
2002-11-10 17:11:49 +00:00
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
NSView *viewWithComboCell = [comboBoxCell controlView];
|
2002-12-23 23:21:43 +00:00
|
|
|
NSRect screenFrame;
|
2004-05-29 13:17:21 +00:00
|
|
|
NSRect comboWindowFrame;
|
|
|
|
NSRect viewWithComboCellFrame;
|
2002-11-10 17:11:49 +00:00
|
|
|
NSRect rect;
|
2002-12-23 23:21:43 +00:00
|
|
|
NSPoint point, oldPoint;
|
2004-05-29 13:17:21 +00:00
|
|
|
NSView *superview = [viewWithComboCell superview];
|
2002-11-10 17:11:49 +00:00
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
[self layoutWithComboBoxCell: comboBoxCell];
|
|
|
|
|
|
|
|
// Now we can ask for the size
|
|
|
|
|
|
|
|
comboWindowFrame = [self frame];
|
|
|
|
if (comboWindowFrame.size.width == 0 || comboWindowFrame.size.height == 0)
|
2002-12-23 23:21:43 +00:00
|
|
|
return;
|
2004-05-29 13:17:21 +00:00
|
|
|
|
|
|
|
screenFrame = [[[viewWithComboCell window] screen] frame];
|
|
|
|
viewWithComboCellFrame = [viewWithComboCell frame];
|
|
|
|
|
|
|
|
point = viewWithComboCellFrame.origin;
|
|
|
|
|
|
|
|
// Switch to the window coordinates
|
|
|
|
point = [[viewWithComboCell superview] convertPoint: point toView: nil];
|
|
|
|
|
|
|
|
// Switch to the screen coordinates
|
|
|
|
point = [[viewWithComboCell window] convertBaseToScreen: point];
|
|
|
|
|
|
|
|
// Take in account flipped view
|
|
|
|
if ([superview isFlipped])
|
|
|
|
point.y += NSHeight([superview frame])
|
|
|
|
- (viewWithComboCellFrame.origin.y * 2 + NSHeight(viewWithComboCellFrame));
|
|
|
|
|
|
|
|
point.y -= 1 + NSHeight(comboWindowFrame);
|
|
|
|
|
2002-12-23 23:21:43 +00:00
|
|
|
if (point.y < 0)
|
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
// Off screen, so move it
|
2002-12-23 23:21:43 +00:00
|
|
|
oldPoint = point;
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
point = viewWithComboCellFrame.origin;
|
|
|
|
point.y = NSMaxY(viewWithComboCellFrame);
|
|
|
|
|
|
|
|
// Switch to the window coordinates
|
|
|
|
point = [[viewWithComboCell superview] convertPoint: point toView: nil];
|
|
|
|
|
|
|
|
// Switch to the screen coordiantes
|
|
|
|
point = [[viewWithComboCell window] convertBaseToScreen: point];
|
|
|
|
|
|
|
|
// Take in account flipped view
|
|
|
|
if ([superview isFlipped])
|
|
|
|
point.y += NSHeight([superview frame])
|
|
|
|
- (viewWithComboCellFrame.origin.y * 2 + NSHeight(viewWithComboCellFrame));
|
|
|
|
|
|
|
|
point.y += 1;
|
|
|
|
|
|
|
|
if (point.y + NSHeight(comboWindowFrame) > NSHeight(screenFrame))
|
|
|
|
point = oldPoint;
|
2002-12-23 23:21:43 +00:00
|
|
|
}
|
2002-11-10 17:11:49 +00:00
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
rect.size.width = NSWidth(comboWindowFrame);
|
|
|
|
rect.size.height = NSHeight(comboWindowFrame);
|
2002-12-23 23:21:43 +00:00
|
|
|
rect.origin.x = point.x;
|
|
|
|
rect.origin.y = point.y;
|
2002-11-10 17:11:49 +00:00
|
|
|
[self setFrame: rect display: NO];
|
2002-12-23 23:21:43 +00:00
|
|
|
}
|
2002-11-10 17:11:49 +00:00
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
- (void) popUpForComboBoxCell: (NSComboBoxCell *)comboBoxCell
|
2002-12-23 23:21:43 +00:00
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
NSString *more;
|
|
|
|
unsigned int index = NSNotFound;
|
2002-11-10 17:11:49 +00:00
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
_cell = comboBoxCell;
|
|
|
|
|
|
|
|
[self positionWithComboBoxCell: _cell];
|
|
|
|
more = [_cell completedString: [_cell stringValue]];
|
|
|
|
index = [[_cell objectValues] indexOfObject: more];
|
|
|
|
if (index != NSNotFound)
|
|
|
|
{
|
|
|
|
[_cell _setSelectedItem: index];
|
|
|
|
}
|
|
|
|
|
|
|
|
[self reloadData];
|
|
|
|
[self enableKeyEquivalentForDefaultButtonCell];
|
|
|
|
[self runModalPopUpWithComboBoxCell: _cell];
|
2002-11-10 17:11:49 +00:00
|
|
|
|
|
|
|
_cell = nil;
|
|
|
|
}
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
- (void) runModalPopUpWithComboBoxCell: (NSComboBoxCell *)comboBoxCell
|
2002-11-10 17:11:49 +00:00
|
|
|
{
|
|
|
|
NSWindow *onWindow;
|
|
|
|
|
|
|
|
onWindow = [[_cell controlView] window];
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
[nc addObserver: self selector: @selector(onWindowEdited:)
|
|
|
|
name: NSWindowWillMoveNotification object: onWindow];
|
|
|
|
[nc addObserver: self selector: @selector(onWindowEdited:)
|
|
|
|
name: NSWindowWillMiniaturizeNotification object: onWindow];
|
|
|
|
/* the notification below doesn't exist currently
|
|
|
|
[nc addObserver: self selector: @selector(onWindowEdited:)
|
|
|
|
name: NSWindowWillResizeNotification object: onWindow];
|
|
|
|
*/
|
|
|
|
[nc addObserver: self selector: @selector(onWindowEdited:)
|
|
|
|
name: NSWindowWillCloseNotification object: onWindow];
|
|
|
|
|
|
|
|
// ### Hack
|
|
|
|
// ### The code below must be removed when the notifications over will work
|
|
|
|
[nc addObserver: self selector: @selector(onWindowEdited:)
|
|
|
|
name: NSWindowDidMoveNotification object: onWindow];
|
|
|
|
[nc addObserver: self selector: @selector(onWindowEdited:)
|
|
|
|
name: NSWindowDidMiniaturizeNotification object: onWindow];
|
|
|
|
[nc addObserver: self selector: @selector(onWindowEdited:)
|
|
|
|
name: NSWindowDidResizeNotification object: onWindow];
|
|
|
|
// ###
|
|
|
|
|
|
|
|
[self orderFront: self];
|
|
|
|
[self makeFirstResponder: _tableView];
|
|
|
|
[self runLoopWithComboBoxCell: comboBoxCell];
|
|
|
|
|
|
|
|
[nc removeObserver: self];
|
|
|
|
[_tableView setDelegate: self];
|
|
|
|
// Hack
|
|
|
|
// Need to reset the delegate to receive the next notifications
|
|
|
|
|
|
|
|
[self close];
|
2002-11-10 17:11:49 +00:00
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
[onWindow makeFirstResponder: [_cell controlView]];
|
2002-11-10 17:11:49 +00:00
|
|
|
}
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
- (void) runLoopWithComboBoxCell: (NSComboBoxCell *)comboBoxCell
|
2002-11-10 17:11:49 +00:00
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
NSEvent *event;
|
2002-12-23 23:21:43 +00:00
|
|
|
NSDate *limit = [NSDate distantFuture];
|
2004-05-29 13:17:21 +00:00
|
|
|
unichar key;
|
2002-11-10 17:11:49 +00:00
|
|
|
CREATE_AUTORELEASE_POOL (pool);
|
2004-05-29 13:17:21 +00:00
|
|
|
|
|
|
|
while (YES)
|
2002-11-10 17:11:49 +00:00
|
|
|
{
|
|
|
|
event = [NSApp nextEventMatchingMask: NSAnyEventMask
|
2004-05-29 13:17:21 +00:00
|
|
|
untilDate: limit
|
|
|
|
inMode: NSDefaultRunLoopMode
|
|
|
|
dequeue: YES];
|
|
|
|
if ([event type] == NSLeftMouseDown
|
|
|
|
|| [event type] == NSRightMouseDown)
|
|
|
|
{
|
|
|
|
if (![comboBoxCell _isWantedEvent: event] && [event window] != self)
|
2002-11-10 17:11:49 +00:00
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
break;
|
2002-11-10 17:11:49 +00:00
|
|
|
}
|
2004-05-29 13:17:21 +00:00
|
|
|
else
|
2002-11-10 17:11:49 +00:00
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
[NSApp sendEvent: event];
|
2002-11-10 17:11:49 +00:00
|
|
|
}
|
2004-05-29 13:17:21 +00:00
|
|
|
}
|
|
|
|
else if ([event type] == NSKeyDown)
|
|
|
|
{
|
|
|
|
key = [[event characters] characterAtIndex: 0];
|
|
|
|
if (key == NSUpArrowFunctionKey)
|
|
|
|
{
|
|
|
|
[self moveUpSelection];
|
|
|
|
}
|
|
|
|
else if (key == NSDownArrowFunctionKey)
|
|
|
|
{
|
|
|
|
[self moveDownSelection];
|
|
|
|
}
|
|
|
|
else if (key == NSNewlineCharacter
|
|
|
|
|| key == NSEnterCharacter
|
|
|
|
|| key == NSCarriageReturnCharacter)
|
|
|
|
{
|
|
|
|
[self validateSelection];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
[NSApp sendEvent: event];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
[NSApp sendEvent: event];
|
2002-11-10 17:11:49 +00:00
|
|
|
}
|
2004-05-29 13:17:21 +00:00
|
|
|
|
|
|
|
if (_stopped)
|
|
|
|
break;
|
2002-11-10 17:11:49 +00:00
|
|
|
}
|
2004-05-29 13:17:21 +00:00
|
|
|
|
|
|
|
_stopped = NO;
|
|
|
|
|
2002-11-10 17:11:49 +00:00
|
|
|
RELEASE(pool);
|
|
|
|
}
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
// onWindow notifications
|
|
|
|
|
|
|
|
- (void) onWindowEdited: (NSNotification *)notification
|
|
|
|
{
|
|
|
|
_stopped = YES;
|
|
|
|
}
|
|
|
|
|
2002-12-23 23:21:43 +00:00
|
|
|
- (void) reloadData
|
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
if (!ForceBrowser)
|
|
|
|
{
|
|
|
|
[_tableView reloadData];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
[_browser loadColumnZero];
|
|
|
|
}
|
2002-12-23 23:21:43 +00:00
|
|
|
[self selectItemAtIndex: [_cell indexOfSelectedItem]];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) noteNumberOfItemsChanged
|
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
// FIXME: Should only load the additional items
|
2002-12-23 23:21:43 +00:00
|
|
|
[self reloadData];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) scrollItemAtIndexToTop: (int)index
|
|
|
|
{
|
|
|
|
NSRect rect;
|
2004-05-29 13:17:21 +00:00
|
|
|
|
|
|
|
if (!ForceBrowser)
|
|
|
|
{
|
|
|
|
rect = [_tableView frameOfCellAtColumn: 0 row: index];
|
|
|
|
[_tableView scrollPoint: rect.origin];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NSMatrix *matrix = [_browser matrixInColumn: 0];
|
2002-12-23 23:21:43 +00:00
|
|
|
|
|
|
|
rect = [matrix cellFrameAtRow: index column: 0];
|
|
|
|
[matrix scrollPoint: rect.origin];
|
2004-05-29 13:17:21 +00:00
|
|
|
}
|
2002-12-23 23:21:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) scrollItemAtIndexToVisible: (int)index
|
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
if (!ForceBrowser)
|
|
|
|
{
|
|
|
|
[_tableView scrollRowToVisible: index];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NSMatrix *matrix = [_browser matrixInColumn: 0];
|
2002-12-23 23:21:43 +00:00
|
|
|
|
|
|
|
[matrix scrollCellToVisibleAtRow: index column: 0];
|
2004-05-29 13:17:21 +00:00
|
|
|
}
|
2002-12-23 23:21:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) selectItemAtIndex: (int)index
|
2004-05-29 13:17:21 +00:00
|
|
|
{
|
|
|
|
if (index < 0)
|
|
|
|
return;
|
|
|
|
|
|
|
|
if (!ForceBrowser)
|
|
|
|
{
|
|
|
|
if ([_tableView selectedRow] == index || [_tableView numberOfRows] <= index)
|
|
|
|
return;
|
|
|
|
_localSelection = YES;
|
|
|
|
// Will block the TableDidSelectionChange: action
|
|
|
|
[_tableView selectRow: index byExtendingSelection: NO];
|
|
|
|
_localSelection = NO;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NSMatrix *matrix = [_browser matrixInColumn: 0];
|
|
|
|
|
|
|
|
if ([matrix selectedRow] == index || [matrix numberOfRows] <= index)
|
|
|
|
return;
|
|
|
|
[_browser selectRow: index inColumn: 0];
|
|
|
|
}
|
2002-12-23 23:21:43 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) deselectItemAtIndex: (int)index
|
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
if (!ForceBrowser)
|
|
|
|
{
|
|
|
|
[_tableView deselectAll: self];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NSMatrix *matrix = [_browser matrixInColumn: 0];
|
2002-12-23 23:21:43 +00:00
|
|
|
|
|
|
|
[matrix deselectSelectedCell];
|
2004-05-29 13:17:21 +00:00
|
|
|
}
|
2002-12-23 23:21:43 +00:00
|
|
|
}
|
2002-11-10 17:11:49 +00:00
|
|
|
|
|
|
|
// Target/Action of Browser
|
|
|
|
- (void) selectItem: (id)sender
|
|
|
|
{
|
|
|
|
if (_cell)
|
2004-05-29 13:17:21 +00:00
|
|
|
{
|
2002-12-23 23:21:43 +00:00
|
|
|
[_cell selectItemAtIndex: [sender selectedRowInColumn: 0]];
|
2002-11-10 17:11:49 +00:00
|
|
|
_stopped = YES;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
// Browser delegate methods
|
2002-11-10 17:11:49 +00:00
|
|
|
- (int) browser: (NSBrowser *)sender
|
|
|
|
numberOfRowsInColumn: (int)column
|
|
|
|
{
|
|
|
|
if (!_cell)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
return [_cell numberOfItems];
|
|
|
|
}
|
|
|
|
|
2002-12-23 23:21:43 +00:00
|
|
|
- (void) browser: (NSBrowser *)sender
|
|
|
|
willDisplayCell: (id)aCell
|
|
|
|
atRow: (int)row
|
|
|
|
column: (int)column
|
2002-11-10 17:11:49 +00:00
|
|
|
{
|
2002-12-23 23:21:43 +00:00
|
|
|
if (!_cell)
|
|
|
|
return;
|
|
|
|
|
|
|
|
[aCell setStringValue: [_cell _stringValueAtIndex: row]];
|
2002-11-10 17:11:49 +00:00
|
|
|
[aCell setLeaf: YES];
|
|
|
|
}
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
// Table view data source methods
|
|
|
|
- (int) numberOfRowsInTableView: (NSTableView *)tv
|
|
|
|
{
|
|
|
|
return [_cell numberOfItems];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) tableView: (NSTableView *)tv objectValueForTableColumn: (NSTableColumn *)tc row: (int)row
|
|
|
|
{
|
|
|
|
return [_cell _stringValueAtIndex: row];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Table view delegate methods
|
|
|
|
- (void) tableViewSelectionDidChange: (NSNotification *)notification
|
|
|
|
{
|
|
|
|
[self validateSelection];
|
|
|
|
}
|
|
|
|
|
|
|
|
// Key actions methods
|
|
|
|
- (void) moveUpSelection
|
|
|
|
{
|
|
|
|
if (!ForceBrowser)
|
|
|
|
{
|
|
|
|
int index = [_tableView selectedRow] - 1;
|
|
|
|
|
|
|
|
if (index > -1 && index < [_tableView numberOfRows])
|
|
|
|
{
|
|
|
|
_localSelection = YES;
|
|
|
|
[_tableView selectRow: index byExtendingSelection: NO];
|
|
|
|
[_tableView scrollRowToVisible: index];
|
|
|
|
_localSelection = NO;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int index = [_browser selectedRowInColumn: 0] - 1;
|
|
|
|
|
|
|
|
if (index > -1 && index < [[_browser matrixInColumn: 0] numberOfRows])
|
|
|
|
{
|
|
|
|
_localSelection = YES;
|
|
|
|
[_browser selectRow: index inColumn: 0];
|
|
|
|
_localSelection = NO;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) moveDownSelection
|
|
|
|
{
|
|
|
|
if (!ForceBrowser)
|
|
|
|
{
|
|
|
|
int index = [_tableView selectedRow] + 1;
|
|
|
|
|
|
|
|
if (index > -1 && index < [_tableView numberOfRows])
|
|
|
|
{
|
|
|
|
_localSelection = YES;
|
|
|
|
[_tableView selectRow: index byExtendingSelection: NO];
|
|
|
|
[_tableView scrollRowToVisible: index];
|
|
|
|
_localSelection = NO;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int index = [_browser selectedRowInColumn: 0] + 1;
|
|
|
|
|
|
|
|
if (index > -1 && index < [[_browser matrixInColumn: 0] numberOfRows])
|
|
|
|
{
|
|
|
|
_localSelection = YES;
|
|
|
|
[_browser selectRow: index inColumn: 0];
|
|
|
|
_localSelection = NO;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) validateSelection
|
|
|
|
{
|
|
|
|
if (_cell && _localSelection == NO)
|
|
|
|
{
|
|
|
|
if (!ForceBrowser)
|
|
|
|
{
|
|
|
|
[_cell selectItemAtIndex: [_tableView selectedRow]];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
[_cell selectItemAtIndex: [_browser selectedRowInColumn: 0]];
|
|
|
|
}
|
|
|
|
_stopped = YES;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2002-11-10 17:11:49 +00:00
|
|
|
@end
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
// ---
|
2002-12-23 23:21:43 +00:00
|
|
|
|
1999-09-09 20:06:52 +00:00
|
|
|
@implementation NSComboBoxCell
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
//
|
|
|
|
// Class methods
|
|
|
|
//
|
|
|
|
+ (void) initialize
|
|
|
|
{
|
|
|
|
if (self == [NSComboBoxCell class])
|
|
|
|
{
|
|
|
|
[self setVersion: 1];
|
|
|
|
nc = [NSNotificationCenter defaultCenter];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) initTextCell: (NSString *)aString
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
self = [super initTextCell: aString];
|
|
|
|
|
|
|
|
// Implicitly set by allocation:
|
|
|
|
//
|
|
|
|
//_dataSource = nil;
|
|
|
|
//_buttonCell = nil;
|
|
|
|
//_usesDataSource = NO;
|
|
|
|
//_completes = NO;
|
2002-12-23 23:21:43 +00:00
|
|
|
_popUpList = [[NSMutableArray alloc] init];
|
2001-06-09 23:36:23 +00:00
|
|
|
_hasVerticalScroller = YES;
|
|
|
|
_visibleItems = 10;
|
|
|
|
_intercellSpacing = NSMakeSize(3.0, 2.0);
|
|
|
|
_itemHeight = 16;
|
2001-07-09 02:49:03 +00:00
|
|
|
_selectedItem = -1;
|
2000-12-07 00:20:17 +00:00
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
if (!ForceArrowIcon)
|
|
|
|
{
|
|
|
|
_buttonCell = [[NSButtonCell alloc] initImageCell:
|
|
|
|
[NSImage imageNamed: @"common_ComboBoxEllipsis"]];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
_buttonCell = [[NSButtonCell alloc] initImageCell:
|
|
|
|
[NSImage imageNamed: @"NSComboArrow"]];
|
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
[_buttonCell setImagePosition: NSImageOnly];
|
|
|
|
[_buttonCell setButtonType: NSMomentaryPushButton];
|
|
|
|
[_buttonCell setHighlightsBy: NSPushInCellMask];
|
|
|
|
[_buttonCell setBordered: YES];
|
|
|
|
[_buttonCell setTarget: self];
|
2004-05-29 13:17:21 +00:00
|
|
|
[_buttonCell setAction: @selector(_didClickWithinButton:)];
|
1999-09-09 20:06:52 +00:00
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
return self;
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (void) dealloc
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
RELEASE(_buttonCell);
|
|
|
|
RELEASE(_popUpList);
|
|
|
|
|
|
|
|
[super dealloc];
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (BOOL) hasVerticalScroller { return _hasVerticalScroller; }
|
|
|
|
- (void) setHasVerticalScroller: (BOOL)flag
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
_hasVerticalScroller = flag;
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (NSSize) intercellSpacing { return _intercellSpacing; }
|
|
|
|
- (void) setIntercellSpacing: (NSSize)aSize
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
_intercellSpacing = aSize;
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (float) itemHeight { return _itemHeight; }
|
|
|
|
- (void) setItemHeight: (float)itemHeight
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
if (itemHeight > 14)
|
|
|
|
_itemHeight = itemHeight;
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (int) numberOfVisibleItems { return _visibleItems; }
|
|
|
|
- (void) setNumberOfVisibleItems: (int)visibleItems
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-11-20 15:53:49 +00:00
|
|
|
if (visibleItems > 10)
|
2001-06-09 23:36:23 +00:00
|
|
|
_visibleItems = visibleItems;
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (void) reloadData
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2002-12-23 23:21:43 +00:00
|
|
|
[_popup reloadData];
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (void) noteNumberOfItemsChanged
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2002-12-23 23:21:43 +00:00
|
|
|
[_popup noteNumberOfItemsChanged];
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (BOOL) usesDataSource { return _usesDataSource; }
|
|
|
|
- (void) setUsesDataSource: (BOOL)flag
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
_usesDataSource = flag;
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (void) scrollItemAtIndexToTop: (int)index
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2002-12-23 23:21:43 +00:00
|
|
|
[_popup scrollItemAtIndexToTop: index];
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (void) scrollItemAtIndexToVisible: (int)index
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2002-12-23 23:21:43 +00:00
|
|
|
[_popup scrollItemAtIndexToVisible: index];
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (void) selectItemAtIndex: (int)index
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
// Method called by GSComboWindow when a selection is done in the table view or
|
|
|
|
// the browser
|
|
|
|
|
|
|
|
NSText *textObject = [[[self controlView] window] fieldEditor: YES
|
|
|
|
forObject: self];
|
|
|
|
if ([self usesDataSource])
|
|
|
|
{
|
|
|
|
if ([self numberOfItems] <= index)
|
|
|
|
; // raise exception
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ([_popUpList count] <= index)
|
|
|
|
; // raise exception
|
|
|
|
}
|
|
|
|
|
|
|
|
if (index < 0)
|
|
|
|
; // rais exception
|
2001-07-09 02:49:03 +00:00
|
|
|
|
|
|
|
if (_selectedItem != index)
|
|
|
|
{
|
|
|
|
_selectedItem = index;
|
2002-12-23 23:21:43 +00:00
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
[_popup selectItemAtIndex: index];
|
|
|
|
// This method call will not create a infinite loop when the index has been
|
|
|
|
// already set by a mouse click because the method is not completed when the
|
|
|
|
// current index is not different from the index parameter
|
|
|
|
|
|
|
|
[textObject setString: [self _stringValueAtIndex: _selectedItem]];
|
|
|
|
[textObject setSelectedRange: NSMakeRange(0, [[textObject string] length])];
|
2002-12-23 23:21:43 +00:00
|
|
|
|
2001-07-09 02:49:03 +00:00
|
|
|
[nc postNotificationName: NSComboBoxSelectionDidChangeNotification
|
2004-05-29 13:17:21 +00:00
|
|
|
object: [self controlView]
|
|
|
|
userInfo: nil];
|
2001-07-09 02:49:03 +00:00
|
|
|
}
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (void) deselectItemAtIndex: (int)index
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
if (_selectedItem == index)
|
2004-05-29 13:17:21 +00:00
|
|
|
{
|
|
|
|
_selectedItem = -1;
|
2002-12-23 23:21:43 +00:00
|
|
|
|
|
|
|
[_popup deselectItemAtIndex: index];
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
[nc postNotificationName: NSComboBoxSelectionDidChangeNotification
|
|
|
|
object: [self controlView]
|
|
|
|
userInfo: nil];
|
|
|
|
}
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (int) indexOfSelectedItem
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
return _selectedItem;
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
- (int) numberOfItems
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
if (_usesDataSource)
|
|
|
|
{
|
1999-09-09 20:06:52 +00:00
|
|
|
if (!_dataSource)
|
2004-05-29 13:17:21 +00:00
|
|
|
{
|
|
|
|
NSLog(@"%@: A DataSource should be specified", self);
|
|
|
|
}
|
1999-09-09 20:06:52 +00:00
|
|
|
else
|
2001-06-09 23:36:23 +00:00
|
|
|
{
|
|
|
|
if ([_dataSource respondsToSelector: @selector(numberOfItemsInComboBox:)])
|
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
return [_dataSource numberOfItemsInComboBox:
|
|
|
|
(NSComboBox *)[self controlView]];
|
2001-06-09 23:36:23 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if ([_dataSource respondsToSelector: @selector(numberOfItemsInComboBoxCell:)])
|
|
|
|
return [_dataSource numberOfItemsInComboBoxCell: self];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
return [_popUpList count];
|
1999-09-09 20:06:52 +00:00
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
return 0;
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (id) dataSource { return _dataSource; }
|
|
|
|
- (void) setDataSource: (id)aSource
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
if (!_usesDataSource)
|
2004-05-29 13:17:21 +00:00
|
|
|
NSLog(@"%@: This method is invalid, this combo box is not set to use a data source",
|
|
|
|
self);
|
2001-06-09 23:36:23 +00:00
|
|
|
else
|
2003-03-02 18:50:07 +00:00
|
|
|
_dataSource = aSource;
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (void) addItemWithObjectValue: (id)object
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
if (_usesDataSource)
|
2004-05-29 13:17:21 +00:00
|
|
|
NSLog(@"%@: This method is invalid, this combo box is set to use a data source",
|
|
|
|
self);
|
2001-06-09 23:36:23 +00:00
|
|
|
else
|
|
|
|
[_popUpList addObject: object];
|
2004-05-29 13:17:21 +00:00
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
[self reloadData];
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (void) addItemsWithObjectValues: (NSArray *)objects
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
if (_usesDataSource)
|
2004-05-29 13:17:21 +00:00
|
|
|
NSLog(@"%@: This method is invalid, this combo box is set to use a data source",
|
|
|
|
self);
|
2001-06-09 23:36:23 +00:00
|
|
|
else
|
|
|
|
[_popUpList addObjectsFromArray: objects];
|
2004-05-29 13:17:21 +00:00
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
[self reloadData];
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (void) insertItemWithObjectValue: (id)object atIndex: (int)index
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
if (_usesDataSource)
|
2004-05-29 13:17:21 +00:00
|
|
|
NSLog(@"%@: This method is invalid, this combo box is set to use a data source",
|
|
|
|
self);
|
2001-06-09 23:36:23 +00:00
|
|
|
else
|
|
|
|
[_popUpList insertObject: object atIndex: index];
|
2004-05-29 13:17:21 +00:00
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
[self reloadData];
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (void) removeItemWithObjectValue: (id)object
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
if (_usesDataSource)
|
2004-05-29 13:17:21 +00:00
|
|
|
NSLog(@"%@: This method is invalid, this combo box is set to use a data source",
|
|
|
|
self);
|
2001-06-09 23:36:23 +00:00
|
|
|
else
|
|
|
|
[_popUpList removeObject: object];
|
2004-05-29 13:17:21 +00:00
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
[self reloadData];
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (void) removeItemAtIndex: (int)index
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
if (_usesDataSource)
|
2004-05-29 13:17:21 +00:00
|
|
|
NSLog(@"%@: This method is invalid, this combo box is set to use a data source",
|
|
|
|
self);
|
2001-06-09 23:36:23 +00:00
|
|
|
else
|
|
|
|
[_popUpList removeObjectAtIndex: index];
|
2004-05-29 13:17:21 +00:00
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
[self reloadData];
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (void) removeAllItems
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
if (_usesDataSource)
|
2004-05-29 13:17:21 +00:00
|
|
|
NSLog(@"%@: This method is invalid, this combo box is set to use a data source",
|
|
|
|
self);
|
2001-06-09 23:36:23 +00:00
|
|
|
else
|
|
|
|
[_popUpList removeAllObjects];
|
2004-05-29 13:17:21 +00:00
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
[self reloadData];
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (void) selectItemWithObjectValue: (id)object
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
if (_usesDataSource)
|
2004-05-29 13:17:21 +00:00
|
|
|
NSLog(@"%@: This method is invalid, this combo box is set to use a data source",
|
|
|
|
self);
|
2001-06-09 23:36:23 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
int i = [_popUpList indexOfObject: object];
|
|
|
|
|
2001-07-09 02:49:03 +00:00
|
|
|
if (i == NSNotFound)
|
|
|
|
i = -1;
|
|
|
|
|
|
|
|
[self selectItemAtIndex: i];
|
2001-06-09 23:36:23 +00:00
|
|
|
}
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (id) itemObjectValueAtIndex: (int)index
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
if (_usesDataSource)
|
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
NSLog(@"%@: This method is invalid, this combo box is set to use a data source",
|
|
|
|
self);
|
2001-06-09 23:36:23 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
else
|
2004-05-29 13:17:21 +00:00
|
|
|
{
|
|
|
|
return [_popUpList objectAtIndex: index];
|
|
|
|
}
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (id) objectValueOfSelectedItem
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
if (_usesDataSource)
|
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
NSLog(@"%@: This method is invalid, this combo box is set to use a data source",
|
|
|
|
self);
|
2001-06-09 23:36:23 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
int index = [self indexOfSelectedItem];
|
|
|
|
|
2001-07-09 02:49:03 +00:00
|
|
|
if (index == -1)
|
2001-06-09 23:36:23 +00:00
|
|
|
return nil;
|
|
|
|
else
|
|
|
|
return [_popUpList objectAtIndex: index];
|
|
|
|
}
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
- (int) indexOfItemWithObjectValue: (id)object
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2002-12-23 23:21:43 +00:00
|
|
|
if (_usesDataSource)
|
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
NSLog(@"%@: This method is invalid, this combo box is set to use a data source",
|
|
|
|
self);
|
1999-09-09 20:06:52 +00:00
|
|
|
return 0;
|
2002-12-23 23:21:43 +00:00
|
|
|
}
|
2004-05-29 13:17:21 +00:00
|
|
|
|
2002-12-23 23:21:43 +00:00
|
|
|
return [_popUpList indexOfObject: object];
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSArray *)objectValues
|
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
if (_usesDataSource)
|
2002-12-23 23:21:43 +00:00
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
NSLog(@"%@: This method is invalid, this combo box is set to use a data source",
|
|
|
|
self);
|
2002-12-23 23:21:43 +00:00
|
|
|
return nil;
|
|
|
|
}
|
2004-05-29 13:17:21 +00:00
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
return _popUpList;
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-04-09 21:24:53 +00:00
|
|
|
// Text completion
|
|
|
|
- (NSString *)completedString:(NSString *)substring
|
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
if (_usesDataSource)
|
|
|
|
{
|
|
|
|
if (!_dataSource)
|
2004-05-29 13:17:21 +00:00
|
|
|
NSLog(@"%@: A data source should be specified", self);
|
2001-06-09 23:36:23 +00:00
|
|
|
else if ([_dataSource respondsToSelector: @selector(comboBox:completedString:)])
|
|
|
|
{
|
|
|
|
return [_dataSource comboBox: (NSComboBox *)[self controlView]
|
2004-05-29 13:17:21 +00:00
|
|
|
completedString: substring];
|
2001-06-09 23:36:23 +00:00
|
|
|
}
|
|
|
|
else if ([_dataSource respondsToSelector: @selector(comboBoxCell:completedString:)])
|
|
|
|
{
|
|
|
|
return [_dataSource comboBoxCell: self completedString: substring];
|
|
|
|
}
|
2004-05-29 13:17:21 +00:00
|
|
|
else
|
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i = 0; i < [self numberOfItems]; i++)
|
|
|
|
{
|
|
|
|
NSString *str = [self _stringValueAtIndex: i];
|
|
|
|
|
|
|
|
if ([str length] > [substring length] && [str hasPrefix: substring])
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
}
|
2001-06-09 23:36:23 +00:00
|
|
|
}
|
|
|
|
else
|
2004-05-29 13:17:21 +00:00
|
|
|
{
|
|
|
|
unsigned int i;
|
|
|
|
|
|
|
|
for (i = 0; i < [_popUpList count]; i++)
|
|
|
|
{
|
|
|
|
NSString *str = [[_popUpList objectAtIndex: i] description];
|
|
|
|
|
|
|
|
if ([str length] > [substring length] && [str hasPrefix: substring])
|
|
|
|
return str;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-04-09 21:24:53 +00:00
|
|
|
return substring;
|
|
|
|
}
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
- (BOOL)completes { return _completes; }
|
2001-04-09 21:24:53 +00:00
|
|
|
- (void)setCompletes:(BOOL)completes
|
|
|
|
{
|
|
|
|
_completes = completes;
|
|
|
|
}
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
// Inlined methods
|
|
|
|
#define ButtonWidth 18
|
|
|
|
#define BorderWidth 2
|
|
|
|
// the inset border for the top and the bottom of the button
|
2001-04-09 21:24:53 +00:00
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
static inline NSRect textCellFrameFromRect(NSRect cellRect)
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
return NSMakeRect(NSMinX(cellRect),
|
|
|
|
NSMinY(cellRect),
|
2004-05-29 13:17:21 +00:00
|
|
|
NSWidth(cellRect) - ButtonWidth,
|
2001-06-09 23:36:23 +00:00
|
|
|
NSHeight(cellRect));
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
static inline NSRect buttonCellFrameFromRect(NSRect cellRect)
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
return NSMakeRect(NSMaxX(cellRect) - ButtonWidth,
|
|
|
|
NSMinY(cellRect) + BorderWidth,
|
|
|
|
ButtonWidth,
|
|
|
|
NSHeight(cellRect) - (BorderWidth * 2.0));
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Overridden
|
2004-05-29 13:17:21 +00:00
|
|
|
+ (BOOL) prefersTrackingUntilMouseUp
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
return YES;
|
|
|
|
/* Needed to have the clickability of the button take in account when the tracking happens.
|
|
|
|
This method is call by the NSControl -mouseDown: method with the code :
|
|
|
|
[_cell trackMouse: e
|
|
|
|
inRect: _bounds
|
|
|
|
ofView: self
|
|
|
|
untilMouseUp: [[_cell class] prefersTrackingUntilMouseUp]] */
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) drawWithFrame:(NSRect)cellFrame inView:(NSView *)controlView
|
|
|
|
{
|
|
|
|
// FIX ME: Is this test case below with the method call really needed ?
|
|
|
|
if ([GSCurrentContext() isDrawingToScreen])
|
2001-06-09 23:36:23 +00:00
|
|
|
{
|
|
|
|
[super drawWithFrame: textCellFrameFromRect(cellFrame)
|
2004-05-29 13:17:21 +00:00
|
|
|
inView: controlView];
|
2001-06-09 23:36:23 +00:00
|
|
|
[_buttonCell drawWithFrame: buttonCellFrameFromRect(cellFrame)
|
2004-05-29 13:17:21 +00:00
|
|
|
inView: controlView];
|
2001-06-09 23:36:23 +00:00
|
|
|
}
|
|
|
|
else
|
2004-05-29 13:17:21 +00:00
|
|
|
{
|
|
|
|
[super drawWithFrame: cellFrame inView: controlView];
|
|
|
|
}
|
|
|
|
|
|
|
|
_lastValidFrame = cellFrame; // used by GSComboWindow to appear in the right position
|
2001-06-09 23:36:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) highlight: (BOOL)flag
|
|
|
|
withFrame: (NSRect)cellFrame
|
|
|
|
inView: (NSView *)controlView
|
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
// FIX ME: Is this test case below with the method call really needed ?
|
2001-06-09 23:36:23 +00:00
|
|
|
if ([GSCurrentContext() isDrawingToScreen])
|
|
|
|
{
|
|
|
|
[super highlight: flag
|
|
|
|
withFrame: textCellFrameFromRect(cellFrame)
|
2004-05-29 13:17:21 +00:00
|
|
|
inView: controlView];
|
2001-06-09 23:36:23 +00:00
|
|
|
[_buttonCell highlight: flag
|
|
|
|
withFrame: buttonCellFrameFromRect(cellFrame)
|
2004-05-29 13:17:21 +00:00
|
|
|
inView: controlView];
|
2001-06-09 23:36:23 +00:00
|
|
|
}
|
|
|
|
else
|
2004-05-29 13:17:21 +00:00
|
|
|
{
|
|
|
|
[super highlight: flag withFrame: cellFrame inView: controlView];
|
|
|
|
}
|
2001-06-09 23:36:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL) trackMouse: (NSEvent *)theEvent
|
|
|
|
inRect: (NSRect)cellFrame
|
|
|
|
ofView: (NSView *)controlView
|
|
|
|
untilMouseUp: (BOOL)flag
|
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
NSWindow *cvWindow = [controlView window];
|
2001-06-09 23:36:23 +00:00
|
|
|
NSPoint point;
|
2004-05-29 13:17:21 +00:00
|
|
|
BOOL isFlipped = [controlView isFlipped];
|
|
|
|
BOOL clicked = NO;
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
// Should this be set by NSActionCell ?
|
|
|
|
if (_control_view != controlView)
|
|
|
|
_control_view = controlView;
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
point = [controlView convertPoint: [theEvent locationInWindow]
|
|
|
|
fromView: nil];
|
2001-06-09 23:36:23 +00:00
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
if (!NSMouseInRect(point, cellFrame, isFlipped))
|
|
|
|
return NO;
|
|
|
|
else if ([theEvent type] == NSLeftMouseDown)
|
2001-06-09 23:36:23 +00:00
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
if (NSMouseInRect(point, textCellFrameFromRect(cellFrame), isFlipped))
|
|
|
|
{
|
|
|
|
return YES;// continue
|
2001-06-09 23:36:23 +00:00
|
|
|
}
|
2004-05-29 13:17:21 +00:00
|
|
|
else if (NSMouseInRect(point, buttonCellFrameFromRect(cellFrame), isFlipped))
|
|
|
|
{
|
|
|
|
[controlView lockFocus];
|
|
|
|
[_buttonCell highlight: YES withFrame: buttonCellFrameFromRect(cellFrame) inView: controlView];
|
|
|
|
[controlView unlockFocus];
|
|
|
|
[cvWindow flushWindow];
|
|
|
|
|
|
|
|
clicked = [_buttonCell trackMouse: theEvent
|
|
|
|
inRect: buttonCellFrameFromRect(cellFrame)
|
|
|
|
ofView: controlView
|
|
|
|
untilMouseUp: NO];
|
|
|
|
|
|
|
|
/* We can do the call below but it is already done by the target/action we have set for the button cell
|
|
|
|
if (clicked)
|
|
|
|
[self _didClickWithinButton: self]; // not to be used */
|
|
|
|
|
|
|
|
[controlView lockFocus];
|
|
|
|
[_buttonCell highlight: NO withFrame: buttonCellFrameFromRect(cellFrame) inView: controlView];
|
|
|
|
[controlView unlockFocus];
|
|
|
|
[cvWindow flushWindow];
|
|
|
|
|
|
|
|
return NO;
|
|
|
|
}
|
2001-06-09 23:36:23 +00:00
|
|
|
}
|
2004-05-29 13:17:21 +00:00
|
|
|
|
|
|
|
return NO;
|
2001-06-09 23:36:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) resetCursorRect: (NSRect)cellFrame inView: (NSView *)controlView
|
|
|
|
{
|
2002-12-23 23:21:43 +00:00
|
|
|
[super resetCursorRect: textCellFrameFromRect(cellFrame)
|
|
|
|
inView: controlView];
|
2001-06-09 23:36:23 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setEnabled: (BOOL)flag
|
|
|
|
{
|
2002-12-23 23:21:43 +00:00
|
|
|
[_buttonCell setEnabled: flag];
|
|
|
|
[super setEnabled: flag];
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
// NSCoding
|
|
|
|
- (void) encodeWithCoder: (NSCoder *)coder
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2001-06-09 23:36:23 +00:00
|
|
|
[super encodeWithCoder: coder];
|
1999-09-09 20:06:52 +00:00
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
[coder encodeValueOfObjCType: @encode(id) at: &_buttonCell];
|
|
|
|
[coder encodeValueOfObjCType: @encode(id) at: &_popUpList];
|
|
|
|
[coder encodeValueOfObjCType: @encode(BOOL) at: &_usesDataSource];
|
|
|
|
[coder encodeValueOfObjCType: @encode(BOOL) at: &_hasVerticalScroller];
|
|
|
|
[coder encodeValueOfObjCType: @encode(BOOL) at: &_completes];
|
|
|
|
[coder encodeValueOfObjCType: @encode(BOOL) at: &_usesDataSource];
|
|
|
|
[coder encodeValueOfObjCType: @encode(int) at: &_visibleItems];
|
|
|
|
[coder encodeValueOfObjCType: @encode(NSSize) at: &_intercellSpacing];
|
|
|
|
[coder encodeValueOfObjCType: @encode(float) at: &_itemHeight];
|
|
|
|
[coder encodeValueOfObjCType: @encode(int) at: &_selectedItem];
|
1999-09-09 20:06:52 +00:00
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
if (_usesDataSource == YES)
|
2002-12-23 23:21:43 +00:00
|
|
|
[coder encodeConditionalObject: _dataSource];
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2004-02-06 00:16:54 +00:00
|
|
|
- (id) initWithCoder: (NSCoder *)aDecoder
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2004-02-06 00:16:54 +00:00
|
|
|
self = [super initWithCoder: aDecoder];
|
2002-12-23 23:21:43 +00:00
|
|
|
|
2004-02-06 00:16:54 +00:00
|
|
|
if ([aDecoder allowsKeyedCoding])
|
|
|
|
{
|
|
|
|
//id delegate = [aDecoder decodeObjectForKey: @"NSDelegate"];
|
|
|
|
// FIXME: This does not match the way GNUstep currently implements
|
|
|
|
// the list of popup items.
|
|
|
|
//id table = [aDecoder decodeObjectForKey: @"NSTableView"];
|
1999-09-09 20:06:52 +00:00
|
|
|
|
2004-02-06 00:16:54 +00:00
|
|
|
if ([aDecoder containsValueForKey: @"NSHasVerticalScroller"])
|
|
|
|
{
|
|
|
|
[self setHasVerticalScroller: [aDecoder decodeBoolForKey:
|
|
|
|
@"NSHasVerticalScroller"]];
|
|
|
|
}
|
|
|
|
if ([aDecoder containsValueForKey: @"NSVisibleItemCount"])
|
|
|
|
{
|
|
|
|
[self setNumberOfVisibleItems: [aDecoder decodeIntForKey:
|
|
|
|
@"NSVisibleItemCount"]];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
BOOL dummy;
|
|
|
|
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(id) at: &_buttonCell];
|
|
|
|
RETAIN(_buttonCell);
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(id) at: &_popUpList];
|
|
|
|
RETAIN(_popUpList);
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_usesDataSource];
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_hasVerticalScroller];
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &_completes];
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &dummy];
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(int) at: &_visibleItems];
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(NSSize) at: &_intercellSpacing];
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(float) at: &_itemHeight];
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(int) at: &_selectedItem];
|
|
|
|
|
|
|
|
if (_usesDataSource == YES)
|
|
|
|
[self setDataSource: [aDecoder decodeObject]];
|
|
|
|
}
|
1999-09-09 20:06:52 +00:00
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
return self;
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
- (void) selectWithFrame: (NSRect)aRect
|
|
|
|
inView: (NSView *)controlView
|
|
|
|
editor: (NSText *)textObj
|
|
|
|
delegate: (id)anObject
|
|
|
|
start: (int)selStart
|
|
|
|
length: (int)selLength
|
|
|
|
{
|
|
|
|
[super selectWithFrame: textCellFrameFromRect(aRect)
|
|
|
|
inView: controlView
|
|
|
|
editor: textObj
|
|
|
|
delegate: anObject
|
|
|
|
start: selStart
|
|
|
|
length: selLength];
|
|
|
|
|
|
|
|
[nc addObserver: self
|
|
|
|
selector: @selector(textDidChange:)
|
|
|
|
name: NSTextDidChangeNotification
|
|
|
|
object: textObj];
|
|
|
|
[nc addObserver: self
|
|
|
|
selector: @selector(textViewDidChangeSelection:)
|
|
|
|
name: NSTextViewDidChangeSelectionNotification
|
|
|
|
object: textObj];
|
|
|
|
|
|
|
|
// This method is called when the cell obtains the focus;
|
|
|
|
// don't know why the next method editWithFrame: is not called
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) editWithFrame: (NSRect)frame
|
|
|
|
inView: (NSView *)controlView
|
|
|
|
editor: (NSText *)textObj
|
|
|
|
delegate: (id)delegate
|
|
|
|
event: (NSEvent *)theEvent
|
|
|
|
{
|
|
|
|
[super editWithFrame: textCellFrameFromRect(frame)
|
|
|
|
inView: controlView
|
|
|
|
editor: textObj
|
|
|
|
delegate: delegate
|
|
|
|
event: theEvent];
|
|
|
|
|
|
|
|
/*
|
|
|
|
[nc addObserver: self
|
|
|
|
selector: @selector(textDidChange:)
|
|
|
|
name: NSTextDidChangeNotification
|
|
|
|
object: textObj];
|
|
|
|
[nc addObserver: self
|
|
|
|
selector: @selector(textViewDidChangeSelection:)
|
|
|
|
name: NSTextViewDidChangeSelectionNotification
|
|
|
|
object: textObj]; */
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) endEditing: (NSText *)editor
|
|
|
|
{
|
|
|
|
[super endEditing: editor];
|
|
|
|
[nc removeObserver: self name: NSTextDidChangeNotification object: editor];
|
|
|
|
[nc removeObserver: self
|
|
|
|
name: NSTextViewDidChangeSelectionNotification
|
|
|
|
object: editor];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) textViewDidChangeSelection: (NSNotification *)notification
|
|
|
|
{
|
|
|
|
_prevSelectedRange = [[[notification userInfo]
|
|
|
|
objectForKey: @"NSOldSelectedCharacterRange"] rangeValue];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) textDidChange: (NSNotification *)notification
|
|
|
|
{
|
|
|
|
NSText *textObject = [notification object];
|
|
|
|
|
|
|
|
if ([self completes])
|
|
|
|
{
|
|
|
|
NSString *myString = [[textObject string] copy];
|
|
|
|
NSString *more;
|
|
|
|
unsigned int myStringLength = [myString length];
|
|
|
|
unsigned int location, length;
|
|
|
|
NSRange selectedRange = [textObject selectedRange];
|
|
|
|
|
|
|
|
if (myStringLength != 0
|
|
|
|
&& selectedRange.location == myStringLength
|
|
|
|
&& _prevSelectedRange.location < selectedRange.location)
|
|
|
|
{
|
|
|
|
more = [self completedString: myString];
|
|
|
|
if (![more isEqualToString: myString])
|
|
|
|
{
|
|
|
|
[textObject setString: more];
|
|
|
|
location = myStringLength;
|
|
|
|
length = [more length] - location;
|
|
|
|
[textObject setSelectedRange: NSMakeRange(location, length)];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-09-09 20:06:52 +00:00
|
|
|
@end
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
@implementation NSComboBoxCell (GNUstepPrivate)
|
1999-09-09 20:06:52 +00:00
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
- (NSString *) _stringValueAtIndex: (int)index
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2002-12-23 23:21:43 +00:00
|
|
|
if (!_usesDataSource)
|
|
|
|
{
|
|
|
|
return [[self itemObjectValueAtIndex: index] description];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (!_dataSource)
|
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
NSLog(@"%@: No data source currently specified", self);
|
2002-12-23 23:21:43 +00:00
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
if ([_dataSource respondsToSelector:
|
|
|
|
@selector(comboBox:objectValueForItemAtIndex:)])
|
|
|
|
{
|
|
|
|
return [[_dataSource comboBox: (NSComboBox *)[self controlView]
|
|
|
|
objectValueForItemAtIndex: index] description];
|
|
|
|
}
|
|
|
|
else if ([_dataSource respondsToSelector:
|
|
|
|
@selector(comboBoxCell:objectValueForItemAtIndex:)])
|
|
|
|
{
|
|
|
|
return [[_dataSource comboBoxCell: self
|
|
|
|
objectValueForItemAtIndex: index] description];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil;
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
- (void) _performClickWithFrame: (NSRect)cellFrame
|
|
|
|
inView: (NSView *)controlView
|
2001-06-09 23:36:23 +00:00
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
NSWindow *cvWindow = [controlView window];
|
2003-02-01 05:10:00 +00:00
|
|
|
|
|
|
|
[controlView lockFocus];
|
2001-06-09 23:36:23 +00:00
|
|
|
[_buttonCell highlight: YES
|
|
|
|
withFrame: buttonCellFrameFromRect(cellFrame)
|
2004-05-29 13:17:21 +00:00
|
|
|
inView: controlView];
|
2003-02-01 05:10:00 +00:00
|
|
|
[controlView unlockFocus];
|
2004-05-29 13:17:21 +00:00
|
|
|
[cvWindow flushWindow];
|
2001-06-09 23:36:23 +00:00
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
[self _didClickWithinButton: self];
|
2001-06-09 23:36:23 +00:00
|
|
|
|
2003-02-01 05:10:00 +00:00
|
|
|
[controlView lockFocus];
|
2001-06-09 23:36:23 +00:00
|
|
|
[_buttonCell highlight: NO
|
|
|
|
withFrame: buttonCellFrameFromRect(cellFrame)
|
2004-05-29 13:17:21 +00:00
|
|
|
inView: controlView];
|
2003-02-01 05:10:00 +00:00
|
|
|
[controlView unlockFocus];
|
2004-05-29 13:17:21 +00:00
|
|
|
[cvWindow flushWindow];
|
2003-02-01 05:10:00 +00:00
|
|
|
|
2001-06-09 23:36:23 +00:00
|
|
|
}
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
- (void) _didClickWithinButton: (id)sender
|
2001-06-09 23:36:23 +00:00
|
|
|
{
|
2004-05-29 13:17:21 +00:00
|
|
|
NSView *controlView = [self controlView];
|
|
|
|
|
|
|
|
if ((_cell.is_disabled) || (controlView == nil))
|
2001-06-09 23:36:23 +00:00
|
|
|
return;
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
[nc postNotificationName: NSComboBoxWillPopUpNotification
|
|
|
|
object: controlView
|
|
|
|
userInfo: nil];
|
|
|
|
|
2002-12-23 23:21:43 +00:00
|
|
|
_popup = [self _popUp];
|
2004-05-29 13:17:21 +00:00
|
|
|
[_popup popUpForComboBoxCell: self];
|
2002-12-23 23:21:43 +00:00
|
|
|
_popup = nil;
|
2001-06-09 23:36:23 +00:00
|
|
|
|
|
|
|
[nc postNotificationName: NSComboBoxWillDismissNotification
|
2004-05-29 13:17:21 +00:00
|
|
|
object: controlView
|
|
|
|
userInfo: nil];
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
- (BOOL) _isWantedEvent: (NSEvent *)event
|
|
|
|
{
|
|
|
|
NSPoint loc;
|
|
|
|
NSWindow *window = [event window];
|
|
|
|
NSView *controlView = [self controlView];
|
|
|
|
|
|
|
|
if (window == [[self controlView] window])
|
|
|
|
{
|
|
|
|
loc = [event locationInWindow];
|
|
|
|
loc = [controlView convertPoint: loc fromView: nil];
|
|
|
|
return NSMouseInRect(loc, [self _textCellFrame], [controlView isFlipped]);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (GSComboWindow *) _popUp
|
1999-09-09 20:06:52 +00:00
|
|
|
{
|
2002-12-23 23:21:43 +00:00
|
|
|
return [GSComboWindow defaultPopUp];
|
1999-09-09 20:06:52 +00:00
|
|
|
}
|
|
|
|
|
2004-05-29 13:17:21 +00:00
|
|
|
- (NSRect) _textCellFrame
|
|
|
|
{
|
|
|
|
return textCellFrameFromRect(_lastValidFrame);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) _setSelectedItem: (int)index
|
|
|
|
{
|
|
|
|
_selectedItem = index;
|
|
|
|
}
|
|
|
|
|
1999-09-09 20:06:52 +00:00
|
|
|
@end
|