Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scrollable Tree View #47

Open
rafael-guerra-www opened this issue Dec 6, 2023 · 5 comments · May be fixed by #75
Open

Scrollable Tree View #47

rafael-guerra-www opened this issue Dec 6, 2023 · 5 comments · May be fixed by #75
Labels
Acknowledged We are aware of this issue and will respond soon Help Asks for help, rather than pointing out a problem

Comments

@rafael-guerra-www
Copy link

rafael-guerra-www commented Dec 6, 2023

How can we produce a scrollable Tree View using Mousetrap.jl, as in this Gtk.jl example

@Clemapfel Clemapfel added Help Asks for help, rather than pointing out a problem Acknowledged We are aware of this issue and will respond soon labels Dec 11, 2023
@Clemapfel
Copy link
Owner

Clemapfel commented Dec 11, 2023

Hi, sorry for the late reply. TreeView was deprecated in GTK4, but mousetrap has ColumnView which works almost identically.

image

To make any widget scrollable, you insert it into a Viewport, see here for more information.

To create the above, first update mousetrap (as there was a bug with ColumnView that was only fixed recently):

import Pkg; Pkg.update("Mousetrap")

Then run:

using Mousetrap

main() do app::Application
    window = Window(app)

    # create column view with columns
    column_view = ColumnView()

    row_index_column = push_back_column!(column_view, " ")
    count_column = push_back_column!(column_view, "#")
    name_column = push_back_column!(column_view, "Name")
    weight_column = push_back_column!(column_view, "Weight")
    unit_column = push_back_column!(column_view, "Units")

    # fill columns with text
    for i in 1:100
        row = [
            Label(string(i)),           # row index
            Label(string(rand(0:99))),  # count
            Label(rand(["Apple", "Orange", "Banana", "Kumquat", "Durian", "Mangosteen"])), # name
            Label(string(rand(0:100))), # weight
            Label(string(rand(["mg", "g", "kg", "ton"]))) # unit
        ]

        set_horizontal_alignment!.(row, ALIGNMENT_START)
        push_back_row!(column_view, row...)
    end

    # create viewport, this will add a scrollbar
    scrolled_viewport = Viewport()
    set_propagate_natural_width!(scrolled_viewport, true) # hides horizontal scrollbar
    set_child!(scrolled_viewport, column_view)

    # show both in window
    set_child!(window, scrolled_viewport)
    present!(window)
end

@rafael-guerra-www
Copy link
Author

rafael-guerra-www commented Dec 14, 2023

@Clemapfel, thanks for your time and nice example, which ran fine.

How can we add to the Mousetrap.jl code above some subtitles (or submenus) that expand when clicked to show their respective column view items?

See the example in the linked original Gtk code:

Gtk_TreeView

@Clemapfel
Copy link
Owner

ColumnView does not support nested rows, I removed that feature because it would've made filtering rows, which is a feature scheduled for a future version of mousetrap, impossible.

You can still kinda do this by inserting a widget that has the expandable element as a row, keeping everything but the first column empty.

There are two options for the widget, you can either use Expander, which has a label and a child:

expander = Expander()
set_label_widget!(expander, Label("Expander VEGETABLE"))
set_child!(expander, Label("Nested Tomato"))
set_widget_at!(column_view, row_index_column, 5, expander)

Or you can use a nested ListView, which is a little more complicated, but it auto-indents the nested elements, and you can have more than one nested child:

expander_list = ListView(ORIENTATION_VERTICAL)
nested_it = push_back!(expander_list, Label("ListView VEGETABLE"))
push_back!(expander_list, Label("Nested Tomato"), nested_it)
push_back!(expander_list, Label("Nested Apple"), nested_it)
set_widget_at!(column_view, row_index_column, 6, expander_list)

Here the outermost listview has only one child, which acts as the label "ListView VEGETABLE", while the inner listview has the actual elements "Nested Tomato", "Nested Apple".

image

You can see how the first column is stretched to fit the entire expander, which isn't ideal, but its the closest you can get using ColumnView.

Full main.jl for the image above is:

using Mousetrap

main() do app::Application
    window = Window(app)

    # create column view with columns
    column_view = ColumnView()

    row_index_column = push_back_column!(column_view, " ")
    count_column = push_back_column!(column_view, "#")
    name_column = push_back_column!(column_view, "Name")
    weight_column = push_back_column!(column_view, "Weight")
    unit_column = push_back_column!(column_view, "Units")

    set_expand!.((row_index_column, count_column, name_column, weight_column, unit_column), true)

    # fill columns with text
    for i in 1:100
        row = [
            Label(string(i)),           # row index
            Label(string(rand(0:99))),  # count
            Label(rand(["Apple", "Orange", "Banana", "Kumquat", "Durian", "Mangosteen"])), # name
            Label(string(rand(0:100))), # weight
            Label(string(rand(["mg", "g", "kg", "ton"]))) # unit
        ]

        # insert empty row, then set first element to expandable item, while leaving the other columns empty
        if i == 5 # using `Expander`
            expander = Expander()
            set_label_widget!(expander, Label("Expander VEGETABLE"))
            set_child!(expander, Label("Nested Tomato"))
            set_widget_at!(column_view, row_index_column, 5, expander)

        elseif i == 6 # using nested `ListView`
            expander_list = ListView(ORIENTATION_VERTICAL)
            nested_it = push_back!(expander_list, Label("ListView VEGETABLE"))
            push_back!(expander_list, Label("Nested Tomato"), nested_it)
            push_back!(expander_list, Label("Nested Apple"), nested_it)
            set_widget_at!(column_view, row_index_column, 6, expander_list)
        
        else # else fill all columns
            set_horizontal_alignment!.(row, ALIGNMENT_START)
            push_back_row!(column_view, row...)
        end
    end
   
    # create viewport, this will add a scrollbar
    scrolled_viewport = Viewport()
    set_propagate_natural_width!(scrolled_viewport, true) # hides horizontal scrollbar
    set_child!(scrolled_viewport, column_view)

    # show both in window
    set_child!(window, scrolled_viewport)
    present!(window)
end

In my personal opinion, if the nested elements are the last rows of the column view like in the GTK picture you send, I would do this by doing a vertical box whose first element is the column view, and the last two elements are ListViews. That way the first column doesn't get stretched.

image

# after `column_view` was filled

vbox = Box(ORIENTATION_VERTICAL)
push_back!(vbox, column_view)

expander_list = ListView(ORIENTATION_VERTICAL)
nested_it = push_back!(expander_list, Label("ListView VEGETABLE"))
push_back!(expander_list, Label("Nested Tomato"), nested_it)
push_back!(expander_list, Label("Nested Apple"), nested_it)
push_back!(vbox, expander_list)

scrolled_viewport = Viewport()
set_propagate_natural_width!(scrolled_viewport, true) # hides horizontal scrollbar
set_child!(scrolled_viewport, vbox) # child is now vbox, which contains column_view

But this way you can't have rows after the nested elements, since the end of the column_view is above them

@rafael-guerra-www
Copy link
Author

rafael-guerra-www commented Dec 15, 2023

Thank you for your feedback and I am sorry, but I could not test your latest code as I am now experiencing errors:

(julia.exe:20440): GLib-GIO-WARNING **: 21:13:43.406: C:\Users\jguerra\.julia\artifacts\13606487e48c4dea9d20813adf4f03a3edea59fd\bin\gdbus.exe dbus binary failed to launch bus, maybe incompatible version
[ERROR] In Mousetrap.main: MethodError: no method matching set_expand!(::ColumnViewColumn, ::Bool)

I will get back to you later when this has been sorted out.

PS:
Meanwhile your snapshots do not seem to match the Gtk example? Tbc.

@Clemapfel
Copy link
Owner

Clemapfel commented Dec 15, 2023

My bad, I was using the development version of Mousetrap, simply remove the line 16 with set_expand! and it should work.

It doesn't match your picture because ColumnView does not support expanded rows, like I said the closest you can do is inserting a row that has an expander. The picture is using Gtk.TreeView, which was deprecated in 4.10 and is not part of mousetrap.

@Clemapfel Clemapfel linked a pull request Feb 8, 2024 that will close this issue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Acknowledged We are aware of this issue and will respond soon Help Asks for help, rather than pointing out a problem
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants