up/down selection BRFrames dont allow selecting upon them for now. horizontal bars are now drawn selected. ect.

This commit is contained in:
mjudge%netscape.com 1999-06-19 20:36:44 +00:00
Родитель d6d7acd471
Коммит 9eccad5750
15 изменённых файлов: 645 добавлений и 234 удалений

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

@ -241,7 +241,7 @@ PRBool GetNodeBracketPoints(nsIContent* aNode,
else
{
nsCOMPtr<nsIContent> cN(do_QueryInterface(*outParent));
if (NS_FAILED(cN->IndexOf(aNode, indx)))
if (!cn || NS_FAILED(cN->IndexOf(aNode, indx)))
return PR_FALSE;
*outStartOffset = indx;
*outEndOffset = indx+1;

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

@ -22,7 +22,7 @@
#include "nsIFrame.h"
class nsICaret;
class nsIPresContext;
// IID for the nsIFocusTracker interface
@ -58,10 +58,11 @@ public:
nsIFrame** aPrimaryFrame) const = 0;
/**
* GetCaret will return the nsICaret Interface from this FocusTracker
* GetPresContent will return the nsIPresContext Interface from this
* FocusTracker
* usefull for getting screen coordinates of current selection
*/
NS_IMETHOD GetCaret(nsICaret **aCaret) = 0;
NS_IMETHOD GetPresContext(nsIPresContext **aContext) = 0;
};

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

@ -603,7 +603,8 @@ public:
* nsIFrame and the frame offset. THIS DOES NOT CHANGE SELECTION STATE
* uses frame's begin selection state to start. if no selection on this frame will
* return NS_ERROR_FAILURE
* @param aCaret is the caret interface to get geometry of the current selection
* @param aTracker is used to get the PresContext usefull for measuring text ect.
* @param aDesiredX is the "desired" location of the new caret
* @param aAmount eWord, eCharacter, eLine
* @param aDirection enum defined in this file to be eForward or eBackward
* @param aStartOffset start offset to start the peek. 0 == beginning -1 = end
@ -611,7 +612,7 @@ public:
* @param aResultOffset offset for result content
* @param aEatingWS boolean to tell us the state of our search for Next/Prev
*/
NS_IMETHOD PeekOffset(nsICaret *aCaret, nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 aStartOffset,
NS_IMETHOD PeekOffset(nsIFocusTracker *aTracker, PRInt32 aDesiredX, nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 aStartOffset,
nsIContent **aResultContent, PRInt32 *aResultOffset, PRBool aEatingWS) = 0;
/**

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

@ -241,7 +241,7 @@ PRBool GetNodeBracketPoints(nsIContent* aNode,
else
{
nsCOMPtr<nsIContent> cN(do_QueryInterface(*outParent));
if (NS_FAILED(cN->IndexOf(aNode, indx)))
if (!cn || NS_FAILED(cN->IndexOf(aNode, indx)))
return PR_FALSE;
*outStartOffset = indx;
*outEndOffset = indx+1;

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

@ -39,11 +39,13 @@
#include "nsIDOMSelectionListener.h"
#include "nsIContentIterator.h"
//included for desired x position;
#include "nsIPresContext.h"
#include "nsIPresShell.h"
#include "nsICaret.h"
#include "nsIScriptObjectOwner.h"
#include "nsIScriptGlobalObject.h"
#include "nsICaret.h"
#define STATUS_CHECK_RETURN_MACRO() {if (!mTracker) return NS_ERROR_FAILURE;}
@ -152,6 +154,9 @@ private:
nsIDOMNode* FetchEndParent(nsIDOMRange *aRange); //skip all the com stuff and give me the start/end
PRInt32 FetchEndOffset(nsIDOMRange *aRange);
nscoord FetchDesiredX(); //the x position requested by the Key Handling for up down
void InvalidateDesiredX(); //do not listen to mDesiredX you must get another.
void SetDesiredX(nscoord aX); //set the mDesiredX
void setAnchorFocusRange(PRInt32); //pass in index into rangelist
@ -169,6 +174,7 @@ private:
NS_IMETHOD SetOriginalAnchorPoint(nsIDOMNode *aNode, PRInt32 aOffset);
NS_IMETHOD GetOriginalAnchorPoint(nsIDOMNode **aNode, PRInt32 *aOffset);
NS_IMETHOD GetPrimaryFrameForFocusNode(nsIFrame **aResultFrame);
nsCOMPtr<nsISupportsArray> mRangeArray;
nsCOMPtr<nsIDOMRange> mAnchorFocusRange;
@ -187,6 +193,8 @@ private:
void* mScriptObject;
nsIFocusTracker *mTracker;
PRBool mMouseDownState; //for drag purposes
PRInt32 mDesiredX;
PRBool mDesiredXSet;
static nsIAtom *sTableAtom;
static nsIAtom *sCellAtom;
static nsIAtom *sTbodyAtom;
@ -724,6 +732,58 @@ nsRangeList::FetchEndOffset(nsIDOMRange *aRange)
nscoord
nsRangeList::FetchDesiredX() //the x position requested by the Key Handling for up down
{
if (!mTracker)
{
NS_ASSERTION(0,"fetch desired X failed\n");
return -1;
}
if (mDesiredXSet)
return mDesiredX;
else {
nsPoint coord;
PRBool collapsed;
nsCOMPtr<nsICaret> caret;
nsCOMPtr<nsIPresContext> context;
nsCOMPtr<nsIPresShell> shell;
nsresult result = mTracker->GetPresContext(getter_AddRefs(context));
if (NS_FAILED(result) || !context)
return result;
result = context->GetShell(getter_AddRefs(shell));
if (NS_FAILED(result) || !shell)
return result;
result = shell->GetCaret(getter_AddRefs(caret));
if (NS_FAILED(result) || !caret)
return result;
result = caret->GetWindowRelativeCoordinates(coord,collapsed);
if (NS_FAILED(result))
return result;
return coord.x;
}
}
void
nsRangeList::InvalidateDesiredX() //do not listen to mDesiredX you must get another.
{
mDesiredXSet = PR_FALSE;
}
void
nsRangeList::SetDesiredX(nscoord aX) //set the mDesiredX
{
mDesiredX = aX;
mDesiredXSet = PR_TRUE;
}
nsresult
nsRangeList::AddItem(nsISupports *aItem)
{
@ -867,6 +927,7 @@ nsRangeList::Init(nsIFocusTracker *aTracker)
{
mTracker = aTracker;
mMouseDownState = PR_FALSE;
mDesiredXSet = PR_FALSE;
return NS_OK;
}
@ -908,6 +969,7 @@ nsRangeList::HandleKeyEvent(nsGUIEvent *aGuiEvent)
if (!aGuiEvent)
return NS_ERROR_NULL_POINTER;
STATUS_CHECK_RETURN_MACRO();
nsresult result = NS_OK;
if (NS_KEY_DOWN == aGuiEvent->message) {
nsKeyEvent *keyEvent = (nsKeyEvent *)aGuiEvent; //this is ok. It really is a keyevent
@ -916,90 +978,94 @@ nsRangeList::HandleKeyEvent(nsGUIEvent *aGuiEvent)
nsSelectionAmount amount = eSelectCharacter;
if (keyEvent->isControl)
amount = eSelectWord;
nsCOMPtr<nsICaret> caret;
result = mTracker->GetCaret(getter_AddRefs(caret));
PRBool isCollapsed;
nscoord desiredX; //we must keep this around and revalidate it when its just UP/DOWN
result = GetIsCollapsed(&isCollapsed);
if (NS_FAILED(result))
return result;
if (keyEvent->keyCode == nsIDOMUIEvent::VK_UP || keyEvent->keyCode == nsIDOMUIEvent::VK_DOWN)
desiredX= FetchDesiredX();
if (!isCollapsed && !keyEvent->isShift) {
switch (keyEvent->keyCode){
case nsIDOMUIEvent::VK_LEFT :
case nsIDOMUIEvent::VK_UP : {
if ((GetDirection() == eDirPrevious)) { //f,a
offsetused = FetchFocusOffset();
weakNodeUsed = FetchFocusNode();
}
else {
offsetused = FetchAnchorOffset();
weakNodeUsed = FetchAnchorNode();
}
result = Collapse(weakNodeUsed,offsetused);
} break;
case nsIDOMUIEvent::VK_RIGHT :
case nsIDOMUIEvent::VK_DOWN : {
if ((GetDirection() == eDirPrevious)) { //f,a
offsetused = FetchAnchorOffset();
weakNodeUsed = FetchAnchorNode();
}
else {
offsetused = FetchFocusOffset();
weakNodeUsed = FetchFocusNode();
}
result = Collapse(weakNodeUsed,offsetused);
} break;
}
if (keyEvent->keyCode == nsIDOMUIEvent::VK_UP || keyEvent->keyCode == nsIDOMUIEvent::VK_DOWN)
SetDesiredX(desiredX);
return NS_OK;
}
offsetused = FetchFocusOffset();
weakNodeUsed = FetchFocusNode();
nsIFrame *frame;
nsCOMPtr<nsIContent> content;
result = GetPrimaryFrameForFocusNode(&frame);
if (NS_FAILED(result))
return result;
switch (keyEvent->keyCode){
case nsIDOMUIEvent::VK_LEFT :
{
//we need to look for the previous PAINTED location to move the cursor to.
#ifdef DEBUG_NAVIGATION
printf("debug vk left\n");
#endif
if (keyEvent->isShift || (GetDirection() == eDirPrevious)) { //f,a
offsetused = FetchFocusOffset();
weakNodeUsed = FetchFocusNode();
}
else {
offsetused = FetchAnchorOffset();
weakNodeUsed = FetchAnchorNode();
}
if (weakNodeUsed && offsetused >=0){
nsIFrame *frame;
nsCOMPtr<nsIContent> content = do_QueryInterface(weakNodeUsed);
if (content){
result = mTracker->GetPrimaryFrameFor(content, &frame);
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(frame->PeekOffset(caret, amount, eDirPrevious, offsetused, getter_AddRefs(content), &offsetused, PR_FALSE)) && content){
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(frame->PeekOffset(mTracker, desiredX, amount, eDirPrevious, offsetused, getter_AddRefs(content), &offsetused, PR_FALSE)) && content){
result = TakeFocus(content, offsetused, offsetused, keyEvent->isShift);
}
result = ScrollIntoView();
}
}
break;
case nsIDOMUIEvent::VK_RIGHT :
{
//we need to look for the previous PAINTED location to move the cursor to.
#ifdef DEBUG_NAVIGATION
printf("debug vk left\n");
#endif
if (keyEvent->isShift || (GetDirection() == eDirPrevious)) { //f,a
offsetused = FetchFocusOffset();
weakNodeUsed = FetchFocusNode();
}
else {
offsetused = FetchAnchorOffset();
weakNodeUsed = FetchAnchorNode();
}
if (weakNodeUsed && offsetused >=0){
nsIFrame *frame;
nsCOMPtr<nsIContent> content = do_QueryInterface(weakNodeUsed);
if (content){
result = mTracker->GetPrimaryFrameFor(content, &frame);
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(frame->PeekOffset(caret, amount, eDirNext, offsetused, getter_AddRefs(content), &offsetused, PR_FALSE)) && content){
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(frame->PeekOffset(mTracker, desiredX, amount, eDirNext, offsetused, getter_AddRefs(content), &offsetused, PR_FALSE)) && content){
result = TakeFocus(content, offsetused, offsetused, keyEvent->isShift);
}
result = ScrollIntoView();
}
}
break;
case nsIDOMUIEvent::VK_UP :
case nsIDOMUIEvent::VK_DOWN :
{
//we need to look for the previous PAINTED location to move the cursor to.
amount = eSelectLine;
#ifdef DEBUG_NAVIGATION
printf("debug vk left\n");
#endif
if (keyEvent->isShift || (GetDirection() == eDirPrevious)) { //f,a
offsetused = FetchFocusOffset();
weakNodeUsed = FetchFocusNode();
if (nsIDOMUIEvent::VK_UP == keyEvent->keyCode)
{
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(frame->PeekOffset(mTracker, desiredX, amount, eDirPrevious, offsetused, getter_AddRefs(content), &offsetused, PR_FALSE)) && content){
result = TakeFocus(content, offsetused, offsetused, keyEvent->isShift);
}
else {
offsetused = FetchAnchorOffset();
weakNodeUsed = FetchAnchorNode();
}
if (weakNodeUsed && offsetused >=0){
nsIFrame *frame;
nsCOMPtr<nsIContent> content = do_QueryInterface(weakNodeUsed);
if (content){
result = mTracker->GetPrimaryFrameFor(content, &frame);
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(frame->PeekOffset(caret, amount, eDirPrevious, offsetused, getter_AddRefs(content), &offsetused, PR_FALSE)) && content){
else
if (NS_SUCCEEDED(result) && NS_SUCCEEDED(frame->PeekOffset(mTracker, desiredX, amount, eDirNext, offsetused, getter_AddRefs(content), &offsetused, PR_FALSE)) && content){
result = TakeFocus(content, offsetused, offsetused, keyEvent->isShift);
}
result = ScrollIntoView();
}
}
SetDesiredX(desiredX);
}
break;
case nsIDOMUIEvent::VK_DOWN :
#ifdef DEBUG_NAVIGATION
printf("debug vk down\n");
#endif
@ -1010,6 +1076,36 @@ nsRangeList::HandleKeyEvent(nsGUIEvent *aGuiEvent)
return result;
}
//utility method to get the primary frame of node or use the offset to get frame of child node
NS_IMETHODIMP
nsRangeList::GetPrimaryFrameForFocusNode(nsIFrame **aReturnFrame)
{
if (!aReturnFrame)
return NS_ERROR_NULL_POINTER;
nsCOMPtr<nsIDOMNode> node = dont_QueryInterface(FetchFocusNode());
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
PRBool canContainChildren = PR_FALSE;
nsresult result = content->CanContainChildren(canContainChildren);
if (NS_SUCCEEDED(result) && canContainChildren)
{
PRInt32 offset = FetchFocusOffset();
if (GetDirection() == eDirNext)
offset--;
if (offset >0)
{
nsCOMPtr<nsIContent> child;
result = content->ChildAt(offset, *getter_AddRefs(child));
if (NS_FAILED(result) || !child) //out of bounds?
return result;
content = child;//releases the focusnode
}
}
result = mTracker->GetPrimaryFrameFor(content,aReturnFrame);
return result;
}
#ifdef DEBUG
void nsRangeList::printSelection()
{
@ -1139,8 +1235,8 @@ nsRangeList::TakeFocus(nsIContent *aNewFocus, PRUint32 aContentOffset,
nsCOMPtr<nsIContent> parent2;
if (NS_FAILED(aNewFocus->GetParent(*getter_AddRefs(parent))) || !parent)
return NS_ERROR_FAILURE;
if (NS_FAILED(parent->GetParent(*getter_AddRefs(parent2))) || !parent2)
return NS_ERROR_FAILURE;
//if (NS_FAILED(parent->GetParent(*getter_AddRefs(parent2))) || !parent2)
//return NS_ERROR_FAILURE;
//END HACKHACKHACK /checking for root frames/content
@ -1319,25 +1415,7 @@ nsRangeList::ScrollIntoView()
{
nsresult result;
nsIFrame *frame;
nsCOMPtr<nsIDOMNode> node = dont_QueryInterface(FetchFocusNode());
nsCOMPtr<nsIContent> content = do_QueryInterface(node);
PRBool canContainChildren = PR_FALSE;
result = content->CanContainChildren(canContainChildren);
if (NS_SUCCEEDED(result) && canContainChildren)
{
PRInt32 offset = FetchFocusOffset();
if (GetDirection() == eDirNext)
offset--;
if (offset >0)
{
nsCOMPtr<nsIContent> child;
result = content->ChildAt(offset, *getter_AddRefs(child));
if (NS_FAILED(result) || !child) //out of bounds?
return result;
content = child;//releases the focusnode
}
}
result = mTracker->GetPrimaryFrameFor(content,&frame);
result = GetPrimaryFrameForFocusNode(&frame);
if (NS_FAILED(result))
return result;
result = mTracker->ScrollFrameIntoView(frame);
@ -1426,7 +1504,7 @@ NS_IMETHODIMP
nsRangeList::Collapse(nsIDOMNode* aParentNode, PRInt32 aOffset)
{
nsresult result;
InvalidateDesiredX();
// Delete all of the current ranges
if (!mRangeArray)
return NS_ERROR_FAILURE;
@ -1827,7 +1905,7 @@ nsRangeList::Extend(nsIDOMNode* aParentNode, PRInt32 aOffset)
// First, find the range containing the old focus point:
if (!mRangeArray)
return NS_ERROR_FAILURE;
InvalidateDesiredX();
nsCOMPtr<nsIDOMRange> difRange;
nsresult res;
res = nsComponentManager::CreateInstance(kRangeCID, nsnull,

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

@ -39,6 +39,11 @@ public:
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD GetPosition(nsIPresContext& aCX,
nscoord aXCoord,
nsIContent ** aNewContent,
PRInt32& aContentOffset,
PRInt32& aContentOffsetEnd);
protected:
virtual ~BRFrame();
@ -130,3 +135,14 @@ BRFrame::Reflow(nsIPresContext& aPresContext,
}
return NS_OK;
}
NS_IMETHODIMP BRFrame::GetPosition(nsIPresContext&,
nscoord ,
nsIContent ** ,
PRInt32& ,
PRInt32& )
{
return NS_ERROR_FAILURE;
}

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

@ -87,6 +87,8 @@ nsIContent * fTrackerContentArrayAddList[1024];
PRInt32 fTrackerAddListMax = 0;
#include "nsICaret.h"
#include "nsILineIterator.h"
// [HACK] Foward Declarations
void ForceDrawFrame(nsFrame * aFrame);
#if 0
@ -922,7 +924,7 @@ NS_IMETHODIMP nsFrame::HandleDrag(nsIPresContext& aPresContext,
if (!DisplaySelection(aPresContext)) {
return NS_OK;
}
printf("handledrag %x\n",this);
nsCOMPtr<nsIPresShell> shell;
nsresult rv = aPresContext.GetShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell) {
@ -1631,18 +1633,123 @@ nsFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, PRInt32* outFram
}
NS_IMETHODIMP
nsFrame::PeekOffset(nsICaret *aCaret,
nsFrame::PeekOffset(nsIFocusTracker *aTracker,
nscoord aDesiredX,
nsSelectionAmount aAmount,
nsDirection aDirection,
PRInt32 aStartOffset,
nsIContent **aResultContent,
PRInt32 *aContentOffset,
PRBool aEatingWS)
{
if (!aResultContent || !aContentOffset ||!aTracker)
return NS_ERROR_NULL_POINTER;
nsresult result;
switch (aAmount){
case eSelectLine :
{
if (!aTracker)
return NS_ERROR_NULL_POINTER;
nscoord coord = aDesiredX;
nsCOMPtr<nsILineIterator> it;
nsIFrame *blockFrame = this;
nsIFrame *thisBlock = this;
result = blockFrame->GetParent(&blockFrame);
if (NS_FAILED(result)) //if at line 0 then nothing to do
return result;
result = blockFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it));
while (NS_FAILED(result) && blockFrame)
{
thisBlock = blockFrame;
result = blockFrame->GetParent(&blockFrame);
if (NS_SUCCEEDED(result) && blockFrame){
result = blockFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it));
}
}
if (NS_FAILED(result) || !it || !blockFrame)
return result;
nsIFrame *resultFrame = nsnull;
PRInt32 thisLine = 0;
result = it->FindLineContaining(thisBlock, &thisLine);
if (NS_FAILED(result)) //if at line 0 then nothing to do
return result;
PRInt32 searchingLine = thisLine;
PRBool isBeforeFirstFrame, isAfterLastFrame;
PRBool found = PR_FALSE;
while (!found)
{
if (aDirection == eDirPrevious)
searchingLine --;
else
searchingLine ++;
result = it->FindFrameAt(searchingLine, coord, &resultFrame, &isBeforeFirstFrame, &isAfterLastFrame);
if (NS_SUCCEEDED(result) && resultFrame)
{
nsIFrame *child;
PRBool exhaustedAllSiblings = PR_FALSE;
while ( !found && !exhaustedAllSiblings)
{
while (NS_SUCCEEDED(resultFrame->FirstChild(nsnull, &child)) && child){
resultFrame = child;
if (aDirection == eDirPrevious) //go to last child now.
{
while (NS_SUCCEEDED(result) && child)
{
resultFrame = child;
result = resultFrame->GetNextSibling(&child);
}
}
}
if (!resultFrame)
return NS_ERROR_FAILURE;
//now we need to get the local frame coordinates
coord = PR_MAX(0, coord);
nsCOMPtr<nsIPresContext> context;
result = aTracker->GetPresContext(getter_AddRefs(context));
result = resultFrame->GetPosition(*(context.get()),coord,
aResultContent,*aContentOffset, *aContentOffset);
//if (isAfterLastFrame) //get previous frame.
if (NS_SUCCEEDED(result))
found = PR_TRUE;
else{
if (aDirection == eDirNext)
#if 0 {
result = resultFrame->GetPrevSibling(&child);
}
else
#endif
result = resultFrame->GetNextSibling(&child);
if (NS_FAILED(result) || !child)
exhaustedAllSiblings = PR_TRUE;
else
resultFrame = child;
}
}
}
else {
//we need to jump to new block frame.
if (aDirection == eDirNext)
return blockFrame->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, 0, aResultContent,
aContentOffset, aEatingWS);
else
return blockFrame->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, -1, aResultContent,
aContentOffset, aEatingWS);
}
}
break;
}
default:
{
//this will use the nsFrameTraversal as the default peek method.
//this should change to use geometry and also look to ALL the child lists
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
nsresult result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,this);
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,this);
if (NS_FAILED(result))
return result;
nsISupports *isupports = nsnull;
@ -1662,12 +1769,13 @@ nsFrame::PeekOffset(nsICaret *aCaret,
//for speed reasons
nsIFrame *newFrame = (nsIFrame *)isupports;
if (aDirection == eDirNext)
return newFrame->PeekOffset(aCaret, aAmount, aDirection, 0, aResultContent,
return newFrame->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, 0, aResultContent,
aContentOffset, aEatingWS);
else
return newFrame->PeekOffset(aCaret, aAmount, aDirection, -1, aResultContent,
return newFrame->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, -1, aResultContent,
aContentOffset, aEatingWS);
}
}
return NS_OK;
}

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

@ -211,7 +211,8 @@ public:
NS_IMETHOD VerifyTree() const;
NS_IMETHOD SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread);
NS_IMETHOD GetSelected(PRBool *aSelected) const;
NS_IMETHOD PeekOffset(nsICaret *aCaret,
NS_IMETHOD PeekOffset(nsIFocusTracker *aTracker,
nscoord aDesiredX,
nsSelectionAmount aAmount,
nsDirection aDirection,
PRInt32 aStartOffset,

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

@ -603,7 +603,8 @@ public:
* nsIFrame and the frame offset. THIS DOES NOT CHANGE SELECTION STATE
* uses frame's begin selection state to start. if no selection on this frame will
* return NS_ERROR_FAILURE
* @param aCaret is the caret interface to get geometry of the current selection
* @param aTracker is used to get the PresContext usefull for measuring text ect.
* @param aDesiredX is the "desired" location of the new caret
* @param aAmount eWord, eCharacter, eLine
* @param aDirection enum defined in this file to be eForward or eBackward
* @param aStartOffset start offset to start the peek. 0 == beginning -1 = end
@ -611,7 +612,7 @@ public:
* @param aResultOffset offset for result content
* @param aEatingWS boolean to tell us the state of our search for Next/Prev
*/
NS_IMETHOD PeekOffset(nsICaret *aCaret, nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 aStartOffset,
NS_IMETHOD PeekOffset(nsIFocusTracker *aTracker, PRInt32 aDesiredX, nsSelectionAmount aAmount, nsDirection aDirection, PRInt32 aStartOffset,
nsIContent **aResultContent, PRInt32 *aResultOffset, PRBool aEatingWS) = 0;
/**

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

@ -56,6 +56,8 @@
#include "nsIDOMSelection.h"
#include "nsIDOMRange.h"
#include "nsILineIterator.h"
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
#ifdef NS_DEBUG
@ -238,7 +240,8 @@ public:
NS_IMETHOD SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread);
NS_IMETHOD PeekOffset(nsICaret *aCaret,
NS_IMETHOD PeekOffset(nsIFocusTracker *aTracker,
nscoord aDesiredX,
nsSelectionAmount aAmount,
nsDirection aDirection,
PRInt32 aStartOffset,
@ -1007,7 +1010,8 @@ nsTextFrame::GetPositionSlowly(nsIPresContext& aPresContext,
doc->GetWordBreaker(getter_AddRefs(wb));
nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE, lb,wb);
PrepareUnicodeText(tx, ip, paintBuf, &textLength);
if (textLength <= 0)
return NS_ERROR_FAILURE;
nsPoint origin;
nsIView * view;
GetView(&view);
@ -1750,6 +1754,8 @@ nsTextFrame::GetPosition(nsIPresContext& aCX,
doc->GetWordBreaker(getter_AddRefs(wb));
nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE,lb,wb);
PrepareUnicodeText(tx, ip, paintBuf, &textLength);
if (textLength <=0) //invalid frame to get position on
return NS_ERROR_FAILURE;
ip[mContentLength] = ip[mContentLength-1];
if ((ip[mContentLength]-mContentOffset) < textLength) {
//must set up last one for selection beyond edge if in boundary
@ -2010,7 +2016,8 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset,
NS_IMETHODIMP
nsTextFrame::PeekOffset(nsICaret *aCaret,
nsTextFrame::PeekOffset(nsIFocusTracker *aTracker,
nscoord aDesiredX,
nsSelectionAmount aAmount,
nsDirection aDirection,
PRInt32 aStartOffset,
@ -2034,7 +2041,7 @@ nsTextFrame::PeekOffset(nsICaret *aCaret,
NS_ASSERTION(PR_FALSE,"nsTextFrame::PeekOffset no more flow \n");
return NS_ERROR_INVALID_ARG;
}
return nextInFlow->PeekOffset(aCaret, aAmount,aDirection,aStartOffset,
return nextInFlow->PeekOffset(aTracker, aDesiredX, aAmount,aDirection,aStartOffset,
aResultContent,aContentOffset,aEatingWS);
}
@ -2112,11 +2119,11 @@ nsTextFrame::PeekOffset(nsICaret *aCaret,
}
if (!found){
if (frameUsed){
result = frameUsed->PeekOffset(aCaret, eSelectCharacter, aDirection, start, aResultContent,
result = frameUsed->PeekOffset(aTracker, aDesiredX, eSelectCharacter, aDirection, start, aResultContent,
aContentOffset, aEatingWS);
}
else {//reached end ask the frame for help
result = nsFrame::PeekOffset(aCaret, eSelectCharacter, aDirection, start, aResultContent,
result = nsFrame::PeekOffset(aTracker, aDesiredX, eSelectCharacter, aDirection, start, aResultContent,
aContentOffset, aEatingWS);
}
}
@ -2193,11 +2200,11 @@ nsTextFrame::PeekOffset(nsICaret *aCaret,
}
if (!found || (*aContentOffset > (mContentOffset + mContentLength)) || (*aContentOffset < mContentOffset)){ //gone too far
if (frameUsed){
result = frameUsed->PeekOffset(aCaret, aAmount, aDirection, start, aResultContent,
result = frameUsed->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, start, aResultContent,
aContentOffset, aEatingWS);
}
else {//reached end ask the frame for help
result = nsFrame::PeekOffset(aCaret, aAmount, aDirection, start, aResultContent,
result = nsFrame::PeekOffset(aTracker, aDesiredX, aAmount, aDirection, start, aResultContent,
aContentOffset, aEatingWS);
}
}
@ -2210,30 +2217,15 @@ nsTextFrame::PeekOffset(nsICaret *aCaret,
break;
case eSelectLine :
{
#if 0
nsPoint origin;
nsIView* view;
nsPoint coord;
PRBool collapsed;
result = aCaret->GetWindowRelativeCoordinates(coord,collapsed);
if (NS_FAILED(result))
return result;
nsIFrame *frame = GetPrevInFlow();
while(frame){
result = NS_OK;
nsPoint futurecoord;
do {
result = frame->GetOffsetFromView(futurecoord, &view);
// Cleanup
if (paintBuf != paintBufMem) {
delete [] paintBuf;
}
while (NS_SUCCEEDED(result) && view);
if (coord.y < futurecoord.y)
{
lineup = PR_TRUE;
GetPosition
if (ip != indicies) {
delete [] ip;
}
}
#endif
return nsFrame::PeekOffset(aTracker, aDesiredX, aAmount, aDirection, aStartOffset,
aResultContent, aContentOffset, aEatingWS);
}
break;
default: result = NS_ERROR_FAILURE; break;
@ -2269,9 +2261,9 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
nsInputEvent *inputEvent = (nsInputEvent *)aEvent;
if (NS_SUCCEEDED(rv) && shell) {
nsCOMPtr<nsIRenderingContext> acx;
nsCOMPtr<nsICaret> caret;
rv = shell->GetCaret(getter_AddRefs(caret));
if (NS_FAILED(rv))
nsCOMPtr<nsIFocusTracker> tracker;
tracker = do_QueryInterface(shell, &rv);
if (NS_FAILED(rv) || !tracker)
return rv;
rv = shell->CreateRenderingContext(this, getter_AddRefs(acx));
if (NS_SUCCEEDED(rv)){
@ -2289,7 +2281,8 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
PRInt32 startOffset;
PRInt32 endOffset;
//peeks{}
rv = PeekOffset(caret,
rv = PeekOffset(tracker,
0,
eSelectWord,
eDirPrevious,
startPos,
@ -2298,7 +2291,8 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
PR_FALSE);
if (NS_FAILED(rv))
return rv;
rv = PeekOffset(caret,
rv = PeekOffset(tracker,
0,
eSelectWord,
eDirNext,
startPos,
@ -3100,3 +3094,49 @@ nsTextFrame::List(FILE* out, PRInt32 aIndent) const
return NS_OK;
}
//STORAGE FOR LATER MAYBE
#if 0
nsTextFrame *frame = this;
while(frame = (nsTextFrame *)frame->GetPrevInFlow()){
result = NS_OK;
nsPoint futurecoord;
frame->GetOffsetFromView(futurecoord, &view);
if (view == nsnull) return NS_ERROR_UNEXPECTED;
nscoord x,y;
do {
view->GetPosition(&x, &y);
futurecoord.x += x;
futurecoord.y += y;
view->GetParent(view);
} while (view);
if (coord.y > futurecoord.y)
{
if (coord.x < futurecoord.x)
{//keep going back until y is up again or coord.x is greater than future coord.x
nsTextFrame *lookahead = nsnull;
while(lookahead = (nsTextFrame *)frame->GetPrevInFlow()){
result = NS_OK;
nsPoint futurecoord2;
lookahead->GetOffsetFromView(futurecoord2, &view);
if (view == nsnull) return NS_ERROR_UNEXPECTED;
do {
view->GetPosition(&x, &y);
futurecoord2.x += x;
futurecoord2.y += y;
view->GetParent(view);
} while (view);
if (futurecoord.y > futurecoord2.y)//gone too far
break;
frame = lookahead;
futurecoord = futurecoord2;
if (coord.x >=futurecoord2.x)
break;
}
}
//definately this one then
nscoord newcoord;
newcoord = coord.x ;//- futurecoord.x;
#endif

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

@ -39,6 +39,11 @@ public:
nsHTMLReflowMetrics& aDesiredSize,
const nsHTMLReflowState& aReflowState,
nsReflowStatus& aStatus);
NS_IMETHOD GetPosition(nsIPresContext& aCX,
nscoord aXCoord,
nsIContent ** aNewContent,
PRInt32& aContentOffset,
PRInt32& aContentOffsetEnd);
protected:
virtual ~BRFrame();
@ -130,3 +135,14 @@ BRFrame::Reflow(nsIPresContext& aPresContext,
}
return NS_OK;
}
NS_IMETHODIMP BRFrame::GetPosition(nsIPresContext&,
nscoord ,
nsIContent ** ,
PRInt32& ,
PRInt32& )
{
return NS_ERROR_FAILURE;
}

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

@ -87,6 +87,8 @@ nsIContent * fTrackerContentArrayAddList[1024];
PRInt32 fTrackerAddListMax = 0;
#include "nsICaret.h"
#include "nsILineIterator.h"
// [HACK] Foward Declarations
void ForceDrawFrame(nsFrame * aFrame);
#if 0
@ -922,7 +924,7 @@ NS_IMETHODIMP nsFrame::HandleDrag(nsIPresContext& aPresContext,
if (!DisplaySelection(aPresContext)) {
return NS_OK;
}
printf("handledrag %x\n",this);
nsCOMPtr<nsIPresShell> shell;
nsresult rv = aPresContext.GetShell(getter_AddRefs(shell));
if (NS_SUCCEEDED(rv) && shell) {
@ -1631,18 +1633,123 @@ nsFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset, PRInt32* outFram
}
NS_IMETHODIMP
nsFrame::PeekOffset(nsICaret *aCaret,
nsFrame::PeekOffset(nsIFocusTracker *aTracker,
nscoord aDesiredX,
nsSelectionAmount aAmount,
nsDirection aDirection,
PRInt32 aStartOffset,
nsIContent **aResultContent,
PRInt32 *aContentOffset,
PRBool aEatingWS)
{
if (!aResultContent || !aContentOffset ||!aTracker)
return NS_ERROR_NULL_POINTER;
nsresult result;
switch (aAmount){
case eSelectLine :
{
if (!aTracker)
return NS_ERROR_NULL_POINTER;
nscoord coord = aDesiredX;
nsCOMPtr<nsILineIterator> it;
nsIFrame *blockFrame = this;
nsIFrame *thisBlock = this;
result = blockFrame->GetParent(&blockFrame);
if (NS_FAILED(result)) //if at line 0 then nothing to do
return result;
result = blockFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it));
while (NS_FAILED(result) && blockFrame)
{
thisBlock = blockFrame;
result = blockFrame->GetParent(&blockFrame);
if (NS_SUCCEEDED(result) && blockFrame){
result = blockFrame->QueryInterface(nsILineIterator::GetIID(),getter_AddRefs(it));
}
}
if (NS_FAILED(result) || !it || !blockFrame)
return result;
nsIFrame *resultFrame = nsnull;
PRInt32 thisLine = 0;
result = it->FindLineContaining(thisBlock, &thisLine);
if (NS_FAILED(result)) //if at line 0 then nothing to do
return result;
PRInt32 searchingLine = thisLine;
PRBool isBeforeFirstFrame, isAfterLastFrame;
PRBool found = PR_FALSE;
while (!found)
{
if (aDirection == eDirPrevious)
searchingLine --;
else
searchingLine ++;
result = it->FindFrameAt(searchingLine, coord, &resultFrame, &isBeforeFirstFrame, &isAfterLastFrame);
if (NS_SUCCEEDED(result) && resultFrame)
{
nsIFrame *child;
PRBool exhaustedAllSiblings = PR_FALSE;
while ( !found && !exhaustedAllSiblings)
{
while (NS_SUCCEEDED(resultFrame->FirstChild(nsnull, &child)) && child){
resultFrame = child;
if (aDirection == eDirPrevious) //go to last child now.
{
while (NS_SUCCEEDED(result) && child)
{
resultFrame = child;
result = resultFrame->GetNextSibling(&child);
}
}
}
if (!resultFrame)
return NS_ERROR_FAILURE;
//now we need to get the local frame coordinates
coord = PR_MAX(0, coord);
nsCOMPtr<nsIPresContext> context;
result = aTracker->GetPresContext(getter_AddRefs(context));
result = resultFrame->GetPosition(*(context.get()),coord,
aResultContent,*aContentOffset, *aContentOffset);
//if (isAfterLastFrame) //get previous frame.
if (NS_SUCCEEDED(result))
found = PR_TRUE;
else{
if (aDirection == eDirNext)
#if 0 {
result = resultFrame->GetPrevSibling(&child);
}
else
#endif
result = resultFrame->GetNextSibling(&child);
if (NS_FAILED(result) || !child)
exhaustedAllSiblings = PR_TRUE;
else
resultFrame = child;
}
}
}
else {
//we need to jump to new block frame.
if (aDirection == eDirNext)
return blockFrame->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, 0, aResultContent,
aContentOffset, aEatingWS);
else
return blockFrame->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, -1, aResultContent,
aContentOffset, aEatingWS);
}
}
break;
}
default:
{
//this will use the nsFrameTraversal as the default peek method.
//this should change to use geometry and also look to ALL the child lists
nsCOMPtr<nsIBidirectionalEnumerator> frameTraversal;
nsresult result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,this);
result = NS_NewFrameTraversal(getter_AddRefs(frameTraversal),LEAF,this);
if (NS_FAILED(result))
return result;
nsISupports *isupports = nsnull;
@ -1662,12 +1769,13 @@ nsFrame::PeekOffset(nsICaret *aCaret,
//for speed reasons
nsIFrame *newFrame = (nsIFrame *)isupports;
if (aDirection == eDirNext)
return newFrame->PeekOffset(aCaret, aAmount, aDirection, 0, aResultContent,
return newFrame->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, 0, aResultContent,
aContentOffset, aEatingWS);
else
return newFrame->PeekOffset(aCaret, aAmount, aDirection, -1, aResultContent,
return newFrame->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, -1, aResultContent,
aContentOffset, aEatingWS);
}
}
return NS_OK;
}

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

@ -211,7 +211,8 @@ public:
NS_IMETHOD VerifyTree() const;
NS_IMETHOD SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread);
NS_IMETHOD GetSelected(PRBool *aSelected) const;
NS_IMETHOD PeekOffset(nsICaret *aCaret,
NS_IMETHOD PeekOffset(nsIFocusTracker *aTracker,
nscoord aDesiredX,
nsSelectionAmount aAmount,
nsDirection aDirection,
PRInt32 aStartOffset,

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

@ -158,7 +158,7 @@ HRuleFrame::Paint(nsIPresContext& aPresContext,
width - diameter, height);
}
}
return NS_OK;
return nsFrame::Paint(aPresContext, aRenderingContext, aDirtyRect, aWhichLayer);
}
NS_IMETHODIMP

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

@ -56,6 +56,8 @@
#include "nsIDOMSelection.h"
#include "nsIDOMRange.h"
#include "nsILineIterator.h"
static NS_DEFINE_IID(kIDOMTextIID, NS_IDOMTEXT_IID);
#ifdef NS_DEBUG
@ -238,7 +240,8 @@ public:
NS_IMETHOD SetSelected(nsIDOMRange *aRange,PRBool aSelected, nsSpread aSpread);
NS_IMETHOD PeekOffset(nsICaret *aCaret,
NS_IMETHOD PeekOffset(nsIFocusTracker *aTracker,
nscoord aDesiredX,
nsSelectionAmount aAmount,
nsDirection aDirection,
PRInt32 aStartOffset,
@ -1007,7 +1010,8 @@ nsTextFrame::GetPositionSlowly(nsIPresContext& aPresContext,
doc->GetWordBreaker(getter_AddRefs(wb));
nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE, lb,wb);
PrepareUnicodeText(tx, ip, paintBuf, &textLength);
if (textLength <= 0)
return NS_ERROR_FAILURE;
nsPoint origin;
nsIView * view;
GetView(&view);
@ -1750,6 +1754,8 @@ nsTextFrame::GetPosition(nsIPresContext& aCX,
doc->GetWordBreaker(getter_AddRefs(wb));
nsTextTransformer tx(wordBufMem, WORD_BUF_SIZE,lb,wb);
PrepareUnicodeText(tx, ip, paintBuf, &textLength);
if (textLength <=0) //invalid frame to get position on
return NS_ERROR_FAILURE;
ip[mContentLength] = ip[mContentLength-1];
if ((ip[mContentLength]-mContentOffset) < textLength) {
//must set up last one for selection beyond edge if in boundary
@ -2010,7 +2016,8 @@ nsTextFrame::GetChildFrameContainingOffset(PRInt32 inContentOffset,
NS_IMETHODIMP
nsTextFrame::PeekOffset(nsICaret *aCaret,
nsTextFrame::PeekOffset(nsIFocusTracker *aTracker,
nscoord aDesiredX,
nsSelectionAmount aAmount,
nsDirection aDirection,
PRInt32 aStartOffset,
@ -2034,7 +2041,7 @@ nsTextFrame::PeekOffset(nsICaret *aCaret,
NS_ASSERTION(PR_FALSE,"nsTextFrame::PeekOffset no more flow \n");
return NS_ERROR_INVALID_ARG;
}
return nextInFlow->PeekOffset(aCaret, aAmount,aDirection,aStartOffset,
return nextInFlow->PeekOffset(aTracker, aDesiredX, aAmount,aDirection,aStartOffset,
aResultContent,aContentOffset,aEatingWS);
}
@ -2112,11 +2119,11 @@ nsTextFrame::PeekOffset(nsICaret *aCaret,
}
if (!found){
if (frameUsed){
result = frameUsed->PeekOffset(aCaret, eSelectCharacter, aDirection, start, aResultContent,
result = frameUsed->PeekOffset(aTracker, aDesiredX, eSelectCharacter, aDirection, start, aResultContent,
aContentOffset, aEatingWS);
}
else {//reached end ask the frame for help
result = nsFrame::PeekOffset(aCaret, eSelectCharacter, aDirection, start, aResultContent,
result = nsFrame::PeekOffset(aTracker, aDesiredX, eSelectCharacter, aDirection, start, aResultContent,
aContentOffset, aEatingWS);
}
}
@ -2193,11 +2200,11 @@ nsTextFrame::PeekOffset(nsICaret *aCaret,
}
if (!found || (*aContentOffset > (mContentOffset + mContentLength)) || (*aContentOffset < mContentOffset)){ //gone too far
if (frameUsed){
result = frameUsed->PeekOffset(aCaret, aAmount, aDirection, start, aResultContent,
result = frameUsed->PeekOffset(aTracker, aDesiredX, aAmount, aDirection, start, aResultContent,
aContentOffset, aEatingWS);
}
else {//reached end ask the frame for help
result = nsFrame::PeekOffset(aCaret, aAmount, aDirection, start, aResultContent,
result = nsFrame::PeekOffset(aTracker, aDesiredX, aAmount, aDirection, start, aResultContent,
aContentOffset, aEatingWS);
}
}
@ -2210,30 +2217,15 @@ nsTextFrame::PeekOffset(nsICaret *aCaret,
break;
case eSelectLine :
{
#if 0
nsPoint origin;
nsIView* view;
nsPoint coord;
PRBool collapsed;
result = aCaret->GetWindowRelativeCoordinates(coord,collapsed);
if (NS_FAILED(result))
return result;
nsIFrame *frame = GetPrevInFlow();
while(frame){
result = NS_OK;
nsPoint futurecoord;
do {
result = frame->GetOffsetFromView(futurecoord, &view);
// Cleanup
if (paintBuf != paintBufMem) {
delete [] paintBuf;
}
while (NS_SUCCEEDED(result) && view);
if (coord.y < futurecoord.y)
{
lineup = PR_TRUE;
GetPosition
if (ip != indicies) {
delete [] ip;
}
}
#endif
return nsFrame::PeekOffset(aTracker, aDesiredX, aAmount, aDirection, aStartOffset,
aResultContent, aContentOffset, aEatingWS);
}
break;
default: result = NS_ERROR_FAILURE; break;
@ -2269,9 +2261,9 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
nsInputEvent *inputEvent = (nsInputEvent *)aEvent;
if (NS_SUCCEEDED(rv) && shell) {
nsCOMPtr<nsIRenderingContext> acx;
nsCOMPtr<nsICaret> caret;
rv = shell->GetCaret(getter_AddRefs(caret));
if (NS_FAILED(rv))
nsCOMPtr<nsIFocusTracker> tracker;
tracker = do_QueryInterface(shell, &rv);
if (NS_FAILED(rv) || !tracker)
return rv;
rv = shell->CreateRenderingContext(this, getter_AddRefs(acx));
if (NS_SUCCEEDED(rv)){
@ -2289,7 +2281,8 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
PRInt32 startOffset;
PRInt32 endOffset;
//peeks{}
rv = PeekOffset(caret,
rv = PeekOffset(tracker,
0,
eSelectWord,
eDirPrevious,
startPos,
@ -2298,7 +2291,8 @@ nsTextFrame::HandleMultiplePress(nsIPresContext& aPresContext,
PR_FALSE);
if (NS_FAILED(rv))
return rv;
rv = PeekOffset(caret,
rv = PeekOffset(tracker,
0,
eSelectWord,
eDirNext,
startPos,
@ -3100,3 +3094,49 @@ nsTextFrame::List(FILE* out, PRInt32 aIndent) const
return NS_OK;
}
//STORAGE FOR LATER MAYBE
#if 0
nsTextFrame *frame = this;
while(frame = (nsTextFrame *)frame->GetPrevInFlow()){
result = NS_OK;
nsPoint futurecoord;
frame->GetOffsetFromView(futurecoord, &view);
if (view == nsnull) return NS_ERROR_UNEXPECTED;
nscoord x,y;
do {
view->GetPosition(&x, &y);
futurecoord.x += x;
futurecoord.y += y;
view->GetParent(view);
} while (view);
if (coord.y > futurecoord.y)
{
if (coord.x < futurecoord.x)
{//keep going back until y is up again or coord.x is greater than future coord.x
nsTextFrame *lookahead = nsnull;
while(lookahead = (nsTextFrame *)frame->GetPrevInFlow()){
result = NS_OK;
nsPoint futurecoord2;
lookahead->GetOffsetFromView(futurecoord2, &view);
if (view == nsnull) return NS_ERROR_UNEXPECTED;
do {
view->GetPosition(&x, &y);
futurecoord2.x += x;
futurecoord2.y += y;
view->GetParent(view);
} while (view);
if (futurecoord.y > futurecoord2.y)//gone too far
break;
frame = lookahead;
futurecoord = futurecoord2;
if (coord.x >=futurecoord2.x)
break;
}
}
//definately this one then
nscoord newcoord;
newcoord = coord.x ;//- futurecoord.x;
#endif