diff --git a/widget/src/xpwidgets/makefile.win b/widget/src/xpwidgets/makefile.win index d3b018bbc6c0..00f6f7d684d4 100644 --- a/widget/src/xpwidgets/makefile.win +++ b/widget/src/xpwidgets/makefile.win @@ -27,8 +27,15 @@ CPPSRCS = \ nsMenuButton.cpp \ nsToolbarItemHolder.cpp \ nsToolbarManager.cpp \ - nsImageButton.cpp \ nsToolBar.cpp \ + nsHTColumn.cpp \ + nsHTControlStripItem.cpp \ + nsHTTreeItem.cpp \ + nsHTItem.cpp \ + nsHTTreeDataModel.cpp \ + nsHTDataModel.cpp \ + nsTreeView.cpp \ + nsImageButton.cpp \ $(NULL) MODULE=raptor @@ -39,6 +46,13 @@ OBJS=.\$(OBJDIR)\nsBaseWidget.obj \ .\$(OBJDIR)\nsToolbarManager.obj \ .\$(OBJDIR)\nsImageButton.obj \ .\$(OBJDIR)\nsToolBar.obj \ + .\$(OBJDIR)\nsHTColumn.obj \ + .\$(OBJDIR)\nsHTControlStripItem.obj \ + .\$(OBJDIR)\nsHTTreeItem.obj \ + .\$(OBJDIR)\nsHTItem.obj \ + .\$(OBJDIR)\nsHTTreeDataModel.obj \ + .\$(OBJDIR)\nsHTDataModel.obj \ + .\$(OBJDIR)\nsTreeView.obj \ $(NULL) LINCS= \ diff --git a/widget/src/xpwidgets/nsDataModelWidget.h b/widget/src/xpwidgets/nsDataModelWidget.h new file mode 100644 index 000000000000..658417e44ab5 --- /dev/null +++ b/widget/src/xpwidgets/nsDataModelWidget.h @@ -0,0 +1,39 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsDataModelWidget_h___ +#define nsDataModelWidget_h___ + +#include "nsWindow.h" + +// Events +const int cDMImageLoaded = 0; + +class nsDataModelWidget : public ChildWindow + +{ +protected: + nsDataModelWidget() {}; + +public: + virtual ~nsDataModelWidget() {}; + + virtual void HandleDataModelEvent(int event, nsHierarchicalDataItem* pItem) = 0; +}; + +#endif diff --git a/widget/src/xpwidgets/nsHTColumn.cpp b/widget/src/xpwidgets/nsHTColumn.cpp new file mode 100644 index 000000000000..87e1873bee18 --- /dev/null +++ b/widget/src/xpwidgets/nsHTColumn.cpp @@ -0,0 +1,65 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "nspr.h" +#include "nsString.h" +#include "nsTreeColumn.h" +#include "nsHTColumn.h" + +nsHTColumn::nsHTColumn() : nsTreeColumn() +{ + mPixelWidth = 25; + mDesiredPercentage = 0.33; +} + +//-------------------------------------------------------------------- +nsHTColumn::~nsHTColumn() +{ +} + + +// TreeColumn Implementation --------------------- +int nsHTColumn::GetPixelWidth() const +{ + return mPixelWidth; +} + +double nsHTColumn::GetDesiredPercentage() const +{ + return mDesiredPercentage; +} + +void nsHTColumn::GetColumnName(nsString& name) const +{ + name = "Header"; +} + +PRBool nsHTColumn::IsSortColumn() const +{ + return PR_FALSE; +} + +void nsHTColumn::SetPixelWidth(int newWidth) +{ + mPixelWidth = newWidth; +} + +void nsHTColumn::SetDesiredPercentage(double newPercentage) +{ + mDesiredPercentage = newPercentage; +} diff --git a/widget/src/xpwidgets/nsHTColumn.h b/widget/src/xpwidgets/nsHTColumn.h new file mode 100644 index 000000000000..829ee21b4a99 --- /dev/null +++ b/widget/src/xpwidgets/nsHTColumn.h @@ -0,0 +1,50 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsHTColumn_h___ +#define nsHTColumn_h___ + +#include "nsTreeColumn.h" + +//------------------------------------------------------------ +// This class functions as the data source for column information (things like +// width, desired percentage, and sorting). + +class nsHTColumn : public nsTreeColumn + +{ +public: + nsHTColumn(); + virtual ~nsHTColumn(); + + // Inspectors + virtual int GetPixelWidth() const; + virtual double GetDesiredPercentage() const; + virtual PRBool IsSortColumn() const; + virtual void GetColumnName(nsString& name) const; + + // Setters + virtual void SetPixelWidth(int newWidth); + virtual void SetDesiredPercentage(double newPercentage); + +protected: + int mPixelWidth; + double mDesiredPercentage; +}; + +#endif /* nsHTColumn_h___ */ diff --git a/widget/src/xpwidgets/nsHTControlStripItem.cpp b/widget/src/xpwidgets/nsHTControlStripItem.cpp new file mode 100644 index 000000000000..fb4203236b21 --- /dev/null +++ b/widget/src/xpwidgets/nsHTControlStripItem.cpp @@ -0,0 +1,30 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "nspr.h" +#include "nsString.h" +#include "nsHTControlStripItem.h" + +nsHTControlStripItem::nsHTControlStripItem() : nsTreeControlStripItem() +{ +} + +void nsHTControlStripItem::GetText(nsString& text) const +{ + text = "Blah"; +} diff --git a/widget/src/xpwidgets/nsHTControlStripItem.h b/widget/src/xpwidgets/nsHTControlStripItem.h new file mode 100644 index 000000000000..93a5f43ddc76 --- /dev/null +++ b/widget/src/xpwidgets/nsHTControlStripItem.h @@ -0,0 +1,34 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsHTControlStripItem_h___ +#define nsHTControlStripItem_h___ + +#include "nsTreeControlStripItem.h" + +class nsHTControlStripItem : public nsTreeControlStripItem + +{ +public: + nsHTControlStripItem(); + virtual ~nsHTControlStripItem() {}; + + virtual void GetText(nsString& text) const; +}; + +#endif /* nsHTControlStripItem_h___ */ diff --git a/widget/src/xpwidgets/nsHTDataModel.cpp b/widget/src/xpwidgets/nsHTDataModel.cpp new file mode 100644 index 000000000000..23893b307aa3 --- /dev/null +++ b/widget/src/xpwidgets/nsHTDataModel.cpp @@ -0,0 +1,96 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "nspr.h" +#include "nsString.h" +#include "nsFont.h" +#include "nsHTTreeDataModel.h" +#include "nsWidgetsCID.h" +#include "nsDataModelWidget.h" +#include "nsTreeColumn.h" +#include "nsHTTreeItem.h" +#include "nsIDeviceContext.h" + +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); + +nsHTDataModel::nsHTDataModel() +{ + mListener = nsnull; + mImageGroup = nsnull; + + // Init. one of our hard-coded values + mSingleNode = new nsHTTreeItem(); // TODO: This is all ridiculously illegal. + ((nsHTTreeItem*)mSingleNode)->SetDataModel((nsHTTreeDataModel*)this); // This is very bad. Just doing to test. +} + +//-------------------------------------------------------------------- +nsHTDataModel::~nsHTDataModel() +{ + if (mImageGroup) + { + mImageGroup->Interrupt(); + NS_RELEASE(mImageGroup); + } + + // Delete hard-coded value + delete mSingleNode; +} + +void nsHTDataModel::SetDataModelListenerDelegate(nsDataModelWidget* pWidget) +{ + NS_IF_RELEASE(mImageGroup); + mListener = pWidget; + if (pWidget != nsnull && NS_NewImageGroup(&mImageGroup) == NS_OK) + { + nsIDeviceContext * deviceCtx = pWidget->GetDeviceContext(); + mImageGroup->Init(deviceCtx, nsnull); + NS_RELEASE(deviceCtx); + } +} + +// Hierarchical Data Model Implementation --------------------- + + +nsHierarchicalDataItem* nsHTDataModel::GetRootDelegate() const +{ + return (nsHTTreeItem*)mSingleNode; +} + + +PRUint32 nsHTDataModel::GetFirstVisibleItemIndexDelegate() const +{ + return 0; +} + +void nsHTDataModel::SetFirstVisibleItemIndexDelegate(PRUint32 n) +{ +} + +nsHierarchicalDataItem* nsHTDataModel::GetNthItemDelegate(PRUint32 n) const +{ + return (nsHTTreeItem*)mSingleNode; +} + +void nsHTDataModel::ImageLoaded(nsHierarchicalDataItem* pItem) +{ + if (mListener) + { + // Send it on along. Let the view know what happened. + mListener->HandleDataModelEvent(cDMImageLoaded, pItem); + } +} \ No newline at end of file diff --git a/widget/src/xpwidgets/nsHTDataModel.h b/widget/src/xpwidgets/nsHTDataModel.h new file mode 100644 index 000000000000..8997a4a1cdce --- /dev/null +++ b/widget/src/xpwidgets/nsHTDataModel.h @@ -0,0 +1,67 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsHTDataModel_h___ +#define nsHTDataModel_h___ + +#include "nsWindow.h" +#include "nsHierarchicalDataModel.h" +#include "nsIImageGroup.h" + +class nsDataModelWidget; +class nsHTItem; + +//------------------------------------------------------------ +// The HyperTree Base Class +// This class is a simplified API that wraps calls into the DOM +// interfaces. It is shared by the HT Tree Widget and the HT +// Toolbar. +// ----------------------------------------------------------- + +class nsHTDataModel + +{ +public: + nsHTDataModel(); + virtual ~nsHTDataModel(); + + // Retrieve the root node of the data model. + virtual nsHierarchicalDataItem* GetRootDelegate() const; + + // A visibility hint can be stored and retrieved (e.g., the leftmost or topmost + // item in the current scrolled view). + virtual PRUint32 GetFirstVisibleItemIndexDelegate() const; + virtual void SetFirstVisibleItemIndexDelegate(PRUint32 index); + virtual nsHierarchicalDataItem* GetNthItemDelegate(PRUint32 n) const; + + virtual void SetDataModelListenerDelegate(nsDataModelWidget* pListener); + +public: + void ImageLoaded(nsHierarchicalDataItem* pItem); + nsIImageGroup* GetImageGroup() const { NS_ADDREF(mImageGroup); return mImageGroup; } + +protected: + nsDataModelWidget* mListener; // Events are sent to the listening widget. + nsIImageGroup* mImageGroup; // Image group used for loading all images in the model. + +protected: + // Hard-coded values for testing. Will go away. + nsHTItem* mSingleNode; +}; + +#endif /* nsToolbar_h___ */ diff --git a/widget/src/xpwidgets/nsHTItem.cpp b/widget/src/xpwidgets/nsHTItem.cpp new file mode 100644 index 000000000000..554bc3ee5566 --- /dev/null +++ b/widget/src/xpwidgets/nsHTItem.cpp @@ -0,0 +1,40 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "nspr.h" +#include "nsString.h" +#include "nsHTItem.h" + +nsHTItem::nsHTItem() +{ +} + +//-------------------------------------------------------------------- +nsHTItem::~nsHTItem() +{ +} + +PRBool nsHTItem::IsExpandedDelegate() const +{ + return PR_FALSE; +} + +PRUint32 nsHTItem::GetIndentationLevelDelegate() const +{ + return 0; +} diff --git a/widget/src/xpwidgets/nsHTItem.h b/widget/src/xpwidgets/nsHTItem.h new file mode 100644 index 000000000000..fb1e52cfb780 --- /dev/null +++ b/widget/src/xpwidgets/nsHTItem.h @@ -0,0 +1,40 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsHTItem_h___ +#define nsHTItem_h___ + +class nsHierarchicalDataModel; + +class nsHTItem + +{ +public: + nsHTItem(); + virtual ~nsHTItem(); + + virtual PRBool IsExpandedDelegate() const; + virtual PRUint32 GetIndentationLevelDelegate() const; + + virtual void SetDataModelDelegate(nsHierarchicalDataModel* pDataModel) { mDataModel = pDataModel; } + +protected: + nsHierarchicalDataModel* mDataModel; +}; + +#endif /* nsHTItem_h___ */ diff --git a/widget/src/xpwidgets/nsHTTreeDataModel.cpp b/widget/src/xpwidgets/nsHTTreeDataModel.cpp new file mode 100644 index 000000000000..bba2771ade41 --- /dev/null +++ b/widget/src/xpwidgets/nsHTTreeDataModel.cpp @@ -0,0 +1,284 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "nspr.h" +#include "nsString.h" +#include "nsFont.h" +#include "nsHTTreeDataModel.h" +#include "nsWidgetsCID.h" +#include "nsDataModelWidget.h" +#include "nsHTColumn.h" +#include "nsHTControlStripItem.h" +#include "nsIDeviceContext.h" +#include "nsIImageObserver.h" +#include "nsIImageRequest.h" +#include "nsIImageGroup.h" + +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +static NS_DEFINE_IID(kIImageObserverIID, NS_IIMAGEREQUESTOBSERVER_IID); + +NS_IMPL_ADDREF(nsHTTreeDataModel) +NS_IMPL_RELEASE(nsHTTreeDataModel) + +nsHTTreeDataModel::nsHTTreeDataModel() : nsTreeDataModel(), nsHTDataModel() +{ + NS_INIT_REFCNT(); + + // Image Request Inits + mTitleBGRequest = nsnull; + mControlStripBGRequest = nsnull; + mColumnHeaderBGRequest = nsnull; + + // Hard-coded values. + mVisibleColumnCount = 3; + mTotalColumnCount = 3; + mSingleColumn = new nsHTColumn(); + mSecondColumn = new nsHTColumn(); + mThirdColumn = new nsHTColumn(); + mSingleControlStripItem = new nsHTControlStripItem(); +} + +//-------------------------------------------------------------------- +nsHTTreeDataModel::~nsHTTreeDataModel() +{ + // Delete hard-coded value + delete mSingleColumn; + delete mSecondColumn; + delete mThirdColumn; + delete mSingleControlStripItem; +} + +// ISupports Implementation -------------------------------------------------------------------- +nsresult nsHTTreeDataModel::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (NULL == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + if (aIID.Equals(kISupportsIID)) { + *aInstancePtr = (void*) (nsISupports *)(nsIImageRequestObserver*)this; + AddRef(); + return NS_OK; + } + if (aIID.Equals(kIImageObserverIID)) { + *aInstancePtr = (void*)(nsIImageRequestObserver*)this; + AddRef(); + return NS_OK; + } + return NS_ERROR_NULL_POINTER; +} + +// Hierarchical Tree Data Model Implementation --------------------- + +PRUint32 nsHTTreeDataModel::GetVisibleColumnCount() const +{ + return mVisibleColumnCount; +} + +PRUint32 nsHTTreeDataModel::GetColumnCount() const +{ + return mTotalColumnCount; +} + +nsTreeColumn* nsHTTreeDataModel::GetNthColumn(PRUint32 n) const +{ + if (n == 0) + return mSingleColumn; + else if (n == 1) + return mSecondColumn; + else return mThirdColumn; +} + +void nsHTTreeDataModel::SetVisibleColumnCount(PRUint32 columnCount) +{ + mVisibleColumnCount = columnCount; +} + +PRUint32 nsHTTreeDataModel::GetControlStripItemCount() const +{ + return 3; +} + +nsTreeControlStripItem* nsHTTreeDataModel::GetNthControlStripItem(PRUint32 n) const +{ + return mSingleControlStripItem; +} + +void nsHTTreeDataModel::GetControlStripCloseText(nsString& closeText) const +{ + closeText = "Close"; +} + +PRBool nsHTTreeDataModel::ShowTitleBar() const +{ + return PR_TRUE; +} + +PRBool nsHTTreeDataModel::ShowTitleBarText() const +{ + return PR_TRUE; +} + +PRBool nsHTTreeDataModel::ShowControlStrip() const +{ + return PR_TRUE; +} + +PRBool nsHTTreeDataModel::ShowColumnHeaders() const +{ + return PR_TRUE; +} + +void nsHTTreeDataModel::GetTitleBarStyle(nsIDeviceContext* dc, nsBasicStyleInfo& styleInfo) const +{ + // Initialize the font. + nsString fontFamily("Haettenschweiler"); + int fontSize = 24; + int fontWeight = 400; + int fontStyle = NS_FONT_STYLE_NORMAL; + int fontDecoration = NS_FONT_DECORATION_NONE; + + float t2d; + dc->GetTwipsToDevUnits(t2d); + nsFont theFont(fontFamily, fontStyle, NS_FONT_VARIANT_NORMAL, + fontWeight, fontDecoration, + nscoord(t2d * NSIntPointsToTwips(fontSize))); + + styleInfo.font = theFont; + + // Init the colors + styleInfo.foregroundColor = NS_RGB(255,255,255); + styleInfo.backgroundColor = NS_RGB(0,0,0); + + styleInfo.pBackgroundImage = GetTitleBGImage(); +} + +void nsHTTreeDataModel::GetColumnHeaderStyle(nsIDeviceContext* dc, nsColumnHeaderStyleInfo& styleInfo) const +{ + // Initialize the font. + nsString fontFamily("Lucida Handwriting"); + int fontSize = 12; + int fontWeight = 400; + int fontStyle = NS_FONT_STYLE_NORMAL; + int fontDecoration = NS_FONT_DECORATION_NONE; + + float t2d; + dc->GetTwipsToDevUnits(t2d); + nsFont theFont(fontFamily, fontStyle, NS_FONT_VARIANT_NORMAL, + fontWeight, fontDecoration, + nscoord(t2d * NSIntPointsToTwips(fontSize))); + + styleInfo.font = theFont; + + // Init the colors + styleInfo.foregroundColor = NS_RGB(255,255,255); + styleInfo.backgroundColor = NS_RGB(192,192,192); + styleInfo.sortFGColor = NS_RGB(0,0,0); + styleInfo.sortBGColor = NS_RGB(64,64,64); + + styleInfo.pBackgroundImage = GetColumnHeaderBGImage(); +} + +void nsHTTreeDataModel::GetControlStripStyle(nsIDeviceContext* dc, nsBasicStyleInfo& styleInfo) const +{ + // Initialize the font. + nsString fontFamily("Arial Narrow"); + int fontSize = 12; + int fontWeight = 400; + int fontStyle = NS_FONT_STYLE_NORMAL; + int fontDecoration = NS_FONT_DECORATION_NONE; + + float t2d; + dc->GetTwipsToDevUnits(t2d); + nsFont theFont(fontFamily, fontStyle, NS_FONT_VARIANT_NORMAL, + fontWeight, fontDecoration, + nscoord(t2d * NSIntPointsToTwips(fontSize))); + + styleInfo.font = theFont; + + // Init the colors + styleInfo.foregroundColor = NS_RGB(255,255,255); + styleInfo.backgroundColor = NS_RGB(0,0,0); + + styleInfo.pBackgroundImage = GetControlStripBGImage(); +} + +void nsHTTreeDataModel::GetTitleBarText(nsString& text) const +{ + text = "Bookmarks"; +} + +// Protected Helpers +nsIImage* nsHTTreeDataModel::GetTitleBGImage() const +{ + nsString url("http://www.shadowland.org/images/ancient_glyphs.jpg"); + if (mTitleBGRequest == nsnull) + mTitleBGRequest = RequestImage(url); + return mTitleBGRequest->GetImage(); +} + +nsIImage* nsHTTreeDataModel::GetControlStripBGImage() const +{ + nsString url("http://www.shadowland.org/images/minute_bumps.jpg"); + if (mControlStripBGRequest == nsnull) + mControlStripBGRequest = RequestImage(url); + return mControlStripBGRequest->GetImage(); +} + +nsIImage* nsHTTreeDataModel::GetColumnHeaderBGImage() const +{ + nsString url("http://www.shadowland.org/images/tapestry.jpg"); + if (mColumnHeaderBGRequest == nsnull) + mColumnHeaderBGRequest = RequestImage(url); + return mColumnHeaderBGRequest->GetImage(); +} + +nsIImageRequest* nsHTTreeDataModel::RequestImage(nsString& reqUrl) const +{ + nsIImageGroup* pGroup = GetImageGroup(); + + char * url = reqUrl.ToNewCString(); + + nsIImageRequest * request; + request = pGroup->GetImage(url, + (nsIImageRequestObserver*)this, + NULL, 0, 0, + 0); + delete url; + + return request; +} + +// image request observer implementation +void nsHTTreeDataModel::Notify(nsIImageRequest *aImageRequest, + nsIImage *aImage, + nsImageNotification aNotificationType, + PRInt32 aParam1, PRInt32 aParam2, + void *aParam3) +{ + if (aNotificationType == nsImageNotification_kImageComplete) + { + // Notify the data source that we loaded. It can then inform the data source listener + // regarding what happened. + ImageLoaded(nsnull); + } +} + +void nsHTTreeDataModel::NotifyError(nsIImageRequest *aImageRequest, + nsImageError aErrorType) +{ +} \ No newline at end of file diff --git a/widget/src/xpwidgets/nsHTTreeDataModel.h b/widget/src/xpwidgets/nsHTTreeDataModel.h new file mode 100644 index 000000000000..929dee6f12e4 --- /dev/null +++ b/widget/src/xpwidgets/nsHTTreeDataModel.h @@ -0,0 +1,112 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsHTTreeDataModel_h___ +#define nsHTTreeDataModel_h___ + +#include "nsHTDataModel.h" +#include "nsTreeDataModel.h" +#include "nsIImageObserver.h" + +class nsTreeColumn; +class nsTreeControlStripItem; + +//------------------------------------------------------------ +// An abstract API for communication with a hierarchical store of +// information. Iteration over children in the model is provided. +// The model also provides a flattened view of the tree (a list +// of visible nodes). +//------------------------------------------------------------ + +class nsHTTreeDataModel : public nsHTDataModel, public nsTreeDataModel, public nsIImageRequestObserver + +{ +public: + nsHTTreeDataModel(); + virtual ~nsHTTreeDataModel(); + + // Isupports interface ------------------ + NS_DECL_ISUPPORTS + + // IImageRequestObserver Interface ---------------- + void Notify(nsIImageRequest *aImageRequest, + nsIImage *aImage, + nsImageNotification aNotificationType, + PRInt32 aParam1, PRInt32 aParam2, + void *aParam3); + + void NotifyError(nsIImageRequest *aImageRequest, + nsImageError aErrorType); + // End of interfaces + + // Functions inherited from abstract hierarchical data model should be delegated to our + // concrete base class + virtual nsHierarchicalDataItem* GetRoot() const { return GetRootDelegate(); } + virtual PRUint32 GetFirstVisibleItemIndex() const { return GetFirstVisibleItemIndexDelegate(); }; + virtual void SetFirstVisibleItemIndex(PRUint32 index) { SetFirstVisibleItemIndexDelegate(index); }; + virtual nsHierarchicalDataItem* GetNthItem(PRUint32 n) const { return GetNthItemDelegate(n) ;}; + virtual void SetDataModelListener(nsDataModelWidget* pListener) { SetDataModelListenerDelegate(pListener); }; + // End of delegated functions + + // Column Iteration + virtual PRUint32 GetVisibleColumnCount() const; + virtual PRUint32 GetColumnCount() const; + virtual nsTreeColumn* GetNthColumn(PRUint32 n) const; + virtual void SetVisibleColumnCount(PRUint32 n); + + // Control Strip Iteration + virtual PRUint32 GetControlStripItemCount() const; + virtual nsTreeControlStripItem* GetNthControlStripItem(PRUint32 n) const; + virtual void GetControlStripCloseText(nsString& closeText) const; + + // Visibility Queries + virtual PRBool ShowTitleBar() const; + virtual PRBool ShowTitleBarText() const; + virtual PRBool ShowColumnHeaders() const; + virtual PRBool ShowControlStrip() const; + + // Style Retrievers + virtual void GetTitleBarStyle(nsIDeviceContext* pContext, + nsBasicStyleInfo& styleInfo) const; + virtual void GetColumnHeaderStyle(nsIDeviceContext* pContext, + nsColumnHeaderStyleInfo& styleInfo) const; + virtual void GetControlStripStyle(nsIDeviceContext* pContext, + nsBasicStyleInfo& styleInfo) const; + + // Text for the title bar, control strip and column headers + virtual void GetTitleBarText(nsString& text) const; + +protected: + nsIImageRequest* RequestImage(nsString& reqUrl) const; // Helper to kick off the image load. + nsIImage* GetTitleBGImage() const; + nsIImage* GetControlStripBGImage() const; + nsIImage* GetColumnHeaderBGImage() const; + +private: + nsTreeColumn *mSingleColumn, *mSecondColumn, *mThirdColumn; + nsTreeControlStripItem *mSingleControlStripItem; + + PRUint32 mVisibleColumnCount; + PRUint32 mTotalColumnCount; + mutable nsIImageRequest* mTitleBGRequest; // The title bar background image + mutable nsIImageRequest* mControlStripBGRequest;// The control strip bg image + mutable nsIImageRequest* mColumnHeaderBGRequest;// The column header background image + +}; + +#endif /* nsHTTreeDataModel_h___ */ diff --git a/widget/src/xpwidgets/nsHTTreeItem.cpp b/widget/src/xpwidgets/nsHTTreeItem.cpp new file mode 100644 index 000000000000..7a4884645306 --- /dev/null +++ b/widget/src/xpwidgets/nsHTTreeItem.cpp @@ -0,0 +1,180 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "nspr.h" +#include "nsString.h" +#include "nsHTTreeItem.h" +#include "nsHTTreeDataModel.h" +#include "nsWidgetsCID.h" +#include "nsRepository.h" +#include "nsIImageObserver.h" +#include "nsIImageRequest.h" +#include "nsIImageGroup.h" + +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +static NS_DEFINE_IID(kIImageObserverIID, NS_IIMAGEREQUESTOBSERVER_IID); + +NS_IMPL_ADDREF(nsHTTreeItem) +NS_IMPL_RELEASE(nsHTTreeItem) + +nsHTTreeItem::nsHTTreeItem() : nsTreeItem(), nsHTItem() +{ + NS_INIT_REFCNT(); + mClosedIconRequest = nsnull; + mOpenIconRequest = nsnull; + mClosedTriggerRequest = nsnull; + mOpenTriggerRequest = nsnull; + mBackgroundRequest = nsnull; +} + +//-------------------------------------------------------------------- +nsHTTreeItem::~nsHTTreeItem() +{ +} + +// ISupports Implementation -------------------------------------------------------------------- +nsresult nsHTTreeItem::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (NULL == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + if (aIID.Equals(kISupportsIID)) { + *aInstancePtr = (void*) (nsISupports *)(nsIImageRequestObserver*)this; + AddRef(); + return NS_OK; + } + if (aIID.Equals(kIImageObserverIID)) { + *aInstancePtr = (void*)(nsIImageRequestObserver*)this; + AddRef(); + return NS_OK; + } + return NS_ERROR_NULL_POINTER; +} + +// TreeItem Implementation --------------------- + +void nsHTTreeItem::GetItemStyle(nsIDeviceContext* dc, nsTreeItemStyleInfo& styleInfo) const +{ + styleInfo.foregroundColor = NS_RGB(0,0,0); + styleInfo.backgroundColor = NS_RGB(240,240,240); + styleInfo.showTrigger = PR_TRUE; + styleInfo.showIcon = PR_TRUE; + styleInfo.leftJustifyTrigger = PR_FALSE; + + if (styleInfo.showTrigger) + styleInfo.pTriggerImage = GetTriggerImage(); + + if (styleInfo.showIcon) + styleInfo.pIconImage = GetIconImage(); + + styleInfo.pBackgroundImage = GetBackgroundImage(); +} + +nsIImage* nsHTTreeItem::GetTriggerImage() const +{ + // TODO: Really read in these properties + nsString openTriggerURL("file:///c|/Program%20Files/SL/CLIENT/IMAGES/overlay.gif"); + nsString closedTriggerURL("file:///c|/Program%20Files/SL/CLIENT/IMAGES/overlay.gif"); + + if (IsExpanded()) + { + if (mOpenTriggerRequest == nsnull) + { + // Request the image. + mOpenTriggerRequest = RequestImage(openTriggerURL); + } + return mOpenTriggerRequest->GetImage(); + } + else + { + if (mClosedTriggerRequest == nsnull) + mClosedTriggerRequest = RequestImage(closedTriggerURL); + return mClosedTriggerRequest->GetImage(); + } +} + +nsIImage* nsHTTreeItem::GetIconImage() const +{ + nsString openIconURL("file:///c|/Program%20Files/SL/CLIENT/IMAGES/OpenRead.gif"); + nsString closedIconURL("file:///c|/Program%20Files/SL/CLIENT/IMAGES/ClosedRead.gif"); + + if (IsExpanded()) + { + if (mOpenIconRequest == nsnull) + mOpenIconRequest = RequestImage(openIconURL); + return mOpenIconRequest->GetImage(); + } + else + { + if (mClosedIconRequest == nsnull) + mClosedIconRequest = RequestImage(closedIconURL); + return mClosedIconRequest->GetImage(); + } +} + +nsIImage* nsHTTreeItem::GetBackgroundImage() const +{ + nsString bgURL("http://www.shadowland.org/images/chalk.jpg"); + if (mBackgroundRequest == nsnull) + mBackgroundRequest = RequestImage(bgURL); + return mBackgroundRequest->GetImage(); +} + +nsIImageRequest* nsHTTreeItem::RequestImage(nsString& reqUrl) const +{ + nsHTTreeDataModel* pDataModel = (nsHTTreeDataModel*)(mDataModel); + nsIImageGroup* pGroup = pDataModel->GetImageGroup(); + + char * url = reqUrl.ToNewCString(); + + nsIImageRequest * request; + request = pGroup->GetImage(url, + (nsIImageRequestObserver*)this, + NULL, 0, 0, + 0); + delete url; + + return request; +} + +void nsHTTreeItem::GetTextForColumn(nsTreeColumn* pColumn, nsString& nodeText) const +{ + nodeText = "Node Stuff"; +} + +// image request observer implementation +void nsHTTreeItem::Notify(nsIImageRequest *aImageRequest, + nsIImage *aImage, + nsImageNotification aNotificationType, + PRInt32 aParam1, PRInt32 aParam2, + void *aParam3) +{ + if (aNotificationType == nsImageNotification_kImageComplete) + { + // Notify the data source that we loaded. It can then inform the data source listener + // regarding what happened. + nsHTTreeDataModel* pDataModel = (nsHTTreeDataModel*)(mDataModel); + if (pDataModel) + pDataModel->ImageLoaded(this); + } +} + +void nsHTTreeItem::NotifyError(nsIImageRequest *aImageRequest, + nsImageError aErrorType) +{ +} \ No newline at end of file diff --git a/widget/src/xpwidgets/nsHTTreeItem.h b/widget/src/xpwidgets/nsHTTreeItem.h new file mode 100644 index 000000000000..ad7bff10276c --- /dev/null +++ b/widget/src/xpwidgets/nsHTTreeItem.h @@ -0,0 +1,80 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsHTTreeItem_h___ +#define nsHTTreeItem_h___ + +#include "nsTreeItem.h" +#include "nsHTItem.h" +#include "nsIImageObserver.h" + +class nsHTDataModel; +class nsIImageGroup; + +//------------------------------------------------------------ +// This class functions as the data source for column information (things like +// width, desired percentage, and sorting). + +class nsHTTreeItem : public nsTreeItem, public nsHTItem, public nsIImageRequestObserver + +{ +public: + nsHTTreeItem(); + virtual ~nsHTTreeItem(); + + // Isupports interface ------------------ + NS_DECL_ISUPPORTS + + // IImageRequestObserver Interface ---------------- + void Notify(nsIImageRequest *aImageRequest, + nsIImage *aImage, + nsImageNotification aNotificationType, + PRInt32 aParam1, PRInt32 aParam2, + void *aParam3); + + void NotifyError(nsIImageRequest *aImageRequest, + nsImageError aErrorType); + // End of interfaces + + // All functions inherited from HierarchicalDataItem are delegated to + // the concrete implementation. + virtual PRBool IsExpanded() const { return IsExpandedDelegate(); }; + virtual PRUint32 GetIndentationLevel() const { return GetIndentationLevelDelegate(); }; + virtual void SetDataModel(nsHierarchicalDataModel* pDataModel) { SetDataModelDelegate(pDataModel); }; + // End of delegated functions + + virtual void GetItemStyle(nsIDeviceContext* dc, + nsTreeItemStyleInfo& styleInfo) const; + + virtual void GetTextForColumn(nsTreeColumn* pColumn, nsString& nodeText) const; + +protected: + nsIImageRequest* RequestImage(nsString& reqUrl) const; // Helper to kick off the image load. + nsIImage* GetTriggerImage() const; + nsIImage* GetIconImage() const; + nsIImage* GetBackgroundImage() const; + +protected: + mutable nsIImageRequest* mClosedIconRequest; // Closed image + mutable nsIImageRequest* mOpenIconRequest; // Open image + mutable nsIImageRequest* mClosedTriggerRequest; // Closed trigger image + mutable nsIImageRequest* mOpenTriggerRequest; // Open trigger image + mutable nsIImageRequest* mBackgroundRequest; // The background image +}; + +#endif /* nsHTTreeItem_h___ */ diff --git a/widget/src/xpwidgets/nsHierarchicalDataItem.h b/widget/src/xpwidgets/nsHierarchicalDataItem.h new file mode 100644 index 000000000000..46bdfe204f7d --- /dev/null +++ b/widget/src/xpwidgets/nsHierarchicalDataItem.h @@ -0,0 +1,43 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsHierarchicalDataItem_h___ +#define nsHierarchicalDataItem_h___ + +class nsHierarchicalDataModel; + +//------------------------------------------------------------ +// A single item in a hierarchical data model. +//------------------------------------------------------------ + +class nsHierarchicalDataItem + +{ +protected: + nsHierarchicalDataItem() {}; // Disallow instantiation of abstract class. + +public: + virtual ~nsHierarchicalDataItem() {}; + + virtual PRBool IsExpanded() const = 0; + virtual PRUint32 GetIndentationLevel() const = 0; + + virtual void SetDataModel(nsHierarchicalDataModel* pDataModel) = 0; +}; + +#endif /* nsHierarchicalDataItem_h___ */ diff --git a/widget/src/xpwidgets/nsHierarchicalDataModel.h b/widget/src/xpwidgets/nsHierarchicalDataModel.h new file mode 100644 index 000000000000..feff6cc3ee90 --- /dev/null +++ b/widget/src/xpwidgets/nsHierarchicalDataModel.h @@ -0,0 +1,68 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsHierarchicalDataModel_h___ +#define nsHierarchicalDataModel_h___ + +class nsHierarchicalDataItem; +class nsDataModelWidget; + +// Style info helper struct shared by most widgets. +struct nsBasicStyleInfo +{ + nsFont font; + nscolor foregroundColor; + nscolor backgroundColor; + nsIImage* pBackgroundImage; + + nsBasicStyleInfo(const nsFont& aFont) + :font(aFont) + { + pBackgroundImage = nsnull; + } +}; + +// ----------------------------------------------------------------- +// An abstract API for communication with a hierarchical store of +// information. Iteration over children in the model is provided. +// The model also provides a flattened view of the tree (a list +// of visible nodes). +//------------------------------------------------------------ + +class nsHierarchicalDataModel + +{ +protected: + nsHierarchicalDataModel() {}; // Disallow instantiation of abstract class. + +public: + virtual ~nsHierarchicalDataModel() {}; + + // Retrieve the root node of the data model. + virtual nsHierarchicalDataItem* GetRoot() const = 0; + + // A visibility hint can be stored and retrieved (e.g., the leftmost or topmost + // item in the current scrolled view). + virtual PRUint32 GetFirstVisibleItemIndex() const = 0; + virtual void SetFirstVisibleItemIndex(PRUint32 index) = 0; + virtual nsHierarchicalDataItem* GetNthItem(PRUint32 n) const = 0; + + virtual void SetDataModelListener(nsDataModelWidget* pListener) = 0; +}; + +#endif /* nsHierarchicalDataModel_h___ */ diff --git a/widget/src/xpwidgets/nsTreeColumn.h b/widget/src/xpwidgets/nsTreeColumn.h new file mode 100644 index 000000000000..09069f0ee747 --- /dev/null +++ b/widget/src/xpwidgets/nsTreeColumn.h @@ -0,0 +1,43 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsTreeColumn_h___ +#define nsTreeColumn_h___ + +class nsTreeColumn + +{ +protected: + nsTreeColumn() {}; // Disallow instantiation of abstract class. + +public: + virtual ~nsTreeColumn() {}; + + // Inspectors + virtual int GetPixelWidth() const = 0; + virtual double GetDesiredPercentage() const = 0; + virtual PRBool IsSortColumn() const = 0; + virtual void GetColumnName(nsString& name) const = 0; + + // Setters + virtual void SetPixelWidth(int newWidth) = 0; + virtual void SetDesiredPercentage(double newPercentage) = 0; + +}; + +#endif /* nsTreeColumn_h___ */ diff --git a/widget/src/xpwidgets/nsTreeControlStripItem.h b/widget/src/xpwidgets/nsTreeControlStripItem.h new file mode 100644 index 000000000000..8d5fddb075b3 --- /dev/null +++ b/widget/src/xpwidgets/nsTreeControlStripItem.h @@ -0,0 +1,34 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsTreeControlStripItem_h___ +#define nsTreeControlStripItem_h___ + +class nsTreeControlStripItem + +{ +protected: + nsTreeControlStripItem() {}; // Disallow instantiation of abstract class. + +public: + virtual ~nsTreeControlStripItem() {}; + + virtual void GetText(nsString& text) const = 0; +}; + +#endif /* nsTreeControlStripItem_h___ */ diff --git a/widget/src/xpwidgets/nsTreeDataModel.h b/widget/src/xpwidgets/nsTreeDataModel.h new file mode 100644 index 000000000000..1e0f218bf689 --- /dev/null +++ b/widget/src/xpwidgets/nsTreeDataModel.h @@ -0,0 +1,128 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsTreeDataModel_h___ +#define nsTreeDataModel_h___ + +#include "nsHierarchicalDataModel.h" + +class nsTreeItem; +class nsTreeColumn; +class nsTreeControlStripItem; + +struct nsColumnHeaderStyleInfo: public nsBasicStyleInfo +{ + nscolor sortFGColor; + nscolor sortBGColor; + nsIImage* pSortBackgroundImage; + PRBool transparentSort; + nsFont sortFont; + + nsColumnHeaderStyleInfo(const nsFont& aFont) + :nsBasicStyleInfo(aFont), sortFont(aFont) + { pSortBackgroundImage = nsnull; }; +}; + +struct nsTreeItemStyleInfo: public nsBasicStyleInfo +{ + PRBool selectWholeLine; + nscolor selectionFGColor; + nscolor selectionBGColor; + nsIImage* pSelectionBackgroundImage; + PRBool transparentSelection; + nsFont selectionFont; + + PRBool rolloverWholeLine; + nscolor rolloverFGColor; + nscolor rolloverBGColor; + nsIImage* pRolloverBackgroundImage; + PRBool transparentRollover; + nsFont rolloverFont; + + nscolor sortFGColor; + nscolor sortBGColor; + nsIImage* pSortBackgroundImage; + PRBool transparentSort; + nsFont sortFont; + + PRBool showTrigger; + PRBool leftJustifyTrigger; + PRBool showIcon; + + nsIImage* pTriggerImage; + nsIImage* pIconImage; + + nscolor showHorizontalDivider; + nscolor horizontalDividerColor; + + nscolor showVerticalDivider; + nscolor verticalDividerColor; + + nsTreeItemStyleInfo(const nsFont& aFont) + :nsBasicStyleInfo(aFont), sortFont(aFont), selectionFont(aFont), rolloverFont(aFont) + { + pSelectionBackgroundImage = pSortBackgroundImage = + pTriggerImage = pIconImage = nsnull; + }; +}; + +//------------------------------------------------------------ +// An abstract API for communication with a hierarchical store of +// information that is designed to go into a tree widget (a widget +// with tree lines and multiple columns). +//------------------------------------------------------------ + +class nsTreeDataModel : public nsHierarchicalDataModel + +{ +protected: + nsTreeDataModel() {}; // Disallow instantiation of abstract class. + +public: + virtual ~nsTreeDataModel() {}; + + // Column APIs + virtual PRUint32 GetVisibleColumnCount() const = 0; + virtual PRUint32 GetColumnCount() const = 0; + virtual nsTreeColumn* GetNthColumn(PRUint32 n) const = 0; + virtual void SetVisibleColumnCount(PRUint32 n) = 0; + + // Control Strip Iteration + virtual PRUint32 GetControlStripItemCount() const = 0; + virtual nsTreeControlStripItem* GetNthControlStripItem(PRUint32 n) const = 0; + virtual void GetControlStripCloseText(nsString& closeText) const = 0; + + // Visibility Queries + virtual PRBool ShowTitleBar() const = 0; + virtual PRBool ShowTitleBarText() const = 0; + virtual PRBool ShowColumnHeaders() const = 0; + virtual PRBool ShowControlStrip() const = 0; + + // Style Retrievers + virtual void GetTitleBarStyle(nsIDeviceContext* pContext, + nsBasicStyleInfo& styleInfo) const = 0; + virtual void GetColumnHeaderStyle(nsIDeviceContext* pContext, + nsColumnHeaderStyleInfo& styleInfo) const = 0; + virtual void GetControlStripStyle(nsIDeviceContext* pContext, + nsBasicStyleInfo& styleInfo) const = 0; + + // Text for the title bar + virtual void GetTitleBarText(nsString& text) const = 0; +}; + +#endif /* nsTreeDataModel_h___ */ diff --git a/widget/src/xpwidgets/nsTreeItem.h b/widget/src/xpwidgets/nsTreeItem.h new file mode 100644 index 000000000000..1c16b5a200b9 --- /dev/null +++ b/widget/src/xpwidgets/nsTreeItem.h @@ -0,0 +1,53 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsTreeItem_h___ +#define nsTreeItem_h___ + +class nsTreeColumn; +class nsIDeviceContext; +class nsIImage; + +#include "nsColor.h" +#include "nsFont.h" +#include "nsTreeDataModel.h" + +//------------------------------------------------------------ +// A single item in a hierarchical data model for a tree widget +// with columns. +//------------------------------------------------------------ + +#include "nsHierarchicalDataItem.h" + +class nsTreeItem : public nsHierarchicalDataItem + +{ +protected: + nsTreeItem() {}; // Disallow instantiation of abstract class. + +public: + virtual ~nsTreeItem() {}; + + virtual void GetItemStyle(nsIDeviceContext* dc, + nsTreeItemStyleInfo& styleInfo) const = 0; + + virtual void GetTextForColumn(nsTreeColumn* pColumn, nsString& nodeText) const = 0; + +}; + +#endif /* nsTreeItem_h___ */ diff --git a/widget/src/xpwidgets/nsTreeView.cpp b/widget/src/xpwidgets/nsTreeView.cpp new file mode 100644 index 000000000000..30e6c48fe6b4 --- /dev/null +++ b/widget/src/xpwidgets/nsTreeView.cpp @@ -0,0 +1,1016 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#include "nspr.h" +#include "nsString.h" +#include "nsWidgetsCID.h" +#include "nsIWidget.h" +#include "nsRepository.h" +#include "nsFont.h" +#include "nsIFontMetrics.h" +#include "nsIDeviceContext.h" +#include "nsIImageGroup.h" +#include "nsIImage.h" +#include "nsTreeView.h" +#include "nsHTTreeDataModel.h" + +static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); +static NS_DEFINE_IID(kCTreeViewCID, NS_TREEVIEW_CID); +static NS_DEFINE_IID(kITreeViewIID, NS_ITREEVIEW_IID); +static NS_DEFINE_IID(kIWidgetIID, NS_IWIDGET_IID); + +NS_IMPL_ADDREF(nsTreeView) +NS_IMPL_RELEASE(nsTreeView) + +static nsEventStatus PR_CALLBACK +HandleTreeEvent(nsGUIEvent *aEvent) +{ + nsEventStatus result = nsEventStatus_eIgnore; + nsITreeView * tree; + if (NS_OK == aEvent->widget->QueryInterface(kITreeViewIID,(void**)&tree)) { + result = tree->HandleEvent(aEvent); + NS_RELEASE(tree); + } + return result; +} + +NS_METHOD nsTreeView::Create(nsIWidget *aParent, + const nsRect &aRect, + EVENT_CALLBACK aHandleEventFunction, + nsIDeviceContext *aContext, + nsIAppShell *aAppShell, + nsIToolkit *aToolkit, + nsWidgetInitData *aInitData) +{ + nsresult answer = ChildWindow::Create(aParent, aRect, + nsnull != aHandleEventFunction ? aHandleEventFunction : HandleTreeEvent, + aContext, aAppShell, aToolkit, aInitData); + + if (mDataModel) + mDataModel->SetDataModelListener(this); + + return answer; +} + +nsTreeView::nsTreeView() : nsITreeView(), nsDataModelWidget() +{ + NS_INIT_REFCNT(); + mDataModel = nsnull; + mColumnBarRect.SetRect(0,0,0,0); + mTitleBarRect.SetRect(0,0,0,0); + mControlStripRect.SetRect(0,0,0,0); + mTreeRect.SetRect(0,0,0,0); + mCachedMoveRect.SetRect(0,0,0,0); + mMouseDown = PR_FALSE; + mMouseDragging = PR_FALSE; + mDraggingColumnHeader = PR_FALSE; + mDraggingColumnEdge = PR_FALSE; + mLastXPosition = 0; + mMousedColumnIndex = 0; + + // The data model is created and bound to the widget. + mDataModel = new nsHTTreeDataModel(); +} + +//-------------------------------------------------------------------- +nsTreeView::~nsTreeView() +{ + // The tree has the responsibility of deleting the data model. + delete mDataModel; +} + +// ISupports Implementation -------------------------------------------------------------------- +nsresult nsTreeView::QueryInterface(REFNSIID aIID, void** aInstancePtr) +{ + if (NULL == aInstancePtr) { + return NS_ERROR_NULL_POINTER; + } + if (aIID.Equals(kITreeViewIID)) { + *aInstancePtr = (void*) (nsITreeView *)this; + AddRef(); + return NS_OK; + } + return (nsWindow::QueryInterface(aIID, aInstancePtr)); +} + +void nsTreeView::HandleDataModelEvent(int anEvent, nsHierarchicalDataItem* pItem) +{ + Invalidate(PR_FALSE); +} + +//----------------------------------------------------- +nsEventStatus nsTreeView::HandleEvent(nsGUIEvent *aEvent) +{ + if (aEvent->message == NS_SIZE) + { + nsRect r; + aEvent->widget->GetBounds(r); + + // Adjust our column headers' positions. + ResizeColumns(r.width); + + // Do a repaint. + if (mTitleBarRect.width != r.width) + aEvent->widget->Invalidate(PR_FALSE); + } + else if (aEvent->message == NS_PAINT) + { + nsRect r; + aEvent->widget->GetBounds(r); + r.x = 0; + r.y = 0; + + nsRect rect(r); + + nsDrawingSurface ds; + nsIRenderingContext * ctx = ((nsPaintEvent*)aEvent)->renderingContext; + + ctx->CreateDrawingSurface(&r, 0, ds); + ctx->SelectOffScreenDrawingSurface(ds); + + if (mDataModel) + { + // Paint the title bar. + PaintTitleBar(ctx, r); + + // Paint the control strip. + PaintControlStrip(ctx, r); + + // Paint the column bar. + PaintColumnBar(ctx, r); + + // Paint the tree. + PaintTreeLines(ctx, r); + } + ctx->CopyOffScreenBits(ds, 0, 0, rect, NS_COPYBITS_USE_SOURCE_CLIP_REGION); + ctx->DestroyDrawingSurface(ds); + } + else if (aEvent->message == NS_MOUSE_EXIT) + { + aEvent->widget->Invalidate(PR_FALSE); // Makes sure we ditch rollover feedback on exit. + } + else if (aEvent->message == NS_MOUSE_MOVE) + { + mCachedMovePoint.x = aEvent->point.x; + mCachedMovePoint.y = aEvent->point.y; + + if (mMouseDown) + { + if (!mMouseDragging) + { + // We have the left mouse button down and we're moving. Check to see if we should + // initiate a drag and drop operation. + if (mCachedMovePoint.x < mCachedDownPoint.x - 3 || + mCachedMovePoint.x > mCachedDownPoint.x + 3 || + mCachedMovePoint.y < mCachedDownPoint.y - 3 || + mCachedMovePoint.y > mCachedDownPoint.y + 3) + { + // We're dragging baby. + mMouseDragging = PR_TRUE; + + // Question is, just what are we dragging? + if (mColumnBarRect.Contains(mCachedDownPoint.x, mCachedDownPoint.y)) + { + // The user is messing with the columns. Either a column header + // is being resized or a column is being dragged. + if (DownOnColumnEdge(mCachedDownPoint)) + { + mDraggingColumnEdge = PR_TRUE; + mLastXPosition = mCachedDownPoint.x; + DragColumnEdge(mCachedMovePoint.x); + } + } + } + } + else + { + if (mDraggingColumnEdge) + { + // Keep on dragging. + DragColumnEdge(mCachedMovePoint.x); + } + } + } + else + { + aEvent->widget->Invalidate(PR_FALSE); + + if (mColumnBarRect.Contains(mCachedMovePoint.x, mCachedMovePoint.y) && + DownOnColumnEdge(mCachedMovePoint)) + { + // Change the cursor to a WE resize if on a column edge. + aEvent->widget->SetCursor(eCursor_sizeWE); + } + else aEvent->widget->SetCursor(eCursor_standard); + } + } + else if (aEvent->message == NS_MOUSE_LEFT_BUTTON_DOWN) + { + mCachedDownPoint.x = aEvent->point.x; + mCachedDownPoint.y = aEvent->point.y; + + mMouseDown = PR_TRUE; // We could potentially initiate a drag. Don't kick it off until + // we know for sure. + } + else if (aEvent->message = NS_MOUSE_LEFT_BUTTON_UP) + { + if (mMouseDown) + { + mCachedMovePoint.x = aEvent->point.x; + mCachedMovePoint.y = aEvent->point.y; + + mMouseDown = PR_FALSE; + mMouseDragging = PR_FALSE; + + if (mDraggingColumnEdge) + { + // Finish up. + DragColumnEdge(mCachedMovePoint.x); + + // TODO: Need to recompute the column percentages + + mDraggingColumnEdge = PR_FALSE; + } + + if (mColumnBarRect.Contains(mCachedMovePoint.x, mCachedMovePoint.y)) + { + int currentPosition = 0; + int remainingSpace = mColumnBarRect.width; + int totalSpace = mColumnBarRect.width; + PRUint32 count = mDataModel->GetVisibleColumnCount(); + + // The user boinked a column or a pusher. Figure out which. + for (PRUint32 n = 0; n < count; n++) + { + // Fetch each column. + nsTreeColumn* pColumn = mDataModel->GetNthColumn(n); + int pixelWidth = pColumn->GetPixelWidth(); + remainingSpace -= pixelWidth; + currentPosition += pixelWidth; + + // TODO: See if we hit this column header + } + + // Must have hit a pusher + if (mCachedMovePoint.x < (currentPosition + (remainingSpace / 2))) + ShowColumn(); // Hit the left pusher + else HideColumn(); // Hit the right pusher + } + } + } + return nsEventStatus_eIgnore; +} + +void nsTreeView::PaintTitleBar(nsIRenderingContext* drawCtx, + nsRect& rect) +{ + mTitleBarRect.SetRect(0,0,0,0); + if (mDataModel) // There is no title bar shown unless we have a valid data model to query. + { + nsRect titleBarRect(rect); + int titleBarHeight = 0; + int fontHeight = 0; + + if (mDataModel->ShowTitleBar()) + { + titleBarHeight = 30; // Assume an initial height of 30. Change if font doesn't fit. + nsIDeviceContext* dc = GetDeviceContext(); + float t2d; + dc->GetTwipsToDevUnits(t2d); + + // Need to figure out our style info for the title bar. + nsFont titleBarFont("MS Sans Serif", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL, + 400, NS_FONT_DECORATION_NONE, + nscoord(t2d * NSIntPointsToTwips(10))); + + nsBasicStyleInfo styleInfo(titleBarFont); + + mDataModel->GetTitleBarStyle(dc, styleInfo); + + NS_RELEASE(dc); + drawCtx->SetFont(styleInfo.font); + nsIFontMetrics* fontMetrics; + drawCtx->GetFontMetrics(fontMetrics); + fontMetrics->GetHeight(fontHeight); + titleBarHeight = fontHeight + 4; // Pad just a little. + NS_RELEASE(fontMetrics); + + // Modify the rect we'll be returning for future painting. + titleBarRect.height = titleBarHeight; + rect.y = titleBarRect.height; + rect.height -= titleBarRect.height; + mTitleBarRect = titleBarRect; + + // First we lay down the background, and then we draw the text. + drawCtx->SetColor(styleInfo.backgroundColor); + drawCtx->FillRect(titleBarRect); + + // If there is a background image, draw it. + if (styleInfo.pBackgroundImage) + PaintBackgroundImage(drawCtx, styleInfo.pBackgroundImage, mTitleBarRect); + + if (mDataModel->ShowTitleBarText()) // Only show the text if we should. + { + drawCtx->SetColor(styleInfo.foregroundColor); + nsString titleBarText; + mDataModel->GetTitleBarText(titleBarText); + DrawCroppedString(drawCtx, titleBarText, mTitleBarRect); + } + } + } +} + +void nsTreeView::PaintControlStrip(nsIRenderingContext* drawCtx, + nsRect& rect) +{ + // Paint the add box, the edit box, and the close box. + mControlStripRect.SetRect(0,0,0,0); + if (mDataModel) // There is no title bar shown unless we have a valid data source to query. + { + nsRect controlStripRect(rect); + int controlStripHeight = 0; // Assume an initial height of 0. + int fontHeight = 0; + nsIDeviceContext* dc = GetDeviceContext(); + + if (mDataModel->ShowControlStrip()) + { + // Need to figure out which font we're using for the control strip + float t2d; + dc->GetTwipsToDevUnits(t2d); + nsFont controlStripFont("MS Sans Serif", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL, + 400, NS_FONT_DECORATION_NONE, + nscoord(t2d * NSIntPointsToTwips(10))); + + nsBasicStyleInfo styleInfo(controlStripFont); + mDataModel->GetControlStripStyle(dc, styleInfo); + + NS_RELEASE(dc); + + drawCtx->SetFont(styleInfo.font); + nsIFontMetrics* fontMetrics; + drawCtx->GetFontMetrics(fontMetrics); + fontMetrics->GetHeight(fontHeight); + controlStripHeight = fontHeight + 4; // Pad just a little. + NS_RELEASE(fontMetrics); + + // Modify the rect we'll be returning for future painting. + controlStripRect.height = controlStripHeight; + rect.y += controlStripRect.height; + rect.height -= controlStripRect.height; + mControlStripRect = controlStripRect; + + // We now know the size of the control strip. Retrieve the color information. + + // First we lay down the background, and then we draw the text. + drawCtx->SetColor(styleInfo.backgroundColor); + drawCtx->FillRect(controlStripRect); + + // If there is a background image, draw it. + if (styleInfo.pBackgroundImage) + PaintBackgroundImage(drawCtx, styleInfo.pBackgroundImage, mControlStripRect); + + drawCtx->SetColor(styleInfo.foregroundColor); + + // Iterate over the control strip items. + PRUint32 itemCount = mDataModel->GetControlStripItemCount(); + int xOffset = 2; + for (PRUint32 i = 0; i < itemCount; i++) + { + nsTreeControlStripItem* pItem = mDataModel->GetNthControlStripItem(i); + nsString itemText; + pItem->GetText(itemText); + + drawCtx->DrawString(itemText, xOffset, controlStripRect.y + 2, 1); // Indent slightly + + // Offset by the width of the text + 10. + int strWidth = 0; + drawCtx->GetWidth(itemText, strWidth); + + nsRect itemRect(xOffset-2, controlStripRect.y, + strWidth + 4, controlStripRect.height); + + xOffset += strWidth + 10; + + if (itemRect.Contains(mCachedMovePoint.x, mCachedMovePoint.y)) + drawCtx->DrawRect(itemRect); + } + + // Draw the close text at the rightmost side of the tree. + nsString nsCloseText; + mDataModel->GetControlStripCloseText(nsCloseText); + int strWidth = 0; + drawCtx->GetWidth(nsCloseText, strWidth); + drawCtx->DrawString(nsCloseText, controlStripRect.width - strWidth - 2, + controlStripRect.y + 2, 1); + nsRect closeRect = nsRect(controlStripRect.width - strWidth - 4, + controlStripRect.y, + strWidth + 4, + controlStripRect.height); + + if (closeRect.Contains(mCachedMovePoint.x, mCachedMovePoint.y)) + drawCtx->DrawRect(closeRect); + } + } +} + +void nsTreeView::PaintColumnBar(nsIRenderingContext* drawCtx, + nsRect& rect) +{ + // The painting of the column headers along with the pushers. + if (mDataModel) + { + // The very first step is to find out exactly how tall the column + // bar needs to be given the font being used. + + BOOL needToResizeColumns = FALSE; + if (mDataModel->ShowColumnHeaders() && mColumnBarRect == nsRect(0,0,0,0)) + { + // Column sizes haven't been properly computed yet. Let's make + // sure we're sane. + needToResizeColumns = PR_TRUE; + } + + mColumnBarRect.SetRect(0,0,0,0); + + nsRect columnBarRect(rect); + int columnBarHeight = 0; // Assume an initial height of 0. + int fontHeight = 0; + + if (mDataModel->ShowColumnHeaders()) // Default assumption is that we show it. + { + // Need to figure out our style info. + nsIDeviceContext* dc = GetDeviceContext(); + float t2d; + dc->GetTwipsToDevUnits(t2d); + nsFont columnHeaderFont("MS Sans Serif", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL, + 400, NS_FONT_DECORATION_NONE, + nscoord(t2d * NSIntPointsToTwips(10))); + + nsColumnHeaderStyleInfo styleInfo(columnHeaderFont); + mDataModel->GetColumnHeaderStyle(dc, styleInfo); + + NS_RELEASE(dc); + drawCtx->SetFont(styleInfo.font); + nsIFontMetrics* fontMetrics; + drawCtx->GetFontMetrics(fontMetrics); + fontMetrics->GetHeight(fontHeight); + columnBarHeight = fontHeight + 4; // Pad just a little. + NS_RELEASE(fontMetrics); + + // Modify the rect we'll be returning for future painting. + columnBarRect.height = columnBarHeight; + rect.y += columnBarRect.height; + rect.height -= columnBarRect.height; + mColumnBarRect = columnBarRect; + + // We now know the size of the column bar + // If our size info was screwy before, let's sync it up now. + // Don't move this. Code ordering is critical here. + if (needToResizeColumns) + ResizeColumns(columnBarRect.width); + + // First we lay down the background color and image if there is one + drawCtx->SetColor(styleInfo.backgroundColor); + drawCtx->FillRect(mColumnBarRect); + // If there is a background image, draw it. + if (styleInfo.pBackgroundImage) + PaintBackgroundImage(drawCtx, styleInfo.pBackgroundImage, + mColumnBarRect); + + // Draw the columns. + PRUint32 count = mDataModel->GetVisibleColumnCount(); + PRUint32 currentPosition = 0; + for (PRUint32 n = 0; n < count; n++) + { + // Fetch each column. + nsTreeColumn* pColumn = mDataModel->GetNthColumn(n); + if (pColumn) + { + PaintColumnHeader(drawCtx, pColumn, currentPosition, + styleInfo); + } + } + + // Draw the column pushers + int pusherWidth = (int)(mColumnBarRect.height * 1.25); + if (pusherWidth%2 != 0) + pusherWidth++; + int singlePusher = pusherWidth / 2; + + drawCtx->SetColor(styleInfo.foregroundColor); + drawCtx->DrawRect(currentPosition-1, mColumnBarRect.y, + singlePusher+1, mColumnBarRect.height); + + drawCtx->DrawRect(currentPosition+singlePusher-1, + mColumnBarRect.y, singlePusher+1, + mColumnBarRect.height); + + PaintPusherArrow(drawCtx, PR_TRUE, currentPosition, singlePusher); + PaintPusherArrow(drawCtx, PR_FALSE, currentPosition+singlePusher, singlePusher); + } + } +} + +void nsTreeView::PaintColumnHeader(nsIRenderingContext* drawCtx, + nsTreeColumn* pColumn, + PRUint32& currentPosition, + const nsColumnHeaderStyleInfo& styleInfo) +{ + // If we're sorted, then fill with a sort column header color. + PRBool isSortColumn = pColumn->IsSortColumn(); + if (isSortColumn) + drawCtx->SetColor(styleInfo.sortBGColor); + else drawCtx->SetColor(styleInfo.backgroundColor); + + // Compute this column's rectangle. + int pixelWidth = pColumn->GetPixelWidth(); + nsRect colRect(currentPosition, mColumnBarRect.y, pixelWidth, mColumnBarRect.height); + + // Set to foreground color to draw the framing rect and text. + if (isSortColumn) + drawCtx->SetColor(styleInfo.sortFGColor); + else drawCtx->SetColor(styleInfo.foregroundColor); + + // Draw the frame rect. + colRect.x--; // The next two lines assure that there's no ugly left border on the first column + // and that the borderlines of each column header overlap. + colRect.width++; + drawCtx->DrawRect(colRect); + + // Now draw the text. + nsString columnName("Name"); + pColumn->GetColumnName(columnName); + + colRect.x++; + colRect.width--; + DrawCroppedString(drawCtx, columnName, colRect); + + if (isSortColumn) + { + // TODO: Now draw the sort indicator (up or down arrow) as needed. + } + + // Update the current position for the next column. + currentPosition += pixelWidth; +} + +void nsTreeView::PaintPusherArrow(nsIRenderingContext* drawCtx, + PRBool isLeftArrow, int left, int width) +{ + int horStart; + int horEnd; + int change; + if (isLeftArrow) + { + horStart = left+3; + horEnd = left+width-5; + change = 1; + } + else + { + horStart = left+width-5; + horEnd = left+3; + change = -1; + } + + int lineHeight = 0; + for (int i = horStart; i != horEnd; i += change, lineHeight += 2) + { + int vertStart = mColumnBarRect.y + (mColumnBarRect.height - lineHeight)/2; + int vertEnd = vertStart + lineHeight; + + if (vertStart < mColumnBarRect.y + 2) + break; + + drawCtx->DrawLine(i, vertStart, i, vertEnd); + } +} + +void nsTreeView::PaintTreeLines(nsIRenderingContext* drawCtx, + nsRect& rect) +{ + // The fun part. Painting of the individual lines of the tree. + + // Start at the top line, getting the hint for what the top line is + // from the data model.. Let each line paint itself and update its + // position so that the next line knows where to begin. Stop when you run out of lines + // or when you're dealing with lines that are no longer visible. + if (!mDataModel) + return; + + int yPosition = rect.y; + PRUint32 n = mDataModel->GetFirstVisibleItemIndex(); + nsTreeItem* pItem = (nsTreeItem*)mDataModel->GetNthItem(n); + + while (pItem && yPosition < rect.y + rect.height) + { + PaintTreeLine(drawCtx, pItem, yPosition); + n++; + pItem = (nsTreeItem*)mDataModel->GetNthItem(n); + } + + if (yPosition < rect.y + rect.height) + { + // Fill the remaining area. TODO: Account for sort highlighting + nsRect remainderRect(0, yPosition, rect.width, rect.height - yPosition); + nscolor viewBGColor = NS_RGB(240,240,240); + drawCtx->SetColor(viewBGColor); + drawCtx->FillRect(rect); + } +} + +void nsTreeView::PaintTreeLine(nsIRenderingContext* drawCtx, nsTreeItem* pItem, int& yPosition) +{ + // Determine the height of this tree line. It is going to be the max of + // three objects: the trigger image, the icon, and the font height. + // Will take whichever of these three is the largest, and we will add on 5 pixels. + // 4 pixels of padding, and 1 pixel for the horizontal divider line. + // Need to figure out which font we're using for the title bar. + nsIDeviceContext* dc = GetDeviceContext(); + float t2d; + dc->GetTwipsToDevUnits(t2d); + nsFont treeItemFont("MS Sans Serif", NS_FONT_STYLE_NORMAL, NS_FONT_VARIANT_NORMAL, + 400, NS_FONT_DECORATION_NONE, + nscoord(t2d * NSIntPointsToTwips(10))); + nsTreeItemStyleInfo styleInfo(treeItemFont); + + pItem->GetItemStyle(dc, styleInfo); + + int lineHeight = 19; + int fontHeight = 0; + + NS_RELEASE(dc); + drawCtx->SetFont(styleInfo.font); + nsIFontMetrics* fontMetrics; + drawCtx->GetFontMetrics(fontMetrics); + fontMetrics->GetHeight(fontHeight); + + int fontWithPadding = fontHeight + 4; + + int triggerHeight = 0; + int iconHeight = 0; + nsIImage* pTriggerImage = styleInfo.pTriggerImage; + nsIImage* pIconImage = styleInfo.pIconImage; + PRBool showTrigger = styleInfo.showTrigger; + PRBool leftJustifyTrigger = styleInfo.leftJustifyTrigger; + PRBool showIcon = styleInfo.showIcon; + + if (pTriggerImage) + triggerHeight = pTriggerImage->GetHeight(); + if (pIconImage) + iconHeight = pIconImage->GetHeight(); + + lineHeight = fontWithPadding + 1; + if (triggerHeight + 5 > lineHeight) + lineHeight = triggerHeight + 5; // Ensure 2 pixels of padding on either side + 1 for div. + if (iconHeight + 5 > lineHeight) + lineHeight = iconHeight + 5; // Ensure pixel padding plus 1 for div. + + NS_RELEASE(fontMetrics); + + // Modify the position we'll be returning for future painting. + nsRect lineRect(0, yPosition, mColumnBarRect.width, lineHeight); + yPosition += lineHeight; + + // Fill the rect with our BGColor. TODO: Fetch properties etc. + drawCtx->SetColor(styleInfo.backgroundColor); + drawCtx->FillRect(lineRect); + if (styleInfo.pBackgroundImage) + { + PaintBackgroundImage(drawCtx, styleInfo.pBackgroundImage, lineRect); + } + + // Draw the horizontal divider + drawCtx->SetColor(styleInfo.horizontalDividerColor); + drawCtx->DrawLine(0, yPosition-1, mColumnBarRect.width, yPosition-1); + + // Set to foreground color. + drawCtx->SetColor(styleInfo.foregroundColor); + + // Iterate over the visible columns and paint the data specified. + PRUint32 count = mDataModel->GetVisibleColumnCount(); + int currentPosition = 0; + for (PRUint32 n = 0; n < count; n++) + { + // Fetch each column. + nsTreeColumn* pColumn = mDataModel->GetNthColumn(n); + if (pColumn) + { + // Retrieve the column's current pixel width. + int pixelWidth = pColumn->GetPixelWidth(); + + // Draw our text indented slightly, centered in our line rect, and cropped. + nsString nodeText("Column Data"); + pItem->GetTextForColumn(pColumn, nodeText); + + int textStart = currentPosition + 2; + if (n == 0) + { + // This is the image column. + // Draw the trigger image at the appropriate spot. + int indentation = pItem->GetIndentationLevel(); + int pixelIndent = cIndentAmount * indentation; + int iconMargin = cIconMargin; // Distance from trigger edge to icon edge + int triggerStart = 4; + + int triggerWidth = (pTriggerImage && showTrigger ? pTriggerImage->GetWidth() : 0); + int iconStart = triggerStart + triggerWidth + + cIconMargin + pixelIndent; + if (!leftJustifyTrigger) + { + triggerStart = 4 + pixelIndent; + iconStart = triggerStart + triggerWidth + cIconMargin; + } + + if (pTriggerImage && showTrigger) + drawCtx->DrawImage(pTriggerImage, triggerStart, + lineRect.y + (lineHeight-1-triggerHeight)/2); + if (pIconImage) + drawCtx->DrawImage(pIconImage, iconStart, + lineRect.y + (lineHeight-1-iconHeight)/2); + + textStart = iconStart + (showIcon && pIconImage ? pIconImage->GetWidth() : 0) + 2; + } + + // Determine the rect to use. + int start = lineRect.y + (lineHeight-fontWithPadding-1)/2; + nsRect textRect(textStart, start, pixelWidth-2-(textStart-currentPosition), fontWithPadding); + DrawCroppedString(drawCtx, nodeText, textRect); + + currentPosition += pixelWidth; + } + } +} + +void nsTreeView::PaintBackgroundImage(nsIRenderingContext* ctx, + nsIImage* bgImage, const nsRect& constraintRect, + int xSrcOffset, int ySrcOffset) +{ + // This code gets a bit intense. Will comment heavily. + + int imageWidth = bgImage->GetWidth(); // The dimensions of the background image being tiled. + int imageHeight = bgImage->GetHeight(); + + int totalWidth = constraintRect.width; // The dimensions of the space we're + int totalHeight = constraintRect.height; // drawing into. + + if (imageWidth <= 0 || imageHeight <= 0) // Don't draw anything if we don't have a sane image. + return; + + int xSize = imageWidth - xSrcOffset; // The dimensions of the actual tile we'll end + int ySize = imageHeight - ySrcOffset; // up drawing. A subset of the full BG image. + + xSize = (xSize > totalWidth) ? totalWidth : xSize; + ySize = (ySize > totalHeight) ? totalHeight : ySize; + + int rightMostPoint = constraintRect.x + constraintRect.width; // Edges of the space we're + int bottomMostPoint = constraintRect.y + constraintRect.height; // drawing into. + + int xDstOffset = constraintRect.x; // Top-left coordinates in the space where + int yDstOffset = constraintRect.y; // we'll be drawing. Where we'll place the tile. + + int initXOffset = xSrcOffset; + + // Tile vertically until we move out of the constraining rect. + while (yDstOffset < bottomMostPoint) + { + // Tile horizontally until we move out of the constraining rect. + while (xDstOffset < rightMostPoint) + { + // Draw the subimage. Pull the subimage from the larger image + // and then draw it. + ctx->DrawImage(bgImage, nsRect(xSrcOffset, ySrcOffset, xSize, ySize), + nsRect(xDstOffset, yDstOffset, xSize, ySize)); + + // The next subimage will be as much of the full BG image as can fit in the + // constraining rect. If we're at the edge, we don't draw quite as much. + xSrcOffset = 0; + xDstOffset += xSize; + xSize = (xDstOffset + imageWidth) > rightMostPoint ? imageWidth - (xDstOffset + imageWidth) + rightMostPoint : imageWidth; + } + + xSrcOffset = initXOffset; // Start of all rows will be at the same initial x offset. + xDstOffset = constraintRect.x; // Reset our x-position for drawing the next row. + xSize = (xDstOffset + imageWidth) > rightMostPoint ? rightMostPoint - xDstOffset : imageWidth; + + // Determine the height of the next row. Will be as much of the BG image + // as can fit in the constraining rect. If we're at the bottom edge, we don't + // draw quite as much. + ySrcOffset = 0; + yDstOffset += ySize; + ySize = (yDstOffset + imageHeight) > bottomMostPoint ? bottomMostPoint - yDstOffset : imageHeight; + } +} + +void nsTreeView::ShowColumn() +{ + int pusherWidth = (int)(mColumnBarRect.height * 1.25); + if (pusherWidth % 2 != 0) + pusherWidth++; + + int totalSpace = mColumnBarRect.width - pusherWidth; + int remainingSpace = totalSpace; + PRUint32 visColumns = mDataModel->GetVisibleColumnCount(); + PRUint32 totalColumns = mDataModel->GetColumnCount(); + + if (visColumns < totalColumns) + { + visColumns++; + mDataModel->SetVisibleColumnCount(visColumns); + + double newColPercentage = 1.0 / visColumns; + + // Do a recomputation of column widths and percentages + for (PRUint32 i = 0; i < visColumns; i++) + { + nsTreeColumn* pColumn = mDataModel->GetNthColumn(i); + if (i < visColumns-1) + { + // An already visible column is being adjusted + pColumn->SetDesiredPercentage(pColumn->GetDesiredPercentage() * + (1.0 - newColPercentage)); + } + else pColumn->SetDesiredPercentage(newColPercentage); // New column + + pColumn->SetPixelWidth((int)(pColumn->GetDesiredPercentage() * totalSpace)); + remainingSpace -= pColumn->GetPixelWidth(); + if (i == visColumns-1) + pColumn->SetPixelWidth(pColumn->GetPixelWidth() + remainingSpace); + } + + Invalidate(PR_FALSE); + } +} + + +void nsTreeView::HideColumn() +{ + int pusherWidth = (int)(mColumnBarRect.height * 1.25); + if (pusherWidth % 2 != 0) + pusherWidth++; + + int totalSpace = mColumnBarRect.width - pusherWidth; + int remainingSpace = totalSpace; + PRUint32 visColumns = mDataModel->GetVisibleColumnCount(); + PRUint32 totalColumns = mDataModel->GetColumnCount(); + + if (visColumns > 1) + { + visColumns--; + mDataModel->SetVisibleColumnCount(visColumns); + + // Do a recomputation of column widths and percentages + nsTreeColumn* pHiddenColumn = mDataModel->GetNthColumn(visColumns); + double totalPercentage = 1.0 - pHiddenColumn->GetDesiredPercentage(); + for (PRUint32 i = 0; i < visColumns; i++) + { + nsTreeColumn* pColumn = mDataModel->GetNthColumn(i); + pColumn->SetDesiredPercentage(pColumn->GetDesiredPercentage() / totalPercentage); + pColumn->SetPixelWidth((int)(pColumn->GetDesiredPercentage() * totalSpace)); + remainingSpace -= pColumn->GetPixelWidth(); + if (i == visColumns-1) + pColumn->SetPixelWidth(pColumn->GetPixelWidth() + remainingSpace); + + } + + Invalidate(PR_FALSE); + } +} + +void nsTreeView::ResizeColumns(int width) +{ + // Need to do the appropriate resizing of the columns. + PRUint32 count = mDataModel->GetVisibleColumnCount(); + int currentPosition = 0; + int pusherWidth = (int)(mColumnBarRect.height * 1.25); + if (pusherWidth % 2 != 0) + pusherWidth++; + + int remainingSpace = width - pusherWidth; + int totalSpace = remainingSpace; + double newColPercentage = 1.0 / count; + + for (PRUint32 n = 0; n < count; n++) + { + // Fetch each column. + nsTreeColumn* pColumn = mDataModel->GetNthColumn(n); + if (pColumn) + { + double desiredPercentage = pColumn->GetDesiredPercentage(); + int newPixelWidth = (int)(desiredPercentage*totalSpace); + pColumn->SetPixelWidth(newPixelWidth); + remainingSpace -= newPixelWidth; + if (n == count-1) + pColumn->SetPixelWidth(newPixelWidth + remainingSpace); + } + } +} + +PRBool nsTreeView::DownOnColumnEdge(const nsPoint& point) +{ + int x = point.x; // Only x coord is relevant. + if (!mDataModel) return PR_FALSE; + + PRUint32 count = mDataModel->GetVisibleColumnCount(); + int currentPosition = 0; + + for (PRUint32 n = 0; n < count-1; n++) + { + // Fetch each column. + nsTreeColumn* pColumn = mDataModel->GetNthColumn(n); + if (pColumn) + { + int pixelWidth = pColumn->GetPixelWidth(); + if (currentPosition + pixelWidth - 2 <= x && + x <= currentPosition + pixelWidth + 2) + { + // Cache the column hit in case we end up dragging it around. + mMousedColumnIndex = n; + return PR_TRUE; + } + + if (x < currentPosition + pixelWidth) + return PR_FALSE; + + currentPosition += pixelWidth; + } + } + return PR_FALSE; +} + +void nsTreeView::DragColumnEdge(int xPos) +{ + nsTreeColumn* pLeftColumn = mDataModel->GetNthColumn(mMousedColumnIndex); + nsTreeColumn* pRightColumn = mDataModel->GetNthColumn(mMousedColumnIndex+1); + if (pLeftColumn && pRightColumn) + { + // Adjust the two columns' pixel widths. + int leftPixelWidth = pLeftColumn->GetPixelWidth(); + int rightPixelWidth = pRightColumn->GetPixelWidth(); + int dragDiff = ((int)xPos) - ((int)mLastXPosition); + int newLeft = leftPixelWidth+dragDiff; + int newRight = rightPixelWidth-dragDiff; + if (newLeft > cMinColumnWidth && newRight > cMinColumnWidth) + { + pLeftColumn->SetPixelWidth(newLeft); + pRightColumn->SetPixelWidth(newRight); + + mLastXPosition = xPos; + Invalidate(PR_FALSE); + } + } +} + +// Helpers +void nsTreeView::ParseColor(char* colorString, nscolor& colorValue) +{ + if (!NS_ColorNameToRGB(colorString, &colorValue)) + NS_HexToRGB(colorString, &colorValue); +} + +void nsTreeView::DrawCroppedString(nsIRenderingContext* drawCtx, nsString text, + const nsRect& rect) +{ + int strWidth = 0; + drawCtx->GetWidth(text, strWidth); + nsString cropString(text); + if (strWidth + 4 > rect.width) + { + int length = text.Length(); + if (length > 3) + { + cropString = ""; + text.Left(cropString, length - 3); + cropString += "..."; + + drawCtx->GetWidth(cropString, strWidth); + while (strWidth + 4 > rect.width && length > 3) + { + length--; + cropString = ""; + text.Left(cropString, length - 3); + cropString += "..."; + drawCtx->GetWidth(cropString, strWidth); + } + } + } + + // Draw the cropString. + drawCtx->DrawString(cropString, rect.x + 2, rect.y + 2, 1); +} + diff --git a/widget/src/xpwidgets/nsTreeView.h b/widget/src/xpwidgets/nsTreeView.h new file mode 100644 index 000000000000..6f0c97222a71 --- /dev/null +++ b/widget/src/xpwidgets/nsTreeView.h @@ -0,0 +1,144 @@ +/* -*- 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 "NPL"); you may not use this file except in + * compliance with the NPL. You may obtain a copy of the NPL at + * http://www.mozilla.org/NPL/ + * + * Software distributed under the NPL is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the NPL + * for the specific language governing rights and limitations under the + * NPL. + * + * The Initial Developer of this code under the NPL is Netscape + * Communications Corporation. Portions created by Netscape are + * Copyright (C) 1998 Netscape Communications Corporation. All Rights + * Reserved. + */ + +#ifndef nsTreeView_h___ +#define nsTreeView_h___ + +#include "nsITreeView.h" +#include "nsTreeDataModel.h" +#include "nsTreeItem.h" +#include "nsTreeColumn.h" +#include "nsTreeControlStripItem.h" +#include "nsDataModelWidget.h" + +class nsIImageGroup; +class nsIImage; + +// Constants +const int cIndentAmount = 19; +const int cIconMargin = 2; +const int cMinColumnWidth = 30; + +//------------------------------------------------------------ +// A tree view consists of several components: a title bar, a control strip, +// a column bar, the actual tree contents, and an accompanying scrollbar for the +// tree contents. +// +// The actual tree view knows nothing about the data it is displaying. It queries +// a data model for all properties, and then just uses the values it obtains +// to display the data. It passes all expand/collapse/deletion/etc. events back +// to the data model. + +class nsTreeView : public nsITreeView, + public nsDataModelWidget + +{ +public: + nsTreeView(); + virtual ~nsTreeView(); + + // nsISupports Interface -------------------------------- + NS_DECL_ISUPPORTS + + void HandleDataModelEvent(int event, nsHierarchicalDataItem* pItem); + + // Override the widget creation method + NS_IMETHOD Create(nsIWidget *aParent, + const nsRect &aRect, + EVENT_CALLBACK aHandleEventFunction, + nsIDeviceContext *aContext, + nsIAppShell *aAppShell, + nsIToolkit *aToolkit, + nsWidgetInitData *aInitData); + +protected: + // These functions are all used in painting. + void PaintTitleBar(nsIRenderingContext* drawCtx, + nsRect& rect); + void PaintControlStrip(nsIRenderingContext* drawCtx, + nsRect& rect); + + // These functions are used in painting the column bar. + void PaintColumnBar(nsIRenderingContext* drawCtx, + nsRect& rect); + void PaintColumnHeader(nsIRenderingContext* drawCtx, + nsTreeColumn* pColumn, + PRUint32& currentPosition, + const nsColumnHeaderStyleInfo& styleInfo); + void PaintPusherArrow(nsIRenderingContext* drawCtx, + PRBool isLeftArrow, int left, int width); + + // These functions are used to paint the lines in the tree. + void PaintTreeLines(nsIRenderingContext* drawCtx, + nsRect& rect); + void PaintTreeLine(nsIRenderingContext* drawCtx, nsTreeItem* pItem, int& yPosition); + + // General function for painting a background image. + void PaintBackgroundImage(nsIRenderingContext* drawCtx, + nsIImage* bgImage, const nsRect& constraintRect, + int xSrcOffset = 0, int ySrcOffset = 0); + + // Helper to parse color strings. + void ParseColor(char* colorString, nscolor& colorValue); + + // Column Adjusters/Routines + void ResizeColumns(int width); + void ShowColumn(); + void HideColumn(); + void DragColumnEdge(int xPos); + PRBool DownOnColumnEdge(const nsPoint& point); + + // String drawing helper. Crops left, inserts ellipses, and left justifies string. + // Assumption is that the font has been set in the + // rendering context, so the font metrics can be retrieved and used. + void DrawCroppedString(nsIRenderingContext* drawCtx, nsString text, + const nsRect& rect); + + NS_IMETHOD_(nsEventStatus) HandleEvent(nsGUIEvent *aEvent); + +protected: + // Data members + nsTreeDataModel* mDataModel; // The data source from which everything to draw is obtained. + nsIImageGroup* mImageGroup; // Used to make requests for tree images. + + // Cached rects for fast hit testing computation. + nsRect mTitleBarRect; + nsRect mControlStripRect; + nsRect mColumnBarRect; + nsRect mTreeRect; + + // This rect is an area that needs to be invalidated once the mouse leaves it. + // Used on mouse move events. + nsRect mCachedMoveRect; // Is either the control strip or lines in the tree. Only + // these items can possibly be invalidated on a mouse move. + nsPoint mCachedMovePoint; // Cache the last mouse move. + nsPoint mCachedDownPoint; // Cache the mouse down point. + + PRBool mMouseDown; // Whether or not the mouse is pressed. + PRBool mMouseDragging; // Whether or not we're dragging something. + + // These members all have to do with dragging the edges of columns to resize them. + int mMousedColumnIndex; // The index of the column edge hit on a mouse down. + int mLastXPosition; // The last X position of the dragged column edge. + PRBool mDraggingColumnEdge; // Whether or not we're dragging a column edge. + + PRBool mDraggingColumnHeader; // Whether or not we're dragging a column header + +}; + +#endif /* nsToolbar_h___ */