1 /** \file drivemodelwidget.c
2 * \brief Drive model selection widget
3 *
4 * \author Bas Wassink <b.wassink@ziggo.nl>
5 */
6
7 /*
8 * $VICERES Drive8Type -vsid
9 * $VICERES Drive9Type -vsid
10 * $VICERES Drive10Type -vsid
11 * $VICERES Drive11Type -vsid
12 */
13
14 /*
15 * This file is part of VICE, the Versatile Commodore Emulator.
16 * See README for copyright notice.
17 *
18 * This program is free software; you can redistribute it and/or modify
19 * it under the terms of the GNU General Public License as published by
20 * the Free Software Foundation; either version 2 of the License, or
21 * (at your option) any later version.
22 *
23 * This program is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
26 * GNU General Public License for more details.
27 *
28 * You should have received a copy of the GNU General Public License
29 * along with this program; if not, write to the Free Software
30 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
31 * 02111-1307 USA.
32 *
33 */
34
35 #include "vice.h"
36
37 #include <gtk/gtk.h>
38
39 #include "widgethelpers.h"
40 #include "debug_gtk3.h"
41 #include "machine-drive.h"
42 #include "resources.h"
43 #include "drive.h"
44 #include "drive-check.h"
45 #include "driveparallelcablewidget.h"
46 #include "drivewidgethelpers.h"
47 #include "driveoptionswidget.h"
48
49 #include "drivemodelwidget.h"
50
51
52 /** \brief Handler for the "toggled" event of the radio buttons
53 *
54 * \param[in] widget radio button
55 * \param[in] user_data unit number
56 */
on_radio_toggled(GtkWidget * widget,gpointer user_data)57 static void on_radio_toggled(GtkWidget *widget, gpointer user_data)
58 {
59 if (gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget))) {
60 GtkWidget *parent;
61 int unit;
62 int new_type;
63 int old_type;
64
65 parent = gtk_widget_get_parent(widget);
66 unit = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(parent), "UnitNumber"));
67 new_type = GPOINTER_TO_INT(user_data);
68 old_type = ui_get_drive_type(unit);
69
70
71 /* prevent drive reset when switching unit number and updating the
72 * drive type widget */
73 if (new_type != old_type) {
74 void (*cb_func)(GtkWidget *, gpointer);
75 gpointer cb_data;
76
77 debug_gtk3("setting Drive%dType to %d.", unit, new_type);
78 resources_set_int_sprintf("Drive%dType", new_type, unit);
79
80 /* check for a custom callback */
81 parent = gtk_widget_get_parent(widget);
82 cb_func = g_object_get_data(G_OBJECT(parent), "CallbackFunc");
83 if (cb_func != NULL) {
84 /* get callback data */
85 cb_data = g_object_get_data(G_OBJECT(parent), "CallbackData");
86 /* trigger callback */
87 cb_func(widget, cb_data);
88 }
89
90 }
91
92 /* this should be handled by signal handlers in uidrivesettings.c now */
93 #if 0
94 /* enable/disable 40-track settings widget */
95 if (drive_extend_widget != NULL) {
96 tgtk_widget_set_sensitive(drive_extend_widget,
97 drive_check_extend_policy(new_type));
98 }
99 /* update expansions widget */
100 if (drive_expansion_widget != NULL) {
101 drive_expansion_widget_update(drive_expansion_widget, unit_number);
102 }
103 /* update parallel cable widget */
104 if (drive_parallel_cable_widget != NULL) {
105 drive_parallel_cable_widget_update(drive_parallel_cable_widget,
106 unit_number);
107 }
108 if (drive_options_widget != NULL) {
109 drive_options_widget_update(drive_options_widget, unit_number);
110 }
111 #endif
112 }
113 }
114
115
116 /** \brief Create a drive unit selection widget
117 *
118 * Creates a widget with four radio buttons, horizontally aligned, to select
119 * a drive unit (8-11)
120 *
121 * \param[in] unit default drive unit
122 *
123 * \return GtkGrid
124 */
drive_model_widget_create(int unit)125 GtkWidget *drive_model_widget_create(int unit)
126 {
127 GtkWidget *grid;
128 drive_type_info_t *list;
129 GtkRadioButton *last = NULL;
130 GSList *group = NULL;
131 size_t i;
132 int type;
133 int num;
134 int row;
135
136 resources_get_int_sprintf("Drive%dType", &type, unit);
137
138 grid = uihelpers_create_grid_with_label("Drive type", 2);
139 /* store unit number as a property in the widget */
140 g_object_set_data(G_OBJECT(grid), "UnitNumber", GINT_TO_POINTER(unit));
141
142 list = machine_drive_get_type_info_list();
143 for (i = 0; list[i].name != NULL; i++) {
144 /* NOP */
145 }
146 num = i;
147
148 for (i = 0; list[i].name != NULL && i < num / 2; i++) {
149 GtkWidget *radio = gtk_radio_button_new_with_label(group, list[i].name);
150 gtk_radio_button_join_group(GTK_RADIO_BUTTON(radio), last);
151 g_object_set(radio, "margin-left", 16, NULL);
152 g_object_set_data(G_OBJECT(radio), "ModelID",
153 GINT_TO_POINTER(list[i].id));
154
155 if (list[i].id == type) {
156 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE);
157 }
158
159 g_signal_connect(radio, "toggled", G_CALLBACK(on_radio_toggled),
160 GINT_TO_POINTER(list[i].id));
161
162 gtk_grid_attach(GTK_GRID(grid), radio, 0, i + 1, 1, 1);
163 last = GTK_RADIO_BUTTON(radio);
164 }
165
166 row = 1;
167 while (list[i].name != NULL) {
168 GtkWidget *radio = gtk_radio_button_new_with_label(group, list[i].name);
169 gtk_radio_button_join_group(GTK_RADIO_BUTTON(radio), last);
170 g_object_set(radio, "margin-left", 16, NULL);
171 g_object_set_data(G_OBJECT(radio), "ModelID",
172 GINT_TO_POINTER(list[i].id));
173 if (list[i].id == type) {
174 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE);
175 }
176
177 g_signal_connect(radio, "toggled", G_CALLBACK(on_radio_toggled),
178 GINT_TO_POINTER(list[i].id));
179
180 gtk_grid_attach(GTK_GRID(grid), radio, 1, row, 1, 1);
181 row++;
182 last = GTK_RADIO_BUTTON(radio);
183 i++;
184 }
185
186 drive_model_widget_update(grid);
187
188 gtk_widget_show_all(grid);
189 return grid;
190 }
191
192
193 /** \brief Update the drive type widget
194 *
195 * This reiterates the drive info list to see if any setting changes made drive
196 * types available/unavailable.
197 *
198 * \param[in,out] widget drive type widget
199 * \param[in] unit new unit number
200 */
drive_model_widget_update(GtkWidget * widget)201 void drive_model_widget_update(GtkWidget *widget)
202 {
203 drive_type_info_t *list;
204 size_t i;
205 int unit;
206 int type;
207 int num;
208 int row;
209
210 unit = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(widget), "UnitNumber"));
211 type = ui_get_drive_type(unit);
212
213 list = machine_drive_get_type_info_list();
214 debug_gtk3("updating drive type list.");
215
216 for (i = 0; list[i].name != NULL; i++) {
217 /* NOP */
218 }
219 num = i;
220
221
222 for (i = 0; list[i].name != NULL && i < num / 2; i++) {
223
224 GtkWidget *radio = gtk_grid_get_child_at(GTK_GRID(widget), 0, i + 1);
225 if (radio != NULL && GTK_IS_RADIO_BUTTON(radio)) {
226 debug_gtk3("row 0: checking drive ID %d", list[i].id);
227 gtk_widget_set_sensitive(radio, drive_check_type(
228 (unsigned int)(list[i].id), (unsigned int)(unit - 8)));
229 if (list[i].id == type) {
230 /* TODO: temporary block the resource-set callback */
231 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE);
232 }
233 }
234 }
235
236 row = 1;
237 while (list[i].name != NULL) {
238 GtkWidget *radio = gtk_grid_get_child_at(GTK_GRID(widget), 1, row);
239 if (radio != NULL && GTK_IS_RADIO_BUTTON(radio)) {
240 debug_gtk3("row 1: checking drive ID %d", list[i].id);
241 gtk_widget_set_sensitive(radio, drive_check_type(
242 (unsigned int)(list[i].id),
243 (unsigned int)(unit - 8)));
244 if (list[i].id == type) {
245 /* TODO: temporary block the resource-set callback */
246 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(radio), TRUE);
247 }
248 }
249 row++;
250 i++;
251 }
252 }
253
254
drive_model_widget_add_callback(GtkWidget * widget,void (* cb_func)(GtkWidget *,gpointer),gpointer cb_data)255 void drive_model_widget_add_callback(GtkWidget *widget,
256 void (*cb_func)(GtkWidget *, gpointer),
257 gpointer cb_data)
258 {
259 g_object_set_data(G_OBJECT(widget), "CallbackFunc", (gpointer)cb_func);
260 g_object_set_data(G_OBJECT(widget), "CallbackData", cb_data);
261 }
262