Initial community commit
This commit is contained in:
parent
537bcbc862
commit
fc06254474
16440 changed files with 4239995 additions and 2 deletions
388
Src/external_dependencies/openmpt-trunk/mptrack/TuningDialog.h
Normal file
388
Src/external_dependencies/openmpt-trunk/mptrack/TuningDialog.h
Normal file
|
@ -0,0 +1,388 @@
|
|||
/*
|
||||
* TuningDialog.h
|
||||
* --------------
|
||||
* Purpose: Alternative sample tuning configuration dialog.
|
||||
* Notes : (currently none)
|
||||
* Authors: 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 "tuningRatioMapWnd.h"
|
||||
#include "tuningcollection.h"
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include "resource.h"
|
||||
#include "CDecimalSupport.h"
|
||||
|
||||
OPENMPT_NAMESPACE_BEGIN
|
||||
|
||||
|
||||
// Tunings exist even outside of CSoundFile objects. We thus cannot use the
|
||||
// GetCharsetInternal() encoding consistently. For now, just always treat
|
||||
// tuning strings as Charset::Locale. As of OpenMPT 1.27, this distinction does
|
||||
// not yet matter, because GetCharsetInteral() is always mpt::Charset::Locale if
|
||||
// MODPLUG_TRACKER anyway.
|
||||
extern const mpt::Charset TuningCharsetFallback;
|
||||
|
||||
template<class T1, class T2>
|
||||
class CBijectiveMap
|
||||
{
|
||||
public:
|
||||
CBijectiveMap(const T1& a, const T2& b)
|
||||
: m_NotFoundT1(a),
|
||||
m_NotFoundT2(b)
|
||||
{}
|
||||
|
||||
void AddPair(const T1& a, const T2& b)
|
||||
{
|
||||
m_T1.push_back(a);
|
||||
m_T2.push_back(b);
|
||||
}
|
||||
|
||||
void ClearMapping()
|
||||
{
|
||||
m_T1.clear();
|
||||
m_T2.clear();
|
||||
}
|
||||
|
||||
size_t Size() const
|
||||
{
|
||||
ASSERT(m_T1.size() == m_T2.size());
|
||||
return m_T1.size();
|
||||
}
|
||||
|
||||
void RemoveValue_1(const T1& a)
|
||||
{
|
||||
auto iter = find(m_T1.begin(), m_T1.end(), a);
|
||||
if(iter != m_T1.end())
|
||||
{
|
||||
m_T2.erase(m_T2.begin() + (iter-m_T1.begin()));
|
||||
m_T1.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
void RemoveValue_2(const T2& b)
|
||||
{
|
||||
auto iter = find(m_T2.begin(), m_T2.end(), b);
|
||||
if(iter != m_T2.end())
|
||||
{
|
||||
m_T1.erase(m_T1.begin() + (iter-m_T2.begin()));
|
||||
m_T2.erase(iter);
|
||||
}
|
||||
}
|
||||
|
||||
T2 GetMapping_12(const T1& a) const
|
||||
{
|
||||
auto iter = find(m_T1.begin(), m_T1.end(), a);
|
||||
if(iter != m_T1.end())
|
||||
{
|
||||
return m_T2[iter-m_T1.begin()];
|
||||
}
|
||||
else
|
||||
return m_NotFoundT2;
|
||||
}
|
||||
|
||||
T1 GetMapping_21(const T2& b) const
|
||||
{
|
||||
auto iter = find(m_T2.begin(), m_T2.end(), b);
|
||||
if(iter != m_T2.end())
|
||||
{
|
||||
return m_T1[iter-m_T2.begin()];
|
||||
}
|
||||
else
|
||||
return m_NotFoundT1;
|
||||
}
|
||||
|
||||
private:
|
||||
//Elements are collected to two arrays so that elements with the
|
||||
//same index are mapped to each other.
|
||||
std::vector<T1> m_T1;
|
||||
std::vector<T2> m_T2;
|
||||
|
||||
T1 m_NotFoundT1;
|
||||
T2 m_NotFoundT2;
|
||||
};
|
||||
|
||||
class CTuningDialog;
|
||||
|
||||
class CTuningTreeCtrl : public CTreeCtrl
|
||||
{
|
||||
private:
|
||||
CTuningDialog& m_rParentDialog;
|
||||
bool m_Dragging;
|
||||
|
||||
public:
|
||||
CTuningTreeCtrl(CTuningDialog* parent)
|
||||
: m_rParentDialog(*parent)
|
||||
, m_Dragging(false)
|
||||
{}
|
||||
//Note: Parent address may be given in its initializer list.
|
||||
|
||||
void SetDragging(bool state = true) {m_Dragging = state;}
|
||||
bool IsDragging() {return m_Dragging;}
|
||||
|
||||
afx_msg void OnMouseMove(UINT nFlags, CPoint point);
|
||||
afx_msg void OnLButtonUp(UINT nFlags, CPoint point);
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
class CTuningTreeItem
|
||||
{
|
||||
private:
|
||||
CTuning* m_pTuning;
|
||||
CTuningCollection* m_pTuningCollection;
|
||||
|
||||
public:
|
||||
CTuningTreeItem() : m_pTuning(NULL),
|
||||
m_pTuningCollection(NULL)
|
||||
{}
|
||||
|
||||
CTuningTreeItem(CTuning* pT) :
|
||||
m_pTuning(pT),
|
||||
m_pTuningCollection(NULL)
|
||||
{}
|
||||
|
||||
CTuningTreeItem(CTuningCollection* pTC) :
|
||||
m_pTuning(NULL),
|
||||
m_pTuningCollection(pTC)
|
||||
{}
|
||||
|
||||
bool operator==(const CTuningTreeItem& ti) const
|
||||
{
|
||||
if(m_pTuning == ti.m_pTuning &&
|
||||
m_pTuningCollection == ti.m_pTuningCollection)
|
||||
return true;
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
void Reset() {m_pTuning = NULL; m_pTuningCollection = NULL;}
|
||||
|
||||
|
||||
void Set(CTuning* pT)
|
||||
{
|
||||
m_pTuning = pT;
|
||||
m_pTuningCollection = NULL;
|
||||
}
|
||||
|
||||
void Set(CTuningCollection* pTC)
|
||||
{
|
||||
m_pTuning = NULL;
|
||||
m_pTuningCollection = pTC;
|
||||
}
|
||||
|
||||
operator bool () const
|
||||
{
|
||||
return m_pTuning || m_pTuningCollection;
|
||||
}
|
||||
bool operator ! () const
|
||||
{
|
||||
return !operator bool();
|
||||
}
|
||||
|
||||
CTuningCollection* GetTC() {return m_pTuningCollection;}
|
||||
|
||||
CTuning* GetT() {return m_pTuning;}
|
||||
};
|
||||
|
||||
// CTuningDialog dialog
|
||||
|
||||
class CTuningDialog : public CDialog
|
||||
{
|
||||
friend class CTuningTreeCtrl;
|
||||
|
||||
enum EnSclImport
|
||||
{
|
||||
enSclImportOk,
|
||||
enSclImportFailTooLargeNumDenomIntegers,
|
||||
enSclImportFailZeroDenominator,
|
||||
enSclImportFailNegativeRatio,
|
||||
enSclImportFailUnableToOpenFile,
|
||||
enSclImportLineCountMismatch,
|
||||
enSclImportTuningCreationFailure,
|
||||
enSclImportAddTuningFailure,
|
||||
enSclImportFailTooManyNotes
|
||||
};
|
||||
|
||||
public:
|
||||
using TUNINGVECTOR = std::vector<CTuningCollection*>;
|
||||
|
||||
public:
|
||||
CTuningDialog(CWnd* pParent, INSTRUMENTINDEX inst, CSoundFile &csf);
|
||||
virtual ~CTuningDialog();
|
||||
|
||||
BOOL OnInitDialog();
|
||||
|
||||
void UpdateRatioMapEdits(const Tuning::NOTEINDEXTYPE&);
|
||||
|
||||
bool GetModifiedStatus(const CTuningCollection* const pTc) const;
|
||||
|
||||
// Dialog Data
|
||||
enum { IDD = IDD_TUNING };
|
||||
|
||||
protected:
|
||||
virtual void DoDataExchange(CDataExchange* pDX); // DDX/DDV support
|
||||
|
||||
private:
|
||||
|
||||
bool CanEdit(CTuningCollection * pTC) const;
|
||||
bool CanEdit(CTuning * pT, CTuningCollection * pTC) const;
|
||||
|
||||
void UpdateView(const int UpdateMask = 0);
|
||||
void UpdateTuningType();
|
||||
|
||||
HTREEITEM AddTreeItem(CTuningCollection* pTC, HTREEITEM parent, HTREEITEM insertAfter);
|
||||
HTREEITEM AddTreeItem(CTuning* pT, HTREEITEM parent, HTREEITEM insertAfter);
|
||||
|
||||
void DeleteTreeItem(CTuning* pT);
|
||||
void DeleteTreeItem(CTuningCollection* pTC);
|
||||
|
||||
// Check if item can be dropped here. If yes, the target collection is returned, otherwise nullptr.
|
||||
CTuningCollection *CanDrop(HTREEITEM dragDestItem);
|
||||
void OnEndDrag(HTREEITEM dragDestItem);
|
||||
|
||||
//Returns pointer to the tuning collection where tuning given as argument
|
||||
//belongs to.
|
||||
CTuningCollection* GetpTuningCollection(const CTuning* const) const;
|
||||
|
||||
//Returns the address of corresponding tuningcollection; if it points
|
||||
//to tuning-entry, returning the owning tuningcollection
|
||||
CTuningCollection* GetpTuningCollection(HTREEITEM ti) const;
|
||||
|
||||
//Checks whether tuning collection can be deleted.
|
||||
bool IsDeletable(const CTuningCollection* const pTC) const;
|
||||
|
||||
// Scl-file import.
|
||||
EnSclImport ImportScl(const mpt::PathString &filename, const mpt::ustring &name, std::unique_ptr<CTuning> & result);
|
||||
EnSclImport ImportScl(std::istream& iStrm, const mpt::ustring &name, std::unique_ptr<CTuning> & result);
|
||||
|
||||
|
||||
private:
|
||||
|
||||
CSoundFile & m_sndFile;
|
||||
|
||||
CTuningRatioMapWnd m_RatioMapWnd;
|
||||
TUNINGVECTOR m_TuningCollections;
|
||||
std::vector<CTuningCollection*> m_DeletableTuningCollections;
|
||||
|
||||
std::map<const CTuningCollection*, CString> m_TuningCollectionsNames;
|
||||
std::map<const CTuningCollection*, mpt::PathString> m_TuningCollectionsFilenames;
|
||||
|
||||
CTuning* m_pActiveTuning;
|
||||
CTuningCollection* m_pActiveTuningCollection;
|
||||
|
||||
CComboBox m_CombobTuningType;
|
||||
|
||||
//Tuning Edits-->
|
||||
CEdit m_EditSteps;
|
||||
CNumberEdit m_EditRatioPeriod;
|
||||
CNumberEdit m_EditRatio;
|
||||
CEdit m_EditNotename;
|
||||
CEdit m_EditMiscActions;
|
||||
CEdit m_EditFineTuneSteps;
|
||||
CEdit m_EditName;
|
||||
//<--Tuning Edits
|
||||
|
||||
CButton m_ButtonSet;
|
||||
CButton m_ButtonNew;
|
||||
CButton m_ButtonExport;
|
||||
CButton m_ButtonImport;
|
||||
CButton m_ButtonRemove;
|
||||
|
||||
CTuningTreeCtrl m_TreeCtrlTuning;
|
||||
|
||||
private:
|
||||
using TUNINGTREEITEM = CTuningTreeItem;
|
||||
using TREETUNING_MAP = CBijectiveMap<HTREEITEM, TUNINGTREEITEM>;
|
||||
TREETUNING_MAP m_TreeItemTuningItemMap;
|
||||
|
||||
TUNINGTREEITEM m_DragItem;
|
||||
TUNINGTREEITEM m_CommandItemSrc;
|
||||
TUNINGTREEITEM m_CommandItemDest;
|
||||
//Commanditem is used when receiving context menu-commands,
|
||||
//m_CommandItemDest is used when the command really need only
|
||||
//one argument.
|
||||
|
||||
using MODIFIED_MAP = std::map<const CTuningCollection* const, bool>;
|
||||
MODIFIED_MAP m_ModifiedTCs;
|
||||
//If tuning collection seems to have been modified, its address
|
||||
//is added to this map.
|
||||
|
||||
enum
|
||||
{
|
||||
TT_TUNINGCOLLECTION = 1,
|
||||
TT_TUNING
|
||||
};
|
||||
|
||||
static CString GetSclImportFailureMsg(EnSclImport);
|
||||
static constexpr size_t s_nSclImportMaxNoteCount = 256;
|
||||
|
||||
//To indicate whether to apply changes made to
|
||||
//those edit boxes(they are modified by certain activities
|
||||
//in case which the modifications should not be applied to
|
||||
//tuning data.
|
||||
bool m_NoteEditApply;
|
||||
bool m_RatioEditApply;
|
||||
|
||||
enum
|
||||
{
|
||||
UM_TUNINGDATA = 1, //UM <-> Update Mask
|
||||
UM_TUNINGCOLLECTION = 2,
|
||||
};
|
||||
|
||||
static const TUNINGTREEITEM s_notFoundItemTuning;
|
||||
static const HTREEITEM s_notFoundItemTree;
|
||||
|
||||
bool AddTuning(CTuningCollection*, CTuning* pT);
|
||||
bool AddTuning(CTuningCollection*, Tuning::Type type);
|
||||
|
||||
//Flag to prevent multiple exit error-messages.
|
||||
bool m_DoErrorExit;
|
||||
|
||||
void DoErrorExit();
|
||||
|
||||
virtual void OnOK();
|
||||
|
||||
//Treectrl context menu functions.
|
||||
public:
|
||||
afx_msg void OnRemoveTuning();
|
||||
afx_msg void OnAddTuningGeneral();
|
||||
afx_msg void OnAddTuningGroupGeometric();
|
||||
afx_msg void OnAddTuningGeometric();
|
||||
afx_msg void OnCopyTuning();
|
||||
afx_msg void OnRemoveTuningCollection();
|
||||
|
||||
//Event-functions
|
||||
public:
|
||||
afx_msg void OnEnChangeEditSteps();
|
||||
afx_msg void OnEnChangeEditRatioperiod();
|
||||
afx_msg void OnEnChangeEditNotename();
|
||||
afx_msg void OnBnClickedButtonSetvalues();
|
||||
afx_msg void OnEnChangeEditRatiovalue();
|
||||
afx_msg void OnBnClickedButtonNew();
|
||||
afx_msg void OnBnClickedButtonExport();
|
||||
afx_msg void OnBnClickedButtonImport();
|
||||
afx_msg void OnBnClickedButtonRemove();
|
||||
afx_msg void OnEnChangeEditFinetunesteps();
|
||||
afx_msg void OnEnKillfocusEditFinetunesteps();
|
||||
afx_msg void OnEnKillfocusEditName();
|
||||
afx_msg void OnEnKillfocusEditSteps();
|
||||
afx_msg void OnEnKillfocusEditRatioperiod();
|
||||
afx_msg void OnEnKillfocusEditRatiovalue();
|
||||
afx_msg void OnEnKillfocusEditNotename();
|
||||
|
||||
//Treeview events
|
||||
afx_msg void OnTvnSelchangedTreeTuning(NMHDR *pNMHDR, LRESULT *pResult);
|
||||
afx_msg void OnTvnDeleteitemTreeTuning(NMHDR *pNMHDR, LRESULT *pResult);
|
||||
afx_msg void OnNMRclickTreeTuning(NMHDR *pNMHDR, LRESULT *pResult);
|
||||
afx_msg void OnTvnBegindragTreeTuning(NMHDR *pNMHDR, LRESULT *pResult);
|
||||
|
||||
DECLARE_MESSAGE_MAP()
|
||||
};
|
||||
|
||||
OPENMPT_NAMESPACE_END
|
Loading…
Add table
Add a link
Reference in a new issue