Просмотр исходного кода

* Fixed selection redrawing bugs
* Changed "x1, y2, x2, y2" arguments to "x, y, w, h"

sg 25 лет назад
Родитель
Сommit
8ef976f232
2 измененных файлов с 91 добавлено и 31 удалено
  1. 37 18
      fcl/shedit/drawing.inc
  2. 54 13
      fcl/shedit/shedit.pp

+ 37 - 18
fcl/shedit/drawing.inc

@@ -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

+ 54 - 13
fcl/shedit/shedit.pp

@@ -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