Search code examples
gtkgtk3glade

GTK revealer and paned


I would like to essentially have a image/drawing surface as the main widget but then have some sort of panel or widget that can be revealed.

----------------

      Image

----------------
xxxxxxxxxxxxxxxx
----------------

The xxx are basically stuff(gtk widgets) that the user can use to interact with the app but they can minimize it and the app can minimize it(say for a slide show).

So, A paned allows the user to adjust the size to suit them but I also need the ability completely minimize and restore it's size(an arrow that many apps have like photoshop that reveal the underlying widget) and also be able to do this easily programmatically.

This is because the app will sort of have two modes: The main viewing of the image in which nothing else should be seen and then an editing mode which has a floating toolbar and a bottom area that gives more advanced editing features and stuff. The user and app need to be able to switch between these modes easily.

Any ideas? I'm new to gtk so this might be obvious. I figured a vertical paned would work fine and I can add a small button that can be used to expand or collapse the bottom container part... but I saw the revealer there and it seems like it might do all this for me, but not sure how to use it.


Solution

  • Well, this question is very broad in many aspects as there are many approaches, design opinions, etc.

    In fact GtkPaned ain't the best option although it would fit your purposes. Regarding GtkRevealer it's a good option and allied with GtkOverlay it would work nicely.

    GtkRevealer is basically a widget container that toggles visibility with the method/function set_reveal_child. This action can have an animated transition.

    GtkOverlay allows widgets to stack on top of each other.

    Here is a simple example. Not sure if i understood exactly your goal:

    enter image description here

    The upper right button would toggle edit/view modes with edit mode showing a "toolbar" on the bottom.

    Here is the glade ui file (named idea.ui otherwise change the code to reflect changes):

    <?xml version="1.0" encoding="UTF-8"?>
    <!-- Generated with glade 3.20.0 -->
    <interface>
      <requires lib="gtk+" version="3.20"/>
      <object class="GtkWindow" id="window1">
        <property name="can_focus">False</property>
        <child>
          <object class="GtkOverlay">
            <property name="visible">True</property>
            <property name="can_focus">False</property>
            <child>
              <object class="GtkImage">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="pixbuf">idea.png</property>
              </object>
              <packing>
                <property name="index">-1</property>
              </packing>
            </child>
            <child type="overlay">
              <object class="GtkRevealer" id="revealer1">
                <property name="visible">True</property>
                <property name="can_focus">False</property>
                <property name="transition_type">crossfade</property>
                <child>
                  <object class="GtkButtonBox">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="halign">center</property>
                    <property name="valign">end</property>
                    <property name="margin_bottom">20</property>
                    <property name="layout_style">expand</property>
                    <child>
                      <object class="GtkButton">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="receives_default">True</property>
                        <property name="valign">center</property>
                        <child>
                          <object class="GtkImage">
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="icon_name">document-edit-symbolic.symbolic</property>
                          </object>
                        </child>
                      </object>
                      <packing>
                        <property name="expand">True</property>
                        <property name="fill">True</property>
                        <property name="position">0</property>
                      </packing>
                    </child>
                    <child>
                      <object class="GtkButton">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="receives_default">True</property>
                        <child>
                          <object class="GtkImage">
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="icon_name">edit-cut-symbolic.symbolic</property>
                          </object>
                        </child>
                      </object>
                      <packing>
                        <property name="expand">True</property>
                        <property name="fill">True</property>
                        <property name="position">1</property>
                      </packing>
                    </child>
                    <child>
                      <object class="GtkButton">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="receives_default">True</property>
                        <child>
                          <object class="GtkImage">
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="icon_name">edit-clear-all-symbolic.symbolic</property>
                          </object>
                        </child>
                      </object>
                      <packing>
                        <property name="expand">True</property>
                        <property name="fill">True</property>
                        <property name="position">2</property>
                      </packing>
                    </child>
                    <child>
                      <object class="GtkButton">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="receives_default">True</property>
                        <child>
                          <object class="GtkImage">
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="icon_name">color-select-symbolic.symbolic</property>
                          </object>
                        </child>
                      </object>
                      <packing>
                        <property name="expand">True</property>
                        <property name="fill">True</property>
                        <property name="position">3</property>
                      </packing>
                    </child>
                    <child>
                      <object class="GtkButton">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="receives_default">True</property>
                        <child>
                          <object class="GtkImage">
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="icon_name">format-text-bold-symbolic.symbolic</property>
                          </object>
                        </child>
                      </object>
                      <packing>
                        <property name="expand">True</property>
                        <property name="fill">True</property>
                        <property name="position">4</property>
                      </packing>
                    </child>
                    <child>
                      <object class="GtkButton">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="receives_default">True</property>
                        <child>
                          <object class="GtkImage">
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="icon_name">preferences-color-symbolic.symbolic</property>
                          </object>
                        </child>
                      </object>
                      <packing>
                        <property name="expand">True</property>
                        <property name="fill">True</property>
                        <property name="position">5</property>
                      </packing>
                    </child>
                    <child>
                      <object class="GtkButton">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="receives_default">True</property>
                        <child>
                          <object class="GtkImage">
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="icon_name">folder-publicshare-symbolic.symbolic</property>
                          </object>
                        </child>
                      </object>
                      <packing>
                        <property name="expand">True</property>
                        <property name="fill">True</property>
                        <property name="position">6</property>
                      </packing>
                    </child>
                    <child>
                      <object class="GtkButton">
                        <property name="visible">True</property>
                        <property name="can_focus">True</property>
                        <property name="receives_default">True</property>
                        <child>
                          <object class="GtkImage">
                            <property name="visible">True</property>
                            <property name="can_focus">False</property>
                            <property name="icon_name">view-app-grid-symbolic.symbolic</property>
                          </object>
                        </child>
                      </object>
                      <packing>
                        <property name="expand">True</property>
                        <property name="fill">True</property>
                        <property name="position">7</property>
                      </packing>
                    </child>
                    <style>
                      <class name="linked"/>
                    </style>
                  </object>
                </child>
              </object>
            </child>
            <child type="overlay">
              <object class="GtkButton" id="button1">
                <property name="visible">True</property>
                <property name="can_focus">True</property>
                <property name="receives_default">True</property>
                <property name="halign">end</property>
                <property name="valign">start</property>
                <property name="margin_right">20</property>
                <property name="margin_top">20</property>
                <property name="relief">none</property>
                <child>
                  <object class="GtkImage">
                    <property name="visible">True</property>
                    <property name="can_focus">False</property>
                    <property name="icon_name">open-menu-symbolic.symbolic</property>
                  </object>
                </child>
              </object>
              <packing>
                <property name="index">1</property>
              </packing>
            </child>
          </object>
        </child>
      </object>
    </interface>
    

    And since you didn't indicate any programming language, for simplicity sake i've used a simple python code to give some dynamic behavior to the button:

    import gi
    gi.require_version('Gtk', '3.0')
    from gi.repository import Gtk
    
    def onMenuClicked(self):
        revealer.set_reveal_child(not revealer.get_reveal_child()) 
    
    builder = Gtk.Builder()
    builder.add_from_file("idea.ui")
    
    window = builder.get_object("window1")
    revealer = builder.get_object("revealer1")
    menuButton = builder.get_object("button1")
    menuButton.connect ("clicked", onMenuClicked)
    
    window.connect ("destroy", Gtk.main_quit)
    window.show_all()
    
    Gtk.main()
    

    The "toolbar" buttons are dummy buttons and preform no actions... it's just a simple mockup.

    There are many other approaches that you can follow so not sure this question suits SO guidelines as it is vague regarding the answers. Good luck though.

    PS: For the drawing area, GtkImage, you can use some other image. To avoid license problems i've used something very basic :) if you want, change the glade file to point to another image or save an image named as idea.png.