Zrythm
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
arranger_object.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: © 2019-2022 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
10#ifndef __GUI_BACKEND_ARRANGER_OBJECT_H__
11#define __GUI_BACKEND_ARRANGER_OBJECT_H__
12
13#include <stdbool.h>
14
15#include "dsp/curve.h"
16#include "dsp/position.h"
18#include "utils/yaml.h"
19
20#include <glib/gi18n.h>
21
22typedef struct ArrangerObject ArrangerObject;
24typedef struct _ArrangerWidget ArrangerWidget;
25typedef struct _ArrangerObjectWidget ArrangerObjectWidget;
26typedef struct UndoableAction UndoableAction;
28
35#define ARRANGER_OBJECT_MAGIC 347616554
36#define IS_ARRANGER_OBJECT(tr) \
37 (((ArrangerObject *) tr)->magic == ARRANGER_OBJECT_MAGIC \
38 && ((ArrangerObject *) tr)->type >= ARRANGER_OBJECT_TYPE_REGION \
39 && ((ArrangerObject *) tr)->type <= ARRANGER_OBJECT_TYPE_VELOCITY)
40#define IS_ARRANGER_OBJECT_AND_NONNULL(x) (x && IS_ARRANGER_OBJECT (x))
41
46{
47 ARRANGER_OBJECT_RESIZE_NORMAL,
48 ARRANGER_OBJECT_RESIZE_LOOP,
49 ARRANGER_OBJECT_RESIZE_FADE,
50 ARRANGER_OBJECT_RESIZE_STRETCH,
51
60
65{
66 /* These two are not actual object types. */
67 ARRANGER_OBJECT_TYPE_NONE,
68 ARRANGER_OBJECT_TYPE_ALL,
69
70 ARRANGER_OBJECT_TYPE_REGION,
71 ARRANGER_OBJECT_TYPE_MIDI_NOTE,
72 ARRANGER_OBJECT_TYPE_CHORD_OBJECT,
73 ARRANGER_OBJECT_TYPE_SCALE_OBJECT,
74 ARRANGER_OBJECT_TYPE_MARKER,
75 ARRANGER_OBJECT_TYPE_AUTOMATION_POINT,
76 ARRANGER_OBJECT_TYPE_VELOCITY,
78
79static const char * arranger_object_type_strings[] = {
80 N_ ("None"), N_ ("All"),
81 N_ ("Region"), N_ ("Midi Note"),
82 N_ ("Chord Object"), N_ ("Scale Object"),
83 N_ ("Marker"), N_ ("Automation Point"),
84 N_ ("Velocity"),
85};
86
98
99typedef enum ArrangerObjectPositionType
100{
101 ARRANGER_OBJECT_POSITION_TYPE_START,
102 ARRANGER_OBJECT_POSITION_TYPE_END,
103 ARRANGER_OBJECT_POSITION_TYPE_CLIP_START,
104 ARRANGER_OBJECT_POSITION_TYPE_LOOP_START,
105 ARRANGER_OBJECT_POSITION_TYPE_LOOP_END,
106 ARRANGER_OBJECT_POSITION_TYPE_FADE_IN,
107 ARRANGER_OBJECT_POSITION_TYPE_FADE_OUT,
108} ArrangerObjectPositionType;
109
113typedef struct ArrangerObject
114{
116
119
131
141
151
155
164
171
178
181
184
188 GdkRectangle full_rect;
189
193 // GdkRectangle draw_rect;
194
197 int textw;
198 int texth;
199
207
213
215 bool muted;
216
217 int magic;
218
221
232
240
241 /* --- The following should only be used for objects that really need caching,
242 * such as audio regions --- */
243
250
261 cairo_t * cached_cr[2];
262
273 cairo_surface_t * cached_surface[2];
274
277 GdkRectangle last_name_rect;
278
283
287#define arranger_object_type_has_length(type) \
288 (type == ARRANGER_OBJECT_TYPE_REGION \
289 || type == ARRANGER_OBJECT_TYPE_MIDI_NOTE)
290
294#define arranger_object_type_has_global_pos(type) \
295 (type == ARRANGER_OBJECT_TYPE_REGION \
296 || type == ARRANGER_OBJECT_TYPE_SCALE_OBJECT \
297 || type == ARRANGER_OBJECT_TYPE_MARKER)
298
299#define arranger_object_type_has_name(type) \
300 (type == ARRANGER_OBJECT_TYPE_REGION || type == ARRANGER_OBJECT_TYPE_MARKER)
301
305#define arranger_object_can_have_lanes(_obj) \
306 ((_obj)->type == ARRANGER_OBJECT_TYPE_REGION \
307 && region_type_has_lane (((ZRegion *) _obj)->id.type))
308
310#define arranger_object_type_can_loop(type) \
311 (type == ARRANGER_OBJECT_TYPE_REGION)
312
313#define arranger_object_can_fade(_obj) \
314 ((_obj)->type == ARRANGER_OBJECT_TYPE_REGION \
315 && region_type_can_fade (((ZRegion *) _obj)->id.type))
316
317#define arranger_object_can_mute(_obj) \
318 ((_obj)->type == ARRANGER_OBJECT_TYPE_REGION \
319 || (_obj)->type == ARRANGER_OBJECT_TYPE_MIDI_NOTE)
320
321#define arranger_object_owned_by_region(_obj) \
322 ((_obj)->type == ARRANGER_OBJECT_TYPE_VELOCITY \
323 || (_obj)->type == ARRANGER_OBJECT_TYPE_MIDI_NOTE \
324 || (_obj)->type == ARRANGER_OBJECT_TYPE_CHORD_OBJECT \
325 || (_obj)->type == ARRANGER_OBJECT_TYPE_AUTOMATION_POINT)
326
330#define arranger_object_can_cache_drawing(_obj) (false)
331
332#if 0
333 ((_obj)->type == ARRANGER_OBJECT_TYPE_REGION && \
335 ((ZRegion *) _obj)->id.type))
336#endif
337
343
347void
349
354HOT ZRegion *
356
361const char *
363
372char *
374
379void
381
386void
388
395
396void
397arranger_object_init (ArrangerObject * self);
398
402void
404
411
419void
421 ArrangerObject * self,
422 const bool select,
423 const bool append,
424 bool fire_events);
425
434NONNULL_ARGS (1)
435PURE WARN_UNUSED_RESULT bool arranger_object_is_hit (
436 const ArrangerObject * self,
437 const Position * start,
438 const Position * end);
439
444int
445arranger_object_get_num_loops (ArrangerObject * self, const int count_incomplete);
446
450bool
452
457NONNULL void
459
470NONNULL bool
471arranger_object_get_muted (ArrangerObject * self, bool check_parent);
472
476void
477arranger_object_set_muted (ArrangerObject * self, bool muted, bool fire_events);
478
482void
484
488void
490
494void
496
500void
502
506void
508
512void
514
518void
520
521void
522arranger_object_get_position_from_type (
523 const ArrangerObject * self,
524 Position * pos,
525 ArrangerObjectPositionType type);
526
532void
534
540void
542 const ArrangerObject * self,
544
545void
546arranger_object_edit_position_finish (const ArrangerObject * self);
547
554void
556
561void
563
568void
570 ArrangerObject * self,
571 const Position * pos);
572
577void
579 ArrangerObject * self,
580 const Position * pos);
581
586void
588
595HOT NONNULL WARN_UNUSED_RESULT bool
597 const ArrangerObject * const self,
598 const Position * pos,
599 ArrangerObjectPositionType pos_type);
600
601#define arranger_object_validate_pos arranger_object_is_position_valid
602
614bool
616 ArrangerObject * self,
617 const Position * pos,
618 ArrangerObjectPositionType pos_type,
619 const bool validate);
620
624void
626
627void
628arranger_object_add_linked_region (ArrangerObject * self, ZRegion * region);
629
630void
631arranger_object_remove_linked_region (ArrangerObject * self, ZRegion * region);
632
638void
639arranger_object_move (ArrangerObject * self, const double ticks);
640
646NONNULL WARN_UNUSED_RESULT static inline double
647arranger_object_get_length_in_ticks (const ArrangerObject * const self)
648{
649 g_return_val_if_fail (arranger_object_type_has_length (self->type), 0);
650
651 return self->end_pos.ticks - self->pos.ticks;
652}
653
660NONNULL WARN_UNUSED_RESULT static inline signed_frame_t
661arranger_object_get_length_in_frames (const ArrangerObject * const self)
662{
663 g_return_val_if_fail (arranger_object_type_has_length (self->type), 0);
664
665 return self->end_pos.frames - self->pos.frames;
666}
667
671NONNULL static inline double
672arranger_object_get_loop_length_in_ticks (const ArrangerObject * const self)
673{
674 g_return_val_if_fail (arranger_object_type_has_length (self->type), 0);
675
676 return self->loop_end_pos.ticks - self->loop_start_pos.ticks;
677}
678
682NONNULL HOT static inline signed_frame_t
683arranger_object_get_loop_length_in_frames (const ArrangerObject * const self)
684{
685 g_return_val_if_fail (arranger_object_type_has_length (self->type), 0);
686
687 return self->loop_end_pos.frames - self->loop_start_pos.frames;
688}
689
698void
700 ArrangerObject * self,
701 bool from_ticks,
702 bool bpm_change,
703 UndoableAction * action);
704
708void
710
722WARN_UNUSED_RESULT bool
724 ArrangerObject * self,
725 const bool left,
727 const double ticks,
728 bool during_ui_action,
729 GError ** error);
730
731void
732arranger_object_append_children (ArrangerObject * self, GPtrArray * children);
733
737void
739
743#define _ARRANGER_OBJECT_FREE_AND_SET_STRING(_obj, _val_name, _val_value) \
744 g_free_and_null (_obj->_val_name); \
745 _obj->_val_name = g_strdup (_val_value)
746
755#define arranger_object_set_string(cc, obj, val_name, val_value) \
756 { \
757 cc * _obj = (cc *) obj; \
758 _ARRANGER_OBJECT_FREE_AND_SET_STRING (_obj, val_name, val_value); \
759 }
760
764HOT NONNULL Track *
766
767static inline const char *
768arranger_object_get_type_as_string (ArrangerObjectType type)
769{
770 return arranger_object_type_strings[type];
771}
772
773void
774arranger_object_post_deserialize (ArrangerObject * self);
775
783bool
785
791bool
793
802
808
830WARN_UNUSED_RESULT bool
832 ArrangerObject * self,
833 const Position * pos,
834 const bool pos_is_local,
835 ArrangerObject ** r1,
836 ArrangerObject ** r2,
837 bool is_project,
838 GError ** error);
839
845WARN_UNUSED_RESULT NONNULL_ARGS (1, 2) bool arranger_object_unsplit (
846 ArrangerObject * r1,
847 ArrangerObject * r2,
848 ArrangerObject ** obj,
849 bool fire_events,
850 GError ** error);
851
857void
858arranger_object_set_name (
859 ArrangerObject * self,
860 const char * name,
861 int fire_events);
862
869void
871
876void
878
883void
885
893WARN_UNUSED_RESULT NONNULL_ARGS (1) bool arranger_object_add_to_project (
894 ArrangerObject * obj,
895 bool fire_events,
896 GError ** error);
897
909WARN_UNUSED_RESULT bool
911
917void
919
924bool
926
931bool
933
934bool
935arranger_object_is_renamable (const ArrangerObject * obj);
936
940void
942
947#endif
Curves.
ArrangerSelectionsActionEditType
Type used when the action is an EDIT action.
#define region_type_can_fade(rtype)
Returns if the given ZRegion type can have fades.
Definition region.h:279
void arranger_object_set_start_pos_full_size(ArrangerObject *obj, Position *pos)
Sets the end position of the ArrangerObject and also sets the loop end and fade out so that they are ...
ArrangerObject * arranger_object_clone(const ArrangerObject *self)
Clones the ArrangerObject.
void arranger_object_loop_end_pos_setter(ArrangerObject *self, const Position *pos)
The setter is for use in e.g.
void arranger_object_get_end_pos(const ArrangerObject *self, Position *pos)
Getter.
void arranger_object_pos_setter(ArrangerObject *self, const Position *pos)
The setter is for use in e.g.
void arranger_object_free(ArrangerObject *self)
Frees only this object.
void arranger_object_select(ArrangerObject *self, const bool select, const bool append, bool fire_events)
Selects the object by adding it to its corresponding selections or making it the only selection.
HOT NONNULL WARN_UNUSED_RESULT bool arranger_object_is_position_valid(const ArrangerObject *const self, const Position *pos, ArrangerObjectPositionType pos_type)
Returns if the given Position is valid.
WARN_UNUSED_RESULT bool arranger_object_insert_to_project(ArrangerObject *obj, GError **error)
Inserts the ArrangerObject where it belongs in the project (eg, a Track).
bool arranger_object_is_deletable(const ArrangerObject *obj)
Returns whether the given object is deletable or not (eg, start marker).
void arranger_object_set_to_object(ArrangerObject *dest, ArrangerObject *src)
Sets the dest object's values to the main src object's values.
void arranger_object_get_clip_start_pos(const ArrangerObject *self, Position *pos)
Getter.
ArrangerObject * arranger_object_get_object(ArrangerObject *self)
Gets the object the ArrangerObjectInfo represents.
void arranger_object_remove_child(ArrangerObject *self, ArrangerObject *child)
Removes the child from the given object.
void arranger_object_set_name_with_action(ArrangerObject *self, const char *name)
Changes the name and adds an action to the undo stack.
void arranger_object_edit_finish(const ArrangerObject *self, ArrangerSelectionsActionEditType type)
Callback when finishing editing the object.
void arranger_object_get_pos(const ArrangerObject *self, Position *pos)
Getter.
WARN_UNUSED_RESULT bool arranger_object_split(ArrangerObject *self, const Position *pos, const bool pos_is_local, ArrangerObject **r1, ArrangerObject **r2, bool is_project, GError **error)
Splits the given object at the given Position.
void arranger_object_get_fade_in_pos(const ArrangerObject *self, Position *pos)
Getter.
ArrangerSelections * arranger_object_get_selections_for_type(ArrangerObjectType type)
Returns the ArrangerSelections corresponding to the given object type.
NONNULL void arranger_object_print(const ArrangerObject *self)
Prints debug information about the given object.
void arranger_object_move(ArrangerObject *self, const double ticks)
Moves the object by the given amount of ticks.
void arranger_object_get_fade_out_pos(const ArrangerObject *self, Position *pos)
Getter.
void arranger_object_set_magic(ArrangerObject *self)
Sets the magic on the arranger object.
char * arranger_object_gen_human_readable_name(const ArrangerObject *self)
Generates a human readable name for the object.
void arranger_object_get_loop_start_pos(const ArrangerObject *self, Position *pos)
Getter.
void arranger_object_update_positions(ArrangerObject *self, bool from_ticks, bool bpm_change, UndoableAction *action)
Updates the positions in each child recursively.
void arranger_object_add_ticks_to_children(ArrangerObject *self, const double ticks)
Adds the given ticks to each included object.
void arranger_object_edit_begin(const ArrangerObject *self)
Callback when beginning to edit the object.
ArrangerObjectFlags
ArrangerObject flags.
void arranger_object_set_muted(ArrangerObject *self, bool muted, bool fire_events)
Sets the mute status of the object.
bool arranger_object_validate_name(ArrangerObject *self, const char *name)
Validates the given name.
void arranger_object_get_loop_end_pos(const ArrangerObject *self, Position *pos)
Getter.
#define arranger_object_type_has_length(type)
Returns if the object type has a length.
void arranger_object_set_end_pos_full_size(ArrangerObject *obj, Position *pos)
Sets the end position of the ArrangerObject and also sets the loop end and fade out to that position.
bool arranger_object_is_selected(ArrangerObject *self)
Returns if the object is in the selections.
void arranger_object_init_loaded(ArrangerObject *self)
Initializes the object after loading a Project.
bool arranger_object_set_position(ArrangerObject *self, const Position *pos, ArrangerObjectPositionType pos_type, const bool validate)
Sets the given position on the object, optionally attempting to validate before.
void arranger_object_clip_start_pos_setter(ArrangerObject *self, const Position *pos)
The setter is for use in e.g.
void arranger_object_remove_from_project(ArrangerObject *obj)
Removes the object from its parent in the project.
ArrangerObjectType
The type of the object.
PURE WARN_UNUSED_RESULT bool arranger_object_is_hit(const ArrangerObject *self, const Position *start, const Position *end)
Returns whether the given object is hit by the given position or range.
const char * arranger_object_get_name(const ArrangerObject *self)
Returns a pointer to the name of the object, if the object can have names.
ArrangerObjectResizeType
Flag used in some functions.
NONNULL bool arranger_object_get_muted(ArrangerObject *self, bool check_parent)
Gets the mute status of the object.
void arranger_object_copy_identifier(ArrangerObject *dest, ArrangerObject *src)
Copies the identifier from src to dest.
void arranger_object_loop_start_pos_setter(ArrangerObject *self, const Position *pos)
The setter is for use in e.g.
bool arranger_object_validate(const ArrangerObject *const self)
Validates the arranger object.
HOT ZRegion * arranger_object_get_region(const ArrangerObject *const self)
If the object is part of a ZRegion, returns it, otherwise returns NULL.
bool arranger_object_is_frozen(ArrangerObject *obj)
Returns whether the arranger object is part of a frozen track.
void arranger_object_gen_escaped_name(const ArrangerObject *self)
Generates the escaped name for the object, where applicable.
WARN_UNUSED_RESULT NONNULL_ARGS(1, 2) bool arranger_object_unsplit(ArrangerObject *r1
Undoes what arranger_object_split() did.
ArrangerObject * arranger_object_find(ArrangerObject *obj)
Returns the ArrangerObject matching the given one.
WARN_UNUSED_RESULT bool arranger_object_resize(ArrangerObject *self, const bool left, ArrangerObjectResizeType type, const double ticks, bool during_ui_action, GError **error)
Resizes the object on the left side or right side by given amount of ticks, for objects that do not h...
HOT NONNULL Track * arranger_object_get_track(const ArrangerObject *const self)
Returns the Track this ArrangerObject is in.
int arranger_object_get_num_loops(ArrangerObject *self, const int count_incomplete)
Returns the number of loops in the ArrangerObject, optionally including incomplete ones.
void arranger_object_end_pos_setter(ArrangerObject *self, const Position *pos)
The setter is for use in e.g.
ArrangerWidget * arranger_object_get_arranger(const ArrangerObject *self)
Gets the arranger for this arranger object.
@ ARRANGER_OBJECT_FLAG_NON_PROJECT
This object is not a project object, but an object used temporarily eg.
@ ARRANGER_OBJECT_RESIZE_STRETCH_BPM_CHANGE
Used when we want to resize to contents when BPM changes.
int_fast64_t signed_frame_t
Signed type for frame index.
Definition types.h:55
Position struct and API.
Region identifier.
Base struct for arranger objects.
ArrangerObjectFlags flags
Flags.
Position fade_in_pos
Fade in position, relative to the object's start.
bool deleted_temporarily
Whether deleted with delete tool.
RegionIdentifier region_id
Parent region identifier for objects that are part of a region.
bool muted
Whether muted or not (if applicable).
Position loop_start_pos
Loop start Position, if the object has one, relative to the object's start.
Position fade_out_pos
Fade out position, relative to the object's start.
int textw
The rectangle this object was last drawn in (ie, after any necessary clipping), in absolute coordinat...
ArrangerObject * transient
A copy ArrangerObject corresponding to this, such as when ctrl+dragging.
Position clip_start_pos
Start position of the clip loop, relative to the object's start.
GdkRectangle last_name_rect
Last drawn name rectangle, if object has a name.
bool is_auditioner
Whether part of an auditioner track.
cairo_surface_t * cached_surface[2]
Cached surface containing drawing.
Position end_pos
End Position, if the object has one.
Position loop_end_pos
End position of the clip loop, relative to the object's start.
CurveOptions fade_out_opts
Fade out curve options.
ArrangerObject * main
The opposite of the above.
GdkRectangle full_rect
The full rectangle this object covers including off-screen parts, in absolute coordinates.
CurveOptions fade_in_opts
Fade in curve options.
Position pos
Position (or start Position if the object has length).
cairo_t * cached_cr[2]
Cached cairo_t.
int index_in_prev_lane
Object's index in the previous lane (before being moved to a new lane/track).
bool use_cache
Set to true to blit the cached surface, false to redraw.
The arranger widget is a canvas that draws all the arranger objects it contains.
Definition arranger.h:108
Curve options.
Definition curve.h:108
A Position is made up of bars.beats.sixteenths.ticks.
Definition position.h:126
double ticks
Precise total number of ticks.
Definition position.h:128
signed_frame_t frames
Position in frames (samples).
Definition position.h:135
Index/identifier for a Region, so we can get Region objects quickly with it without searching by name...
Track to be inserted into the Project's Tracklist.
Definition track.h:177
Base struct to be inherited by implementing undoable actions.
A region (clip) is an object on the timeline that contains either MidiNote's or AudioClip's.
Definition region.h:72
YAML utils.