* Fixed drawing of selection

* Several small corrections (removed superfluous local variables etc.)
This commit is contained in:
sg 1999-12-12 17:50:50 +00:00
parent 13c71bc1b3
commit e3ab54a015
3 changed files with 179 additions and 187 deletions

View File

@ -95,15 +95,22 @@ procedure TSHTextEdit.DrawContent(x1, y1, x2, y2: Integer);
ShowCursor;
end;
var
i, j, py, LineNumber, CheckLine: Integer;
OrigStr, sh, s, s2: PChar;
i, spos, x: Integer;
flags: Byte;
r: TRect;
InSel: Boolean;
// If Lenght(s) < x, add as many spaces to s so that x will be at
// the end of s.
procedure ProvideSpace(var s: String; x: Integer);
begin
while Length(s) < x do
s := s + ' ';
end;
RequestedColor, LastCol: Char;
var
i, LineNumber, CheckLine: Integer;
OrigStr, sh, s, s2: PChar;
spos, x: Integer;
flags: Byte;
InSel: Boolean;
LastCol: Char;
LineWithSpace: String; // used for virtual whitespace expanding
begin
@ -117,7 +124,6 @@ begin
end;
LineNumber := y1;
py := LineNumber;
// Check if syntax highlighting flags are valid:
if (FDoc.LineFlags[LineNumber] and LF_SH_Valid) <> 0 then
@ -140,115 +146,106 @@ begin
end;
// if FSel.IsValid then writeln('Selection: ',FSel.OStartX,',',FSel.OStartY,'-',FSel.OEndX,',',FSel.OEndY);
// if FSel.IsValid then writeln('Selection: ',FSel.OStartX,',',FSel.OStartY,'-',FSel.OEndX,',',FSel.OEndY);
while (LineNumber < FDoc.LineCount) and (py <= y2) do begin
while (LineNumber < FDoc.LineCount) and (LineNumber <= y2) do begin
i := 0;
// Do virtual whitespace expanding
LineWithSpace := FDoc.LineText[LineNumber];
if LineNumber = FSel.OStartY then
ProvideSpace(LineWithSpace, FSel.OStartX);
if LineNumber = FSel.OEndY then
ProvideSpace(LineWithSpace, FSel.OEndX);
if LineNumber = FCursorY then
ProvideSpace(LineWithSpace, FCursorX);
// Call syntax highlighter for this line
GetMem(sh, FDoc.LineLen[LineNumber] * 3 + 8);
GetMem(sh, Length(LineWithSpace) * 3 + 8);
s := sh;
FDoc.LineFlags[LineNumber] := flags or LF_SH_Valid;
OrigStr := PChar(FDoc.LineText[LineNumber]);
OrigStr := PChar(LineWithSpace);
DoHighlighting(flags, OrigStr, s);
// Handle current selection
if FSel.IsValid then
begin
if (LineNumber > FSel.OStartY) and (LineNumber < FSel.OEndY) then
begin
if (LineNumber > FSel.OStartY) and (LineNumber < FSel.OEndY) then begin
s[0] := LF_Escape;
s[1] := Chr(shSelected);
StrCopy(@s[2], OrigStr);
end else if OrigStr[0] = #0 then begin
if LineNumber = FSel.OStartY then begin
s[0] := LF_Escape;
s[1] := Chr(shSelected);
StrCopy(@s[2], OrigStr);
end
else
if OrigStr[0] = #0 then
begin
if LineNumber = FSel.OStartY then
begin
s[0] := LF_Escape;
s[1] := Chr(shSelected);
s[2] := #0;
s[2] := #0;
end;
end else if (LineNumber = FSel.OStartY) or
(LineNumber = FSel.OEndY) then begin
s2 := StrNew(s);
spos := 0;
i := 0;
x := 0;
if LineNumber > FSel.OStartY then begin
s[0] := LF_Escape;
s[1] := Chr(shSelected);
InSel := True;
spos := 2;
end else
InSel := False;
LastCol := Chr(shDefault);
while True do begin
if s2[i] = LF_Escape then begin
LastCol := s2[i + 1];
if not InSel then begin
s[spos] := LF_Escape;
s[spos + 1] := LastCol;
Inc(spos, 2);
end;
end
else
if (LineNumber = FSel.OStartY) or
(LineNumber = FSel.OEndY) then
begin
s2 := StrNew(s);
spos := 0;
i := 0;
x := 0;
if LineNumber > FSel.OStartY then
begin
s[0] := LF_Escape;
s[1] := Chr(shSelected);
InSel := True;
spos := 2;
end
else
InSel := False;
LastCol := Chr(shDefault);
while True do
begin
if s2[i] = LF_Escape then
begin
LastCol := s2[i + 1];
if not InSel then
begin
s[spos] := LF_Escape;
s[spos + 1] := LastCol;
Inc(spos, 2);
end;
Inc(i, 2);
end
else
begin
if InSel then
begin
if (LineNumber = FSel.OEndY) and (x = FSel.OEndX) then
begin
s[spos] := LF_Escape;
s[spos + 1] := LastCol;
Inc(spos, 2);
InSel := False;
end;
end
else
if (LineNumber = FSel.OStartY) and (x = FSel.OStartX) then
begin
s[spos] := LF_Escape;
s[spos + 1] := Chr(shSelected);
Inc(spos, 2);
InSel := True;
end;
if s2[i] = #0 then
break; // only exit of 'while' loop!
s[spos] := s2[i];
Inc(spos);
Inc(i);
Inc(x);
end;
end;
s[spos] := #0;
StrDispose(s2);
Inc(i, 2);
end else begin
if InSel then begin
if (LineNumber = FSel.OEndY) and (x = FSel.OEndX) then begin
s[spos] := LF_Escape;
s[spos + 1] := LastCol;
Inc(spos, 2);
InSel := False;
end;
end else
if (LineNumber = FSel.OStartY) and (x = FSel.OStartX) then begin
s[spos] := LF_Escape;
s[spos + 1] := Chr(shSelected);
Inc(spos, 2);
InSel := True;
end;
if s2[i] = #0 then break; // only exit of 'while' loop!
s[spos] := s2[i];
Inc(spos);
Inc(i);
Inc(x);
end;
end;
end;
s[spos] := #0;
StrDispose(s2);
end;
Renderer.DrawTextLine(x1, x2, py, s);
Renderer.DrawTextLine(x1, x2, LineNumber, s);
FreeMem(sh, FDoc.LineLen[LineNumber] * 3 + 8);
FreeMem(sh);
Inc(LineNumber);
Inc(py);
end;
PostprocessOutput(py);
PostprocessOutput(LineNumber);
end;
{
$Log$
Revision 1.3 1999-12-10 15:01:02 peter
Revision 1.4 1999-12-12 17:50:50 sg
* Fixed drawing of selection
* Several small corrections (removed superfluous local variables etc.)
Revision 1.3 1999/12/10 15:01:02 peter
* first things for selection
* Better Adjusting of range/cursor

View File

@ -138,18 +138,19 @@ procedure TGtkSHEdit_Expose(GtkWidget: PGtkWidget; event: PGdkEventExpose; edit:
var
x1, y1, x2, y2: Integer;
begin
x1:=event^.area.x;
if x1>0 then
dec(x1,edit.LeftIndent);
x2:=x1+event^.area.width - 1;
x1:=x1 div edit.CharW;
x2:=(x2+edit.CharW-1) div edit.CharW;
x1 := event^.area.x;
if x1 > 0 then
Dec(x1, edit.LeftIndent);
x2 := x1 + event^.area.width - 1;
x1 := x1 div edit.CharW;
x2 := (x2 + edit.CharW - 1) div edit.CharW;
y1 := event^.area.y div edit.CharH;
y2 := (event^.area.y + event^.area.height - 1) div edit.CharH;
// WriteLn(Format('Expose(%d/%d - %d/%d) for %s', [x1, y1, x2, y2, edit.ClassName]));
edit.GdkWnd := edit.PaintBox^.window;
edit.GC := gdk_gc_new(edit.GdkWnd);
edit.CurGCColor := 0; // Reset color, because we have a new GC!
gdk_gc_copy(edit.GC, PGtkStyle(edit.PaintBox^.thestyle)^.
fg_gc[edit.PaintBox^.state]);
@ -181,6 +182,7 @@ begin
GDK_Shift_L..GDK_Hyper_R :
begin
// Don't let modifier keys trough as normal keys
// *** This doesn't work reliably! (sg)
exit;
end;
else
@ -366,10 +368,10 @@ procedure TGtkSHEdit.InvalidateRect(x1, y1, x2, y2: Integer);
var
r : TGdkRectangle;
begin
r.x:=x1*CharW+LeftIndent;
r.y:=y1*CharH;
r.Width:=(x1 - x2 + 1) * CharW;
r.Height:=(y2 - y1 + 1) * CharH;
r.x := x1 * CharW + LeftIndent;
r.y := y1 * CharH;
r.Width := (x2 - x1 + 1) * CharW;
r.Height := (y2 - y1 + 1) * CharH;
gtk_widget_draw(PGtkWidget(PaintBox), @r);
end;
@ -379,11 +381,11 @@ var
r : TGdkRectangle;
w,h : integer;
begin
gdk_window_get_size(PGdkDrawable(GdkWnd),@w,@h);
r.x:=0;
r.y:=y1 * CharH;
r.Width:=w;
r.Height:=(y2 - y1 + 1) * CharH;
gdk_window_get_size(PGdkDrawable(GdkWnd), @w, @h);
r.x := 0;
r.y := y1 * CharH;
r.Width := w;
r.Height := (y2 - y1 + 1) * CharH;
gtk_widget_draw(PGtkWidget(PaintBox), @r);
end;
@ -391,108 +393,92 @@ end;
procedure TGtkSHEdit.DrawTextLine(x1, x2, y: Integer; s: PChar);
var
CurColor: LongWord;
rx1,rx2 : Integer;
CurX1, CurX2: Integer;
procedure doerase;
procedure DoErase;
begin
if rx2>x1 then
begin
SetGCColor(CurColor);
gdk_draw_rectangle(PGdkDrawable(GdkWnd), GC, 1,
rx1 * CharW + LeftIndent, y * CharH, (rx2 - rx1 + 1) * CharW, CharH);
rx1:=rx2;
end;
SetGCColor(CurColor);
if CurX1 < x1 then
CurX1 := x1;
if CurX2 > CurX1 then begin
gdk_draw_rectangle(PGdkDrawable(GdkWnd), GC, 1,
CurX1 * CharW + LeftIndent, y * CharH, (CurX2 - CurX1) * CharW, CharH);
end;
CurX1 := CurX2;
end;
var
RequestedColor: Char;
i, j, px: Integer;
RequestedColor: Integer;
NewColor: LongWord;
hs : pchar;
hs : PChar;
begin
// WriteLn(Format('DrawTextLine(%d) for %s ', [y, ClassName]));
// Erase the (potentially multi-coloured) background
rx1 := x1;
rx2 := 0;
j := 0;
hs := s;
CurColor := SHStyles^[shWhitespace].Background;
// Clear background
hs:=s;
rx2:=0;
repeat
CurX1 := 0;
CurX2 := 0;
while (hs[0] <> #0) and (CurX2 <= x2) do begin
case hs[0] of
#0 :
break;
LF_Escape :
begin
LF_Escape: begin
NewColor := SHStyles^[Ord(hs[1])].Background;
if NewColor = colDefault then
NewColor := SHStyles^[shWhitespace].Background;
if (NewColor <> CurColor) then
begin
DoErase;
CurColor := NewColor;
end;
NewColor := SHStyles^[shWhitespace].Background;
if NewColor <> CurColor then begin
DoErase;
CurColor := NewColor;
end;
Inc(hs, 2);
end;
#9 :
begin
#9: begin
repeat
Inc(rx2, CharW);
Inc(i);
until (i and 7) = 0;
Inc(CurX2);
until (CurX2 and 7) = 0;
Inc(hs);
end;
else
begin
Inc(hs);
Inc(i);
Inc(rx2);
end;
else begin
Inc(hs);
Inc(CurX2);
end;
end;
until false;
rx2 := x2;
end;
CurX2 := x2;
DoErase;
// Draw text line
RequestedColor := #1;
CurGCColor := colInvalid;
i := 0;
px := 0;
repeat
RequestedColor := shWhitespace;
CurX1 := 0;
while s[0] <> #0 do
case s[0] of
#0 :
break;
LF_Escape :
begin
RequestedColor := s[1];
LF_Escape: begin
RequestedColor := Ord(s[1]);
Inc(s, 2);
end;
#9 :
begin
#9: begin
repeat
Inc(px, CharW);
Inc(i);
until (i and 7) = 0;
Inc(CurX1);
until (CurX1 and 7) = 0;
Inc(s);
end;
else
begin
if (px >= x1) and (px <= x2) then
begin
SetGCColor(SHStyles^[Ord(RequestedColor)].Color);
gdk_draw_text(PGdkDrawable(GdkWnd),
Font[SHStyles^[Ord(RequestedColor)].FontStyle], GC,
px * CharW + LeftIndent, (y + 1) * CharH - 3, s, 1);
end;
' ': begin
Inc(s);
Inc(i);
Inc(px);
Inc(CurX1);
end;
else begin
if (CurX1 >= x1) and (CurX1 <= x2) then begin
SetGCColor(SHStyles^[RequestedColor].Color);
gdk_draw_text(PGdkDrawable(GdkWnd),
Font[SHStyles^[RequestedColor].FontStyle], GC,
CurX1 * CharW + LeftIndent, (y + 1) * CharH - 3, s, 1);
end;
Inc(s);
Inc(CurX1);
end;
end;
until false;
end;
@ -596,7 +582,11 @@ end;
end.
{
$Log$
Revision 1.6 1999-12-10 15:01:02 peter
Revision 1.7 1999-12-12 17:50:50 sg
* Fixed drawing of selection
* Several small corrections (removed superfluous local variables etc.)
Revision 1.6 1999/12/10 15:01:02 peter
* first things for selection
* Better Adjusting of range/cursor

View File

@ -471,7 +471,7 @@ procedure TSHTextEdit.KeyPressed(KeyCode: LongWord; ShiftState: TShiftState);
procedure RedrawArea(x1, y1, x2, y2: Integer);
begin
WriteLn('Redraw: ', x1, '/', y1, ' - ', x2, '/', y2);
// WriteLn('Redraw: ', x1, '/', y1, ' - ', x2, '/', y2);
if y1 = y2 then
Renderer.InvalidateRect(x1,y1,x2,y2)
else
@ -535,11 +535,12 @@ begin
end;
end;
if not AssignmentMatched then
begin
if ShiftState * [ssCtrl, ssAlt] = [] then
ExecKey(Chr(KeyCode), False);
end;
if (not AssignmentMatched) and (ShiftState * [ssCtrl, ssAlt] = []) then
ExecKey(Chr(KeyCode), False);
// Check selection
if FSel.IsValid and (FSel.StartX = FSel.EndX) and (FSel.StartY = FSel.EndY) then
FSel.Clear;
{Write('Sel = ', FSel.StartX, '/', FSel.StartY, ' - ', FSel.EndX, '/', FSel.EndY);
if OldSelValid then WriteLn(' Old = ', OldSelStartX, '/', OldSelStartY, ' - ', OldSelEndX, '/', OldSelEndY)
@ -591,7 +592,11 @@ end;
{
$Log$
Revision 1.5 1999-12-10 15:01:02 peter
Revision 1.6 1999-12-12 17:50:50 sg
* Fixed drawing of selection
* Several small corrections (removed superfluous local variables etc.)
Revision 1.5 1999/12/10 15:01:02 peter
* first things for selection
* Better Adjusting of range/cursor