]> Pileus Git - grits/blob - src/gis-demo.c
Update docs
[grits] / src / gis-demo.c
1 /*
2  * Copyright (C) 2009-2010 Andy Spencer <andy753421@gmail.com>
3  *
4  * This program is free software: you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation, either version 3 of the License, or
7  * (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
16  */
17
18 #include <config.h>
19 #include <gtk/gtk.h>
20 #include <gdk/gdkkeysyms.h>
21
22 #include "gis.h"
23
24
25 static GisPrefs   *prefs;
26 static GisPlugins *plugins;
27 static GisViewer  *viewer;
28
29
30 /*************
31  * Callbacks *
32  *************/
33 static void on_offline(GtkToggleAction *action, gpointer _)
34 {
35         gboolean active = gtk_toggle_action_get_active(action);
36         gis_viewer_set_offline(viewer, active);
37 }
38
39 static void on_plugin(GtkToggleAction *action, GtkWidget *notebook)
40 {
41         const gchar *name = gtk_action_get_name(GTK_ACTION(action));
42         gboolean active = gtk_toggle_action_get_active(action);
43         if (active) {
44                 GisPlugin *plugin = gis_plugins_enable(plugins, name,
45                                 GIS_VIEWER(viewer), prefs);
46                 GtkWidget *config = gis_plugin_get_config(plugin);
47                 if (config) {
48                         gtk_notebook_append_page(GTK_NOTEBOOK(notebook), config,
49                                         gtk_label_new(name));
50                         gtk_widget_show_all(config);
51                 }
52         } else {
53                 gis_plugins_disable(plugins, name);
54                 guint n_pages = gtk_notebook_get_n_pages(GTK_NOTEBOOK(notebook));
55                 for (int i = 0; i < n_pages; i++) {
56                         GtkWidget *body = gtk_notebook_get_nth_page(GTK_NOTEBOOK(notebook), i);
57                         if (!body) continue;
58                         GtkWidget *tab = gtk_notebook_get_tab_label(GTK_NOTEBOOK(notebook), body);
59                         if (!tab) continue;
60                         const gchar *tab_name = gtk_label_get_text(GTK_LABEL(tab));
61                         if (tab_name && g_str_equal(name, tab_name))
62                                 gtk_notebook_remove_page(GTK_NOTEBOOK(notebook), i);
63                 }
64                 gtk_widget_queue_draw(GTK_WIDGET(viewer));
65         }
66 }
67
68
69 /******************
70  * Static UI Data *
71  ******************/
72 static const gchar menu_xml[] =
73         "<ui>"
74         "  <menubar name='Menu' >"
75         "    <menu name='File'          action='File' >"
76         "      <menuitem name='Offline' action='Offline' />"
77         "      <menuitem name='Quit'    action='Quit' />"
78         "    </menu>"
79         "    <menu name='Plugins'       action='Plugins' >"
80         "      <placeholder name='PluginsItems' />"
81         "    </menu>"
82         "  </menubar>"
83         "</ui>"
84 ;
85
86 static GtkActionEntry action_data[] =
87 {
88         /* name, stock id, label, accel, tooltip, callback */
89         {"File",    NULL, "_File"},
90         {"Plugins", NULL, "_Plugins"},
91         {"Quit", GTK_STOCK_QUIT, "_Quit", "q", NULL,
92                 G_CALLBACK(gtk_main_quit)},
93 };
94 static GtkToggleActionEntry toggle_action_data[] =
95 {
96         /* name, stock id, label, accel, tooltip, callback, is_active */
97         {"Offline", GTK_STOCK_DISCONNECT, "_Offline", NULL, NULL,
98                 G_CALLBACK(on_offline), FALSE},
99 };
100
101
102 /***********
103  * Helpers *
104  ***********/
105 static GtkUIManager *setup_actions()
106 {
107         GtkUIManager   *manager = gtk_ui_manager_new();
108         GtkActionGroup *actions = gtk_action_group_new("Actions");
109         gtk_action_group_add_actions(actions, action_data,
110                         G_N_ELEMENTS(action_data), NULL);
111         gtk_action_group_add_toggle_actions(actions, toggle_action_data,
112                         G_N_ELEMENTS(toggle_action_data), NULL);
113         gtk_ui_manager_insert_action_group(manager, actions, 0);
114         gtk_ui_manager_add_ui_from_string(manager, menu_xml, sizeof(menu_xml)-1, NULL);
115         return manager;
116 }
117
118 static GtkWidget *setup_window(GtkUIManager *manager, GtkWidget **_notebook)
119 {
120         GtkWidget *window   = gtk_window_new(GTK_WINDOW_TOPLEVEL);
121         GtkWidget *menu     = gtk_ui_manager_get_widget(manager, "/Menu");
122         GtkWidget *notebook = gtk_notebook_new();
123         GtkWidget *vbox     = gtk_vbox_new(FALSE, 0);
124         gtk_container_add(GTK_CONTAINER(window), vbox);
125         gtk_box_pack_start(GTK_BOX(vbox), menu,               FALSE, TRUE, 0);
126         gtk_box_pack_start(GTK_BOX(vbox), GTK_WIDGET(viewer), TRUE,  TRUE, 0);
127         gtk_box_pack_start(GTK_BOX(vbox), notebook,           FALSE, TRUE, 0);
128         g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit), NULL);
129         gtk_window_add_accel_group(GTK_WINDOW(window),
130                         gtk_ui_manager_get_accel_group(manager));
131         *_notebook = notebook;
132         return window;
133 }
134
135 static void setup_plugins(GtkUIManager *manager, GtkNotebook *notebook)
136 {
137         GtkActionGroup *actions = gtk_action_group_new("Plugins");
138         gtk_ui_manager_insert_action_group(manager, actions, 1);
139         guint merge_id = gtk_ui_manager_new_merge_id(manager);
140         for (GList *cur = gis_plugins_available(plugins); cur; cur = cur->next) {
141                 gchar *name = cur->data;
142                 GtkToggleAction *action = gtk_toggle_action_new(name, name, NULL, NULL);
143                 g_signal_connect(action, "toggled", G_CALLBACK(on_plugin), notebook);
144                 gtk_action_group_add_action(actions, GTK_ACTION(action));
145                 gtk_ui_manager_add_ui(manager, merge_id, "/Menu/Plugins", name, name,
146                                 GTK_UI_MANAGER_AUTO, TRUE);
147                 if (gis_prefs_get_boolean_v(prefs, "plugins", name, NULL))
148                         gtk_toggle_action_set_active(action, TRUE);
149         }
150 }
151
152 static void restore_states(GtkUIManager *manager)
153 {
154         GtkAction *action = gtk_ui_manager_get_action(manager, "/Menu/File/Offline");
155         gtk_toggle_action_set_active(GTK_TOGGLE_ACTION(action),
156                         gis_viewer_get_offline(viewer));
157         g_message("offline=%d", gis_viewer_get_offline(viewer));
158 }
159
160 int main(int argc, char **argv)
161 {
162         g_thread_init(NULL);
163         gdk_threads_init();
164         gtk_init(&argc, &argv);
165
166         prefs   = gis_prefs_new(NULL, NULL);
167         plugins = gis_plugins_new(g_getenv("GIS_PLUGIN_PATH"), prefs);
168         viewer  = gis_opengl_new(plugins, prefs);
169
170         gdk_threads_enter();
171
172         GtkWidget    *notebook = NULL;
173         GtkUIManager *manager  = setup_actions();
174         GtkWidget    *window   = setup_window(manager, &notebook);
175         setup_plugins(manager, GTK_NOTEBOOK(notebook));
176         restore_states(manager);
177         gtk_ui_manager_ensure_update(manager);
178         gtk_widget_show_all(window);
179
180         gtk_main();
181
182         gis_plugins_free(plugins);
183         g_object_unref(prefs);
184
185         gdk_threads_leave();
186
187         return 0;
188 }