"Adopt instrument" action also adopts octave (#2095)

* push test

* remove test file

* add GUI_ACTION_PAT_ABSORB_INSTRUMENT action (set current instrument to channel's current instrument column)

* rename 'absorb instrument' to 'adopt instrument' (clearer), adopt octave as well, replace editor octave min/max numbers in the code with defines

* CRAP

* rename 'adopt instrument' back to 'absorb instrument'

---------

Co-authored-by: Adam Lederer <adam@adamlederer.com>
Co-authored-by: tildearrow <me@tildearrow.org>
This commit is contained in:
alederer 2024-08-19 11:19:50 -07:00 committed by GitHub
parent a410b90452
commit 28dc0b12a1
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 35 additions and 16 deletions

View file

@ -123,16 +123,16 @@ void FurnaceGUI::doAction(int what) {
pendingStepUpdate=1;
break;
case GUI_ACTION_OCTAVE_UP:
if (++curOctave>7) {
curOctave=7;
if (++curOctave>GUI_EDIT_OCTAVE_MAX) {
curOctave=GUI_EDIT_OCTAVE_MAX;
} else {
e->autoNoteOffAll();
failedNoteOn=false;
}
break;
case GUI_ACTION_OCTAVE_DOWN:
if (--curOctave<-5) {
curOctave=-5;
if (--curOctave<GUI_EDIT_OCTAVE_MIN) {
curOctave=GUI_EDIT_OCTAVE_MIN;
} else {
e->autoNoteOffAll();
failedNoteOn=false;
@ -679,10 +679,26 @@ void FurnaceGUI::doAction(int what) {
case GUI_ACTION_PAT_ABSORB_INSTRUMENT: {
DivPattern* pat=e->curPat[cursor.xCoarse].getPattern(e->curOrders->ord[cursor.xCoarse][curOrder],false);
if (!pat) break;
for (int i=cursor.y; i>=0; i--) {
if (pat->data[i][2] >= 0) {
bool foundIns=false;
bool foundOctave=false;
for (int i=cursor.y; i>=0 && !(foundIns && foundOctave); i--) {
// absorb most recent instrument
if (!foundIns && pat->data[i][2] >= 0) {
curIns=pat->data[i][2];
break;
foundIns=true;
}
// absorb most recent octave (i.e. set curOctave such that the "main row" (QWERTY) of notes
// will result in an octave number equal to the previous note).
if (!foundOctave && pat->data[i][0] != 0) {
// decode octave data (was signed cast to unsigned char)
int octave=pat->data[i][1];
if (octave>128) octave-=256;
// @NOTE the special handling when note==12, which is really an octave above what's
// stored in the octave data. without this handling, if you press Q, then
// "ABSORB_INSTRUMENT", then Q again, you'd get a different octave!
if (pat->data[i][0]==12) octave++;
curOctave=CLAMP(octave-1, GUI_EDIT_OCTAVE_MIN, GUI_EDIT_OCTAVE_MAX);
foundOctave=true;
}
}
break;

View file

@ -647,8 +647,8 @@ void FurnaceGUI::drawEditControls() {
ImGui::TableNextColumn();
ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x);
if (ImGui::InputInt("##Octave",&curOctave,1,1)) {
if (curOctave>7) curOctave=7;
if (curOctave<-5) curOctave=-5;
if (curOctave>GUI_EDIT_OCTAVE_MAX) curOctave=GUI_EDIT_OCTAVE_MAX;
if (curOctave<GUI_EDIT_OCTAVE_MIN) curOctave=GUI_EDIT_OCTAVE_MIN;
e->autoNoteOffAll();
failedNoteOn=false;
@ -808,8 +808,8 @@ void FurnaceGUI::drawEditControls() {
ImGui::SameLine();
ImGui::SetNextItemWidth(96.0f*dpiScale);
if (ImGui::InputInt("##Octave",&curOctave,1,1)) {
if (curOctave>7) curOctave=7;
if (curOctave<-5) curOctave=-5;
if (curOctave>GUI_EDIT_OCTAVE_MAX) curOctave=GUI_EDIT_OCTAVE_MAX;
if (curOctave<GUI_EDIT_OCTAVE_MIN) curOctave=GUI_EDIT_OCTAVE_MIN;
e->autoNoteOffAll();
failedNoteOn=false;
@ -926,8 +926,8 @@ void FurnaceGUI::drawEditControls() {
float avail=ImGui::GetContentRegionAvail().x;
ImGui::SetNextItemWidth(avail);
if (ImGui::InputInt("##Octave",&curOctave,0,0)) {
if (curOctave>7) curOctave=7;
if (curOctave<-5) curOctave=-5;
if (curOctave>GUI_EDIT_OCTAVE_MAX) curOctave=GUI_EDIT_OCTAVE_MAX;
if (curOctave<GUI_EDIT_OCTAVE_MIN) curOctave=GUI_EDIT_OCTAVE_MIN;
e->autoNoteOffAll();
failedNoteOn=false;
@ -1093,8 +1093,8 @@ void FurnaceGUI::drawEditControls() {
float avail=ImGui::GetContentRegionAvail().x;
ImGui::SetNextItemWidth(avail);
if (ImGui::InputInt("##Octave",&curOctave,1,1)) {
if (curOctave>7) curOctave=7;
if (curOctave<-5) curOctave=-5;
if (curOctave>GUI_EDIT_OCTAVE_MAX) curOctave=GUI_EDIT_OCTAVE_MAX;
if (curOctave<GUI_EDIT_OCTAVE_MIN) curOctave=GUI_EDIT_OCTAVE_MIN;
e->autoNoteOffAll();
failedNoteOn=false;

View file

@ -137,6 +137,9 @@ enum FurnaceGUIRenderBackend {
#define ngettext momo_ngettext
#endif
#define GUI_EDIT_OCTAVE_MIN -5
#define GUI_EDIT_OCTAVE_MAX 7
// TODO:
// - add colors for FM envelope and waveform
// - maybe add "alternate" color for FM modulators/carriers (a bit difficult)

View file

@ -687,7 +687,7 @@ const FurnaceGUIActionDef guiActions[GUI_ACTION_MAX]={
D("PAT_LATCH", _N("Set note input latch"), 0),
D("PAT_SCROLL_MODE", _N("Change mobile scroll mode"), 0),
D("PAT_CLEAR_LATCH", _N("Clear note input latch"), 0),
D("PAT_ABSORB_INSTRUMENT", _N("Set current instrument to channel's current instrument column"), 0),
D("PAT_ABSORB_INSTRUMENT", _N("Absorb instrument/octave from status at cursor"), 0),
D("PAT_MAX", "", NOT_AN_ACTION),
D("INS_LIST_MIN", _N("---Instrument list"), NOT_AN_ACTION),