+static void cylinder_activate_cb(GtkComboBox *combo_box, gpointer data)
+{
+ struct cylinder_widget *cylinder = data;
+ cylinder_cb(cylinder->description, data);
+}
+
+/* Return a frame containing a hbox inside a hbox */
+static GtkWidget *frame_box(const char *title, GtkWidget *vbox)
+{
+ GtkWidget *hbox, *frame;
+
+ hbox = gtk_hbox_new(FALSE, 10);
+ gtk_box_pack_start(GTK_BOX(vbox), hbox, TRUE, FALSE, 0);
+
+ frame = gtk_frame_new(title);
+ gtk_box_pack_start(GTK_BOX(hbox), frame, TRUE, FALSE, 0);
+
+ hbox = gtk_hbox_new(FALSE, 10);
+ gtk_container_add(GTK_CONTAINER(frame), hbox);
+
+ return hbox;
+}
+
+static GtkWidget *labeled_spinbutton(GtkWidget *box, const char *name, double min, double max, double incr)
+{
+ GtkWidget *hbox, *label, *button;
+
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_box_pack_start(GTK_BOX(box), hbox, TRUE, FALSE, 0);
+
+ label = gtk_label_new(name);
+ gtk_box_pack_start(GTK_BOX(hbox), label, TRUE, FALSE, 0);
+
+ button = gtk_spin_button_new_with_range(min, max, incr);
+ gtk_box_pack_start(GTK_BOX(hbox), button, TRUE, FALSE, 0);
+
+ gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(button), GTK_UPDATE_IF_VALID);
+
+ return button;
+}
+