123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302 |
- /*
- * Ctrl_pat.cpp
- * ------------
- * Purpose: Pattern tab, upper panel.
- * Notes : (currently none)
- * Authors: Olivier Lapicque
- * OpenMPT Devs
- * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
- */
- #include "stdafx.h"
- #include "Mptrack.h"
- #include "Mainfrm.h"
- #include "InputHandler.h"
- #include "ImageLists.h"
- #include "Childfrm.h"
- #include "Moddoc.h"
- #include "../soundlib/mod_specifications.h"
- #include "Globals.h"
- #include "Ctrl_pat.h"
- #include "View_pat.h"
- #include "PatternEditorDialogs.h"
- #include "ChannelManagerDlg.h"
- #include "../common/mptStringBuffer.h"
- OPENMPT_NAMESPACE_BEGIN
- //////////////////////////////////////////////////////////////
- // CCtrlPatterns
- BEGIN_MESSAGE_MAP(CCtrlPatterns, CModControlDlg)
- //{{AFX_MSG_MAP(CCtrlPatterns)
- ON_WM_KEYDOWN()
- ON_WM_VSCROLL()
- ON_WM_XBUTTONUP()
- ON_COMMAND(IDC_BUTTON1, &CCtrlPatterns::OnSequenceNext)
- ON_COMMAND(IDC_BUTTON2, &CCtrlPatterns::OnSequencePrev)
- ON_COMMAND(ID_PLAYER_PAUSE, &CCtrlPatterns::OnPlayerPause)
- ON_COMMAND(IDC_PATTERN_NEW, &CCtrlPatterns::OnPatternNew)
- ON_COMMAND(IDC_PATTERN_STOP, &CCtrlPatterns::OnPatternStop)
- ON_COMMAND(IDC_PATTERN_PLAY, &CCtrlPatterns::OnPatternPlay)
- ON_COMMAND(IDC_PATTERN_PLAYFROMSTART, &CCtrlPatterns::OnPatternPlayFromStart)
- ON_COMMAND(IDC_PATTERN_RECORD, &CCtrlPatterns::OnPatternRecord)
- ON_COMMAND(IDC_PATTERN_LOOP, &CCtrlPatterns::OnChangeLoopStatus)
- ON_COMMAND(ID_PATTERN_PLAYROW, &CCtrlPatterns::OnPatternPlayRow)
- ON_COMMAND(ID_PATTERN_CHANNELMANAGER, &CCtrlPatterns::OnChannelManager)
- ON_COMMAND(ID_PATTERN_VUMETERS, &CCtrlPatterns::OnPatternVUMeters)
- ON_COMMAND(ID_VIEWPLUGNAMES, &CCtrlPatterns::OnPatternViewPlugNames)
- ON_COMMAND(ID_NEXTINSTRUMENT, &CCtrlPatterns::OnNextInstrument)
- ON_COMMAND(ID_PREVINSTRUMENT, &CCtrlPatterns::OnPrevInstrument)
- ON_COMMAND(IDC_PATTERN_FOLLOWSONG, &CCtrlPatterns::OnFollowSong)
- ON_COMMAND(ID_PATTERN_CHORDEDIT, &CCtrlPatterns::OnChordEditor)
- ON_COMMAND(ID_PATTERN_PROPERTIES, &CCtrlPatterns::OnPatternProperties)
- ON_COMMAND(ID_PATTERN_EXPAND, &CCtrlPatterns::OnPatternExpand)
- ON_COMMAND(ID_PATTERN_SHRINK, &CCtrlPatterns::OnPatternShrink)
- ON_COMMAND(ID_PATTERN_AMPLIFY, &CCtrlPatterns::OnPatternAmplify)
- ON_COMMAND(ID_ORDERLIST_NEW, &CCtrlPatterns::OnPatternNew)
- ON_COMMAND(ID_ORDERLIST_COPY, &CCtrlPatterns::OnPatternDuplicate)
- ON_COMMAND(ID_ORDERLIST_MERGE, &CCtrlPatterns::OnPatternMerge)
- ON_COMMAND(ID_PATTERNCOPY, &CCtrlPatterns::OnPatternCopy)
- ON_COMMAND(ID_PATTERNPASTE, &CCtrlPatterns::OnPatternPaste)
- ON_COMMAND(ID_EDIT_UNDO, &CCtrlPatterns::OnEditUndo)
- ON_COMMAND(ID_PATTERNDETAIL_LO, &CCtrlPatterns::OnDetailLo)
- ON_COMMAND(ID_PATTERNDETAIL_MED, &CCtrlPatterns::OnDetailMed)
- ON_COMMAND(ID_PATTERNDETAIL_HI, &CCtrlPatterns::OnDetailHi)
- ON_COMMAND(ID_OVERFLOWPASTE, &CCtrlPatterns::OnToggleOverflowPaste)
- ON_CBN_SELCHANGE(IDC_COMBO_INSTRUMENT, &CCtrlPatterns::OnInstrumentChanged)
- ON_COMMAND(IDC_PATINSTROPLUGGUI, &CCtrlPatterns::TogglePluginEditor) //rewbs.instroVST
- ON_EN_CHANGE(IDC_EDIT_SPACING, &CCtrlPatterns::OnSpacingChanged)
- ON_EN_CHANGE(IDC_EDIT_PATTERNNAME, &CCtrlPatterns::OnPatternNameChanged)
- ON_EN_CHANGE(IDC_EDIT_SEQUENCE_NAME, &CCtrlPatterns::OnSequenceNameChanged)
- ON_EN_CHANGE(IDC_EDIT_SEQNUM, &CCtrlPatterns::OnSequenceNumChanged)
- ON_UPDATE_COMMAND_UI(IDC_PATTERN_RECORD,&CCtrlPatterns::OnUpdateRecord)
- ON_NOTIFY_EX(TTN_NEEDTEXT, 0, &CCtrlPatterns::OnToolTipText)
- //}}AFX_MSG_MAP
- ON_WM_MOUSEWHEEL()
- END_MESSAGE_MAP()
- void CCtrlPatterns::DoDataExchange(CDataExchange *pDX)
- {
- CModControlDlg::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CCtrlPatterns)
- DDX_Control(pDX, IDC_BUTTON1, m_BtnNext);
- DDX_Control(pDX, IDC_BUTTON2, m_BtnPrev);
- DDX_Control(pDX, IDC_COMBO_INSTRUMENT, m_CbnInstrument);
- DDX_Control(pDX, IDC_EDIT_SPACING, m_EditSpacing);
- DDX_Control(pDX, IDC_EDIT_PATTERNNAME, m_EditPatName);
- DDX_Control(pDX, IDC_EDIT_SEQNUM, m_EditSequence);
- DDX_Control(pDX, IDC_SPIN_SPACING, m_SpinSpacing);
- DDX_Control(pDX, IDC_SPIN_INSTRUMENT, m_SpinInstrument);
- DDX_Control(pDX, IDC_SPIN_SEQNUM, m_SpinSequence);
- DDX_Control(pDX, IDC_TOOLBAR1, m_ToolBar);
- //}}AFX_DATA_MAP
- }
- const ModSequence &CCtrlPatterns::Order() const { return m_sndFile.Order(); }
- ModSequence &CCtrlPatterns::Order() { return m_sndFile.Order(); }
- CCtrlPatterns::CCtrlPatterns(CModControlView &parent, CModDoc &document)
- : CModControlDlg(parent, document), m_OrderList(*this, document)
- {
- m_bVUMeters = TrackerSettings::Instance().gbPatternVUMeters;
- m_bPluginNames = TrackerSettings::Instance().gbPatternPluginNames;
- m_bRecord = TrackerSettings::Instance().gbPatternRecord;
- }
- BOOL CCtrlPatterns::OnInitDialog()
- {
- CRect rect, rcOrderList;
- CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
- CModControlDlg::OnInitDialog();
- EnableToolTips();
- if(!pMainFrm)
- return TRUE;
- SetRedraw(FALSE);
- LockControls();
- // Order List
- m_BtnNext.GetWindowRect(&rect);
- ScreenToClient(&rect);
- auto margins = Util::ScalePixels(4, m_hWnd);
- rcOrderList.left = rect.right + margins;
- rcOrderList.top = rect.top;
- rcOrderList.bottom = rect.bottom + GetSystemMetrics(SM_CYHSCROLL);
- GetClientRect(&rect);
- rcOrderList.right = rect.right - margins;
- m_OrderList.Init(rcOrderList, pMainFrm->GetGUIFont());
- // Toolbar buttons
- m_ToolBar.Init(CMainFrame::GetMainFrame()->m_PatternIcons, CMainFrame::GetMainFrame()->m_PatternIconsDisabled);
- m_ToolBar.AddButton(IDC_PATTERN_NEW, TIMAGE_PATTERN_NEW);
- m_ToolBar.AddButton(IDC_PATTERN_PLAY, TIMAGE_PATTERN_PLAY);
- m_ToolBar.AddButton(IDC_PATTERN_PLAYFROMSTART, TIMAGE_PATTERN_RESTART);
- m_ToolBar.AddButton(IDC_PATTERN_STOP, TIMAGE_PATTERN_STOP);
- m_ToolBar.AddButton(ID_PATTERN_PLAYROW, TIMAGE_PATTERN_PLAYROW);
- m_ToolBar.AddButton(IDC_PATTERN_RECORD, TIMAGE_PATTERN_RECORD, TBSTYLE_CHECK, (m_bRecord ? TBSTATE_CHECKED : 0) | TBSTATE_ENABLED);
- m_ToolBar.AddButton(ID_SEPARATOR, 0, TBSTYLE_SEP);
- m_ToolBar.AddButton(ID_PATTERN_VUMETERS, TIMAGE_PATTERN_VUMETERS, TBSTYLE_CHECK, (m_bVUMeters ? TBSTATE_CHECKED : 0) | TBSTATE_ENABLED);
- m_ToolBar.AddButton(ID_VIEWPLUGNAMES, TIMAGE_PATTERN_PLUGINS, TBSTYLE_CHECK, (m_bPluginNames ? TBSTATE_CHECKED : 0) | TBSTATE_ENABLED);
- m_ToolBar.AddButton(ID_PATTERN_CHANNELMANAGER, TIMAGE_CHANNELMANAGER);
- m_ToolBar.AddButton(ID_SEPARATOR, 0, TBSTYLE_SEP);
- m_ToolBar.AddButton(ID_PATTERN_MIDIMACRO, TIMAGE_MACROEDITOR);
- m_ToolBar.AddButton(ID_PATTERN_CHORDEDIT, TIMAGE_CHORDEDITOR);
- m_ToolBar.AddButton(ID_SEPARATOR, 0, TBSTYLE_SEP);
- m_ToolBar.AddButton(ID_EDIT_UNDO, TIMAGE_UNDO);
- m_ToolBar.AddButton(ID_PATTERN_PROPERTIES, TIMAGE_PATTERN_PROPERTIES);
- m_ToolBar.AddButton(ID_PATTERN_EXPAND, TIMAGE_PATTERN_EXPAND);
- m_ToolBar.AddButton(ID_PATTERN_SHRINK, TIMAGE_PATTERN_SHRINK);
- // m_ToolBar.AddButton(ID_PATTERN_AMPLIFY, TIMAGE_SAMPLE_AMPLIFY);
- m_ToolBar.AddButton(ID_SEPARATOR, 0, TBSTYLE_SEP);
- m_ToolBar.AddButton(ID_PATTERNDETAIL_LO, TIMAGE_PATTERN_DETAIL_LO, TBSTYLE_CHECK, TBSTATE_ENABLED);
- m_ToolBar.AddButton(ID_PATTERNDETAIL_MED, TIMAGE_PATTERN_DETAIL_MED, TBSTYLE_CHECK, TBSTATE_ENABLED);
- m_ToolBar.AddButton(ID_PATTERNDETAIL_HI, TIMAGE_PATTERN_DETAIL_HI, TBSTYLE_CHECK, TBSTATE_ENABLED | TBSTATE_CHECKED);
- m_ToolBar.AddButton(ID_SEPARATOR, 0, TBSTYLE_SEP);
- m_ToolBar.AddButton(ID_OVERFLOWPASTE, TIMAGE_PATTERN_OVERFLOWPASTE, TBSTYLE_CHECK, ((TrackerSettings::Instance().m_dwPatternSetup & PATTERN_OVERFLOWPASTE) ? TBSTATE_CHECKED : 0) | TBSTATE_ENABLED);
- // Special edit controls -> tab switch to view
- m_EditSequence.SetParent(this);
- m_EditSpacing.SetParent(this);
- m_EditPatName.SetParent(this);
- m_EditPatName.SetLimitText(MAX_PATTERNNAME - 1);
- // Spin controls
- m_SpinSpacing.SetRange32(0, MAX_SPACING);
- m_SpinSpacing.SetPos(TrackerSettings::Instance().gnPatternSpacing);
- m_SpinInstrument.SetRange32(-1, 1);
- m_SpinInstrument.SetPos(0);
- SetDlgItemInt(IDC_EDIT_SPACING, TrackerSettings::Instance().gnPatternSpacing);
- CheckDlgButton(IDC_PATTERN_FOLLOWSONG, !(TrackerSettings::Instance().m_dwPatternSetup & PATTERN_FOLLOWSONGOFF));
- m_SpinSequence.SetRange32(1, m_sndFile.Order.GetNumSequences());
- m_SpinSequence.SetPos(m_sndFile.Order.GetCurrentSequenceIndex() + 1);
- SetDlgItemText(IDC_EDIT_SEQUENCE_NAME, mpt::ToCString(Order().GetName()));
- m_OrderList.SetFocus();
- UpdateView(PatternHint().Names().ModType(), NULL);
- RecalcLayout();
- m_bInitialized = TRUE;
- UnlockControls();
- SetRedraw(TRUE);
- return FALSE;
- }
- void CCtrlPatterns::RecalcLayout()
- {
- // Update Order List Position
- if(m_OrderList.m_hWnd)
- {
- CRect rect;
- int cx, cy, cellcx;
- m_BtnNext.GetWindowRect(&rect);
- ScreenToClient(&rect);
- cx = -(rect.right + 4);
- cy = rect.bottom - rect.top + GetSystemMetrics(SM_CYHSCROLL);
- GetClientRect(&rect);
- cx += rect.right - 8;
- cellcx = m_OrderList.GetFontWidth();
- if(cellcx > 0)
- cx -= (cx % cellcx);
- cx += 2;
- if((cx > 0) && (cy > 0))
- {
- m_OrderList.SetWindowPos(NULL, 0, 0, cx, cy, SWP_NOMOVE | SWP_NOZORDER | SWP_DRAWFRAME);
- }
- }
- }
- void CCtrlPatterns::UpdateView(UpdateHint hint, CObject *pObj)
- {
- m_OrderList.UpdateView(hint, pObj);
- FlagSet<HintType> hintType = hint.GetType();
- const bool updateAll = hintType[HINT_MODTYPE];
- const bool updateSeq = hint.GetCategory() == HINTCAT_SEQUENCE;
- const bool updatePlug = hint.GetCategory() == HINTCAT_PLUGINS && hintType[HINT_MIXPLUGINS];
- const PatternHint patternHint = hint.ToType<PatternHint>();
- if(updateAll || (updateSeq && hintType[HINT_SEQNAMES]))
- {
- SetDlgItemText(IDC_EDIT_SEQUENCE_NAME, mpt::ToCString(Order().GetName()));
- }
- if(updateAll || (updateSeq && hintType[HINT_MODSEQUENCE]))
- {
- m_SpinSequence.SetRange(1, m_sndFile.Order.GetNumSequences());
- m_SpinSequence.SetPos(m_sndFile.Order.GetCurrentSequenceIndex() + 1);
- // Enable/disable multisequence controls according the current modtype.
- const BOOL isMultiSeqAvail = (m_sndFile.GetModSpecifications().sequencesMax > 1 || m_sndFile.Order.GetNumSequences() > 1) ? TRUE : FALSE;
- GetDlgItem(IDC_STATIC_SEQUENCE_NAME)->EnableWindow(isMultiSeqAvail);
- GetDlgItem(IDC_EDIT_SEQUENCE_NAME)->EnableWindow(isMultiSeqAvail);
- GetDlgItem(IDC_EDIT_SEQNUM)->EnableWindow(isMultiSeqAvail);
- GetDlgItem(IDC_SPIN_SEQNUM)->EnableWindow(isMultiSeqAvail);
- }
- if(updateAll || updatePlug)
- {
- GetDlgItem(IDC_PATINSTROPLUGGUI)->EnableWindow(HasValidPlug(m_nInstrument) ? TRUE : FALSE);
- }
- if(updateAll)
- {
- // Enable/disable pattern names
- const BOOL isPatNameAvail = m_sndFile.GetModSpecifications().hasPatternNames ? TRUE : FALSE;
- GetDlgItem(IDC_STATIC_PATTERNNAME)->EnableWindow(isPatNameAvail);
- GetDlgItem(IDC_EDIT_PATTERNNAME)->EnableWindow(isPatNameAvail);
- }
- if(hintType[HINT_MPTOPTIONS])
- {
- m_ToolBar.UpdateStyle();
- m_ToolBar.SetState(ID_OVERFLOWPASTE, ((TrackerSettings::Instance().m_dwPatternSetup & PATTERN_OVERFLOWPASTE) ? TBSTATE_CHECKED : 0) | TBSTATE_ENABLED);
- }
- bool instrPluginsChanged = false;
- if(hint.GetCategory() == HINTCAT_PLUGINS && hintType[HINT_PLUGINNAMES])
- {
- const auto changedPlug = hint.ToType<PluginHint>().GetPlugin();
- for(INSTRUMENTINDEX i = 1; i <= m_sndFile.GetNumInstruments(); i++)
- {
- const auto ins = m_sndFile.Instruments[i];
- if(ins != nullptr && (!changedPlug && ins->nMixPlug != 0) || (changedPlug && ins->nMixPlug == changedPlug))
- {
- instrPluginsChanged = true;
- break;
- }
- }
- }
- const bool updatePatNames = patternHint.GetType()[HINT_PATNAMES];
- const bool updateSmpNames = hint.GetCategory() == HINTCAT_SAMPLES && hintType[HINT_SMPNAMES];
- const bool updateInsNames = (hint.GetCategory() == HINTCAT_INSTRUMENTS && hintType[HINT_INSNAMES]) || instrPluginsChanged;
- if(updateAll || updatePatNames || updateSmpNames || updateInsNames)
- {
- LockControls();
- CString s;
- if(updateAll || updateSmpNames || updateInsNames)
- {
- constexpr TCHAR szSplitFormat[] = _T("%02u %s %02u: %s/%s");
- UINT nPos = 0;
- m_CbnInstrument.SetRedraw(FALSE);
- m_CbnInstrument.ResetContent();
- m_CbnInstrument.SetItemData(m_CbnInstrument.AddString(_T(" No Instrument")), 0);
- const INSTRUMENTINDEX nSplitIns = m_modDoc.GetSplitKeyboardSettings().splitInstrument;
- const ModCommand::NOTE noteSplit = 1 + m_modDoc.GetSplitKeyboardSettings().splitNote;
- const CString sSplitInsName = m_modDoc.GetPatternViewInstrumentName(nSplitIns, true, false);
- if(m_sndFile.GetNumInstruments())
- {
- // Show instrument names
- for(INSTRUMENTINDEX i = 1; i <= m_sndFile.GetNumInstruments(); i++)
- {
- if(m_sndFile.Instruments[i] == nullptr)
- continue;
- CString sDisplayName;
- if(m_modDoc.GetSplitKeyboardSettings().IsSplitActive())
- {
- s.Format(szSplitFormat,
- nSplitIns,
- mpt::ToCString(m_sndFile.GetNoteName(noteSplit, nSplitIns)).GetString(),
- i,
- sSplitInsName.GetString(),
- m_modDoc.GetPatternViewInstrumentName(i, true, false).GetString());
- sDisplayName = s;
- }
- else
- sDisplayName = m_modDoc.GetPatternViewInstrumentName(i);
- UINT n = m_CbnInstrument.AddString(sDisplayName);
- if(n == m_nInstrument) nPos = n;
- m_CbnInstrument.SetItemData(n, i);
- }
- } else
- {
- // Show sample names
- SAMPLEINDEX nmax = m_sndFile.GetNumSamples();
- for(SAMPLEINDEX i = 1; i <= nmax; i++) if (m_sndFile.GetSample(i).HasSampleData() || m_sndFile.GetSample(i).uFlags[CHN_ADLIB])
- {
- if (m_modDoc.GetSplitKeyboardSettings().IsSplitActive())
- s.Format(szSplitFormat,
- nSplitIns,
- mpt::ToCString(m_sndFile.GetNoteName(noteSplit, nSplitIns)).GetString(),
- i,
- mpt::ToCString(m_sndFile.GetCharsetInternal(), m_sndFile.m_szNames[nSplitIns]).GetString(),
- mpt::ToCString(m_sndFile.GetCharsetInternal(), m_sndFile.m_szNames[i]).GetString());
- else
- s.Format(_T("%02u: %s"),
- i,
- mpt::ToCString(m_sndFile.GetCharsetInternal(), m_sndFile.m_szNames[i]).GetString());
- UINT n = m_CbnInstrument.AddString(s);
- if(n == m_nInstrument) nPos = n;
- m_CbnInstrument.SetItemData(n, i);
- }
- }
- m_CbnInstrument.SetCurSel(nPos);
- m_CbnInstrument.SetRedraw(TRUE);
- m_CbnInstrument.Invalidate(FALSE);
- }
- if(updateAll || updatePatNames)
- {
- PATTERNINDEX nPat;
- if(patternHint.GetType()[HINT_PATNAMES])
- nPat = patternHint.GetPattern();
- else
- nPat = (PATTERNINDEX)SendViewMessage(VIEWMSG_GETCURRENTPATTERN);
- if(m_sndFile.Patterns.IsValidIndex(nPat))
- {
- m_EditPatName.SetWindowText(mpt::ToCString(m_sndFile.GetCharsetInternal(), m_sndFile.Patterns[nPat].GetName()));
- }
- BOOL bXMIT = (m_sndFile.GetType() & (MOD_TYPE_XM | MOD_TYPE_IT | MOD_TYPE_MPT)) ? TRUE : FALSE;
- m_ToolBar.EnableButton(ID_PATTERN_MIDIMACRO, bXMIT);
- m_ToolBar.EnableButton(ID_PATTERN_PROPERTIES, bXMIT);
- m_ToolBar.EnableButton(ID_PATTERN_EXPAND, bXMIT);
- m_ToolBar.EnableButton(ID_PATTERN_SHRINK, bXMIT);
- }
- UnlockControls();
- }
- if(hintType[HINT_MODTYPE | HINT_UNDO])
- {
- m_ToolBar.EnableButton(ID_EDIT_UNDO, m_modDoc.GetPatternUndo().CanUndo());
- }
- }
- CRuntimeClass *CCtrlPatterns::GetAssociatedViewClass()
- {
- return RUNTIME_CLASS(CViewPattern);
- }
- LRESULT CCtrlPatterns::OnModCtrlMsg(WPARAM wParam, LPARAM lParam)
- {
- switch(wParam)
- {
- case CTRLMSG_GETCURRENTINSTRUMENT:
- return m_nInstrument;
- case CTRLMSG_GETCURRENTPATTERN:
- return m_OrderList.GetCurrentPattern();
- case CTRLMSG_PATTERNCHANGED:
- UpdateView(PatternHint(static_cast<PATTERNINDEX>(lParam)).Names());
- break;
- case CTRLMSG_PAT_PREVINSTRUMENT:
- OnPrevInstrument();
- break;
- case CTRLMSG_PAT_NEXTINSTRUMENT:
- OnNextInstrument();
- break;
- case CTRLMSG_NOTIFYCURRENTORDER:
- if(m_OrderList.GetCurSel().GetSelCount() > 1 || m_OrderList.m_bDragging)
- {
- // Only update play cursor in case there's a selection
- m_OrderList.Invalidate(FALSE);
- break;
- }
- // Otherwise, just act the same as a normal selection change
- [[fallthrough]];
- case CTRLMSG_SETCURRENTORDER:
- // Set order list selection and refresh GUI if change successful
- m_OrderList.SetCurSel(static_cast<ORDERINDEX>(lParam), false, false, true);
- break;
- case CTRLMSG_FORCEREFRESH:
- //refresh GUI
- m_OrderList.InvalidateRect(NULL, FALSE);
- break;
- case CTRLMSG_GETCURRENTORDER:
- return m_OrderList.GetCurSel(true).firstOrd;
- case CTRLMSG_SETCURRENTINSTRUMENT:
- case CTRLMSG_PAT_SETINSTRUMENT:
- return SetCurrentInstrument(static_cast<uint32>(lParam));
- case CTRLMSG_SETVIEWWND:
- {
- SendViewMessage(VIEWMSG_FOLLOWSONG, IsDlgButtonChecked(IDC_PATTERN_FOLLOWSONG));
- SendViewMessage(VIEWMSG_PATTERNLOOP, (m_sndFile.m_SongFlags & SONG_PATTERNLOOP) ? TRUE : FALSE);
- OnSpacingChanged();
- SendViewMessage(VIEWMSG_SETDETAIL, m_nDetailLevel);
- SendViewMessage(VIEWMSG_SETRECORD, m_bRecord);
- SendViewMessage(VIEWMSG_SETVUMETERS, m_bVUMeters);
- SendViewMessage(VIEWMSG_SETPLUGINNAMES, m_bPluginNames);
- }
- break;
- case CTRLMSG_SETSPACING:
- SetDlgItemInt(IDC_EDIT_SPACING, static_cast<UINT>(lParam));
- break;
- case CTRLMSG_SETFOCUS:
- GetParentFrame()->SetActiveView(&m_parent);
- m_OrderList.SetFocus();
- break;
- case CTRLMSG_SETRECORD:
- if (lParam >= 0) m_bRecord = (BOOL)(lParam); else m_bRecord = !m_bRecord;
- m_ToolBar.SetState(IDC_PATTERN_RECORD, ((m_bRecord) ? TBSTATE_CHECKED : 0)|TBSTATE_ENABLED);
- TrackerSettings::Instance().gbPatternRecord = (m_bRecord != 0);
- SendViewMessage(VIEWMSG_SETRECORD, m_bRecord);
- break;
- case CTRLMSG_PREVORDER:
- m_OrderList.SetCurSel(Order().GetPreviousOrderIgnoringSkips(m_OrderList.GetCurSel(true).firstOrd), true);
- break;
- case CTRLMSG_NEXTORDER:
- m_OrderList.SetCurSel(Order().GetNextOrderIgnoringSkips(m_OrderList.GetCurSel(true).firstOrd), true);
- break;
- //rewbs.customKeys
- case CTRLMSG_PAT_FOLLOWSONG:
- // parameters: 0 = turn off, 1 = toggle
- {
- UINT state = FALSE;
- if(lParam == 1) // toggle
- {
- state = !IsDlgButtonChecked(IDC_PATTERN_FOLLOWSONG);
- }
- CheckDlgButton(IDC_PATTERN_FOLLOWSONG, state);
- OnFollowSong();
- }
- break;
- case CTRLMSG_PAT_LOOP:
- {
- bool setLoop = false;
- if (lParam == -1)
- {
- //Toggle loop state
- setLoop = !m_sndFile.m_SongFlags[SONG_PATTERNLOOP];
- } else
- {
- setLoop = (lParam != 0);
- }
- m_sndFile.m_SongFlags.set(SONG_PATTERNLOOP, setLoop);
- CheckDlgButton(IDC_PATTERN_LOOP, setLoop ? BST_CHECKED : BST_UNCHECKED);
- break;
- }
- case CTRLMSG_PAT_NEWPATTERN:
- OnPatternNew();
- break;
- case CTRLMSG_PAT_DUPPATTERN:
- OnPatternDuplicate();
- break;
- case CTRLMSG_PAT_SETSEQUENCE:
- m_OrderList.SelectSequence(static_cast<SEQUENCEINDEX>(lParam));
- UpdateView(SequenceHint(static_cast<SEQUENCEINDEX>(lParam)).Names(), nullptr);
- break;
- default:
- return CModControlDlg::OnModCtrlMsg(wParam, lParam);
- }
- return 0;
- }
- void CCtrlPatterns::SetCurrentPattern(PATTERNINDEX nPat)
- {
- SendViewMessage(VIEWMSG_SETCURRENTPATTERN, (LPARAM)nPat);
- }
- BOOL CCtrlPatterns::SetCurrentInstrument(UINT nIns)
- {
- if(nIns == m_nInstrument)
- return TRUE;
- int n = m_CbnInstrument.GetCount();
- for(int i = 0; i < n; i++)
- {
- if(m_CbnInstrument.GetItemData(i) == nIns)
- {
- m_CbnInstrument.SetCurSel(i);
- m_nInstrument = static_cast<INSTRUMENTINDEX>(nIns);
- GetDlgItem(IDC_PATINSTROPLUGGUI)->EnableWindow(HasValidPlug(m_nInstrument) ? TRUE : FALSE);
- return TRUE;
- }
- }
- return FALSE;
- }
- ////////////////////////////////////////////////////////////
- // CCtrlPatterns messages
- void CCtrlPatterns::OnActivatePage(LPARAM lParam)
- {
- int nIns = m_parent.GetInstrumentChange();
- if(nIns > 0)
- {
- SetCurrentInstrument(nIns);
- }
- if(!(lParam & 0x80000000))
- {
- // Pattern item
- auto pat = static_cast<PATTERNINDEX>(lParam & 0xFFFF);
- if(m_sndFile.Patterns.IsValidIndex(pat))
- {
- for(SEQUENCEINDEX seq = 0; seq < m_sndFile.Order.GetNumSequences(); seq++)
- {
- if(ORDERINDEX ord = m_sndFile.Order(seq).FindOrder(pat); ord != ORDERINDEX_INVALID)
- {
- m_OrderList.SelectSequence(seq);
- m_OrderList.SetCurSel(ord, true);
- UpdateView(SequenceHint(seq).Names(), nullptr);
- break;
- }
- }
- }
- SetCurrentPattern(pat);
- } else if((lParam & 0x80000000))
- {
- // Order item
- auto ord = static_cast<ORDERINDEX>(lParam & 0xFFFF);
- auto seq = static_cast<SEQUENCEINDEX>((lParam >> 16) & 0x7FFF);
- if(seq < m_sndFile.Order.GetNumSequences())
- {
- m_OrderList.SelectSequence(seq);
- const auto &order = Order();
- if(ord < order.size())
- {
- m_OrderList.SetCurSel(ord);
- SetCurrentPattern(order[ord]);
- }
- UpdateView(SequenceHint(static_cast<SEQUENCEINDEX>(seq)).Names(), nullptr);
- }
- }
- if(m_hWndView)
- {
- OnSpacingChanged();
- if(m_bRecord)
- SendViewMessage(VIEWMSG_SETRECORD, m_bRecord);
- CChildFrame *pFrame = (CChildFrame *)GetParentFrame();
- // Restore all save pattern state, except pattern number which we might have just set.
- PATTERNVIEWSTATE &patternViewState = pFrame->GetPatternViewState();
- if(patternViewState.initialOrder != ORDERINDEX_INVALID)
- {
- if(CMainFrame::GetMainFrame()->GetModPlaying() != &m_modDoc)
- m_OrderList.SetCurSel(patternViewState.initialOrder);
- patternViewState.initialOrder = ORDERINDEX_INVALID;
- }
- patternViewState.nPattern = static_cast<PATTERNINDEX>(SendViewMessage(VIEWMSG_GETCURRENTPATTERN));
- SendViewMessage(VIEWMSG_LOADSTATE, (LPARAM)&patternViewState);
- SwitchToView();
- }
- // Combo boxes randomly disappear without this... why?
- Invalidate();
- }
- void CCtrlPatterns::OnDeactivatePage()
- {
- CChildFrame *pFrame = (CChildFrame *)GetParentFrame();
- if((pFrame) && (m_hWndView))
- SendViewMessage(VIEWMSG_SAVESTATE, (LPARAM)&pFrame->GetPatternViewState());
- }
- void CCtrlPatterns::OnVScroll(UINT nSBCode, UINT nPos, CScrollBar *pScrollBar)
- {
- CModControlDlg::OnVScroll(nSBCode, nPos, pScrollBar);
- short int pos = (short int)m_SpinInstrument.GetPos();
- if(pos)
- {
- m_SpinInstrument.SetPos(0);
- if(pos < 0)
- OnPrevInstrument();
- else
- OnNextInstrument();
- }
- }
- void CCtrlPatterns::OnSequencePrev()
- {
- m_OrderList.SetCurSel(m_OrderList.GetCurSel(true).firstOrd - 1);
- m_OrderList.SetFocus();
- }
- void CCtrlPatterns::OnSequenceNext()
- {
- m_OrderList.SetCurSel(m_OrderList.GetCurSel(true).firstOrd + 1);
- m_OrderList.SetFocus();
- }
- void CCtrlPatterns::OnChannelManager()
- {
- m_modDoc.OnChannelManager();
- }
- void CCtrlPatterns::OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags)
- {
- CModControlDlg::OnKeyDown(nChar, nRepCnt, nFlags);
- }
- void CCtrlPatterns::OnSpacingChanged()
- {
- if((m_EditSpacing.m_hWnd) && (m_EditSpacing.GetWindowTextLength() > 0))
- {
- TrackerSettings::Instance().gnPatternSpacing = GetDlgItemInt(IDC_EDIT_SPACING);
- if(TrackerSettings::Instance().gnPatternSpacing > MAX_SPACING)
- {
- TrackerSettings::Instance().gnPatternSpacing = MAX_SPACING;
- SetDlgItemInt(IDC_EDIT_SPACING, TrackerSettings::Instance().gnPatternSpacing, FALSE);
- }
- SendViewMessage(VIEWMSG_SETSPACING, TrackerSettings::Instance().gnPatternSpacing);
- }
- }
- void CCtrlPatterns::OnInstrumentChanged()
- {
- int n = m_CbnInstrument.GetCurSel();
- if(n >= 0)
- {
- n = static_cast<int>(m_CbnInstrument.GetItemData(n));
- int nmax = (m_sndFile.m_nInstruments) ? m_sndFile.m_nInstruments : m_sndFile.m_nSamples;
- if((n >= 0) && (n <= nmax) && (n != (int)m_nInstrument))
- {
- m_nInstrument = static_cast<INSTRUMENTINDEX>(n);
- m_parent.InstrumentChanged(m_nInstrument);
- }
- SwitchToView();
- ::EnableWindow(::GetDlgItem(m_hWnd, IDC_PATINSTROPLUGGUI), HasValidPlug(m_nInstrument));
- }
- }
- void CCtrlPatterns::OnPrevInstrument()
- {
- int n = m_CbnInstrument.GetCount();
- if(n > 0)
- {
- int pos = m_CbnInstrument.GetCurSel();
- if(pos > 0)
- pos--;
- else
- pos = n - 1;
- m_CbnInstrument.SetCurSel(pos);
- OnInstrumentChanged();
- }
- }
- void CCtrlPatterns::OnNextInstrument()
- {
- int n = m_CbnInstrument.GetCount();
- if(n > 0)
- {
- int pos = m_CbnInstrument.GetCurSel() + 1;
- if(pos >= n)
- pos = 0;
- m_CbnInstrument.SetCurSel(pos);
- OnInstrumentChanged();
- }
- }
- void CCtrlPatterns::OnPlayerPause()
- {
- CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
- if(pMainFrm)
- pMainFrm->PauseMod();
- }
- void CCtrlPatterns::OnPatternNew()
- {
- const auto &order = Order();
- ORDERINDEX curOrd = m_OrderList.GetCurSel(true).firstOrd;
- PATTERNINDEX curPat = (curOrd < order.size()) ? order[curOrd] : 0;
- ROWINDEX rows = 64;
- if(m_sndFile.Patterns.IsValidPat(curPat))
- {
- // Only if the current oder is already occupied, create a new pattern at the next position.
- curOrd++;
- } else
- {
- // Use currently edited pattern for new pattern length
- curPat = static_cast<PATTERNINDEX>(SendViewMessage(VIEWMSG_GETCURRENTPATTERN));
- }
- if(m_sndFile.Patterns.IsValidPat(curPat))
- {
- rows = m_sndFile.Patterns[curPat].GetNumRows();
- }
- rows = Clamp(rows, m_sndFile.GetModSpecifications().patternRowsMin, m_sndFile.GetModSpecifications().patternRowsMax);
- const PATTERNINDEX newPat = m_modDoc.InsertPattern(rows, curOrd);
- if(m_sndFile.Patterns.IsValidPat(newPat))
- {
- // update time signature
- if(m_sndFile.Patterns.IsValidIndex(curPat))
- {
- if(m_sndFile.Patterns[curPat].GetOverrideSignature())
- m_sndFile.Patterns[newPat].SetSignature(m_sndFile.Patterns[curPat].GetRowsPerBeat(), m_sndFile.Patterns[curPat].GetRowsPerMeasure());
- if(m_sndFile.Patterns[curPat].HasTempoSwing())
- m_sndFile.Patterns[newPat].SetTempoSwing(m_sndFile.Patterns[curPat].GetTempoSwing());
- }
- // move to new pattern
- m_OrderList.SetCurSel(curOrd);
- m_OrderList.Invalidate(FALSE);
- SetCurrentPattern(newPat);
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(NULL, PatternHint(newPat).Names(), this);
- m_modDoc.UpdateAllViews(NULL, SequenceHint().Data(), this);
- SwitchToView();
- }
- }
- // Duplicates one or more patterns.
- void CCtrlPatterns::OnPatternDuplicate()
- {
- OrdSelection selection = m_OrderList.GetCurSel();
- const ORDERINDEX insertFrom = selection.firstOrd;
- const ORDERINDEX insertWhere = selection.lastOrd + 1u;
- if(insertWhere >= m_sndFile.GetModSpecifications().ordersMax)
- return;
- const ORDERINDEX insertCount = std::min(selection.GetSelCount(), static_cast<ORDERINDEX>(m_sndFile.GetModSpecifications().ordersMax - insertWhere));
- if(!insertCount)
- return;
- bool success = false, outOfPatterns = false;
- // Has this pattern been duplicated already? (for multiselect)
- std::vector<PATTERNINDEX> patReplaceIndex(m_sndFile.Patterns.Size(), PATTERNINDEX_INVALID);
- ModSequence &order = Order();
- for(ORDERINDEX i = 0; i < insertCount; i++)
- {
- PATTERNINDEX curPat = order[insertFrom + i];
- if(curPat < patReplaceIndex.size() && patReplaceIndex[curPat] == PATTERNINDEX_INVALID)
- {
- PATTERNINDEX newPat = m_sndFile.Patterns.Duplicate(curPat, true);
- if(newPat != PATTERNINDEX_INVALID)
- {
- order.insert(insertWhere + i, 1, newPat);
- success = true;
- // Mark as duplicated, so if this pattern is to be duplicated again, the same new pattern number is inserted into the order list.
- patReplaceIndex[curPat] = newPat;
- } else
- {
- if(m_sndFile.Patterns.IsValidPat(curPat))
- outOfPatterns = true;
- continue;
- }
- } else
- {
- // Invalid pattern, or it has been duplicated before (multiselect)
- PATTERNINDEX newPat;
- if(curPat < patReplaceIndex.size() && patReplaceIndex[curPat] != PATTERNINDEX_INVALID)
- {
- // Take care of patterns that have been duplicated before
- newPat = patReplaceIndex[curPat];
- } else
- {
- newPat = order[insertFrom + i];
- }
- order.insert(insertWhere + i, 1, newPat);
- success = true;
- }
- }
- if(success)
- {
- m_OrderList.InsertUpdatePlaystate(selection.firstOrd, selection.lastOrd);
- m_OrderList.Invalidate(FALSE);
- m_OrderList.SetCurSel(insertWhere, true, false, true);
- // If the first duplicated order is e.g. a +++ item, we need to move the pattern display on or else we'll still edit the previously shown pattern.
- ORDERINDEX showPattern = std::min(insertWhere, order.GetLastIndex());
- while(!order.IsValidPat(showPattern) && showPattern < order.GetLastIndex())
- {
- showPattern++;
- }
- SetCurrentPattern(order[showPattern]);
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(nullptr, SequenceHint().Data(), this);
- m_modDoc.UpdateAllViews(nullptr, PatternHint(PATTERNINDEX_INVALID).Names(), this);
- if(selection.lastOrd != selection.firstOrd)
- m_OrderList.m_nScrollPos2nd = insertWhere + insertCount - 1u;
- }
- if(outOfPatterns)
- {
- const auto &specs = m_sndFile.GetModSpecifications();
- Reporting::Error(MPT_AFORMAT("Pattern limit of the {} format ({} patterns) has been reached.")(mpt::ToUpperCaseAscii(specs.fileExtension), specs.patternsMax), "Duplicate Patterns");
- }
- SwitchToView();
- }
- // Merges one or more patterns into a single pattern
- void CCtrlPatterns::OnPatternMerge()
- {
- const OrdSelection selection = m_OrderList.GetCurSel();
- const ORDERINDEX firstOrder = selection.firstOrd;
- const ORDERINDEX numOrders = selection.GetSelCount();
- // Get the total number of lines to be merged
- ROWINDEX numRows = 0u;
- ModSequence &order = Order();
- for(ORDERINDEX i = 0; i < numOrders; i++)
- {
- PATTERNINDEX pat = order[firstOrder + i];
- if(m_sndFile.Patterns.IsValidPat(pat))
- numRows += m_sndFile.Patterns[pat].GetNumRows();
- }
- if(!numRows || numOrders < 2)
- {
- MessageBeep(MB_ICONWARNING);
- SwitchToView();
- return;
- }
- // Try to create a new pattern for the merge
- const auto &specs = m_sndFile.GetModSpecifications();
- const auto format = mpt::ToUpperCaseAscii(specs.fileExtension);
- if(numRows > specs.patternRowsMax)
- {
- Reporting::Error(MPT_AFORMAT("Merged pattern size ({} rows) exceeds the row limit ({} rows) of the {} format.")(numRows, specs.patternRowsMax, format), "Merge Patterns");
- SwitchToView();
- return;
- }
- CriticalSection cs;
- const PATTERNINDEX newPat = m_sndFile.Patterns.InsertAny(std::max(numRows, specs.patternRowsMin), true);
- if(newPat == PATTERNINDEX_INVALID)
- {
- cs.Leave();
- Reporting::Error(MPT_AFORMAT("Pattern limit of the {} format ({} patterns) has been reached.")(format, specs.patternsMax), "Merge Patterns");
- SwitchToView();
- return;
- }
- auto &pattern = m_sndFile.Patterns[newPat];
- auto it = pattern.begin();
- for(ORDERINDEX i = 0; i < numOrders; i++)
- {
- PATTERNINDEX pat = order[firstOrder + i];
- if(m_sndFile.Patterns.IsValidPat(pat))
- it = std::copy(m_sndFile.Patterns[pat].begin(), m_sndFile.Patterns[pat].end(), it);
- }
- if(pattern.GetNumRows() > numRows)
- pattern.WriteEffect(EffectWriter(CMD_PATTERNBREAK, 0).Row(numRows - 1).RetryNextRow());
- // Remove the merged patterns...
- order.Remove(selection.firstOrd, selection.lastOrd);
- m_OrderList.DeleteUpdatePlaystate(selection.firstOrd, selection.lastOrd);
- // ...and insert the new one
- order.insert(firstOrder, 1, newPat);
- m_OrderList.InsertUpdatePlaystate(firstOrder, firstOrder);
- m_OrderList.Invalidate(FALSE);
- m_OrderList.SetSelection(firstOrder);
- SetCurrentPattern(newPat);
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(nullptr, SequenceHint().Data(), this);
- m_modDoc.UpdateAllViews(nullptr, PatternHint(PATTERNINDEX_INVALID).Names(), this);
- SwitchToView();
- }
- void CCtrlPatterns::OnPatternStop()
- {
- CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
- if(pMainFrm)
- pMainFrm->PauseMod(&m_modDoc);
- m_sndFile.ResetChannels();
- SwitchToView();
- }
- void CCtrlPatterns::OnPatternPlay()
- {
- m_modDoc.OnPatternPlay();
- SwitchToView();
- }
- //rewbs.playSongFromCursor
- void CCtrlPatterns::OnPatternPlayNoLoop()
- {
- m_modDoc.OnPatternPlayNoLoop();
- SwitchToView();
- }
- //end rewbs.playSongFromCursor
- void CCtrlPatterns::OnPatternPlayFromStart()
- {
- m_modDoc.OnPatternRestart();
- SwitchToView();
- }
- void CCtrlPatterns::OnPatternRecord()
- {
- UINT nState = m_ToolBar.GetState(IDC_PATTERN_RECORD);
- m_bRecord = ((nState & TBSTATE_CHECKED) != 0);
- TrackerSettings::Instance().gbPatternRecord = (m_bRecord != 0);
- SendViewMessage(VIEWMSG_SETRECORD, m_bRecord);
- SwitchToView();
- }
- void CCtrlPatterns::OnPatternVUMeters()
- {
- UINT nState = m_ToolBar.GetState(ID_PATTERN_VUMETERS);
- m_bVUMeters = ((nState & TBSTATE_CHECKED) != 0);
- TrackerSettings::Instance().gbPatternVUMeters = (m_bVUMeters != 0);
- SendViewMessage(VIEWMSG_SETVUMETERS, m_bVUMeters);
- SwitchToView();
- }
- //rewbs.patPlugName
- void CCtrlPatterns::OnPatternViewPlugNames()
- {
- UINT nState = m_ToolBar.GetState(ID_VIEWPLUGNAMES);
- m_bPluginNames = ((nState & TBSTATE_CHECKED) != 0);
- TrackerSettings::Instance().gbPatternPluginNames = (m_bPluginNames != 0);
- SendViewMessage(VIEWMSG_SETPLUGINNAMES, m_bPluginNames);
- SwitchToView();
- }
- //end rewbs.patPlugName
- void CCtrlPatterns::OnPatternProperties()
- {
- SendViewMessage(VIEWMSG_PATTERNPROPERTIES, PATTERNINDEX_INVALID);
- SwitchToView();
- }
- void CCtrlPatterns::OnPatternExpand()
- {
- SendViewMessage(VIEWMSG_EXPANDPATTERN);
- SwitchToView();
- }
- void CCtrlPatterns::OnPatternCopy()
- {
- SendViewMessage(VIEWMSG_COPYPATTERN);
- SwitchToView();
- }
- void CCtrlPatterns::OnPatternPaste()
- {
- SendViewMessage(VIEWMSG_PASTEPATTERN);
- SwitchToView();
- }
- void CCtrlPatterns::OnPatternShrink()
- {
- SendViewMessage(VIEWMSG_SHRINKPATTERN);
- SwitchToView();
- }
- void CCtrlPatterns::OnPatternAmplify()
- {
- SendViewMessage(VIEWMSG_AMPLIFYPATTERN);
- SwitchToView();
- }
- void CCtrlPatterns::OnPatternPlayRow()
- {
- ::SendMessage(m_hWndView, WM_COMMAND, ID_PATTERN_PLAYROW, 0);
- SwitchToView();
- }
- void CCtrlPatterns::OnUpdateRecord(CCmdUI *pCmdUI)
- {
- if(pCmdUI)
- pCmdUI->SetCheck((m_bRecord) ? TRUE : FALSE);
- }
- void CCtrlPatterns::OnFollowSong()
- {
- SendViewMessage(VIEWMSG_FOLLOWSONG, IsDlgButtonChecked(IDC_PATTERN_FOLLOWSONG));
- SwitchToView();
- }
- void CCtrlPatterns::OnChangeLoopStatus()
- {
- OnModCtrlMsg(CTRLMSG_PAT_LOOP, IsDlgButtonChecked(IDC_PATTERN_LOOP));
- SwitchToView();
- }
- void CCtrlPatterns::OnEditUndo()
- {
- if(m_hWndView)
- ::SendMessage(m_hWndView, WM_COMMAND, ID_EDIT_UNDO, 0);
- SwitchToView();
- }
- void CCtrlPatterns::OnSwitchToView()
- {
- PostViewMessage(VIEWMSG_SETFOCUS);
- }
- void CCtrlPatterns::OnPatternNameChanged()
- {
- if(!IsLocked())
- {
- const PATTERNINDEX nPat = (PATTERNINDEX)SendViewMessage(VIEWMSG_GETCURRENTPATTERN);
- CString tmp;
- m_EditPatName.GetWindowText(tmp);
- const std::string s = mpt::ToCharset(m_sndFile.GetCharsetInternal(), tmp);
- if(m_sndFile.Patterns[nPat].GetName() != s)
- {
- if(m_sndFile.Patterns[nPat].SetName(s))
- {
- if(m_sndFile.GetType() & (MOD_TYPE_XM | MOD_TYPE_IT | MOD_TYPE_MPT))
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(NULL, PatternHint(nPat).Names(), this);
- }
- }
- }
- }
- void CCtrlPatterns::OnSequenceNameChanged()
- {
- CString tmp;
- GetDlgItemText(IDC_EDIT_SEQUENCE_NAME, tmp);
- const mpt::ustring str = mpt::ToUnicode(tmp);
- auto &order = Order();
- if(str != order.GetName())
- {
- order.SetName(str);
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(nullptr, SequenceHint(m_sndFile.Order.GetCurrentSequenceIndex()).Names(), this);
- }
- }
- void CCtrlPatterns::OnChordEditor()
- {
- CChordEditor dlg(this);
- dlg.DoModal();
- SwitchToView();
- }
- void CCtrlPatterns::OnDetailLo()
- {
- m_ToolBar.SetState(ID_PATTERNDETAIL_LO, TBSTATE_CHECKED | TBSTATE_ENABLED);
- if(m_nDetailLevel != PatternCursor::instrColumn)
- {
- m_nDetailLevel = PatternCursor::instrColumn;
- m_ToolBar.SetState(ID_PATTERNDETAIL_MED, TBSTATE_ENABLED);
- m_ToolBar.SetState(ID_PATTERNDETAIL_HI, TBSTATE_ENABLED);
- SendViewMessage(VIEWMSG_SETDETAIL, m_nDetailLevel);
- }
- SwitchToView();
- }
- void CCtrlPatterns::OnDetailMed()
- {
- m_ToolBar.SetState(ID_PATTERNDETAIL_MED, TBSTATE_CHECKED | TBSTATE_ENABLED);
- if(m_nDetailLevel != PatternCursor::volumeColumn)
- {
- m_nDetailLevel = PatternCursor::volumeColumn;
- m_ToolBar.SetState(ID_PATTERNDETAIL_LO, TBSTATE_ENABLED);
- m_ToolBar.SetState(ID_PATTERNDETAIL_HI, TBSTATE_ENABLED);
- SendViewMessage(VIEWMSG_SETDETAIL, m_nDetailLevel);
- }
- SwitchToView();
- }
- void CCtrlPatterns::OnDetailHi()
- {
- m_ToolBar.SetState(ID_PATTERNDETAIL_HI, TBSTATE_CHECKED | TBSTATE_ENABLED);
- if(m_nDetailLevel != PatternCursor::lastColumn)
- {
- m_nDetailLevel = PatternCursor::lastColumn;
- m_ToolBar.SetState(ID_PATTERNDETAIL_LO, TBSTATE_ENABLED);
- m_ToolBar.SetState(ID_PATTERNDETAIL_MED, TBSTATE_ENABLED);
- SendViewMessage(VIEWMSG_SETDETAIL, m_nDetailLevel);
- }
- SwitchToView();
- }
- void CCtrlPatterns::OnToggleOverflowPaste()
- {
- TrackerSettings::Instance().m_dwPatternSetup ^= PATTERN_OVERFLOWPASTE;
- UpdateView(UpdateHint().MPTOptions());
- SwitchToView();
- }
- void CCtrlPatterns::TogglePluginEditor()
- {
- if(m_sndFile.GetInstrumentPlugin(m_nInstrument) != nullptr)
- {
- m_modDoc.TogglePluginEditor(m_sndFile.Instruments[m_nInstrument]->nMixPlug - 1, CMainFrame::GetInputHandler()->ShiftPressed());
- }
- }
- bool CCtrlPatterns::HasValidPlug(INSTRUMENTINDEX instr) const
- {
- return m_sndFile.GetInstrumentPlugin(instr) != nullptr;
- }
- BOOL CCtrlPatterns::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
- {
- if(nFlags == 0)
- {
- PostViewMessage(VIEWMSG_DOSCROLL, zDelta);
- }
- return CModControlDlg::OnMouseWheel(nFlags, zDelta, pt);
- }
- void CCtrlPatterns::OnXButtonUp(UINT nFlags, UINT nButton, CPoint point)
- {
- if(nButton == XBUTTON1)
- OnModCtrlMsg(CTRLMSG_PREVORDER, 0);
- else if(nButton == XBUTTON2)
- OnModCtrlMsg(CTRLMSG_NEXTORDER, 0);
- CModControlDlg::OnXButtonUp(nFlags, nButton, point);
- }
- BOOL CCtrlPatterns::OnToolTip(UINT /*id*/, NMHDR *pNMHDR, LRESULT * /*pResult*/)
- {
- TOOLTIPTEXT *pTTT = (TOOLTIPTEXT *)pNMHDR;
- UINT_PTR nID = pNMHDR->idFrom;
- if(pTTT->uFlags & TTF_IDISHWND)
- {
- // idFrom is actually the HWND of the tool
- nID = ::GetDlgCtrlID((HWND)nID);
- if(nID)
- {
- pTTT->lpszText = MAKEINTRESOURCE(nID);
- pTTT->hinst = AfxGetResourceHandle();
- return TRUE;
- }
- }
- return FALSE;
- }
- BOOL CCtrlPatterns::GetToolTipText(UINT id, LPTSTR str)
- {
- CString fmt;
- const TCHAR *s = nullptr;
- CommandID cmd = kcNull;
- switch(id)
- {
- case IDC_PATTERN_NEW: s = _T("Insert Pattern"); cmd = kcNewPattern; break;
- case IDC_PATTERN_PLAY: s = _T("Play Pattern"); cmd = kcPlayPatternFromCursor; break;
- case IDC_PATTERN_PLAYFROMSTART: s = _T("Replay Pattern"); cmd = kcPlayPatternFromStart; break;
- case IDC_PATTERN_STOP: s = _T("Stop"); cmd = kcPauseSong; break;
- case ID_PATTERN_PLAYROW: s = _T("Play Row"); cmd = kcPatternPlayRow; break;
- case IDC_PATTERN_RECORD: s = _T("Record"); cmd = kcPatternRecord; break;
- case ID_PATTERN_VUMETERS: s = _T("VU-Meters"); break;
- case ID_VIEWPLUGNAMES: s = _T("Show Plugins"); break;
- case ID_PATTERN_CHANNELMANAGER: s = _T("Channel Manager"); cmd = kcViewChannelManager; break;
- case ID_PATTERN_MIDIMACRO: s = _T("Zxx Macro Configuration"); cmd = kcShowMacroConfig; break;
- case ID_PATTERN_CHORDEDIT: s = _T("Chord Editor"); cmd = kcChordEditor; break;
- case ID_EDIT_UNDO:
- fmt = _T("Undo");
- if(m_modDoc.GetPatternUndo().CanUndo())
- fmt += _T(" ") + m_modDoc.GetPatternUndo().GetUndoName();
- cmd = kcEditUndo;
- break;
- case ID_PATTERN_PROPERTIES: s = _T("Pattern Properties"); cmd = kcShowPatternProperties; break;
- case ID_PATTERN_EXPAND: s = _T("Expand Pattern"); break;
- case ID_PATTERN_SHRINK: s = _T("Shrink Pattern"); break;
- case ID_PATTERNDETAIL_LO: s = _T("Low Pattern Detail Level"); break;
- case ID_PATTERNDETAIL_MED: s = _T("Medium Pattern Detail Level"); break;
- case ID_PATTERNDETAIL_HI: s = _T("High Pattern Detail Level"); break;
- case ID_OVERFLOWPASTE: s = _T("Toggle Overflow Paste"); cmd = kcToggleOverflowPaste; break;
- case IDC_PATTERN_LOOP: s = _T("Toggle Loop Pattern"); cmd = kcChangeLoopStatus; break;
- case IDC_PATTERN_FOLLOWSONG: s = _T("Toggle Follow Song"); cmd = kcToggleFollowSong; break;
- default:
- return FALSE;
- }
- if(s != nullptr)
- fmt = s;
- if(cmd != kcNull)
- {
- auto keyText = CMainFrame::GetInputHandler()->m_activeCommandSet->GetKeyTextFromCommand(cmd, 0);
- if(!keyText.IsEmpty())
- fmt += MPT_CFORMAT(" ({})")(keyText);
- }
- _tcscpy(str, fmt.GetString());
- return TRUE;
- }
- void CCtrlPatterns::OnSequenceNumChanged()
- {
- if((m_EditSequence.m_hWnd) && (m_EditSequence.GetWindowTextLength() > 0))
- {
- SEQUENCEINDEX newSeq = static_cast<SEQUENCEINDEX>(GetDlgItemInt(IDC_EDIT_SEQNUM) - 1);
- if(newSeq == m_sndFile.Order.GetCurrentSequenceIndex())
- return;
- if(newSeq >= m_sndFile.Order.GetNumSequences())
- {
- newSeq = m_sndFile.Order.GetNumSequences() - 1;
- SetDlgItemInt(IDC_EDIT_SEQNUM, newSeq + 1, FALSE);
- }
- m_OrderList.SelectSequence(newSeq);
- UpdateView(SequenceHint(newSeq).Names(), nullptr);
- }
- }
- OPENMPT_NAMESPACE_END
|