Browse Source

port event viewers to GtkColumnView

* port event viewers to GtkColumnView
* use different event viewer for each editor in a GtkStack
audio_region_bpm_change_fix
parent
commit
94ae6e94c3
Signed by: alex
GPG Key ID: 022EAE42313D70F3
  1. 8
      data/css-themes/zrythm/theme.scss
  2. 4
      inc/audio/chord_object.h
  3. 6
      inc/audio/midi_note.h
  4. 21
      inc/gui/backend/arranger_object.h
  5. 1
      inc/gui/backend/wrapped_object_with_change_signal.h
  6. 15
      inc/gui/widgets/bot_dock_edge.h
  7. 1
      inc/gui/widgets/cc_bindings_tree.h
  8. 51
      inc/gui/widgets/event_viewer.h
  9. 13
      inc/gui/widgets/item_factory.h
  10. 9
      inc/gui/widgets/popover_menu_bin.h
  11. 5
      inc/plugins/plugin_descriptor.h
  12. 4
      inc/settings/chord_preset.h
  13. 4
      inc/settings/chord_preset_pack.h
  14. 3
      inc/settings/chord_preset_pack_manager.h
  15. 5
      inc/utils/flags.h
  16. 17
      inc/utils/gtk.h
  17. 2
      meson.build
  18. 9
      resources/ui/event_viewer.ui
  19. 8
      src/actions/actions.c
  20. 4
      src/audio/chord_object.c
  21. 6
      src/audio/midi_note.c
  22. 136
      src/gui/backend/arranger_object.c
  23. 52
      src/gui/backend/event_manager.c
  24. 4
      src/gui/widgets/balance_control.c
  25. 88
      src/gui/widgets/bot_dock_edge.c
  26. 33
      src/gui/widgets/cc_bindings_tree.c
  27. 1139
      src/gui/widgets/event_viewer.c
  28. 481
      src/gui/widgets/item_factory.c
  29. 4
      src/gui/widgets/main_notebook.c
  30. 2
      src/gui/widgets/main_window.c
  31. 2
      src/gui/widgets/popover_menu_bin.c
  32. 169
      src/plugins/plugin_descriptor.c
  33. 38
      src/settings/chord_preset.c
  34. 35
      src/settings/chord_preset_pack.c
  35. 2
      src/settings/chord_preset_pack_manager.c
  36. 65
      src/utils/gtk.c

8
data/css-themes/zrythm/theme.scss

@ -81,7 +81,8 @@ spinbutton button:focus @@ -81,7 +81,8 @@ spinbutton button:focus
border-left-color: $bright_orange;
}
entry selection
entry selection,
text selection
{
background-color: $z_yellow;
}
@ -648,3 +649,8 @@ folder-channel menubutton:hover, @@ -648,3 +649,8 @@ folder-channel menubutton:hover,
folder-channel button.toggle:hover {
background-color: $hover_color;
}
viewswitcher stack,
event-viewer stack {
background-color: transparent;
}

4
inc/audio/chord_object.h

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2021 Alexandros Theodotou <alex at zrythm dot org>
* Copyright (C) 2018-2022 Alexandros Theodotou <alex at zrythm dot org>
*
* This file is part of Zrythm
*
@ -131,7 +131,7 @@ chord_object_set_region_and_index ( @@ -131,7 +131,7 @@ chord_object_set_region_and_index (
*/
ChordDescriptor *
chord_object_get_chord_descriptor (
ChordObject * self);
const ChordObject * self);
/**
* Finds the ChordObject in the project

6
inc/audio/midi_note.h

@ -177,9 +177,9 @@ midi_note_is_equal ( @@ -177,9 +177,9 @@ midi_note_is_equal (
*/
void
midi_note_get_val_as_string (
MidiNote * self,
char * buf,
const int use_markup);
const MidiNote * self,
char * buf,
const int use_markup);
/**
* For debugging.

21
inc/gui/backend/arranger_object.h

@ -448,7 +448,7 @@ static const cyaml_schema_value_t @@ -448,7 +448,7 @@ static const cyaml_schema_value_t
*/
ArrangerWidget *
arranger_object_get_arranger (
ArrangerObject * self);
const ArrangerObject * self);
/**
* Sets the magic on the arranger object.
@ -472,7 +472,20 @@ arranger_object_get_region ( @@ -472,7 +472,20 @@ arranger_object_get_region (
*/
const char *
arranger_object_get_name (
ArrangerObject * self);
const ArrangerObject * self);
/**
* Generates a human readable name for the object.
*
* If the object has a name, this returns a copy
* of the name, otherwise generates something
* appropriate.
*
* Must be free'd by caller.
*/
char *
arranger_object_gen_human_readable_name (
const ArrangerObject * self);
/**
* Generates the escaped name for the object,
@ -480,7 +493,7 @@ arranger_object_get_name ( @@ -480,7 +493,7 @@ arranger_object_get_name (
*/
void
arranger_object_gen_escaped_name (
ArrangerObject * self);
const ArrangerObject * self);
/**
* Sets the dest object's values to the main
@ -958,7 +971,7 @@ arranger_object_find ( @@ -958,7 +971,7 @@ arranger_object_find (
*/
ArrangerObject *
arranger_object_clone (
ArrangerObject * self);
const ArrangerObject * self);
/**
* Splits the given object at the given Position.

1
inc/gui/backend/wrapped_object_with_change_signal.h

@ -52,6 +52,7 @@ typedef enum WrappedObjectType @@ -52,6 +52,7 @@ typedef enum WrappedObjectType
WRAPPED_OBJECT_TYPE_CHORD_PSET_PACK,
WRAPPED_OBJECT_TYPE_SUPPORTED_FILE,
WRAPPED_OBJECT_TYPE_MIDI_MAPPING,
WRAPPED_OBJECT_TYPE_ARRANGER_OBJECT,
} WrappedObjectType;
typedef struct _WrappedObjectWithChangeSignal

15
inc/gui/widgets/bot_dock_edge.h

@ -71,8 +71,12 @@ typedef struct _BotDockEdgeWidget @@ -71,8 +71,12 @@ typedef struct _BotDockEdgeWidget
GtkPaned * clip_editor_plus_event_viewer_paned;
/** Event viewer. */
EventViewerWidget * event_viewer;
/** Event viewers. */
GtkStack * event_viewer_stack;
EventViewerWidget * event_viewer_midi;
EventViewerWidget * event_viewer_chord;
EventViewerWidget * event_viewer_automation;
EventViewerWidget * event_viewer_audio;
/** Wrapper. */
GtkBox * clip_editor_box;
@ -93,6 +97,13 @@ void @@ -93,6 +97,13 @@ void
bot_dock_edge_widget_setup (
BotDockEdgeWidget * self);
/**
* Sets the appropriate stack page.
*/
void
bot_dock_edge_widget_update_event_viewer_stack_page (
BotDockEdgeWidget * self);
/**
* Brings up the clip editor.
*

1
inc/gui/widgets/cc_bindings_tree.h

@ -53,7 +53,6 @@ typedef struct _CcBindingsTreeWidget @@ -53,7 +53,6 @@ typedef struct _CcBindingsTreeWidget
/** Array of ItemFactory pointers for each
* column. */
/* TODO destroy in finalize() */
GPtrArray * item_factories;
} CcBindingsTreeWidget;

51
inc/gui/widgets/event_viewer.h

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright (C) 2019, 2021 Alexandros Theodotou <alex at zrythm dot org>
* Copyright (C) 2019, 2021-2022 Alexandros Theodotou <alex at zrythm dot org>
*
* This file is part of Zrythm
*
@ -33,10 +33,8 @@ @@ -33,10 +33,8 @@
#define EVENT_VIEWER_WIDGET_TYPE \
(event_viewer_widget_get_type ())
G_DECLARE_FINAL_TYPE (
EventViewerWidget,
event_viewer_widget,
Z, EVENT_VIEWER_WIDGET,
GtkBox)
EventViewerWidget, event_viewer_widget,
Z, EVENT_VIEWER_WIDGET, GtkBox)
typedef struct _ArrangerWidget ArrangerWidget;
typedef struct ArrangerSelections ArrangerSelections;
@ -49,13 +47,24 @@ typedef struct ArrangerSelections ArrangerSelections; @@ -49,13 +47,24 @@ typedef struct ArrangerSelections ArrangerSelections;
#define MW_TIMELINE_EVENT_VIEWER \
MW_MAIN_NOTEBOOK->event_viewer
#define MW_EDITOR_EVENT_VIEWER \
MW_BOT_DOCK_EDGE->event_viewer
#define MW_EDITOR_EVENT_VIEWER_STACK \
MW_BOT_DOCK_EDGE->event_viewer_stack
#define MW_MIDI_EVENT_VIEWER \
MW_BOT_DOCK_EDGE->event_viewer_midi
#define MW_CHORD_EVENT_VIEWER \
MW_BOT_DOCK_EDGE->event_viewer_chord
#define MW_AUDIO_EVENT_VIEWER \
MW_BOT_DOCK_EDGE->event_viewer_audio
#define MW_AUTOMATION_EVENT_VIEWER \
MW_BOT_DOCK_EDGE->event_viewer_automation
typedef enum EventViewerType
{
EVENT_VIEWER_TYPE_TIMELINE,
EVENT_VIEWER_TYPE_EDITOR,
EVENT_VIEWER_TYPE_CHORD,
EVENT_VIEWER_TYPE_MIDI,
EVENT_VIEWER_TYPE_AUDIO,
EVENT_VIEWER_TYPE_AUTOMATION,
} EventViewerType;
typedef struct _EventViewerWidget
@ -63,8 +72,11 @@ typedef struct _EventViewerWidget @@ -63,8 +72,11 @@ typedef struct _EventViewerWidget
GtkBox parent_instance;
/** The tree view. */
GtkTreeModel * model;
GtkTreeView * treeview;
GtkColumnView * column_view;
/** Array of ItemFactory pointers for each
* column. */
GPtrArray * item_factories;
/** Type. */
EventViewerType type;
@ -73,16 +85,24 @@ typedef struct _EventViewerWidget @@ -73,16 +85,24 @@ typedef struct _EventViewerWidget
* readd the columns. */
RegionType region_type;
/** Clone of last selections used. */
ArrangerSelections * last_selections;
/** Temporary flag. */
bool marking_selected_objs;
} EventViewerWidget;
/**
* Called to update the models.
* Called to update the models/selections.
*
* @param selections_only Only update the selection
* status of each item without repopulating the
* model.
*/
void
event_viewer_widget_refresh (
EventViewerWidget * self);
EventViewerWidget * self,
bool selections_only);
/**
* Convenience function.
@ -93,10 +113,15 @@ event_viewer_widget_refresh_for_selections ( @@ -93,10 +113,15 @@ event_viewer_widget_refresh_for_selections (
/**
* Convenience function.
*
* @param selections_only Only update the selection
* status of each item without repopulating the
* model.
*/
void
event_viewer_widget_refresh_for_arranger (
ArrangerWidget * arranger);
const ArrangerWidget * arranger,
bool selections_only);
EventViewerWidget *
event_viewer_widget_new (void);

13
inc/gui/widgets/item_factory.h

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Alexandros Theodotou <alex at zrythm dot org>
* Copyright (C) 2021-2022 Alexandros Theodotou <alex at zrythm dot org>
*
* This file is part of Zrythm
*
@ -39,9 +39,15 @@ typedef enum ItemFactoryType @@ -39,9 +39,15 @@ typedef enum ItemFactoryType
ITEM_FACTORY_TOGGLE,
ITEM_FACTORY_TEXT,
/** Integer display. */
ITEM_FACTORY_INTEGER,
/** Composite type (eg, used in plugin
* browser). */
ITEM_FACTORY_ICON_AND_TEXT,
/** Position. */
ITEM_FACTORY_POSITION,
} ItemFactoryType;
/**
@ -84,8 +90,11 @@ item_factory_new ( @@ -84,8 +90,11 @@ item_factory_new (
/**
* Shorthand to generate and append a column to
* a column view.
*
* @return The newly created ItemFactory, for
* convenience.
*/
void
ItemFactory *
item_factory_generate_and_append_column (
GtkColumnView * column_view,
GPtrArray * item_factories,

9
inc/gui/widgets/popover_menu_bin.h

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright (C) 2021 Alexandros Theodotou <alex at zrythm dot org>
* Copyright (C) 2021-2022 Alexandros Theodotou <alex at zrythm dot org>
*
* This file is part of Zrythm
*
@ -31,10 +31,8 @@ @@ -31,10 +31,8 @@
#define POPOVER_MENU_BIN_WIDGET_TYPE \
(popover_menu_bin_widget_get_type ())
G_DECLARE_FINAL_TYPE (
PopoverMenuBinWidget,
popover_menu_bin_widget,
Z, POPOVER_MENU_BIN_WIDGET,
GtkWidget)
PopoverMenuBinWidget, popover_menu_bin_widget,
Z, POPOVER_MENU_BIN_WIDGET, GtkWidget)
/**
* @addtogroup widgets
@ -54,6 +52,7 @@ typedef struct _PopoverMenuBinWidget @@ -54,6 +52,7 @@ typedef struct _PopoverMenuBinWidget
GMenuModel * menu_model;
/** Context menu. */
GtkPopoverMenu * popover_menu;
} PopoverMenuBinWidget;

5
inc/plugins/plugin_descriptor.h

@ -436,6 +436,11 @@ CarlaBridgeMode @@ -436,6 +436,11 @@ CarlaBridgeMode
plugin_descriptor_get_min_bridge_mode (
const PluginDescriptor * self);
NONNULL
GMenuModel *
plugin_descriptor_generate_context_menu (
const PluginDescriptor * self);
NONNULL
void
plugin_descriptor_free (

4
inc/settings/chord_preset.h

@ -106,6 +106,10 @@ chord_preset_set_name ( @@ -106,6 +106,10 @@ chord_preset_set_name (
ChordPreset * self,
const char * name);
GMenuModel *
chord_preset_generate_context_menu (
const ChordPreset * self);
/**
* Frees the plugin setting.
*/

4
inc/settings/chord_preset_pack.h

@ -122,6 +122,10 @@ ChordPresetPack * @@ -122,6 +122,10 @@ ChordPresetPack *
chord_preset_pack_clone (
const ChordPresetPack * src);
GMenuModel *
chord_preset_pack_generate_context_menu (
const ChordPresetPack * self);
void
chord_preset_pack_free (
ChordPresetPack * self);

3
inc/settings/chord_preset_pack_manager.h

@ -71,10 +71,11 @@ chord_preset_pack_manager_get_pack_at ( @@ -71,10 +71,11 @@ chord_preset_pack_manager_get_pack_at (
const ChordPresetPackManager * self,
int idx);
NONNULL
ChordPresetPack *
chord_preset_pack_manager_get_pack_for_preset (
ChordPresetPackManager * self,
ChordPreset * pset);
const ChordPreset * pset);
int
chord_preset_pack_manager_get_pack_index (

5
inc/utils/flags.h

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright (C) 2019-2021 Alexandros Theodotou <alex at zrythm dot org>
* Copyright (C) 2019-2022 Alexandros Theodotou <alex at zrythm dot org>
*
* This file is part of Zrythm
*
@ -355,4 +355,7 @@ @@ -355,4 +355,7 @@
#define Z_F_TEMPLATE 1
#define Z_F_NOT_TEMPLATE 0
#define Z_F_EDITABLE 1
#define Z_F_NOT_EDITABLE 0
#endif

17
inc/utils/gtk.h

@ -184,6 +184,14 @@ void @@ -184,6 +184,14 @@ void
z_gtk_tree_view_remove_all_columns (
GtkTreeView * treeview);
void
z_gtk_column_view_remove_all_columnes (
GtkColumnView * column_view);
GListStore *
z_gtk_column_view_get_list_store (
GtkColumnView * column_view);
/**
* @note Bumps reference, must be decremented after
* calling.
@ -793,6 +801,15 @@ z_gtk_simple_action_shortcut_func ( @@ -793,6 +801,15 @@ z_gtk_simple_action_shortcut_func (
GVariant * args,
gpointer user_data);
/**
* Recursively searches the children of \ref widget
* for a child of type \ref type.
*/
GtkWidget *
z_gtk_widget_find_child_of_type (
GtkWidget * widget,
GType type);
/**
* @}
*/

2
meson.build

@ -135,8 +135,6 @@ flatpak_build = get_option ('for_flathub') or get_option ('flatpak') @@ -135,8 +135,6 @@ flatpak_build = get_option ('for_flathub') or get_option ('flatpak')
# Used for building manpages, manual, etc., using
# foreach.
# The actual languages to use are specified in
# po/LINGUAS.
language_mappings = {
'af_ZA': 'Afrikaans',
'ar': 'ุงูŽู„ู’ุนูŽุฑูŽุจููŠูŽู‘ุฉูโ€Ž',

9
resources/ui/event_viewer.ui

@ -14,15 +14,14 @@ @@ -14,15 +14,14 @@
<property name="hscrollbar-policy">never</property>
<property name="vexpand">1</property>
<property name="child">
<object class="GtkTreeView" id="treeview">
<object class="GtkColumnView" id="column_view">
<style>
<class name="data-table"/>
</style>
<property name="focusable">1</property>
<property name="rubber-banding">1</property>
</object>
</property>
</object>
</child>
<child>
<placeholder/>
</child>
</template>
</interface>

8
src/actions/actions.c

@ -2299,19 +2299,21 @@ activate_toggle_editor_event_viewer ( @@ -2299,19 +2299,21 @@ activate_toggle_editor_event_viewer (
GVariant * variant,
gpointer user_data)
{
if (!MW_EDITOR_EVENT_VIEWER)
if (!MW_EDITOR_EVENT_VIEWER_STACK)
return;
int new_visibility =
!gtk_widget_get_visible (
GTK_WIDGET (MW_EDITOR_EVENT_VIEWER));
GTK_WIDGET (MW_EDITOR_EVENT_VIEWER_STACK));
g_settings_set_boolean (
S_UI, "editor-event-viewer-visible",
new_visibility);
gtk_widget_set_visible (
GTK_WIDGET (MW_EDITOR_EVENT_VIEWER),
GTK_WIDGET (MW_EDITOR_EVENT_VIEWER_STACK),
new_visibility);
bot_dock_edge_widget_update_event_viewer_stack_page (
MW_BOT_DOCK_EDGE);
}
DEFINE_SIMPLE (activate_insert_silence)

4
src/audio/chord_object.c

@ -1,5 +1,5 @@ @@ -1,5 +1,5 @@
/*
* Copyright (C) 2018-2021 Alexandros Theodotou <alex at zrythm dot org>
* Copyright (C) 2018-2022 Alexandros Theodotou <alex at zrythm dot org>
*
* This file is part of Zrythm
*
@ -64,7 +64,7 @@ chord_object_new ( @@ -64,7 +64,7 @@ chord_object_new (
*/
ChordDescriptor *
chord_object_get_chord_descriptor (
ChordObject * self)
const ChordObject * self)
{
g_return_val_if_fail (CLIP_EDITOR, NULL);
return CHORD_EDITOR->chords[self->chord_index];

6
src/audio/midi_note.c

@ -244,9 +244,9 @@ midi_note_get_global_start_pos ( @@ -244,9 +244,9 @@ midi_note_get_global_start_pos (
*/
void
midi_note_get_val_as_string (
MidiNote * self,
char * buf,
const int use_markup)
const MidiNote * self,
char * buf,
const int use_markup)
{
const char * note_str =
chord_descriptor_note_to_string (

136
src/gui/backend/arranger_object.c

@ -1983,7 +1983,7 @@ arranger_object_get_track ( @@ -1983,7 +1983,7 @@ arranger_object_get_track (
*/
ArrangerWidget *
arranger_object_get_arranger (
ArrangerObject * self)
const ArrangerObject * self)
{
g_return_val_if_fail (
IS_ARRANGER_OBJECT (self), NULL);
@ -2267,7 +2267,7 @@ arranger_object_find ( @@ -2267,7 +2267,7 @@ arranger_object_find (
static ArrangerObject *
clone_region (
ZRegion * region)
const ZRegion * region)
{
g_return_val_if_fail (region->name, NULL);
@ -2284,24 +2284,25 @@ clone_region ( @@ -2284,24 +2284,25 @@ clone_region (
region->id.track_name_hash,
region->id.lane_pos,
region->id.idx);
ZRegion * mr_orig = region;
const ZRegion * mr_orig = region;
for (int i = 0;
i < mr_orig->num_midi_notes; i++)
{
MidiNote * orig_mn =
const MidiNote * orig_mn =
mr_orig->midi_notes[i];
ArrangerObject * orig_mn_obj =
(ArrangerObject *) orig_mn;
MidiNote * mn;
const ArrangerObject * orig_mn_obj =
(const ArrangerObject *) orig_mn;
#if 0
/* FIXME why is this editing the
* original object? check and remove */
region_identifier_copy (
&orig_mn_obj->region_id,
&mr_orig->id);
mn =
#endif
MidiNote * mn =
(MidiNote *)
arranger_object_clone (
(ArrangerObject *)
mr_orig->midi_notes[i]);
arranger_object_clone (orig_mn_obj);
midi_region_add_midi_note (
mr, mn, F_NO_PUBLISH_EVENTS);
@ -2353,17 +2354,17 @@ clone_region ( @@ -2353,17 +2354,17 @@ clone_region (
region->id.track_name_hash,
region->id.at_idx,
region->id.idx);
ZRegion * ar_orig = region;
const ZRegion * ar_orig = region;
/* add automation points */
AutomationPoint * src_ap, * dest_ap;
for (int j = 0; j < ar_orig->num_aps; j++)
{
src_ap = ar_orig->aps[j];
ArrangerObject * src_ap_obj =
const AutomationPoint * src_ap =
ar_orig->aps[j];
const ArrangerObject * src_ap_obj =
(ArrangerObject *) src_ap;
dest_ap =
AutomationPoint * dest_ap =
automation_point_new_float (
src_ap->fvalue,
src_ap->normalized_val,
@ -2383,15 +2384,15 @@ clone_region ( @@ -2383,15 +2384,15 @@ clone_region (
chord_region_new (
&r_obj->pos, &r_obj->end_pos,
region->id.idx);
ZRegion * cr_orig = region;
ChordObject * src_co, * dest_co;
const ZRegion * cr_orig = region;
for (int i = 0;
i < cr_orig->num_chord_objects;
i++)
{
src_co = cr_orig->chord_objects[i];
const ChordObject * src_co =
cr_orig->chord_objects[i];
dest_co =
ChordObject * dest_co =
(ChordObject *)
arranger_object_clone (
(ArrangerObject *) src_co);
@ -2431,19 +2432,19 @@ clone_region ( @@ -2431,19 +2432,19 @@ clone_region (
*/
const char *
arranger_object_get_name (
ArrangerObject * self)
const ArrangerObject * self)
{
switch (self->type)
{
case ARRANGER_OBJECT_TYPE_REGION:
{
ZRegion * r = (ZRegion *) self;
const ZRegion * r = (const ZRegion *) self;
return r->name;
}
break;
case ARRANGER_OBJECT_TYPE_MARKER:
{
Marker * m = (Marker *) self;
const Marker * m = (const Marker *) self;
return m->name;
}
break;
@ -2453,13 +2454,67 @@ arranger_object_get_name ( @@ -2453,13 +2454,67 @@ arranger_object_get_name (
return NULL;
}
/**
* Generates a human readable name for the object.
*
* If the object has a name, this returns a copy
* of the name, otherwise generates something
* appropriate.
*
* Must be free'd by caller.
*/
char *
arranger_object_gen_human_readable_name (
const ArrangerObject * self)
{
switch (self->type)
{
case ARRANGER_OBJECT_TYPE_REGION:
{
const ZRegion * r = (const ZRegion *) self;
return g_strdup (r->name);
}
break;
case ARRANGER_OBJECT_TYPE_MARKER:
{
const Marker * m = (const Marker *) self;
return g_strdup (m->name);
}
break;
case ARRANGER_OBJECT_TYPE_MIDI_NOTE:
{
const MidiNote * mn =
(const MidiNote *) self;
char str[40];
midi_note_get_val_as_string (mn, str, 0);
return g_strdup (str);
}
break;
case ARRANGER_OBJECT_TYPE_CHORD_OBJECT:
{
const ChordObject * co =
(const ChordObject *) self;
ChordDescriptor * descr =
chord_object_get_chord_descriptor (co);
char str[400];
chord_descriptor_to_string (descr, str);
return g_strdup (str);
}
break;
default:
break;
}
g_return_val_if_reached (NULL);
}
/**
* Generates the escaped name for the object,
* where applicable.
*/
void
arranger_object_gen_escaped_name (
ArrangerObject * self)
const ArrangerObject * self)
{
switch (self->type)
{
@ -2484,7 +2539,7 @@ arranger_object_gen_escaped_name ( @@ -2484,7 +2539,7 @@ arranger_object_gen_escaped_name (
static ArrangerObject *
clone_midi_note (
MidiNote * src)
const MidiNote * src)
{
ArrangerObject * src_obj =
(ArrangerObject *) src;
@ -2503,7 +2558,7 @@ clone_midi_note ( @@ -2503,7 +2558,7 @@ clone_midi_note (
static ArrangerObject *
clone_chord_object (
ChordObject * src)
const ChordObject * src)
{
ArrangerObject * src_obj =
(ArrangerObject *) src;
@ -2517,7 +2572,7 @@ clone_chord_object ( @@ -2517,7 +2572,7 @@ clone_chord_object (
static ArrangerObject *
clone_scale_object (
ScaleObject * src)
const ScaleObject * src)
{
MusicalScale * musical_scale =
musical_scale_clone (src->scale);
@ -2530,7 +2585,7 @@ clone_scale_object ( @@ -2530,7 +2585,7 @@ clone_scale_object (
static ArrangerObject *
clone_marker (
Marker * src)
const Marker * src)
{
Marker * marker = marker_new (src->name);
marker->index = src->index;
@ -2542,7 +2597,7 @@ clone_marker ( @@ -2542,7 +2597,7 @@ clone_marker (
static ArrangerObject *
clone_automation_point (
AutomationPoint * src)
const AutomationPoint * src)
{
if (ZRYTHM_TESTING)
{
@ -2574,7 +2629,7 @@ clone_automation_point ( @@ -2574,7 +2629,7 @@ clone_automation_point (
*/
ArrangerObject *
arranger_object_clone (
ArrangerObject * self)
const ArrangerObject * self)
{
g_return_val_if_fail (self, NULL);
@ -2583,39 +2638,40 @@ arranger_object_clone ( @@ -2583,39 +2638,40 @@ arranger_object_clone (
{
case TYPE (REGION):
new_obj =
clone_region ((ZRegion *) self);
clone_region ((const ZRegion *) self);
break;
case TYPE (MIDI_NOTE):
new_obj =
clone_midi_note ((MidiNote *) self);
clone_midi_note ((const MidiNote *) self);
break;
case TYPE (CHORD_OBJECT):
new_obj =
clone_chord_object (
(ChordObject *) self);
(const ChordObject *) self);
break;
case TYPE (SCALE_OBJECT):
new_obj =
clone_scale_object (
(ScaleObject *) self);
(const ScaleObject *) self);
break;
case TYPE (AUTOMATION_POINT):
new_obj =
clone_automation_point (
(AutomationPoint *) self);
(const AutomationPoint *) self);
break;
case TYPE (MARKER):
new_obj =
clone_marker (
(Marker *) self);
(const Marker *) self);
break;
case TYPE (VELOCITY):
{
Velocity * src = (Velocity *) self;
MidiNote * mn =
velocity_get_midi_note (src);
const Velocity * src =
(const Velocity *) self;
/*const MidiNote * mn =*/
/*velocity_get_midi_note (src);*/
Velocity * new_vel =
velocity_new (mn, src->vel);
velocity_new (NULL, src->vel);
new_obj =
(ArrangerObject *) new_vel;
new_vel->vel_at_start = src->vel_at_start;

52
src/gui/backend/event_manager.c

@ -390,23 +390,29 @@ refresh_for_selections_type ( @@ -390,23 +390,29 @@ refresh_for_selections_type (
{
case ARRANGER_SELECTIONS_TYPE_TIMELINE:
event_viewer_widget_refresh (
MW_TIMELINE_EVENT_VIEWER);
MW_TIMELINE_EVENT_VIEWER, false);
break;
case ARRANGER_SELECTIONS_TYPE_MIDI:
event_viewer_widget_refresh (
MW_EDITOR_EVENT_VIEWER);
MW_MIDI_EVENT_VIEWER, false);
break;
case ARRANGER_SELECTIONS_TYPE_CHORD:
event_viewer_widget_refresh (
MW_EDITOR_EVENT_VIEWER);
MW_CHORD_EVENT_VIEWER, false);
break;
case ARRANGER_SELECTIONS_TYPE_AUTOMATION:
event_viewer_widget_refresh (
MW_EDITOR_EVENT_VIEWER);
MW_AUTOMATION_EVENT_VIEWER, false);
break;
case ARRANGER_SELECTIONS_TYPE_AUDIO:
event_viewer_widget_refresh (
MW_AUDIO_EVENT_VIEWER, false);
break;
default:
g_return_if_reached ();
}
bot_dock_edge_widget_update_event_viewer_stack_page (
MW_BOT_DOCK_EDGE);
}
static void
@ -429,27 +435,29 @@ arranger_selections_change_redraw_everything ( @@ -429,27 +435,29 @@ arranger_selections_change_redraw_everything (
{
case ARRANGER_SELECTIONS_TYPE_TIMELINE:
event_viewer_widget_refresh (
MW_TIMELINE_EVENT_VIEWER);
MW_TIMELINE_EVENT_VIEWER, false);
break;
case ARRANGER_SELECTIONS_TYPE_MIDI:
event_viewer_widget_refresh (
MW_EDITOR_EVENT_VIEWER);
MW_MIDI_EVENT_VIEWER, false);
break;
case ARRANGER_SELECTIONS_TYPE_CHORD:
event_viewer_widget_refresh (
MW_EDITOR_EVENT_VIEWER);
MW_CHORD_EVENT_VIEWER, false);
break;
case ARRANGER_SELECTIONS_TYPE_AUTOMATION:
event_viewer_widget_refresh (
MW_EDITOR_EVENT_VIEWER);
MW_AUTOMATION_EVENT_VIEWER, false);
break;
case ARRANGER_SELECTIONS_TYPE_AUDIO:
event_viewer_widget_refresh (
MW_EDITOR_EVENT_VIEWER);
MW_AUDIO_EVENT_VIEWER, false);
break;
default:
g_return_if_reached ();
}
bot_dock_edge_widget_update_event_viewer_stack_page (
MW_BOT_DOCK_EDGE);
}
static void
@ -535,18 +543,11 @@ on_arranger_object_changed ( @@ -535,18 +543,11 @@ on_arranger_object_changed (
{
g_return_if_fail (IS_ARRANGER_OBJECT (obj));
/* parent region, if any */
ArrangerObject * parent_r_obj =
(ArrangerObject *)
arranger_object_get_region (obj);
bool is_timeline = !parent_r_obj;
if (is_timeline)
event_viewer_widget_refresh (
MW_TIMELINE_EVENT_VIEWER);
else
event_viewer_widget_refresh (
MW_EDITOR_EVENT_VIEWER);
ArrangerSelections * sel =
arranger_object_get_selections_for_type (
obj->type);
event_viewer_widget_refresh_for_selections (
sel);
switch (obj->type)
{
@ -883,12 +884,13 @@ event_manager_process_event ( @@ -883,12 +884,13 @@ event_manager_process_event (
on_playhead_changed (true);
break;
case ET_CLIP_EDITOR_REGION_CHANGED:
/*on_clip_editor_region_changed ();*/
clip_editor_widget_on_region_changed (
MW_CLIP_EDITOR);
PIANO_ROLL->num_current_notes = 0;
piano_roll_keys_widget_redraw_full (
MW_PIANO_ROLL_KEYS);
bot_dock_edge_widget_update_event_viewer_stack_page (
MW_BOT_DOCK_EDGE);
break;
case ET_TRACK_AUTOMATION_VISIBILITY_CHANGED:
tracklist_widget_update_track_visibility (
@ -1115,7 +1117,7 @@ event_manager_process_event ( @@ -1115,7 +1117,7 @@ event_manager_process_event (
ArrangerWidget * arranger =
Z_ARRANGER_WIDGET (ev->arg);
event_viewer_widget_refresh_for_arranger (
arranger);
arranger, true);
timeline_toolbar_widget_refresh (
MW_TIMELINE_TOOLBAR);
}
@ -1125,9 +1127,11 @@ event_manager_process_event ( @@ -1125,9 +1127,11 @@ event_manager_process_event (
break;
case ET_CLIP_EDITOR_FIRST_TIME_REGION_SELECTED:
gtk_widget_set_visible (
GTK_WIDGET (MW_EDITOR_EVENT_VIEWER),
GTK_WIDGET (MW_EDITOR_EVENT_VIEWER_STACK),
g_settings_get_boolean (
S_UI, "editor-event-viewer-visible"));
bot_dock_edge_widget_update_event_viewer_stack_page (
MW_BOT_DOCK_EDGE);
break;
case ET_PIANO_ROLL_MIDI_MODIFIER_CHANGED:
break;

4
src/gui/widgets/balance_control.c

@ -422,13 +422,9 @@ static void @@ -422,13 +422,9 @@ static void
balance_control_finalize (
BalanceControlWidget * self)
{
g_debug ("finalizing...");
G_OBJECT_CLASS (
balance_control_widget_parent_class)->
finalize (G_OBJECT (self));
g_debug ("done");
}
static void

88
src/gui/widgets/bot_dock_edge.c

@ -55,6 +55,47 @@ on_notebook_switch_page ( @@ -55,6 +55,47 @@ on_notebook_switch_page (
S_UI, "bot-panel-tab", (int) page_num);
}
/**
* Sets the appropriate stack page.
*/
void
bot_dock_edge_widget_update_event_viewer_stack_page (
BotDockEdgeWidget * self)
{
ZRegion * r =
clip_editor_get_region (CLIP_EDITOR);
if (r)
{
switch (r->id.type)
{
case REGION_TYPE_MIDI:
gtk_stack_set_visible_child_name (
self->event_viewer_stack, "midi");
event_viewer_widget_refresh (
self->event_viewer_midi, false);
break;
case REGION_TYPE_AUDIO:
gtk_stack_set_visible_child_name (
self->event_viewer_stack, "audio");
event_viewer_widget_refresh (
self->event_viewer_audio, false);
break;
case REGION_TYPE_CHORD:
gtk_stack_set_visible_child_name (
self->event_viewer_stack, "chord");
event_viewer_widget_refresh (
self->event_viewer_chord, false);
break;
case REGION_TYPE_AUTOMATION:
gtk_stack_set_visible_child_name (
self->event_viewer_stack, "automation");
event_viewer_widget_refresh (
self->event_viewer_automation, false);
break;
}
}
}
void
bot_dock_edge_widget_setup (
BotDockEdgeWidget * self)
@ -65,8 +106,19 @@ bot_dock_edge_widget_setup ( @@ -65,8 +106,19 @@ bot_dock_edge_widget_setup (
GTK_POS_BOTTOM);
event_viewer_widget_setup (
self->event_viewer,
EVENT_VIEWER_TYPE_EDITOR);
self->event_viewer_midi,
EVENT_VIEWER_TYPE_MIDI);
event_viewer_widget_setup (
self->event_viewer_audio,
EVENT_VIEWER_TYPE_AUDIO);
event_viewer_widget_setup (
self->event_viewer_chord,
EVENT_VIEWER_TYPE_CHORD);
event_viewer_widget_setup (
self->event_viewer_automation,
EVENT_VIEWER_TYPE_AUTOMATION);
bot_dock_edge_widget_update_event_viewer_stack_page (
self);
chord_pad_panel_widget_setup (
self->chord_pad_panel);
@ -82,7 +134,8 @@ bot_dock_edge_widget_setup ( @@ -82,7 +134,8 @@ bot_dock_edge_widget_setup (
visibility = true;
}
gtk_widget_set_visible (
GTK_WIDGET (self->event_viewer), visibility);
GTK_WIDGET (self->event_viewer_stack),
visibility);
GtkNotebook * notebook =
foldable_notebook_widget_get_notebook (
@ -131,6 +184,9 @@ bot_dock_edge_widget_show_clip_editor ( @@ -131,6 +184,9 @@ bot_dock_edge_widget_show_clip_editor (
}
}
bot_dock_edge_widget_update_event_viewer_stack_page (
self);
if (navigate_to_region_start
&& CLIP_EDITOR->has_region)
{
@ -180,10 +236,32 @@ generate_bot_notebook ( @@ -180,10 +236,32 @@ generate_bot_notebook (
gtk_paned_set_start_child (
self->clip_editor_plus_event_viewer_paned,
GTK_WIDGET (self->clip_editor));
self->event_viewer = event_viewer_widget_new ();
self->event_viewer_stack =
GTK_STACK (gtk_stack_new ());
self->event_viewer_midi =
event_viewer_widget_new ();
gtk_stack_add_named (
self->event_viewer_stack,
GTK_WIDGET (self->event_viewer_midi), "midi");
self->event_viewer_chord =
event_viewer_widget_new ();
gtk_stack_add_named (
self->event_viewer_stack,
GTK_WIDGET (self->event_viewer_chord), "chord");
self->event_viewer_automation =
event_viewer_widget_new ();
gtk_stack_add_named (
self->event_viewer_stack,
GTK_WIDGET (self->event_viewer_automation),
"automation");
self->event_viewer_audio =
event_viewer_widget_new ();
gtk_stack_add_named (
self->event_viewer_stack,
GTK_WIDGET (self->event_viewer_audio), "audio");
gtk_paned_set_end_child (
self->clip_editor_plus_event_viewer_paned,
GTK_WIDGET (self->event_viewer));
GTK_WIDGET (self->event_viewer_stack));
self->mixer_box =
GTK_BOX (

33
src/gui/widgets/cc_bindings_tree.c

@ -132,18 +132,6 @@ on_right_click ( @@ -132,18 +132,6 @@ on_right_click (
#endif
}
static GListStore *
get_list_store (
CcBindingsTreeWidget * self)
{
GtkSelectionModel * sel_model =
gtk_column_view_get_model (self->column_view);
GListModel * model =
gtk_multi_selection_get_model (
GTK_MULTI_SELECTION (sel_model));
return G_LIST_STORE (model);
}
/**
* Refreshes the tree model.
*/
@ -151,7 +139,9 @@ void @@ -151,7 +139,9 @@ void
cc_bindings_tree_widget_refresh (
CcBindingsTreeWidget * self)
{
GListStore * store = get_list_store (self);
GListStore * store =
z_gtk_column_view_get_list_store (
self->column_view);
g_list_store_remove_all (store);
@ -259,10 +249,25 @@ cc_bindings_tree_widget_new () @@ -259,10 +249,25 @@ cc_bindings_tree_widget_new ()
return self;
}
static void
cc_bindings_tree_finalize (
CcBindingsTreeWidget * self)
{
g_ptr_array_unref (self->item_factories);
G_OBJECT_CLASS (
cc_bindings_tree_widget_parent_class)->
finalize (G_OBJECT (self));
}
static void
cc_bindings_tree_widget_class_init (
CcBindingsTreeWidgetClass * _klass)
CcBindingsTreeWidgetClass * klass)
{
GObjectClass * oklass =
G_OBJECT_CLASS (klass);
oklass->finalize =
(GObjectFinalizeFunc) cc_bindings_tree_finalize;
}
static void

1139
src/gui/widgets/event_viewer.c

File diff suppressed because it is too large Load Diff

481
src/gui/widgets/item_factory.c

@ -19,6 +19,7 @@ @@ -19,6 +19,7 @@
#include "audio/midi_mapping.h"
#include "gui/backend/wrapped_object_with_change_signal.h"
#include "gui/widgets/digital_meter.h"
#include "gui/widgets/item_factory.h"
#include "gui/widgets/popover_menu_bin.h"
#include "plugins/collection.h"
@ -165,23 +166,52 @@ item_factory_setup_cb ( @@ -165,23 +166,52 @@ item_factory_setup_cb (
{
GtkWidget * check_btn =
gtk_check_button_new ();
if (!self->editable)
{
gtk_widget_set_sensitive (
GTK_WIDGET (check_btn), false);
}
popover_menu_bin_widget_set_child (
bin, check_btn);
gtk_list_item_set_child (
listitem, GTK_WIDGET (bin));
}
break;
case ITEM_FACTORY_TEXT:
case ITEM_FACTORY_INTEGER:
case ITEM_FACTORY_POSITION:
{
GtkWidget * label = gtk_label_new ("");
GtkWidget * label;
const int max_chars = 20;
if (self->editable)
{
label = gtk_editable_label_new ("");
gtk_editable_set_max_width_chars (
GTK_EDITABLE (label), max_chars);
GtkWidget * inner_label =
z_gtk_widget_find_child_of_type (
label, GTK_TYPE_LABEL);
g_return_if_fail (inner_label);
gtk_label_set_ellipsize (
GTK_LABEL (inner_label),
PANGO_ELLIPSIZE_END);
gtk_label_set_max_width_chars (
GTK_LABEL (inner_label), max_chars);
}
else
{
label = gtk_label_new ("");
gtk_label_set_ellipsize (
GTK_LABEL (label),
PANGO_ELLIPSIZE_END);
gtk_label_set_max_width_chars (
GTK_LABEL (label), max_chars);
}
popover_menu_bin_widget_set_child (
bin, label);
gtk_list_item_set_child (
listitem, GTK_WIDGET (bin));
}
break;
case ITEM_FACTORY_ICON_AND_TEXT:
{
g_return_if_fail (!self->editable);
GtkBox * box =
GTK_BOX (
gtk_box_new (
@ -194,14 +224,15 @@ item_factory_setup_cb ( @@ -194,14 +224,15 @@ item_factory_setup_cb (
gtk_box_append (GTK_BOX (box), label);
popover_menu_bin_widget_set_child (
bin, GTK_WIDGET (box));
gtk_list_item_set_child (
listitem, GTK_WIDGET (bin));
}
break;
default:
break;
}
gtk_list_item_set_child (
listitem, GTK_WIDGET (bin));
#if 0
g_signal_connect (
G_OBJECT (listitem), "notify::selected",
@ -214,169 +245,14 @@ add_plugin_descr_context_menu ( @@ -214,169 +245,14 @@ add_plugin_descr_context_menu (
PopoverMenuBinWidget * bin,
PluginDescriptor * descr)
{
GMenu * menu =
G_MENU (
popover_menu_bin_widget_get_menu_model (bin));
if (menu)
g_menu_remove_all (menu);
else
menu = g_menu_new ();
GMenuItem * menuitem;
char tmp[600];
/* TODO */
#if 0
/* add option for native generic LV2 UI */
if (descr->protocol == PROT_LV2
&&
descr->min_bridge_mode == CARLA_BRIDGE_NONE)
{
menuitem =
z_gtk_create_menu_item (
_("Add to project (native generic UI)"),
NULL,
"app.plugin-browser-add-to-project");
g_menu_append_item (menu, menuitem);
}
#endif
#ifdef HAVE_CARLA
sprintf (
tmp,
"app.plugin-browser-add-to-project-carla::%p",
descr);
menuitem =
z_gtk_create_menu_item (
_("Add to project"), NULL, tmp);
g_menu_append_item (menu, menuitem);
PluginSetting * new_setting =
plugin_setting_new_default (descr);
if (descr->has_custom_ui &&
descr->min_bridge_mode ==
CARLA_BRIDGE_NONE &&
!new_setting->force_generic_ui)
{
sprintf (
tmp,
"app.plugin-browser-add-to-project-"
"bridged-ui::%p",
descr);
menuitem =
z_gtk_create_menu_item (
_("Add to project (bridged UI)"), NULL,
tmp);
g_menu_append_item (menu, menuitem);
}
plugin_setting_free (new_setting);
sprintf (
tmp,
"app.plugin-browser-add-to-project-bridged-"
"full::%p",
descr);
menuitem =
z_gtk_create_menu_item (
_("Add to project (bridged full)"), NULL,
tmp);
g_menu_append_item (menu, menuitem);
#endif
#if 0
menuitem =
GTK_MENU_ITEM (
gtk_check_menu_item_new_with_mnemonic (
_("Use _Generic UI")));
APPEND;
gtk_check_menu_item_set_active (
GTK_CHECK_MENU_ITEM (menuitem),
new_setting->force_generic_ui);
g_signal_connect (
G_OBJECT (menuitem), "toggled",
G_CALLBACK (on_use_generic_ui_toggled), descr);
#endif
/* add to collection */
GMenu * add_collections_submenu = g_menu_new ();
int num_added = 0;
for (int i = 0;
i < PLUGIN_MANAGER->collections->
num_collections;
i++)
{
PluginCollection * coll =
PLUGIN_MANAGER->collections->collections[i];
if (plugin_collection_contains_descriptor (
coll, descr, false))
{
continue;
}
sprintf (
tmp,
"app.plugin-browser-add-to-collection::%p",
coll);
menuitem =
z_gtk_create_menu_item (
coll->name, NULL, tmp);
g_menu_append_item (