1 #ifndef EFFECTUI_H 2 #define EFFECTUI_H 3 4 #include "collapsiblewidget.h" 5 #include "effects/effect.h" 6 7 /** 8 * @brief The EffectUI class 9 * 10 * EffectUI is a complete QWidget-based representation of an Effect that can be added to any Qt layout. It overrides 11 * CollapsibleWidget (meaning the Effect can be collapsed to just a titlebar to save space). The titlebar is 12 * automatically set to the Effect's name and the contents are composed of a grid layout (QGridLayout) corresponding 13 * to the Effect's EffectRow and EffectField children. 14 * 15 * Many EffectUIs can be created from a single Effect, and many Effects can be attached to a single EffectUI (provided 16 * the Effects are all the same type). Neither gains ownership of each other and deleting an EffectUI without any other 17 * work is perfectly safe (deleting an Effect with an open EffectUI however, is not). 18 */ 19 class EffectUI : public CollapsibleWidget { 20 Q_OBJECT 21 public: 22 /** 23 * @brief EffectUI Constructor 24 * 25 * Creates a QWidget-based UI representation of an Effect. 26 * 27 * @param e 28 * 29 * The Effect to make a UI of. It must be a valid object. 30 */ 31 EffectUI(Effect* e); 32 33 /** 34 * @brief Attach additional effects to this UI 35 * 36 * Olive allows users to modify several effects (of the same type) with one UI representation. To do this, you can 37 * add any amount of extra Effect objects using this function and the UI will attach all of its UI functions to that 38 * Effect as well without creating any new QWidgets. 39 * 40 * @param e 41 * 42 * The Effect to add to this UI object. 43 */ 44 void AddAdditionalEffect(Effect* e); 45 46 /** 47 * @brief Get the primary Effect that this UI object was created for 48 * 49 * @return 50 * 51 * The Effect object passed to the constructor when creating this EffectUI. 52 */ 53 Effect* GetEffect(); 54 55 /** 56 * @brief Get the Y position of a given row 57 * 58 * Retrieve the on-screen Y position of the attached Effect's EffectRow at a given index. This is primarily used for 59 * displaying UI elements that align with the the row's on-screen widgets (e.g. keyframes in the EffectControls 60 * panel). 61 * 62 * The Y value provided is specifically the center point of the row's name label. It gets mapped to a provided 63 * QWidget object so it can be used locally by that QWidget without further modification. 64 * 65 * @param row 66 * 67 * The index of the EffectRow to retrieve the Y position of. 68 * 69 * @param mapToWidget 70 * 71 * The widget to map the Y value to. 72 * 73 * @return 74 * 75 * The row's Y position. 76 */ 77 int GetRowY(int row, QWidget *mapToWidget); 78 79 /** 80 * @brief Update widgets with the current Effect's values. 81 * 82 * When the Timeline playhead moves, the current values in the Effect might change if its fields are keyframed. 83 * In order to visually update these values on the UI, this function should be called. It will loop through all 84 * fields of all attached effects and update them to the value at the current Timeline playhead. 85 * 86 * Currently this function is called by update_ui() which is also responsible for updating other parts of the UI 87 * like the Timeline and Viewer so they all get updated together. 88 */ 89 void UpdateFromEffect(); 90 91 /** 92 * @brief Check if a given Clip has an Effect referenced by this EffectUI 93 * 94 * Olive allows users to modify several effects (of the same type) with one UI representation. The behavior is if 95 * multiple clips are selected that have effects of the same type, all those Effects can be modified by the same 96 * EffectUI object. However this behavior is undesirable if a single Clip has more than one of the same type of Effect 97 * (e.g. two or more blurs). In this scenario, the user will most likely expect two separate UI objects for each of 98 * these effects individually, rather than consolidating them into one UI object. 99 * 100 * To address this, EffectControls will check this function to determine if this EffectUI already references 101 * an Effect of this type from this Clip. If it does, it's assumed a new EffectUI should be made rather than 102 * consolidating that Effect into the same EffectUI. 103 * 104 * @param c 105 * 106 * The Clip to determine whether an Effect of this type is already referenced by this EffectUI. 107 * 108 * @return 109 * 110 * True is an Effect from this Clip is already attached to this EffectUI. 111 */ 112 bool IsAttachedToClip(Clip* c); 113 114 signals: 115 /** 116 * @brief Cut signal 117 * 118 * Emitted when the user selects Cut from the right-click context menu. 119 */ 120 void CutRequested(); 121 122 /** 123 * @brief Copy signal 124 * 125 * Emitted when the user selects Copy from the right-click context menu. 126 */ 127 void CopyRequested(); 128 private: 129 /** 130 * @brief Retrieve the QWidget corresponding a specific EffectField 131 * 132 * Convenience function equivalent to widgets_.at(row).at(field). 133 * 134 * @param row 135 * 136 * EffectRow index to retrieve field QWidget from 137 * 138 * @param field 139 * 140 * EffectField index to retrieve QWidget from 141 * 142 * @return 143 * 144 * The QWidget at this row and field index. 145 */ 146 QWidget* Widget(int row, int field); 147 148 /** 149 * @brief Internal reference to the Effect this object was constructed around. 150 */ 151 Effect* effect_; 152 153 /** 154 * @brief Internal array of additional Effect objects attached to this UI. 155 */ 156 QVector<Effect*> additional_effects_; 157 158 /** 159 * @brief Layout for UI widgets 160 */ 161 QGridLayout* layout_; 162 163 /** 164 * @brief Grid array of QWidgets corresponding to the Effect's rows and fields 165 */ 166 QVector< QVector<QWidget*> > widgets_; 167 168 /** 169 * @brief Array of QLabel objects corresponding to each row's name(). 170 */ 171 QVector<QLabel*> labels_; 172 173 /** 174 * @brief Array of KeyframeNavigator objects corresponding to each row. 175 */ 176 QVector<KeyframeNavigator*> keyframe_navigators_; 177 178 /** 179 * @brief Attach a KeyframeNavigator object to an EffectRow. 180 * 181 * Internal function for connecting a KeyframeNavigator UI object to an EffectRow. 182 * 183 * @param row 184 * 185 * The EffectRow object. 186 * 187 * @param nav 188 * 189 * The KeyframeNavigator object. 190 */ 191 void AttachKeyframeNavigationToRow(EffectRow* row, KeyframeNavigator* nav); 192 private slots: 193 /** 194 * @brief Slot for titlebar's right-click signal to show a context menu for extra Effect functions. 195 */ 196 void show_context_menu(const QPoint&); 197 }; 198 199 #endif // EFFECTUI_H 200