Beginnings of keyboard navigation in the tree widget. No, it doesn't work

yet.
This commit is contained in:
hyatt%netscape.com 1999-08-24 08:14:21 +00:00
Родитель b22a966f53
Коммит 87872fe749
5 изменённых файлов: 188 добавлений и 21 удалений

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

@ -26,7 +26,10 @@
#include "nsCellMap.h" #include "nsCellMap.h"
#include "nsIDOMXULTreeElement.h" #include "nsIDOMXULTreeElement.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsTreeRowGroupFrame.h"
#include "nsXULAtoms.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMXULTreeElement.h"
// //
// NS_NewTreeFrame // NS_NewTreeFrame
// //
@ -107,6 +110,28 @@ void nsTreeFrame::RangedSelection(nsIPresContext& aPresContext, nsTreeCellFrame*
// XXX Re-implement! // XXX Re-implement!
} }
void
nsTreeFrame::GetTreeBody(nsTreeRowGroupFrame** aResult)
{
nsIFrame* curr = mFrames.FirstChild();
while (curr) {
nsCOMPtr<nsIContent> content;
curr->GetContent(getter_AddRefs(content));
if (content) {
nsCOMPtr<nsIAtom> tag;
content->GetTag(*getter_AddRefs(tag));
if (tag && tag.get() == nsXULAtoms::treechildren) {
// This is our actual treechildren frame.
nsTreeRowGroupFrame* rowGroup = (nsTreeRowGroupFrame*)curr; // XXX I am evil.
*aResult = rowGroup;
return;
}
}
curr->GetNextSibling(&curr);
}
}
NS_IMETHODIMP NS_IMETHODIMP
nsTreeFrame::HandleEvent(nsIPresContext& aPresContext, nsTreeFrame::HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent, nsGUIEvent* aEvent,
@ -114,7 +139,74 @@ nsTreeFrame::HandleEvent(nsIPresContext& aPresContext,
{ {
aEventStatus = nsEventStatus_eConsumeDoDefault; aEventStatus = nsEventStatus_eConsumeDoDefault;
if (aEvent->message == NS_KEY_DOWN) { if (aEvent->message == NS_KEY_DOWN) {
printf("YES!\n"); nsKeyEvent* keyEvent = (nsKeyEvent*)aEvent;
PRUint32 keyCode = keyEvent->keyCode;
if (keyCode == NS_VK_UP ||
keyCode == NS_VK_DOWN) {
// Get our treechildren child frame.
nsTreeRowGroupFrame* treeRowGroup = nsnull;
GetTreeBody(&treeRowGroup);
if (!treeRowGroup)
return NS_OK; // No tree body. Just bail.
nsCOMPtr<nsIDOMXULTreeElement> treeElement = do_QueryInterface(mContent);
nsCOMPtr<nsIDOMNodeList> itemNodeList;
nsCOMPtr<nsIDOMNodeList> cellNodeList;
treeElement->GetSelectedItems(getter_AddRefs(itemNodeList));
treeElement->GetSelectedCells(getter_AddRefs(cellNodeList));
PRUint32 itemLength;
PRUint32 cellLength;
itemNodeList->GetLength(&itemLength);
cellNodeList->GetLength(&cellLength);
PRInt32 rowIndex = -1;
PRInt32 cellIndex = 0;
if (cellLength != 0 && itemLength == 0) {
nsCOMPtr<nsIDOMNode> node;
cellNodeList->Item(0, getter_AddRefs(node));
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
treeRowGroup->IndexOfCell(content, rowIndex, cellIndex);
}
else if (cellLength == 0 && itemLength != 0) {
nsCOMPtr<nsIDOMNode> node;
itemNodeList->Item(0, getter_AddRefs(node));
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
treeRowGroup->IndexOfRow(content, rowIndex);
}
else if (cellLength != 0 && itemLength != 0) {
nsCOMPtr<nsIDOMNode> node;
cellNodeList->Item(0, getter_AddRefs(node));
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
treeRowGroup->IndexOfCell(content, rowIndex, cellIndex);
}
// We now have a valid row and cell index for the current selection. Based on the
// direction, let's adjust the row and column index.
if (rowIndex == -1)
rowIndex = 0;
else if (keyCode == NS_VK_DOWN)
rowIndex++;
else if (keyCode == NS_VK_UP)
rowIndex--;
if (!treeRowGroup->IsValidRow(rowIndex))
return NS_OK;
// Ensure that the required index is visible.
treeRowGroup->EnsureRowIsVisible(rowIndex);
// Now that the row is scrolled into view, we have a frame created. We can retrieve the cell.
nsTreeCellFrame* cellFrame;
treeRowGroup->GetCellFrameAtIndex(rowIndex, cellIndex, &cellFrame);
if (!cellFrame)
return NS_OK; // No cell. Whatever. Bail.
// We got it! Perform the selection.
SetSelection(aPresContext, cellFrame);
}
} }
return NS_OK; return NS_OK;
} }
@ -127,7 +219,7 @@ void nsTreeFrame::MoveUp(nsIPresContext& aPresContext, nsTreeCellFrame* pFrame)
pFrame->GetColIndex(colIndex); pFrame->GetColIndex(colIndex);
if (rowIndex > 0) if (rowIndex > 0)
{ {
MoveToRowCol(aPresContext, rowIndex-1, colIndex, pFrame); MoveToRowCol(aPresContext, rowIndex-1, colIndex);
} }
} }
@ -141,7 +233,7 @@ void nsTreeFrame::MoveDown(nsIPresContext& aPresContext, nsTreeCellFrame* pFrame
if (rowIndex < totalRows-1) if (rowIndex < totalRows-1)
{ {
MoveToRowCol(aPresContext, rowIndex+1, colIndex, pFrame); MoveToRowCol(aPresContext, rowIndex+1, colIndex);
} }
} }
@ -153,31 +245,31 @@ void nsTreeFrame::MoveLeft(nsIPresContext& aPresContext, nsTreeCellFrame* pFrame
pFrame->GetColIndex(colIndex); pFrame->GetColIndex(colIndex);
if (colIndex > 0) if (colIndex > 0)
{ {
MoveToRowCol(aPresContext, rowIndex, colIndex-1, pFrame); MoveToRowCol(aPresContext, rowIndex, colIndex-1);
} }
} }
void nsTreeFrame::MoveRight(nsIPresContext& aPresContext, nsTreeCellFrame* pFrame) void nsTreeFrame::MoveRight(nsIPresContext& aPresContext, nsTreeCellFrame* aFrame)
{ {
PRInt32 rowIndex; PRInt32 rowIndex;
pFrame->GetRowIndex(rowIndex); aFrame->GetRowIndex(rowIndex);
PRInt32 colIndex; PRInt32 colIndex;
pFrame->GetColIndex(colIndex); aFrame->GetColIndex(colIndex);
PRInt32 totalCols = mCellMap->GetColCount(); PRInt32 totalCols = mCellMap->GetColCount();
if (colIndex < totalCols-1) if (colIndex < totalCols-1)
{ {
MoveToRowCol(aPresContext, rowIndex, colIndex+1, pFrame); MoveToRowCol(aPresContext, rowIndex, colIndex+1);
} }
} }
void nsTreeFrame::MoveToRowCol(nsIPresContext& aPresContext, PRInt32 row, PRInt32 col, nsTreeCellFrame* pFrame) void nsTreeFrame::MoveToRowCol(nsIPresContext& aPresContext, PRInt32 aRow, PRInt32 aCol)
{ {
nsTableCellFrame *cellFrame = mCellMap->GetCellInfoAt(row, col); nsTableCellFrame* cellFrame = mCellMap->GetCellInfoAt(aRow, aCol);
// We now have the cell that should be selected. // We now have the cell that should be selected.
nsTreeCellFrame* pTreeCell = NS_STATIC_CAST(nsTreeCellFrame*, cellFrame); nsTreeCellFrame* treeCell = NS_STATIC_CAST(nsTreeCellFrame*, cellFrame);
SetSelection(aPresContext, pTreeCell); SetSelection(aPresContext, treeCell);
} }
NS_IMETHODIMP NS_IMETHODIMP

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

@ -21,6 +21,7 @@
#include "nsVoidArray.h" #include "nsVoidArray.h"
class nsTreeCellFrame; class nsTreeCellFrame;
class nsTreeRowGroupFrame;
class nsTreeFrame : public nsTableFrame class nsTreeFrame : public nsTableFrame
{ {
@ -35,11 +36,13 @@ public:
void MoveDown(nsIPresContext& aPresContext, nsTreeCellFrame* pFrame); void MoveDown(nsIPresContext& aPresContext, nsTreeCellFrame* pFrame);
void MoveLeft(nsIPresContext& aPresContext, nsTreeCellFrame* pFrame); void MoveLeft(nsIPresContext& aPresContext, nsTreeCellFrame* pFrame);
void MoveRight(nsIPresContext& aPresContext, nsTreeCellFrame* pFrame); void MoveRight(nsIPresContext& aPresContext, nsTreeCellFrame* pFrame);
void MoveToRowCol(nsIPresContext& aPresContext, PRInt32 row, PRInt32 col, nsTreeCellFrame* pFrame); void MoveToRowCol(nsIPresContext& aPresContext, PRInt32 row, PRInt32 col);
PRBool IsSlatedForReflow() { return mSlatedForReflow; }; PRBool IsSlatedForReflow() { return mSlatedForReflow; };
void SlateForReflow() { mSlatedForReflow = PR_TRUE; }; void SlateForReflow() { mSlatedForReflow = PR_TRUE; };
void GetTreeBody(nsTreeRowGroupFrame** aResult);
// Overridden methods // Overridden methods
NS_IMETHOD Destroy(nsIPresContext& aPresContext); NS_IMETHOD Destroy(nsIPresContext& aPresContext);
PRBool RowGroupsShouldBeConstrained() { return PR_TRUE; } PRBool RowGroupsShouldBeConstrained() { return PR_TRUE; }

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

@ -26,6 +26,7 @@
#include "nsCellMap.h" #include "nsCellMap.h"
#include "nsIDOMXULTreeElement.h" #include "nsIDOMXULTreeElement.h"
#include "nsINameSpaceManager.h" #include "nsINameSpaceManager.h"
#include "nsXULAtoms.h"
// //
// NS_NewTreeOuterFrame // NS_NewTreeOuterFrame
@ -65,7 +66,22 @@ nsTreeOuterFrame::HandleEvent(nsIPresContext& aPresContext,
{ {
aEventStatus = nsEventStatus_eConsumeDoDefault; aEventStatus = nsEventStatus_eConsumeDoDefault;
if (aEvent->message == NS_KEY_DOWN) { if (aEvent->message == NS_KEY_DOWN) {
printf("YES!\n"); // Retrieve the tree frame.
nsIFrame* curr = mFrames.FirstChild();
while (curr) {
nsCOMPtr<nsIContent> content;
curr->GetContent(getter_AddRefs(content));
if (content) {
nsCOMPtr<nsIAtom> tag;
content->GetTag(*getter_AddRefs(tag));
if (tag && tag.get() == nsXULAtoms::tree) {
// This is our actual tree frame.
return curr->HandleEvent(aPresContext, aEvent, aEventStatus);
}
}
curr->GetNextSibling(&curr);
}
} }
return NS_OK; return NS_OK;
} }

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

@ -364,7 +364,7 @@ nsTreeRowGroupFrame::FindPreviousRowContent(PRInt32& aDelta, nsIContent* aUpward
} }
void void
nsTreeRowGroupFrame::GetVisibleRowCount(PRInt32& aCount, nsIContent* aParent) nsTreeRowGroupFrame::ComputeVisibleRowCount(PRInt32& aCount, nsIContent* aParent)
{ {
PRInt32 childCount; PRInt32 childCount;
aParent->ChildCount(childCount); aParent->ChildCount(childCount);
@ -379,7 +379,7 @@ nsTreeRowGroupFrame::GetVisibleRowCount(PRInt32& aCount, nsIContent* aParent)
} }
else if (tag.get() == nsXULAtoms::treeitem) { else if (tag.get() == nsXULAtoms::treeitem) {
// Descend into this row group and try to find the next row. // Descend into this row group and try to find the next row.
GetVisibleRowCount(aCount, childContent); ComputeVisibleRowCount(aCount, childContent);
// If it's open, descend into its treechildren. // If it's open, descend into its treechildren.
nsCOMPtr<nsIAtom> openAtom = dont_AddRef(NS_NewAtom("open")); nsCOMPtr<nsIAtom> openAtom = dont_AddRef(NS_NewAtom("open"));
@ -401,7 +401,7 @@ nsTreeRowGroupFrame::GetVisibleRowCount(PRInt32& aCount, nsIContent* aParent)
break; break;
} }
if (j >= 0 && grandChild) if (j >= 0 && grandChild)
GetVisibleRowCount(aCount, grandChild); ComputeVisibleRowCount(aCount, grandChild);
} }
} }
} }
@ -656,7 +656,7 @@ nsTreeRowGroupFrame::ReflowAfterRowLayout(nsIPresContext& aPresContext,
CreateScrollbar(aPresContext); CreateScrollbar(aPresContext);
PRInt32 rowCount = 0; PRInt32 rowCount = 0;
GetVisibleRowCount(rowCount, mContent); // XXX This sucks! Needs to be cheap! ComputeVisibleRowCount(rowCount, mContent); // XXX This sucks! Needs to be cheap!
// Set the maxpos of the scrollbar. // Set the maxpos of the scrollbar.
nsCOMPtr<nsIContent> scrollbarContent; nsCOMPtr<nsIContent> scrollbarContent;
@ -1091,3 +1091,34 @@ void nsTreeRowGroupFrame::CreateScrollbar(nsIPresContext& aPresContext)
} }
} }
void
nsTreeRowGroupFrame::IndexOfCell(nsIContent* aCellContent, PRInt32& aRowIndex, PRInt32& aColIndex)
{
}
void
nsTreeRowGroupFrame::IndexOfRow(nsIContent* aRowContent, PRInt32& aRowIndex)
{
}
PRBool
nsTreeRowGroupFrame::IsValidRow(PRInt32 aRowIndex)
{
return PR_FALSE;
}
void
nsTreeRowGroupFrame::EnsureRowIsVisible(PRInt32 aRowIndex)
{
}
void
nsTreeRowGroupFrame::GetCellFrameAtIndex(PRInt32 aRowIndex, PRInt32 aColIndex,
nsTreeCellFrame** aResult)
{
}

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

@ -54,6 +54,8 @@ public:
const nsRect& aDirtyRect, const nsRect& aDirtyRect,
nsFramePaintLayer aWhichLayer); nsFramePaintLayer aWhichLayer);
NS_IMETHOD Destroy(nsIPresContext& aPresContext);
PRBool ContinueReflow(nsIPresContext& aPresContext, nscoord y, nscoord height); PRBool ContinueReflow(nsIPresContext& aPresContext, nscoord y, nscoord height);
PRBool IsFull() { return mIsFull; }; PRBool IsFull() { return mIsFull; };
@ -109,9 +111,32 @@ protected:
nsIContent** aResult); nsIContent** aResult);
void GetFirstRowContent(nsIContent** aRowContent); void GetFirstRowContent(nsIContent** aRowContent);
void GetVisibleRowCount(PRInt32& rowCount, nsIContent* aParent); void ComputeVisibleRowCount(PRInt32& rowCount, nsIContent* aParent);
NS_IMETHOD Destroy(nsIPresContext& aPresContext); public:
// Helpers that allow access to info. The tree is the primary consumer of this
// info.
// Tells you the row and index of a cell (given only the content node).
// This method is expensive.
void IndexOfCell(nsIContent* aCellContent, PRInt32& aRowIndex, PRInt32& aColIndex);
// Tells you the row index of a row (given only the content node).
// This method is expensive.
void IndexOfRow(nsIContent* aRowContent, PRInt32& aRowIndex);
// Whether or not the row is valid. This is a cheap method, since the total row count
// is cached.
PRBool IsValidRow(PRInt32 aRowIndex);
// This method ensures that a row is onscreen. It will scroll the tree widget such
// that the row is at the top of the screen (if the row was offscreen to start with).
void EnsureRowIsVisible(PRInt32 aRowIndex);
// This method retrieves a cell at a given index. The intent of this method is that it be
// cheap. It should not cause frames to be built, so this should only be called when the
// cell is onscreen (use EnsureRowIsVisible to guarantee this).
void GetCellFrameAtIndex(PRInt32 aRowIndex, PRInt32 aColIndex, nsTreeCellFrame** aResult);
protected: // Data Members protected: // Data Members
nsIFrame* mTopFrame; // The current topmost frame in the view. nsIFrame* mTopFrame; // The current topmost frame in the view.