From 672e606b6d857e370ac75c076a1b2982e5bccd67 Mon Sep 17 00:00:00 2001 From: Kaz Kylheku Date: Sun, 15 Sep 2013 21:57:55 -0700 Subject: Converted Sekaiju 3.6 to Visual Studio 2008. --- src/EventListIndexScaleView.cpp | 454 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 454 insertions(+) create mode 100644 src/EventListIndexScaleView.cpp (limited to 'src/EventListIndexScaleView.cpp') diff --git a/src/EventListIndexScaleView.cpp b/src/EventListIndexScaleView.cpp new file mode 100644 index 0000000..20593e2 --- /dev/null +++ b/src/EventListIndexScaleView.cpp @@ -0,0 +1,454 @@ +//****************************************************************************** +// MIDIシーケンサーソフト『世界樹』 +// イベントリストインデックススケールビュークラス +// (C)2002-2013 おーぷんMIDIぷろじぇくと/くず +//****************************************************************************** + +/* This library is free software; you can redistribute it and/or */ +/* modify it under the terms of the GNU Lesser General Public */ +/* License as published by the Free Software Foundation; either */ +/* version 2.1 of the License, or (at your option) any later version. */ + +/* This library is distributed in the hope that it will be useful, */ +/* but WITHOUT ANY WARRANTY; without even the implied warranty of */ +/* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU */ +/* Lesser General Public License for more details. */ + +/* You should have received a copy of the GNU Lesser General Public */ +/* License along with this library; if not, write to the Free Software */ +/* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include "winver.h" +#include +#include +#include +#include "../../MIDIIO/MIDIIO.h" +#include "../../MIDIData/MIDIData.h" +#include "../../MIDIClock/MIDIClock.h" +#include "../../MIDIStatus/MIDIStatus.h" +#include "../../MIDIInstrument/MIDIInstrument.h" +#include "mousewheel.h" +#include "ColorfulComboBox.h" +#include "ColorfulCheckListBox.h" +#include "HistoryRecord.h" +#include "HistoryUnit.h" +#include "SekaijuApp.h" +#include "SekaijuDoc.h" +#include "SekaijuView.h" +#include "SekaijuToolBar.h" +#include "SekaijuStatusBar.h" +#include "ChildFrame.h" +#include "EventListFrame.h" +#include "EventListIndexScaleView.h" + +#ifdef _DEBUG +#define new DEBUG_NEW +#undef THIS_FILE +static char THIS_FILE[] = __FILE__; +#endif + + +IMPLEMENT_DYNCREATE (CEventListIndexScaleView, CSekaijuView) + +// メッセージマップ +BEGIN_MESSAGE_MAP (CEventListIndexScaleView, CSekaijuView) + ON_WM_CREATE () + ON_WM_KEYDOWN () + ON_WM_LBUTTONDOWN () + ON_WM_RBUTTONDOWN () + ON_WM_LBUTTONUP () + ON_WM_RBUTTONUP () + ON_WM_MOUSEMOVE () + ON_WM_LBUTTONDBLCLK () + ON_WM_RBUTTONDBLCLK () + ON_WM_TIMER () + ON_WM_MOUSEWHEEL40 () +END_MESSAGE_MAP () + +//------------------------------------------------------------------------------ +// 構築と破壊 +//------------------------------------------------------------------------------ + +// コンストラクタ +CEventListIndexScaleView::CEventListIndexScaleView () { +} + +// デストラクタ +CEventListIndexScaleView::~CEventListIndexScaleView () { +} + + +//------------------------------------------------------------------------------ +// オペレーション +//------------------------------------------------------------------------------ + +// セルの長方形を取得 +CRect CEventListIndexScaleView::GetRectFromRow (long lRow) { + CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent (); + CRect rcClient; + GetClientRect (&rcClient); + CRect rcCell (0, 0, 0 ,0); + rcCell.left = 0; + rcCell.right = rcCell.left + rcClient.Width (); + long lRowZoom = pEventListFrame->GetRowZoom (); + rcCell.top = lRow * lRowZoom; + rcCell.bottom = (lRow + 1) * lRowZoom; + ASSERT (rcCell.left < rcCell.right); + ASSERT (rcCell.top < rcCell.bottom); + return rcCell; +} + +//------------------------------------------------------------------------------ +// オーバーライド +//------------------------------------------------------------------------------ + +// 原点の移動をオーバーライド +void CEventListIndexScaleView::OnPrepareDC (CDC* pDC, CPrintInfo* pInfo) { + CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent (); + pDC->SetWindowOrg (0, pEventListFrame->GetRowScrollPos ()); +} + +// 描画 +void CEventListIndexScaleView::OnDraw (CDC* pDC) { + CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp (); + CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent (); + CSekaijuDoc* pSekaijuDoc = GetDocument (); + pSekaijuDoc->m_theCriticalSection.Lock (); + BOOL bEventZeroOrigin = pSekaijuApp->m_theGeneralOption.m_bEventZeroOrigin; + + CRect rcClient; + GetClientRect (&rcClient); + pDC->DPtoLP (&rcClient); + pDC->SetBkMode (TRANSPARENT); + CFont* pOldFont = pDC->SelectObject (pEventListFrame->GetParentFont ()); + long lColorBlack = RGB (0, 0, 0); + long lColorWhite = RGB (255, 255, 255); + long lColorBtnFace = ::GetSysColor (COLOR_BTNFACE); + long lColorBtnShadow = ::GetSysColor (COLOR_BTNSHADOW); + long lColorBtnHighlight = ::GetSysColor (COLOR_BTNHIGHLIGHT); + long lColorBtnText = ::GetSysColor (COLOR_BTNTEXT); + + long lTopIndex = pEventListFrame->GetVisibleTopRow (); + long lBottomIndex = pEventListFrame->GetVisibleBottomRow (); + long y = 0; + long yold = 0; + TCHAR szBuf[256]; + + long lRowZoom = pEventListFrame->GetRowZoom (); + for (long i = lTopIndex; i <= lBottomIndex; i++) { + MIDIEvent* pMIDIEvent = pEventListFrame->GetVisibleEvent (i); + long bEventSelected = FALSE; + if (pMIDIEvent) { + bEventSelected = pSekaijuDoc->IsEventSelected (pMIDIEvent); + } + y = i * lRowZoom; + CRect theRect (0, y, rcClient.Width (), y + lRowZoom); + memset (szBuf, 0, sizeof (szBuf)); + _sntprintf (szBuf, 255, _T("%d"), i + (bEventZeroOrigin ? 0 : 1)); + if (bEventSelected) { + pDC->FillSolidRect (&theRect, lColorBlack); + pDC->Draw3dRect (&theRect, lColorBlack, lColorBtnShadow); + pDC->SetTextColor (lColorWhite); + pDC->DrawText (szBuf, -1, &theRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); + } + else { + pDC->FillSolidRect (&theRect, lColorBtnFace); + pDC->Draw3dRect (&theRect, lColorBtnHighlight, lColorBtnShadow); + pDC->SetTextColor (lColorBtnText); + pDC->DrawText (szBuf, -1, &theRect, DT_SINGLELINE | DT_CENTER | DT_VCENTER); + } + yold = y; + } + pDC->SelectObject (pOldFont); + pSekaijuDoc->m_theCriticalSection.Unlock (); + ::Sleep (0); +} + + +// ビューの更新 +void CEventListIndexScaleView::OnUpdate (CView* pSender, LPARAM lHint, CObject* pHint) { + // クリティカルセクションはロックされているものとする。 + CSekaijuView::OnUpdate (pSender, lHint, pHint); +} + + +//------------------------------------------------------------------------------ +// メッセージマップ +//------------------------------------------------------------------------------ + +// ウィンドウ生成時 +BOOL CEventListIndexScaleView::OnCreate (LPCREATESTRUCT lpcs) { + return CSekaijuView::OnCreate (lpcs); +} + +// キー押し下げ時 +void CEventListIndexScaleView::OnKeyDown (UINT nChar, UINT nRepCnt, UINT nFlags) { + CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent (); + pEventListFrame->PostMessage (WM_KEYDOWN, nChar, (nFlags << 16) | nRepCnt); +} + +// マウス左ボタン押された時 +void CEventListIndexScaleView::OnLButtonDown (UINT nFlags, CPoint point) { + CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp (); + CSekaijuDoc* pSekaijuDoc = GetDocument (); + CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent (); + + // 録音中は何もしない + if (pSekaijuApp->m_bRecording) { + ::SetCursor (pSekaijuApp->m_hCursorNo); + return; + } + // MIDIデータがロックされている場合は何もしない + if (pSekaijuDoc->m_bEditLocked) { + ::SetCursor (pSekaijuApp->m_hCursorNo); + return; + } + + pSekaijuDoc->m_theCriticalSection.Lock (); + + CRect rcClient; + GetClientRect (&rcClient); + rcClient += CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ()); + point += CSize (pEventListFrame->GetColumnScrollPos (), pEventListFrame->GetRowScrollPos ()); + + MIDIData* pMIDIData = pSekaijuDoc->m_pMIDIData; + MIDITrack* pMIDITrack = NULL; + MIDIEvent* pMIDIEvent = NULL; + MIDITrack* pCloneTrack = NULL; + MIDIEvent* pCloneEvent = NULL; + CHistoryUnit* pCurHistoryUnit = NULL; + VERIFY (pSekaijuDoc->AddHistoryUnit (_T("選択/選択解除"))); + VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ()); + + // 旧選択イベントの選択解除(Shiftが押されていない場合かつCtrlが押されていない場合のみ) + if ((nFlags & MK_SHIFT) == 0 && (nFlags & MK_CONTROL) == 0) { + pSekaijuDoc->SelectNoObject (pCurHistoryUnit); + pEventListFrame->MakeVisibleEventArray (); // TODO 他のフレームウィンドウが不正になる + } + + // イベントの選択 + long lOldRow = pEventListFrame->YtoRow (m_ptMouseDown.y); + long lCurRow = pEventListFrame->YtoRow (point.y); + // シフトが押されている場合 + if (nFlags & MK_SHIFT) { + long lMinRow = __min (lOldRow, lCurRow); + long lMaxRow = __max (lOldRow, lCurRow); + long i; + for (i = lMinRow; i <= lMaxRow; i++) { + pMIDIEvent = pEventListFrame->GetVisibleEvent (i); + if (pMIDIEvent) { + MIDIEvent* pFirstCombinedEvent = MIDIEvent_GetFirstCombinedEvent (pMIDIEvent); + pCloneEvent = pSekaijuDoc->SelectEvent (pFirstCombinedEvent, 1, pCurHistoryUnit); + if (pCloneEvent) { + pEventListFrame->ReplaceVisibleEvent (pFirstCombinedEvent, pCloneEvent); + } + } + } + } + // シフトが押されていない場合 + else { + pMIDIEvent = pEventListFrame->GetVisibleEvent (lCurRow); + if (pMIDIEvent) { + MIDIEvent* pFirstCombinedEvent = MIDIEvent_GetFirstCombinedEvent (pMIDIEvent); + pCloneEvent = pSekaijuDoc->SelectEvent (pFirstCombinedEvent, 1, pCurHistoryUnit); + if (pCloneEvent) { + pEventListFrame->ReplaceVisibleEvent (pFirstCombinedEvent, pCloneEvent); + } + } + } + + SetCapture (); + SetTimer (0x21, 55, NULL); + Invalidate (); + + m_ptMouseDown = m_ptMouseMove = point; + m_nMouseDownFlags = m_nMouseMoveFlags = nFlags; + pEventListFrame->m_bAutoPageUpdate = FALSE; + + pSekaijuDoc->m_theCriticalSection.Unlock (); + ::Sleep (0); +} + +// マウス右ボタン押された時 +void CEventListIndexScaleView::OnRButtonDown (UINT nFlags, CPoint point) { +} + +// マウス左ボタン離されたとき +void CEventListIndexScaleView::OnLButtonUp (UINT nFlags, CPoint point) { + CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp (); + CSekaijuDoc* pSekaijuDoc = GetDocument (); + CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent (); + + // 録音中は何もしない + if (pSekaijuApp->m_bRecording) { + ::SetCursor (pSekaijuApp->m_hCursorNo); + return; + } + // MIDIデータがロックされている場合は何もしない + if (pSekaijuDoc->m_bEditLocked) { + ::SetCursor (pSekaijuApp->m_hCursorNo); + return; + } + + if (GetCapture () == this) { + pSekaijuDoc->m_theCriticalSection.Lock (); + ReleaseCapture (); + KillTimer (0x21); + pSekaijuDoc->UpdateAllViews (NULL, SEKAIJUDOC_MIDIDATACHANGED | + SEKAIJUDOC_MIDITRACKCHANGED | SEKAIJUDOC_MIDIEVENTCHANGED); + pSekaijuDoc->m_theCriticalSection.Unlock (); + ::Sleep (0); + } + +} + +// マウス右ボタン離されたとき +void CEventListIndexScaleView::OnRButtonUp (UINT nFlags, CPoint point) { +} + +// マウスが動かされたとき +void CEventListIndexScaleView::OnMouseMove (UINT nFlags, CPoint point) { + CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp (); + CSekaijuDoc* pSekaijuDoc = GetDocument (); + CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent (); + + // 録音中は何もしない + if (pSekaijuApp->m_bRecording) { + ::SetCursor (pSekaijuApp->m_hCursorNo); + return; + } + // MIDIデータがロックされている場合は何もしない + if (pSekaijuDoc->m_bEditLocked) { + ::SetCursor (pSekaijuApp->m_hCursorNo); + return; + } + + if (GetCapture () == this) { + CRect rcClient; + GetClientRect (&rcClient); + rcClient += CSize (0, pEventListFrame->GetRowScrollPos ()); + point += CSize (0, pEventListFrame->GetRowScrollPos ()); + pSekaijuDoc->m_theCriticalSection.Lock (); + + // イベントの選択又は選択解除 + long lCurRow = pEventListFrame->YtoRow (point.y); + long lDownRow = pEventListFrame->YtoRow (m_ptMouseDown.y); + long lOldRow = pEventListFrame->YtoRow (m_ptMouseMove.y); + if (lOldRow != lCurRow) { + long lVisibleEventCount = pEventListFrame->GetVisibleEventCount (); + long lMinRow = __min (lOldRow, lCurRow); + long lMaxRow = __max (lOldRow, lCurRow); + long i; + MIDITrack* pMIDITrack = NULL; + MIDIEvent* pMIDIEvent = NULL; + MIDIEvent* pCloneEvent = NULL; + CHistoryUnit* pCurHistoryUnit = NULL; + VERIFY (pCurHistoryUnit = pSekaijuDoc->GetCurHistoryUnit ()); + if (lDownRow <= lOldRow && lOldRow <= lCurRow || + lDownRow >= lOldRow && lOldRow >= lCurRow) { + for (i = lMinRow; i <= lMaxRow; i++) { + pMIDIEvent = pEventListFrame->GetVisibleEvent (i); + if (pMIDIEvent) { + MIDIEvent* pFirstCombinedEvent = MIDIEvent_GetFirstCombinedEvent (pMIDIEvent); + pCloneEvent = pSekaijuDoc->SelectEvent (pFirstCombinedEvent, 1, pCurHistoryUnit); + if (pCloneEvent) { + pEventListFrame->ReplaceVisibleEvent (pFirstCombinedEvent, pCloneEvent); + } + } + } + } + else if ((nFlags & MK_SHIFT) == 0 && (nFlags & MK_CONTROL) == 0) { + for (i = lMinRow; i <= lMaxRow; i++) { + if (i != lCurRow) { + pMIDIEvent = pEventListFrame->GetVisibleEvent (i); + if (pMIDIEvent) { + MIDIEvent* pFirstCombinedEvent = MIDIEvent_GetFirstCombinedEvent (pMIDIEvent); + pCloneEvent = pSekaijuDoc->SelectEvent (pFirstCombinedEvent, 0, pCurHistoryUnit); + if (pCloneEvent) { + pEventListFrame->ReplaceVisibleEvent (pFirstCombinedEvent, pCloneEvent); + } + } + } + } + } + Invalidate (FALSE); + } + m_ptMouseMove = point; + m_nMouseMoveFlags = nFlags; + pSekaijuDoc->m_theCriticalSection.Unlock (); + ::Sleep (0); + } + + +} + +// マウス左ボタンがダブルクリックされたとき +void CEventListIndexScaleView::OnLButtonDblClk (UINT nFlags, CPoint point) { +} + +// マウス右ボタンがダブルクリックされたとき +void CEventListIndexScaleView::OnRButtonDblClk (UINT nFlags, CPoint point) { +} + + +// タイマー時 +void CEventListIndexScaleView::OnTimer (UINT nIDEvent) { + CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent (); + CSekaijuDoc* pSekaijuDoc = GetDocument (); + + // マウスキャプター中にクライアント領域をはみ出した場合の自動スクロール処理 + if (nIDEvent == 0x21) { + if (GetCapture () == this) { + CClientDC dc (this); + OnPrepareDC (&dc, NULL); + CRect rcClient; + GetClientRect (&rcClient); + rcClient += CSize (0, pEventListFrame->GetRowScrollPos ()); + if (!rcClient.PtInRect (m_ptMouseMove)) { + long lOldRowScrollPos = pEventListFrame->GetRowScrollPos (); + pSekaijuDoc->m_theCriticalSection.Lock (); + if (m_ptMouseMove.y < rcClient.top) { + pEventListFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEUP, + (LPARAM)(pEventListFrame->m_wndRowScroll.GetSafeHwnd ())); + } + else if (m_ptMouseMove.y > rcClient.bottom) { + pEventListFrame->SendMessage (WM_VSCROLL, (WPARAM)SB_LINEDOWN, + (LPARAM)(pEventListFrame->m_wndRowScroll.GetSafeHwnd ())); + } + WORD wX = (WORD)(m_ptMouseMove.x); + WORD wY = (WORD)(m_ptMouseMove.y - lOldRowScrollPos); + PostMessage (WM_MOUSEMOVE, (WPARAM)m_nMouseMoveFlags, (LPARAM)((wY << 16) | wX)); + pSekaijuDoc->m_theCriticalSection.Unlock (); + ::Sleep (0); + } + } + } + + ::Sleep (0); +} + +// マウスホイールが回された時 +void CEventListIndexScaleView::OnMouseWheel40 (UINT nFlags, CPoint point) { + CEventListFrame* pEventListFrame = (CEventListFrame*)GetParent (); + CSekaijuApp* pSekaijuApp = (CSekaijuApp*)AfxGetApp (); + CSekaijuDoc* pSekaijuDoc = GetDocument (); + long lDelta = (short)HIWORD (nFlags); + long lFlags = LOWORD (nFlags); + if (lFlags & MK_CONTROL) { + if (lDelta > 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel == 0 || + lDelta < 0 && pSekaijuApp->m_theGeneralOption.m_bInvertCtrlMouseWheel != 0) { + pEventListFrame->PostMessage (WM_COMMAND, ID_CONTROL_PREVMEASURE); + } + else { + pEventListFrame->PostMessage (WM_COMMAND, ID_CONTROL_NEXTMEASURE); + } + } + else { + long lRowScrollPos = pEventListFrame->GetRowScrollPos (); + long lRowZoom = pEventListFrame->GetRowZoom (); + lRowScrollPos -= lRowZoom * lDelta / WHEELDELTA; + pEventListFrame->SetRowScrollPos (lRowScrollPos); + pEventListFrame->m_bAutoPageUpdate = FALSE; + } +} + -- cgit v1.2.3