1
/* c-basic-offset: 2; tab-width: 2; indent-tabs-mode: nil
2
* vi: set shiftwidth=2 tabstop=2 expandtab:
3
* :indentSize=2:tabSize=2:noTabs=true:
7
#include "GPumpSettings.h"
8
#include "GPumpSettingsData.h"
10
#define GPUMP_APP_GET_PRIVATE(obj)\
11
(G_TYPE_INSTANCE_GET_PRIVATE ((obj), GPUMP_TYPE_APP, GPumpAppPrivate))
13
G_DEFINE_TYPE (GPumpApp, gpump_app, GTK_TYPE_APPLICATION)
15
struct GPumpAppPrivate {
19
GtkWidget * header_bar;
20
GtkWidget * layout; /* GtkBox */
21
GtkWidget * scroll_view; /* GtkScrolledWindow */
22
GtkWidget * post_list_box; /* GtkListBox */
23
GtkWidget * btn_gear; /* GtkMenuButton */
24
GtkWidget * btn_new_post;
25
GtkWidget * btn_refresh;
28
GtkWidget * gear_menu; /* GtkMenu */
31
GtkListStore * post_list_store;
33
/* hold a reference to the settings for propper dispotiour */
34
GPumpSettingsData * settings;
38
GPUPM_APP_MAIN_LIST_COL = 0,
39
GPUMP_APP_MAIN_LIST_NUM_COL
44
/* * Callback and private function declarations *******************************/
45
void gpump_app_class_init (GPumpAppClass * klass);
46
void gpump_app_activate (GApplication * application);
47
void gpump_app_init (GPumpApp * self);
48
void gpump_app_dispose (GObject * object);
50
void _prepere_window (GPumpApp * self);
51
void _prepere_gear_menu (GPumpApp * self);
52
void _prepere_new_post_button (GPumpApp * self);
53
void _prepere_refresh_button (GPumpApp * self);
54
void _prepere_app_menu (GPumpApp * self);
56
void _cb_show_settings (GSimpleAction * action, GVariant * parameter,
58
void _cb_do_nothing (GSimpleAction * action, GVariant * parameter,
60
void _cb_quit (GSimpleAction * action, GVariant * parameter,
63
/* * Class functions **********************************************************/
64
GPumpApp * gpump_app_new (void) {
65
GPumpApp * self = g_object_new (GPUMP_TYPE_APP,
66
"application-id", "org.gego.gpump",
67
"flags",G_APPLICATION_FLAGS_NONE,
72
void gpump_app_init (GPumpApp * self) {
75
self->priv = GPUMP_APP_GET_PRIVATE (self);
77
/* We have to keep an instance of GPumpSettigsData alive
78
* It is later freed in *_dispose ()
80
* Keep in mind that when ever an instance of GPumpSettingsData is
81
* gotten it _will_ run g_object_ref () on it, meaning that it has to be
84
* When the GPumpApp is disposed of the last reference should be freed.
86
self->priv->settings = gpump_settings_data_get_default ();
89
void gpump_app_class_init (GPumpAppClass * klass) {
90
g_print("GPumpApp class init.\n");
92
g_type_class_add_private (klass, sizeof(GPumpAppPrivate));
94
GApplicationClass * application_class = G_APPLICATION_CLASS (klass);
96
application_class->activate = gpump_app_activate;
98
GObjectClass * object_class = G_OBJECT_CLASS (application_class);
99
object_class->dispose = gpump_app_dispose;
101
g_print ("GPumpApp class init done.\n");
104
void gpump_app_dispose (GObject * object) {
105
g_print ("Disponsing of Application...\n");
107
GPumpApp * self = GPUMP_APP (object);
109
/* Dispose of the widgets... */
111
/* Dispose of the GPumpSettingsData object */
112
g_object_unref (self->priv->settings);
114
if (self->priv->settings) {
115
g_print ("there was a dangling reference to GPumpSettingsData somewhare,"
116
"pleace check that all \"*_get_default_instance ()\" calles have"
117
"an g_object_unref () at the end of the scope!\n");
120
G_OBJECT_CLASS (gpump_app_parent_class)->dispose (object);
123
void gpump_app_activate (GApplication * application) {
124
g_print ("GPumpApp activate.\n");
126
/* Check for uniques of window */
127
GList * w_list = gtk_application_get_windows (GTK_APPLICATION(application));
129
gtk_window_present (GTK_WINDOW (w_list->data));
133
g_list_free (w_list);
136
_prepere_window (GPUMP_APP (application));
137
_prepere_gear_menu (GPUMP_APP (application));
138
_prepere_app_menu (GPUMP_APP (application));
139
_prepere_new_post_button (GPUMP_APP (application));
140
_prepere_refresh_button (GPUMP_APP (application));
142
/* Init the settings object */
145
gtk_widget_show_all (GTK_WIDGET(GPUMP_APP(application)->priv->window));
148
g_print ("done GPumpApp activate.\n");
151
void _prepere_window (GPumpApp * self) {
152
GPumpAppPrivate * priv = self->priv;
153
GtkWidget * window = priv->window =
154
gtk_application_window_new (GTK_APPLICATION (self));
155
GtkWidget * header_bar = priv->header_bar = gtk_header_bar_new ();
156
GtkWidget * layout = priv->layout =
157
gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 3);
159
gtk_header_bar_set_title (GTK_HEADER_BAR (header_bar), "GPump");
160
gtk_header_bar_set_subtitle (GTK_HEADER_BAR (header_bar),
161
_("A Pump.io Client"));
162
gtk_header_bar_set_show_close_button (GTK_HEADER_BAR (header_bar), TRUE);
164
GtkWidget * scroll = priv->post_list_box =
165
gtk_scrolled_window_new (NULL, NULL);
167
gtk_scrolled_window_set_policy (GTK_SCROLLED_WINDOW (scroll),
168
GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
170
GtkWidget * post_list_box = priv->post_list_box =
173
gtk_container_add (GTK_CONTAINER(scroll), post_list_box);
175
gtk_window_set_titlebar (GTK_WINDOW (window), header_bar);
176
gtk_window_set_default_size (GTK_WINDOW(window), 500,500);
178
gtk_box_pack_start (GTK_BOX (layout), scroll, TRUE, TRUE, 1);
180
gtk_container_add (GTK_CONTAINER (window), layout);
182
/* Hide window instead of destroying it */
183
g_signal_connect (G_OBJECT (window), "delete_event" ,
184
G_CALLBACK (gtk_widget_hide_on_delete), self);
187
void _prepere_app_menu (GPumpApp * self) {
188
/* App menu actions */
189
const GActionEntry _app_actions[] = {
190
{"settings", _cb_show_settings},
191
{"about", _cb_do_nothing},
195
/* Map actions to application ... I do not know... :-S */
196
g_action_map_add_action_entries (G_ACTION_MAP (self), _app_actions,
197
G_N_ELEMENTS(_app_actions), GTK_APPLICATION(self));
199
GMenu * menu = g_menu_new ();
201
g_menu_append (menu, _("Settings"), "app.settings");
202
g_menu_append (menu, _("About"), "app.about");
203
g_menu_append (menu, _("Quit"), "app.quit");
205
gtk_application_set_app_menu (GTK_APPLICATION (self), G_MENU_MODEL (menu));
206
g_object_unref (menu);
209
void _prepere_gear_menu (GPumpApp * self) {
210
GPumpAppPrivate * priv = self->priv;
212
/* Create menu and menu items. */
213
priv->gear_menu = gtk_menu_new();
214
GtkWidget * mi_profiles = gtk_menu_item_new_with_label (_("Profiles"));
217
/* Add items to menu. */
218
gtk_container_add (GTK_CONTAINER (priv->gear_menu), mi_profiles);
220
/* I have no idea why we need to run these, it seems trange, this
221
* should be handled by the caller of gtk_
223
gtk_widget_show (GTK_WIDGET(mi_profiles));
225
/* Hook up signals. */
227
g_signal_connect (G_OBJECT (mi_profiles), "activate",
231
/* create and attatch the gear menu button */
232
priv->btn_gear = gtk_menu_button_new ();
233
gtk_menu_button_set_popup (GTK_MENU_BUTTON (priv->btn_gear),
234
GTK_WIDGET(priv->gear_menu));
235
gtk_header_bar_pack_end (GTK_HEADER_BAR (priv->header_bar), priv->btn_gear);
238
GtkWidget * gear_icon = gtk_image_new_from_icon_name(
239
"emblem-system-symbolic", GTK_ICON_SIZE_LARGE_TOOLBAR);
240
gtk_button_set_image (GTK_BUTTON (priv->btn_gear), gear_icon);
242
gtk_widget_set_tooltip_text (GTK_WIDGET (priv->btn_gear), _("GPump gear menu"));
245
void _prepere_new_post_button (GPumpApp * self) {
246
GPumpAppPrivate * priv = self->priv;
248
GtkWidget * share_icon = gtk_image_new_from_icon_name ("text-editor-symbolic",
249
GTK_ICON_SIZE_LARGE_TOOLBAR);
250
priv->btn_new_post = gtk_button_new ();
251
gtk_button_set_image (GTK_BUTTON (priv->btn_new_post), share_icon);
253
gtk_header_bar_pack_start (GTK_HEADER_BAR (priv->header_bar),
255
gtk_widget_set_tooltip_text (GTK_WIDGET (priv->btn_new_post),
256
_("Create new post"));
259
void _prepere_refresh_button (GPumpApp * self) {
260
GPumpAppPrivate * priv = self->priv;
261
GtkWidget * refresh_icon = gtk_image_new_from_icon_name
262
("emblem-synchronizing-symbolic", GTK_ICON_SIZE_LARGE_TOOLBAR);
263
priv->btn_refresh = gtk_button_new ();
264
gtk_button_set_image (GTK_BUTTON (priv->btn_refresh), refresh_icon);
265
gtk_header_bar_pack_start (GTK_HEADER_BAR(priv->header_bar),
267
gtk_widget_set_tooltip_text (GTK_WIDGET (priv->btn_refresh),
268
_("Refresh the stream"));
271
/* * Callback implemenations **************************************************/
272
void _cb_show_settings (GSimpleAction * action, GVariant * parameter,
273
gpointer user_data) {
274
GPumpApp * self = GPUMP_APP (user_data);
275
GPumpSettings * settings = gpump_settings_new (self->priv->window);
276
gpump_settings_show (settings);
279
void _cb_do_nothing (GSimpleAction * action, GVariant * parameter,
280
gpointer user_data) {}
282
void _cb_quit (GSimpleAction * action, GVariant * parameter,
283
gpointer user_data) {
284
g_application_quit (G_APPLICATION(user_data));