From: <sag...@us...> - 2015-03-03 19:02:42
|
Revision: 4815 http://sourceforge.net/p/modplug/code/4815 Author: saga-games Date: 2015-03-03 19:02:34 +0000 (Tue, 03 Mar 2015) Log Message: ----------- [New] Instrument tab Can now load and save envelopes (http://bugs.openmpt.org/view.php?id=398) [Mod] OpenMPT: Version is now 1.24.02.04 Modified Paths: -------------- trunk/OpenMPT/common/versionNumber.h trunk/OpenMPT/mptrack/CommandSet.cpp trunk/OpenMPT/mptrack/CommandSet.h trunk/OpenMPT/mptrack/Mainfrm.h trunk/OpenMPT/mptrack/Moddoc.h trunk/OpenMPT/mptrack/Modedit.cpp trunk/OpenMPT/mptrack/View_ins.cpp trunk/OpenMPT/mptrack/View_ins.h trunk/OpenMPT/mptrack/res/envelope_toolbar.png trunk/OpenMPT/mptrack/res/originals/envelope_toolbar.pfi trunk/OpenMPT/mptrack/resource.h Modified: trunk/OpenMPT/common/versionNumber.h =================================================================== --- trunk/OpenMPT/common/versionNumber.h 2015-03-03 17:39:05 UTC (rev 4814) +++ trunk/OpenMPT/common/versionNumber.h 2015-03-03 19:02:34 UTC (rev 4815) @@ -19,7 +19,7 @@ #define VER_MAJORMAJOR 1 #define VER_MAJOR 24 #define VER_MINOR 02 -#define VER_MINORMINOR 03 +#define VER_MINORMINOR 04 //Version string. For example "1.17.02.28" #define MPT_VERSION_STR VER_STRINGIZE(VER_MAJORMAJOR) "." VER_STRINGIZE(VER_MAJOR) "." VER_STRINGIZE(VER_MINOR) "." VER_STRINGIZE(VER_MINORMINOR) Modified: trunk/OpenMPT/mptrack/CommandSet.cpp =================================================================== --- trunk/OpenMPT/mptrack/CommandSet.cpp 2015-03-03 17:39:05 UTC (rev 4814) +++ trunk/OpenMPT/mptrack/CommandSet.cpp 2015-03-03 19:02:34 UTC (rev 4815) @@ -674,8 +674,11 @@ DefineKeyCommand(kcSampleCenterLoopEnd, 1917, _T("Center loop end in view")); DefineKeyCommand(kcSampleCenterSustainStart, 1918, _T("Center sustain loop start in view")); DefineKeyCommand(kcSampleCenterSustainEnd, 1919, _T("Center sustain loop end in view")); + DefineKeyCommand(kcInstrumentEnvelopeLoad, 1920, _T("Load Envelope")); + DefineKeyCommand(kcInstrumentEnvelopeSave, 1921, _T("Save Envelope")); + // Add new key commands here. #ifdef _DEBUG Modified: trunk/OpenMPT/mptrack/CommandSet.h =================================================================== --- trunk/OpenMPT/mptrack/CommandSet.h 2015-03-03 17:39:05 UTC (rev 4814) +++ trunk/OpenMPT/mptrack/CommandSet.h 2015-03-03 19:02:34 UTC (rev 4815) @@ -620,6 +620,8 @@ kcInstrumentLoad=kcStartInstrumentMisc, kcInstrumentSave, kcInstrumentNew, + kcInstrumentEnvelopeLoad, + kcInstrumentEnvelopeSave, kcInstrumentEnvelopeZoomIn, kcInstrumentEnvelopeZoomOut, kcInstrumentEnvelopePointPrev, Modified: trunk/OpenMPT/mptrack/Mainfrm.h =================================================================== --- trunk/OpenMPT/mptrack/Mainfrm.h 2015-03-03 17:39:05 UTC (rev 4814) +++ trunk/OpenMPT/mptrack/Mainfrm.h 2015-03-03 19:02:34 UTC (rev 4815) @@ -246,6 +246,8 @@ IIMAGE_NOZOOMIN, IIMAGE_ZOOMOUT, IIMAGE_NOZOOMOUT, + IIMAGE_SAVE, + IIMAGE_LOAD, ENVIMG_NUMIMAGES }; Modified: trunk/OpenMPT/mptrack/Moddoc.h =================================================================== --- trunk/OpenMPT/mptrack/Moddoc.h 2015-03-03 17:39:05 UTC (rev 4814) +++ trunk/OpenMPT/mptrack/Moddoc.h 2015-03-03 19:02:34 UTC (rev 4815) @@ -245,8 +245,10 @@ BOOL ExpandPattern(PATTERNINDEX nPattern); BOOL ShrinkPattern(PATTERNINDEX nPattern); - bool CopyEnvelope(UINT nIns, enmEnvelopeTypes nEnv); - bool PasteEnvelope(UINT nIns, enmEnvelopeTypes nEnv); + bool CopyEnvelope(INSTRUMENTINDEX nIns, enmEnvelopeTypes nEnv); + bool SaveEnvelope(INSTRUMENTINDEX nIns, enmEnvelopeTypes nEnv, const mpt::PathString &fileName); + bool PasteEnvelope(INSTRUMENTINDEX nIns, enmEnvelopeTypes nEnv); + bool LoadEnvelope(INSTRUMENTINDEX nIns, enmEnvelopeTypes nEnv, const mpt::PathString &fileName); LRESULT ActivateView(UINT nIdView, DWORD dwParam); void UpdateAllViews(CView *pSender, UpdateHint hint, CObject *pHint=NULL); Modified: trunk/OpenMPT/mptrack/Modedit.cpp =================================================================== --- trunk/OpenMPT/mptrack/Modedit.cpp 2015-03-03 17:39:05 UTC (rev 4814) +++ trunk/OpenMPT/mptrack/Modedit.cpp 2015-03-03 19:02:34 UTC (rev 4815) @@ -17,6 +17,7 @@ #include "modsmp_ctrl.h" #include "../common/misc_util.h" #include "../common/StringFixer.h" +#include "../common/mptFileIO.h" // VST cloning #include "Vstplug.h" #include "VstPresets.h" @@ -225,6 +226,10 @@ { m_SndFile.ChnSettings[nChn] = settings[newOrder[nChn]]; m_SndFile.m_PlayState.Chn[nChn] = chns[newOrder[nChn]]; + if(chns[newOrder[nChn]].nMasterChn > 0 && chns[newOrder[nChn]].nMasterChn <= nRemainingChannels) + { + m_SndFile.m_PlayState.Chn[nChn].nMasterChn = newOrder[chns[newOrder[nChn]].nMasterChn - 1] + 1; + } if(recordStates[newOrder[nChn]] == 1) Record1Channel(nChn, true); if(recordStates[newOrder[nChn]] == 2) Record2Channel(nChn, true); m_SndFile.m_bChannelMuteTogglePending[nChn] = chnMutePendings[newOrder[nChn]]; @@ -989,50 +994,119 @@ ///////////////////////////////////////////////////////////////////////////////////////// // Copy/Paste envelope -static LPCSTR pszEnvHdr = "Modplug Tracker Envelope\r\n"; -static LPCSTR pszEnvFmt = "%d,%d,%d,%d,%d,%d,%d,%d\r\n"; +static const CHAR *pszEnvHdr = "ModPlug Tracker Envelope\r\n"; +static const CHAR *pszEnvFmt = "%d,%d,%d,%d,%d,%d,%d,%d\r\n"; -bool CModDoc::CopyEnvelope(UINT nIns, enmEnvelopeTypes nEnv) -//---------------------------------------------------------- +static bool EnvelopeToString(CStringA &s, const InstrumentEnvelope &env) +//---------------------------------------------------------------------- { - CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); - HANDLE hCpy; - CHAR s[4096]; - ModInstrument *pIns; - DWORD dwMemSize; - - if ((nIns < 1) || (nIns > m_SndFile.m_nInstruments) || (!m_SndFile.Instruments[nIns]) || (!pMainFrm)) return false; - BeginWaitCursor(); - pIns = m_SndFile.Instruments[nIns]; - if(pIns == nullptr) return false; - - const InstrumentEnvelope &env = pIns->GetEnvelope(nEnv); - // We don't want to copy empty envelopes if(env.nNodes == 0) { return false; } - strcpy(s, pszEnvHdr); - wsprintf(s + strlen(s), pszEnvFmt, env.nNodes, env.nSustainStart, env.nSustainEnd, env.nLoopStart, env.nLoopEnd, + s.Preallocate(2048); + s = pszEnvHdr; + s.AppendFormat(pszEnvFmt, env.nNodes, env.nSustainStart, env.nSustainEnd, env.nLoopStart, env.nLoopEnd, env.dwFlags[ENV_SUSTAIN] ? 1 : 0, env.dwFlags[ENV_LOOP] ? 1 : 0, env.dwFlags[ENV_CARRY] ? 1 : 0); - for (UINT i = 0; i < env.nNodes; i++) + for(uint32 i = 0; i < env.nNodes; i++) { - if (strlen(s) >= sizeof(s)-32) break; - wsprintf(s+strlen(s), "%d,%d\r\n", env.Ticks[i], env.Values[i]); + s.AppendFormat("%d,%d\r\n", env.Ticks[i], env.Values[i]); } - //Writing release node - if(strlen(s) < sizeof(s) - 32) - wsprintf(s+strlen(s), "%u\r\n", env.nReleaseNode); + // Writing release node + s.AppendFormat("%u\r\n", env.nReleaseNode); + return true; +} - dwMemSize = strlen(s)+1; + +static bool StringToEnvelope(const std::string &s, InstrumentEnvelope &env, const CModSpecifications &specs) +//---------------------------------------------------------------------------------------------------------- +{ + uint32 susBegin = 0, susEnd = 0, loopBegin = 0, loopEnd = 0, bSus = 0, bLoop = 0, bCarry = 0, nPoints = 0, releaseNode = ENV_RELEASE_NODE_UNSET; + size_t length = s.size(), pos = strlen(pszEnvHdr); + if (length <= pos || mpt::strnicmp(s.c_str(), pszEnvHdr, pos - 2)) + { + return false; + } + sscanf(&s[pos], pszEnvFmt, &nPoints, &susBegin, &susEnd, &loopBegin, &loopEnd, &bSus, &bLoop, &bCarry); + while (pos < length && s[pos] != '\r' && s[pos] != '\n') pos++; + + nPoints = MIN(nPoints, specs.envelopePointsMax); + if (susEnd >= nPoints) susEnd = 0; + if (susBegin > susEnd) susBegin = susEnd; + if (loopEnd >= nPoints) loopEnd = 0; + if (loopBegin > loopEnd) loopBegin = loopEnd; + + env.nNodes = nPoints; + env.nSustainStart = susBegin; + env.nSustainEnd = susEnd; + env.nLoopStart = loopBegin; + env.nLoopEnd = loopEnd; + env.nReleaseNode = releaseNode; + env.dwFlags.set(ENV_LOOP, bLoop != 0); + env.dwFlags.set(ENV_SUSTAIN, bSus != 0); + env.dwFlags.set(ENV_CARRY, bCarry != 0); + env.dwFlags.set(ENV_ENABLED, nPoints > 0); + + int oldn = 0; + for (uint32 i = 0; i < nPoints; i++) + { + while (pos < length && (s[pos] < '0' || s[pos] > '9')) pos++; + if (pos >= length) break; + int n1 = atoi(&s[pos]); + while (pos < length && s[pos] != ',') pos++; + while (pos < length && (s[pos] < '0' || s[pos] > '9')) pos++; + if (pos >= length) break; + int n2 = atoi(&s[pos]); + if (n1 < oldn) n1 = oldn + 1; + Limit(n2, ENVELOPE_MIN, ENVELOPE_MAX); + env.Ticks[i] = (uint16)n1; + env.Values[i] = (uint8)n2; + oldn = n1; + while (pos < length && s[pos] != '\r' && s[pos] != '\n') pos++; + if (pos >= length) break; + } + env.Ticks[0] = 0; + + // Read release node information. + env.nReleaseNode = ENV_RELEASE_NODE_UNSET; + if(pos < length) + { + uint8 r = static_cast<uint8>(atoi(&s[pos])); + if(r == 0 || r >= nPoints || !specs.hasReleaseNode) + r = ENV_RELEASE_NODE_UNSET; + env.nReleaseNode = r; + } + return true; +} + + +bool CModDoc::CopyEnvelope(INSTRUMENTINDEX nIns, enmEnvelopeTypes nEnv) +//--------------------------------------------------------------------- +{ + CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); + HANDLE hCpy; + DWORD dwMemSize; + + if ((nIns < 1) || (nIns > m_SndFile.m_nInstruments) || (!m_SndFile.Instruments[nIns]) || (!pMainFrm)) return false; + BeginWaitCursor(); + const ModInstrument *pIns = m_SndFile.Instruments[nIns]; + if(pIns == nullptr) return false; + + CStringA s; + EnvelopeToString(s, pIns->GetEnvelope(nEnv)); + + dwMemSize = s.GetLength() + 1; if ((pMainFrm->OpenClipboard()) && ((hCpy = GlobalAlloc(GMEM_MOVEABLE|GMEM_DDESHARE, dwMemSize))!=NULL)) { EmptyClipboard(); LPBYTE p = (LPBYTE)GlobalLock(hCpy); - memcpy(p, s, dwMemSize); + if(p != nullptr) + { + memcpy(p, s.GetString(), dwMemSize); + } GlobalUnlock(hCpy); SetClipboardData (CF_TEXT, (HANDLE)hCpy); CloseClipboard(); @@ -1042,12 +1116,35 @@ } -bool CModDoc::PasteEnvelope(UINT nIns, enmEnvelopeTypes nEnv) -//----------------------------------------------------------- +bool CModDoc::SaveEnvelope(INSTRUMENTINDEX nIns, enmEnvelopeTypes nEnv, const mpt::PathString &fileName) +//------------------------------------------------------------------------------------------------------ { + if (nIns < 1 || nIns > m_SndFile.m_nInstruments || !m_SndFile.Instruments[nIns]) return false; + BeginWaitCursor(); + const ModInstrument *pIns = m_SndFile.Instruments[nIns]; + if(pIns == nullptr) return false; + + CStringA s; + EnvelopeToString(s, pIns->GetEnvelope(nEnv)); + + FILE *f = mpt_fopen(fileName, "wb"); + if(f == nullptr) + { + EndWaitCursor(); + return false; + } + fwrite(s.GetString(), s.GetLength(), 1, f); + fclose(f); + EndWaitCursor(); + return true; +} + + +bool CModDoc::PasteEnvelope(INSTRUMENTINDEX nIns, enmEnvelopeTypes nEnv) +//---------------------------------------------------------------------- +{ CMainFrame *pMainFrm = CMainFrame::GetMainFrame(); - - if ((nIns < 1) || (nIns > m_SndFile.m_nInstruments) || (!m_SndFile.Instruments[nIns]) || (!pMainFrm)) return false; + if (nIns < 1 || nIns > m_SndFile.m_nInstruments || !m_SndFile.Instruments[nIns] || !pMainFrm) return false; BeginWaitCursor(); if (!pMainFrm->OpenClipboard()) { @@ -1057,72 +1154,34 @@ HGLOBAL hCpy = ::GetClipboardData(CF_TEXT); LPCSTR p; bool result = false; - if ((hCpy) && ((p = (LPSTR)GlobalLock(hCpy)) != NULL)) + if ((hCpy) && ((p = (LPSTR)GlobalLock(hCpy)) != nullptr)) { - ModInstrument *pIns = m_SndFile.Instruments[nIns]; - - UINT susBegin = 0, susEnd = 0, loopBegin = 0, loopEnd = 0, bSus = 0, bLoop = 0, bCarry = 0, nPoints = 0, releaseNode = ENV_RELEASE_NODE_UNSET; - DWORD dwMemSize = GlobalSize(hCpy), dwPos = strlen(pszEnvHdr); - if ((dwMemSize > dwPos) && (!mpt::strnicmp(p, pszEnvHdr, dwPos - 2))) - { - sscanf(p + dwPos, pszEnvFmt, &nPoints, &susBegin, &susEnd, &loopBegin, &loopEnd, &bSus, &bLoop, &bCarry); - while ((dwPos < dwMemSize) && (p[dwPos] != '\r') && (p[dwPos] != '\n')) dwPos++; - - nPoints = MIN(nPoints, m_SndFile.GetModSpecifications().envelopePointsMax); - if (susEnd >= nPoints) susEnd = 0; - if (susBegin > susEnd) susBegin = susEnd; - if (loopEnd >= nPoints) loopEnd = 0; - if (loopBegin > loopEnd) loopBegin = loopEnd; - - InstrumentEnvelope &env = pIns->GetEnvelope(nEnv); - - env.nNodes = nPoints; - env.nSustainStart = susBegin; - env.nSustainEnd = susEnd; - env.nLoopStart = loopBegin; - env.nLoopEnd = loopEnd; - env.nReleaseNode = releaseNode; - env.dwFlags.set(ENV_LOOP, bLoop != 0); - env.dwFlags.set(ENV_SUSTAIN, bSus != 0); - env.dwFlags.set(ENV_CARRY, bCarry != 0); - env.dwFlags.set(ENV_ENABLED, nPoints > 0); - - int oldn = 0; - for (UINT i=0; i<nPoints; i++) - { - while ((dwPos < dwMemSize) && ((p[dwPos] < '0') || (p[dwPos] > '9'))) dwPos++; - if (dwPos >= dwMemSize) break; - int n1 = atoi(p+dwPos); - while ((dwPos < dwMemSize) && (p[dwPos] != ',')) dwPos++; - while ((dwPos < dwMemSize) && ((p[dwPos] < '0') || (p[dwPos] > '9'))) dwPos++; - if (dwPos >= dwMemSize) break; - int n2 = atoi(p+dwPos); - if (n1 < oldn) n1 = oldn + 1; - env.Ticks[i] = (WORD)n1; - env.Values[i] = (BYTE)n2; - oldn = n1; - while ((dwPos < dwMemSize) && (p[dwPos] != '\r') && (p[dwPos] != '\n')) dwPos++; - if (dwPos >= dwMemSize) break; - } - - //Read releasenode information. - if(dwPos < dwMemSize) - { - BYTE r = static_cast<BYTE>(atoi(p + dwPos)); - if(r == 0 || r >= nPoints || !m_SndFile.GetModSpecifications().hasReleaseNode) - r = ENV_RELEASE_NODE_UNSET; - env.nReleaseNode = r; - } - } + std::string data(p, p + GlobalSize(hCpy)); GlobalUnlock(hCpy); CloseClipboard(); - result = true; + + result = StringToEnvelope(data, m_SndFile.Instruments[nIns]->GetEnvelope(nEnv), m_SndFile.GetModSpecifications()); } EndWaitCursor(); return result; } +bool CModDoc::LoadEnvelope(INSTRUMENTINDEX nIns, enmEnvelopeTypes nEnv, const mpt::PathString &fileName) +//------------------------------------------------------------------------------------------------------ +{ + InputFile f(fileName); + if (nIns < 1 || nIns > m_SndFile.m_nInstruments || !m_SndFile.Instruments[nIns] || !f.IsValid()) return false; + BeginWaitCursor(); + FileReader file = GetFileReader(f); + std::string data; + file.ReadNullString(data, 1 << 20); + bool result = StringToEnvelope(data, m_SndFile.Instruments[nIns]->GetEnvelope(nEnv), m_SndFile.GetModSpecifications()); + EndWaitCursor(); + return result; +} + + // Check which channels contain note data. maxRemoveCount specified how many empty channels are reported at max. void CModDoc::CheckUsedChannels(std::vector<bool> &usedMask, CHANNELINDEX maxRemoveCount) const //--------------------------------------------------------------------------------------------- Modified: trunk/OpenMPT/mptrack/View_ins.cpp =================================================================== --- trunk/OpenMPT/mptrack/View_ins.cpp 2015-03-03 17:39:05 UTC (rev 4814) +++ trunk/OpenMPT/mptrack/View_ins.cpp 2015-03-03 19:02:34 UTC (rev 4815) @@ -23,6 +23,7 @@ #include "ScaleEnvPointsDlg.h" #include "../soundlib/MIDIEvents.h" #include "../common/StringFixer.h" +#include "FileDialog.h" OPENMPT_NAMESPACE_BEGIN @@ -44,7 +45,7 @@ #define ENV_LEFTBAR_CYBTN 22 -const UINT cLeftBarButtons[ENV_LEFTBAR_BUTTONS] = +static const UINT cLeftBarButtons[ENV_LEFTBAR_BUTTONS] = { ID_ENVSEL_VOLUME, ID_ENVSEL_PANNING, @@ -65,6 +66,9 @@ ID_SEPARATOR, ID_ENVELOPE_ZOOM_IN, ID_ENVELOPE_ZOOM_OUT, + ID_SEPARATOR, + ID_ENVELOPE_LOAD, + ID_ENVELOPE_SAVE, }; @@ -103,6 +107,8 @@ ON_COMMAND(ID_ENVELOPE_VIEWGRID, OnEnvToggleGrid) //rewbs.envRowGrid ON_COMMAND(ID_ENVELOPE_ZOOM_IN, OnEnvZoomIn) ON_COMMAND(ID_ENVELOPE_ZOOM_OUT, OnEnvZoomOut) + ON_COMMAND(ID_ENVELOPE_LOAD, OnEnvLoad) + ON_COMMAND(ID_ENVELOPE_SAVE, OnEnvSave) ON_COMMAND(ID_ENVSEL_VOLUME, OnSelectVolumeEnv) ON_COMMAND(ID_ENVSEL_PANNING, OnSelectPanningEnv) ON_COMMAND(ID_ENVSEL_PITCH, OnSelectPitchEnv) @@ -155,6 +161,7 @@ CModScrollView::OnInitialUpdate(); ModifyStyleEx(0, WS_EX_ACCEPTFILES); UpdateScrollSize(); + UpdateNcButtonState(); } @@ -752,6 +759,8 @@ case ID_ENVELOPE_VIEWGRID: if (m_bGrid) dwStyle |= NCBTNS_CHECKED; break; case ID_ENVELOPE_ZOOM_IN: if (m_fZoom >= ENV_MAX_ZOOM) dwStyle |= NCBTNS_DISABLED; break; case ID_ENVELOPE_ZOOM_OUT: if (m_fZoom <= ENV_MIN_ZOOM) dwStyle |= NCBTNS_DISABLED; break; + case ID_ENVELOPE_LOAD: + case ID_ENVELOPE_SAVE: if (GetInstrumentPtr() == nullptr) dwStyle |= NCBTNS_DISABLED; break; } if (m_nBtnMouseOver == i) { @@ -1261,6 +1270,8 @@ case ID_ENVELOPE_VIEWGRID: nImage = IIMAGE_GRID; break; case ID_ENVELOPE_ZOOM_IN: nImage = (dwStyle & NCBTNS_DISABLED) ? IIMAGE_NOZOOMIN : IIMAGE_ZOOMIN; break; case ID_ENVELOPE_ZOOM_OUT: nImage = (dwStyle & NCBTNS_DISABLED) ? IIMAGE_NOZOOMOUT : IIMAGE_ZOOMOUT; break; + case ID_ENVELOPE_LOAD: nImage = IIMAGE_LOAD; break; + case ID_ENVELOPE_SAVE: nImage = IIMAGE_SAVE; break; } pDC->Draw3dRect(rect.left-1, rect.top-1, ENV_LEFTBAR_CXBTN+2, ENV_LEFTBAR_CYBTN+2, c3, c4); pDC->Draw3dRect(rect.left, rect.top, ENV_LEFTBAR_CXBTN, ENV_LEFTBAR_CYBTN, c1, c2); @@ -2219,6 +2230,8 @@ case kcInstrumentNew: SendCtrlMessage(IDC_INSTRUMENT_NEW); return wParam; // envelope editor + case kcInstrumentEnvelopeLoad: OnEnvLoad(); return wParam; + case kcInstrumentEnvelopeSave: OnEnvSave(); return wParam; case kcInstrumentEnvelopeZoomIn: OnEnvZoomIn(); return wParam; case kcInstrumentEnvelopeZoomOut: OnEnvZoomOut(); return wParam; case kcInstrumentEnvelopePointPrev: EnvKbdSelectPrevPoint(); return wParam; @@ -2528,4 +2541,47 @@ } +void CViewInstrument::OnEnvLoad() +//------------------------------- +{ + if(GetInstrumentPtr() == nullptr) return; + + FileDialog dlg = OpenFileDialog() + .DefaultExtension("envelope") + .ExtensionFilter("Instrument Envelopes (*.envelope)|*.envelope||") + .WorkingDirectory(TrackerDirectories::Instance().GetWorkingDirectory(DIR_INSTRUMENTS)); + if(!dlg.Show(this)) return; + TrackerDirectories::Instance().SetWorkingDirectory(dlg.GetWorkingDirectory(), DIR_INSTRUMENTS); + + if(GetDocument()->LoadEnvelope(m_nInstrument, m_nEnv, dlg.GetFirstFile())) + { + SetModified(InstrumentHint(m_nInstrument).Envelope(), true); + } +} + + +void CViewInstrument::OnEnvSave() +//------------------------------- +{ + InstrumentEnvelope *env = GetEnvelopePtr(); + if(env == nullptr || env->nNodes == 0) + { + MessageBeep(MB_ICONWARNING); + return; + } + + FileDialog dlg = SaveFileDialog() + .DefaultExtension("envelope") + .ExtensionFilter("Instrument Envelopes (*.envelope)|*.envelope||") + .WorkingDirectory(TrackerDirectories::Instance().GetWorkingDirectory(DIR_INSTRUMENTS)); + if(!dlg.Show(this)) return; + TrackerDirectories::Instance().SetWorkingDirectory(dlg.GetWorkingDirectory(), DIR_INSTRUMENTS); + + if(!GetDocument()->SaveEnvelope(m_nInstrument, m_nEnv, dlg.GetFirstFile())) + { + Reporting::Error(L"Unable to save file " + dlg.GetFirstFile().ToWide(), L"OpenMPT", this); + } +} + + OPENMPT_NAMESPACE_END Modified: trunk/OpenMPT/mptrack/View_ins.h =================================================================== --- trunk/OpenMPT/mptrack/View_ins.h 2015-03-03 17:39:05 UTC (rev 4814) +++ trunk/OpenMPT/mptrack/View_ins.h 2015-03-03 19:02:34 UTC (rev 4815) @@ -18,7 +18,7 @@ #define INSSTATUS_SPLITCURSOR 0x04 // Non-Client toolbar buttons -#define ENV_LEFTBAR_BUTTONS 19 +#define ENV_LEFTBAR_BUTTONS 22 //========================================== class CViewInstrument: public CModScrollView @@ -204,7 +204,9 @@ afx_msg void OnEnvPanChanged(); afx_msg void OnEnvPitchChanged(); afx_msg void OnEnvFilterChanged(); - afx_msg void OnEnvToggleGrid(); //rewbs.envRowGrid + afx_msg void OnEnvToggleGrid(); + afx_msg void OnEnvLoad(); + afx_msg void OnEnvSave(); afx_msg void OnEditCopy(); afx_msg void OnEditPaste(); afx_msg void OnEditSampleMap(); Modified: trunk/OpenMPT/mptrack/res/envelope_toolbar.png =================================================================== (Binary files differ) Modified: trunk/OpenMPT/mptrack/res/originals/envelope_toolbar.pfi =================================================================== (Binary files differ) Modified: trunk/OpenMPT/mptrack/resource.h =================================================================== --- trunk/OpenMPT/mptrack/resource.h 2015-03-03 17:39:05 UTC (rev 4814) +++ trunk/OpenMPT/mptrack/resource.h 2015-03-03 19:02:34 UTC (rev 4815) @@ -1227,6 +1227,8 @@ #define ID_HELP_EXAMPLEMODULES 44459 #define ID_FILE_SAVEASTEMPLATE 44460 #define ID_ORDERLIST_INSERT_SEPARATOR 44461 +#define ID_ENVELOPE_LOAD 44462 +#define ID_ENVELOPE_SAVE 44463 #define ID_PLUGINEDITOR_SLIDERS_BASE 44500 // From here: Command range [ID_PLUGINEDITOR_SLIDERS_BASE, ID_PLUGINEDITOR_SLIDERS_BASE + NUM_PLUGINEDITOR_PARAMETERS] #define ID_PLUGINEDITOR_EDIT_BASE 44550 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |