How to implement a button opening a new window in GTK


  • Resident Tankie ☭

    I'm using Ardour on Linux mainly because I'm a masochist and this is a project of mine (I'm using an old laptop as an always-on recorder to export rehearsals on the fly). The mixer strip in Ardour shows processing applied to the tracks in a small box over the faders. This box is really small on a small laptop screen. There is currently no way to detach this box, so I'd like to implement it. How hard can it be?

    So, I'm not asking you to give me the solution, I'd like you to point me towards it as I'm a total beginner when it comes to GUI programming. It's a Gtk app ( :doing_it_wrong: ). What has always blocked me from actually delving into programming is the actual motivation to do something, and now I have it, and it's probably a very simple task I should be able to pull off.


  • Notification Spam Recipient

    @admiral_p said in How to implement a button opening a new window in GTK:

    it's probably a very simple task I should be able to pull off.

    Keep that attitude. Chain it to your ankle if you have to. You're going to need it on your journey....


  • Notification Spam Recipient

    @admiral_p said in How to implement a button opening a new window in GTK:

    Ardour on Linux

    Doing an extremely quick scan of their "How to do" instructions, I came across this:

    Source Code

    You'll need to build this yourself. That can be a challenging and complex process, especially on Windows and OS X. We don't provide help for this process, and we can't support the end result. But if you're hoping to modify Ardour or get involved in our development process, this is where to start.

    Their Linux guide starts here: https://ardour.org/building_linux.html

    Hopefully you get that far. Good luck!


  • Discourse touched me in a no-no place

    @admiral_p said in How to implement a button opening a new window in GTK:

    Gtk

    Now, I loathe GTK and haven't used it in decades but the key thing to remember is that all GUI programming is fundamentally asynchronous. Everything apart from initial application launch is done in callbacks. Sometimes you have to also write the event loop doing the calling back yourself, but that isn't so with GTK (because event dispatch is one of those things that it's nice to have a framework do for you) for which this whole callback thing is handled with a concept called signals. That is important.

    That said, we're now able to look at an example. Googling the interwebs gives me this:

    #include <gtk/gtk.h>
    
    void button_clicked(GtkWidget *widget, gpointer data) {
        
      g_print("clicked\n");
    }
    
    int main(int argc, char *argv[]) {
        
      GtkWidget *window;
      GtkWidget *halign;
      GtkWidget *btn;
    
      gtk_init(&argc, &argv);
    
      window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
      gtk_window_set_title(GTK_WINDOW(window), "GtkButton");
      gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
      gtk_container_set_border_width(GTK_CONTAINER(window), 15);
      gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
    
      halign = gtk_alignment_new(0, 0, 0, 0);
      btn = gtk_button_new_with_label("Click");
      gtk_widget_set_size_request(btn, 70, 30);
      
      gtk_container_add(GTK_CONTAINER(halign), btn);
      gtk_container_add(GTK_CONTAINER(window), halign);
    
      g_signal_connect(G_OBJECT(btn), "clicked", 
          G_CALLBACK(button_clicked), NULL);
    
      g_signal_connect(G_OBJECT(window), "destroy", 
          G_CALLBACK(gtk_main_quit), NULL);
    
      gtk_widget_show_all(window);
    
      gtk_main();
    
      return 0;
    }
    

    See that button_clicked function? That's a callback, and the name is unimportant because it is attached to its widget with:

      g_signal_connect(G_OBJECT(btn), "clicked", 
          G_CALLBACK(button_clicked), NULL);
    

    The first argument is the widget, the second is the name of the signal (see the docs for what is available, but the key one for buttons is clicked), and the third is the function to call when the event happens. The fourth is an arbitrary pointer you can control to pass over to your function, required because this is C and not C++ (where you'd instead combine it with the third to make a pointer-to-member; you've not got that here so you have to slum it by passing the pointer to the object data structure as a separate argument).

    Now that we can see the basics, the trick for what you're looking to do is going to be to make a callback that creates a whole new window by calling gtk_window_new() and setting it up after that, rather than only ever doing that in main() directly.



  • @Tsaukpaetra said in How to implement a button opening a new window in GTK:

    @admiral_p said in How to implement a button opening a new window in GTK:

    it's probably a very simple task I should be able to pull off.

    Keep that attitude. Chain it to your ankle if you have to. You're going to need it on your journey....

    Take this. It may help you on your quest.


  • 🚽 Regular

    @admiral_p

    Disclaimer: I'm talking out of my ass from the peanut gallery.

    If I understand you correctly your idea is to customize Ardour's source code to your needs, yes?

    Could it be possible to just fool around with the padding and sizes values in mixer_strip.cc and/or hide GUI components you don't care about? Perhaps you don't need to open a new window after all.


Log in to reply