Added Clear timing in region option to timing menu in edit mode. Disabled pasting clipboard timing if it's not safe to fix crash.

This commit is contained in:
Kyzentun Keeslala
2016-01-18 11:48:50 -07:00
parent e60797c1df
commit ae5ff0724a
5 changed files with 95 additions and 14 deletions
+1
View File
@@ -990,6 +990,7 @@ Clear Machine Stats=Clear Machine Scores
Clear USB edits=Clear USB edits Clear USB edits=Clear USB edits
Clear area=Clear area Clear area=Clear area
Clear clipboard=Clear clipboard Clear clipboard=Clear clipboard
Clear timing in region=Clear timing in region
CoinMode=Coin Mode CoinMode=Coin Mode
CoinModeNoHome=Coin Mode CoinModeNoHome=Coin Mode
CoinsPerCredit=Coins Per Credit CoinsPerCredit=Coins Per Credit
+30 -9
View File
@@ -1051,7 +1051,15 @@ static MenuDef g_SongInformation(
true, EditMode_Full, true, true, 0, NULL ) true, EditMode_Full, true, true, 0, NULL )
); );
// Ugh, I don't like making this global pointer to clipboardFullTiming, but
// it's the only way to make it visible to EnabledIfClipboardTimingIsSafe for
// making sure it's safe to paste as the timing data for the Steps/Song. -Kyz
static TimingData* clipboard_full_timing= NULL;
static bool EnabledIfClipboardTimingIsSafe();
static bool EnabledIfClipboardTimingIsSafe()
{
return clipboard_full_timing != NULL && clipboard_full_timing->IsSafeFullTiming();
}
static MenuDef g_TimingDataInformation( static MenuDef g_TimingDataInformation(
"ScreenMiniMenuTimingDataInformation", "ScreenMiniMenuTimingDataInformation",
MenuRowDef(ScreenEdit::beat_0_offset, MenuRowDef(ScreenEdit::beat_0_offset,
@@ -1102,6 +1110,9 @@ static MenuDef g_TimingDataInformation(
MenuRowDef(ScreenEdit::copy_timing_in_region, MenuRowDef(ScreenEdit::copy_timing_in_region,
"Copy timing in region", "Copy timing in region",
true, EditMode_Full, true, true, 0, NULL), true, EditMode_Full, true, true, 0, NULL),
MenuRowDef(ScreenEdit::clear_timing_in_region,
"Clear timing in region",
true, EditMode_Full, true, true, 0, NULL),
MenuRowDef(ScreenEdit::paste_timing_from_clip, MenuRowDef(ScreenEdit::paste_timing_from_clip,
"Paste timing from clipboard", "Paste timing from clipboard",
true, EditMode_Full, true, true, 0, NULL), true, EditMode_Full, true, true, 0, NULL),
@@ -1110,7 +1121,7 @@ static MenuDef g_TimingDataInformation(
true, EditMode_Full, true, true, 0, NULL ), true, EditMode_Full, true, true, 0, NULL ),
MenuRowDef(ScreenEdit::paste_full_timing, MenuRowDef(ScreenEdit::paste_full_timing,
"Paste timing data", "Paste timing data",
true, EditMode_Full, true, true, 0, NULL ), EnabledIfClipboardTimingIsSafe, EditMode_Full, true, true, 0, NULL ),
MenuRowDef(ScreenEdit::erase_step_timing, MenuRowDef(ScreenEdit::erase_step_timing,
"Erase step timing", "Erase step timing",
true, EditMode_Full, true, true, 0, NULL ) true, EditMode_Full, true, true, 0, NULL )
@@ -1502,6 +1513,7 @@ void ScreenEdit::Init()
m_Clipboard.SetNumTracks( m_NoteDataEdit.GetNumTracks() ); m_Clipboard.SetNumTracks( m_NoteDataEdit.GetNumTracks() );
clipboardFullTiming = GAMESTATE->m_pCurSong->m_SongTiming; // always have a backup. clipboardFullTiming = GAMESTATE->m_pCurSong->m_SongTiming; // always have a backup.
clipboard_full_timing= &clipboardFullTiming;
m_bHasUndo = false; m_bHasUndo = false;
m_Undo.SetNumTracks( m_NoteDataEdit.GetNumTracks() ); m_Undo.SetNumTracks( m_NoteDataEdit.GetNumTracks() );
@@ -5877,17 +5889,21 @@ void ScreenEdit::HandleTimingDataInformationChoice( TimingDataInformationChoice
break; break;
} }
case shift_timing_in_region_down: case shift_timing_in_region_down:
m_timing_is_being_copied= false; m_timing_change_menu_purpose= menu_is_for_shifting;
m_timing_rows_being_shitted= GetRowsFromAnswers(c, iAnswers); m_timing_rows_being_shitted= GetRowsFromAnswers(c, iAnswers);
DisplayTimingChangeMenu(); DisplayTimingChangeMenu();
break; break;
case shift_timing_in_region_up: case shift_timing_in_region_up:
m_timing_is_being_copied= false; m_timing_change_menu_purpose= menu_is_for_shifting;
m_timing_rows_being_shitted= -GetRowsFromAnswers(c, iAnswers); m_timing_rows_being_shitted= -GetRowsFromAnswers(c, iAnswers);
DisplayTimingChangeMenu(); DisplayTimingChangeMenu();
break; break;
case copy_timing_in_region: case copy_timing_in_region:
m_timing_is_being_copied= true; m_timing_change_menu_purpose= menu_is_for_copying;
DisplayTimingChangeMenu();
break;
case clear_timing_in_region:
m_timing_change_menu_purpose= menu_is_for_clearing;
DisplayTimingChangeMenu(); DisplayTimingChangeMenu();
break; break;
case paste_timing_from_clip: case paste_timing_from_clip:
@@ -5972,14 +5988,19 @@ void ScreenEdit::HandleTimingDataChangeChoice(TimingDataChangeChoice choice,
{ {
end= MAX_NOTE_ROW; end= MAX_NOTE_ROW;
} }
if(m_timing_is_being_copied) switch(m_timing_change_menu_purpose)
{ {
case menu_is_for_copying:
clipboardFullTiming.Clear(); clipboardFullTiming.Clear();
GetAppropriateTiming().CopyRange(begin, end, change_type, 0, clipboardFullTiming); GetAppropriateTiming().CopyRange(begin, end, change_type, 0, clipboardFullTiming);
} break;
else case menu_is_for_shifting:
{
GetAppropriateTimingForUpdate().ShiftRange(begin, end, change_type, m_timing_rows_being_shitted); GetAppropriateTimingForUpdate().ShiftRange(begin, end, change_type, m_timing_rows_being_shitted);
break;
case menu_is_for_clearing:
GetAppropriateTimingForUpdate().ClearRange(begin, end, change_type);
break;
default: break;
} }
} }
+8 -1
View File
@@ -268,7 +268,13 @@ protected:
/** @brief Display the TimingData menu for editing song and step timing. */ /** @brief Display the TimingData menu for editing song and step timing. */
void DisplayTimingMenu(); void DisplayTimingMenu();
bool m_timing_is_being_copied; // Instead of being shifted. enum TimingChangeMenuPurpose
{
menu_is_for_copying,
menu_is_for_shifting,
menu_is_for_clearing
};
TimingChangeMenuPurpose m_timing_change_menu_purpose;
int m_timing_rows_being_shitted; // How far the timing is being shitted. int m_timing_rows_being_shitted; // How far the timing is being shitted.
void DisplayTimingChangeMenu(); void DisplayTimingChangeMenu();
@@ -610,6 +616,7 @@ public:
shift_timing_in_region_down, shift_timing_in_region_down,
shift_timing_in_region_up, shift_timing_in_region_up,
copy_timing_in_region, copy_timing_in_region,
clear_timing_in_region,
paste_timing_from_clip, paste_timing_from_clip,
copy_full_timing, copy_full_timing,
paste_full_timing, paste_full_timing,
+50
View File
@@ -50,6 +50,30 @@ void TimingData::Clear()
} }
} }
bool TimingData::IsSafeFullTiming()
{
static vector<TimingSegmentType> needed_segments;
if(needed_segments.empty())
{
needed_segments.push_back(SEGMENT_BPM);
needed_segments.push_back(SEGMENT_TIME_SIG);
needed_segments.push_back(SEGMENT_TICKCOUNT);
needed_segments.push_back(SEGMENT_COMBO);
needed_segments.push_back(SEGMENT_LABEL);
needed_segments.push_back(SEGMENT_SPEED);
needed_segments.push_back(SEGMENT_SCROLL);
}
vector<TimingSegment *> *segs = m_avpTimingSegments;
for(size_t s= 0; s < needed_segments.size(); ++s)
{
if(segs[needed_segments[s]].empty())
{
return false;
}
}
return true;
}
TimingData::~TimingData() TimingData::~TimingData()
{ {
Clear(); Clear();
@@ -301,6 +325,32 @@ void TimingData::ShiftRange(int start_row, int end_row,
} }
} }
void TimingData::ClearRange(int start_row, int end_row, TimingSegmentType clear_type)
{
FOREACH_TimingSegmentType(seg_type)
{
if(seg_type == clear_type || clear_type == TimingSegmentType_Invalid)
{
vector<TimingSegment*>& segs= GetTimingSegments(seg_type);
int first_affected= GetSegmentIndexAtRow(seg_type, start_row);
int last_affected= GetSegmentIndexAtRow(seg_type, end_row);
if(first_affected == INVALID_INDEX)
{
continue;
}
for(int index= last_affected; index >= first_affected; --index)
{
int seg_row= segs[index]->GetRow();
if(segs.size() > 1 && seg_row > 0 && seg_row >= start_row &&
seg_row <= end_row)
{
EraseSegment(segs, index, segs[index]);
}
}
}
}
}
void TimingData::GetActualBPM( float &fMinBPMOut, float &fMaxBPMOut, float highest ) const void TimingData::GetActualBPM( float &fMinBPMOut, float &fMaxBPMOut, float highest ) const
{ {
fMinBPMOut = FLT_MAX; fMinBPMOut = FLT_MAX;
+2
View File
@@ -67,6 +67,7 @@ public:
void Copy( const TimingData &other ); void Copy( const TimingData &other );
void Clear(); void Clear();
bool IsSafeFullTiming();
TimingData( const TimingData &cpy ) { Copy(cpy); } TimingData( const TimingData &cpy ) { Copy(cpy); }
TimingData& operator=( const TimingData &cpy ) { Copy(cpy); return *this; } TimingData& operator=( const TimingData &cpy ) { Copy(cpy); return *this; }
@@ -151,6 +152,7 @@ public:
void CopyRange(int start_row, int end_row, TimingSegmentType copy_type, int dest_row, TimingData& dest) const; void CopyRange(int start_row, int end_row, TimingSegmentType copy_type, int dest_row, TimingData& dest) const;
void ShiftRange(int start_row, int end_row, TimingSegmentType shift_type, int shift_amount); void ShiftRange(int start_row, int end_row, TimingSegmentType shift_type, int shift_amount);
void ClearRange(int start_row, int end_row, TimingSegmentType clear_type);
/** /**
* @brief Gets the actual BPM of the song, * @brief Gets the actual BPM of the song,
* while respecting a limit. * while respecting a limit.