Camino only - Bug 155956: Make 'zoom' button zoom window to fit contents. Patch by Torben <torben@Spamfence.net>. r=hwaara sr=pink

This commit is contained in:
stridey%gmail.com 2006-11-14 23:52:05 +00:00
Родитель 7cd5f5c401
Коммит ae1e372ae6
6 изменённых файлов: 168 добавлений и 14 удалений

Просмотреть файл

@ -64,6 +64,9 @@
- (void)reflowButtons;
- (void)reflowButtonsStartingAtIndex:(int)aIndex;
// This is need for correct window zooming
- (float)computeHeight:(float)aWidth startingAtIndex:(int)aIndex;
- (BOOL)isShown;
- (void)setDrawBottomBorder:(BOOL)drawBorder;
- (void)showBookmarksToolbar:(BOOL)aShow;

Просмотреть файл

@ -322,7 +322,23 @@ static void VerticalGrayGradient(void* inInfo, float const* inData, float* outDa
// coordinates for this view are flipped, making it easier to lay out from top left
// to bottom right.
float oldHeight = [self frame].size.height;
float oldHeight = [self frame].size.height;
float computedHeight = [self computeHeight:NSWidth([self bounds]) startingAtIndex:aIndex];
// our size has changed, readjust our view's frame and the content area
if (computedHeight != oldHeight) {
[super setFrame:NSMakeRect([self frame].origin.x, [self frame].origin.y + (oldHeight - computedHeight),
[self frame].size.width, computedHeight)];
// tell the superview to resize its subviews
[[self superview] resizeSubviewsWithOldSize:[[self superview] frame].size];
}
[self setNeedsDisplay:YES];
}
- (float)computeHeight:(float)aWidth startingAtIndex:(int)aIndex
{
int count = [mButtons count];
float curRowYOrigin = kBookmarkToolbarTopPadding;
float curX = kBookmarkButtonHorizPadding;
@ -346,7 +362,7 @@ static void VerticalGrayGradient(void* inInfo, float const* inData, float* outDa
buttonRect = NSMakeRect(curX, curRowYOrigin + kBookmarkButtonVerticalPadding, width, kBookmarkButtonHeight);
curX += NSWidth(buttonRect) + kBookmarkButtonHorizPadding;
if (NSMaxX(buttonRect) > NSWidth([self bounds])) {
if (NSMaxX(buttonRect) > aWidth) {
// jump to the next line
curX = kBookmarkButtonHorizPadding;
curRowYOrigin += (kBookmarkButtonHeight + 2 * kBookmarkButtonVerticalPadding);
@ -358,18 +374,7 @@ static void VerticalGrayGradient(void* inInfo, float const* inData, float* outDa
}
}
float computedHeight = curRowYOrigin + (kBookmarkButtonHeight + 2 * kBookmarkButtonVerticalPadding + kBookmarkToolbarBottomPadding);
// our size has changed, readjust our view's frame and the content area
if (computedHeight != oldHeight) {
[super setFrame:NSMakeRect([self frame].origin.x, [self frame].origin.y + (oldHeight - computedHeight),
[self frame].size.width, computedHeight)];
// tell the superview to resize its subviews
[[self superview] resizeSubviewsWithOldSize:[[self superview] frame].size];
}
[self setNeedsDisplay:YES];
return curRowYOrigin + (kBookmarkButtonHeight + 2 * kBookmarkButtonVerticalPadding + kBookmarkToolbarBottomPadding);
}
- (BOOL)isFlipped

Просмотреть файл

@ -162,6 +162,10 @@ typedef enum
unsigned int mChromeMask; // Indicates which parts of the window to show (e.g., don't show toolbars)
// Needed for correct window zooming
NSRect mLastFrameSize;
BOOL mShouldZoom;
// C++ object that holds owning refs to XPCOM objects (and related data)
BWCDataOwner* mDataOwner;

Просмотреть файл

@ -35,6 +35,8 @@
*
* ***** END LICENSE BLOCK ***** */
#import <AppKit/NSScroller.h>
#import <AddressBook/AddressBook.h>
#import "ABAddressBook+Utils.h"
@ -553,6 +555,8 @@ enum BWCOpenDest {
- (void)insertForceAlternatesIntoMenu:(NSMenu *)inMenu;
- (BOOL)prepareSpellingSuggestionMenu:(NSMenu*)inMenu tag:(int)inTag;
- (void)setZoomState:(NSRect)newFrame defaultFrame:(NSRect)defaultFrame;
@end
#pragma mark -
@ -1010,6 +1014,9 @@ enum BWCOpenDest {
[[self window] setFrameOrigin: testBrowserFrame.origin];
}
// cache the original window frame, we may need this for correct zooming
mLastFrameSize = [[self window] frame];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(newTab:)
name:kTabBarBackgroundDoubleClickedNotification object:mTabBrowser];
@ -1022,6 +1029,89 @@ enum BWCOpenDest {
return proposedFrameSize;
}
// zoom to fit contents
- (NSRect)windowWillUseStandardFrame:(NSWindow *)sender defaultFrame:(NSRect)defaultFrame
{
// If the window is empty or the bookmark manager is loaded maximize to screen
if ([[self getBrowserWrapper] isEmpty] || [self bookmarkManagerIsVisible]) {
[self setZoomState:defaultFrame defaultFrame:defaultFrame];
return defaultFrame;
}
// Get the needed content size
nsCOMPtr<nsIDOMWindow> contentWindow = [[mBrowserView getBrowserView] getContentWindow];
if (!contentWindow) {
[self setZoomState:defaultFrame defaultFrame:defaultFrame];
return defaultFrame;
}
PRInt32 contentWidth = 0, contentHeight = 0;
GeckoUtils::GetIntrisicSize(contentWindow, &contentWidth, &contentHeight);
if (contentWidth <= 1 || contentHeight <= 1) {
// Something went wrong, maximize to screen
[self setZoomState:defaultFrame defaultFrame:defaultFrame];
return defaultFrame;
}
// Get the current content size and calculate the changes.
NSSize curFrameSize = [[mBrowserView getBrowserView] frame].size;
float widthChange = contentWidth - curFrameSize.width;
float heightChange = contentHeight - curFrameSize.height;
// Change the window size, but don't let it be to narrow
NSRect stdFrame = [[self window] frame];
stdFrame.size.width = MAX([[self window] minSize].width, stdFrame.size.width + widthChange);
if ([mPersonalToolbar isShown])
// if the personal toolbar is shown we need to adjust for its height change
heightChange += [mPersonalToolbar computeHeight:stdFrame.size.width startingAtIndex:0]
- [mPersonalToolbar frame].size.height;
stdFrame.size.height += heightChange;
stdFrame.origin.y -= heightChange;
// add space for scrollers if needed
float scrollerSize = [NSScroller scrollerWidth];
if (stdFrame.size.height > defaultFrame.size.height)
stdFrame.size.width += scrollerSize;
if (stdFrame.size.width > defaultFrame.size.width) {
stdFrame.size.height += scrollerSize;
stdFrame.origin.y -= scrollerSize;
}
[self setZoomState:stdFrame defaultFrame:defaultFrame];
return stdFrame;
}
- (BOOL)windowShouldZoom:(NSWindow *)sender toFrame:(NSRect)newFrame
{
return mShouldZoom;
}
// Don't zoom a window that has not been zoomed before and we're not changing its size,
// strange things will happen (see bug 155956 for details)
- (void)setZoomState:(NSRect)newFrame defaultFrame:(NSRect)defaultFrame
{
const int kMinZoomChange = 10;
mShouldZoom = (ABS(mLastFrameSize.size.width - [[self window] frame].size.width) > kMinZoomChange ||
ABS(mLastFrameSize.size.height - [[self window] frame].size.height) > kMinZoomChange ||
ABS(MIN(newFrame.size.width, defaultFrame.size.width) - [[self window] frame].size.width) > kMinZoomChange ||
ABS(MIN(newFrame.size.height, defaultFrame.size.height) - [[self window] frame].size.height) > kMinZoomChange);
}
// If the window is resized update the cached windowframe unless we are zooming the window
- (void)windowDidResize:(NSNotification *)aNotification
{
if (!mShouldZoom)
mLastFrameSize = [[self window] frame];
else
// reset mShouldZoom so further resizes will be catched
mShouldZoom = NO;
}
#pragma mark -
// -createToolbarPopupButton:

Просмотреть файл

@ -58,6 +58,10 @@
#include "nsIDocShell.h"
#include "nsIDocShellTreeItem.h"
#include "nsIDOMDocument.h"
#include "nsIDOMWindowInternal.h"
#include "nsIDOMNSHTMLElement.h"
/* static */
void GeckoUtils::GatherTextUnder(nsIDOMNode* aNode, nsString& aResult)
{
@ -265,3 +269,47 @@ void GeckoUtils::GetAnchorNodeFromSelection(nsIEditor* inEditor, nsIDOMNode** ou
selection->GetAnchorOffset(outOffset);
selection->GetAnchorNode(outAnchorNode);
}
void GeckoUtils::GetIntrisicSize(nsIDOMWindow* aWindow, PRInt32* outWidth, PRInt32* outHeight)
{
if (!aWindow)
return;
nsCOMPtr<nsIDOMDocument> domDocument;
aWindow->GetDocument(getter_AddRefs(domDocument));
if (!domDocument)
return;
nsCOMPtr<nsIDOMElement> docElement;
domDocument->GetDocumentElement(getter_AddRefs(docElement));
if (!docElement)
return;
nsCOMPtr<nsIDOMNSHTMLElement> nsElement = do_QueryInterface(docElement);
if (!nsElement)
return;
// scrollHeight always gets the wanted height but scrollWidth may not if the page contains
// non-scrollable elements (eg <pre>), therefor we find the slientWidth and adds the max x
// offset if the window has a horizontal scroller. For more see bug 155956 and
// http://developer.mozilla.org/en/docs/DOM:element.scrollWidth
// http://developer.mozilla.org/en/docs/DOM:element.clientWidth
// http://developer.mozilla.org/en/docs/DOM:window.scrollMaxX
nsElement->GetClientWidth(outWidth);
nsElement->GetScrollHeight(outHeight);
// Add 1 px extra to the height and width to guard against these values being rounded down
*outWidth += 1;
*outHeight += 1;
nsCOMPtr<nsIDOMWindowInternal> domWindow = do_QueryInterface(aWindow);
if (!domWindow)
return;
PRInt32 scrollMaxX = 0;
domWindow->GetScrollMaxX(&scrollMaxX);
if (scrollMaxX > 0)
*outWidth += scrollMaxX;
return;
}

Просмотреть файл

@ -43,6 +43,7 @@
#include "jsapi.h"
#include "nsIJSContextStack.h"
class nsIDOMWindow;
class nsIDOMNode;
class nsIDOMElement;
class nsIDocShell;
@ -68,6 +69,9 @@ class GeckoUtils
found somewhere in a document's docshell tree. NOTE: Addrefs the found docshell!
*/
static void FindDocShellForURI(nsIURI *aURI, nsIDocShell *aRoot, nsIDocShell **outMatch);
/* Finds the preferred size (ie the minimum size where scrollbars are not needed) of the content window. */
static void GetIntrisicSize(nsIDOMWindow* aWindow, PRInt32* outWidth, PRInt32* outHeight);
};
/* Stack-based utility that will push a null JSContext onto the JS stack during the