From: glenlow Date: Mon, 11 Feb 2008 12:34:07 +0000 (+0000) Subject: Mac tweak panel for graph, default node and default edge attributes; objects are... X-Git-Tag: LAST_LIBGRAPH~32^2~4738 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7f64609f2ef16084206fb0794a71aba6bb5a1710;p=graphviz Mac tweak panel for graph, default node and default edge attributes; objects are graph-centric instead of context-centric --- diff --git a/macosx/GVGraphDefaultAttributes.h b/macosx/GVGraphDefaultAttributes.h new file mode 100644 index 000000000..ef040d2cc --- /dev/null +++ b/macosx/GVGraphDefaultAttributes.h @@ -0,0 +1,44 @@ +/* $Id$ $Revision$ */ +/* vim:set shiftwidth=4 ts=8: */ + +/********************************************************** +* This software is part of the graphviz package * +* http://www.graphviz.org/ * +* * +* Copyright (c) 1994-2008 AT&T Corp. * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Corp. * +* * +* Information and Software Systems Research * +* AT&T Research, Florham Park NJ * +**********************************************************/ + +#import + +#include +#include + +@class GVGraph; + +@interface GVGraphDefaultAttributes : NSMutableDictionary +{ + GVGraph *_graph; + Agdict_t *_defaultAttributes; + Agsym_t *(*_attributeDeclaration)(Agraph_t *, char *, char *); +} + +@property(readonly) NSString *name; + +- (id)initWithGraph:(GVGraph *)graph defaultAttributes:(Agdict_t *)defaultAttributes attributeDeclaration:(Agsym_t *(*)(Agraph_t *, char *, char *))attributeDeclaration; + +/* dictionary primitive methods */ +- (NSUInteger)count; +- (NSEnumerator *)keyEnumerator; +- (id)objectForKey:(id)aKey; + +/* mutable dictionary primitive methods */ +- (void)setObject:(id)anObject forKey:(id)aKey; +- (void)removeObjectForKey:(id)aKey; + +@end diff --git a/macosx/GVGraphDefaultAttributes.m b/macosx/GVGraphDefaultAttributes.m new file mode 100644 index 000000000..ed4bf7980 --- /dev/null +++ b/macosx/GVGraphDefaultAttributes.m @@ -0,0 +1,120 @@ +/* $Id$ $Revision$ */ +/* vim:set shiftwidth=4 ts=8: */ + +/********************************************************** +* This software is part of the graphviz package * +* http://www.graphviz.org/ * +* * +* Copyright (c) 1994-2008 AT&T Corp. * +* and is licensed under the * +* Common Public License, Version 1.0 * +* by AT&T Corp. * +* * +* Information and Software Systems Research * +* AT&T Research, Florham Park NJ * +**********************************************************/ + +#import "GVGraphDefaultAttributes.h" +#import "GVGraph.h" + +@interface GVGraphDefaultAttributeKeyEnumerator : NSEnumerator +{ + Agsym_t **_nextSymbol; + Agsym_t **_lastSymbol; +} + +- (id)initWithSymbols:(Agsym_t **)symbols count:(NSUInteger)count; +- (NSArray *)allObjects; +- (id)nextObject; + +@end + +@implementation GVGraphDefaultAttributeKeyEnumerator + +- (id)initWithSymbols:(Agsym_t **)symbols count:(NSUInteger)count +{ + if (self = [super init]) { + _nextSymbol = symbols; + _lastSymbol = symbols + count; + } + return self; +} + +- (NSArray *)allObjects +{ + NSMutableArray* all = [NSMutableArray array]; + for (; _nextSymbol < _lastSymbol; ++_nextSymbol) + if ((*_nextSymbol)->value && *(*_nextSymbol)->value) + [all addObject:[NSString stringWithUTF8String:(*_nextSymbol)->name]]; + + return all; +} + +- (id)nextObject +{ + char* nextName = NULL; + for (; _nextSymbol < _lastSymbol && !nextName; ++_nextSymbol) + if ((*_nextSymbol)->value && *(*_nextSymbol)->value) + nextName = (*_nextSymbol)->name; + + return nextName ? [NSString stringWithUTF8String:nextName] : nil; +} + +@end + +@implementation GVGraphDefaultAttributes + +- (id)initWithGraph:(GVGraph *)graph defaultAttributes:(Agdict_t *)defaultAttributes attributeDeclaration:(Agsym_t *(*)(Agraph_t *, char *, char *))attributeDeclaration +{ + if (self = [super init]) { + _graph = graph; /* not retained to avoid a retain cycle */ + _defaultAttributes = defaultAttributes; + _attributeDeclaration = attributeDeclaration; + } + return self; +} + +- (NSString*)name +{ + return _defaultAttributes->name ? [NSString stringWithUTF8String:_defaultAttributes->name] : nil; +} + +- (NSUInteger)count +{ + NSUInteger symbolCount = 0; + Agsym_t **nextSymbol, **lastSymbol; + for (nextSymbol = _defaultAttributes->list, lastSymbol = _defaultAttributes->list + dtsize(_defaultAttributes->dict); nextSymbol < lastSymbol; ++nextSymbol) + if ((*nextSymbol)->value && *(*nextSymbol)->value) + ++symbolCount; + return symbolCount; +} + +- (NSEnumerator *)keyEnumerator +{ + return [[[GVGraphDefaultAttributeKeyEnumerator alloc] initWithSymbols: _defaultAttributes->list count:dtsize(_defaultAttributes->dict)] autorelease]; +} + +- (id)objectForKey:(id)aKey +{ + id object = nil; + Agsym_t *attributeSymbol = dtmatch(_defaultAttributes->dict, [aKey UTF8String]); + if (attributeSymbol) { + char *attributeValue = attributeSymbol->value; + if (attributeValue && *attributeValue) + object = [NSString stringWithUTF8String:attributeSymbol->value]; + } + return object; +} + +- (void)setObject:(id)anObject forKey:(id)aKey +{ + _attributeDeclaration([_graph graph], (char *)[aKey UTF8String], (char *)[anObject UTF8String]); + [_graph noteChanged:YES]; +} + +- (void)removeObjectForKey:(id)aKey +{ + _attributeDeclaration([_graph graph], (char *)[aKey UTF8String], ""); + [_graph noteChanged:YES]; +} +@end diff --git a/macosx/GVWindowController.h b/macosx/GVWindowController.h index 480b9316c..48c7b8bc0 100644 --- a/macosx/GVWindowController.h +++ b/macosx/GVWindowController.h @@ -18,11 +18,22 @@ #import #import +@class GVGraph; + @interface GVWindowController : NSWindowController { IBOutlet PDFView *documentView; + + GVGraph *_graph; } -- (void)windowDidLoad; +@property(readonly) GVGraph *graph; + +- (id)init; +- (void)setDocument: (NSDocument *)document; +- (void)awakeFromNib; + +- (void)graphDidChange:(NSNotification*)notification; +- (void)dealloc; @end diff --git a/macosx/GVWindowController.m b/macosx/GVWindowController.m index 04905f8a2..04f3385aa 100644 --- a/macosx/GVWindowController.m +++ b/macosx/GVWindowController.m @@ -15,20 +15,61 @@ **********************************************************/ #import "GVWindowController.h" -#import "GVContext.h" +#import "GVGraph.h" #import "GVDocument.h" @implementation GVWindowController -- (void)windowDidLoad +@synthesize graph = _graph; + +- (id)init +{ + if (self = [super initWithWindowNibName: @"Document"]) + _graph = nil; + return self; +} + +- (void)setDocument: (NSDocument *)document { - GVDocument *graphDocument = [self document]; - if ([graphDocument respondsToSelector:@selector(graph)]) { - graph_t *graph = [graphDocument graph]; - GVContext* context = [GVContext sharedContext]; - [context layoutGraph:graph withEngine:@"dot"]; - [documentView setDocument:[[[PDFDocument alloc] initWithData:[context renderGraph:graph withFormat:@"pdf:quartz"]] autorelease]]; + if ([document respondsToSelector:@selector(graph)]) { + GVGraph *newGraph = [(GVDocument *)document graph]; + if (_graph != newGraph) { + /* retain the new document graph and start observing any changes from it */ + NSNotificationCenter* defaultCenter = [NSNotificationCenter defaultCenter]; + if (_graph) { + [defaultCenter removeObserver:self name:@"GVGraphDidChange" object:_graph]; + [_graph release]; + } + _graph = nil; + if (newGraph) { + _graph = [newGraph retain]; + [defaultCenter addObserver:self selector:@selector(graphDidChange:) name:@"GVGraphDidChange" object:newGraph]; + } + } } + + [super setDocument:document]; +} + +- (void)awakeFromNib +{ + [self graphDidChange:nil]; +} + +- (void)graphDidChange:(NSNotification*)notification +{ + /* whenever the graph changes, rerender its PDF and display that */ + [documentView setDocument:[[[PDFDocument alloc] initWithData:[_graph renderWithFormat:@"pdf:quartz"]] autorelease]]; +} + +- (void)dealloc +{ + if (_graph) { + [[NSNotificationCenter defaultCenter] removeObserver:self name:@"GVGraphDidChange" object:_graph]; + [_graph release]; + } + + [super dealloc]; } @end