TextDocumentView: Preparations for selection support
Added methods to deal with caret offset and selection anchor, constructing a BShape enclosing the selection range and drawing it. Added mouse event stubs.
This commit is contained in:
@@ -8,6 +8,7 @@
|
|||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
|
|
||||||
#include <ScrollBar.h>
|
#include <ScrollBar.h>
|
||||||
|
#include <Shape.h>
|
||||||
|
|
||||||
|
|
||||||
TextDocumentView::TextDocumentView(const char* name)
|
TextDocumentView::TextDocumentView(const char* name)
|
||||||
@@ -16,7 +17,14 @@ TextDocumentView::TextDocumentView(const char* name)
|
|||||||
fInsetLeft(0.0f),
|
fInsetLeft(0.0f),
|
||||||
fInsetTop(0.0f),
|
fInsetTop(0.0f),
|
||||||
fInsetRight(0.0f),
|
fInsetRight(0.0f),
|
||||||
fInsetBottom(0.0f)
|
fInsetBottom(0.0f),
|
||||||
|
|
||||||
|
fSelectionAnchorOffset(0),
|
||||||
|
fCaretOffset(0),
|
||||||
|
fCaretAnchorX(0.0f),
|
||||||
|
fShowCaret(false),
|
||||||
|
|
||||||
|
fMouseDown(false)
|
||||||
{
|
{
|
||||||
fTextDocumentLayout.SetWidth(_TextLayoutWidth(Bounds().Width()));
|
fTextDocumentLayout.SetWidth(_TextLayoutWidth(Bounds().Width()));
|
||||||
|
|
||||||
@@ -37,6 +45,28 @@ TextDocumentView::Draw(BRect updateRect)
|
|||||||
|
|
||||||
fTextDocumentLayout.SetWidth(_TextLayoutWidth(Bounds().Width()));
|
fTextDocumentLayout.SetWidth(_TextLayoutWidth(Bounds().Width()));
|
||||||
fTextDocumentLayout.Draw(this, BPoint(fInsetLeft, fInsetTop), updateRect);
|
fTextDocumentLayout.Draw(this, BPoint(fInsetLeft, fInsetTop), updateRect);
|
||||||
|
|
||||||
|
if (fSelectionAnchorOffset == fCaretOffset)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int32 start;
|
||||||
|
int32 end;
|
||||||
|
if (fSelectionAnchorOffset <= fCaretOffset) {
|
||||||
|
start = fSelectionAnchorOffset;
|
||||||
|
end = fCaretOffset;
|
||||||
|
} else {
|
||||||
|
start = fCaretOffset;
|
||||||
|
end = fSelectionAnchorOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
BShape shape;
|
||||||
|
_GetSelectionShape(shape, start, end);
|
||||||
|
|
||||||
|
SetHighColor(60, 40, 0);
|
||||||
|
SetDrawingMode(B_OP_SUBTRACT);
|
||||||
|
|
||||||
|
MovePenTo(fInsetLeft, fInsetTop);
|
||||||
|
FillShape(&shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -55,6 +85,25 @@ TextDocumentView::FrameResized(float width, float height)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TextDocumentView::MouseDown(BPoint where)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TextDocumentView::MouseUp(BPoint where)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TextDocumentView::MouseMoved(BPoint where, uint32 transit,
|
||||||
|
const BMessage* dragMessage)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
BSize
|
BSize
|
||||||
TextDocumentView::MinSize()
|
TextDocumentView::MinSize()
|
||||||
{
|
{
|
||||||
@@ -106,6 +155,11 @@ TextDocumentView::SetTextDocument(const TextDocumentRef& document)
|
|||||||
{
|
{
|
||||||
fTextDocument = document;
|
fTextDocument = document;
|
||||||
fTextDocumentLayout.SetTextDocument(fTextDocument);
|
fTextDocumentLayout.SetTextDocument(fTextDocument);
|
||||||
|
|
||||||
|
fSelectionAnchorOffset = 0;
|
||||||
|
fCaretOffset = 0;
|
||||||
|
fCaretAnchorX = 0.0f;
|
||||||
|
|
||||||
InvalidateLayout();
|
InvalidateLayout();
|
||||||
Invalidate();
|
Invalidate();
|
||||||
_UpdateScrollBars();
|
_UpdateScrollBars();
|
||||||
@@ -192,3 +246,112 @@ TextDocumentView::_UpdateScrollBars()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TextDocumentView::_SetCaretOffset(int32 offset, bool updateAnchor,
|
||||||
|
bool lockSelectionAnchor)
|
||||||
|
{
|
||||||
|
if (offset < 0)
|
||||||
|
offset = 0;
|
||||||
|
int32 length = fTextDocument->Length();
|
||||||
|
if (offset > length)
|
||||||
|
offset = length;
|
||||||
|
|
||||||
|
if (offset == fCaretOffset && (lockSelectionAnchor
|
||||||
|
|| offset == fSelectionAnchorOffset)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!lockSelectionAnchor)
|
||||||
|
fSelectionAnchorOffset = offset;
|
||||||
|
|
||||||
|
fCaretOffset = offset;
|
||||||
|
fShowCaret = true;
|
||||||
|
|
||||||
|
if (updateAnchor) {
|
||||||
|
float x1;
|
||||||
|
float y1;
|
||||||
|
float x2;
|
||||||
|
float y2;
|
||||||
|
|
||||||
|
fTextDocumentLayout.GetTextBounds(fCaretOffset, x1, y1, x2, y2);
|
||||||
|
fCaretAnchorX = x1;
|
||||||
|
}
|
||||||
|
|
||||||
|
Invalidate();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// _GetSelectionShape
|
||||||
|
void
|
||||||
|
TextDocumentView::_GetSelectionShape(BShape& shape,
|
||||||
|
int32 start, int32 end)
|
||||||
|
{
|
||||||
|
float startX1;
|
||||||
|
float startY1;
|
||||||
|
float startX2;
|
||||||
|
float startY2;
|
||||||
|
fTextDocumentLayout.GetTextBounds(start, startX1, startY1, startX2,
|
||||||
|
startY2);
|
||||||
|
|
||||||
|
float endX1;
|
||||||
|
float endY1;
|
||||||
|
float endX2;
|
||||||
|
float endY2;
|
||||||
|
fTextDocumentLayout.GetTextBounds(end, endX1, endY1, endX2, endY2);
|
||||||
|
|
||||||
|
int32 startLineIndex = fTextDocumentLayout.LineIndexForOffset(start);
|
||||||
|
int32 endLineIndex = fTextDocumentLayout.LineIndexForOffset(end);
|
||||||
|
|
||||||
|
if (startLineIndex == endLineIndex) {
|
||||||
|
// Selection on one line
|
||||||
|
BPoint lt(startX1, startY1);
|
||||||
|
BPoint rt(endX1, endY1);
|
||||||
|
BPoint rb(endX1, endY2);
|
||||||
|
BPoint lb(startX1, startY2);
|
||||||
|
|
||||||
|
shape.MoveTo(lt);
|
||||||
|
shape.LineTo(rt);
|
||||||
|
shape.LineTo(rb);
|
||||||
|
shape.LineTo(lb);
|
||||||
|
shape.Close();
|
||||||
|
} else if (startLineIndex == endLineIndex - 1 && endX1 <= startX1) {
|
||||||
|
// Selection on two lines, with gap:
|
||||||
|
// ---------
|
||||||
|
// ------###
|
||||||
|
// ##-------
|
||||||
|
// ---------
|
||||||
|
BPoint lt(startX1, startY1);
|
||||||
|
BPoint rt(fTextDocumentLayout.Width(), startY1);
|
||||||
|
BPoint rb(fTextDocumentLayout.Width(), startY2);
|
||||||
|
BPoint lb(startX1, startY2);
|
||||||
|
|
||||||
|
shape.MoveTo(lt);
|
||||||
|
shape.LineTo(rt);
|
||||||
|
shape.LineTo(rb);
|
||||||
|
shape.LineTo(lb);
|
||||||
|
shape.Close();
|
||||||
|
|
||||||
|
lt = BPoint(0, endY1);
|
||||||
|
rt = BPoint(endX1, endY1);
|
||||||
|
rb = BPoint(endX1, endY2);
|
||||||
|
lb = BPoint(0, endY2);
|
||||||
|
|
||||||
|
shape.MoveTo(lt);
|
||||||
|
shape.LineTo(rt);
|
||||||
|
shape.LineTo(rb);
|
||||||
|
shape.LineTo(lb);
|
||||||
|
shape.Close();
|
||||||
|
} else {
|
||||||
|
// Selection over multiple lines
|
||||||
|
shape.MoveTo(BPoint(startX1, startY1));
|
||||||
|
shape.LineTo(BPoint(fTextDocumentLayout.Width(), startY1));
|
||||||
|
shape.LineTo(BPoint(fTextDocumentLayout.Width(), endY1));
|
||||||
|
shape.LineTo(BPoint(endX1, endY1));
|
||||||
|
shape.LineTo(BPoint(endX1, endY2));
|
||||||
|
shape.LineTo(BPoint(0, endY2));
|
||||||
|
shape.LineTo(BPoint(0, startY2));
|
||||||
|
shape.LineTo(BPoint(startX1, startY2));
|
||||||
|
shape.Close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -22,6 +22,11 @@ public:
|
|||||||
virtual void AttachedToWindow();
|
virtual void AttachedToWindow();
|
||||||
virtual void FrameResized(float width, float height);
|
virtual void FrameResized(float width, float height);
|
||||||
|
|
||||||
|
virtual void MouseDown(BPoint where);
|
||||||
|
virtual void MouseUp(BPoint where);
|
||||||
|
virtual void MouseMoved(BPoint where, uint32 transit,
|
||||||
|
const BMessage* dragMessage);
|
||||||
|
|
||||||
virtual BSize MinSize();
|
virtual BSize MinSize();
|
||||||
virtual BSize MaxSize();
|
virtual BSize MaxSize();
|
||||||
virtual BSize PreferredSize();
|
virtual BSize PreferredSize();
|
||||||
@@ -42,6 +47,12 @@ private:
|
|||||||
|
|
||||||
void _UpdateScrollBars();
|
void _UpdateScrollBars();
|
||||||
|
|
||||||
|
void _SetCaretOffset(int32 offset, bool updateAnchor,
|
||||||
|
bool lockSelectionAnchor);
|
||||||
|
|
||||||
|
void _GetSelectionShape(BShape& shape,
|
||||||
|
int32 start, int32 end);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextDocumentRef fTextDocument;
|
TextDocumentRef fTextDocument;
|
||||||
TextDocumentLayout fTextDocumentLayout;
|
TextDocumentLayout fTextDocumentLayout;
|
||||||
@@ -50,6 +61,13 @@ private:
|
|||||||
float fInsetTop;
|
float fInsetTop;
|
||||||
float fInsetRight;
|
float fInsetRight;
|
||||||
float fInsetBottom;
|
float fInsetBottom;
|
||||||
|
|
||||||
|
int32 fSelectionAnchorOffset;
|
||||||
|
int32 fCaretOffset;
|
||||||
|
float fCaretAnchorX;
|
||||||
|
bool fShowCaret;
|
||||||
|
|
||||||
|
bool fMouseDown;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // TEXT_DOCUMENT_VIEW_H
|
#endif // TEXT_DOCUMENT_VIEW_H
|
||||||
|
|||||||
Reference in New Issue
Block a user