--- gigedit/trunk/src/gigedit/dimregionedit.cpp 2014/05/20 14:35:36 2566 +++ gigedit/trunk/src/gigedit/dimregionedit.cpp 2015/08/30 10:00:49 2841 @@ -1,5 +1,5 @@ /* - * Copyright (C) 2006-2014 Andreas Persson + * Copyright (C) 2006-2015 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 @@ -230,6 +230,8 @@ eMSDecode(_("Decode Mid/Side Recordings")), eSampleStartOffset(_("Sample start offset"), 0, 2000), eUnityNote(_("Unity note")), + eSampleFormatInfo(_("Sample Format")), + eSampleID("Sample ID"), eFineTune(_("Fine tune"), -49, 50), eGain(_("Gain"), -96, 0, 2, -655360), eGainPlus6(_("Gain +6dB"), eGain, 6 * -655360), @@ -239,6 +241,7 @@ eSampleLoopType(_("Loop type")), eSampleLoopInfinite(_("Infinite loop")), eSampleLoopPlayCount(_("Playback count"), 1), + buttonSelectSample(UNICODE_LEFT_ARROW + " " + _("Select Sample")), update_model(0) { connect(eEG1PreAttack, &gig::DimensionRegion::EG1PreAttack); @@ -348,6 +351,9 @@ connect(eSampleLoopLength, &DimRegionEdit::set_LoopLength); connect(eSampleLoopInfinite, &DimRegionEdit::set_LoopInfinite); connect(eSampleLoopPlayCount, &DimRegionEdit::set_LoopPlayCount); + buttonSelectSample.signal_clicked().connect( + sigc::mem_fun(*this, &DimRegionEdit::onButtonSelectSamplePressed) + ); for (int i = 0 ; i < 7 ; i++) { table[i] = new Gtk::Table(3, 1); @@ -358,6 +364,9 @@ eUnityNote.set_tip( _("Note this sample is associated with (a.k.a. 'root note')") ); + buttonSelectSample.set_tooltip_text( + _("Selects the sample of this dimension region on the left hand side's sample tree view.") + ); eSampleStartOffset.set_tip(_("Sample position at which playback should be started")); ePan.set_tip(_("Stereo balance (left/right)")); eChannelOffset.set_tip( @@ -441,7 +450,12 @@ firstRowInBlock = 0; addHeader(_("Mandatory Settings")); - addString(_("Sample"), lSample, wSample); + addString(_("Sample"), lSample, wSample, buttonNullSampleReference); + buttonNullSampleReference->set_label("X"); + buttonNullSampleReference->set_tooltip_text(_("Remove current sample reference (NULL reference). This can be used to define a \"silent\" case where no sample shall be played.")); + buttonNullSampleReference->signal_clicked().connect( + sigc::mem_fun(*this, &DimRegionEdit::nullOutSampleReference) + ); //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, _("Drag & drop a sample here")); @@ -449,6 +463,9 @@ wSample->set_tooltip_text(_("Drag & drop a sample here")); #endif addProp(eUnityNote); + addProp(eSampleFormatInfo); + addProp(eSampleID); + addRightHandSide(buttonSelectSample); addHeader(_("Optional Settings")); addProp(eSampleStartOffset); addProp(eChannelOffset); @@ -823,6 +840,28 @@ rowno++; } +void DimRegionEdit::addString(const char* labelText, Gtk::Label*& label, + Gtk::Entry*& widget, Gtk::Button*& button) +{ + label = new Gtk::Label(Glib::ustring(labelText) + ":"); + label->set_alignment(Gtk::ALIGN_START); + + table[pageno]->attach(*label, 1, 2, rowno, rowno + 1, + Gtk::FILL, Gtk::SHRINK); + + widget = new Gtk::Entry(); + button = new Gtk::Button(); + + Gtk::HBox* hbox = new Gtk::HBox; + hbox->pack_start(*widget); + hbox->pack_start(*button, Gtk::PACK_SHRINK); + + table[pageno]->attach(*hbox, 2, 3, rowno, rowno + 1, + Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK); + + rowno++; +} + Gtk::Label* DimRegionEdit::addHeader(const char* text) { if (firstRowInBlock < rowno - 1) @@ -880,6 +919,12 @@ rowno++; } +void DimRegionEdit::addRightHandSide(Gtk::Widget& widget) +{ + table[pageno]->attach(widget, 2, 3, rowno, rowno + 1, + Gtk::EXPAND | Gtk::FILL, Gtk::SHRINK); + rowno++; +} void DimRegionEdit::set_dim_region(gig::DimensionRegion* d) { @@ -972,6 +1017,38 @@ eMSDecode.set_value(d->MSDecode); eSampleStartOffset.set_value(d->SampleStartOffset); eUnityNote.set_value(d->UnityNote); + // assemble sample format info string + { + Glib::ustring s; + if (d->pSample) { + switch (d->pSample->Channels) { + case 1: s = _("Mono"); break; + case 2: s = _("Stereo"); break; + default: + s = ToString(d->pSample->Channels) + _(" audio channels"); + break; + } + s += " " + ToString(d->pSample->BitDepth) + " Bits"; + s += " " + ToString(d->pSample->SamplesPerSecond/1000) + "." + + ToString((d->pSample->SamplesPerSecond%1000)/100) + " kHz"; + } else { + s = _("No sample assigned to this dimension region."); + } + eSampleFormatInfo.text.set_text(s); + } + // generate sample's memory address pointer string + { + Glib::ustring s; + if (d->pSample) { + char buf[64] = {}; + snprintf(buf, sizeof(buf), "%p", d->pSample); + s = buf; + } else { + s = "---"; + } + eSampleID.text.set_text(s); + } + buttonSelectSample.set_sensitive(d && d->pSample); eFineTune.set_value(d->FineTune); eGain.set_value(d->Gain); eGainPlus6.set_value(d->Gain); @@ -1418,3 +1495,59 @@ { if (d->pSample) d->pSample->LoopPlayCount = value; } + +void DimRegionEdit::nullOutSampleReference() { + if (!dimregion) return; + gig::Sample* oldref = dimregion->pSample; + if (!oldref) return; + + dimreg_to_be_changed_signal.emit(dimregion); + + // in case currently assigned sample is a stereo one, then remove both + // references (expected to be due to a "stereo dimension") + gig::DimensionRegion* d[2] = { dimregion, NULL }; + if (oldref->Channels == 2) { + gig::Region* region = dimregion->GetParent(); + { + int stereo_bit = 0; + int bitcount = 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]; + } + } + } + + if (d[0]) d[0]->pSample = NULL; + if (d[1]) d[1]->pSample = NULL; + + // update UI elements + set_dim_region(dimregion); + + sample_ref_changed_signal.emit(oldref, NULL); + dimreg_changed_signal.emit(dimregion); +} + +void DimRegionEdit::onButtonSelectSamplePressed() { + if (!dimregion) return; + if (!dimregion->pSample) return; + select_sample_signal.emit(dimregion->pSample); +} + +sigc::signal& DimRegionEdit::signal_select_sample() { + return select_sample_signal; +}