* Fixed selection redrawing bugs

* Changed "x1, y2, x2, y2" arguments to "x, y, w, h"
This commit is contained in:
sg 2000-01-31 19:23:37 +00:00
parent 58d62aca51
commit 8ef976f232
2 changed files with 91 additions and 31 deletions

View File

@ -71,19 +71,21 @@ begin
end;
// Redraw all lines with changed SH flags
FWidget.InvalidateLines(line, CurLine);
FWidget.InvalidateRect(line, 0, (CurLine - line) + 1, FWidget.PageWidth);
end;
procedure TSHTextEdit.DrawContent(x1, y1, x2, y2: Integer);
procedure TSHTextEdit.DrawContent(x, y, w, h: Integer);
var
x2, y2: Integer;
procedure PostprocessOutput(py: Integer);
begin
// Erase free space below the text area
if py < y2 then
FWidget.ClearRect(0, py, x2, y2);
FWidget.ClearRect(x, py, w, y2 - py);
if (FCursorX >= x1) and (FCursorY >= y1) and
if (FCursorX >= x) and (FCursorY >= y) and
(FCursorX <= x2) and (FCursorY <= y2) then
ShowCursor;
end;
@ -97,9 +99,9 @@ procedure TSHTextEdit.DrawContent(x1, y1, x2, y2: Integer);
end;
var
i, LineNumber, CheckLine: Integer;
i, cx, LineNumber, CheckLine: Integer;
OrigStr, s, s2: PChar;
spos, x, smem: Integer;
spos, smem: Integer;
flags: Byte;
InSel: Boolean;
LastCol: Char;
@ -107,16 +109,29 @@ var
begin
if (FCursorX >= x1) and (FCursorY >= y1) and
if x < 0 then begin
Inc(w, x);
x := 0;
end;
if y < 0 then begin
Inc(h, y);
y := 0;
end;
if (w < 0) or (h < 0) then exit;
x2 := x + w;
y2 := y + h;
if (FCursorX >= x) and (FCursorY >= y) and
(FCursorX <= x2) and (FCursorY <= y2) then
HideCursor;
if (FDoc = nil) or (FDoc.LineCount <= y1) then begin
PostprocessOutput(y1);
if (FDoc = nil) or (FDoc.LineCount <= y) then begin
PostprocessOutput(y);
exit;
end;
LineNumber := y1;
LineNumber := y;
// Check if syntax highlighting flags are valid:
if (FDoc.LineFlags[LineNumber] and LF_SH_Valid) <> 0 then
@ -175,12 +190,12 @@ begin
s[1] := Chr(shSelected);
s[2] := #0;
end;
end else if (LineNumber = FSel.OStartY) or
(LineNumber = FSel.OEndY) then begin
end else if ((LineNumber = FSel.OStartY) or (LineNumber = FSel.OEndY))
and not FSel.IsEmpty then begin
s2 := StrNew(s);
spos := 0;
i := 0;
x := 0;
cx := 0;
if LineNumber > FSel.OStartY then begin
ASSERT(smem >= 2);
s[0] := LF_Escape;
@ -203,7 +218,7 @@ begin
Inc(i, 2);
end else begin
if InSel then begin
if (LineNumber = FSel.OEndY) and (x = FSel.OEndX) then begin
if (LineNumber = FSel.OEndY) and (cx = FSel.OEndX) then begin
ASSERT(smem > spos + 1);
s[spos] := LF_Escape;
s[spos + 1] := LastCol;
@ -211,7 +226,7 @@ begin
InSel := False;
end;
end else
if (LineNumber = FSel.OStartY) and (x = FSel.OStartX) then begin
if (LineNumber = FSel.OStartY) and (cx = FSel.OStartX) then begin
ASSERT(smem > spos + 1);
s[spos] := LF_Escape;
s[spos + 1] := Chr(shSelected);
@ -223,7 +238,7 @@ begin
s[spos] := s2[i];
Inc(spos);
Inc(i);
Inc(x);
Inc(cx);
end;
end;
ASSERT(smem > spos);
@ -231,7 +246,7 @@ begin
StrDispose(s2);
end;
FWidget.DrawTextLine(x1, x2, LineNumber, s);
FWidget.DrawTextLine(x, x2, LineNumber, s);
FreeMem(s);
Inc(LineNumber);
@ -243,7 +258,11 @@ end;
{
$Log$
Revision 1.8 2000-01-07 01:24:34 peter
Revision 1.9 2000-01-31 19:23:37 sg
* Fixed selection redrawing bugs
* Changed "x1, y2, x2, y2" arguments to "x, y, w, h"
Revision 1.8 2000/01/07 01:24:34 peter
* updated copyright to 2000
Revision 1.7 2000/01/06 01:20:34 peter

View File

@ -99,6 +99,7 @@ type
StartX, StartY, EndX, EndY: Integer;
function IsValid: Boolean;
function IsEmpty: Boolean;
// Ordered coordinates: swaps start and end if necessary
function OStartX: Integer;
function OStartY: Integer;
@ -113,9 +114,8 @@ type
ISHWidget = class
// Drawing
procedure InvalidateRect(x1, y1, x2, y2: Integer); virtual; abstract;
procedure InvalidateLines(y1, y2: Integer); virtual; abstract;
procedure ClearRect(x1, y1, x2, y2: Integer); virtual; abstract;
procedure InvalidateRect(x, y, w, h: Integer); virtual; abstract;
procedure ClearRect(x, y, w, h: Integer); virtual; abstract;
procedure DrawTextLine(x1, x2, y: Integer; s: PChar); virtual; abstract;
// Cursor placement
@ -231,6 +231,7 @@ type
public
constructor Create(ADoc: TTextDoc; AWidget: ISHWidget); virtual;
destructor Destroy; override;
function AddKeyboardAction(AMethod: TKeyboardActionProc;ASelectionAction:TSelectionAction;ADescr: String): TKeyboardActionDescr;
function AddKeyboardAssignment(AKeyCode: Integer; AShiftState: TShiftState;
AAction: TKeyboardActionDescr): TShortcut;
@ -238,7 +239,7 @@ type
procedure FocusIn;
procedure FocusOut;
procedure DrawContent(x1, y1, x2, y2: Integer);
procedure DrawContent(x, y, w, h: Integer);
// Return value: True=Key has been pressed, False=Key has not been processed
function KeyPressed(KeyCode: LongWord; ShiftState: TShiftState): Boolean; virtual;
@ -284,6 +285,11 @@ begin
Result := StartX <> -1;
end;
function TSelection.IsEmpty: Boolean;
begin
Result := (StartX = EndX) and (StartY = EndY);
end;
function TSelection.OStartX: Integer;
begin
if (StartY > EndY) or ((StartY = EndY) and (StartX > EndX)) then
@ -353,6 +359,33 @@ begin
CursorY:=0;
end;
destructor TSHTextEdit.Destroy;
var
buf, prev: TUndoInfo;
begin
ViewInfo.Free;
FDoc.Release;
KeyboardActions.Free;
Shortcuts.Free;
FSel.Free;
buf := LastUndoInfo;
while Assigned(buf) do begin
prev := buf.prev;
buf.Free;
buf := prev;
end;
buf := LastRedoInfo;
while Assigned(buf) do begin
prev := buf.prev;
buf.Free;
buf := prev;
end;
inherited Destroy;
end;
procedure TSHTextEdit.ModifiedChanged(Sender: TObject);
begin
if Assigned(OnModifiedChange) then
@ -422,25 +455,29 @@ procedure TSHTextEdit.EndSelectionChange;
procedure RedrawArea(x1, y1, x2, y2: Integer);
begin
// WriteLn('Redraw: ', x1, '/', y1, ' - ', x2, '/', y2);
WriteLn('Redraw: ', x1, '/', y1, ' - ', x2, '/', y2);
if y1 = y2 then
FWidget.InvalidateRect(x1, y1, x2, y2)
FWidget.InvalidateRect(x1, y1, (x2 - x1) + 1, (y2 - y1) + 1)
else begin
FWidget.InvalidateRect(x1, y1, x1 + FWidget.PageWidth, y1);
FWidget.InvalidateRect(x1, y1, FWidget.PageWidth, 1);
if y1 < y2 - 1 then
FWidget.InvalidateRect(0, y1+1, FWidget.PageWidth, y2 - 1);
FWidget.InvalidateRect(0, y2, x2, y2+1);
FWidget.InvalidateRect(0, y1 + 1, FWidget.PageWidth, (y2 - y1) - 1);
FWidget.InvalidateRect(0, y2, x2, 1);
end;
end;
begin
WriteLn('=> TSHTextEdit.EndSelectionChange');
if not OldSelValid then begin
if FSel.IsValid then
RedrawArea(FSel.OStartX, FSel.OStartY, FSel.OEndX, FSel.OEndY);
end else begin
if not FSel.IsValid then
RedrawArea(OldSelStartX, OldSelStartY, OldSelEndX, OldSelEndY)
else begin
WriteLn('Old selection: ', OldSelStartX, '/', OldSelStartY, ' - ', OldSelEndX, '/', OldSelEndY);
if not FSel.IsValid then begin
WriteLn('No new selection');
RedrawArea(OldSelStartX, OldSelStartY, OldSelEndX, OldSelEndY);
end else begin
WriteLn('New selection: ', FSel.OStartX, '/', FSel.OStartY, ' - ', FSel.OEndX, '/', FSel.OEndY);
// Do OldSel and FSel intersect?
if (OldSelEndY < FSel.OStartY) or (OldSelStartY > FSel.OEndY) or
((OldSelEndY = FSel.OStartY) and (OldSelEndX <= FSel.OStartX)) or
@ -476,7 +513,11 @@ end.
{
$Log$
Revision 1.14 2000-01-23 23:59:02 sg
Revision 1.15 2000-01-31 19:23:37 sg
* Fixed selection redrawing bugs
* Changed "x1, y2, x2, y2" arguments to "x, y, w, h"
Revision 1.14 2000/01/23 23:59:02 sg
* KeyPressed now returns a Boolean which indicates if the key has been
processed or not