CommandPost / FCPCafe

FCP Cafe Website
https://fcp.cafe
MIT License
26 stars 15 forks source link

Can't change ParameterSubGroup Name in parameterChanged #312

Open latenitefilms opened 6 months ago

latenitefilms commented 6 months ago

Apple Feedback Assistant ID: FB13500374

DESCRIBE THE BUG: You can't change a ParameterSubGroup Name using dynamicParamAPI?.setParameter(paramID, name: "Test") when triggered from parameterChanged. The code executes without error, but the Sub Group name doesn't actually change in the Final Cut Pro interface.

I've also tried using FxCustomParameterActionAPI_v4 before and after setParameter, but it has no impact.


TO REPRODUCE: Create a ParameterSubGroup, then try and change the name of the subgroup dynamically via code.


EXPECTED BEHAVIOUR: You should be able to update the name like you can any other parameter.


SCREENSHOTS: NA


SPECS:


ADDITIONAL COMMENTS: None

latenitefilms commented 5 months ago

FWIW - I've been able to get this to work in Motion using the FxBrightness sample app from the FxPlug v4.2.9 SDK using this code:

    @objc func pushButton() {
        let dynamicParamAPI = _apiManager!.api(for: FxDynamicParameterAPI_v3.self) as! FxDynamicParameterAPI_v3
        dynamicParamAPI.setParameter(2, name: "BOO")
    }

    func addParameters() throws {
        let paramAPI = _apiManager!.api(for: FxParameterCreationAPI_v5.self) as! FxParameterCreationAPI_v5

        paramAPI.addFloatSlider(withName: "Brightness", parameterID: 1, defaultValue: 1.0, parameterMin: 0.0, parameterMax: 100.0, sliderMin: 0.0, sliderMax: 5.0, delta: 0.1, parameterFlags: FxParameterFlags(kFxParameterFlag_DEFAULT))

        paramAPI.startParameterSubGroup("Test SubGroup", parameterID: 2, parameterFlags: FxParameterFlags(kFxParameterFlag_DEFAULT))

        paramAPI.addPushButton(withName: "Change Name", parameterID: 3, selector: #selector(pushButton), parameterFlags: FxParameterFlags(kFxParameterFlag_DEFAULT))

    }

But publishing this as a Title to Final Cut Pro doesn't work. Pressing the button doesn't update the SubGroup name.

I'm guessing this is because there's no official way to publish SubGroup's in Motion - even though lots of Motion Templates do it by modifying the Motion XML.

latenitefilms commented 5 months ago

Interestingly, whilst this works in Motion, it doesn't in Final Cut Pro:

@objc func pushButton() {

    let setParamAPI = _apiManager!.api(for: FxParameterSettingAPI_v5.self) as! FxParameterSettingAPI_v5

    let dynamicParamAPI = _apiManager!.api(for: FxDynamicParameterAPI_v3.self) as! FxDynamicParameterAPI_v3

    setParamAPI.setParameterFlags(FxParameterFlags(kFxParameterFlag_HIDDEN), toParameter: 2)

    dynamicParamAPI.setParameter(2, name: "NEW SUBGROUP NAME")

    setParamAPI.setParameterFlags(FxParameterFlags(kFxParameterFlag_DEFAULT), toParameter: 2)
    setParamAPI.setParameterFlags(FxParameterFlags(kFxParameterFlag_COLLAPSED), toParameter: 2)

    dynamicParamAPI.setParameter(1, name: "NEW BRIGHTNESS NAME")
}

func addParameters() throws {
    let paramAPI = _apiManager!.api(for: FxParameterCreationAPI_v5.self) as! FxParameterCreationAPI_v5

    paramAPI.addFloatSlider(withName: "Brightness", parameterID: 1, defaultValue: 1.0, parameterMin: 0.0, parameterMax: 100.0, sliderMin: 0.0, sliderMax: 5.0, delta: 0.1, parameterFlags: FxParameterFlags(kFxParameterFlag_DEFAULT))

    paramAPI.startParameterSubGroup("Test SubGroup", parameterID: 2, parameterFlags: FxParameterFlags(kFxParameterFlag_DEFAULT))

    paramAPI.addPushButton(withName: "Change Name", parameterID: 3, selector: #selector(pushButton), parameterFlags: FxParameterFlags(kFxParameterFlag_DEFAULT))

    paramAPI.endParameterSubGroup()
}

However the group does collapse - it's just none of the names get updated.

latenitefilms commented 5 months ago

Note to self, I did also try using FxCustomParameterActionAPI_v4, but you shouldn't use that in buttons anyway, and it doesn't work due to:

A plugin attempted to call [-FxCustomParameterActionAPI startAction:] at an inappropriate time. Plugins should not call this method when they have been called by the host application.

Here's the code:

@objc func pushButton() {

    let actionAPI = _apiManager!.api(for: FxCustomParameterActionAPI_v4.self) as! FxCustomParameterActionAPI_v4

    actionAPI.startAction(self)

    let setParamAPI = _apiManager!.api(for: FxParameterSettingAPI_v5.self) as! FxParameterSettingAPI_v5

    let dynamicParamAPI = _apiManager!.api(for: FxDynamicParameterAPI_v3.self) as! FxDynamicParameterAPI_v3

    setParamAPI.setParameterFlags(FxParameterFlags(kFxParameterFlag_HIDDEN), toParameter: 2)

    dynamicParamAPI.setParameter(2, name: "NEW SUBGROUP NAME")

    setParamAPI.setParameterFlags(FxParameterFlags(kFxParameterFlag_DEFAULT), toParameter: 2)
    setParamAPI.setParameterFlags(FxParameterFlags(kFxParameterFlag_COLLAPSED), toParameter: 2)

    dynamicParamAPI.setParameter(1, name: "NEW BRIGHTNESS NAME")

    actionAPI.endAction(self)
}

func addParameters() throws {
    let paramAPI = _apiManager!.api(for: FxParameterCreationAPI_v5.self) as! FxParameterCreationAPI_v5

    paramAPI.addFloatSlider(withName: "Brightness", parameterID: 1, defaultValue: 1.0, parameterMin: 0.0, parameterMax: 100.0, sliderMin: 0.0, sliderMax: 5.0, delta: 0.1, parameterFlags: FxParameterFlags(kFxParameterFlag_DEFAULT))

    paramAPI.startParameterSubGroup("Test SubGroup", parameterID: 2, parameterFlags: FxParameterFlags(kFxParameterFlag_DEFAULT))

    paramAPI.addPushButton(withName: "Change Name", parameterID: 3, selector: #selector(pushButton), parameterFlags: FxParameterFlags(kFxParameterFlag_DEFAULT))

    paramAPI.endParameterSubGroup()
}
latenitefilms commented 5 months ago

Apple confirms:

The dynamic parameter API doesn’t do what you want in FCP. This is a known limitation. I thought we had documented this somewhere, but I’m not finding it.

Basically, the problem is that using the dynamic parameter API changes the underlying Motion document data. In Motion, the user simply saves the project and it’s fine. But in FCP there’s no way for the user to save the Motion Template, nor would they want to, since it would change all instances of the plug-in in all projects.