Added support for widgetless viewmanager. Changed code pattern that assumed the root view

always has a nsIWidget instance to call viewmanager to get widget instance. b=22069; r=rods@netscape.com
This commit is contained in:
kmcclusk%netscape.com 2000-01-26 23:04:40 +00:00
parent 17dd1d08c5
commit eeeb109f4c
13 changed files with 192 additions and 114 deletions

View File

@ -336,11 +336,7 @@ NS_METHOD nsDOMEvent::GetClientX(PRInt32* aClientX)
nsIViewManager* vm;
shell->GetViewManager(&vm);
if (vm) {
nsIView* rootView = nsnull;
vm->GetRootView(rootView);
if (rootView) {
rootView->GetWidget(rootWidget);
}
vm->GetWidget(&rootWidget);
NS_RELEASE(vm);
}
NS_RELEASE(shell);
@ -385,11 +381,7 @@ NS_METHOD nsDOMEvent::GetClientY(PRInt32* aClientY)
nsIViewManager* vm;
shell->GetViewManager(&vm);
if (vm) {
nsIView* rootView = nsnull;
vm->GetRootView(rootView);
if (rootView) {
rootView->GetWidget(rootWidget);
}
vm->GetWidget(&rootWidget);
NS_RELEASE(vm);
}
NS_RELEASE(shell);

View File

@ -958,14 +958,7 @@ nsEventStateManager::PostHandleEvent(nsIPresContext* aPresContext,
if (NS_OK == aView->GetViewManager(vm) && nsnull != vm) {
// I'd use Composite here, but it doesn't always work.
// vm->Composite();
nsIView* rootView = nsnull;
if (NS_OK == vm->GetRootView(rootView) && nsnull != rootView) {
nsIWidget* rootWidget = nsnull;
if (NS_OK == rootView->GetWidget(rootWidget) && nsnull != rootWidget) {
rootWidget->Update();
NS_RELEASE(rootWidget);
}
}
vm->ForceUpdate();
NS_RELEASE(vm);
}
}
@ -2461,15 +2454,7 @@ void nsEventStateManager::ForceViewUpdate(nsIView* aView)
if (NS_OK == aView->GetViewManager(vm) && nsnull != vm) {
// I'd use Composite here, but it doesn't always work.
// vm->Composite();
nsIView* rootView = nsnull;
if (NS_OK == vm->GetRootView(rootView) && nsnull != rootView) {
nsIWidget* rootWidget = nsnull;
if (NS_OK == rootView->GetWidget(rootWidget) &&
nsnull != rootWidget) {
rootWidget->Update();
NS_RELEASE(rootWidget);
}
}
vm->ForceUpdate();
NS_RELEASE(vm);
}
}

View File

@ -1325,15 +1325,10 @@ GlobalWindowImpl::Focus()
nsIViewManager *vm = nsnull;
shell->GetViewManager(&vm);
if (nsnull != vm) {
nsIView *rootview = nsnull;
vm->GetRootView(rootview);
if (rootview) {
nsIWidget* widget;
rootview->GetWidget(widget);
if (widget) {
result = widget->SetFocus();
NS_RELEASE(widget);
}
nsCOMPtr<nsIWidget> widget;
vm->GetWidget(getter_AddRefs(widget));
if (widget) {
result = widget->SetFocus();
}
NS_RELEASE(vm);
}

View File

@ -1446,15 +1446,7 @@ PresShell::ScrollLine(PRBool aForward)
// I'd use Composite here, but it doesn't always work.
// vm->Composite();
nsIView* rootView = nsnull;
if (NS_OK == viewManager->GetRootView(rootView) && nsnull != rootView)
{
nsCOMPtr<nsIWidget> rootWidget;
if (NS_OK == rootView->GetWidget(*getter_AddRefs(rootWidget)) && rootWidget!= nsnull)
{
rootWidget->Update();
}
}
viewManager->ForceUpdate();
}
}
@ -2048,7 +2040,6 @@ PresShell::CreateRenderingContext(nsIFrame *aFrame,
return NS_ERROR_NULL_POINTER;
}
nsIWidget *widget = nsnull;
nsIView *view = nsnull;
nsPoint pt;
nsresult rv;
@ -2058,17 +2049,11 @@ PresShell::CreateRenderingContext(nsIFrame *aFrame,
if (nsnull == view)
aFrame->GetOffsetFromView(mPresContext, pt, &view);
while (nsnull != view)
{
view->GetWidget(widget);
if (nsnull != widget)
{
NS_RELEASE(widget);
break;
}
view->GetParent(view);
nsCOMPtr<nsIWidget> widget;
if (nsnull != view) {
nsCOMPtr<nsIViewManager> vm;
view->GetViewManager(*getter_AddRefs(vm));
vm->GetWidgetForView(view, getter_AddRefs(widget));
}
nsCOMPtr<nsIDeviceContext> dx;
@ -2076,8 +2061,8 @@ PresShell::CreateRenderingContext(nsIFrame *aFrame,
nsIRenderingContext* result = nsnull;
rv = mPresContext->GetDeviceContext(getter_AddRefs(dx));
if (NS_SUCCEEDED(rv) && dx) {
if (nsnull != view) {
rv = dx->CreateRenderingContext(view, result);
if (nsnull != widget) {
rv = dx->CreateRenderingContext(widget, result);
}
else {
rv = dx->CreateRenderingContext(result);

View File

@ -336,11 +336,7 @@ NS_METHOD nsDOMEvent::GetClientX(PRInt32* aClientX)
nsIViewManager* vm;
shell->GetViewManager(&vm);
if (vm) {
nsIView* rootView = nsnull;
vm->GetRootView(rootView);
if (rootView) {
rootView->GetWidget(rootWidget);
}
vm->GetWidget(&rootWidget);
NS_RELEASE(vm);
}
NS_RELEASE(shell);
@ -385,11 +381,7 @@ NS_METHOD nsDOMEvent::GetClientY(PRInt32* aClientY)
nsIViewManager* vm;
shell->GetViewManager(&vm);
if (vm) {
nsIView* rootView = nsnull;
vm->GetRootView(rootView);
if (rootView) {
rootView->GetWidget(rootWidget);
}
vm->GetWidget(&rootWidget);
NS_RELEASE(vm);
}
NS_RELEASE(shell);

View File

@ -958,14 +958,7 @@ nsEventStateManager::PostHandleEvent(nsIPresContext* aPresContext,
if (NS_OK == aView->GetViewManager(vm) && nsnull != vm) {
// I'd use Composite here, but it doesn't always work.
// vm->Composite();
nsIView* rootView = nsnull;
if (NS_OK == vm->GetRootView(rootView) && nsnull != rootView) {
nsIWidget* rootWidget = nsnull;
if (NS_OK == rootView->GetWidget(rootWidget) && nsnull != rootWidget) {
rootWidget->Update();
NS_RELEASE(rootWidget);
}
}
vm->ForceUpdate();
NS_RELEASE(vm);
}
}
@ -2461,15 +2454,7 @@ void nsEventStateManager::ForceViewUpdate(nsIView* aView)
if (NS_OK == aView->GetViewManager(vm) && nsnull != vm) {
// I'd use Composite here, but it doesn't always work.
// vm->Composite();
nsIView* rootView = nsnull;
if (NS_OK == vm->GetRootView(rootView) && nsnull != rootView) {
nsIWidget* rootWidget = nsnull;
if (NS_OK == rootView->GetWidget(rootWidget) &&
nsnull != rootWidget) {
rootWidget->Update();
NS_RELEASE(rootWidget);
}
}
vm->ForceUpdate();
NS_RELEASE(vm);
}
}

View File

@ -1508,6 +1508,27 @@ NS_IMETHODIMP nsFrame::GetWindow(nsIPresContext* aPresContext,
}
}
}
if (nsnull == window) {
// Ask the view manager for the widget
// First we have to get to a frame with a view
nsIView* view;
GetView(aPresContext, &view);
if (nsnull == view) {
GetParentWithView(aPresContext, &frame);
if (nsnull != frame) {
GetView(aPresContext, &view);
}
}
// From the view get the view manager
if (nsnull != view) {
nsCOMPtr<nsIViewManager> vm;
view->GetViewManager(*getter_AddRefs(vm));
vm->GetWidget(&window);
}
}
NS_POSTCONDITION(nsnull != window, "no window in frame tree");
*aWindow = window;
return NS_OK;

View File

@ -1508,6 +1508,27 @@ NS_IMETHODIMP nsFrame::GetWindow(nsIPresContext* aPresContext,
}
}
}
if (nsnull == window) {
// Ask the view manager for the widget
// First we have to get to a frame with a view
nsIView* view;
GetView(aPresContext, &view);
if (nsnull == view) {
GetParentWithView(aPresContext, &frame);
if (nsnull != frame) {
GetView(aPresContext, &view);
}
}
// From the view get the view manager
if (nsnull != view) {
nsCOMPtr<nsIViewManager> vm;
view->GetViewManager(*getter_AddRefs(vm));
vm->GetWidget(&window);
}
}
NS_POSTCONDITION(nsnull != window, "no window in frame tree");
*aWindow = window;
return NS_OK;

View File

@ -1446,15 +1446,7 @@ PresShell::ScrollLine(PRBool aForward)
// I'd use Composite here, but it doesn't always work.
// vm->Composite();
nsIView* rootView = nsnull;
if (NS_OK == viewManager->GetRootView(rootView) && nsnull != rootView)
{
nsCOMPtr<nsIWidget> rootWidget;
if (NS_OK == rootView->GetWidget(*getter_AddRefs(rootWidget)) && rootWidget!= nsnull)
{
rootWidget->Update();
}
}
viewManager->ForceUpdate();
}
}
@ -2048,7 +2040,6 @@ PresShell::CreateRenderingContext(nsIFrame *aFrame,
return NS_ERROR_NULL_POINTER;
}
nsIWidget *widget = nsnull;
nsIView *view = nsnull;
nsPoint pt;
nsresult rv;
@ -2058,17 +2049,11 @@ PresShell::CreateRenderingContext(nsIFrame *aFrame,
if (nsnull == view)
aFrame->GetOffsetFromView(mPresContext, pt, &view);
while (nsnull != view)
{
view->GetWidget(widget);
if (nsnull != widget)
{
NS_RELEASE(widget);
break;
}
view->GetParent(view);
nsCOMPtr<nsIWidget> widget;
if (nsnull != view) {
nsCOMPtr<nsIViewManager> vm;
view->GetViewManager(*getter_AddRefs(vm));
vm->GetWidgetForView(view, getter_AddRefs(widget));
}
nsCOMPtr<nsIDeviceContext> dx;
@ -2076,8 +2061,8 @@ PresShell::CreateRenderingContext(nsIFrame *aFrame,
nsIRenderingContext* result = nsnull;
rv = mPresContext->GetDeviceContext(getter_AddRefs(dx));
if (NS_SUCCEEDED(rv) && dx) {
if (nsnull != view) {
rv = dx->CreateRenderingContext(view, result);
if (nsnull != widget) {
rv = dx->CreateRenderingContext(widget, result);
}
else {
rv = dx->CreateRenderingContext(result);

View File

@ -70,9 +70,15 @@ public:
/**
* Set the root of the view tree. Does not destroy the current root view.
* One of following must be true:
* a) the aWidget parameter is an nsIWidget instance to render into
* that is not owned by any view or
* b) aView has a nsIWidget instance or
* c) aView has a parent view managed by a different view manager
* @param aView view to set as root
* @param aWidget widget to render into. (Can not be owned by a view)
*/
NS_IMETHOD SetRootView(nsIView *aView) = 0;
NS_IMETHOD SetRootView(nsIView *aView, nsIWidget* aWidget = nsnull) = 0;
/**
* Get the current framerate i.e. the rate at which timed
@ -427,6 +433,34 @@ public:
* @result error status
*/
NS_IMETHOD RemoveCompositeListener(nsICompositeListener *aListener) = 0;
/**
* Retrieve the widget that a view renders into.
* @param aView the view to get the widget for
* @param aWidget the widget that aView renders into.
* @result error status
*/
NS_IMETHOD GetWidgetForView(nsIView *aView, nsIWidget **aWidget) = 0;
/**
* Retrieve the widget that a view manager renders into
* @param aWidget the widget that aView renders into.
* @result error status
*/
NS_IMETHOD GetWidget(nsIWidget **aWidget) = 0;
/**
* Force update of view manager widget
* Callers should use UpdateView(view, NS_VMREFRESH_IMMEDIATE) in most cases instead
* @param aWidget the widget that aView renders into.
* @result error status
*/
NS_IMETHOD ForceUpdate() = 0;
};
//when the refresh happens, should it be double buffered?

View File

@ -1392,6 +1392,7 @@ NS_IMETHODIMP nsView :: GetViewFlags(PRUint32 *aFlags) const
NS_IMETHODIMP nsView :: GetOffsetFromWidget(nscoord *aDx, nscoord *aDy, nsIWidget *&aWidget)
{
nsIView *ancestor;
aWidget = nsnull;
// XXX aDx and aDy are OUT parameters and so we should initialize them
// to 0 rather than relying on the caller to do so...
@ -1415,7 +1416,15 @@ NS_IMETHODIMP nsView :: GetOffsetFromWidget(nscoord *aDx, nscoord *aDy, nsIWidge
ancestor->GetParent(ancestor);
}
aWidget = nsnull;
if (nsnull == aWidget) {
// The root view doesn't have a widget
// but maybe the view manager does.
nsCOMPtr<nsIViewManager> vm;
GetViewManager(*getter_AddRefs(vm));
vm->GetWidget(&aWidget);
}
return NS_OK;
}

View File

@ -298,7 +298,7 @@ NS_IMETHODIMP nsViewManager :: GetRootView(nsIView *&aView)
return NS_OK;
}
NS_IMETHODIMP nsViewManager :: SetRootView(nsIView *aView)
NS_IMETHODIMP nsViewManager :: SetRootView(nsIView *aView, nsIWidget* aWidget)
{
UpdateTransCnt(mRootView, aView);
// Do NOT destroy the current root view. It's the caller's responsibility
@ -308,8 +308,27 @@ NS_IMETHODIMP nsViewManager :: SetRootView(nsIView *aView)
//now get the window too.
NS_IF_RELEASE(mRootWindow);
if (nsnull != mRootView)
// The window must be specified through one of the following:
//* a) The aView has a nsIWidget instance or
//* b) the aWidget parameter is an nsIWidget instance to render into
//* that is not owned by a view.
//* c) aView has a parent view managed by a different view manager or
if (nsnull != aWidget) {
mRootWindow = aWidget;
NS_ADDREF(mRootWindow);
return NS_OK;
}
// case b) The aView has a nsIWidget instance
if (nsnull != mRootView) {
mRootView->GetWidget(mRootWindow);
if (nsnull != mRootWindow) {
return NS_OK;
}
}
// case c) aView has a parent view managed by a different view manager
return NS_OK;
}
@ -2454,6 +2473,56 @@ NS_IMETHODIMP nsViewManager :: RemoveCompositeListener(nsICompositeListener* aLi
return NS_ERROR_FAILURE;
}
NS_IMETHODIMP nsViewManager::GetWidgetForView(nsIView *aView, nsIWidget **aWidget)
{
*aWidget = nsnull;
nsIView *view = aView;
PRBool hasWidget = PR_FALSE;
while (!hasWidget && view)
{
view->HasWidget(&hasWidget);
if (!hasWidget)
view->GetParent(view);
}
if (hasWidget) {
// Widget was found in the view hierarchy
view->GetWidget(*aWidget);
} else {
// No widget was found in the view hierachy, so use try to use the mRootWindow
if (nsnull != mRootWindow) {
#ifdef NS_DEBUG
nsCOMPtr<nsIViewManager> vm;
nsCOMPtr<nsIViewManager> thisInstance(this);
aView->GetViewManager(*getter_AddRefs(vm));
NS_ASSERTION(thisInstance == vm, "Must use the view instances view manager when calling GetWidgetForView");
#endif
*aWidget = mRootWindow;
NS_ADDREF(mRootWindow);
}
}
return NS_OK;
}
NS_IMETHODIMP nsViewManager::GetWidget(nsIWidget **aWidget)
{
NS_IF_ADDREF(mRootWindow);
*aWidget = mRootWindow;
return NS_OK;
}
NS_IMETHODIMP nsViewManager::ForceUpdate()
{
if (mRootWindow) {
mRootWindow->Update();
}
return NS_OK;
}
PRBool nsViewManager :: CreateDisplayList(nsIView *aView, PRInt32 *aIndex,
nscoord aOriginX, nscoord aOriginY, nsIView *aRealView,
const nsRect *aDamageRect, nsIView *aTopView,
@ -2754,3 +2823,4 @@ void nsViewManager::ViewToWidget(nsIView *aView, nsIView* aWidgetView, nsRect &a
mContext->GetAppUnitsToDevUnits(t2p);
aRect.ScaleRoundOut(t2p);
}

View File

@ -48,7 +48,7 @@ public:
NS_IMETHOD Init(nsIDeviceContext* aContext);
NS_IMETHOD GetRootView(nsIView *&aView);
NS_IMETHOD SetRootView(nsIView *aView);
NS_IMETHOD SetRootView(nsIView *aView, nsIWidget* aWidget=nsnull);
NS_IMETHOD GetFrameRate(PRUint32 &aRate);
NS_IMETHOD SetFrameRate(PRUint32 frameRate);
@ -129,6 +129,10 @@ public:
NS_IMETHOD AddCompositeListener(nsICompositeListener *aListener);
NS_IMETHOD RemoveCompositeListener(nsICompositeListener *aListener);
NS_IMETHOD GetWidgetForView(nsIView *aView, nsIWidget **aWidget);
NS_IMETHOD GetWidget(nsIWidget **aWidget);
NS_IMETHOD ForceUpdate();
protected:
virtual ~nsViewManager();