diff options
Diffstat (limited to 'Src/Plugins/Visualization/vis_milk2/menu.cpp')
-rw-r--r-- | Src/Plugins/Visualization/vis_milk2/menu.cpp | 751 |
1 files changed, 751 insertions, 0 deletions
diff --git a/Src/Plugins/Visualization/vis_milk2/menu.cpp b/Src/Plugins/Visualization/vis_milk2/menu.cpp new file mode 100644 index 00000000..be632314 --- /dev/null +++ b/Src/Plugins/Visualization/vis_milk2/menu.cpp @@ -0,0 +1,751 @@ +/* + LICENSE + ------- +Copyright 2005-2013 Nullsoft, Inc. +All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + + * Neither the name of Nullsoft nor the names of its contributors may be used to + endorse or promote products derived from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND +FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER +IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT +OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include "api__vis_milk2.h" +#include "state.h" // for CBlendableFloat - fix this +#include "menu.h" +#include "plugin.h" +#include <stdio.h> +#include <math.h> +#include <assert.h> +#include "resource.h" + +extern CPlugin g_plugin; // declared in main.cpp + +//---------------------------------------- + +CMilkMenuItem::CMilkMenuItem() +{ + WASABI_API_LNGSTRINGW_BUF(IDS_UNTITLED_MENU_ITEM,m_szName,64); + m_szToolTip[0] = 0; + m_type = MENUITEMTYPE_BUNK; + m_fMin = 0.0f; + m_fMax = 0.0f; + m_var_offset = NULL; + m_pCallbackFn = NULL; + m_pNext = NULL; + m_original_value = NULL; + m_nLastCursorPos = 0; + m_bEnabled = true; +} + +CMilkMenuItem::~CMilkMenuItem() +{ + if (m_pNext) + { + delete m_pNext; + m_pNext = NULL; + } +} + +//---------------------------------------- + +CMilkMenu::CMilkMenu() +{ + //Reset(); +} + +CMilkMenu::~CMilkMenu() +{ + /* + if (m_pFirstChildItem) + { + delete m_pFirstChildItem; + m_pFirstChildItem = NULL; + } + */ +} + +//---------------------------------------- + +bool CMilkMenu::ItemIsEnabled(int j) +{ + if (j < m_nChildMenus) + return m_ppChildMenu[j]->IsEnabled(); + + int i = m_nChildMenus; + CMilkMenuItem *pChild = m_pFirstChildItem; + while (pChild && i<j) + { + pChild = pChild->m_pNext; + i++; + } + if (pChild) + return pChild->m_bEnabled; + + return false; +} + +//---------------------------------------- + +void CMilkMenu::EnableItem(wchar_t* szName, bool bEnable) +{ + //search submenus + int i = 0; + for (i=0; i<m_nChildMenus; i++) { + if (!wcscmp(m_ppChildMenu[i]->GetName(), szName)) + { + m_ppChildMenu[i]->Enable(bEnable); + if (!bEnable) + { + while (m_nCurSel > 0 && !ItemIsEnabled(m_nCurSel)) + m_nCurSel--; + if (m_nCurSel==0 && !ItemIsEnabled(m_nCurSel)) + while (m_nCurSel < m_nChildMenus+m_nChildItems-1 && !ItemIsEnabled(m_nCurSel)) + m_nCurSel++; + } + return; + } + } + + //search child items + CMilkMenuItem *pChild = m_pFirstChildItem; + while (pChild) + { + if (!wcscmp(pChild->m_szName, szName)) + { + pChild->m_bEnabled = bEnable; + if (!bEnable) + { + while (m_nCurSel > 0 && !ItemIsEnabled(m_nCurSel)) + m_nCurSel--; + if (m_nCurSel==0 && !ItemIsEnabled(m_nCurSel)) + while (m_nCurSel < m_nChildMenus+m_nChildItems-1 && !ItemIsEnabled(m_nCurSel)) + m_nCurSel++; + } + return; + } + pChild = pChild->m_pNext; + i++; + } +} + +//---------------------------------------- + +void CMilkMenu::Reset() +{ + m_pParentMenu = NULL; + for (int i=0; i<MAX_CHILD_MENUS; i++) + m_ppChildMenu[i] = NULL; + m_pFirstChildItem = NULL; + WASABI_API_LNGSTRINGW_BUF(IDS_UNTITLED_MENU,m_szMenuName,64); + m_nChildMenus = 0; + m_nChildItems = 0; + m_nCurSel = 0; + m_bEditingCurSel = false; + m_bEnabled = true; +} + +//---------------------------------------- + +void CMilkMenu::Init(wchar_t *szName) +{ + Reset(); + if (szName && szName[0]) + wcsncpy(m_szMenuName, szName, 64); +} + +void CMilkMenu::Finish() +{ + if (m_pFirstChildItem) + { + delete m_pFirstChildItem; + m_pFirstChildItem = NULL; + } +} + +//---------------------------------------- + +void CMilkMenu::AddChildMenu(CMilkMenu *pMenu) +{ + if (m_nChildMenus < MAX_CHILD_MENUS) + { + m_ppChildMenu[m_nChildMenus++] = pMenu; + pMenu->SetParentPointer(this); + } +} + +//---------------------------------------- + +void CMilkMenu::AddItem(wchar_t *szName, void *var, MENUITEMTYPE type, wchar_t *szToolTip, + float min, float max, MilkMenuCallbackFnPtr pCallback, + unsigned int wParam, unsigned int lParam) +{ + CMilkMenuItem *pLastItem = NULL; + + // find last item in linked list + if (!m_pFirstChildItem) + { + // first item + m_pFirstChildItem = new CMilkMenuItem; + pLastItem = m_pFirstChildItem; + } + else + { + pLastItem = m_pFirstChildItem; + while (pLastItem->m_pNext) + pLastItem = pLastItem->m_pNext; + + // allocate a new CMilkMenuItem + pLastItem->m_pNext = new CMilkMenuItem; + pLastItem = pLastItem->m_pNext; + } + + // set its attributes + wcsncpy(pLastItem->m_szName, szName, 64); + wcsncpy(pLastItem->m_szToolTip, szToolTip, 1024); + pLastItem->m_var_offset = (size_t)var - (size_t)(g_plugin.m_pState); + pLastItem->m_type = type; + pLastItem->m_fMin = min; + pLastItem->m_fMax = max; + pLastItem->m_wParam = wParam; + pLastItem->m_lParam = lParam; + if ((type==MENUITEMTYPE_LOGBLENDABLE || type==MENUITEMTYPE_LOGFLOAT) && min==max) + { + // special defaults + pLastItem->m_fMin = 0.01f; + pLastItem->m_fMax = 100.0f; + } + pLastItem->m_pCallbackFn = pCallback; + + m_nChildItems++; +} + +//---------------------------------------- + +void MyMenuTextOut(eFontIndex font_index, wchar_t* str, DWORD color, RECT* pRect, int bCalcRect, RECT* pCalcRect) +{ + if (bCalcRect) + { + RECT t = *pRect; + pRect->top += g_plugin.m_text.DrawTextW(g_plugin.GetFont(font_index), str, -1, &t, DT_SINGLELINE | DT_END_ELLIPSIS | DT_CALCRECT, 0xFFFFFFFF, false); + pCalcRect->bottom += t.bottom - t.top; + //if (pCalcRect->bottom > pRect->bottom) + // pCalcRect->bottom = pRect->bottom; + pCalcRect->right = max(pCalcRect->right, pCalcRect->left + t.right - t.left); + } + else + { + pRect->top += g_plugin.m_text.DrawTextW(g_plugin.GetFont(font_index), str, -1, pRect, DT_SINGLELINE | DT_END_ELLIPSIS, color, false); + } +} + +void CMilkMenu::DrawMenu(RECT rect, int xR, int yB, int bCalcRect, RECT* pCalcRect) +{ + // 'rect' is the bounding rectangle in which we're allowed to draw the menu; + // it's .top member is incremented as we draw downward. + // if bCalcRect==1, then we return pCalcRect as the area that the menu actually + // occupies, excluding any tooltips. + + if (bCalcRect!=0 && pCalcRect==NULL) + return; + + if (bCalcRect) + { + pCalcRect->left = rect.left; + pCalcRect->right = rect.left; + pCalcRect->top = rect.top; + pCalcRect->bottom = rect.top; + } + + if (!m_bEditingCurSel) + { + int nLines = (rect.bottom - rect.top - PLAYLIST_INNER_MARGIN*2) / g_plugin.GetFontHeight(SIMPLE_FONT) - 1; // save 1 line for the tooltip + if (nLines<1) return; + int nStart = (m_nCurSel/nLines)*nLines; + + int nLinesDrawn = 0; + int i = 0; + for (i=0; i < m_nChildMenus; i++) + { + if (i >= nStart && i < nStart+nLines) + { + //rect.top += g_plugin.GetFont(SIMPLE_FONT)->DrawText(m_ppChildMenu[i]->m_szMenuName, -1, pRect, DT_SINGLELINE | DT_END_ELLIPSIS, (i == m_nCurSel) ? MENU_HILITE_COLOR : MENU_COLOR); + if (m_ppChildMenu[i]->IsEnabled()) { + MyMenuTextOut(SIMPLE_FONT, m_ppChildMenu[i]->m_szMenuName, (i == m_nCurSel) ? MENU_HILITE_COLOR : MENU_COLOR, &rect, bCalcRect, pCalcRect); + nLinesDrawn++; + } + + if (g_plugin.m_bShowMenuToolTips && i == m_nCurSel && !bCalcRect) + { + // tooltip: + g_plugin.DrawTooltip(WASABI_API_LNGSTRINGW(IDS_SZ_MENU_NAV_TOOLTIP), xR, yB); + } + } + } + + CMilkMenuItem *pItem = m_pFirstChildItem; + + while (pItem && nLinesDrawn < nStart+nLines) + { + if (!pItem->m_bEnabled) + { + pItem = pItem->m_pNext; + i++; + continue; + } + + size_t addr = pItem->m_var_offset + (size_t)g_plugin.m_pState; + if (i >= nStart) + { + wchar_t szItemText[256]; + switch(pItem->m_type) + { + case MENUITEMTYPE_STRING: + lstrcpyW(szItemText, pItem->m_szName); + break; + case MENUITEMTYPE_BOOL: + swprintf(szItemText, L"%s [%s]", pItem->m_szName, + WASABI_API_LNGSTRINGW(*((bool *)(addr)) ? IDS_ON : IDS_OFF)); + break; + default: + lstrcpyW(szItemText, pItem->m_szName); + break; + } + + if (i == m_nCurSel) + { + MyMenuTextOut(SIMPLE_FONT, szItemText, MENU_HILITE_COLOR, &rect, bCalcRect, pCalcRect); + + if (g_plugin.m_bShowMenuToolTips && !bCalcRect) + { + // tooltip: + g_plugin.DrawTooltip(pItem->m_szToolTip, xR, yB); + } + } + else + { + MyMenuTextOut(SIMPLE_FONT, szItemText, MENU_COLOR, &rect, bCalcRect, pCalcRect); + } + nLinesDrawn++; + } + + pItem = pItem->m_pNext; + i++; + } + } + else + { + // editing current selection + + // find the item + CMilkMenuItem *pItem = m_pFirstChildItem; + for (int i=m_nChildMenus; i < m_nCurSel; i++) + pItem = pItem->m_pNext; + size_t addr = pItem->m_var_offset + (size_t)g_plugin.m_pState; + + wchar_t buf[256]; + + MyMenuTextOut(SIMPLE_FONT, WASABI_API_LNGSTRINGW(IDS_USE_UP_DOWN_ARROW_KEYS), MENU_COLOR, &rect, bCalcRect, pCalcRect); + swprintf(buf, WASABI_API_LNGSTRINGW(IDS_CURRENT_VALUE_OF_X), pItem->m_szName); + MyMenuTextOut(SIMPLE_FONT, buf, MENU_COLOR, &rect, bCalcRect, pCalcRect); + + switch(pItem->m_type) + { + case MENUITEMTYPE_INT: + swprintf(buf, L" %d ", *((int*)(addr)) ); + break; + case MENUITEMTYPE_FLOAT: + case MENUITEMTYPE_LOGFLOAT: + swprintf(buf, L" %5.3f ", *((float*)(addr)) ); + break; + case MENUITEMTYPE_BLENDABLE: + case MENUITEMTYPE_LOGBLENDABLE: + swprintf(buf, L" %5.3f ", ((CBlendableFloat*)addr)->eval(-1) ); + break; + default: + lstrcpyW(buf, L" ? "); + break; + } + + MyMenuTextOut(SIMPLE_FONT, buf, MENU_HILITE_COLOR, &rect, bCalcRect, pCalcRect); + + // tooltip: + if (g_plugin.m_bShowMenuToolTips && !bCalcRect) + { + g_plugin.DrawTooltip(pItem->m_szToolTip, xR, yB); + } + } +} + +void CMilkMenu::OnWaitStringAccept(wchar_t *szNewString) +{ + m_bEditingCurSel = false; + + // find the item + CMilkMenuItem *pItem = m_pFirstChildItem; + for (int i=m_nChildMenus; i < m_nCurSel; i++) + pItem = pItem->m_pNext; + size_t addr = pItem->m_var_offset + (size_t)g_plugin.m_pState; + + assert(pItem->m_type == MENUITEMTYPE_STRING); + + // apply the edited string + lstrcpyW((wchar_t *)(addr), szNewString); + + // if user gave us a callback function pointer, call it now + if (pItem->m_pCallbackFn) + { + pItem->m_pCallbackFn(0, 0); + } + + // remember the last cursor position + pItem->m_nLastCursorPos = g_plugin.m_waitstring.nCursorPos; +} + +//---------------------------------------- + +LRESULT CMilkMenu::HandleKeydown(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) +{ + // all WM_KEYDOWNS that your app gets when a menu is up should be handled here, + // by the menu that is currently active. + + // return value: FALSE if it handled the key; TRUE if it didn't + + int nRepeat = LOWORD(lParam); + int rep; + + if (!m_bEditingCurSel) + { + switch(wParam) + { + case VK_UP: + for (rep=0; rep<nRepeat; rep++) + { + if (m_nCurSel==0) + break; + do { + m_nCurSel--; + } while (m_nCurSel > 0 && !ItemIsEnabled(m_nCurSel)); + } + if (m_nCurSel < 0) m_nCurSel = 0;//m_nChildMenus + m_nChildItems - 1; + while (m_nCurSel < m_nChildMenus + m_nChildItems - 1 && !ItemIsEnabled(m_nCurSel)) + m_nCurSel++; + return 0; // we processed (or absorbed) the key + + case VK_DOWN: + for (rep=0; rep<nRepeat; rep++) + { + if (m_nCurSel == m_nChildMenus + m_nChildItems - 1) + break; + do { + m_nCurSel++; + } while (m_nCurSel < m_nChildMenus + m_nChildItems - 1 && !ItemIsEnabled(m_nCurSel)); + } + if (m_nCurSel >= m_nChildMenus + m_nChildItems) m_nCurSel = m_nChildMenus + m_nChildItems - 1;//0; + while (m_nCurSel > 0 && !ItemIsEnabled(m_nCurSel)) + m_nCurSel--; + return 0; // we processed (or absorbed) the key + + case VK_HOME: + m_nCurSel = 0; + return 0; // we processed (or absorbed) the key + + case VK_END: + m_nCurSel = m_nChildMenus + m_nChildItems - 1; + return 0; // we processed (or absorbed) the key + + case VK_ESCAPE: + g_plugin.m_UI_mode = UI_REGULAR; + return 0; // we processed (or absorbed) the key + + case VK_BACK: + case VK_LEFT: + if (m_pParentMenu) + g_plugin.m_pCurMenu = m_pParentMenu; + else + g_plugin.m_UI_mode = UI_REGULAR; // exit the menu + return 0; // we processed (or absorbed) the key + + case VK_RETURN: + case VK_RIGHT: + case VK_SPACE: + if (m_nCurSel < m_nChildMenus) + { + // go to sub-menu + g_plugin.m_pCurMenu = m_ppChildMenu[m_nCurSel]; + } + else + { + // find the item + CMilkMenuItem *pItem = GetCurItem(); + size_t addr = pItem->m_var_offset + (size_t)g_plugin.m_pState; + + float fTemp; + + // begin editing the item + + switch(pItem->m_type) + { + case MENUITEMTYPE_UIMODE: + g_plugin.m_UI_mode = (ui_mode)pItem->m_wParam; + + if (g_plugin.m_UI_mode==UI_IMPORT_WAVE || + g_plugin.m_UI_mode==UI_EXPORT_WAVE || + g_plugin.m_UI_mode==UI_IMPORT_SHAPE || + g_plugin.m_UI_mode==UI_EXPORT_SHAPE) + { + g_plugin.m_bPresetLockedByCode = true; + + // enter WaitString mode + g_plugin.m_waitstring.bActive = true; + g_plugin.m_waitstring.bFilterBadChars = false; + g_plugin.m_waitstring.bDisplayAsCode = false; + g_plugin.m_waitstring.nSelAnchorPos = -1; + g_plugin.m_waitstring.nMaxLen = min(sizeof(g_plugin.m_waitstring.szText)-1, MAX_PATH - wcslen(g_plugin.GetPresetDir()) - 6); // 6 for the extension + null char. We set this because win32 LoadFile, MoveFile, etc. barf if the path+filename+ext are > MAX_PATH chars. + swprintf(g_plugin.m_waitstring.szText, L"%sfile.dat", g_plugin.m_szPresetDir); + if (g_plugin.m_UI_mode==UI_IMPORT_WAVE || g_plugin.m_UI_mode==UI_IMPORT_SHAPE) + WASABI_API_LNGSTRINGW_BUF(IDS_LOAD_FROM_FILE,g_plugin.m_waitstring.szPrompt,512); + else + WASABI_API_LNGSTRINGW_BUF(IDS_SAVE_TO_FILE,g_plugin.m_waitstring.szPrompt,512); + g_plugin.m_waitstring.szToolTip[0] = 0; + g_plugin.m_waitstring.nCursorPos = wcslen(g_plugin.m_waitstring.szText); // set the starting edit position + } + break; + case MENUITEMTYPE_BOOL: + *((bool *)addr) = !(*((bool *)addr)); + break; + case MENUITEMTYPE_INT: + m_bEditingCurSel = true; + pItem->m_original_value = (LPARAM)(*((int*)(addr))); + break; + case MENUITEMTYPE_FLOAT: + case MENUITEMTYPE_LOGFLOAT: + m_bEditingCurSel = true; + pItem->m_original_value = (LPARAM)(*((float*)(addr))*10000L); + break; + case MENUITEMTYPE_BLENDABLE: + case MENUITEMTYPE_LOGBLENDABLE: + m_bEditingCurSel = true; + { + //CBlendableFloat *p = (CBlendableFloat*)(pItem->m_pVariable); + //*p = 0.99f; + fTemp = ((CBlendableFloat*)addr)->eval(-1);//p->eval(-1); + } + pItem->m_original_value = (LPARAM)(fTemp*10000L); + break; + case MENUITEMTYPE_STRING: + // enter waitstring mode. ***This function will cease to receive keyboard input + // while the string is being edited*** + g_plugin.m_UI_mode = UI_EDIT_MENU_STRING; + g_plugin.m_waitstring.bActive = true; + g_plugin.m_waitstring.bFilterBadChars = false; + g_plugin.m_waitstring.bDisplayAsCode = true; + g_plugin.m_waitstring.nSelAnchorPos = -1; + g_plugin.m_waitstring.nMaxLen = pItem->m_wParam ? pItem->m_wParam : 8190; + g_plugin.m_waitstring.nMaxLen = min(g_plugin.m_waitstring.nMaxLen, sizeof(g_plugin.m_waitstring.szText)-16); + //lstrcpyW(g_plugin.m_waitstring.szText, (wchar_t *)addr); + lstrcpyA((char*)g_plugin.m_waitstring.szText, (char*)addr); + swprintf(g_plugin.m_waitstring.szPrompt, WASABI_API_LNGSTRINGW(IDS_ENTER_THE_NEW_STRING), pItem->m_szName); + lstrcpyW(g_plugin.m_waitstring.szToolTip, pItem->m_szToolTip); + g_plugin.m_waitstring.nCursorPos = strlen/*wcslen*/((char*)g_plugin.m_waitstring.szText); + if (pItem->m_nLastCursorPos < g_plugin.m_waitstring.nCursorPos) + g_plugin.m_waitstring.nCursorPos = pItem->m_nLastCursorPos; + break; + /* + case MENUITEMTYPE_OSC: + m_bEditingCurSel = true; + pItem->m_bEditingSubSel = false; + break; + */ + } + } + return 0; // we processed (or absorbed) the key + + default: + // key wasn't handled + return TRUE; + break; + } + } + else // m_bEditingCurSel + { + float fMult = 1.0f; + bool bDec; + + // find the item + CMilkMenuItem *pItem = m_pFirstChildItem; + for (int i=m_nChildMenus; i < m_nCurSel; i++) + pItem = pItem->m_pNext; + size_t addr = pItem->m_var_offset + (size_t)g_plugin.m_pState; + + switch(wParam) + { + case VK_ESCAPE: // exit Edit mode & restore original value + + switch(pItem->m_type) + { + case MENUITEMTYPE_INT: + m_bEditingCurSel = false; + *((int *)addr) = (int)pItem->m_original_value; + break; + case MENUITEMTYPE_FLOAT: + m_bEditingCurSel = false; + *((float *)addr) = ((float)pItem->m_original_value)*0.0001f; + break; + case MENUITEMTYPE_LOGFLOAT: + m_bEditingCurSel = false; + *((float *)addr) = ((float)pItem->m_original_value)*0.0001f; + break; + case MENUITEMTYPE_BLENDABLE: + m_bEditingCurSel = false; + *((CBlendableFloat *)(addr)) = ((float)(pItem->m_original_value))*0.0001f; + break; + case MENUITEMTYPE_LOGBLENDABLE: + m_bEditingCurSel = false; + *((CBlendableFloat *)(addr)) = ((float)(pItem->m_original_value))*0.0001f; + break; + //case MENUITEMTYPE_STRING: + // won't ever happen - see OnWaitStringCancel() + } + return 0; + + case VK_RETURN: + + //if (pItem->m_type == MENUITEMTYPE_STRING) + // ... won't ever happen - see OnWaitStringAccept() + + m_bEditingCurSel = false; + return 0; + + + case VK_NEXT: + case VK_PRIOR: + fMult *= 10.0f; + // break intentionally left out here... + case VK_UP: + case VK_DOWN: + + { + USHORT mask = 1 << (sizeof(USHORT)*8 - 1); // we want the highest-order bit + bool bShiftHeldDown = (GetKeyState(VK_SHIFT) & mask) != 0; + //bool bCtrlHeldDown = (GetKeyState(VK_CONTROL) & mask) != 0; + if (bShiftHeldDown && (wParam==VK_UP || wParam==VK_DOWN)) + fMult *= 0.1f; + } + + bDec = (wParam == VK_DOWN || wParam == VK_NEXT); + + switch(pItem->m_type) + { + case MENUITEMTYPE_INT: + { + int *pInt = ((int *)addr); + if (fMult<1) fMult=1; + (*pInt) += (int)((bDec) ? -fMult : fMult); + if (*pInt < pItem->m_fMin) *pInt = (int)pItem->m_fMin; + if (*pInt > pItem->m_fMax) *pInt = (int)pItem->m_fMax; + } + break; + case MENUITEMTYPE_FLOAT: + { + float *pFloat = ((float *)addr); + float fInc = (pItem->m_fMax - pItem->m_fMin)*0.01f*fMult; + (*pFloat) += (bDec) ? -fInc : fInc; + if (*pFloat < pItem->m_fMin) *pFloat = pItem->m_fMin; + if (*pFloat > pItem->m_fMax) *pFloat = pItem->m_fMax; + } + break; + case MENUITEMTYPE_LOGFLOAT: + { + float *pFloat = ((float *)addr); + (*pFloat) *= (bDec) ? powf(1.0f/1.01f, fMult) : powf(1.01f, fMult); + if (*pFloat < pItem->m_fMin) *pFloat = pItem->m_fMin; + if (*pFloat > pItem->m_fMax) *pFloat = pItem->m_fMax; + } + break; + case MENUITEMTYPE_BLENDABLE: + { + CBlendableFloat *pBlend = ((CBlendableFloat *)addr); + float fInc = (pItem->m_fMax - pItem->m_fMin)*0.01f*fMult; + (*pBlend) += (bDec) ? -fInc : fInc; + if (pBlend->eval(-1) < pItem->m_fMin) *pBlend = pItem->m_fMin; + if (pBlend->eval(-1) > pItem->m_fMax) *pBlend = pItem->m_fMax; + } + break; + case MENUITEMTYPE_LOGBLENDABLE: + { + CBlendableFloat *pBlend = ((CBlendableFloat *)addr); + (*pBlend) *= (bDec) ? powf(1.0f/1.01f, fMult) : powf(1.01f, fMult); + if (pBlend->eval(-1) < pItem->m_fMin) *pBlend = pItem->m_fMin; + if (pBlend->eval(-1) > pItem->m_fMax) *pBlend = pItem->m_fMax; + } + break; + /* + case MENUITEMTYPE_OSC: + if (pItem->m_bEditingSubSel) + { + if (wParam == VK_UP) + { + pItem->m_nSubSel--; + if (pItem->m_nSubSel < 0) pItem->m_nSubSel = 4; + } + else if (wParam == VK_DOWN) + { + pItem->m_nSubSel++; + if (pItem->m_nSubSel > 4) pItem->m_nSubSel = 0; + } + } + else + { + switch(pItem->m_nSubSel) + { + also to do: make 'drawtext' draw it properly + + case 0: + fixme - what are the bounds for each type? and are incs constant or log? + break; + case 1: + fixme + break; + case 2: + fixme + break; + case 3: + fixme + break; + case 4: + fixme + break; + } + } + break; + */ + } + return 0; + + default: + // key wasn't handled + return TRUE; + break; + } + } + + return TRUE; +}
\ No newline at end of file |