I looked through all the samples and the howto projects, but i'm not finding anything.
What i'd like to do is when a value changes in my parameters, to change the edit type of another parameter between EDITTYPE_UNIVERSE and EDITTYPE_FLOAT. What I have is a dropdown that for certain options changes how some distance values are interpreted, one being relative, the rest being world coordinates. I just want the distance to reflect percentage of bounding box as either 0.0 - 1.0 or 0% to 100% maybe even better. i'm just not sure how to make that change during runtime. I tried to get the ParamDef and change the spin_type, but that didn't work. i'm thinking it may be something like getting the controls by their HWND and then modifying it there or something. but I just don't know how to go about that. if there's anybody out there that's dealt with this before I would be most appreciative of some information. thanks!
Solved! Go to Solution.
Solved by tim-bot. Go to Solution.
Solved by denisT.MaxDoctor. Go to Solution.
Solved by denisT.MaxDoctor. Go to Solution.
When I sometimes need either a combobox OR an edit field, I add both controls to the dialog and hide the one I don't need.
yeah, I tried to think up some way to just hide/show what I need, but i'm just not sure how to do that without having multiple parameters for the same thing. which i'd like to avoid.
I have a partially working solution, it's just not updating the interface unless I deselect the item and then reselect it again, then the spin_type gets updated on the spinners.
in my ParamMap2UserDlgProc::DlgProg
case WM_COMMAND:
{
switch (LOWORD(wParam))
{
case IDC_Opt_TransformRange_ComboBox:
{
SetEditType(map, t);
....
Then
void SetEditType(IParamMap2* map, TimeValue t)
{
static std::vector<APBIDs> RangeAffected = { APBIDs::AdvArrayOffset };
IParamBlock2* pb = map->GetParamBlock();
TransformRange TR = (TransformRange)pb->GetInt(APBIDs::AdvArrayOptTransformRange, t);
EditSpinnerType ST = EditSpinnerType::EDITTYPE_INT;
switch (TR)
{
case AdvArray::TransformRange::Absolute: ST = EditSpinnerType::EDITTYPE_UNIVERSE; break;
case AdvArray::TransformRange::Reletive: ST = EditSpinnerType::EDITTYPE_FLOAT; break;
case AdvArray::TransformRange::Extents: ST = EditSpinnerType::EDITTYPE_UNIVERSE; break;
}
if (ST != EditSpinnerType::EDITTYPE_INT)
{
for (int i = 0; i < RangeAffected.size(); i++)
{
ParamDef& pDef = pb->GetParamDef(RangeAffected[i]);
if (pDef.spin_type != ST)
{
pDef.spin_type = ST;
}
}
map->Invalidate();
map->SetParamBlock(pb);
map->UpdateUI(t);
}
}
Which does change the spin_type, but it's not updating the UI while the item is selected. i'm certain it's got to be possible, as changing the units updates the type while it's selected. i'm just not sure what to do to get the UI to refresh
Thanks for the suggestions, I tried them out, but it doesn't appear to be a redraw issue. as changing the spinner value continues to use the current type until the whole panel gets rebuilt after deselecting and reselecting.
Long time ago I created customized spinner controls - afair the source code of the spinner can be found in the debug release.
I have another idea: why don't you directly access the spinner control?
The Spinner Control is 'combined' control which includes an 'edit' control and 'buttons' control.
You can change the type of a spinner using ISpinnerControl::LinkToEdit or directly assinging ((SpinnerControl*)sp)->spin_type, but it doesn't rebuild the Edit control automatically, and you can't see the difference. It's because the current Edit control was created using previous type (settings), and it continue be a part of whole Spinner control.
The only way is to force rebuild UI with all included controls...
finally i found the way to change and update a spinner type on the fly:
sp->LinkToEdit(hwnd, type); ((SpinnerControl*)control)->spin_type = type; control->Reload(); control->InvalidateUI();
where:
control is SpinnerControl
sp is ISpinnerControl of control
hwnd is previous window to control's HWND (hwnd of spinner's CustEdit control)
awesome! thanks for that, I'll plug that in and let you know how it goes!
ok, I've got this most of the way setup, but i'm having trouble getting my hands on the SpinnerControl. I see that defined in rollouts.h as the correct one? I just can't seem to find where to get that from the data I have. any help with resolving that and I think I could get this working. thanks!
I might be digging myself in a hole here. in my class derived from ParamMap2UserDlgProc, in the DlgProc:
INT_PTR DlgProc(TimeValue t, IParamMap2* map, HWND hWnd, UINT msg, WPARAM wParam, LPARAM lParam)
I was trying to use that hWnd to get the ISpinnerControl. but the spinner controls are actually on different rollout panels, so it's returning null. I thought maybe if I stored the HWND's for each panel during WM_INITDIALOG would work, but LOWORD(wParam) doesn't give the same results as I get during WM_COMMAND. bummer... hopefully you know a better way of getting that at that time or if there's another better way to be going about this whole business.
I was looking at some of the samples, and I see some of them creating their rollups manually and handling the dialog process there, which gives them the HWND to the actual rollup during BeginEditParams. do you think I should be going that direction here?
thanks again for helping me out with this!
i think that you have to know your parameter in param block2. Using ParamBlockDesc2 you can get an associated with the parameter control. If it's spinner control you can change its type
ok, thanks for all the suggestions, I finally got it working!
I ended up using this code, which basically i'm getting the correct map associated with each of the spinners I want to adjust using the IParamBlock2->GetMap function, then I get the HWND using the IParamMap2->GetHWnd function and use that in the GetDlgItem function to get the spinner and custom edit box. and I don't even need to call any invalidate ui functions for it to work B)
for each (EditTypeChangeInfo eInfo in ChangeInfos) { ParamDef& pDef = pbd->GetParamDef(eInfo.Id); if (pDef.spin_type != ST) { pDef.spin_type = ST; IParamMap2* pMap = pb->GetMap((MapID)eInfo.RollID); if (pMap) { HWND pHwnd = pMap->GetHWnd(); if (pHwnd) { for each (SpinnerIDPair sIdP in eInfo.SpinnerPairIDs) { ISpinnerControl* Sp = GetISpinner(GetDlgItem(pHwnd, sIdP.SpinnerID)); if (Sp) { Sp->LinkToEdit(GetDlgItem(pHwnd, sIdP.EditID), ST); ReleaseISpinner(Sp); } } } } } }
still needs a little work as the next time the modifier is created it still maintains the spin_type set here, so i'll just need to make the adjustments during initialization as well.
thanks again for all the help!
yeah, just a couple of stucts that I have to match my spinner pairs with their parameter ids and roll ids. just so I don't have to have a massive switch statement, I can instead just loop through them.
struct SpinnerIDPair { int SpinnerID; int EditID; }; struct EditTypeChangeInfo { APBIDs Id; RollIDs RollID; std::vector<SpinnerIDPair> SpinnerPairIDs; };
static std::vector<EditTypeChangeInfo> ChangeInfos = { {APBIDs::AdvArrayOffset, RollIDs::Params, { { IDC_OffsetX_Spinner, IDC_OffsetX_EditBox }, { IDC_OffsetY_Spinner, IDC_OffsetY_EditBox }, { IDC_OffsetZ_Spinner, IDC_OffsetZ_EditBox } } }, { APBIDs::AdvArrayCenOffset, RollIDs::Center,{ { IDC_Cen_OffsetX_Spinner, IDC_Cen_OffsetX_EditBox }, { IDC_Cen_OffsetY_Spinner, IDC_Cen_OffsetY_EditBox }, { IDC_Cen_OffsetZ_Spinner, IDC_Cen_OffsetZ_EditBox } } }, { APBIDs::AdvArrayPreOffset, RollIDs::PreTransform,{ { IDC_Pre_OffsetX_Spinner, IDC_Pre_OffsetX_EditBox }, { IDC_Pre_OffsetY_Spinner, IDC_Pre_OffsetY_EditBox }, { IDC_Pre_OffsetZ_Spinner, IDC_Pre_OffsetZ_EditBox } } }, { APBIDs::AdvArrayRndOffset, RollIDs::Random,{ { IDC_Rnd_OffsetX_Spinner, IDC_Rnd_OffsetX_EditBox }, { IDC_Rnd_OffsetY_Spinner, IDC_Rnd_OffsetY_EditBox }, { IDC_Rnd_OffsetZ_Spinner, IDC_Rnd_OffsetZ_EditBox } } }, { APBIDs::AdvArrayOscPosAmp, RollIDs::Oscillate,{ { IDC_Osc_Pos_AmpX_Spinner, IDC_Osc_Pos_AmpX_EditBox }, { IDC_Osc_Pos_AmpY_Spinner, IDC_Osc_Pos_AmpY_EditBox }, { IDC_Osc_Pos_AmpZ_Spinner, IDC_Osc_Pos_AmpZ_EditBox } } } };
in case you were curious, here's what ultimately came of this
https://apps.autodesk.com/ACD/en/Detail/Index?id=7221085778557027350&appLang=en&os=Win64