зеркало из https://github.com/mozilla/gecko-dev.git
229 строки
6.2 KiB
C++
229 строки
6.2 KiB
C++
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||
|
*
|
||
|
* The contents of this file are subject to the Netscape Public License
|
||
|
* Version 1.0 (the "License"); you may not use this file except in
|
||
|
* compliance with the License. You may obtain a copy of the License at
|
||
|
* http://www.mozilla.org/NPL/
|
||
|
*
|
||
|
* Software distributed under the License is distributed on an "AS IS"
|
||
|
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
|
||
|
* the License for the specific language governing rights and limitations
|
||
|
* under the License.
|
||
|
*
|
||
|
* The Original Code is Mozilla Communicator client code.
|
||
|
*
|
||
|
* The Initial Developer of the Original Code is Netscape Communications
|
||
|
* Corporation. Portions created by Netscape are Copyright (C) 1998
|
||
|
* Netscape Communications Corporation. All Rights Reserved.
|
||
|
*/
|
||
|
#include "nsHTMLParts.h"
|
||
|
#include "nsLeafFrame.h"
|
||
|
#include "nsCSSLayout.h"
|
||
|
#include "nsIPresContext.h"
|
||
|
#include "nsIPresShell.h"
|
||
|
#include "nsWidgetsCID.h"
|
||
|
#include "nsViewsCID.h"
|
||
|
#include "nsIView.h"
|
||
|
#include "nsIViewManager.h"
|
||
|
|
||
|
#define nsObjectFrameSuper nsLeafFrame
|
||
|
|
||
|
class nsObjectFrame : public nsObjectFrameSuper {
|
||
|
public:
|
||
|
nsObjectFrame(nsIContent* aContent, nsIFrame* aParentFrame);
|
||
|
|
||
|
NS_IMETHOD Reflow(nsIPresContext* aPresContext,
|
||
|
nsReflowMetrics& aDesiredSize,
|
||
|
const nsReflowState& aReflowState,
|
||
|
nsReflowStatus& aStatus);
|
||
|
|
||
|
NS_IMETHOD DidReflow(nsIPresContext& aPresContext,
|
||
|
nsDidReflowStatus aStatus);
|
||
|
|
||
|
protected:
|
||
|
virtual ~nsObjectFrame();
|
||
|
|
||
|
virtual void GetDesiredSize(nsIPresContext* aPresContext,
|
||
|
const nsReflowState& aReflowState,
|
||
|
nsReflowMetrics& aDesiredSize);
|
||
|
|
||
|
nsresult CreateWidget(nsIPresContext* aPresContext,
|
||
|
nscoord aWidth, nscoord aHeight);
|
||
|
};
|
||
|
|
||
|
nsObjectFrame::nsObjectFrame(nsIContent* aContent, nsIFrame* aParentFrame)
|
||
|
: nsObjectFrameSuper(aContent, aParentFrame)
|
||
|
{
|
||
|
}
|
||
|
|
||
|
nsObjectFrame::~nsObjectFrame()
|
||
|
{
|
||
|
}
|
||
|
|
||
|
static NS_DEFINE_IID(kViewCID, NS_VIEW_CID);
|
||
|
static NS_DEFINE_IID(kIViewIID, NS_IVIEW_IID);
|
||
|
static NS_DEFINE_IID(kWidgetCID, NS_CHILD_CID);
|
||
|
|
||
|
nsresult
|
||
|
nsObjectFrame::CreateWidget(nsIPresContext* aPresContext,
|
||
|
nscoord aWidth, nscoord aHeight)
|
||
|
{
|
||
|
nsIView* view;
|
||
|
|
||
|
// Create our view and widget
|
||
|
|
||
|
nsresult result =
|
||
|
NSRepository::CreateInstance(kViewCID, nsnull, kIViewIID,
|
||
|
(void **)&view);
|
||
|
if (NS_OK != result) {
|
||
|
return result;
|
||
|
}
|
||
|
nsIPresShell *presShell = aPresContext->GetShell(); // need to release
|
||
|
nsIViewManager *viewMan = presShell->GetViewManager(); // need to release
|
||
|
|
||
|
nsRect boundBox(0, 0, aWidth, aHeight);
|
||
|
|
||
|
nsIFrame* parWithView;
|
||
|
nsIView *parView;
|
||
|
|
||
|
GetParentWithView(parWithView);
|
||
|
parWithView->GetView(parView);
|
||
|
|
||
|
// nsWidgetInitData* initData = GetWidgetInitData(*aPresContext); // needs to be deleted
|
||
|
// initialize the view as hidden since we don't know the (x,y) until Paint
|
||
|
result = view->Init(viewMan, boundBox, parView, &kWidgetCID, nsnull,
|
||
|
nsnull, 0, nsnull,
|
||
|
1.0f, nsViewVisibility_kHide);
|
||
|
// if (nsnull != initData) {
|
||
|
// delete(initData);
|
||
|
// }
|
||
|
if (NS_OK != result) {
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
#if 0
|
||
|
// set the content's widget, so it can get content modified by the widget
|
||
|
nsIWidget *widget;
|
||
|
result = GetWidget(view, &widget);
|
||
|
if (NS_OK == result) {
|
||
|
nsInput* content = (nsInput *)mContent; // change this cast to QueryInterface
|
||
|
content->SetWidget(widget);
|
||
|
NS_IF_RELEASE(widget);
|
||
|
} else {
|
||
|
NS_ASSERTION(0, "could not get widget");
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
viewMan->InsertChild(parView, view, 0);
|
||
|
|
||
|
SetView(view);
|
||
|
NS_RELEASE(view);
|
||
|
|
||
|
NS_IF_RELEASE(parView);
|
||
|
NS_IF_RELEASE(viewMan);
|
||
|
NS_IF_RELEASE(presShell);
|
||
|
return result;
|
||
|
}
|
||
|
|
||
|
#define EMBED_DEF_DIM 50
|
||
|
|
||
|
void
|
||
|
nsObjectFrame::GetDesiredSize(nsIPresContext* aPresContext,
|
||
|
const nsReflowState& aReflowState,
|
||
|
nsReflowMetrics& aDesiredSize)
|
||
|
{
|
||
|
// Determine our size stylistically
|
||
|
nsSize styleSize;
|
||
|
PRIntn ss = nsCSSLayout::GetStyleSize(aPresContext, aReflowState, styleSize);
|
||
|
PRBool haveWidth = PR_FALSE;
|
||
|
PRBool haveHeight = PR_FALSE;
|
||
|
if (0 != (ss & NS_SIZE_HAS_WIDTH)) {
|
||
|
aDesiredSize.width = styleSize.width;
|
||
|
haveWidth = PR_TRUE;
|
||
|
}
|
||
|
if (0 != (ss & NS_SIZE_HAS_HEIGHT)) {
|
||
|
aDesiredSize.height = styleSize.height;
|
||
|
haveHeight = PR_TRUE;
|
||
|
}
|
||
|
|
||
|
// XXX Temporary auto-sizing logic
|
||
|
if (!haveWidth) {
|
||
|
if (haveHeight) {
|
||
|
aDesiredSize.width = aDesiredSize.height;
|
||
|
}
|
||
|
else {
|
||
|
float p2t = aPresContext->GetPixelsToTwips();
|
||
|
aDesiredSize.width = nscoord(p2t * EMBED_DEF_DIM);
|
||
|
}
|
||
|
}
|
||
|
if (!haveHeight) {
|
||
|
if (haveWidth) {
|
||
|
aDesiredSize.height = aDesiredSize.width;
|
||
|
}
|
||
|
else {
|
||
|
float p2t = aPresContext->GetPixelsToTwips();
|
||
|
aDesiredSize.height = nscoord(p2t * EMBED_DEF_DIM);
|
||
|
}
|
||
|
}
|
||
|
aDesiredSize.ascent = aDesiredSize.height;
|
||
|
aDesiredSize.descent = 0;
|
||
|
}
|
||
|
|
||
|
NS_IMETHODIMP
|
||
|
nsObjectFrame::Reflow(nsIPresContext* aPresContext,
|
||
|
nsReflowMetrics& aDesiredSize,
|
||
|
const nsReflowState& aReflowState,
|
||
|
nsReflowStatus& aStatus)
|
||
|
{
|
||
|
// Get our desired size
|
||
|
GetDesiredSize(aPresContext, aReflowState, aDesiredSize);
|
||
|
|
||
|
// XXX deal with border and padding the usual way...wrap it up!
|
||
|
|
||
|
// Create view if necessary
|
||
|
nsIView* view;
|
||
|
GetView(view);
|
||
|
if (nsnull == view) {
|
||
|
nsresult rv = CreateWidget(aPresContext, aDesiredSize.width,
|
||
|
aDesiredSize.height);
|
||
|
if (NS_OK != rv) {
|
||
|
return rv;
|
||
|
}
|
||
|
}
|
||
|
else {
|
||
|
NS_RELEASE(view);
|
||
|
}
|
||
|
|
||
|
aStatus = NS_FRAME_COMPLETE;
|
||
|
return NS_OK;
|
||
|
}
|
||
|
|
||
|
NS_IMETHODIMP
|
||
|
nsObjectFrame::DidReflow(nsIPresContext& aPresContext,
|
||
|
nsDidReflowStatus aStatus)
|
||
|
{
|
||
|
nsresult rv = nsObjectFrameSuper::DidReflow(aPresContext, aStatus);
|
||
|
|
||
|
// The view is created hidden; once we have reflowed it and it has been
|
||
|
// positioned then we show it.
|
||
|
if (NS_FRAME_REFLOW_FINISHED == aStatus) {
|
||
|
nsIView* view = nsnull;
|
||
|
GetView(view);
|
||
|
if (nsnull != view) {
|
||
|
view->SetVisibility(nsViewVisibility_kShow);
|
||
|
NS_RELEASE(view);
|
||
|
}
|
||
|
}
|
||
|
return rv;
|
||
|
}
|
||
|
|
||
|
nsresult NS_NewObjectFrame(nsIFrame*& aFrameResult, nsIContent* aContent,
|
||
|
nsIFrame* aParentFrame)
|
||
|
{
|
||
|
aFrameResult = new nsObjectFrame(aContent, aParentFrame);
|
||
|
if (nsnull == aFrameResult) {
|
||
|
return NS_ERROR_OUT_OF_MEMORY;
|
||
|
}
|
||
|
return NS_OK;
|
||
|
}
|