1999-12-16 18:06:22 +00:00
|
|
|
/* GormPalettesManager.m
|
1999-12-08 15:04:57 +00:00
|
|
|
*
|
|
|
|
* Copyright (C) 1999 Free Software Foundation, Inc.
|
|
|
|
*
|
|
|
|
* Author: Richard Frith-Macdonald <richard@brainstrom.co.uk>
|
|
|
|
* Date: 1999
|
|
|
|
*
|
|
|
|
* This file is part of GNUstep.
|
|
|
|
*
|
|
|
|
* This program is free software; you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* This program 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 General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with this program; if not, write to the Free Software
|
|
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "GormPrivate.h"
|
|
|
|
|
1999-12-16 18:06:22 +00:00
|
|
|
@interface GormPalettePanel : NSPanel
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation GormPalettePanel
|
2001-01-27 06:18:17 +00:00
|
|
|
- (BOOL) canBecomeKeyWindow
|
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
- (BOOL) canBecomeMainWindow
|
1999-12-16 18:06:22 +00:00
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
@end
|
|
|
|
|
1999-12-08 15:04:57 +00:00
|
|
|
@interface GormPaletteView : NSView
|
|
|
|
{
|
|
|
|
NSPasteboard *dragPb;
|
|
|
|
}
|
|
|
|
- (void) draggedImage: (NSImage*)i endedAt: (NSPoint)p deposited: (BOOL)f;
|
|
|
|
- (unsigned int) draggingSourceOperationMaskForLocal: (BOOL)flag;
|
|
|
|
@end
|
|
|
|
|
|
|
|
@implementation GormPaletteView
|
|
|
|
|
|
|
|
static NSImage *dragImage = nil;
|
|
|
|
+ (void) initialize
|
|
|
|
{
|
|
|
|
if (self == [GormPaletteView class])
|
|
|
|
{
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2001-01-27 06:18:17 +00:00
|
|
|
- (BOOL) acceptsFirstMouse: (NSEvent*)theEvent
|
|
|
|
{
|
|
|
|
return YES; /* Ensure we get initial mouse down event. */
|
|
|
|
}
|
|
|
|
|
1999-12-08 15:04:57 +00:00
|
|
|
/*
|
|
|
|
* Initialisation - register to receive DnD with our own types.
|
|
|
|
*/
|
|
|
|
- (id) initWithFrame: (NSRect)aFrame
|
|
|
|
{
|
|
|
|
self = [super initWithFrame: aFrame];
|
|
|
|
if (self != nil)
|
|
|
|
{
|
|
|
|
[self registerForDraggedTypes: [NSArray arrayWithObjects:
|
|
|
|
IBCellPboardType, IBMenuPboardType, IBMenuCellPboardType,
|
|
|
|
IBObjectPboardType, IBViewPboardType, IBWindowPboardType, nil]];
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
2001-01-26 18:19:12 +00:00
|
|
|
- (void) dealloc
|
|
|
|
{
|
|
|
|
DESTROY(dragPb);
|
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
1999-12-08 15:04:57 +00:00
|
|
|
/*
|
|
|
|
* Dragging source protocol implementation
|
|
|
|
*/
|
|
|
|
- (void) draggedImage: (NSImage*)i endedAt: (NSPoint)p deposited: (BOOL)f
|
|
|
|
{
|
|
|
|
NSString *type = [[dragPb types] lastObject];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Windows are an exception to the normal DnD mechanism - we create them
|
|
|
|
* if they are dropped anywhere except back in the pallettes view -
|
|
|
|
* ie. if they are dragged, but the drop fails.
|
|
|
|
*/
|
|
|
|
if (f == NO && [type isEqual: IBWindowPboardType] == YES)
|
|
|
|
{
|
|
|
|
id<IBDocuments> active = [(id<IB>)NSApp activeDocument];
|
|
|
|
|
|
|
|
if (active != nil)
|
|
|
|
{
|
|
|
|
[active pasteType: type fromPasteboard: dragPb parent: nil];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
- (unsigned int) draggingSourceOperationMaskForLocal: (BOOL)flag
|
|
|
|
{
|
|
|
|
return NSDragOperationCopy;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Dragging destination protocol implementation
|
|
|
|
*
|
|
|
|
* We actually don't handle anything being dropped on the palette,
|
|
|
|
* but we pretend to accept drops from ourself, so that the drag
|
|
|
|
* session quietly terminates - and it looks like the drop has
|
|
|
|
* been successful - this stops windows being created when they are
|
|
|
|
* dropped back on the palette (a window is normally created if the
|
|
|
|
* dnd drop is refused).
|
|
|
|
*/
|
|
|
|
- (unsigned) draggingEntered: (id<NSDraggingInfo>)sender
|
|
|
|
{
|
|
|
|
return NSDragOperationCopy;;
|
|
|
|
}
|
|
|
|
- (BOOL) performDragOperation: (id<NSDraggingInfo>)sender
|
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
- (BOOL) prepareForDragOperation: (id<NSDraggingInfo>)sender
|
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Intercepting events in the view and handling them
|
|
|
|
*/
|
|
|
|
- (NSView*) hitTest: (NSPoint)loc
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Stop the subviews receiving events - we grab them all.
|
|
|
|
*/
|
|
|
|
if ([super hitTest: loc] != nil)
|
|
|
|
return self;
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) mouseDown: (NSEvent*)theEvent
|
|
|
|
{
|
2001-01-27 07:11:31 +00:00
|
|
|
NSPoint dragPoint = [theEvent locationInWindow];
|
|
|
|
NSView *view = [super hitTest: dragPoint];
|
|
|
|
GormDocument *active = [(id<IB>)NSApp activeDocument];
|
2001-06-07 03:57:51 +00:00
|
|
|
NSRect rect;
|
2001-01-27 07:11:31 +00:00
|
|
|
NSString *type;
|
|
|
|
id obj;
|
|
|
|
NSPasteboard *pb;
|
|
|
|
NSImageRep *rep;
|
1999-12-08 15:04:57 +00:00
|
|
|
|
2001-01-27 07:11:31 +00:00
|
|
|
if (view == self || view == nil)
|
1999-12-08 15:04:57 +00:00
|
|
|
{
|
2001-01-27 07:11:31 +00:00
|
|
|
return; // No subview to drag.
|
1999-12-08 15:04:57 +00:00
|
|
|
}
|
2001-06-07 03:57:51 +00:00
|
|
|
/* Make sure we're dragging the proper control and not a subview of a
|
|
|
|
control (like the contentView of an NSBox) */
|
|
|
|
while (view != nil && [view superview] != self)
|
|
|
|
view = [view superview];
|
|
|
|
rect = [view frame];
|
|
|
|
|
2001-01-27 07:11:31 +00:00
|
|
|
if (active == nil)
|
1999-12-08 15:04:57 +00:00
|
|
|
{
|
2001-01-27 07:11:31 +00:00
|
|
|
NSRunAlertPanel (NULL, @"No document is currently active",
|
|
|
|
@"OK", NULL, NULL);
|
|
|
|
return;
|
1999-12-08 15:04:57 +00:00
|
|
|
}
|
|
|
|
|
2001-01-27 07:11:31 +00:00
|
|
|
RELEASE(dragImage);
|
|
|
|
dragImage = [NSImage new];
|
|
|
|
rep = [[NSCachedImageRep alloc] initWithWindow: [self window]
|
|
|
|
rect: rect];
|
|
|
|
[dragImage setSize: rect.size];
|
|
|
|
[dragImage addRepresentation: rep];
|
|
|
|
RELEASE(rep);
|
|
|
|
|
|
|
|
type = [IBPalette typeForView: view];
|
|
|
|
obj = [IBPalette objectForView: view];
|
|
|
|
pb = [NSPasteboard pasteboardWithName: NSDragPboard];
|
|
|
|
ASSIGN(dragPb, pb);
|
|
|
|
[active copyObject: obj type: type toPasteboard: pb];
|
|
|
|
|
|
|
|
[self dragImage: dragImage
|
|
|
|
at: rect.origin
|
|
|
|
offset: NSMakeSize(0,0)
|
|
|
|
event: theEvent
|
|
|
|
pasteboard: pb
|
|
|
|
source: self
|
|
|
|
slideBack: [type isEqual: IBWindowPboardType] ? NO : YES];
|
1999-12-08 15:04:57 +00:00
|
|
|
}
|
|
|
|
@end
|
|
|
|
|
|
|
|
|
|
|
|
@implementation GormPalettesManager
|
|
|
|
|
|
|
|
- (void) dealloc
|
|
|
|
{
|
1999-12-15 15:29:27 +00:00
|
|
|
[[NSNotificationCenter defaultCenter] removeObserver: self];
|
1999-12-08 15:04:57 +00:00
|
|
|
RELEASE(panel);
|
|
|
|
RELEASE(bundles);
|
|
|
|
RELEASE(palettes);
|
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
1999-12-15 15:29:27 +00:00
|
|
|
- (void) handleNotification: (NSNotification*)aNotification
|
|
|
|
{
|
|
|
|
NSString *name = [aNotification name];
|
|
|
|
|
|
|
|
if ([name isEqual: IBWillBeginTestingInterfaceNotification] == YES)
|
|
|
|
{
|
|
|
|
if ([panel isVisible] == YES)
|
|
|
|
{
|
|
|
|
hiddenDuringTest = YES;
|
|
|
|
[panel orderOut: self];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if ([name isEqual: IBWillEndTestingInterfaceNotification] == YES)
|
|
|
|
{
|
|
|
|
if (hiddenDuringTest == YES)
|
|
|
|
{
|
|
|
|
hiddenDuringTest = NO;
|
|
|
|
[panel orderFront: self];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-12-08 15:04:57 +00:00
|
|
|
- (id) init
|
|
|
|
{
|
1999-12-15 15:29:27 +00:00
|
|
|
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
1999-12-08 15:04:57 +00:00
|
|
|
NSScrollView *scrollView;
|
|
|
|
NSArray *array;
|
|
|
|
NSRect contentRect = {{0, 0}, {272, 266}};
|
|
|
|
NSRect selectionRect = {{0, 0}, {52, 52}};
|
|
|
|
NSRect scrollRect = {{0, 192}, {272, 74}};
|
|
|
|
NSRect dragRect = {{0, 0}, {272, 192}};
|
|
|
|
unsigned int style = NSTitledWindowMask | NSClosableWindowMask | NSResizableWindowMask;
|
|
|
|
|
2001-01-27 06:18:17 +00:00
|
|
|
panel = [[GormPalettePanel alloc] initWithContentRect: contentRect
|
1999-12-08 15:04:57 +00:00
|
|
|
styleMask: style
|
|
|
|
backing: NSBackingStoreRetained
|
|
|
|
defer: NO];
|
|
|
|
[panel setTitle: @"Palettes"];
|
|
|
|
[panel setMinSize: [panel frame].size];
|
|
|
|
|
|
|
|
bundles = [NSMutableArray new];
|
|
|
|
palettes = [NSMutableArray new];
|
|
|
|
|
|
|
|
scrollView = [[NSScrollView alloc] initWithFrame: scrollRect];
|
|
|
|
[scrollView setHasHorizontalScroller: YES];
|
|
|
|
[scrollView setHasVerticalScroller: NO];
|
|
|
|
[scrollView setAutoresizingMask: NSViewMinYMargin | NSViewWidthSizable];
|
|
|
|
selectionView = [[NSMatrix alloc] initWithFrame: selectionRect
|
|
|
|
mode: NSRadioModeMatrix
|
|
|
|
cellClass: [NSImageCell class]
|
|
|
|
numberOfRows: 1
|
|
|
|
numberOfColumns: 0];
|
|
|
|
[selectionView setTarget: self];
|
|
|
|
[selectionView setAction: @selector(setCurrentPalette:)];
|
|
|
|
[selectionView setCellSize: NSMakeSize(52,52)];
|
|
|
|
[selectionView setIntercellSpacing: NSMakeSize(0,0)];
|
|
|
|
[scrollView setDocumentView: selectionView];
|
|
|
|
RELEASE(selectionView);
|
|
|
|
[[panel contentView] addSubview: scrollView];
|
|
|
|
RELEASE(scrollView);
|
|
|
|
|
|
|
|
dragView = [[GormPaletteView alloc] initWithFrame: dragRect];
|
|
|
|
[dragView setAutoresizingMask: NSViewHeightSizable | NSViewWidthSizable];
|
|
|
|
[[panel contentView] addSubview: dragView];
|
|
|
|
RELEASE(dragView);
|
|
|
|
|
|
|
|
[panel setFrameUsingName: @"Palettes"];
|
|
|
|
[panel setFrameAutosaveName: @"Palettes"];
|
|
|
|
current = -1;
|
|
|
|
|
|
|
|
array = [[NSBundle mainBundle] pathsForResourcesOfType: @"palette"
|
|
|
|
inDirectory: nil];
|
|
|
|
if ([array count] > 0)
|
|
|
|
{
|
|
|
|
unsigned index;
|
|
|
|
|
1999-12-16 21:41:21 +00:00
|
|
|
array = [array sortedArrayUsingSelector: @selector(compare:)];
|
1999-12-08 15:04:57 +00:00
|
|
|
for (index = 0; index < [array count]; index++)
|
|
|
|
{
|
|
|
|
[self loadPalette: [array objectAtIndex: index]];
|
|
|
|
}
|
|
|
|
}
|
2000-01-04 16:25:39 +00:00
|
|
|
/*
|
|
|
|
* Select initial palette - this should be the standard controls palette.
|
|
|
|
*/
|
|
|
|
[selectionView selectCellAtRow: 0 column: 2];
|
|
|
|
[self setCurrentPalette: selectionView];
|
1999-12-08 15:04:57 +00:00
|
|
|
|
1999-12-15 15:29:27 +00:00
|
|
|
[nc addObserver: self
|
|
|
|
selector: @selector(handleNotification:)
|
|
|
|
name: IBWillBeginTestingInterfaceNotification
|
|
|
|
object: nil];
|
|
|
|
[nc addObserver: self
|
|
|
|
selector: @selector(handleNotification:)
|
|
|
|
name: IBWillEndTestingInterfaceNotification
|
|
|
|
object: nil];
|
|
|
|
|
1999-12-08 15:04:57 +00:00
|
|
|
return self;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) loadPalette: (NSString*)path
|
|
|
|
{
|
|
|
|
NSBundle *bundle;
|
|
|
|
NSWindow *window;
|
|
|
|
Class paletteClass;
|
|
|
|
NSDictionary *paletteInfo;
|
|
|
|
NSString *className;
|
|
|
|
IBPalette *palette;
|
|
|
|
NSImageCell *cell;
|
|
|
|
int col;
|
|
|
|
|
|
|
|
for (col = 0; col < [bundles count]; col++)
|
|
|
|
{
|
|
|
|
bundle = [bundles objectAtIndex: col];
|
|
|
|
if ([path isEqualToString: [bundle bundlePath]] == YES)
|
|
|
|
{
|
|
|
|
NSRunAlertPanel (NULL, @"Palette has already been loaded",
|
|
|
|
@"OK", NULL, NULL);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
bundle = [NSBundle bundleWithPath: path];
|
|
|
|
if (bundle == nil)
|
|
|
|
{
|
|
|
|
NSRunAlertPanel(NULL, @"Could not load Palette",
|
|
|
|
@"OK", NULL, NULL);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
[bundles addObject: bundle];
|
|
|
|
|
|
|
|
path = [bundle pathForResource: @"palette" ofType: @"table"];
|
|
|
|
if (path == nil)
|
|
|
|
{
|
|
|
|
NSRunAlertPanel(NULL, @"File 'palette.table' missing",
|
|
|
|
@"OK", NULL, NULL);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
paletteInfo = [[NSString stringWithContentsOfFile: path]
|
|
|
|
propertyListFromStringsFileFormat];
|
|
|
|
if (paletteInfo == nil)
|
|
|
|
{
|
|
|
|
NSRunAlertPanel(NULL, @"Failed to load 'palette.table'",
|
|
|
|
@"OK", NULL, NULL);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
className = [paletteInfo objectForKey: @"Class"];
|
|
|
|
if (className == nil)
|
|
|
|
{
|
|
|
|
NSRunAlertPanel(NULL, @"No palette class in 'palette.table'",
|
|
|
|
@"OK", NULL, NULL);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
paletteClass = [bundle classNamed: className];
|
|
|
|
if (paletteClass == 0)
|
|
|
|
{
|
|
|
|
NSRunAlertPanel (NULL, @"Could not load palette class",
|
|
|
|
@"OK", NULL, NULL);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
palette = [paletteClass new];
|
|
|
|
if ([palette isKindOfClass: [IBPalette class]] == NO)
|
|
|
|
{
|
|
|
|
NSRunAlertPanel (NULL, @"Palette contains wrong type of class",
|
|
|
|
@"OK", NULL, NULL);
|
|
|
|
RELEASE(palette);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
[palette finishInstantiate];
|
|
|
|
window = [palette originalWindow];
|
|
|
|
[window setExcludedFromWindowsMenu: YES];
|
|
|
|
|
|
|
|
[palettes addObject: palette];
|
|
|
|
[selectionView addColumn];
|
|
|
|
[[palette paletteIcon] setBackgroundColor: [selectionView backgroundColor]];
|
|
|
|
col = [selectionView numberOfColumns] - 1;
|
|
|
|
cell = [selectionView cellAtRow: 0 column: col];
|
|
|
|
[cell setImageFrameStyle: NSImageFrameButton];
|
|
|
|
[cell setImage: [palette paletteIcon]];
|
|
|
|
[selectionView sizeToCells];
|
|
|
|
[selectionView selectCellAtRow: 0 column: col];
|
2000-01-04 16:25:39 +00:00
|
|
|
[self setCurrentPalette: selectionView];
|
1999-12-08 15:04:57 +00:00
|
|
|
RELEASE(palette);
|
|
|
|
}
|
|
|
|
|
|
|
|
- (id) openPalette: (id) sender
|
|
|
|
{
|
|
|
|
NSArray *fileTypes = [NSArray arrayWithObject: @"palette"];
|
|
|
|
NSOpenPanel *oPanel = [NSOpenPanel openPanel];
|
|
|
|
int result;
|
|
|
|
|
|
|
|
[oPanel setAllowsMultipleSelection: YES];
|
|
|
|
[oPanel setCanChooseFiles: YES];
|
|
|
|
[oPanel setCanChooseDirectories: NO];
|
|
|
|
result = [oPanel runModalForDirectory: NSHomeDirectory()
|
|
|
|
file: nil
|
|
|
|
types: fileTypes];
|
|
|
|
|
|
|
|
if (result == NSOKButton)
|
|
|
|
{
|
|
|
|
NSArray *filesToOpen = [oPanel filenames];
|
|
|
|
unsigned count = [filesToOpen count];
|
|
|
|
unsigned i;
|
|
|
|
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
NSString *aFile = [filesToOpen objectAtIndex: i];
|
|
|
|
|
|
|
|
[self loadPalette: aFile];
|
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
|
|
|
return nil;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (NSPanel*) panel
|
|
|
|
{
|
|
|
|
return panel;
|
|
|
|
}
|
|
|
|
|
|
|
|
- (void) setCurrentPalette: (id)anObj
|
|
|
|
{
|
|
|
|
NSView *wv;
|
|
|
|
NSView *sv;
|
|
|
|
NSEnumerator *enumerator;
|
|
|
|
|
|
|
|
if (current >= 0)
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Move the views in the drag view back to the content view of the
|
|
|
|
* window they originally came from.
|
|
|
|
*/
|
|
|
|
wv = [[[palettes objectAtIndex: current] originalWindow] contentView];
|
|
|
|
enumerator = [[dragView subviews] objectEnumerator];
|
|
|
|
while ((sv = [enumerator nextObject]) != nil)
|
|
|
|
{
|
|
|
|
RETAIN(sv);
|
|
|
|
[sv removeFromSuperview];
|
|
|
|
[wv addSubview: sv];
|
|
|
|
RELEASE(sv);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
current = [anObj selectedColumn];
|
|
|
|
if (current >= 0 && current < [palettes count])
|
|
|
|
{
|
|
|
|
/*
|
|
|
|
* Move the views from their original window into our drag view.
|
|
|
|
* Resize our drag view to the right size fitrst.
|
|
|
|
*/
|
|
|
|
wv = [[[palettes objectAtIndex: current] originalWindow] contentView];
|
2001-10-17 04:06:11 +00:00
|
|
|
if (wv)
|
|
|
|
[dragView setFrameSize: [wv frame].size];
|
1999-12-08 15:04:57 +00:00
|
|
|
enumerator = [[wv subviews] objectEnumerator];
|
|
|
|
while ((sv = [enumerator nextObject]) != nil)
|
|
|
|
{
|
|
|
|
RETAIN(sv);
|
|
|
|
[sv removeFromSuperview];
|
|
|
|
[dragView addSubview: sv];
|
|
|
|
RELEASE(sv);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
NSLog(@"Bad palette selection - %d", [anObj selectedColumn]);
|
|
|
|
current = -1;
|
|
|
|
}
|
|
|
|
[dragView setNeedsDisplay: YES];
|
|
|
|
}
|
|
|
|
|
|
|
|
@end
|