1 /*
2 * Copyright (C) 2019-2021 Alexandros Theodotou <alex at zrythm dot org>
3 *
4 * This file is part of Zrythm
5 *
6 * Zrythm is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Zrythm is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 #include "actions/arranger_selections.h"
21 #include "audio/quantize_options.h"
22 #include "gui/widgets/bar_slider.h"
23 #include "gui/widgets/digital_meter.h"
24 #include "gui/widgets/dialogs/quantize_dialog.h"
25 #include "project.h"
26 #include "utils/error.h"
27 #include "utils/io.h"
28 #include "utils/resources.h"
29 #include "zrythm_app.h"
30
31 #include <gtk/gtk.h>
32 #include <glib/gi18n.h>
33
G_DEFINE_TYPE(QuantizeDialogWidget,quantize_dialog_widget,GTK_TYPE_DIALOG)34 G_DEFINE_TYPE (
35 QuantizeDialogWidget,
36 quantize_dialog_widget,
37 GTK_TYPE_DIALOG)
38
39 static void
40 on_adjust_end_toggled (
41 GtkToggleButton * toggle,
42 QuantizeDialogWidget * self)
43 {
44 self->opts->adj_end =
45 gtk_toggle_button_get_active (toggle);
46 }
47
48 static void
on_adjust_start_toggled(GtkToggleButton * toggle,QuantizeDialogWidget * self)49 on_adjust_start_toggled (
50 GtkToggleButton * toggle,
51 QuantizeDialogWidget * self)
52 {
53 self->opts->adj_start =
54 gtk_toggle_button_get_active (toggle);
55 }
56
57 static void
on_cancel_clicked(GtkButton * btn,QuantizeDialogWidget * self)58 on_cancel_clicked (
59 GtkButton * btn,
60 QuantizeDialogWidget * self)
61 {
62 gtk_window_close (GTK_WINDOW (self));
63 }
64
65 static void
on_quantize_clicked(GtkButton * btn,QuantizeDialogWidget * self)66 on_quantize_clicked (
67 GtkButton * btn,
68 QuantizeDialogWidget * self)
69 {
70 if (QUANTIZE_OPTIONS_IS_EDITOR (self->opts))
71 {
72 ArrangerSelections * sel =
73 clip_editor_get_arranger_selections (
74 CLIP_EDITOR);
75 g_return_if_fail (sel);
76
77 GError * err = NULL;
78 bool ret =
79 arranger_selections_action_perform_quantize (
80 sel, self->opts, &err);
81 if (!ret)
82 {
83 HANDLE_ERROR (
84 err, "%s",
85 _("Failed to quantize editor "
86 "selections"));
87 }
88 }
89 else if (QUANTIZE_OPTIONS_IS_TIMELINE (self->opts))
90 {
91 GError * err = NULL;
92 bool ret =
93 arranger_selections_action_perform_quantize (
94 (ArrangerSelections *) TL_SELECTIONS,
95 self->opts, &err);
96 if (!ret)
97 {
98 HANDLE_ERROR (
99 err, "%s",
100 _("Failed to quantize timeline "
101 "selections"));
102 }
103 }
104 }
105
106 /**
107 * Creates a new quantize dialog.
108 */
109 QuantizeDialogWidget *
quantize_dialog_widget_new(QuantizeOptions * opts)110 quantize_dialog_widget_new (
111 QuantizeOptions * opts)
112 {
113 QuantizeDialogWidget * self =
114 g_object_new (QUANTIZE_DIALOG_WIDGET_TYPE, NULL);
115
116 self->opts = opts;
117
118 gtk_toggle_button_set_active (
119 self->adjust_start, opts->adj_start);
120 gtk_toggle_button_set_active (
121 self->adjust_end, opts->adj_end);
122
123 g_signal_connect (
124 G_OBJECT (self->adjust_start), "toggled",
125 G_CALLBACK (on_adjust_start_toggled), self);
126 g_signal_connect (
127 G_OBJECT (self->adjust_end), "toggled",
128 G_CALLBACK (on_adjust_end_toggled), self);
129
130 self->note_length =
131 digital_meter_widget_new (
132 DIGITAL_METER_TYPE_NOTE_LENGTH,
133 &opts->note_length,
134 &opts->note_type,
135 _("note length"));
136 gtk_container_add (
137 GTK_CONTAINER (self->note_length_box),
138 GTK_WIDGET (self->note_length));
139 self->note_type =
140 digital_meter_widget_new (
141 DIGITAL_METER_TYPE_NOTE_TYPE,
142 &opts->note_length,
143 &opts->note_type,
144 _("note type"));
145 gtk_container_add (
146 GTK_CONTAINER (self->note_type_box),
147 GTK_WIDGET (self->note_type));
148
149 int w = 100, h = -1;
150 self->amount =
151 bar_slider_widget_new (
152 quantize_options_get_amount,
153 quantize_options_set_amount,
154 opts, 0, 100, w, h, 0, 0,
155 UI_DRAG_MODE_CURSOR, "%");
156 gtk_container_add (
157 GTK_CONTAINER (self->amount_box),
158 GTK_WIDGET (self->amount));
159 self->swing =
160 bar_slider_widget_new (
161 quantize_options_get_swing,
162 quantize_options_set_swing,
163 opts, 0, 100, w, h, 0, 0,
164 UI_DRAG_MODE_CURSOR, "%");
165 gtk_container_add (
166 GTK_CONTAINER (self->swing_box),
167 GTK_WIDGET (self->swing));
168 self->randomization =
169 bar_slider_widget_new (
170 quantize_options_get_randomization,
171 quantize_options_set_randomization,
172 opts, 0.f, 100.f, w, h, 0, 0,
173 UI_DRAG_MODE_CURSOR, " ticks");
174 gtk_container_add (
175 GTK_CONTAINER (self->randomization_box),
176 GTK_WIDGET (self->randomization));
177
178 return self;
179 }
180
181 static void
quantize_dialog_widget_class_init(QuantizeDialogWidgetClass * _klass)182 quantize_dialog_widget_class_init (
183 QuantizeDialogWidgetClass * _klass)
184 {
185 GtkWidgetClass * klass = GTK_WIDGET_CLASS (_klass);
186 resources_set_class_template (
187 klass, "quantize_dialog.ui");
188
189 #define BIND_CHILD(x) \
190 gtk_widget_class_bind_template_child ( \
191 klass, \
192 QuantizeDialogWidget, \
193 x)
194
195 BIND_CHILD (cancel_btn);
196 BIND_CHILD (quantize_btn);
197 BIND_CHILD (adjust_start);
198 BIND_CHILD (adjust_end);
199 BIND_CHILD (note_length_box);
200 BIND_CHILD (note_type_box);
201 BIND_CHILD (amount_box);
202 BIND_CHILD (swing_box);
203 BIND_CHILD (randomization_box);
204
205 gtk_widget_class_bind_template_callback (
206 klass,
207 on_cancel_clicked);
208 gtk_widget_class_bind_template_callback (
209 klass,
210 on_quantize_clicked);
211 }
212
213 static void
quantize_dialog_widget_init(QuantizeDialogWidget * self)214 quantize_dialog_widget_init (
215 QuantizeDialogWidget * self)
216 {
217 gtk_widget_init_template (GTK_WIDGET (self));
218 }
219