Fixed artifacts when highlighing text, added Hiroshi Lockheimer to the authors list (BTextView is based on his SteEngine), reformatted the code some more to comply with our guidelines
git-svn-id: file:///srv/svn/repos/haiku/trunk/current@5563 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -20,7 +20,9 @@
|
|||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
//
|
//
|
||||||
// File Name: TextView.cpp
|
// File Name: TextView.cpp
|
||||||
// Author: Marc Flerackers ([email protected]e)
|
// Authors: Hiroshi Lockheimer (TextView is based on his STEEngine)
|
||||||
|
// Marc Flerackers ([email protected])
|
||||||
|
// Stefano Ceccherini ([email protected])
|
||||||
// Description: BTextView displays and manages styled text.
|
// Description: BTextView displays and manages styled text.
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
@@ -66,6 +68,7 @@ struct flattened_text_run {
|
|||||||
uint16 _reserved_; /* 0 */
|
uint16 _reserved_; /* 0 */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
struct flattened_text_run_array {
|
struct flattened_text_run_array {
|
||||||
uchar magic[4]; /* 41 6c 69 21 */
|
uchar magic[4]; /* 41 6c 69 21 */
|
||||||
uchar version[4]; /* 00 00 00 00 */
|
uchar version[4]; /* 00 00 00 00 */
|
||||||
@@ -73,6 +76,12 @@ struct flattened_text_run_array {
|
|||||||
flattened_text_run styles[1];
|
flattened_text_run styles[1];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
enum {
|
||||||
|
B_SEPARATOR_CHARACTER,
|
||||||
|
B_OTHER_CHARACTER
|
||||||
|
} separatorCharacters;
|
||||||
|
|
||||||
// _BTextTrackState_ class -----------------------------------------------------
|
// _BTextTrackState_ class -----------------------------------------------------
|
||||||
class _BTextTrackState_ {
|
class _BTextTrackState_ {
|
||||||
|
|
||||||
@@ -89,8 +98,7 @@ public:
|
|||||||
|
|
||||||
// Globals ---------------------------------------------------------------------
|
// Globals ---------------------------------------------------------------------
|
||||||
static property_info
|
static property_info
|
||||||
prop_list[] =
|
prop_list[] = {
|
||||||
{
|
|
||||||
{
|
{
|
||||||
"Selection",
|
"Selection",
|
||||||
{ B_GET_PROPERTY, 0 },
|
{ B_GET_PROPERTY, 0 },
|
||||||
@@ -237,23 +245,25 @@ BTextView::BTextView(BRect frame, const char *name, BRect textRect,
|
|||||||
BTextView::BTextView(BMessage *archive)
|
BTextView::BTextView(BMessage *archive)
|
||||||
: BView(archive)
|
: BView(archive)
|
||||||
{
|
{
|
||||||
const char *text;
|
|
||||||
int32 flag, flag2;
|
|
||||||
float value;
|
|
||||||
BRect rect;
|
BRect rect;
|
||||||
bool toggle;
|
|
||||||
|
|
||||||
if (archive->FindRect("_trect", &rect) != B_OK)
|
if (archive->FindRect("_trect", &rect) != B_OK)
|
||||||
rect.Set(0, 0, 0, 0);
|
rect.Set(0, 0, 0, 0);
|
||||||
|
|
||||||
InitObject(rect, NULL, NULL);
|
InitObject(rect, NULL, NULL);
|
||||||
|
|
||||||
|
const char *text = NULL;
|
||||||
|
|
||||||
if (archive->FindString("_text", &text) == B_OK)
|
if (archive->FindString("_text", &text) == B_OK)
|
||||||
SetText(text);
|
SetText(text);
|
||||||
|
|
||||||
|
int32 flag, flag2;
|
||||||
|
|
||||||
if (archive->FindInt32("_align", &flag) == B_OK)
|
if (archive->FindInt32("_align", &flag) == B_OK)
|
||||||
SetAlignment((alignment)flag);
|
SetAlignment((alignment)flag);
|
||||||
|
|
||||||
|
float value;
|
||||||
|
|
||||||
if (archive->FindFloat("_tab", &value) == B_OK)
|
if (archive->FindFloat("_tab", &value) == B_OK)
|
||||||
SetTabWidth(value);
|
SetTabWidth(value);
|
||||||
|
|
||||||
@@ -267,6 +277,8 @@ BTextView::BTextView(BMessage *archive)
|
|||||||
archive->FindInt32("_sel", &flag2) == B_OK)
|
archive->FindInt32("_sel", &flag2) == B_OK)
|
||||||
Select(flag, flag2);
|
Select(flag, flag2);
|
||||||
|
|
||||||
|
bool toggle;
|
||||||
|
|
||||||
if (archive->FindBool("_stylable", &toggle) == B_OK)
|
if (archive->FindBool("_stylable", &toggle) == B_OK)
|
||||||
SetStylable(toggle);
|
SetStylable(toggle);
|
||||||
|
|
||||||
@@ -348,11 +360,12 @@ BTextView::Archive(BMessage *data, bool deep) const
|
|||||||
|
|
||||||
ssize_t runSize = 0;
|
ssize_t runSize = 0;
|
||||||
text_run_array *runArray = RunArray(0, TextLength());
|
text_run_array *runArray = RunArray(0, TextLength());
|
||||||
|
|
||||||
void *flattened = FlattenRunArray(runArray, (int32*)&runSize);
|
void *flattened = FlattenRunArray(runArray, (int32*)&runSize);
|
||||||
|
if (flattened != NULL) {
|
||||||
data->AddData("_runs", B_RAW_TYPE, flattened, runSize);
|
data->AddData("_runs", B_RAW_TYPE, flattened, runSize);
|
||||||
|
|
||||||
free(flattened);
|
free(flattened);
|
||||||
|
}
|
||||||
free(runArray);
|
free(runArray);
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
@@ -421,7 +434,7 @@ BTextView::MouseDown(BPoint where)
|
|||||||
bool shiftDown = modifiers() & B_SHIFT_KEY;
|
bool shiftDown = modifiers() & B_SHIFT_KEY;
|
||||||
|
|
||||||
// should we initiate a drag?
|
// should we initiate a drag?
|
||||||
if ((fSelStart != fSelEnd) && (!shiftDown)) {
|
if (fSelStart != fSelEnd && !shiftDown) {
|
||||||
BPoint loc;
|
BPoint loc;
|
||||||
ulong buttons;
|
ulong buttons;
|
||||||
GetMouse(&loc, &buttons);
|
GetMouse(&loc, &buttons);
|
||||||
@@ -429,7 +442,7 @@ BTextView::MouseDown(BPoint where)
|
|||||||
// since dragging works also with the primary button.
|
// since dragging works also with the primary button.
|
||||||
if (buttons == B_SECONDARY_MOUSE_BUTTON) {
|
if (buttons == B_SECONDARY_MOUSE_BUTTON) {
|
||||||
// was the click within the selection range?
|
// was the click within the selection range?
|
||||||
if ((mouseOffset >= fSelStart) && (mouseOffset <= fSelEnd)) {
|
if (mouseOffset >= fSelStart && mouseOffset <= fSelEnd) {
|
||||||
InitiateDrag();
|
InitiateDrag();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -441,8 +454,8 @@ BTextView::MouseDown(BPoint where)
|
|||||||
get_click_speed(&clickSpeed);
|
get_click_speed(&clickSpeed);
|
||||||
|
|
||||||
// is this a double/triple click, or is it a new click?
|
// is this a double/triple click, or is it a new click?
|
||||||
if ( (clickSpeed > (system_time() - fClickTime)) &&
|
if ( clickSpeed > (system_time() - fClickTime) &&
|
||||||
(mouseOffset == fClickOffset) ) {
|
mouseOffset == fClickOffset ) {
|
||||||
if (fClickCount > 1) {
|
if (fClickCount > 1) {
|
||||||
// triple click
|
// triple click
|
||||||
fClickCount = 0;
|
fClickCount = 0;
|
||||||
@@ -452,8 +465,7 @@ BTextView::MouseDown(BPoint where)
|
|||||||
fClickCount = 2;
|
fClickCount = 2;
|
||||||
fClickTime = system_time();
|
fClickTime = system_time();
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// new click
|
// new click
|
||||||
fClickOffset = mouseOffset;
|
fClickOffset = mouseOffset;
|
||||||
fClickCount = 1;
|
fClickCount = 1;
|
||||||
@@ -480,8 +492,7 @@ BTextView::MouseDown(BPoint where)
|
|||||||
if (mouseOffset > anchor) {
|
if (mouseOffset > anchor) {
|
||||||
start = anchor;
|
start = anchor;
|
||||||
end = mouseOffset;
|
end = mouseOffset;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
start = mouseOffset;
|
start = mouseOffset;
|
||||||
end = anchor;
|
end = anchor;
|
||||||
}
|
}
|
||||||
@@ -534,7 +545,7 @@ BTextView::MouseDown(BPoint where)
|
|||||||
if (vDelta != 0)
|
if (vDelta != 0)
|
||||||
ScrollBar(B_VERTICAL)->SetValue(ScrollBar(B_VERTICAL)->Value() + vDelta);
|
ScrollBar(B_VERTICAL)->SetValue(ScrollBar(B_VERTICAL)->Value() + vDelta);
|
||||||
}
|
}
|
||||||
if ((hDelta != 0) || (vDelta != 0))
|
if (hDelta != 0 || vDelta != 0)
|
||||||
Window()->UpdateIfNeeded();
|
Window()->UpdateIfNeeded();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -557,7 +568,7 @@ BTextView::MouseMoved(BPoint where, uint32 code, const BMessage *message)
|
|||||||
{
|
{
|
||||||
switch (code) {
|
switch (code) {
|
||||||
case B_ENTERED_VIEW:
|
case B_ENTERED_VIEW:
|
||||||
if ((fActive) && (message == NULL))
|
if (fActive && message == NULL)
|
||||||
SetViewCursor(B_CURSOR_I_BEAM);
|
SetViewCursor(B_CURSOR_I_BEAM);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -588,8 +599,7 @@ BTextView::WindowActivated(bool state)
|
|||||||
if (state && IsFocus()) {
|
if (state && IsFocus()) {
|
||||||
if (!fActive)
|
if (!fActive)
|
||||||
Activate();
|
Activate();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (fActive)
|
if (fActive)
|
||||||
Deactivate();
|
Deactivate();
|
||||||
}
|
}
|
||||||
@@ -656,7 +666,7 @@ BTextView::KeyDown(const char *bytes, int32 numBytes)
|
|||||||
void
|
void
|
||||||
BTextView::Pulse()
|
BTextView::Pulse()
|
||||||
{
|
{
|
||||||
if ((fActive) && (fEditable) && (fSelStart == fSelEnd)) {
|
if (fActive && fEditable && fSelStart == fSelEnd) {
|
||||||
if (system_time() > (fCaretTime + 500000.0))
|
if (system_time() > (fCaretTime + 500000.0))
|
||||||
InvertCaret();
|
InvertCaret();
|
||||||
}
|
}
|
||||||
@@ -678,8 +688,7 @@ BTextView::MakeFocus(bool focusState)
|
|||||||
if (focusState && Window()->IsActive()) {
|
if (focusState && Window()->IsActive()) {
|
||||||
if (!fActive)
|
if (!fActive)
|
||||||
Activate();
|
Activate();
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (fActive)
|
if (fActive)
|
||||||
Deactivate();
|
Deactivate();
|
||||||
}
|
}
|
||||||
@@ -794,9 +803,6 @@ BTextView::ResolveSpecifier(BMessage *message, int32 index,
|
|||||||
BHandler *target = NULL;
|
BHandler *target = NULL;
|
||||||
|
|
||||||
switch (propInfo.FindMatch(message, 0, specifier, form, property)) {
|
switch (propInfo.FindMatch(message, 0, specifier, form, property)) {
|
||||||
case B_ERROR:
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 0:
|
case 0:
|
||||||
case 1:
|
case 1:
|
||||||
case 2:
|
case 2:
|
||||||
@@ -806,6 +812,9 @@ BTextView::ResolveSpecifier(BMessage *message, int32 index,
|
|||||||
case 6:
|
case 6:
|
||||||
target = this;
|
target = this;
|
||||||
break;
|
break;
|
||||||
|
case B_ERROR:
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!target)
|
if (!target)
|
||||||
@@ -1052,7 +1061,7 @@ void
|
|||||||
BTextView::GetText(int32 offset, int32 length, char *buffer) const
|
BTextView::GetText(int32 offset, int32 length, char *buffer) const
|
||||||
{
|
{
|
||||||
int32 textLen = fText->Length();
|
int32 textLen = fText->Length();
|
||||||
if ((offset < 0) || (offset > (textLen - 1))) {
|
if (offset < 0 || offset > (textLen - 1)) {
|
||||||
buffer[0] = '\0';
|
buffer[0] = '\0';
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -1132,7 +1141,8 @@ BTextView::Paste(BClipboard *clipboard)
|
|||||||
BMessage *clip = NULL;
|
BMessage *clip = NULL;
|
||||||
|
|
||||||
if (clipboard->Lock()) {
|
if (clipboard->Lock()) {
|
||||||
if ((clip = clipboard->Data()) != NULL) {
|
clip = clipboard->Data();
|
||||||
|
if (clip != NULL) {
|
||||||
const char *text = NULL;
|
const char *text = NULL;
|
||||||
ssize_t len = 0;
|
ssize_t len = 0;
|
||||||
|
|
||||||
@@ -1203,7 +1213,7 @@ BTextView::Select(int32 startOffset, int32 endOffset)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
// is the new selection any different from the current selection?
|
// is the new selection any different from the current selection?
|
||||||
if ((startOffset == fSelStart) && (endOffset == fSelEnd))
|
if (startOffset == fSelStart && endOffset == fSelEnd)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
fStyles->InvalidateNullStyle();
|
fStyles->InvalidateNullStyle();
|
||||||
@@ -1224,8 +1234,7 @@ BTextView::Select(int32 startOffset, int32 endOffset)
|
|||||||
Highlight(fSelStart, fSelEnd);
|
Highlight(fSelStart, fSelEnd);
|
||||||
}
|
}
|
||||||
fSelStart = fSelEnd = startOffset;
|
fSelStart = fSelEnd = startOffset;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (fActive) {
|
if (fActive) {
|
||||||
// draw only those ranges that are different
|
// draw only those ranges that are different
|
||||||
long start, end;
|
long start, end;
|
||||||
@@ -1234,8 +1243,7 @@ BTextView::Select(int32 startOffset, int32 endOffset)
|
|||||||
if (startOffset > fSelStart) {
|
if (startOffset > fSelStart) {
|
||||||
start = fSelStart;
|
start = fSelStart;
|
||||||
end = startOffset;
|
end = startOffset;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
start = startOffset;
|
start = startOffset;
|
||||||
end = fSelStart;
|
end = fSelStart;
|
||||||
}
|
}
|
||||||
@@ -1247,8 +1255,7 @@ BTextView::Select(int32 startOffset, int32 endOffset)
|
|||||||
if (endOffset > fSelEnd) {
|
if (endOffset > fSelEnd) {
|
||||||
start = fSelEnd;
|
start = fSelEnd;
|
||||||
end = endOffset;
|
end = endOffset;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
start = endOffset;
|
start = endOffset;
|
||||||
end = fSelEnd;
|
end = fSelEnd;
|
||||||
}
|
}
|
||||||
@@ -1299,7 +1306,7 @@ BTextView::SetFontAndColor(const BFont *inFont, uint32 inMode,
|
|||||||
fStyles->SetStyleRange(fSelStart, fSelEnd, fText->Length(),
|
fStyles->SetStyleRange(fSelStart, fSelEnd, fText->Length(),
|
||||||
inMode, &newFont, inColor);
|
inMode, &newFont, inColor);
|
||||||
|
|
||||||
if ((inMode & doFont) || (inMode & doSize))
|
if (inMode & doFont || inMode & doSize)
|
||||||
// recalc the line breaks and redraw with new style
|
// recalc the line breaks and redraw with new style
|
||||||
Refresh(fSelStart, fSelEnd, fSelStart != fSelEnd, false);
|
Refresh(fSelStart, fSelEnd, fSelStart != fSelEnd, false);
|
||||||
else
|
else
|
||||||
@@ -1339,7 +1346,7 @@ BTextView::SetFontAndColor(int32 startOffset, int32 endOffset,
|
|||||||
fStyles->SetStyleRange(startOffset, endOffset, fText->Length(),
|
fStyles->SetStyleRange(startOffset, endOffset, fText->Length(),
|
||||||
inMode, &newFont, inColor);
|
inMode, &newFont, inColor);
|
||||||
|
|
||||||
if ((inMode & doFont) || (inMode & doSize))
|
if (inMode & doFont || inMode & doSize)
|
||||||
// recalc the line breaks and redraw with new style
|
// recalc the line breaks and redraw with new style
|
||||||
Refresh(startOffset, endOffset, startOffset != endOffset, false);
|
Refresh(startOffset, endOffset, startOffset != endOffset, false);
|
||||||
else
|
else
|
||||||
@@ -1455,14 +1462,13 @@ BTextView::PointAt(int32 inOffset, float *outHeight) const
|
|||||||
result.y = line->origin + fTextRect.top;
|
result.y = line->origin + fTextRect.top;
|
||||||
|
|
||||||
// special case: go down one line if inOffset is a newline
|
// special case: go down one line if inOffset is a newline
|
||||||
if ((inOffset == textLength) && ((*fText)[textLength - 1] == '\n')) {
|
if (inOffset == textLength && (*fText)[textLength - 1] == '\n') {
|
||||||
float ascent, descent;
|
float ascent, descent;
|
||||||
StyledWidth(inOffset, 1, &ascent, &descent);
|
StyledWidth(inOffset, 1, &ascent, &descent);
|
||||||
|
|
||||||
result.y += height;
|
result.y += height;
|
||||||
height = ascent + descent;
|
height = ascent + descent;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
int32 offset = line->offset;
|
int32 offset = line->offset;
|
||||||
int32 length = inOffset - line->offset;
|
int32 length = inOffset - line->offset;
|
||||||
int32 numChars = length;
|
int32 numChars = length;
|
||||||
@@ -1480,7 +1486,7 @@ BTextView::PointAt(int32 inOffset, float *outHeight) const
|
|||||||
offset += numChars;
|
offset += numChars;
|
||||||
length -= numChars;
|
length -= numChars;
|
||||||
numChars = length;
|
numChars = length;
|
||||||
} while ((foundTab) && (length > 0));
|
} while (foundTab && length > 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// convert from text rect coordinates
|
// convert from text rect coordinates
|
||||||
@@ -1501,10 +1507,8 @@ BTextView::OffsetAt(BPoint point) const
|
|||||||
// should we even bother?
|
// should we even bother?
|
||||||
if (point.y >= fTextRect.bottom)
|
if (point.y >= fTextRect.bottom)
|
||||||
return fText->Length();
|
return fText->Length();
|
||||||
else {
|
else if (point.y < fTextRect.top)
|
||||||
if (point.y < fTextRect.top)
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
|
||||||
|
|
||||||
int32 lineNum = LineAt(point);
|
int32 lineNum = LineAt(point);
|
||||||
STELinePtr line = (*fLines)[lineNum];
|
STELinePtr line = (*fLines)[lineNum];
|
||||||
@@ -1540,8 +1544,8 @@ BTextView::OffsetAt(BPoint point) const
|
|||||||
|
|
||||||
if (foundTab) {
|
if (foundTab) {
|
||||||
// is the point in the right-half of the tab?
|
// is the point in the right-half of the tab?
|
||||||
if ((point.x >= (sigmaWidth - (tabWidth / 2))) &&
|
if (point.x >= (sigmaWidth - (tabWidth / 2)) &&
|
||||||
(point.x < sigmaWidth))
|
point.x < sigmaWidth)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1565,15 +1569,13 @@ BTextView::OffsetAt(BPoint point) const
|
|||||||
offset += delta;
|
offset += delta;
|
||||||
done = true;
|
done = true;
|
||||||
break;
|
break;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// still too far to the left, measure some more
|
// still too far to the left, measure some more
|
||||||
offset += delta;
|
offset += delta;
|
||||||
delta /= 2;
|
delta /= 2;
|
||||||
delta = (delta < 1) ? 1 : delta;
|
delta = (delta < 1) ? 1 : delta;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// oops, we overshot the point, go back some
|
// oops, we overshot the point, go back some
|
||||||
sigmaWidth -= deltaWidth;
|
sigmaWidth -= deltaWidth;
|
||||||
|
|
||||||
@@ -1589,7 +1591,7 @@ BTextView::OffsetAt(BPoint point) const
|
|||||||
} while (offset < (numChars + saveOffset));
|
} while (offset < (numChars + saveOffset));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (done || (offset >= limit))
|
if (done || offset >= limit)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
if (foundTab) {
|
if (foundTab) {
|
||||||
@@ -1606,18 +1608,18 @@ BTextView::OffsetAt(BPoint point) const
|
|||||||
offset = saveOffset + numChars;
|
offset = saveOffset + numChars;
|
||||||
length -= numChars;
|
length -= numChars;
|
||||||
numChars = length;
|
numChars = length;
|
||||||
} while ((foundTab) && (length > 0));
|
} while (foundTab && length > 0);
|
||||||
|
|
||||||
if (offset == (line + 1)->offset) {
|
if (offset == (line + 1)->offset) {
|
||||||
// special case: newlines aren't visible
|
// special case: newlines aren't visible
|
||||||
// return the offset of the character preceding the newline
|
// return the offset of the character preceding the newline
|
||||||
if ((*fText)[offset - 1] == '\n')
|
if ((*fText)[offset - 1] == '\n')
|
||||||
return (--offset);
|
return --offset;
|
||||||
|
|
||||||
// special case: return the offset preceding any spaces that
|
// special case: return the offset preceding any spaces that
|
||||||
// aren't at the end of the buffer
|
// aren't at the end of the buffer
|
||||||
if ((offset != fText->Length()) && ((*fText)[offset - 1] == ' '))
|
if (offset != fText->Length() && (*fText)[offset - 1] == ' ')
|
||||||
return (--offset);
|
return --offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
return offset;
|
return offset;
|
||||||
@@ -1632,8 +1634,6 @@ BTextView::OffsetAt(int32 line) const
|
|||||||
return (*fLines)[line]->offset;
|
return (*fLines)[line]->offset;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
enum { B_SEPARATOR_CHARACTER, B_OTHER_CHARACTER };
|
|
||||||
|
|
||||||
void
|
void
|
||||||
BTextView::FindWord(int32 inOffset, int32 *outFromOffset,
|
BTextView::FindWord(int32 inOffset, int32 *outFromOffset,
|
||||||
int32 *outToOffset)
|
int32 *outToOffset)
|
||||||
@@ -1662,29 +1662,7 @@ BTextView::FindWord(int32 inOffset, int32 *outFromOffset,
|
|||||||
bool
|
bool
|
||||||
BTextView::CanEndLine(int32 offset)
|
BTextView::CanEndLine(int32 offset)
|
||||||
{
|
{
|
||||||
switch ((*fText)[offset]) {
|
return (CharClassification(offset) == B_SEPARATOR_CHARACTER);
|
||||||
case '\0':
|
|
||||||
case '\t':
|
|
||||||
case '\n':
|
|
||||||
case ' ':
|
|
||||||
case '&':
|
|
||||||
case '*':
|
|
||||||
case '+':
|
|
||||||
case '-':
|
|
||||||
case '/':
|
|
||||||
case '<':
|
|
||||||
case '=':
|
|
||||||
case '>':
|
|
||||||
case '\\':
|
|
||||||
case '^':
|
|
||||||
case '|':
|
|
||||||
return true;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
float
|
float
|
||||||
@@ -1719,7 +1697,7 @@ BTextView::TextHeight(int32 startLine, int32 endLine) const
|
|||||||
float height = (*fLines)[endLine + 1]->origin -
|
float height = (*fLines)[endLine + 1]->origin -
|
||||||
(*fLines)[startLine]->origin;
|
(*fLines)[startLine]->origin;
|
||||||
|
|
||||||
if ((endLine == numLines - 1) && ((*fText)[fText->Length() - 1] == '\n'))
|
if (endLine == numLines - 1 && (*fText)[fText->Length() - 1] == '\n')
|
||||||
height += (*fLines)[endLine + 1]->origin - (*fLines)[endLine]->origin;
|
height += (*fLines)[endLine + 1]->origin - (*fLines)[endLine]->origin;
|
||||||
|
|
||||||
return height;
|
return height;
|
||||||
@@ -1739,6 +1717,7 @@ BTextView::GetTextRegion(int32 startOffset, int32 endOffset,
|
|||||||
float endLineHeight = 0.0;
|
float endLineHeight = 0.0;
|
||||||
BPoint startPt = PointAt(startOffset, &startLineHeight);
|
BPoint startPt = PointAt(startOffset, &startLineHeight);
|
||||||
BPoint endPt = PointAt(endOffset, &endLineHeight);
|
BPoint endPt = PointAt(endOffset, &endLineHeight);
|
||||||
|
|
||||||
BRect selRect;
|
BRect selRect;
|
||||||
|
|
||||||
if (startPt.y == endPt.y) {
|
if (startPt.y == endPt.y) {
|
||||||
@@ -1748,8 +1727,7 @@ BTextView::GetTextRegion(int32 startOffset, int32 endOffset,
|
|||||||
selRect.right = endPt.x - 1.0;
|
selRect.right = endPt.x - 1.0;
|
||||||
selRect.bottom = endPt.y + endLineHeight - 1.0;
|
selRect.bottom = endPt.y + endLineHeight - 1.0;
|
||||||
outRegion->Include(selRect);
|
outRegion->Include(selRect);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// more than one line in the specified offset range
|
// more than one line in the specified offset range
|
||||||
selRect.left = (startPt.x < fTextRect.left) ? fTextRect.left : startPt.x;
|
selRect.left = (startPt.x < fTextRect.left) ? fTextRect.left : startPt.x;
|
||||||
selRect.top = startPt.y;
|
selRect.top = startPt.y;
|
||||||
@@ -1757,10 +1735,10 @@ BTextView::GetTextRegion(int32 startOffset, int32 endOffset,
|
|||||||
selRect.bottom = startPt.y + startLineHeight - 1.0;
|
selRect.bottom = startPt.y + startLineHeight - 1.0;
|
||||||
outRegion->Include(selRect);
|
outRegion->Include(selRect);
|
||||||
|
|
||||||
if ((startPt.y + startLineHeight) < endPt.y) {
|
if (startPt.y + startLineHeight < endPt.y) {
|
||||||
// more than two lines in the range
|
// more than two lines in the range
|
||||||
selRect.left = fTextRect.left;
|
selRect.left = fTextRect.left;
|
||||||
selRect.top = startPt.y + startLineHeight;
|
selRect.top = startPt.y + startLineHeight + 1.0;
|
||||||
selRect.right = fTextRect.right;
|
selRect.right = fTextRect.right;
|
||||||
selRect.bottom = endPt.y - 1.0;
|
selRect.bottom = endPt.y - 1.0;
|
||||||
outRegion->Include(selRect);
|
outRegion->Include(selRect);
|
||||||
@@ -1783,12 +1761,12 @@ BTextView::ScrollToOffset(int32 inOffset)
|
|||||||
BPoint point = PointAt(inOffset, &lineHeight);
|
BPoint point = PointAt(inOffset, &lineHeight);
|
||||||
|
|
||||||
if (ScrollBar(B_HORIZONTAL) != NULL) {
|
if (ScrollBar(B_HORIZONTAL) != NULL) {
|
||||||
if ((point.x < bounds.left) || (point.x >= bounds.right))
|
if (point.x < bounds.left || point.x >= bounds.right)
|
||||||
ScrollBar(B_HORIZONTAL)->SetValue(point.x - (bounds.IntegerWidth() / 2));
|
ScrollBar(B_HORIZONTAL)->SetValue(point.x - (bounds.IntegerWidth() / 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ScrollBar(B_VERTICAL) != NULL) {
|
if (ScrollBar(B_VERTICAL) != NULL) {
|
||||||
if ((point.y < bounds.top) || ((point.y + lineHeight) >= bounds.bottom))
|
if (point.y < bounds.top || (point.y + lineHeight) >= bounds.bottom)
|
||||||
ScrollBar(B_VERTICAL)->SetValue(point.y - (bounds.IntegerHeight() / 2));
|
ScrollBar(B_VERTICAL)->SetValue(point.y - (bounds.IntegerHeight() / 2));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1809,11 +1787,9 @@ BTextView::Highlight(int32 startOffset, int32 endOffset)
|
|||||||
BRegion selRegion;
|
BRegion selRegion;
|
||||||
GetTextRegion(startOffset, endOffset, &selRegion);
|
GetTextRegion(startOffset, endOffset, &selRegion);
|
||||||
|
|
||||||
ConstrainClippingRegion(&selRegion);
|
SetDrawingMode(B_OP_INVERT);
|
||||||
InvertRect(selRegion.Frame());
|
FillRegion(&selRegion, B_SOLID_HIGH);
|
||||||
ConstrainClippingRegion(NULL);
|
SetDrawingMode(B_OP_COPY);
|
||||||
|
|
||||||
Flush(); ////
|
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void
|
void
|
||||||
@@ -1899,7 +1875,7 @@ BTextView::MakeEditable(bool editable)
|
|||||||
|
|
||||||
if (Window() != NULL) {
|
if (Window() != NULL) {
|
||||||
if (fActive) {
|
if (fActive) {
|
||||||
if ((!fEditable) && (fCaretVisible))
|
if (!fEditable && fCaretVisible)
|
||||||
InvertCaret();
|
InvertCaret();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2200,7 +2176,7 @@ BTextView::DeleteText(int32 fromOffset, int32 toOffset)
|
|||||||
//_ASSERT ( _CrtCheckMemory () );
|
//_ASSERT ( _CrtCheckMemory () );
|
||||||
|
|
||||||
// sanity checking
|
// sanity checking
|
||||||
if ((fromOffset >= toOffset) || (fromOffset < 0) || (toOffset < 0))
|
if (fromOffset >= toOffset || fromOffset < 0 || toOffset < 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// set nullStyle to style at beginning of range
|
// set nullStyle to style at beginning of range
|
||||||
@@ -2236,6 +2212,9 @@ void
|
|||||||
BTextView::GetDragParameters(BMessage *drag, BBitmap **bitmap,
|
BTextView::GetDragParameters(BMessage *drag, BBitmap **bitmap,
|
||||||
BPoint *point, BHandler **handler)
|
BPoint *point, BHandler **handler)
|
||||||
{
|
{
|
||||||
|
if (drag == NULL)
|
||||||
|
return;
|
||||||
|
|
||||||
// What is this for ?
|
// What is this for ?
|
||||||
drag->AddInt32("be_actions", B_TRASH_TARGET);
|
drag->AddInt32("be_actions", B_TRASH_TARGET);
|
||||||
|
|
||||||
@@ -2254,6 +2233,11 @@ BTextView::GetDragParameters(BMessage *drag, BBitmap **bitmap,
|
|||||||
drag->AddPointer("be:originator", this);
|
drag->AddPointer("be:originator", this);
|
||||||
|
|
||||||
free(styles);
|
free(styles);
|
||||||
|
|
||||||
|
if (bitmap != NULL)
|
||||||
|
*bitmap = NULL;
|
||||||
|
if (handler != NULL)
|
||||||
|
*handler = NULL;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void BTextView::_ReservedTextView3() {}
|
void BTextView::_ReservedTextView3() {}
|
||||||
@@ -2293,7 +2277,6 @@ BTextView::InitObject(BRect textRect, const BFont *initialFont,
|
|||||||
void
|
void
|
||||||
BTextView::HandleBackspace()
|
BTextView::HandleBackspace()
|
||||||
{
|
{
|
||||||
|
|
||||||
if (fUndo) {
|
if (fUndo) {
|
||||||
_BTypingUndoBuffer_ *undoBuffer = dynamic_cast<_BTypingUndoBuffer_ *>(fUndo);
|
_BTypingUndoBuffer_ *undoBuffer = dynamic_cast<_BTypingUndoBuffer_ *>(fUndo);
|
||||||
if (!undoBuffer) {
|
if (!undoBuffer) {
|
||||||
@@ -2335,13 +2318,11 @@ BTextView::HandleArrowKey(uint32 inArrowKey)
|
|||||||
if (shiftDown) {
|
if (shiftDown) {
|
||||||
if (selStart > 0)
|
if (selStart > 0)
|
||||||
selStart = PreviousInitialByte(selStart);
|
selStart = PreviousInitialByte(selStart);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (selStart == selEnd) {
|
if (selStart == selEnd) {
|
||||||
if (selStart > 0)
|
if (selStart > 0)
|
||||||
selEnd = selStart = PreviousInitialByte(selStart);
|
selEnd = selStart = PreviousInitialByte(selStart);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
selEnd = selStart;
|
selEnd = selStart;
|
||||||
}
|
}
|
||||||
scrollToOffset = selStart;
|
scrollToOffset = selStart;
|
||||||
@@ -2351,8 +2332,7 @@ BTextView::HandleArrowKey(uint32 inArrowKey)
|
|||||||
if (shiftDown) {
|
if (shiftDown) {
|
||||||
if (selEnd < fText->Length())
|
if (selEnd < fText->Length())
|
||||||
selEnd = NextInitialByte(selEnd);
|
selEnd = NextInitialByte(selEnd);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (selStart == selEnd) {
|
if (selStart == selEnd) {
|
||||||
if (selStart < fText->Length())
|
if (selStart < fText->Length())
|
||||||
selStart = selEnd = NextInitialByte(selEnd);
|
selStart = selEnd = NextInitialByte(selEnd);
|
||||||
@@ -2413,8 +2393,7 @@ BTextView::HandleDelete()
|
|||||||
return;
|
return;
|
||||||
else
|
else
|
||||||
fSelEnd = NextInitialByte(fSelEnd);
|
fSelEnd = NextInitialByte(fSelEnd);
|
||||||
}
|
} else
|
||||||
else
|
|
||||||
Highlight(fSelStart, fSelEnd);
|
Highlight(fSelStart, fSelEnd);
|
||||||
|
|
||||||
DeleteText(fSelStart, fSelEnd);
|
DeleteText(fSelStart, fSelEnd);
|
||||||
@@ -2507,8 +2486,8 @@ BTextView::Refresh(int32 fromOffset, int32 toOffset, bool erase,
|
|||||||
float newHeight = fTextRect.Height();
|
float newHeight = fTextRect.Height();
|
||||||
|
|
||||||
// if the line breaks have changed, force an erase
|
// if the line breaks have changed, force an erase
|
||||||
if ( (fromLine != saveFromLine) || (toLine != saveToLine) ||
|
if ( fromLine != saveFromLine || toLine != saveToLine ||
|
||||||
(newHeight != saveHeight) )
|
newHeight != saveHeight )
|
||||||
erase = true;
|
erase = true;
|
||||||
|
|
||||||
if (newHeight != saveHeight) {
|
if (newHeight != saveHeight) {
|
||||||
@@ -2526,8 +2505,8 @@ BTextView::Refresh(int32 fromOffset, int32 toOffset, bool erase,
|
|||||||
toLine = (toLine > toVisible) ? toVisible : toLine;
|
toLine = (toLine > toVisible) ? toVisible : toLine;
|
||||||
|
|
||||||
int32 drawOffset = fromOffset;
|
int32 drawOffset = fromOffset;
|
||||||
if ( (LineHeight(fromLine) != saveLineHeight) ||
|
if ( LineHeight(fromLine) != saveLineHeight ||
|
||||||
(newHeight < saveHeight) || (fromLine < saveFromLine) )
|
newHeight < saveHeight || fromLine < saveFromLine )
|
||||||
drawOffset = (*fLines)[fromLine]->offset;
|
drawOffset = (*fLines)[fromLine]->offset;
|
||||||
|
|
||||||
DrawLines(fromLine, toLine, drawOffset, erase);
|
DrawLines(fromLine, toLine, drawOffset, erase);
|
||||||
@@ -2536,7 +2515,7 @@ BTextView::Refresh(int32 fromOffset, int32 toOffset, bool erase,
|
|||||||
BRect eraseRect = bounds;
|
BRect eraseRect = bounds;
|
||||||
eraseRect.top = fTextRect.top + (*fLines)[fLines->NumLines()]->origin;
|
eraseRect.top = fTextRect.top + (*fLines)[fLines->NumLines()]->origin;
|
||||||
eraseRect.bottom = fTextRect.top + saveHeight;
|
eraseRect.bottom = fTextRect.top + saveHeight;
|
||||||
if ((eraseRect.bottom > eraseRect.top) && (eraseRect.Intersects(bounds))) {
|
if (eraseRect.bottom > eraseRect.top && eraseRect.Intersects(bounds)) {
|
||||||
SetLowColor(ViewColor());
|
SetLowColor(ViewColor());
|
||||||
FillRect(eraseRect, B_SOLID_LOW);
|
FillRect(eraseRect, B_SOLID_LOW);
|
||||||
}
|
}
|
||||||
@@ -2572,7 +2551,7 @@ BTextView::RecalLineBreaks(int32 *startLine, int32 *endLine)
|
|||||||
&descent, &width);
|
&descent, &width);
|
||||||
|
|
||||||
// we want to advance at least by one character
|
// we want to advance at least by one character
|
||||||
if ((toOffset == fromOffset) && (fromOffset < textLength))
|
if (toOffset == fromOffset && fromOffset < textLength)
|
||||||
toOffset = NextInitialByte(toOffset);
|
toOffset = NextInitialByte(toOffset);
|
||||||
|
|
||||||
// set the ascent of this line
|
// set the ascent of this line
|
||||||
@@ -2580,23 +2559,22 @@ BTextView::RecalLineBreaks(int32 *startLine, int32 *endLine)
|
|||||||
|
|
||||||
lineIndex++;
|
lineIndex++;
|
||||||
STELine saveLine = *nextLine;
|
STELine saveLine = *nextLine;
|
||||||
if ( (lineIndex > fLines->NumLines()) ||
|
if ( lineIndex > fLines->NumLines() ||
|
||||||
(toOffset < nextLine->offset) ) {
|
toOffset < nextLine->offset ) {
|
||||||
// the new line comes before the old line start, add a line
|
// the new line comes before the old line start, add a line
|
||||||
STELine newLine;
|
STELine newLine;
|
||||||
newLine.offset = toOffset;
|
newLine.offset = toOffset;
|
||||||
newLine.origin = curLine->origin + ascent + descent;
|
newLine.origin = curLine->origin + ascent + descent;
|
||||||
newLine.ascent = 0;
|
newLine.ascent = 0;
|
||||||
fLines->InsertLine(&newLine, lineIndex);
|
fLines->InsertLine(&newLine, lineIndex);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// update the exising line
|
// update the exising line
|
||||||
nextLine->offset = toOffset;
|
nextLine->offset = toOffset;
|
||||||
nextLine->origin = curLine->origin + ascent + descent;
|
nextLine->origin = curLine->origin + ascent + descent;
|
||||||
|
|
||||||
// remove any lines that start before the current line
|
// remove any lines that start before the current line
|
||||||
while ( (lineIndex < fLines->NumLines()) &&
|
while ( lineIndex < fLines->NumLines() &&
|
||||||
(toOffset >= ((*fLines)[lineIndex] + 1)->offset) )
|
toOffset >= ((*fLines)[lineIndex] + 1)->offset )
|
||||||
fLines->RemoveLines(lineIndex + 1);
|
fLines->RemoveLines(lineIndex + 1);
|
||||||
|
|
||||||
nextLine = (*fLines)[lineIndex];
|
nextLine = (*fLines)[lineIndex];
|
||||||
@@ -2607,9 +2585,8 @@ BTextView::RecalLineBreaks(int32 *startLine, int32 *endLine)
|
|||||||
lineIndex + 1);
|
lineIndex + 1);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
if (lineIndex > 0 && lineIndex == *startLine)
|
||||||
if ((lineIndex > 0) && (lineIndex == *startLine))
|
|
||||||
*startLine = lineIndex - 1;
|
*startLine = lineIndex - 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2705,14 +2682,13 @@ BTextView::FindLineBreak(int32 fromOffset, float *outAscent,
|
|||||||
done = true;
|
done = true;
|
||||||
delta++;
|
delta++;
|
||||||
break;
|
break;
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
// include all trailing spaces and tabs,
|
// include all trailing spaces and tabs,
|
||||||
// but not spaces after tabs
|
// but not spaces after tabs
|
||||||
if ((theChar != ' ') && (theChar != '\t'))
|
if (theChar != ' ' && theChar != '\t')
|
||||||
break;
|
break;
|
||||||
else {
|
else {
|
||||||
if ((theChar == ' ') && (foundTab))
|
if (theChar == ' ' && foundTab)
|
||||||
break;
|
break;
|
||||||
else {
|
else {
|
||||||
if (theChar == '\t')
|
if (theChar == '\t')
|
||||||
@@ -2744,18 +2720,18 @@ BTextView::FindLineBreak(int32 fromOffset, float *outAscent,
|
|||||||
bool foundNewline = done;
|
bool foundNewline = done;
|
||||||
done = true;
|
done = true;
|
||||||
int32 pos = delta - 1;
|
int32 pos = delta - 1;
|
||||||
if (((*fText)[offset + pos] != ' ') &&
|
if ((*fText)[offset + pos] != ' ' &&
|
||||||
((*fText)[offset + pos] != '\t') &&
|
(*fText)[offset + pos] != '\t' &&
|
||||||
((*fText)[offset + pos] != '\n'))
|
(*fText)[offset + pos] != '\n')
|
||||||
break;
|
break;
|
||||||
|
|
||||||
strWidth -= (deltaWidth + tabWidth);
|
strWidth -= (deltaWidth + tabWidth);
|
||||||
|
|
||||||
for ( ; ((offset + pos) > offset); pos--) {
|
for ( ; ((offset + pos) > offset); pos--) {
|
||||||
uchar theChar = (*fText)[offset + pos];
|
uchar theChar = (*fText)[offset + pos];
|
||||||
if ((theChar != ' ') &&
|
if (theChar != ' ' &&
|
||||||
(theChar != '\t') &&
|
theChar != '\t' &&
|
||||||
(theChar != '\n'))
|
theChar != '\n')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2765,12 +2741,12 @@ BTextView::FindLineBreak(int32 fromOffset, float *outAscent,
|
|||||||
|
|
||||||
if (!foundNewline) {
|
if (!foundNewline) {
|
||||||
for ( ; (offset + delta) < limit; delta++) {
|
for ( ; (offset + delta) < limit; delta++) {
|
||||||
if (((*fText)[offset + delta] != ' ') &&
|
if ((*fText)[offset + delta] != ' ' &&
|
||||||
((*fText)[offset + delta] != '\t'))
|
(*fText)[offset + delta] != '\t')
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if ( ((offset + delta) < limit) &&
|
if ( (offset + delta) < limit &&
|
||||||
((*fText)[offset + delta] == '\n') )
|
(*fText)[offset + delta] == '\n' )
|
||||||
delta++;
|
delta++;
|
||||||
}
|
}
|
||||||
// get the ascent and descent of the spaces/tabs
|
// get the ascent and descent of the spaces/tabs
|
||||||
@@ -2782,7 +2758,7 @@ BTextView::FindLineBreak(int32 fromOffset, float *outAscent,
|
|||||||
|
|
||||||
offset += delta;
|
offset += delta;
|
||||||
delta = 0;
|
delta = 0;
|
||||||
} while ((offset < limit) && (!done));
|
} while (offset < limit && !done);
|
||||||
|
|
||||||
if ((offset - fromOffset) < 1) {
|
if ((offset - fromOffset) < 1) {
|
||||||
// there weren't any words that fit entirely in this line
|
// there weren't any words that fit entirely in this line
|
||||||
@@ -2881,7 +2857,7 @@ BTextView::DrawLines(int32 startLine, int32 endLine, int32 startOffset,
|
|||||||
long startEraseLine = startLine;
|
long startEraseLine = startLine;
|
||||||
STELinePtr line = (*fLines)[startLine];
|
STELinePtr line = (*fLines)[startLine];
|
||||||
|
|
||||||
if ((erase) && (startOffset != -1)) {
|
if (erase && startOffset != -1) {
|
||||||
// erase only to the right of startOffset
|
// erase only to the right of startOffset
|
||||||
startEraseLine++;
|
startEraseLine++;
|
||||||
long startErase = startOffset;
|
long startErase = startOffset;
|
||||||
@@ -2911,7 +2887,7 @@ BTextView::DrawLines(int32 startLine, int32 endLine, int32 startOffset,
|
|||||||
|
|
||||||
MovePenTo(fTextRect.left, line->origin + line->ascent + fTextRect.top);
|
MovePenTo(fTextRect.left, line->origin + line->ascent + fTextRect.top);
|
||||||
|
|
||||||
if ((erase) && (i >= startEraseLine)) {
|
if (erase && i >= startEraseLine) {
|
||||||
eraseRect.top = line->origin + fTextRect.top;
|
eraseRect.top = line->origin + fTextRect.top;
|
||||||
eraseRect.bottom = (line + 1)->origin + fTextRect.top;
|
eraseRect.bottom = (line + 1)->origin + fTextRect.top;
|
||||||
|
|
||||||
@@ -2975,7 +2951,7 @@ BTextView::DrawLines(int32 startLine, int32 endLine, int32 startOffset,
|
|||||||
numChars -= tabChars;
|
numChars -= tabChars;
|
||||||
tabChars = numChars;
|
tabChars = numChars;
|
||||||
numTabs = 0;
|
numTabs = 0;
|
||||||
} while ((foundTab) && (tabChars > 0));
|
} while (foundTab && tabChars > 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
line++;
|
line++;
|
||||||
@@ -3026,7 +3002,7 @@ BTextView::DragCaret(int32 offset)
|
|||||||
if (offset != -1) {
|
if (offset != -1) {
|
||||||
if (fActive) {
|
if (fActive) {
|
||||||
// ignore if offset is within active selection
|
// ignore if offset is within active selection
|
||||||
if ((offset >= fSelStart) && (offset <= fSelEnd)) {
|
if (offset >= fSelStart && offset <= fSelEnd) {
|
||||||
fDragOffset = -1;
|
fDragOffset = -1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -3104,7 +3080,7 @@ BTextView::MessageDropped(BMessage *inMessage, BPoint where, BPoint offset)
|
|||||||
if (dropOffset > TextLength())
|
if (dropOffset > TextLength())
|
||||||
dropOffset = TextLength();
|
dropOffset = TextLength();
|
||||||
|
|
||||||
void *from;
|
void *from = NULL;
|
||||||
inMessage->FindPointer("be:originator", &from);
|
inMessage->FindPointer("be:originator", &from);
|
||||||
|
|
||||||
bool internalDrop = (from == this && fSelEnd != fSelStart);
|
bool internalDrop = (from == this && fSelEnd != fSelStart);
|
||||||
@@ -3184,16 +3160,22 @@ BTextView::AutoResize(bool doredraw)
|
|||||||
void
|
void
|
||||||
BTextView::NewOffscreen(float padding)
|
BTextView::NewOffscreen(float padding)
|
||||||
{
|
{
|
||||||
if (fOffscreen)
|
if (fOffscreen != NULL)
|
||||||
DeleteOffscreen();
|
DeleteOffscreen();
|
||||||
|
/*
|
||||||
//TODO: Implement
|
BRect bitmapRect(0, 0, fTextRect.Width() + padding, fTextRect.Height());
|
||||||
|
fOffscreen = new BBitmap(bitmapRect, fColorSpace, true, false);
|
||||||
|
if (fOffscreen != NULL && fOffscreen->Lock()) {
|
||||||
|
BView *bufferView = new BView(bitmapRect, "buffer view", 0, 0);
|
||||||
|
fOffscreen->AddChild(bufferView);
|
||||||
|
fOffscreen->Unlock();
|
||||||
|
}*/
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
void
|
void
|
||||||
BTextView::DeleteOffscreen()
|
BTextView::DeleteOffscreen()
|
||||||
{
|
{
|
||||||
if (fOffscreen && fOffscreen->Lock()) {
|
if (fOffscreen != NULL && fOffscreen->Lock()) {
|
||||||
delete fOffscreen;
|
delete fOffscreen;
|
||||||
fOffscreen = NULL;
|
fOffscreen = NULL;
|
||||||
}
|
}
|
||||||
@@ -3207,8 +3189,7 @@ BTextView::Activate()
|
|||||||
if (fSelStart != fSelEnd) {
|
if (fSelStart != fSelEnd) {
|
||||||
if (fSelectable)
|
if (fSelectable)
|
||||||
Highlight(fSelStart, fSelEnd);
|
Highlight(fSelStart, fSelEnd);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (fEditable)
|
if (fEditable)
|
||||||
InvertCaret();
|
InvertCaret();
|
||||||
}
|
}
|
||||||
@@ -3228,8 +3209,7 @@ BTextView::Deactivate()
|
|||||||
if (fSelStart != fSelEnd) {
|
if (fSelStart != fSelEnd) {
|
||||||
if (fSelectable)
|
if (fSelectable)
|
||||||
Highlight(fSelStart, fSelEnd);
|
Highlight(fSelStart, fSelEnd);
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
if (fCaretVisible)
|
if (fCaretVisible)
|
||||||
InvertCaret();
|
InvertCaret();
|
||||||
}
|
}
|
||||||
@@ -3260,8 +3240,8 @@ BTextView::CharClassification(int32 offset) const
|
|||||||
case '_':
|
case '_':
|
||||||
case '.':
|
case '.':
|
||||||
case '\0':
|
case '\0':
|
||||||
case '\t':
|
case B_TAB:
|
||||||
case '\n':
|
case B_ENTER:
|
||||||
case '&':
|
case '&':
|
||||||
case '*':
|
case '*':
|
||||||
case '+':
|
case '+':
|
||||||
@@ -3316,7 +3296,9 @@ BTextView::GetProperty(BMessage *specifier, int32 form,
|
|||||||
reply->AddInt32("result", fSelStart);
|
reply->AddInt32("result", fSelStart);
|
||||||
reply->AddInt32("result", fSelEnd);
|
reply->AddInt32("result", fSelEnd);
|
||||||
reply->AddInt32("error", B_OK);
|
reply->AddInt32("error", B_OK);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else if (strcmp(property, "Text") == 0) {
|
} else if (strcmp(property, "Text") == 0) {
|
||||||
int32 index, range;
|
int32 index, range;
|
||||||
char *buffer;
|
char *buffer;
|
||||||
@@ -3331,7 +3313,9 @@ BTextView::GetProperty(BMessage *specifier, int32 form,
|
|||||||
reply->AddString("result", buffer);
|
reply->AddString("result", buffer);
|
||||||
delete buffer;
|
delete buffer;
|
||||||
reply->AddInt32("error", B_OK);
|
reply->AddInt32("error", B_OK);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
} else if (strcmp(property, "text_run_array") == 0)
|
} else if (strcmp(property, "text_run_array") == 0)
|
||||||
return false;
|
return false;
|
||||||
else
|
else
|
||||||
@@ -3354,8 +3338,8 @@ BTextView::SetProperty(BMessage *specifier, int32 form,
|
|||||||
reply->AddInt32("error", B_OK);
|
reply->AddInt32("error", B_OK);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
else if (strcmp(property, "Text") == 0) {
|
} else if (strcmp(property, "Text") == 0) {
|
||||||
int32 index, range;
|
int32 index, range;
|
||||||
const char *buffer;
|
const char *buffer;
|
||||||
|
|
||||||
@@ -3371,8 +3355,8 @@ BTextView::SetProperty(BMessage *specifier, int32 form,
|
|||||||
reply->AddInt32("error", B_OK);
|
reply->AddInt32("error", B_OK);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
else if (strcmp(property, "text_run_array") == 0)
|
} else if (strcmp(property, "text_run_array") == 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -3389,8 +3373,8 @@ BTextView::CountProperties(BMessage *specifier, int32 form,
|
|||||||
reply->AddInt32("error", B_OK);
|
reply->AddInt32("error", B_OK);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
|
||||||
else
|
} else
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|||||||
Reference in New Issue
Block a user