/* -*- c++ -*- * Copyright (C) 2006, 2007 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 * published by the Free Software Foundation; either version 2, or (at * your option) any later version. * * This program 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with program; see the file COPYING. If not, write to the Free * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA * 02110-1301 USA. */ #ifndef GIGEDIT_MAINWINDOW_H #define GIGEDIT_MAINWINDOW_H #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "regionchooser.h" #include "dimregionchooser.h" extern bool update_gui; class MainWindow; class PropDialog : public Gtk::Window { public: PropDialog(); void set_info(DLS::Info* info); protected: Gtk::Table table; Gtk::Label label[16]; Gtk::Entry entry[16]; }; class InstrumentProps : public Gtk::Window { public: InstrumentProps(); void set_instrument(gig::Instrument* instrument); protected: Gtk::VBox vbox; Gtk::HButtonBox buttonBox; Gtk::Button quitButton; Gtk::Table table; Gtk::Label label[10]; Gtk::Entry entry[8]; Gtk::CheckButton check[2]; }; class LoadDialog : public Gtk::Dialog { public: LoadDialog(); void set_fraction(float fraction) { progressBar.set_fraction(fraction); } protected: Gtk::ProgressBar progressBar; }; class Loader : public sigc::trackable { public: Loader(const char* filename); void launch(); Glib::Dispatcher& signal_progress(); Glib::Dispatcher& signal_finished(); void progress_callback(float fraction); float get_progress(); const char* filename; gig::File* gig; private: Glib::Thread* thread; void thread_function(); Glib::Dispatcher finished_dispatcher; Glib::Dispatcher progress_dispatcher; Glib::Mutex progressMutex; float progress; }; class LabelWidget { public: Gtk::Label label; Gtk::Widget& widget; LabelWidget(char* labelText, Gtk::Widget& widget); void set_sensitive(bool sensitive = true); }; template class NumEntry : public LabelWidget { protected: Gtk::Adjustment adjust; Gtk::HScale scale; Gtk::SpinButton spinbutton; Gtk::HBox box; T2* dimreg; public: NumEntry(char* labelText, double lower = 0, double upper = 127, int decimals = 0); void set_value(double value) { spinbutton.set_value(value); } Glib::SignalProxy0 signal_value_changed() { return spinbutton.signal_value_changed(); } double get_value() const { return spinbutton.get_value(); } }; template NumEntry::NumEntry(char* labelText, double lower, double upper, int decimals) : adjust(lower, lower, upper, 1, 10), scale(adjust), spinbutton(adjust), LabelWidget(labelText, box) { spinbutton.set_digits(decimals); scale.set_draw_value(false); box.pack_start(spinbutton, Gtk::PACK_SHRINK); box.add(scale); } class NumEntryGain : public NumEntry { private: void value_changed(); public: NumEntryGain(char* labelText, double lower, double upper, int decimals); void set_dimreg(gig::DimensionRegion* dimreg); }; template class NumEntryX : public NumEntry { private: T& (*access)(gig::DimensionRegion*); void value_changed(); public: NumEntryX(char* labelText, T& (*access)(gig::DimensionRegion*), double lower = 0, double upper = 127, int decimals = 0); void set_dimreg(gig::DimensionRegion* dimreg); }; template NumEntryX::NumEntryX(char* labelText, T& (*access)(gig::DimensionRegion*), double lower, double upper, int decimals) : NumEntry(labelText, lower, upper, decimals), access(access) { spinbutton.signal_value_changed().connect( sigc::mem_fun(*this, &NumEntryX::value_changed)); } template void NumEntryX::value_changed() { if (dimreg && update_gui) { access(dimreg) = T(spinbutton.get_value()); } } template void NumEntryX::set_dimreg(gig::DimensionRegion* dimreg) { this->dimreg = 0; set_value(access(dimreg)); this->dimreg = dimreg; } class NoteEntry : public NumEntryX { public: NoteEntry(char* labelText, uint8_t& (*access)(gig::DimensionRegion*)); private: int on_input(double* new_value); bool on_output(); }; template class NumEntryTemp : public NumEntry { using NumEntry::spinbutton; using NumEntry::dimreg; private: T T2::* param; void value_changed(); public: NumEntryTemp(char* labelText, T T2::* param, double lower = 0, double upper = 127, int decimals = 0); void set_dimreg(gig::DimensionRegion* dimreg); }; template NumEntryTemp::NumEntryTemp(char* labelText, T T2::* param, double lower, double upper, int decimals) : NumEntry(labelText, lower, upper, decimals), param(param) { spinbutton.signal_value_changed().connect( sigc::mem_fun(*this, &NumEntryTemp::value_changed)); } template void NumEntryTemp::value_changed() { if (dimreg && update_gui) { dimreg->*param = T(spinbutton.get_value()); } } template void NumEntryTemp::set_dimreg(gig::DimensionRegion* dimreg) { this->dimreg = 0; set_value(dimreg->*param); this->dimreg = dimreg; } class NumEntryPermille : public NumEntry { private: uint16_t gig::DimensionRegion::* param; void value_changed(); public: NumEntryPermille(char* labelText, uint16_t gig::DimensionRegion::* param, double lower = 0, double upper = 127, int decimals = 0); void set_dimreg(gig::DimensionRegion* dimreg); }; template class ChoiceEntry : public LabelWidget { private: Gtk::ComboBoxText combobox; Gtk::Alignment align; T gig::DimensionRegion::* param; gig::DimensionRegion* dimreg; void value_changed(); const T* values; public: ChoiceEntry(char* labelText, T gig::DimensionRegion::* param); void set_choices(char** texts, const T* values); void set_dimreg(gig::DimensionRegion* dimreg); int get_active_row_number() { return combobox.get_active_row_number(); } Glib::SignalProxy0 signal_changed() { return combobox.signal_changed(); } }; template ChoiceEntry::ChoiceEntry(char* labelText, T gig::DimensionRegion::* param) : align(0, 0, 0, 0), LabelWidget(labelText, align), param(param) { combobox.signal_changed().connect( sigc::mem_fun(*this, &ChoiceEntry::value_changed)); align.add(combobox); } template void ChoiceEntry::set_choices(char** texts, const T* values) { for (int i = 0 ; texts[i] ; i++) { combobox.append_text(texts[i]); } this->values = values; } template void ChoiceEntry::value_changed() { if (dimreg && update_gui) { int rowno = combobox.get_active_row_number(); if (rowno != -1) dimreg->*param = values[rowno]; } } template void ChoiceEntry::set_dimreg(gig::DimensionRegion* dimreg) { this->dimreg = 0; T value = dimreg->*param; int row = 0; int nb_rows = combobox.get_model()->children().size(); for (; row < nb_rows ; row++) { if (value == values[row]) break; } combobox.set_active(row == nb_rows ? -1 : row); this->dimreg = dimreg; } class ChoiceEntryLeverageCtrl : public LabelWidget { private: Gtk::ComboBoxText combobox; Gtk::Alignment align; gig::leverage_ctrl_t gig::DimensionRegion::* param; gig::DimensionRegion* dimreg; void value_changed(); public: ChoiceEntryLeverageCtrl(char* labelText, gig::leverage_ctrl_t gig::DimensionRegion::* param); void set_dimreg(gig::DimensionRegion* dimreg); int get_active_row_number() { return combobox.get_active_row_number(); } Glib::SignalProxy0 signal_changed() { return combobox.signal_changed(); } }; class BoolEntry : public LabelWidget { private: Gtk::CheckButton checkbutton; bool gig::DimensionRegion::* param; gig::DimensionRegion* dimreg; void value_changed(); public: BoolEntry(char* labelText, bool gig::DimensionRegion::* param); void set_dimreg(gig::DimensionRegion* dimreg); bool get_active() { return checkbutton.get_active(); } Glib::SignalProxy0 signal_toggled() { return checkbutton.signal_toggled(); } }; class MainWindow : public Gtk::Window { public: MainWindow(); virtual ~MainWindow(); void getInfo(const char* filename); protected: Glib::RefPtr actionGroup; Glib::RefPtr uiManager; int rowno; int pageno; int firstRowInBlock; NumEntryTemp eVelocityUpperLimit; NumEntryPermille eEG1PreAttack; NumEntryTemp eEG1Attack; NumEntryTemp eEG1Decay1; NumEntryTemp eEG1Decay2; BoolEntry eEG1InfiniteSustain; NumEntryPermille eEG1Sustain; NumEntryTemp eEG1Release; BoolEntry eEG1Hold; ChoiceEntryLeverageCtrl eEG1Controller; BoolEntry eEG1ControllerInvert; NumEntryTemp eEG1ControllerAttackInfluence; NumEntryTemp eEG1ControllerDecayInfluence; NumEntryTemp eEG1ControllerReleaseInfluence; NumEntryTemp eLFO1Frequency; NumEntryTemp eLFO1InternalDepth; NumEntryTemp eLFO1ControlDepth; ChoiceEntry eLFO1Controller; BoolEntry eLFO1FlipPhase; BoolEntry eLFO1Sync; NumEntryPermille eEG2PreAttack; NumEntryTemp eEG2Attack; NumEntryTemp eEG2Decay1; NumEntryTemp eEG2Decay2; BoolEntry eEG2InfiniteSustain; NumEntryPermille eEG2Sustain; NumEntryTemp eEG2Release; ChoiceEntryLeverageCtrl eEG2Controller; BoolEntry eEG2ControllerInvert; NumEntryTemp eEG2ControllerAttackInfluence; NumEntryTemp eEG2ControllerDecayInfluence; NumEntryTemp eEG2ControllerReleaseInfluence; NumEntryTemp eLFO2Frequency; NumEntryTemp eLFO2InternalDepth; NumEntryTemp eLFO2ControlDepth; ChoiceEntry eLFO2Controller; BoolEntry eLFO2FlipPhase; BoolEntry eLFO2Sync; NumEntryTemp eEG3Attack; NumEntryTemp eEG3Depth; NumEntryTemp eLFO3Frequency; NumEntryTemp eLFO3InternalDepth; NumEntryTemp eLFO3ControlDepth; ChoiceEntry eLFO3Controller; BoolEntry eLFO3Sync; BoolEntry eVCFEnabled; ChoiceEntry eVCFType; ChoiceEntry eVCFCutoffController; BoolEntry eVCFCutoffControllerInvert; NumEntryTemp eVCFCutoff; ChoiceEntry eVCFVelocityCurve; NumEntryTemp eVCFVelocityScale; NumEntryTemp eVCFVelocityDynamicRange; NumEntryTemp eVCFResonance; BoolEntry eVCFResonanceDynamic; ChoiceEntry eVCFResonanceController; BoolEntry eVCFKeyboardTracking; NumEntryTemp eVCFKeyboardTrackingBreakpoint; ChoiceEntry eVelocityResponseCurve; NumEntryTemp eVelocityResponseDepth; NumEntryTemp eVelocityResponseCurveScaling; ChoiceEntry eReleaseVelocityResponseCurve; NumEntryTemp eReleaseVelocityResponseDepth; NumEntryTemp eReleaseTriggerDecay; NumEntryX eCrossfade_in_start; NumEntryX eCrossfade_in_end; NumEntryX eCrossfade_out_start; NumEntryX eCrossfade_out_end; BoolEntry ePitchTrack; ChoiceEntry eDimensionBypass; NumEntryTemp ePan; BoolEntry eSelfMask; ChoiceEntryLeverageCtrl eAttenuationController; BoolEntry eInvertAttenuationController; NumEntryTemp eAttenuationControllerThreshold; NumEntryTemp eChannelOffset; BoolEntry eSustainDefeat; BoolEntry eMSDecode; NumEntryTemp eSampleStartOffset; // NumEntryX eUnityNote; NoteEntry eUnityNote; NumEntryX eFineTune; NumEntryGain eGain; NumEntryX eSampleLoops; void addProp(LabelWidget& labelwidget); void addString(char* labelText, Gtk::Label*& label, Gtk::Entry*& widget); void addHeader(char* text); void nextPage(); RegionChooser m_RegionChooser; DimRegionChooser m_DimRegionChooser; void set_dim_region(gig::DimensionRegion* d); PropDialog propDialog; InstrumentProps instrumentProps; void on_sel_change(); void region_changed(); void dimreg_changed(); void on_loader_progress(); void on_loader_finished(); class ModelColumns : public Gtk::TreeModel::ColumnRecord { public: ModelColumns() { add(m_col_name); add(m_col_instr); } Gtk::TreeModelColumn m_col_name; Gtk::TreeModelColumn m_col_instr; }; ModelColumns m_Columns; Gtk::VBox m_VBox; Gtk::HPaned m_HPaned; Gtk::ScrolledWindow m_ScrolledWindow; Gtk::TreeView m_TreeView; Glib::RefPtr m_refTreeModel; Gtk::Notebook m_Notebook; Gtk::Table* table[5]; // dimensionregion parameter widgets // TODO: remove: Gtk::Label* lSample; Gtk::Entry* wSample; void VCFEnabled_toggled(); void VCFCutoffController_changed(); void VCFResonanceController_changed(); void EG1InfiniteSustain_toggled(); void EG2InfiniteSustain_toggled(); void EG1Controller_changed(); void EG2Controller_changed(); void AttenuationController_changed(); void LFO1Controller_changed(); void LFO2Controller_changed(); void LFO3Controller_changed(); void crossfade1_changed(); void crossfade2_changed(); void crossfade3_changed(); void crossfade4_changed(); void on_action_file_new(); void on_action_file_open(); void on_action_file_save(); void on_action_file_save_as(); void on_action_file_properties(); void on_action_help_about(); LoadDialog* load_dialog; Loader* loader; void load_gig(gig::File* gig, const char* filename); gig::File* file; void on_button_release(GdkEventButton* button); Gtk::Menu* popup_menu; }; #endif