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 "nsIDOMXULTreeElement.h"
#include "nsINameSpaceManager.h"
#include "nsTreeRowGroupFrame.h"
#include "nsXULAtoms.h"
#include "nsIDOMNodeList.h"
#include "nsIDOMXULTreeElement.h"
//
// NS_NewTreeFrame
//
@ -107,6 +110,28 @@ void nsTreeFrame::RangedSelection(nsIPresContext& aPresContext, nsTreeCellFrame*
// 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
nsTreeFrame::HandleEvent(nsIPresContext& aPresContext,
nsGUIEvent* aEvent,
@ -114,7 +139,74 @@ nsTreeFrame::HandleEvent(nsIPresContext& aPresContext,
{
aEventStatus = nsEventStatus_eConsumeDoDefault;
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;
}
@ -127,7 +219,7 @@ void nsTreeFrame::MoveUp(nsIPresContext& aPresContext, nsTreeCellFrame* pFrame)
pFrame->GetColIndex(colIndex);
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)
{
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);
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;
pFrame->GetRowIndex(rowIndex);
aFrame->GetRowIndex(rowIndex);
PRInt32 colIndex;
pFrame->GetColIndex(colIndex);
aFrame->GetColIndex(colIndex);
PRInt32 totalCols = mCellMap->GetColCount();
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.
nsTreeCellFrame* pTreeCell = NS_STATIC_CAST(nsTreeCellFrame*, cellFrame);
SetSelection(aPresContext, pTreeCell);
nsTreeCellFrame* treeCell = NS_STATIC_CAST(nsTreeCellFrame*, cellFrame);
SetSelection(aPresContext, treeCell);
}
NS_IMETHODIMP

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

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

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

@ -26,6 +26,7 @@
#include "nsCellMap.h"
#include "nsIDOMXULTreeElement.h"
#include "nsINameSpaceManager.h"
#include "nsXULAtoms.h"
//
// NS_NewTreeOuterFrame
@ -65,7 +66,22 @@ nsTreeOuterFrame::HandleEvent(nsIPresContext& aPresContext,
{
aEventStatus = nsEventStatus_eConsumeDoDefault;
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;
}

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

@ -364,7 +364,7 @@ nsTreeRowGroupFrame::FindPreviousRowContent(PRInt32& aDelta, nsIContent* aUpward
}
void
nsTreeRowGroupFrame::GetVisibleRowCount(PRInt32& aCount, nsIContent* aParent)
nsTreeRowGroupFrame::ComputeVisibleRowCount(PRInt32& aCount, nsIContent* aParent)
{
PRInt32 childCount;
aParent->ChildCount(childCount);
@ -379,7 +379,7 @@ nsTreeRowGroupFrame::GetVisibleRowCount(PRInt32& aCount, nsIContent* aParent)
}
else if (tag.get() == nsXULAtoms::treeitem) {
// 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.
nsCOMPtr<nsIAtom> openAtom = dont_AddRef(NS_NewAtom("open"));
@ -401,7 +401,7 @@ nsTreeRowGroupFrame::GetVisibleRowCount(PRInt32& aCount, nsIContent* aParent)
break;
}
if (j >= 0 && grandChild)
GetVisibleRowCount(aCount, grandChild);
ComputeVisibleRowCount(aCount, grandChild);
}
}
}
@ -656,7 +656,7 @@ nsTreeRowGroupFrame::ReflowAfterRowLayout(nsIPresContext& aPresContext,
CreateScrollbar(aPresContext);
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.
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,
nsFramePaintLayer aWhichLayer);
NS_IMETHOD Destroy(nsIPresContext& aPresContext);
PRBool ContinueReflow(nsIPresContext& aPresContext, nscoord y, nscoord height);
PRBool IsFull() { return mIsFull; };
@ -109,9 +111,32 @@ protected:
nsIContent** aResult);
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
nsIFrame* mTopFrame; // The current topmost frame in the view.