OSDN Git Service

HMBrowserWindowControllerからFlash部分を切り離した
[kcd/KCD.git] / KCD / HMBroserWindowController.m
1 //
2 //  HMBroserWindowController.m
3 //  KCD
4 //
5 //  Created by Hori,Masaki on 2014/02/11.
6 //  Copyright (c) 2014年 Hori,Masaki. All rights reserved.
7 //
8
9 #import "HMBroserWindowController.h"
10
11 #import "HMAppDelegate.h"
12 #import "HMUserDefaults.h"
13 #import "HMDocksViewController.h"
14 #import "HMShipViewController.h"
15 #import "HMPowerUpSupportViewController.h"
16 #import "HMStrengthenListViewController.h"
17 #import "HMGameViewController.h"
18 #import "HMCombileViewController.h"
19 #import "HMCombinedCommand.h"
20 #import "HMFleetViewController.h"
21
22 #import "HMServerDataStore.h"
23
24 #import <JavaScriptCore/JavaScriptCore.h>
25
26
27
28 typedef NS_ENUM(NSInteger, ViewType) {
29         kScheduleType = 0,
30         kOrganizeType = 1,
31         kPowerUpType = 2,
32 };
33
34 typedef NS_ENUM(NSUInteger, FleetViewPosition) {
35         kAbove,
36         kBelow,
37         kDivided,
38         
39         kOldStyle = 0xffffffff,
40 };
41
42 static NSString *gamePageURL = @"http://www.dmm.com/netgame/social/-/gadgets/=/app_id=854854/";
43 static NSString *loginPageURLPrefix = @"https://www.dmm.com/my/-/login/=/";
44
45 @interface HMBroserWindowController ()
46 @property (strong) HMGameViewController *gameViewController;
47
48 @property (strong) NSNumber *flagShipID;
49
50 @property (strong) HMFleetViewController *fleetViewController;
51 @property FleetViewPosition fleetViewPosition;
52
53 @property (weak) IBOutlet NSTabView *informations;
54 @property (strong) HMDocksViewController *docksViewController;
55 @property (strong) HMShipViewController *shipViewController;
56 @property (strong) HMPowerUpSupportViewController *powerUpViewController;
57 @property (strong) HMStrengthenListViewController *strengthedListViewController;
58
59 @property (strong) HMCombileViewController *combinedViewController;
60 @property BOOL isCombinedMode;
61
62 @end
63
64 @implementation HMBroserWindowController
65 @synthesize fleetViewPosition = _fleetViewPosition;
66
67 + (NSSet *)keyPathsForValuesAffectingFlagShipName
68 {
69         return [NSSet setWithObject:@"flagShipID"];
70 }
71
72 + (NSSet *)keyPathsForValuesAffectingShipNumberColor
73 {
74         return [NSSet setWithObjects:@"maxChara", @"shipCount", @"minimumColoredShipCount", nil];
75 }
76
77 - (id)init
78 {
79         self = [super initWithWindowNibName:NSStringFromClass([self class])];
80         if(self) {
81                 [self loadWindow];
82         }
83         return self;
84 }
85
86 - (void)awakeFromNib
87 {
88         self.gameViewController = [HMGameViewController new];
89         [self.gameViewController.view setFrame:[self.placeholder frame]];
90         [self.gameViewController.view setFrameOrigin:NSZeroPoint];
91         [self.gameViewController.view setAutoresizingMask:[self.placeholder autoresizingMask]];
92         [self.placeholder addSubview:self.gameViewController.view];
93         
94         self.docksViewController = [HMDocksViewController new];
95         self.shipViewController = [HMShipViewController new];
96         self.powerUpViewController = [HMPowerUpSupportViewController new];
97         self.strengthedListViewController = [HMStrengthenListViewController new];
98         NSTabViewItem *item = [self.informations tabViewItemAtIndex:0];
99         item.view = self.docksViewController.view;
100         item = [self.informations tabViewItemAtIndex:1];
101         item.view = self.shipViewController.view;
102         item = [self.informations tabViewItemAtIndex:2];
103         item.view = self.powerUpViewController.view;
104         item = [self.informations tabViewItemAtIndex:3];
105         item.view = self.strengthedListViewController.view;
106         
107         _fleetViewController = [HMFleetViewController viewControlerWithViewType:detailViewType];
108         [self.fleetViewController.view setFrame:[self.deckPlaceholder frame]];
109         [self.fleetViewController.view setAutoresizingMask:[self.deckPlaceholder autoresizingMask]];
110         [[self.deckPlaceholder superview] replaceSubview:self.deckPlaceholder with:self.fleetViewController.view];
111         _fleetViewPosition = kBelow;
112         [self setFleetViewPosition:HMStandardDefaults.fleetViewPosition animation:NO];
113         self.fleetViewController.enableAnimation = NO;
114         self.fleetViewController.shipOrder = HMStandardDefaults.fleetViewShipOrder;
115         self.fleetViewController.enableAnimation = YES;
116         
117         [self bind:@"flagShipID" toObject:self.deckContoller withKeyPath:@"selection.ship_0" options:nil];
118         
119         [self bind:@"maxChara" toObject:self.basicController withKeyPath:@"selection.max_chara" options:nil];
120         [self bind:@"shipCount" toObject:self.shipController withKeyPath:@"arrangedObjects.@count" options:nil];
121         
122         
123         NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
124         [nc addObserver:self
125                    selector:@selector(didCangeCombined:)
126                            name:HMCombinedCommandCombinedDidCangeNotification
127                          object:nil];
128         
129         if(HMStandardDefaults.lastHasCombinedView) {
130                 [self showCombinedView];
131         }
132 }
133
134 - (void)windowWillClose:(id)notification
135 {
136         HMStandardDefaults.lastHasCombinedView = self.isCombinedMode;
137 }
138
139 - (NSManagedObjectContext *)managedObjectContext
140 {
141         return [HMServerDataStore defaultManager].managedObjectContext;
142 }
143
144 - (NSAttributedString *)linksString
145 {
146         NSBundle *main = [NSBundle mainBundle];
147         NSURL *url = [main URLForResource:@"Links" withExtension:@"rtf"];
148         NSAttributedString *linksString = [[NSAttributedString alloc] initWithURL:url documentAttributes:nil];
149         
150         return linksString;
151 }
152
153 - (void)showViewWithNumber:(ViewType)type
154 {
155         [self.informations selectTabViewItemAtIndex:type];
156 }
157
158 - (IBAction)reloadContent:(id)sender
159 {
160         [self.gameViewController reloadContent:sender];
161 }
162
163 - (IBAction)deleteCacheAndReload:(id)sender
164 {
165         [self.gameViewController deleteCacheAndReload:sender];
166 }
167
168 - (IBAction)clearQuestList:(id)sender
169 {
170         HMServerDataStore *store = [HMServerDataStore oneTimeEditor];
171         NSArray *objects = [store objectsWithEntityName:@"Quest"
172                                                                                   predicate:nil
173                                                                                           error:NULL];
174         NSManagedObjectContext *moc = store.managedObjectContext;
175         for(id object in objects) {
176                 [moc deleteObject:object];
177         }
178 }
179
180 - (NSString *)flagShipName
181 {
182         NSError *error = nil;
183         NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"Ship"];
184         NSPredicate *predicate = [NSPredicate predicateWithFormat:@"id = %@", self.flagShipID];
185         [request setPredicate:predicate];
186         NSArray *array = [self.managedObjectContext executeFetchRequest:request
187                                                                                                          error:&error];
188         if([array count] == 0) {
189                 return nil;
190         }
191         
192         id flagShipName = [array[0] valueForKeyPath:@"master_ship.name"];
193         if(!flagShipName || [flagShipName isKindOfClass:[NSNull class]]) {
194                 return nil;
195         }
196         
197         return flagShipName;
198 }
199
200 - (NSColor *)shipNumberColor
201 {
202         NSInteger max = self.maxChara.integerValue;
203         NSInteger current = self.shipCount.integerValue;
204         
205         if(current > max - self.minimumColoredShipCount) {
206                 return [NSColor orangeColor];
207         }
208         
209         return [NSColor controlTextColor];
210 }
211 - (void)setMinimumColoredShipCount:(NSInteger)minimumColoredShipCount
212 {
213         HMStandardDefaults.minimumColoredShipCount = minimumColoredShipCount;
214 }
215 - (NSInteger)minimumColoredShipCount
216 {
217         return HMStandardDefaults.minimumColoredShipCount;
218 }
219
220 - (IBAction)selectView:(id)sender
221 {
222         [self showViewWithNumber:[sender tag]];
223 }
224 - (IBAction)screenShot:(id)sender
225 {
226         [self.gameViewController screenShot:sender];
227 }
228
229 - (void)swipeWithEvent:(NSEvent *)event
230 {
231         if(!HMStandardDefaults.useSwipeChangeCombinedView) return;
232         
233         if([event deltaX] > 0) {
234                 [self showCombinedView];
235         }
236         if([event deltaX] < 0) {
237                 [self hideCombinedView];
238         }
239 }
240
241 #pragma mark - Combined view
242 - (IBAction)showHideCombinedView:(id)sender
243 {
244         if(self.isCombinedMode) {
245                 [self hideCombinedView];
246         } else {
247                 [self showCombinedView];
248         }
249 }
250 - (void)showCombinedView
251 {
252         if(self.isCombinedMode) return;
253         if(self.fleetViewPosition == kOldStyle) return;
254         
255         self.isCombinedMode = YES;
256         
257         if(!self.combinedViewController) {
258                 self.combinedViewController = [HMCombileViewController new];
259                 self.combinedViewController.view.hidden = YES;
260                 
261                 [self.combinedViewController.view setAutoresizingMask:[self.combinedViewPlaceholder autoresizingMask]];
262                 [[self.combinedViewPlaceholder superview] replaceSubview:self.combinedViewPlaceholder with:self.combinedViewController.view];
263         }
264         
265         NSRect winFrame = self.window.frame;
266         CGFloat incrementWidth = NSMaxX(self.combinedViewController.view.frame);
267         winFrame.size.width += incrementWidth;
268         winFrame.origin.x -= incrementWidth;
269         
270         self.combinedViewController.view.hidden = NO;
271         [self.window setFrame:winFrame display:YES animate:YES];
272 }
273 - (void)hideCombinedView
274 {
275         if(!self.isCombinedMode) return;
276         self.isCombinedMode = NO;
277         
278         NSRect winFrame = self.window.frame;
279         CGFloat incrementWidth = NSMaxX(self.combinedViewController.view.frame);
280         winFrame.size.width -= incrementWidth;
281         winFrame.origin.x += incrementWidth;
282         
283         [self.window setFrame:winFrame display:YES animate:YES];
284         self.combinedViewController.view.hidden = YES;
285 }
286
287 - (void)didCangeCombined:(id)notification
288 {
289         if(!HMStandardDefaults.autoCombinedView) return;
290         
291         NSDictionary *info = [notification userInfo];
292         NSNumber *typeValue = info[HMCombinedType];
293         CombineType type = typeValue.integerValue;
294         if(![NSThread isMainThread]) {
295                 [NSThread sleepForTimeInterval:0.1];
296         }
297         dispatch_async(dispatch_get_main_queue(),
298                                    ^{
299                                            switch(type) {
300                                                    case cancel:
301                                                            [self hideCombinedView];
302                                                            break;
303                                                    case maneuver:
304                                                    case water:
305                                                    case transportation:
306                                                            [self showCombinedView];
307                                                            break;
308                                                    default:
309                                                            NSLog(@"combined type is unknown type. %ld", type);
310                                                            [self showCombinedView];
311                                                            break;
312                                            }
313                                    });
314 }
315
316 #pragma mark - FleetView position
317 // ###############################
318 const CGFloat margin = 1;
319 const CGFloat flashTopMargin = 4;
320 // ###############################
321
322
323 - (void)changeFleetViewForFleetViewPositionIfNeeded:(FleetViewPosition)fleetViewPosition
324 {
325         if(self.fleetViewPosition == fleetViewPosition) return;
326         if(self.fleetViewPosition != kOldStyle && fleetViewPosition != kOldStyle) return;
327         
328         if(fleetViewPosition == kOldStyle && self.isCombinedMode) {
329                 [self hideCombinedView];
330         }
331         
332         HMFleetViewType type = fleetViewPosition == kOldStyle ? minimumViewType : detailViewType;
333         
334         HMFleetViewController *newController = [HMFleetViewController viewControlerWithViewType:type];
335         newController.enableAnimation = YES;
336         newController.shipOrder = self.fleetViewController.shipOrder;
337         
338         NSView *currentView = self.fleetViewController.view;
339         NSRect newFrame = newController.view.frame;
340         newFrame.origin = currentView.frame.origin;
341         newController.view.frame = newFrame;
342         newController.view.autoresizingMask = currentView.autoresizingMask;
343         [currentView.superview replaceSubview:currentView with:newController.view];
344         
345         self.fleetViewController = newController;
346 }
347
348 - (CGFloat)windowHeightForFleetViewPosition:(FleetViewPosition)fleetViewPosition
349 {
350         CGFloat windowContentHeight = [self.window.contentView frame].size.height;
351         
352         if(self.fleetViewPosition == fleetViewPosition) return windowContentHeight;
353         
354         if(self.fleetViewPosition == kOldStyle) {
355                 windowContentHeight += HMFleetViewController.heightDifference;
356         }
357         if(fleetViewPosition == kOldStyle) {
358                 windowContentHeight -= HMFleetViewController.heightDifference;
359         }
360         
361         return windowContentHeight;
362 }
363 - (NSRect)windowFrameForFleetViewPosition:(FleetViewPosition)fleetViewPosition
364 {
365         NSRect windowContentRect = [self.window frame];
366         
367         if(self.fleetViewPosition == fleetViewPosition) return windowContentRect;
368         
369         if(self.fleetViewPosition == kOldStyle) {
370                 windowContentRect.size.height += HMFleetViewController.heightDifference;
371                 windowContentRect.origin.y -= HMFleetViewController.heightDifference;
372         }
373         if(fleetViewPosition == kOldStyle) {
374                 windowContentRect.size.height -= HMFleetViewController.heightDifference;
375                 windowContentRect.origin.y += HMFleetViewController.heightDifference;
376         }
377         
378         return windowContentRect;
379 }
380
381 - (NSRect)flashFrameForFleetViewPosition:(FleetViewPosition)fleetViewPosition
382 {
383         CGFloat flashY;
384         
385         CGFloat windowContentHeight = [self windowHeightForFleetViewPosition:fleetViewPosition];
386         NSRect flashRect = self.placeholder.frame;
387         
388         switch(fleetViewPosition) {
389                 case kAbove:
390                         flashY = windowContentHeight - flashRect.size.height - self.fleetViewController.normalHeight;
391                         break;
392                 case kBelow:
393                         flashY = windowContentHeight - flashRect.size.height;
394                         break;
395                 case kDivided:
396                         flashY = windowContentHeight - flashRect.size.height - self.fleetViewController.upsideHeight - margin;
397                         break;
398                 case kOldStyle:
399                         flashY = windowContentHeight - flashRect.size.height - flashTopMargin;
400                         break;
401                 default:
402                         NSLog(@"%s: unknown position.", __PRETTY_FUNCTION__);
403                         return NSZeroRect;
404         }
405         
406         flashRect.origin.y = flashY;
407         return flashRect;
408 }
409
410 - (NSRect)fleetViewFrameForFleetViewPosition:(FleetViewPosition)fleetViewPosition
411 {
412         CGFloat fleetViewHeight;
413         CGFloat fleetViewY;
414         
415         CGFloat windowContentHeight = [self windowHeightForFleetViewPosition:fleetViewPosition];
416         NSRect flashRect = self.placeholder.frame;
417         NSRect fleetListRect = self.fleetViewController.view.frame;
418         
419         switch(fleetViewPosition) {
420                 case kAbove:
421                         fleetViewHeight = self.fleetViewController.normalHeight;
422                         fleetViewY = windowContentHeight - fleetViewHeight;
423                         break;
424                 case kBelow:
425                         fleetViewHeight = self.fleetViewController.normalHeight;
426                         fleetViewY = windowContentHeight - fleetViewHeight - flashRect.size.height - margin;
427                         break;
428                 case kDivided:
429                         fleetViewHeight = self.fleetViewController.normalHeight + flashRect.size.height + margin + margin;
430                         fleetViewY = windowContentHeight - fleetViewHeight;
431                         break;
432                 case kOldStyle:
433                         fleetViewHeight = HMFleetViewController.oldStyleFleetViewHeight;
434                         fleetViewY = windowContentHeight - fleetViewHeight - flashRect.size.height - margin - flashTopMargin;
435                         break;
436                 default:
437                         NSLog(@"%s: unknown position.", __PRETTY_FUNCTION__);
438                         return NSZeroRect;
439         }
440         
441         fleetListRect.size.height = fleetViewHeight;
442         fleetListRect.origin.y = fleetViewY;
443         return fleetListRect;
444 }
445
446 - (void)setFleetViewPosition:(FleetViewPosition)fleetViewPosition animation:(BOOL)flag
447 {
448         [self changeFleetViewForFleetViewPositionIfNeeded:fleetViewPosition];
449         
450         NSRect windowFrame = [self windowFrameForFleetViewPosition:fleetViewPosition];
451         NSRect flashRect = [self flashFrameForFleetViewPosition:fleetViewPosition];
452         NSRect fleetListRect = [self fleetViewFrameForFleetViewPosition:fleetViewPosition];
453         
454         _fleetViewPosition = fleetViewPosition;
455         HMStandardDefaults.fleetViewPosition = fleetViewPosition;
456         
457         if(flag) {
458                 NSDictionary *winAnime = @{
459                                                                    NSViewAnimationTargetKey : self.window,
460                                                                    NSViewAnimationEndFrameKey : [NSValue valueWithRect:windowFrame],
461                                                                    };
462                 NSDictionary *flashAnime = @{
463                                                    NSViewAnimationTargetKey : self.placeholder,
464                                                    NSViewAnimationEndFrameKey : [NSValue valueWithRect:flashRect],
465                                                    };
466                 NSDictionary *fleetAnime = @{
467                                                                  NSViewAnimationTargetKey : self.fleetViewController.view,
468                                                                  NSViewAnimationEndFrameKey : [NSValue valueWithRect:fleetListRect],
469                                                                  };
470                 NSAnimation *anime = [[NSViewAnimation alloc] initWithViewAnimations:@[winAnime, flashAnime, fleetAnime]];
471                 [anime startAnimation];
472         } else {
473                 [self.window setFrame:windowFrame display:NO];
474                 self.placeholder.frame = flashRect;
475                 self.fleetViewController.view.frame = fleetListRect;
476         }
477 }
478
479 - (void)setFleetViewPosition:(FleetViewPosition)fleetViewPosition
480 {
481         [self setFleetViewPosition:fleetViewPosition animation:YES];
482 }
483 - (FleetViewPosition)fleetViewPosition
484 {
485         return _fleetViewPosition;
486 }
487 - (IBAction)fleetListAbove:(id)sender
488 {
489         self.fleetViewPosition = kAbove;
490 }
491 - (IBAction)fleetListBelow:(id)sender
492 {
493         self.fleetViewPosition = kBelow;
494 }
495 - (IBAction)fleetListDivide:(id)sender
496 {
497         self.fleetViewPosition = kDivided;
498 }
499 - (IBAction)fleetListSimple:(id)sender
500 {
501         self.fleetViewPosition = kOldStyle;
502 }
503
504 - (IBAction)reorderToDoubleLine:(id)sender
505 {
506         self.fleetViewController.shipOrder = doubleLine;
507         HMStandardDefaults.fleetViewShipOrder = doubleLine;
508 }
509 - (IBAction)reorderToLeftToRight:(id)sender
510 {
511         self.fleetViewController.shipOrder = leftToRight;
512         HMStandardDefaults.fleetViewShipOrder = leftToRight;
513 }
514
515 - (IBAction)selectNextFleet:(id)sender
516 {
517         [_fleetViewController selectNextFleet:sender];
518 }
519 - (IBAction)selectPreviousFleet:(id)sender
520 {
521         [_fleetViewController selectPreviousFleet:sender];
522 }
523
524
525 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
526 {
527         SEL action = menuItem.action;
528         
529         if(action == @selector(reloadContent:) && action == @selector(screenShot:) && action == @selector(deleteCacheAndReload:)) {
530                 return [self.gameViewController validateMenuItem:menuItem];
531         }
532         if(action == @selector(selectView:)) {
533                 return YES;
534         }
535         if(action == @selector(selectNextFleet:) || action == @selector(selectPreviousFleet:)) {
536                 return YES;
537         }
538         
539         if(action == @selector(fleetListAbove:)) {
540                 if(self.fleetViewPosition == kAbove) {
541                         menuItem.state = NSOnState;
542                 } else {
543                         menuItem.state = NSOffState;
544                 }
545                 return YES;
546         }
547         if(action == @selector(fleetListBelow:)) {
548                 if(self.fleetViewPosition == kBelow) {
549                         menuItem.state = NSOnState;
550                 } else {
551                         menuItem.state = NSOffState;
552                 }
553                 return YES;
554         }
555         if(action == @selector(fleetListDivide:)) {
556                 if(self.fleetViewPosition == kDivided) {
557                         menuItem.state = NSOnState;
558                 } else {
559                         menuItem.state = NSOffState;
560                 }
561                 return YES;
562         }
563         if(action == @selector(fleetListSimple:)) {
564                 if(self.fleetViewPosition == kOldStyle) {
565                         menuItem.state = NSOnState;
566                 } else {
567                         menuItem.state = NSOffState;
568                 }
569                 return YES;
570         }
571         
572         if(action == @selector(reorderToDoubleLine:)) {
573                 if(self.fleetViewController.shipOrder == doubleLine) {
574                         menuItem.state = NSOnState;
575                 } else {
576                         menuItem.state = NSOffState;
577                 }
578                 return YES;
579         }
580         if(action == @selector(reorderToLeftToRight:)) {
581                 if(self.fleetViewController.shipOrder == leftToRight) {
582                         menuItem.state = NSOnState;
583                 } else {
584                         menuItem.state = NSOffState;
585                 }
586                 return YES;
587         }
588         if(action == @selector(clearQuestList:)) {
589                 return YES;
590         }
591         if(action == @selector(showHideCombinedView:)) {
592                 if(self.isCombinedMode) {
593                         menuItem.title = NSLocalizedString(@"Hide Combined View", @"View menu, hide combined view");
594                 } else {
595                         menuItem.title = NSLocalizedString(@"Show Combined View", @"View menu, show combined view");
596                 }
597                 if(self.fleetViewPosition == kOldStyle) return NO;
598                 return YES;
599         }
600         
601         return NO;
602 }
603
604 @end