14#include "utils/localization.h"
18#include <glib/gi18n.h>
20#include "gtk_wrapper.h"
31#define UI_MAX_CURSORS 400
33#define UI_CACHES (zrythm_app->ui_caches)
34#define UI_COLORS (&UI_CACHES->colors)
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
67#define UI_DELETE_ICON_NAME "z-edit-delete"
69static const GdkRGBA UI_COLOR_BLACK = { 0, 0, 0, 1 };
79static const char * ui_detail_str[] = {
86static inline const char *
87ui_detail_to_string (UiDetail detail)
89 return ui_detail_str[detail];
99 GdkRGBA bright_orange;
102 GdkRGBA bright_green;
103 GdkRGBA darkish_green;
104 GdkRGBA prefader_send;
105 GdkRGBA postfader_send;
106 GdkRGBA record_active;
107 GdkRGBA record_checked;
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;
154 bool detail_level_set;
155 UiDetail detail_level;
161#define UI_RESIZE_CURSOR_SPACE 8
170#define TARGET_ENTRY_PLUGIN_DESCR "PLUGIN_DESCR"
173#define TARGET_ENTRY_SUPPORTED_FILE "SUPPORTED_FILE"
176#define TARGET_ENTRY_PLUGIN "PLUGIN"
179#define TARGET_ENTRY_FILE_PATH "FILE_PATH"
182#define TARGET_ENTRY_URI_LIST "text/uri-list"
190#define TARGET_ENTRY_TRACK "TRACK"
195#define TARGET_ENTRY_CHORD_DESCR "CHORD_DESCR"
198#define TARGET_ENTRY_TL_SELECTIONS "TL_SELECTIONS"
200#define GET_ATOM(x) gdk_atom_intern (x, 1)
202#define ui_add_widget_tooltip(widget, txt) \
203 gtk_widget_set_tooltip_text (GTK_WIDGET (widget), txt)
205#define ui_set_hover_status_bar_signals(w, t) \
207 G_OBJECT (w), "enter-notify-event", \
208 G_CALLBACK (ui_on_motion_set_status_bar_text_cb), g_strdup (t)); \
210 G_OBJECT (w), "leave-notify-event", \
211 G_CALLBACK (ui_on_motion_set_status_bar_text_cb), g_strdup (t));
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)
218#define ui_show_notification_idle_printf(fmt, ...) \ …
222#define ui_show_notification_idle(msg) \
223 ui_show_notification_idle_printf ("%s", msg)
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)
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,
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,
262 UI_OVERLAY_ACTION_STARTING_AUDITIONING,
263 UI_OVERLAY_ACTION_AUDITIONING,
275 UI_OVERLAY_ACTION_STARTING_ERASING,
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,
295 UI_OVERLAY_ACTION_SELECTING,
300 UI_OVERLAY_ACTION_DELETE_SELECTING,
302 UI_OVERLAY_ACTION_STARTING_RAMP,
303 UI_OVERLAY_ACTION_RAMPING,
304 UI_OVERLAY_ACTION_CUTTING,
306 UI_OVERLAY_ACTION_RENAMING,
308 UI_OVERLAY_ACTION_STARTING_PANNING,
309 UI_OVERLAY_ACTION_PANNING,
310 NUM_UI_OVERLAY_ACTIONS,
316static const char * ui_overlay_strings[] = {
327 "RESIZING_UP_FADE_IN",
328 "RESIZING_UP_FADE_OUT",
331 "STARTING_AUDITIONING",
337 "STARTING_MOVING_COPY",
338 "STARTING_MOVING_LINK",
342 "STARTING_CHANGING_CURVE",
344 "STARTING_SELECTION",
346 "STARTING_DELETE_SELECTION",
357static inline const char *
360 return ui_overlay_strings[action];
380ui_set_pointer_cursor (GtkWidget * widget);
382#define ui_set_pencil_cursor(widget) \
383 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "edit-cursor", 2, 3);
385#define ui_set_brush_cursor(widget) \
386 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "brush-cursor", 2, 3);
388#define ui_set_cut_clip_cursor(widget) \
389 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "cut-cursor", 9, 7);
391#define ui_set_eraser_cursor(widget) \
392 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "eraser-cursor", 4, 2);
394#define ui_set_line_cursor(widget) \
395 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "ramp-cursor", 2, 3);
397#define ui_set_speaker_cursor(widget) \
398 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "audition-cursor", 10, 12);
400#define ui_set_hand_cursor(widget) \
401 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "move-cursor", 12, 11);
403#define ui_set_left_resize_cursor(widget) \
404 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "w-resize-cursor", 14, 11);
406#define ui_set_left_stretch_cursor(widget) \
407 ui_set_cursor_from_icon_name ( \
408 GTK_WIDGET (widget), "w-stretch-cursor", 14, 11);
410#define ui_set_left_resize_loop_cursor(widget) \
411 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "w-loop-cursor", 14, 11);
413#define ui_set_right_resize_cursor(widget) \
414 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "e-resize-cursor", 10, 11);
416#define ui_set_right_stretch_cursor(widget) \
417 ui_set_cursor_from_icon_name ( \
418 GTK_WIDGET (widget), "e-stretch-cursor", 10, 11);
420#define ui_set_right_resize_loop_cursor(widget) \
421 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "e-loop-cursor", 10, 11);
423#define ui_set_time_select_cursor(widget) \
424 ui_set_cursor_from_icon_name ( \
425 GTK_WIDGET (widget), "time-select-cursor", 10, 12);
427#define ui_set_fade_in_cursor(widget) \
428 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "fade-in-cursor", 3, 1);
430#define ui_set_fade_out_cursor(widget) \
431 ui_set_cursor_from_icon_name (GTK_WIDGET (widget), "fade-out-cursor", 3, 1);
450ui_on_motion_set_status_bar_text_cb (
468 ...) G_GNUC_PRINTF (3, 4);
470#define UI_ACTIVE_WINDOW_OR_NULL \
471 (gtk_application_get_active_window (GTK_APPLICATION (zrythm_app)) \
473 gtk_application_get_active_window (GTK_APPLICATION (zrythm_app))) \
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__)
479#define ui_show_message_printf(title, fmt, ...) \ …
486#define ui_show_message_literal(title, str) \
487 ui_show_message_full (GTK_WIDGET (UI_ACTIVE_WINDOW_OR_NULL), title, "%s", str)
486#define ui_show_message_literal(title, str) \ …
493#define ui_show_error_message_printf(title, fmt, ...) \
494 ui_show_message_printf (title, fmt, __VA_ARGS__);
493#define ui_show_error_message_printf(title, fmt, ...) \ …
496#define ui_show_error_message(title, msg) ui_show_message_literal (title, msg)
550 const double x_padding,
551 const double y_padding);
564ui_get_detail_level (
void);
635ui_gdk_rgba_to_hex (GdkRGBA * color,
char * buf);
685 AdwComboRow * combo_row,
712ui_show_warning_for_tempo_track_experimental_feature (
void);
736 const float transition);
741NONNULL
static inline bool
742ui_rectangle_overlap (
743 const GdkRectangle *
const rect1,
744 const GdkRectangle *
const rect2)
747 if (rect1->x > rect2->x + rect2->width || rect2->x > rect1->x + rect1->width)
751 if (rect1->y > rect2->y + rect2->height || rect2->y > rect1->y + rect1->height)
767 const bool is_hovered,
768 const bool is_selected,
769 const bool is_transient,
770 const bool is_muted);
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.
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.
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.
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.
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.
@ UI_DRAG_MODE_RELATIVE
Value is changed based on the offset.
@ UI_DRAG_MODE_RELATIVE_WITH_MULTIPLIER
Value is changed based on the offset, times a multiplier.
@ UI_OVERLAY_ACTION_AUTOFILLING
Auto-filling in edit mode.
@ UI_OVERLAY_ACTION_STARTING_DELETE_SELECTION
Like selecting but it auto deletes whatever touches the selection.
@ UI_OVERLAY_ACTION_STARTING_SELECTION
To be set in drag_start.
@ UI_OVERLAY_ACTION_STARTING_MOVING
To be set in drag_start.
@ UI_OVERLAY_ACTION_ERASING
Erasing.
Must ONLY be created via port_new()
A Position is made up of bars.beats.sixteenths.ticks.
Specification for a cursor.
Commonly used UI textures.