From bf12b45df071c7717aeb43e490e626809702f93e Mon Sep 17 00:00:00 2001 From: netcrep Date: Thu, 20 Mar 1997 19:23:21 +0000 Subject: [PATCH] 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 --- ChangeLog | 40 +++++++++++--- Source/NSControl.m | 17 ++++-- Source/NSImage.m | 64 ++++++++++------------ Source/NSScroller.m | 111 +++++++++++++++++++++++++++++++-------- Source/NSTextField.m | 18 +++++++ Source/NSTextFieldCell.m | 1 + Source/NSView.m | 37 ++++++++++++- Source/tiff.m | 1 + 8 files changed, 219 insertions(+), 70 deletions(-) diff --git a/ChangeLog b/ChangeLog index 365933fa5..47d10920c 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,32 @@ -Fri Mar 14 18:23:18 1997 Ovidiu Predescu +Thu Mar 20 10:40:51 1997 GNUstep Development + + * 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 * Flush the view's window after a redraw. * Source/NSButton.m (-mouseDown:): Likewise. @@ -28,7 +56,7 @@ Wed Mar 5 17:43:34 1997 GNUstep Development * Headers/gnustep/gui/nsimage-tiff.h: Include gnustep-gui config. * Source/tiff.m: Include header file. -Tue Mar 4 18:05:24 1997 Ovidiu Predescu +Tue Mar 4 18:05:24 1997 Ovidiu Predescu * Source/NSFont.m (-minimumAdvancement): New method. * Source/NSButton.m (-initWithFrame:): Use an autoreleased cell. @@ -118,7 +146,7 @@ Tue Mar 4 09:28:57 1997 GNUstep Development * Source/NSBundle.m (+imageNamed:): Create a bundle with gnustep library install path for searching system resources. -Mon Feb 17 19:30:50 1997 Ovidiu Predescu +Mon Feb 17 19:30:50 1997 Ovidiu Predescu * Source/NSButton.m: New methods -setAlignment: and -alignment, setIntValue:, setFloatValue:, setDoubleValue:, setAlignment:, @@ -133,7 +161,7 @@ Mon Feb 17 19:30:50 1997 Ovidiu Predescu way in which setIntValue:, setFloatValue: and setDoubleValue: work. Commented out a point conversion that works wrong (why?). -Sat Feb 15 23:12:35 1997 Ovidiu Predescu +Sat Feb 15 23:12:35 1997 Ovidiu Predescu * Major reorganization of header files. Types and constants were moved 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 * NSView.m: Don't use -isKindOfClass: because it isn't working as we expect with the backend classes doing a +poseAs: -Mon Feb 10 17:23:06 1997 Ovidiu Predescu +Mon Feb 10 17:23:06 1997 Ovidiu Predescu * Source/NSFont.m: Completely reworked. Get the default fonts using the NSUserDefaults class instead of hard-coding them. Almost all the @@ -267,7 +295,7 @@ Thu Jan 23 15:10:13 1997 Scott Christley defined in NSApplication. * Source/NSTextFieldCell.m (-initWithFrame:): Bezeled by default. -Tue Jan 14 9:33:04 1997 Ovidiu Predescu +Tue Jan 14 9:33:04 1997 Ovidiu Predescu * Source/Functions.m: Exclude from compiling the NSLog functions when working with libFoundation. diff --git a/Source/NSControl.m b/Source/NSControl.m index 32d796c4a..f8c2f6527 100644 --- a/Source/NSControl.m +++ b/Source/NSControl.m @@ -104,11 +104,12 @@ NSString *NSControlTextDidChangeNotification = @"NSControlTextDidChangeNotificat - copyWithZone:(NSZone *)zone { id c; - c = NSAllocateObject (isa, 0, zone); + c = NSCopyObject (self, 0, zone); NSLog(@"NSControl: copyWithZone\n"); // make sure the new copy also has a new copy of the cell + [cell retain]; [c setCell: [[cell copy] autorelease]]; return c; } @@ -296,12 +297,22 @@ right:(unsigned)rightDigits // - (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 { - if (cell == aCell) [cell drawInteriorWithFrame:bounds inView:self]; + if (cell == aCell) + { + [self lockFocus]; + [cell drawInteriorWithFrame:bounds inView:self]; + [self unlockFocus]; + } } - (void)selectCell:(NSCell *)aCell diff --git a/Source/NSImage.m b/Source/NSImage.m index 689b66f98..510a13852 100644 --- a/Source/NSImage.m +++ b/Source/NSImage.m @@ -72,30 +72,6 @@ static NSMutableDictionary* nameDict; 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 */ rep_data_t 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* path = nil; NSBundle* main; + NSArray *array; + NSString *the_name = aName; 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 */ if (ext) - path = [main pathForResource: aName ofType: ext]; + path = [main pathForResource: the_name ofType: ext]; else { id o, e; - NSArray* array; - array = [self imageFileTypes]; - if (!array) - NSDebugLog(@"array is nil\n"); e = [array objectEnumerator]; while ((o = [e nextObject])) { NSDebugLog(@"extension %s\n", [o cString]); - path = [main pathForResource:aName + path = [main pathForResource:the_name ofType: o]; if ([path length] != 0) break; @@ -204,7 +192,7 @@ set_repd_for_rep(NSMutableArray *_reps, NSImageRep *rep, rep_data_t *new_repd) NSBundle *system = [NSBundle bundleWithPath: gnustep_libdir]; if (ext) - path = [system pathForResource: aName + path = [system pathForResource: the_name ofType: ext inDirectory: NSImage_PATH]; else @@ -218,7 +206,7 @@ set_repd_for_rep(NSMutableArray *_reps, NSImageRep *rep, rep_data_t *new_repd) e = [array objectEnumerator]; while ((o = [e nextObject])) { - path = [system pathForResource: aName + path = [system pathForResource: the_name ofType: o inDirectory: NSImage_PATH]; 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]; if (image) - [image setName:_base_name(path)]; + [image setName: [[path lastPathComponent] + stringByDeletingPathExtension]]; + [nameDict setObject: image forKey: [image name]]; return image; } } @@ -665,7 +655,7 @@ set_repd_for_rep(NSMutableArray *_reps, NSImageRep *rep, rep_data_t *new_repd) NSString* ext; rep_data_t repd; - ext = extension(fileName); + ext = [fileName pathExtension]; if (!ext) return NO; array = [[self class] imageFileTypes]; diff --git a/Source/NSScroller.m b/Source/NSScroller.m index 1267f3126..d71ed7e87 100644 --- a/Source/NSScroller.m +++ b/Source/NSScroller.m @@ -146,8 +146,8 @@ id gnustep_gui_nsscroller_class = nil; - (void)setFloatValue:(float)aFloat knobProportion:(float)ratio { - [cell setFloatValue: aFloat]; knob_proportion = ratio; + [cell setFloatValue: aFloat]; } - (void)setFloatValue:(float)aFloat @@ -164,6 +164,9 @@ id gnustep_gui_nsscroller_class = nil; // - (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]; } @@ -206,6 +209,7 @@ id gnustep_gui_nsscroller_class = nil; if (!knob_dimple) knob_dimple = [NSImage imageNamed: @"common_Dimple"]; [self drawKnob]; + [[self window] flushWindow]; } - (void)highlight:(BOOL)flag @@ -264,10 +268,10 @@ id gnustep_gui_nsscroller_class = nil; unsigned int event_mask = NSLeftMouseDownMask | NSLeftMouseUpMask | NSMouseMovedMask | NSLeftMouseDraggedMask | NSRightMouseDraggedMask; - NSRect partRect = [self boundsOfScrollerPart: NSScrollerKnob]; NSPoint point = [self convertPoint: [theEvent locationInWindow] fromView: nil]; NSPoint last_point; + NSRect knobRect = [self boundsOfScrollerPart: NSScrollerKnob]; NSRect barRect = [self boundsOfScrollerPart: NSScrollerKnobSlot]; float pos; @@ -286,21 +290,21 @@ id gnustep_gui_nsscroller_class = nil; 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 lockFocus]; [self drawBar]; [self drawKnob]; - [self unlockFocus]; + [[self window] flushWindow]; } 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 lockFocus]; [self drawBar]; [self drawKnob]; - [self unlockFocus]; + [[self window] flushWindow]; } // Did the mouse go up? @@ -316,49 +320,108 @@ id gnustep_gui_nsscroller_class = nil; // Have the target perform the action [self sendAction:[self action] to:[self target]]; + + // Update the display + [self drawParts]; + [[self window] flushWindow]; } - (void)trackScrollButtons:(NSEvent *)theEvent { NSApplication *theApp = [NSApplication sharedApplication]; - BOOL mouseUp, done; + BOOL done; NSEvent *e; unsigned int event_mask = NSLeftMouseDownMask | NSLeftMouseUpMask | 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 [[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; - e = theEvent; while (!done) { - mouseUp = [cell trackMouse: e inRect: bounds - ofView:self untilMouseUp:YES]; - e = [theApp currentEvent]; + last_point = point; + e = [theApp nextEventMatchingMask:event_mask untilDate:nil + inMode:nil dequeue:YES]; - // If mouse went up then we are done - if ((mouseUp) || ([e type] == NSLeftMouseUp)) - done = YES; + point = [self convertPoint: [e locationInWindow] fromView: nil]; + + // 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 { - NSDebugLog(@"NSScroller process another event\n"); - e = [theApp nextEventMatchingMask:event_mask untilDate:nil - inMode:nil dequeue:YES]; + // Point is in cell + // highlight cell if not highlighted + 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 [[self window] releaseMouse: self]; // If the mouse went up in the button - if (mouseUp) - { - // Set a new value + if ([self mouse: point inRect: partRect]) + { + // unhighlight arrow + [self drawArrow: arrow highlight: NO]; + [[self window] flushWindow]; // Have the target perform the action [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 hit_part = area; + [self lockFocus]; + // Track the knob if that's where it hit if ((hit_part == NSScrollerKnob) || (hit_part == NSScrollerKnobSlot)) [self trackKnob: theEvent]; @@ -404,6 +469,8 @@ id gnustep_gui_nsscroller_class = nil; (hit_part == NSScrollerIncrementPage) || (hit_part == NSScrollerIncrementLine)) [self trackScrollButtons: theEvent]; + + [self unlockFocus]; } // diff --git a/Source/NSTextField.m b/Source/NSTextField.m index a5d26e016..e896db700 100644 --- a/Source/NSTextField.m +++ b/Source/NSTextField.m @@ -87,6 +87,24 @@ static id MB_NSTEXTFIELDCELL_CLASS = nil; 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 // diff --git a/Source/NSTextFieldCell.m b/Source/NSTextFieldCell.m index b49b149db..a1e493168 100644 --- a/Source/NSTextFieldCell.m +++ b/Source/NSTextFieldCell.m @@ -80,6 +80,7 @@ background_color = [NSColor whiteColor]; text_color = [NSColor blackColor]; cell_font = [NSFont systemFontOfSize:12]; + draw_background = YES; return self; } diff --git a/Source/NSView.m b/Source/NSView.m index 57ca1facc..c40884a05 100644 --- a/Source/NSView.m +++ b/Source/NSView.m @@ -259,9 +259,28 @@ NSString *NSViewFocusChangedNotification = @"NSViewFocusChangedNotification"; - (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 @@ -734,11 +753,25 @@ NSString *NSViewFocusChangedNotification = @"NSViewFocusChangedNotification"; // - (void)lockFocus { + NSView *s = [self superview]; + + // lock our superview + if (s) + [s lockFocus]; + + // push ourselves [[self class] pushFocusView: self]; } - (void)unlockFocus { + NSView *s = [self superview]; + + // unlock our superview + if (s) + [s unlockFocus]; + + // pop ourselves [[self class] popFocusView]; } diff --git a/Source/tiff.m b/Source/tiff.m index cf40b788b..b2b4c2310 100644 --- a/Source/tiff.m +++ b/Source/tiff.m @@ -356,6 +356,7 @@ NSTiffRead(int imageNumber, TIFF* image, NSTiffInfo* info, char* data) for ( col = 0; col < newinfo->width; col++) for (i = 0; i < newinfo->samplesPerPixel; i++) { + NSDebugLog(@"%d", *inP); *outP++ = *inP++; } }