Skip to content

Commit e792346

Browse files
committed
Added tabs
1 parent ade3503 commit e792346

File tree

4 files changed

+347
-189
lines changed

4 files changed

+347
-189
lines changed

gui-helper-gtk.c

Lines changed: 143 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,10 @@ int ShowMessageBox(const char* title, const char* message)
1515
);
1616
gtk_window_set_title(GTK_WINDOW(dialog), title);
1717

18-
g_signal_connect_swapped (
18+
g_signal_connect_swapped(
1919
dialog,
2020
"response",
21-
G_CALLBACK (gtk_widget_destroy),
21+
G_CALLBACK(gtk_widget_destroy),
2222
dialog
2323
);
2424

@@ -30,120 +30,197 @@ enum {
3030
COLUMN_INDEX = 1,
3131
};
3232

33-
static void button_callback(GtkWidget *widget, gpointer *data)
33+
typedef struct {
34+
GtkWidget* treeview;
35+
int selection;
36+
int selected_index;
37+
int tab_index;
38+
} TabData;
39+
40+
typedef struct {
41+
TabData* tab1;
42+
TabData* tab2;
43+
} TabsContext;
44+
45+
static void button_callback(gpointer data)
3446
{
35-
GtkWidget* treeview = (GtkWidget*)data;
47+
TabData* tab_data = (TabData*)data;
48+
GtkWidget* treeview = tab_data->treeview;
3649

3750
GtkTreeSelection* selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
38-
39-
GtkTreeModel *model;
51+
GtkTreeModel* model;
4052
GtkTreeIter iter;
4153
if (gtk_tree_selection_get_selected(selection, &model, &iter))
4254
{
43-
int* selected_index = g_object_get_data(G_OBJECT(treeview), "selected_index");
44-
gtk_tree_model_get (model, &iter, COLUMN_INDEX, selected_index, -1);
55+
gtk_tree_model_get(model, &iter, COLUMN_INDEX, &tab_data->selected_index, -1);
4556
gtk_main_quit();
4657
}
4758
}
4859

49-
int SelectionDialog(const char* title, int count, const char** list, int selection)
60+
static void on_tab_switch(GtkNotebook* notebook, GtkWidget* page, guint page_num, gpointer user_data)
5061
{
51-
gtk_init(NULL, NULL);
52-
53-
int selected_index = -1;
54-
55-
// Setup a stylesheet to match the original UI
56-
const char* stylesheet = " \
57-
#box { \
58-
padding: 10px; \
59-
} \
60-
";
62+
TabsContext* ctx = (TabsContext*)user_data;
63+
GtkButton* btn = GTK_BUTTON(g_object_get_data(G_OBJECT(notebook), "ok_button"));
6164

62-
GtkCssProvider* provider = gtk_css_provider_new();
63-
gtk_css_provider_load_from_data(provider, stylesheet, -1, NULL);
64-
65-
GdkDisplay* display = gdk_display_get_default();
66-
GdkScreen* screen = gdk_display_get_default_screen(display);
67-
gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_USER);
65+
if (page_num == 0)
66+
{
67+
g_object_set_data(G_OBJECT(btn), "tabdata", ctx->tab1);
68+
}
69+
else
70+
{
71+
g_object_set_data(G_OBJECT(btn), "tabdata", ctx->tab2);
72+
}
73+
}
6874

69-
// Put list into a GtkListStore
70-
GtkListStore *store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_INT);
75+
static void on_ok_button_clicked(GtkButton* button, gpointer user_data)
76+
{
77+
TabData* data = (TabData*)g_object_get_data(G_OBJECT(button), "tabdata");
78+
button_callback(data);
79+
}
7180

81+
GtkWidget* create_treeview(const char** items, int count, int initial_selection, int* selected_index)
82+
{
83+
GtkListStore* store = gtk_list_store_new(
84+
2, // 2 tabs
85+
G_TYPE_STRING,
86+
G_TYPE_INT
87+
);
7288
GtkTreeIter iter;
7389
for (int i = 0; i < count; ++i) {
7490
gtk_list_store_append(store, &iter);
75-
gtk_list_store_set(store, &iter,
76-
COLUMN_ITEM, list[i],
77-
COLUMN_INDEX, i,
78-
-1);
91+
gtk_list_store_set(store, &iter, COLUMN_ITEM, items[i], COLUMN_INDEX, i, -1);
7992
}
8093

81-
// Dervice a TreeView from the ListStore
82-
GtkWidget *treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
94+
GtkWidget* treeview = gtk_tree_view_new_with_model(GTK_TREE_MODEL(store));
8395
// Attached the selected index to the treeview so we can easily reference it in the button callback
8496
g_object_set_data(G_OBJECT(treeview), "selected_index", &selected_index);
8597
gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(treeview), FALSE);
8698

87-
// Change selection mode to single and set the current selected option if needed
88-
{
89-
GtkTreeSelection* treeselection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
90-
gtk_tree_selection_set_mode(treeselection, GTK_SELECTION_SINGLE);
99+
GtkTreeSelection* treeselection = gtk_tree_view_get_selection(GTK_TREE_VIEW(treeview));
100+
gtk_tree_selection_set_mode(treeselection, GTK_SELECTION_SINGLE);
91101

92-
if (selection < count && selection >= 0) {
93-
GtkTreePath *path = gtk_tree_path_new_from_indices(selection, -1);
94-
gtk_tree_selection_select_path(treeselection, path);
95-
gtk_tree_path_free(path);
96-
}
102+
if (initial_selection < count && initial_selection >= 0) {
103+
GtkTreePath* path = gtk_tree_path_new_from_indices(initial_selection, -1);
104+
gtk_tree_selection_select_path(treeselection, path);
105+
gtk_tree_path_free(path);
97106
}
98107

99-
// Define TreeView Cell Layout in the UI
100-
{
101-
GtkCellRenderer* renderer = gtk_cell_renderer_text_new ();
102-
gtk_tree_view_insert_column_with_attributes (
103-
GTK_TREE_VIEW(treeview),
104-
-1,
105-
"",
106-
renderer,
107-
"text", COLUMN_ITEM,
108-
NULL
109-
);
110-
}
108+
GtkCellRenderer* renderer = gtk_cell_renderer_text_new();
109+
gtk_tree_view_insert_column_with_attributes(
110+
GTK_TREE_VIEW(treeview),
111+
-1,
112+
"",
113+
renderer,
114+
"text",
115+
COLUMN_ITEM,
116+
NULL
117+
);
111118

112-
// Put the TreeView into a ScrolledWindow
113-
GtkWidget* scrollable = gtk_scrolled_window_new(NULL, NULL);
114-
gtk_container_add(GTK_CONTAINER(scrollable), treeview);
119+
return treeview;
120+
}
115121

116-
// Put a nice frame around the window to match the original
117-
GtkWidget* frame = gtk_frame_new(NULL);
118-
gtk_container_add(GTK_CONTAINER(frame), scrollable);
122+
int SelectionDialog(const char* title, int count, const char** list, int modsCount, const char** modsList, int selection)
123+
{
124+
gtk_init(NULL, NULL);
125+
int selected_index = -1;
126+
127+
// Stylesheet
128+
const char* stylesheet = "#box { padding: 10px; }";
129+
GtkCssProvider* provider = gtk_css_provider_new();
130+
gtk_css_provider_load_from_data(provider, stylesheet, -1, NULL);
131+
GdkDisplay* display = gdk_display_get_default();
132+
GdkScreen* screen = gdk_display_get_default_screen(display);
133+
gtk_style_context_add_provider_for_screen(screen, GTK_STYLE_PROVIDER(provider), GTK_STYLE_PROVIDER_PRIORITY_USER);
119134

135+
// Setup main window
120136
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
121137
gtk_window_set_title(GTK_WINDOW(window), title);
122138
gtk_window_set_default_size(GTK_WINDOW(window), 454, 388);
123-
g_signal_connect(G_OBJECT(window), "destroy", gtk_main_quit, NULL);
139+
g_signal_connect(window, "destroy", gtk_main_quit, NULL);
124140

125141
GtkWidget* box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 10);
126142
gtk_widget_set_name(box, "box");
127143
gtk_container_add(GTK_CONTAINER(window), box);
128-
gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 0);
129144

145+
// Tabs via GtkNotebook
146+
GtkWidget* notebook = gtk_notebook_new();
147+
gtk_box_pack_start(GTK_BOX(box), notebook, TRUE, TRUE, 0);
148+
149+
int selectionTab = 0;
150+
if (selection >= count) {
151+
selectionTab = 1;
152+
selection -= count;
153+
}
154+
155+
// Non-Steam apps tab
156+
TabData* nonsteam_data = g_new0(TabData, 1);
157+
nonsteam_data->tab_index = 0;
158+
nonsteam_data->treeview = create_treeview(list, count, selection, &nonsteam_data->selected_index);
159+
160+
GtkWidget* scroll1 = gtk_scrolled_window_new(NULL, NULL);
161+
gtk_container_add(GTK_CONTAINER(scroll1), nonsteam_data->treeview);
162+
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scroll1, gtk_label_new("Non-Steam"));
163+
164+
// Mods tab
165+
TabData* mods_data = g_new0(TabData, 1);
166+
mods_data->tab_index = 1;
167+
mods_data->treeview = create_treeview(modsList, modsCount, selection, &mods_data->selected_index);
168+
169+
GtkWidget* scroll2 = gtk_scrolled_window_new(NULL, NULL);
170+
gtk_container_add(GTK_CONTAINER(scroll2), mods_data->treeview);
171+
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), scroll2, gtk_label_new("GoldSrc/Source Mods"));
172+
173+
TabsContext* context = g_malloc(sizeof(TabsContext));
174+
context->tab1 = nonsteam_data;
175+
context->tab2 = mods_data;
176+
//context->tab3 = steam_data;
177+
178+
// Button contianer
130179
GtkWidget* buttons = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 5);
131180
gtk_box_pack_end(GTK_BOX(box), buttons, FALSE, FALSE, 0);
132181
gtk_widget_set_halign(buttons, GTK_ALIGN_END);
133182
gtk_widget_set_valign(buttons, GTK_ALIGN_START);
134183

184+
// COnfirm button
135185
GtkWidget* ok_button = gtk_button_new_with_label("OK");
136186
gtk_widget_set_size_request(ok_button, 75, 40);
137-
g_signal_connect(G_OBJECT(ok_button), "clicked", G_CALLBACK(button_callback), treeview);
138187
gtk_container_add(GTK_CONTAINER(buttons), ok_button);
188+
g_object_set_data(G_OBJECT(notebook), "ok_button", ok_button);
139189

190+
// Cancel button
140191
GtkWidget* cancel_button = gtk_button_new_with_label("Cancel");
141192
gtk_widget_set_size_request(cancel_button, 75, 40);
142-
g_signal_connect(G_OBJECT(cancel_button), "clicked", gtk_main_quit, NULL);
193+
g_signal_connect(cancel_button, "clicked", gtk_main_quit, NULL);
143194
gtk_container_add(GTK_CONTAINER(buttons), cancel_button);
144195

196+
// Switch callback to update which tab is active
197+
g_signal_connect(notebook, "switch-page", G_CALLBACK(on_tab_switch), context);
198+
199+
// Update button callback to extract correct data
200+
g_signal_connect(ok_button, "clicked", G_CALLBACK(on_ok_button_clicked), NULL);
201+
145202
gtk_widget_show_all(window);
203+
204+
// initial tab data
205+
if (selectionTab == 0) {
206+
gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 0);
207+
g_object_set_data(G_OBJECT(ok_button), "tabdata", context->tab1);
208+
}
209+
else {
210+
gtk_notebook_set_current_page(GTK_NOTEBOOK(notebook), 1);
211+
g_object_set_data(G_OBJECT(ok_button), "tabdata", context->tab2);
212+
}
213+
146214
gtk_main();
147215

148-
return selected_index;
149-
}
216+
// Clean up and return
217+
TabData* final_tabdata = (TabData*)g_object_get_data(G_OBJECT(ok_button), "tabdata");
218+
int final_selection = final_tabdata->selected_index;
219+
g_free(nonsteam_data);
220+
g_free(mods_data);
221+
222+
if (final_tabdata->tab_index > 0) {
223+
final_selection += count;
224+
}
225+
return final_selection;
226+
}

0 commit comments

Comments
 (0)