I am already aware that it is not the best title, but we are going to come to my problem.
After I got the Source Code of gtk_demo_application from Emmanuele Bassi ( Thank you by the way) I tried to implement it my Self.
In the Source code I noticed that GtkAccelLabel was used , but me I am only interested in GMenu and Actions, so I did my own menu which looks almost the same like the original.
Here is the Picture of gtk-demo-application:
And here is the Picture of my Own Menu:
As you can see, more or less is the same.
Now there is something which I am not clear, If one take a look at the color submenu there are 3 items:
- red
- green
- blue
As you can see, if one clicks on one of those tree items , there is a dot in front of it which gets selected based on the item i choose.
I would like to know How exactly was implemented, because I can not figure out my self from the source code and how can I adapt it to my Code.
Here is the Source code of what I have so far:
#include <gtk/gtk.h>
static void theme_clbk ( GSimpleAction *action, GVariant *parameter )
{
GVariant *action_state;
action_state = g_action_get_state ( G_ACTION ( action ) );
if ( g_variant_get_boolean ( action_state ) == FALSE )
{
g_print ( "The DarkTheme Menu was Checked...\n" );
g_simple_action_set_state ( action, g_variant_new_boolean ( TRUE ) );
}
else
{
g_print ( "The DarkTheme Menu was Unchecked\n" );
g_simple_action_set_state ( action, g_variant_new_boolean ( FALSE ) );
}
/* Not used */
( void ) parameter;
}
static void titlebar_clbk ( GSimpleAction *action, GVariant *parameter )
{
GVariant *action_state;
action_state = g_action_get_state ( G_ACTION ( action ) );
if ( g_variant_get_boolean ( action_state ) == FALSE )
{
g_print ( "The Hide Title Menu was Checked...\n" );
g_simple_action_set_state ( action, g_variant_new_boolean ( TRUE ) );
}
else
{
g_print ( "The Hide Title Menu was Unchecked\n" );
g_simple_action_set_state ( action, g_variant_new_boolean ( FALSE ) );
}
/* Not used */
( void ) parameter;
}
static void bold_clbk ( GSimpleAction *action, GVariant *parameter )
{
GVariant *action_state;
action_state = g_action_get_state ( G_ACTION ( action ) );
if ( g_variant_get_boolean ( action_state ) == FALSE )
{
g_print ( "The Bold Menu was Checked...\n" );
g_simple_action_set_state ( action, g_variant_new_boolean ( TRUE ) );
}
else
{
g_print ( "The Bold Menu was Unchecked\n" );
g_simple_action_set_state ( action, g_variant_new_boolean ( FALSE ) );
}
/* Not used */
( void ) parameter;
}
static void red_clbk ( GSimpleAction *action, GVariant *parameter, gpointer user_data )
{
g_print ( "Action %s Selected\n", g_action_get_name ( G_ACTION ( action ) ) );
/* Not used */
( void ) parameter;
( void ) user_data;
}
static void green_clbk ( GSimpleAction *action, GVariant *parameter, gpointer user_data )
{
g_print ( "Action %s Selected\n", g_action_get_name ( G_ACTION ( action ) ) );
/* Not used */
( void ) parameter;
( void ) user_data;
}
static void blue_clbk ( GSimpleAction *action, GVariant *parameter, gpointer user_data )
{
g_print ( "Action %s Selected\n", g_action_get_name ( G_ACTION ( action ) ) );
/* Not used */
( void ) parameter;
( void ) user_data;
}
static void square_clbk ( GSimpleAction *action, GVariant *parameter, gpointer user_data )
{
g_print ( "Action %s Selected\n", g_action_get_name ( G_ACTION ( action ) ) );
/* Not used */
( void ) parameter;
( void ) user_data;
}
static void rectangle_clbk ( GSimpleAction *action, GVariant *parameter, gpointer user_data )
{
g_print ( "Action %s Selected\n", g_action_get_name ( G_ACTION ( action ) ) );
/* Not used */
( void ) parameter;
( void ) user_data;
}
static void oval_clbk ( GSimpleAction *action, GVariant *parameter, gpointer user_data )
{
g_print ( "Action %s Selected\n", g_action_get_name ( G_ACTION ( action ) ) );
/* Not used */
( void ) parameter;
( void ) user_data;
}
static void startup ( GtkApplication *application )
{
static GActionEntry actions[] =
{
{ "red", red_clbk, NULL, NULL, NULL, { 0, 0, 0 } },
{ "green", green_clbk, NULL, NULL, NULL, { 0, 0, 0 } },
{ "blue", blue_clbk, NULL, NULL, NULL, { 0, 0, 0 } },
/* */
{ "square", square_clbk, NULL, NULL, NULL, { 0, 0, 0 } },
{ "rectangle", rectangle_clbk, NULL, NULL, NULL, { 0, 0, 0 } },
{ "oval", oval_clbk, NULL, NULL, NULL, { 0, 0, 0 } },
};
GMenu *main_menu;
GMenu *file_menu;
GMenuItem *item;
GActionMap *action_map;
GSimpleAction *theme_action;
GSimpleAction *tBar_action;
GSimpleAction *bold_action;
GVariant *state;
/// ***
state = g_variant_new ( "b", FALSE );
/// ***
action_map = G_ACTION_MAP ( application );
theme_action = g_simple_action_new_stateful ( "theme", NULL, state );
tBar_action = g_simple_action_new_stateful ( "tbar", NULL, state );
bold_action = g_simple_action_new_stateful ( "bold", NULL, state );
/// ***
g_action_map_add_action ( action_map, G_ACTION ( theme_action ) );
g_action_map_add_action ( action_map, G_ACTION ( tBar_action ) );
g_action_map_add_action ( action_map, G_ACTION ( bold_action ) );
g_action_map_add_action_entries ( G_ACTION_MAP ( application ), actions, G_N_ELEMENTS ( actions ), NULL );
/// ***
g_signal_connect_swapped ( tBar_action, "activate", G_CALLBACK ( titlebar_clbk ), tBar_action );
g_signal_connect_swapped ( theme_action, "activate", G_CALLBACK ( theme_clbk ), theme_action );
g_signal_connect_swapped ( bold_action, "activate", G_CALLBACK ( bold_clbk ), bold_action );
/// ***
main_menu = g_menu_new ();
file_menu = g_menu_new();
/// ***
item = g_menu_item_new ( "Prefer Dark Theme", "app.theme" );
g_menu_append_item ( file_menu, G_MENU_ITEM ( item ) );
g_object_unref ( item );
/// ***
item = g_menu_item_new ( "Hide Titlebar when maximized", "app.tbar" );
g_menu_append_item ( file_menu, G_MENU_ITEM ( item ) );
g_object_unref ( item );
/// ***
GMenu *submenu;
GMenu *submenu2;
submenu = g_menu_new ();
submenu2 = g_menu_new ();
/// ***
item = g_menu_item_new ( "Color", NULL );
g_menu_item_set_submenu ( item, G_MENU_MODEL ( submenu ) );
g_menu_insert_item ( file_menu, 2, G_MENU_ITEM ( item ) );
g_object_unref ( item );
/// ***
item = g_menu_item_new ( "Red", "app.red" );
g_menu_item_set_attribute ( item, "accel", "s", "<Ctrl>R", NULL );
g_menu_insert_item ( submenu, 0, G_MENU_ITEM ( item ) );
g_object_unref ( item );
/// ***
item = g_menu_item_new ( "Green", "app.green" );
g_menu_item_set_attribute ( item, "accel", "s", "<Ctrl>G", NULL );
g_menu_insert_item ( submenu, 1, G_MENU_ITEM ( item ) );
g_object_unref ( item );
/// ***
item = g_menu_item_new ( "Blue", "app.blue" );
g_menu_item_set_attribute ( item, "accel", "s", "<Ctrl>B", NULL );
g_menu_insert_item ( submenu, 2, G_MENU_ITEM ( item ) );
g_object_unref ( item );
/// ***
item = g_menu_item_new ( "Shape", NULL );
g_menu_item_set_submenu ( item, G_MENU_MODEL ( submenu2 ) );
g_menu_insert_item ( file_menu, 3, G_MENU_ITEM ( item ) );
g_object_unref ( item );
/// ***
item = g_menu_item_new ( "Square", "app.square" );
g_menu_item_set_attribute ( item, "accel", "s", "<Ctrl>S", NULL );
g_menu_insert_item ( submenu2, 0, G_MENU_ITEM ( item ) );
g_object_unref ( item );
/// ***
item = g_menu_item_new ( "Rectangle", "app.rectangle" );
g_menu_item_set_attribute ( item, "accel", "s", "<Ctrl><Alt>R", NULL );
g_menu_insert_item ( submenu2, 1, G_MENU_ITEM ( item ) );
g_object_unref ( item );
/// ***
item = g_menu_item_new ( "Oval", "app.oval" );
g_menu_item_set_attribute ( item, "accel", "s", "<Ctrl>O", NULL );
g_menu_insert_item ( submenu2, 2, G_MENU_ITEM ( item ) );
g_object_unref ( item );
/// ***
item = g_menu_item_new ( "Bold", "app.bold" );
g_menu_item_set_attribute ( item, "accel", "s", "<Ctrl><Shift>B", NULL );
g_menu_append_item ( file_menu, G_MENU_ITEM ( item ) );
g_object_unref ( item );
g_menu_insert_submenu ( main_menu, 0, "Preferences", G_MENU_MODEL ( file_menu ) );
/// ***
gtk_application_set_menubar ( application, G_MENU_MODEL ( main_menu ) );
g_object_unref ( main_menu );
}
static void activate ( GtkApplication *app )
{
GtkWidget *window;
window = gtk_application_window_new ( app );
gtk_window_set_application ( GTK_WINDOW ( window ), GTK_APPLICATION ( app ) );
gtk_window_set_title ( GTK_WINDOW ( window ), "Hello GNOME" );
gtk_widget_show_all ( GTK_WIDGET ( window ) );
}
int main ( int argc, char **argv )
{
GtkApplication *app;
int status;
app = gtk_application_new ( "org.gtk.example", G_APPLICATION_FLAGS_NONE );
g_signal_connect_swapped ( app, "startup", G_CALLBACK ( startup ), app );
g_signal_connect_swapped ( app, "activate", G_CALLBACK ( activate ), app );
status = g_application_run ( G_APPLICATION ( app ), argc, argv );
g_object_unref ( app );
return status;
}