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 "utils/localization.h"
15#include "utils/types.h"
16
17#include <adwaita.h>
18#include <glib/gi18n.h>
19
20#include "gtk_wrapper.h"
21
22typedef struct Position Position;
23typedef struct Port Port;
24
31#define UI_MAX_CURSORS 400
32
33#define UI_CACHES (zrythm_app->ui_caches)
34#define UI_COLORS (&UI_CACHES->colors)
35
36/* copied from css */
37#define UI_COLOR_DARK_TEXT "#323232"
38#define UI_COLOR_BRIGHT_TEXT "#cdcdcd"
39#define UI_COLOR_YELLOW "#F9CA1B"
40#define UI_COLOR_PURPLE "#9D3955"
41#define UI_COLOR_BUTTON_NORMAL "#343434"
42#define UI_COLOR_BUTTON_HOVER "#444444"
43#define UI_COLOR_RECORD_CHECKED "#ED2939"
44#define UI_COLOR_RECORD_ACTIVE "#FF2400"
45#define UI_COLOR_BRIGHT_GREEN "#1DD169"
46#define UI_COLOR_DARKISH_GREEN "#19664c"
47#define UI_COLOR_DARK_ORANGE "#D68A0C"
48#define UI_COLOR_Z_YELLOW "#F9CA1B"
49#define UI_COLOR_BRIGHT_ORANGE "#F79616"
50#define UI_COLOR_Z_PURPLE "#9D3955"
51#define UI_COLOR_MATCHA "#2eb398"
52#define UI_COLOR_LIGHT_BLUEISH "#1aa3ffcc"
53#define UI_COLOR_PREFADER_SEND "#D21E6D"
54#define UI_COLOR_POSTFADER_SEND "#901ed2"
55#define UI_COLOR_SOLO_ACTIVE UI_COLOR_MATCHA
56#define UI_COLOR_SOLO_CHECKED UI_COLOR_DARKISH_GREEN
57#define UI_COLOR_HIGHLIGHT_SCALE_BG "#662266"
58#define UI_COLOR_HIGHLIGHT_CHORD_BG "#BB22BB"
59#define UI_COLOR_HIGHLIGHT_BASS_BG UI_COLOR_LIGHT_BLUEISH
60#define UI_COLOR_HIGHLIGHT_BOTH_BG "#FF22FF"
61#define UI_COLOR_HIGHLIGHT_SCALE_FG "#F79616"
62#define UI_COLOR_HIGHLIGHT_CHORD_FG UI_COLOR_HIGHLIGHT_SCALE_FG
63#define UI_COLOR_HIGHLIGHT_BASS_FG "white"
64#define UI_COLOR_HIGHLIGHT_BOTH_FG "white"
65#define UI_COLOR_FADER_FILL_END UI_COLOR_Z_YELLOW
66
67#define UI_DELETE_ICON_NAME "z-edit-delete"
68
69static const GdkRGBA UI_COLOR_BLACK = { 0, 0, 0, 1 };
70
71typedef enum UiDetail
72{
73 UI_DETAIL_HIGH,
74 UI_DETAIL_NORMAL,
75 UI_DETAIL_LOW,
76 UI_DETAIL_ULTRA_LOW,
77} UiDetail;
78
79static const char * ui_detail_str[] = {
80 N_ ("High"),
81 N_ ("Normal"),
82 N_ ("Low"),
83 N_ ("Ultra Low"),
84};
85
86static inline const char *
87ui_detail_to_string (UiDetail detail)
88{
89 return ui_detail_str[detail];
90}
91
95typedef struct UiColors
96{
97 GdkRGBA dark_text;
98 GdkRGBA dark_orange;
99 GdkRGBA bright_orange;
100 GdkRGBA bright_text;
101 GdkRGBA matcha;
102 GdkRGBA bright_green;
103 GdkRGBA darkish_green;
104 GdkRGBA prefader_send;
105 GdkRGBA postfader_send;
106 GdkRGBA record_active;
107 GdkRGBA record_checked;
108 GdkRGBA solo_active;
109 GdkRGBA solo_checked;
110 GdkRGBA fader_fill_start;
111 GdkRGBA fader_fill_end;
112 GdkRGBA highlight_scale_bg;
113 GdkRGBA highlight_chord_bg;
114 GdkRGBA highlight_bass_bg;
115 GdkRGBA highlight_both_bg;
116 GdkRGBA highlight_scale_fg;
117 GdkRGBA highlight_chord_fg;
118 GdkRGBA highlight_bass_fg;
119 GdkRGBA highlight_both_fg;
120 GdkRGBA z_yellow;
121 GdkRGBA z_purple;
122} UiColors;
123
127typedef struct UiTextures
128{
129} UiTextures;
130
136typedef struct UiCursor
137{
138 char name[400];
139 GdkCursor * cursor;
140 int offset_x;
141 int offset_y;
142} UiCursor;
143
147typedef struct UiCaches
148{
149 UiColors colors;
150 // UiTextures textures;
151 UiCursor cursors[UI_MAX_CURSORS];
152 int num_cursors;
153
154 bool detail_level_set;
155 UiDetail detail_level;
156} UiCaches;
157
161#define UI_RESIZE_CURSOR_SPACE 8
162
163/*
164 * Drag n Drop related.
165 * Gtk target entries.
166 */
167
170#define TARGET_ENTRY_PLUGIN_DESCR "PLUGIN_DESCR"
171
173#define TARGET_ENTRY_SUPPORTED_FILE "SUPPORTED_FILE"
174
176#define TARGET_ENTRY_PLUGIN "PLUGIN"
177
178/* File path. Not used at the moment. */
179#define TARGET_ENTRY_FILE_PATH "FILE_PATH"
180
182#define TARGET_ENTRY_URI_LIST "text/uri-list"
183
190#define TARGET_ENTRY_TRACK "TRACK"
191
195#define TARGET_ENTRY_CHORD_DESCR "CHORD_DESCR"
196
197/* */
198#define TARGET_ENTRY_TL_SELECTIONS "TL_SELECTIONS"
199
200#define GET_ATOM(x) gdk_atom_intern (x, 1)
201
202#define ui_add_widget_tooltip(widget, txt) \
203 gtk_widget_set_tooltip_text (GTK_WIDGET (widget), txt)
204
205#define ui_set_hover_status_bar_signals(w, t) \
206 g_signal_connect ( \
207 G_OBJECT (w), "enter-notify-event", \
208 G_CALLBACK (ui_on_motion_set_status_bar_text_cb), g_strdup (t)); \
209 g_signal_connect ( \
210 G_OBJECT (w), "leave-notify-event", \
211 G_CALLBACK (ui_on_motion_set_status_bar_text_cb), g_strdup (t));
212
218#define ui_show_notification_idle_printf(fmt, ...) \
219 char * text = g_strdup_printf (fmt, __VA_ARGS__); \
220 g_idle_add ((GSourceFunc) ui_show_notification_idle_func, (void *) text)
221
222#define ui_show_notification_idle(msg) \
223 ui_show_notification_idle_printf ("%s", msg)
224
225#define ui_is_widget_revealed(widget) \
226 (gtk_widget_get_height (GTK_WIDGET (widget)) > 1 \
227 || gtk_widget_get_width (GTK_WIDGET (widget)) > 1)
228
232typedef enum UiCursorState
233{
234 UI_CURSOR_STATE_DEFAULT,
235 UI_CURSOR_STATE_RESIZE_L,
236 UI_CURSOR_STATE_REPEAT_L,
237 UI_CURSOR_STATE_RESIZE_R,
238 UI_CURSOR_STATE_REPEAT_R,
239 UI_CURSOR_STATE_RESIZE_UP,
241
245typedef enum UiOverlayAction
246{
247 UI_OVERLAY_ACTION_NONE,
248 UI_OVERLAY_ACTION_CREATING_RESIZING_R,
249 UI_OVERLAY_ACTION_CREATING_MOVING,
250 UI_OVERLAY_ACTION_RESIZING_L,
251 UI_OVERLAY_ACTION_RESIZING_L_LOOP,
252 UI_OVERLAY_ACTION_RESIZING_L_FADE,
253 UI_OVERLAY_ACTION_RESIZING_R,
254 UI_OVERLAY_ACTION_RESIZING_R_LOOP,
255 UI_OVERLAY_ACTION_RESIZING_R_FADE,
256 UI_OVERLAY_ACTION_RESIZING_UP,
257 UI_OVERLAY_ACTION_RESIZING_UP_FADE_IN,
258 UI_OVERLAY_ACTION_RESIZING_UP_FADE_OUT,
259 UI_OVERLAY_ACTION_STRETCHING_L,
260 UI_OVERLAY_ACTION_STRETCHING_R,
261
262 UI_OVERLAY_ACTION_STARTING_AUDITIONING,
263 UI_OVERLAY_ACTION_AUDITIONING,
264
272
275 UI_OVERLAY_ACTION_STARTING_ERASING,
276
281 UI_OVERLAY_ACTION_STARTING_MOVING_COPY,
282 UI_OVERLAY_ACTION_STARTING_MOVING_LINK,
283 UI_OVERLAY_ACTION_MOVING,
284 UI_OVERLAY_ACTION_MOVING_COPY,
285 UI_OVERLAY_ACTION_MOVING_LINK,
286 UI_OVERLAY_ACTION_STARTING_CHANGING_CURVE,
287 UI_OVERLAY_ACTION_CHANGING_CURVE,
288
295 UI_OVERLAY_ACTION_SELECTING,
296
300 UI_OVERLAY_ACTION_DELETE_SELECTING,
301
302 UI_OVERLAY_ACTION_STARTING_RAMP,
303 UI_OVERLAY_ACTION_RAMPING,
304 UI_OVERLAY_ACTION_CUTTING,
305
306 UI_OVERLAY_ACTION_RENAMING,
307
308 UI_OVERLAY_ACTION_STARTING_PANNING,
309 UI_OVERLAY_ACTION_PANNING,
310 NUM_UI_OVERLAY_ACTIONS,
312
316static const char * ui_overlay_strings[] = {
317 "NONE",
318 "RESIZING_R",
319 "MOVING",
320 "RESIZING_L",
321 "RESIZING_L_LOOP",
322 "RESIZING_L_FADE",
323 "RESIZING_R",
324 "RESIZING_R_LOOP",
325 "RESIZING_R_FADE",
326 "RESIZING_UP",
327 "RESIZING_UP_FADE_IN",
328 "RESIZING_UP_FADE_OUT",
329 "STRETCHING_L",
330 "STRETCHING_R",
331 "STARTING_AUDITIONING",
332 "AUDITIONING",
333 "AUTOFILLING",
334 "ERASING",
335 "STARTING_ERASING",
336 "STARTING_MOVING",
337 "STARTING_MOVING_COPY",
338 "STARTING_MOVING_LINK",
339 "MOVING",
340 "MOVING_COPY",
341 "MOVING_LINK",
342 "STARTING_CHANGING_CURVE",
343 "CHANGING_CURVE",
344 "STARTING_SELECTION",
345 "SELECTING",
346 "STARTING_DELETE_SELECTION",
347 "DELETE_SELECTING",
348 "STARTING_RAMP",
349 "RAMPING",
350 "CUTTING",
351 "RENAMING",
352 "STARTING_PANNING",
353 "PANNING",
354 "--INVALID--",
355};
356
357static inline const char *
358ui_get_overlay_action_string (UiOverlayAction action)
359{
360 return ui_overlay_strings[action];
361}
362
378
379void
380ui_set_pointer_cursor (GtkWidget * widget);
381
382#define ui_set_pencil_cursor(widget) \
383 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "edit-cursor", 2, 3);
384
385#define ui_set_brush_cursor(widget) \
386 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "brush-cursor", 2, 3);
387
388#define ui_set_cut_clip_cursor(widget) \
389 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "cut-cursor", 9, 7);
390
391#define ui_set_eraser_cursor(widget) \
392 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "eraser-cursor", 4, 2);
393
394#define ui_set_line_cursor(widget) \
395 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "ramp-cursor", 2, 3);
396
397#define ui_set_speaker_cursor(widget) \
398 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "audition-cursor", 10, 12);
399
400#define ui_set_hand_cursor(widget) \
401 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "move-cursor", 12, 11);
402
403#define ui_set_left_resize_cursor(widget) \
404 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "w-resize-cursor", 14, 11);
405
406#define ui_set_left_stretch_cursor(widget) \
407 ui_set_cursor_from_icon_name ( \
408 GTK_WIDGET (widget), "w-stretch-cursor", 14, 11);
409
410#define ui_set_left_resize_loop_cursor(widget) \
411 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "w-loop-cursor", 14, 11);
412
413#define ui_set_right_resize_cursor(widget) \
414 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "e-resize-cursor", 10, 11);
415
416#define ui_set_right_stretch_cursor(widget) \
417 ui_set_cursor_from_icon_name ( \
418 GTK_WIDGET (widget), "e-stretch-cursor", 10, 11);
419
420#define ui_set_right_resize_loop_cursor(widget) \
421 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "e-loop-cursor", 10, 11);
422
423#define ui_set_time_select_cursor(widget) \
424 ui_set_cursor_from_icon_name ( \
425 GTK_WIDGET (widget), "time-select-cursor", 10, 12);
426
427#define ui_set_fade_in_cursor(widget) \
428 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "fade-in-cursor", 3, 1);
429
430#define ui_set_fade_out_cursor(widget) \
431 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "fade-out-cursor", 3, 1);
432
436void
438 GtkWidget * widget,
439 const char * name,
440 int offset_x,
441 int offset_y);
442
446void
447ui_set_cursor_from_name (GtkWidget * widget, const char * name);
448
449gboolean
450ui_on_motion_set_status_bar_text_cb (
451 GtkWidget * widget,
452 GdkEvent * event,
453 char * text);
454
463AdwDialog *
465 GtkWidget * parent,
466 const char * title,
467 const char * format,
468 ...) G_GNUC_PRINTF (3, 4);
469
470#define UI_ACTIVE_WINDOW_OR_NULL \
471 (gtk_application_get_active_window (GTK_APPLICATION (zrythm_app)) \
472 ? GTK_WIDGET ( \
473 gtk_application_get_active_window (GTK_APPLICATION (zrythm_app))) \
474 : NULL)
475
479#define ui_show_message_printf(title, fmt, ...) \
480 ui_show_message_full ( \
481 GTK_WIDGET (UI_ACTIVE_WINDOW_OR_NULL), title, fmt, __VA_ARGS__)
482
486#define ui_show_message_literal(title, str) \
487 ui_show_message_full (GTK_WIDGET (UI_ACTIVE_WINDOW_OR_NULL), title, "%s", str)
488
493#define ui_show_error_message_printf(title, fmt, ...) \
494 ui_show_message_printf (title, fmt, __VA_ARGS__);
495
496#define ui_show_error_message(title, msg) ui_show_message_literal (title, msg)
497
515bool
517 GdkRectangle * rect,
518 const bool check_x,
519 const bool check_y,
520 double x,
521 double y,
522 double x_padding,
523 double y_padding);
524
542NONNULL int
544 GtkWidget * parent,
545 GtkWidget * child,
546 const int check_x,
547 const int check_y,
548 const double x,
549 const double y,
550 const double x_padding,
551 const double y_padding);
552
560GtkWidget *
561ui_get_hit_child (GtkWidget * parent, double x, double y, GType type);
562
563UiDetail
564ui_get_detail_level (void);
565
577NONNULL void
578ui_px_to_pos_timeline (double px, Position * pos, bool has_padding);
579
588ui_px_to_frames_timeline (double px, bool has_padding);
589
598ui_px_to_frames_editor (double px, bool has_padding);
599
604NONNULL int
605ui_pos_to_px_timeline (const Position * pos, int use_padding);
606
611NONNULL int
612ui_pos_to_px_editor (const Position * pos, bool use_padding);
613
625NONNULL void
626ui_px_to_pos_editor (double px, Position * pos, bool has_padding);
627
631void
632ui_rgb_to_hex (double red, double green, double blue, char * buf);
633
634void
635ui_gdk_rgba_to_hex (GdkRGBA * color, char * buf);
636
640void
641ui_show_notification (const char * msg);
642
649int
651
656void
657ui_setup_language_combo_row (AdwComboRow * combo_row);
658
665AdwComboRow *
667
674AdwComboRow *
676
683void
685 AdwComboRow * combo_row,
686 bool populate,
687 bool with_signal);
688
692void
693ui_setup_vst_paths_entry (GtkEntry * entry);
694
699void
701
708char *
709ui_get_locale_not_available_string (LocalizationLanguage lang);
710
711void
712ui_show_warning_for_tempo_track_experimental_feature (void);
713
722void
723ui_get_contrast_color (GdkRGBA * src, GdkRGBA * dest);
724
731void
733 GdkRGBA * dest,
734 const GdkRGBA * c1,
735 const GdkRGBA * c2,
736 const float transition);
737
741NONNULL static inline bool
742ui_rectangle_overlap (
743 const GdkRectangle * const rect1,
744 const GdkRectangle * const rect2)
745{
746 /* if one rect is on the side of the other */
747 if (rect1->x > rect2->x + rect2->width || rect2->x > rect1->x + rect1->width)
748 return false;
749
750 /* if one rect is above the other */
751 if (rect1->y > rect2->y + rect2->height || rect2->y > rect1->y + rect1->height)
752 return false;
753
754 return true;
755}
756
764void
766 GdkRGBA * color,
767 const bool is_hovered,
768 const bool is_selected,
769 const bool is_transient,
770 const bool is_muted);
771
781double
783 double size,
784 double cur_val,
785 double start_px,
786 double cur_px,
787 double last_px,
788 double multiplier,
789 UiDragMode mode);
790
795void
796ui_get_db_value_as_string (float val, char * buf);
797
798UiCaches *
799ui_caches_new (void);
800
801void
802ui_caches_free (UiCaches * self);
803
808#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 haveselected..." text based on the given language.
UiCursorState
Various cursor states to be shared.
Definition ui.h:233
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:59
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:367
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:246
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:369
@ UI_DRAG_MODE_RELATIVE
Value is changed based on the offset.
Definition ui.h:372
@ UI_DRAG_MODE_RELATIVE_WITH_MULTIPLIER
Value is changed based on the offset, times a multiplier.
Definition ui.h:376
@ UI_OVERLAY_ACTION_AUTOFILLING
Auto-filling in edit mode.
Definition ui.h:271
@ UI_OVERLAY_ACTION_STARTING_DELETE_SELECTION
Like selecting but it auto deletes whatever touches the selection.
Definition ui.h:299
@ UI_OVERLAY_ACTION_STARTING_SELECTION
To be set in drag_start.
Definition ui.h:294
@ UI_OVERLAY_ACTION_STARTING_MOVING
To be set in drag_start.
Definition ui.h:280
@ UI_OVERLAY_ACTION_ERASING
Erasing.
Definition ui.h:274
Must ONLY be created via port_new()
Definition port.h:136
A Position is made up of bars.beats.sixteenths.ticks.
Definition position.h:124
Caches.
Definition ui.h:148
Commonly used UI colors.
Definition ui.h:96
Specification for a cursor.
Definition ui.h:137
Commonly used UI textures.
Definition ui.h:128
Custom types.