1996-05-30 20:03:15 +00:00
|
|
|
/*
|
|
|
|
NSColorPanel.m
|
|
|
|
|
|
|
|
System generic color panel
|
|
|
|
|
|
|
|
Copyright (C) 1996 Free Software Foundation, Inc.
|
|
|
|
|
|
|
|
Author: Scott Christley <scottc@net-community.com>
|
|
|
|
Date: 1996
|
|
|
|
|
|
|
|
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
|
1996-10-18 17:14:13 +00:00
|
|
|
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.
|
1996-05-30 20:03:15 +00:00
|
|
|
*/
|
|
|
|
|
1997-09-23 22:43:24 +00:00
|
|
|
#include <gnustep/gui/config.h>
|
2000-04-18 02:27:45 +00:00
|
|
|
#include <Foundation/NSBundle.h>
|
|
|
|
#include <Foundation/NSEnumerator.h>
|
|
|
|
#include <Foundation/NSFileManager.h>
|
|
|
|
#include <Foundation/NSLock.h>
|
|
|
|
#include <Foundation/NSPathUtilities.h>
|
|
|
|
#include <AppKit/NSColor.h>
|
1997-02-18 00:29:25 +00:00
|
|
|
#include <AppKit/NSColorPanel.h>
|
2000-04-18 02:27:45 +00:00
|
|
|
#include <AppKit/NSColorPicker.h>
|
|
|
|
#include <AppKit/NSColorPicking.h>
|
|
|
|
#include <AppKit/NSColorWell.h>
|
|
|
|
#include <AppKit/NSPasteboard.h>
|
|
|
|
#include <AppKit/NSWindow.h>
|
|
|
|
#include <AppKit/IMLoading.h>
|
|
|
|
|
|
|
|
static NSLock *_gs_gui_color_panel_lock = nil;
|
|
|
|
static NSColorPanel *_gs_gui_color_panel = nil;
|
|
|
|
static int _gs_gui_color_picker_mask = NSColorPanelAllModesMask;
|
|
|
|
static int _gs_gui_color_picker_mode = NSRGBModeColorPanel;
|
|
|
|
|
|
|
|
@interface GSAppKitPanelController : NSObject
|
|
|
|
{
|
|
|
|
@public
|
|
|
|
id panel;
|
|
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation GSAppKitPanelController
|
|
|
|
@end
|
|
|
|
|
|
|
|
@interface NSColorPanel (PrivateMethods)
|
|
|
|
- (void) _loadPickers;
|
|
|
|
- (void) _loadPickerAtPath: (NSString *)path;
|
|
|
|
- (void) _fixupMatrix;
|
|
|
|
- (void) _setupPickers;
|
|
|
|
- (void) _showNewPicker: (id)sender;
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation NSColorPanel (PrivateMethods)
|
|
|
|
|
|
|
|
- (void) _loadPickers
|
|
|
|
{
|
|
|
|
NSArray *paths;
|
|
|
|
NSString *path;
|
|
|
|
NSEnumerator *pathEnumerator;
|
|
|
|
NSArray *bundles;
|
|
|
|
NSEnumerator *bundleEnumerator;
|
|
|
|
NSString *bundleName;
|
|
|
|
|
|
|
|
_pickers = [NSMutableArray new];
|
|
|
|
|
|
|
|
paths = NSSearchPathForDirectoriesInDomains(NSLibraryDirectory,
|
|
|
|
NSAllDomainsMask, YES);
|
|
|
|
|
|
|
|
pathEnumerator = [paths objectEnumerator];
|
|
|
|
while ((path = [pathEnumerator nextObject]))
|
|
|
|
{
|
|
|
|
path = [path stringByAppendingPathComponent: @"ColorPickers"];
|
|
|
|
bundles = [[NSFileManager defaultManager] directoryContentsAtPath: path];
|
|
|
|
|
|
|
|
bundleEnumerator = [bundles objectEnumerator];
|
|
|
|
while ((bundleName = [bundleEnumerator nextObject]))
|
|
|
|
[self _loadPickerAtPath:
|
|
|
|
[path stringByAppendingPathComponent: bundleName]];
|
|
|
|
}
|
|
|
|
|
|
|
|
paths = [[NSBundle mainBundle] pathsForResourcesOfType: @"bundle"
|
|
|
|
inDirectory: @"ColorPickers"];
|
|
|
|
|
|
|
|
pathEnumerator = [paths objectEnumerator];
|
|
|
|
while ((path = [pathEnumerator nextObject]))
|
|
|
|
[self _loadPickerAtPath: path];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) _loadPickerAtPath: (NSString *)path
|
|
|
|
{
|
|
|
|
NSBundle *bundle;
|
|
|
|
Class pickerClass;
|
|
|
|
NSColorPicker *picker;
|
|
|
|
|
|
|
|
bundle = [NSBundle bundleWithPath: path];
|
|
|
|
if (bundle && (pickerClass = [bundle principalClass]))
|
|
|
|
{
|
|
|
|
picker = [[pickerClass alloc] initWithPickerMask:_gs_gui_color_picker_mask
|
|
|
|
colorPanel:_gs_gui_color_panel];
|
|
|
|
if (picker && [picker conformsToProtocol:@protocol(NSColorPickingCustom)])
|
|
|
|
{
|
|
|
|
[picker provideNewView: YES];
|
|
|
|
[_pickers addObject: picker];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
NSLog(@"%@ does not contain a valid color picker.");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// FIXME - this is a HACK to get around problems in the gmodel code
|
|
|
|
- (void) _fixupMatrix
|
|
|
|
{
|
|
|
|
[_pickerMatrix setFrame: NSMakeRect(4, 190, 192, 36)];
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) _setupPickers
|
|
|
|
{
|
|
|
|
NSColorPicker *picker;
|
|
|
|
NSButtonCell *cell;
|
|
|
|
NSMutableArray *cells = [NSMutableArray new];
|
|
|
|
int i, count;
|
|
|
|
NSSize size = [_pickerMatrix frame].size;
|
|
|
|
|
|
|
|
count = [_pickers count];
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
cell = [[_pickerMatrix prototype] copy];
|
|
|
|
[cell setTag: i];
|
|
|
|
picker = [_pickers objectAtIndex: i];
|
|
|
|
[picker insertNewButtonImage: [picker provideNewButtonImage] in: cell];
|
|
|
|
[cells addObject: cell];
|
|
|
|
}
|
|
|
|
|
|
|
|
[_pickerMatrix addRowWithCells: cells];
|
|
|
|
[_pickerMatrix setCellSize: NSMakeSize(size.width / count, size.height)];
|
|
|
|
[_pickerMatrix setTarget: self];
|
|
|
|
[_pickerMatrix setAction: @selector(_showNewPicker:)];
|
|
|
|
|
|
|
|
// use the space occupied by the matrix of color picker buttons if the
|
|
|
|
// button matrix is useless, i.e. it contains only one button
|
|
|
|
if (count < 2)
|
|
|
|
{
|
|
|
|
[_pickerBox setFrame: NSUnionRect([_pickerBox frame],
|
|
|
|
[_pickerMatrix frame])];
|
|
|
|
[_pickerBox setNeedsDisplay: YES];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) _showNewPicker: (id)sender
|
|
|
|
{
|
|
|
|
_currentPicker = [_pickers objectAtIndex: [sender selectedColumn]];
|
|
|
|
[_pickerBox setContentView: [_currentPicker provideNewView: NO]];
|
|
|
|
}
|
|
|
|
@end
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
@implementation NSColorPanel
|
|
|
|
|
|
|
|
//
|
|
|
|
// Class methods
|
|
|
|
//
|
|
|
|
+ (void)initialize
|
|
|
|
{
|
|
|
|
if (self == [NSColorPanel class])
|
|
|
|
{
|
|
|
|
// Initial version
|
|
|
|
[self setVersion:1];
|
2000-04-18 02:27:45 +00:00
|
|
|
_gs_gui_color_panel_lock = [NSLock new];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Creating the NSColorPanel
|
|
|
|
//
|
|
|
|
+ (NSColorPanel *)sharedColorPanel
|
|
|
|
{
|
2000-04-18 02:27:45 +00:00
|
|
|
if (_gs_gui_color_panel == nil)
|
|
|
|
{
|
|
|
|
[_gs_gui_color_panel_lock lock];
|
|
|
|
if (!_gs_gui_color_panel)
|
|
|
|
{
|
|
|
|
GSAppKitPanelController *panelCtrl = [GSAppKitPanelController new];
|
|
|
|
|
|
|
|
if ([GMModel loadIMFile:@"ColorPanel" owner:panelCtrl])
|
|
|
|
{
|
|
|
|
_gs_gui_color_panel = panelCtrl->panel;
|
|
|
|
[_gs_gui_color_panel _fixupMatrix];
|
|
|
|
[_gs_gui_color_panel _loadPickers];
|
|
|
|
[_gs_gui_color_panel _setupPickers];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
[_gs_gui_color_panel_lock unlock];
|
|
|
|
}
|
|
|
|
|
|
|
|
//[_gs_gui_color_panel setMode: _gs_gui_color_picker_mode];
|
|
|
|
[_gs_gui_color_panel setMode: NSColorListModeColorPanel];
|
|
|
|
return _gs_gui_color_panel;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
+ (BOOL)sharedColorPanelExists
|
|
|
|
{
|
2000-04-18 02:27:45 +00:00
|
|
|
return (_gs_gui_color_panel == nil) ? NO : YES;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Setting the NSColorPanel
|
|
|
|
//
|
|
|
|
+ (void)setPickerMask:(int)mask
|
2000-04-18 02:27:45 +00:00
|
|
|
{
|
|
|
|
_gs_gui_color_picker_mask = mask;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
+ (void)setPickerMode:(int)mode
|
2000-04-18 02:27:45 +00:00
|
|
|
{
|
|
|
|
_gs_gui_color_picker_mode = mode;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// Setting Color
|
|
|
|
//
|
2000-04-18 02:27:45 +00:00
|
|
|
+ (BOOL)dragColor:(NSColor *)aColor
|
|
|
|
withEvent:(NSEvent *)anEvent
|
|
|
|
fromView:(NSView *)sourceView
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
2000-04-18 02:27:45 +00:00
|
|
|
NSPasteboard *pb = [NSPasteboard pasteboardWithName: NSDragPboard];
|
2000-04-28 00:33:36 +00:00
|
|
|
NSImage *image = [NSImage imageNamed: @"common_ColorSwatch"];
|
2000-04-18 02:27:45 +00:00
|
|
|
|
|
|
|
[pb declareTypes: [NSArray arrayWithObjects: NSColorPboardType, nil]
|
|
|
|
owner: aColor];
|
|
|
|
[aColor writeToPasteboard: pb];
|
|
|
|
[image setBackgroundColor: aColor];
|
|
|
|
|
|
|
|
[sourceView dragImage: image
|
2000-08-31 23:17:42 +00:00
|
|
|
at: [sourceView bounds].origin
|
2000-04-18 02:27:45 +00:00
|
|
|
offset: NSMakeSize(0,0)
|
|
|
|
event: anEvent
|
|
|
|
pasteboard: pb
|
|
|
|
source: sourceView
|
|
|
|
slideBack: NO];
|
|
|
|
|
|
|
|
return YES;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Instance methods
|
|
|
|
//
|
|
|
|
|
|
|
|
//
|
|
|
|
// Setting the NSColorPanel
|
|
|
|
//
|
|
|
|
- (NSView *)accessoryView
|
|
|
|
{
|
2000-04-18 02:27:45 +00:00
|
|
|
return [_accessoryBox contentView];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (BOOL)isContinuous
|
|
|
|
{
|
2000-04-18 02:27:45 +00:00
|
|
|
return _isContinuous;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (int)mode
|
|
|
|
{
|
2000-04-18 02:27:45 +00:00
|
|
|
if (_currentPicker != nil)
|
|
|
|
return [_currentPicker currentMode];
|
|
|
|
else
|
|
|
|
return 0;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setAccessoryView:(NSView *)aView
|
2000-04-18 02:27:45 +00:00
|
|
|
{
|
|
|
|
[_accessoryBox setContentView: aView];
|
|
|
|
// [_accessoryBox sizeToFit];
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
- (void)setAction:(SEL)aSelector
|
2000-04-18 02:27:45 +00:00
|
|
|
{
|
|
|
|
_action = aSelector;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
- (void)setContinuous:(BOOL)flag
|
2000-04-18 02:27:45 +00:00
|
|
|
{
|
|
|
|
_isContinuous = flag;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
- (void)setMode:(int)mode
|
2000-04-18 02:27:45 +00:00
|
|
|
{
|
|
|
|
int i, count;
|
|
|
|
|
|
|
|
if (mode == [self mode])
|
|
|
|
return;
|
|
|
|
|
|
|
|
count = [_pickers count];
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
if ([[_pickers objectAtIndex: i] supportsMode: mode])
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
// if i == count, no picker was found
|
|
|
|
if (i != count)
|
|
|
|
{
|
|
|
|
[_pickerMatrix selectCellWithTag: i];
|
|
|
|
[self _showNewPicker: _pickerMatrix];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// This code is very simple-minded. Instead of removing the alpha slider,
|
|
|
|
// why not just cover it up?
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
- (void)setShowsAlpha:(BOOL)flag
|
2000-04-18 02:27:45 +00:00
|
|
|
{
|
|
|
|
if (flag && ![self showsAlpha])
|
|
|
|
{
|
|
|
|
NSRect newFrame = [_pickerBox frame];
|
|
|
|
float offset = [_alphaSlider frame].size.height + 4;
|
|
|
|
|
|
|
|
newFrame.origin.y += offset;
|
|
|
|
newFrame.size.height -= offset;
|
|
|
|
[_pickerBox setFrame: newFrame];
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
[_pickerBox setFrame: NSUnionRect([_pickerBox frame],
|
|
|
|
[_alphaSlider frame])];
|
|
|
|
}
|
|
|
|
|
|
|
|
[_pickers makeObjectsPerformSelector: @selector(alphaControlAddedOrRemoved:)
|
|
|
|
withObject: self];
|
|
|
|
|
|
|
|
[_topView setNeedsDisplay: YES];
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
- (void)setTarget:(id)anObject
|
2000-04-18 02:27:45 +00:00
|
|
|
{
|
|
|
|
ASSIGN(_target, anObject);
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
- (BOOL)showsAlpha
|
|
|
|
{
|
2000-04-18 02:27:45 +00:00
|
|
|
if (NSIntersectsRect([_pickerBox frame], [_alphaSlider frame]))
|
|
|
|
return NO;
|
|
|
|
else
|
|
|
|
return YES;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// Attaching a Color List
|
|
|
|
//
|
|
|
|
- (void)attachColorList:(NSColorList *)aColorList
|
2000-04-18 02:27:45 +00:00
|
|
|
{
|
|
|
|
NSEnumerator *enumerator;
|
|
|
|
id picker;
|
|
|
|
|
|
|
|
if ((_pickers != nil) && ([_pickers count] > 0))
|
|
|
|
{
|
|
|
|
enumerator = [_pickers objectEnumerator];
|
|
|
|
while ((picker = [enumerator nextObject]))
|
|
|
|
[picker attachColorList: aColorList];
|
|
|
|
}
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
- (void)detachColorList:(NSColorList *)aColorList
|
2000-04-18 02:27:45 +00:00
|
|
|
{
|
|
|
|
NSEnumerator *enumerator;
|
|
|
|
id picker;
|
|
|
|
|
|
|
|
if ((_pickers != nil) && ([_pickers count] > 0))
|
|
|
|
{
|
|
|
|
enumerator = [_pickers objectEnumerator];
|
|
|
|
while ((picker = [enumerator nextObject]))
|
|
|
|
[picker detachColorList: aColorList];
|
|
|
|
}
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// Setting Color
|
|
|
|
//
|
|
|
|
- (float)alpha
|
|
|
|
{
|
2000-04-18 02:27:45 +00:00
|
|
|
if ([self showsAlpha])
|
|
|
|
return [_alphaSlider floatValue];
|
|
|
|
else
|
|
|
|
return 1.0;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (NSColor *)color
|
|
|
|
{
|
2000-04-18 02:27:45 +00:00
|
|
|
return [_colorWell color];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setColor:(NSColor *)aColor
|
2000-04-18 02:27:45 +00:00
|
|
|
{
|
|
|
|
[_colorWell setColor: aColor];
|
|
|
|
[[NSNotificationCenter defaultCenter]
|
|
|
|
postNotificationName: NSColorPanelColorChangedNotification
|
|
|
|
object: (id)self];
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// NSCoding protocol
|
|
|
|
//
|
1999-03-02 08:58:30 +00:00
|
|
|
- (void) encodeWithCoder: (NSCoder*)aCoder
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1999-03-02 08:58:30 +00:00
|
|
|
[super encodeWithCoder: aCoder];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1999-03-02 08:58:30 +00:00
|
|
|
- (id) initWithCoder: (NSCoder*)aDecoder
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1999-03-02 08:58:30 +00:00
|
|
|
[super initWithCoder: aDecoder];
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|