can't get text iterators from a TextBuffer
Gir.Core doesn't seem to expose any methods that would return a Gtk.TextIter from a Gtk.TextBuffer. This seriously limits the set of operations that a program may perform with a TextBuffer. For example:
-
gtk_text_buffer_get_selection_bounds() has no binding, so I can't retrieve TextIter objects at the start and end of the current selection.
-
gtk_text_buffer_get_iter_at_line() has no binding, so I can't get an iterator at a given line number.
-
gtk_text_buffer_get_iter_at_mark() has no binding, so I can't convert a mark (such as the current cursor position) to a TextIter.
-
gtk_text_buffer_get_start_iter() and gtk_text_buffer_get_end_iter() have no binding, so I can't get iterators at the start/end of the buffer.
If you open issues which directly reference some c api please insert links to the documentation. This makes life for me easier.
OK, no problem. I just edited my posting above and added links to it.
Hey! I'm trying to implement these (gtk_text_buffer_get_start_iter() and gtk_text_buffer_get_end_iter()) methods so I added 2 files to Internal and Public folders inside Gtk-4 Lib with native function calls. While it seems to work inside these methods (checked with debugger TextIter objects are created) the test app crushes right after return call.
Could you help me and point me where to dig?
Internal/TextBuffer.Methods.cs
public partial class TextBuffer
{
[DllImport(ImportResolver.Library, EntryPoint = "gtk_text_buffer_get_start_iter")]
public static extern void GetStartIter(IntPtr buffer, out IntPtr iter);
[DllImport(ImportResolver.Library, EntryPoint = "gtk_text_buffer_get_end_iter")]
public static extern void GetEndIter(IntPtr buffer, out IntPtr iter);
}
Public/TextBuffer.Methods.cs
public partial class TextBuffer
{
public Gtk.TextIter GetStartIter()
{
Internal.TextBuffer.GetStartIter(Handle.DangerousGetHandle(), out var iter);
var owned = TextIterOwnedHandle.FromUnowned(iter);
return new TextIter(owned);
}
public Gtk.TextIter GetEndIter()
{
Internal.TextBuffer.GetEndIter(Handle.DangerousGetHandle(), out var iter);
var owned = TextIterOwnedHandle.FromUnowned(iter);
return new TextIter(owned);
}
}
Program.cs
using Gtk;
GtkSource.Module.Initialize();
var application = Gtk.Application.New("org.gir.core", Gio.ApplicationFlags.FlagsNone);
application.OnActivate += (sender, args) =>
{
var window = Gtk.ApplicationWindow.New((Gtk.Application) sender);
window.Title = "GtkSource5 Demo";
window.SetDefaultSize(300, 300);
var boldTag = TextTag.New("bold");
var tagTable = TextTagTable.New();
tagTable.Add(boldTag);
var buf = GtkSource.Buffer.New(tagTable);
var view = GtkSource.View.NewWithBuffer(buf);
buf.SetText("Lorem Ipsum\nDolor sit amet\nConsectetur adipiscing elit", -1);
TextIter startIter = buf.GetStartIter();
TextIter endIter = buf.GetEndIter();
buf.ApplyTag(boldTag, startIter, endIter);
view.Monospace = true;
view.ShowLineNumbers = true;
var settings = Gtk.Settings.GetDefault();
if (settings?.GtkApplicationPreferDarkTheme == true ||
settings?.GtkThemeName?.ToLower()?.Contains("dark") == true)
buf.SetStyleScheme(GtkSource.StyleSchemeManager.GetDefault().GetScheme("Adwaita-dark"));
window.Child = view;
window.Show();
};
return application.RunWithSynchronizationContext(null);
@amka The following works for me. The memory for the TextIter needs to be allocated first so that the native code can fill its data.
[DllImport(ImportResolver.Library, EntryPoint = "gtk_text_buffer_get_start_iter")]
public static extern void GetStartIter(IntPtr buffer, IntPtr iter);
[DllImport(ImportResolver.Library, EntryPoint = "gtk_text_buffer_get_end_iter")]
public static extern void GetEndIter(IntPtr buffer, IntPtr iter);
[DllImport(ImportResolver.Library, EntryPoint = "gtk_text_buffer_get_bounds")]
public static extern void GetBounds(IntPtr buffer, IntPtr start, IntPtr end);
[DllImport(ImportResolver.Library, EntryPoint = "gtk_text_buffer_get_iter_at_mark")]
public static extern void GetIterAtMark(IntPtr buffer, IntPtr iter, IntPtr mark);
public TextIter GetStartIter()
{
var iter = new TextIter();
Internal.TextBuffer.GetStartIter(Handle.DangerousGetHandle(), iter.Handle.DangerousGetHandle());
return iter;
}
public TextIter GetEndIter()
{
var iter = new TextIter();
Internal.TextBuffer.GetEndIter(Handle.DangerousGetHandle(), iter.Handle.DangerousGetHandle());
return iter;
}
public void GetBounds(out TextIter start, out TextIter end)
{
start = new TextIter();
end = new TextIter();
Internal.TextBuffer.GetBounds(Handle.DangerousGetHandle(), start.Handle.DangerousGetHandle(), end.Handle.DangerousGetHandle());
}
public TextIter GetIterAtMark(TextMark mark)
{
var iter = new TextIter();
Internal.TextBuffer.GetIterAtMark(Handle.DangerousGetHandle(), iter.Handle.DangerousGetHandle(), mark.Handle.DangerousGetHandle());
return iter;
}
These methods are now generated with #1324