Zrythm
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
arranger.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: © 2018-2022 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
10#ifndef __GUI_WIDGETS_ARRANGER_H__
11#define __GUI_WIDGETS_ARRANGER_H__
12
13#include "dsp/position.h"
14#include "dsp/transport.h"
15#include "gui/widgets/main_window.h"
16#include "utils/ui.h"
17
18#include "gtk_wrapper.h"
19
20#define ARRANGER_WIDGET_TYPE (arranger_widget_get_type ())
21G_DECLARE_FINAL_TYPE (ArrangerWidget, arranger_widget, Z, ARRANGER_WIDGET, GtkWidget)
22
23typedef struct _ArrangerBgWidget ArrangerBgWidget;
24typedef struct MidiNote MidiNote;
25typedef struct SnapGrid SnapGrid;
26typedef struct AutomationPoint AutomationPoint;
27
28typedef struct _GtkEventControllerMotion GtkEventControllerMotion;
29typedef struct ArrangerObject ArrangerObject;
31typedef struct EditorSettings EditorSettings;
32typedef struct ObjectPool ObjectPool;
33typedef struct _RulerWidget RulerWidget;
34enum class ArrangerObjectType;
35enum class TransportDisplay;
36
43#define ARRANGER_WIDGET_GET_ACTION(arr, actn) \
44 (arr->action == UI_OVERLAY_ACTION_##actn)
45
47{
50 ARRANGER_CURSOR_SELECT,
51 ARRANGER_CURSOR_SELECT_STRETCH,
52 ARRANGER_CURSOR_EDIT,
53 ARRANGER_CURSOR_AUTOFILL,
54 ARRANGER_CURSOR_CUT,
55 ARRANGER_CURSOR_ERASER,
56 ARRANGER_CURSOR_AUDITION,
57 ARRANGER_CURSOR_RAMP,
58 ARRANGER_CURSOR_GRAB,
59 ARRANGER_CURSOR_GRABBING,
60 ARRANGER_CURSOR_RESIZING_L,
61 ARRANGER_CURSOR_RESIZING_L_FADE,
62 ARRANGER_CURSOR_STRETCHING_L,
63 ARRANGER_CURSOR_RESIZING_L_LOOP,
64 ARRANGER_CURSOR_RESIZING_R,
65 ARRANGER_CURSOR_RESIZING_R_FADE,
66 ARRANGER_CURSOR_STRETCHING_R,
67 ARRANGER_CURSOR_RESIZING_R_LOOP,
68 ARRANGER_CURSOR_RESIZING_UP,
69 ARRANGER_CURSOR_RESIZING_UP_FADE_IN,
70 ARRANGER_CURSOR_RESIZING_UP_FADE_OUT,
71 ARRANGER_CURSOR_GRABBING_COPY,
72 ARRANGER_CURSOR_GRABBING_LINK,
73 ARRANGER_CURSOR_RANGE,
74 ARRANGER_CURSOR_FADE_IN,
75 ARRANGER_CURSOR_FADE_OUT,
76 ARRANGER_CURSOR_RENAME,
77 ARRANGER_CURSOR_PANNING,
78};
79
84{
85 ARRANGER_WIDGET_TYPE_TIMELINE,
86 ARRANGER_WIDGET_TYPE_MIDI,
87 ARRANGER_WIDGET_TYPE_MIDI_MODIFIER,
88 ARRANGER_WIDGET_TYPE_AUDIO,
89 ARRANGER_WIDGET_TYPE_CHORD,
90 ARRANGER_WIDGET_TYPE_AUTOMATION,
91};
92
93#if 0
94typedef enum ArrangerWidgetHoverType
95{
96 ARRANGER_WIDGET_HOVER_TYPE_NONE,
97 ARRANGER_WIDGET_HOVER_TYPE_TRACK,
98 ARRANGER_WIDGET_HOVER_TYPE_TRACK_LANE,
99 ARRANGER_WIDGET_HOVER_TYPE_AUTOMATION_TRACK,
100} ArrangerWidgetHoverType;
101#endif
102
107typedef struct _ArrangerWidget
108{
109 GtkWidget parent_instance;
110
113
114 GtkGestureDrag * drag;
115 GtkGestureClick * click;
116 GtkGestureClick * right_click;
117 GtkEventControllerMotion * motion_controller;
118
121 double last_offset_y;
122
128 double offset_y_from_scroll;
129
130 UiOverlayAction action;
131
133 double start_x;
134
136 double start_y;
137
141
150
154
158
165
179
182
186
196
201
205
208 // Position earliest_obj_pos;
209
213
217
220
224
229
232
236
238 gboolean key_is_pressed;
239
241 double hover_x;
242 double hover_y;
243
244 bool hovered;
245
248
251
254
257
260
261 gint64 last_frame_time;
262
263 /* ----- TIMELINE ------ */
264
268
272
277
281
286
292
293 AutomationTrack * hovered_at;
294 TrackLane * hovered_lane;
295 Track * hovered_track;
296
297 /* textures used as region icons */
298 GdkTexture * symbolic_link_texture;
299 GdkTexture * music_note_16th_texture;
300 GdkTexture * fork_awesome_snowflake_texture;
301 GdkTexture * media_playlist_repeat_texture;
302
305
307 GskRenderNode * loop_line_node;
308 GskRenderNode * clip_start_line_node;
309 GskRenderNode * cut_line_node;
310
311 /* ----- END TIMELINE ----- */
312
313 /* ------ MIDI (PIANO ROLL) ---- */
314
317
318 /* ------ END MIDI (PIANO ROLL) ---- */
319
320 /* ------ MIDI MODIFIER ---- */
321
324
334
335 /* ------ END MIDI MODIFIER ---- */
336
337 /* ------- CHORD ------- */
338
341
342 /* ------- END CHORD ------- */
343
344 /* --- AUDIO --- */
345
352
353 double dval_at_start;
354
355 /* --- END AUDIO --- */
356
361
363 bool redraw;
364
365 // cairo_t * cached_cr;
366
367 // cairo_surface_t * cached_surface;
368
370 graphene_rect_t last_rect;
371
379
382
384 GdkRectangle highlight_rect;
385 // GdkRectangle prev_highlight_rect;
386 //
387
391
399
408
412
415
422 PangoLayout * vel_layout;
423
430 PangoLayout * ap_layout;
431
435 PangoLayout * audio_layout;
436
438 PangoLayout * debug_layout;
439
449
455 GPtrArray * hit_objs_to_draw;
456
458 GtkPopoverMenu * popover_menu;
460
461const char *
462arranger_widget_get_type_str (ArrangerWidgetType type);
463
467bool
469
474void
476 ArrangerWidget * self,
478 SnapGrid * snap_grid);
479
484void
486
491int
492arranger_widget_pos_to_px (ArrangerWidget * self, Position * pos, int use_padding);
493
500
505void
507
511void
512arranger_widget_get_all_objects (ArrangerWidget * self, GPtrArray * objs_arr);
513
518void
520 ArrangerWidget * self,
521 double px,
522 Position * pos,
523 bool has_padding);
524
530void
532
543void
545 ArrangerWidget * self,
547 double x,
548 double y,
549 GPtrArray * arr);
550
560void
562 ArrangerWidget * self,
564 GdkRectangle * rect,
565 GPtrArray * arr);
566
578 ArrangerWidget * self,
580 const double x,
581 const double y);
582
583void
584arranger_widget_select_all (ArrangerWidget * self, bool select, bool fire_events);
585
593NONNULL bool
595
600RETURNS_NONNULL
603
607void
609
610SnapGrid *
611arranger_widget_get_snap_grid (ArrangerWidget * self);
612
617gboolean
619 GtkEventControllerKey * key_controller,
620 guint keyval,
621 guint keycode,
622 GdkModifierType state,
623 ArrangerWidget * self);
624
625void
626arranger_widget_on_key_release (
627 GtkEventControllerKey * key_controller,
628 guint keyval,
629 guint keycode,
630 GdkModifierType state,
631 ArrangerWidget * self);
632
641NONNULL void
643 ArrangerWidget * self,
644 ArrangerObject * obj,
645 int horizontal,
646 int up,
647 int left,
648 int padding);
649
656void
658 ArrangerWidget * self,
659 ArrangerObject * clicked_object);
660
665void
667
674void
676
683
690
691bool
692arranger_widget_is_playhead_visible (ArrangerWidget * self);
693
694NONNULL void
695arranger_widget_handle_playhead_auto_scroll (ArrangerWidget * self, bool force);
696
697typedef void (*ArrangerWidgetForeachFunc) (ArrangerWidget * arranger);
698
702NONNULL void
703arranger_widget_foreach (ArrangerWidgetForeachFunc func);
704
705NONNULL RulerWidget *
706arranger_widget_get_ruler (ArrangerWidget * self);
707
712bool
714
719int
721
722#define arranger_widget_print_action(self) \
723 g_debug ("action: %s", ui_overlay_strings[self->action])
724
729bool
731
739NONNULL void
741 ArrangerWidget * self,
742 double start_x,
743 double start_y,
744 bool autofilling);
745
753NONNULL bool
755 ArrangerWidget * self,
756 double x,
757 double y);
758
762int
764
769#endif
TransportDisplay
Corrseponts to "transport-display" in the gsettings.
Definition transport.h:96
ArrangerObjectType
The type of the object.
UiOverlayAction
Various overlay actions to be shared.
Definition ui.h:246
ArrangerCursor
Definition arranger.h:47
void arranger_widget_get_hit_objects_at_point(ArrangerWidget *self, ArrangerObjectType type, double x, double y, GPtrArray *arr)
Fills in the given array with the ArrangerObject's of the given type that appear in the given ranger.
void arranger_widget_get_min_possible_position(ArrangerWidget *self, Position *pos)
Returns the earliest possible position allowed in this arranger (eg, 1.1.0.0 for timeline).
ArrangerWidgetType
Type of arranger.
Definition arranger.h:84
EditorSettings * arranger_widget_get_editor_settings(ArrangerWidget *self)
Returns the EditorSettings corresponding to the given arranger.
gboolean arranger_widget_on_key_press(GtkEventControllerKey *key_controller, guint keyval, guint keycode, GdkModifierType state, ArrangerWidget *self)
Called from MainWindowWidget because some events don't reach here.
EditorSettings arranger_widget_get_editor_setting_values(ArrangerWidget *self)
Get just the values, adjusted properly for special cases (like pinned timeline).
int arranger_widget_get_playhead_px(ArrangerWidget *self)
Returns the playhead's x coordinate in absolute coordinates.
bool arranger_widget_get_drum_mode_enabled(ArrangerWidget *self)
Returns true if MIDI arranger and track mode is enabled.
ArrangerCursor arranger_widget_get_cursor(ArrangerWidget *self)
Gets the cursor based on the current hover position.
bool arranger_widget_any_doing_action(void)
Returns whether any arranger is in the middle of an action.
void arranger_widget_redraw_playhead(ArrangerWidget *self)
Only redraws the playhead part.
ArrangerObject * arranger_widget_get_hit_arranger_object(ArrangerWidget *self, ArrangerObjectType type, const double x, const double y)
Returns the ArrangerObject of the given type at (x,y).
void arranger_widget_set_highlight_rect(ArrangerWidget *self, GdkRectangle *rect)
Sets the highlight rectangle.
int arranger_widget_get_total_height(ArrangerWidget *self)
Returns the total height (including off-screen).
void arranger_widget_refresh_cursor(ArrangerWidget *self)
Figures out which cursor should be used based on the current state and then sets it.
void arranger_widget_set_cursor(ArrangerWidget *self, ArrangerCursor cursor)
Sets the cursor on the arranger and all of its children.
NONNULL void arranger_widget_foreach(ArrangerWidgetForeachFunc func)
Runs the given function for each arranger.
void arranger_widget_toggle_selections_muted(ArrangerWidget *self, ArrangerObject *clicked_object)
Toggles the mute status of the selection, based on the mute status of the selected object.
void arranger_widget_get_visible_rect(ArrangerWidget *self, GdkRectangle *rect)
Returns the current visible rectangle.
RETURNS_NONNULL ArrangerSelections * arranger_widget_get_selections(ArrangerWidget *self)
Returns the ArrangerSelections for this ArrangerWidget.
NONNULL void arranger_widget_create_item(ArrangerWidget *self, double start_x, double start_y, bool autofilling)
Called when an item needs to be created at the given position.
NONNULL bool arranger_widget_finish_creating_item_from_action(ArrangerWidget *self, double x, double y)
To be called after using arranger_widget_create_item() in an action (ie, not from click + drag intera...
void arranger_widget_get_all_objects(ArrangerWidget *self, GPtrArray *objs_arr)
Get all objects currently present in the arranger.
NONNULL bool arranger_widget_is_in_moving_operation(ArrangerWidget *self)
Returns if the arranger is in a moving-related operation or starting a moving-related operation.
void arranger_widget_px_to_pos(ArrangerWidget *self, double px, Position *pos, bool has_padding)
Wrapper for ui_px_to_pos depending on the arranger type.
void arranger_widget_get_hit_objects_in_rect(ArrangerWidget *self, ArrangerObjectType type, GdkRectangle *rect, GPtrArray *arr)
Fills in the given array with the ArrangerObject's of the given type that appear in the given ranger.
void arranger_widget_setup(ArrangerWidget *self, ArrangerWidgetType type, SnapGrid *snap_grid)
Creates a timeline widget using the given timeline data.
bool arranger_widget_can_scroll_vertically(ArrangerWidget *self)
Returns if the arranger can scroll vertically.
int arranger_widget_pos_to_px(ArrangerWidget *self, Position *pos, int use_padding)
Wrapper of the UI functions based on the arranger type.
NONNULL void arranger_widget_scroll_until_obj(ArrangerWidget *self, ArrangerObject *obj, int horizontal, int up, int left, int padding)
Scroll until the given object is visible.
@ ARRANGER_CURSOR_NONE
Invalid cursor.
Position struct and API.
Base struct for arranger objects.
The arranger widget is a canvas that draws all the arranger objects it contains.
Definition arranger.h:108
bool is_highlighted
Whether a rectangle is highlighted for DND.
Definition arranger.h:381
PangoLayout * ap_layout
Layout for drawing automation point text.
Definition arranger.h:430
GskRenderNode * loop_line_node
Cached nodes for region loop lines.
Definition arranger.h:307
bool was_paused
Whether playback was paused during drag begin.
Definition arranger.h:216
ArrangerObject * start_object
The object that was clicked in this drag cycle, if any.
Definition arranger.h:178
int is_pinned
Whether this TimelineArrangerWidget is for the PinnedTracklist or not.
Definition arranger.h:280
double adj_ticks_diff
The adjusted diff in ticks to use for moving objects starting from their cached start positions.
Definition arranger.h:228
Position start_pos
Start Position of the earliest object currently.
Definition arranger.h:212
double last_offset_x
Used when dragging.
Definition arranger.h:120
bool redraw
Set to 1 to redraw.
Definition arranger.h:363
SnapGrid * snap_grid
Associated SnapGrid.
Definition arranger.h:250
double curr_ticks_diff_from_start
The absolute (not snapped) current diff in ticks from the curr_pos to the start_pos.
Definition arranger.h:223
Position playhead_pos_at_start
Playhead position at start of drag.
Definition arranger.h:219
int visible_at_diff
The number of visible automation t racks moved during a moving operation between automation tracks up...
Definition arranger.h:276
TransportDisplay ruler_display
Cached setting.
Definition arranger.h:414
double start_x
X-axis coordinate at start of drag.
Definition arranger.h:133
GdkRectangle highlight_rect
The rectangle to highlight.
Definition arranger.h:384
guint drag_start_btn
Drag start button (primary, secondary, etc.).
Definition arranger.h:398
double last_adj_ticks_diff
adj_ticks_diff in last cycle.
Definition arranger.h:231
GdkRectangle last_selection_rect
Last selection rectangle, used to redraw the union of the new selection and this.
Definition arranger.h:390
double start_y
Y-axis coordinate at start of drag.
Definition arranger.h:136
int resizing_range_start
1 if this is the first call to resize the range, so range1 can be set.
Definition arranger.h:291
GtkPopoverMenu * popover_menu
Popover to be reused for context menus.
Definition arranger.h:458
double hover_x
Current hovering positions (absolute).
Definition arranger.h:241
ArrangerObject * hovered_object
Object currently hovered.
Definition arranger.h:181
int last_playhead_px
Px the playhead was last drawn at, so we can redraw this and the new px only when the playhead change...
Definition arranger.h:360
PangoLayout * debug_layout
Layout for debug text.
Definition arranger.h:438
bool can_link
Whether the current selections can link (ie, only regions are selected).
Definition arranger.h:378
int alt_held
Whether Alt is currently held down.
Definition arranger.h:259
graphene_rect_t last_rect
Rectangle in the last call.
Definition arranger.h:370
Position earliest_obj_start_pos
Start Position of the earliest object at the start of the drag.
Definition arranger.h:157
ArrangerSelections * sel_at_start
A clone of the ArrangerSelections on drag begin.
Definition arranger.h:195
PangoLayout * vel_layout
Layout for drawing velocity text.
Definition arranger.h:422
Region * region_at_start
Region on drag begin, if editing automation.
Definition arranger.h:200
Position fade_pos_at_start
Fade in/out position at start.
Definition arranger.h:164
Position end_pos
for moving regions
Definition arranger.h:237
int vel_diff
Maximum Velocity diff applied in this action.
Definition arranger.h:333
ArrangerSelections * sel_to_delete
Selections to delete, used with the eraser tool.
Definition arranger.h:204
int hovered_note
The note currently hovering over.
Definition arranger.h:316
int start_vel_val
1-127.
Definition arranger.h:323
int queued_playhead_px
Cached playhead x to draw.
Definition arranger.h:448
float fval_at_start
Float value at start.
Definition arranger.h:351
bool first_draw
Whether this is the first time the widget is drawn.
Definition arranger.h:407
double offset_x_from_scroll
Whether there is an offset from a user scroll that should be added to the offset while dragging.
Definition arranger.h:127
int lane_diff
The number of lanes moved during a moving operation between lanes, up to the last cycle.
Definition arranger.h:271
int n_press
Number of clicks in current action.
Definition arranger.h:247
bool earliest_obj_exists
Whether an object exists, so we can use the earliest_obj_start_pos.
Definition arranger.h:153
int start_object_was_selected
Whether the start object was selected before drag_begin.
Definition arranger.h:185
Position curr_pos
The absolute (not snapped) Position as of the current action.
Definition arranger.h:235
ArrangerWidgetType type
Type of arranger this is.
Definition arranger.h:112
int region_icon_texture_size
Size of above textures.
Definition arranger.h:304
int hovered_chord_index
Index of the chord being hovered on.
Definition arranger.h:340
bool drag_update_started
Whether a drag update operation started.
Definition arranger.h:149
double start_pos_px
X-axis coordinate at the start of the drag, in pixels.
Definition arranger.h:140
int resizing_range
1 if resizing range.
Definition arranger.h:285
PangoLayout * audio_layout
Layout for drawing audio editor text.
Definition arranger.h:435
int ctrl_held
Whether Ctrl button is held down.
Definition arranger.h:256
double new_hadj_val
New temporary hadjustment value used when zooming in/out.
Definition arranger.h:411
GPtrArray * hit_objs_to_draw
Array of objects to draw.
Definition arranger.h:455
int shift_held
Whether shift button is held down.
Definition arranger.h:253
int visible_track_diff
The number of visible tracks moved during a moving operation between tracks up to the last cycle.
Definition arranger.h:267
An automation point inside an AutomationTrack.
Common editor settings.
A MIDI note inside a Region shown in the piano roll.
Definition midi_note.h:49
A Position is made up of bars.beats.sixteenths.ticks.
Definition position.h:124
A region (clip) is an object on the timeline that contains either MidiNote's or AudioClip's.
Definition region.h:72
A TrackLane belongs to a Track (can have many TrackLanes in a Track) and contains Regions.
Definition track_lane.h:45
Track to be inserted into the Project's Tracklist.
Definition track.h:177
Transport API.
User Interface utils.