1
0

tuningRatioMapWnd.cpp 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. /*
  2. * tuningRatioMapWnd.cpp
  3. * ---------------------
  4. * Purpose: Alternative sample tuning configuration dialog - ratio map edit control.
  5. * Notes : (currently none)
  6. * Authors: OpenMPT Devs
  7. * The OpenMPT source code is released under the BSD license. Read LICENSE for more details.
  8. */
  9. #include "stdafx.h"
  10. #include "Mptrack.h"
  11. #include "Mainfrm.h"
  12. #include "../soundlib/tuning.h"
  13. #include "tuningRatioMapWnd.h"
  14. #include "TuningDialog.h"
  15. OPENMPT_NAMESPACE_BEGIN
  16. BEGIN_MESSAGE_MAP(CTuningRatioMapWnd, CStatic)
  17. ON_WM_PAINT()
  18. ON_WM_SETFOCUS()
  19. ON_WM_KILLFOCUS()
  20. ON_WM_LBUTTONDOWN()
  21. ON_WM_MOUSEWHEEL()
  22. END_MESSAGE_MAP()
  23. void CTuningRatioMapWnd::Init(CTuningDialog* const pParent, CTuning* const tuning)
  24. {
  25. m_pParent = pParent;
  26. m_pTuning = tuning;
  27. }
  28. void CTuningRatioMapWnd::OnPaint()
  29. {
  30. CPaintDC dc(this);
  31. if(!m_pTuning) return;
  32. CRect rcClient;
  33. GetClientRect(&rcClient);
  34. const auto colorText = GetSysColor(COLOR_WINDOWTEXT);
  35. const auto colorTextSel = GetSysColor(COLOR_HIGHLIGHTTEXT);
  36. const auto highlightBrush = GetSysColorBrush(COLOR_HIGHLIGHT), windowBrush = GetSysColorBrush(COLOR_WINDOW);
  37. auto oldFont = dc.SelectObject(CMainFrame::GetGUIFont());
  38. dc.SetBkMode(TRANSPARENT);
  39. if ((m_cxFont <= 0) || (m_cyFont <= 0))
  40. {
  41. CSize sz;
  42. sz = dc.GetTextExtent(_T("123456789"));
  43. m_cyFont = sz.cy + 2;
  44. m_cxFont = rcClient.right / 4;
  45. }
  46. dc.IntersectClipRect(&rcClient);
  47. if ((m_cxFont > 0) && (m_cyFont > 0))
  48. {
  49. const bool focus = (::GetFocus() == m_hWnd);
  50. CRect rect;
  51. NOTEINDEXTYPE nNotes = static_cast<NOTEINDEXTYPE>((rcClient.bottom + m_cyFont - 1) / m_cyFont);
  52. //if(!m_nNote) m_nNote = m_nNoteCentre;
  53. NOTEINDEXTYPE nPos = m_nNote - (nNotes/2);
  54. int ypaint = 0;
  55. for (int ynote=0; ynote<nNotes; ynote++, ypaint+=m_cyFont, nPos++)
  56. {
  57. // Note
  58. NOTEINDEXTYPE noteToDraw = nPos - m_nNoteCentre;
  59. const bool isValidNote = m_pTuning->IsValidNote(noteToDraw);
  60. rect.SetRect(0, ypaint, m_cxFont, ypaint + m_cyFont);
  61. const auto noteStr = isValidNote ? mpt::tfmt::val(noteToDraw) : mpt::tstring(_T("..."));
  62. DrawButtonRect(dc, &rect, noteStr.c_str(), FALSE, FALSE);
  63. // Mapped Note
  64. const bool highLight = focus && (nPos == (int)m_nNote);
  65. rect.left = rect.right;
  66. rect.right = m_cxFont*4-1;
  67. FillRect(dc, &rect, highLight ? highlightBrush : windowBrush);
  68. if(nPos == (int)m_nNote)
  69. {
  70. rect.InflateRect(-1, -1);
  71. dc.DrawFocusRect(&rect);
  72. rect.InflateRect(1, 1);
  73. }
  74. dc.SetTextColor(highLight ? colorTextSel : colorText);
  75. rect.SetRect(m_cxFont * 1, ypaint, m_cxFont * 2 - 1, ypaint + m_cyFont);
  76. dc.DrawText(mpt::ToCString(m_pTuning->GetNoteName(noteToDraw)), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX);
  77. rect.SetRect(m_cxFont * 2, ypaint, m_cxFont * 3 - 1, ypaint + m_cyFont);
  78. dc.DrawText(mpt::cfmt::flt(m_pTuning->GetRatio(noteToDraw), 6), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX);
  79. rect.SetRect(m_cxFont * 3, ypaint, m_cxFont * 4 - 1, ypaint + m_cyFont);
  80. dc.DrawText(mpt::cfmt::fix(std::log2(static_cast<double>(m_pTuning->GetRatio(noteToDraw))) * 1200.0, 1), -1, &rect, DT_SINGLELINE | DT_CENTER | DT_VCENTER | DT_NOPREFIX);
  81. }
  82. rect.SetRect(rcClient.left + m_cxFont * 4 - 1, rcClient.top, rcClient.left + m_cxFont * 4 + 3, ypaint);
  83. DrawButtonRect(dc, &rect, _T(""));
  84. if (ypaint < rcClient.bottom)
  85. {
  86. rect.SetRect(rcClient.left, ypaint, rcClient.right, rcClient.bottom);
  87. FillRect(dc, &rect, GetSysColorBrush(COLOR_BTNFACE));
  88. }
  89. }
  90. dc.SelectObject(oldFont);
  91. }
  92. void CTuningRatioMapWnd::OnSetFocus(CWnd *pOldWnd)
  93. {
  94. CWnd::OnSetFocus(pOldWnd);
  95. InvalidateRect(NULL, FALSE);
  96. }
  97. void CTuningRatioMapWnd::OnKillFocus(CWnd *pNewWnd)
  98. {
  99. CWnd::OnKillFocus(pNewWnd);
  100. InvalidateRect(NULL, FALSE);
  101. }
  102. BOOL CTuningRatioMapWnd::OnMouseWheel(UINT nFlags, short zDelta, CPoint pt)
  103. {
  104. NOTEINDEXTYPE note = static_cast<NOTEINDEXTYPE>(m_nNote - mpt::signum(zDelta));
  105. if(m_pTuning->IsValidNote(note - m_nNoteCentre))
  106. {
  107. m_nNote = note;
  108. InvalidateRect(NULL, FALSE);
  109. if(m_pParent)
  110. m_pParent->UpdateRatioMapEdits(GetShownCentre());
  111. }
  112. return CWnd::OnMouseWheel(nFlags, zDelta, pt);
  113. }
  114. void CTuningRatioMapWnd::OnLButtonDown(UINT, CPoint pt)
  115. {
  116. if ((pt.x >= m_cxFont) && (pt.x < m_cxFont*2))
  117. {
  118. InvalidateRect(NULL, FALSE);
  119. }
  120. if ((pt.x > m_cxFont*2) && (pt.x <= m_cxFont*3))
  121. {
  122. InvalidateRect(NULL, FALSE);
  123. }
  124. if ((pt.x >= 0) && (m_cyFont))
  125. {
  126. CRect rcClient;
  127. GetClientRect(&rcClient);
  128. int nNotes = (rcClient.bottom + m_cyFont - 1) / m_cyFont;
  129. const int n = (pt.y / m_cyFont) + m_nNote - (nNotes/2);
  130. const NOTEINDEXTYPE note = static_cast<NOTEINDEXTYPE>(n - m_nNoteCentre);
  131. if(m_pTuning->IsValidNote(note))
  132. {
  133. m_nNote = static_cast<NOTEINDEXTYPE>(n);
  134. InvalidateRect(NULL, FALSE);
  135. if(m_pParent)
  136. m_pParent->UpdateRatioMapEdits(GetShownCentre());
  137. }
  138. }
  139. SetFocus();
  140. }
  141. NOTEINDEXTYPE CTuningRatioMapWnd::GetShownCentre() const
  142. {
  143. return m_nNote - m_nNoteCentre;
  144. }
  145. OPENMPT_NAMESPACE_END