diff options
author | pinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-19 19:11:25 +0000 |
---|---|---|
committer | pinkerton@chromium.org <pinkerton@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-03-19 19:11:25 +0000 |
commit | c0e5501cc6e6259381211007e5fc5f3950fc4fab (patch) | |
tree | 8b2ae9f6aee6af45c29c0f6543c5673c18f766e1 /chrome/browser/cocoa/tab_view.mm | |
parent | 63c85eee887a619b61fe4454b579237fdcaf25b9 (diff) | |
download | chromium_src-c0e5501cc6e6259381211007e5fc5f3950fc4fab.zip chromium_src-c0e5501cc6e6259381211007e5fc5f3950fc4fab.tar.gz chromium_src-c0e5501cc6e6259381211007e5fc5f3950fc4fab.tar.bz2 |
Stage 1 of tab dragging infrastructure, disabled. Put in a base class below the browser window for windows with tabs to promote re-use in contexts other than just the browser. Add code to the tab view to track drags, but it's disabled as it still needs much work.
Review URL: http://codereview.chromium.org/42397
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@12125 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/cocoa/tab_view.mm')
-rw-r--r-- | chrome/browser/cocoa/tab_view.mm | 191 |
1 files changed, 189 insertions, 2 deletions
diff --git a/chrome/browser/cocoa/tab_view.mm b/chrome/browser/cocoa/tab_view.mm index ffca1de..5fee1d5 100644 --- a/chrome/browser/cocoa/tab_view.mm +++ b/chrome/browser/cocoa/tab_view.mm @@ -4,6 +4,8 @@ #include "chrome/browser/cocoa/tab_view.h" +#include "chrome/browser/cocoa/tab_window_controller.h" + @implementation TabView - (id)initWithFrame:(NSRect)frame { @@ -38,13 +40,198 @@ // Handle clicks and drags in this button. We get here because we have // overridden acceptsFirstMouse: and the click is within our bounds. +// TODO(pinkerton/alcor): This routine needs *a lot* of work to marry Cole's +// ideas of dragging cocoa views between windows and how the Browser and +// TabStrip models want to manage tabs. - (void)mouseDown:(NSEvent *)theEvent { - // fire the action to select the tab + // Make sure the controller doesn't go away while we're doing this. + // TODO(pinkerton): cole had this, not sure why it's necessary. + [[controller_ retain] autorelease]; + + // Fire the action to select the tab. if ([[controller_ target] respondsToSelector:[controller_ action]]) [[controller_ target] performSelector:[controller_ action] withObject:self]; - // TODO(alcor): handle dragging... + // TODO(pinkerton): necessary to pre-arrange the tabs here? + + // Resolve overlay back to original window. + NSWindow* sourceWindow = [self window]; + if ([sourceWindow isKindOfClass:[NSPanel class]]) { + sourceWindow = [sourceWindow parentWindow]; + } + TabWindowController* sourceController = [sourceWindow windowController]; + TabWindowController* draggedController = nil; + TabWindowController* targetController = nil; + + BOOL isLastTab = NO; // TODO(alcor) + + NSWindow* dragWindow = nil; + NSWindow* dragOverlay = nil; + BOOL dragging = YES; + BOOL moved = NO; + + NSDate* targetDwellDate = nil; // The date this target was first chosen + NSMutableArray* targets = [NSMutableArray array]; + + NSPoint lastPoint = + [[theEvent window] convertBaseToScreen:[theEvent locationInWindow]]; + + while (dragging) { + theEvent = + [NSApp nextEventMatchingMask:NSLeftMouseUpMask | NSLeftMouseDraggedMask + untilDate:[NSDate distantFuture] + inMode:NSDefaultRunLoopMode dequeue:YES]; + NSPoint thisPoint = [NSEvent mouseLocation]; + + // Find all the windows that could be a target. It has to be of the + // appropriate class, and visible (obviously). + if (![targets count]) { + for (NSWindow* window in [NSApp windows]) { + if (window == sourceWindow && isLastTab) continue; + if (window == dragWindow) continue; + if (![window isVisible]) continue; + NSWindowController *controller = [window windowController]; + if ([controller isKindOfClass:[TabWindowController class]]) { + [targets addObject:controller]; + } + } + } + + // Iterate over possible targets checking for the one the mouse is in. + // The mouse can be in either the tab or window frame. + TabWindowController* newTarget = nil; + for (TabWindowController* target in targets) { + NSRect windowFrame = [[target window] frame]; + if (NSPointInRect(thisPoint, windowFrame)) { + if (NSPointInRect(thisPoint, [[target tabStripView] frame])) { + newTarget = target; + } + break; + } + } + + // If we're now targeting a new window, re-layout the tabs in the old + // target and reset how long we've been hovering over this new one. + if (targetController != newTarget) { + targetDwellDate = [NSDate date]; + [targetController arrangeTabs]; + targetController = newTarget; + } + + NSEventType type = [theEvent type]; + if (type == NSLeftMouseDragged) { +#if 0 + // TODO(alcor): get this working... + moved = YES; + if (!draggedController) { + if (isLastTab) { + draggedController = sourceController; + dragWindow = [draggedController window]; + } else { + // Detach from the current window. + // TODO(pinkerton): Create a new window, probably with + // Browser::CreateNewStripWithContents(), but that requires that + // we make some changes to return the new Browser object. + draggedController = [sourceController detachTabToNewWindow:self]; + dragWindow = [draggedController window]; + + // TODO(pinkerton): reconcile how the view moves from one window + // to the other with the TabStrip model wanting to create the tabs. + // [[sourceController tabController] removeTab:tab_]; + // [[sourceController tabController] addTab:tab_]; + [dragWindow setAlphaValue:0.0]; + } + + // Bring the target window to the front and make sure it has a border. + [[draggedController window] setLevel:NSFloatingWindowLevel]; + [dragWindow orderFront:nil]; + [dragWindow makeMainWindow]; + [draggedController showOverlay]; + dragOverlay = [draggedController overlayWindow]; + + if (![targets count]) + [dragOverlay setHasShadow:NO]; + } else { + NSPoint origin = [dragWindow frame].origin; + origin.x += thisPoint.x - lastPoint.x; + origin.y += thisPoint.y - lastPoint.y; + [dragWindow setFrameOrigin:NSMakePoint(origin.x, origin.y)]; + } + + // If we're not hovering over any window, make the window is fully + // opaque. Otherwise, find where the tab might be dropped and insert + // a placeholder so it appears like it's part of that window. + if (!targetContoller) { + [[dragWindow animator] setAlphaValue:1.0]; + } else { + if (![[targetController window] isKeyWindow]) { + // && ([targetDwellDate timeIntervalSinceNow] < -REQUIRED_DWELL)) { + [[targetController window] makeKeyAndOrderFront:nil]; + [targets removeAllObjects]; + targetDwellDate = nil; + } + + // Compute where placeholder should go and insert it into the + // destination tab strip. + NSRect dropTabFrame = [[targetController tabStripView] frame]; + NSPoint point = + [sourceWindow convertBaseToScreen: + [self convertPointToBase:NSZeroPoint]]; + int x = NSWidth([self bounds]) / 2 + point.x - dropTabFrame.origin.x; + [targetController insertPlaceholderForTab:tab_ atLocation:x]; + [targetController arrangeTabs]; + + if (!targetController) + [dragWindow makeKeyAndOrderFront:nil]; + [[dragWindow animator] setAlphaValue:targetController ? 0.0 : 0.333]; + + [[[draggedController overlayWindow] animator] + setAlphaValue:targetController ? 0.85 : 1.0]; + // [setAlphaValue:targetController ? 0.0 : 0.6]; + } +#endif + } else if (type == NSLeftMouseUp) { + // Mouse up, break out of the drag event tracking loop + dragging = NO; + } + lastPoint = thisPoint; + } // while tracking mouse + + // The drag/click is done. If the user dragged the mouse, finalize the drag + // and clean up. + if (moved) { + TabWindowController *dropController = targetController; + if (dropController) { + NSRect adjustedFrame = [self bounds]; + NSRect dropTabFrame = [[dropController tabStripView] frame]; + adjustedFrame.origin = [self convertPointToBase:NSZeroPoint]; + adjustedFrame.origin = + [sourceWindow convertBaseToScreen:adjustedFrame.origin]; + adjustedFrame.origin.x = adjustedFrame.origin.x - dropTabFrame.origin.x; +// adjustedFrame.origin.y = adjustedFrame.origin.y - dropTabFrame.origin.y; +// adjustedFrame.size.height += adjustedFrame.origin.y; + adjustedFrame.origin.y = 0; + + // TODO(alcor): get add tab stuff working + // [dropController addTab:tab_]; + + [self setFrame:adjustedFrame]; + [dropController arrangeTabs]; + [draggedController close]; + [dropController showWindow:nil]; + } else { + [[dragWindow animator] setAlphaValue:1.0]; + [dragOverlay setHasShadow:NO]; + [draggedController removeOverlayAfterDelay: + [[NSAnimationContext currentContext] duration]]; + [dragWindow makeKeyAndOrderFront:nil]; + + [[draggedController window] setLevel:NSNormalWindowLevel]; + [draggedController arrangeTabs]; + } + [sourceController arrangeTabs]; + } } @end |