COCKOS
CONFEDERATED FORUMS
Cockos : REAPER : NINJAM : Forums
Forum Home : Register : FAQ : Members List : Search :

Go Back   Cockos Incorporated Forums > Other Software Discussion > WDL users forum

Reply
 
Thread Tools Display Modes
Old 04-21-2017, 05:15 PM   #1
Bobflip
Human being with feelings
 
Join Date: Nov 2016
Posts: 341
Default Accessing popup menu selection from OnParamChange

I’m having trouble getting the index value from an IPopupMenu when clicked.

I have this in my OnParamChange:

Code:
case kCustomPopup:
      pCustomControl->SetParam(GetParam(kCustomPopup)->Value());
and the below as my doPopupMenu(), though as I modified the code from the WDL-OL IPlugMultiTargets example, I’m not sure I have this right.

Code:
	void doPopupMenu()
	{
		IPopupMenu* selectedMenu = mPlug->GetGUI()->CreateIPopupMenu(&mMainMenu, &mDrawRECT);
		
		int itemChosen = selectedMenu->GetChosenItemIdx();
		selectedMenu->CheckItemAlone(itemChosen);
		DBGMSG("item chosen, main menu %i\n", itemChosen);
		
		mMainMenu.SetChosenItemIdx(itemChosen);
	}
Any pointers on what I'm missing here?
Bobflip is offline   Reply With Quote
Old 04-22-2017, 10:50 AM   #2
earlevel
Human being with feelings
 
Join Date: Dec 2015
Posts: 331
Default

I don't think the control's mValue is getting set anywhere.

My doPopupMenu looks like this, for instance:

Code:
    void doPopupMenu() {
        int selectionIdx = mValue * mMaxIndex + 0.5;
        mMainMenu.SetChosenItemIdx(selectionIdx);
        mMainMenu.CheckItemAlone(selectionIdx);
        IPopupMenu* selectedMenu = mPlug->GetGUI()->CreateIPopupMenu(&mMainMenu, &mRECT);

        if (selectedMenu == &mMainMenu) {
            int itemChosen = selectedMenu->GetChosenItemIdx();
            selectedMenu->CheckItemAlone(itemChosen);
            mValue = itemChosen / (double)mMaxIndex;
            SetDirty();
        }
    }
earlevel is offline   Reply With Quote
Old 04-23-2017, 02:53 PM   #3
Bobflip
Human being with feelings
 
Join Date: Nov 2016
Posts: 341
Default

Hmmm, yes you're right there, thanks!

Something's still bizarre though, I don't seem to be able to get the correct mValue from the GetParam(kCustomPopup)->Value call. It always gives 0.

I've traced mValue in the CustomPopup class, and it's showing the correct value every time a menu item is clicked, but for some reason this isn't coming through.

I tried copying the code from the IPlugMultiTargets and pasting it into a fresh IPlugEffect with your suggested modification to the doPopupMenu, but still have the same problem.

Here's the code I have:

Code:
class ITestPopupMenu : public IControl
{
private:
  IPopupMenu mMainMenu, mSubMenu;
  int mMaxIndex;
  
public:
  ITestPopupMenu(IPlugBase *pPlug, IRECT pR, int paramIdx)
  : IControl(pPlug, pR, paramIdx)
  {
    mMainMenu.AddItem("first item");
    mMainMenu.AddItem("second item");
    mMainMenu.AddItem("third item");
    
    mSubMenu.AddItem("first item");
    mSubMenu.AddItem("second item");
    mSubMenu.AddItem("third item");
    
    mMainMenu.AddItem("sub menu", &mSubMenu);
    mMaxIndex = 7;
  }
  
  bool Draw(IGraphics* pGraphics)
  {
    return pGraphics->FillIRect(&COLOR_WHITE, &mDrawRECT);;
  }
  
  void OnMouseDown(int x, int y, IMouseMod* pMod)
  {
    doPopupMenu();
    
    Redraw(); // seems to need this
    SetDirty();
  }
  
  void doPopupMenu() {
    int selectionIdx = mValue * mMaxIndex + 0.5;
    mMainMenu.SetChosenItemIdx(selectionIdx);
    mMainMenu.CheckItemAlone(selectionIdx);
    IPopupMenu* selectedMenu = mPlug->GetGUI()->CreateIPopupMenu(&mMainMenu, &mDrawRECT);
    
    if (selectedMenu == &mMainMenu) {
      int itemChosen = selectedMenu->GetChosenItemIdx();
      selectedMenu->CheckItemAlone(itemChosen);
      mValue = itemChosen / (double)mMaxIndex;
      SetDirty();
    }
  }
};
and this in the cpp file:

Code:
 pGraphics->AttachControl(new ITestPopupMenu(this, IRECT(110, 200, 160, 215), kTestPopup));


void IPlugEffect::OnParamChange(int paramIdx)
{
  IMutexLock lock(this);

  switch (paramIdx)
  {
    case kGain:
      mGain = GetParam(kGain)->Value() / 100.;
      break;
    case kTestPopup:
      double i;
      i = GetParam(kTestPopup)->Value();
      break;
    default:
      break;
  }
}
Bobflip is offline   Reply With Quote
Old 04-23-2017, 03:38 PM   #4
Bobflip
Human being with feelings
 
Join Date: Nov 2016
Posts: 341
Default

Got it, needed to use a pointer to the control and use GetValue instead.

Code:
ITestPopupMenu *pTestPopupMenu;

pGraphics->AttachControl(pTestPopupMenu = new ITestPopupMenu(this, IRECT(110, 200, 160, 215), kTestPopup));

    case kTestPopup:
      double i;
      i = pTestPopupMenu->GetValue();
      // do stuff here
      break;
Bobflip is offline   Reply With Quote
Old 04-23-2017, 10:46 PM   #5
earlevel
Human being with feelings
 
Join Date: Dec 2015
Posts: 331
Default

Quote:
Originally Posted by Bobflip View Post
Got it, needed to use a pointer to the control and use GetValue instead.
Maybe your menu isn't attached to a parameter (perhaps a UI item that doesn't need automating, or storing as a preset)? My popup menu selects the effect "model", I respond to changes in OnParamChange much as you suggested earlier:
Code:
        int which = GetParam(kEffect)->Value();
BTW, in your OnMouseDown handler, Redraw/SetDirty ("seems to need this")—shouldn't be necessary, should already be hitting SetDirty in doPopupMenu. No harm, though.
earlevel is offline   Reply With Quote
Old 04-24-2017, 07:17 AM   #6
Bobflip
Human being with feelings
 
Join Date: Nov 2016
Posts: 341
Default

Quote:
Originally Posted by earlevel View Post
Maybe your menu isn't attached to a parameter (perhaps a UI item that doesn't need automating, or storing as a preset)? My popup menu selects the effect "model", I respond to changes in OnParamChange much as you suggested earlier:
Code:
        int which = GetParam(kEffect)->Value();
BTW, in your OnMouseDown handler, Redraw/SetDirty ("seems to need this")—shouldn't be necessary, should already be hitting SetDirty in doPopupMenu. No harm, though.
I'll check out the parameter attachment, even though I've solved it another way now it's worth a look as it's better to understand what's going on! Had thought that it should be accessible with ->Value


Good spot on the SetDirty as well, was a leftover from the code taken from IPlugMultiControls, thanks.
Bobflip is offline   Reply With Quote
Old 04-24-2017, 12:52 PM   #7
earlevel
Human being with feelings
 
Join Date: Dec 2015
Posts: 331
Default

Quote:
Originally Posted by Bobflip View Post
I'll check out the parameter attachment, even though I've solved it another way now it's worth a look as it's better to understand what's going on! Had thought that it should be accessible with ->Value
Yes, it's fine that you solved it by going to the control instead, but my concern is that since you couldn't get it via the parameter (->Value), that parameter might not be working, might show up as an automation or preset issue, etc., if you're indeed using the parameter.
earlevel is offline   Reply With Quote
Old 07-19-2017, 04:38 AM   #8
Bobflip
Human being with feelings
 
Join Date: Nov 2016
Posts: 341
Default

Had some other things get in the way, but got back to this bit and you were indeed right about the parameter not working with automation and preset recall. This is the template code I’ve got now, which includes a basic draw function to show the selected item:

Here's the code I have:

Code:
class ITestPopupMenu : public IControl, ycairo_gui {
private:
     IPopupMenu mMainMenu;
     int mMaxIndex;
     
public:
     ITestPopupMenu(IPlugBase *pPlug, ycairo_base *ycairo_base, IRECT pR, int paramIdx)
     : IControl(pPlug, pR, paramIdx), ycairo_gui(ycairo_base, this) {
          
          mMainMenu.SetMultiCheck(false);
          mMainMenu.AddItem("Option 1");
          mMainMenu.AddItem("Option 2");
          mMainMenu.AddItem("Option 3");
          mMainMenu.AddItem("Option 4");
          
          mMaxIndex = 3;
          
          mMainMenu.CheckItem(mValue, true);
          mMainMenu.SetChosenItemIdx(mValue);
     }
     
     bool Draw(IGraphics* pGraphics) {
          WDL_String mDebugText;
          
          pGraphics->FillIRect(&COLOR_WHITE, &mDrawRECT);
          
          mDebugText.SetFormatted(80, mMainMenu.GetItemText(mValue*mMaxIndex));
          pGraphics->DrawIText(&mText, mDebugText.Get(), &mDrawRECT);
          
          return true;
     }
     
     void OnMouseDown(int x, int y, IMouseMod* pMod) {
          doPopupMenu();
          
          Redraw(); // seems to need this
          SetDirty();
     }
     
     void doPopupMenu() {
          int selectionIdx = mValue * mMaxIndex + 0.5;
          mMainMenu.SetChosenItemIdx(selectionIdx);
          mMainMenu.CheckItemAlone(selectionIdx);
          IPopupMenu* selectedMenu = mPlug->GetGUI()->CreateIPopupMenu(&mMainMenu, &mDrawRECT);
          
          if (selectedMenu == &mMainMenu) {
               int itemChosen = selectedMenu->GetChosenItemIdx();
               selectedMenu->CheckItemAlone(itemChosen);
               mValue = itemChosen / (double)mMaxIndex;
          }
     }
     
     void SetValue(int value) {
          if (value > 0 && value < mMaxIndex) {
               mValue = value;
               
               Redraw(); // seems to need this
               SetDirty();
          }
     }
};

     int *mTestPopup;
     ITestPopupMenu *pTestPopup;


and this in the cpp file:

(in the constructor)
Code:
     GetParam(kTestPopup)->InitEnum("Test Menu", 0, 4);
     GetParam(kTestPopup)->SetDisplayText(0, "Option 1"); // Needed for VST3, thanks plunntic
     GetParam(kTestPopup)->SetDisplayText(1, "Option 2"); // Needed for VST3, thanks plunntic
     GetParam(kTestPopup)->SetDisplayText(2, "Option 3"); // Needed for VST3, thanks plunntic
     GetParam(kTestPopup)->SetDisplayText(3, "Option 4"); // Needed for VST3, thanks plunntic
     mTestPopup = pGraphics->AttachControl(pTestPopup = new ITestPopupMenu(this, GetYCAIRO(), IRECT(kTestPopupX, kTestPopupY, kTestPopupX + kTestPopupWidth, kTestPopupY + kTestPopupHeight), kTestPopup));
(in OnParamChange)
Code:
          case kTestPopup:
               i = (int)GetParam(kTestPopup)->Value();
               break;
Bobflip is offline   Reply With Quote
Old 07-19-2017, 05:11 AM   #9
Bobflip
Human being with feelings
 
Join Date: Nov 2016
Posts: 341
Default

I’ve also been playing around with multi check popup menus. Took me a bit of time to figure out how to manage the but ended up with the following template code. It seems functional with both automation and preset recall, does it look good to you? Also posting it here for others to use, provided there’s nothing I’ve got wrong there!

Code:
class ITestPopupMenu : public IControl, ycairo_gui {
private:
     IPopupMenu mMainMenu;
     int mMaxIndex, mMaxIndexA, mMinIndexB, mMaxIndexB;
     int mValueA, mValueB;
     
     
public:
     ITestPopupMenu(IPlugBase *pPlug, ycairo_base *ycairo_base, IRECT pR, int paramIdx)
     : IControl(pPlug, pR, paramIdx), ycairo_gui(ycairo_base, this) {
          
          mMainMenu.SetMultiCheck(true);
          mMainMenu.AddItem("Option 1.1");             // 1
          mMainMenu.AddItem("Option 1.2");             // 2
          mMainMenu.AddItem("Option 1.3");             // 3
          mMainMenu.AddItem("Option 1.4");             // 4
          mMainMenu.AddSeparator();				// 5
          mMainMenu.AddItem("Option 2.1");             // 6
          mMainMenu.AddItem("Option 2.2");             // 7
          mMainMenu.AddItem("Option 2.3");             // 8
          mMainMenu.AddItem("Option 2.4");             // 9
          
          mMaxIndex = 8;
          
          mMaxIndexA = 3;
          mMinIndexB = 5;
          mMaxIndexB = 8;
          
          mMainMenu.CheckItem(mValue, true);
          mMainMenu.SetChosenItemIdx(mValue);
     }
     
     bool Draw(IGraphics* pGraphics) {
          WDL_String mDebugText;
          
          pGraphics->FillIRect(&COLOR_WHITE, &mDrawRECT);
          
          mDebugText.SetFormatted(80, mMainMenu.GetItemText(mValue*mMaxIndex));
          pGraphics->DrawIText(&mText, mDebugText.Get(), &mDrawRECT);
          
          for (int i=0; i<=mMaxIndex; i++)
               mMainMenu.CheckItem(i, false);
          mMainMenu.CheckItem(mValueA, true);
          mMainMenu.CheckItem(mValueB+mMinIndexB, true);
          
          return true;
     }
     
     void OnMouseDown(int x, int y, IMouseMod* pMod) {
          doPopupMenu();
          
          Redraw(); // seems to need this
          SetDirty();
     }
     
     void doPopupMenu() {
          int selectionIdx = mValue * mMaxIndex + 0.5;
          mMainMenu.SetChosenItemIdx(selectionIdx);
          //          mMainMenu.CheckItemAlone(selectionIdx);
          IPopupMenu* selectedMenu = mPlug->GetGUI()->CreateIPopupMenu(&mMainMenu, &mDrawRECT);
          
          if (selectedMenu == &mMainMenu) {
               int itemChosen = selectedMenu->GetChosenItemIdx();
               
               if ((itemChosen >= 0) && (itemChosen <= mMaxIndexA)) {
                    for (int i=0; i<=mMaxIndexA; i++)
                         mMainMenu.CheckItem(i, false);
                    mMainMenu.CheckItem(itemChosen, true);
                    mValue = itemChosen / (double)mMaxIndex;
               }
               if ((itemChosen >= mMinIndexB ) && (itemChosen <= mMaxIndexB)) {
                    for (int i=mMinIndexB; i<=mMaxIndexB; i++)
                         mMainMenu.CheckItem(i, false);
                    mMainMenu.CheckItem(itemChosen, true);
                    mValue = itemChosen / (double)mMaxIndex;
               }
          }
     }
     
     void SetAValue(int value) {
          mValueA = value;
     }
     
     void SetBValue(int value) {
          mValueB = value;
     }
};

     int *mTestPopup;
     ITestPopupMenu *pTestPopup;

In resource.h:
Code:
enum EParam
{
     // public:
     kGain,
     kMenuOptionA,
     kMenuOptionB,
     // private:
     kTestPopup,
};
In the constructor:
Code:
     GetParam(kMenuOptionA)->InitEnum("Menu A", 0, 4);
     GetParam(kMenuOptionA)->SetDisplayText(0, "Option 1.1"); // Needed for VST3, thanks plunntic
     GetParam(kMenuOptionA)->SetDisplayText(1, "Option 1.2"); // Needed for VST3, thanks plunntic
     GetParam(kMenuOptionA)->SetDisplayText(2, "Option 1.3"); // Needed for VST3, thanks plunntic
     GetParam(kMenuOptionA)->SetDisplayText(3, "Option 1.4"); // Needed for VST3, thanks plunntic
     
     GetParam(kMenuOptionB)->InitEnum("Menu B", 0, 4);
     GetParam(kMenuOptionB)->SetDisplayText(0, "Option 2.1"); // Needed for VST3, thanks plunntic
     GetParam(kMenuOptionB)->SetDisplayText(1, "Option 2.2"); // Needed for VST3, thanks plunntic
     GetParam(kMenuOptionB)->SetDisplayText(2, "Option 2.3"); // Needed for VST3, thanks plunntic
     GetParam(kMenuOptionB)->SetDisplayText(3, "Option 2.4"); // Needed for VST3, thanks plunntic
     
     GetParam(kTestPopup)->InitInt("Test Menu", 0, 0, 8, "");
     
     mTestPopup = pGraphics->AttachControl(pTestPopup = new ITestPopupMenu(this, GetYCAIRO(), IRECT(kTestPopupX, kTestPopupY, kTestPopupX + 100, kTestPopupY + 20), kTestPopup));
     
     GetParam(kMenuOptionA)->SetCanAutomate(true);
     GetParam(kMenuOptionB)->SetCanAutomate(true);
     GetParam(kTestPopup)->SetCanAutomate(false);
     
     GetParam(kTestPopup)->SetIsMeta(true);
     GetParam(kMenuOptionA)->SetIsMeta(true);
     GetParam(kMenuOptionB)->SetIsMeta(true);
Code:
In OnParamChange:
          case kTestPopup:
               i = (int)GetParam(kTestPopup)->Value();
               
               if ((i >= 0) && (i <=3 )) {
                    GetParam(kMenuOptionA)->Set(i);
                    pTestPopup->SetAValue(i);
               }
               if ((i >= 5) && (i <=8 )) {
                    GetParam(kMenuOptionB)->Set(i-5);
                    pTestPopup->SetBValue(i-5);
               }
               break;
          case kMenuOptionA:
               i = (int)GetParam(kMenuOptionA)->Value();
               pTestPopup->SetAValue(i);
               break;
          case kMenuOptionB:
               i = (int)GetParam(kMenuOptionB)->Value();
               pTestPopup->SetBValue(i);
               break;
Bobflip is offline   Reply With Quote
Reply

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off

Forum Jump


All times are GMT -7. The time now is 12:30 PM.


Powered by vBulletin® Version 3.8.11
Copyright ©2000 - 2024, vBulletin Solutions Inc.