2 // HMBroserWindowController.m
5 // Created by Hori,Masaki on 2014/02/11.
6 // Copyright (c) 2014年 Hori,Masaki. All rights reserved.
9 #import "HMBroserWindowController.h"
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"
22 #import "HMServerDataStore.h"
24 #import <JavaScriptCore/JavaScriptCore.h>
28 typedef NS_ENUM(NSInteger, ViewType) {
34 typedef NS_ENUM(NSUInteger, FleetViewPosition) {
39 kOldStyle = 0xffffffff,
42 static NSString *gamePageURL = @"http://www.dmm.com/netgame/social/-/gadgets/=/app_id=854854/";
43 static NSString *loginPageURLPrefix = @"https://www.dmm.com/my/-/login/=/";
45 @interface HMBroserWindowController ()
46 @property (strong) HMGameViewController *gameViewController;
48 @property (strong) NSNumber *flagShipID;
50 @property (strong) HMFleetViewController *fleetViewController;
51 @property FleetViewPosition fleetViewPosition;
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;
59 @property (strong) HMCombileViewController *combinedViewController;
60 @property BOOL isCombinedMode;
64 @implementation HMBroserWindowController
65 @synthesize fleetViewPosition = _fleetViewPosition;
67 + (NSSet *)keyPathsForValuesAffectingFlagShipName
69 return [NSSet setWithObject:@"flagShipID"];
72 + (NSSet *)keyPathsForValuesAffectingShipNumberColor
74 return [NSSet setWithObjects:@"maxChara", @"shipCount", @"minimumColoredShipCount", nil];
79 self = [super initWithWindowNibName:NSStringFromClass([self class])];
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];
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;
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;
117 [self bind:@"flagShipID" toObject:self.deckContoller withKeyPath:@"selection.ship_0" options:nil];
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];
123 NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
125 selector:@selector(didCangeCombined:)
126 name:HMCombinedCommandCombinedDidCangeNotification
129 if(HMStandardDefaults.lastHasCombinedView) {
130 [self showCombinedView];
134 - (void)windowWillClose:(id)notification
136 HMStandardDefaults.lastHasCombinedView = self.isCombinedMode;
139 - (NSManagedObjectContext *)managedObjectContext
141 return [HMServerDataStore defaultManager].managedObjectContext;
144 - (NSAttributedString *)linksString
146 NSBundle *main = [NSBundle mainBundle];
147 NSURL *url = [main URLForResource:@"Links" withExtension:@"rtf"];
148 NSAttributedString *linksString = [[NSAttributedString alloc] initWithURL:url documentAttributes:nil];
153 - (void)showViewWithNumber:(ViewType)type
155 [self.informations selectTabViewItemAtIndex:type];
158 - (IBAction)reloadContent:(id)sender
160 [self.gameViewController reloadContent:sender];
163 - (IBAction)deleteCacheAndReload:(id)sender
165 [self.gameViewController deleteCacheAndReload:sender];
168 - (IBAction)clearQuestList:(id)sender
170 HMServerDataStore *store = [HMServerDataStore oneTimeEditor];
171 NSArray *objects = [store objectsWithEntityName:@"Quest"
174 NSManagedObjectContext *moc = store.managedObjectContext;
175 for(id object in objects) {
176 [moc deleteObject:object];
180 - (NSString *)flagShipName
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
188 if([array count] == 0) {
192 id flagShipName = [array[0] valueForKeyPath:@"master_ship.name"];
193 if(!flagShipName || [flagShipName isKindOfClass:[NSNull class]]) {
200 - (NSColor *)shipNumberColor
202 NSInteger max = self.maxChara.integerValue;
203 NSInteger current = self.shipCount.integerValue;
205 if(current > max - self.minimumColoredShipCount) {
206 return [NSColor orangeColor];
209 return [NSColor controlTextColor];
211 - (void)setMinimumColoredShipCount:(NSInteger)minimumColoredShipCount
213 HMStandardDefaults.minimumColoredShipCount = minimumColoredShipCount;
215 - (NSInteger)minimumColoredShipCount
217 return HMStandardDefaults.minimumColoredShipCount;
220 - (IBAction)selectView:(id)sender
222 [self showViewWithNumber:[sender tag]];
224 - (IBAction)screenShot:(id)sender
226 [self.gameViewController screenShot:sender];
229 - (void)swipeWithEvent:(NSEvent *)event
231 if(!HMStandardDefaults.useSwipeChangeCombinedView) return;
233 if([event deltaX] > 0) {
234 [self showCombinedView];
236 if([event deltaX] < 0) {
237 [self hideCombinedView];
241 #pragma mark - Combined view
242 - (IBAction)showHideCombinedView:(id)sender
244 if(self.isCombinedMode) {
245 [self hideCombinedView];
247 [self showCombinedView];
250 - (void)showCombinedView
252 if(self.isCombinedMode) return;
253 if(self.fleetViewPosition == kOldStyle) return;
255 self.isCombinedMode = YES;
257 if(!self.combinedViewController) {
258 self.combinedViewController = [HMCombileViewController new];
259 self.combinedViewController.view.hidden = YES;
261 [self.combinedViewController.view setAutoresizingMask:[self.combinedViewPlaceholder autoresizingMask]];
262 [[self.combinedViewPlaceholder superview] replaceSubview:self.combinedViewPlaceholder with:self.combinedViewController.view];
265 NSRect winFrame = self.window.frame;
266 CGFloat incrementWidth = NSMaxX(self.combinedViewController.view.frame);
267 winFrame.size.width += incrementWidth;
268 winFrame.origin.x -= incrementWidth;
270 self.combinedViewController.view.hidden = NO;
271 [self.window setFrame:winFrame display:YES animate:YES];
273 - (void)hideCombinedView
275 if(!self.isCombinedMode) return;
276 self.isCombinedMode = NO;
278 NSRect winFrame = self.window.frame;
279 CGFloat incrementWidth = NSMaxX(self.combinedViewController.view.frame);
280 winFrame.size.width -= incrementWidth;
281 winFrame.origin.x += incrementWidth;
283 [self.window setFrame:winFrame display:YES animate:YES];
284 self.combinedViewController.view.hidden = YES;
287 - (void)didCangeCombined:(id)notification
289 if(!HMStandardDefaults.autoCombinedView) return;
291 NSDictionary *info = [notification userInfo];
292 NSNumber *typeValue = info[HMCombinedType];
293 CombineType type = typeValue.integerValue;
294 if(![NSThread isMainThread]) {
295 [NSThread sleepForTimeInterval:0.1];
297 dispatch_async(dispatch_get_main_queue(),
301 [self hideCombinedView];
306 [self showCombinedView];
309 NSLog(@"combined type is unknown type. %ld", type);
310 [self showCombinedView];
316 #pragma mark - FleetView position
317 // ###############################
318 const CGFloat margin = 1;
319 const CGFloat flashTopMargin = 4;
320 // ###############################
323 - (void)changeFleetViewForFleetViewPositionIfNeeded:(FleetViewPosition)fleetViewPosition
325 if(self.fleetViewPosition == fleetViewPosition) return;
326 if(self.fleetViewPosition != kOldStyle && fleetViewPosition != kOldStyle) return;
328 if(fleetViewPosition == kOldStyle && self.isCombinedMode) {
329 [self hideCombinedView];
332 HMFleetViewType type = fleetViewPosition == kOldStyle ? minimumViewType : detailViewType;
334 HMFleetViewController *newController = [HMFleetViewController viewControlerWithViewType:type];
335 newController.enableAnimation = YES;
336 newController.shipOrder = self.fleetViewController.shipOrder;
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];
345 self.fleetViewController = newController;
348 - (CGFloat)windowHeightForFleetViewPosition:(FleetViewPosition)fleetViewPosition
350 CGFloat windowContentHeight = [self.window.contentView frame].size.height;
352 if(self.fleetViewPosition == fleetViewPosition) return windowContentHeight;
354 if(self.fleetViewPosition == kOldStyle) {
355 windowContentHeight += HMFleetViewController.heightDifference;
357 if(fleetViewPosition == kOldStyle) {
358 windowContentHeight -= HMFleetViewController.heightDifference;
361 return windowContentHeight;
363 - (NSRect)windowFrameForFleetViewPosition:(FleetViewPosition)fleetViewPosition
365 NSRect windowContentRect = [self.window frame];
367 if(self.fleetViewPosition == fleetViewPosition) return windowContentRect;
369 if(self.fleetViewPosition == kOldStyle) {
370 windowContentRect.size.height += HMFleetViewController.heightDifference;
371 windowContentRect.origin.y -= HMFleetViewController.heightDifference;
373 if(fleetViewPosition == kOldStyle) {
374 windowContentRect.size.height -= HMFleetViewController.heightDifference;
375 windowContentRect.origin.y += HMFleetViewController.heightDifference;
378 return windowContentRect;
381 - (NSRect)flashFrameForFleetViewPosition:(FleetViewPosition)fleetViewPosition
385 CGFloat windowContentHeight = [self windowHeightForFleetViewPosition:fleetViewPosition];
386 NSRect flashRect = self.placeholder.frame;
388 switch(fleetViewPosition) {
390 flashY = windowContentHeight - flashRect.size.height - self.fleetViewController.normalHeight;
393 flashY = windowContentHeight - flashRect.size.height;
396 flashY = windowContentHeight - flashRect.size.height - self.fleetViewController.upsideHeight - margin;
399 flashY = windowContentHeight - flashRect.size.height - flashTopMargin;
402 NSLog(@"%s: unknown position.", __PRETTY_FUNCTION__);
406 flashRect.origin.y = flashY;
410 - (NSRect)fleetViewFrameForFleetViewPosition:(FleetViewPosition)fleetViewPosition
412 CGFloat fleetViewHeight;
415 CGFloat windowContentHeight = [self windowHeightForFleetViewPosition:fleetViewPosition];
416 NSRect flashRect = self.placeholder.frame;
417 NSRect fleetListRect = self.fleetViewController.view.frame;
419 switch(fleetViewPosition) {
421 fleetViewHeight = self.fleetViewController.normalHeight;
422 fleetViewY = windowContentHeight - fleetViewHeight;
425 fleetViewHeight = self.fleetViewController.normalHeight;
426 fleetViewY = windowContentHeight - fleetViewHeight - flashRect.size.height - margin;
429 fleetViewHeight = self.fleetViewController.normalHeight + flashRect.size.height + margin + margin;
430 fleetViewY = windowContentHeight - fleetViewHeight;
433 fleetViewHeight = HMFleetViewController.oldStyleFleetViewHeight;
434 fleetViewY = windowContentHeight - fleetViewHeight - flashRect.size.height - margin - flashTopMargin;
437 NSLog(@"%s: unknown position.", __PRETTY_FUNCTION__);
441 fleetListRect.size.height = fleetViewHeight;
442 fleetListRect.origin.y = fleetViewY;
443 return fleetListRect;
446 - (void)setFleetViewPosition:(FleetViewPosition)fleetViewPosition animation:(BOOL)flag
448 [self changeFleetViewForFleetViewPositionIfNeeded:fleetViewPosition];
450 NSRect windowFrame = [self windowFrameForFleetViewPosition:fleetViewPosition];
451 NSRect flashRect = [self flashFrameForFleetViewPosition:fleetViewPosition];
452 NSRect fleetListRect = [self fleetViewFrameForFleetViewPosition:fleetViewPosition];
454 _fleetViewPosition = fleetViewPosition;
455 HMStandardDefaults.fleetViewPosition = fleetViewPosition;
458 NSDictionary *winAnime = @{
459 NSViewAnimationTargetKey : self.window,
460 NSViewAnimationEndFrameKey : [NSValue valueWithRect:windowFrame],
462 NSDictionary *flashAnime = @{
463 NSViewAnimationTargetKey : self.placeholder,
464 NSViewAnimationEndFrameKey : [NSValue valueWithRect:flashRect],
466 NSDictionary *fleetAnime = @{
467 NSViewAnimationTargetKey : self.fleetViewController.view,
468 NSViewAnimationEndFrameKey : [NSValue valueWithRect:fleetListRect],
470 NSAnimation *anime = [[NSViewAnimation alloc] initWithViewAnimations:@[winAnime, flashAnime, fleetAnime]];
471 [anime startAnimation];
473 [self.window setFrame:windowFrame display:NO];
474 self.placeholder.frame = flashRect;
475 self.fleetViewController.view.frame = fleetListRect;
479 - (void)setFleetViewPosition:(FleetViewPosition)fleetViewPosition
481 [self setFleetViewPosition:fleetViewPosition animation:YES];
483 - (FleetViewPosition)fleetViewPosition
485 return _fleetViewPosition;
487 - (IBAction)fleetListAbove:(id)sender
489 self.fleetViewPosition = kAbove;
491 - (IBAction)fleetListBelow:(id)sender
493 self.fleetViewPosition = kBelow;
495 - (IBAction)fleetListDivide:(id)sender
497 self.fleetViewPosition = kDivided;
499 - (IBAction)fleetListSimple:(id)sender
501 self.fleetViewPosition = kOldStyle;
504 - (IBAction)reorderToDoubleLine:(id)sender
506 self.fleetViewController.shipOrder = doubleLine;
507 HMStandardDefaults.fleetViewShipOrder = doubleLine;
509 - (IBAction)reorderToLeftToRight:(id)sender
511 self.fleetViewController.shipOrder = leftToRight;
512 HMStandardDefaults.fleetViewShipOrder = leftToRight;
515 - (IBAction)selectNextFleet:(id)sender
517 [_fleetViewController selectNextFleet:sender];
519 - (IBAction)selectPreviousFleet:(id)sender
521 [_fleetViewController selectPreviousFleet:sender];
525 - (BOOL)validateMenuItem:(NSMenuItem *)menuItem
527 SEL action = menuItem.action;
529 if(action == @selector(reloadContent:) && action == @selector(screenShot:) && action == @selector(deleteCacheAndReload:)) {
530 return [self.gameViewController validateMenuItem:menuItem];
532 if(action == @selector(selectView:)) {
535 if(action == @selector(selectNextFleet:) || action == @selector(selectPreviousFleet:)) {
539 if(action == @selector(fleetListAbove:)) {
540 if(self.fleetViewPosition == kAbove) {
541 menuItem.state = NSOnState;
543 menuItem.state = NSOffState;
547 if(action == @selector(fleetListBelow:)) {
548 if(self.fleetViewPosition == kBelow) {
549 menuItem.state = NSOnState;
551 menuItem.state = NSOffState;
555 if(action == @selector(fleetListDivide:)) {
556 if(self.fleetViewPosition == kDivided) {
557 menuItem.state = NSOnState;
559 menuItem.state = NSOffState;
563 if(action == @selector(fleetListSimple:)) {
564 if(self.fleetViewPosition == kOldStyle) {
565 menuItem.state = NSOnState;
567 menuItem.state = NSOffState;
572 if(action == @selector(reorderToDoubleLine:)) {
573 if(self.fleetViewController.shipOrder == doubleLine) {
574 menuItem.state = NSOnState;
576 menuItem.state = NSOffState;
580 if(action == @selector(reorderToLeftToRight:)) {
581 if(self.fleetViewController.shipOrder == leftToRight) {
582 menuItem.state = NSOnState;
584 menuItem.state = NSOffState;
588 if(action == @selector(clearQuestList:)) {
591 if(action == @selector(showHideCombinedView:)) {
592 if(self.isCombinedMode) {
593 menuItem.title = NSLocalizedString(@"Hide Combined View", @"View menu, hide combined view");
595 menuItem.title = NSLocalizedString(@"Show Combined View", @"View menu, show combined view");
597 if(self.fleetViewPosition == kOldStyle) return NO;