Zrythm
a highly automated and intuitive digital audio workstation
Loading...
Searching...
No Matches
ui.h
Go to the documentation of this file.
1// SPDX-FileCopyrightText: © 2018-2024 Alexandros Theodotou <alex@zrythm.org>
2// SPDX-License-Identifier: LicenseRef-ZrythmLicense
3
11#ifndef __UTILS_UI_H__
12#define __UTILS_UI_H__
13
14#include <stdbool.h>
15
16#include "utils/localization.h"
17#include "utils/types.h"
18
19#include <adwaita.h>
20#include <glib/gi18n.h>
21#include <gtk/gtk.h>
22
23typedef struct Position Position;
24typedef struct Port Port;
25
32#define UI_MAX_CURSORS 400
33
34#define UI_CACHES (zrythm_app->ui_caches)
35#define UI_COLORS (&UI_CACHES->colors)
36
37/* copied from css */
38#define UI_COLOR_DARK_TEXT "#323232"
39#define UI_COLOR_BRIGHT_TEXT "#cdcdcd"
40#define UI_COLOR_YELLOW "#F9CA1B"
41#define UI_COLOR_PURPLE "#9D3955"
42#define UI_COLOR_BUTTON_NORMAL "#343434"
43#define UI_COLOR_BUTTON_HOVER "#444444"
44#define UI_COLOR_RECORD_CHECKED "#ED2939"
45#define UI_COLOR_RECORD_ACTIVE "#FF2400"
46#define UI_COLOR_BRIGHT_GREEN "#1DD169"
47#define UI_COLOR_DARKISH_GREEN "#19664c"
48#define UI_COLOR_DARK_ORANGE "#D68A0C"
49#define UI_COLOR_Z_YELLOW "#F9CA1B"
50#define UI_COLOR_BRIGHT_ORANGE "#F79616"
51#define UI_COLOR_Z_PURPLE "#9D3955"
52#define UI_COLOR_MATCHA "#2eb398"
53#define UI_COLOR_LIGHT_BLUEISH "#1aa3ffcc"
54#define UI_COLOR_PREFADER_SEND "#D21E6D"
55#define UI_COLOR_POSTFADER_SEND "#901ed2"
56#define UI_COLOR_SOLO_ACTIVE UI_COLOR_MATCHA
57#define UI_COLOR_SOLO_CHECKED UI_COLOR_DARKISH_GREEN
58#define UI_COLOR_HIGHLIGHT_SCALE_BG "#662266"
59#define UI_COLOR_HIGHLIGHT_CHORD_BG "#BB22BB"
60#define UI_COLOR_HIGHLIGHT_BASS_BG UI_COLOR_LIGHT_BLUEISH
61#define UI_COLOR_HIGHLIGHT_BOTH_BG "#FF22FF"
62#define UI_COLOR_HIGHLIGHT_SCALE_FG "#F79616"
63#define UI_COLOR_HIGHLIGHT_CHORD_FG UI_COLOR_HIGHLIGHT_SCALE_FG
64#define UI_COLOR_HIGHLIGHT_BASS_FG "white"
65#define UI_COLOR_HIGHLIGHT_BOTH_FG "white"
66#define UI_COLOR_FADER_FILL_END UI_COLOR_Z_YELLOW
67
68#define UI_DELETE_ICON_NAME "z-edit-delete"
69
70static const GdkRGBA UI_COLOR_BLACK = { 0, 0, 0, 1 };
71
72typedef enum UiDetail
73{
74 UI_DETAIL_HIGH,
75 UI_DETAIL_NORMAL,
76 UI_DETAIL_LOW,
77 UI_DETAIL_ULTRA_LOW,
78} UiDetail;
79
80static const char * ui_detail_str[] = {
81 N_ ("High"),
82 N_ ("Normal"),
83 N_ ("Low"),
84 N_ ("Ultra Low"),
85};
86
87static inline const char *
88ui_detail_to_string (UiDetail detail)
89{
90 return ui_detail_str[detail];
91}
92
96typedef struct UiColors
97{
98 GdkRGBA dark_text;
99 GdkRGBA dark_orange;
100 GdkRGBA bright_orange;
101 GdkRGBA bright_text;
102 GdkRGBA matcha;
103 GdkRGBA bright_green;
104 GdkRGBA darkish_green;
105 GdkRGBA prefader_send;
106 GdkRGBA postfader_send;
107 GdkRGBA record_active;
108 GdkRGBA record_checked;
109 GdkRGBA solo_active;
110 GdkRGBA solo_checked;
111 GdkRGBA fader_fill_start;
112 GdkRGBA fader_fill_end;
113 GdkRGBA highlight_scale_bg;
114 GdkRGBA highlight_chord_bg;
115 GdkRGBA highlight_bass_bg;
116 GdkRGBA highlight_both_bg;
117 GdkRGBA highlight_scale_fg;
118 GdkRGBA highlight_chord_fg;
119 GdkRGBA highlight_bass_fg;
120 GdkRGBA highlight_both_fg;
121 GdkRGBA z_yellow;
122 GdkRGBA z_purple;
123} UiColors;
124
128typedef struct UiTextures
129{
130} UiTextures;
131
137typedef struct UiCursor
138{
139 char name[400];
140 GdkCursor * cursor;
141 int offset_x;
142 int offset_y;
143} UiCursor;
144
148typedef struct UiCaches
149{
150 UiColors colors;
151 // UiTextures textures;
152 UiCursor cursors[UI_MAX_CURSORS];
153 int num_cursors;
154
155 bool detail_level_set;
156 UiDetail detail_level;
157} UiCaches;
158
162#define UI_RESIZE_CURSOR_SPACE 8
163
164/*
165 * Drag n Drop related.
166 * Gtk target entries.
167 */
168
171#define TARGET_ENTRY_PLUGIN_DESCR "PLUGIN_DESCR"
172
174#define TARGET_ENTRY_SUPPORTED_FILE "SUPPORTED_FILE"
175
177#define TARGET_ENTRY_PLUGIN "PLUGIN"
178
179/* File path. Not used at the moment. */
180#define TARGET_ENTRY_FILE_PATH "FILE_PATH"
181
183#define TARGET_ENTRY_URI_LIST "text/uri-list"
184
191#define TARGET_ENTRY_TRACK "TRACK"
192
196#define TARGET_ENTRY_CHORD_DESCR "CHORD_DESCR"
197
198/* */
199#define TARGET_ENTRY_TL_SELECTIONS "TL_SELECTIONS"
200
201#define GET_ATOM(x) gdk_atom_intern (x, 1)
202
203#define ui_add_widget_tooltip(widget, txt) \
204 gtk_widget_set_tooltip_text (GTK_WIDGET (widget), txt)
205
206#define ui_set_hover_status_bar_signals(w, t) \
207 g_signal_connect ( \
208 G_OBJECT (w), "enter-notify-event", \
209 G_CALLBACK (ui_on_motion_set_status_bar_text_cb), g_strdup (t)); \
210 g_signal_connect ( \
211 G_OBJECT (w), "leave-notify-event", \
212 G_CALLBACK (ui_on_motion_set_status_bar_text_cb), g_strdup (t));
213
219#define ui_show_notification_idle_printf(fmt, ...) \
220 char * text = g_strdup_printf (fmt, __VA_ARGS__); \
221 g_idle_add ((GSourceFunc) ui_show_notification_idle_func, (void *) text)
222
223#define ui_show_notification_idle(msg) \
224 ui_show_notification_idle_printf ("%s", msg)
225
226#define ui_is_widget_revealed(widget) \
227 (gtk_widget_get_height (GTK_WIDGET (widget)) > 1 \
228 || gtk_widget_get_width (GTK_WIDGET (widget)) > 1)
229
233typedef enum UiCursorState
234{
235 UI_CURSOR_STATE_DEFAULT,
236 UI_CURSOR_STATE_RESIZE_L,
237 UI_CURSOR_STATE_REPEAT_L,
238 UI_CURSOR_STATE_RESIZE_R,
239 UI_CURSOR_STATE_REPEAT_R,
240 UI_CURSOR_STATE_RESIZE_UP,
242
246typedef enum UiOverlayAction
247{
248 UI_OVERLAY_ACTION_NONE,
249 UI_OVERLAY_ACTION_CREATING_RESIZING_R,
250 UI_OVERLAY_ACTION_CREATING_MOVING,
251 UI_OVERLAY_ACTION_RESIZING_L,
252 UI_OVERLAY_ACTION_RESIZING_L_LOOP,
253 UI_OVERLAY_ACTION_RESIZING_L_FADE,
254 UI_OVERLAY_ACTION_RESIZING_R,
255 UI_OVERLAY_ACTION_RESIZING_R_LOOP,
256 UI_OVERLAY_ACTION_RESIZING_R_FADE,
257 UI_OVERLAY_ACTION_RESIZING_UP,
258 UI_OVERLAY_ACTION_RESIZING_UP_FADE_IN,
259 UI_OVERLAY_ACTION_RESIZING_UP_FADE_OUT,
260 UI_OVERLAY_ACTION_STRETCHING_L,
261 UI_OVERLAY_ACTION_STRETCHING_R,
262
263 UI_OVERLAY_ACTION_STARTING_AUDITIONING,
264 UI_OVERLAY_ACTION_AUDITIONING,
265
273
276 UI_OVERLAY_ACTION_STARTING_ERASING,
277
282 UI_OVERLAY_ACTION_STARTING_MOVING_COPY,
283 UI_OVERLAY_ACTION_STARTING_MOVING_LINK,
284 UI_OVERLAY_ACTION_MOVING,
285 UI_OVERLAY_ACTION_MOVING_COPY,
286 UI_OVERLAY_ACTION_MOVING_LINK,
287 UI_OVERLAY_ACTION_STARTING_CHANGING_CURVE,
288 UI_OVERLAY_ACTION_CHANGING_CURVE,
289
296 UI_OVERLAY_ACTION_SELECTING,
297
301 UI_OVERLAY_ACTION_DELETE_SELECTING,
302
303 UI_OVERLAY_ACTION_STARTING_RAMP,
304 UI_OVERLAY_ACTION_RAMPING,
305 UI_OVERLAY_ACTION_CUTTING,
306
307 UI_OVERLAY_ACTION_RENAMING,
308
309 UI_OVERLAY_ACTION_STARTING_PANNING,
310 UI_OVERLAY_ACTION_PANNING,
311 NUM_UI_OVERLAY_ACTIONS,
313
317static const char * ui_overlay_strings[] = {
318 "NONE",
319 "RESIZING_R",
320 "MOVING",
321 "RESIZING_L",
322 "RESIZING_L_LOOP",
323 "RESIZING_L_FADE",
324 "RESIZING_R",
325 "RESIZING_R_LOOP",
326 "RESIZING_R_FADE",
327 "RESIZING_UP",
328 "RESIZING_UP_FADE_IN",
329 "RESIZING_UP_FADE_OUT",
330 "STRETCHING_L",
331 "STRETCHING_R",
332 "STARTING_AUDITIONING",
333 "AUDITIONING",
334 "AUTOFILLING",
335 "ERASING",
336 "STARTING_ERASING",
337 "STARTING_MOVING",
338 "STARTING_MOVING_COPY",
339 "STARTING_MOVING_LINK",
340 "MOVING",
341 "MOVING_COPY",
342 "MOVING_LINK",
343 "STARTING_CHANGING_CURVE",
344 "CHANGING_CURVE",
345 "STARTING_SELECTION",
346 "SELECTING",
347 "STARTING_DELETE_SELECTION",
348 "DELETE_SELECTING",
349 "STARTING_RAMP",
350 "RAMPING",
351 "CUTTING",
352 "RENAMING",
353 "STARTING_PANNING",
354 "PANNING",
355 "--INVALID--",
356};
357
358static inline const char *
359ui_get_overlay_action_string (UiOverlayAction action)
360{
361 return ui_overlay_strings[action];
362}
363
379
380void
381ui_set_pointer_cursor (GtkWidget * widget);
382
383#define ui_set_pencil_cursor(widget) \
384 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "edit-cursor", 2, 3);
385
386#define ui_set_brush_cursor(widget) \
387 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "brush-cursor", 2, 3);
388
389#define ui_set_cut_clip_cursor(widget) \
390 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "cut-cursor", 9, 7);
391
392#define ui_set_eraser_cursor(widget) \
393 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "eraser-cursor", 4, 2);
394
395#define ui_set_line_cursor(widget) \
396 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "ramp-cursor", 2, 3);
397
398#define ui_set_speaker_cursor(widget) \
399 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "audition-cursor", 10, 12);
400
401#define ui_set_hand_cursor(widget) \
402 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "move-cursor", 12, 11);
403
404#define ui_set_left_resize_cursor(widget) \
405 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "w-resize-cursor", 14, 11);
406
407#define ui_set_left_stretch_cursor(widget) \
408 ui_set_cursor_from_icon_name ( \
409 GTK_WIDGET (widget), "w-stretch-cursor", 14, 11);
410
411#define ui_set_left_resize_loop_cursor(widget) \
412 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "w-loop-cursor", 14, 11);
413
414#define ui_set_right_resize_cursor(widget) \
415 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "e-resize-cursor", 10, 11);
416
417#define ui_set_right_stretch_cursor(widget) \
418 ui_set_cursor_from_icon_name ( \
419 GTK_WIDGET (widget), "e-stretch-cursor", 10, 11);
420
421#define ui_set_right_resize_loop_cursor(widget) \
422 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "e-loop-cursor", 10, 11);
423
424#define ui_set_time_select_cursor(widget) \
425 ui_set_cursor_from_icon_name ( \
426 GTK_WIDGET (widget), "time-select-cursor", 10, 12);
427
428#define ui_set_fade_in_cursor(widget) \
429 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "fade-in-cursor", 3, 1);
430
431#define ui_set_fade_out_cursor(widget) \
432 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "fade-out-cursor", 3, 1);
433
437void
439 GtkWidget * widget,
440 const char * name,
441 int offset_x,
442 int offset_y);
443
447void
448ui_set_cursor_from_name (GtkWidget * widget, const char * name);
449
450gboolean
451ui_on_motion_set_status_bar_text_cb (
452 GtkWidget * widget,
453 GdkEvent * event,
454 char * text);
455
464AdwDialog *
466 GtkWidget * parent,
467 const char * title,
468 const char * format,
469 ...) G_GNUC_PRINTF (3, 4);
470
471#define UI_ACTIVE_WINDOW_OR_NULL \
472 (gtk_application_get_active_window (GTK_APPLICATION (zrythm_app)) \
473 ? GTK_WIDGET ( \
474 gtk_application_get_active_window (GTK_APPLICATION (zrythm_app))) \
475 : NULL)
476
480#define ui_show_message_printf(title, fmt, ...) \
481 ui_show_message_full ( \
482 GTK_WIDGET (UI_ACTIVE_WINDOW_OR_NULL), title, fmt, __VA_ARGS__)
483
487#define ui_show_message_literal(title, str) \
488 ui_show_message_full (GTK_WIDGET (UI_ACTIVE_WINDOW_OR_NULL), title, "%s", str)
489
494#define ui_show_error_message_printf(title, fmt, ...) \
495 ui_show_message_printf (title, fmt, __VA_ARGS__);
496
497#define ui_show_error_message(title, msg) ui_show_message_literal (title, msg)
498
516bool
518 GdkRectangle * rect,
519 const bool check_x,
520 const bool check_y,
521 double x,
522 double y,
523 double x_padding,
524 double y_padding);
525
543NONNULL int
545 GtkWidget * parent,
546 GtkWidget * child,
547 const int check_x,
548 const int check_y,
549 const double x,
550 const double y,
551 const double x_padding,
552 const double y_padding);
553
561GtkWidget *
562ui_get_hit_child (GtkWidget * parent, double x, double y, GType type);
563
564UiDetail
565ui_get_detail_level (void);
566
578NONNULL void
579ui_px_to_pos_timeline (double px, Position * pos, bool has_padding);
580
589ui_px_to_frames_timeline (double px, bool has_padding);
590
599ui_px_to_frames_editor (double px, bool has_padding);
600
605NONNULL int
606ui_pos_to_px_timeline (const Position * pos, int use_padding);
607
612NONNULL int
613ui_pos_to_px_editor (const Position * pos, bool use_padding);
614
626NONNULL void
627ui_px_to_pos_editor (double px, Position * pos, bool has_padding);
628
632void
633ui_rgb_to_hex (double red, double green, double blue, char * buf);
634
635void
636ui_gdk_rgba_to_hex (GdkRGBA * color, char * buf);
637
641void
642ui_show_notification (const char * msg);
643
650int
652
657void
658ui_setup_language_combo_row (AdwComboRow * combo_row);
659
666AdwComboRow *
668
675AdwComboRow *
677
684void
686 AdwComboRow * combo_row,
687 bool populate,
688 bool with_signal);
689
693void
694ui_setup_vst_paths_entry (GtkEntry * entry);
695
700void
702
709char *
710ui_get_locale_not_available_string (LocalizationLanguage lang);
711
712void
713ui_show_warning_for_tempo_track_experimental_feature (void);
714
723void
724ui_get_contrast_color (GdkRGBA * src, GdkRGBA * dest);
725
732void
734 GdkRGBA * dest,
735 const GdkRGBA * c1,
736 const GdkRGBA * c2,
737 const float transition);
738
742NONNULL PURE static inline bool
743ui_rectangle_overlap (
744 const GdkRectangle * const rect1,
745 const GdkRectangle * const rect2)
746{
747 /* if one rect is on the side of the other */
748 if (rect1->x > rect2->x + rect2->width || rect2->x > rect1->x + rect1->width)
749 return false;
750
751 /* if one rect is above the other */
752 if (rect1->y > rect2->y + rect2->height || rect2->y > rect1->y + rect1->height)
753 return false;
754
755 return true;
756}
757
765void
767 GdkRGBA * color,
768 const bool is_hovered,
769 const bool is_selected,
770 const bool is_transient,
771 const bool is_muted);
772
782double
784 double size,
785 double cur_val,
786 double start_px,
787 double cur_px,
788 double last_px,
789 double multiplier,
790 UiDragMode mode);
791
796void
797ui_get_db_value_as_string (float val, char * buf);
798
799UiCaches *
800ui_caches_new (void);
801
802void
803ui_caches_free (UiCaches * self);
804
809#endif
double ui_get_normalized_draggable_value(double size, double cur_val, double start_px, double cur_px, double last_px, double multiplier, UiDragMode mode)
Gets a draggable value as a normalized value between 0 and 1.
AdwComboRow * ui_gen_audio_backends_combo_row(bool with_signal)
Generates a combo row for selecting the audio backend.
void ui_set_cursor_from_name(GtkWidget *widget, const char *name)
Sets cursor from standard cursor name.
void ui_setup_audio_device_name_combo_row(AdwComboRow *combo_row, bool populate, bool with_signal)
Sets up a combo row for selecting the audio device name.
char * ui_get_locale_not_available_string(LocalizationLanguage lang)
Returns the "a locale for the language you have selected..." text based on the given language.
UiCursorState
Various cursor states to be shared.
Definition ui.h:234
void ui_rgb_to_hex(double red, double green, double blue, char *buf)
Converts RGB to hex string.
NONNULL int ui_pos_to_px_timeline(const Position *pos, int use_padding)
Converts position to px, optionally adding the ruler padding.
int_fast64_t signed_frame_t
Signed type for frame index.
Definition types.h:55
signed_frame_t ui_px_to_frames_editor(double px, bool has_padding)
Converts from pixels to frames.
UiDragMode
Dragging modes for widgets that have click&drag.
Definition ui.h:368
int ui_show_notification_idle_func(char *msg)
Show notification from non-GTK threads.
void ui_setup_vst_paths_entry(GtkEntry *entry)
Sets up the VST paths entry.
GtkWidget * ui_get_hit_child(GtkWidget *parent, double x, double y, GType type)
Returns the matching hit child, or NULL.
void ui_get_contrast_color(GdkRGBA *src, GdkRGBA *dest)
Returns the contrasting color (variation of black or white) based on if the given color is dark enoug...
NONNULL void ui_px_to_pos_editor(double px, Position *pos, bool has_padding)
Converts from pixels to position.
AdwComboRow * ui_gen_midi_backends_combo_row(bool with_signal)
Generates a combo row for selecting the MIDI backend.
UiOverlayAction
Various overlay actions to be shared.
Definition ui.h:247
bool ui_is_point_in_rect_hit(GdkRectangle *rect, const bool check_x, const bool check_y, double x, double y, double x_padding, double y_padding)
Returns if rect is hit or not by the given coordinate.
void ui_setup_language_combo_row(AdwComboRow *combo_row)
Sets up a combo box to have a selection of languages.
NONNULL int ui_is_child_hit(GtkWidget *parent, GtkWidget *child, const int check_x, const int check_y, const double x, const double y, const double x_padding, const double y_padding)
Returns if the child is hit or not by the coordinates in parent.
AdwDialog * ui_show_message_full(GtkWidget *parent, const char *title, const char *format,...) G_GNUC_PRINTF(3
Shows a popup message of the given type with the given message.
NONNULL int ui_pos_to_px_editor(const Position *pos, bool use_padding)
Converts position to px, optionally adding the ruler padding.
void ui_set_cursor_from_icon_name(GtkWidget *widget, const char *name, int offset_x, int offset_y)
Sets cursor from icon name.
signed_frame_t ui_px_to_frames_timeline(double px, bool has_padding)
Converts from pixels to frames.
NONNULL void ui_px_to_pos_timeline(double px, Position *pos, bool has_padding)
Converts from pixels to position.
void ui_get_db_value_as_string(float val, char *buf)
Returns an appropriate string representation of the given dB value.
void ui_show_notification(const char *msg)
Shows a notification in the revealer.
void ui_get_mid_color(GdkRGBA *dest, const GdkRGBA *c1, const GdkRGBA *c2, const float transition)
Returns the color in-between two colors.
void ui_get_arranger_object_color(GdkRGBA *color, const bool is_hovered, const bool is_selected, const bool is_transient, const bool is_muted)
Gets the color the widget should be.
void ui_update_vst_paths_from_entry(GtkEntry *entry)
Updates the the VST paths in the gsettings from the text in the entry.
@ UI_DRAG_MODE_CURSOR
Value is wherever the cursor is.
Definition ui.h:370
@ UI_DRAG_MODE_RELATIVE
Value is changed based on the offset.
Definition ui.h:373
@ UI_DRAG_MODE_RELATIVE_WITH_MULTIPLIER
Value is changed based on the offset, times a multiplier.
Definition ui.h:377
@ UI_OVERLAY_ACTION_AUTOFILLING
Auto-filling in edit mode.
Definition ui.h:272
@ UI_OVERLAY_ACTION_STARTING_DELETE_SELECTION
Like selecting but it auto deletes whatever touches the selection.
Definition ui.h:300
@ UI_OVERLAY_ACTION_STARTING_SELECTION
To be set in drag_start.
Definition ui.h:295
@ UI_OVERLAY_ACTION_STARTING_MOVING
To be set in drag_start.
Definition ui.h:281
@ UI_OVERLAY_ACTION_ERASING
Erasing.
Definition ui.h:275
Must ONLY be created via port_new()
Definition port.h:140
A Position is made up of bars.beats.sixteenths.ticks.
Definition position.h:129
Caches.
Definition ui.h:149
Commonly used UI colors.
Definition ui.h:97
Specification for a cursor.
Definition ui.h:138
Commonly used UI textures.
Definition ui.h:129
Custom types.