Search code examples
rustgtkgtk3

How to I add a "header" to the tab and page parts of a notebook?


I am using gtk-rs to create a GUI. I want something like the image below:

A header above the tabs and page part of a notebook

However, I cannot find a way to position a header relative to either the tabs or the page part of the notebook. Even after investigating the original gtk documentation, I cannot find a way to position widgets relative to the position of the tabs/page part of the notebook.

I recognize that I could just have a box above the notebook and put my widgets there, but I can't position the widgets relative to the notebook that way. If there is a way to position the widgets relative to the parts of the notebook itself, that would be great.


Solution

  • It sounds like you're using a GtkNotebook, which is inherently a bit more opinionated than a GtkStack. I managed to make something like your prototype using GtkStack and GtkStackSidebar. It also required adding in some GtkSeparators.

    prototype implemented in GTK+ 3

    The code

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- Generated with glade 3.22.1 -->
    <interface>
      <requires lib="gtk+" version="3.20"/>
      <object class="GtkApplicationWindow">
        <property name="can_focus">False</property>
        <child>
          <placeholder/>
        </child>
        <child>
          <object class="GtkNotebook">
            <property name="visible">True</property>
            <property name="can_focus">True</property>
            <child>
              <placeholder/>
            </child>
            <child type="tab">
              <object class="GtkLabel">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes">page 1</property>
              </object>
              <packing>
                <property name="tab_fill">False</property>
              </packing>
            </child>
            <child>
              <placeholder/>
            </child>
            <child type="tab">
              <object class="GtkLabel">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes">page 2</property>
              </object>
              <packing>
                <property name="position">1</property>
                <property name="tab_fill">False</property>
              </packing>
            </child>
            <child>
              <placeholder/>
            </child>
            <child type="tab">
              <object class="GtkLabel">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="label" translatable="yes">page 3</property>
              </object>
              <packing>
                <property name="position">2</property>
                <property name="tab_fill">False</property>
              </packing>
            </child>
          </object>
        </child>
      </object>
      <object class="GtkTextBuffer" id="buffer1">
        <property name="text" translatable="yes">placeholder text</property>
      </object>
      <object class="GtkTextBuffer" id="buffer2">
        <property name="text" translatable="yes">placeholder text</property>
      </object>
      <object class="GtkTextBuffer" id="buffer3">
        <property name="text" translatable="yes">placeholder text</property>
      </object>
      <object class="GtkApplicationWindow">
        <property name="can_focus">False</property>
        <property name="window_position">mouse</property>
        <property name="default_width">440</property>
        <property name="default_height">250</property>
        <child>
          <placeholder/>
        </child>
        <child>
          <object class="GtkBox">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <object class="GtkBox">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="orientation">vertical</property>
                <child>
                  <object class="GtkBox">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <child>
                      <object class="GtkLabel">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                        <property name="margin_left">3</property>
                        <property name="margin_right">3</property>
                        <property name="margin_top">3</property>
                        <property name="margin_bottom">3</property>
                        <property name="label" translatable="yes">TABS_HEADER</property>
                      </object>
                      <packing>
                        <property name="expand">False</property>
                        <property name="fill">True</property>
                        <property name="position">0</property>
                      </packing>
                    </child>
                    <child>
                      <object class="GtkSeparator">
                        <property name="visible">True</property>
                        <property name="can_focus">False</property>
                      </object>
                      <packing>
                        <property name="expand">False</property>
                        <property name="fill">True</property>
                        <property name="position">1</property>
                      </packing>
                    </child>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">0</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkSeparator">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">1</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkStackSidebar">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="stack">stack1</property>
                  </object>
                  <packing>
                    <property name="expand">True</property>
                    <property name="fill">True</property>
                    <property name="position">2</property>
                  </packing>
                </child>
              </object>
              <packing>
                <property name="expand">False</property>
                <property name="fill">True</property>
                <property name="position">0</property>
              </packing>
            </child>
            <child>
              <object class="GtkBox">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="orientation">vertical</property>
                <child>
                  <object class="GtkLabel">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="margin_left">3</property>
                    <property name="margin_right">3</property>
                    <property name="margin_top">3</property>
                    <property name="margin_bottom">3</property>
                    <property name="label" translatable="yes">PAGE_HEADER</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">0</property>
                  </packing>
                </child>
                <child>
                  <object class="GtkSeparator">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">1</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="GtkTextView">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="buffer">buffer3</property>
                      </object>
                      <packing>
                        <property name="name">tab1</property>
                        <property name="title" translatable="yes">tab1</property>
                      </packing>
                    </child>
                    <child>
                      <object class="GtkTextView">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="buffer">buffer1</property>
                      </object>
                      <packing>
                        <property name="name">tab2</property>
                        <property name="title" translatable="yes">tab2</property>
                        <property name="position">1</property>
                      </packing>
                    </child>
                    <child>
                      <object class="GtkTextView">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="buffer">buffer2</property>
                      </object>
                      <packing>
                        <property name="name">tab3</property>
                        <property name="title" translatable="yes">tab3</property>
                        <property name="position">2</property>
                      </packing>
                    </child>
                  </object>
                  <packing>
                    <property name="expand">False</property>
                    <property name="fill">True</property>
                    <property name="position">2</property>
                  </packing>
                </child>
              </object>
              <packing>
                <property name="expand">True</property>
                <property name="fill">True</property>
                <property name="position">1</property>
              </packing>
            </child>
          </object>
        </child>
      </object>
    </interface>