mirror of https://github.com/AxioDL/amuse.git
New code style refactor
This commit is contained in:
parent
b4c073c373
commit
a7a408cc66
|
@ -1,5 +1,5 @@
|
|||
---
|
||||
IndentWidth: 4
|
||||
BasedOnStyle: LLVM
|
||||
ColumnLimit: 120
|
||||
UseTab: Never
|
||||
---
|
||||
|
@ -8,7 +8,6 @@ DerivePointerAlignment: false
|
|||
PointerAlignment: Left
|
||||
AlignAfterOpenBracket: Align
|
||||
AlignConsecutiveAssignments: false
|
||||
BreakBeforeBraces: Allman
|
||||
IndentCaseLabels: false
|
||||
AllowShortBlocksOnASingleLine: true
|
||||
AlignOperands: true
|
||||
|
@ -16,7 +15,6 @@ AlignTrailingComments: true
|
|||
AlwaysBreakBeforeMultilineStrings: true
|
||||
AlwaysBreakTemplateDeclarations: true
|
||||
BreakConstructorInitializersBeforeComma: true
|
||||
BreakStringLiterals: true
|
||||
AlwaysBreakAfterReturnType: None
|
||||
AlwaysBreakAfterDefinitionReturnType: None
|
||||
AllowShortFunctionsOnASingleLine: All
|
||||
|
@ -25,6 +23,6 @@ NamespaceIndentation: None
|
|||
BinPackArguments: true
|
||||
BinPackParameters: true
|
||||
SortIncludes: false
|
||||
AccessModifierOffset: -4
|
||||
AccessModifierOffset: -2
|
||||
ConstructorInitializerIndentWidth: 0
|
||||
ConstructorInitializerAllOnOneLineOrOnePerLine: true
|
||||
|
|
|
@ -5,50 +5,46 @@
|
|||
#include <amuse/BooBackend.hpp>
|
||||
#include <boo/audiodev/IAudioVoiceEngine.hpp>
|
||||
|
||||
@interface DataOutlineView : NSOutlineView
|
||||
{
|
||||
@interface DataOutlineView : NSOutlineView {
|
||||
@public
|
||||
IBOutlet NSButton* removeDataButton;
|
||||
IBOutlet NSMenuItem* deleteMenuItem;
|
||||
IBOutlet NSButton* removeDataButton;
|
||||
IBOutlet NSMenuItem* deleteMenuItem;
|
||||
}
|
||||
@end
|
||||
|
||||
@interface SamplesTableController : NSObject <NSTableViewDataSource, NSTableViewDelegate>
|
||||
{
|
||||
AudioGroupFilePresenter* presenter;
|
||||
@interface SamplesTableController : NSObject <NSTableViewDataSource, NSTableViewDelegate> {
|
||||
AudioGroupFilePresenter* presenter;
|
||||
}
|
||||
- (id)initWithAudioGroupPresenter:(AudioGroupFilePresenter*)present;
|
||||
@end
|
||||
|
||||
@interface SFXTableController : NSObject <NSTableViewDataSource, NSTableViewDelegate>
|
||||
{
|
||||
AudioGroupFilePresenter* presenter;
|
||||
@interface SFXTableController : NSObject <NSTableViewDataSource, NSTableViewDelegate> {
|
||||
AudioGroupFilePresenter* presenter;
|
||||
}
|
||||
- (id)initWithAudioGroupPresenter:(AudioGroupFilePresenter*)present;
|
||||
@end
|
||||
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate, AudioGroupClient>
|
||||
{
|
||||
IBOutlet NSWindow* mainWindow;
|
||||
IBOutlet NSOutlineView* dataOutline;
|
||||
IBOutlet NSSearchField* dataSearchField;
|
||||
IBOutlet NSTableView* sfxTable;
|
||||
IBOutlet NSTableView* samplesTable;
|
||||
IBOutlet NSTextView* creditsView;
|
||||
@interface AppDelegate : NSObject <NSApplicationDelegate, AudioGroupClient> {
|
||||
IBOutlet NSWindow* mainWindow;
|
||||
IBOutlet NSOutlineView* dataOutline;
|
||||
IBOutlet NSSearchField* dataSearchField;
|
||||
IBOutlet NSTableView* sfxTable;
|
||||
IBOutlet NSTableView* samplesTable;
|
||||
IBOutlet NSTextView* creditsView;
|
||||
|
||||
IBOutlet NSButton* removeDataButton;
|
||||
IBOutlet NSMenuItem* removeDataMenu;
|
||||
IBOutlet NSButton* removeDataButton;
|
||||
IBOutlet NSMenuItem* removeDataMenu;
|
||||
|
||||
AudioGroupFilePresenter* groupFilePresenter;
|
||||
AudioGroupFilePresenter* groupFilePresenter;
|
||||
|
||||
SamplesTableController* samplesController;
|
||||
SFXTableController* sfxController;
|
||||
SamplesTableController* samplesController;
|
||||
SFXTableController* sfxController;
|
||||
|
||||
@public
|
||||
std::unique_ptr<boo::IAudioVoiceEngine> booEngine;
|
||||
std::experimental::optional<amuse::BooBackendVoiceAllocator> amuseAllocator;
|
||||
std::experimental::optional<amuse::Engine> amuseEngine;
|
||||
std::shared_ptr<amuse::Voice> activeSFXVox;
|
||||
std::unique_ptr<boo::IAudioVoiceEngine> booEngine;
|
||||
std::experimental::optional<amuse::BooBackendVoiceAllocator> amuseAllocator;
|
||||
std::experimental::optional<amuse::Engine> amuseEngine;
|
||||
std::shared_ptr<amuse::Voice> activeSFXVox;
|
||||
}
|
||||
- (BOOL)importURL:(NSURL*)url;
|
||||
- (void)outlineView:(DataOutlineView*)ov selectionChanged:(id)item;
|
||||
|
@ -56,4 +52,3 @@
|
|||
- (void)startSFX:(int)sfxId;
|
||||
- (void)startSample:(int)sampId;
|
||||
@end
|
||||
|
||||
|
|
|
@ -19,142 +19,127 @@
|
|||
- (amuse::Engine&)getAmuseEngine;
|
||||
@end
|
||||
|
||||
struct AudioGroupDataCollection
|
||||
{
|
||||
std::string m_name;
|
||||
NSURL* m_proj;
|
||||
NSURL* m_pool;
|
||||
NSURL* m_sdir;
|
||||
NSURL* m_samp;
|
||||
NSURL* m_meta;
|
||||
struct AudioGroupDataCollection {
|
||||
std::string m_name;
|
||||
NSURL* m_proj;
|
||||
NSURL* m_pool;
|
||||
NSURL* m_sdir;
|
||||
NSURL* m_samp;
|
||||
NSURL* m_meta;
|
||||
|
||||
AudioGroupDataToken* m_token;
|
||||
AudioGroupDataToken* m_token;
|
||||
|
||||
std::vector<uint8_t> m_projData;
|
||||
std::vector<uint8_t> m_poolData;
|
||||
std::vector<uint8_t> m_sdirData;
|
||||
std::vector<uint8_t> m_sampData;
|
||||
std::vector<uint8_t> m_projData;
|
||||
std::vector<uint8_t> m_poolData;
|
||||
std::vector<uint8_t> m_sdirData;
|
||||
std::vector<uint8_t> m_sampData;
|
||||
|
||||
struct MetaData
|
||||
{
|
||||
amuse::DataFormat fmt;
|
||||
uint32_t absOffs;
|
||||
uint32_t active;
|
||||
MetaData(amuse::DataFormat fmtIn, uint32_t absOffsIn, uint32_t activeIn)
|
||||
: fmt(fmtIn), absOffs(absOffsIn), active(activeIn)
|
||||
{
|
||||
}
|
||||
MetaData(athena::io::FileReader& r)
|
||||
: fmt(amuse::DataFormat(r.readUint32Little())), absOffs(r.readUint32Little()), active(r.readUint32Little())
|
||||
{
|
||||
}
|
||||
};
|
||||
std::experimental::optional<MetaData> m_metaData;
|
||||
struct MetaData {
|
||||
amuse::DataFormat fmt;
|
||||
uint32_t absOffs;
|
||||
uint32_t active;
|
||||
MetaData(amuse::DataFormat fmtIn, uint32_t absOffsIn, uint32_t activeIn)
|
||||
: fmt(fmtIn), absOffs(absOffsIn), active(activeIn) {}
|
||||
MetaData(athena::io::FileReader& r)
|
||||
: fmt(amuse::DataFormat(r.readUint32Little())), absOffs(r.readUint32Little()), active(r.readUint32Little()) {}
|
||||
};
|
||||
std::experimental::optional<MetaData> m_metaData;
|
||||
|
||||
std::experimental::optional<amuse::AudioGroupData> m_loadedData;
|
||||
const amuse::AudioGroup* m_loadedGroup;
|
||||
std::vector<AudioGroupToken*> m_groupTokens;
|
||||
std::experimental::optional<amuse::AudioGroupData> m_loadedData;
|
||||
const amuse::AudioGroup* m_loadedGroup;
|
||||
std::vector<AudioGroupToken*> m_groupTokens;
|
||||
|
||||
void moveURL(NSURL* oldUrl, NSURL* newUrl);
|
||||
void moveURL(NSURL* oldUrl, NSURL* newUrl);
|
||||
|
||||
bool loadProj(AudioGroupFilePresenter* presenter);
|
||||
bool loadPool(AudioGroupFilePresenter* presenter);
|
||||
bool loadSdir(AudioGroupFilePresenter* presenter);
|
||||
bool loadSamp(AudioGroupFilePresenter* presenter);
|
||||
bool loadMeta(AudioGroupFilePresenter* presenter);
|
||||
bool loadProj(AudioGroupFilePresenter* presenter);
|
||||
bool loadPool(AudioGroupFilePresenter* presenter);
|
||||
bool loadSdir(AudioGroupFilePresenter* presenter);
|
||||
bool loadSamp(AudioGroupFilePresenter* presenter);
|
||||
bool loadMeta(AudioGroupFilePresenter* presenter);
|
||||
|
||||
AudioGroupDataCollection(std::string_view name, NSURL* proj, NSURL* pool, NSURL* sdir, NSURL* samp, NSURL* meta);
|
||||
bool isDataComplete() const
|
||||
{
|
||||
return m_projData.size() && m_poolData.size() && m_sdirData.size() && m_sampData.size() && m_metaData;
|
||||
}
|
||||
bool _attemptLoad(AudioGroupFilePresenter* presenter);
|
||||
bool _indexData(AudioGroupFilePresenter* presenter);
|
||||
AudioGroupDataCollection(std::string_view name, NSURL* proj, NSURL* pool, NSURL* sdir, NSURL* samp, NSURL* meta);
|
||||
bool isDataComplete() const {
|
||||
return m_projData.size() && m_poolData.size() && m_sdirData.size() && m_sampData.size() && m_metaData;
|
||||
}
|
||||
bool _attemptLoad(AudioGroupFilePresenter* presenter);
|
||||
bool _indexData(AudioGroupFilePresenter* presenter);
|
||||
|
||||
void enable(AudioGroupFilePresenter* presenter);
|
||||
void disable(AudioGroupFilePresenter* presenter);
|
||||
void enable(AudioGroupFilePresenter* presenter);
|
||||
void disable(AudioGroupFilePresenter* presenter);
|
||||
};
|
||||
|
||||
struct AudioGroupCollection
|
||||
{
|
||||
NSURL* m_url;
|
||||
struct AudioGroupCollection {
|
||||
NSURL* m_url;
|
||||
|
||||
AudioGroupCollectionToken* m_token;
|
||||
std::map<std::string, std::unique_ptr<AudioGroupDataCollection>> m_groups;
|
||||
std::vector<std::map<std::string, std::unique_ptr<AudioGroupDataCollection>>::iterator> m_filterGroups;
|
||||
AudioGroupCollectionToken* m_token;
|
||||
std::map<std::string, std::unique_ptr<AudioGroupDataCollection>> m_groups;
|
||||
std::vector<std::map<std::string, std::unique_ptr<AudioGroupDataCollection>>::iterator> m_filterGroups;
|
||||
|
||||
AudioGroupCollection(NSURL* url);
|
||||
void addCollection(AudioGroupFilePresenter* presenter,
|
||||
std::vector<std::pair<std::string, amuse::IntrusiveAudioGroupData>>&& collection);
|
||||
void update(AudioGroupFilePresenter* presenter);
|
||||
bool doSearch(std::string_view str);
|
||||
bool doActiveFilter();
|
||||
void addSFX(std::vector<AudioGroupSFXToken*>& vecOut);
|
||||
void addSamples(std::vector<AudioGroupSampleToken*>& vecOut);
|
||||
AudioGroupCollection(NSURL* url);
|
||||
void addCollection(AudioGroupFilePresenter* presenter,
|
||||
std::vector<std::pair<std::string, amuse::IntrusiveAudioGroupData>>&& collection);
|
||||
void update(AudioGroupFilePresenter* presenter);
|
||||
bool doSearch(std::string_view str);
|
||||
bool doActiveFilter();
|
||||
void addSFX(std::vector<AudioGroupSFXToken*>& vecOut);
|
||||
void addSamples(std::vector<AudioGroupSampleToken*>& vecOut);
|
||||
};
|
||||
|
||||
@interface AudioGroupDataToken : NSObject
|
||||
{
|
||||
@interface AudioGroupDataToken : NSObject {
|
||||
@public
|
||||
AudioGroupDataCollection* m_collection;
|
||||
AudioGroupDataCollection* m_collection;
|
||||
}
|
||||
- (id)initWithDataCollection:(AudioGroupDataCollection*)collection;
|
||||
@end
|
||||
|
||||
@interface AudioGroupCollectionToken : NSObject
|
||||
{
|
||||
@interface AudioGroupCollectionToken : NSObject {
|
||||
@public
|
||||
AudioGroupCollection* m_collection;
|
||||
AudioGroupCollection* m_collection;
|
||||
}
|
||||
- (id)initWithCollection:(AudioGroupCollection*)collection;
|
||||
@end
|
||||
|
||||
@interface AudioGroupSFXToken : NSObject
|
||||
{
|
||||
@interface AudioGroupSFXToken : NSObject {
|
||||
@public
|
||||
NSAttributedString* m_name;
|
||||
int m_loadId;
|
||||
const amuse::SFXGroupIndex::SFXEntry* m_sfx;
|
||||
NSAttributedString* m_name;
|
||||
int m_loadId;
|
||||
const amuse::SFXGroupIndex::SFXEntry* m_sfx;
|
||||
}
|
||||
- (id)initWithName:(NSAttributedString*)name loadId:(int)loadId sfx:(const amuse::SFXGroupIndex::SFXEntry*)sfx;
|
||||
@end
|
||||
|
||||
@interface AudioGroupSampleToken : NSObject
|
||||
{
|
||||
@interface AudioGroupSampleToken : NSObject {
|
||||
@public
|
||||
NSAttributedString* m_name;
|
||||
const std::pair<amuse::AudioGroupSampleDirectory::Entry, amuse::AudioGroupSampleDirectory::ADPCMParms>* m_sample;
|
||||
NSAttributedString* m_name;
|
||||
const std::pair<amuse::AudioGroupSampleDirectory::Entry, amuse::AudioGroupSampleDirectory::ADPCMParms>* m_sample;
|
||||
}
|
||||
- (id)
|
||||
initWithName:(NSAttributedString*)name
|
||||
samp:(const std::pair<amuse::AudioGroupSampleDirectory::Entry, amuse::AudioGroupSampleDirectory::ADPCMParms>*)
|
||||
sample;
|
||||
- (id)initWithName:(NSAttributedString*)name
|
||||
samp:(const std::pair<amuse::AudioGroupSampleDirectory::Entry,
|
||||
amuse::AudioGroupSampleDirectory::ADPCMParms>*)sample;
|
||||
@end
|
||||
|
||||
@interface AudioGroupToken : NSObject
|
||||
{
|
||||
@interface AudioGroupToken : NSObject {
|
||||
@public
|
||||
NSString* m_name;
|
||||
int m_id;
|
||||
const amuse::SongGroupIndex* m_song;
|
||||
const amuse::SFXGroupIndex* m_sfx;
|
||||
NSString* m_name;
|
||||
int m_id;
|
||||
const amuse::SongGroupIndex* m_song;
|
||||
const amuse::SFXGroupIndex* m_sfx;
|
||||
}
|
||||
- (id)initWithName:(NSString*)name id:(int)gid songGroup:(const amuse::SongGroupIndex*)group;
|
||||
- (id)initWithName:(NSString*)name id:(int)gid sfxGroup:(const amuse::SFXGroupIndex*)group;
|
||||
@end
|
||||
|
||||
@interface AudioGroupFilePresenter : NSObject <NSFilePresenter, NSOutlineViewDataSource, NSOutlineViewDelegate>
|
||||
{
|
||||
@interface AudioGroupFilePresenter : NSObject <NSFilePresenter, NSOutlineViewDataSource, NSOutlineViewDelegate> {
|
||||
@public
|
||||
id<AudioGroupClient> m_audioGroupClient;
|
||||
NSURL* m_groupURL;
|
||||
std::map<std::string, std::unique_ptr<AudioGroupCollection>> m_audioGroupCollections;
|
||||
std::vector<std::map<std::string, std::unique_ptr<AudioGroupCollection>>::iterator> m_filterAudioGroupCollections;
|
||||
NSOutlineView* m_lastOutlineView;
|
||||
NSString* m_searchStr;
|
||||
id<AudioGroupClient> m_audioGroupClient;
|
||||
NSURL* m_groupURL;
|
||||
std::map<std::string, std::unique_ptr<AudioGroupCollection>> m_audioGroupCollections;
|
||||
std::vector<std::map<std::string, std::unique_ptr<AudioGroupCollection>>::iterator> m_filterAudioGroupCollections;
|
||||
NSOutlineView* m_lastOutlineView;
|
||||
NSString* m_searchStr;
|
||||
|
||||
std::vector<AudioGroupSFXToken*> m_sfxTableData;
|
||||
std::vector<AudioGroupSampleToken*> m_sampleTableData;
|
||||
std::vector<AudioGroupSFXToken*> m_sfxTableData;
|
||||
std::vector<AudioGroupSampleToken*> m_sampleTableData;
|
||||
}
|
||||
- (id)initWithAudioGroupClient:(id<AudioGroupClient>)client;
|
||||
- (BOOL)addCollectionName:(std::string&&)name
|
||||
|
@ -164,4 +149,3 @@ initWithName:(NSAttributedString*)name
|
|||
- (void)setSearchFilter:(NSString*)str;
|
||||
- (void)removeSelectedItem;
|
||||
@end
|
||||
|
||||
|
|
|
@ -19,29 +19,26 @@
|
|||
|
||||
@class AudioUnitViewController;
|
||||
|
||||
namespace amuse
|
||||
{
|
||||
namespace amuse {
|
||||
|
||||
/** Backend voice allocator implementation for AudioUnit mixer */
|
||||
class AudioUnitBackendVoiceAllocator : public BooBackendVoiceAllocator
|
||||
{
|
||||
class AudioUnitBackendVoiceAllocator : public BooBackendVoiceAllocator {
|
||||
public:
|
||||
AudioUnitBackendVoiceAllocator(boo::IAudioVoiceEngine& booEngine) : BooBackendVoiceAllocator(booEngine) {}
|
||||
AudioUnitBackendVoiceAllocator(boo::IAudioVoiceEngine& booEngine) : BooBackendVoiceAllocator(booEngine) {}
|
||||
};
|
||||
|
||||
void RegisterAudioUnit();
|
||||
}
|
||||
} // namespace amuse
|
||||
|
||||
@interface AmuseAudioUnit : AUAudioUnit <AudioGroupClient>
|
||||
{
|
||||
@interface AmuseAudioUnit : AUAudioUnit <AudioGroupClient> {
|
||||
@public
|
||||
AudioUnitViewController* m_viewController;
|
||||
std::unique_ptr<boo::IAudioVoiceEngine> m_booBackend;
|
||||
std::experimental::optional<amuse::AudioUnitBackendVoiceAllocator> m_voxAlloc;
|
||||
std::experimental::optional<amuse::Engine> m_engine;
|
||||
AudioGroupFilePresenter* m_filePresenter;
|
||||
AUAudioUnitBus* m_outBus;
|
||||
AUAudioUnitBusArray* m_outs;
|
||||
AudioUnitViewController* m_viewController;
|
||||
std::unique_ptr<boo::IAudioVoiceEngine> m_booBackend;
|
||||
std::experimental::optional<amuse::AudioUnitBackendVoiceAllocator> m_voxAlloc;
|
||||
std::experimental::optional<amuse::Engine> m_engine;
|
||||
AudioGroupFilePresenter* m_filePresenter;
|
||||
AUAudioUnitBus* m_outBus;
|
||||
AUAudioUnitBusArray* m_outs;
|
||||
}
|
||||
- (nullable id)initWithComponentDescription:(AudioComponentDescription)componentDescription
|
||||
error:(NSError* __nullable* __nonnull)outError
|
||||
|
|
|
@ -5,19 +5,16 @@
|
|||
|
||||
@class AmuseAudioUnit;
|
||||
|
||||
@interface GroupBrowserDelegate : NSObject <NSBrowserDelegate>
|
||||
{
|
||||
AmuseAudioUnit* m_audioUnit;
|
||||
@interface GroupBrowserDelegate : NSObject <NSBrowserDelegate> {
|
||||
AmuseAudioUnit* m_audioUnit;
|
||||
}
|
||||
- (id)initWithAudioUnit:(AmuseAudioUnit*)au;
|
||||
@end
|
||||
|
||||
@interface AudioUnitViewController : AUViewController <AUAudioUnitFactory>
|
||||
{
|
||||
@interface AudioUnitViewController : AUViewController <AUAudioUnitFactory> {
|
||||
@public
|
||||
AmuseAudioUnit* m_audioUnit;
|
||||
IBOutlet NSBrowser* m_groupBrowser;
|
||||
GroupBrowserDelegate* m_groupBrowserDelegate;
|
||||
AmuseAudioUnit* m_audioUnit;
|
||||
IBOutlet NSBrowser* m_groupBrowser;
|
||||
GroupBrowserDelegate* m_groupBrowserDelegate;
|
||||
}
|
||||
@end
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -10,73 +10,71 @@
|
|||
|
||||
class ADSREditor;
|
||||
|
||||
class ADSRView : public QWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
friend class ADSRControls;
|
||||
amuse::ObjToken<ProjectModel::ADSRNode> m_node;
|
||||
QFont m_gridFont;
|
||||
QStaticText m_percentTexts[11];
|
||||
std::vector<QStaticText> m_timeTexts;
|
||||
int m_dragPoint = -1;
|
||||
uint64_t m_cycleIdx = 0;
|
||||
ADSREditor* getEditor() const;
|
||||
public:
|
||||
explicit ADSRView(QWidget* parent = Q_NULLPTR);
|
||||
void loadData(ProjectModel::ADSRNode* node);
|
||||
void unloadData();
|
||||
ProjectModel::INode* currentNode() const;
|
||||
class ADSRView : public QWidget {
|
||||
Q_OBJECT
|
||||
friend class ADSRControls;
|
||||
amuse::ObjToken<ProjectModel::ADSRNode> m_node;
|
||||
QFont m_gridFont;
|
||||
QStaticText m_percentTexts[11];
|
||||
std::vector<QStaticText> m_timeTexts;
|
||||
int m_dragPoint = -1;
|
||||
uint64_t m_cycleIdx = 0;
|
||||
ADSREditor* getEditor() const;
|
||||
|
||||
void paintEvent(QPaintEvent* ev);
|
||||
void mousePressEvent(QMouseEvent* ev);
|
||||
void mouseReleaseEvent(QMouseEvent* ev);
|
||||
void mouseMoveEvent(QMouseEvent* ev);
|
||||
public:
|
||||
explicit ADSRView(QWidget* parent = Q_NULLPTR);
|
||||
void loadData(ProjectModel::ADSRNode* node);
|
||||
void unloadData();
|
||||
ProjectModel::INode* currentNode() const;
|
||||
|
||||
void paintEvent(QPaintEvent* ev);
|
||||
void mousePressEvent(QMouseEvent* ev);
|
||||
void mouseReleaseEvent(QMouseEvent* ev);
|
||||
void mouseMoveEvent(QMouseEvent* ev);
|
||||
};
|
||||
|
||||
class ADSRControls : public QFrame
|
||||
{
|
||||
Q_OBJECT
|
||||
friend class ADSRView;
|
||||
QDoubleSpinBox* m_attack;
|
||||
QDoubleSpinBox* m_decay;
|
||||
QDoubleSpinBox* m_sustain;
|
||||
QDoubleSpinBox* m_release;
|
||||
QCheckBox* m_dls;
|
||||
QLabel* m_velToAttackLab;
|
||||
QDoubleSpinBox* m_velToAttack;
|
||||
QLabel* m_keyToDecayLab;
|
||||
QDoubleSpinBox* m_keyToDecay;
|
||||
bool m_enableUpdate = true;
|
||||
ADSREditor* getEditor() const;
|
||||
void setAttackAndDecay(double attack, double decay, uint64_t cycleCount);
|
||||
void setDecayAndSustain(double decay, double sustain, uint64_t cycleCount);
|
||||
void setRelease(double release, uint64_t cycleCount);
|
||||
class ADSRControls : public QFrame {
|
||||
Q_OBJECT
|
||||
friend class ADSRView;
|
||||
QDoubleSpinBox* m_attack;
|
||||
QDoubleSpinBox* m_decay;
|
||||
QDoubleSpinBox* m_sustain;
|
||||
QDoubleSpinBox* m_release;
|
||||
QCheckBox* m_dls;
|
||||
QLabel* m_velToAttackLab;
|
||||
QDoubleSpinBox* m_velToAttack;
|
||||
QLabel* m_keyToDecayLab;
|
||||
QDoubleSpinBox* m_keyToDecay;
|
||||
bool m_enableUpdate = true;
|
||||
ADSREditor* getEditor() const;
|
||||
void setAttackAndDecay(double attack, double decay, uint64_t cycleCount);
|
||||
void setDecayAndSustain(double decay, double sustain, uint64_t cycleCount);
|
||||
void setRelease(double release, uint64_t cycleCount);
|
||||
|
||||
public:
|
||||
explicit ADSRControls(QWidget* parent = Q_NULLPTR);
|
||||
void loadData();
|
||||
void unloadData();
|
||||
explicit ADSRControls(QWidget* parent = Q_NULLPTR);
|
||||
void loadData();
|
||||
void unloadData();
|
||||
public slots:
|
||||
void attackChanged(double val);
|
||||
void decayChanged(double val);
|
||||
void sustainChanged(double val);
|
||||
void releaseChanged(double val);
|
||||
void dlsStateChanged(int state);
|
||||
void velToAttackChanged(double val);
|
||||
void keyToDecayChanged(double val);
|
||||
void attackChanged(double val);
|
||||
void decayChanged(double val);
|
||||
void sustainChanged(double val);
|
||||
void releaseChanged(double val);
|
||||
void dlsStateChanged(int state);
|
||||
void velToAttackChanged(double val);
|
||||
void keyToDecayChanged(double val);
|
||||
};
|
||||
|
||||
class ADSREditor : public EditorWidget
|
||||
{
|
||||
Q_OBJECT
|
||||
friend class ADSRView;
|
||||
friend class ADSRControls;
|
||||
ADSRView* m_adsrView;
|
||||
ADSRControls* m_controls;
|
||||
class ADSREditor : public EditorWidget {
|
||||
Q_OBJECT
|
||||
friend class ADSRView;
|
||||
friend class ADSRControls;
|
||||
ADSRView* m_adsrView;
|
||||
ADSRControls* m_controls;
|
||||
|
||||
public:
|
||||
explicit ADSREditor(QWidget* parent = Q_NULLPTR);
|
||||
bool loadData(ProjectModel::ADSRNode* node);
|
||||
void unloadData();
|
||||
ProjectModel::INode* currentNode() const;
|
||||
explicit ADSREditor(QWidget* parent = Q_NULLPTR);
|
||||
bool loadData(ProjectModel::ADSRNode* node);
|
||||
void unloadData();
|
||||
ProjectModel::INode* currentNode() const;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -4,105 +4,93 @@
|
|||
#include <QObject>
|
||||
#include <QProcess>
|
||||
|
||||
boo::SystemString QStringToSysString(const QString& str)
|
||||
{
|
||||
boo::SystemString QStringToSysString(const QString& str) {
|
||||
#ifdef _WIN32
|
||||
return (wchar_t*)str.utf16();
|
||||
return (wchar_t*)str.utf16();
|
||||
#else
|
||||
return str.toUtf8().toStdString();
|
||||
return str.toUtf8().toStdString();
|
||||
#endif
|
||||
}
|
||||
|
||||
QString SysStringToQString(const boo::SystemString& str)
|
||||
{
|
||||
QString SysStringToQString(const boo::SystemString& str) {
|
||||
#ifdef _WIN32
|
||||
return QString::fromStdWString(str);
|
||||
return QString::fromStdWString(str);
|
||||
#else
|
||||
return QString::fromStdString(str);
|
||||
return QString::fromStdString(str);
|
||||
#endif
|
||||
}
|
||||
|
||||
bool MkPath(const QString& path, UIMessenger& messenger)
|
||||
{
|
||||
QFileInfo fInfo(path);
|
||||
return MkPath(fInfo.dir(), fInfo.fileName(), messenger);
|
||||
bool MkPath(const QString& path, UIMessenger& messenger) {
|
||||
QFileInfo fInfo(path);
|
||||
return MkPath(fInfo.dir(), fInfo.fileName(), messenger);
|
||||
}
|
||||
|
||||
bool MkPath(const QDir& dir, const QString& file, UIMessenger& messenger)
|
||||
{
|
||||
if (!dir.mkpath(file))
|
||||
{
|
||||
QString msg = QString(MainWindow::tr("A directory at '%1/%2' could not be created.")).arg(dir.path()).arg(file);
|
||||
messenger.critical(MainWindow::tr("Unable to create directory"), msg);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
bool MkPath(const QDir& dir, const QString& file, UIMessenger& messenger) {
|
||||
if (!dir.mkpath(file)) {
|
||||
QString msg = QString(MainWindow::tr("A directory at '%1/%2' could not be created.")).arg(dir.path()).arg(file);
|
||||
messenger.critical(MainWindow::tr("Unable to create directory"), msg);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void ShowInGraphicalShell(QWidget* parent, const QString& pathIn)
|
||||
{
|
||||
const QFileInfo fileInfo(pathIn);
|
||||
// Mac, Windows support folder or file.
|
||||
void ShowInGraphicalShell(QWidget* parent, const QString& pathIn) {
|
||||
const QFileInfo fileInfo(pathIn);
|
||||
// Mac, Windows support folder or file.
|
||||
#if defined(Q_OS_WIN)
|
||||
QString paths = QProcessEnvironment::systemEnvironment().value(QStringLiteral("Path"));
|
||||
QString explorer;
|
||||
for (QString path : paths.split(QStringLiteral(";")))
|
||||
{
|
||||
QFileInfo finfo(QDir(path), QStringLiteral("explorer.exe"));
|
||||
if (finfo.exists())
|
||||
{
|
||||
explorer = finfo.filePath();
|
||||
break;
|
||||
}
|
||||
QString paths = QProcessEnvironment::systemEnvironment().value(QStringLiteral("Path"));
|
||||
QString explorer;
|
||||
for (QString path : paths.split(QStringLiteral(";"))) {
|
||||
QFileInfo finfo(QDir(path), QStringLiteral("explorer.exe"));
|
||||
if (finfo.exists()) {
|
||||
explorer = finfo.filePath();
|
||||
break;
|
||||
}
|
||||
if (explorer.isEmpty()) {
|
||||
QMessageBox::warning(parent,
|
||||
MainWindow::tr("Launching Windows Explorer Failed"),
|
||||
MainWindow::tr("Could not find explorer.exe in path to launch Windows Explorer."));
|
||||
return;
|
||||
}
|
||||
QStringList param;
|
||||
if (!fileInfo.isDir())
|
||||
param += QLatin1String("/select,");
|
||||
param += QDir::toNativeSeparators(fileInfo.canonicalFilePath());
|
||||
QProcess::startDetached(explorer, param);
|
||||
}
|
||||
if (explorer.isEmpty()) {
|
||||
QMessageBox::warning(parent, MainWindow::tr("Launching Windows Explorer Failed"),
|
||||
MainWindow::tr("Could not find explorer.exe in path to launch Windows Explorer."));
|
||||
return;
|
||||
}
|
||||
QStringList param;
|
||||
if (!fileInfo.isDir())
|
||||
param += QLatin1String("/select,");
|
||||
param += QDir::toNativeSeparators(fileInfo.canonicalFilePath());
|
||||
QProcess::startDetached(explorer, param);
|
||||
#elif defined(Q_OS_MAC)
|
||||
QStringList scriptArgs;
|
||||
scriptArgs << QLatin1String("-e")
|
||||
<< QString::fromLatin1("tell application \"Finder\" to reveal POSIX file \"%1\"")
|
||||
.arg(fileInfo.canonicalFilePath());
|
||||
QProcess::execute(QLatin1String("/usr/bin/osascript"), scriptArgs);
|
||||
scriptArgs.clear();
|
||||
scriptArgs << QLatin1String("-e")
|
||||
<< QLatin1String("tell application \"Finder\" to activate");
|
||||
QProcess::execute(QLatin1String("/usr/bin/osascript"), scriptArgs);
|
||||
QStringList scriptArgs;
|
||||
scriptArgs << QLatin1String("-e")
|
||||
<< QString::fromLatin1("tell application \"Finder\" to reveal POSIX file \"%1\"")
|
||||
.arg(fileInfo.canonicalFilePath());
|
||||
QProcess::execute(QLatin1String("/usr/bin/osascript"), scriptArgs);
|
||||
scriptArgs.clear();
|
||||
scriptArgs << QLatin1String("-e") << QLatin1String("tell application \"Finder\" to activate");
|
||||
QProcess::execute(QLatin1String("/usr/bin/osascript"), scriptArgs);
|
||||
#else
|
||||
// we cannot select a file here, because no file browser really supports it...
|
||||
const QString folder = fileInfo.isDir() ? fileInfo.absoluteFilePath() : fileInfo.filePath();
|
||||
QProcess browserProc;
|
||||
const QString browserArgs = QStringLiteral("xdg-open \"%1\"").arg(QFileInfo(folder).path());
|
||||
browserProc.startDetached(browserArgs);
|
||||
// we cannot select a file here, because no file browser really supports it...
|
||||
const QString folder = fileInfo.isDir() ? fileInfo.absoluteFilePath() : fileInfo.filePath();
|
||||
QProcess browserProc;
|
||||
const QString browserArgs = QStringLiteral("xdg-open \"%1\"").arg(QFileInfo(folder).path());
|
||||
browserProc.startDetached(browserArgs);
|
||||
#endif
|
||||
}
|
||||
|
||||
QString ShowInGraphicalShellString()
|
||||
{
|
||||
QString ShowInGraphicalShellString() {
|
||||
#if defined(Q_OS_WIN)
|
||||
return MainWindow::tr("Show in Explorer");
|
||||
return MainWindow::tr("Show in Explorer");
|
||||
#elif defined(Q_OS_MAC)
|
||||
return MainWindow::tr("Show in Finder");
|
||||
return MainWindow::tr("Show in Finder");
|
||||
#else
|
||||
return MainWindow::tr("Show in Browser");
|
||||
return MainWindow::tr("Show in Browser");
|
||||
#endif
|
||||
}
|
||||
|
||||
QTransform RectToRect(const QRectF& from, const QRectF& to)
|
||||
{
|
||||
QPolygonF orig(from);
|
||||
orig.pop_back();
|
||||
QPolygonF resize(to);
|
||||
resize.pop_back();
|
||||
QTransform ret;
|
||||
QTransform::quadToQuad(orig, resize, ret);
|
||||
return ret;
|
||||
QTransform RectToRect(const QRectF& from, const QRectF& to) {
|
||||
QPolygonF orig(from);
|
||||
orig.pop_back();
|
||||
QPolygonF resize(to);
|
||||
resize.pop_back();
|
||||
QTransform ret;
|
||||
QTransform::quadToQuad(orig, resize, ret);
|
||||
return ret;
|
||||
}
|
||||
|
|
|
@ -8,32 +8,27 @@
|
|||
class MainWindow;
|
||||
extern MainWindow* g_MainWindow;
|
||||
|
||||
class UIMessenger : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
class UIMessenger : public QObject {
|
||||
Q_OBJECT
|
||||
public:
|
||||
using QObject::QObject;
|
||||
using QObject::QObject;
|
||||
signals:
|
||||
QMessageBox::StandardButton information(const QString &title,
|
||||
const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
||||
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
||||
int question(const QString &title,
|
||||
const QString& text,
|
||||
const QString& button0Text,
|
||||
const QString& button1Text = QString(),
|
||||
const QString& button2Text = QString(),
|
||||
int defaultButtonNumber = 0,
|
||||
int escapeButtonNumber = -1);
|
||||
QMessageBox::StandardButton question(const QString &title,
|
||||
const QString &text, QMessageBox::StandardButtons buttons =
|
||||
QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No),
|
||||
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
||||
QMessageBox::StandardButton warning(const QString &title,
|
||||
const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
||||
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
||||
QMessageBox::StandardButton critical(const QString &title,
|
||||
const QString &text, QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
||||
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
||||
QMessageBox::StandardButton information(const QString& title, const QString& text,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
||||
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
||||
int question(const QString& title, const QString& text, const QString& button0Text,
|
||||
const QString& button1Text = QString(), const QString& button2Text = QString(),
|
||||
int defaultButtonNumber = 0, int escapeButtonNumber = -1);
|
||||
QMessageBox::StandardButton
|
||||
question(const QString& title, const QString& text,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::StandardButtons(QMessageBox::Yes | QMessageBox::No),
|
||||
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
||||
QMessageBox::StandardButton warning(const QString& title, const QString& text,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
||||
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
||||
QMessageBox::StandardButton critical(const QString& title, const QString& text,
|
||||
QMessageBox::StandardButtons buttons = QMessageBox::Ok,
|
||||
QMessageBox::StandardButton defaultButton = QMessageBox::NoButton);
|
||||
};
|
||||
|
||||
boo::SystemString QStringToSysString(const QString& str);
|
||||
|
@ -45,22 +40,14 @@ bool MkPath(const QDir& dir, const QString& file, UIMessenger& messenger);
|
|||
void ShowInGraphicalShell(QWidget* parent, const QString& pathIn);
|
||||
QString ShowInGraphicalShellString();
|
||||
|
||||
static QLatin1String StringViewToQString(std::string_view sv)
|
||||
{
|
||||
return QLatin1String(sv.data(), int(sv.size()));
|
||||
}
|
||||
static QLatin1String StringViewToQString(std::string_view sv) { return QLatin1String(sv.data(), int(sv.size())); }
|
||||
|
||||
/* Used for generating transform matrices to map SVG coordinate space */
|
||||
QTransform RectToRect(const QRectF& from, const QRectF& to);
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<> struct hash<QString>
|
||||
{
|
||||
std::size_t operator()(const QString& s) const noexcept
|
||||
{
|
||||
return qHash(s);
|
||||
}
|
||||
namespace std {
|
||||
template <>
|
||||
struct hash<QString> {
|
||||
std::size_t operator()(const QString& s) const noexcept { return qHash(s); }
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace std
|
||||
|
|
|
@ -6,321 +6,266 @@
|
|||
#include <QMouseEvent>
|
||||
#include <QJSValueIterator>
|
||||
|
||||
class CurveEditUndoCommand : public EditorUndoCommand
|
||||
{
|
||||
uint8_t m_redoData[128];
|
||||
uint8_t m_undoData[128];
|
||||
bool m_usedExpr;
|
||||
bool m_undid = false;
|
||||
class CurveEditUndoCommand : public EditorUndoCommand {
|
||||
uint8_t m_redoData[128];
|
||||
uint8_t m_undoData[128];
|
||||
bool m_usedExpr;
|
||||
bool m_undid = false;
|
||||
|
||||
public:
|
||||
CurveEditUndoCommand(const uint8_t* redoData, bool usedExpr,
|
||||
amuse::ObjToken<ProjectModel::CurveNode> node)
|
||||
: EditorUndoCommand(node.get(), CurveControls::tr("Edit Curve")), m_usedExpr(usedExpr)
|
||||
{
|
||||
std::memcpy(m_redoData, redoData, 128);
|
||||
CurveEditUndoCommand(const uint8_t* redoData, bool usedExpr, amuse::ObjToken<ProjectModel::CurveNode> node)
|
||||
: EditorUndoCommand(node.get(), CurveControls::tr("Edit Curve")), m_usedExpr(usedExpr) {
|
||||
std::memcpy(m_redoData, redoData, 128);
|
||||
}
|
||||
void undo() {
|
||||
m_undid = true;
|
||||
amuse::ITable& table = **m_node.cast<ProjectModel::CurveNode>()->m_obj;
|
||||
if (table.Isa() == amuse::ITable::Type::Curve) {
|
||||
amuse::Curve& curve = static_cast<amuse::Curve&>(table);
|
||||
curve.data.resize(128);
|
||||
std::memcpy(curve.data.data(), m_undoData, 128);
|
||||
}
|
||||
void undo()
|
||||
{
|
||||
m_undid = true;
|
||||
amuse::ITable& table = **m_node.cast<ProjectModel::CurveNode>()->m_obj;
|
||||
if (table.Isa() == amuse::ITable::Type::Curve)
|
||||
{
|
||||
amuse::Curve& curve = static_cast<amuse::Curve&>(table);
|
||||
curve.data.resize(128);
|
||||
std::memcpy(curve.data.data(), m_undoData, 128);
|
||||
}
|
||||
EditorUndoCommand::undo();
|
||||
EditorUndoCommand::undo();
|
||||
}
|
||||
void redo() {
|
||||
amuse::ITable& table = **m_node.cast<ProjectModel::CurveNode>()->m_obj;
|
||||
if (table.Isa() == amuse::ITable::Type::Curve) {
|
||||
amuse::Curve& curve = static_cast<amuse::Curve&>(table);
|
||||
curve.data.resize(128);
|
||||
std::memcpy(m_undoData, curve.data.data(), 128);
|
||||
std::memcpy(curve.data.data(), m_redoData, 128);
|
||||
}
|
||||
void redo()
|
||||
{
|
||||
amuse::ITable& table = **m_node.cast<ProjectModel::CurveNode>()->m_obj;
|
||||
if (table.Isa() == amuse::ITable::Type::Curve)
|
||||
{
|
||||
amuse::Curve& curve = static_cast<amuse::Curve&>(table);
|
||||
curve.data.resize(128);
|
||||
std::memcpy(m_undoData, curve.data.data(), 128);
|
||||
std::memcpy(curve.data.data(), m_redoData, 128);
|
||||
}
|
||||
if (m_undid)
|
||||
EditorUndoCommand::redo();
|
||||
if (m_undid)
|
||||
EditorUndoCommand::redo();
|
||||
}
|
||||
bool mergeWith(const QUndoCommand* other) {
|
||||
if (other->id() == id() && !m_usedExpr && !static_cast<const CurveEditUndoCommand*>(other)->m_usedExpr) {
|
||||
std::memcpy(m_redoData, static_cast<const CurveEditUndoCommand*>(other)->m_redoData, 128);
|
||||
return true;
|
||||
}
|
||||
bool mergeWith(const QUndoCommand* other)
|
||||
{
|
||||
if (other->id() == id() && !m_usedExpr && !static_cast<const CurveEditUndoCommand*>(other)->m_usedExpr)
|
||||
{
|
||||
std::memcpy(m_redoData, static_cast<const CurveEditUndoCommand*>(other)->m_redoData, 128);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
int id() const { return int(Id::CurveEdit); }
|
||||
return false;
|
||||
}
|
||||
int id() const { return int(Id::CurveEdit); }
|
||||
};
|
||||
|
||||
CurveEditor* CurveView::getEditor() const
|
||||
{
|
||||
return qobject_cast<CurveEditor*>(parentWidget());
|
||||
CurveEditor* CurveView::getEditor() const { return qobject_cast<CurveEditor*>(parentWidget()); }
|
||||
|
||||
void CurveView::loadData(ProjectModel::CurveNode* node) { m_node = node; }
|
||||
|
||||
void CurveView::unloadData() { m_node.reset(); }
|
||||
|
||||
ProjectModel::INode* CurveView::currentNode() const { return m_node.get(); }
|
||||
|
||||
void CurveView::paintEvent(QPaintEvent* ev) {
|
||||
if (!m_node)
|
||||
return;
|
||||
amuse::ITable& table = **m_node->m_obj;
|
||||
if (table.Isa() != amuse::ITable::Type::Curve)
|
||||
return;
|
||||
amuse::Curve& curve = static_cast<amuse::Curve&>(table);
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
|
||||
qreal deviceRatio = devicePixelRatioF();
|
||||
qreal penWidth = std::max(std::floor(deviceRatio), 1.0) / deviceRatio;
|
||||
|
||||
painter.setPen(QPen(QColor(127, 127, 127), penWidth));
|
||||
painter.setFont(m_gridFont);
|
||||
qreal yIncrement = (height() - 16.0) / 10.0;
|
||||
for (int i = 0; i < 11; ++i) {
|
||||
qreal thisY = i * yIncrement;
|
||||
qreal textY = thisY - (i == 0 ? 2.0 : (i == 10 ? 16.0 : 8.0));
|
||||
painter.drawStaticText(QPointF(0.0, textY), m_percentTexts[i]);
|
||||
painter.drawLine(QPointF(30.0, thisY), QPointF(width(), thisY));
|
||||
}
|
||||
|
||||
qreal xIncrement = (width() - 30.0) / 10.0;
|
||||
for (int i = 0; i < 11; ++i) {
|
||||
qreal thisX = i * xIncrement + 30.0;
|
||||
qreal textX = thisX - (i == 10 ? 30.0 : 15.0);
|
||||
painter.drawStaticText(QPointF(textX, height() - 16.0), m_percentTextsCenter[i]);
|
||||
painter.drawLine(QPointF(thisX, 0.0), QPointF(thisX, height() - 16.0));
|
||||
}
|
||||
|
||||
int i;
|
||||
xIncrement = (width() - 30.0) / 127.0;
|
||||
QPointF lastPt;
|
||||
painter.setPen(QPen(Qt::white, penWidth * 3.0));
|
||||
for (i = 0; i < curve.data.size(); ++i) {
|
||||
QPointF thisPt(i * xIncrement + 30.0, (height() - 16.0) - (height() - 16.0) * (curve.data[i] / 127.0));
|
||||
if (i)
|
||||
painter.drawLine(lastPt, thisPt);
|
||||
lastPt = thisPt;
|
||||
}
|
||||
for (; i < 128; ++i) {
|
||||
QPointF thisPt(i * xIncrement + 30.0, height() - 16.0);
|
||||
if (i)
|
||||
painter.drawLine(lastPt, thisPt);
|
||||
lastPt = thisPt;
|
||||
}
|
||||
}
|
||||
|
||||
void CurveView::loadData(ProjectModel::CurveNode* node)
|
||||
{
|
||||
m_node = node;
|
||||
void CurveView::mousePressEvent(QMouseEvent* ev) { mouseMoveEvent(ev); }
|
||||
|
||||
void CurveView::mouseMoveEvent(QMouseEvent* ev) {
|
||||
CurveView* view = getEditor()->m_curveView;
|
||||
amuse::ITable& table = **view->m_node->m_obj;
|
||||
if (table.Isa() != amuse::ITable::Type::Curve)
|
||||
return;
|
||||
amuse::Curve& curve = static_cast<amuse::Curve&>(table);
|
||||
|
||||
qreal xIncrement = (width() - 30.0) / 127.0;
|
||||
int idx = int(std::round((ev->localPos().x() - 30.0) / xIncrement));
|
||||
if (idx < 0 || idx > 127)
|
||||
return;
|
||||
int val = 127 - amuse::clamp(0, int(std::round(ev->localPos().y() / (height() - 16.0) * 127.0)), 127);
|
||||
|
||||
curve.data.resize(128);
|
||||
uint8_t newData[128];
|
||||
std::memcpy(newData, curve.data.data(), 128);
|
||||
newData[idx] = uint8_t(val);
|
||||
|
||||
g_MainWindow->pushUndoCommand(new CurveEditUndoCommand(newData, false, m_node));
|
||||
update();
|
||||
}
|
||||
|
||||
void CurveView::unloadData()
|
||||
{
|
||||
m_node.reset();
|
||||
CurveView::CurveView(QWidget* parent) : QWidget(parent) {
|
||||
for (int i = 0; i < 11; ++i) {
|
||||
m_percentTexts[i].setText(QStringLiteral("%1%").arg(100 - i * 10));
|
||||
m_percentTexts[i].setTextOption(QTextOption(Qt::AlignVCenter | Qt::AlignRight));
|
||||
m_percentTexts[i].setTextWidth(28.0);
|
||||
m_percentTextsCenter[i].setText(QStringLiteral("%1%").arg(i * 10));
|
||||
m_percentTextsCenter[i].setTextOption(QTextOption(Qt::AlignBaseline | Qt::AlignCenter));
|
||||
m_percentTextsCenter[i].setTextWidth(28.0);
|
||||
}
|
||||
m_gridFont.setPointSize(8);
|
||||
}
|
||||
|
||||
ProjectModel::INode* CurveView::currentNode() const
|
||||
{
|
||||
return m_node.get();
|
||||
CurveEditor* CurveControls::getEditor() const { return qobject_cast<CurveEditor*>(parentWidget()); }
|
||||
|
||||
void CurveControls::loadData() {
|
||||
m_lineEdit->setDisabled(false);
|
||||
m_setExpr->setDisabled(false);
|
||||
}
|
||||
|
||||
void CurveView::paintEvent(QPaintEvent* ev)
|
||||
{
|
||||
if (!m_node)
|
||||
return;
|
||||
amuse::ITable& table = **m_node->m_obj;
|
||||
if (table.Isa() != amuse::ITable::Type::Curve)
|
||||
return;
|
||||
amuse::Curve& curve = static_cast<amuse::Curve&>(table);
|
||||
void CurveControls::unloadData() {
|
||||
m_lineEdit->setDisabled(true);
|
||||
m_setExpr->setDisabled(true);
|
||||
}
|
||||
|
||||
QPainter painter(this);
|
||||
painter.setRenderHint(QPainter::Antialiasing);
|
||||
void CurveControls::exprCommit() {
|
||||
CurveView* view = getEditor()->m_curveView;
|
||||
amuse::ITable& table = **view->m_node->m_obj;
|
||||
if (table.Isa() != amuse::ITable::Type::Curve)
|
||||
return;
|
||||
amuse::Curve& curve = static_cast<amuse::Curve&>(table);
|
||||
|
||||
qreal deviceRatio = devicePixelRatioF();
|
||||
qreal penWidth = std::max(std::floor(deviceRatio), 1.0) / deviceRatio;
|
||||
|
||||
painter.setPen(QPen(QColor(127, 127, 127), penWidth));
|
||||
painter.setFont(m_gridFont);
|
||||
qreal yIncrement = (height() - 16.0) / 10.0;
|
||||
for (int i = 0; i < 11; ++i)
|
||||
{
|
||||
qreal thisY = i * yIncrement;
|
||||
qreal textY = thisY - (i == 0 ? 2.0 : (i == 10 ? 16.0 : 8.0));
|
||||
painter.drawStaticText(QPointF(0.0, textY), m_percentTexts[i]);
|
||||
painter.drawLine(QPointF(30.0, thisY), QPointF(width(), thisY));
|
||||
QString progText = m_lineEdit->text();
|
||||
curve.data.resize(128);
|
||||
uint8_t newData[128];
|
||||
std::memcpy(newData, curve.data.data(), 128);
|
||||
bool notANumber = false;
|
||||
for (int i = 0; i < 128; ++i) {
|
||||
m_engine.globalObject().setProperty(QStringLiteral("x"), i / 127.0);
|
||||
QJSValue val = m_engine.evaluate(progText);
|
||||
if (val.isError()) {
|
||||
m_errLabel->setText(val.toString());
|
||||
return;
|
||||
} else if (val.isNumber()) {
|
||||
newData[i] = uint8_t(amuse::clamp(0, int(std::round(val.toNumber() * 127.0)), 127));
|
||||
} else {
|
||||
notANumber = true;
|
||||
newData[i] = 0;
|
||||
}
|
||||
}
|
||||
if (notANumber)
|
||||
m_errLabel->setText(tr("Did not evaluate as a number"));
|
||||
|
||||
qreal xIncrement = (width() - 30.0) / 10.0;
|
||||
for (int i = 0; i < 11; ++i)
|
||||
{
|
||||
qreal thisX = i * xIncrement + 30.0;
|
||||
qreal textX = thisX - (i == 10 ? 30.0 : 15.0);
|
||||
painter.drawStaticText(QPointF(textX, height() - 16.0), m_percentTextsCenter[i]);
|
||||
painter.drawLine(QPointF(thisX, 0.0), QPointF(thisX, height() - 16.0));
|
||||
}
|
||||
|
||||
int i;
|
||||
xIncrement = (width() - 30.0) / 127.0;
|
||||
QPointF lastPt;
|
||||
painter.setPen(QPen(Qt::white, penWidth * 3.0));
|
||||
for (i = 0; i < curve.data.size(); ++i)
|
||||
{
|
||||
QPointF thisPt(i * xIncrement + 30.0, (height() - 16.0) - (height() - 16.0) * (curve.data[i] / 127.0));
|
||||
if (i)
|
||||
painter.drawLine(lastPt, thisPt);
|
||||
lastPt = thisPt;
|
||||
}
|
||||
for (; i < 128; ++i)
|
||||
{
|
||||
QPointF thisPt(i * xIncrement + 30.0, height() - 16.0);
|
||||
if (i)
|
||||
painter.drawLine(lastPt, thisPt);
|
||||
lastPt = thisPt;
|
||||
}
|
||||
g_MainWindow->pushUndoCommand(new CurveEditUndoCommand(newData, true, view->m_node));
|
||||
view->update();
|
||||
}
|
||||
|
||||
void CurveView::mousePressEvent(QMouseEvent* ev)
|
||||
{
|
||||
mouseMoveEvent(ev);
|
||||
void CurveControls::resizeEvent(QResizeEvent* ev) { m_errLabel->setGeometry(22, 78, width() - 44, 14); }
|
||||
|
||||
CurveControls::CurveControls(QWidget* parent) : QFrame(parent) {
|
||||
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||
setFixedHeight(100);
|
||||
setFrameShape(QFrame::StyledPanel);
|
||||
setFrameShadow(QFrame::Sunken);
|
||||
setBackgroundRole(QPalette::Base);
|
||||
setAutoFillBackground(true);
|
||||
|
||||
QHBoxLayout* mainLayout = new QHBoxLayout;
|
||||
|
||||
QGridLayout* leftLayout = new QGridLayout;
|
||||
|
||||
leftLayout->addWidget(new QLabel(tr("Expression")), 0, 0);
|
||||
m_lineEdit = new QLineEdit;
|
||||
m_lineEdit->setDisabled(true);
|
||||
QPalette palette = m_lineEdit->palette();
|
||||
palette.setColor(QPalette::Base, palette.color(QPalette::Background));
|
||||
m_lineEdit->setPalette(palette);
|
||||
connect(m_lineEdit, SIGNAL(returnPressed()), this, SLOT(exprCommit()));
|
||||
leftLayout->addWidget(m_lineEdit, 1, 0);
|
||||
|
||||
m_setExpr = new QPushButton(tr("Apply"));
|
||||
m_setExpr->setDisabled(true);
|
||||
connect(m_setExpr, SIGNAL(clicked(bool)), this, SLOT(exprCommit()));
|
||||
leftLayout->addWidget(m_setExpr, 1, 1);
|
||||
|
||||
m_errLabel = new QLabel(this);
|
||||
QFont font = m_errLabel->font();
|
||||
font.setPointSize(8);
|
||||
m_errLabel->setFont(font);
|
||||
palette.setColor(QPalette::Text, Qt::red);
|
||||
m_errLabel->setPalette(palette);
|
||||
|
||||
leftLayout->setColumnMinimumWidth(0, 500);
|
||||
leftLayout->setColumnStretch(0, 1);
|
||||
leftLayout->setColumnMinimumWidth(1, 75);
|
||||
leftLayout->setColumnStretch(1, 0);
|
||||
leftLayout->setRowMinimumHeight(0, 22);
|
||||
leftLayout->setRowMinimumHeight(1, 37);
|
||||
leftLayout->setContentsMargins(10, 6, 10, 14);
|
||||
|
||||
mainLayout->addLayout(leftLayout);
|
||||
setLayout(mainLayout);
|
||||
|
||||
QJSValueIterator it(m_engine.globalObject().property(QStringLiteral("Math")));
|
||||
QString docStr =
|
||||
tr("Expression interpreter mapping x:[0,1] to y:[0,1] with the following constants and functions available:\n");
|
||||
bool needsComma = false;
|
||||
while (it.hasNext()) {
|
||||
it.next();
|
||||
m_engine.globalObject().setProperty(it.name(), it.value());
|
||||
if (needsComma)
|
||||
docStr += QStringLiteral(", ");
|
||||
needsComma = true;
|
||||
docStr += it.name();
|
||||
}
|
||||
m_lineEdit->setToolTip(docStr);
|
||||
}
|
||||
|
||||
void CurveView::mouseMoveEvent(QMouseEvent* ev)
|
||||
{
|
||||
CurveView* view = getEditor()->m_curveView;
|
||||
amuse::ITable& table = **view->m_node->m_obj;
|
||||
if (table.Isa() != amuse::ITable::Type::Curve)
|
||||
return;
|
||||
amuse::Curve& curve = static_cast<amuse::Curve&>(table);
|
||||
|
||||
qreal xIncrement = (width() - 30.0) / 127.0;
|
||||
int idx = int(std::round((ev->localPos().x() - 30.0) / xIncrement));
|
||||
if (idx < 0 || idx > 127)
|
||||
return;
|
||||
int val = 127 - amuse::clamp(0, int(std::round(ev->localPos().y() / (height() - 16.0) * 127.0)), 127);
|
||||
|
||||
curve.data.resize(128);
|
||||
uint8_t newData[128];
|
||||
std::memcpy(newData, curve.data.data(), 128);
|
||||
newData[idx] = uint8_t(val);
|
||||
|
||||
g_MainWindow->pushUndoCommand(new CurveEditUndoCommand(newData, false, m_node));
|
||||
update();
|
||||
bool CurveEditor::loadData(ProjectModel::CurveNode* node) {
|
||||
m_curveView->loadData(node);
|
||||
m_controls->loadData();
|
||||
return true;
|
||||
}
|
||||
|
||||
CurveView::CurveView(QWidget* parent)
|
||||
: QWidget(parent)
|
||||
{
|
||||
for (int i = 0; i < 11; ++i)
|
||||
{
|
||||
m_percentTexts[i].setText(QStringLiteral("%1%").arg(100 - i * 10));
|
||||
m_percentTexts[i].setTextOption(QTextOption(Qt::AlignVCenter | Qt::AlignRight));
|
||||
m_percentTexts[i].setTextWidth(28.0);
|
||||
m_percentTextsCenter[i].setText(QStringLiteral("%1%").arg(i * 10));
|
||||
m_percentTextsCenter[i].setTextOption(QTextOption(Qt::AlignBaseline | Qt::AlignCenter));
|
||||
m_percentTextsCenter[i].setTextWidth(28.0);
|
||||
}
|
||||
m_gridFont.setPointSize(8);
|
||||
void CurveEditor::unloadData() {
|
||||
m_curveView->unloadData();
|
||||
m_controls->unloadData();
|
||||
}
|
||||
|
||||
CurveEditor* CurveControls::getEditor() const
|
||||
{
|
||||
return qobject_cast<CurveEditor*>(parentWidget());
|
||||
}
|
||||
|
||||
void CurveControls::loadData()
|
||||
{
|
||||
m_lineEdit->setDisabled(false);
|
||||
m_setExpr->setDisabled(false);
|
||||
}
|
||||
|
||||
void CurveControls::unloadData()
|
||||
{
|
||||
m_lineEdit->setDisabled(true);
|
||||
m_setExpr->setDisabled(true);
|
||||
}
|
||||
|
||||
void CurveControls::exprCommit()
|
||||
{
|
||||
CurveView* view = getEditor()->m_curveView;
|
||||
amuse::ITable& table = **view->m_node->m_obj;
|
||||
if (table.Isa() != amuse::ITable::Type::Curve)
|
||||
return;
|
||||
amuse::Curve& curve = static_cast<amuse::Curve&>(table);
|
||||
|
||||
QString progText = m_lineEdit->text();
|
||||
curve.data.resize(128);
|
||||
uint8_t newData[128];
|
||||
std::memcpy(newData, curve.data.data(), 128);
|
||||
bool notANumber = false;
|
||||
for (int i = 0; i < 128; ++i)
|
||||
{
|
||||
m_engine.globalObject().setProperty(QStringLiteral("x"), i / 127.0);
|
||||
QJSValue val = m_engine.evaluate(progText);
|
||||
if (val.isError())
|
||||
{
|
||||
m_errLabel->setText(val.toString());
|
||||
return;
|
||||
}
|
||||
else if (val.isNumber())
|
||||
{
|
||||
newData[i] = uint8_t(amuse::clamp(0, int(std::round(val.toNumber() * 127.0)), 127));
|
||||
}
|
||||
else
|
||||
{
|
||||
notANumber = true;
|
||||
newData[i] = 0;
|
||||
}
|
||||
}
|
||||
if (notANumber)
|
||||
m_errLabel->setText(tr("Did not evaluate as a number"));
|
||||
|
||||
g_MainWindow->pushUndoCommand(new CurveEditUndoCommand(newData, true, view->m_node));
|
||||
view->update();
|
||||
}
|
||||
|
||||
void CurveControls::resizeEvent(QResizeEvent* ev)
|
||||
{
|
||||
m_errLabel->setGeometry(22, 78, width() - 44, 14);
|
||||
}
|
||||
|
||||
CurveControls::CurveControls(QWidget* parent)
|
||||
: QFrame(parent)
|
||||
{
|
||||
setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Fixed);
|
||||
setFixedHeight(100);
|
||||
setFrameShape(QFrame::StyledPanel);
|
||||
setFrameShadow(QFrame::Sunken);
|
||||
setBackgroundRole(QPalette::Base);
|
||||
setAutoFillBackground(true);
|
||||
|
||||
QHBoxLayout* mainLayout = new QHBoxLayout;
|
||||
|
||||
QGridLayout* leftLayout = new QGridLayout;
|
||||
|
||||
leftLayout->addWidget(new QLabel(tr("Expression")), 0, 0);
|
||||
m_lineEdit = new QLineEdit;
|
||||
m_lineEdit->setDisabled(true);
|
||||
QPalette palette = m_lineEdit->palette();
|
||||
palette.setColor(QPalette::Base, palette.color(QPalette::Background));
|
||||
m_lineEdit->setPalette(palette);
|
||||
connect(m_lineEdit, SIGNAL(returnPressed()), this, SLOT(exprCommit()));
|
||||
leftLayout->addWidget(m_lineEdit, 1, 0);
|
||||
|
||||
m_setExpr = new QPushButton(tr("Apply"));
|
||||
m_setExpr->setDisabled(true);
|
||||
connect(m_setExpr, SIGNAL(clicked(bool)), this, SLOT(exprCommit()));
|
||||
leftLayout->addWidget(m_setExpr, 1, 1);
|
||||
|
||||
m_errLabel = new QLabel(this);
|
||||
QFont font = m_errLabel->font();
|
||||
font.setPointSize(8);
|
||||
m_errLabel->setFont(font);
|
||||
palette.setColor(QPalette::Text, Qt::red);
|
||||
m_errLabel->setPalette(palette);
|
||||
|
||||
leftLayout->setColumnMinimumWidth(0, 500);
|
||||
leftLayout->setColumnStretch(0, 1);
|
||||
leftLayout->setColumnMinimumWidth(1, 75);
|
||||
leftLayout->setColumnStretch(1, 0);
|
||||
leftLayout->setRowMinimumHeight(0, 22);
|
||||
leftLayout->setRowMinimumHeight(1, 37);
|
||||
leftLayout->setContentsMargins(10, 6, 10, 14);
|
||||
|
||||
mainLayout->addLayout(leftLayout);
|
||||
setLayout(mainLayout);
|
||||
|
||||
QJSValueIterator it(m_engine.globalObject().property(QStringLiteral("Math")));
|
||||
QString docStr = tr("Expression interpreter mapping x:[0,1] to y:[0,1] with the following constants and functions available:\n");
|
||||
bool needsComma = false;
|
||||
while (it.hasNext())
|
||||
{
|
||||
it.next();
|
||||
m_engine.globalObject().setProperty(it.name(), it.value());
|
||||
if (needsComma)
|
||||
docStr += QStringLiteral(", ");
|
||||
needsComma = true;
|
||||
docStr += it.name();
|
||||
}
|
||||
m_lineEdit->setToolTip(docStr);
|
||||
}
|
||||
|
||||
bool CurveEditor::loadData(ProjectModel::CurveNode* node)
|
||||
{
|
||||
|