Olive
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
Public Types | Signals | Public Member Functions | Public Attributes | Private Member Functions | Private Attributes | List of all members
EffectField Class Referenceabstract

The EffectField class. More...

#include <effectfield.h>

Inheritance diagram for EffectField:
BoolField ButtonField ColorField ComboField DoubleField FileField FontField LabelField StringField

Public Types

enum  EffectFieldType {
  EFFECT_FIELD_DOUBLE, EFFECT_FIELD_COLOR, EFFECT_FIELD_STRING, EFFECT_FIELD_BOOL,
  EFFECT_FIELD_COMBO, EFFECT_FIELD_FONT, EFFECT_FIELD_FILE, EFFECT_FIELD_UI
}
 The EffectFieldType enum. More...
 

Signals

void Changed ()
 Changed signal. More...
 
void Clicked ()
 Clicked signal. More...
 
void EnabledChanged (bool)
 Enable change state signal. More...
 

Public Member Functions

 EffectField (EffectRow *parent, const QString &i, EffectFieldType t)
 EffectField Constructor. More...
 
EffectRowGetParentRow ()
 Get the EffectRow that this field is a member of. More...
 
const EffectFieldTypetype ()
 Get the type of data to expect from this field. More...
 
const QString & id ()
 Get the unique identifier of this field set in the constructor. More...
 
QVariant GetValueAt (double timecode)
 Get the value of this field at a given timecode. More...
 
void SetValueAt (double time, const QVariant &value)
 Set the value of this field at a given timecode. More...
 
double Now ()
 Get the current clip/media time. More...
 
void PrepareDataForKeyframing (bool enabled, ComboAction *ca)
 Set up keyframing on this field. More...
 
int GetColumnSpan ()
 Get field's column span. More...
 
void SetColumnSpan (int i)
 Set field's column span. More...
 
virtual QString ConvertValueToString (const QVariant &v)
 Convert a value from this field to a string. More...
 
virtual QVariant ConvertStringToValue (const QString &s)
 Convert a string to a value appropriate for this field. More...
 
virtual QWidget * CreateWidget (QWidget *existing=nullptr)=0
 Create a widget for the user to interact with this field. More...
 
virtual void UpdateWidgetValue (QWidget *widget, double timecode)
 Update a widget created by CreateWidget() using the value at a given time. More...
 
double GetValidKeyframeHandlePosition (int key, bool post)
 Get the correct X position/time value of a bezier keyframe's handles. More...
 
bool IsEnabled ()
 Return whether this field is enabled or not. More...
 
void SetEnabled (bool e)
 Set the enabled state of this field. More...
 

Public Attributes

QVariant persistent_data_
 Persistent data object. More...
 
QVector< EffectKeyframekeyframes
 Keyframe array. More...
 

Private Member Functions

bool HasKeyframes ()
 Used by GetValueAt() to determine whether to use keyframe data or persistent data. More...
 
double FrameToSeconds (long frame)
 Convert clip time in frames to clip time in seconds. More...
 
long SecondsToFrame (double seconds)
 Convert clip time in seconds to clip time in frames. More...
 
void GetKeyframeData (double timecode, int &before, int &after, double &d)
 Internal function for determining where we are between the available keyframes. More...
 
long NowInFrames ()
 Retrieve the current clip as a frame number. More...
 

Private Attributes

EffectFieldType type_
 Internal type variable set in the constructor. Access with type(). More...
 
QString id_
 Internal unique identifier for this field set in the constructor. Access with id(). More...
 
bool enabled_
 Internal enabled value. More...
 
int colspan_
 Internal column span value. More...
 

Detailed Description

The EffectField class.

Any user-interactive element of an Effect. Usually a parameter that modifies the effect output, but sometimes just a UI object that performs some other function (e.g. LabelField and ButtonField).

EffectField provides a largely abstract interface for Effect classes to pull information from. The class itself handles keyframing between linear, bezier, and hold interpolation accessible through GetValueAt(). This class is abstract, and therefore never intended to be used on its own. Instead you should always use a derived class.

EffectField objects are not UI objects on their own. Instead, they're largely a system of values that can change over time. For a widget that the user can use to edit/modify these values, use CreateWidget().

Derived classes are expected to override at least CreateWidget() to create a visual interactive widget corresponding to the field. If this field is a value used in the Effect (as most will be), UpdateWidgetValue() should also be overridden to display the correct value for this field as the user moves around the Timeline.

If the field is intended to be saved and loaded from Olive project files (as most will be), ConvertStringToValue() and ConvertValueToString() may also have to be overridden depending on how the derived class's data works.

Member Enumeration Documentation

The EffectFieldType enum.

Predetermined types of fields. Used throughout Olive to identify what kind of data to expect from GetValueAt().

This enum is also currently used to match an external XML effect's fields with the correct derived class (e.g. EFFECT_FIELD_DOUBLE matches to DoubleField).

Enumerator
EFFECT_FIELD_DOUBLE 

Values are doubles. Also corresponds to DoubleField.

EFFECT_FIELD_COLOR 

Values are colors. Also corresponds to ColorField.

EFFECT_FIELD_STRING 

Values are strings. Also corresponds to StringField.

EFFECT_FIELD_BOOL 

Values are booleans. Also corresponds to BoolField.

EFFECT_FIELD_COMBO 

Values are arbitrary data. Also corresponds to ComboField.

EFFECT_FIELD_FONT 

Values are font family names (in string). Also corresponds to FontField.

EFFECT_FIELD_FILE 

Values are filenames (in string). Also corresponds to FileField.

EFFECT_FIELD_UI 

Values is a UI object with no data. Corresponds to nothing.

Constructor & Destructor Documentation

EffectField::EffectField ( EffectRow parent,
const QString &  i,
EffectFieldType  t 
)

EffectField Constructor.

Creates a new EffectField object.

Parameters
parentThe EffectRow to add this field to. This must be a valid EffectRow. The EffectRow takes ownership of the field using the QObject parent/child system to automate memory management. EffectFields are never expected to change parent during their lifetime.
iField ID. Must be non-empty. Must also be unique within this Effect. Used for saving/loading values into project files so that if ordering of fields are changed, or fields are added/removed from Effects later in development, saved values in project files will still link with the correct field. Also used as the uniform variable name in GLSL shaders.
tThe type of data contained within this field. This is expected to be filled by a derived class.

Member Function Documentation

void EffectField::Changed ( )
signal

Changed signal.

Emitted whenever SetValueAt() is called in order to trigger a UI update and Viewer repaint. Note this is NOT triggered as the value changes from keyframing. Only when the user themselves triggers a change.

void EffectField::Clicked ( )
signal

Clicked signal.

Emitted when the user clicks on a QWidget attached to this field. Derived classes should connect this to the clicked signal of any QWidget's created (or attached) in CreateWidget().

QVariant EffectField::ConvertStringToValue ( const QString &  s)
virtual

Convert a string to a value appropriate for this field.

This function is the inverse of ConvertValueToString(), converting a string back to field data.

Parameters
sThe string to convert to data.
Returns

QVariant data converted from the provided string.

Reimplemented in DoubleField, BoolField, and ColorField.

QString EffectField::ConvertValueToString ( const QVariant &  v)
virtual

Convert a value from this field to a string.

When saving effect data to a project file, the data needs to be converted to a string format for saving in XML. The needs of this string representation may differ depending on the needs of the derived class, therefore you derived classes may need to override it.

Default behavior is a simple QVariant <-> QString conversion, which should suffice in most cases.

Parameters
vThe QVariant data (retrieved from this field) to convert to string
Returns

A string representation of the QVariant data provided.

Reimplemented in DoubleField, BoolField, and ColorField.

virtual QWidget* EffectField::CreateWidget ( QWidget *  existing = nullptr)
pure virtual

Create a widget for the user to interact with this field.

EffectField objects are not UI objects on their own. Instead, they're largely a system of values that can change over time. This function creates a QWidget object that can be placed somewhere in the UI so the user can interact with and change the data in this field.

This function must be overridden by derived classes in order to create a widget that appropriate for that field's data. The derived class is also responsible for connecting signals like EnabledChanged(), Clicked(), and any other data that needs to be transferred between the widget and the field (setting up the signals and slots to do so). The field does NOT retain ownership (or any reference for that matter) to widgets it creates, so keeping the widget and field up to date with each other relies solely on setting up signals and slots. Infinite widgets can be created from a single field and used throughout Olive this way.

Ownership is passed to the caller, and therefore the caller is responsible for freeing it.

Parameters
existingOlive allows multiple effects to attach to one UI layout. Pass a QWidget to this parameter (instead of nullptr) to attach this field additionally to the widget's signals/slots without creating a new one. The QWidget must be a widget previously created from the same derived class type or the result is undefined.
Returns

A new QWidget object for this EffectField, or the same QWidget passed to existing if one was specified.

Implemented in DoubleField, ComboField, ButtonField, StringField, FontField, FileField, BoolField, ColorField, and LabelField.

void EffectField::EnabledChanged ( bool  )
signal

Enable change state signal.

Emitted when the field's enabled state is changed through SetEnabled(). Derived classes should connect this to the setEnabled() slot of any QWidget's created (or attached) in CreateWidget().

double EffectField::FrameToSeconds ( long  frame)
private

Convert clip time in frames to clip time in seconds.

Parameters
frameClip time in frames
Returns

Clip time in seconds

int EffectField::GetColumnSpan ( )

Get field's column span.

Used whenever constructing the effect's UI. EffectFields are visually laid out in a table, and some widgets can be set to take up multiple columns for a better visual flow.

Returns

The current column span.

void EffectField::GetKeyframeData ( double  timecode,
int &  before,
int &  after,
double &  d 
)
private

Internal function for determining where we are between the available keyframes.

Parameters
timecodeTimecode to get keyframe data at
beforeThe index (in the keyframes array) in the keyframe prior to this timecode.
afterThe index (in the keyframes array) in the keyframe after this timecode.
dThe progress between the before keyframe and after keyframe from 0.0 to 1.0.
EffectRow * EffectField::GetParentRow ( )

Get the EffectRow that this field is a member of.

Equivalent to static_cast<EffectRow*>(EffectField::parent())

Returns

The EffectRow that this field is a member of.

double EffectField::GetValidKeyframeHandlePosition ( int  key,
bool  post 
)

Get the correct X position/time value of a bezier keyframe's handles.

Retrieves the X value (time value) of a bezier keyframe's handles. Internally, the handles' X values are allowed to be arbitrary values. This however can lead to inadvertently creating impossible bezier curves (ones that, for example, mathematically loop over each other, but obviously a field can't have two values at the same time).

This function returns the keyframe handles' X values adjusted to prevent this from happening. All calculations are consistent (i.e. the post handle of one keyframe will be adjusted the same way as the pre handle of the keyframe before it). It's recommended to always use this function to retrieve keyframe handle X values.

Parameters
keyIndex of the keyframe (in keyframes) to retrieve the handle position from.
postFALSE to retrieve the "pre" handle (handle to the left of the keyframe), TRUE to retrieve the "post" handle (handle to the right of the keyframe).
Returns

The adjusted X value of that keyframe handle.

QVariant EffectField::GetValueAt ( double  timecode)

Get the value of this field at a given timecode.

EffectFields are designed to be keyframable, meaning the user can make the values change over the course of the Sequence. This is the main function used through Olive to retrieve what value this field will be at a given time.

A common use case for this function would be EffectField::GetValueAt(EffectField::Now()), which will automatically retrieve the timecode at the current playhead.

If the parent EffectRow is NOT keyframing, this function will simply return persistent_data_. If it IS keyframing, this will use the values in keyframes to determine what value should be specifically at this time. (bezier or linear interpolating it between values if necessary). Therefore this function should almost always be used to retrieve data from this field as the value will always be correct for the given time.

Parameters
timecodeThe time to retrieve the value in clip/media seconds (e.g. 0.0 is the very start of the media, 1.0 is one second into the media).
Returns

A QVariant representation of the value at the given timecode.

bool EffectField::HasKeyframes ( )
private

Used by GetValueAt() to determine whether to use keyframe data or persistent data.

Returns

TRUE if this keyframe data should be retrieved, FALSE if persistent data should be retrieved

const QString & EffectField::id ( )

Get the unique identifier of this field set in the constructor.

Mostly used for saving/loading or interacting with GLSL-based shader effects (see EffectField() for more details).

Returns
bool EffectField::IsEnabled ( )

Return whether this field is enabled or not.

Returns

TRUE if this field is enabled.

double EffectField::Now ( )

Get the current clip/media time.

A convenience function that can be plugged into GetValueAt() to get the value wherever the appropriate Sequence's playhead it.

Returns

Current clip/media time in seconds.

long EffectField::NowInFrames ( )
private

Retrieve the current clip as a frame number.

Same as Now() but retrieves the value as a frame number (in the appropriate Sequence's frame rate) instead of seconds.

Returns

The current clip time in frames

void EffectField::PrepareDataForKeyframing ( bool  enabled,
ComboAction ca 
)

Set up keyframing on this field.

This should always be called if the user is enabling/disabling keyframing on the parent row. This function will move data between persistent_data_ and keyframes depending on whether keyframing is being enabled or disabled.

If keyframing is getting ENABLED, this function will create the first keyframe automatically at the current time using the current value in persistent_data_.

If keyframing is getting DISABLED, persistent_data_ is set to the current value at this time (GetValueAt(Now())) and delete all current keyframes.

Parameters
enabledTRUE if keyframing is getting enabled.
caA valid ComboAction object. It's expected that this function will be part of a larger action to enable/disable keyframing on the parent EffectRow, so this function will add commands to this ComboAction.
long EffectField::SecondsToFrame ( double  seconds)
private

Convert clip time in seconds to clip time in frames.

Parameters
secondsClip time in seconds
Returns

Clip time in frames

void EffectField::SetColumnSpan ( int  i)

Set field's column span.

Used whenever constructing the effect's UI. EffectFields are visually laid out in a table, and some widgets can be set to take up multiple columns for a better visual flow.

Parameters
iThe column span to set on this field.
void EffectField::SetEnabled ( bool  e)

Set the enabled state of this field.

Parameters
eTRUE to enable this field, FALSE to disable it.
void EffectField::SetValueAt ( double  time,
const QVariant &  value 
)

Set the value of this field at a given timecode.

EffectFields are designed to be keyframable, meaning the user can make the values change over the course of the Sequence. This is the main function used through Olive to set what value this field will be at a given time.

If the parent EffectRow is keyframing, this function will determine whether a keyframe exists at this time already. If it does, it will change the value at that keyframe to value. Otherwise, it'll create a new keyframe at the specified time with the specified value.

If the parent EffectRow is not keyframing, the data is simply stored in persistent_data_.

When constructing an Effect

Parameters
timeThe time to retrieve the value at in clip/media seconds (e.g. 0.0 is the very start of the media, 1.0 is one second into the media).
valueThe QVariant value to set at this time.
const EffectField::EffectFieldType & EffectField::type ( )

Get the type of data to expect from this field.

Returns

A member of the EffectFieldType enum.

void EffectField::UpdateWidgetValue ( QWidget *  widget,
double  timecode 
)
virtual

Update a widget created by CreateWidget() using the value at a given time.

Use this function to update a QWidget (obtained from CreateWidget()) with the correct value from the field at a given time.

Since only the derived classes know what type of QWidget it created in CreateWidget() and how to work with them, derived classes are also expected to override this function if the field is an active value used in the Effect that should visually update as the user moves around the Timeline. However if the field does NOT need to update live (e.g. the field is just a UI wrapper like LabelField or ButtonField), this function does not need to be overridden as the default behavior (to do nothing) will suffice in those cases.

Parameters
widgetThe QWidget to set the value of (must be a QWidget obtained from CreateWidget() or the behavior is undefined).
timecodeThe time in clip/media seconds to retrieve data from.

Reimplemented in DoubleField, ComboField, StringField, FontField, FileField, BoolField, and ColorField.

Member Data Documentation

int EffectField::colspan_
private

Internal column span value.

bool EffectField::enabled_
private

Internal enabled value.

QString EffectField::id_
private

Internal unique identifier for this field set in the constructor. Access with id().

QVector<EffectKeyframe> EffectField::keyframes

Keyframe array.

Contains all data about this field's keyframes, from the keyframe times, to their data, to their type (linear, bezier, or hold), to the bezier handles (if using bezier). If the row is not keyframing, this array is never used (persistent_data_ is used instead). If it is, this array will always be used unless the array is empty, in which case persistent_data_ will be used again.

QVariant EffectField::persistent_data_

Persistent data object.

If the parent EffectRow is not keyframing, all field data is stored and retrieved here. If the row IS keyframing, this variable goes basically unused unless keyframes is empty.

NOTE: It is NOT recommended to access this variable directly. Use GetValueAt() instead.

EffectFieldType EffectField::type_
private

Internal type variable set in the constructor. Access with type().


The documentation for this class was generated from the following files: