Change GTK Label position in window - C - c

I am currently coding in C for linux and I need a GUI, so I took the GTK library to do so . I now have a window with a label (to begin with) but I don't know how to move it (in (x,y) coordinates, not in zPosition) to put it at the top of the window.
Here is my GTK code in main()
//Label
pLabel=gtk_label_new(NULL);
sUtf8 = g_locale_to_utf8("<span font_desc=\"Times New Roman italic 12\" foreground=\"#0000FF\">Neural Network - XOR Example</span>\n"
,-1, NULL, NULL, NULL);
gtk_label_set_markup(GTK_LABEL(pLabel), sUtf8);
g_free(sUtf8);
gtk_label_set_justify(GTK_LABEL(pLabel), GTK_JUSTIFY_CENTER);
//Window
gtk_window_set_position(GTK_WINDOW(pWindow), GTK_WIN_POS_CENTER);
gtk_window_set_title(GTK_WINDOW(pWindow), "Neural Network");
gtk_window_set_default_size(GTK_WINDOW(pWindow), 900, 600);
gtk_container_add(GTK_CONTAINER(pWindow), pLabel);
g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(OnDestroy), NULL);
gtk_widget_show_all(pWindow);
gtk_main();
Has anybody an idea on how to move it ?
Thank you!
Here is what I got:
(source: hostingpics.net)

carl gave you part of the answer.
As to why you see what you have, there are two parts:
First, GtkLabel has an archaic alignment mechanism it inherits from the deprecated GtkMisc class. See GtkMisc's documentation for details: the xalign and yalign properties control the position of the text within the label's allocation, and it's set to centered by default. But remember that they are deprecated, so there's usually better alternatives.
Second, you can only have one control in a GtkWindow. This control gets allocated the entire space of the window.
Put these two facts together and you should see why you have what you have.
So what is correct instead?
You have to use a container, such as GtkBox or GtkGrid, to get more than one widget into a GtkWindow. Each widget carries with it four special properties: hexpand, halign, vexpand, and valign which control the position and size of each member of the container. These are properties of the widgets themselves.
hexpand and vexpand determine whether or not the container allocates whatever space is left over to this control in the X and Y directions, respectively. If multiple widgets have expand set, the space is divided evenly.
halign and valign determine the position of a widget in its allocation. GTK_ALIGN_START, GTK_ALIGN_CENTER, and GTK_ALIGN_END put the widget at the start, middle, and end of the given alignment side, respectively. GTK_ALIGN_FILL fills the widget to fit the allocation.
This page has more information.
If you're trying to do exact positioning of controls, you should first investigate if GtkGrid and GtkBox (applied recursively) provide what you want. An important thing about the default internal centering of GtkLabels is that a GtkLabel in a GtkGrid will already be vertically aligned to its neighbor's text; just set halign to start or end to get the label left-aligned or right-aligned (and set valign to start if its neighbor is something big like a table). There are also functions that provide margins and padding to make the UI look nice.
If you absolutely must position things yourself, however, keep everything in mind.

Related

Prevent gtk2 toggle buttons and progress bars from stretching vertically

I'm trying to write an interface in GTK+2, and I can't find a way to make sure toggle buttons and progress bars won't try to fill up entire space avaiable to them.
My interface has a picture, and a bunch of progress bars and toggle buttons on the other side. If there's enough of them to make the entire vbox with them higher than the picture itself, everything is fine:
However, when there isn't enough of them, they get vertically stretched, which makes them look wrong:
I can't find any way to make sure this doesn't happen, the only thing that I found in the documentation related to setting height of these widgets is setting their minimal height. I'm looking for a way to ensure these widgets don't try to take up all space they can.
My code is here. I couldn't include the placeholder image that I'm using here, but it's just a 128x128 placeholder that can be easily replaced if needed.
When you create your widget for a single CPU, you add it to the parent container:
gtk_container_add(GTK_CONTAINER (vbox), current->box);
Container functions are generic for multiple types of widgets to hold children but don't allow specific adjustments.
In a box you can specify whether the available space should be added to the child widget and how it should appear.
To use this you need to change this line to:
gtk_box_pack_start(GTK_BOX(vbox), current->box, FALSE, FALSE, <borderline>);
This should prevent the widget to be enlarged.

GTK3 Set GtkButton size

I have a very simple code, wich create a GtkWindow and place in it a GtkButton.
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request(_window, 800, 450);
gtk_window_set_decorated(GTK_WINDOW (_window), FALSE);
gtk_window_set_position(GTK_WINDOW (_window),GTK_WIN_POS_CENTER_ALWAYS);
gtk_window_set_resizable(GTK_WINDOW (_window), FALSE);
_startbutton = gtk_button_new_with_label("myLabel");
gtk_container_add(GTK_CONTAINER(_window), _startbutton);
gtk_widget_show_all(_window);
Yet, this doesn't work as expected because the button fills the whole window.
I tried to find a way to change the button size, but all the methods that i found use some methods that are deprecated...
Can someone explain to me the way to do this ?
Because the GtkButton is the only control in the GtkWindow, it will be given the entire area of the GtkWindow to fill. If you want to do anything more complicated, you will need to use layout containers like GtkBox and GtkGrid to explicitly lay out the button, usually in relation to other controls that you will also have in the window.
Once you do lay out your controls, you can use expansion and alignment to control how the button makes use of its allotted space.

How to make a Gtk+ widget inside a GtkScrolledWindow to expand when packed into a GtkPane?

I have a program which shows two GtkTreeViews packed inside a GtkPaned (sscce: here):
gtk_paned_add1(GTK_PANED(paned), tree_view1);
gtk_paned_add2(GTK_PANED(paned), tree_view2);
The result is the following:
However, the tables can become bigger, so I added then to GtkScrolledWindows (sscce: here):
GtkWidget *scrolled_window1 = gtk_scrolled_window_new(NULL, NULL),
*scrolled_window2 = gtk_scrolled_window_new(NULL, NULL);
gtk_container_add(GTK_CONTAINER(scrolled_window1), tree_view1);
gtk_container_add(GTK_CONTAINER(scrolled_window2), tree_view2);
gtk_paned_add1(GTK_PANED(paned), scrolled_window1);
gtk_paned_add2(GTK_PANED(paned), scrolled_window2);
However, now the window collapses itself to the point it is almost a thin trance, as in the screenshot below:
If I maximize the window, the first column does not appear (although I can manually expand it):
So, what is the best method of getting the appearance of the first screenshot wen using GtkScrolledWindows in this scenario? Also, could I define the size of the pane columns in relation to one another (for example, 30% for the first one, 70% for the second one?
I've been using this pattern (I'd be happy if someone posted a better answer):
GtkWidget* treeView_, pane1_;
// [Removed code to create and show the widget heirarchy.]
GtkRequisition sizeReq;
gtk_widget_size_request(treeView_, &sizeReq); // get tree's preferred size
gtk_paned_set_position(GTK_PANED(pane1_), sizeReq.width);
This gets pretty close, but you'll probably have a horizontal scrollbar with a few hidden pixels. Since our application remembers the user's adjustments to the pane positions, it only needs to look "good enough" on initial layout.
Also, there are requirements for gtk_widget_size_request() returning something meaningful. In my case, I've invoked a gtk_widget_show_all() on the hierarchy before retrieving the size request.
The solution I adopted was to actually set the size of the scrolled windows (sscce):
gtk_widget_set_size_request(scrolled_window1, 200, 600);
gtk_widget_set_size_request(scrolled_window2, 600, 600);
The result was, as one would expect, a window with 800x600:
I am not satisfied: this approach relies on arbitrary sizes and it seems too "manual". Nonetheless, I want to use my software so I will adopt it for now.

Automatically sizing a GtkTextView in a GtkScrolledWindow

I work on gschem, a free software tool for editing electronics schematic diagrams. Recently we have encountered a problem using a GtkScrolledWindow containing a GtkTextView.
Context
Recent versions of Ubuntu use overlay scrollbars, which mean that GtkScrolledWindows no longer set a minimum height that provides enough room for a legacy scrollbar (in fact, they have a minimum height of 0). Likewise, a GtkTextView with no text to display requests a height of 0. This means that one of the scrollable GtkTextViews in gschem has been being displayed as one pixel in height, and this is obviously unusable.
In the dialog box on the right of the screenshot shown above, note the invisible widget between the "Value:" label and the "Add" button.
This has been reported independently by several users -- see also the bug report.
Question
Obviously, we could fix this by doing:
g_object_set (textview, "height-request", 100, NULL);
However, this is pretty inelegant, and will break for users who set very large font sizes in pixels (e.g. users with vision problems or who use high-DPI screens).
Ideally, therefore, we want to set the minimum size of the GtkTextView relative to the default font size, e.g. tell it to "show at least three lines of text".
Can anyone suggest a sensible/elegant approach for doing this?
Just disable the ubuntu overlay scrollbars in your application by doing:
putenv("LIBOVERLAY_SCROLLBAR=0");
Not ideal, but it's a quite good until you can find a more permanent solution. Alternatively just wait until Ubuntu disables overlay scrollbars...
I would add code to dig out the current/default style information, use that to figure out the font baseline height, and then compute some rough size allocation based on that, around three lines as you mention.
Does it have to be a textview ? If you can use an eventbox instead, then you can make a cairo surface from it, render the text with pango, and then use pango_layout_get_size() to get the text height.
Likewise, a GtkTextView with no text to display requests a height of 0.
Probably you can create GtkTextView with some text inside. Like several spaces, and set empty value after creation.

Resizing a drawing area in GTK

My application performs a 90 degree rotation on a drawing area, so the width and height of the drawing area need to be swapped.
How can I resize the drawing area with GTK in a way so that the new width and height are actually enforced, not just requested?
Width/height cannot be enforced by a widget, they are determined by its container only. Widget can only request given dimension and its container will allocate the requested area or more (or even less, but all standard containers won't do this).
So, the answer would completely depend on how the area is packed and into what container. If your window (as in GtkWindow) doesn't include anything expandable, setting it to be non-resizable mode will achieve what you want. Otherwise, please specify how the area is packed and/or what other widgets are in the toplevel.

Resources