1999-02-19 20:19:58 +00:00
|
|
|
/*
|
1998-07-28 17:51:55 +00:00
|
|
|
NSSplitView.h
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1998-07-28 17:51:55 +00:00
|
|
|
Allows multiple views to share a region in a window
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
Copyright (C) 1996 Free Software Foundation, Inc.
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
Author: Robert Vasvari < vrobi@ddrummer.com >
|
1998-07-28 17:51:55 +00:00
|
|
|
Date: Jul 1998
|
1999-02-19 20:19:58 +00:00
|
|
|
Author: Felipe A. Rodriguez < far@ix.netcom.com >
|
1998-11-25 17:16:48 +00:00
|
|
|
Date: November 1998
|
1999-02-19 20:19:58 +00:00
|
|
|
Author: Richard Frith-Macdonald < richard@brainstorm.co.uk >
|
|
|
|
Date: January 1999
|
|
|
|
|
1996-05-30 20:03:15 +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.
|
1999-02-19 20:19:58 +00:00
|
|
|
|
1996-05-30 20:03:15 +00:00
|
|
|
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.
|
1999-02-19 20:19:58 +00:00
|
|
|
*/
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1998-08-19 09:00:26 +00:00
|
|
|
#include <gnustep/gui/config.h>
|
1998-11-25 17:16:48 +00:00
|
|
|
#include <string.h>
|
|
|
|
#include <math.h>
|
|
|
|
|
1998-07-28 17:51:55 +00:00
|
|
|
#import <Foundation/Foundation.h>
|
1998-11-25 17:16:48 +00:00
|
|
|
|
1998-07-28 17:51:55 +00:00
|
|
|
#import <AppKit/AppKit.h>
|
|
|
|
|
1998-08-19 09:00:26 +00:00
|
|
|
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
@implementation NSSplitView
|
|
|
|
|
1998-12-16 11:48:33 +00:00
|
|
|
//
|
|
|
|
// Instance methods
|
|
|
|
//
|
1999-03-24 11:31:06 +00:00
|
|
|
- (BOOL) acceptsFirstMouse: (NSEvent *)theEvent
|
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (void) mouseDown: (NSEvent*)theEvent
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
NSApplication *app = [NSApplication sharedApplication];
|
|
|
|
static NSRect oldRect; //only one can be dragged at a time
|
|
|
|
NSPoint p;
|
|
|
|
NSEvent *e;
|
|
|
|
NSRect r, r1, bigRect, vis;
|
1999-04-01 06:19:37 +00:00
|
|
|
id v = nil, prev = nil;
|
1999-02-19 20:19:58 +00:00
|
|
|
float minCoord, maxCoord;
|
|
|
|
NSArray *subs = [self subviews];
|
|
|
|
int offset = 0,i,count = [subs count];
|
|
|
|
float divVertical, divHorizontal, div = [self dividerThickness];
|
|
|
|
NSColor *divColor = [self dividerColor];
|
|
|
|
NSDate *farAway = [NSDate distantFuture];
|
|
|
|
unsigned int eventMask = NSLeftMouseDownMask | NSLeftMouseUpMask
|
|
|
|
| NSLeftMouseDraggedMask | NSMouseMovedMask
|
|
|
|
| NSPeriodicMask;
|
|
|
|
|
|
|
|
/* if there are less the two subviews, there is nothing to do */
|
|
|
|
if (count < 2)
|
|
|
|
return;
|
|
|
|
|
|
|
|
[[self window] setAcceptsMouseMovedEvents: YES];
|
1998-07-28 17:51:55 +00:00
|
|
|
vis = [self visibleRect];
|
|
|
|
|
|
|
|
/* find out which divider it is */
|
1999-02-19 20:19:58 +00:00
|
|
|
p = [theEvent locationInWindow];
|
|
|
|
p = [self convertPoint: p fromView: nil];
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
v = [subs objectAtIndex: i];
|
|
|
|
r = [v frame];
|
1998-07-28 17:51:55 +00:00
|
|
|
/* if the click is inside of a subview, return.
|
|
|
|
this should never happen */
|
1999-02-19 20:19:58 +00:00
|
|
|
if ([self isVertical] == NO)
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
if ((p.y > NSMinY(r)) && (p.y < NSMaxY(r)))
|
1998-07-28 17:51:55 +00:00
|
|
|
goto RETURN_LABEL;
|
1999-02-19 20:19:58 +00:00
|
|
|
if (NSMaxY(r) > p.y)
|
|
|
|
{
|
|
|
|
offset = i;
|
1998-07-28 17:51:55 +00:00
|
|
|
|
|
|
|
/* get the enclosing rect for the two views */
|
1999-02-19 20:19:58 +00:00
|
|
|
if (prev) r = [prev frame];
|
1998-07-28 17:51:55 +00:00
|
|
|
else r = NSZeroRect;
|
1999-02-19 20:19:58 +00:00
|
|
|
if (v) r1= [v frame];
|
|
|
|
bigRect = r;
|
|
|
|
bigRect = NSUnionRect(r1 , bigRect);
|
1998-07-28 17:51:55 +00:00
|
|
|
break;
|
|
|
|
}
|
1999-02-19 20:19:58 +00:00
|
|
|
prev = v;
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
if ((p.x > NSMinX(r)) && (p.x < NSMaxX(r)))
|
1998-07-28 17:51:55 +00:00
|
|
|
goto RETURN_LABEL;
|
1999-02-19 20:19:58 +00:00
|
|
|
if ((NSMinX(r) + NSWidth(r)) > p.x)
|
|
|
|
{
|
|
|
|
offset = i;
|
1998-07-28 17:51:55 +00:00
|
|
|
|
|
|
|
/* get the enclosing rect for the two views */
|
1999-02-19 20:19:58 +00:00
|
|
|
if (prev) r = [prev frame];
|
1998-07-28 17:51:55 +00:00
|
|
|
else r = NSZeroRect;
|
1999-02-19 20:19:58 +00:00
|
|
|
if (v) r1= [v frame];
|
|
|
|
bigRect = r;
|
|
|
|
bigRect = NSUnionRect(r1 , bigRect);
|
1998-07-28 17:51:55 +00:00
|
|
|
break;
|
|
|
|
}
|
1999-02-19 20:19:58 +00:00
|
|
|
prev = v;
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
}
|
1999-02-19 20:19:58 +00:00
|
|
|
if ([self isVertical] == NO)
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
divVertical = div;
|
|
|
|
divHorizontal = NSWidth([self frame]);
|
1998-07-28 17:51:55 +00:00
|
|
|
/* set the default limits on the dragging */
|
1999-02-19 20:19:58 +00:00
|
|
|
minCoord = NSMinY(bigRect) + divVertical;
|
|
|
|
maxCoord = NSHeight(bigRect) + NSMinY(bigRect) - divVertical;
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
divHorizontal = div;
|
|
|
|
divVertical = NSHeight([self frame]);
|
1998-07-28 17:51:55 +00:00
|
|
|
/* set the default limits on the dragging */
|
1999-02-19 20:19:58 +00:00
|
|
|
minCoord = NSMinX(bigRect) + divHorizontal;
|
|
|
|
maxCoord = NSWidth(bigRect) + NSMinX(bigRect) - divHorizontal;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
1998-07-28 17:51:55 +00:00
|
|
|
/* find out what the dragging limit is */
|
1999-02-19 20:19:58 +00:00
|
|
|
if (delegate && [delegate respondsToSelector:
|
|
|
|
@selector(splitView:constrainMinCoordinate:maxCoordinate:ofSubviewAt:)])
|
|
|
|
{
|
|
|
|
if ([self isVertical] == NO)
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
float delMinY= minCoord, delMaxY= maxCoord;
|
|
|
|
[delegate splitView: self
|
|
|
|
constrainMinCoordinate: &delMinY
|
|
|
|
maxCoordinate: &delMaxY
|
|
|
|
ofSubviewAt: offset];
|
1998-07-28 17:51:55 +00:00
|
|
|
/* we are still constrained by the original bounds */
|
1999-02-19 20:19:58 +00:00
|
|
|
if (delMinY > minCoord) minCoord = delMinY;
|
|
|
|
if (delMaxY < maxCoord) maxCoord = delMaxY;
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
float delMinX= minCoord, delMaxX= maxCoord;
|
|
|
|
[delegate splitView: self
|
|
|
|
constrainMinCoordinate: &delMinX
|
|
|
|
maxCoordinate: &delMaxX
|
|
|
|
ofSubviewAt: offset];
|
1998-07-28 17:51:55 +00:00
|
|
|
/* we are still constrained by the original bounds */
|
1999-02-19 20:19:58 +00:00
|
|
|
if (delMinX > minCoord) minCoord = delMinX;
|
|
|
|
if (delMaxX < maxCoord) maxCoord = delMaxX;
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
oldRect = NSZeroRect;
|
|
|
|
[self lockFocus];
|
|
|
|
|
|
|
|
/* FIXME: Are these really needed? */
|
1999-02-19 20:19:58 +00:00
|
|
|
[NSEvent startPeriodicEventsAfterDelay: 0.1 withPeriod: 0.1];
|
|
|
|
[[NSRunLoop currentRunLoop] limitDateForMode: NSEventTrackingRunLoopMode];
|
|
|
|
|
1998-07-28 17:51:55 +00:00
|
|
|
[divColor set];
|
|
|
|
r.size.width = divHorizontal;
|
|
|
|
r.size.height = divVertical;
|
1999-02-19 20:19:58 +00:00
|
|
|
e = [app nextEventMatchingMask: eventMask
|
|
|
|
untilDate: farAway
|
|
|
|
inMode: NSEventTrackingRunLoopMode
|
|
|
|
dequeue: YES];
|
|
|
|
|
|
|
|
// user is moving the knob loop until left mouse up
|
|
|
|
while ([e type] != NSLeftMouseUp)
|
|
|
|
{
|
|
|
|
if ([e type] != NSPeriodic)
|
|
|
|
p = [self convertPoint: [e locationInWindow] fromView: nil];
|
|
|
|
if ([self isVertical] == NO)
|
|
|
|
{
|
|
|
|
if (p.y < minCoord)
|
|
|
|
p.y = minCoord;
|
|
|
|
if (p.y > maxCoord)
|
|
|
|
p.y = maxCoord;
|
|
|
|
r.origin.y = p.y - (divVertical/2.);
|
|
|
|
r.origin.x = NSMinX(vis);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
if (p.x < minCoord)
|
|
|
|
p.x = minCoord;
|
|
|
|
if (p.x > maxCoord)
|
|
|
|
p.x = maxCoord;
|
|
|
|
r.origin.x = p.x - (divHorizontal/2.);
|
|
|
|
r.origin.y = NSMinY(vis);
|
|
|
|
}
|
|
|
|
NSDebugLog(@"drawing divider at x: %d, y: %d, w: %d, h: %d\n",
|
|
|
|
(int)NSMinX(r),(int)NSMinY(r),(int)NSWidth(r),
|
|
|
|
(int)NSHeight(r));
|
|
|
|
[dividerColor set];
|
|
|
|
NSHighlightRect(r);
|
1998-11-25 17:16:48 +00:00
|
|
|
// [[NSDrawContext currentContext] flush];
|
1999-02-19 20:19:58 +00:00
|
|
|
oldRect = r;
|
|
|
|
e = [app nextEventMatchingMask: eventMask
|
|
|
|
untilDate: farAway
|
|
|
|
inMode: NSEventTrackingRunLoopMode
|
|
|
|
dequeue: YES];
|
|
|
|
[dividerColor set];
|
|
|
|
NSHighlightRect(oldRect);
|
|
|
|
}
|
1998-07-28 17:51:55 +00:00
|
|
|
|
|
|
|
[self unlockFocus];
|
|
|
|
[NSEvent stopPeriodicEvents];
|
|
|
|
|
|
|
|
/* resize the subviews accordingly */
|
|
|
|
r = [prev frame];
|
1999-02-19 20:19:58 +00:00
|
|
|
if ([self isVertical] == NO)
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
r.size.height = p.y - NSMinY(bigRect) - (divVertical/2.);
|
|
|
|
if (NSHeight(r) < 1.) r.size.height = 1.;
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
r.size.width = p.x - NSMinX(bigRect) - (divHorizontal/2.);
|
|
|
|
if (NSWidth(r) < 1.) r.size.width = 1.;
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
1999-02-19 20:19:58 +00:00
|
|
|
[prev setFrame: r];
|
|
|
|
NSDebugLog(@"drawing PREV at x: %d, y: %d, w: %d, h: %d\n",
|
1998-07-28 17:51:55 +00:00
|
|
|
(int)NSMinX(r),(int)NSMinY(r),(int)NSWidth(r),(int)NSHeight(r));
|
|
|
|
|
|
|
|
r1 = [v frame];
|
1999-02-19 20:19:58 +00:00
|
|
|
if ([self isVertical] == NO)
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
r1.origin.y = p.y + (divVertical/2.);
|
|
|
|
if (NSMinY(r1) < 0.) r1.origin.y = 0.;
|
|
|
|
r1.size.height = NSHeight(bigRect) - NSHeight(r) - divVertical;
|
|
|
|
if (NSHeight(r) < 1.) r.size.height = 1.;
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
r1.origin.x = p.x + (divHorizontal/2.);
|
|
|
|
if (NSMinX(r1) < 0.) r1.origin.x = 0.;
|
|
|
|
r1.size.width = NSWidth(bigRect) - NSWidth(r) - divHorizontal;
|
|
|
|
if (NSWidth(r1) < 1.) r1.size.width = 1.;
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
1999-02-19 20:19:58 +00:00
|
|
|
[v setFrame: r1];
|
|
|
|
NSDebugLog(@"drawing LAST at x: %d, y: %d, w: %d, h: %d\n",
|
1998-07-28 17:51:55 +00:00
|
|
|
(int)NSMinX(r1),(int)NSMinY(r1),(int)NSWidth(r1),
|
|
|
|
(int)NSHeight(r1));
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
[[self window] invalidateCursorRectsForView: self];
|
1998-07-28 17:51:55 +00:00
|
|
|
|
|
|
|
RETURN_LABEL:
|
1999-02-19 20:19:58 +00:00
|
|
|
[[self window] setAcceptsMouseMovedEvents: NO];
|
|
|
|
[self setNeedsDisplay: YES];
|
1998-11-25 17:16:48 +00:00
|
|
|
|
|
|
|
[self display];
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
|
1999-02-17 09:13:43 +00:00
|
|
|
- (void) adjustSubviews
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
1999-02-17 09:13:43 +00:00
|
|
|
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
|
|
|
|
NSRect fr = [self frame];
|
|
|
|
|
|
|
|
[nc postNotificationName: NSSplitViewWillResizeSubviewsNotification
|
|
|
|
object: self];
|
1998-07-28 17:51:55 +00:00
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
if (delegate && [delegate respondsToSelector:
|
|
|
|
@selector(splitView:resizeSubviewsWithOldSize:)])
|
|
|
|
{
|
|
|
|
[delegate splitView: self resizeSubviewsWithOldSize: fr.size];
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{ /* split the area up evenly */
|
1999-01-18 18:24:37 +00:00
|
|
|
NSArray *subs = [self subviews];
|
|
|
|
unsigned count = [subs count];
|
|
|
|
NSView *views[count];
|
|
|
|
NSRect frames[count];
|
|
|
|
NSRect bd = [self bounds];
|
|
|
|
float thickness = [self dividerThickness];
|
|
|
|
NSSize newSize;
|
|
|
|
NSPoint newPoint;
|
|
|
|
unsigned i;
|
|
|
|
NSRect r;
|
|
|
|
float oldTotal;
|
|
|
|
float newTotal;
|
|
|
|
float scale;
|
|
|
|
float running;
|
|
|
|
|
|
|
|
[subs getObjects: views];
|
1999-02-19 20:19:58 +00:00
|
|
|
if ([self isVertical] == NO)
|
1999-01-18 18:24:37 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
newTotal = NSHeight(bd) - thickness*(count - 1);
|
1999-01-18 18:24:37 +00:00
|
|
|
oldTotal = 0.0;
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
frames[i] = [views[i] frame];
|
|
|
|
oldTotal += NSHeight(frames[i]);
|
|
|
|
}
|
|
|
|
scale = newTotal/oldTotal;
|
|
|
|
running = 0.0;
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
float newHeight;
|
|
|
|
|
|
|
|
r = [views[i] frame];
|
|
|
|
newHeight = NSHeight(frames[i]) * scale;
|
|
|
|
if (i == count - 1)
|
|
|
|
newHeight = floor(newHeight);
|
|
|
|
else
|
|
|
|
newHeight = ceil(newHeight);
|
|
|
|
newSize = NSMakeSize(NSWidth(bd), newHeight);
|
|
|
|
newPoint = NSMakePoint(0.0, running);
|
|
|
|
running += newHeight + thickness;
|
|
|
|
[views[i] setFrameSize: newSize];
|
|
|
|
[views[i] setFrameOrigin: newPoint];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
newTotal = NSWidth(bd) - thickness*(count - 1);
|
1999-01-18 18:24:37 +00:00
|
|
|
oldTotal = 0.0;
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
oldTotal += NSWidth([views[i] frame]);
|
|
|
|
}
|
|
|
|
scale = newTotal/oldTotal;
|
|
|
|
running = 0.0;
|
|
|
|
for (i = 0; i < count; i++)
|
|
|
|
{
|
|
|
|
float newWidth;
|
|
|
|
|
|
|
|
r = [views[i] frame];
|
|
|
|
newWidth = NSWidth(r) * scale;
|
|
|
|
if (i == count - 1)
|
|
|
|
newWidth = floor(newWidth);
|
|
|
|
else
|
|
|
|
newWidth = ceil(newWidth);
|
|
|
|
newSize = NSMakeSize(newWidth, NSHeight(bd));
|
|
|
|
newPoint = NSMakePoint(running, 0.0);
|
|
|
|
running += newWidth + thickness;
|
|
|
|
[views[i] setFrameSize: newSize];
|
|
|
|
[views[i] setFrameOrigin: newPoint];
|
|
|
|
}
|
|
|
|
}
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
1999-02-17 09:13:43 +00:00
|
|
|
[nc postNotificationName: NSSplitViewDidResizeSubviewsNotification
|
|
|
|
object: self];
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (void) addSubview: (NSView*)aView
|
|
|
|
positioned: (NSWindowOrderingMode)place
|
|
|
|
relativeTo: (NSView*)otherView
|
|
|
|
{
|
|
|
|
[super addSubview: aView positioned: place relativeTo: otherView];
|
1998-07-28 17:51:55 +00:00
|
|
|
[self adjustSubviews];
|
|
|
|
}
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (void) addSubview: aView
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
[super addSubview: aView];
|
1998-07-28 17:51:55 +00:00
|
|
|
[self adjustSubviews];
|
|
|
|
}
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (float) dividerThickness //defaults to 8
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
|
|
|
return dividerWidth;
|
|
|
|
}
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (void) setDividerThickNess: (float)newWidth
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
dividerWidth = ceil(newWidth);
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (float) draggedBarWidth //defaults to 8
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1998-07-28 17:51:55 +00:00
|
|
|
return draggedBarWidth;
|
|
|
|
}
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (void) setDraggedBarWidth: (float)newWidth
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
draggedBarWidth = newWidth;
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
|
1999-03-30 13:59:35 +00:00
|
|
|
static inline NSPoint centerSizeInRect(NSSize innerSize, NSRect outerRect)
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
|
|
|
NSPoint p;
|
1999-02-19 20:19:58 +00:00
|
|
|
p.x = MAX(NSMidX(outerRect) - (innerSize.width/2.),0.);
|
|
|
|
p.y = MAX(NSMidY(outerRect) - (innerSize.height/2.),0.);
|
1998-07-28 17:51:55 +00:00
|
|
|
return p;
|
|
|
|
}
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (void) drawDividerInRect: (NSRect)aRect
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
|
|
|
NSPoint dimpleOrigin;
|
|
|
|
NSSize dimpleSize;
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1998-07-28 17:51:55 +00:00
|
|
|
/* focus is already on self */
|
1999-02-19 20:19:58 +00:00
|
|
|
if (!dimpleImage)
|
|
|
|
return;
|
|
|
|
dimpleSize = [dimpleImage size];
|
1998-07-28 17:51:55 +00:00
|
|
|
|
1999-03-30 13:59:35 +00:00
|
|
|
dimpleOrigin = centerSizeInRect(dimpleSize, aRect);
|
|
|
|
/*
|
|
|
|
* Images are always drawn with their bottom-left corner at the origin
|
|
|
|
* so we must adjust the position to take account of a flipped view.
|
|
|
|
*/
|
1999-02-19 20:19:58 +00:00
|
|
|
if ([self isFlipped])
|
1999-03-30 13:59:35 +00:00
|
|
|
dimpleOrigin.y -= dimpleSize.height;
|
1999-02-19 20:19:58 +00:00
|
|
|
[dimpleImage compositeToPoint: dimpleOrigin operation: NSCompositeSourceOver];
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
/* Vertical splitview has a vertical split bar */
|
|
|
|
- (void) setVertical: (BOOL)flag
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
isVertical = flag;
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (BOOL) isVertical
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
|
|
|
return isVertical;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (void) setDimpleImage: (NSImage *)anImage resetDividerThickness: (BOOL)flag
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
ASSIGN(dimpleImage, anImage);
|
1998-07-28 17:51:55 +00:00
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
if (flag)
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
NSSize s = NSMakeSize(8., 8.);
|
1998-07-28 17:51:55 +00:00
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
if (dimpleImage)
|
|
|
|
s = [dimpleImage size];
|
|
|
|
[self setDividerThickNess: isVertical ? s.width : s.height];
|
|
|
|
}
|
1998-11-25 17:16:48 +00:00
|
|
|
}
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (void) drawRect: (NSRect)r
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
NSArray *subs = [self subviews];
|
|
|
|
int i, count = [subs count];
|
1998-07-28 17:51:55 +00:00
|
|
|
id v;
|
|
|
|
NSRect divRect;
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
if ([self isOpaque])
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
|
|
|
[[self backgroundColor] set];
|
1998-11-25 17:16:48 +00:00
|
|
|
NSRectFill(r);
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/* draw the dimples */
|
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
for (i = 0; i < (count-1); i++)
|
|
|
|
{
|
|
|
|
v = [subs objectAtIndex: i];
|
|
|
|
divRect = [v frame];
|
|
|
|
if ([self isVertical] == NO)
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
divRect.origin.y = NSMaxY(divRect);
|
|
|
|
divRect.size.height = [self dividerThickness];
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
divRect.origin.x = NSMaxX(divRect);
|
|
|
|
divRect.size.width = [self dividerThickness];
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
1999-02-19 20:19:58 +00:00
|
|
|
[self drawDividerInRect: divRect];
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (NSImage*) dimpleImage
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
|
|
|
return dimpleImage;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Overridden Methods */
|
1999-02-19 20:19:58 +00:00
|
|
|
- (BOOL) isFlipped
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
|
|
|
return NO;
|
|
|
|
}
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (BOOL) isOpaque
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
|
|
|
return YES;
|
|
|
|
}
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (id) initWithFrame: (NSRect)frameRect
|
|
|
|
{
|
|
|
|
if ((self = [super initWithFrame: frameRect]) != nil)
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
dividerWidth = 8;
|
|
|
|
draggedBarWidth = 8;
|
|
|
|
isVertical = NO;
|
|
|
|
[self setDividerColor: [NSColor darkGrayColor]];
|
|
|
|
[self setBackgroundColor: [NSColor lightGrayColor]];
|
1998-07-28 17:51:55 +00:00
|
|
|
[self setDimpleImage:
|
1999-02-19 20:19:58 +00:00
|
|
|
[NSImage imageNamed: @"common_Dimple.tiff"] resetDividerThickness: YES];
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
return self;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (void) resizeWithOldSuperviewSize: (NSSize)oldSize
|
|
|
|
{
|
|
|
|
[super resizeWithOldSuperviewSize: oldSize];
|
1998-07-28 17:51:55 +00:00
|
|
|
[self adjustSubviews];
|
1999-02-19 20:19:58 +00:00
|
|
|
[[self window] invalidateCursorRectsForView: self];
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
|
1999-02-17 09:13:43 +00:00
|
|
|
- (id) delegate
|
1999-02-19 20:19:58 +00:00
|
|
|
{
|
1998-07-28 17:51:55 +00:00
|
|
|
return delegate;
|
|
|
|
}
|
|
|
|
|
1999-02-17 09:13:43 +00:00
|
|
|
- (void) setDelegate: (id)anObject
|
1999-02-19 20:19:58 +00:00
|
|
|
{
|
1999-02-17 09:13:43 +00:00
|
|
|
NSNotificationCenter* nc = [NSNotificationCenter defaultCenter];
|
|
|
|
|
|
|
|
if (delegate)
|
|
|
|
[nc removeObserver: delegate name: nil object: self];
|
|
|
|
delegate = anObject;
|
|
|
|
|
|
|
|
#define SET_DELEGATE_NOTIFICATION(notif_name) \
|
|
|
|
if ([delegate respondsToSelector: @selector(splitView##notif_name:)]) \
|
|
|
|
[nc addObserver: delegate \
|
1999-02-19 20:19:58 +00:00
|
|
|
selector: @selector(splitView##notif_name: ) \
|
1999-02-17 09:13:43 +00:00
|
|
|
name: NSSplitView##notif_name##Notification \
|
|
|
|
object: self]
|
|
|
|
|
|
|
|
SET_DELEGATE_NOTIFICATION(DidResizeSubviews);
|
|
|
|
SET_DELEGATE_NOTIFICATION(WillResizeSubviews);
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (NSColor*) dividerColor
|
|
|
|
{
|
1998-07-28 17:51:55 +00:00
|
|
|
return dividerColor;
|
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (void) setDividerColor: (NSColor*) aColor
|
|
|
|
{
|
|
|
|
ASSIGN(dividerColor, aColor);
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (NSColor*) backgroundColor
|
|
|
|
{
|
1998-07-28 17:51:55 +00:00
|
|
|
return backgroundColor;
|
|
|
|
}
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (void) setBackgroundColor: (NSColor*)aColor
|
|
|
|
{
|
|
|
|
ASSIGN(backgroundColor, aColor);
|
1998-07-28 17:51:55 +00:00
|
|
|
}
|
1996-05-30 20:03:15 +00:00
|
|
|
|
|
|
|
//
|
|
|
|
// NSCoding protocol
|
|
|
|
//
|
1999-02-19 20:19:58 +00:00
|
|
|
- (void) encodeWithCoder: (NSCoder*)aCoder
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
[super encodeWithCoder: aCoder];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Encode objects we don't own.
|
|
|
|
*/
|
|
|
|
[aCoder encodeConditionalObject: delegate];
|
|
|
|
[aCoder encodeConditionalObject: splitCursor];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Encode the objects we do own.
|
|
|
|
*/
|
|
|
|
[aCoder encodeObject: dimpleImage];
|
|
|
|
[aCoder encodeObject: backgroundColor];
|
|
|
|
[aCoder encodeObject: dividerColor];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Encode the rest of the ivar data.
|
|
|
|
*/
|
|
|
|
[aCoder encodeValueOfObjCType: @encode(int) at: ÷rWidth];
|
|
|
|
[aCoder encodeValueOfObjCType: @encode(int) at: &draggedBarWidth];
|
|
|
|
[aCoder encodeValueOfObjCType: @encode(BOOL) at: &isVertical];
|
1996-05-30 20:03:15 +00:00
|
|
|
}
|
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (id) initWithCoder: (NSCoder*)aDecoder
|
1996-05-30 20:03:15 +00:00
|
|
|
{
|
1999-02-19 20:19:58 +00:00
|
|
|
self = [super initWithCoder: aDecoder];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Decode objects that we don't retain.
|
|
|
|
*/
|
|
|
|
delegate = [aDecoder decodeObject];
|
|
|
|
splitCursor = [aDecoder decodeObject];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Decode objects that we do retain.
|
|
|
|
*/
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(id) at: &dimpleImage];
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(id) at: &backgroundColor];
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(id) at: ÷rColor];
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Decode non-object data.
|
|
|
|
*/
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(int) at: ÷rWidth];
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(int) at: &draggedBarWidth];
|
|
|
|
[aDecoder decodeValueOfObjCType: @encode(BOOL) at: &isVertical];
|
|
|
|
|
1996-05-30 20:03:15 +00:00
|
|
|
return self;
|
|
|
|
}
|
1998-07-28 17:51:55 +00:00
|
|
|
|
1999-02-19 20:19:58 +00:00
|
|
|
- (void) dealloc
|
1998-07-28 17:51:55 +00:00
|
|
|
{
|
|
|
|
[backgroundColor release];
|
|
|
|
[dividerColor release];
|
|
|
|
[dimpleImage release];
|
|
|
|
[super dealloc];
|
|
|
|
}
|
|
|
|
|
1996-05-30 20:03:15 +00:00
|
|
|
@end
|