Gtk-rs, gtk3 how does one enable or disable a page in a stack?

Hi,

Background

I’m a beginner in Rust development as well as using gtk, who started a project to help generate bootscreens for linux from video files.

Goal

The “phenomenal” UI (generated by Glade) is supposed to work like GtkAssisant, but requires the ability to configure extra stuff like if the video should be scaled, where it should be placed, text properties (font, color, placement, etc.) and probably more.

The goal is to move from step 1-4 and add validation for each step.

Problem

Disabling the tabs is where I’m hitting a snag.
Gtk4 introduced gtk_stack_get_pages, but I’m limited to gtk3.

What has been tried

getting the page by the page name from Glade

For example, page 2 is called step__videobut builder.get_object("step__video").unwrap() just fails.

I can’t find where gtkbuilder.c uses that “packing” information or which property it assigns it to.

iterating over all the children of GtkSidebar

Well, iterating works, but I don’t know if the order is stable and I can’t find a way to properly identify the tab; properly meaning it should be page.get_text() == "3. Generation". As mentioned above, the packing information doesn’t seem to be present in a property (that I can find), so I can’t seem to use that information either.

Possible alternatives

I’ve been at it for a while and probably tried other things that I can’t remember. It’s either:

  • reimplement GtkStack and GtkStackSidebar
  • open a GtkAssistant dialog from a big button that replaces the stack
  • Start a GtkAssistant straight away and add the options in a menu
  • ask you guys for help :slightly_smiling_face:

The way to do this would be to use gtk_container_child_get on the tab with one of the title or name child properties, but this function appears to not have a safe Rust wrapper yet. You could try to call the unsafe function: gtk_sys::gtk_container_child_get - Rust

Just a side note: That gtkbuilder.c linked is on the master branch, if you’re trying to look at the source for GTK3, you would want to make sure you’re on the right gtk-3-* branch in git (the latest is gtk-3-24).

Apparently the plan was to implement it in gtk-rs but that hasn’t been done yet. I’ll give a shot. Thanks.

If that doesn’t work (rust newbie here), I’ll just use GtkAssistant and add an “options” page.

Only on the phone right now so short answer: Builder get_object expects the id of the widget. So if you give the widget an id in Glade and use that, get_object should work.

The goal is to move from step 1-4 and add validation for each step.

How exactly should this happen, from the user side?
Is there any back/next button, or you mean that once that the user complies Step 1, step 2 should be clickable?

@jfrancis exaple makes it clear, check this Video.

The latter with no back/next buttons. I wanted to do it that way because GtkAssistant is a top-level window and I didn’t want to introduce a button just to open a dialog.
Now I also discovered that the GtkAssistant can’t have a menu.

I had a look at that, but gtk_stack_get_child_by_name () only gets the child of stack i.e GtkGrid or whatever is added to the stack. I tried “desensitizing” the child, however the buttons in GtkStackSidbar aren’t affected. Attempting to get a named child of GtkStackSidebar doesn’t work either because they aren’t named.

@sophieherold unfortunately I’m trying to get the buttons in the GtkStackSidebar not in the GtkStack. The .glade doesn’t have allow assigning ids to the children of the GtkStackSidebar.

Here’s an example

<?xml version="1.0" encoding="UTF-8"?>
<!-- Generated with glade 3.22.1 -->
<interface>
  <requires lib="gtk+" version="3.20"/>
  <object class="GtkWindow">
    <property name="can_focus">False</property>
    <child>
      <placeholder/>
    </child>
    <child>
      <object class="GtkBox">
        <property name="visible">True</property>
        <property name="can_focus">False</property>
        <child>
          <object class="GtkStackSidebar" id="sidebar">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="stack">stack1</property>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">0</property>
          </packing>
        </child>
        <child>
          <object class="GtkStack" id="stack1">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <property name="hexpand">True</property>
            <property name="vexpand">True</property>
            <child>
              <object class="GtkButton" id="button_page1">
                <property name="label" translatable="yes">Page 1</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </object>
              <packing>
                <property name="name">page1</property>
                <property name="title" translatable="yes">Page 1</property>
              </packing>
            </child>
            <child>
              <object class="GtkButton" id="button_page2">
                <property name="label" translatable="yes">Page 2</property>
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
              </object>
              <packing>
                <property name="name">page1</property>
                <property name="title" translatable="yes">Page 2</property>
                <property name="position">1</property>
              </packing>
            </child>
          </object>
          <packing>
            <property name="expand">False</property>
            <property name="fill">True</property>
            <property name="position">2</property>
          </packing>
        </child>
      </object>
    </child>
  </object>
</interface>

In any case, thank you all for your time. I worked around the problem by just using a GtkAssistant and adding an “options” page.

I’ll see if I can close the thread. There’s a new one I have to open about responding to resize events in the window to resize a GtkImage widget.

Cheers

1 Like

If you .hide() a child of the stack the corresponding entry in the sidebar will disappear.

1 Like

Oh! I see. I’ll try that out today and report back.

Edit: That was it! Thank you @sophieherold :+1:

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.