Fixed gtk2 bug #9974. Now Gtk2 Memo will scroll correctly for sure when Selstart is set or the Cursor is at the insertion point when text is added

git-svn-id: trunk@12556 -
This commit is contained in:
andrew 2007-10-22 22:44:31 +00:00
parent a09e060255
commit 71cb81c8b0
2 changed files with 51 additions and 17 deletions

View File

@ -9,6 +9,7 @@ type
FGtkText : PGtkTextView;
FGtkBuf: PGtkTextBuffer;
FOwner: TWinControl;
FQueueCursorMove: Integer;
protected
function GetTextStr: string; override;
function GetCount: integer; override;
@ -25,6 +26,7 @@ type
procedure Insert(Index : integer; const S: string); override;
procedure SetText(TheText: PChar); override;
//procedure Sort; virtual;
procedure QueueCursorMove(APosition: Integer);
public
//property Sorted: boolean read FSorted write SetSorted;
property Owner: TWinControl read FOwner;
@ -36,6 +38,29 @@ Implementation
}
function UpdateMemoCursorCB(AStrings: TGtk2MemoStrings): guint; cdecl;
var
TextMark: PGtkTextMark;
CursorIter: TGtkTextIter;
begin
Result := Ord(False); // destroy this timer
if AStrings.FQueueCursorMove = -1 then
begin
// always scroll so the cursor is visible
TextMark := gtk_text_buffer_get_insert(AStrings.FGtkBuf);
gtk_text_buffer_get_iter_at_mark(AStrings.FGtkBuf, @CursorIter, TextMark);
end
else begin
// SelStart was used and we should move to that location
gtk_text_buffer_get_iter_at_offset(AStrings.FGtkBuf, @CursorIter, AStrings.FQueueCursorMove);
gtk_text_buffer_place_cursor(AStrings.FGtkBuf, @CursorIter); // needed to move the cursor
end;
gtk_text_view_scroll_to_iter(AStrings.FGtkText, @CursorIter, 0, False, 0, 0);
AStrings.FQueueCursorMove := 0;
end;
function TGtk2MemoStrings.GetTextStr: string;
var
StartIter,
@ -125,16 +150,15 @@ end;
procedure TGtk2MemoStrings.Insert(Index: integer; const S: string);
var
StartIter: TGtkTextIter;
StartIter,
CursorIter: TGtkTextIter;
NewLine: String;
TextMark: PGtkTextMark;
CursorIter: TGtkTextIter;
begin
if Index < gtk_text_buffer_get_line_count(FGtkBuf) then begin
//insert with LineEnding
NewLine := S+LineEnding;
gtk_text_buffer_get_iter_at_line(FGtkBuf, @StartIter, Index);
gtk_text_buffer_insert(FGtkBuf, @StartIter, PChar(NewLine) ,-1);
end
else begin
//append with a preceding LineEnding
@ -143,17 +167,32 @@ begin
NewLine := LineEnding+S+LineEnding
else
NewLine := S+LineEnding;
gtk_text_buffer_insert(FGtkBuf, @StartIter, PChar(NewLine) ,-1);
end;
if FQueueCursorMove = 0 then
begin
TextMark := gtk_text_buffer_get_insert(FGtkBuf);
gtk_text_buffer_get_iter_at_mark(FGtkBuf, @CursorIter, TextMark);
if gtk_text_iter_equal(@StartIter, @CursorIter) then
QueueCursorMove(-1);
end;
// always scroll so the cursor is visible
TextMark := gtk_text_buffer_get_insert(FGtkBuf);
gtk_text_buffer_get_iter_at_mark(FGtkBuf, @CursorIter, TextMark);
gtk_text_view_scroll_to_iter(FGtkText, @CursorIter, 0, False, 0, 0);
// and finally insert the new text
gtk_text_buffer_insert(FGtkBuf, @StartIter, PChar(NewLine) ,-1);
end;
procedure TGtk2MemoStrings.SetText(TheText: PChar);
begin
gtk_text_buffer_set_text(FGtkBuf, TheText, -1);
end;
procedure TGtk2MemoStrings.QueueCursorMove(APosition: Integer);
begin
// needed because there is a callback that updates the GtkBuffer
// internally so that it actually knows where the cursor is
if FQueueCursorMove = 0 then
g_idle_add(TGSourceFunc(@UpdateMemoCursorCB), Pointer(Self));
FQueueCursorMove := APosition;
end;
{$ENDIF}

View File

@ -184,17 +184,12 @@ end;
class procedure TGtk2WSCustomMemo.SetSelStart(const ACustomEdit: TCustomEdit;
NewStart: integer);
var
TextView: PGtkTextView;
TextBuffer: PGtkTextBuffer;
TextIter: TGtkTextIter;
MemoStrings: TGtk2MemoStrings;
begin
if not ACustomEdit.HandleAllocated then exit;
TextView := PGtkTextView(GetWidgetInfo(Pointer(ACustomEdit.Handle), False)^.CoreWidget);
TextBuffer := gtk_text_view_get_buffer(TextView);
gtk_text_buffer_get_iter_at_offset(TextBuffer, @TextIter, NewStart);
gtk_text_buffer_place_cursor(TextBuffer, @TextIter); // needed to move the cursor
gtk_text_view_scroll_to_iter(TextView, @TextIter, 0, False, 0, 0); // this ensures the cursor is visible
MemoStrings := TCustomMemo(ACustomEdit).Lines as TGtk2MemoStrings;
MemoStrings.QueueCursorMove(NewStart);
end;
class procedure TGtk2WSCustomMemo.SetSelLength(const ACustomEdit: TCustomEdit;