Additional NSScroller implementation.

Fix locking/unlocking of focus for view hierarchy.
Numerous bug fixes.


git-svn-id: svn+ssh://svn.gna.org/svn/gnustep/libs/gui/trunk@2255 72102866-910b-0410-8b05-ffd578937521
This commit is contained in:
netcrep 1997-03-20 19:23:21 +00:00
parent 0a72d4bd4d
commit bf12b45df0
8 changed files with 219 additions and 70 deletions

View file

@ -1,4 +1,32 @@
Fri Mar 14 18:23:18 1997 Ovidiu Predescu <ovidiu@bx.logicnet.ro> Thu Mar 20 10:40:51 1997 GNUstep Development <gnustep@net-community.com>
* Source/NSControl.m (-copyWithZone:): Copy the object instead of
allocating so that instance variable values are copied. Retain
the cell because it will be released when we set a new one.
(-drawCell:, -drawCellInside:): Lock and unlock the focus
when drawing the cell.
* Source/NSImage.m (_base_name, extension): Delete functions;
functionality is now provided by NSString.
(+imageNamed:) Use NSString methods instead of local functions for
obtaining base name and extension. Check if extension is one of
the image types before deleting.
(-useFromFile:): Use NSString methods instead of local functions
for obtaining the extension.
* Source/NSScroller.m (-setFloatValue:knobProportion:): Set knob
proportion first before setting float value.
(-drawRect:): Remove method.
(-drawParts): Flush window.
(-trackKnob:): Correct position of knob relative to pointer.
(-trackScrollButtons:): Fill out implementation.
(-mouseDown:): Lock and unlock focus.
* Source/NSTextField.m (-setTextCursor:, -copyWithZone:): New methods.
* Source/NSTextFieldCell.m (-initTextCell:): By default
it draws the background.
* Source/NSView.m (-ancestoreSharedWithView:): Implement.
(-lockFocus, -unlockFocus): Make sure our superview locks or unlocks
the focus before us.
Fri Mar 14 18:23:18 1997 Ovidiu Predescu <ovidiu@net-community.com>
* Flush the view's window after a redraw. * Flush the view's window after a redraw.
* Source/NSButton.m (-mouseDown:): Likewise. * Source/NSButton.m (-mouseDown:): Likewise.
@ -28,7 +56,7 @@ Wed Mar 5 17:43:34 1997 GNUstep Development <gnustep@net-community.com>
* Headers/gnustep/gui/nsimage-tiff.h: Include gnustep-gui config. * Headers/gnustep/gui/nsimage-tiff.h: Include gnustep-gui config.
* Source/tiff.m: Include header file. * Source/tiff.m: Include header file.
Tue Mar 4 18:05:24 1997 Ovidiu Predescu <ovidiu@bx.logicnet.ro> Tue Mar 4 18:05:24 1997 Ovidiu Predescu <ovidiu@net-community.com>
* Source/NSFont.m (-minimumAdvancement): New method. * Source/NSFont.m (-minimumAdvancement): New method.
* Source/NSButton.m (-initWithFrame:): Use an autoreleased cell. * Source/NSButton.m (-initWithFrame:): Use an autoreleased cell.
@ -118,7 +146,7 @@ Tue Mar 4 09:28:57 1997 GNUstep Development <gnustep@net-community.com>
* Source/NSBundle.m (+imageNamed:): Create a bundle with * Source/NSBundle.m (+imageNamed:): Create a bundle with
gnustep library install path for searching system resources. gnustep library install path for searching system resources.
Mon Feb 17 19:30:50 1997 Ovidiu Predescu <ovidiu@bx.logicnet.ro> Mon Feb 17 19:30:50 1997 Ovidiu Predescu <ovidiu@net-community.com>
* Source/NSButton.m: New methods -setAlignment: and -alignment, * Source/NSButton.m: New methods -setAlignment: and -alignment,
setIntValue:, setFloatValue:, setDoubleValue:, setAlignment:, setIntValue:, setFloatValue:, setDoubleValue:, setAlignment:,
@ -133,7 +161,7 @@ Mon Feb 17 19:30:50 1997 Ovidiu Predescu <ovidiu@bx.logicnet.ro>
way in which setIntValue:, setFloatValue: and setDoubleValue: work. way in which setIntValue:, setFloatValue: and setDoubleValue: work.
Commented out a point conversion that works wrong (why?). Commented out a point conversion that works wrong (why?).
Sat Feb 15 23:12:35 1997 Ovidiu Predescu <ovidiu@bx.logicnet.ro> Sat Feb 15 23:12:35 1997 Ovidiu Predescu <ovidiu@net-community.com>
* Major reorganization of header files. Types and constants were moved * Major reorganization of header files. Types and constants were moved
in the files they belong (too many to enumerate here). Each header in the files they belong (too many to enumerate here). Each header
@ -175,7 +203,7 @@ Thu Feb 6 19:31:54 1997 GNUstep Development <gnustep@net-community.com>
* NSView.m: Don't use -isKindOfClass: because it isn't working * NSView.m: Don't use -isKindOfClass: because it isn't working
as we expect with the backend classes doing a +poseAs: as we expect with the backend classes doing a +poseAs:
Mon Feb 10 17:23:06 1997 Ovidiu Predescu <ovidiu@bx.logicnet.ro> Mon Feb 10 17:23:06 1997 Ovidiu Predescu <ovidiu@net-community.com>
* Source/NSFont.m: Completely reworked. Get the default fonts using * Source/NSFont.m: Completely reworked. Get the default fonts using
the NSUserDefaults class instead of hard-coding them. Almost all the the NSUserDefaults class instead of hard-coding them. Almost all the
@ -267,7 +295,7 @@ Thu Jan 23 15:10:13 1997 Scott Christley <scottc@net-community.com>
defined in NSApplication. defined in NSApplication.
* Source/NSTextFieldCell.m (-initWithFrame:): Bezeled by default. * Source/NSTextFieldCell.m (-initWithFrame:): Bezeled by default.
Tue Jan 14 9:33:04 1997 Ovidiu Predescu <ovidiu@bx.logicnet.ro> Tue Jan 14 9:33:04 1997 Ovidiu Predescu <ovidiu@net-community.com>
* Source/Functions.m: Exclude from compiling the NSLog functions when * Source/Functions.m: Exclude from compiling the NSLog functions when
working with libFoundation. working with libFoundation.

View file

@ -104,11 +104,12 @@ NSString *NSControlTextDidChangeNotification = @"NSControlTextDidChangeNotificat
- copyWithZone:(NSZone *)zone - copyWithZone:(NSZone *)zone
{ {
id c; id c;
c = NSAllocateObject (isa, 0, zone); c = NSCopyObject (self, 0, zone);
NSLog(@"NSControl: copyWithZone\n"); NSLog(@"NSControl: copyWithZone\n");
// make sure the new copy also has a new copy of the cell // make sure the new copy also has a new copy of the cell
[cell retain];
[c setCell: [[cell copy] autorelease]]; [c setCell: [[cell copy] autorelease]];
return c; return c;
} }
@ -296,12 +297,22 @@ right:(unsigned)rightDigits
// //
- (void)drawCell:(NSCell *)aCell - (void)drawCell:(NSCell *)aCell
{ {
if (cell == aCell) [cell drawWithFrame:bounds inView:self]; if (cell == aCell)
{
[self lockFocus];
[cell drawWithFrame:bounds inView:self];
[self unlockFocus];
}
} }
- (void)drawCellInside:(NSCell *)aCell - (void)drawCellInside:(NSCell *)aCell
{ {
if (cell == aCell) [cell drawInteriorWithFrame:bounds inView:self]; if (cell == aCell)
{
[self lockFocus];
[cell drawInteriorWithFrame:bounds inView:self];
[self unlockFocus];
}
} }
- (void)selectCell:(NSCell *)aCell - (void)selectCell:(NSCell *)aCell

View file

@ -72,30 +72,6 @@ static NSMutableDictionary* nameDict;
NSArray *iterate_reps_for_types(NSArray *imageReps, SEL method); NSArray *iterate_reps_for_types(NSArray *imageReps, SEL method);
/* (NSString doesn't do these yet) */
/* Strip the extension from a name */
#define BASENAME(str) ((strrchr(str, '/')) ? strrchr(str, '/')+1 : str)
static NSString *
_base_name(NSString *name)
{
return [NSString stringWithCString: BASENAME([name cString])];
}
/* Get the extension from a name */
static NSString *
extension(NSString *name)
{
const char* cname;
char *s;
cname = [name cString];
s = strrchr(cname, '.');
if (s > strrchr(cname, '/'))
return [NSString stringWithCString:s+1];
else
return nil;
}
/* Find the rep_data_t holding a representation */ /* Find the rep_data_t holding a representation */
rep_data_t rep_data_t
repd_for_rep(NSArray *_reps, NSImageRep *rep) repd_for_rep(NSArray *_reps, NSImageRep *rep)
@ -171,27 +147,39 @@ set_repd_for_rep(NSMutableArray *_reps, NSImageRep *rep, rep_data_t *new_repd)
NSString* ext; NSString* ext;
NSString* path = nil; NSString* path = nil;
NSBundle* main; NSBundle* main;
NSArray *array;
NSString *the_name = aName;
main = [NSBundle mainBundle]; main = [NSBundle mainBundle];
ext = extension(aName); ext = [aName pathExtension];
/* Check if extension is one of the image types */
array = [self imageFileTypes];
if ([array indexOfObject: ext] != NSNotFound)
{
/* Extension is one of the image types
So remove from the name */
the_name = [aName stringByDeletingPathExtension];
}
else
{
/* Otherwise extension is not an image type
So leave it alone */
the_name = aName;
ext = nil;
}
NSDebugLog(@"search locally\n");
NSDebugLog(@"extension is %s\n", [ext cString]);
/* First search locally */ /* First search locally */
if (ext) if (ext)
path = [main pathForResource: aName ofType: ext]; path = [main pathForResource: the_name ofType: ext];
else else
{ {
id o, e; id o, e;
NSArray* array;
array = [self imageFileTypes];
if (!array)
NSDebugLog(@"array is nil\n");
e = [array objectEnumerator]; e = [array objectEnumerator];
while ((o = [e nextObject])) while ((o = [e nextObject]))
{ {
NSDebugLog(@"extension %s\n", [o cString]); NSDebugLog(@"extension %s\n", [o cString]);
path = [main pathForResource:aName path = [main pathForResource:the_name
ofType: o]; ofType: o];
if ([path length] != 0) if ([path length] != 0)
break; break;
@ -204,7 +192,7 @@ set_repd_for_rep(NSMutableArray *_reps, NSImageRep *rep, rep_data_t *new_repd)
NSBundle *system = [NSBundle bundleWithPath: gnustep_libdir]; NSBundle *system = [NSBundle bundleWithPath: gnustep_libdir];
if (ext) if (ext)
path = [system pathForResource: aName path = [system pathForResource: the_name
ofType: ext ofType: ext
inDirectory: NSImage_PATH]; inDirectory: NSImage_PATH];
else else
@ -218,7 +206,7 @@ set_repd_for_rep(NSMutableArray *_reps, NSImageRep *rep, rep_data_t *new_repd)
e = [array objectEnumerator]; e = [array objectEnumerator];
while ((o = [e nextObject])) while ((o = [e nextObject]))
{ {
path = [system pathForResource: aName path = [system pathForResource: the_name
ofType: o ofType: o
inDirectory: NSImage_PATH]; inDirectory: NSImage_PATH];
if ([path length] != 0) if ([path length] != 0)
@ -231,7 +219,9 @@ set_repd_for_rep(NSMutableArray *_reps, NSImageRep *rep, rep_data_t *new_repd)
{ {
NSImage* image = [[NSImage alloc] initByReferencingFile:path]; NSImage* image = [[NSImage alloc] initByReferencingFile:path];
if (image) if (image)
[image setName:_base_name(path)]; [image setName: [[path lastPathComponent]
stringByDeletingPathExtension]];
[nameDict setObject: image forKey: [image name]];
return image; return image;
} }
} }
@ -665,7 +655,7 @@ set_repd_for_rep(NSMutableArray *_reps, NSImageRep *rep, rep_data_t *new_repd)
NSString* ext; NSString* ext;
rep_data_t repd; rep_data_t repd;
ext = extension(fileName); ext = [fileName pathExtension];
if (!ext) if (!ext)
return NO; return NO;
array = [[self class] imageFileTypes]; array = [[self class] imageFileTypes];

View file

@ -146,8 +146,8 @@ id gnustep_gui_nsscroller_class = nil;
- (void)setFloatValue:(float)aFloat - (void)setFloatValue:(float)aFloat
knobProportion:(float)ratio knobProportion:(float)ratio
{ {
[cell setFloatValue: aFloat];
knob_proportion = ratio; knob_proportion = ratio;
[cell setFloatValue: aFloat];
} }
- (void)setFloatValue:(float)aFloat - (void)setFloatValue:(float)aFloat
@ -164,6 +164,9 @@ id gnustep_gui_nsscroller_class = nil;
// //
- (void)drawRect:(NSRect)rect - (void)drawRect:(NSRect)rect
{ {
// xxx We can add some smarts here so that only the parts
// which intersect with the rect get drawn.
[self drawParts]; [self drawParts];
} }
@ -206,6 +209,7 @@ id gnustep_gui_nsscroller_class = nil;
if (!knob_dimple) if (!knob_dimple)
knob_dimple = [NSImage imageNamed: @"common_Dimple"]; knob_dimple = [NSImage imageNamed: @"common_Dimple"];
[self drawKnob]; [self drawKnob];
[[self window] flushWindow];
} }
- (void)highlight:(BOOL)flag - (void)highlight:(BOOL)flag
@ -264,10 +268,10 @@ id gnustep_gui_nsscroller_class = nil;
unsigned int event_mask = NSLeftMouseDownMask | NSLeftMouseUpMask | unsigned int event_mask = NSLeftMouseDownMask | NSLeftMouseUpMask |
NSMouseMovedMask | NSLeftMouseDraggedMask | NSRightMouseDraggedMask; NSMouseMovedMask | NSLeftMouseDraggedMask | NSRightMouseDraggedMask;
NSRect partRect = [self boundsOfScrollerPart: NSScrollerKnob];
NSPoint point = [self convertPoint: [theEvent locationInWindow] NSPoint point = [self convertPoint: [theEvent locationInWindow]
fromView: nil]; fromView: nil];
NSPoint last_point; NSPoint last_point;
NSRect knobRect = [self boundsOfScrollerPart: NSScrollerKnob];
NSRect barRect = [self boundsOfScrollerPart: NSScrollerKnobSlot]; NSRect barRect = [self boundsOfScrollerPart: NSScrollerKnobSlot];
float pos; float pos;
@ -286,21 +290,21 @@ id gnustep_gui_nsscroller_class = nil;
if (is_horizontal) if (is_horizontal)
{ {
pos = (point.x - barRect.origin.x) / barRect.size.width; pos = (point.x - barRect.origin.x - (knobRect.size.width/2))
/ (barRect.size.width - knobRect.size.width);
[self setFloatValue: pos]; [self setFloatValue: pos];
[self lockFocus];
[self drawBar]; [self drawBar];
[self drawKnob]; [self drawKnob];
[self unlockFocus]; [[self window] flushWindow];
} }
else else
{ {
pos = (point.y - barRect.origin.y) / barRect.size.height; pos = (point.y - barRect.origin.y - (knobRect.size.height/2))
/ (barRect.size.height - knobRect.size.height);
[self setFloatValue: pos]; [self setFloatValue: pos];
[self lockFocus];
[self drawBar]; [self drawBar];
[self drawKnob]; [self drawKnob];
[self unlockFocus]; [[self window] flushWindow];
} }
// Did the mouse go up? // Did the mouse go up?
@ -316,49 +320,108 @@ id gnustep_gui_nsscroller_class = nil;
// Have the target perform the action // Have the target perform the action
[self sendAction:[self action] to:[self target]]; [self sendAction:[self action] to:[self target]];
// Update the display
[self drawParts];
[[self window] flushWindow];
} }
- (void)trackScrollButtons:(NSEvent *)theEvent - (void)trackScrollButtons:(NSEvent *)theEvent
{ {
NSApplication *theApp = [NSApplication sharedApplication]; NSApplication *theApp = [NSApplication sharedApplication];
BOOL mouseUp, done; BOOL done;
NSEvent *e; NSEvent *e;
unsigned int event_mask = NSLeftMouseDownMask | NSLeftMouseUpMask | unsigned int event_mask = NSLeftMouseDownMask | NSLeftMouseUpMask |
NSMouseMovedMask | NSLeftMouseDraggedMask | NSRightMouseDraggedMask; NSMouseMovedMask | NSLeftMouseDraggedMask | NSRightMouseDraggedMask;
NSRect partRect = [self boundsOfScrollerPart: hit_part];
NSPoint point = [self convertPoint: [theEvent locationInWindow]
fromView: nil];
NSPoint last_point;
NSScrollerArrow arrow;
BOOL arrow_highlighted = NO;
// Find out which arrow button
switch (hit_part)
{
case NSScrollerDecrementPage:
case NSScrollerDecrementLine:
arrow = NSScrollerDecrementArrow;
break;
case NSScrollerIncrementPage:
case NSScrollerIncrementLine:
default:
arrow = NSScrollerIncrementArrow;
break;
}
// capture mouse // capture mouse
[[self window] captureMouse: self]; [[self window] captureMouse: self];
// If point is in arrow then highlight it
if ([self mouse: point inRect: partRect])
{
[self drawArrow: arrow highlight: YES];
[[self window] flushWindow];
arrow_highlighted = YES;
}
else
return;
// Get next mouse events until a mouse up is obtained
done = NO; done = NO;
e = theEvent;
while (!done) while (!done)
{ {
mouseUp = [cell trackMouse: e inRect: bounds last_point = point;
ofView:self untilMouseUp:YES]; e = [theApp nextEventMatchingMask:event_mask untilDate:nil
e = [theApp currentEvent]; inMode:nil dequeue:YES];
// If mouse went up then we are done point = [self convertPoint: [e locationInWindow] fromView: nil];
if ((mouseUp) || ([e type] == NSLeftMouseUp))
done = YES; // Point is not in arrow
if (![self mouse: point inRect: partRect])
{
// unhighlight arrow if highlighted
if (arrow_highlighted)
{
[self drawArrow: arrow highlight: NO];
[[self window] flushWindow];
arrow_highlighted = NO;
}
}
else else
{ {
NSDebugLog(@"NSScroller process another event\n"); // Point is in cell
e = [theApp nextEventMatchingMask:event_mask untilDate:nil // highlight cell if not highlighted
inMode:nil dequeue:YES]; if (!arrow_highlighted)
{
[self drawArrow: arrow highlight: YES];
[[self window] flushWindow];
arrow_highlighted = YES;
}
} }
// Did the mouse go up?
if ([e type] == NSLeftMouseUp)
done = YES;
} }
// Release mouse // Release mouse
[[self window] releaseMouse: self]; [[self window] releaseMouse: self];
// If the mouse went up in the button // If the mouse went up in the button
if (mouseUp) if ([self mouse: point inRect: partRect])
{ {
// Set a new value // unhighlight arrow
[self drawArrow: arrow highlight: NO];
[[self window] flushWindow];
// Have the target perform the action // Have the target perform the action
[self sendAction:[self action] to:[self target]]; [self sendAction:[self action] to:[self target]];
} }
// Update the display
[self drawParts];
[[self window] flushWindow];
} }
// //
@ -394,6 +457,8 @@ id gnustep_gui_nsscroller_class = nil;
// We must have hit a real part so record it // We must have hit a real part so record it
hit_part = area; hit_part = area;
[self lockFocus];
// Track the knob if that's where it hit // Track the knob if that's where it hit
if ((hit_part == NSScrollerKnob) || (hit_part == NSScrollerKnobSlot)) if ((hit_part == NSScrollerKnob) || (hit_part == NSScrollerKnobSlot))
[self trackKnob: theEvent]; [self trackKnob: theEvent];
@ -404,6 +469,8 @@ id gnustep_gui_nsscroller_class = nil;
(hit_part == NSScrollerIncrementPage) || (hit_part == NSScrollerIncrementPage) ||
(hit_part == NSScrollerIncrementLine)) (hit_part == NSScrollerIncrementLine))
[self trackScrollButtons: theEvent]; [self trackScrollButtons: theEvent];
[self unlockFocus];
} }
// //

View file

@ -87,6 +87,24 @@ static id MB_NSTEXTFIELDCELL_CLASS = nil;
return self; return self;
} }
//
// Creating copies
//
- (void)setTextCursor:(NSCursor *)aCursor
{
text_cursor = aCursor;
}
- copyWithZone:(NSZone *)zone
{
id c;
c = [super copyWithZone: zone];
[c setTextCursor: [NSCursor IBeamCursor]];
return c;
}
// //
// Setting User Access to Text // Setting User Access to Text
// //

View file

@ -80,6 +80,7 @@
background_color = [NSColor whiteColor]; background_color = [NSColor whiteColor];
text_color = [NSColor blackColor]; text_color = [NSColor blackColor];
cell_font = [NSFont systemFontOfSize:12]; cell_font = [NSFont systemFontOfSize:12];
draw_background = YES;
return self; return self;
} }

View file

@ -259,9 +259,28 @@ NSString *NSViewFocusChangedNotification = @"NSViewFocusChangedNotification";
- (NSView *)ancestorSharedWithView:(NSView *)aView - (NSView *)ancestorSharedWithView:(NSView *)aView
{ {
NSView *v = nil; // Are they the same?
if (self == aView)
return self;
return v; // Is self a descendant of view?
if ([self isDescendantOf: aView])
return aView;
// Is view a descendant of self?
if ([aView isDescendantOf: self])
return self;
// If neither are descendants of each other
// and either does not have a superview
// then they cannot have a common ancestor
if (![self superview])
return nil;
if (![aView superview])
return nil;
// Find the common ancestor of superviews
return [[self superview] ancestorSharedWithView: [aView superview]];
} }
- (BOOL)isDescendantOf:(NSView *)aView - (BOOL)isDescendantOf:(NSView *)aView
@ -734,11 +753,25 @@ NSString *NSViewFocusChangedNotification = @"NSViewFocusChangedNotification";
// //
- (void)lockFocus - (void)lockFocus
{ {
NSView *s = [self superview];
// lock our superview
if (s)
[s lockFocus];
// push ourselves
[[self class] pushFocusView: self]; [[self class] pushFocusView: self];
} }
- (void)unlockFocus - (void)unlockFocus
{ {
NSView *s = [self superview];
// unlock our superview
if (s)
[s unlockFocus];
// pop ourselves
[[self class] popFocusView]; [[self class] popFocusView];
} }

View file

@ -356,6 +356,7 @@ NSTiffRead(int imageNumber, TIFF* image, NSTiffInfo* info, char* data)
for ( col = 0; col < newinfo->width; col++) for ( col = 0; col < newinfo->width; col++)
for (i = 0; i < newinfo->samplesPerPixel; i++) for (i = 0; i < newinfo->samplesPerPixel; i++)
{ {
NSDebugLog(@"%d", *inP);
*outP++ = *inP++; *outP++ = *inP++;
} }
} }