1 /*
2 * Copyright (C) 2018-2021 Alexandros Theodotou <alex at zrythm dot org>
3 *
4 * This file is part of Zrythm
5 *
6 * Zrythm is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * Zrythm is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
15 *
16 * You should have received a copy of the GNU Affero General Public License
17 * along with Zrythm. If not, see <https://www.gnu.org/licenses/>.
18 */
19
20 /**
21 * \file
22 *
23 * User Interface utils.
24 *
25 */
26
27 #ifndef __UTILS_UI_H__
28 #define __UTILS_UI_H__
29
30 #include <stdbool.h>
31
32 #include "utils/localization.h"
33
34 #include <gtk/gtk.h>
35
36 typedef struct Position Position;
37 typedef struct Port Port;
38
39 /**
40 * @addtogroup utils
41 *
42 * @{
43 */
44
45 #define UI_MAX_CURSORS 400
46
47 #define UI_CACHES (zrythm_app->ui_caches)
48 #define UI_COLORS (&UI_CACHES->colors)
49
50 /* FIXME remove these and use theme */
51 #define UI_COLOR_DARK_TEXT "#323232"
52 #define UI_COLOR_BRIGHT_TEXT "#cdcdcd"
53 #define UI_COLOR_YELLOW "#F9CA1B"
54 #define UI_COLOR_PURPLE "#9D3955"
55 #define UI_COLOR_BUTTON_NORMAL "#343434"
56 #define UI_COLOR_BUTTON_HOVER "#444444"
57 #define UI_COLOR_RECORD_CHECKED "#ED2939"
58 #define UI_COLOR_RECORD_ACTIVE "#FF2400"
59
60 #define UI_DELETE_ICON_NAME "z-edit-delete"
61
62 static const GdkRGBA UI_COLOR_BLACK = {
63 0, 0, 0, 1
64 };
65
66 typedef enum UiDetail
67 {
68 UI_DETAIL_HIGH,
69 UI_DETAIL_NORMAL,
70 UI_DETAIL_LOW,
71 UI_DETAIL_ULTRA_LOW,
72 } UiDetail;
73
74 static const char * ui_detail_str[] =
75 {
76 __("High"),
77 __("Normal"),
78 __("Low"),
79 __("Ultra Low"),
80 };
81
82 static inline const char *
ui_detail_to_string(UiDetail detail)83 ui_detail_to_string (
84 UiDetail detail)
85 {
86 return ui_detail_str[detail];
87 }
88
89 /**
90 * Commonly used UI colors.
91 */
92 typedef struct UiColors
93 {
94 GdkRGBA dark_text;
95 GdkRGBA dark_orange;
96 GdkRGBA bright_orange;
97 GdkRGBA bright_text;
98 GdkRGBA matcha;
99 GdkRGBA bright_green;
100 GdkRGBA darkish_green;
101 GdkRGBA prefader_send;
102 GdkRGBA postfader_send;
103 GdkRGBA record_active;
104 GdkRGBA record_checked;
105 GdkRGBA solo_active;
106 GdkRGBA solo_checked;
107 GdkRGBA fader_fill_start;
108 GdkRGBA fader_fill_end;
109 GdkRGBA highlight_scale_bg;
110 GdkRGBA highlight_chord_bg;
111 GdkRGBA highlight_bass_bg;
112 GdkRGBA highlight_both_bg;
113 GdkRGBA highlight_scale_fg;
114 GdkRGBA highlight_chord_fg;
115 GdkRGBA highlight_bass_fg;
116 GdkRGBA highlight_both_fg;
117 } UiColors;
118
119 /**
120 * Specification for a cursor.
121 *
122 * Used for caching.
123 */
124 typedef struct UiCursor
125 {
126 char name[400];
127 GdkCursor * cursor;
128 GdkPixbuf * pixbuf;
129 int offset_x;
130 int offset_y;
131 } UiCursor;
132
133 /**
134 * Caches.
135 */
136 typedef struct UiCaches
137 {
138 UiColors colors;
139 UiCursor cursors[UI_MAX_CURSORS];
140 int num_cursors;
141 } UiCaches;
142
143 /**
144 * Space on the edges to show resize cursors
145 */
146 #define UI_RESIZE_CURSOR_SPACE 8
147
148 /*
149 * Drag n Drop related.
150 * Gtk target entries.
151 */
152
153 /** Plugin descriptor, used to instantiate plugins.
154 */
155 #define TARGET_ENTRY_PLUGIN_DESCR "PLUGIN_DESCR"
156
157 /** For SupportedFile pointers. */
158 #define TARGET_ENTRY_SUPPORTED_FILE "SUPPORTED_FILE"
159
160 /** Plugin ID, used to move/copy plugins. */
161 #define TARGET_ENTRY_PLUGIN "PLUGIN"
162
163 /* File path. Not used at the moment. */
164 #define TARGET_ENTRY_FILE_PATH "FILE_PATH"
165
166 /** URI list. */
167 #define TARGET_ENTRY_URI_LIST "text/uri-list"
168
169 /**
170 * Track target entry.
171 *
172 * This is just the identifier. The
173 * TracklistSelections will be used.
174 */
175 #define TARGET_ENTRY_TRACK "TRACK"
176
177 /**
178 * Chord descriptor target entry.
179 */
180 #define TARGET_ENTRY_CHORD_DESCR "CHORD_DESCR"
181
182 /* */
183 #define TARGET_ENTRY_TL_SELECTIONS \
184 "TL_SELECTIONS"
185
186 #define GET_ATOM(x) \
187 gdk_atom_intern (x, 1)
188
189 #define ui_add_widget_tooltip(widget,txt) \
190 gtk_widget_set_tooltip_text ( \
191 GTK_WIDGET (widget), txt)
192
193 #define ui_set_hover_status_bar_signals(w,t) \
194 g_signal_connect ( \
195 G_OBJECT (w), "enter-notify-event", \
196 G_CALLBACK ( \
197 ui_on_motion_set_status_bar_text_cb), \
198 g_strdup (t)); \
199 g_signal_connect ( \
200 G_OBJECT(w), "leave-notify-event", \
201 G_CALLBACK ( \
202 ui_on_motion_set_status_bar_text_cb), \
203 g_strdup (t));
204
205 /**
206 * Shows the notification when idle.
207 *
208 * This should be called from threads other than GTK main
209 * thread.
210 */
211 #define ui_show_notification_idle(msg) \
212 char * text = g_strdup (msg); \
213 g_message (msg); \
214 g_idle_add ((GSourceFunc) ui_show_notification_idle_func, \
215 (void *) text); \
216 g_free (text)
217
218 #define ui_is_widget_revealed(widget) \
219 (gtk_widget_get_allocated_height ( \
220 GTK_WIDGET (widget)) > 1 || \
221 gtk_widget_get_allocated_width ( \
222 GTK_WIDGET (widget)) > 1)
223
224 /**
225 * Used in handlers to get the state mask.
226 */
227 GdkModifierType
228 ui_get_state_mask (
229 GtkGesture * gesture);
230
231 /**
232 * Various cursor states to be shared.
233 */
234 typedef enum UiCursorState
235 {
236 UI_CURSOR_STATE_DEFAULT,
237 UI_CURSOR_STATE_RESIZE_L,
238 UI_CURSOR_STATE_REPEAT_L,
239 UI_CURSOR_STATE_RESIZE_R,
240 UI_CURSOR_STATE_REPEAT_R,
241 UI_CURSOR_STATE_RESIZE_UP,
242 } UiCursorState;
243
244 /**
245 * Various overlay actions to be shared.
246 */
247 typedef enum UiOverlayAction
248 {
249 UI_OVERLAY_ACTION_NONE,
250 UI_OVERLAY_ACTION_CREATING_RESIZING_R,
251 UI_OVERLAY_ACTION_CREATING_MOVING,
252 UI_OVERLAY_ACTION_RESIZING_L,
253 UI_OVERLAY_ACTION_RESIZING_L_LOOP,
254 UI_OVERLAY_ACTION_RESIZING_L_FADE,
255 UI_OVERLAY_ACTION_RESIZING_R,
256 UI_OVERLAY_ACTION_RESIZING_R_LOOP,
257 UI_OVERLAY_ACTION_RESIZING_R_FADE,
258 UI_OVERLAY_ACTION_RESIZING_UP,
259 UI_OVERLAY_ACTION_RESIZING_UP_FADE_IN,
260 UI_OVERLAY_ACTION_RESIZING_UP_FADE_OUT,
261 UI_OVERLAY_ACTION_STRETCHING_L,
262 UI_OVERLAY_ACTION_STRETCHING_R,
263
264 UI_OVERLAY_ACTION_AUDITIONING,
265
266 /**
267 * Auto-filling in edit mode.
268 *
269 * @note This is also used for the pencil tool in
270 * velocity and automation editors.
271 */
272 UI_OVERLAY_ACTION_AUTOFILLING,
273
274 /** Erasing. */
275 UI_OVERLAY_ACTION_ERASING,
276 UI_OVERLAY_ACTION_STARTING_ERASING,
277
278 /**
279 * To be set in drag_start.
280 */
281 UI_OVERLAY_ACTION_STARTING_MOVING,
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
290 /**
291 * To be set in drag_start.
292 *
293 * Useful to check if nothing was clicked.
294 */
295 UI_OVERLAY_ACTION_STARTING_SELECTION,
296 UI_OVERLAY_ACTION_SELECTING,
297
298 /** Like selecting but it auto deletes whatever
299 * touches the selection. */
300 UI_OVERLAY_ACTION_STARTING_DELETE_SELECTION,
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 NUM_UI_OVERLAY_ACTIONS,
309 } UiOverlayAction;
310
311 /**
312 * Various overlay actions to be shared.
313 */
314 static const char * ui_overlay_strings[] =
315 {
316 "NONE",
317 "RESIZING_R",
318 "MOVING",
319 "RESIZING_L",
320 "RESIZING_L_LOOP",
321 "RESIZING_L_FADE",
322 "RESIZING_R",
323 "RESIZING_R_LOOP",
324 "RESIZING_R_FADE",
325 "RESIZING_UP",
326 "RESIZING_UP_FADE_IN",
327 "RESIZING_UP_FADE_OUT",
328 "STRETCHING_L",
329 "STRETCHING_R",
330 "AUDITIONING",
331 "AUTOFILLING",
332 "ERASING",
333 "STARTING_ERASING",
334 "STARTING_MOVING",
335 "STARTING_MOVING_COPY",
336 "STARTING_MOVING_LINK",
337 "MOVING",
338 "MOVING_COPY",
339 "MOVING_LINK",
340 "STARTING_CHANGING_CURVE",
341 "CHANGING_CURVE",
342 "STARTING_SELECTION",
343 "SELECTING",
344 "STARTING_DELETE_SELECTION",
345 "DELETE_SELECTING",
346 "STARTING_RAMP",
347 "RAMPING",
348 "CUTTING",
349 "RENAMING",
350 "INVALID",
351 };
352
353 static inline const char *
ui_get_overlay_action_string(UiOverlayAction action)354 ui_get_overlay_action_string (
355 UiOverlayAction action)
356 {
357 return ui_overlay_strings[action];
358 }
359
360 /**
361 * Dragging modes for widgets that have click&drag.
362 */
363 typedef enum UiDragMode
364 {
365 /** Value is wherever the cursor is. */
366 UI_DRAG_MODE_CURSOR,
367
368 /** Value is changed based on the offset. */
369 UI_DRAG_MODE_RELATIVE,
370
371 /** Value is changed based on the offset, times
372 * a multiplier. */
373 UI_DRAG_MODE_RELATIVE_WITH_MULTIPLIER,
374 } UiDragMode;
375
376 void
377 ui_set_pointer_cursor (
378 GtkWidget * widget);
379
380 #define ui_set_pencil_cursor(widget) \
381 ui_set_cursor_from_icon_name ( \
382 GTK_WIDGET (widget), \
383 "pencil", 3, 18);
384
385 #define ui_set_brush_cursor(widget) \
386 ui_set_cursor_from_icon_name ( \
387 GTK_WIDGET (widget), \
388 "draw-brush", 3, 18);
389
390 #define ui_set_cut_clip_cursor(widget) \
391 ui_set_cursor_from_icon_name ( \
392 GTK_WIDGET (widget), \
393 "cut-tool", 9, 6);
394
395 #define ui_set_eraser_cursor(widget) \
396 ui_set_cursor_from_icon_name ( \
397 GTK_WIDGET (widget), \
398 "draw-eraser", 3, 6);
399
400 #define ui_set_line_cursor(widget) \
401 ui_set_cursor_from_icon_name ( \
402 GTK_WIDGET (widget), \
403 "draw-line", 3, 6);
404
405 #define ui_set_speaker_cursor(widget) \
406 ui_set_cursor_from_icon_name ( \
407 GTK_WIDGET (widget), \
408 "audio-volume-high", 3, 6);
409
410 #define ui_set_hand_cursor(widget) \
411 ui_set_cursor_from_icon_name ( \
412 GTK_WIDGET (widget), \
413 "transform-move", 10, 10);
414
415 #define ui_set_left_resize_cursor(widget) \
416 ui_set_cursor_from_icon_name ( \
417 GTK_WIDGET (widget), \
418 "object-resize-left", 0, 10);
419
420 #define ui_set_left_stretch_cursor(widget) \
421 ui_set_cursor_from_icon_name ( \
422 GTK_WIDGET (widget), \
423 "object-stretch-left", 0, 10);
424
425 #define ui_set_left_resize_loop_cursor(widget) \
426 ui_set_cursor_from_icon_name ( \
427 GTK_WIDGET (widget), \
428 "object-resize-loop-left", 0, 10);
429
430 #define ui_set_right_resize_cursor(widget) \
431 ui_set_cursor_from_icon_name ( \
432 GTK_WIDGET (widget), \
433 "object-resize-right", 15, 10);
434
435 #define ui_set_right_stretch_cursor(widget) \
436 ui_set_cursor_from_icon_name ( \
437 GTK_WIDGET (widget), \
438 "object-stretch-right", 15, 10);
439
440 #define ui_set_right_resize_loop_cursor(widget) \
441 ui_set_cursor_from_icon_name ( \
442 GTK_WIDGET (widget), \
443 "object-resize-loop-right", 15, 10);
444
445 #define ui_set_fade_in_cursor(widget) \
446 ui_set_cursor_from_icon_name ( \
447 GTK_WIDGET (widget), \
448 "fade-in", 11, 11);
449
450 #define ui_set_fade_out_cursor(widget) \
451 ui_set_cursor_from_icon_name ( \
452 GTK_WIDGET (widget), \
453 "fade-out", 11, 11);
454
455 /**
456 * Sets cursor from icon name.
457 */
458 void
459 ui_set_cursor_from_icon_name (
460 GtkWidget * widget,
461 const char * name,
462 int offset_x,
463 int offset_y);
464
465 /**
466 * Sets cursor from standard cursor name.
467 */
468 void
469 ui_set_cursor_from_name (
470 GtkWidget * widget,
471 const char * name);
472
473 gboolean
474 ui_on_motion_set_status_bar_text_cb (
475 GtkWidget * widget,
476 GdkEvent * event,
477 char * text);
478
479 /**
480 * Shows a popup message of the given type with the
481 * given message.
482 */
483 void
484 ui_show_message_full (
485 GtkWindow * parent_window,
486 GtkMessageType type,
487 const char * format,
488 ...) G_GNUC_PRINTF (3, 4);
489
490 /**
491 * Wrapper to show error message so that no casting
492 * of the window is needed on the caller side.
493 */
494 #define ui_show_error_message(win, msg) \
495 ui_show_message_full ( \
496 win ? GTK_WINDOW (win) : NULL, \
497 GTK_MESSAGE_ERROR, \
498 "%s", msg);
499
500 /**
501 * Type can be GTK_MESSAGE_ERROR, etc.
502 */
503 #define ui_show_message_printf(win,type,fmt,...) \
504 ui_show_message_full ( \
505 win ? GTK_WINDOW (win) : NULL, \
506 type, fmt, __VA_ARGS__)
507
508 /**
509 * Returns if \ref rect is hit or not by the
510 * given coordinate.
511 *
512 * @param check_x Check x-axis for match.
513 * @param check_y Check y-axis for match.
514 * @param x x in parent space.
515 * @param y y in parent space.
516 * @param x_padding Padding to add to the x
517 * of the object when checking if hit.
518 * The bigger the padding the more space the
519 * child will have to get hit.
520 * @param y_padding Padding to add to the y
521 * of the object when checking if hit.
522 * The bigger the padding the more space the
523 * child will have to get hit.
524 */
525 bool
526 ui_is_point_in_rect_hit (
527 GdkRectangle * rect,
528 const bool check_x,
529 const bool check_y,
530 double x,
531 double y,
532 double x_padding,
533 double y_padding);
534
535 /**
536 * Returns if the child is hit or not by the
537 * coordinates in parent.
538 *
539 * @param check_x Check x-axis for match.
540 * @param check_y Check y-axis for match.
541 * @param x x in parent space.
542 * @param y y in parent space.
543 * @param x_padding Padding to add to the x
544 * of the object when checking if hit.
545 * The bigger the padding the more space the
546 * child will have to get hit.
547 * @param y_padding Padding to add to the y
548 * of the object when checking if hit.
549 * The bigger the padding the more space the
550 * child will have to get hit.
551 */
552 int
553 ui_is_child_hit (
554 GtkWidget * parent,
555 GtkWidget * child,
556 const int check_x,
557 const int check_y,
558 const double x,
559 const double y,
560 const double x_padding,
561 const double y_padding);
562
563 /**
564 * Returns the matching hit child, or NULL.
565 */
566 GtkWidget *
567 ui_get_hit_child (
568 GtkContainer * parent,
569 double x, ///< x in parent space
570 double y, ///< y in parent space
571 GType type); ///< type to look for
572
573 UiDetail
574 ui_get_detail_level (void);
575
576 /**
577 * Converts from pixels to position.
578 *
579 * Only works with positive numbers. Negatives will
580 * be clamped at 0. If a negative is needed, pass
581 * the abs to this function and then change the
582 * sign.
583 *
584 * @param has_padding Whether @ref px contains
585 * padding.
586 */
587 NONNULL
588 void
589 ui_px_to_pos_timeline (
590 double px,
591 Position * pos,
592 bool has_padding);
593
594 /**
595 * Converts from pixels to frames.
596 *
597 * Returns the frames.
598 *
599 * @param has_padding Whether then given px contains
600 * padding.
601 */
602 long
603 ui_px_to_frames_timeline (
604 double px,
605 int has_padding);
606
607 /**
608 * Converts from pixels to frames.
609 *
610 * Returns the frames.
611 *
612 * @param has_padding Whether then given px contains
613 * padding.
614 */
615 long
616 ui_px_to_frames_editor (
617 double px,
618 int has_padding);
619
620 /**
621 * Converts position to px, optionally adding the
622 * ruler padding.
623 */
624 NONNULL
625 int
626 ui_pos_to_px_timeline (
627 Position * pos,
628 int use_padding);
629
630 /**
631 * Converts position to px, optionally adding the ruler
632 * padding.
633 */
634 NONNULL
635 int
636 ui_pos_to_px_editor (
637 Position * pos,
638 bool use_padding);
639
640 /**
641 * Converts from pixels to position.
642 *
643 * Only works with positive numbers. Negatives will
644 * be clamped at 0. If a negative is needed, pass
645 * the abs to this function and then change the
646 * sign.
647 *
648 * @param has_padding Whether @ref px contains
649 * padding.
650 */
651 NONNULL
652 void
653 ui_px_to_pos_editor (
654 double px,
655 Position * pos,
656 bool has_padding);
657
658 /**
659 * Converts RGB to hex string.
660 */
661 void
662 ui_rgb_to_hex (
663 double red,
664 double green,
665 double blue,
666 char * buf);
667
668 void
669 ui_gdk_rgba_to_hex (
670 GdkRGBA * color,
671 char * buf);
672
673 /**
674 * Shows a notification in the revealer.
675 */
676 void
677 ui_show_notification (const char * msg);
678
679 /**
680 * Show notification from non-GTK threads.
681 *
682 * This should be used internally. Use the
683 * ui_show_notification_idle macro instead.
684 */
685 int
686 ui_show_notification_idle_func (char * msg);
687
688 /**
689 * Returns the modifier type (state mask) from the
690 * given gesture.
691 */
692 void
693 ui_get_modifier_type_from_gesture (
694 GtkGestureSingle * gesture,
695 GdkModifierType * state_mask); ///< return value
696
697 /**
698 * Sets up a combo box to have a selection of
699 * languages.
700 */
701 void
702 ui_setup_language_combo_box (
703 GtkComboBox * language);
704
705 /**
706 * Sets up an audio backends combo box.
707 */
708 void
709 ui_setup_audio_backends_combo_box (
710 GtkComboBox * cb);
711
712 /**
713 * Sets up a MIDI backends combo box.
714 */
715 void
716 ui_setup_midi_backends_combo_box (
717 GtkComboBox * cb);
718
719 /**
720 * Sets up a pan algorithm combo box.
721 */
722 void
723 ui_setup_pan_algo_combo_box (
724 GtkComboBox * cb);
725
726 /**
727 * Sets up a pan law combo box.
728 */
729 void
730 ui_setup_pan_law_combo_box (
731 GtkComboBox * cb);
732
733 /**
734 * Sets up a pan law combo box.
735 */
736 void
737 ui_setup_buffer_size_combo_box (
738 GtkComboBox * cb);
739
740 /**
741 * Sets up a pan law combo box.
742 */
743 void
744 ui_setup_samplerate_combo_box (
745 GtkComboBox * cb);
746
747 /**
748 * Sets up a pan law combo box.
749 */
750 void
751 ui_setup_device_name_combo_box (
752 GtkComboBoxText * cb);
753
754 /**
755 * Sets up the VST paths entry.
756 */
757 void
758 ui_setup_vst_paths_entry (
759 GtkEntry * entry);
760
761 /**
762 * Updates the the VST paths in the gsettings from
763 * the text in the entry.
764 */
765 void
766 ui_update_vst_paths_from_entry (
767 GtkEntry * entry);
768
769 /**
770 * Returns the "a locale for the language you have
771 * selected..." text based on the given language.
772 *
773 * Must be free'd by caller.
774 */
775 char *
776 ui_get_locale_not_available_string (
777 LocalizationLanguage lang);
778
779 /**
780 * Returns the contrasting color (variation of
781 * black or white) based on if the given color is
782 * dark enough or not.
783 *
784 * @param src The source color.
785 * @param dest The desination color to write to.
786 */
787 void
788 ui_get_contrast_color (
789 GdkRGBA * src,
790 GdkRGBA * dest);
791
792 /**
793 * Returns the color in-between two colors.
794 *
795 * @param transition How far to transition (0.5 for
796 * half).
797 */
798 void
799 ui_get_mid_color (
800 GdkRGBA * dest,
801 const GdkRGBA * c1,
802 const GdkRGBA * c2,
803 const double transition);
804
805 /**
806 * Returns if the 2 rectangles overlay.
807 */
808 NONNULL
809 PURE
810 static inline bool
ui_rectangle_overlap(const GdkRectangle * const rect1,const GdkRectangle * const rect2)811 ui_rectangle_overlap (
812 const GdkRectangle * const rect1,
813 const GdkRectangle * const rect2)
814 {
815 /* if one rect is on the side of the other */
816 if (rect1->x > rect2->x + rect2->width ||
817 rect2->x > rect1->x + rect1->width)
818 return false;
819
820 /* if one rect is above the other */
821 if (rect1->y > rect2->y + rect2->height ||
822 rect2->y > rect1->y + rect1->height)
823 return false;
824
825 return true;
826 }
827
828 /**
829 * Gets the color the widget should be.
830 *
831 * @param color The original color.
832 * @param is_selected Whether the widget is supposed
833 * to be selected or not.
834 */
835 void
836 ui_get_arranger_object_color (
837 GdkRGBA * color,
838 const bool is_hovered,
839 const bool is_selected,
840 const bool is_transient,
841 const bool is_muted);
842
843 /**
844 * Gets a draggable value as a normalized value
845 * between 0 and 1.
846 *
847 * @param size Widget size (either width or height).
848 * @param start_px Px at start of drag.
849 * @param cur_px Current px.
850 * @param last_px Px during last call.
851 */
852 double
853 ui_get_normalized_draggable_value (
854 double size,
855 double cur_val,
856 double start_px,
857 double cur_px,
858 double last_px,
859 double multiplier,
860 UiDragMode mode);
861
862 /**
863 * All purpose menuitem callback for binding MIDI
864 * CC to a port.
865 *
866 * An action will be performed if bound.
867 */
868 void
869 ui_bind_midi_cc_item_activate_cb (
870 GtkMenuItem * menuitem,
871 Port * port);
872
873 UiCaches *
874 ui_caches_new (void);
875
876 void
877 ui_caches_free (
878 UiCaches * self);
879
880 /**
881 * @}
882 */
883
884 #endif
885