844 lines
20 KiB
C++
844 lines
20 KiB
C++
/*
|
|
* 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
|