Zrythm v2.0.0-DEV
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
arranger.h
1// SPDX-FileCopyrightText: © 2018-2022, 2024 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
4#ifndef __GUI_WIDGETS_ARRANGER_H__
5#define __GUI_WIDGETS_ARRANGER_H__
6
7#include "common/dsp/position.h"
8#include "common/dsp/transport.h"
9#include "common/utils/ui.h"
10#include "gui/backend/backend/editor_settings.h"
11#include "gui/backend/gtk_widgets/gtk_wrapper.h"
12#include "gui/backend/gtk_widgets/main_window.h"
13
14#define ARRANGER_WIDGET_TYPE (arranger_widget_get_type ())
15G_DECLARE_FINAL_TYPE (ArrangerWidget, arranger_widget, Z, ARRANGER_WIDGET, GtkWidget)
16
17TYPEDEF_STRUCT_UNDERSCORED (ArrangerBgWidget);
18TYPEDEF_STRUCT_UNDERSCORED (GtkEventControllerMotion);
19TYPEDEF_STRUCT_UNDERSCORED (RulerWidget);
20
26
27#define ARRANGER_WIDGET_GET_ACTION(arr, actn) (arr->action == ##actn)
28
30{
33 Select,
34 SelectStretch,
35 Edit,
36 Autofill,
37 ARRANGER_CURSOR_CUT,
38 Eraser,
39 Audition,
40 Ramp,
41 Grab,
42 Grabbing,
43 ResizingL,
44 ResizingLFade,
45 ARRANGER_CURSOR_STRETCHING_L,
46 ARRANGER_CURSOR_RESIZING_L_LOOP,
47 ResizingR,
48 ARRANGER_CURSOR_RESIZING_R_FADE,
49 ARRANGER_CURSOR_STRETCHING_R,
50 ARRANGER_CURSOR_RESIZING_R_LOOP,
51 ResizingUp,
52 ResizingUpFadeIn,
53 ResizingUpFadeOut,
54 GrabbingCopy,
55 GrabbingLink,
56 Range,
57 FadeIn,
58 FadeOut,
59 Rename,
60 Panning,
61};
62
67{
68 Timeline,
69 Midi,
70 MidiModifier,
71 Audio,
72 Chord,
73 Automation,
74};
75
76#if 0
77typedef enum ArrangerWidgetHoverType
78{
79 ARRANGER_WIDGET_HOVER_TYPE_NONE,
80 ARRANGER_WIDGET_HOVER_TYPE_TRACK,
81 ARRANGER_WIDGET_HOVER_TYPE_TRACK_LANE,
82 ARRANGER_WIDGET_HOVER_TYPE_AUTOMATION_TRACK,
83} ArrangerWidgetHoverType;
84#endif
85
95using ArrangerWidget = struct _ArrangerWidget
96{
97 GtkWidget parent_instance;
98
101
102 GtkGestureDrag * drag;
103 GtkGestureClick * click;
104 GtkGestureClick * right_click;
105 GtkEventControllerMotion * motion_controller;
106
108 double last_offset_x;
109 double last_offset_y;
110
115 double offset_x_from_scroll;
116 double offset_y_from_scroll;
117
118 UiOverlayAction action;
119
121 double start_x;
122
124 double start_y;
125
128 double start_pos_px;
129
137 bool drag_update_started;
138
141 std::unique_ptr<Position> earliest_obj_start_pos;
142
148 Position fade_pos_at_start;
149
158 std::unique_ptr<ArrangerObject> start_object;
159
165 std::weak_ptr<ArrangerObject> prj_start_object;
166
168 std::weak_ptr<ArrangerObject> hovered_object;
169
171 bool start_object_was_selected;
172
180 std::unique_ptr<ArrangerSelections> sel_at_start;
181
182#if 0
189 std::vector<ArrangerObject *> live_selections;
190#endif
191
195 std::unique_ptr<Region> region_at_start;
196
198 std::unique_ptr<ArrangerSelections> sel_to_delete;
199
202 Position start_pos;
203
206 bool was_paused;
207
209 Position playhead_pos_at_start;
210
213 double curr_ticks_diff_from_start;
214
218 double adj_ticks_diff;
219
221 double last_adj_ticks_diff;
222
225 Position curr_pos;
226
227 Position end_pos;
228 gboolean key_is_pressed;
229
231 double hover_x;
232 double hover_y;
233
234 bool hovered;
235
237 int n_press;
238
240 std::shared_ptr<SnapGrid> snap_grid;
241
243 int shift_held;
244
246 int ctrl_held;
247
249 int alt_held;
250
251 gint64 last_frame_time;
252
253 /* ----- TIMELINE ------ */
254
257 int visible_track_diff;
258
261 int lane_diff;
262
266 int visible_at_diff;
267
270 int is_pinned;
271
275 int resizing_range;
276
281 int resizing_range_start;
282
283 AutomationTrack * hovered_at;
284 TrackLane * hovered_lane;
285 Track * hovered_track;
286
287 /* textures used as region icons */
288 GdkTexture * symbolic_link_texture;
289 GdkTexture * music_note_16th_texture;
290 GdkTexture * fork_awesome_snowflake_texture;
291 GdkTexture * media_playlist_repeat_texture;
292
294 int region_icon_texture_size;
295
297 GskRenderNode * loop_line_node;
298 GskRenderNode * clip_start_line_node;
299 GskRenderNode * cut_line_node;
300
301 /* ----- END TIMELINE ----- */
302
303 /* ------ MIDI (PIANO ROLL) ---- */
304
306 int hovered_note;
307
308 /* ------ END MIDI (PIANO ROLL) ---- */
309
310 /* ------ MIDI MODIFIER ---- */
311
313 int start_vel_val;
314
323 int vel_diff;
324
325 /* ------ END MIDI MODIFIER ---- */
326
327 /* ------- CHORD ------- */
328
330 int hovered_chord_index;
331
332 /* ------- END CHORD ------- */
333
334 /* --- AUDIO --- */
335
341 float fval_at_start;
342
343 double dval_at_start;
344
345 /* --- END AUDIO --- */
346
350 int last_playhead_px;
351
353 bool redraw;
354
355 // cairo_t * cached_cr;
356
357 // cairo_surface_t * cached_surface;
358
360 graphene_rect_t last_rect;
361
368 bool can_link;
369
371 bool is_highlighted;
372
374 GdkRectangle highlight_rect;
375 // GdkRectangle prev_highlight_rect;
376 //
377
380 GdkRectangle last_selection_rect;
381
388 guint drag_start_btn;
389
397 bool first_draw;
398
401 double new_hadj_val;
402
404 Transport::Display ruler_display;
405
412 PangoLayoutUniquePtr vel_layout;
413
420 PangoLayoutUniquePtr ap_layout;
421
425 PangoLayoutUniquePtr audio_layout;
426
428 PangoLayoutUniquePtr debug_layout;
429
437 int queued_playhead_px;
438
440 GtkPopoverMenu * popover_menu;
441
442 guint unlisten_notes_timeout_id;
443};
444
445const char *
446arranger_widget_get_type_str (ArrangerWidgetType type);
447
451bool
453
458void
460 ArrangerWidget * self,
462 const std::shared_ptr<SnapGrid> &snap_grid);
463
468void
470
474int
476 ArrangerWidget * self,
477 const Position pos,
478 bool use_padding);
479
486
491void
493
497void
499 ArrangerWidget * self,
500 std::vector<ArrangerObject *> &objs_arr);
501
505Position
506arranger_widget_px_to_pos (ArrangerWidget * self, double px, bool has_padding);
507
513void
515
525void
527 ArrangerWidget * self,
528 ArrangerObject::Type type,
529 double x,
530 double y,
531 std::vector<ArrangerObject *> &arr);
532
541void
543 ArrangerWidget * self,
544 ArrangerObject::Type type,
545 GdkRectangle * rect,
546 std::vector<ArrangerObject *> &arr);
547
555ArrangerObject *
557 ArrangerWidget * self,
558 ArrangerObject::Type type,
559 const double x,
560 const double y);
561
562void
563arranger_widget_select_all (ArrangerWidget * self, bool select, bool fire_events);
564
565template <typename T = ArrangerObject>
566 requires std::derived_from<T, ArrangerObject>
567void
568arranger_widget_set_start_object (ArrangerWidget * self, std::shared_ptr<T> obj)
569{
570 self->start_object = obj->clone_unique ();
571 self->prj_start_object = obj;
572}
573
580ATTR_NONNULL bool
582
586template <typename T = ArrangerSelections>
587 requires std::derived_from<T, ArrangerSelections>
588T *
589arranger_widget_get_selections (ArrangerWidget * self) ATTR_RETURNS_NONNULL;
590
594void
596
597SnapGrid *
598arranger_widget_get_snap_grid (ArrangerWidget * self);
599
603gboolean
605 GtkEventControllerKey * key_controller,
606 guint keyval,
607 guint keycode,
608 GdkModifierType state,
609 ArrangerWidget * self);
610
611void
612arranger_widget_on_key_release (
613 GtkEventControllerKey * key_controller,
614 guint keyval,
615 guint keycode,
616 GdkModifierType state,
617 ArrangerWidget * self);
618
622void
624
632ATTR_NONNULL void
634 ArrangerWidget * self,
635 ArrangerObject * obj,
636 bool horizontal,
637 bool up,
638 bool left,
639 int padding);
640
647void
649 ArrangerWidget * self,
650 ArrangerObject * clicked_object);
651
656void
658
665void
667
671EditorSettingsPtrVariant
673
678std::unique_ptr<EditorSettings>
680
681bool
682arranger_widget_is_playhead_visible (ArrangerWidget * self);
683
684ATTR_NONNULL void
685arranger_widget_handle_playhead_auto_scroll (ArrangerWidget * self, bool force);
686
687typedef void (*ArrangerWidgetForeachFunc) (ArrangerWidget * arranger);
688
692ATTR_NONNULL void
693arranger_widget_foreach (ArrangerWidgetForeachFunc func);
694
695ATTR_NONNULL RulerWidget *
696arranger_widget_get_ruler (ArrangerWidget * self);
697
701bool
703
707int
709
710#define arranger_widget_print_action(self) z_debug ("action: {}", self->action)
711
715bool
717
723ATTR_NONNULL void
725 ArrangerWidget * self,
726 double start_x,
727 double start_y,
728 bool autofilling);
729
736ATTR_NONNULL bool
738 ArrangerWidget * self,
739 double x,
740 double y);
741
745int
747
751bool
753
760std::pair<ArrangerObject::ResizeType, bool>
762 UiOverlayAction action);
763
764extern template MidiSelections *
766extern template TimelineSelections *
768extern template ChordSelections *
770extern template AutomationSelections *
772
776
777#endif
UiOverlayAction
Various overlay actions to be shared.
Definition ui.h:117
ArrangerCursor
Definition arranger.h:30
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:67
ArrangerObject * arranger_widget_get_hit_arranger_object(ArrangerWidget *self, ArrangerObject::Type type, const double x, const double y)
Returns the ArrangerObject of the given type at (x,y).
ATTR_NONNULL void arranger_widget_foreach(ArrangerWidgetForeachFunc func)
Runs the given function for each 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.
Position arranger_widget_px_to_pos(ArrangerWidget *self, double px, bool has_padding)
Wrapper for ui_px_to_pos depending on the arranger type.
ATTR_NONNULL void arranger_widget_scroll_until_obj(ArrangerWidget *self, ArrangerObject *obj, bool horizontal, bool up, bool left, int padding)
Scroll until the given object is visible.
std::pair< ArrangerObject::ResizeType, bool > arranger_widget_get_resize_type_and_direction_from_action(UiOverlayAction action)
int arranger_widget_get_playhead_px(ArrangerWidget *self)
Returns the playhead's x coordinate in absolute coordinates.
void arranger_widget_get_hit_objects_in_rect(ArrangerWidget *self, ArrangerObject::Type type, GdkRectangle *rect, std::vector< ArrangerObject * > &arr)
Fills in the given array with the ArrangerObject's of the given type that appear in the given ranger.
bool arranger_widget_get_drum_mode_enabled(ArrangerWidget *self)
Returns true if MIDI arranger and track mode is enabled.
bool arranger_widget_is_cursor_in_top_half(ArrangerWidget *self, double y)
Returns whether the cursor at y is in the top half of the arranger.
struct _ArrangerWidget { GtkWidget parent_instance; ArrangerWidgetType type; GtkGestureDrag * drag; GtkGestureClick * click; GtkGestureClick * right_click; GtkEventControllerMotion *motion_controller; double last_offset_x; double last_offset_y; double offset_x_from_scroll; double offset_y_from_scroll; UiOverlayAction action; double start_x; double start_y; double start_pos_px; bool drag_update_started; std::unique_ptr< Position > earliest_obj_start_pos; Position fade_pos_at_start; std::unique_ptr< ArrangerObject > start_object; std::weak_ptr< ArrangerObject > prj_start_object; std::weak_ptr< ArrangerObject > hovered_object; bool start_object_was_selected; std::unique_ptr< ArrangerSelections > sel_at_start; std::unique_ptr< Region > region_at_start; std::unique_ptr< ArrangerSelections > sel_to_delete; Position start_pos; bool was_paused; Position playhead_pos_at_start; double curr_ticks_diff_from_start; double adj_ticks_diff; double last_adj_ticks_diff; Position curr_pos; Position end_pos; gboolean key_is_pressed; double hover_x; double hover_y; bool hovered; int n_press; std::shared_ptr< SnapGrid > snap_grid; int shift_held; int ctrl_held; int alt_held; gint64 last_frame_time; int visible_track_diff; int lane_diff; int visible_at_diff; int is_pinned; int resizing_range; int resizing_range_start; AutomationTrack *hovered_at; TrackLane * hovered_lane; Track * hovered_track; GdkTexture *symbolic_link_texture; GdkTexture *music_note_16th_texture; GdkTexture *fork_awesome_snowflake_texture; GdkTexture *media_playlist_repeat_texture; int region_icon_texture_size; GskRenderNode *loop_line_node; GskRenderNode *clip_start_line_node; GskRenderNode *cut_line_node; int hovered_note; int start_vel_val; int vel_diff; int hovered_chord_index; float fval_at_start; double dval_at_start; int last_playhead_px; bool redraw; graphene_rect_t last_rect; bool can_link; bool is_highlighted; GdkRectangle highlight_rect; GdkRectangle last_selection_rect; guint drag_start_btn; bool first_draw; double new_hadj_val; Transport::Display ruler_display; PangoLayoutUniquePtr vel_layout; PangoLayoutUniquePtr ap_layout; PangoLayoutUniquePtr audio_layout; PangoLayoutUniquePtr debug_layout; int queued_playhead_px; GtkPopoverMenu *popover_menu; guint unlisten_notes_timeout_id;} ArrangerWidget
A canvas widget for drawing and interacting with arranger objects.
Definition arranger.h:95
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.
int arranger_widget_pos_to_px(ArrangerWidget *self, const Position pos, bool use_padding)
Wrapper of the UI functions based on the arranger type.
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.
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_setup(ArrangerWidget *self, ArrangerWidgetType type, const std::shared_ptr< SnapGrid > &snap_grid)
Creates a timeline widget using the given timeline data.
void arranger_widget_get_visible_rect(ArrangerWidget *self, GdkRectangle *rect)
Returns the current visible rectangle.
ATTR_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...
std::unique_ptr< EditorSettings > arranger_widget_get_editor_setting_values(ArrangerWidget *self)
Get just the values, adjusted properly for special cases (like pinned timeline).
ATTR_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.
T * arranger_widget_get_selections(ArrangerWidget *self) ATTR_RETURNS_NONNULL
Returns the ArrangerSelections for this ArrangerWidget.
void arranger_widget_get_hit_objects_at_point(ArrangerWidget *self, ArrangerObject::Type type, double x, double y, std::vector< ArrangerObject * > &arr)
Fills in the given array with the ArrangerObject's of the given type that appear in the given ranger.
ATTR_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.
bool arranger_widget_can_scroll_vertically(ArrangerWidget *self)
Returns if the arranger can scroll vertically.
void arranger_widget_get_all_objects(ArrangerWidget *self, std::vector< ArrangerObject * > &objs_arr)
Get all objects currently present in the arranger.
void arranger_widget_handle_erase_action(ArrangerWidget *self)
To be called on drag_end() to handle erase actions.
EditorSettingsPtrVariant arranger_widget_get_editor_settings(ArrangerWidget *self)
Returns the EditorSettings corresponding to the given arranger.
@ None
Invalid cursor.
Definition arranger.h:32