mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-09-08 10:39:15 +02:00
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:
parent
a09e060255
commit
71cb81c8b0
@ -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}
|
||||
|
@ -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;
|
||||
|
Loading…
Reference in New Issue
Block a user