@@ -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