From 61d935ba7011ecf6edd9fbf2f71dd2868b1ad7a9 Mon Sep 17 00:00:00 2001 From: Jason Felds Date: Fri, 10 Jun 2011 03:04:47 -0400 Subject: [PATCH] Split the Editor's Area menu into two menus. Use the "Enter" key for the old menu, and the "A" key for the Alter menu (requires having selected an area of notes). --- Docs/Changelog_sm5.txt | 8 + Themes/_fallback/Languages/en.ini | 3 +- Themes/_fallback/metrics.ini | 3 + src/ScreenEdit.cpp | 470 ++++++++++++++++-------------- src/ScreenEdit.h | 47 ++- 5 files changed, 307 insertions(+), 224 deletions(-) diff --git a/Docs/Changelog_sm5.txt b/Docs/Changelog_sm5.txt index cce227e55d..3aff3dbb7f 100644 --- a/Docs/Changelog_sm5.txt +++ b/Docs/Changelog_sm5.txt @@ -8,7 +8,15 @@ ________________________________________________________________________________ StepMania 5.0 Preview 2 | 20110??? -------------------------------------------------------------------------------- +2011/06/10 +---------- +* [ScreenEdit] Split the Area Menu into the Area Menu and Alter Menu. Use the + "A" key to enter the Alter Menu when a selection of notes/rows are + highlighted. Use the Enter key to enter the old Area Menu for the options that + do not depend on selecting NoteData. [Wolfman2000] + 2011/06/09 +---------- * [ScreenSyncOverlay] Ensure that F11 / F12 work with all charts due to Split Timing. [Wolfman2000] diff --git a/Themes/_fallback/Languages/en.ini b/Themes/_fallback/Languages/en.ini index 63c9701cc0..3b77e336c3 100644 --- a/Themes/_fallback/Languages/en.ini +++ b/Themes/_fallback/Languages/en.ini @@ -1257,7 +1257,7 @@ Enter a new min BPM.=Enter the minimum displayed BPM. Enter a new max BPM.=Enter the maximum displayed BPM. More than %d notes per measure is not allowed. This change has been reverted.=More than %d notes per measure is not allowed. This change has been reverted. No backgrounds available=No backgrounds available -EditHelpText=Up/Down:\n change beat\nLeft/Right:\n change snap\nNumber keys:\n add/remove\n tap note\nN and M keys:\n swap tap notes\nCreate hold note:\n Hold a number\n while moving\n Up or Down\nCreate roll note:\n Hold Shift,\n then create a\n hold note.\nSpace bar:\n Set area\n marker\nT key:\n Switch Timing\nEnter:\n Area Menu\nEscape:\n Main Menu\nF4:\n Timing Menu\nF1:\n Show help\n +EditHelpText=Up/Down:\n change beat\nLeft/Right:\n change snap\nNumber keys:\n add/remove\n tap note\nN and M keys:\n swap tap notes\nCreate hold note:\n Hold a number\n while moving\n Up or Down\nCreate roll note:\n Hold Shift,\n then create a\n hold note.\nSpace bar:\n Set area\n marker\nT key:\n Switch Timing\nEnter:\n Area Menu\nA Key: Alter Menu\nEscape:\n Main Menu\nF4:\n Timing Menu\nF1:\n Show help\n PlayRecordHelpText=Press START to end Save successful.=Save successful. Saved as SM and DWI.=Saved as SM and DWI. @@ -1269,6 +1269,7 @@ This change creates notes past the end of the music and is not allowed.=This cha This will destroy all unsaved changes.=This will destroy all unsaved changes. Undo=Undo You must be in Song Timing Mode to edit BG Changes.=You must be in Song Timing Mode to edit BG Changes. +You must have an area selected to enter the Alter Menu.=You must have an area selected to enter the Alter Menu. Current beat=Current beat Current second=Current second diff --git a/Themes/_fallback/metrics.ini b/Themes/_fallback/metrics.ini index 18712e9a16..e504462b0e 100644 --- a/Themes/_fallback/metrics.ini +++ b/Themes/_fallback/metrics.ini @@ -3752,6 +3752,9 @@ TitleX=SCREEN_CENTER_X-80 [ScreenMiniMenuAreaMenu] Fallback="ScreenMiniMenu" +[ScreenMiniMenuAlterMenu] +Fallback="ScreenMiniMenu" + [ScreenMiniMenuStepsInformation] Fallback="ScreenMiniMenu" diff --git a/src/ScreenEdit.cpp b/src/ScreenEdit.cpp index e0c805a5ad..340545e112 100644 --- a/src/ScreenEdit.cpp +++ b/src/ScreenEdit.cpp @@ -61,6 +61,7 @@ const float RECORD_HOLD_SECONDS = 0.3f; AutoScreenMessage( SM_UpdateTextInfo ); AutoScreenMessage( SM_BackFromMainMenu ); AutoScreenMessage( SM_BackFromAreaMenu ); +AutoScreenMessage( SM_BackFromAlterMenu ); AutoScreenMessage( SM_BackFromStepsInformation ); AutoScreenMessage( SM_BackFromOptions ); AutoScreenMessage( SM_BackFromSongInformation ); @@ -170,6 +171,7 @@ void ScreenEdit::InitEditMappings() m_EditMappingsMenuButton.button [EDIT_BUTTON_OPEN_EDIT_MENU][0] = GAME_BUTTON_START; m_EditMappingsMenuButton.button [EDIT_BUTTON_OPEN_EDIT_MENU][1] = GAME_BUTTON_BACK; + // Escape, Enter = exit play/record m_PlayMappingsDeviceInput.button [EDIT_BUTTON_RETURN_TO_EDIT][0] = DeviceInput(DEVICE_KEYBOARD, KEY_ENTER); m_PlayMappingsDeviceInput.button [EDIT_BUTTON_RETURN_TO_EDIT][1] = DeviceInput(DEVICE_KEYBOARD, KEY_ESC); @@ -280,6 +282,7 @@ void ScreenEdit::InitEditMappings() m_EditMappingsMenuButton.button[EDIT_BUTTON_OPEN_EDIT_MENU][0] = GAME_BUTTON_START; m_EditMappingsMenuButton.button[EDIT_BUTTON_OPEN_EDIT_MENU][1] = GAME_BUTTON_BACK; m_EditMappingsDeviceInput.button[EDIT_BUTTON_OPEN_AREA_MENU][0] = DeviceInput(DEVICE_KEYBOARD, KEY_ENTER); + m_EditMappingsDeviceInput.button[EDIT_BUTTON_OPEN_ALTER_MENU][0] = DeviceInput(DEVICE_KEYBOARD, KEY_Ca); m_EditMappingsDeviceInput.button[EDIT_BUTTON_OPEN_INPUT_HELP][0] = DeviceInput(DEVICE_KEYBOARD, KEY_F1); m_EditMappingsDeviceInput.button[EDIT_BUTTON_BAKE_RANDOM_FROM_SONG_GROUP][0] = DeviceInput(DEVICE_KEYBOARD, KEY_Cb); @@ -505,26 +508,48 @@ static MenuDef g_MainMenu( MenuRowDef( ScreenEdit::exit, "Exit Edit Mode", true, EditMode_Practice, true, true, 0, NULL ) ); +static MenuDef g_AlterMenu( + "ScreenMiniMenuAlterMenu", + MenuRowDef(ScreenEdit::cut, "Cut", true, + EditMode_Practice, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::copy, "Copy", true, + EditMode_Practice, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::clear, "Clear area", true, + EditMode_Practice, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::quantize, "Quantize", true, + EditMode_Practice, true, true, 0, + "4th","8th","12th","16th","24th","32nd","48th","64th","192nd"), + MenuRowDef(ScreenEdit::turn, "Turn", true, + EditMode_Practice, true, true, 0, "Left","Right","Mirror","Shuffle","SuperShuffle" ), + MenuRowDef(ScreenEdit::transform, "Transform", true, + EditMode_Practice, true, true, 0, "NoHolds","NoMines","Little","Wide", + "Big","Quick","Skippy","Mines","Echo","Stomp","Planted","Floored", + "Twister","NoJumps","NoHands","NoQuads","NoStretch" ), + MenuRowDef(ScreenEdit::alter, "Alter", true, + EditMode_Practice, true, true, 0, "Autogen To Fill Width","Backwards","Swap Sides", + "Copy Left To Right","Copy Right To Left","Clear Left","Clear Right", + "Collapse To One","Collapse Left","Shift Left","Shift Right" ), + MenuRowDef(ScreenEdit::tempo, "Tempo", true, + EditMode_Full, true, true, 0, "Compress 2x","Compress 3->2", + "Compress 4->3","Expand 3->4","Expand 2->3","Expand 2x" ), + MenuRowDef(ScreenEdit::play, "Play selection", true, + EditMode_Practice, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::record, "Record in selection", true, + EditMode_Practice, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::convert_to_pause, "Convert selection to pause", true, + EditMode_Full, true, true, 0, NULL ) +); + static MenuDef g_AreaMenu( "ScreenMiniMenuAreaMenu", - MenuRowDef( ScreenEdit::cut, "Cut", true, EditMode_Practice, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::copy, "Copy", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::paste_at_current_beat, "Paste at current beat", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::paste_at_begin_marker, "Paste at begin marker", true, EditMode_Practice, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::clear, "Clear area", true, EditMode_Practice, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::quantize, "Quantize", true, EditMode_Practice, true, true, 0, "4th","8th","12th","16th","24th","32nd","48th","64th","192nd"), - MenuRowDef( ScreenEdit::turn, "Turn", true, EditMode_Practice, true, true, 0, "Left","Right","Mirror","Shuffle","SuperShuffle" ), - MenuRowDef( ScreenEdit::transform, "Transform", true, EditMode_Practice, true, true, 0, "NoHolds","NoMines","Little","Wide","Big","Quick","Skippy","Mines","Echo","Stomp","Planted","Floored","Twister","NoJumps","NoHands","NoQuads","NoStretch" ), - MenuRowDef( ScreenEdit::alter, "Alter", true, EditMode_Practice, true, true, 0, "Autogen To Fill Width","Backwards","Swap Sides","Copy Left To Right","Copy Right To Left","Clear Left","Clear Right","Collapse To One","Collapse Left","Shift Left","Shift Right" ), - MenuRowDef( ScreenEdit::tempo, "Tempo", true, EditMode_Full, true, true, 0, "Compress 2x","Compress 3->2","Compress 4->3","Expand 3->4","Expand 2->3","Expand 2x" ), - MenuRowDef( ScreenEdit::play, "Play selection", true, EditMode_Practice, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::record, "Record in selection", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::insert_and_shift, "Insert beat and shift down", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::delete_and_shift, "Delete beat and shift up", true, EditMode_Practice, true, true, 0, NULL ), MenuRowDef( ScreenEdit::shift_pauses_forward, "Shift all timing changes down", true, EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::shift_pauses_backward, "Shift all timing changes up", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::convert_to_pause, "Convert selection to pause", true, EditMode_Full, true, true, 0, NULL ), - MenuRowDef( ScreenEdit::convert_pause_to_beat, "Convert pause to beats", true, EditMode_Full, true, true, 0, NULL ), + MenuRowDef(ScreenEdit::convert_pause_to_beat, "Convert pause to beats", true, + EditMode_Full, true, true, 0, NULL ), MenuRowDef( ScreenEdit::undo, "Undo", true, EditMode_Practice, true, true, 0, NULL ) ); @@ -1299,7 +1324,7 @@ static int FindAttackAtTime( const AttackArray& attacks, float fStartTime ) } static LocalizedString BG_CHANGE_STEP_TIMING ( "ScreenEdit", "You must be in Song Timing Mode to edit BG Changes." ); - +static LocalizedString ALTER_MENU_NO_SELECTION ( "ScreenEdit", "You must have an area selected to enter the Alter Menu." ); static LocalizedString SWITCHED_TO ( "ScreenEdit", "Switched to" ); static LocalizedString NO_BACKGROUNDS_AVAILABLE ( "ScreenEdit", "No backgrounds available" ); static ThemeMetric INVERT_SCROLL_BUTTONS ( "ScreenEdit", "InvertScrollSpeedButtons" ); @@ -1561,24 +1586,27 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) case EDIT_BUTTON_OPEN_AREA_MENU: { // update enabled/disabled in g_AreaMenu - bool bAreaSelected = m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1; - g_AreaMenu.rows[cut].bEnabled = bAreaSelected; - g_AreaMenu.rows[copy].bEnabled = bAreaSelected; g_AreaMenu.rows[paste_at_current_beat].bEnabled = !m_Clipboard.IsEmpty(); g_AreaMenu.rows[paste_at_begin_marker].bEnabled = !m_Clipboard.IsEmpty() != 0 && m_NoteFieldEdit.m_iBeginMarker!=-1; - g_AreaMenu.rows[clear].bEnabled = bAreaSelected; - g_AreaMenu.rows[quantize].bEnabled = bAreaSelected; - g_AreaMenu.rows[turn].bEnabled = bAreaSelected; - g_AreaMenu.rows[transform].bEnabled = bAreaSelected; - g_AreaMenu.rows[alter].bEnabled = bAreaSelected; - g_AreaMenu.rows[tempo].bEnabled = bAreaSelected; - g_AreaMenu.rows[play].bEnabled = bAreaSelected; - g_AreaMenu.rows[record].bEnabled = bAreaSelected; - g_AreaMenu.rows[convert_to_pause].bEnabled = bAreaSelected; g_AreaMenu.rows[undo].bEnabled = m_bHasUndo; EditMiniMenu( &g_AreaMenu, SM_BackFromAreaMenu ); } break; + case EDIT_BUTTON_OPEN_ALTER_MENU: + { + bool bAreaSelected = m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1; + if (!bAreaSelected) + { + SCREENMAN->SystemMessage( ALTER_MENU_NO_SELECTION ); + SCREENMAN->PlayInvalidSound(); + } + else + { + EditMiniMenu(&g_AlterMenu, SM_BackFromAlterMenu); + } + break; + + } case EDIT_BUTTON_OPEN_EDIT_MENU: EditMiniMenu( &g_MainMenu, SM_BackFromMainMenu ); break; @@ -2044,7 +2072,7 @@ void ScreenEdit::InputEdit( const InputEventPlus &input, EditButton EditB ) case EDIT_BUTTON_RECORD_SELECTION: if( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ) { - HandleAreaMenuChoice( record ); + HandleAlterMenuChoice( record ); } else { @@ -2644,6 +2672,10 @@ void ScreenEdit::HandleScreenMessage( const ScreenMessage SM ) { HandleAreaMenuChoice( (AreaMenuChoice)ScreenMiniMenu::s_iLastRowCode, ScreenMiniMenu::s_viLastAnswers ); } + else if( SM == SM_BackFromAlterMenu ) + { + HandleAlterMenuChoice( (AlterMenuChoice)ScreenMiniMenu::s_iLastRowCode, ScreenMiniMenu::s_viLastAnswers ); + } else if( SM == SM_BackFromStepsInformation ) { HandleStepsInformationChoice( (StepsInformationChoice)ScreenMiniMenu::s_iLastRowCode, ScreenMiniMenu::s_viLastAnswers ); @@ -3248,7 +3280,7 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns DEFAULT_FAIL( c ); case play_selection: if( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ) - HandleAreaMenuChoice( play ); + HandleAlterMenuChoice( play ); else if( m_NoteFieldEdit.m_iBeginMarker!=-1 ) HandleMainMenuChoice( play_selection_start_to_end ); else @@ -3464,14 +3496,208 @@ void ScreenEdit::HandleMainMenuChoice( MainMenuChoice c, const vector &iAns GAMESTATE->SetProcessedTimingData(NULL); } +void ScreenEdit::HandleAlterMenuChoice(AlterMenuChoice c, const vector &iAnswers, bool bAllowUndo) +{ + bool bSaveUndo = true; + switch (c) + { + case cut: + case copy: + { + bSaveUndo = false; + } + default: + break; + } + + if( bSaveUndo ) + SetDirty( true ); + + /* We call HandleAreaMenuChoice recursively. Only the outermost + * HandleAreaMenuChoice should allow Undo so that the inner calls don't + * also save Undo and mess up the outermost */ + if( !bAllowUndo ) + bSaveUndo = false; + + if( bSaveUndo ) + SaveUndo(); + + switch(c) + { + case cut: + { + HandleAlterMenuChoice( copy ); + HandleAlterMenuChoice( clear ); + } + break; + case copy: + { + ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); + m_Clipboard.ClearAll(); + m_Clipboard.CopyRange( m_NoteDataEdit, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker ); + } + break; + case clear: + { + ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); + m_NoteDataEdit.ClearRange( m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker ); + } + break; + case quantize: + { + NoteType nt = (NoteType)iAnswers[c]; + NoteDataUtil::SnapToNearestNoteType(m_NoteDataEdit, nt, nt, + m_NoteFieldEdit.m_iBeginMarker, + m_NoteFieldEdit.m_iEndMarker ); + break; + } + case turn: + { + const NoteData OldClipboard( m_Clipboard ); + HandleAlterMenuChoice( cut ); + + StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType; + TurnType tt = (TurnType)iAnswers[c]; + switch( tt ) + { + DEFAULT_FAIL( tt ); + case left: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::left ); break; + case right: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::right ); break; + case mirror: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::mirror ); break; + case shuffle: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::shuffle ); break; + case super_shuffle: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::super_shuffle ); break; + } + + HandleAreaMenuChoice( paste_at_begin_marker ); + m_Clipboard = OldClipboard; + } + break; + case transform: + { + int iBeginRow = m_NoteFieldEdit.m_iBeginMarker; + int iEndRow = m_NoteFieldEdit.m_iEndMarker; + TransformType tt = (TransformType)iAnswers[c]; + StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType; + + switch( tt ) + { + DEFAULT_FAIL( tt ); + case noholds: NoteDataUtil::RemoveHoldNotes( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case nomines: NoteDataUtil::RemoveMines( m_NoteDataEdit, iBeginRow, iBeginRow ); break; + case little: NoteDataUtil::Little( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case wide: NoteDataUtil::Wide( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case big: NoteDataUtil::Big( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case quick: NoteDataUtil::Quick( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case skippy: NoteDataUtil::Skippy( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case add_mines: NoteDataUtil::AddMines( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case echo: NoteDataUtil::Echo( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case stomp: NoteDataUtil::Stomp( m_NoteDataEdit, st, iBeginRow, iEndRow ); break; + case planted: NoteDataUtil::Planted( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case floored: NoteDataUtil::Floored( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case twister: NoteDataUtil::Twister( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case nojumps: NoteDataUtil::RemoveJumps( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case nohands: NoteDataUtil::RemoveHands( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case noquads: NoteDataUtil::RemoveQuads( m_NoteDataEdit, iBeginRow, iEndRow ); break; + case nostretch: NoteDataUtil::RemoveStretch( m_NoteDataEdit, st, iBeginRow, iBeginRow );break; + } + + // bake in the additions + NoteDataUtil::ConvertAdditionsToRegular( m_NoteDataEdit ); + break; + } + case alter: + { + const NoteData OldClipboard( m_Clipboard ); + HandleAlterMenuChoice( cut ); + + AlterType at = (AlterType)iAnswers[c]; + switch( at ) + { + DEFAULT_FAIL( at ); + case autogen_to_fill_width: + { + NoteData temp( m_Clipboard ); + int iMaxNonEmptyTrack = NoteDataUtil::GetMaxNonEmptyTrack( temp ); + if( iMaxNonEmptyTrack == -1 ) + break; + temp.SetNumTracks( iMaxNonEmptyTrack+1 ); + NoteDataUtil::LoadTransformedSlidingWindow( temp, m_Clipboard, m_Clipboard.GetNumTracks() ); + NoteDataUtil::RemoveStretch( m_Clipboard, GAMESTATE->m_pCurSteps[0]->m_StepsType ); + } + break; + case backwards: NoteDataUtil::Backwards( m_Clipboard ); break; + case swap_sides: NoteDataUtil::SwapSides( m_Clipboard ); break; + case copy_left_to_right: NoteDataUtil::CopyLeftToRight( m_Clipboard ); break; + case copy_right_to_left: NoteDataUtil::CopyRightToLeft( m_Clipboard ); break; + case clear_left: NoteDataUtil::ClearLeft( m_Clipboard ); break; + case clear_right: NoteDataUtil::ClearRight( m_Clipboard ); break; + case collapse_to_one: NoteDataUtil::CollapseToOne( m_Clipboard ); break; + case collapse_left: NoteDataUtil::CollapseLeft( m_Clipboard ); break; + case shift_left: NoteDataUtil::ShiftLeft( m_Clipboard ); break; + case shift_right: NoteDataUtil::ShiftRight( m_Clipboard ); break; + } + + HandleAreaMenuChoice( paste_at_begin_marker ); + m_Clipboard = OldClipboard; + break; + } + case tempo: + { + // This affects all steps. + AlterType at = (AlterType)iAnswers[c]; + float fScale = -1; + + switch( at ) + { + DEFAULT_FAIL( at ); + case compress_2x: fScale = 0.5f; break; + case compress_3_2: fScale = 2.0f/3; break; + case compress_4_3: fScale = 0.75f; break; + case expand_4_3: fScale = 4.0f/3; break; + case expand_3_2: fScale = 1.5f; break; + case expand_2x: fScale = 2; break; + } + + int iStartIndex = m_NoteFieldEdit.m_iBeginMarker; + int iEndIndex = m_NoteFieldEdit.m_iEndMarker; + int iNewEndIndex = iEndIndex + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ); + + // scale currently editing notes + NoteDataUtil::ScaleRegion( m_NoteDataEdit, fScale, iStartIndex, iEndIndex ); + + // scale timing data + GetAppropriateTiming().ScaleRegion(fScale, + m_NoteFieldEdit.m_iBeginMarker, + m_NoteFieldEdit.m_iEndMarker, true ); + + m_NoteFieldEdit.m_iEndMarker = iNewEndIndex; + break; + + } + + case play: + ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); + m_iStartPlayingAt = m_NoteFieldEdit.m_iBeginMarker; + m_iStopPlayingAt = m_NoteFieldEdit.m_iEndMarker; + TransitionEditState( STATE_PLAYING ); + break; + case record: + ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); + m_iStartPlayingAt = m_NoteFieldEdit.m_iBeginMarker; + m_iStopPlayingAt = m_NoteFieldEdit.m_iEndMarker; + TransitionEditState( STATE_RECORDING ); + break; + + } + +} + void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAnswers, bool bAllowUndo ) { bool bSaveUndo = false; switch( c ) { DEFAULT_FAIL( c ); - case cut: - case copy: case play: case record: case undo: @@ -3479,12 +3705,6 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns break; case paste_at_current_beat: case paste_at_begin_marker: - case clear: - case quantize: - case turn: - case transform: - case alter: - case tempo: case insert_and_shift: case delete_and_shift: case shift_pauses_forward: @@ -3510,19 +3730,7 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns switch( c ) { DEFAULT_FAIL( c ); - case cut: - { - HandleAreaMenuChoice( copy ); - HandleAreaMenuChoice( clear ); - } - break; - case copy: - { - ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); - m_Clipboard.ClearAll(); - m_Clipboard.CopyRange( m_NoteDataEdit, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker ); - } - break; + case paste_at_current_beat: case paste_at_begin_marker: { @@ -3543,172 +3751,6 @@ void ScreenEdit::HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAns m_NoteDataEdit.CopyRange( m_Clipboard, 0, iRowsToCopy, iDestFirstRow ); } break; - case clear: - { - ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); - m_NoteDataEdit.ClearRange( m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker ); - } - break; - case quantize: - { - NoteType nt = (NoteType)iAnswers[c]; - NoteDataUtil::SnapToNearestNoteType( m_NoteDataEdit, nt, nt, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker ); - } - break; - case turn: - { - const NoteData OldClipboard( m_Clipboard ); - HandleAreaMenuChoice( cut ); - - StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType; - TurnType tt = (TurnType)iAnswers[c]; - switch( tt ) - { - DEFAULT_FAIL( tt ); - case left: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::left ); break; - case right: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::right ); break; - case mirror: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::mirror ); break; - case shuffle: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::shuffle ); break; - case super_shuffle: NoteDataUtil::Turn( m_Clipboard, st, NoteDataUtil::super_shuffle ); break; - } - - HandleAreaMenuChoice( paste_at_begin_marker ); - m_Clipboard = OldClipboard; - } - break; - case transform: - { - int iBeginRow = m_NoteFieldEdit.m_iBeginMarker; - int iEndRow = m_NoteFieldEdit.m_iEndMarker; - TransformType tt = (TransformType)iAnswers[c]; - StepsType st = GAMESTATE->GetCurrentStyle()->m_StepsType; - - switch( tt ) - { - DEFAULT_FAIL( tt ); - case noholds: NoteDataUtil::RemoveHoldNotes( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case nomines: NoteDataUtil::RemoveMines( m_NoteDataEdit, iBeginRow, iBeginRow ); break; - case little: NoteDataUtil::Little( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case wide: NoteDataUtil::Wide( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case big: NoteDataUtil::Big( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case quick: NoteDataUtil::Quick( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case skippy: NoteDataUtil::Skippy( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case add_mines: NoteDataUtil::AddMines( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case echo: NoteDataUtil::Echo( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case stomp: NoteDataUtil::Stomp( m_NoteDataEdit, st, iBeginRow, iEndRow ); break; - case planted: NoteDataUtil::Planted( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case floored: NoteDataUtil::Floored( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case twister: NoteDataUtil::Twister( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case nojumps: NoteDataUtil::RemoveJumps( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case nohands: NoteDataUtil::RemoveHands( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case noquads: NoteDataUtil::RemoveQuads( m_NoteDataEdit, iBeginRow, iEndRow ); break; - case nostretch: NoteDataUtil::RemoveStretch( m_NoteDataEdit, st, iBeginRow, iBeginRow );break; - } - - // bake in the additions - NoteDataUtil::ConvertAdditionsToRegular( m_NoteDataEdit ); - } - break; - case alter: - { - const NoteData OldClipboard( m_Clipboard ); - HandleAreaMenuChoice( cut ); - - AlterType at = (AlterType)iAnswers[c]; - switch( at ) - { - DEFAULT_FAIL( at ); - case autogen_to_fill_width: - { - NoteData temp( m_Clipboard ); - int iMaxNonEmptyTrack = NoteDataUtil::GetMaxNonEmptyTrack( temp ); - if( iMaxNonEmptyTrack == -1 ) - break; - temp.SetNumTracks( iMaxNonEmptyTrack+1 ); - NoteDataUtil::LoadTransformedSlidingWindow( temp, m_Clipboard, m_Clipboard.GetNumTracks() ); - NoteDataUtil::RemoveStretch( m_Clipboard, GAMESTATE->m_pCurSteps[0]->m_StepsType ); - } - break; - case backwards: NoteDataUtil::Backwards( m_Clipboard ); break; - case swap_sides: NoteDataUtil::SwapSides( m_Clipboard ); break; - case copy_left_to_right: NoteDataUtil::CopyLeftToRight( m_Clipboard ); break; - case copy_right_to_left: NoteDataUtil::CopyRightToLeft( m_Clipboard ); break; - case clear_left: NoteDataUtil::ClearLeft( m_Clipboard ); break; - case clear_right: NoteDataUtil::ClearRight( m_Clipboard ); break; - case collapse_to_one: NoteDataUtil::CollapseToOne( m_Clipboard ); break; - case collapse_left: NoteDataUtil::CollapseLeft( m_Clipboard ); break; - case shift_left: NoteDataUtil::ShiftLeft( m_Clipboard ); break; - case shift_right: NoteDataUtil::ShiftRight( m_Clipboard ); break; - } - - HandleAreaMenuChoice( paste_at_begin_marker ); - m_Clipboard = OldClipboard; - } - break; - case tempo: - { - // This affects all steps. - AlterType at = (AlterType)iAnswers[c]; - float fScale = -1; - - switch( at ) - { - DEFAULT_FAIL( at ); - case compress_2x: fScale = 0.5f; break; - case compress_3_2: fScale = 2.0f/3; break; - case compress_4_3: fScale = 0.75f; break; - case expand_4_3: fScale = 4.0f/3; break; - case expand_3_2: fScale = 1.5f; break; - case expand_2x: fScale = 2; break; - } - - int iStartIndex = m_NoteFieldEdit.m_iBeginMarker; - int iEndIndex = m_NoteFieldEdit.m_iEndMarker; - int iNewEndIndex = iEndIndex + lrintf( (iEndIndex - iStartIndex) * (fScale - 1) ); - - // scale currently editing notes - NoteDataUtil::ScaleRegion( m_NoteDataEdit, fScale, iStartIndex, iEndIndex ); - - // scale timing data - GetAppropriateTiming().ScaleRegion( fScale, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker, true ); - - // scale all other steps. - /* - const vector sIter = m_pSong->GetAllSteps(); - RString sTempStyle, sTempDiff; - for( unsigned i = 0; i < sIter.size(); i++ ) - { - if( sIter[i]->IsAutogen() ) - continue; - - // XXX: Edits are distinguished by description. - // Compare vs m_pSteps. - if( (sIter[i]->m_StepsType == GAMESTATE->m_pCurSteps[PLAYER_1]->m_StepsType) && - (sIter[i]->GetDifficulty() == GAMESTATE->m_pCurSteps[PLAYER_1]->GetDifficulty()) ) - continue; - - NoteData ndTemp; - sIter[i]->GetNoteData( ndTemp ); - NoteDataUtil::ScaleRegion( ndTemp, fScale, m_NoteFieldEdit.m_iBeginMarker, m_NoteFieldEdit.m_iEndMarker ); - sIter[i]->SetNoteData( ndTemp ); - } - */ - m_NoteFieldEdit.m_iEndMarker = iNewEndIndex; - - } - break; - case play: - ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); - m_iStartPlayingAt = m_NoteFieldEdit.m_iBeginMarker; - m_iStopPlayingAt = m_NoteFieldEdit.m_iEndMarker; - TransitionEditState( STATE_PLAYING ); - break; - case record: - ASSERT( m_NoteFieldEdit.m_iBeginMarker!=-1 && m_NoteFieldEdit.m_iEndMarker!=-1 ); - m_iStartPlayingAt = m_NoteFieldEdit.m_iBeginMarker; - m_iStopPlayingAt = m_NoteFieldEdit.m_iEndMarker; - TransitionEditState( STATE_RECORDING ); - break; case insert_and_shift: NoteDataUtil::InsertRows( m_NoteDataEdit, BeatToNoteRow( GetBeat() ), BeatToNoteRow(1) ); break; diff --git a/src/ScreenEdit.h b/src/ScreenEdit.h index 2b92f8bbd5..7e2f82eebd 100644 --- a/src/ScreenEdit.h +++ b/src/ScreenEdit.h @@ -87,6 +87,7 @@ enum EditButton EDIT_BUTTON_OPEN_EDIT_MENU, EDIT_BUTTON_OPEN_TIMING_MENU, + EDIT_BUTTON_OPEN_ALTER_MENU, EDIT_BUTTON_OPEN_AREA_MENU, EDIT_BUTTON_OPEN_BGCHANGE_LAYER1_MENU, EDIT_BUTTON_OPEN_BGCHANGE_LAYER2_MENU, @@ -209,7 +210,12 @@ public: virtual void PushSelf( lua_State *L ); protected: - virtual ScreenType GetScreenType() const { return m_EditState==STATE_PLAYING ? gameplay : ScreenWithMenuElements::GetScreenType(); } + virtual ScreenType GetScreenType() const + { + return m_EditState==STATE_PLAYING ? + gameplay : + ScreenWithMenuElements::GetScreenType(); + } void TransitionEditState( EditState em ); void ScrollTo( float fDestinationBeat ); @@ -268,7 +274,8 @@ protected: BitmapText m_textPlayRecordHelp; // keep track of where we are and what we're doing - float m_fTrailingBeat; // this approaches GAMESTATE->m_fSongBeat, which is the actual beat + float m_fTrailingBeat; + // the above approaches GAMESTATE->m_fSongBeat, which is the actual beat /** * @brief The location we were at when shift was pressed. * @@ -365,13 +372,12 @@ public: void HandleMainMenuChoice( MainMenuChoice c ) { const vector v; HandleMainMenuChoice( c, v ); } MainMenuChoice m_CurrentAction; - enum AreaMenuChoice + enum AlterMenuChoice { cut, copy, - paste_at_current_beat, - paste_at_begin_marker, clear, + // clear_undo, quantize, turn, transform, @@ -379,17 +385,37 @@ public: tempo, play, record, + convert_to_pause, + NUM_ALTER_MENU_CHOICES + + }; + + enum AreaMenuChoice + { + paste_at_current_beat, + paste_at_begin_marker, insert_and_shift, delete_and_shift, shift_pauses_forward, shift_pauses_backward, - convert_to_pause, convert_pause_to_beat, undo, NUM_AREA_MENU_CHOICES }; + void HandleAlterMenuChoice(AlterMenuChoice c, + const vector &iAnswers, + bool bAllowUndo = true); + void HandleAlterMenuChoice(AlterMenuChoice c, + bool bAllowUndo = true) + { + const vector v; HandleAlterMenuChoice(c, v, bAllowUndo); + } + void HandleAreaMenuChoice( AreaMenuChoice c, const vector &iAnswers, bool bAllowUndo = true ); - void HandleAreaMenuChoice( AreaMenuChoice c, bool bAllowUndo = true ) { const vector v; HandleAreaMenuChoice( c, v, bAllowUndo ); } + void HandleAreaMenuChoice( AreaMenuChoice c, bool bAllowUndo = true ) + { + const vector v; HandleAreaMenuChoice( c, v, bAllowUndo ); + } /** @brief How should the selected notes be transformed? */ enum TurnType { @@ -511,7 +537,8 @@ public: NUM_TIMING_DATA_INFORMATION_CHOICES }; - void HandleTimingDataInformationChoice ( TimingDataInformationChoice c, const vector &iAnswers ); + void HandleTimingDataInformationChoice (TimingDataInformationChoice c, + const vector &iAnswers ); enum BGChangeChoice { @@ -581,7 +608,9 @@ public: MapEditButtonToMenuButton m_RecordPausedMappingsMenuButton; void MakeFilteredMenuDef( const MenuDef* pDef, MenuDef &menu ); - void EditMiniMenu( const MenuDef* pDef, ScreenMessage SM_SendOnOK = SM_None, ScreenMessage SM_SendOnCancel = SM_None ); + void EditMiniMenu(const MenuDef* pDef, + ScreenMessage SM_SendOnOK = SM_None, + ScreenMessage SM_SendOnCancel = SM_None ); private: /** * @brief Retrieve the appropriate TimingData based on GAMESTATE.