diff --git a/Applications/Gorm/English.lproj/GormLayeredInspector.gorm/data.classes b/Applications/Gorm/English.lproj/GormLayeredInspector.gorm/data.classes new file mode 100644 index 000000000..e95bb5b8f --- /dev/null +++ b/Applications/Gorm/English.lproj/GormLayeredInspector.gorm/data.classes @@ -0,0 +1,11 @@ +{ + "## Comment" = "Do NOT change this file, Gorm maintains it"; + GormLayeredInspectorController = { + Actions = ( + ); + Outlets = ( + "_tableView" + ); + Super = NSViewController; + }; +} \ No newline at end of file diff --git a/Applications/Gorm/English.lproj/GormLayeredInspector.gorm/data.info b/Applications/Gorm/English.lproj/GormLayeredInspector.gorm/data.info new file mode 100644 index 000000000..f888a1175 Binary files /dev/null and b/Applications/Gorm/English.lproj/GormLayeredInspector.gorm/data.info differ diff --git a/Applications/Gorm/English.lproj/GormLayeredInspector.gorm/objects.gorm b/Applications/Gorm/English.lproj/GormLayeredInspector.gorm/objects.gorm new file mode 100644 index 000000000..dc9e79e8c Binary files /dev/null and b/Applications/Gorm/English.lproj/GormLayeredInspector.gorm/objects.gorm differ diff --git a/Applications/Gorm/GNUmakefile b/Applications/Gorm/GNUmakefile index 62fc49f2e..590ac81f0 100644 --- a/Applications/Gorm/GNUmakefile +++ b/Applications/Gorm/GNUmakefile @@ -155,11 +155,13 @@ Gorm_LANGUAGES = \ Gorm_HEADERS = \ GormAppDelegate.h \ - GormLanguageViewController.h + GormLanguageViewController.h \ + GormLayeredInspectorController.h Gorm_OBJC_FILES = \ GormAppDelegate.m \ GormLanguageViewController.m \ + GormLayeredInspectorController.m \ main.m -include GNUmakefile.preamble diff --git a/Applications/Gorm/GormLayeredInspectorController.h b/Applications/Gorm/GormLayeredInspectorController.h new file mode 100644 index 000000000..6a0caea46 --- /dev/null +++ b/Applications/Gorm/GormLayeredInspectorController.h @@ -0,0 +1,36 @@ +/* GormLayeredInspectorController.h + * + * Copyright (C) 2025 Free Software Foundation, Inc. + * + * Author: Gregory John Casamento + * Date: 2025 + * + * 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 3 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + */ + +#ifndef GormLayeredInspectorController_H_INCLUDE +#define GormLayeredInspectorController_H_INCLUDE + +#import + +@interface GormLayeredInspectorController : NSViewController +{ + IBOutlet id _tableView; +} +@end + +#endif // GormLayeredInspectorController_H_INCLUDE diff --git a/Applications/Gorm/GormLayeredInspectorController.m b/Applications/Gorm/GormLayeredInspectorController.m new file mode 100644 index 000000000..bf6874ecc --- /dev/null +++ b/Applications/Gorm/GormLayeredInspectorController.m @@ -0,0 +1,46 @@ +/* GormLayeredInspectorController.h + * + * Copyright (C) 2025 Free Software Foundation, Inc. + * + * Author: Gregory John Casamento + * Date: 2025 + * + * 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 3 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., 51 Franklin Street, Fifth Floor, Boston, MA 02111 USA. + */ + +#import +#import "GormLayeredInspectorController.h" + +@implementation GormLayeredInspectorController + +// Data source + +- (NSInteger) numberOfRowsInTableView: (NSTableView *)tableView +{ + return 0; // get all inspectors for the selection... +} + +// Delegate + +- (NSView *) tableView: (NSTableView *)tableView + viewForTableColumn: (NSTableColumn *)tableColumn + row: (NSInteger)row +{ + return nil; // given the class and all subclasses, find all inspectors... +} + +@end diff --git a/Applications/Gorm/Palettes/0Menus/inspectors.m b/Applications/Gorm/Palettes/0Menus/inspectors.m index ebf51bad8..93a9038a6 100644 --- a/Applications/Gorm/Palettes/0Menus/inspectors.m +++ b/Applications/Gorm/Palettes/0Menus/inspectors.m @@ -30,17 +30,23 @@ @implementation NSMenu (IBObjectAdditions) +/** + * Inspector for menu attributes + */ - (NSString*) inspectorClassName { return @"GormMenuAttributesInspector"; } +/** + * Menu editor class + */ - (NSString*) editorClassName { return @"GormMenuEditor"; } -/* +/** * Method to return the image that should be used to display menus within * the matrix containing the objects in a document. */ @@ -61,6 +67,9 @@ - (NSImage*) imageForViewer @implementation NSMenuItem (IBObjectAdditions) +/** + * Inspector class for NSMenuItem instances. + */ - (NSString*) inspectorClassName { return @"GormMenuItemAttributesInspector"; diff --git a/Applications/Gorm/Palettes/3Containers/GormNSTableViewInspector.gorm/data.classes b/Applications/Gorm/Palettes/3Containers/GormNSTableViewInspector.gorm/data.classes index 8505b3b87..adb532277 100644 --- a/Applications/Gorm/Palettes/3Containers/GormNSTableViewInspector.gorm/data.classes +++ b/Applications/Gorm/Palettes/3Containers/GormNSTableViewInspector.gorm/data.classes @@ -16,7 +16,8 @@ columnSelectionSwitch, drawgridSwitch, resizingSwitch, - reorderingSwitch + reorderingSwitch, + viewBased ); Super = IBInspector; }; diff --git a/Applications/Gorm/Palettes/3Containers/GormNSTableViewInspector.gorm/data.info b/Applications/Gorm/Palettes/3Containers/GormNSTableViewInspector.gorm/data.info index 744f736ac..f888a1175 100644 Binary files a/Applications/Gorm/Palettes/3Containers/GormNSTableViewInspector.gorm/data.info and b/Applications/Gorm/Palettes/3Containers/GormNSTableViewInspector.gorm/data.info differ diff --git a/Applications/Gorm/Palettes/3Containers/GormNSTableViewInspector.gorm/objects.gorm b/Applications/Gorm/Palettes/3Containers/GormNSTableViewInspector.gorm/objects.gorm index 356043a5b..42ae1e877 100644 Binary files a/Applications/Gorm/Palettes/3Containers/GormNSTableViewInspector.gorm/objects.gorm and b/Applications/Gorm/Palettes/3Containers/GormNSTableViewInspector.gorm/objects.gorm differ diff --git a/GormCore/English.lproj/GormSoundInspector.gorm/data.info b/GormCore/English.lproj/GormSoundInspector.gorm/data.info index 744f736ac..f888a1175 100644 Binary files a/GormCore/English.lproj/GormSoundInspector.gorm/data.info and b/GormCore/English.lproj/GormSoundInspector.gorm/data.info differ diff --git a/GormCore/English.lproj/GormSoundInspector.gorm/objects.gorm b/GormCore/English.lproj/GormSoundInspector.gorm/objects.gorm index 8457a9652..a903314ac 100644 Binary files a/GormCore/English.lproj/GormSoundInspector.gorm/objects.gorm and b/GormCore/English.lproj/GormSoundInspector.gorm/objects.gorm differ diff --git a/GormCore/GormInspectorsManager.h b/GormCore/GormInspectorsManager.h index c12753c2f..65f428662 100644 --- a/GormCore/GormInspectorsManager.h +++ b/GormCore/GormInspectorsManager.h @@ -40,21 +40,25 @@ @interface GormInspectorsManager : IBInspectorManager { IBOutlet NSPanel *panel; - NSMutableDictionary *cache; IBOutlet NSPopUpButton *popup; IBOutlet NSBox *selectionView; IBOutlet NSBox *inspectorView; + IBOutlet IBInspector *inspector; + + NSMutableDictionary *cache; NSView *buttonView; NSString *oldInspector; - IBOutlet IBInspector *inspector; int current; BOOL hiddenDuringTest; NSRect origFrame; } -- (NSPanel*) panel; + +- (NSPanel *) panel; - (void) setClassInspector; - (void) setCurrentInspector: (id)anObject; - (void) updateSelection; +- (NSArray *) inspectorsForObject: (id)anObject mode: (NSString *)mode; + @end #endif diff --git a/GormCore/GormInspectorsManager.m b/GormCore/GormInspectorsManager.m index b018fba7a..f9ae196f7 100644 --- a/GormCore/GormInspectorsManager.m +++ b/GormCore/GormInspectorsManager.m @@ -493,4 +493,10 @@ - (void) setCurrentInspector: (id)anObj // inspect the object. [inspector setObject: [currentMode object]]; } + +- (NSArray *) inspectorsForObject: (id)anObject mode: (NSString *)mode +{ + +} + @end diff --git a/GormCore/GormObjectEditor.m b/GormCore/GormObjectEditor.m index 2a974f4b3..c6a1bcf2d 100644 --- a/GormCore/GormObjectEditor.m +++ b/GormCore/GormObjectEditor.m @@ -84,6 +84,32 @@ - (NSString*) editorClassName return @"GormObjectEditor"; } +// Class level inspector methods... ++ (NSString*) inspectorClassName +{ + return @"GormObjectInspector"; +} + ++ (NSString*) connectInspectorClassName +{ + return @"GormConnectionInspector"; +} + ++ (NSString*) sizeInspectorClassName +{ + return @"GormNotApplicableInspector"; +} + ++ (NSString*) helpInspectorClassName +{ + return @"GormNotApplicableInspector"; +} + ++ (NSString*) classInspectorClassName +{ + return @"GormCustomClassInspector"; +} + @end @implementation NSView (GormObjectAdditions) diff --git a/GormCore/GormSoundView.h b/GormCore/GormSoundView.h index dd6103d4d..3c3430818 100644 --- a/GormCore/GormSoundView.h +++ b/GormCore/GormSoundView.h @@ -26,12 +26,24 @@ /* All Rights reserved */ -#include +#include @interface GormSoundView : NSView { + short *_samples; + NSUInteger _sampleCount; + float _sampleRate; NSSound *_sound; } -- (void)setSound: (NSSound *)sound; -- (NSSound *)sound; + +- (void)setSamples:(short *)newSamples + sampleCount:(NSUInteger)count + sampleRate:(float)rate; + +- (BOOL)loadFromSound:(NSSound *)sound; + +- (void) setSound: (NSSound *)sound; + +- (NSSound *) sound; + @end diff --git a/GormCore/GormSoundView.m b/GormCore/GormSoundView.m index cd93a29fa..bf963d633 100644 --- a/GormCore/GormSoundView.m +++ b/GormCore/GormSoundView.m @@ -43,33 +43,159 @@ - (NSData *)data } @end -/* -static float findMax(NSData *data) +@implementation GormSoundView + +- (void)setSamples:(short *)newSamples + sampleCount:(NSUInteger)count + sampleRate:(float)rate { - float max = 0.0; - NSInteger index = 0; - float *array = (float *)[data bytes]; - NSInteger len = [data length]; + if (_samples) + { + free(_samples); + } - // find the maximum... - for(index = 0; index < len; index++) + _samples = malloc(sizeof(short) * count); + if (_samples && newSamples) { - float d = array[index]; - if(d > max) - { - max = d; - } + memcpy(_samples, newSamples, sizeof(short) * count); } - return max; + _sampleCount = count; + _sampleRate = rate; + + [self setNeedsDisplay:YES]; +} + +- (BOOL)loadFromSound:(NSSound *)sound +{ + NSData *soundData = [sound valueForKey:@"_data"]; + if (!soundData) + { + return NO; + } + + const void *bytes = [soundData bytes]; + NSUInteger length = [soundData length]; + + if (length < 44) + { + return NO; + } + + const unsigned char *ptr = (const unsigned char *)bytes; + if (memcmp(ptr, "RIFF", 4) != 0 + || memcmp(ptr + 8, "WAVE", 4) != 0) + { + return NO; + } + + int offset = 12; + int fmtFound = 0; + int dataFound = 0; + unsigned short bitsPerSample = 0; + unsigned short numChannels = 0; + unsigned int sampleRateRead = 0; + unsigned int dataSize = 0; + short *pcmStart = NULL; + + while (offset + 8 <= length) + { + char chunkId[5] = {0}; + memcpy(chunkId, ptr + offset, 4); + unsigned int chunkSize = *(unsigned int *)(ptr + offset + 4); + + if (memcmp(chunkId, "fmt ", 4) == 0) + { + if (chunkSize < 16) + { + return NO; + } + + numChannels = *(unsigned short *)(ptr + offset + 10); + sampleRateRead = *(unsigned int *)(ptr + offset + 12); + bitsPerSample = *(unsigned short *)(ptr + offset + 22); + fmtFound = 1; + } + else if (memcmp(chunkId, "data", 4) == 0) + { + dataSize = chunkSize; + pcmStart = (short *)(ptr + offset + 8); + dataFound = 1; + break; + } + + offset += 8 + chunkSize; + } + + if (!fmtFound + || !dataFound + || bitsPerSample != 16 + || numChannels != 1) + { + return NO; + } + + NSUInteger count = dataSize / 2; + short *copy = malloc(dataSize); + if (!copy) + { + return NO; + } + memcpy(copy, pcmStart, dataSize); + + [self setSamples:copy sampleCount:count + sampleRate:(float)sampleRateRead]; + free(copy); + + return YES; +} + +- (void)drawRect:(NSRect)dirtyRect +{ + NSRect bounds = [self bounds]; + [[NSColor blackColor] set]; + NSRectFill(bounds); + + if (!_samples || _sampleCount == 0) + { + return; + } + + [[NSColor greenColor] set]; + + NSBezierPath *path = [NSBezierPath bezierPath]; + + float midY = bounds.size.height / 2.0; + float xScale = bounds.size.width / (float)_sampleCount; + float yScale = midY / 32768.0; + + [path moveToPoint:NSMakePoint(0, midY)]; + + for (NSUInteger i = 0; i < _sampleCount; ++i) + { + float x = (float)i * xScale; + float y = midY + _samples[i] * yScale; + [path lineToPoint:NSMakePoint(x, y)]; + } + + [path stroke]; +} + +- (void)dealloc +{ + if (_samples) + { + free(_samples); + } + + [super dealloc]; } -*/ -@implementation GormSoundView - (void) setSound: (NSSound *)sound { NSLog(@"Set sound..."); - ASSIGN(_sound,sound); + ASSIGN(_sound, sound); + [self loadFromSound: sound]; [self setNeedsDisplay: YES]; } @@ -78,48 +204,4 @@ - (NSSound *)sound return _sound; } -/* -- (void) drawRect: (NSRect)aRect -{ - float w = aRect.size.width; - float h = aRect.size.height; - float offset = (h/2); - NSData *soundData = [_sound data]; - float *data = 0; - float x1 = 0, x2 = 0, y1 = offset, y2 = offset; - float max = findMax(soundData); - float multiplier = h/max; - NSInteger length = [soundData length]; - NSInteger index = 0; - NSInteger step = (length/(int)w); - - [super drawRect: aRect]; - - PSsetrgbcolor(1.0,0,0); // red - data = (float *)[soundData bytes]; - - if( length > 2 ) - { - - x1 = (data[0] * multiplier); - y1 = offset; - for(index = step; index < w; index+=step) - { - NSInteger i = (int)index; - float d = data[i]; - - // calc new position... - x2 = d * multiplier; - y2 = index + offset; - - PSmoveto(x1,y1); - PSlineto(x2,y2); - - // move to old vars... - x1 = x2; - y1 = y2; - } - } -} -*/ @end diff --git a/GormCore/Resources/ClassInformation.plist b/GormCore/Resources/ClassInformation.plist index 8c670922f..3c16e5355 100644 --- a/GormCore/Resources/ClassInformation.plist +++ b/GormCore/Resources/ClassInformation.plist @@ -257,6 +257,10 @@ NSMenu = {Actions = ("submenuAction:"); Super = NSObject; }; NSMenuItem = {Outlets = (target); Super = NSObject; }; NSMenuItemCell = {Super = NSButtonCell; }; + NSMovieView = { + Actions = ("copy:","clear:","cut:","gotoBeginning:","gotoEnd:","gotoPosterFrame:","paste:","start:","stepBack:","stepForward:","stop:","undo:"); + Super = NSView; + }; NSMutableArray = {Super = NSArray; }; NSMutableDictionary = {Super = NSDictionary; }; NSNumberFormatter = {Super = NSFormatter; }; diff --git a/InterfaceBuilder/IBInspectorMode.h b/InterfaceBuilder/IBInspectorMode.h index 287a97d3e..5645d7e6b 100644 --- a/InterfaceBuilder/IBInspectorMode.h +++ b/InterfaceBuilder/IBInspectorMode.h @@ -34,24 +34,36 @@ NSString *identifier; NSString *localizedLabel; NSString *inspectorClassName; - id object; - float ordering; + id object; + float ordering; } + - (id) initWithIdentifier: (NSString *)ident forObject: (id)obj localizedLabel: (NSString *)lab inspectorClassName: (NSString *)cn ordering: (float)ord; + - (void) setIdentifier: (NSString *)ident; + - (NSString *) identifier; + - (void) setObject: (id)obj; + - (id) object; + - (void) setLocalizedLabel: (NSString *)label; + - (NSString *) localizedLabel; + - (void) setInspectorClassName: (NSString *)className; + - (NSString *) inspectorClassName; + - (void) setOrdering: (float)ord; + - (float) ordering; + @end #endif diff --git a/InterfaceBuilder/IBObjectProtocol.h b/InterfaceBuilder/IBObjectProtocol.h index 859fd9999..df5729cba 100644 --- a/InterfaceBuilder/IBObjectProtocol.h +++ b/InterfaceBuilder/IBObjectProtocol.h @@ -27,6 +27,36 @@ #include +/** + * GNUstep additions to support layered inspectors. + */ +@interface NSObject (IBObjectProtocolAdditions) +/** + * Attributes inspector name + */ ++ (NSString *) inspectorClassName; + +/** + * Connections inspector name + */ ++ (NSString *) connectInspectorClassName; + +/** + * Help inspector name + */ ++ (NSString *) helpInspectorClassName; + +/** + * Size inspector name + */ ++ (NSString *) sizeInspectorClassName; + +/** + * Class inspector name + */ ++ (NSString *) classInspectorClassName; +@end + @protocol IBObjectProtocol /** * Returns YES, if receiver can be displayed in