forked from AuroraMiddleware/gtk
eed307713b
Change the format of GtkBuilder <menu> to be more in-line with the style of the rest of GtkBuilder so that we can do translation in a consistent way. The format is now substantially more difficult to hand-write, but tools should be along soon. There is an xslt program attached to the bug to help you convert your existing .ui files from the old format to the new one. https://bugzilla.gnome.org/show_bug.cgi?id=668696
396 lines
13 KiB
C
396 lines
13 KiB
C
#include <stdlib.h>
|
|
#include <gtk/gtk.h>
|
|
|
|
static void
|
|
activate_toggle (GSimpleAction *action,
|
|
GVariant *parameter,
|
|
gpointer user_data)
|
|
{
|
|
GVariant *state;
|
|
|
|
state = g_action_get_state (G_ACTION (action));
|
|
g_action_change_state (G_ACTION (action), g_variant_new_boolean (!g_variant_get_boolean (state)));
|
|
g_variant_unref (state);
|
|
}
|
|
|
|
static void
|
|
activate_radio (GSimpleAction *action,
|
|
GVariant *parameter,
|
|
gpointer user_data)
|
|
{
|
|
g_action_change_state (G_ACTION (action), parameter);
|
|
}
|
|
|
|
static void
|
|
change_fullscreen_state (GSimpleAction *action,
|
|
GVariant *state,
|
|
gpointer user_data)
|
|
{
|
|
if (g_variant_get_boolean (state))
|
|
gtk_window_fullscreen (user_data);
|
|
else
|
|
gtk_window_unfullscreen (user_data);
|
|
|
|
g_simple_action_set_state (action, state);
|
|
}
|
|
|
|
static void
|
|
change_justify_state (GSimpleAction *action,
|
|
GVariant *state,
|
|
gpointer user_data)
|
|
{
|
|
GtkTextView *text = g_object_get_data (user_data, "bloatpad-text");
|
|
const gchar *str;
|
|
|
|
str = g_variant_get_string (state, NULL);
|
|
|
|
if (g_str_equal (str, "left"))
|
|
gtk_text_view_set_justification (text, GTK_JUSTIFY_LEFT);
|
|
else if (g_str_equal (str, "center"))
|
|
gtk_text_view_set_justification (text, GTK_JUSTIFY_CENTER);
|
|
else if (g_str_equal (str, "right"))
|
|
gtk_text_view_set_justification (text, GTK_JUSTIFY_RIGHT);
|
|
else
|
|
/* ignore this attempted change */
|
|
return;
|
|
|
|
g_simple_action_set_state (action, state);
|
|
}
|
|
|
|
static GtkClipboard *
|
|
get_clipboard (GtkWidget *widget)
|
|
{
|
|
return gtk_widget_get_clipboard (widget, gdk_atom_intern_static_string ("CLIPBOARD"));
|
|
}
|
|
|
|
static void
|
|
window_copy (GSimpleAction *action,
|
|
GVariant *parameter,
|
|
gpointer user_data)
|
|
{
|
|
GtkWindow *window = GTK_WINDOW (user_data);
|
|
GtkTextView *text = g_object_get_data ((GObject*)window, "bloatpad-text");
|
|
|
|
gtk_text_buffer_copy_clipboard (gtk_text_view_get_buffer (text),
|
|
get_clipboard ((GtkWidget*) text));
|
|
}
|
|
|
|
static void
|
|
window_paste (GSimpleAction *action,
|
|
GVariant *parameter,
|
|
gpointer user_data)
|
|
{
|
|
GtkWindow *window = GTK_WINDOW (user_data);
|
|
GtkTextView *text = g_object_get_data ((GObject*)window, "bloatpad-text");
|
|
|
|
gtk_text_buffer_paste_clipboard (gtk_text_view_get_buffer (text),
|
|
get_clipboard ((GtkWidget*) text),
|
|
NULL,
|
|
TRUE);
|
|
|
|
}
|
|
|
|
static GActionEntry win_entries[] = {
|
|
{ "copy", window_copy, NULL, NULL, NULL },
|
|
{ "paste", window_paste, NULL, NULL, NULL },
|
|
{ "fullscreen", activate_toggle, NULL, "false", change_fullscreen_state },
|
|
{ "justify", activate_radio, "s", "'left'", change_justify_state }
|
|
};
|
|
|
|
static void
|
|
new_window (GApplication *app,
|
|
GFile *file)
|
|
{
|
|
GtkWidget *window, *grid, *scrolled, *view;
|
|
GtkWidget *toolbar;
|
|
GtkToolItem *button;
|
|
GtkWidget *sw, *box, *label;
|
|
|
|
window = gtk_application_window_new (GTK_APPLICATION (app));
|
|
gtk_window_set_default_size ((GtkWindow*)window, 640, 480);
|
|
g_action_map_add_action_entries (G_ACTION_MAP (window), win_entries, G_N_ELEMENTS (win_entries), window);
|
|
gtk_window_set_title (GTK_WINDOW (window), "Bloatpad");
|
|
|
|
grid = gtk_grid_new ();
|
|
gtk_container_add (GTK_CONTAINER (window), grid);
|
|
|
|
toolbar = gtk_toolbar_new ();
|
|
button = gtk_toggle_tool_button_new_from_stock (GTK_STOCK_JUSTIFY_LEFT);
|
|
gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.justify::left");
|
|
gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (button));
|
|
|
|
button = gtk_toggle_tool_button_new_from_stock (GTK_STOCK_JUSTIFY_CENTER);
|
|
gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.justify::center");
|
|
gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (button));
|
|
|
|
button = gtk_toggle_tool_button_new_from_stock (GTK_STOCK_JUSTIFY_RIGHT);
|
|
gtk_actionable_set_detailed_action_name (GTK_ACTIONABLE (button), "win.justify::right");
|
|
gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (button));
|
|
|
|
button = gtk_separator_tool_item_new ();
|
|
gtk_separator_tool_item_set_draw (GTK_SEPARATOR_TOOL_ITEM (button), FALSE);
|
|
gtk_tool_item_set_expand (GTK_TOOL_ITEM (button), TRUE);
|
|
gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (button));
|
|
|
|
button = gtk_tool_item_new ();
|
|
box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 6);
|
|
gtk_container_add (GTK_CONTAINER (button), box);
|
|
label = gtk_label_new ("Fullscreen:");
|
|
gtk_container_add (GTK_CONTAINER (box), label);
|
|
sw = gtk_switch_new ();
|
|
gtk_actionable_set_action_name (GTK_ACTIONABLE (sw), "win.fullscreen");
|
|
gtk_container_add (GTK_CONTAINER (box), sw);
|
|
gtk_container_add (GTK_CONTAINER (toolbar), GTK_WIDGET (button));
|
|
|
|
gtk_grid_attach (GTK_GRID (grid), toolbar, 0, 0, 1, 1);
|
|
|
|
scrolled = gtk_scrolled_window_new (NULL, NULL);
|
|
gtk_widget_set_hexpand (scrolled, TRUE);
|
|
gtk_widget_set_vexpand (scrolled, TRUE);
|
|
view = gtk_text_view_new ();
|
|
|
|
g_object_set_data ((GObject*)window, "bloatpad-text", view);
|
|
|
|
gtk_container_add (GTK_CONTAINER (scrolled), view);
|
|
|
|
gtk_grid_attach (GTK_GRID (grid), scrolled, 0, 1, 1, 1);
|
|
|
|
if (file != NULL)
|
|
{
|
|
gchar *contents;
|
|
gsize length;
|
|
|
|
if (g_file_load_contents (file, NULL, &contents, &length, NULL, NULL))
|
|
{
|
|
GtkTextBuffer *buffer;
|
|
|
|
buffer = gtk_text_view_get_buffer (GTK_TEXT_VIEW (view));
|
|
gtk_text_buffer_set_text (buffer, contents, length);
|
|
g_free (contents);
|
|
}
|
|
}
|
|
|
|
gtk_widget_show_all (GTK_WIDGET (window));
|
|
}
|
|
|
|
static void
|
|
bloat_pad_activate (GApplication *application)
|
|
{
|
|
new_window (application, NULL);
|
|
}
|
|
|
|
static void
|
|
bloat_pad_open (GApplication *application,
|
|
GFile **files,
|
|
gint n_files,
|
|
const gchar *hint)
|
|
{
|
|
gint i;
|
|
|
|
for (i = 0; i < n_files; i++)
|
|
new_window (application, files[i]);
|
|
}
|
|
|
|
typedef GtkApplication BloatPad;
|
|
typedef GtkApplicationClass BloatPadClass;
|
|
|
|
G_DEFINE_TYPE (BloatPad, bloat_pad, GTK_TYPE_APPLICATION)
|
|
|
|
static void
|
|
bloat_pad_finalize (GObject *object)
|
|
{
|
|
G_OBJECT_CLASS (bloat_pad_parent_class)->finalize (object);
|
|
}
|
|
|
|
static void
|
|
new_activated (GSimpleAction *action,
|
|
GVariant *parameter,
|
|
gpointer user_data)
|
|
{
|
|
GApplication *app = user_data;
|
|
|
|
g_application_activate (app);
|
|
}
|
|
|
|
static void
|
|
about_activated (GSimpleAction *action,
|
|
GVariant *parameter,
|
|
gpointer user_data)
|
|
{
|
|
gtk_show_about_dialog (NULL,
|
|
"program-name", "Bloatpad",
|
|
"title", "About Bloatpad",
|
|
"comments", "Not much to say, really.",
|
|
NULL);
|
|
}
|
|
|
|
static void
|
|
quit_app (GtkApplication *app)
|
|
{
|
|
GList *list, *next;
|
|
GtkWindow *win;
|
|
|
|
g_print ("Going down...\n");
|
|
|
|
list = gtk_application_get_windows (app);
|
|
while (list)
|
|
{
|
|
win = list->data;
|
|
next = list->next;
|
|
|
|
gtk_widget_destroy (GTK_WIDGET (win));
|
|
|
|
list = next;
|
|
}
|
|
}
|
|
|
|
static void
|
|
quit_activated (GSimpleAction *action,
|
|
GVariant *parameter,
|
|
gpointer user_data)
|
|
{
|
|
GtkApplication *app = user_data;
|
|
|
|
quit_app (app);
|
|
}
|
|
|
|
static GActionEntry app_entries[] = {
|
|
{ "new", new_activated, NULL, NULL, NULL },
|
|
{ "about", about_activated, NULL, NULL, NULL },
|
|
{ "quit", quit_activated, NULL, NULL, NULL },
|
|
};
|
|
|
|
static void
|
|
bloat_pad_startup (GApplication *application)
|
|
{
|
|
GtkBuilder *builder;
|
|
|
|
G_APPLICATION_CLASS (bloat_pad_parent_class)
|
|
->startup (application);
|
|
|
|
g_action_map_add_action_entries (G_ACTION_MAP (application), app_entries, G_N_ELEMENTS (app_entries), application);
|
|
|
|
builder = gtk_builder_new ();
|
|
gtk_builder_add_from_string (builder,
|
|
"<interface>"
|
|
" <menu id='app-menu'>"
|
|
" <section>"
|
|
" <item>"
|
|
" <attribute name='label'>_New Window</attribute>"
|
|
" <attribute name='action'>app.new</attribute>"
|
|
" <attribute name='accel'><Primary>n</attribute>"
|
|
" </item>"
|
|
" </section>"
|
|
" <section>"
|
|
" <item>"
|
|
" <attribute name='label'>_About Bloatpad</attribute>"
|
|
" <attribute name='action'>app.about</attribute>"
|
|
" </item>"
|
|
" </section>"
|
|
" <section>"
|
|
" <item>"
|
|
" <attribute name='label'>_Quit</attribute>"
|
|
" <attribute name='action'>app.quit</attribute>"
|
|
" <attribute name='accel'><Primary>q</attribute>"
|
|
" </item>"
|
|
" </section>"
|
|
" </menu>"
|
|
" <menu id='menubar'>"
|
|
" <submenu>"
|
|
" <attribute name='label'>_Edit</attribute>"
|
|
" <section>"
|
|
" <item>"
|
|
" <attribute name='label'>_Copy</attribute>"
|
|
" <attribute name='action'>win.copy</attribute>"
|
|
" <attribute name='accel'><Primary>c</attribute>"
|
|
" </item>"
|
|
" <item>"
|
|
" <attribute name='label'>_Parse</attribute>"
|
|
" <attribute name='action'>win.parse</attribute>"
|
|
" <attribute name='accel'><Primary>v</attribute>"
|
|
" </item>"
|
|
" </section>"
|
|
" </submenu>"
|
|
" <submenu>"
|
|
" <attribute name='label'>_View</attribute>"
|
|
" <section>"
|
|
" <item>"
|
|
" <attribute name='label'>_Fullscreen</attribute>"
|
|
" <attribute name='action'>win.fullscreen</attribute>"
|
|
" <attribute name='accel'>F11</attribute>"
|
|
" </item>"
|
|
" </section>"
|
|
" </submenu>"
|
|
" </menu>"
|
|
"</interface>", -1, NULL);
|
|
gtk_application_set_app_menu (GTK_APPLICATION (application), G_MENU_MODEL (gtk_builder_get_object (builder, "app-menu")));
|
|
gtk_application_set_menubar (GTK_APPLICATION (application), G_MENU_MODEL (gtk_builder_get_object (builder, "menubar")));
|
|
g_object_unref (builder);
|
|
}
|
|
|
|
static void
|
|
bloat_pad_init (BloatPad *app)
|
|
{
|
|
}
|
|
|
|
static void
|
|
bloat_pad_class_init (BloatPadClass *class)
|
|
{
|
|
GApplicationClass *application_class = G_APPLICATION_CLASS (class);
|
|
GObjectClass *object_class = G_OBJECT_CLASS (class);
|
|
|
|
application_class->startup = bloat_pad_startup;
|
|
application_class->activate = bloat_pad_activate;
|
|
application_class->open = bloat_pad_open;
|
|
|
|
object_class->finalize = bloat_pad_finalize;
|
|
|
|
}
|
|
|
|
static void
|
|
quit_cb (GtkApplication *app)
|
|
{
|
|
g_print ("Session manager to us to quit\n");
|
|
|
|
quit_app (app);
|
|
}
|
|
|
|
BloatPad *
|
|
bloat_pad_new (void)
|
|
{
|
|
GtkApplication *bloat_pad;
|
|
|
|
g_type_init ();
|
|
|
|
g_set_application_name ("Bloatpad");
|
|
|
|
bloat_pad = g_object_new (bloat_pad_get_type (),
|
|
"application-id", "org.gtk.Test.bloatpad",
|
|
"flags", G_APPLICATION_HANDLES_OPEN,
|
|
"inactivity-timeout", 30000,
|
|
"register-session", TRUE,
|
|
NULL);
|
|
|
|
g_signal_connect (bloat_pad, "quit", G_CALLBACK (quit_cb), NULL);
|
|
|
|
return bloat_pad;
|
|
}
|
|
|
|
int
|
|
main (int argc, char **argv)
|
|
{
|
|
BloatPad *bloat_pad;
|
|
int status;
|
|
|
|
bloat_pad = bloat_pad_new ();
|
|
|
|
gtk_application_add_accelerator (GTK_APPLICATION (bloat_pad),
|
|
"F11", "win.fullscreen", NULL);
|
|
|
|
status = g_application_run (G_APPLICATION (bloat_pad), argc, argv);
|
|
|
|
g_object_unref (bloat_pad);
|
|
|
|
return status;
|
|
}
|