Skip to content

Commit

Permalink
misc.
Browse files Browse the repository at this point in the history
  • Loading branch information
jwahlstrand committed Nov 9, 2024
1 parent d39dee5 commit a065121
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 32 deletions.
28 changes: 15 additions & 13 deletions docs/src/manual/listtreeview.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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),
Expand All @@ -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`.
Expand Down
29 changes: 14 additions & 15 deletions examples/custom_widget.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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}))
Expand All @@ -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
1 change: 1 addition & 0 deletions src/cairo.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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)
17 changes: 15 additions & 2 deletions test/gui/listviews.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -35,7 +39,7 @@ function bind_cb(f, li)
label.label = text
end


factory = GtkSignalListItemFactory()
list = GtkListView(GtkSelectionModel(GtkSingleSelection(model)))
Gtk4.factory(list,factory)

Expand Down Expand Up @@ -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
Expand Down
16 changes: 14 additions & 2 deletions test/pango.jl
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using Gtk4.Pango
using Gtk4.Pango, Cairo, Gtk4
using Test

@testset "layout" begin
Expand All @@ -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
Expand Down Expand Up @@ -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

0 comments on commit a065121

Please sign in to comment.