BrowserWindowController.mm
上传用户:center1979
上传日期:2022-07-26
资源大小:50633k
文件大小:13k
源码类别:

OpenGL

开发平台:

Visual C++

  1. //
  2. //  BrowserWindowController.mm
  3. //  celestia
  4. //
  5. //  Created by Hank Ramsey on Tue Dec 28 2004.
  6. //  Copyright (c) 2002 Chris Laurel. All rights reserved.
  7. //  Modifications Copyright (c) 2004 Hank Ramsey. All rights reserved.
  8. //
  9. #import "BrowserWindowController.h"
  10. #import "BrowserItem.h"
  11. #import "NSString_ObjCPlusPlus.h"
  12. #import "CelestiaAppCore.h"
  13. #import "CelestiaStar_PrivateAPI.h"
  14. #import "CelestiaBody_PrivateAPI.h"
  15. #import "CelestiaDSO.h"
  16. #import "CelestiaLocation.h"
  17. #include "celestiacore.h"
  18. #include "celestia.h"
  19. #include "selection.h"
  20. #include "starbrowser.h"
  21. #define BROWSER_MAX_DSO_COUNT   300
  22. #define BROWSER_MAX_STAR_COUNT  100
  23. @interface BrowserWindowController(Private)
  24. - (NSDictionary *) deepSkyObjects;
  25. - (NSDictionary *) starsOfKind: (int) kind;
  26. - (BrowserItem *) sol;
  27. @end
  28. @implementation BrowserWindowController
  29. static NSDictionary *rootItems;
  30. static CelestiaCore *appCore;
  31. - (id) init
  32. {
  33.     self = [super initWithWindowNibName: @"BrowserWindow" ];
  34.     if (self)
  35.     {
  36.         appCore = (CelestiaCore*) [[CelestiaAppCore sharedAppCore] appCore];
  37.         rootId = @"solarSystem";
  38.     }
  39.     return self;
  40. }
  41. - (void) windowDidLoad
  42. {
  43.     if ([self window]==nil) NSLog(@"loaded browser window is nil");
  44. }
  45. //--------------------------------------------------------------
  46. - (NSDictionary *) deepSkyObjects
  47. {
  48.     int objCount;
  49.     int i = 0;
  50.     NSMutableDictionary *countPerType;
  51.     NSMutableDictionary *result;
  52.     NSMutableDictionary *tempDict;
  53.     NSDictionary *typeMap;
  54.     NSMutableDictionary *group;
  55.     DSODatabase* catalog = appCore->getSimulation()->getUniverse()->getDSOCatalog();
  56.     DeepSkyObject *obj;
  57.     CelestiaDSO *dsoWrapper;
  58.     NSString *name;
  59.     NSString *type;
  60.     objCount = catalog->size();
  61.     typeMap = [[NSDictionary alloc] initWithObjectsAndKeys:
  62.         NSLocalizedString(@"Galaxies (Barred Spiral)",@""), @"SB",
  63.         NSLocalizedString(@"Galaxies (Spiral)",@""),        @"S",
  64.         NSLocalizedString(@"Galaxies (Elliptical)",@""),    @"E",
  65.         NSLocalizedString(@"Galaxies (Irregular)",@""),     @"Irr",
  66.         NSLocalizedString(@"Nebulae",@""),                  @"Neb",
  67.         NSLocalizedStringFromTable(@"Globulars",@"po",@""), @"Glob",
  68.         NSLocalizedString(@"Open Clusters",@""),            @"Clust",
  69.         NSLocalizedString(@"Unknown",@""),                  @"Unknown",
  70.         nil];
  71.     tempDict = [NSMutableDictionary dictionaryWithObjectsAndKeys:
  72.         [NSMutableDictionary dictionary], @"SB",
  73.         [NSMutableDictionary dictionary], @"S",
  74.         [NSMutableDictionary dictionary], @"E",
  75.         [NSMutableDictionary dictionary], @"Irr",
  76.         [NSMutableDictionary dictionary], @"Neb",
  77.         [NSMutableDictionary dictionary], @"Glob",
  78.         [NSMutableDictionary dictionary], @"Clust",
  79.         [NSMutableDictionary dictionary], @"Unknown",
  80.         nil];
  81.     countPerType = [NSMutableDictionary dictionaryWithCapacity: [tempDict count]];
  82.     result = [NSMutableDictionary dictionaryWithCapacity: [tempDict count]];
  83.     for (; i < objCount; ++i)
  84.     {
  85.         obj = catalog->getDSO(i);
  86.         if (obj)
  87.         {
  88.             dsoWrapper = [[[CelestiaDSO alloc] initWithDSO: obj] autorelease];
  89.             type = [dsoWrapper type];
  90.             NSNumber *typeCount = [countPerType objectForKey: type];
  91.             if (nil == typeCount)
  92.             {
  93.                 typeCount = [NSNumber numberWithInt: 0];
  94.             }
  95.             if ([typeCount intValue] == BROWSER_MAX_DSO_COUNT) continue;
  96.             [countPerType setObject:[NSNumber numberWithInt:([typeCount intValue]+1)] forKey:type];
  97.             if ([type hasPrefix: @"SB"])
  98.                 group = [tempDict objectForKey: @"SB"];
  99.             else if ([type hasPrefix: @"S"])
  100.                 group = [tempDict objectForKey: @"S"];
  101.             else if ([type hasPrefix: @"E"])
  102.                 group = [tempDict objectForKey: @"E"];
  103.             else if ([type hasPrefix: @"Irr"])
  104.                 group = [tempDict objectForKey: @"Irr"];
  105.             else if ([type hasPrefix: @"Neb"])
  106.                 group = [tempDict objectForKey: @"Neb"];
  107.             else if ([type hasPrefix: @"Clust"])
  108.                 group = [tempDict objectForKey: @"Clust"];
  109.             else if ([type hasPrefix: @"Glob"])
  110.                 group = [tempDict objectForKey: @"Glob"];
  111.             else
  112.                 group = [tempDict objectForKey: @"Unknown"];
  113.             name = [NSString stringWithStdString: catalog->getDSOName(obj)];
  114.             [group setObject: [[[BrowserItem alloc] initWithCelestiaDSO: dsoWrapper] autorelease]
  115.                       forKey: name];
  116.         }
  117.     }
  118.     NSEnumerator *tempEnum = [tempDict keyEnumerator];
  119.     while ((type = [tempEnum nextObject]))
  120.     {
  121.         if ([[tempDict objectForKey: type] count] > 0)
  122.         {
  123.             [result setObject: [[[BrowserItem alloc] initWithName: [typeMap objectForKey: type] children: [tempDict objectForKey: type]] autorelease]
  124.                        forKey: [typeMap objectForKey: type]];
  125.         }
  126.     }
  127.     [typeMap release];
  128.     return result;       
  129. }
  130. - (BrowserItem *) sol
  131. {
  132.     Selection sol = appCore->getSimulation()->getUniverse()->find("Sol");
  133.     return [[[BrowserItem alloc] initWithCelestiaStar: [[[CelestiaStar alloc] initWithStar: sol.star()] autorelease]] autorelease];
  134. }
  135. - (NSDictionary *) starsOfKind: (int) kind
  136. {
  137.     std::vector<const Star*>* nearStars;
  138.     int starCount = 0;
  139.     Simulation *sim = appCore->getSimulation();
  140.     StarBrowser* sb = new StarBrowser(sim,kind);
  141.     nearStars = sb->listStars( BROWSER_MAX_STAR_COUNT );
  142.     if (nearStars == nil ) return [NSDictionary dictionary];
  143.     starCount = nearStars->size();            
  144.     NSMutableDictionary* starDict = [NSMutableDictionary dictionaryWithCapacity: starCount+2];
  145.     const Star *aStar;
  146.     NSString *starName;
  147.     int i;
  148.     for (i=0;i<starCount;i++)
  149.     {
  150.         aStar = (*nearStars)[i];
  151.         starName = [NSString  stringWithStdString: sim->getUniverse()->getStarCatalog()->getStarName(*aStar) ];
  152.         [starDict setObject:
  153.             [[[BrowserItem alloc] initWithCelestiaStar: [[[CelestiaStar alloc] initWithStar: aStar] autorelease]] autorelease]
  154.                      forKey: starName];
  155.     }
  156.     delete sb;
  157.     delete nearStars;
  158.     return starDict;
  159. }
  160. -(BrowserItem *) root
  161. {
  162.     if (rootItems) return [rootItems objectForKey: rootId];
  163.     BrowserItem *sol;
  164.     BrowserItem *stars;
  165.     BrowserItem *dsos;
  166.     sol = [self sol];
  167.     [BrowserItem addChildrenToStar: sol];
  168.     stars = [[BrowserItem alloc] initWithName: @""];
  169.     [stars addChild: [[[BrowserItem alloc] initWithName:
  170.         NSLocalizedString(@"Nearest Stars",@"")      children:
  171.         [self starsOfKind: StarBrowser::NearestStars]] autorelease]];
  172.     [stars addChild: [[[BrowserItem alloc] initWithName:
  173.         NSLocalizedString(@"Brightest Stars",@"")    children:
  174.         [self starsOfKind: StarBrowser::BrighterStars]] autorelease]];
  175.     [stars addChild: [[[BrowserItem alloc] initWithName:
  176.         NSLocalizedString(@"Stars With Planets",@"") children:
  177.         [self starsOfKind: StarBrowser::StarsWithPlanets]] autorelease]];
  178.     dsos = [[BrowserItem alloc] initWithName: @"" children: [self deepSkyObjects]];
  179.     rootItems = [[NSDictionary alloc] initWithObjectsAndKeys:
  180.         sol,   @"solarSystem",
  181.         stars, @"star",
  182.         dsos,  @"dso",
  183.         nil];
  184.     [stars release];
  185.     [dsos  release];
  186.     return [rootItems objectForKey: rootId];
  187. }
  188. - (BrowserItem *) itemForPathArray: (NSArray*) pathNames
  189. {
  190.     BrowserItem *lastItem = [self root];
  191.     BrowserItem *nextItem = lastItem;
  192.     NSString *lastKey = nil;
  193.     id body;
  194.     unsigned i;
  195.     for (i=1;i<[pathNames count];i++)
  196.     {
  197.         lastKey = [pathNames objectAtIndex: i];
  198.         nextItem = [lastItem childNamed: lastKey];
  199.         if (nil==nextItem) break;
  200.         lastItem = nextItem;
  201.     }
  202.     if (nextItem)
  203.     {
  204.         body = [nextItem body];
  205.         if (body)
  206.         {
  207.             if      ([body respondsToSelector: @selector(star)])
  208.                 [BrowserItem addChildrenToStar: nextItem];
  209.             else if ([body respondsToSelector: @selector(body)])
  210.                 [BrowserItem addChildrenToBody: nextItem];
  211.         }
  212.     }
  213.     
  214.     return lastItem;
  215. }
  216. - (Selection *) selFromPathArray: (NSArray*) pathNames
  217. {
  218.     Selection *sel = NULL;
  219.     BrowserItem *item = [self itemForPathArray: pathNames];
  220.     id body = [item body];
  221.     if (body)
  222.     {
  223.         if ([body respondsToSelector: @selector(star)])
  224.             sel = new Selection([(CelestiaStar *)body star]);
  225.         else if ([body respondsToSelector: @selector(body)])
  226.             sel = new Selection([(CelestiaBody *)body body]);
  227.         else if ([body respondsToSelector: @selector(DSO)])
  228.             sel = new Selection([(CelestiaDSO *)body DSO]);
  229.         else if ([body respondsToSelector: @selector(location)])
  230.             sel = new Selection([(CelestiaLocation *)body location]);
  231.     }
  232.     return sel;
  233. }
  234. - (int) browser: (NSBrowser*) sender numberOfRowsInColumn: (int) column
  235. {
  236.     if (browser != sender)
  237.     {
  238.         browser = sender;
  239. //        if ([browser respondsToSelector:@selector(setColumnResizingType:)])
  240. //            [browser setColumnResizingType: 2];
  241. //        [browser setMinColumnWidth: 80];
  242.         [browser setDoubleAction:@selector(doubleClick:)];
  243.     }
  244.     BrowserItem *itemForColumn = [self itemForPathArray: [[sender pathToColumn: column ] componentsSeparatedByString: [sender pathSeparator] ] ];
  245.     return [itemForColumn childCount];
  246. }
  247. - (BOOL) isLeaf: (BrowserItem *) aItem
  248. {
  249.     if ([aItem childCount] > 0) return NO;
  250.     id body = [aItem body];
  251.     if (body)
  252.     {
  253.         if      ([body respondsToSelector: @selector(star)])
  254.         {
  255.             if (appCore->getSimulation()->getUniverse()->getSolarSystem([(CelestiaStar *)body star]))
  256.                 return NO;
  257.         }
  258.         else if ([body respondsToSelector: @selector(body)])
  259.         {
  260.             if ([(CelestiaBody *)body body]->getSatellites() || [(CelestiaBody *)body body]->getLocations())
  261.                 return NO;
  262.         }
  263.     }
  264.     return YES;
  265. }
  266. - (void) browser: (NSBrowser*) sender willDisplayCell: (id) cell atRow: (int) row column: (int) column
  267. {
  268.     BrowserItem *itemForColumn = [self itemForPathArray: [[sender pathToColumn: column ] componentsSeparatedByString: [sender pathSeparator] ] ];
  269.     NSArray* colKeys = [itemForColumn allChildNames];
  270.     BOOL isLeaf = YES;
  271.     NSString* itemName = [colKeys objectAtIndex: row];
  272.     if (!itemName)
  273.         itemName = @"????";
  274.     else
  275.         isLeaf = [self isLeaf: [itemForColumn childNamed: itemName ]];
  276.     NSRange rightParenRange = {NSNotFound, 0};
  277.     NSRange leftParenRange  = {NSNotFound, 0};
  278.     NSRange parenRange      = {NSNotFound, 0};
  279.     if (isLeaf)
  280.     {
  281.         rightParenRange = [itemName rangeOfString:@")"
  282.                                           options:NSBackwardsSearch];
  283.         if (rightParenRange.length == 1)
  284.         {
  285.             leftParenRange = NSMakeRange(0, rightParenRange.location - 1);
  286.             parenRange = [itemName rangeOfString:@"("
  287.                                          options:NSBackwardsSearch
  288.                                            range:leftParenRange];
  289.             if (parenRange.length == 1)
  290.             {
  291.                 parenRange.length = rightParenRange.location - parenRange.location + 1;
  292.             }
  293.         }
  294.     }
  295.     if (parenRange.location != NSNotFound)
  296.     {
  297.         NSDictionary *parenAttr = [NSDictionary dictionaryWithObjectsAndKeys:
  298.             [NSColor grayColor], NSForegroundColorAttributeName,
  299.             nil];
  300.         NSMutableAttributedString *attrStr = [[[NSMutableAttributedString alloc] initWithString: itemName] autorelease];
  301.         [attrStr setAttributes:parenAttr range:parenRange];
  302.         [cell setAttributedStringValue:attrStr];
  303.     }
  304.     else
  305.     {
  306.         [cell setTitle: itemName ];
  307.     }
  308.     [cell setLeaf: isLeaf];
  309. }
  310. - (IBAction) go: (id) sender
  311. {
  312.     Selection *sel = [self selFromPathArray: [[browser path] componentsSeparatedByString: [browser pathSeparator] ]];
  313.     if (sel)
  314.     {
  315.         appCore->getSimulation()->setSelection(*sel);
  316.         if ([sender tag]!=0) appCore->charEntered([sender tag]);
  317.         delete sel;
  318.     }
  319. }
  320. - (void) doubleClick: (id) sender
  321. {
  322.     browser = sender;
  323.     NSArray *pathArray = [[browser path] componentsSeparatedByString: [browser pathSeparator]];
  324.     Selection *sel = [self selFromPathArray: pathArray];
  325.     if (sel)
  326.     {
  327.         appCore->getSimulation()->setSelection(*sel);
  328.         appCore->charEntered('g');
  329.         delete sel;
  330.     }
  331. }
  332. - (void)tabView: (NSTabView *)aTabView didSelectTabViewItem: (NSTabViewItem *)aTabViewItem
  333. {
  334.     rootId = [aTabViewItem identifier];
  335. }
  336. - (void)windowDidBecomeKey:(NSNotification *)aNotification
  337. {
  338.     if ([aNotification object] == [self window])
  339.     {
  340.         NSTabViewItem *curTab = [tabView selectedTabViewItem];
  341.         if (nil == curTab) return;
  342.         rootId = [curTab identifier];
  343.         if (browser && [rootId isEqualToString: @"star"])
  344.         {
  345.             BrowserItem *rootItem = [self root];
  346.             [rootItem addChild: [[[BrowserItem alloc] initWithName:
  347.                 NSLocalizedString(@"Nearest Stars",@"")   children:
  348.                 [self starsOfKind: StarBrowser::NearestStars]] autorelease]];
  349.             // Immediately synch browser display with reloaded star list,
  350.             // but only if star list is showing
  351.             NSArray *selection = [[browser path] componentsSeparatedByString: [browser pathSeparator]];
  352.             if ([selection count]>1 && [[selection objectAtIndex: 1] isEqualToString: NSLocalizedString(@"Nearest Stars",@"")])
  353.             {
  354.                 for (int i=1; i<[browser numberOfVisibleColumns]; ++i)
  355.                     [browser reloadColumn: i];
  356.             }
  357.         }
  358.     }
  359. }
  360. @end