123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816 |
- /*
- * Ctrl_gen.cpp
- * ------------
- * Purpose: General 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 "Moddoc.h"
- #include "Globals.h"
- #include "dlg_misc.h"
- #include "Ctrl_gen.h"
- #include "View_gen.h"
- #include "../common/misc_util.h"
- #include "../common/mptTime.h"
- #include "../soundlib/mod_specifications.h"
- OPENMPT_NAMESPACE_BEGIN
- BEGIN_MESSAGE_MAP(CCtrlGeneral, CModControlDlg)
- //{{AFX_MSG_MAP(CCtrlGeneral)
- ON_WM_VSCROLL()
- ON_COMMAND(IDC_BUTTON1, &CCtrlGeneral::OnTapTempo)
- ON_COMMAND(IDC_BUTTON_MODTYPE, &CCtrlGeneral::OnSongProperties)
- ON_COMMAND(IDC_CHECK_LOOPSONG, &CCtrlGeneral::OnLoopSongChanged)
- ON_EN_CHANGE(IDC_EDIT_SONGTITLE, &CCtrlGeneral::OnTitleChanged)
- ON_EN_CHANGE(IDC_EDIT_ARTIST, &CCtrlGeneral::OnArtistChanged)
- ON_EN_CHANGE(IDC_EDIT_TEMPO, &CCtrlGeneral::OnTempoChanged)
- ON_EN_CHANGE(IDC_EDIT_SPEED, &CCtrlGeneral::OnSpeedChanged)
- ON_EN_CHANGE(IDC_EDIT_GLOBALVOL, &CCtrlGeneral::OnGlobalVolChanged)
- ON_EN_CHANGE(IDC_EDIT_RESTARTPOS, &CCtrlGeneral::OnRestartPosChanged)
- ON_EN_CHANGE(IDC_EDIT_VSTIVOL, &CCtrlGeneral::OnVSTiVolChanged)
- ON_EN_CHANGE(IDC_EDIT_SAMPLEPA, &CCtrlGeneral::OnSamplePAChanged)
- ON_MESSAGE(WM_MOD_UPDATEPOSITION, &CCtrlGeneral::OnUpdatePosition)
- ON_EN_SETFOCUS(IDC_EDIT_SONGTITLE, &CCtrlGeneral::OnEnSetfocusEditSongtitle)
- ON_EN_KILLFOCUS(IDC_EDIT_RESTARTPOS, &CCtrlGeneral::OnRestartPosDone)
- ON_CBN_SELCHANGE(IDC_COMBO1, &CCtrlGeneral::OnResamplingChanged)
- //}}AFX_MSG_MAP
- END_MESSAGE_MAP()
- void CCtrlGeneral::DoDataExchange(CDataExchange* pDX)
- {
- CModControlDlg::DoDataExchange(pDX);
- //{{AFX_DATA_MAP(CCtrlGeneral)
- DDX_Control(pDX, IDC_EDIT_SONGTITLE, m_EditTitle);
- DDX_Control(pDX, IDC_EDIT_ARTIST, m_EditArtist);
- //DDX_Control(pDX, IDC_EDIT_TEMPO, m_EditTempo);
- DDX_Control(pDX, IDC_SPIN_TEMPO, m_SpinTempo);
- DDX_Control(pDX, IDC_EDIT_SPEED, m_EditSpeed);
- DDX_Control(pDX, IDC_SPIN_SPEED, m_SpinSpeed);
- DDX_Control(pDX, IDC_EDIT_GLOBALVOL, m_EditGlobalVol);
- DDX_Control(pDX, IDC_SPIN_GLOBALVOL, m_SpinGlobalVol);
- DDX_Control(pDX, IDC_EDIT_VSTIVOL, m_EditVSTiVol);
- DDX_Control(pDX, IDC_SPIN_VSTIVOL, m_SpinVSTiVol);
- DDX_Control(pDX, IDC_EDIT_SAMPLEPA, m_EditSamplePA);
- DDX_Control(pDX, IDC_SPIN_SAMPLEPA, m_SpinSamplePA);
- DDX_Control(pDX, IDC_EDIT_RESTARTPOS, m_EditRestartPos);
- DDX_Control(pDX, IDC_SPIN_RESTARTPOS, m_SpinRestartPos);
- DDX_Control(pDX, IDC_SLIDER_SONGTEMPO, m_SliderTempo);
- DDX_Control(pDX, IDC_SLIDER_VSTIVOL, m_SliderVSTiVol);
- DDX_Control(pDX, IDC_SLIDER_GLOBALVOL, m_SliderGlobalVol);
- DDX_Control(pDX, IDC_SLIDER_SAMPLEPREAMP, m_SliderSamplePreAmp);
- DDX_Control(pDX, IDC_BUTTON_MODTYPE, m_BtnModType);
- DDX_Control(pDX, IDC_VUMETER_LEFT, m_VuMeterLeft);
- DDX_Control(pDX, IDC_VUMETER_RIGHT, m_VuMeterRight);
- DDX_Control(pDX, IDC_COMBO1, m_CbnResampling);
- //}}AFX_DATA_MAP
- }
- CCtrlGeneral::CCtrlGeneral(CModControlView &parent, CModDoc &document) : CModControlDlg(parent, document)
- {
- }
- BOOL CCtrlGeneral::OnInitDialog()
- {
- const auto &specs = m_sndFile.GetModSpecifications();
- CModControlDlg::OnInitDialog();
- // Song Title
- m_EditTitle.SetLimitText(specs.modNameLengthMax);
- m_SpinGlobalVol.SetRange(0, (short)(256 / GetGlobalVolumeFactor()));
- m_SpinSamplePA.SetRange(0, 2000);
- m_SpinVSTiVol.SetRange(0, 2000);
- m_SpinRestartPos.SetRange32(0, ORDERINDEX_MAX);
-
- m_SliderGlobalVol.SetRange(0, MAX_SLIDER_GLOBAL_VOL);
- m_SliderVSTiVol.SetRange(0, MAX_SLIDER_VSTI_VOL);
- m_SliderSamplePreAmp.SetRange(0, MAX_SLIDER_SAMPLE_VOL);
- m_SpinTempo.SetRange(-10, 10);
- m_SliderTempo.SetLineSize(1);
- m_SliderTempo.SetPageSize(10);
- m_EditTempo.SubclassDlgItem(IDC_EDIT_TEMPO, this);
- m_EditTempo.AllowNegative(false);
-
- m_editsLocked = false;
- UpdateView(GeneralHint().ModType());
- OnActivatePage(0);
- m_bInitialized = TRUE;
-
- return FALSE;
- }
- CRuntimeClass *CCtrlGeneral::GetAssociatedViewClass()
- {
- return RUNTIME_CLASS(CViewGlobals);
- }
- void CCtrlGeneral::RecalcLayout()
- {
- }
- void CCtrlGeneral::OnActivatePage(LPARAM)
- {
- m_modDoc.SetNotifications(Notification::Default);
- m_modDoc.SetFollowWnd(m_hWnd);
- PostViewMessage(VIEWMSG_SETACTIVE, NULL);
- SetFocus();
- // Combo boxes randomly disappear without this... why?
- Invalidate();
- }
- void CCtrlGeneral::OnDeactivatePage()
- {
- m_modDoc.SetFollowWnd(NULL);
- m_VuMeterLeft.SetVuMeter(0, true);
- m_VuMeterRight.SetVuMeter(0, true);
- m_tapTimer = nullptr; // Reset high-precision clock if required
- }
- TEMPO CCtrlGeneral::TempoSliderRange() const
- {
- return (TEMPO_SPLIT_THRESHOLD - m_tempoMin) + TEMPO((m_tempoMax - TEMPO_SPLIT_THRESHOLD).GetInt() / TEMPO_SPLIT_PRECISION, 0);
- }
- TEMPO CCtrlGeneral::SliderToTempo(int value) const
- {
- if(m_tempoMax < TEMPO_SPLIT_THRESHOLD)
- {
- return m_tempoMax - TEMPO(value, 0);
- } else
- {
- const auto tempoSliderSplit = TempoToSlider(TEMPO_SPLIT_THRESHOLD);
- if(value <= tempoSliderSplit)
- return m_tempoMax - TEMPO(value * TEMPO_SPLIT_PRECISION, 0);
- else
- return m_tempoMin + TempoSliderRange() - TEMPO(value, 0);
- }
- }
- int CCtrlGeneral::TempoToSlider(TEMPO tempo) const
- {
- if(m_tempoMax < TEMPO_SPLIT_THRESHOLD)
- {
- return (m_tempoMax - tempo).GetInt();
- } else
- {
- if(tempo < TEMPO_SPLIT_THRESHOLD)
- return (TempoSliderRange() - (std::max(m_tempoMin, tempo) - m_tempoMin)).GetInt();
- else
- return (m_tempoMax - std::min(m_tempoMax, tempo)).GetInt() / TEMPO_SPLIT_PRECISION;
- }
- }
- void CCtrlGeneral::OnTapTempo()
- {
- using TapType = decltype(m_tapTimer->Now());
- static std::array<TapType, 32> tapTime;
- static TapType lastTap = 0;
- static uint32 numTaps = 0;
- if(m_tapTimer == nullptr)
- m_tapTimer = std::make_unique<Util::MultimediaClock>(1);
- const uint32 now = m_tapTimer->Now();
- if(now - lastTap >= 2000)
- numTaps = 0;
- lastTap = now;
- if(static_cast<size_t>(numTaps) >= tapTime.size())
- {
- // Shift back the previously recorded tap history
- // cppcheck false-positive
- // cppcheck-suppress mismatchingContainers
- std::copy(tapTime.begin() + 1, tapTime.end(), tapTime.begin());
- numTaps = static_cast<uint32>(tapTime.size() - 1);
- }
-
- tapTime[numTaps++] = now;
- if(numTaps <= 1)
- return;
- // Now apply least squares to tap history
- double sum = 0.0, weightedSum = 0.0;
- for(uint32 i = 0; i < numTaps; i++)
- {
- const double tapMs = tapTime[i] / 1000.0;
- sum += tapMs;
- weightedSum += i * tapMs;
- }
- const double lengthSum = numTaps * (numTaps - 1) / 2;
- const double lengthSumSum = lengthSum * (2 * numTaps - 1) / 3.0;
- const double secondsPerBeat = (numTaps * weightedSum - lengthSum * sum) / (lengthSumSum * numTaps - lengthSum * lengthSum);
- double newTempo = 60.0 / secondsPerBeat;
- if(m_sndFile.m_nTempoMode != TempoMode::Modern)
- newTempo *= (m_sndFile.m_nDefaultSpeed * m_sndFile.m_nDefaultRowsPerBeat) / 24.0;
- if(!m_sndFile.GetModSpecifications().hasFractionalTempo)
- newTempo = std::round(newTempo);
- TEMPO t(newTempo);
- Limit(t, m_tempoMin, m_tempoMax);
- m_EditTempo.SetTempoValue(t);
- }
- void CCtrlGeneral::UpdateView(UpdateHint hint, CObject *pHint)
- {
- if (pHint == this) return;
- FlagSet<HintType> hintType = hint.GetType();
- const bool updateAll = hintType[HINT_MODTYPE];
- const auto resamplingModes = Resampling::AllModes();
- if (hintType == HINT_MPTOPTIONS || updateAll)
- {
- CString defaultResampler;
- if(m_sndFile.m_SongFlags[SONG_ISAMIGA] && TrackerSettings::Instance().ResamplerEmulateAmiga != Resampling::AmigaFilter::Off)
- defaultResampler = _T("Amiga Resampler");
- else
- defaultResampler = CTrackApp::GetResamplingModeName(TrackerSettings::Instance().ResamplerMode, 1, false);
- m_CbnResampling.ResetContent();
- m_CbnResampling.SetItemData(m_CbnResampling.AddString(_T("Default (") + defaultResampler + _T(")")), SRCMODE_DEFAULT);
- for(auto mode : resamplingModes)
- {
- m_CbnResampling.SetItemData(m_CbnResampling.AddString(CTrackApp::GetResamplingModeName(mode, 2, true)), mode);
- }
- m_CbnResampling.Invalidate(FALSE);
- }
- if(updateAll)
- {
- const auto &specs = m_sndFile.GetModSpecifications();
- // S3M HACK: ST3 will ignore speed 255, even though it can be used with Axx.
- if(m_sndFile.GetType() == MOD_TYPE_S3M)
- m_SpinSpeed.SetRange32(1, 254);
- else
- m_SpinSpeed.SetRange32(specs.speedMin, specs.speedMax);
- m_tempoMin = specs.GetTempoMin();
- m_tempoMax = specs.GetTempoMax();
- // IT Hack: There are legacy OpenMPT-made ITs out there which use a higher default speed than 255.
- // Changing the upper tempo limit in the mod specs would break them, so do it here instead.
- if(m_sndFile.GetType() == MOD_TYPE_IT && m_sndFile.m_nDefaultTempo <= TEMPO(255, 0))
- m_tempoMax.Set(255);
- // Lower resolution for BPM above 256
- if(m_tempoMax >= TEMPO_SPLIT_THRESHOLD)
- m_SliderTempo.SetRange(0, TempoSliderRange().GetInt());
- else
- m_SliderTempo.SetRange(0, m_tempoMax.GetInt() - m_tempoMin.GetInt());
- m_EditTempo.AllowFractions(specs.hasFractionalTempo);
- const BOOL bIsNotMOD = (m_sndFile.GetType() != MOD_TYPE_MOD);
- const BOOL bIsNotMOD_XM = ((bIsNotMOD) && (m_sndFile.GetType() != MOD_TYPE_XM));
- m_EditArtist.EnableWindow(specs.hasArtistName);
- m_EditTempo.EnableWindow(bIsNotMOD);
- m_SpinTempo.EnableWindow(bIsNotMOD);
- GetDlgItem(IDC_BUTTON1)->EnableWindow(bIsNotMOD);
- m_SliderTempo.EnableWindow(bIsNotMOD);
- m_EditSpeed.EnableWindow(bIsNotMOD);
- m_SpinSpeed.EnableWindow(bIsNotMOD);
- const BOOL globalVol = bIsNotMOD_XM || m_sndFile.m_nDefaultGlobalVolume != MAX_GLOBAL_VOLUME;
- m_SliderGlobalVol.EnableWindow(globalVol);
- m_EditGlobalVol.EnableWindow(globalVol);
- m_SpinGlobalVol.EnableWindow(globalVol);
- m_EditSamplePA.EnableWindow(bIsNotMOD);
- m_SpinSamplePA.EnableWindow(bIsNotMOD);
- m_SliderVSTiVol.EnableWindow(bIsNotMOD);
- m_EditVSTiVol.EnableWindow(bIsNotMOD);
- m_SpinVSTiVol.EnableWindow(bIsNotMOD);
- m_EditRestartPos.EnableWindow((specs.hasRestartPos || m_sndFile.Order().GetRestartPos() != 0));
- m_SpinRestartPos.EnableWindow(m_EditRestartPos.IsWindowEnabled());
- //Note: Sample volume slider is not disabled for MOD
- //on purpose (can be used to control play volume)
- }
- if(updateAll || (hint.GetCategory() == HINTCAT_GLOBAL && hintType[HINT_MODCHANNELS]))
- {
- // MOD Type
- mpt::ustring modType;
- switch(m_sndFile.GetType())
- {
- case MOD_TYPE_MOD: modType = U_("MOD (ProTracker)"); break;
- case MOD_TYPE_S3M: modType = U_("S3M (Scream Tracker)"); break;
- case MOD_TYPE_XM: modType = U_("XM (FastTracker 2)"); break;
- case MOD_TYPE_IT: modType = U_("IT (Impulse Tracker)"); break;
- case MOD_TYPE_MPT: modType = U_("MPTM (OpenMPT)"); break;
- default: modType = MPT_UFORMAT("{} ({})")(mpt::ToUpperCase(m_sndFile.m_modFormat.type), m_sndFile.m_modFormat.formatName); break;
- }
- CString s;
- s.Format(_T("%s, %u channel%s"), mpt::ToCString(modType).GetString(), m_sndFile.GetNumChannels(), (m_sndFile.GetNumChannels() != 1) ? _T("s") : _T(""));
- m_BtnModType.SetWindowText(s);
- }
- if (updateAll || (hint.GetCategory() == HINTCAT_SEQUENCE && hintType[HINT_MODSEQUENCE | HINT_RESTARTPOS]))
- {
- // Set max valid restart position
- m_SpinRestartPos.SetRange32(0, std::max(m_sndFile.Order().GetRestartPos(), static_cast<ORDERINDEX>(m_sndFile.Order().GetLengthTailTrimmed() - 1)));
- SetDlgItemInt(IDC_EDIT_RESTARTPOS, m_sndFile.Order().GetRestartPos(), FALSE);
- }
- if (updateAll || (hint.GetCategory() == HINTCAT_GENERAL && hintType[HINT_MODGENERAL]))
- {
- if (!m_editsLocked)
- {
- m_EditTitle.SetWindowText(mpt::ToCString(m_sndFile.GetCharsetInternal(), m_sndFile.GetTitle()));
- m_EditArtist.SetWindowText(mpt::ToCString(m_sndFile.m_songArtist));
- m_EditTempo.SetTempoValue(m_sndFile.m_nDefaultTempo);
- SetDlgItemInt(IDC_EDIT_SPEED, m_sndFile.m_nDefaultSpeed, FALSE);
- SetDlgItemInt(IDC_EDIT_GLOBALVOL, m_sndFile.m_nDefaultGlobalVolume / GetGlobalVolumeFactor(), FALSE);
- SetDlgItemInt(IDC_EDIT_VSTIVOL, m_sndFile.m_nVSTiVolume, FALSE);
- SetDlgItemInt(IDC_EDIT_SAMPLEPA, m_sndFile.m_nSamplePreAmp, FALSE);
- }
- m_SliderGlobalVol.SetPos(MAX_SLIDER_GLOBAL_VOL - m_sndFile.m_nDefaultGlobalVolume);
- m_SliderVSTiVol.SetPos(MAX_SLIDER_VSTI_VOL - m_sndFile.m_nVSTiVolume);
- m_SliderSamplePreAmp.SetPos(MAX_SLIDER_SAMPLE_VOL - m_sndFile.m_nSamplePreAmp);
- m_SliderTempo.SetPos(TempoToSlider(m_sndFile.m_nDefaultTempo));
- }
- if(updateAll || hintType == HINT_MPTOPTIONS || (hint.GetCategory() == HINTCAT_GENERAL && hintType[HINT_MODGENERAL]))
- {
- for(int i = 0; i < m_CbnResampling.GetCount(); ++i)
- {
- if(m_sndFile.m_nResampling == static_cast<ResamplingMode>(m_CbnResampling.GetItemData(i)))
- {
- m_CbnResampling.SetCurSel(i);
- break;
- }
- }
- }
- CheckDlgButton(IDC_CHECK_LOOPSONG, (TrackerSettings::Instance().gbLoopSong) ? TRUE : FALSE);
- if (hintType[HINT_MPTOPTIONS])
- {
- m_VuMeterLeft.InvalidateRect(NULL, FALSE);
- m_VuMeterRight.InvalidateRect(NULL, FALSE);
- }
- }
- void CCtrlGeneral::OnVScroll(UINT code, UINT pos, CScrollBar *pscroll)
- {
- CDialog::OnVScroll(code, pos, pscroll);
- if (m_bInitialized)
- {
- CSliderCtrl* pSlider = (CSliderCtrl*) pscroll;
- if (pSlider == &m_SliderTempo)
- {
- const TEMPO tempo = SliderToTempo(m_SliderTempo.GetPos());
- if ((tempo >= m_sndFile.GetModSpecifications().GetTempoMin()) && (tempo <= m_sndFile.GetModSpecifications().GetTempoMax()) && (tempo != m_sndFile.m_nDefaultTempo))
- {
- m_sndFile.m_nDefaultTempo = m_sndFile.m_PlayState.m_nMusicTempo = tempo;
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(nullptr, GeneralHint().General(), this);
- m_EditTempo.SetTempoValue(tempo);
- }
- }
- else if (pSlider == &m_SliderGlobalVol)
- {
- const UINT gv = MAX_SLIDER_GLOBAL_VOL - m_SliderGlobalVol.GetPos();
- if ((gv >= 0) && (gv <= MAX_SLIDER_GLOBAL_VOL) && (gv != m_sndFile.m_nDefaultGlobalVolume))
- {
- m_sndFile.m_PlayState.m_nGlobalVolume = gv;
- m_sndFile.m_nDefaultGlobalVolume = gv;
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(nullptr, GeneralHint().General(), this);
- SetDlgItemInt(IDC_EDIT_GLOBALVOL, m_sndFile.m_nDefaultGlobalVolume / GetGlobalVolumeFactor(), FALSE);
- }
- }
- else if (pSlider == &m_SliderSamplePreAmp)
- {
- const UINT spa = MAX_SLIDER_SAMPLE_VOL - m_SliderSamplePreAmp.GetPos();
- if ((spa >= 0) && (spa <= MAX_SLIDER_SAMPLE_VOL) && (spa != m_sndFile.m_nSamplePreAmp))
- {
- m_sndFile.m_nSamplePreAmp = spa;
- if(m_sndFile.GetType() != MOD_TYPE_MOD)
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(nullptr, GeneralHint().General(), this);
- SetDlgItemInt(IDC_EDIT_SAMPLEPA, m_sndFile.m_nSamplePreAmp, FALSE);
- }
- }
- else if (pSlider == &m_SliderVSTiVol)
- {
- const UINT vv = MAX_SLIDER_VSTI_VOL - m_SliderVSTiVol.GetPos();
- if ((vv >= 0) && (vv <= MAX_SLIDER_VSTI_VOL) && (vv != m_sndFile.m_nVSTiVolume))
- {
- m_sndFile.m_nVSTiVolume = vv;
- m_sndFile.RecalculateGainForAllPlugs();
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(nullptr, GeneralHint().General(), this);
- SetDlgItemInt(IDC_EDIT_VSTIVOL, m_sndFile.m_nVSTiVolume, FALSE);
- }
- }
- else if(pSlider == (CSliderCtrl*)&m_SpinTempo)
- {
- int pos32 = m_SpinTempo.GetPos32();
- if(pos32 != 0)
- {
- TEMPO newTempo;
- if(m_sndFile.GetModSpecifications().hasFractionalTempo)
- {
- pos32 *= TEMPO::fractFact;
- if(CMainFrame::GetMainFrame()->GetInputHandler()->CtrlPressed())
- pos32 /= 100;
- else if(CMainFrame::GetMainFrame()->GetInputHandler()->ShiftPressed())
- pos32 /= 10;
- newTempo.SetRaw(pos32);
- } else
- {
- newTempo = TEMPO(pos32, 0);
- }
- newTempo += m_sndFile.m_nDefaultTempo;
- Limit(newTempo, m_tempoMin, m_tempoMax);
- m_sndFile.m_nDefaultTempo = m_sndFile.m_PlayState.m_nMusicTempo = newTempo;
- m_modDoc.SetModified();
- LockControls();
- m_modDoc.UpdateAllViews(nullptr, GeneralHint().General(), this);
- UnlockControls();
- m_SliderTempo.SetPos(TempoToSlider(newTempo));
- m_EditTempo.SetTempoValue(newTempo);
- }
- m_SpinTempo.SetPos(0);
- }
- }
- }
- void CCtrlGeneral::OnTitleChanged()
- {
- if (!m_EditTitle.m_hWnd || !m_EditTitle.GetModify()) return;
- CString title;
- m_EditTitle.GetWindowText(title);
- if(m_sndFile.SetTitle(mpt::ToCharset(m_sndFile.GetCharsetInternal(), title)))
- {
- m_EditTitle.SetModify(FALSE);
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(nullptr, GeneralHint().General(), this);
- }
- }
- void CCtrlGeneral::OnArtistChanged()
- {
- if (!m_EditArtist.m_hWnd || !m_EditArtist.GetModify()) return;
- mpt::ustring artist = GetWindowTextUnicode(m_EditArtist);
- if(artist != m_sndFile.m_songArtist)
- {
- m_EditArtist.SetModify(FALSE);
- m_sndFile.m_songArtist = artist;
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(NULL, GeneralHint().General(), this);
- }
- }
- void CCtrlGeneral::OnTempoChanged()
- {
- if (m_bInitialized && m_EditTempo.GetWindowTextLength() > 0)
- {
- TEMPO tempo = m_EditTempo.GetTempoValue();
- Limit(tempo, m_tempoMin, m_tempoMax);
- if(!m_sndFile.GetModSpecifications().hasFractionalTempo) tempo.Set(tempo.GetInt());
- if (tempo != m_sndFile.m_nDefaultTempo)
- {
- m_editsLocked = true;
- m_EditTempo.SetModify(FALSE);
- m_sndFile.m_nDefaultTempo = tempo;
- m_sndFile.m_PlayState.m_nMusicTempo = tempo;
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(nullptr, GeneralHint().General());
- m_editsLocked = false;
- }
- }
- }
- void CCtrlGeneral::OnSpeedChanged()
- {
- TCHAR s[16];
- if(m_bInitialized)
- {
- m_EditSpeed.GetWindowText(s, mpt::saturate_cast<int>(std::size(s)));
- if (s[0])
- {
- UINT n = ConvertStrTo<UINT>(s);
- n = Clamp(n, m_sndFile.GetModSpecifications().speedMin, m_sndFile.GetModSpecifications().speedMax);
- if (n != m_sndFile.m_nDefaultSpeed)
- {
- m_editsLocked = true;
- m_EditSpeed.SetModify(FALSE);
- m_sndFile.m_nDefaultSpeed = n;
- m_sndFile.m_PlayState.m_nMusicSpeed = n;
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(nullptr, GeneralHint().General(), this);
- // Update envelope grid view
- m_modDoc.UpdateAllViews(nullptr, InstrumentHint().Envelope(), this);
- m_editsLocked = false;
- }
- }
- }
- }
- void CCtrlGeneral::OnVSTiVolChanged()
- {
- TCHAR s[16];
- if (m_bInitialized)
- {
- m_EditVSTiVol.GetWindowText(s, mpt::saturate_cast<int>(std::size(s)));
- if (s[0])
- {
- UINT n = ConvertStrTo<UINT>(s);
- Limit(n, 0u, 2000u);
- if (n != m_sndFile.m_nVSTiVolume)
- {
- m_editsLocked = true;
- m_sndFile.m_nVSTiVolume = n;
- m_sndFile.RecalculateGainForAllPlugs();
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(nullptr, GeneralHint().General(), this);
- UpdateView(GeneralHint().General());
- m_editsLocked = false;
- }
- }
- }
- }
- void CCtrlGeneral::OnSamplePAChanged()
- {
- TCHAR s[16];
- if(m_bInitialized)
- {
- m_EditSamplePA.GetWindowText(s, mpt::saturate_cast<int>(std::size(s)));
- if (s[0])
- {
- UINT n = ConvertStrTo<UINT>(s);
- Limit(n, 0u, 2000u);
- if (n != m_sndFile.m_nSamplePreAmp)
- {
- m_editsLocked = true;
- m_sndFile.m_nSamplePreAmp = n;
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(nullptr, GeneralHint().General(), this);
- UpdateView(GeneralHint().General());
- m_editsLocked = false;
- }
- }
- }
- }
- void CCtrlGeneral::OnGlobalVolChanged()
- {
- TCHAR s[16];
- if(m_bInitialized)
- {
- m_EditGlobalVol.GetWindowText(s, mpt::saturate_cast<int>(std::size(s)));
- if (s[0])
- {
- UINT n = ConvertStrTo<ORDERINDEX>(s) * GetGlobalVolumeFactor();
- Limit(n, 0u, 256u);
- if (n != m_sndFile.m_nDefaultGlobalVolume)
- {
- m_editsLocked = true;
- m_EditGlobalVol.SetModify(FALSE);
- m_sndFile.m_nDefaultGlobalVolume = n;
- m_sndFile.m_PlayState.m_nGlobalVolume = n;
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(nullptr, GeneralHint().General(), this);
- UpdateView(GeneralHint().General());
- m_editsLocked = false;
- }
- }
- }
- }
- void CCtrlGeneral::OnRestartPosChanged()
- {
- if(!m_bInitialized)
- return;
- TCHAR s[32];
- m_EditRestartPos.GetWindowText(s, mpt::saturate_cast<int>(std::size(s)));
- if(!s[0])
- return;
- ORDERINDEX n = ConvertStrTo<ORDERINDEX>(s);
- LimitMax(n, m_sndFile.Order().GetLastIndex());
- while(n > 0 && n < m_sndFile.Order().GetLastIndex() && !m_sndFile.Order().IsValidPat(n))
- n++;
- if(n == m_sndFile.Order().GetRestartPos())
- return;
-
- m_EditRestartPos.SetModify(FALSE);
- m_sndFile.Order().SetRestartPos(n);
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(nullptr, SequenceHint(m_sndFile.Order.GetCurrentSequenceIndex()).RestartPos(), this);
- }
- void CCtrlGeneral::OnRestartPosDone()
- {
- if(m_bInitialized)
- SetDlgItemInt(IDC_EDIT_RESTARTPOS, m_sndFile.Order().GetRestartPos());
- }
- void CCtrlGeneral::OnSongProperties()
- {
- m_modDoc.OnSongProperties();
- }
- void CCtrlGeneral::OnLoopSongChanged()
- {
- m_modDoc.SetLoopSong(IsDlgButtonChecked(IDC_CHECK_LOOPSONG) != BST_UNCHECKED);
- }
- LRESULT CCtrlGeneral::OnUpdatePosition(WPARAM, LPARAM lParam)
- {
- Notification *pnotify = (Notification *)lParam;
- if (pnotify)
- {
- m_VuMeterLeft.SetVuMeter(pnotify->masterVUout[0] & (~Notification::ClipVU), pnotify->type[Notification::Stop]);
- m_VuMeterRight.SetVuMeter(pnotify->masterVUout[1] & (~Notification::ClipVU), pnotify->type[Notification::Stop]);
- }
- return 0;
- }
- BOOL CCtrlGeneral::GetToolTipText(UINT uId, LPTSTR pszText)
- {
- const TCHAR moreRecentMixModeNote[] = _T("Use a more recent mixmode to see dB offsets.");
- if ((pszText) && (uId))
- {
- const bool displayDBValues = m_sndFile.GetPlayConfig().getDisplayDBValues();
- const CWnd *wnd = GetDlgItem(uId);
- const bool isEnabled = wnd ? (wnd->IsWindowEnabled() != FALSE) : true; // nullptr check is for a Wine bug workaround (https://bugs.openmpt.org/view.php?id=1553)
- mpt::tstring notAvailable;
- if(!isEnabled)
- notAvailable = MPT_TFORMAT("Feature is not available in the {} format.")(mpt::ToWin(mpt::Charset::ASCII, mpt::ToUpperCaseAscii(m_sndFile.GetModSpecifications().fileExtension)));
- switch(uId)
- {
- case IDC_BUTTON_MODTYPE:
- _tcscpy(pszText, _T("Song Properties"));
- {
- const auto keyText = CMainFrame::GetInputHandler()->m_activeCommandSet->GetKeyTextFromCommand(kcViewSongProperties, 0);
- if (!keyText.IsEmpty())
- _tcscat(pszText, MPT_TFORMAT(" ({})")(keyText).c_str());
- }
- return TRUE;
- case IDC_BUTTON1:
- if(isEnabled)
- _tcscpy(pszText, _T("Click button multiple times to tap in the desired tempo."));
- else
- _tcscpy(pszText, notAvailable.c_str());
- return TRUE;
- case IDC_SLIDER_SAMPLEPREAMP:
- _tcscpy(pszText, displayDBValues ? CModDoc::LinearToDecibels(m_sndFile.m_nSamplePreAmp, m_sndFile.GetPlayConfig().getNormalSamplePreAmp()).GetString() : moreRecentMixModeNote);
- return TRUE;
- case IDC_SLIDER_VSTIVOL:
- if(isEnabled)
- _tcscpy(pszText, displayDBValues ? CModDoc::LinearToDecibels(m_sndFile.m_nVSTiVolume, m_sndFile.GetPlayConfig().getNormalVSTiVol()).GetString() : moreRecentMixModeNote);
- else
- _tcscpy(pszText, notAvailable.c_str());
- return TRUE;
- case IDC_SLIDER_GLOBALVOL:
- if(isEnabled)
- _tcscpy(pszText, displayDBValues ? CModDoc::LinearToDecibels(m_sndFile.m_PlayState.m_nGlobalVolume, m_sndFile.GetPlayConfig().getNormalGlobalVol()).GetString() : moreRecentMixModeNote);
- else
- _tcscpy(pszText, notAvailable.c_str());
- return TRUE;
- case IDC_SLIDER_SONGTEMPO:
- case IDC_EDIT_ARTIST:
- case IDC_EDIT_TEMPO:
- case IDC_EDIT_SPEED:
- case IDC_EDIT_RESTARTPOS:
- case IDC_EDIT_GLOBALVOL:
- case IDC_EDIT_VSTIVOL:
- if(isEnabled)
- break;
- _tcscpy(pszText, notAvailable.c_str());
- return TRUE;
- }
- }
- return FALSE;
-
- }
- void CCtrlGeneral::OnEnSetfocusEditSongtitle()
- {
- m_EditTitle.SetLimitText(m_sndFile.GetModSpecifications().modNameLengthMax);
- }
- void CCtrlGeneral::OnResamplingChanged()
- {
- int sel = m_CbnResampling.GetCurSel();
- if(sel >= 0)
- {
- m_sndFile.m_nResampling = static_cast<ResamplingMode>(m_CbnResampling.GetItemData(sel));
- if(m_sndFile.GetModSpecifications().hasDefaultResampling)
- {
- m_modDoc.SetModified();
- m_modDoc.UpdateAllViews(nullptr, GeneralHint().General(), this);
- }
- }
- }
- ////////////////////////////////////////////////////////////////////////////////
- //
- // CVuMeter
- //
- BEGIN_MESSAGE_MAP(CVuMeter, CWnd)
- ON_WM_PAINT()
- END_MESSAGE_MAP()
- void CVuMeter::OnPaint()
- {
- CRect rect;
- CPaintDC dc(this);
- GetClientRect(&rect);
- dc.FillSolidRect(rect.left, rect.top, rect.Width(), rect.Height(), RGB(0,0,0));
- m_lastDisplayedLevel = -1;
- DrawVuMeter(dc, true);
- }
- void CVuMeter::SetVuMeter(int level, bool force)
- {
- level >>= 8;
- if (level != m_lastLevel)
- {
- DWORD curTime = timeGetTime();
- if(curTime - m_lastVuUpdateTime >= TrackerSettings::Instance().VuMeterUpdateInterval || force)
- {
- m_lastLevel = level;
- CClientDC dc(this);
- DrawVuMeter(dc);
- m_lastVuUpdateTime = curTime;
- }
- }
- }
- void CVuMeter::DrawVuMeter(CDC &dc, bool /*redraw*/)
- {
- CRect rect;
- GetClientRect(&rect);
- int vu = (m_lastLevel * (rect.bottom-rect.top)) >> 8;
- int cy = rect.bottom - rect.top;
- if (cy < 1) cy = 1;
- for (int ry=rect.bottom-1; ry>rect.top; ry-=2)
- {
- int y0 = rect.bottom - ry;
- int n = Clamp((y0 * NUM_VUMETER_PENS) / cy, 0, NUM_VUMETER_PENS - 1);
- if (vu < y0)
- n += NUM_VUMETER_PENS;
- dc.FillSolidRect(rect.left, ry, rect.Width(), 1, CMainFrame::gcolrefVuMeter[n]);
- }
- m_lastDisplayedLevel = m_lastLevel;
- }
- OPENMPT_NAMESPACE_END
|