1

I am trying to make a shell-ish thing in C using GTK. I want to make a box where:

  1. the user types something
  2. the output appears in a box
  3. The output moves upwards and you can scroll (basically like a regular terminal.)

How would I go about doing this? Here is my code so far:

#include <gtk/gtk.h>
static GtkWidget *entry1 = 0;
void button_clicked(GtkWidget *widget,gpointer data)
{
    const gchar *entry_text1;
    entry_text1 = gtk_entry_get_text (GTK_ENTRY (entry1));
    g_print ("%s\n", entry_text1);
}

void destroy(GtkWidget* widget, gpointer data)
{
    gtk_main_quit();
}
int main(int argc,char *argv[])
{
    gtk_init(&argc,&argv);
    GtkWidget *win = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size (GTK_WINDOW (win), 680, 460);

    entry1 = gtk_entry_new();

    GtkWidget *btn2 = gtk_button_new_with_label("Click Here2");

    GtkWidget *grd = gtk_grid_new();


    g_signal_connect(btn2,"clicked",G_CALLBACK(button_clicked),NULL);

    gtk_grid_attach(grd, entry1, 1,1,1,1);
    gtk_grid_attach(grd, btn2, 2,1,1,1);

    gtk_container_add(GTK_CONTAINER(win),grd);
    gtk_container_set_border_width(GTK_CONTAINER(win), 20);
    g_signal_connect(win, "destroy",G_CALLBACK(destroy), NULL);
    gtk_widget_show_all(win);
    gtk_main();
    return 0;
}

I have no clue what type of widget to use to do something like this.

BobMorane
  • 3,870
  • 3
  • 20
  • 42

1 Answers1

1

I think you should use GtkScrolledWindow to achieve this. For example:

#include <gtk/gtk.h>

// User adds contents to this entry.
static GtkWidget *input = NULL;

// The text buffer containing all previous user entries.
static GtkTextBuffer *buffer = NULL;

// When the "userText" button is clicked, all the user added to the
// entry is transfered to the text area.
void button_clicked(GtkWidget *widget, gpointer data)
{
    // Get the text added to the entry by the user:
    const gchar *userText;
    userText = gtk_entry_get_text(GTK_ENTRY(input));
    
    // Insert in the text view (at the end):
    GtkTextIter end; // Notice how this is created on the stack! Passing a pointer as usual is not working.
                     // See : https://stackoverflow.com/questions/52182527/iterators-do-not-belong-to-their-assigned-text-buffer
    gtk_text_buffer_get_end_iter(buffer, &end);
    
    gtk_text_buffer_insert(buffer, &end, userText, -1);
    gtk_text_buffer_insert(buffer, &end, "\n", -1);
    
    // Clear the user input entry for the next input:
    gtk_entry_set_text(GTK_ENTRY(input), "");
}

void destroy(GtkWidget* widget, gpointer data)
{
    gtk_main_quit();
}

int main(int argc,char *argv[])
{
    gtk_init(&argc,&argv);
    
    GtkWidget *mainWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);

    input = gtk_entry_new();
    
    GtkWidget *send = gtk_button_new_with_label("Send");
 
    // A text view is used to show the user's past input (in terminal
    // fashion). We wrap the text view in a GtkScrollmainWindowdow, which
    // makes the text view's content scrollable:   
    GtkWidget *scrollWindow = gtk_scrolled_window_new(NULL, NULL);
    buffer = gtk_text_buffer_new(NULL);
    GtkWidget *textArea = gtk_text_view_new_with_buffer(buffer);
    gtk_container_add(GTK_CONTAINER(scrollWindow), textArea);

    g_signal_connect(send,"clicked", G_CALLBACK(button_clicked), NULL);

    GtkWidget *layout = gtk_grid_new();
    gtk_grid_attach(GTK_GRID(layout), scrollWindow, 1, 1, 2, 1);
    gtk_grid_attach(GTK_GRID(layout), input, 1, 2, 1, 1);
    gtk_grid_attach(GTK_GRID(layout), send, 2, 2, 1, 1);
    gtk_container_set_focus_child(GTK_CONTAINER(layout), input);

    gtk_container_add(GTK_CONTAINER(mainWindow),layout);
    gtk_container_set_border_width(GTK_CONTAINER(mainWindow), 20);
    g_signal_connect(mainWindow, "destroy", G_CALLBACK(destroy), NULL);
    gtk_widget_show_all(mainWindow);
    
    gtk_main();
    
    return 0;
}

Here is what it looks like after having added "text 1", "text 2", "text 3" and "text 4", in that order:

No scroll bard

At first, it seems like there are no scrollbars (at least on my setup), but hovering the mouse on the right side of the text view makes them appear:

With scroll bars

BobMorane
  • 3,870
  • 3
  • 20
  • 42
  • 1
    Thanks so much!!! one more question, is there a way to make it go from the bottom? – DominikDIOP May 27 '23 at 18:51
  • 1
    It's my pleasure. As for your other question, I would suggestion posting a new question on SO (with more details on what exactly you want) to address that. Don't forget to accept the answer if it solves your issue. – BobMorane May 27 '23 at 19:15
  • 1
    @BobMorane I'm pretty sure he wanted it like a terminal window with the text added to the bottom, not the top. I don't know why you say 'As for your other question', it was part of his original question. `3. The output moves upwards and you can scroll (basically like a regular terminal.)` – Deanie Jul 06 '23 at 18:13
  • @Deanie Reading it again with your pespective I think you are right and that I misunderstood what "the output moves upwards" meant. It is true my answer does not look like a regular terminal. I'll clarify. – BobMorane Jul 06 '23 at 21:41
  • @Deanie Reading : I have updated my answer accordingly. – BobMorane Jul 07 '23 at 14:42