123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289 |
- /*
- * Ctrl_pat.h
- * ----------
- * Purpose: Pattern 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.
- */
- #pragma once
- #include "openmpt/all/BuildSettings.hpp"
- #include "Globals.h"
- #include "PatternCursor.h"
- OPENMPT_NAMESPACE_BEGIN
- class COrderList;
- class CCtrlPatterns;
- struct OrdSelection
- {
- ORDERINDEX firstOrd = 0, lastOrd = 0;
- ORDERINDEX GetSelCount() const { return lastOrd - firstOrd + 1; }
- };
- class COrderList: public CWnd
- {
- friend class CCtrlPatterns;
- protected:
- HFONT m_hFont = nullptr;
- int m_cxFont = 0, m_cyFont = 0;
- //m_nXScroll : The order at the beginning of shown orderlist
- //m_nScrollPos: The same as order
- //m_nScrollPos2nd: 2nd selection point if multiple orders are selected
- // (not neccessarily the higher order - GetCurSel() is taking care of that.)
- ORDERINDEX m_nXScroll = 0, m_nScrollPos = 0, m_nScrollPos2nd = ORDERINDEX_INVALID, m_nDropPos, m_nMouseDownPos, m_playPos = ORDERINDEX_INVALID;
- ORDERINDEX m_nDragOrder;
- //To tell how many orders('orderboxes') to show at least
- //on both sides of current order(when updating orderslist position).
- int m_nOrderlistMargins;
- CModDoc &m_modDoc;
- CCtrlPatterns &m_pParent;
- bool m_bScrolling = false, m_bDragging = false;
- public:
- COrderList(CCtrlPatterns &parent, CModDoc &document);
- public:
- BOOL Init(const CRect&, HFONT hFont);
- void UpdateView(UpdateHint hint, CObject *pObj = nullptr);
- void InvalidateSelection();
- PATTERNINDEX GetCurrentPattern() const;
- // make the current selection the secondary selection (used for keyboard orderlist navigation)
- inline void SetCurSelTo2ndSel(bool isSelectionKeyPressed)
- {
- if(isSelectionKeyPressed && m_nScrollPos2nd == ORDERINDEX_INVALID) m_nScrollPos2nd = m_nScrollPos;
- else if(!isSelectionKeyPressed && m_nScrollPos2nd != ORDERINDEX_INVALID) m_nScrollPos2nd = ORDERINDEX_INVALID;
- };
- void SetSelection(ORDERINDEX firstOrd, ORDERINDEX lastOrd = ORDERINDEX_INVALID);
- // Why VC wants to inline this huge function is beyond my understanding...
- MPT_NOINLINE bool SetCurSel(ORDERINDEX sel, bool setPlayPos = true, bool shiftClick = false, bool ignoreCurSel = false);
- void UpdateScrollInfo();
- void UpdateInfoText();
- int GetFontWidth();
- void QueuePattern(CPoint pt);
- // Check if this module is currently playing
- bool IsPlaying() const;
- ORDERINDEX GetOrderFromPoint(const CPoint &pt) const;
- CRect GetRectFromOrder(ORDERINDEX ord) const;
- // Get the currently selected pattern(s).
- // Set ignoreSelection to true if only the first selected point is important.
- OrdSelection GetCurSel(bool ignoreSelection = false) const;
- // Sets target margin value and returns the effective margin value.
- ORDERINDEX SetMargins(int);
- // Returns the effective margin value.
- ORDERINDEX GetMargins() { return GetMargins(GetMarginsMax()); }
- // Returns the effective margin value.
- ORDERINDEX GetMargins(const ORDERINDEX maxMargins) const { return std::min(maxMargins, static_cast<ORDERINDEX>(m_nOrderlistMargins)); }
- // Returns maximum margin value given current window width.
- ORDERINDEX GetMarginsMax() { return GetMarginsMax(GetLength()); }
- // Returns maximum margin value when shown sequence has nLength orders.
- // For example: If length is 4 orders -> maxMargins = 4/2 - 1 = 1;
- // if maximum is 5 -> maxMargins = (int)5/2 = 2
- ORDERINDEX GetMarginsMax(const ORDERINDEX length) const { return (length > 0 && length % 2 == 0) ? length / 2 - 1 : length / 2; }
- // Returns the number of sequence items visible in the list.
- ORDERINDEX GetLength();
- // Return true if given order is in margins given that first shown order
- // is 'startOrder'. Begin part of the whole sequence
- // is not interpreted to be in margins regardless of the margin value.
- bool IsOrderInMargins(int order, int startOrder);
- // Ensure that a given order index is visible in the orderlist view.
- void EnsureVisible(ORDERINDEX order);
- // Set given sqeuence and update orderlist display.
- void SelectSequence(const SEQUENCEINDEX nSeq);
- // Helper function for entering pattern number
- void EnterPatternNum(int enterNum);
- void OnCopy(bool onlyOrders);
- // Update play state and order lock ranges after inserting order items.
- void InsertUpdatePlaystate(ORDERINDEX first, ORDERINDEX last);
- // Update play state and order lock ranges after deleting order items.
- void DeleteUpdatePlaystate(ORDERINDEX first, ORDERINDEX last);
- //{{AFX_VIRTUAL(COrderList)
- BOOL PreTranslateMessage(MSG *pMsg) override;
- INT_PTR OnToolHitTest(CPoint point, TOOLINFO* pTI) const override;
- HRESULT get_accName(VARIANT varChild, BSTR *pszName) override;
- //}}AFX_VIRTUAL
- protected:
- ModSequence& Order();
- const ModSequence& Order() const;
- void SetScrollPos(int pos);
- int GetScrollPos(bool getTrackPos = false);
- // Resizes the order list if the specified order is past the order list length
- bool EnsureEditable(ORDERINDEX ord);
- //{{AFX_MSG(COrderList)
- afx_msg void OnPaint();
- afx_msg BOOL OnEraseBkgnd(CDC *) { return TRUE; }
- afx_msg void OnSetFocus(CWnd *);
- afx_msg void OnKillFocus(CWnd *);
- afx_msg void OnLButtonDown(UINT, CPoint);
- afx_msg void OnLButtonDblClk(UINT, CPoint);
- afx_msg void OnRButtonDown(UINT, CPoint);
- afx_msg void OnLButtonUp(UINT, CPoint);
- afx_msg void OnMButtonDown(UINT, CPoint);
- afx_msg void OnMouseMove(UINT, CPoint);
- afx_msg void OnHScroll(UINT nSBCode, UINT nPos, CScrollBar*);
- afx_msg void OnSize(UINT nType, int cx, int cy);
- afx_msg void OnSwitchToView();
- afx_msg void OnInsertOrder();
- afx_msg void OnInsertSeparatorPattern();
- afx_msg void OnDeleteOrder();
- afx_msg void OnRenderOrder();
- afx_msg void OnPatternProperties();
- afx_msg void OnPlayerPlay();
- afx_msg void OnPlayerPause();
- afx_msg void OnPlayerPlayFromStart();
- afx_msg void OnPatternPlayFromStart();
- afx_msg void OnCreateNewPattern();
- afx_msg void OnDuplicatePattern();
- afx_msg void OnMergePatterns();
- afx_msg void OnPatternCopy();
- afx_msg void OnPatternPaste();
- afx_msg void OnSetRestartPos();
- afx_msg void OnEditCopy() { OnCopy(false); }
- afx_msg void OnEditCopyOrders() { OnCopy(true); }
- afx_msg void OnEditCut();
- afx_msg LRESULT OnDragonDropping(WPARAM bDoDrop, LPARAM lParam);
- afx_msg LRESULT OnHelpHitTest(WPARAM, LPARAM lParam);
- afx_msg void OnSelectSequence(UINT nid);
- afx_msg LRESULT OnCustomKeyMsg(WPARAM, LPARAM);
- afx_msg void OnLockPlayback();
- afx_msg void OnUnlockPlayback();
- afx_msg BOOL OnToolTipText(UINT, NMHDR *pNMHDR, LRESULT *pResult);
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
- };
- // CPatEdit: Edit control that switches back to the pattern view if Tab key is pressed.
- class CPatEdit: public CEdit
- {
- protected:
- CCtrlPatterns *m_pParent = nullptr;
- public:
- CPatEdit() = default;
- void SetParent(CCtrlPatterns *parent) { m_pParent = parent; }
- BOOL PreTranslateMessage(MSG *pMsg) override;
- };
- class CCtrlPatterns: public CModControlDlg
- {
- friend class COrderList;
- protected:
- COrderList m_OrderList;
- CButton m_BtnPrev, m_BtnNext;
- CComboBox m_CbnInstrument;
- CPatEdit m_EditSpacing, m_EditPatName, m_EditSequence;
- CSpinButtonCtrl m_SpinInstrument, m_SpinSpacing, m_SpinSequence;
- CModControlBar m_ToolBar;
- INSTRUMENTINDEX m_nInstrument = 0;
- PatternCursor::Columns m_nDetailLevel = PatternCursor::lastColumn; // Visible Columns
- bool m_bRecord = false, m_bVUMeters = false, m_bPluginNames = false;
- public:
- CCtrlPatterns(CModControlView &parent, CModDoc &document);
- Setting<LONG> &GetSplitPosRef() override { return TrackerSettings::Instance().glPatternWindowHeight; }
- public:
- const ModSequence &Order() const;
- ModSequence &Order();
- void SetCurrentPattern(PATTERNINDEX nPat);
- BOOL SetCurrentInstrument(UINT nIns);
- BOOL GetFollowSong() { return IsDlgButtonChecked(IDC_PATTERN_FOLLOWSONG); }
- BOOL GetLoopPattern() {return IsDlgButtonChecked(IDC_PATTERN_LOOP);}
- COrderList &GetOrderList() { return m_OrderList; }
- //{{AFX_VIRTUAL(CCtrlPatterns)
- BOOL OnInitDialog() override;
- void DoDataExchange(CDataExchange* pDX) override; // DDX/DDV support
- void RecalcLayout() override;
- void UpdateView(UpdateHint hint = UpdateHint(), CObject *pObj = nullptr) override;
- CRuntimeClass *GetAssociatedViewClass() override;
- LRESULT OnModCtrlMsg(WPARAM wParam, LPARAM lParam) override;
- void OnActivatePage(LPARAM) override;
- void OnDeactivatePage() override;
- BOOL GetToolTipText(UINT, LPTSTR) override;
- //}}AFX_VIRTUAL
- protected:
- //{{AFX_MSG(CCtrlPatterns)
- afx_msg void OnVScroll(UINT nSBCode, UINT nPos, CScrollBar* pScrollBar);
- afx_msg void OnSequenceNext();
- afx_msg void OnSequencePrev();
- afx_msg void OnChannelManager();
- afx_msg void OnKeyDown(UINT nChar, UINT nRepCnt, UINT nFlags);
- afx_msg void OnPlayerPause();
- afx_msg void OnPatternNew();
- afx_msg void OnPatternDuplicate();
- afx_msg void OnPatternMerge();
- afx_msg void OnPatternStop();
- afx_msg void OnPatternPlay();
- afx_msg void OnPatternPlayNoLoop();
- afx_msg void OnPatternPlayRow();
- afx_msg void OnPatternPlayFromStart();
- afx_msg void OnPatternRecord();
- afx_msg void OnPatternVUMeters();
- afx_msg void OnPatternViewPlugNames();
- afx_msg void OnPatternProperties();
- afx_msg void OnPatternExpand();
- afx_msg void OnPatternShrink();
- afx_msg void OnPatternAmplify();
- afx_msg void OnPatternCopy();
- afx_msg void OnPatternPaste();
- afx_msg void OnFollowSong();
- afx_msg void OnChangeLoopStatus();
- afx_msg void OnSwitchToView();
- afx_msg void OnInstrumentChanged();
- afx_msg void OnPrevInstrument();
- afx_msg void OnNextInstrument();
- afx_msg void OnSpacingChanged();
- afx_msg void OnPatternNameChanged();
- afx_msg void OnSequenceNameChanged();
- afx_msg void OnChordEditor();
- afx_msg void OnDetailLo();
- afx_msg void OnDetailMed();
- afx_msg void OnDetailHi();
- afx_msg void OnEditUndo();
- afx_msg void OnUpdateRecord(CCmdUI *pCmdUI);
- afx_msg void TogglePluginEditor();
- afx_msg void OnToggleOverflowPaste();
- afx_msg void OnSequenceNumChanged();
- afx_msg LRESULT OnCustomKeyMsg(WPARAM, LPARAM);
- //}}AFX_MSG
- DECLARE_MESSAGE_MAP()
- private:
- bool HasValidPlug(INSTRUMENTINDEX instr) const;
- public:
- afx_msg BOOL OnMouseWheel(UINT nFlags, short zDelta, CPoint pt);
- afx_msg void OnXButtonUp(UINT nFlags, UINT nButton, CPoint point);
- afx_msg BOOL OnToolTip(UINT id, NMHDR *pTTTStruct, LRESULT *pResult);
- };
- OPENMPT_NAMESPACE_END
|