--- gigedit/trunk/src/gigedit/dimregionedit.cpp 2008/01/04 19:42:45 1623 +++ gigedit/trunk/src/gigedit/dimregionedit.cpp 2013/03/03 17:26:11 2430 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2008 Andreas Persson + * Copyright (C) 2006-2013 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,96 +20,228 @@ #include "dimregionedit.h" #include "global.h" +#include "compat.h" + +VelocityCurve::VelocityCurve(double (gig::DimensionRegion::*getter)(uint8_t)) : + getter(getter), dimreg(0) { + set_size_request(80, 80); +} + +#if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2 +bool VelocityCurve::on_expose_event(GdkEventExpose* e) { + const Cairo::RefPtr& cr = + get_window()->create_cairo_context(); +#if 0 +} +#endif +#else +bool VelocityCurve::on_draw(const Cairo::RefPtr& cr) { +#endif + if (dimreg) { + int w = get_width(); + int h = get_height(); + + for (int pass = 0 ; pass < 2 ; pass++) { + for (double x = 0 ; x <= w ; x++) { + int vel = int(x * (127 - 1e-10) / w + 1); + double y = (1 - (dimreg->*getter)(vel)) * (h - 3) + 1.5; + + if (x < 1e-10) { + cr->move_to(x, y); + } else { + cr->line_to(x, y); + } + } + if (pass == 0) { + cr->line_to(w, h); + cr->line_to(0, h); + cr->set_source_rgba(0.5, 0.44, 1.0, is_sensitive() ? 0.2 : 0.1); + cr->fill(); + } else { + cr->set_line_width(3); + cr->set_source_rgba(0.5, 0.44, 1.0, is_sensitive() ? 1.0 : 0.3); + cr->stroke(); + } + } + } + return true; +} + + +CrossfadeCurve::CrossfadeCurve() : dimreg(0) { + set_size_request(280, 80); +} + +#if (GTKMM_MAJOR_VERSION == 2 && GTKMM_MINOR_VERSION < 90) || GTKMM_MAJOR_VERSION < 2 +bool CrossfadeCurve::on_expose_event(GdkEventExpose* e) { + const Cairo::RefPtr& cr = + get_window()->create_cairo_context(); +#if 0 +} +#endif +#else +bool CrossfadeCurve::on_draw(const Cairo::RefPtr& cr) { +#endif + if (dimreg) { + cr->translate(1.5, 0); + + // first, draw curves for the other layers + gig::Region* region = dimreg->GetParent(); + int dimregno; + for (dimregno = 0 ; dimregno < region->DimensionRegions ; dimregno++) { + if (region->pDimensionRegions[dimregno] == dimreg) { + break; + } + } + int bitcount = 0; + int layer_bit = 0; + for (int dim = 0 ; dim < region->Dimensions ; dim++) { + if (region->pDimensionDefinitions[dim].dimension == + gig::dimension_layer) { + layer_bit = 1 << bitcount; + + int mask = + ~(((1 << region->pDimensionDefinitions[dim].bits) - 1) << + bitcount); + int c = dimregno & mask; // mask away the layer dimension + + for (int i = 0 ; i < region->pDimensionDefinitions[dim].zones ; + i++) { + gig::DimensionRegion* d = + region->pDimensionRegions[c + (i << bitcount)]; + if (d != dimreg) { + draw_one_curve(cr, d, false); + } + } + break; + } + bitcount += region->pDimensionDefinitions[dim].bits; + } + + // then, draw the currently selected layer + draw_one_curve(cr, dimreg, is_sensitive()); + } + return true; +} + +void CrossfadeCurve::draw_one_curve(const Cairo::RefPtr& cr, + const gig::DimensionRegion* d, + bool sensitive) { + int w = get_width(); + int h = get_height(); + + if (d->Crossfade.out_end) { + for (int pass = 0 ; pass < 2 ; pass++) { + cr->move_to(d->Crossfade.in_start / 127.0 * (w - 3), h); + cr->line_to(d->Crossfade.in_end / 127.0 * (w - 3), 1.5); + cr->line_to(d->Crossfade.out_start / 127.0 * (w - 3), 1.5); + cr->line_to(d->Crossfade.out_end / 127.0 * (w - 3), h); + + if (pass == 0) { + cr->set_source_rgba(0.5, 0.44, 1.0, sensitive ? 0.2 : 0.1); + cr->fill(); + } else { + cr->set_line_width(3); + cr->set_source_rgba(0.5, 0.44, 1.0, sensitive ? 1.0 : 0.3); + cr->stroke(); + } + } + } +} + DimRegionEdit::DimRegionEdit() : - eEG1PreAttack("Pre-attack", 0, 100, 2), - eEG1Attack("Attack", 0, 60, 3), - eEG1Decay1("Decay 1", 0.005, 60, 3), - eEG1Decay2("Decay 2", 0, 60, 3), - eEG1InfiniteSustain("Infinite sustain"), - eEG1Sustain("Sustain", 0, 100, 2), - eEG1Release("Release", 0, 60, 3), - eEG1Hold("Hold"), - eEG1Controller("Controller"), - eEG1ControllerInvert("Controller invert"), - eEG1ControllerAttackInfluence("Controller attack influence", 0, 3), - eEG1ControllerDecayInfluence("Controller decay influence", 0, 3), - eEG1ControllerReleaseInfluence("Controller release influence", 0, 3), - eLFO1Frequency("Frequency", 0.1, 10, 2), - eLFO1InternalDepth("Internal depth", 0, 1200), - eLFO1ControlDepth("Control depth", 0, 1200), - eLFO1Controller("Controller"), - eLFO1FlipPhase("Flip phase"), - eLFO1Sync("Sync"), - eEG2PreAttack("Pre-attack", 0, 100, 2), - eEG2Attack("Attack", 0, 60, 3), - eEG2Decay1("Decay 1", 0.005, 60, 3), - eEG2Decay2("Decay 2", 0, 60, 3), - eEG2InfiniteSustain("Infinite sustain"), - eEG2Sustain("Sustain", 0, 100, 2), - eEG2Release("Release", 0, 60, 3), - eEG2Controller("Controller"), - eEG2ControllerInvert("Controller invert"), - eEG2ControllerAttackInfluence("Controller attack influence", 0, 3), - eEG2ControllerDecayInfluence("Controller decay influence", 0, 3), - eEG2ControllerReleaseInfluence("Controller release influence", 0, 3), - eLFO2Frequency("Frequency", 0.1, 10, 2), - eLFO2InternalDepth("Internal depth", 0, 1200), - eLFO2ControlDepth("Control depth", 0, 1200), - eLFO2Controller("Controller"), - eLFO2FlipPhase("Flip phase"), - eLFO2Sync("Sync"), - eEG3Attack("Attack", 0, 10, 3), - eEG3Depth("Depth", -1200, 1200), - eLFO3Frequency("Frequency", 0.1, 10, 2), - eLFO3InternalDepth("Internal depth", 0, 1200), - eLFO3ControlDepth("Control depth", 0, 1200), - eLFO3Controller("Controller"), - eLFO3Sync("Sync"), - eVCFEnabled("Enabled"), - eVCFType("Type"), - eVCFCutoffController("Cutoff controller"), - eVCFCutoffControllerInvert("Cutoff controller invert"), - eVCFCutoff("Cutoff"), - eVCFVelocityCurve("Velocity curve"), - eVCFVelocityScale("Velocity scale"), - eVCFVelocityDynamicRange("Velocity dynamic range", 0, 4), - eVCFResonance("Resonance"), - eVCFResonanceDynamic("Resonance dynamic"), - eVCFResonanceController("Resonance controller"), - eVCFKeyboardTracking("Keyboard tracking"), - eVCFKeyboardTrackingBreakpoint("Keyboard tracking breakpoint"), - eVelocityResponseCurve("Velocity response curve"), - eVelocityResponseDepth("Velocity response depth", 0, 4), - eVelocityResponseCurveScaling("Velocity response curve scaling"), - eReleaseVelocityResponseCurve("Release velocity response curve"), - eReleaseVelocityResponseDepth("Release velocity response depth", 0, 4), - eReleaseTriggerDecay("Release trigger decay", 0, 8), - eCrossfade_in_start("Crossfade-in start"), - eCrossfade_in_end("Crossfade-in end"), - eCrossfade_out_start("Crossfade-out start"), - eCrossfade_out_end("Crossfade-out end"), - ePitchTrack("Pitch track"), - eDimensionBypass("Dimension bypass"), - ePan("Pan", -64, 63), - eSelfMask("Self mask"), - eAttenuationController("Attenuation controller"), - eInvertAttenuationController("Invert attenuation controller"), - eAttenuationControllerThreshold("Attenuation controller threshold"), - eChannelOffset("Channel offset", 0, 9), - eSustainDefeat("Sustain defeat"), - eMSDecode("MS decode"), - eSampleStartOffset("Sample start offset", 0, 2000), - eUnityNote("Unity note"), - eFineTune("Fine tune", -49, 50), - eGain("Gain", -96, 0, 2, -655360), - eGainPlus6("Gain +6dB", eGain, 6 * -655360), - eSampleLoopEnabled("Enabled"), - eSampleLoopStart("Loop start positon"), - eSampleLoopLength("Loop size"), - eSampleLoopType("Loop type"), - eSampleLoopInfinite("Infinite loop"), - eSampleLoopPlayCount("Playback count", 1), + velocity_curve(&gig::DimensionRegion::GetVelocityAttenuation), + release_curve(&gig::DimensionRegion::GetVelocityRelease), + cutoff_curve(&gig::DimensionRegion::GetVelocityCutoff), + eEG1PreAttack(_("Pre-attack"), 0, 100, 2), + eEG1Attack(_("Attack"), 0, 60, 3), + eEG1Decay1(_("Decay 1"), 0.005, 60, 3), + eEG1Decay2(_("Decay 2"), 0, 60, 3), + eEG1InfiniteSustain(_("Infinite sustain")), + eEG1Sustain(_("Sustain"), 0, 100, 2), + eEG1Release(_("Release"), 0, 60, 3), + eEG1Hold(_("Hold")), + eEG1Controller(_("Controller")), + eEG1ControllerInvert(_("Controller invert")), + eEG1ControllerAttackInfluence(_("Controller attack influence"), 0, 3), + eEG1ControllerDecayInfluence(_("Controller decay influence"), 0, 3), + eEG1ControllerReleaseInfluence(_("Controller release influence"), 0, 3), + eLFO1Frequency(_("Frequency"), 0.1, 10, 2), + eLFO1InternalDepth(_("Internal depth"), 0, 1200), + eLFO1ControlDepth(_("Control depth"), 0, 1200), + eLFO1Controller(_("Controller")), + eLFO1FlipPhase(_("Flip phase")), + eLFO1Sync(_("Sync")), + eEG2PreAttack(_("Pre-attack"), 0, 100, 2), + eEG2Attack(_("Attack"), 0, 60, 3), + eEG2Decay1(_("Decay 1"), 0.005, 60, 3), + eEG2Decay2(_("Decay 2"), 0, 60, 3), + eEG2InfiniteSustain(_("Infinite sustain")), + eEG2Sustain(_("Sustain"), 0, 100, 2), + eEG2Release(_("Release"), 0, 60, 3), + eEG2Controller(_("Controller")), + eEG2ControllerInvert(_("Controller invert")), + eEG2ControllerAttackInfluence(_("Controller attack influence"), 0, 3), + eEG2ControllerDecayInfluence(_("Controller decay influence"), 0, 3), + eEG2ControllerReleaseInfluence(_("Controller release influence"), 0, 3), + eLFO2Frequency(_("Frequency"), 0.1, 10, 2), + eLFO2InternalDepth(_("Internal depth"), 0, 1200), + eLFO2ControlDepth(_("Control depth"), 0, 1200), + eLFO2Controller(_("Controller")), + eLFO2FlipPhase(_("Flip phase")), + eLFO2Sync(_("Sync")), + eEG3Attack(_("Attack"), 0, 10, 3), + eEG3Depth(_("Depth"), -1200, 1200), + eLFO3Frequency(_("Frequency"), 0.1, 10, 2), + eLFO3InternalDepth(_("Internal depth"), 0, 1200), + eLFO3ControlDepth(_("Control depth"), 0, 1200), + eLFO3Controller(_("Controller")), + eLFO3Sync(_("Sync")), + eVCFEnabled(_("Enabled")), + eVCFType(_("Type")), + eVCFCutoffController(_("Cutoff controller")), + eVCFCutoffControllerInvert(_("Cutoff controller invert")), + eVCFCutoff(_("Cutoff")), + eVCFVelocityCurve(_("Velocity curve")), + eVCFVelocityScale(_("Velocity scale")), + eVCFVelocityDynamicRange(_("Velocity dynamic range"), 0, 4), + eVCFResonance(_("Resonance")), + eVCFResonanceDynamic(_("Resonance dynamic")), + eVCFResonanceController(_("Resonance controller")), + eVCFKeyboardTracking(_("Keyboard tracking")), + eVCFKeyboardTrackingBreakpoint(_("Keyboard tracking breakpoint")), + eVelocityResponseCurve(_("Velocity response curve")), + eVelocityResponseDepth(_("Velocity response depth"), 0, 4), + eVelocityResponseCurveScaling(_("Velocity response curve scaling")), + eReleaseVelocityResponseCurve(_("Release velocity response curve")), + eReleaseVelocityResponseDepth(_("Release velocity response depth"), 0, 4), + eReleaseTriggerDecay(_("Release trigger decay"), 0, 8), + eCrossfade_in_start(_("Crossfade-in start")), + eCrossfade_in_end(_("Crossfade-in end")), + eCrossfade_out_start(_("Crossfade-out start")), + eCrossfade_out_end(_("Crossfade-out end")), + ePitchTrack(_("Pitch track")), + eDimensionBypass(_("Dimension bypass")), + ePan(_("Pan"), -64, 63), + eSelfMask(_("Self mask")), + eAttenuationController(_("Attenuation controller")), + eInvertAttenuationController(_("Invert attenuation controller")), + eAttenuationControllerThreshold(_("Attenuation controller threshold")), + eChannelOffset(_("Channel offset"), 0, 9), + eSustainDefeat(_("Sustain defeat")), + eMSDecode(_("MS decode")), + eSampleStartOffset(_("Sample start offset"), 0, 2000), + eUnityNote(_("Unity note")), + eFineTune(_("Fine tune"), -49, 50), + eGain(_("Gain"), -96, 0, 2, -655360), + eGainPlus6(_("Gain +6dB"), eGain, 6 * -655360), + eSampleLoopEnabled(_("Enabled")), + eSampleLoopStart(_("Loop start positon")), + eSampleLoopLength(_("Loop size")), + eSampleLoopType(_("Loop type")), + eSampleLoopInfinite(_("Infinite loop")), + eSampleLoopPlayCount(_("Playback count"), 1), update_model(0) { connect(eEG1PreAttack, &gig::DimensionRegion::EG1PreAttack); @@ -265,19 +397,23 @@ firstRowInBlock = 0; addHeader(_("Mandatory Settings")); - addString("Sample", lSample, wSample); + addString(_("Sample"), lSample, wSample); //TODO: the following would break drag&drop: wSample->property_editable().set_value(false); or this: wSample->set_editable(false); +#ifdef OLD_TOOLTIPS tooltips.set_tip(*wSample, _("Drop a sample here")); +#else + wSample->set_tooltip_text(_("Drop a sample here")); +#endif addProp(eUnityNote); addHeader(_("Optional Settings")); addProp(eSampleStartOffset); addProp(eChannelOffset); - addHeader("Loops"); + addHeader(_("Loops")); addProp(eSampleLoopEnabled); addProp(eSampleLoopStart); addProp(eSampleLoopLength); { - const char* choices[] = { "normal", "bidirectional", "backward", 0 }; + const char* choices[] = { _("normal"), _("bidirectional"), _("backward"), 0 }; static const uint32_t values[] = { gig::loop_type_normal, gig::loop_type_bidirectional, @@ -317,8 +453,8 @@ addProp(eLFO1InternalDepth); addProp(eLFO1ControlDepth); { - const char* choices[] = { "internal", "modwheel", "breath", - "internal+modwheel", "internal+breath", 0 }; + const char* choices[] = { _("internal"), _("modwheel"), _("breath"), + _("internal+modwheel"), _("internal+breath"), 0 }; static const gig::lfo1_ctrl_t values[] = { gig::lfo1_ctrl_internal, gig::lfo1_ctrl_modwheel, @@ -331,7 +467,7 @@ addProp(eLFO1Controller); addProp(eLFO1FlipPhase); addProp(eLFO1Sync); - addHeader("Crossfade"); + addHeader(_("Crossfade")); addProp(eAttenuationController); addProp(eInvertAttenuationController); addProp(eAttenuationControllerThreshold); @@ -340,13 +476,28 @@ addProp(eCrossfade_out_start); addProp(eCrossfade_out_end); + Gtk::Frame* frame = new Gtk::Frame; + frame->add(crossfade_curve); + table[pageno]->attach(*frame, 1, 3, rowno, rowno + 1, + Gtk::SHRINK, Gtk::SHRINK); + rowno++; + + eCrossfade_in_start.signal_value_changed().connect( + sigc::mem_fun(crossfade_curve, &CrossfadeCurve::queue_draw)); + eCrossfade_in_end.signal_value_changed().connect( + sigc::mem_fun(crossfade_curve, &CrossfadeCurve::queue_draw)); + eCrossfade_out_start.signal_value_changed().connect( + sigc::mem_fun(crossfade_curve, &CrossfadeCurve::queue_draw)); + eCrossfade_out_end.signal_value_changed().connect( + sigc::mem_fun(crossfade_curve, &CrossfadeCurve::queue_draw)); + nextPage(); addHeader(_("General Filter Settings")); addProp(eVCFEnabled); { - const char* choices[] = { "lowpass", "lowpassturbo", "bandpass", - "highpass", "bandreject", 0 }; + const char* choices[] = { _("lowpass"), _("lowpassturbo"), _("bandpass"), + _("highpass"), _("bandreject"), 0 }; static const gig::vcf_type_t values[] = { gig::vcf_type_lowpass, gig::vcf_type_lowpassturbo, @@ -358,9 +509,9 @@ } addProp(eVCFType); { - const char* choices[] = { "none", "none2", "modwheel", "effect1", "effect2", - "breath", "foot", "sustainpedal", "softpedal", - "genpurpose7", "genpurpose8", "aftertouch", 0 }; + const char* choices[] = { _("none"), _("none2"), _("modwheel"), _("effect1"), _("effect2"), + _("breath"), _("foot"), _("sustainpedal"), _("softpedal"), + _("genpurpose7"), _("genpurpose8"), _("aftertouch"), 0 }; static const gig::vcf_cutoff_ctrl_t values[] = { gig::vcf_cutoff_ctrl_none, gig::vcf_cutoff_ctrl_none2, @@ -380,7 +531,7 @@ addProp(eVCFCutoffController); addProp(eVCFCutoffControllerInvert); addProp(eVCFCutoff); - const char* curve_type_texts[] = { "nonlinear", "linear", "special", 0 }; + const char* curve_type_texts[] = { _("nonlinear"), _("linear"), _("special"), 0 }; static const gig::curve_type_t curve_type_values[] = { gig::curve_type_nonlinear, gig::curve_type_linear, @@ -390,11 +541,27 @@ addProp(eVCFVelocityCurve); addProp(eVCFVelocityScale); addProp(eVCFVelocityDynamicRange); + + eVCFCutoffController.signal_value_changed().connect( + sigc::mem_fun(cutoff_curve, &VelocityCurve::queue_draw)); + eVCFVelocityCurve.signal_value_changed().connect( + sigc::mem_fun(cutoff_curve, &VelocityCurve::queue_draw)); + eVCFVelocityScale.signal_value_changed().connect( + sigc::mem_fun(cutoff_curve, &VelocityCurve::queue_draw)); + eVCFVelocityDynamicRange.signal_value_changed().connect( + sigc::mem_fun(cutoff_curve, &VelocityCurve::queue_draw)); + + frame = new Gtk::Frame; + frame->add(cutoff_curve); + table[pageno]->attach(*frame, 1, 3, rowno, rowno + 1, + Gtk::SHRINK, Gtk::SHRINK); + rowno++; + addProp(eVCFResonance); addProp(eVCFResonanceDynamic); { - const char* choices[] = { "none", "genpurpose3", "genpurpose4", - "genpurpose5", "genpurpose6", 0 }; + const char* choices[] = { _("none"), _("genpurpose3"), _("genpurpose4"), + _("genpurpose5"), _("genpurpose6"), 0 }; static const gig::vcf_res_ctrl_t values[] = { gig::vcf_res_ctrl_none, gig::vcf_res_ctrl_genpurpose3, @@ -428,8 +595,8 @@ addProp(eLFO2InternalDepth); addProp(eLFO2ControlDepth); { - const char* choices[] = { "internal", "modwheel", "foot", - "internal+modwheel", "internal+foot", 0 }; + const char* choices[] = { _("internal"), _("modwheel"), _("foot"), + _("internal+modwheel"), _("internal+foot"), 0 }; static const gig::lfo2_ctrl_t values[] = { gig::lfo2_ctrl_internal, gig::lfo2_ctrl_modwheel, @@ -456,8 +623,8 @@ addProp(eLFO3InternalDepth); addProp(eLFO3ControlDepth); { - const char* choices[] = { "internal", "modwheel", "aftertouch", - "internal+modwheel", "internal+aftertouch", 0 }; + const char* choices[] = { _("internal"), _("modwheel"), _("aftertouch"), + _("internal+modwheel"), _("internal+aftertouch"), 0 }; static const gig::lfo3_ctrl_t values[] = { gig::lfo3_ctrl_internal, gig::lfo3_ctrl_modwheel, @@ -472,17 +639,44 @@ nextPage(); + addHeader(_("Velocity Reponse")); eVelocityResponseCurve.set_choices(curve_type_texts, curve_type_values); addProp(eVelocityResponseCurve); addProp(eVelocityResponseDepth); addProp(eVelocityResponseCurveScaling); + + eVelocityResponseCurve.signal_value_changed().connect( + sigc::mem_fun(velocity_curve, &VelocityCurve::queue_draw)); + eVelocityResponseDepth.signal_value_changed().connect( + sigc::mem_fun(velocity_curve, &VelocityCurve::queue_draw)); + eVelocityResponseCurveScaling.signal_value_changed().connect( + sigc::mem_fun(velocity_curve, &VelocityCurve::queue_draw)); + + frame = new Gtk::Frame; + frame->add(velocity_curve); + table[pageno]->attach(*frame, 1, 3, rowno, rowno + 1, + Gtk::SHRINK, Gtk::SHRINK); + rowno++; + + addHeader(_("Release Velocity Reponse")); eReleaseVelocityResponseCurve.set_choices(curve_type_texts, curve_type_values); addProp(eReleaseVelocityResponseCurve); addProp(eReleaseVelocityResponseDepth); + + eReleaseVelocityResponseCurve.signal_value_changed().connect( + sigc::mem_fun(release_curve, &VelocityCurve::queue_draw)); + eReleaseVelocityResponseDepth.signal_value_changed().connect( + sigc::mem_fun(release_curve, &VelocityCurve::queue_draw)); + frame = new Gtk::Frame; + frame->add(release_curve); + table[pageno]->attach(*frame, 1, 3, rowno, rowno + 1, + Gtk::SHRINK, Gtk::SHRINK); + rowno++; + addProp(eReleaseTriggerDecay); { - const char* choices[] = { "none", "effect4depth", "effect5depth", 0 }; + const char* choices[] = { _("none"), _("effect4depth"), _("effect5depth"), 0 }; static const gig::dim_bypass_ctrl_t values[] = { gig::dim_bypass_ctrl_none, gig::dim_bypass_ctrl_94, @@ -539,13 +733,13 @@ eSampleLoopInfinite.signal_value_changed().connect( sigc::mem_fun(*this, &DimRegionEdit::loop_infinite_toggled)); - append_page(*table[0], "Sample"); - append_page(*table[1], "Amplitude (1)"); - append_page(*table[2], "Amplitude (2)"); - append_page(*table[3], "Filter (1)"); - append_page(*table[4], "Filter (2)"); - append_page(*table[5], "Pitch"); - append_page(*table[6], "Misc"); + append_page(*table[0], _("Sample")); + append_page(*table[1], _("Amplitude (1)")); + append_page(*table[2], _("Amplitude (2)")); + append_page(*table[3], _("Filter (1)")); + append_page(*table[4], _("Filter (2)")); + append_page(*table[5], _("Pitch")); + append_page(*table[6], _("Misc")); } DimRegionEdit::~DimRegionEdit() @@ -556,7 +750,7 @@ Gtk::Entry*& widget) { label = new Gtk::Label(Glib::ustring(labelText) + ":"); - label->set_alignment(Gtk::ALIGN_LEFT); + label->set_alignment(Gtk::ALIGN_START); table[pageno]->attach(*label, 1, 2, rowno, rowno + 1, Gtk::FILL, Gtk::SHRINK); @@ -582,7 +776,7 @@ str += ""; Gtk::Label* label = new Gtk::Label(str); label->set_use_markup(); - label->set_alignment(Gtk::ALIGN_LEFT); + label->set_alignment(Gtk::ALIGN_START); table[pageno]->attach(*label, 0, 3, rowno, rowno + 1, Gtk::FILL, Gtk::SHRINK); rowno++; @@ -630,6 +824,10 @@ void DimRegionEdit::set_dim_region(gig::DimensionRegion* d) { dimregion = d; + velocity_curve.set_dim_region(d); + release_curve.set_dim_region(d); + cutoff_curve.set_dim_region(d); + crossfade_curve.set_dim_region(d); set_sensitive(d); if (!d) return; @@ -730,7 +928,7 @@ d->pSample ? d->pSample->LoopPlayCount : 0); update_model--; - wSample->set_text(d->pSample ? d->pSample->pInfo->Name.c_str() : "NULL"); + wSample->set_text(d->pSample ? d->pSample->pInfo->Name.c_str() : _("NULL")); update_loop_elements(); VCFEnabled_toggled(); @@ -745,6 +943,7 @@ eVCFVelocityCurve.set_sensitive(sensitive); eVCFVelocityScale.set_sensitive(sensitive); eVCFVelocityDynamicRange.set_sensitive(sensitive); + cutoff_curve.set_sensitive(sensitive); eVCFResonance.set_sensitive(sensitive); eVCFResonanceController.set_sensitive(sensitive); eVCFKeyboardTracking.set_sensitive(sensitive); @@ -793,8 +992,8 @@ eVCFCutoffControllerInvert.set_sensitive(hasController); eVCFCutoff.set_sensitive(!hasController); eVCFResonanceDynamic.set_sensitive(!hasController); - eVCFVelocityScale.label.set_text(hasController ? "Minimum cutoff:" : - "Velocity scale:"); + eVCFVelocityScale.label.set_text(hasController ? _("Minimum cutoff:") : + _("Velocity scale:")); } void DimRegionEdit::VCFResonanceController_changed() @@ -837,6 +1036,7 @@ eCrossfade_in_end.set_sensitive(hasController); eCrossfade_out_start.set_sensitive(hasController); eCrossfade_out_end.set_sensitive(hasController); + crossfade_curve.set_sensitive(hasController); } void DimRegionEdit::LFO1Controller_changed() @@ -958,27 +1158,60 @@ // currently commented because we're sending a similar signal in MainWindow::on_sample_label_drop_drag_data_received() //dimreg_to_be_changed_signal.emit(dimregion); + // make sure stereo samples always are the same in both + // dimregs in the samplechannel dimension + int nbDimregs = 1; + gig::DimensionRegion* d[2] = { dimregion, 0 }; + if (sample->Channels == 2) { + gig::Region* region = dimregion->GetParent(); + + int bitcount = 0; + int stereo_bit = 0; + for (int dim = 0 ; dim < region->Dimensions ; dim++) { + if (region->pDimensionDefinitions[dim].dimension == gig::dimension_samplechannel) { + stereo_bit = 1 << bitcount; + break; + } + bitcount += region->pDimensionDefinitions[dim].bits; + } + + if (stereo_bit) { + int dimregno; + for (dimregno = 0 ; dimregno < region->DimensionRegions ; dimregno++) { + if (region->pDimensionRegions[dimregno] == dimregion) { + break; + } + } + d[0] = region->pDimensionRegions[dimregno & ~stereo_bit]; + d[1] = region->pDimensionRegions[dimregno | stereo_bit]; + nbDimregs = 2; + } + } + gig::Sample* oldref = dimregion->pSample; - dimregion->pSample = sample; - // copy sample information from Sample to DimensionRegion + for (int i = 0 ; i < nbDimregs ; i++) { + d[i]->pSample = sample; - dimregion->UnityNote = sample->MIDIUnityNote; - dimregion->FineTune = sample->FineTune; + // copy sample information from Sample to DimensionRegion - int loops = sample->Loops ? 1 : 0; - while (dimregion->SampleLoops > loops) { - dimregion->DeleteSampleLoop(&dimregion->pSampleLoops[0]); - } - while (dimregion->SampleLoops < sample->Loops) { - DLS::sample_loop_t loop; - dimregion->AddSampleLoop(&loop); - } - if (loops) { - dimregion->pSampleLoops[0].Size = sizeof(DLS::sample_loop_t); - dimregion->pSampleLoops[0].LoopType = sample->LoopType; - dimregion->pSampleLoops[0].LoopStart = sample->LoopStart; - dimregion->pSampleLoops[0].LoopLength = sample->LoopEnd - sample->LoopStart + 1; + d[i]->UnityNote = sample->MIDIUnityNote; + d[i]->FineTune = sample->FineTune; + + int loops = sample->Loops ? 1 : 0; + while (d[i]->SampleLoops > loops) { + d[i]->DeleteSampleLoop(&d[i]->pSampleLoops[0]); + } + while (d[i]->SampleLoops < sample->Loops) { + DLS::sample_loop_t loop; + d[i]->AddSampleLoop(&loop); + } + if (loops) { + d[i]->pSampleLoops[0].Size = sizeof(DLS::sample_loop_t); + d[i]->pSampleLoops[0].LoopType = sample->LoopType; + d[i]->pSampleLoops[0].LoopStart = sample->LoopStart; + d[i]->pSampleLoops[0].LoopLength = sample->LoopEnd - sample->LoopStart + 1; + } } // update ui