2

I have a GTK program with 2 GtkButtons and one GtkEntry. I would like to dynamically resize the width of the entry by clicking a button to increase/decrease it. The program I have so far is able to dynamically increase the size of the entry, but is unable to decrease it.

Is it possible to do so for GTK entries?

#include <gtk/gtk.h>


#define INITIAL_WIDTH 200
#define WIDTH_STEP 20

// Function to increase the width of GtkEntry
static void increase_size(GtkWidget *widget, GtkWidget *entry) {
    GtkAllocation allocation;
    gtk_widget_get_allocation(entry, &allocation);

    int new_width = allocation.width + WIDTH_STEP;
    gtk_widget_set_size_request(entry, new_width, -1); // -1 keeps the default height
}

// Function to decrease the width of GtkEntry
static void decrease_size(GtkWidget *widget, GtkWidget *entry) {
    GtkAllocation allocation;
    gtk_widget_get_allocation(entry, &allocation);

    int new_width = allocation.width - WIDTH_STEP;
    if (new_width < 1) new_width = 1; // Ensure width does not become negative or zero
    gtk_widget_set_size_request(entry, new_width, -1); // -1 keeps the default height
}

int main(int argc, char *argv[]) {
    GtkWidget *window;
    GtkWidget *vbox;
    GtkWidget *entry;
    GtkWidget *button_box;
    GtkWidget *plus_button;
    GtkWidget *minus_button;

    // Initialize GTK
    gtk_init(&argc, &argv);

    // Create a new window
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_title(GTK_WINDOW(window), "Resize GtkEntry with Buttons");
    gtk_window_set_default_size(GTK_WINDOW(window), 400, 200);

    // Create a vertical box
    vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
    gtk_container_add(GTK_CONTAINER(window), vbox);

    // Create a new GtkEntry
    entry = gtk_entry_new();
    gtk_entry_set_text(GTK_ENTRY(entry), "Resize me with buttons!");
    gtk_widget_set_size_request(entry, INITIAL_WIDTH, -1); // Set initial width
    gtk_box_pack_start(GTK_BOX(vbox), entry, TRUE, TRUE, 0);

    // Create a button box to hold the plus and minus buttons
    button_box = gtk_button_box_new(GTK_ORIENTATION_HORIZONTAL);
    gtk_box_pack_start(GTK_BOX(vbox), button_box, FALSE, FALSE, 0);

    // Create plus and minus buttons
    plus_button = gtk_button_new_with_label("Increase Size");
    minus_button = gtk_button_new_with_label("Decrease Size");

    // Add buttons to the button box
    gtk_container_add(GTK_CONTAINER(button_box), plus_button);
    gtk_container_add(GTK_CONTAINER(button_box), minus_button);

    // Connect button signals to respective handlers
    g_signal_connect(plus_button, "clicked", G_CALLBACK(increase_size), entry);
    g_signal_connect(minus_button, "clicked", G_CALLBACK(decrease_size), entry);

    // Connect the destroy event to exit the GTK main loop
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);

    // Show all widgets
    gtk_widget_show_all(window);

    // Enter the GTK main loop
    gtk_main();

    return 0;
}
1
  • Add a padding widget (with horizontal auto grow) on the right of your entry - you will see the decreasing entry. Currently - it is almost a direct child of window widget and it has its own rules (auto squeeze is not one of them). Commented Aug 29, 2024 at 22:00

2 Answers 2

1

After having resized the entry, you need to shrink the window as well:

// Function to decrease the width of GtkEntry 
static void decrease_size(GtkWidget *widget, GtkWidget *entry) { 
    // Resize entry: 
    GtkAllocation entry_allocation; 
    gtk_widget_get_allocation(entry, &entry_allocation); 
 
    int new_width = entry_allocation.width - WIDTH_STEP; 
    if (new_width < 1) new_width = 1; // Ensure width does not become negative or zero 
    gtk_widget_set_size_request(entry, new_width, -1); // -1 keeps the default height 
  
    // Shrink surrounding window: 
    GtkWidget* window = gtk_widget_get_toplevel(entry); 
    GtkAllocation window_allocation;

    gtk_widget_get_allocation(window, &window_allocation); 
    gtk_window_resize(GTK_WINDOW(window), 1, window_allocation.height); // One to fit down. 
}
Sign up to request clarification or add additional context in comments.

2 Comments

@codeology Did this answer solve your problem?
Unfortunately for the purposes of my task, I cannot resize the window. Your answer certainly solves what I had asked here though.
0

If you do not want the window to shrink as the entry does, you can simply disable the default alignement, which is set to GTK_ALIGN_FILL;

// Function to decrease the width of GtkEntry
static void decrease_size(GtkWidget *widget, GtkWidget *entry) {
    // Make sure the entry does not fill its container, i.e. the window.
    gtk_widget_set_halign(entry, GTK_ALIGN_START);

    GtkAllocation entry_allocation;
    gtk_widget_get_allocation(entry, &entry_allocation);
 
    int new_width = entry_allocation.width - WIDTH_STEP;
    if (new_width < 1) new_width = 1; // Ensure width does not become negative or zero
    gtk_widget_set_size_request(entry, new_width, -1); // -1 keeps the default height
}

1 Comment

@codeology Did this new answer solve your problem?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.