From a065121d2857af01938e09062b9a77f968e3e9a7 Mon Sep 17 00:00:00 2001 From: Jared Wahlstrand Date: Sat, 9 Nov 2024 08:13:24 -0500 Subject: [PATCH] misc. --- docs/src/manual/listtreeview.md | 28 +++++++++++++++------------- examples/custom_widget.jl | 29 ++++++++++++++--------------- src/cairo.jl | 1 + test/gui/listviews.jl | 17 +++++++++++++++-- test/pango.jl | 16 ++++++++++++++-- 5 files changed, 59 insertions(+), 32 deletions(-) diff --git a/docs/src/manual/listtreeview.md b/docs/src/manual/listtreeview.md index 47cae27e..e7c9562a 100644 --- a/docs/src/manual/listtreeview.md +++ b/docs/src/manual/listtreeview.md @@ -15,13 +15,13 @@ using Gtk4 model = GtkStringList(string.(names(Gtk4))) selmodel = GtkSelectionModel(GtkSingleSelection(GListModel(model))) -function setup_cb(f, li) - set_child(li,GtkLabel("")) +function setup_cb(f, list_item) # here `f` is the item factory + set_child(list_item, GtkLabel("")) end -function bind_cb(f, li) - text = li[].string - label = get_child(li) +function bind_cb(f, list_item) + text = list_item[].string + label = get_child(list_item) label.label = text end @@ -36,7 +36,7 @@ sw[] = list Let's go through each step. First, we create a model that holds the data we want to display. In this example we display a list of strings (all of the names exported by the `Gtk4` module, which was 1053 strings when this was written), and we store them in a `GtkStringList`. This object implements -the interface `GListModel`, which is what all of the list widgets require. +the interface `GListModel`, which stores an ordered list of `GObject`s. Next, we create a "selection model", which wraps the model we just created and controls how the user can select items in the list. Possible wrappers include `GtkNoSelection` (no selection allowed), @@ -47,13 +47,15 @@ Next, a "factory" is created. The list widget can efficiently display a huge num populating display widgets for an item when the item becomes visible. The "factory" is what does this. The constructor takes two callback functions: "setup", which creates a suitable widget for displaying an item, and "bind", which sets the widget to display a particular item. The arguments of the callbacks -are the factory `f` and a list item `li`, which is an object that represents elements of the -GListModel. In the "setup" callback, you can call the function `set_child` on the list item to set a -widget that will be used to display the item. In our example we create a `GtkLabel` to display the -string. In the "bind" callback, we first fetch the element of the list model using the `getindex` -method on the list item (by calling `li[]`) and we get the text from its "string" property. We then -get the `GtkLabel` using the `get_child` function on the list item, and then we set the text of this -`GtkLabel`. +are the factory `f` (often unused) and a `GtkListItem` `list_item`, which is an object that holds pointers to elements of the +`GListModel` (the "item") and the widget (the "child"). + +In the "setup" callback, we use `set_child` to set a new `GtkLabel` as the `GtkListItem`'s child +widget. If you need to set up signals for the widget that don't depend on the item, this is where you would typically do that. This callback is called when the `ListView` widget is created (or resized, presumably), unlike the "bind" callback, which is called multiple times as the user scrolls through the list. + +In the "bind" callback, we first fetch the element of the list model that will be displayed, using the `getindex` +method on the list item (by calling `list_item[]`). Each string in `GtkStringList` is stored inside a `GtkStringObject`. The string can be accessed using the "string" object (i.e. `obj.string`) or using an accessor (i.e. `string(obj)`). We then fetch the text from its "string" property. We then get the `GtkLabel` using the `get_child` function on the list item, and finally we set the text of this +`GtkLabel`. Finally, we construct the `GtkListView` using the selection model and the factory and add it to a `GtkScrolledWindow` and a `GtkWindow`. diff --git a/examples/custom_widget.jl b/examples/custom_widget.jl index dc853011..cce2380d 100644 --- a/examples/custom_widget.jl +++ b/examples/custom_widget.jl @@ -10,8 +10,6 @@ function widget_measure(widget::Ptr{GObject}, orientation::Cint, for_size::Cint, end function widget_snapshot(widget_ptr::Ptr{GObject}, snapshot_ptr::Ptr{GObject}) - t = GLib.G_OBJECT_CLASS_TYPE(widget_ptr) - t2 = GLib.G_OBJECT_CLASS_TYPE(snapshot_ptr) widget = convert(GtkWidget, widget_ptr) snapshot = convert(GtkSnapshot, snapshot_ptr) w,h = size(widget) @@ -23,8 +21,6 @@ function widget_snapshot(widget_ptr::Ptr{GObject}, snapshot_ptr::Ptr{GObject}) end function object_class_init(class::Ptr{_GObjectClass}, user_data) - object_klass_ptr = Ptr{_GObjectClass}(class) - object_klass = unsafe_load(object_klass_ptr) widget_klass_ptr = Ptr{_GtkWidgetClass}(class) widget_klass = unsafe_load(widget_klass_ptr) widget_klass.snapshot = @cfunction(widget_snapshot, Cvoid, (Ptr{GObject}, Ptr{GObject})) @@ -37,31 +33,34 @@ mutable struct MyWidget <: GtkWidget handle::Ptr{GObject} end -const class_init = @cfunction(object_class_init, Cvoid, (Ptr{_GObjectClass}, Ptr{Cvoid})) - -function register_new_widget() - base_gtype = GLib.g_type(GtkWidget) - tq=GLib.G_.type_query(base_gtype) - typeinfo=_GTypeInfo(tq.class_size, +function GLib.g_type(::Type{T}) where T <: MyWidget + gt = GLib.g_type_from_name(:MyWidget) + if gt > 0 + return gt + else + base_gtype = GLib.g_type(GtkWidget) + tq=GLib.G_.type_query(base_gtype) + typeinfo = _GTypeInfo(tq.class_size, C_NULL, # base_init C_NULL, # base_finalize - class_init, + @cfunction(object_class_init, Cvoid, (Ptr{_GObjectClass}, Ptr{Cvoid})), C_NULL, # class_finalize C_NULL, # class_data tq.instance_size, 0, # n_preallocs C_NULL, # instance_init C_NULL) # value_table - GLib.G_.type_register_static(GLib.g_type(GtkWidget),:MyWidget,Ref(typeinfo),GLib.TypeFlags_FINAL) + return GLib.G_.type_register_static(base_gtype,:MyWidget,Ref(typeinfo),GLib.TypeFlags_FINAL) + end end -function create_widget(gtype) +function MyWidget() + gtype = GLib.g_type(MyWidget) h = ccall(("g_object_new", GLib.libgobject), Ptr{GObject}, (UInt64, Ptr{Cvoid}), gtype, C_NULL) MyWidget(h) end -gt=register_new_widget() -w = create_widget(gt) +w = MyWidget() win=GtkWindow("custom widget") win[] = w diff --git a/src/cairo.jl b/src/cairo.jl index 89dcd6e6..8e09364c 100644 --- a/src/cairo.jl +++ b/src/cairo.jl @@ -134,3 +134,4 @@ function cairo_surface(c::GtkCanvas) end CairoContext(cr::cairoContext) = CairoContext(Ptr{Nothing}(cr.handle)) +cairoContext(cr::CairoContext) = cairoContext(Ptr{cairoContext}(cr.ptr),false) diff --git a/test/gui/listviews.jl b/test/gui/listviews.jl index 8e18d947..04515026 100644 --- a/test/gui/listviews.jl +++ b/test/gui/listviews.jl @@ -17,14 +17,18 @@ model = GLib.GListModel(slist) show(IOBuffer(), model) show(IOContext(IOBuffer(),:limit=>true,:displaysize=>(5,80)),model) push!(slist, "Mango") -factory = GtkSignalListItemFactory() @test length(slist) == 4 @test slist[2]=="Orange" +@test slist[end]=="Mango" l = [s for s in model] @test length(l) == 4 +# test GtkStringObject by indexing using GListModel's methods +so1 = GListModel(slist)[1] +@test string(so1) == "Apple" + function setup_cb(f, li) set_child(li,GtkLabel("")) end @@ -35,7 +39,7 @@ function bind_cb(f, li) label.label = text end - +factory = GtkSignalListItemFactory() list = GtkListView(GtkSelectionModel(GtkSingleSelection(model))) Gtk4.factory(list,factory) @@ -146,7 +150,16 @@ Gtk4.set_filter_func(listBox, match) Gtk4.set_sort_func(listBox, alpha_compare) destroy(win) +end + +@testset "GridView" begin +gridview = GtkGridView() +end +@testset "ColumnView" begin +columnview = GtkColumnView() +col = GtkColumnViewColumn("first column") +push!(columnview, col) end @testset "CustomFilter and CustomSorter" begin diff --git a/test/pango.jl b/test/pango.jl index 92d0502b..38e72369 100644 --- a/test/pango.jl +++ b/test/pango.jl @@ -1,4 +1,4 @@ -using Gtk4.Pango +using Gtk4.Pango, Cairo, Gtk4 using Test @testset "layout" begin @@ -19,11 +19,15 @@ using Test @test logical.width == width @test logical.height == height - fd=Pango.font_description(l) + fd=Pango.font_description(l) end @testset "font description" begin fd2 = PangoFontDescription("Sans") + show(IOBuffer(), fd2) + fm=Pango.default_font_map() + c=PangoContext(fm) + c[fd2] end @testset "families" begin @@ -59,3 +63,11 @@ end end end + +@testset "cairo" begin + c = CairoRGBSurface(256,256) + cr = CairoContext(c) + cr2 = Gtk4.cairoContext(cr) + layout = PangoLayout(cr2) +end +