1 /*
2  * Copyright (C) 2020 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/port_action.h"
21 #include "audio/control_port.h"
22 #include "audio/port.h"
23 #include "audio/router.h"
24 #include "gui/backend/event.h"
25 #include "gui/backend/event_manager.h"
26 #include "project.h"
27 #include "utils/flags.h"
28 #include "utils/objects.h"
29 #include "zrythm_app.h"
30 
31 #include <glib/gi18n.h>
32 
33 void
port_action_init_loaded(PortAction * self)34 port_action_init_loaded (
35   PortAction * self)
36 {
37   /* no need */
38 }
39 
40 /**
41  * Create a new action.
42  */
43 UndoableAction *
port_action_new(PortActionType type,PortIdentifier * port_id,float val,bool is_normalized,GError ** error)44 port_action_new (
45   PortActionType   type,
46   PortIdentifier * port_id,
47   float            val,
48   bool             is_normalized,
49   GError **        error)
50 {
51   PortAction * self =
52     object_new (PortAction);
53   UndoableAction * ua = (UndoableAction *) self;
54   undoable_action_init (ua, UA_PORT);
55 
56   self->port_id = *port_id;
57   self->type = type;
58   if (is_normalized)
59     {
60       Port * port =
61         port_find_from_identifier (port_id);
62       self->val =
63         control_port_normalized_val_to_real (
64           port, val);
65     }
66   else
67     {
68       self->val = val;
69     }
70 
71   return ua;
72 }
73 
74 /**
75  * Create a new action.
76  */
77 UndoableAction *
port_action_new_reset_control(PortIdentifier * port_id,GError ** error)78 port_action_new_reset_control (
79   PortIdentifier * port_id,
80   GError **        error)
81 {
82   Port * port =
83     port_find_from_identifier (port_id);
84 
85   return
86     port_action_new (
87       PORT_ACTION_SET_CONTROL_VAL, port_id,
88       port->deff, F_NOT_NORMALIZED, error);
89 }
90 
91 PortAction *
port_action_clone(const PortAction * src)92 port_action_clone (
93   const PortAction * src)
94 {
95   PortAction * self = object_new (PortAction);
96   self->parent_instance = src->parent_instance;
97 
98   self->type = src->type;
99   port_identifier_copy (
100     &self->port_id, &src->port_id);
101   self->val = src->val;
102 
103   return self;
104 }
105 
106 bool
port_action_perform(PortActionType type,PortIdentifier * port_id,float val,bool is_normalized,GError ** error)107 port_action_perform (
108   PortActionType   type,
109   PortIdentifier * port_id,
110   float            val,
111   bool             is_normalized,
112   GError **        error)
113 {
114   UNDO_MANAGER_PERFORM_AND_PROPAGATE_ERR (
115     port_action_new,
116     error, type, port_id, val, is_normalized, error);
117 }
118 
119 bool
port_action_perform_reset_control(PortIdentifier * port_id,GError ** error)120 port_action_perform_reset_control (
121   PortIdentifier * port_id,
122   GError **        error)
123 {
124   UNDO_MANAGER_PERFORM_AND_PROPAGATE_ERR (
125     port_action_new_reset_control,
126     error, port_id, error);
127 }
128 
129 static int
port_action_do_or_undo(PortAction * self,bool _do)130 port_action_do_or_undo (
131   PortAction * self,
132   bool         _do)
133 {
134   Port * port =
135     port_find_from_identifier (&self->port_id);
136 
137   switch (self->type)
138     {
139     case PORT_ACTION_SET_CONTROL_VAL:
140       {
141         float val_before =
142           control_port_get_val (port);
143         port_set_control_value (
144           port, self->val, F_NOT_NORMALIZED,
145           F_PUBLISH_EVENTS);
146         self->val = val_before;
147       }
148       break;
149     default:
150       break;
151     }
152 
153   return 0;
154 }
155 
156 int
port_action_do(PortAction * self,GError ** error)157 port_action_do (
158   PortAction * self,
159   GError **    error)
160 {
161   return
162     port_action_do_or_undo (self, true);
163 }
164 
165 int
port_action_undo(PortAction * self,GError ** error)166 port_action_undo (
167   PortAction * self,
168   GError **    error)
169 {
170   return
171     port_action_do_or_undo (self, false);
172 }
173 
174 char *
port_action_stringize(PortAction * self)175 port_action_stringize (
176   PortAction * self)
177 {
178   switch (self->type)
179     {
180     case PORT_ACTION_SET_CONTROL_VAL:
181       return g_strdup (_("Set control value"));
182       break;
183     default:
184       g_warn_if_reached ();
185     }
186   g_return_val_if_reached (NULL);
187 }
188 
189 void
port_action_free(PortAction * self)190 port_action_free (
191   PortAction * self)
192 {
193   object_zero_and_free (self);
194 }
195