--- gigedit/trunk/src/gigedit/dimregionedit.h 2008/01/04 19:42:45 1623 +++ gigedit/trunk/src/gigedit/dimregionedit.h 2017/07/23 18:31:53 3329 @@ -1,5 +1,5 @@ /* -*- c++ -*- - * Copyright (C) 2006-2008 Andreas Persson + * Copyright (C) 2006-2017 Andreas Persson * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License as @@ -20,17 +20,72 @@ #ifndef GIGEDIT_DIMREGIONEDIT_H #define GIGEDIT_DIMREGIONEDIT_H -#include +#ifdef LIBGIG_HEADER_FILE +# include LIBGIG_HEADER_FILE(gig.h) +#else +# include +#endif +#include +#include +#include #include #include #include #include -#include #include #include "paramedit.h" +#include "global.h" + +class VelocityCurve : public Gtk::DrawingArea { +public: + VelocityCurve(double (gig::DimensionRegion::*getter)(uint8_t)); + void set_dim_region(gig::DimensionRegion* d) { dimreg = d; } + +protected: +#if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2 + bool on_expose_event(GdkEventExpose* e); +#else + bool on_draw(const Cairo::RefPtr& cr); +#endif + +private: + double (gig::DimensionRegion::* const getter)(uint8_t); + gig::DimensionRegion* dimreg; +}; + +class CrossfadeCurve : public Gtk::DrawingArea { +public: + CrossfadeCurve(); + void set_dim_region(gig::DimensionRegion* d) { dimreg = d; } + +protected: +#if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2 + bool on_expose_event(GdkEventExpose* e); +#else + bool on_draw(const Cairo::RefPtr& cr); +#endif + +private: + gig::DimensionRegion* dimreg; + void draw_one_curve(const Cairo::RefPtr& cr, + const gig::DimensionRegion* d, + bool sensitive); +}; + +class EGStateOptions : public Gtk::HBox { +public: + Gtk::Label label; + BoolBox checkBoxAttack; + BoolBox checkBoxAttackHold; + BoolBox checkBoxDecay1; + BoolBox checkBoxDecay2; + BoolBox checkBoxRelease; + + EGStateOptions(); +}; class DimRegionEdit : public Gtk::Notebook { @@ -38,11 +93,14 @@ DimRegionEdit(); virtual ~DimRegionEdit(); void set_dim_region(gig::DimensionRegion* d); - bool set_sample(gig::Sample* sample); + bool set_sample(gig::Sample* sample, bool copy_sample_unity, bool copy_sample_tune, bool copy_sample_loop); + bool set_sample(gig::DimensionRegion* dimreg, gig::Sample* sample, bool copy_sample_unity, bool copy_sample_tune, bool copy_sample_loop); Gtk::Entry* wSample; + Gtk::Button* buttonNullSampleReference; sigc::signal& signal_dimreg_to_be_changed(); sigc::signal& signal_dimreg_changed(); sigc::signal& signal_sample_ref_changed(); + sigc::signal& signal_select_sample(); std::set dimregs; @@ -51,15 +109,36 @@ sigc::signal dimreg_changed_signal; sigc::signal sample_ref_changed_signal; sigc::signal instrument_changed; + sigc::signal select_sample_signal; + + /** + * Ensures that the 2 signals DimRegionEdit::dimreg_to_be_changed_signal and + * DimRegionEdit::dimreg_changed_signal are always triggered correctly as a + * pair. It behaves similar to a "mutex lock guard" design pattern. + */ + class DimRegionChangeGuard : public SignalGuard { + public: + DimRegionChangeGuard(DimRegionEdit* edit, gig::DimensionRegion* pDimReg) : + SignalGuard(edit->dimreg_to_be_changed_signal, edit->dimreg_changed_signal, pDimReg) + { + } + }; gig::DimensionRegion* dimregion; +#ifdef OLD_TOOLTIPS Gtk::Tooltips tooltips; +#endif Gtk::Table* table[7]; Gtk::Label* lSample; + VelocityCurve velocity_curve; + VelocityCurve release_curve; + VelocityCurve cutoff_curve; + CrossfadeCurve crossfade_curve; + NumEntryPermille eEG1PreAttack; NumEntryTemp eEG1Attack; NumEntryTemp eEG1Decay1; @@ -73,6 +152,7 @@ NumEntryTemp eEG1ControllerAttackInfluence; NumEntryTemp eEG1ControllerDecayInfluence; NumEntryTemp eEG1ControllerReleaseInfluence; + EGStateOptions eEG1StateOptions; NumEntryTemp eLFO1Frequency; NumEntryTemp eLFO1InternalDepth; NumEntryTemp eLFO1ControlDepth; @@ -91,6 +171,7 @@ NumEntryTemp eEG2ControllerAttackInfluence; NumEntryTemp eEG2ControllerDecayInfluence; NumEntryTemp eEG2ControllerReleaseInfluence; + EGStateOptions eEG2StateOptions; NumEntryTemp eLFO2Frequency; NumEntryTemp eLFO2InternalDepth; NumEntryTemp eLFO2ControlDepth; @@ -139,6 +220,10 @@ BoolEntry eMSDecode; NumEntryTemp eSampleStartOffset; NoteEntry eUnityNote; + ReadOnlyLabelWidget eSampleGroup; + ReadOnlyLabelWidget eSampleFormatInfo; + ReadOnlyLabelWidget eSampleID; + ReadOnlyLabelWidget eChecksum; NumEntryTemp eFineTune; NumEntryGain eGain; BoolEntryPlus6 eGainPlus6; @@ -151,6 +236,8 @@ Gtk::Label* lEG2; Gtk::Label* lLFO2; + Gtk::Button buttonSelectSample; + int rowno; int pageno; int firstRowInBlock; @@ -159,9 +246,13 @@ void addProp(BoolEntry& boolentry); void addProp(BoolEntryPlus6& boolentry); void addProp(LabelWidget& labelwidget); + void addLine(Gtk::HBox& line); void addString(const char* labelText, Gtk::Label*& label, Gtk::Entry*& widget); + void addString(const char* labelText, Gtk::Label*& label, + Gtk::Entry*& widget, Gtk::Button*& button); Gtk::Label* addHeader(const char* text); + void addRightHandSide(Gtk::Widget& widget); void nextPage(); void VCFEnabled_toggled(); @@ -183,9 +274,23 @@ void loop_start_changed(); void loop_length_changed(); void loop_infinite_toggled(); + void nullOutSampleReference(); int update_model; + /** + * Workaround for the circumstance that C++ does not allow to cast to + * member pointers. + */ + template + union ClassMemberPtr { + memberT classT::*pmember; + void* pvoid; + + ClassMemberPtr(size_t s) : pvoid((void*)s) {} + ClassMemberPtr(void* p) : pvoid(p) {} + }; + // connect a widget to a setter function in DimRegionEdit template void connect(C& widget, @@ -218,16 +323,16 @@ sigc::mem_fun(widget, &C::get_value))); } - // loop through all dimregions being edited ant set a value in + // loop through all dimregions being edited and set a value in // each of them template void set_many(T value, sigc::slot setter) { if (update_model == 0) { for (std::set::iterator i = dimregs.begin() ; - i != dimregs.end() ; i++) + i != dimregs.end() ; ++i) { - dimreg_changed_signal(*i); + DimRegionChangeGuard(this, *i); setter(this, *i, value); } } @@ -255,6 +360,8 @@ void set_LoopLength(gig::DimensionRegion* d, uint32_t value); void set_LoopInfinite(gig::DimensionRegion* d, bool value); void set_LoopPlayCount(gig::DimensionRegion* d, uint32_t value); + + void onButtonSelectSamplePressed(); }; #endif