Web lists-archives.com

Set the role of a GtkModelButton via “action-name”




Hello!

I'm trying to create a popover with a GtkModelButton and a checkbox
directly in C. I can achieve this using the following snippet:

// -----------------------------------------------
const GActionEntry app_actions[] = {
    { "check", NULL, NULL, NULL, check_action }
};

/* ... */

checkButton = gtk_model_button_new();
gtk_box_pack_start (GTK_BOX (popBox), checkButton, TRUE, TRUE, 0);
gtk_button_set_label (GTK_BUTTON (checkButton), "Check Me");

// ????: Setting the following property shouldn't be required when 
//       using action-name and action-target
g_object_set (G_OBJECT (checkButton), "role", 
              GTK_BUTTON_ROLE_CHECK, NULL);

gtk_actionable_set_action_name (GTK_ACTIONABLE (checkButton), 
                                "app.check");

/* ... */
g_action_map_add_action_entries (G_ACTION_MAP (app), app_actions,
                 G_N_ELEMENTS (app_actions), (gpointer) a);
// -----------------------------------------------

Here setting the "role" property does the job. However, the 
documentation of GtkModelButton states that this shouldn't 
be required:

[BEGIN CITE]
When the action is specified via the “action-name” and 
“action-target” properties, the role of the button (i.e. 
whether it is a plain, check or radio button) is determined 
by the type of the action and doesn't have to be explicitly 
specified with the “role” property.
[END CITE]

I'm wondering how I can set the type of the action? I assume 
that I've to this in the GActionEntry, have, however, no real 
clue how to accomplish this?

Below is my small demo program.

Cheers,
Martin

//--------------------------------------------------
/*!
 * \mainpage A simple demo program to show-case a custom popover.
 */
#include <gtk/gtk.h>
#include <glib/gprintf.h>

typedef struct {
	GtkApplication *app;
	GtkWidget *window;
	GtkWidget *omButton;
	GtkWidget *popover;
	GtkAdjustment *spinAdj;
	GtkAdjustment *scaleAdj;
} myWidgets;

static void click_action (GSimpleAction *action, GVariant *parameter, gpointer data);
static void check_action (GSimpleAction *action, GVariant *parameter, gpointer data);
static void popover_action (GSimpleAction *action, GVariant *parameter, gpointer data);
static void set_action (GSimpleAction *action, GVariant *parameter, gpointer data);

GActionEntry app_actions[] = {
	{ "click", click_action },
	{ "check", NULL, NULL, "false", check_action },
	{ "sclick", set_action },
	{ "show", popover_action }
};

static void
check_action (GSimpleAction *action, GVariant *parameter, gpointer data)
{
	if (g_variant_get_boolean (parameter))
		g_printf ("Item is checked.\n");
	else
		g_printf ("Item is unchecked.\n");
	g_simple_action_set_state (action, parameter);
}


static void
click_action (GSimpleAction *action, GVariant *parameter, gpointer data)
{
	static gint i = 1;
	g_printf ("Item cliked %d times.\n", i++);
}

static void
set_action (GSimpleAction *action, GVariant *parameter, gpointer data)
{
	gint ival;
	gdouble fval;
	myWidgets *a = (myWidgets *) data;

	ival = gtk_adjustment_get_value (a->spinAdj);
	g_printf ("Spin widget value: %d\n", ival);
	fval = gtk_adjustment_get_value (a->scaleAdj);
	g_printf ("Scale widget value: %1.2f\n", fval);
	// hide the popover after clicking the SET button
	gtk_widget_hide (a->popover);
}

/*!
 * \brief Construct the popover.
 */
static void
popover_action (GSimpleAction *action, GVariant *parameter, gpointer data)
{
	GtkWidget *popBox;
	GtkWidget *alabel;
	GtkWidget *clickButton;
	GtkWidget *checkButton;
	GtkWidget *sep;
	GtkWidget *slabel;
	GtkWidget *usBox, *usLabel;
	GtkWidget *lsBox, *lsLabel;
	GtkWidget *setButton;
	GtkWidget *scale, *spinner;
	GtkCssProvider *provider;
	GdkDisplay *display;
	GdkScreen *screen;
	gdouble marks[3] = { 0.0, 0.5, 1.0 };
	const gchar *labels[3] = {
		"<small>0.0</small>",
		"<small>0.5</small>",
		"<small>1.0</small>"
	};
	gdouble scaleVal, spinVal;
	myWidgets *a = (myWidgets *) data;

	// construct the popover associated to omButton
	a->popover = gtk_popover_new (a->omButton);
	gtk_popover_set_transitions_enabled (GTK_POPOVER (a->popover), TRUE);
	popBox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0);
	gtk_container_add (GTK_CONTAINER (a->popover), popBox);
	gtk_container_set_border_width (GTK_CONTAINER (a->popover), 10);
	// a gray label
	alabel  = gtk_label_new ("<span color=\"#666666\">Action:</span>");
	gtk_label_set_use_markup (GTK_LABEL (alabel), TRUE);
	g_object_set (G_OBJECT (alabel), "xalign", 0.0, NULL);
	g_object_set (G_OBJECT (alabel), "margin", 2, NULL);
	gtk_box_pack_start (GTK_BOX (popBox), alabel, FALSE, FALSE, 0);
	// a clickable button
	clickButton = gtk_model_button_new();
	gtk_box_pack_start (GTK_BOX (popBox), clickButton, TRUE, TRUE, 0);
	gtk_button_set_label (GTK_BUTTON (clickButton), "Click Me");
	gtk_widget_set_size_request (clickButton, 90, 30);
	g_object_set (G_OBJECT (clickButton), "xalign", 0.0, NULL);
	g_object_set (G_OBJECT (clickButton), "margin", 2, NULL);
	gtk_actionable_set_action_name (GTK_ACTIONABLE (clickButton), "app.click");
	// a checkbox button
	checkButton = gtk_model_button_new();
	gtk_box_pack_start (GTK_BOX (popBox), checkButton, TRUE, TRUE, 0);
	gtk_button_set_label (GTK_BUTTON (checkButton), "Check Me");
	gtk_widget_set_size_request (checkButton, 90, 30);
	g_object_set (G_OBJECT (checkButton), "xalign", 0.0, NULL);
	g_object_set (G_OBJECT (checkButton), "margin", 2, NULL);
	// TODO: Setting the following property shouldn't be required when using
	//       action-name and action-target
	g_object_set (G_OBJECT (checkButton), "role", GTK_BUTTON_ROLE_CHECK, NULL);
	gtk_actionable_set_action_name (GTK_ACTIONABLE (checkButton), "app.check");
	// a separator
	sep = gtk_separator_new (GTK_ORIENTATION_HORIZONTAL);
	gtk_box_pack_start (GTK_BOX (popBox), sep, FALSE, FALSE, 0);
	// a gray label
	slabel  = gtk_label_new ("<span color=\"#666666\">Value:</span>");
	gtk_label_set_use_markup (GTK_LABEL (slabel), TRUE);
	g_object_set (G_OBJECT (slabel), "xalign", 0.0, NULL);
	g_object_set (G_OBJECT (slabel), "margin", 2, NULL);
	gtk_box_pack_start (GTK_BOX (popBox), slabel, FALSE, FALSE, 0);
	// label (next to spinner)
	usBox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
	gtk_box_pack_start (GTK_BOX (popBox), usBox, FALSE, FALSE, 0);
	usLabel = gtk_label_new ("Spin:");
	gtk_widget_set_size_request (usLabel, 90, 25);
	g_object_set (G_OBJECT (usLabel), "xalign", 0.0, NULL);
	g_object_set (G_OBJECT (usLabel), "margin", 2, NULL);
	gtk_box_pack_start (GTK_BOX (usBox), usLabel, FALSE, FALSE, 0);
	// spinner
	if (a->spinAdj != NULL) {
		spinVal = gtk_adjustment_get_value (a->spinAdj);
		gtk_adjustment_set_value (GTK_ADJUSTMENT (a->spinAdj), spinVal);
	} else
		a->spinAdj = gtk_adjustment_new (5, 50, 300, 5, 0, 0);
	spinner = gtk_spin_button_new (a->spinAdj, 5, 0);
	gtk_box_pack_start (GTK_BOX (usBox), spinner, FALSE, FALSE, 0);
	// label (next to scale)
	lsBox = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
	gtk_box_pack_start (GTK_BOX (popBox), lsBox, FALSE, FALSE, 0);
	lsLabel = gtk_label_new ("Scale:");
	gtk_widget_set_size_request (lsLabel, 90, 25);
	g_object_set (G_OBJECT (lsLabel), "xalign", 0.0, NULL);
	g_object_set (G_OBJECT (lsLabel), "margin", 2, NULL);
	gtk_box_pack_start (GTK_BOX (lsBox), lsLabel, FALSE, FALSE, 0);
	// scale
	if (a->scaleAdj != NULL) {
		scaleVal = gtk_adjustment_get_value (a->scaleAdj);
		gtk_adjustment_set_value (GTK_ADJUSTMENT (a->scaleAdj), scaleVal);
	} else
		a->scaleAdj = gtk_adjustment_new (0.5, 0.0, 1.0, 0.1, 0.1, 0.0);
	scale = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, a->scaleAdj);
	gtk_scale_set_draw_value (GTK_SCALE (scale), FALSE);
	gtk_scale_add_mark (GTK_SCALE (scale), marks[0], GTK_POS_BOTTOM, labels[0]);
	gtk_scale_add_mark (GTK_SCALE (scale), marks[1], GTK_POS_BOTTOM, labels[1]);
	gtk_scale_add_mark (GTK_SCALE (scale), marks[2], GTK_POS_BOTTOM, labels[2]);
	gtk_widget_set_size_request (scale, 120, 25);
	gtk_box_pack_start (GTK_BOX (lsBox), scale, FALSE, FALSE, 0);
	// a button
	setButton = gtk_button_new_with_label ("Set");
	g_object_set (G_OBJECT (setButton), "xalign", 0.5, NULL);
	g_object_set (G_OBJECT (setButton), "margin", 2, NULL);
	gtk_box_pack_start (GTK_BOX (popBox), setButton, FALSE, FALSE, 0);
	gtk_actionable_set_action_name (GTK_ACTIONABLE (setButton), "app.sclick");
	// add some padding to some labels
	provider = gtk_css_provider_new ();
	display = gdk_display_get_default ();
	screen = gdk_display_get_default_screen (display);
	gtk_style_context_add_provider_for_screen (screen,
						   GTK_STYLE_PROVIDER (provider),
						   GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
	gtk_css_provider_load_from_data (GTK_CSS_PROVIDER (provider),
					 "GtkModelButton GtkLabel {\n"
					 "	padding-left: 10px;\n"
					 "}\n"
					 "\n"
					 "GtkBox GtkBox GtkLabel {\n"
					 "	padding-left: 10px;\n"
					 "}\n", -1, NULL);
	g_object_unref (provider);
	// display the popover
	gtk_widget_show_all (a->popover);
}

/*!
 * \brief Construct the main window.
 */
static void
activate (GtkApplication *app, gpointer data)
{
	GtkWidget *hBar;
	GtkWidget *omIcon;
	myWidgets *a = (myWidgets *) data;

	// create a window and set some properties
	a->window = gtk_application_window_new (app);
	gtk_window_set_application (GTK_WINDOW (a->window), GTK_APPLICATION (app));
	gtk_window_set_default_size (GTK_WINDOW (a->window), 600, 500);
	// headerbar
	hBar = gtk_header_bar_new ();
	gtk_widget_show (hBar);
	gtk_header_bar_set_title (GTK_HEADER_BAR (hBar), "Popover Demo");
	gtk_header_bar_set_subtitle (GTK_HEADER_BAR (hBar), "Showcase a Popover");
	gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (hBar), TRUE);
	gtk_window_set_titlebar (GTK_WINDOW (a->window), hBar);
	// create the gear menu button
	a->omButton = gtk_button_new();
	omIcon = gtk_image_new_from_icon_name ("format-justify-fill-symbolic",
					       GTK_ICON_SIZE_SMALL_TOOLBAR);
	gtk_button_set_image (GTK_BUTTON (a->omButton), omIcon);
	gtk_header_bar_pack_end (GTK_HEADER_BAR (hBar), a->omButton);
	gtk_actionable_set_action_name (GTK_ACTIONABLE (a->omButton), "app.show");

	// associate actions with callback action functions
	g_action_map_add_action_entries (G_ACTION_MAP (app), app_actions,
					 G_N_ELEMENTS (app_actions), (gpointer) a);
	// show the program
	gtk_widget_show_all (GTK_WIDGET (a->window));
}

int
main (int argc, char **argv)
{
	int status;
	myWidgets *a = g_malloc (sizeof (myWidgets));

	a->app = gtk_application_new ("org.gtk.example", G_APPLICATION_FLAGS_NONE);
	g_signal_connect (a->app, "activate", G_CALLBACK (activate), (gpointer) a);
	status = g_application_run (G_APPLICATION (a->app), argc, argv);
	g_object_unref (a->app);

	g_free (a);
	return status;
}
/*! EOF */
_______________________________________________
gtk-list mailing list
gtk-list@xxxxxxxxx
https://mail.gnome.org/mailman/listinfo/gtk-list