Widget resize and rounding

,

I have a program with text widgets and button in box.
What do I need: resized text widgets with corners rounded (look link with picture below)
What I tried: resize widgets (text and box) with gtk_widget_set_size_request().
Problem: strange position if box size changes; if text widget size changes width doesn’t change and height of all widgets (in the box: text widgets, button) changes

UI prototype: ApplicationPrototype.pdf (19.5 KB)
Full code: https://drive.google.com/file/d/1xcs1FxoJ_teIOUF2uriLm6CJcRBwHToW/view?usp=drive_link

P. S. I also appreciate it if you could give an overview of my coding style and give some advice if necessary.

UPD: I added CSS and it doesn’t work with widgets. The one thing I wrote there is border-radius. I checked data program gets from css file and how it changes but… it doesn’t. Parsing is successful

/*--------------------------TEXTS----------------------------*/
    TextIn = gtk_text_view_new();
    TextOut = gtk_text_view_new();
    gtk_widget_set_margin_bottom(TextIn, 5);
    gtk_widget_set_margin_bottom(TextOut, 3);
    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(TextIn), GTK_WRAP_WORD_CHAR);
    gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(TextOut), GTK_WRAP_WORD_CHAR);
                            /*...*/
/*--------------------------SCROLLED-------------------------*/
    ScrollTextIn = gtk_scrolled_window_new();
    ScrollTextOut = gtk_scrolled_window_new();

    gtk_widget_set_size_request(ScrollTextIn, NULL, 100); 
    // Width option doesn't matter. Height option changes all widget's height
    gchar *css_class = load_css(); // function returns css class (css provider used)
    gtk_widget_add_css_class(ScrollTextIn, css_class);
    gtk_widget_add_css_class(ScrollTextOut, css_class);

    gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(ScrollTextIn), TextIn);
    gtk_scrolled_window_set_child(GTK_SCROLLED_WINDOW(ScrollTextOut), TextOut);
/*--------------------------BUTTON---------------------------*/
    // Default button setting such as creating, signal bindings...
/*--------------------------BOX------------------------------*/
    Box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
    gtk_box_set_homogeneous(GTK_BOX (Box), TRUE);
    gtk_widget_set_size_request(Box, 300, 150); 
    // Maybe there are other ways to resize box?
    gtk_widget_set_valign(Box, GTK_ALIGN_CENTER);
    gtk_widget_set_halign(Box, GTK_ALIGN_CENTER);
    gtk_window_set_child(GTK_WINDOW(Window), Box);
    gtk_box_append(GTK_BOX(Box), ScrollTextIn);
    gtk_box_append(GTK_BOX(Box), ScrollTextOut);
    gtk_box_append(GTK_BOX(Box), Button);
                            /*...*/

P.P.S. Please, edit the question if you can make it more helpful or clearer for others

Hi,

Can you please post the full code and images of what you expect + what you get, directly here in the forum, instead of linking to external documents?

Good afternoon! Of course. Full code is below. Unfortunately I don’t know how to post image directly to forum, I can upload it only as link. But I an explain what I want to make. As you can see in the code there are two text widgets and one button widget. I want text widgets with rounded corners. The round-radius I want keep in single css-file. And I want to resize only text widgets height. Below in the code you can see my comment, where I explain this problem.

Thank you for your reply,
Johann

gchar* 
load_css (){
	GtkCssProvider *Provider;

	Provider = gtk_css_provider_new ();
	gtk_css_provider_load_from_path (Provider, "./css/style.css");
	
	gchar *css_class = gtk_css_provider_to_string (Provider);
	return css_class;
}

void 
translate_to_code (const gchar *str1, gchar *str2){
	const gsize length = strlen (str1);
	str2[0] = '\0';
	for (size_t i = 0; i < length; i++) {
		if (str1[i] >= '0' && str1[i] <= '9'){
			strcat (str2, MORSE_DIGITS[str1[i] - '9']);
		} else if (str1[i] >= 'A' && str1[i] <= 'Z'){
			strcat (str2, MORSE_LETTERS[str1[i] - 'A']);
		} else if (str1[i] >= 'a' && str1[i] <= 'z'){
			strcat (str2, MORSE_LETTERS[str1[i] - 'a']);
		} else if (str1[i] == ' '){
			strcat (str2, "/");
		} else strcat (str2, "?");
		strcat (str2, " "); 
	}
}

void 
translate_text (GtkWidget *Widget, gpointer data) {
	GtkTextView **TextWidgets = (GtkTextView **) data;
	GtkTextView *TextIn = TextWidgets[0];
	GtkTextView *TextOut = TextWidgets[1];
	GtkTextBuffer *Buffer = gtk_text_view_get_buffer (TextIn);
	GtkTextIter start, end;
	gtk_text_buffer_get_bounds (Buffer, &start, &end);
	const gchar *text_src = gtk_text_buffer_get_text (Buffer, &start, &end, FALSE);
	gchar *text_translated = g_new (gchar, strlen (text_src) * 5 + 1);
	translate_to_code (text_src, text_translated);
	GtkTextBuffer *Buffer_out = gtk_text_view_get_buffer (GTK_TEXT_VIEW(TextOut));
	gtk_text_buffer_set_text (Buffer_out, text_translated, strlen (text_translated));
	gtk_text_view_set_buffer (TextOut, Buffer_out);
}

void 
activate_application (GtkApplication* app, gpointer user_data) {
	GtkWidget *Window;
	GtkWidget *Button;
	GtkWidget *Box;
	GtkWidget *TextIn, *TextOut;
	GtkWidget *ScrollTextIn, *ScrollTextOut;
	GtkTextView **TextWidgets = g_new (GtkTextView*, 2);
/*--------------------------WINDOW------------------------------------------------------*/
	Window = gtk_application_window_new (app);
	gtk_window_set_title (GTK_WINDOW (Window), "Telegraf");
	gtk_window_set_default_size (GTK_WINDOW (Window), 350, 400);
	gtk_window_set_resizable (GTK_WINDOW (Window), FALSE);
/*--------------------------TEXTS-------------------------------------------------------*/
	TextIn = gtk_text_view_new ();
	TextOut = gtk_text_view_new ();

	gtk_widget_set_margin_bottom (TextIn, 5);
	gtk_widget_set_margin_bottom (TextOut, 3);
	
	gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW(TextIn), GTK_WRAP_WORD_CHAR);
	gtk_text_view_set_wrap_mode (GTK_TEXT_VIEW(TextOut), GTK_WRAP_WORD_CHAR);

	TextWidgets[0] = GTK_TEXT_VIEW (TextIn);
	TextWidgets[1] = GTK_TEXT_VIEW (TextOut);
/*--------------------------SCROLLED----------------------------------------------------*/
	ScrollTextIn = gtk_scrolled_window_new ();
	ScrollTextOut = gtk_scrolled_window_new ();

	gtk_widget_set_size_request (ScrollTextIn, 0, 100); 
        /* Here second parameter (null) doesn't matter. 
        If I use this function to resize one widget, 
        all widget will be resized. */
    gchar *css_class = load_css();
    gtk_widget_set_classes(ScrollTextIn, css_class);

	gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW(ScrollTextIn), TextIn);
	gtk_scrolled_window_set_child (GTK_SCROLLED_WINDOW(ScrollTextOut), TextOut);
/*--------------------------BUTTON------------------------------------------------------*/
	Button = gtk_button_new_with_label ("Read");
	gtk_widget_set_margin_top (Button, 3);

	g_signal_connect (Button, "clicked", G_CALLBACK(translate_text), TextWidgets);
/*--------------------------BOX---------------------------------------------------------*/
	Box = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);

	gtk_box_set_homogeneous (GTK_BOX(Box), TRUE);

	gtk_widget_set_size_request (Box, 300, 150);

	gtk_widget_set_valign (Box, GTK_ALIGN_CENTER);
	gtk_widget_set_halign (Box, GTK_ALIGN_CENTER);

	gtk_window_set_child (GTK_WINDOW(Window), Box);

	gtk_box_append (GTK_BOX(Box), ScrollTextIn);
	gtk_box_append (GTK_BOX(Box), ScrollTextOut);
	gtk_box_append (GTK_BOX(Box), Button);
/*--------------------------PRESENTATION-------------------------------------------------*/
	gtk_window_present (GTK_WINDOW(Window));
}
1 Like

Thanks!

For loading a css, you have to register it to the display. Then just add the class name to the widget:

void
load_css ()
{
    GtkCssProvider *Provider;

    Provider = gtk_css_provider_new ();
    //gtk_css_provider_load_from_path (Provider, "./css/style.css");
    gtk_css_provider_load_from_string (Provider, ".my_class textview {border-radius: 10px;}");

    gtk_style_context_add_provider_for_display(gdk_display_get_default(),
                                               GTK_STYLE_PROVIDER(Provider),
                                               GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}


void
activate_application (GtkApplication* app, gpointer user_data)
{
   ...
    load_css();
    gtk_widget_add_css_class(ScrollTextIn, "my_class");
   ...
}

That will apply the border-radius to all textviews contained in widgets of class “my_class”, i.e. the ScrollTextIn here.

That’s because of gtk_box_set_homogeneous, it gives the same height to all its children (the texts and the button here). Remove that line if you want to control the heights individually.

By default, widgets try to fill all the available space. Use
gtk_widget_set_halign (ScrollTextIn, GTK_ALIGN_CENTER);
if you want the input text widget to follow its requested width.

Coding style is kind of personal, use the one that you find more readable and maintainable. There are some tips in the official doc.

1 Like

Thank you. It works perfect

1 Like

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.