aboutsummaryrefslogtreecommitdiff
path: root/Src/external_dependencies/openmpt-trunk/mptrack/Globals.cpp
diff options
context:
space:
mode:
authorJean-Francois Mauguit <jfmauguit@mac.com>2024-09-24 09:03:25 -0400
committerGitHub <noreply@github.com>2024-09-24 09:03:25 -0400
commitbab614c421ed7ae329d26bf028c4a3b1d2450f5a (patch)
tree12f17f78986871dd2cfb0a56e5e93b545c1ae0d0 /Src/external_dependencies/openmpt-trunk/mptrack/Globals.cpp
parent4bde6044fddf053f31795b9eaccdd2a5a527d21f (diff)
parent20d28e80a5c861a9d5f449ea911ab75b4f37ad0d (diff)
downloadwinamp-bab614c421ed7ae329d26bf028c4a3b1d2450f5a.tar.gz
Merge pull request #5 from WinampDesktop/community
Merge to main
Diffstat (limited to 'Src/external_dependencies/openmpt-trunk/mptrack/Globals.cpp')
-rw-r--r--Src/external_dependencies/openmpt-trunk/mptrack/Globals.cpp843
1 files changed, 843 insertions, 0 deletions
diff --git a/Src/external_dependencies/openmpt-trunk/mptrack/Globals.cpp b/Src/external_dependencies/openmpt-trunk/mptrack/Globals.cpp
new file mode 100644
index 00000000..d59225b5
--- /dev/null
+++ b/Src/external_dependencies/openmpt-trunk/mptrack/Globals.cpp
@@ -0,0 +1,843 @@
+/*
+ * globals.cpp
+ * -----------
+ * Purpose: Implementation of various views of the tracker interface.
+ * Notes : (currently none)
+ * Authors: 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 "Moddoc.h"
+#include "Childfrm.h"
+#include "Globals.h"
+#include "Ctrl_gen.h"
+#include "Ctrl_pat.h"
+#include "Ctrl_smp.h"
+#include "Ctrl_ins.h"
+#include "Ctrl_com.h"
+#include "ImageLists.h"
+#include "../soundlib/mod_specifications.h"
+
+
+OPENMPT_NAMESPACE_BEGIN
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CModControlDlg
+
+BEGIN_MESSAGE_MAP(CModControlDlg, CDialog)
+ //{{AFX_MSG_MAP(CModControlDlg)
+ ON_WM_SIZE()
+#if !defined(MPT_BUILD_RETRO)
+ ON_MESSAGE(WM_DPICHANGED, &CModControlDlg::OnDPIChanged)
+#endif
+ ON_MESSAGE(WM_MOD_UNLOCKCONTROLS, &CModControlDlg::OnUnlockControls)
+ ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTW, 0, 0xFFFF, &CModControlDlg::OnToolTipText)
+ ON_NOTIFY_EX_RANGE(TTN_NEEDTEXTA, 0, 0xFFFF, &CModControlDlg::OnToolTipText)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+CModControlDlg::CModControlDlg(CModControlView &parent, CModDoc &document) : m_modDoc(document), m_sndFile(document.GetSoundFile()), m_parent(parent)
+{
+ m_bInitialized = FALSE;
+ m_hWndView = NULL;
+ m_nLockCount = 0;
+}
+
+
+CModControlDlg::~CModControlDlg()
+{
+ ASSERT(m_hWnd == NULL);
+}
+
+
+BOOL CModControlDlg::OnInitDialog()
+{
+ CDialog::OnInitDialog();
+ m_nDPIx = Util::GetDPIx(m_hWnd);
+ m_nDPIy = Util::GetDPIy(m_hWnd);
+ EnableToolTips(TRUE);
+ return TRUE;
+}
+
+
+LRESULT CModControlDlg::OnDPIChanged(WPARAM wParam, LPARAM)
+{
+ m_nDPIx = LOWORD(wParam);
+ m_nDPIy = HIWORD(wParam);
+ return 0;
+}
+
+
+void CModControlDlg::OnSize(UINT nType, int cx, int cy)
+{
+ CDialog::OnSize(nType, cx, cy);
+ if (((nType == SIZE_RESTORED) || (nType == SIZE_MAXIMIZED)) && (cx > 0) && (cy > 0))
+ {
+ RecalcLayout();
+ }
+}
+
+
+LRESULT CModControlDlg::OnModCtrlMsg(WPARAM wParam, LPARAM lParam)
+{
+ switch(wParam)
+ {
+ case CTRLMSG_SETVIEWWND:
+ m_hWndView = (HWND)lParam;
+ break;
+
+ case CTRLMSG_ACTIVATEPAGE:
+ OnActivatePage(lParam);
+ break;
+
+ case CTRLMSG_DEACTIVATEPAGE:
+ OnDeactivatePage();
+ break;
+
+ case CTRLMSG_SETFOCUS:
+ GetParentFrame()->SetActiveView(&m_parent);
+ SetFocus();
+ break;
+ }
+ return 0;
+}
+
+
+LRESULT CModControlDlg::SendViewMessage(UINT uMsg, LPARAM lParam) const
+{
+ if (m_hWndView) return ::SendMessage(m_hWndView, WM_MOD_VIEWMSG, uMsg, lParam);
+ return 0;
+}
+
+
+BOOL CModControlDlg::PostViewMessage(UINT uMsg, LPARAM lParam) const
+{
+ if (m_hWndView) return ::PostMessage(m_hWndView, WM_MOD_VIEWMSG, uMsg, lParam);
+ return FALSE;
+}
+
+
+INT_PTR CModControlDlg::OnToolHitTest(CPoint point, TOOLINFO* pTI) const
+{
+ INT_PTR nHit = CDialog::OnToolHitTest(point, pTI);
+ if ((nHit >= 0) && (pTI))
+ {
+ if ((pTI->lpszText == LPSTR_TEXTCALLBACK) && (pTI->hwnd == m_hWnd))
+ {
+ CFrameWnd *pMDIParent = GetParentFrame();
+ if (pMDIParent) pTI->hwnd = pMDIParent->m_hWnd;
+ }
+ }
+ return nHit;
+}
+
+
+BOOL CModControlDlg::OnToolTipText(UINT nID, NMHDR* pNMHDR, LRESULT* pResult)
+{
+ CChildFrame *pChildFrm = (CChildFrame *)GetParentFrame();
+ if (pChildFrm) return pChildFrm->OnToolTipText(nID, pNMHDR, pResult);
+ if (pResult) *pResult = 0;
+ return FALSE;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////
+// CModControlView
+
+BOOL CModTabCtrl::Create(DWORD dwStyle, const RECT& rect, CWnd* pParentWnd, UINT nID)
+{
+ CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
+ if (!pMainFrm) return FALSE;
+ if (!CTabCtrl::Create(dwStyle, rect, pParentWnd, nID)) return FALSE;
+ SendMessage(WM_SETFONT, (WPARAM)pMainFrm->GetGUIFont());
+ SetImageList(&pMainFrm->m_MiscIcons);
+ return TRUE;
+}
+
+
+BOOL CModTabCtrl::InsertItem(int nIndex, LPCTSTR pszText, LPARAM lParam, int iImage)
+{
+ TC_ITEM tci;
+ tci.mask = TCIF_TEXT | TCIF_PARAM | TCIF_IMAGE;
+ tci.pszText = const_cast<LPTSTR>(pszText);
+ tci.lParam = lParam;
+ tci.iImage = iImage;
+ return CTabCtrl::InsertItem(nIndex, &tci);
+}
+
+
+LPARAM CModTabCtrl::GetItemData(int nIndex)
+{
+ TC_ITEM tci;
+ tci.mask = TCIF_PARAM;
+ tci.lParam = 0;
+ if (!GetItem(nIndex, &tci)) return 0;
+ return tci.lParam;
+}
+
+
+/////////////////////////////////////////////////////////////////////////////////
+// CModControlView
+
+IMPLEMENT_DYNCREATE(CModControlView, CView)
+
+BEGIN_MESSAGE_MAP(CModControlView, CView)
+ //{{AFX_MSG_MAP(CModControlView)
+ ON_WM_SIZE()
+ ON_WM_DESTROY()
+ ON_NOTIFY(TCN_SELCHANGE, IDC_TABCTRL1, &CModControlView::OnTabSelchange)
+ ON_MESSAGE(WM_MOD_ACTIVATEVIEW, &CModControlView::OnActivateModView)
+ ON_MESSAGE(WM_MOD_CTRLMSG, &CModControlView::OnModCtrlMsg)
+ ON_MESSAGE(WM_MOD_GETTOOLTIPTEXT, &CModControlView::OnGetToolTipText)
+ ON_COMMAND(ID_EDIT_CUT, &CModControlView::OnEditCut)
+ ON_COMMAND(ID_EDIT_COPY, &CModControlView::OnEditCopy)
+ ON_COMMAND(ID_EDIT_PASTE, &CModControlView::OnEditPaste)
+ ON_COMMAND(ID_EDIT_MIXPASTE, &CModControlView::OnEditMixPaste)
+ ON_COMMAND(ID_EDIT_MIXPASTE_ITSTYLE, &CModControlView::OnEditMixPasteITStyle)
+ ON_COMMAND(ID_EDIT_FIND, &CModControlView::OnEditFind)
+ ON_COMMAND(ID_EDIT_FINDNEXT, &CModControlView::OnEditFindNext)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+CModControlView::CModControlView()
+{
+ MemsetZero(m_Pages);
+ m_nActiveDlg = -1;
+ m_nInstrumentChanged = -1;
+ m_hWndView = NULL;
+ m_hWndMDI = NULL;
+}
+
+
+BOOL CModControlView::PreCreateWindow(CREATESTRUCT& cs)
+{
+ return CView::PreCreateWindow(cs);
+}
+
+
+void CModControlView::OnInitialUpdate() // called first time after construct
+{
+ CView::OnInitialUpdate();
+ CRect rect;
+
+ CChildFrame *pParentFrame = (CChildFrame *)GetParentFrame();
+ if (pParentFrame) m_hWndView = pParentFrame->GetHwndView();
+ GetClientRect(&rect);
+ m_TabCtrl.Create(WS_CHILD|WS_VISIBLE|TCS_FOCUSNEVER|TCS_FORCELABELLEFT, rect, this, IDC_TABCTRL1);
+ UpdateView(UpdateHint().ModType());
+ SetActivePage(0);
+}
+
+
+void CModControlView::OnSize(UINT nType, int cx, int cy)
+{
+ CView::OnSize(nType, cx, cy);
+ if (((nType == SIZE_RESTORED) || (nType == SIZE_MAXIMIZED)) && (cx > 0) && (cy > 0))
+ {
+ RecalcLayout();
+ }
+}
+
+
+void CModControlView::RecalcLayout()
+{
+ CRect rcClient;
+
+ if (m_TabCtrl.m_hWnd == NULL) return;
+ GetClientRect(&rcClient);
+ if ((m_nActiveDlg >= 0) && (m_nActiveDlg < MAX_PAGES) && (m_Pages[m_nActiveDlg]))
+ {
+ CWnd *pDlg = m_Pages[m_nActiveDlg];
+ CRect rect = rcClient;
+ m_TabCtrl.AdjustRect(FALSE, &rect);
+ HDWP hdwp = BeginDeferWindowPos(2);
+ DeferWindowPos(hdwp, m_TabCtrl.m_hWnd, NULL, rcClient.left, rcClient.top, rcClient.Width(), rcClient.Height(), SWP_NOZORDER);
+ DeferWindowPos(hdwp, pDlg->m_hWnd, NULL, rect.left, rect.top, rect.Width(), rect.Height(), SWP_NOZORDER);
+ EndDeferWindowPos(hdwp);
+ } else
+ {
+ m_TabCtrl.MoveWindow(&rcClient);
+ }
+}
+
+
+void CModControlView::OnUpdate(CView *, LPARAM lHint, CObject *pHint)
+{
+ UpdateView(UpdateHint::FromLPARAM(lHint), pHint);
+}
+
+
+void CModControlView::ForceRefresh()
+{
+ SetActivePage(GetActivePage());
+}
+
+
+BOOL CModControlView::SetActivePage(int nIndex, LPARAM lParam)
+{
+ CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
+ CModControlDlg *pDlg = NULL;
+
+
+ if (nIndex == -1) nIndex = m_TabCtrl.GetCurSel();
+
+ const UINT nID = static_cast<UINT>(m_TabCtrl.GetItemData(nIndex));
+ if(nID == 0) return FALSE;
+
+ switch(nID)
+ {
+ //rewbs.graph
+ case IDD_CONTROL_GRAPH:
+ nIndex = 5;
+ break;
+ //end rewbs.graph
+ case IDD_CONTROL_COMMENTS:
+ nIndex = 4;
+ break;
+ case IDD_CONTROL_GLOBALS:
+ nIndex = 0;
+ break;
+ case IDD_CONTROL_PATTERNS:
+ nIndex = 1;
+ break;
+ case IDD_CONTROL_SAMPLES:
+ nIndex = 2;
+ break;
+ case IDD_CONTROL_INSTRUMENTS:
+ nIndex = 3;
+ break;
+ default:
+ return FALSE;
+ }
+
+ if ((nIndex < 0) || (nIndex >= MAX_PAGES) || (!pMainFrm)) return FALSE;
+
+ if (m_Pages[m_nActiveDlg])
+ m_Pages[m_nActiveDlg]->GetSplitPosRef() = ((CChildFrame *)GetParentFrame())->GetSplitterHeight();
+
+ if (nIndex == m_nActiveDlg)
+ {
+ pDlg = m_Pages[m_nActiveDlg];
+ PostMessage(WM_MOD_CTRLMSG, CTRLMSG_ACTIVATEPAGE, lParam);
+ return TRUE;
+ }
+ if ((m_nActiveDlg >= 0) && (m_nActiveDlg < MAX_PAGES))
+ {
+ if (m_Pages[m_nActiveDlg])
+ {
+ OnModCtrlMsg(CTRLMSG_DEACTIVATEPAGE, 0);
+ m_Pages[m_nActiveDlg]->ShowWindow(SW_HIDE);
+ }
+ m_nActiveDlg = -1;
+ }
+ if (m_Pages[nIndex]) //Ctrl window already created?
+ {
+ m_nActiveDlg = nIndex;
+ pDlg = m_Pages[nIndex];
+ } else //Ctrl window is not created yet - creating one.
+ {
+ MPT_ASSERT_ALWAYS(GetDocument() != nullptr);
+ switch(nID)
+ {
+ //rewbs.graph
+ case IDD_CONTROL_GRAPH:
+ //pDlg = new CCtrlGraph();
+ break;
+ //end rewbs.graph
+ case IDD_CONTROL_COMMENTS:
+ pDlg = new CCtrlComments(*this, *GetDocument());
+ break;
+ case IDD_CONTROL_GLOBALS:
+ pDlg = new CCtrlGeneral(*this, *GetDocument());
+ break;
+ case IDD_CONTROL_PATTERNS:
+ pDlg = new CCtrlPatterns(*this, *GetDocument());
+ break;
+ case IDD_CONTROL_SAMPLES:
+ pDlg = new CCtrlSamples(*this, *GetDocument());
+ break;
+ case IDD_CONTROL_INSTRUMENTS:
+ pDlg = new CCtrlInstruments(*this, *GetDocument());
+ break;
+ default:
+ return FALSE;
+ }
+ if (!pDlg) return FALSE;
+ pDlg->SetViewWnd(m_hWndView);
+ BOOL bStatus = pDlg->Create(nID, this);
+ if(bStatus == 0) // Creation failed.
+ {
+ delete pDlg;
+ return FALSE;
+ }
+ m_nActiveDlg = nIndex;
+ m_Pages[nIndex] = pDlg;
+ }
+ RecalcLayout();
+ pMainFrm->SetUserText(_T(""));
+ pMainFrm->SetInfoText(_T(""));
+ pMainFrm->SetXInfoText(_T("")); //rewbs.xinfo
+ pDlg->ShowWindow(SW_SHOW);
+ ((CChildFrame *)GetParentFrame())->SetSplitterHeight(pDlg->GetSplitPosRef());
+ if (m_hWndMDI) ::PostMessage(m_hWndMDI, WM_MOD_CHANGEVIEWCLASS, (WPARAM)lParam, (LPARAM)pDlg);
+ return TRUE;
+}
+
+
+void CModControlView::OnDestroy()
+{
+ m_nActiveDlg = -1;
+ for (UINT nIndex=0; nIndex<MAX_PAGES; nIndex++)
+ {
+ CModControlDlg *pDlg = m_Pages[nIndex];
+ if (pDlg)
+ {
+ m_Pages[nIndex] = NULL;
+ pDlg->DestroyWindow();
+ delete pDlg;
+ }
+ }
+ CView::OnDestroy();
+}
+
+
+void CModControlView::UpdateView(UpdateHint lHint, CObject *pObject)
+{
+ CWnd *pActiveDlg = NULL;
+ CModDoc *pDoc = GetDocument();
+ if (!pDoc) return;
+ // Module type changed: update tabs
+ if (lHint.GetType()[HINT_MODTYPE])
+ {
+ UINT nCount = 4;
+ UINT mask = 1 | 2 | 4 | 16;
+
+ if(pDoc->GetSoundFile().GetModSpecifications().instrumentsMax > 0 || pDoc->GetNumInstruments() > 0)
+ {
+ mask |= 8;
+ //mask |= 32; //rewbs.graph
+ nCount++;
+ }
+ if (nCount != (UINT)m_TabCtrl.GetItemCount())
+ {
+ UINT count = 0;
+ if ((m_nActiveDlg >= 0) && (m_nActiveDlg < MAX_PAGES))
+ {
+ pActiveDlg = m_Pages[m_nActiveDlg];
+ if (pActiveDlg) pActiveDlg->ShowWindow(SW_HIDE);
+ }
+ m_TabCtrl.DeleteAllItems();
+ if (mask & 1) m_TabCtrl.InsertItem(count++, _T("General"), IDD_CONTROL_GLOBALS, IMAGE_GENERAL);
+ if (mask & 2) m_TabCtrl.InsertItem(count++, _T("Patterns"), IDD_CONTROL_PATTERNS, IMAGE_PATTERNS);
+ if (mask & 4) m_TabCtrl.InsertItem(count++, _T("Samples"), IDD_CONTROL_SAMPLES, IMAGE_SAMPLES);
+ if (mask & 8) m_TabCtrl.InsertItem(count++, _T("Instruments"), IDD_CONTROL_INSTRUMENTS, IMAGE_INSTRUMENTS);
+ //if (mask & 32) m_TabCtrl.InsertItem(count++, _T("Graph"), IDD_CONTROL_GRAPH, IMAGE_GRAPH); //rewbs.graph
+ if (mask & 16) m_TabCtrl.InsertItem(count++, _T("Comments"), IDD_CONTROL_COMMENTS, IMAGE_COMMENTS);
+ }
+ }
+ // Update child dialogs
+ for (UINT nIndex=0; nIndex<MAX_PAGES; nIndex++)
+ {
+ CModControlDlg *pDlg = m_Pages[nIndex];
+ if ((pDlg) && (pObject != pDlg)) pDlg->UpdateView(UpdateHint(lHint), pObject);
+ }
+ // Restore the displayed child dialog
+ if (pActiveDlg) pActiveDlg->ShowWindow(SW_SHOW);
+}
+
+
+void CModControlView::OnTabSelchange(NMHDR*, LRESULT* pResult)
+{
+ SetActivePage(m_TabCtrl.GetCurSel());
+ if (pResult) *pResult = 0;
+}
+
+
+LRESULT CModControlView::OnActivateModView(WPARAM nIndex, LPARAM lParam)
+{
+ if(::GetActiveWindow() != CMainFrame::GetMainFrame()->m_hWnd)
+ {
+ // If we are in a dialog (e.g. Amplify Sample), do not allow to switch to a different tab. Otherwise, watch the tracker crash!
+ return 0;
+ }
+
+ if (m_TabCtrl.m_hWnd)
+ {
+ if (nIndex < 100)
+ {
+ m_TabCtrl.SetCurSel(static_cast<int>(nIndex));
+ SetActivePage(static_cast<int>(nIndex), lParam);
+ } else
+ // Might be a dialog id IDD_XXXX
+ {
+ int nItems = m_TabCtrl.GetItemCount();
+ for (int i=0; i<nItems; i++)
+ {
+ if ((WPARAM)m_TabCtrl.GetItemData(i) == nIndex)
+ {
+ m_TabCtrl.SetCurSel(i);
+ SetActivePage(i, lParam);
+ break;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+
+LRESULT CModControlView::OnModCtrlMsg(WPARAM wParam, LPARAM lParam)
+{
+ if ((m_nActiveDlg >= 0) && (m_nActiveDlg < MAX_PAGES))
+ {
+ CModControlDlg *pActiveDlg = m_Pages[m_nActiveDlg];
+ if (pActiveDlg)
+ {
+ switch(wParam)
+ {
+ case CTRLMSG_SETVIEWWND:
+ {
+ m_hWndView = (HWND)lParam;
+ for (UINT i=0; i<MAX_PAGES; i++)
+ {
+ if (m_Pages[i]) m_Pages[i]->SetViewWnd(m_hWndView);
+ }
+ }
+ break;
+ }
+ return pActiveDlg->OnModCtrlMsg(wParam, lParam);
+ }
+ }
+ return 0;
+}
+
+
+LRESULT CModControlView::OnGetToolTipText(WPARAM uId, LPARAM pszText)
+{
+ if ((m_nActiveDlg >= 0) && (m_nActiveDlg < MAX_PAGES))
+ {
+ CModControlDlg *pActiveDlg = m_Pages[m_nActiveDlg];
+ if (pActiveDlg) return (LRESULT)pActiveDlg->GetToolTipText(static_cast<UINT>(uId), (LPTSTR)pszText);
+ }
+ return 0;
+}
+
+
+void CModControlView::SampleChanged(SAMPLEINDEX smp)
+{
+ const CModDoc *modDoc = GetDocument();
+ if(modDoc && modDoc->GetNumInstruments())
+ {
+ INSTRUMENTINDEX k = static_cast<INSTRUMENTINDEX>(GetInstrumentChange());
+ if(!modDoc->IsChildSample(k, smp))
+ {
+ INSTRUMENTINDEX nins = modDoc->FindSampleParent(smp);
+ if(nins != INSTRUMENTINDEX_INVALID)
+ {
+ InstrumentChanged(nins);
+ }
+ }
+ } else
+ {
+ InstrumentChanged(smp);
+ }
+}
+
+
+//////////////////////////////////////////////////////////////////
+// CModScrollView
+
+#ifndef WM_MOUSEHWHEEL
+#define WM_MOUSEHWHEEL 0x20E // Only available on Vista and newer
+#endif
+
+IMPLEMENT_SERIAL(CModScrollView, CScrollView, 0)
+BEGIN_MESSAGE_MAP(CModScrollView, CScrollView)
+ //{{AFX_MSG_MAP(CModScrollView)
+ ON_WM_DESTROY()
+ ON_WM_MOUSEWHEEL()
+ ON_WM_MOUSEHWHEEL()
+#if !defined(MPT_BUILD_RETRO)
+ ON_MESSAGE(WM_DPICHANGED, &CModScrollView::OnDPIChanged)
+#endif
+ ON_MESSAGE(WM_MOD_VIEWMSG, &CModScrollView::OnReceiveModViewMsg)
+ ON_MESSAGE(WM_MOD_DRAGONDROPPING, &CModScrollView::OnDragonDropping)
+ ON_MESSAGE(WM_MOD_UPDATEPOSITION, &CModScrollView::OnUpdatePosition)
+ //}}AFX_MSG_MAP
+END_MESSAGE_MAP()
+
+
+LRESULT CModScrollView::SendCtrlMessage(UINT uMsg, LPARAM lParam) const
+{
+ if (m_hWndCtrl) return ::SendMessage(m_hWndCtrl, WM_MOD_CTRLMSG, uMsg, lParam);
+ return 0;
+}
+
+
+void CModScrollView::SendCtrlCommand(int id) const
+{
+ ::SendMessage(m_hWndCtrl, WM_COMMAND, id, 0);
+}
+
+
+BOOL CModScrollView::PostCtrlMessage(UINT uMsg, LPARAM lParam) const
+{
+ if (m_hWndCtrl) return ::PostMessage(m_hWndCtrl, WM_MOD_CTRLMSG, uMsg, lParam);
+ return FALSE;
+}
+
+
+LRESULT CModScrollView::OnReceiveModViewMsg(WPARAM wParam, LPARAM lParam)
+{
+ return OnModViewMsg(wParam, lParam);
+}
+
+
+void CModScrollView::OnUpdate(CView* pView, LPARAM lHint, CObject*pHint)
+{
+ if (pView != this) UpdateView(UpdateHint::FromLPARAM(lHint), pHint);
+}
+
+
+LRESULT CModScrollView::OnModViewMsg(WPARAM wParam, LPARAM lParam)
+{
+ switch(wParam)
+ {
+ case VIEWMSG_SETCTRLWND:
+ m_hWndCtrl = (HWND)lParam;
+ break;
+
+ case VIEWMSG_SETFOCUS:
+ case VIEWMSG_SETACTIVE:
+ GetParentFrame()->SetActiveView(this);
+ SetFocus();
+ break;
+ }
+ return 0;
+}
+
+
+void CModScrollView::OnInitialUpdate()
+{
+ CScrollView::OnInitialUpdate();
+ m_nDPIx = Util::GetDPIx(m_hWnd);
+ m_nDPIy = Util::GetDPIy(m_hWnd);
+}
+
+
+LRESULT CModScrollView::OnDPIChanged(WPARAM wParam, LPARAM)
+{
+ m_nDPIx = LOWORD(wParam);
+ m_nDPIy = HIWORD(wParam);
+ return 0;
+}
+
+
+void CModScrollView::UpdateIndicator(LPCTSTR lpszText)
+{
+ CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
+ if (pMainFrm) pMainFrm->SetUserText((lpszText) ? lpszText : _T(""));
+}
+
+
+BOOL CModScrollView::OnMouseWheel(UINT fFlags, short zDelta, CPoint point)
+{
+ // we don't handle anything but scrolling just now
+ if (fFlags & (MK_SHIFT | MK_CONTROL)) return FALSE;
+
+ //if the parent is a splitter, it will handle the message
+ //if (GetParentSplitter(this, TRUE)) return FALSE;
+
+ // we can't get out of it--perform the scroll ourselves
+ return DoMouseWheel(fFlags, zDelta, point);
+}
+
+
+void CModScrollView::OnMouseHWheel(UINT fFlags, short zDelta, CPoint point)
+{
+ // we don't handle anything but scrolling just now
+ if (fFlags & (MK_SHIFT | MK_CONTROL))
+ {
+ CScrollView::OnMouseHWheel(fFlags, zDelta, point);
+ return;
+ }
+
+ if (OnScrollBy(CSize(zDelta * m_lineDev.cx / WHEEL_DELTA, 0), TRUE))
+ UpdateWindow();
+}
+
+
+void CModScrollView::OnDestroy()
+{
+ CModDoc *pModDoc = GetDocument();
+ CMainFrame *pMainFrm = CMainFrame::GetMainFrame();
+ if ((pMainFrm) && (pModDoc))
+ {
+ if (pMainFrm->GetFollowSong(pModDoc) == m_hWnd)
+ {
+ pModDoc->SetNotifications(Notification::Default);
+ pModDoc->SetFollowWnd(NULL);
+ }
+ if (pMainFrm->GetMidiRecordWnd() == m_hWnd)
+ {
+ pMainFrm->SetMidiRecordWnd(NULL);
+ }
+ }
+ CScrollView::OnDestroy();
+}
+
+
+LRESULT CModScrollView::OnUpdatePosition(WPARAM, LPARAM lParam)
+{
+ Notification *pnotify = (Notification *)lParam;
+ if (pnotify) return OnPlayerNotify(pnotify);
+ return 0;
+}
+
+
+BOOL CModScrollView::OnScroll(UINT nScrollCode, UINT nPos, BOOL bDoScroll)
+{
+ SCROLLINFO info;
+ if(LOBYTE(nScrollCode) == SB_THUMBTRACK)
+ {
+ if(GetScrollInfo(SB_HORZ, &info, SIF_TRACKPOS))
+ nPos = info.nTrackPos;
+ m_nScrollPosX = nPos;
+ } else if(HIBYTE(nScrollCode) == SB_THUMBTRACK)
+ {
+ if(GetScrollInfo(SB_VERT, &info, SIF_TRACKPOS))
+ nPos = info.nTrackPos;
+ m_nScrollPosY = nPos;
+ }
+ return CScrollView::OnScroll(nScrollCode, nPos, bDoScroll);
+}
+
+
+BOOL CModScrollView::OnScrollBy(CSize sizeScroll, BOOL bDoScroll)
+{
+ BOOL ret = CScrollView::OnScrollBy(sizeScroll, bDoScroll);
+ if(ret)
+ {
+ SCROLLINFO info;
+ if(sizeScroll.cx)
+ {
+ if(GetScrollInfo(SB_HORZ, &info, SIF_POS))
+ m_nScrollPosX = info.nPos;
+ }
+ if(sizeScroll.cy)
+ {
+ if(GetScrollInfo(SB_VERT, &info, SIF_POS))
+ m_nScrollPosY = info.nPos;
+ }
+ }
+ return ret;
+}
+
+
+int CModScrollView::SetScrollPos(int nBar, int nPos, BOOL bRedraw)
+{
+ if(nBar == SB_HORZ)
+ m_nScrollPosX = nPos;
+ else if(nBar == SB_VERT)
+ m_nScrollPosY = nPos;
+ return CScrollView::SetScrollPos(nBar, nPos, bRedraw);
+}
+
+
+void CModScrollView::SetScrollSizes(int nMapMode, SIZE sizeTotal, const SIZE& sizePage, const SIZE& sizeLine)
+{
+ CScrollView::SetScrollSizes(nMapMode, sizeTotal, sizePage, sizeLine);
+ // Fix scroll positions
+ SCROLLINFO info;
+ if(GetScrollInfo(SB_HORZ, &info, SIF_POS))
+ m_nScrollPosX = info.nPos;
+ if(GetScrollInfo(SB_VERT, &info, SIF_POS))
+ m_nScrollPosY = info.nPos;
+}
+
+
+BOOL CModScrollView::OnGesturePan(CPoint ptFrom, CPoint ptTo)
+{
+ // On Windows 8 and later, panning with touch gestures does not generate sensible WM_*SCROLL messages.
+ // OnScrollBy is only ever called with a size of 0/0 in this case.
+ // WM_GESTURE on the other hand gives us sensible data to work with.
+ OnScrollBy(ptTo - ptFrom, TRUE);
+ return TRUE;
+}
+
+
+////////////////////////////////////////////////////////////////////////////
+// CModControlBar
+
+BEGIN_MESSAGE_MAP(CModControlBar, CToolBarCtrl)
+ ON_MESSAGE(WM_HELPHITTEST, &CModControlBar::OnHelpHitTest)
+END_MESSAGE_MAP()
+
+
+BOOL CModControlBar::Init(CImageList &icons, CImageList &disabledIcons)
+{
+ const int imgSize = Util::ScalePixels(16, m_hWnd), btnSizeX = Util::ScalePixels(26, m_hWnd), btnSizeY = Util::ScalePixels(24, m_hWnd);
+ SetButtonStructSize(sizeof(TBBUTTON));
+ SetBitmapSize(CSize(imgSize, imgSize));
+ SetButtonSize(CSize(btnSizeX, btnSizeY));
+
+ // Add bitmaps
+ SetImageList(&icons);
+ SetDisabledImageList(&disabledIcons);
+ UpdateStyle();
+ return TRUE;
+}
+
+
+BOOL CModControlBar::AddButton(UINT nID, int iImage, UINT nStyle, UINT nState)
+{
+ TBBUTTON btn;
+
+ btn.iBitmap = iImage;
+ btn.idCommand = nID;
+ btn.fsStyle = (BYTE)nStyle;
+ btn.fsState = (BYTE)nState;
+ btn.dwData = 0;
+ btn.iString = 0;
+ return AddButtons(1, &btn);
+}
+
+
+void CModControlBar::UpdateStyle()
+{
+ if (m_hWnd)
+ {
+ LONG lStyleOld = GetWindowLong(m_hWnd, GWL_STYLE);
+ if (TrackerSettings::Instance().m_dwPatternSetup & PATTERN_FLATBUTTONS)
+ lStyleOld |= TBSTYLE_FLAT;
+ else
+ lStyleOld &= ~TBSTYLE_FLAT;
+ lStyleOld |= CCS_NORESIZE | CCS_NOPARENTALIGN | CCS_NODIVIDER | TBSTYLE_TOOLTIPS;
+ SetWindowLong(m_hWnd, GWL_STYLE, lStyleOld);
+ Invalidate();
+ }
+}
+
+
+LRESULT CModControlBar::OnHelpHitTest(WPARAM, LPARAM lParam)
+{
+ TBBUTTON tbbn;
+ POINT point;
+ point.x = GET_X_LPARAM(lParam);
+ point.y = GET_Y_LPARAM(lParam);
+ int ndx = HitTest(&point);
+ if ((ndx >= 0) && (GetButton(ndx, &tbbn)))
+ {
+ return HID_BASE_COMMAND + tbbn.idCommand;
+ }
+ return 0;
+}
+
+OPENMPT_NAMESPACE_END