Fleshed out more TextEditor functionality.
TextDocumentView now always has a TextEditor, but editing can be disabled. The selection code lives only in TextEditor. Implemented more cursor navigation code.
This commit is contained in:
@@ -24,14 +24,14 @@ TextDocumentView::TextDocumentView(const char* name)
|
|||||||
fInsetRight(0.0f),
|
fInsetRight(0.0f),
|
||||||
fInsetBottom(0.0f),
|
fInsetBottom(0.0f),
|
||||||
|
|
||||||
fSelectionAnchorOffset(0),
|
fCaretBounds(),
|
||||||
fCaretOffset(0),
|
|
||||||
fCaretAnchorX(0.0f),
|
|
||||||
fShowCaret(false),
|
fShowCaret(false),
|
||||||
|
|
||||||
fMouseDown(false)
|
fMouseDown(false)
|
||||||
{
|
{
|
||||||
fTextDocumentLayout.SetWidth(_TextLayoutWidth(Bounds().Width()));
|
fTextDocumentLayout.SetWidth(_TextLayoutWidth(Bounds().Width()));
|
||||||
|
|
||||||
|
// Set default TextEditor
|
||||||
|
SetTextEditor(TextEditorRef(new(std::nothrow) TextEditor(), true));
|
||||||
|
|
||||||
SetViewColor(B_TRANSPARENT_COLOR);
|
SetViewColor(B_TRANSPARENT_COLOR);
|
||||||
SetLowColor(255, 255, 255, 255);
|
SetLowColor(255, 255, 255, 255);
|
||||||
@@ -67,11 +67,14 @@ 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);
|
||||||
|
|
||||||
bool isCaret = fSelectionAnchorOffset == fCaretOffset;
|
if (fTextEditor.Get() == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool isCaret = fTextEditor->SelectionLength() == 0;
|
||||||
|
|
||||||
if (isCaret) {
|
if (isCaret) {
|
||||||
if (fShowCaret && fTextEditor.Get() != NULL)
|
if (fShowCaret && fTextEditor->IsEditingEnabled())
|
||||||
_DrawCaret(fCaretOffset);
|
_DrawCaret(fTextEditor->CaretOffset());
|
||||||
} else {
|
} else {
|
||||||
_DrawSelection();
|
_DrawSelection();
|
||||||
}
|
}
|
||||||
@@ -174,11 +177,13 @@ TextDocumentView::KeyDown(const char* bytes, int32 numBytes)
|
|||||||
|
|
||||||
if (Window() != NULL && Window()->CurrentMessage() != NULL) {
|
if (Window() != NULL && Window()->CurrentMessage() != NULL) {
|
||||||
BMessage* message = Window()->CurrentMessage();
|
BMessage* message = Window()->CurrentMessage();
|
||||||
message->FindInt32("key", &event.key);
|
message->FindInt32("raw_char", &event.key);
|
||||||
message->FindInt32("modifiers", &event.modifiers);
|
message->FindInt32("modifiers", &event.modifiers);
|
||||||
}
|
}
|
||||||
|
|
||||||
fTextEditor->KeyDown(event);
|
fTextEditor->KeyDown(event);
|
||||||
|
fShowCaret = true;
|
||||||
|
Invalidate();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -245,16 +250,20 @@ TextDocumentView::SetTextDocument(const TextDocumentRef& document)
|
|||||||
if (fTextEditor.Get() != NULL)
|
if (fTextEditor.Get() != NULL)
|
||||||
fTextEditor->SetDocument(document);
|
fTextEditor->SetDocument(document);
|
||||||
|
|
||||||
fSelectionAnchorOffset = 0;
|
|
||||||
fCaretOffset = 0;
|
|
||||||
fCaretAnchorX = 0.0f;
|
|
||||||
|
|
||||||
InvalidateLayout();
|
InvalidateLayout();
|
||||||
Invalidate();
|
Invalidate();
|
||||||
_UpdateScrollBars();
|
_UpdateScrollBars();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TextDocumentView::SetEditingEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
if (fTextEditor.Get() != NULL)
|
||||||
|
fTextEditor->SetEditingEnabled(enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TextDocumentView::SetTextEditor(const TextEditorRef& editor)
|
TextDocumentView::SetTextEditor(const TextEditorRef& editor)
|
||||||
{
|
{
|
||||||
@@ -262,6 +271,8 @@ TextDocumentView::SetTextEditor(const TextEditorRef& editor)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (fTextEditor.Get() != NULL) {
|
if (fTextEditor.Get() != NULL) {
|
||||||
|
fTextEditor->SetDocument(TextDocumentRef());
|
||||||
|
fTextEditor->SetLayout(TextDocumentLayoutRef());
|
||||||
// TODO: Probably has to remove listeners
|
// TODO: Probably has to remove listeners
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -269,6 +280,8 @@ TextDocumentView::SetTextEditor(const TextEditorRef& editor)
|
|||||||
|
|
||||||
if (fTextEditor.Get() != NULL) {
|
if (fTextEditor.Get() != NULL) {
|
||||||
fTextEditor->SetDocument(fTextDocument);
|
fTextEditor->SetDocument(fTextDocument);
|
||||||
|
fTextEditor->SetLayout(TextDocumentLayoutRef(
|
||||||
|
&fTextDocumentLayout));
|
||||||
// TODO: Probably has to add listeners
|
// TODO: Probably has to add listeners
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -307,38 +320,33 @@ TextDocumentView::SetInsets(float left, float top, float right, float bottom)
|
|||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TextDocumentView::SetCaret(const BPoint& location, bool extendSelection)
|
TextDocumentView::SetCaret(BPoint location, bool extendSelection)
|
||||||
{
|
{
|
||||||
if (fTextDocument.Get() == NULL)
|
if (fTextEditor.Get() == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
bool rightOfChar = false;
|
location.x -= fInsetLeft;
|
||||||
int32 caretOffset = fTextDocumentLayout.TextOffsetAt(
|
location.y -= fInsetTop;
|
||||||
location.x - fInsetLeft, location.y - fInsetTop, rightOfChar);
|
|
||||||
|
|
||||||
if (rightOfChar)
|
fTextEditor->SetCaret(location, extendSelection);
|
||||||
caretOffset++;
|
fShowCaret = !extendSelection;
|
||||||
|
Invalidate();
|
||||||
_SetCaretOffset(caretOffset, true, extendSelection);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
TextDocumentView::HasSelection() const
|
TextDocumentView::HasSelection() const
|
||||||
{
|
{
|
||||||
return fSelectionAnchorOffset != fCaretOffset;
|
return fTextEditor.Get() != NULL && fTextEditor->HasSelection();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TextDocumentView::GetSelection(int32& start, int32& end) const
|
TextDocumentView::GetSelection(int32& start, int32& end) const
|
||||||
{
|
{
|
||||||
if (fSelectionAnchorOffset <= fCaretOffset) {
|
if (fTextEditor.Get()) {
|
||||||
start = fSelectionAnchorOffset;
|
start = fTextEditor->SelectionStart();
|
||||||
end = fCaretOffset;
|
end = fTextEditor->SelectionEnd();
|
||||||
} else {
|
|
||||||
start = fCaretOffset;
|
|
||||||
end = fSelectionAnchorOffset;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -346,8 +354,7 @@ TextDocumentView::GetSelection(int32& start, int32& end) const
|
|||||||
void
|
void
|
||||||
TextDocumentView::Copy(BClipboard* clipboard)
|
TextDocumentView::Copy(BClipboard* clipboard)
|
||||||
{
|
{
|
||||||
if (fSelectionAnchorOffset == fCaretOffset
|
if (!HasSelection() || fTextDocument.Get() == NULL) {
|
||||||
|| fTextDocument.Get() == NULL) {
|
|
||||||
// Nothing to copy, don't clear clipboard contents for now reason.
|
// Nothing to copy, don't clear clipboard contents for now reason.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -425,41 +432,6 @@ 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TextDocumentView::_DrawCaret(int32 textOffset)
|
TextDocumentView::_DrawCaret(int32 textOffset)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -52,6 +52,7 @@ public:
|
|||||||
void SetTextDocument(
|
void SetTextDocument(
|
||||||
const TextDocumentRef& document);
|
const TextDocumentRef& document);
|
||||||
|
|
||||||
|
void SetEditingEnabled(bool enabled);
|
||||||
void SetTextEditor(
|
void SetTextEditor(
|
||||||
const TextEditorRef& editor);
|
const TextEditorRef& editor);
|
||||||
|
|
||||||
@@ -60,8 +61,7 @@ public:
|
|||||||
void SetInsets(float left, float top, float right,
|
void SetInsets(float left, float top, float right,
|
||||||
float bottom);
|
float bottom);
|
||||||
|
|
||||||
void SetCaret(const BPoint& where,
|
void SetCaret(BPoint where, bool extendSelection);
|
||||||
bool extendSelection);
|
|
||||||
|
|
||||||
bool HasSelection() const;
|
bool HasSelection() const;
|
||||||
void GetSelection(int32& start, int32& end) const;
|
void GetSelection(int32& start, int32& end) const;
|
||||||
@@ -73,9 +73,6 @@ private:
|
|||||||
|
|
||||||
void _UpdateScrollBars();
|
void _UpdateScrollBars();
|
||||||
|
|
||||||
void _SetCaretOffset(int32 offset, bool updateAnchor,
|
|
||||||
bool lockSelectionAnchor);
|
|
||||||
|
|
||||||
void _DrawCaret(int32 textOffset);
|
void _DrawCaret(int32 textOffset);
|
||||||
void _DrawSelection();
|
void _DrawSelection();
|
||||||
void _GetSelectionShape(BShape& shape,
|
void _GetSelectionShape(BShape& shape,
|
||||||
@@ -91,12 +88,8 @@ private:
|
|||||||
float fInsetRight;
|
float fInsetRight;
|
||||||
float fInsetBottom;
|
float fInsetBottom;
|
||||||
|
|
||||||
int32 fSelectionAnchorOffset;
|
|
||||||
int32 fCaretOffset;
|
|
||||||
float fCaretAnchorX;
|
|
||||||
bool fShowCaret;
|
|
||||||
BRect fCaretBounds;
|
BRect fCaretBounds;
|
||||||
|
bool fShowCaret;
|
||||||
bool fMouseDown;
|
bool fMouseDown;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ TextEditor::TextEditor()
|
|||||||
fLayout(),
|
fLayout(),
|
||||||
fSelection(),
|
fSelection(),
|
||||||
fCaretAnchorX(0.0f),
|
fCaretAnchorX(0.0f),
|
||||||
fStyleAtCaret()
|
fStyleAtCaret(),
|
||||||
|
fEditingEnabled(true)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -25,7 +26,13 @@ TextEditor::TextEditor(const TextEditor& other)
|
|||||||
fLayout(other.fLayout),
|
fLayout(other.fLayout),
|
||||||
fSelection(other.fSelection),
|
fSelection(other.fSelection),
|
||||||
fCaretAnchorX(other.fCaretAnchorX),
|
fCaretAnchorX(other.fCaretAnchorX),
|
||||||
fStyleAtCaret(other.fStyleAtCaret)
|
fStyleAtCaret(other.fStyleAtCaret),
|
||||||
|
fEditingEnabled(other.fEditingEnabled)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
TextEditor::~TextEditor()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -41,6 +48,7 @@ TextEditor::operator=(const TextEditor& other)
|
|||||||
fSelection = other.fSelection;
|
fSelection = other.fSelection;
|
||||||
fCaretAnchorX = other.fCaretAnchorX;
|
fCaretAnchorX = other.fCaretAnchorX;
|
||||||
fStyleAtCaret = other.fStyleAtCaret;
|
fStyleAtCaret = other.fStyleAtCaret;
|
||||||
|
fEditingEnabled = other.fEditingEnabled;
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -55,7 +63,8 @@ TextEditor::operator==(const TextEditor& other) const
|
|||||||
&& fLayout == other.fLayout
|
&& fLayout == other.fLayout
|
||||||
&& fSelection == other.fSelection
|
&& fSelection == other.fSelection
|
||||||
&& fCaretAnchorX == other.fCaretAnchorX
|
&& fCaretAnchorX == other.fCaretAnchorX
|
||||||
&& fStyleAtCaret == other.fStyleAtCaret;
|
&& fStyleAtCaret == other.fStyleAtCaret
|
||||||
|
&& fEditingEnabled == other.fEditingEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -85,6 +94,30 @@ TextEditor::SetLayout(const TextDocumentLayoutRef& ref)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TextEditor::SetEditingEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
fEditingEnabled = enabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TextEditor::SetCaret(BPoint location, bool extendSelection)
|
||||||
|
{
|
||||||
|
if (fDocument.Get() == NULL || fLayout.Get() == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
bool rightOfChar = false;
|
||||||
|
int32 caretOffset = fLayout->TextOffsetAt(location.x, location.y,
|
||||||
|
rightOfChar);
|
||||||
|
|
||||||
|
if (rightOfChar)
|
||||||
|
caretOffset++;
|
||||||
|
|
||||||
|
_SetCaretOffset(caretOffset, true, extendSelection, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
void
|
||||||
TextEditor::SetSelection(TextSelection selection)
|
TextEditor::SetSelection(TextSelection selection)
|
||||||
{
|
{
|
||||||
@@ -116,15 +149,15 @@ TextEditor::KeyDown(KeyEvent event)
|
|||||||
|
|
||||||
switch (event.key) {
|
switch (event.key) {
|
||||||
case B_UP_ARROW:
|
case B_UP_ARROW:
|
||||||
_LineUp(select);
|
LineUp(select);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case B_DOWN_ARROW:
|
case B_DOWN_ARROW:
|
||||||
_LineDown(select);
|
LineDown(select);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case B_LEFT_ARROW:
|
case B_LEFT_ARROW:
|
||||||
if (_HasSelection() && !select) {
|
if (HasSelection() && !select) {
|
||||||
_SetCaretOffset(
|
_SetCaretOffset(
|
||||||
std::min(fSelection.Caret(), fSelection.Anchor()),
|
std::min(fSelection.Caret(), fSelection.Anchor()),
|
||||||
true, false, true
|
true, false, true
|
||||||
@@ -134,7 +167,7 @@ TextEditor::KeyDown(KeyEvent event)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case B_RIGHT_ARROW:
|
case B_RIGHT_ARROW:
|
||||||
if (_HasSelection() && !select) {
|
if (HasSelection() && !select) {
|
||||||
_SetCaretOffset(
|
_SetCaretOffset(
|
||||||
std::max(fSelection.Caret(), fSelection.Anchor()),
|
std::max(fSelection.Caret(), fSelection.Anchor()),
|
||||||
true, false, true
|
true, false, true
|
||||||
@@ -144,11 +177,11 @@ TextEditor::KeyDown(KeyEvent event)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case B_HOME:
|
case B_HOME:
|
||||||
_LineStart(select);
|
LineStart(select);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case B_END:
|
case B_END:
|
||||||
_LineEnd(select);
|
LineEnd(select);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case B_ENTER:
|
case B_ENTER:
|
||||||
@@ -164,8 +197,8 @@ TextEditor::KeyDown(KeyEvent event)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case B_BACKSPACE:
|
case B_BACKSPACE:
|
||||||
if (_HasSelection()) {
|
if (HasSelection()) {
|
||||||
Remove(_SelectionStart(), _SelectionLength());
|
Remove(SelectionStart(), SelectionLength());
|
||||||
} else {
|
} else {
|
||||||
if (fSelection.Caret() > 0)
|
if (fSelection.Caret() > 0)
|
||||||
Remove(fSelection.Caret() - 1, 1);
|
Remove(fSelection.Caret() - 1, 1);
|
||||||
@@ -173,8 +206,8 @@ TextEditor::KeyDown(KeyEvent event)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case B_DELETE:
|
case B_DELETE:
|
||||||
if (_HasSelection()) {
|
if (HasSelection()) {
|
||||||
Remove(_SelectionStart(), _SelectionLength());
|
Remove(SelectionStart(), SelectionLength());
|
||||||
} else {
|
} else {
|
||||||
if (fSelection.Caret() < fDocument->Length())
|
if (fSelection.Caret() < fDocument->Length())
|
||||||
Remove(fSelection.Caret(), 1);
|
Remove(fSelection.Caret(), 1);
|
||||||
@@ -207,6 +240,9 @@ TextEditor::KeyDown(KeyEvent event)
|
|||||||
void
|
void
|
||||||
TextEditor::Insert(int32 offset, const BString& string)
|
TextEditor::Insert(int32 offset, const BString& string)
|
||||||
{
|
{
|
||||||
|
if (!fEditingEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
// TODO: ...
|
// TODO: ...
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -214,14 +250,119 @@ TextEditor::Insert(int32 offset, const BString& string)
|
|||||||
void
|
void
|
||||||
TextEditor::Remove(int32 offset, int32 length)
|
TextEditor::Remove(int32 offset, int32 length)
|
||||||
{
|
{
|
||||||
|
if (!fEditingEnabled)
|
||||||
|
return;
|
||||||
|
|
||||||
// TODO: ...
|
// TODO: ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TextEditor::LineUp(bool select)
|
||||||
|
{
|
||||||
|
if (fLayout.Get() == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int32 lineIndex = fLayout->LineIndexForOffset(fSelection.Caret());
|
||||||
|
_MoveToLine(lineIndex - 1, select);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TextEditor::LineDown(bool select)
|
||||||
|
{
|
||||||
|
if (fLayout.Get() == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int32 lineIndex = fLayout->LineIndexForOffset(fSelection.Caret());
|
||||||
|
_MoveToLine(lineIndex + 1, select);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TextEditor::LineStart(bool select)
|
||||||
|
{
|
||||||
|
if (fLayout.Get() == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int32 lineIndex = fLayout->LineIndexForOffset(fSelection.Caret());
|
||||||
|
_SetCaretOffset(fLayout->FirstOffsetOnLine(lineIndex), true, select,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
TextEditor::LineEnd(bool select)
|
||||||
|
{
|
||||||
|
if (fLayout.Get() == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
|
int32 lineIndex = fLayout->LineIndexForOffset(fSelection.Caret());
|
||||||
|
_SetCaretOffset(fLayout->LastOffsetOnLine(lineIndex), true, select,
|
||||||
|
true);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// #pragma mark -
|
||||||
|
|
||||||
|
|
||||||
|
bool
|
||||||
|
TextEditor::HasSelection() const
|
||||||
|
{
|
||||||
|
return SelectionLength() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
TextEditor::SelectionStart() const
|
||||||
|
{
|
||||||
|
return std::min(fSelection.Caret(), fSelection.Anchor());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
TextEditor::SelectionEnd() const
|
||||||
|
{
|
||||||
|
return std::max(fSelection.Caret(), fSelection.Anchor());
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int32
|
||||||
|
TextEditor::SelectionLength() const
|
||||||
|
{
|
||||||
|
return SelectionEnd() - SelectionStart();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark - private
|
// #pragma mark - private
|
||||||
|
|
||||||
|
|
||||||
// _SetCaretOffset
|
// _MoveToLine
|
||||||
|
void
|
||||||
|
TextEditor::_MoveToLine(int32 lineIndex, bool select)
|
||||||
|
{
|
||||||
|
if (lineIndex < 0 || lineIndex >= fLayout->CountLines())
|
||||||
|
return;
|
||||||
|
|
||||||
|
float x1;
|
||||||
|
float y1;
|
||||||
|
float x2;
|
||||||
|
float y2;
|
||||||
|
fLayout->GetLineBounds(lineIndex , x1, y1, x2, y2);
|
||||||
|
|
||||||
|
bool rightOfCenter;
|
||||||
|
int32 textOffset = fLayout->TextOffsetAt(fCaretAnchorX, (y1 + y2) / 2,
|
||||||
|
rightOfCenter);
|
||||||
|
|
||||||
|
if (rightOfCenter)
|
||||||
|
textOffset++;
|
||||||
|
|
||||||
|
_SetCaretOffset(textOffset, false, select, true);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
TextEditor::_SetCaretOffset(int32 offset, bool updateAnchor,
|
TextEditor::_SetCaretOffset(int32 offset, bool updateAnchor,
|
||||||
bool lockSelectionAnchor, bool updateSelectionStyle)
|
bool lockSelectionAnchor, bool updateSelectionStyle)
|
||||||
@@ -241,7 +382,6 @@ TextEditor::_SetCaretOffset(int32 offset, bool updateAnchor,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// _SetSelection
|
|
||||||
void
|
void
|
||||||
TextEditor::_SetSelection(int32 caret, int32 anchor, bool updateAnchor,
|
TextEditor::_SetSelection(int32 caret, int32 anchor, bool updateAnchor,
|
||||||
bool updateSelectionStyle)
|
bool updateSelectionStyle)
|
||||||
@@ -249,11 +389,11 @@ TextEditor::_SetSelection(int32 caret, int32 anchor, bool updateAnchor,
|
|||||||
if (fLayout.Get() == NULL)
|
if (fLayout.Get() == NULL)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (caret == fSelection.Caret() && caret == fSelection.Anchor())
|
if (caret == fSelection.Caret() && anchor == fSelection.Anchor())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fSelection.SetAnchor(anchor);
|
|
||||||
fSelection.SetCaret(caret);
|
fSelection.SetCaret(caret);
|
||||||
|
fSelection.SetAnchor(anchor);
|
||||||
|
|
||||||
if (updateAnchor) {
|
if (updateAnchor) {
|
||||||
float x1;
|
float x1;
|
||||||
@@ -283,63 +423,3 @@ TextEditor::_UpdateStyleAtCaret()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TextEditor::_LineUp(bool select)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TextEditor::_LineDown(bool select)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TextEditor::_LineStart(bool select)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
TextEditor::_LineEnd(bool select)
|
|
||||||
{
|
|
||||||
// TODO
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// #pragma mark -
|
|
||||||
|
|
||||||
|
|
||||||
bool
|
|
||||||
TextEditor::_HasSelection() const
|
|
||||||
{
|
|
||||||
return _SelectionLength() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int32
|
|
||||||
TextEditor::_SelectionStart() const
|
|
||||||
{
|
|
||||||
return std::min(fSelection.Caret(), fSelection.Anchor());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int32
|
|
||||||
TextEditor::_SelectionEnd() const
|
|
||||||
{
|
|
||||||
return std::max(fSelection.Caret(), fSelection.Anchor());
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int32
|
|
||||||
TextEditor::_SelectionLength() const
|
|
||||||
{
|
|
||||||
return _SelectionEnd() - _SelectionStart();
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
#define TEXT_EDITOR_H
|
#define TEXT_EDITOR_H
|
||||||
|
|
||||||
|
|
||||||
|
#include <Point.h>
|
||||||
#include <Referenceable.h>
|
#include <Referenceable.h>
|
||||||
|
|
||||||
#include "CharacterStyle.h"
|
#include "CharacterStyle.h"
|
||||||
@@ -27,6 +28,7 @@ class TextEditor : public BReferenceable {
|
|||||||
public:
|
public:
|
||||||
TextEditor();
|
TextEditor();
|
||||||
TextEditor(const TextEditor& other);
|
TextEditor(const TextEditor& other);
|
||||||
|
virtual ~TextEditor();
|
||||||
|
|
||||||
TextEditor& operator=(const TextEditor& other);
|
TextEditor& operator=(const TextEditor& other);
|
||||||
bool operator==(const TextEditor& other) const;
|
bool operator==(const TextEditor& other) const;
|
||||||
@@ -41,6 +43,11 @@ public:
|
|||||||
TextDocumentLayoutRef Layout() const
|
TextDocumentLayoutRef Layout() const
|
||||||
{ return fLayout; }
|
{ return fLayout; }
|
||||||
|
|
||||||
|
void SetEditingEnabled(bool enabled);
|
||||||
|
inline bool IsEditingEnabled() const
|
||||||
|
{ return fEditingEnabled; }
|
||||||
|
|
||||||
|
void SetCaret(BPoint location, bool extendSelection);
|
||||||
void SetSelection(TextSelection selection);
|
void SetSelection(TextSelection selection);
|
||||||
inline TextSelection Selection() const
|
inline TextSelection Selection() const
|
||||||
{ return fSelection; }
|
{ return fSelection; }
|
||||||
@@ -49,12 +56,25 @@ public:
|
|||||||
::CharacterStyle CharacterStyle() const
|
::CharacterStyle CharacterStyle() const
|
||||||
{ return fStyleAtCaret; }
|
{ return fStyleAtCaret; }
|
||||||
|
|
||||||
void KeyDown(KeyEvent event);
|
virtual void KeyDown(KeyEvent event);
|
||||||
|
|
||||||
void Insert(int32 offset, const BString& string);
|
virtual void Insert(int32 offset, const BString& string);
|
||||||
void Remove(int32 offset, int32 length);
|
virtual void Remove(int32 offset, int32 length);
|
||||||
|
|
||||||
|
void LineUp(bool select);
|
||||||
|
void LineDown(bool select);
|
||||||
|
void LineStart(bool select);
|
||||||
|
void LineEnd(bool select);
|
||||||
|
|
||||||
|
bool HasSelection() const;
|
||||||
|
int32 SelectionStart() const;
|
||||||
|
int32 SelectionEnd() const;
|
||||||
|
int32 SelectionLength() const;
|
||||||
|
inline int32 CaretOffset() const
|
||||||
|
{ return fSelection.Caret(); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
void _MoveToLine(int32 lineIndex, bool select);
|
||||||
void _SetCaretOffset(int32 offset,
|
void _SetCaretOffset(int32 offset,
|
||||||
bool updateAnchor,
|
bool updateAnchor,
|
||||||
bool lockSelectionAnchor,
|
bool lockSelectionAnchor,
|
||||||
@@ -64,23 +84,13 @@ private:
|
|||||||
bool updateSelectionStyle);
|
bool updateSelectionStyle);
|
||||||
|
|
||||||
void _UpdateStyleAtCaret();
|
void _UpdateStyleAtCaret();
|
||||||
|
|
||||||
void _LineUp(bool select);
|
|
||||||
void _LineDown(bool select);
|
|
||||||
void _LineStart(bool select);
|
|
||||||
void _LineEnd(bool select);
|
|
||||||
|
|
||||||
bool _HasSelection() const;
|
|
||||||
int32 _SelectionStart() const;
|
|
||||||
int32 _SelectionEnd() const;
|
|
||||||
int32 _SelectionLength() const;
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
TextDocumentRef fDocument;
|
TextDocumentRef fDocument;
|
||||||
TextDocumentLayoutRef fLayout;
|
TextDocumentLayoutRef fLayout;
|
||||||
TextSelection fSelection;
|
TextSelection fSelection;
|
||||||
float fCaretAnchorX;
|
float fCaretAnchorX;
|
||||||
::CharacterStyle fStyleAtCaret;
|
::CharacterStyle fStyleAtCaret;
|
||||||
|
bool fEditingEnabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user