Charter/Editor additions and fixes (#793)
* camera highlights again * option to mute all hitsounds * context menus inside context menus and wip sliders in context menu * wip volume slider stuff * strumline preview fix with resizable editors * more slider stuff * editor sfx option should now actually work for everything * fixed strumline vocals volume, fixed note type option keybinds and moved bookmarks and note types into submenus * fix for saving difficulty specific meta json * some extra misc changes fixed camera highlights not updating when zooming in/out, optimized some of the highlight draw code so it doesn't do a full loop, and added the note scale flag into the strumline preview * fix compiling after merge
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 804 B After Width: | Height: | Size: 1.0 KiB |
@@ -223,6 +223,7 @@
|
||||
<str id="resetZoom">Reset Zoom</str>
|
||||
<str id="showSectionsSeparator">Show Sections Separator</str>
|
||||
<str id="showBeatsSeparator">Show Beats Separator</str>
|
||||
<str id="showCameraHighlights">Show Camera Highlights</str>
|
||||
<str id="rainbowWaveforms">Rainbow Waveforms</str>
|
||||
<str id="lowDetailWaveforms">Low Detail Waveforms</str>
|
||||
<str id="scrollLeft">Scroll Left</str>
|
||||
@@ -236,8 +237,9 @@
|
||||
<str id="goEnd">Go forward to the end</str> <!-- used to be "Go to the end" -->
|
||||
<str id="addOpponentCamera">Add camera on Opponent</str>
|
||||
<str id="addPlayerCamera">Add camera on Player</str>
|
||||
<str id="muteInst">Mute instrumental</str>
|
||||
<str id="muteVoices">Mute voices</str>
|
||||
<str id="inst">Instrumental</str>
|
||||
<str id="voices">Voices</str>
|
||||
<str id="hitsounds">Hitsounds</str>
|
||||
</group>
|
||||
|
||||
<group name="BookmarkMenu" prefix="bookmarks.">
|
||||
@@ -250,6 +252,7 @@
|
||||
<str id="editBookmarkListTitle">Bookmark List</str>
|
||||
<str id="editBookmarksTitle">Edit Bookmarks</str>
|
||||
<str id="newBookmarkName">New Bookmark</str>
|
||||
<str id="bookmarkList">Bookmark List</str>
|
||||
</group>
|
||||
|
||||
<str id="topBar.note">Note</str>
|
||||
@@ -258,6 +261,7 @@
|
||||
<str id="subtractSustainLength">Subtract sustain length</str>
|
||||
<str id="selectAll">Select all</str>
|
||||
<str id="selectMeasure">Select measure</str>
|
||||
<str id="noteTypesList">Note Types List</str>
|
||||
<str id="editNoteTypesList">Edit Note Types List</str>
|
||||
</group>
|
||||
<str id="topBar.snap">Snap</str>
|
||||
@@ -308,8 +312,9 @@
|
||||
<group name="StrumlineOptions" prefix="strumLine.">
|
||||
<str id="button-name">Options ↓</str>
|
||||
|
||||
<str id="waveforms">Waveforms</str>
|
||||
<str id="hitsounds">Hitsounds</str>
|
||||
<str id="muteVocals">Mute Vocals</str>
|
||||
<str id="vocals">Vocals</str>
|
||||
<str id="edit">Edit</str>
|
||||
<str id="delete">Delete</str>
|
||||
|
||||
|
||||
@@ -278,9 +278,13 @@ class Chart {
|
||||
var filteredChart = filterChartForSaving(chart, saveSettings.saveMetaInChart, saveSettings.saveLocalEvents, saveSettings.saveGlobalEvents && saveSettings.seperateGlobalEvents != true);
|
||||
|
||||
#if sys
|
||||
var songPath = saveSettings.songFolder == null ? 'songs/${chart.meta.name}' : saveSettings.songFolder, variantSuffix = variant != null && variant != "" ? '-$variant' : "";
|
||||
var metaPath = 'meta$variantSuffix.json', prettyPrint = saveSettings.prettyPrint == true ? Flags.JSON_PRETTY_PRINT : null, temp:String;
|
||||
if ((temp = Paths.assetsTree.getPath('assets/$songPath/$metaPath')) != null) {
|
||||
var songPath = saveSettings.songFolder == null ? 'songs/${chart.meta.name}' : saveSettings.songFolder, variantSuffix = variant != null && variant != "" ? '-$variant' : "", difficultySuffix = difficulty != null && difficulty != "" ? '-$difficulty' : "";
|
||||
var metaPath = 'meta$variantSuffix.json', altMetaPath = 'meta${variantSuffix}${difficultySuffix}.json', prettyPrint = saveSettings.prettyPrint == true ? Flags.JSON_PRETTY_PRINT : null, temp:String;
|
||||
if ((temp = Paths.assetsTree.getPath('assets/$songPath/$altMetaPath')) != null) { //check for difficulty specific
|
||||
songPath = temp.substr(0, temp.length - altMetaPath.length - 1);
|
||||
metaPath = temp;
|
||||
}
|
||||
else if ((temp = Paths.assetsTree.getPath('assets/$songPath/$metaPath')) != null) {
|
||||
songPath = temp.substr(0, temp.length - metaPath.length - 1);
|
||||
metaPath = temp;
|
||||
}
|
||||
|
||||
@@ -403,12 +403,12 @@ class CharacterAnimButton extends UIButton {
|
||||
|
||||
public function toggleGhost() {
|
||||
if (valid && parent.ghosts.indexOf(anim) == -1) {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_CHARACTER_GHOSTENABLE_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_CHARACTER_GHOSTENABLE_SOUND);
|
||||
parent.ghosts.push(anim);
|
||||
ghostIcon.animation.play("alive", true);
|
||||
ghostIcon.color = 0xFFFFFFFF;
|
||||
} else {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_CHARACTER_GHOSTDISABLE_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_CHARACTER_GHOSTDISABLE_SOUND);
|
||||
parent.ghosts.remove(anim);
|
||||
ghostIcon.animation.play("dead", true);
|
||||
ghostIcon.color = 0xFFADADAD;
|
||||
|
||||
@@ -119,7 +119,7 @@ class CharacterAnimsWindow extends UIButtonList<CharacterAnimButton> {
|
||||
}
|
||||
|
||||
public function deleteAnimation(button:CharacterAnimButton, addToUndo:Bool = true) {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_DELETE_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_DELETE_SOUND);
|
||||
if (buttons.members.length <= 1) return;
|
||||
if (character.getAnimName() == button.anim)
|
||||
@:privateAccess CharacterEditor.instance._animation_down(null);
|
||||
|
||||
@@ -453,7 +453,7 @@ class CharacterEditor extends UIState {
|
||||
|
||||
function _file_save(_) {
|
||||
#if sys
|
||||
FlxG.sound.play(Paths.sound('editors/save'));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_SAVE_SOUND);
|
||||
CoolUtil.safeSaveFile(
|
||||
'${Paths.getAssetsRoot()}/data/characters/${character.curCharacter}.xml',
|
||||
buildCharacter()
|
||||
@@ -465,7 +465,7 @@ class CharacterEditor extends UIState {
|
||||
}
|
||||
|
||||
function _file_saveas(_) {
|
||||
FlxG.sound.play(Paths.sound('editors/save'));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_SAVE_SOUND);
|
||||
openSubState(new SaveSubstate(buildCharacter(), {
|
||||
defaultSaveFile: '${character.curCharacter}.xml'
|
||||
}));
|
||||
@@ -499,7 +499,7 @@ class CharacterEditor extends UIState {
|
||||
}
|
||||
|
||||
function _undo(undo:CharacterEditorChange) {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_UNDO_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_UNDO_SOUND);
|
||||
switch (undo) {
|
||||
case null: // do nothing
|
||||
case CCharEditPosition(oldPos, newPos):
|
||||
@@ -573,7 +573,7 @@ class CharacterEditor extends UIState {
|
||||
}
|
||||
|
||||
function _redo(redo:CharacterEditorChange) {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_REDO_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_REDO_SOUND);
|
||||
switch (redo) {
|
||||
case null: // do nothing
|
||||
case CCharEditPosition(oldPos, newPos):
|
||||
|
||||
@@ -77,10 +77,10 @@ class Charter extends UIState {
|
||||
public var strumlineLockButton:CharterStrumlineButton;
|
||||
|
||||
public var hitsound:FlxSound;
|
||||
public var hitsoundGlobalVolume:Float = 1.0;
|
||||
public var metronome:FlxSound;
|
||||
|
||||
public var vocals:FlxSound;
|
||||
public var voicesMuted:Bool = false;
|
||||
|
||||
public var quant:Int = 16;
|
||||
public var quants:Array<Int> = [4, 8, 12, 16, 20, 24, 32, 48, 64, 192]; // different quants
|
||||
@@ -96,6 +96,7 @@ class Charter extends UIState {
|
||||
public var rightEventRowText:UIText;
|
||||
public var leftEventsGroup:CharterEventGroup = new CharterEventGroup();
|
||||
public var rightEventsGroup:CharterEventGroup = new CharterEventGroup();
|
||||
public var cameraMovementChanges:Array<CameraChange> = [];
|
||||
|
||||
public var charterCamera:FlxCamera;
|
||||
public var uiCamera:FlxCamera;
|
||||
@@ -308,6 +309,11 @@ class Charter extends UIState {
|
||||
onSelect: _view_showeventBeatSeparator,
|
||||
icon: Options.charterShowBeats ? 1 : 0
|
||||
},
|
||||
{
|
||||
label: translate("view.showCameraHighlights"),
|
||||
onSelect: _view_showeventCameraHighlights,
|
||||
icon: Options.charterShowCameraHighlights ? 1 : 0
|
||||
},
|
||||
null,
|
||||
{
|
||||
label: translate("view.rainbowWaveforms"),
|
||||
@@ -515,7 +521,7 @@ class Charter extends UIState {
|
||||
|
||||
strumlineLockButton = new CharterStrumlineButton("editors/charter/lock-strumline", translate("lock-unlock"));
|
||||
strumlineLockButton.onClick = function () {
|
||||
FlxG.sound.play(Paths.sound(!strumLines.draggable ? Flags.DEFAULT_CHARTER_STRUMUNLOCK_SOUND : Flags.DEFAULT_CHARTER_STRUMLOCK_SOUND));
|
||||
UIState.playEditorSound(!strumLines.draggable ? Flags.DEFAULT_CHARTER_STRUMUNLOCK_SOUND : Flags.DEFAULT_CHARTER_STRUMLOCK_SOUND);
|
||||
if (strumLines != null) {
|
||||
strumLines.draggable = !strumLines.draggable;
|
||||
strumlineLockButton.textTweenColor.color = strumLines.draggable ? 0xFF5C95CA : 0xFFE16565;
|
||||
@@ -685,6 +691,7 @@ class Charter extends UIState {
|
||||
CharterGridSeperatorBase.lastConductorSprY = Math.NEGATIVE_INFINITY;
|
||||
|
||||
updateWaveforms();
|
||||
updateCameraChanges();
|
||||
}
|
||||
|
||||
public function getWavesToGenerate():Array<{name:String, sound:FlxSound}> {
|
||||
@@ -740,6 +747,38 @@ class Charter extends UIState {
|
||||
}
|
||||
}
|
||||
|
||||
public function updateCameraChanges() {
|
||||
if (!Options.charterShowCameraHighlights) return;
|
||||
|
||||
cameraMovementChanges = [];
|
||||
for (grp in [leftEventsGroup, rightEventsGroup]) {
|
||||
grp.filterEvents();
|
||||
grp.sortEvents();
|
||||
for(e in grp.members) {
|
||||
for(event in e.events) {
|
||||
if (event.name == "Camera Movement") {
|
||||
cameraMovementChanges.push({
|
||||
strumLineID: event.params[0],
|
||||
step: e.step,
|
||||
endStep: __endStep
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//need to sort again for both local and global events to be used
|
||||
cameraMovementChanges.sort(function(e1, e2) {
|
||||
return FlxSort.byValues(FlxSort.ASCENDING, e1.step, e2.step);
|
||||
});
|
||||
//update previous change
|
||||
if (cameraMovementChanges.length > 0) {
|
||||
for (i in 1...cameraMovementChanges.length) {
|
||||
cameraMovementChanges[i-1].endStep = cameraMovementChanges[i].step;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public override function beatHit(curBeat:Int) {
|
||||
super.beatHit(curBeat);
|
||||
if (FlxG.sound.music.playing) {
|
||||
@@ -802,7 +841,7 @@ class Charter extends UIState {
|
||||
else
|
||||
Chart.save(PlayState.SONG, __diff.toLowerCase(), __variant, {saveMetaInChart: true, saveLocalEvents: true, seperateGlobalEvents: true, prettyPrint: Options.editorCharterPrettyPrint});
|
||||
|
||||
FlxG.sound.play(Paths.sound('editors/save'));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_SAVE_SOUND);
|
||||
undos.save();
|
||||
}
|
||||
autoSaveNotif.cancelled = false;
|
||||
@@ -962,7 +1001,7 @@ class Charter extends UIState {
|
||||
notesGroup.add(note);
|
||||
selection = [note];
|
||||
undos.addToUndo(CCreateSelection([note]));
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_CHARTER_NOTEPLACE_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_CHARTER_NOTEPLACE_SOUND);
|
||||
}
|
||||
isSelecting = false;
|
||||
}
|
||||
@@ -1091,7 +1130,7 @@ class Charter extends UIState {
|
||||
if (selected == null) return selected;
|
||||
|
||||
if (selected is CharterNote) {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_CHARTER_NOTEDELETE_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_CHARTER_NOTEDELETE_SOUND);
|
||||
var note:CharterNote = cast selected;
|
||||
note.strumLineID = strumLines.members.indexOf(note.strumLine);
|
||||
note.strumLine = null; // For static undos :D
|
||||
@@ -1571,20 +1610,20 @@ class Charter extends UIState {
|
||||
else {undos = null; FlxG.switchState(new CharterSelection()); Charter.instance.__clearStatics();}
|
||||
}
|
||||
|
||||
function _file_save_all(_) {saveEverything(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_save(_) {saveChart(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_saveas(_) {saveChartAs(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_events_save(_) {saveEvents(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_events_saveas(_) {saveEventsAs(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_save_no_events(_) {saveChart(true, false); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_saveas_no_events(_) {saveChartAs(true, false); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_meta_save(_) {saveMeta(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_meta_saveas(_) {saveMetaAs(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_saveas_fnflegacy(_) {saveLegacyChartAs(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_saveas_psych(_) {savePsychChartAs(); FlxG.sound.play(Paths.sound('editors/save'));}
|
||||
function _file_save_all(_) {saveEverything(); UIState.playEditorSound(Flags.DEFAULT_EDITOR_SAVE_SOUND);}
|
||||
function _file_save(_) {saveChart(); UIState.playEditorSound(Flags.DEFAULT_EDITOR_SAVE_SOUND);}
|
||||
function _file_saveas(_) {saveChartAs(); UIState.playEditorSound(Flags.DEFAULT_EDITOR_SAVE_SOUND);}
|
||||
function _file_events_save(_) {saveEvents(); UIState.playEditorSound(Flags.DEFAULT_EDITOR_SAVE_SOUND);}
|
||||
function _file_events_saveas(_) {saveEventsAs(); UIState.playEditorSound(Flags.DEFAULT_EDITOR_SAVE_SOUND);}
|
||||
function _file_save_no_events(_) {saveChart(true, false); UIState.playEditorSound(Flags.DEFAULT_EDITOR_SAVE_SOUND);}
|
||||
function _file_saveas_no_events(_) {saveChartAs(true, false); UIState.playEditorSound(Flags.DEFAULT_EDITOR_SAVE_SOUND);}
|
||||
function _file_meta_save(_) {saveMeta(); UIState.playEditorSound(Flags.DEFAULT_EDITOR_SAVE_SOUND);}
|
||||
function _file_meta_saveas(_) {saveMetaAs(); UIState.playEditorSound(Flags.DEFAULT_EDITOR_SAVE_SOUND);}
|
||||
function _file_saveas_fnflegacy(_) {saveLegacyChartAs(); UIState.playEditorSound(Flags.DEFAULT_EDITOR_SAVE_SOUND);}
|
||||
function _file_saveas_psych(_) {savePsychChartAs(); UIState.playEditorSound(Flags.DEFAULT_EDITOR_SAVE_SOUND);}
|
||||
|
||||
function _edit_copy(_, playSFX=true) {
|
||||
if (playSFX) FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_COPY_SOUND));
|
||||
if (playSFX) UIState.playEditorSound(Flags.DEFAULT_EDITOR_COPY_SOUND);
|
||||
if(selection.length == 0) return;
|
||||
|
||||
var minStep:Float = selection[0].step;
|
||||
@@ -1603,7 +1642,7 @@ class Charter extends UIState {
|
||||
];
|
||||
}
|
||||
function _edit_paste(_) {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_PASTE_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_PASTE_SOUND);
|
||||
if (clipboard.length <= 0) return;
|
||||
|
||||
var minStep = curStep;
|
||||
@@ -1631,7 +1670,7 @@ class Charter extends UIState {
|
||||
}
|
||||
|
||||
function _edit_cut(_) {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_CUT_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_CUT_SOUND);
|
||||
if (selection == null || selection.length == 0) return;
|
||||
|
||||
_edit_copy(_, false);
|
||||
@@ -1639,7 +1678,7 @@ class Charter extends UIState {
|
||||
}
|
||||
|
||||
function _edit_delete(_) {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_DELETE_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_DELETE_SOUND);
|
||||
if (selection == null || selection.length == 0) return;
|
||||
selection.loop((n:CharterNote) -> {
|
||||
noteDeleteAnims.deleteNotes.push({note: n, time: noteDeleteAnims.deleteTime});
|
||||
@@ -1648,7 +1687,7 @@ class Charter extends UIState {
|
||||
}
|
||||
|
||||
function _undo(undo:CharterChange) {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_UNDO_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_UNDO_SOUND);
|
||||
switch(undo) {
|
||||
case null: // do nothing
|
||||
case CDeleteStrumLine(strumLineID, strumLine):
|
||||
@@ -1709,7 +1748,7 @@ class Charter extends UIState {
|
||||
}
|
||||
|
||||
function _redo(redo:CharterChange) {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_REDO_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_REDO_SOUND);
|
||||
switch(redo) {
|
||||
case null: // do nothing
|
||||
case CDeleteStrumLine(strumLineID, strumLine):
|
||||
@@ -1808,14 +1847,24 @@ class Charter extends UIState {
|
||||
function _playback_metronome(t) {
|
||||
t.icon = (Options.charterMetronomeEnabled = !Options.charterMetronomeEnabled) ? 1 : 0;
|
||||
}
|
||||
function _song_muteinst(t) {
|
||||
FlxG.sound.music.volume = FlxG.sound.music.volume > 0 ? 0 : 1;
|
||||
t.icon = 1 - Std.int(Math.ceil(FlxG.sound.music.volume));
|
||||
|
||||
public function _slider_mutetoggle(t:UIContextMenuOption) {
|
||||
if (t.slider == null) return;
|
||||
t.button.slider.value = t.button.slider.value > 0 ? 0 : 1;
|
||||
}
|
||||
function _song_mutevoices(t) {
|
||||
vocals.volume = (voicesMuted = !voicesMuted) ? 0 : 1;
|
||||
for (strumLine in strumLines.members) strumLine.updateVoicesVolume();
|
||||
t.icon = voicesMuted ? 1 : 0;
|
||||
|
||||
function _song_instvolume(t) {
|
||||
FlxG.sound.music.volume = t.slider.value;
|
||||
t.icon = t.slider.value > 0.5 ? 7 : (t.slider.value > 0 ? 8 : 9);
|
||||
}
|
||||
function _song_voicesvolume(t) {
|
||||
vocals.volume = t.slider.value;
|
||||
for (strumLine in strumLines.members) strumLine.vocals.volume = t.slider.value * strumLine.vocalsVolume;
|
||||
t.icon = t.slider.value > 0.5 ? 7 : (t.slider.value > 0 ? 8 : 9);
|
||||
}
|
||||
function _song_hitsoundvolume(t) {
|
||||
hitsoundGlobalVolume = t.slider.value;
|
||||
t.icon = t.slider.value > 0.5 ? 7 : (t.slider.value > 0 ? 8 : 9);
|
||||
}
|
||||
function _playback_back(_) {
|
||||
if (FlxG.sound.music.playing) return;
|
||||
@@ -1860,6 +1909,7 @@ class Charter extends UIState {
|
||||
__event.refreshEventIcons();
|
||||
(__event.global ? rightEventsGroup : leftEventsGroup).add(__event);
|
||||
undos.addToUndo(CEditEvent(__event, [], __event.events));
|
||||
updateCameraChanges();
|
||||
}
|
||||
|
||||
public function getBookmarkList():Array<ChartBookmark> {
|
||||
@@ -2011,26 +2061,56 @@ class Charter extends UIState {
|
||||
|
||||
if (bookmarks.length > 0)
|
||||
{
|
||||
var bookmarkOptions:Array<UIContextMenuOption> = [];
|
||||
var goToBookmark = TU.getRaw("charter.bookmarks.goTo");
|
||||
for (b in bookmarks)
|
||||
{
|
||||
newChilds.push({
|
||||
bookmarkOptions.push({
|
||||
label: goToBookmark.format([b.name]),
|
||||
onSelect: function(_) { Conductor.songPosition = Conductor.getTimeForStep(b.time); }
|
||||
});
|
||||
}
|
||||
newChilds.push({
|
||||
label: translate("bookmarks.bookmarkList"),
|
||||
childs: bookmarkOptions
|
||||
});
|
||||
newChilds.push(null);
|
||||
}
|
||||
|
||||
|
||||
newChilds.push({
|
||||
label: translate("song.muteInst"),
|
||||
onSelect: _song_muteinst
|
||||
label: translate("song.inst"),
|
||||
slider: {
|
||||
min: 0,
|
||||
max: 1,
|
||||
value: 1,
|
||||
onChange: _song_instvolume
|
||||
},
|
||||
onIconClick: _slider_mutetoggle,
|
||||
icon: 7
|
||||
});
|
||||
|
||||
newChilds.push({
|
||||
label: translate("song.muteVoices"),
|
||||
onSelect: _song_mutevoices
|
||||
label: translate("song.voices"),
|
||||
slider: {
|
||||
min: 0,
|
||||
max: 1,
|
||||
value: 1,
|
||||
onChange: _song_voicesvolume
|
||||
},
|
||||
onIconClick: _slider_mutetoggle,
|
||||
icon: 7
|
||||
});
|
||||
|
||||
newChilds.push({
|
||||
label: translate("song.hitsounds"),
|
||||
slider: {
|
||||
min: 0,
|
||||
max: 1,
|
||||
value: 1,
|
||||
onChange: _song_hitsoundvolume
|
||||
},
|
||||
onIconClick: _slider_mutetoggle,
|
||||
icon: 7
|
||||
});
|
||||
|
||||
if (songTopButton != null) songTopButton.contextMenu = newChilds;
|
||||
@@ -2055,6 +2135,10 @@ class Charter extends UIState {
|
||||
function _view_showeventBeatSeparator(t) {
|
||||
t.icon = (Options.charterShowBeats = !Options.charterShowBeats) ? 1 : 0;
|
||||
}
|
||||
function _view_showeventCameraHighlights(t) {
|
||||
t.icon = (Options.charterShowCameraHighlights = !Options.charterShowCameraHighlights) ? 1 : 0;
|
||||
updateCameraChanges();
|
||||
}
|
||||
function _view_switchWaveformRainbow(t) {
|
||||
t.icon = (Options.charterRainbowWaveforms = !Options.charterRainbowWaveforms) ? 1 : 0;
|
||||
|
||||
@@ -2080,8 +2164,8 @@ class Charter extends UIState {
|
||||
inline function _snap_decreasesnap(_) changequant(-1);
|
||||
inline function _snap_resetsnap(_) setquant(16);
|
||||
|
||||
inline function changequant(change:Int) {FlxG.sound.play(Paths.sound(Flags.DEFAULT_CHARTER_SNAPPINGCHANGE_SOUND)); quant = quants[FlxMath.wrap(quants.indexOf(quant) + change, 0, quants.length-1)]; buildSnapsUI();};
|
||||
inline function setquant(newQuant:Int) {FlxG.sound.play(Paths.sound(Flags.DEFAULT_CHARTER_SNAPPINGCHANGE_SOUND)); quant = newQuant; buildSnapsUI();}
|
||||
inline function changequant(change:Int) {UIState.playEditorSound(Flags.DEFAULT_CHARTER_SNAPPINGCHANGE_SOUND); quant = quants[FlxMath.wrap(quants.indexOf(quant) + change, 0, quants.length-1)]; buildSnapsUI();};
|
||||
inline function setquant(newQuant:Int) {UIState.playEditorSound(Flags.DEFAULT_CHARTER_SNAPPINGCHANGE_SOUND); quant = newQuant; buildSnapsUI();}
|
||||
|
||||
function buildSnapsUI():Array<UIContextMenuOption> {
|
||||
var snapsTopButton:UITopMenuButton = topMenuSpr == null ? null : cast topMenuSpr.members[snapIndex];
|
||||
@@ -2117,12 +2201,12 @@ class Charter extends UIState {
|
||||
}
|
||||
|
||||
inline function _note_addsustain(t) {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_CHARTER_SUSTAINADD_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_CHARTER_SUSTAINADD_SOUND);
|
||||
changeNoteSustain(1);
|
||||
}
|
||||
|
||||
inline function _note_subtractsustain(t) {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_CHARTER_SUSTAINDELETE_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_CHARTER_SUSTAINDELETE_SOUND);
|
||||
changeNoteSustain(-1);
|
||||
}
|
||||
|
||||
@@ -2199,16 +2283,18 @@ class Charter extends UIState {
|
||||
keybind: [CONTROL, SHIFT, A],
|
||||
onSelect: _note_selectmeasure
|
||||
},
|
||||
null,
|
||||
{
|
||||
label: "(0) " + translate("noteTypes.default"),
|
||||
keybind: [ZERO],
|
||||
onSelect: (_) -> {changeNoteType(0);},
|
||||
icon: this.noteType == 0 ? 1 : 0
|
||||
}
|
||||
null
|
||||
];
|
||||
|
||||
var noteKeys:Array<FlxKey> = [ZERO, ONE, TWO, THREE, FOUR, FIVE, SIX, SEVEN, EIGHT, NINE];
|
||||
var noteTypeOptions:Array<UIContextMenuOption> = [{
|
||||
label: "(0) " + translate("noteTypes.default"),
|
||||
keybind: [ZERO],
|
||||
onSelect: (_) -> {changeNoteType(0);},
|
||||
icon: this.noteType == 0 ? 1 : 0
|
||||
}];
|
||||
|
||||
final noteKeys:Array<Array<Array<FlxKey>>> = [[[ZERO], [NUMPADZERO]], [[ONE], [NUMPADONE]], [[TWO], [NUMPADTWO]], [[THREE], [NUMPADTHREE]], [[FOUR], [NUMPADFOUR]], [[FIVE], [NUMPADFIVE]],
|
||||
[[SIX], [NUMPADSIX]], [[SEVEN], [NUMPADSEVEN]], [[EIGHT], [NUMPADEIGHT]], [[NINE], [NUMPADNINE]]];
|
||||
for (i=>type in noteTypes) {
|
||||
var realNoteID:Int = i+1; // Default Note not stored
|
||||
var newChild:UIContextMenuOption = {
|
||||
@@ -2217,9 +2303,13 @@ class Charter extends UIState {
|
||||
onSelect: (_) -> {changeNoteType(realNoteID);},
|
||||
icon: this.noteType == realNoteID ? 1 : 0
|
||||
};
|
||||
if (realNoteID <= 9) newChild.keybind = [noteKeys[realNoteID]];
|
||||
newChilds.push(newChild);
|
||||
if (realNoteID <= 9) newChild.keybinds = noteKeys[realNoteID];
|
||||
noteTypeOptions.push(newChild);
|
||||
}
|
||||
newChilds.push({
|
||||
label: translate("note.noteTypesList"),
|
||||
childs: noteTypeOptions
|
||||
});
|
||||
newChilds.push({
|
||||
label: translate("note.editNoteTypesList"),
|
||||
color: 0xFF959829, icon: 4,
|
||||
@@ -2227,6 +2317,7 @@ class Charter extends UIState {
|
||||
onSelect: editNoteTypesList
|
||||
});
|
||||
if (noteTopButton != null) noteTopButton.contextMenu = newChilds;
|
||||
if (topMenu != null && topMenu[noteIndex] != null) topMenu[noteIndex].childs = newChilds;
|
||||
return newChilds;
|
||||
}
|
||||
|
||||
@@ -2314,8 +2405,12 @@ class Charter extends UIState {
|
||||
}
|
||||
}
|
||||
|
||||
public inline function hitsoundsEnabled(id:Int)
|
||||
return strumLines.members[id] != null && strumLines.members[id].hitsounds;
|
||||
public inline function playHitsound(id:Int) {
|
||||
if (strumLines.members[id] != null && strumLines.members[id].hitsoundVolume > 0 && hitsoundGlobalVolume > 0) {
|
||||
hitsound.volume = hitsoundGlobalVolume * strumLines.members[id].hitsoundVolume;
|
||||
hitsound.replay();
|
||||
}
|
||||
}
|
||||
|
||||
public inline function __fixSelection(selection:Selection):Selection {
|
||||
var newSelection:Selection = new Selection();
|
||||
@@ -2406,7 +2501,7 @@ class Charter extends UIState {
|
||||
quantSelected: quant,
|
||||
noteTypeSelected: noteType,
|
||||
strumlinesDraggable: strumLines.draggable,
|
||||
hitSounds: [for (strumLine in strumLines.members) strumLine.hitsounds],
|
||||
hitSounds: [for (strumLine in strumLines.members) strumLine.hitsoundVolume > 0],
|
||||
mutedVocals: [for (strumLine in strumLines.members) !(strumLine.vocals.volume > 0)],
|
||||
waveforms: [for (strumLine in strumLines.members) strumLine.selectedWaveform]
|
||||
}
|
||||
@@ -2422,7 +2517,7 @@ class Charter extends UIState {
|
||||
strumLines.draggable = playtestInfo.strumlinesDraggable;
|
||||
|
||||
for (i => strumLine in strumLines.members)
|
||||
strumLine.hitsounds = playtestInfo.hitSounds[i];
|
||||
strumLine.hitsoundVolume = playtestInfo.hitSounds[i] ? 1 : 0;
|
||||
for (i => strumLine in strumLines.members)
|
||||
strumLine.vocals.volume = playtestInfo.mutedVocals[i] ? 0 : 1;
|
||||
for (i => strumLine in strumLines.members)
|
||||
@@ -2514,3 +2609,9 @@ typedef PlaytestInfo = {
|
||||
var mutedVocals:Array<Bool>;
|
||||
var waveforms:Array<Int>;
|
||||
}
|
||||
|
||||
typedef CameraChange = {
|
||||
var strumLineID:Int;
|
||||
var step:Float;
|
||||
var endStep:Float;
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ class CharterAutoSaveUI extends UISliceSprite {
|
||||
icon.animation.curAnim.curFrame = 1;
|
||||
for (member in [this, progressBar, progressBarBack, autosavingText]) member.color = 0xFFA3EC95;
|
||||
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_AUTOSAVE_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_AUTOSAVE_SOUND);
|
||||
|
||||
(new FlxTimer()).start(1, (_) -> {disappearAnimation();});
|
||||
});
|
||||
|
||||
@@ -178,6 +178,8 @@ class CharterBackdrop extends FlxTypedGroup<FlxBasic> {
|
||||
public var gridShader:CustomShader = new CustomShader("engine/charterGrid");
|
||||
var __lastKeyCount:Int = 4;
|
||||
|
||||
public var cameraHighlight:CameraHighlight;
|
||||
|
||||
public function new() {
|
||||
super();
|
||||
|
||||
@@ -187,6 +189,10 @@ class CharterBackdrop extends FlxTypedGroup<FlxBasic> {
|
||||
add(gridBackDrop);
|
||||
gridShader.hset("segments", 4);
|
||||
|
||||
cameraHighlight = new CameraHighlight(this);
|
||||
cameraHighlight.makeSolid(1, 1, 0xFFFFFFFF);
|
||||
add(cameraHighlight);
|
||||
|
||||
waveformSprite = new FlxSprite().makeSolid(1, 1, 0xFF000000);
|
||||
waveformSprite.scale.set(160, 1);
|
||||
waveformSprite.updateHitbox();
|
||||
@@ -247,10 +253,11 @@ class CharterBackdrop extends FlxTypedGroup<FlxBasic> {
|
||||
x = strumLine.x;
|
||||
alpha = strumLine.strumLine.visible ? 0.9 : 0.4;
|
||||
keyCount = strumLine.keyCount;
|
||||
cameraHighlight.color = strumLine.highlightColor;
|
||||
} else alpha = 0.9;
|
||||
|
||||
for (spr in [gridBackDrop, beatSeparator, topLimit, bottomLimit,
|
||||
topSeparator, bottomSeparator, conductorFollowerSpr, waveformSprite]) {
|
||||
topSeparator, bottomSeparator, conductorFollowerSpr, waveformSprite, cameraHighlight]) {
|
||||
spr.x = x; if (spr != waveformSprite) spr.alpha = alpha;
|
||||
spr.cameras = this.cameras;
|
||||
}
|
||||
@@ -272,6 +279,9 @@ class CharterBackdrop extends FlxTypedGroup<FlxBasic> {
|
||||
spr.updateHitbox();
|
||||
}
|
||||
|
||||
cameraHighlight.scale.x = (keyCount * 40)-2;
|
||||
cameraHighlight.x += 1;
|
||||
|
||||
waveformSprite.visible = waveformSprite.shader != null;
|
||||
if (waveformSprite.shader == null) return;
|
||||
|
||||
@@ -311,16 +321,19 @@ class CharterGridSeperatorBase extends FlxSprite {
|
||||
private static var lastMaxMeasure:Float = -1;
|
||||
|
||||
public static var lastConductorSprY:Float = Math.NEGATIVE_INFINITY;
|
||||
public static var lastCameraZoom:Float = -1;
|
||||
|
||||
private static var beatStepTimes:Array<Float> = [];
|
||||
private static var measureStepTimes:Array<Float> = [];
|
||||
private static var timeSignatureChangeGaps:Array<Float> = [];
|
||||
|
||||
private function recalculateBeats() {
|
||||
@:privateAccess
|
||||
var currentZoom = Charter.instance.__camZoom;
|
||||
var conductorSprY = Charter.instance.gridBackdrops.conductorSprY;
|
||||
if (conductorSprY == lastConductorSprY) return;
|
||||
if (conductorSprY == lastConductorSprY && currentZoom == lastCameraZoom) return; //only update if song pos or camera zoom has changed
|
||||
|
||||
var zoomOffset = ((FlxG.height * (1/cameras[0].zoom)) * 0.5);
|
||||
var zoomOffset = ((FlxG.height * (1/currentZoom)) * 0.5);
|
||||
|
||||
minStep = (conductorSprY - zoomOffset)/40;
|
||||
maxStep = (conductorSprY + zoomOffset)/40;
|
||||
@@ -359,6 +372,7 @@ class CharterGridSeperatorBase extends FlxSprite {
|
||||
}
|
||||
|
||||
lastConductorSprY = conductorSprY;
|
||||
lastCameraZoom = currentZoom;
|
||||
}
|
||||
|
||||
private inline function calculateTimeSignatureGaps() {
|
||||
@@ -446,6 +460,77 @@ class CharterGridSeperator extends CharterGridSeperatorBase {
|
||||
}
|
||||
}
|
||||
|
||||
class CameraHighlight extends FlxSprite {
|
||||
|
||||
private var grid:CharterBackdrop;
|
||||
private var _currentCameraMovementIndex:Int = 0;
|
||||
public function new(grid:CharterBackdrop) {
|
||||
this.grid = grid;
|
||||
super();
|
||||
}
|
||||
|
||||
override public function draw() {
|
||||
if (!Options.charterShowCameraHighlights || grid.strumLine == null) return;
|
||||
|
||||
@:privateAccess
|
||||
var minStep = CharterGridSeperatorBase.minStep;
|
||||
@:privateAccess
|
||||
var maxStep = CharterGridSeperatorBase.maxStep;
|
||||
@:privateAccess
|
||||
var strumLineID = Charter.instance.strumLines.isDragging ? Charter.instance.strumLines.__pastStrumlines.indexOf(grid.strumLine) : Charter.instance.gridBackdrops.members.indexOf(grid);
|
||||
|
||||
//first default camera change
|
||||
if ((Charter.instance.cameraMovementChanges[0] == null || Charter.instance.cameraMovementChanges[0].step != 0) && strumLineID == 0) {
|
||||
var endStep = Charter.instance.cameraMovementChanges[0] != null ? Charter.instance.cameraMovementChanges[0].step : Charter.instance.__endStep;
|
||||
|
||||
if (endStep >= minStep) {
|
||||
setupHighlight(0, endStep); super.draw();
|
||||
setupLine(endStep); super.draw();
|
||||
}
|
||||
}
|
||||
|
||||
//update index if gone backwards
|
||||
while(_currentCameraMovementIndex > 0) {
|
||||
if (Charter.instance.cameraMovementChanges[_currentCameraMovementIndex] == null || Charter.instance.cameraMovementChanges[_currentCameraMovementIndex].endStep >= minStep) {
|
||||
_currentCameraMovementIndex--;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
var seenFirstVisible = false;
|
||||
for (i in _currentCameraMovementIndex...Charter.instance.cameraMovementChanges.length) {
|
||||
var change = Charter.instance.cameraMovementChanges[i];
|
||||
if (change.endStep >= minStep) {
|
||||
if (!seenFirstVisible) {
|
||||
_currentCameraMovementIndex = i; //remember the index for the next frame, so we dont need to loop through everything every time
|
||||
seenFirstVisible = true;
|
||||
}
|
||||
if (change.strumLineID == strumLineID) {
|
||||
setupHighlight(change.step, change.endStep); super.draw();
|
||||
setupLine(change.step); super.draw();
|
||||
setupLine(change.endStep); super.draw();
|
||||
}
|
||||
}
|
||||
if (change.endStep > maxStep) break;
|
||||
}
|
||||
}
|
||||
|
||||
private inline function setupHighlight(step:Float, endStep:Float) {
|
||||
y = step * 40;
|
||||
alpha = 0.15;
|
||||
scale.y = (endStep -step) * 40;
|
||||
updateHitbox();
|
||||
}
|
||||
|
||||
private inline function setupLine(step:Float) {
|
||||
y = (step * 40)-1;
|
||||
alpha = 0.8;
|
||||
scale.y = 2;
|
||||
updateHitbox();
|
||||
}
|
||||
}
|
||||
|
||||
class EventBackdrop extends FlxBackdrop {
|
||||
public var eventBeatSeparator:CharterEventGridSeperator;
|
||||
|
||||
|
||||
@@ -161,8 +161,9 @@ class CharterNote extends UISprite implements ICharterSelectable {
|
||||
}
|
||||
|
||||
if (__passed != (__passed = step < Conductor.curStepFloat + (Options.songOffsetAffectEditors ? (Conductor.songOffset / Conductor.stepCrochet) : 0))) {
|
||||
if (__passed && FlxG.sound.music.playing && Charter.instance.hitsoundsEnabled(strumLineID))
|
||||
Charter.instance.hitsound.replay();
|
||||
if (__passed && FlxG.sound.music.playing) {
|
||||
Charter.instance.playHitsound(strumLineID);
|
||||
}
|
||||
}
|
||||
|
||||
if (strumLine != null) {
|
||||
|
||||
@@ -21,7 +21,7 @@ class CharterPreviewStrumLine extends FlxTypedGroup<FlxSprite>
|
||||
for (i in 0...keyCount){
|
||||
var strum = new FlxSprite();
|
||||
strum.frames = Paths.getFrames("game/notes/default");
|
||||
strum.setGraphicSize(Std.int((strum.width * 0.7) * scale));
|
||||
strum.setGraphicSize(Std.int((strum.width * Flags.DEFAULT_NOTE_SCALE) * scale));
|
||||
strum.updateHitbox();
|
||||
|
||||
var animPrefix = strumAnimPrefix[i % 4];
|
||||
@@ -33,7 +33,7 @@ class CharterPreviewStrumLine extends FlxTypedGroup<FlxSprite>
|
||||
|
||||
note = new FlxSprite();
|
||||
note.frames = Paths.getFrames("game/notes/default");
|
||||
note.setGraphicSize(Std.int((note.width * 0.7) * scale));
|
||||
note.setGraphicSize(Std.int((note.width * Flags.DEFAULT_NOTE_SCALE) * scale));
|
||||
note.updateHitbox();
|
||||
note.animation.addByPrefix('purple', 'purple0');
|
||||
note.animation.play('purple');
|
||||
@@ -41,7 +41,7 @@ class CharterPreviewStrumLine extends FlxTypedGroup<FlxSprite>
|
||||
add(note);
|
||||
}
|
||||
|
||||
var noteTime:Float = FlxG.height;
|
||||
var noteTime:Float = FlxG.initialHeight;
|
||||
var scroll:Float = 1.0;
|
||||
|
||||
public function updatePos(x:Float, y:Float, scale:Float, spacing:Float, keyCount:Int, scrollSpeed:Float){
|
||||
@@ -53,7 +53,7 @@ class CharterPreviewStrumLine extends FlxTypedGroup<FlxSprite>
|
||||
|
||||
strum.x = CoolUtil.fpsLerp(strum.x, x + (Note.swagWidth * scale * spacing * i), 0.2);
|
||||
strum.y = CoolUtil.fpsLerp(strum.y, y + (Note.swagWidth*0.5) - (Note.swagWidth * scale * 0.5), 0.2);
|
||||
strum.scale.x = strum.scale.y = CoolUtil.fpsLerp(strum.scale.x, 0.7 * scale, 0.2);
|
||||
strum.scale.x = strum.scale.y = CoolUtil.fpsLerp(strum.scale.x, Flags.DEFAULT_NOTE_SCALE * scale, 0.2);
|
||||
strum.updateHitbox();
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ class CharterPreviewStrumLine extends FlxTypedGroup<FlxSprite>
|
||||
scroll = CoolUtil.fpsLerp(scroll, scrollSpeed, 0.2);
|
||||
noteTime -= FlxG.elapsed * scroll * 1000 * 0.45;
|
||||
if (noteTime <= 0.0)
|
||||
noteTime = FlxG.height;
|
||||
noteTime = FlxG.initialHeight;
|
||||
|
||||
note.x = members[0].x;
|
||||
note.y = members[0].y + noteTime;
|
||||
|
||||
@@ -105,6 +105,7 @@ class CharterStrumLineGroup extends FlxTypedGroup<CharterStrumline> {
|
||||
draggingObj = null;
|
||||
fixEvents();
|
||||
refreshStrumlineIDs();
|
||||
Charter.instance.updateCameraChanges();
|
||||
}
|
||||
|
||||
public inline function fixEvents() {
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package funkin.editors.charter;
|
||||
|
||||
import funkin.editors.ui.UIContextMenu.UIContextMenuOption;
|
||||
import flixel.util.FlxColor;
|
||||
import flixel.group.FlxSpriteGroup;
|
||||
import flixel.sound.FlxSound;
|
||||
import funkin.backend.chart.ChartData.ChartStrumLine;
|
||||
@@ -10,11 +12,11 @@ import funkin.game.HealthIcon;
|
||||
|
||||
class CharterStrumline extends UISprite {
|
||||
public var strumLine:ChartStrumLine;
|
||||
public var hitsounds:Bool = true;
|
||||
|
||||
public var draggingSprite:UISprite;
|
||||
public var healthIcons:FlxSpriteGroup;
|
||||
public var button:CharterStrumlineOptions;
|
||||
public var highlightColor:FlxColor;
|
||||
|
||||
public var draggable:Bool = false;
|
||||
public var dragging:Bool = false;
|
||||
@@ -22,7 +24,9 @@ class CharterStrumline extends UISprite {
|
||||
public var curMenu:UIContextMenu = null;
|
||||
|
||||
public var vocals:FlxSound;
|
||||
public var voicesMuted:Bool = false;
|
||||
public var hasVocals:Bool = false;
|
||||
public var vocalsVolume:Float = 1;
|
||||
public var hitsoundVolume:Float = 1;
|
||||
|
||||
public var keyCount:Int = 4;
|
||||
public var startingID(get, null):Int;
|
||||
@@ -142,15 +146,22 @@ class CharterStrumline extends UISprite {
|
||||
if (asset != null) {
|
||||
vocals.reset();
|
||||
vocals.loadEmbedded(asset);
|
||||
hasVocals = true;
|
||||
}
|
||||
else {
|
||||
vocals.destroy();
|
||||
hasVocals = false;
|
||||
}
|
||||
vocals.group = FlxG.sound.defaultMusicGroup;
|
||||
}
|
||||
|
||||
public function updateVoicesVolume() {
|
||||
vocals.volume = (voicesMuted || (Charter.instance?.voicesMuted ?? false)) ? 0 : 1;
|
||||
highlightColor = 0xFFFFFFFF;
|
||||
if (icons[0] != null) {
|
||||
var characterXML = Character.getXMLFromCharName(icons[0]);
|
||||
if (characterXML != null && characterXML.x.exists("color")) highlightColor = FlxColor.fromString(characterXML.x.get("color"));
|
||||
|
||||
//make darker colors more visible for the highlight
|
||||
highlightColor.brightness = Math.max(highlightColor.brightness, 0.65);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -173,18 +184,17 @@ class CharterStrumlineOptions extends UITopMenuButton {
|
||||
contextMenu = [
|
||||
{
|
||||
label: TU.translate("charter.strumLine.hitsounds"),
|
||||
onSelect: function(_) {
|
||||
strLine.hitsounds = !strLine.hitsounds;
|
||||
slider: {
|
||||
min: 0,
|
||||
max: 1,
|
||||
value: strLine.hitsoundVolume,
|
||||
onChange: function(t) {
|
||||
strLine.hitsoundVolume = t.slider.value;
|
||||
t.icon = t.slider.value > 0.5 ? 7 : (t.slider.value > 0 ? 8 : 9);
|
||||
}
|
||||
},
|
||||
icon: strLine.hitsounds ? 1 : 0
|
||||
},
|
||||
{
|
||||
label: TU.translate("charter.strumLine.muteVocals"),
|
||||
onSelect: function(_) {
|
||||
strLine.voicesMuted = !strLine.voicesMuted;
|
||||
strLine.updateVoicesVolume();
|
||||
},
|
||||
icon: strLine.voicesMuted ? 1 : 0
|
||||
onIconClick: Charter.instance._slider_mutetoggle,
|
||||
icon: 7
|
||||
},
|
||||
null,
|
||||
{
|
||||
@@ -205,20 +215,44 @@ class CharterStrumlineOptions extends UITopMenuButton {
|
||||
}
|
||||
];
|
||||
|
||||
contextMenu.insert(0, {
|
||||
label: TU.translate("charter.strumLine.noWaveform"),
|
||||
onSelect: function(_) {strLine.selectedWaveform = -1;},
|
||||
icon: strLine.selectedWaveform == -1 ? 1 : 0
|
||||
});
|
||||
if (strLine.hasVocals) {
|
||||
contextMenu.insert(1, {
|
||||
label: TU.translate("charter.strumLine.vocals"),
|
||||
slider: {
|
||||
min: 0,
|
||||
max: 1,
|
||||
value: strLine.vocalsVolume,
|
||||
onChange: function(t) {
|
||||
strLine.vocalsVolume = t.slider.value;
|
||||
strLine.vocals.volume = Charter.instance.vocals.volume * strLine.vocalsVolume;
|
||||
t.icon = t.slider.value > 0.5 ? 7 : (t.slider.value > 0 ? 8 : 9);
|
||||
}
|
||||
},
|
||||
onIconClick: Charter.instance._slider_mutetoggle,
|
||||
icon: 7
|
||||
});
|
||||
}
|
||||
|
||||
var waveformOptions:Array<UIContextMenuOption> = [
|
||||
{
|
||||
label: TU.translate("charter.strumLine.noWaveform"),
|
||||
onSelect: function(_) {strLine.selectedWaveform = -1;},
|
||||
icon: strLine.selectedWaveform == -1 ? 1 : 0
|
||||
}
|
||||
];
|
||||
|
||||
for (i => name in Charter.waveformHandler.waveformList)
|
||||
contextMenu.insert(1+i, {
|
||||
waveformOptions.push({
|
||||
label: name,
|
||||
onSelect: function(_) {strLine.selectedWaveform = i;},
|
||||
icon: strLine.selectedWaveform == i ? 6 : 5
|
||||
});
|
||||
|
||||
contextMenu.insert(1+Charter.waveformHandler.waveformList.length, null);
|
||||
contextMenu.insert(0, {
|
||||
label: TU.translate("charter.strumLine.waveforms"),
|
||||
childs: waveformOptions
|
||||
});
|
||||
contextMenu.insert(1, null);
|
||||
|
||||
var cam = Charter.instance.charterCamera;
|
||||
var point = CoolUtil.worldToScreenPosition(this, cam);
|
||||
|
||||
@@ -33,6 +33,8 @@ class CharterStrumlineScreen extends UISubstateWindow {
|
||||
|
||||
public var strumLineCam:HudCamera;
|
||||
public var previewStrumLine:CharterPreviewStrumLine;
|
||||
public var previewBorder:Array<FlxSprite> = [];
|
||||
private final borderGap:Int = 5;
|
||||
|
||||
private var onSave:ChartStrumLine -> Void = null;
|
||||
|
||||
@@ -176,20 +178,30 @@ class CharterStrumlineScreen extends UISubstateWindow {
|
||||
addLabelOn(vocalsSuffixDropDown, TU.translate("charterStrumLine.vocalSuffix"));
|
||||
|
||||
keyCountStepper = new UINumericStepper(stagePositionDropdown.x, vocalsSuffixDropDown.y, strumLine.keyCount != null ? strumLine.keyCount : 4, 1, 0, 1, 1000, 84);
|
||||
// if (Flags.CHARTER_ADVANCED_SETTINGS) {
|
||||
add(keyCountStepper);
|
||||
addLabelOn(keyCountStepper, TU.translate("charterStrumLine.keyCount"));
|
||||
// }
|
||||
add(keyCountStepper);
|
||||
addLabelOn(keyCountStepper, TU.translate("charterStrumLine.keyCount"));
|
||||
|
||||
strumLineCam = new HudCamera();
|
||||
strumLineCam.downscroll = Options.downscroll;
|
||||
strumLineCam.bgColor = 0;
|
||||
strumLineCam.alpha = 0;
|
||||
FlxG.cameras.add(strumLineCam, false);
|
||||
updateStrumlineCam(FlxG.width, FlxG.height);
|
||||
|
||||
previewStrumLine = new CharterPreviewStrumLine(0, 0, 0, 1, 4, 0);
|
||||
previewStrumLine.camera = strumLineCam;
|
||||
add(previewStrumLine);
|
||||
FlxTween.tween(strumLineCam, {alpha: 1}, 0.25, {ease: FlxEase.cubeOut});
|
||||
|
||||
//preview border
|
||||
previewBorder.push(new FlxSprite(-borderGap, -borderGap).makeSolid(FlxG.initialWidth + (borderGap*2), borderGap, 0x88FFFFFF));
|
||||
previewBorder.push(new FlxSprite(-borderGap, 0).makeSolid(borderGap, FlxG.initialHeight, 0x88FFFFFF));
|
||||
previewBorder.push(new FlxSprite(FlxG.initialWidth, 0).makeSolid(borderGap, FlxG.initialHeight, 0x88FFFFFF));
|
||||
previewBorder.push(new FlxSprite(-borderGap, FlxG.initialHeight).makeSolid(FlxG.initialWidth + (borderGap*2), borderGap, 0x88FFFFFF));
|
||||
for (border in previewBorder) {
|
||||
border.camera = strumLineCam;
|
||||
add(border);
|
||||
}
|
||||
}
|
||||
|
||||
function saveStrumline() {
|
||||
@@ -222,7 +234,7 @@ class CharterStrumlineScreen extends UISubstateWindow {
|
||||
|
||||
previewStrumLine.visible = visibleCheckbox.checked;
|
||||
|
||||
var xOffset:Float = StrumLine.calculateStartingXPos(hudXStepper.value, hudScaleStepper.value, hudSpacingStepper.value, Std.int(keyCountStepper.value));
|
||||
var xOffset:Float = StrumLine.calculateStartingXPosFromInitialWidth(hudXStepper.value, hudScaleStepper.value, hudSpacingStepper.value, Std.int(keyCountStepper.value));
|
||||
previewStrumLine.updatePos(xOffset, hudYStepper.value, hudScaleStepper.value, hudSpacingStepper.value, Std.int(keyCountStepper.value), scrollSpeed);
|
||||
|
||||
super.update(elapsed);
|
||||
@@ -233,6 +245,26 @@ class CharterStrumlineScreen extends UISubstateWindow {
|
||||
FlxTween.cancelTweensOf(strumLineCam);
|
||||
FlxG.cameras.remove(strumLineCam);
|
||||
}
|
||||
|
||||
public override function onResize(width:Int, height:Int) {
|
||||
super.onResize(width, height);
|
||||
if (!UIState.resolutionAware) return;
|
||||
|
||||
if ((width < FlxG.initialWidth || height < FlxG.initialHeight) && !Options.bypassEditorsResize) {
|
||||
width = FlxG.initialWidth; height = FlxG.initialHeight;
|
||||
}
|
||||
|
||||
updateStrumlineCam(width, height);
|
||||
}
|
||||
|
||||
private function updateStrumlineCam(windowWidth:Int, windowHeight:Int) {
|
||||
strumLineCam.width = FlxG.initialWidth + (borderGap*2);
|
||||
strumLineCam.height = FlxG.initialHeight + (borderGap*2);
|
||||
strumLineCam.x = (windowWidth/2) - (strumLineCam.width/2);
|
||||
strumLineCam.y = (windowHeight/2) - (strumLineCam.height/2);
|
||||
strumLineCam.scroll.x = -borderGap;
|
||||
strumLineCam.scroll.y = -borderGap;
|
||||
}
|
||||
}
|
||||
|
||||
class CharacterButton extends UIButton {
|
||||
|
||||
@@ -508,7 +508,7 @@ class StageEditor extends UIState {
|
||||
|
||||
function _file_save(_) {
|
||||
#if sys
|
||||
FlxG.sound.play(Paths.sound('editors/save'));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_SAVE_SOUND);
|
||||
CoolUtil.safeSaveFile(
|
||||
'${Paths.getAssetsRoot()}/data/stages/${__stage}.xml',
|
||||
buildStage()
|
||||
@@ -520,7 +520,7 @@ class StageEditor extends UIState {
|
||||
}
|
||||
|
||||
function _file_saveas(_) {
|
||||
FlxG.sound.play(Paths.sound('editors/save'));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_SAVE_SOUND);
|
||||
openSubState(new SaveSubstate(buildStage(), {
|
||||
defaultSaveFile: '${__stage}.xml'
|
||||
}));
|
||||
@@ -730,7 +730,7 @@ class StageEditor extends UIState {
|
||||
}
|
||||
|
||||
function _edit_undo(_) {
|
||||
FlxG.sound.play(Flags.DEFAULT_EDITOR_UNDO_SOUND);
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_UNDO_SOUND);
|
||||
var undo = undos.undo();
|
||||
switch(undo) {
|
||||
case null:
|
||||
@@ -756,7 +756,7 @@ class StageEditor extends UIState {
|
||||
}
|
||||
|
||||
function _edit_redo(_) {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_REDO_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_REDO_SOUND);
|
||||
var redo = undos.redo();
|
||||
switch(redo) {
|
||||
case null:
|
||||
|
||||
@@ -30,7 +30,7 @@ class UIButton extends UISliceSprite {
|
||||
super.onHovered();
|
||||
if (FlxG.mouse.justPressed) {
|
||||
hasBeenPressed = true;
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_BUTTONCLICK_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_BUTTONCLICK_SOUND);
|
||||
}
|
||||
if (FlxG.mouse.justReleased && callback != null && shouldPress && hasBeenPressed) {
|
||||
callback();
|
||||
|
||||
@@ -16,6 +16,12 @@ class UIContextMenu extends MusicBeatSubstate {
|
||||
public var contextMenuOptions:Array<UIContextMenuOptionSpr> = [];
|
||||
public var separators:Array<FlxSprite> = [];
|
||||
|
||||
public var childContextMenu:UIContextMenu = null;
|
||||
public var parentContextMenu:UIContextMenu = null;
|
||||
private var childContextMenuOptionIndex:Int = -1;
|
||||
@:allow(funkin.editors.ui.UIContextMenu)
|
||||
private var lastHoveredOptionIndex:Int = -1;
|
||||
|
||||
var scroll:Float = 0.0;
|
||||
var flipped:Bool = false;
|
||||
|
||||
@@ -96,6 +102,10 @@ class UIContextMenu extends MusicBeatSubstate {
|
||||
for(o in separators)
|
||||
o.x -= bg.bWidth;
|
||||
}
|
||||
|
||||
for(o in contextMenuOptions) {
|
||||
o.postCreate();
|
||||
}
|
||||
}
|
||||
|
||||
public function select(option:UIContextMenuOption) {
|
||||
@@ -105,12 +115,12 @@ class UIContextMenu extends MusicBeatSubstate {
|
||||
if (callback != null)
|
||||
callback(this, index, option);
|
||||
if (option.closeOnSelect == null ? true : option.closeOnSelect)
|
||||
close();
|
||||
closeWithParents();
|
||||
}
|
||||
|
||||
public override function update(elapsed:Float) {
|
||||
if (__oobDeletion && FlxG.mouse.justPressed && !bg.hoveredByChild)
|
||||
close();
|
||||
if (__oobDeletion && FlxG.mouse.justPressed && !bg.hoveredByChild && !hoveringAnyChildren())
|
||||
closeWithParents();
|
||||
|
||||
__oobDeletion = true;
|
||||
|
||||
@@ -121,6 +131,14 @@ class UIContextMenu extends MusicBeatSubstate {
|
||||
|
||||
contextCam.scroll.y = CoolUtil.fpsLerp(contextCam.scroll.y, scroll, 0.5);
|
||||
contextCam.alpha = CoolUtil.fpsLerp(contextCam.alpha, 1, 0.25);
|
||||
|
||||
if (parentContextMenu != null) {
|
||||
if (hoveringAnyParents() && parentContextMenu.lastHoveredOptionIndex != parentContextMenu.childContextMenuOptionIndex) {
|
||||
closeWithChildren();
|
||||
parentContextMenu.childContextMenuOptionIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public override function destroy() {
|
||||
@@ -129,6 +147,56 @@ class UIContextMenu extends MusicBeatSubstate {
|
||||
if (UIState.state.curContextMenu == this)
|
||||
UIState.state.curContextMenu = null;
|
||||
}
|
||||
|
||||
public function openChildContextMenu(optionSpr:UIContextMenuOptionSpr) {
|
||||
var index = contextMenuOptions.indexOf(optionSpr);
|
||||
if (index != childContextMenuOptionIndex) {
|
||||
childContextMenuOptionIndex = index;
|
||||
var child = new UIContextMenu(optionSpr.option.childs, null, optionSpr.x + optionSpr.bWidth + 4, optionSpr.y - 4);
|
||||
persistentDraw = true;
|
||||
persistentUpdate = true;
|
||||
child.parentContextMenu = this;
|
||||
childContextMenu = child;
|
||||
openSubState(child);
|
||||
}
|
||||
}
|
||||
public function closeWithParents() {
|
||||
close();
|
||||
if (parentContextMenu != null) {
|
||||
parentContextMenu.closeWithParents();
|
||||
}
|
||||
}
|
||||
public function closeWithChildren() {
|
||||
if (childContextMenu != null) {
|
||||
childContextMenu.closeWithChildren();
|
||||
}
|
||||
close();
|
||||
}
|
||||
public function hoveringAnyParents() {
|
||||
if (parentContextMenu != null) {
|
||||
return parentContextMenu.bg.hoveredByChild || parentContextMenu.hoveringAnyParents();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
public function hoveringAnyChildren() {
|
||||
if (childContextMenu != null) {
|
||||
return childContextMenu.bg.hoveredByChild || childContextMenu.hoveringAnyChildren();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
typedef UIContextMenuSliderOptionData = {
|
||||
var min:Float;
|
||||
var max:Float;
|
||||
var value:Float;
|
||||
var ?onChange:UIContextMenuOption->Void;
|
||||
//default = 120, ignored if sameLine = false
|
||||
var ?width:Float;
|
||||
//disables stepper and text if false, default = false
|
||||
var ?showValues:Bool;
|
||||
//if true, the slider will be on the same line as the label text, otherwise it will be on the next line below the label
|
||||
var ?sameLine:Bool;
|
||||
}
|
||||
|
||||
typedef UIContextMenuCallback = UIContextMenu->Int->UIContextMenuOption->Void;
|
||||
@@ -144,13 +212,24 @@ typedef UIContextMenuOption = {
|
||||
var ?button:UIContextMenuOptionSpr;
|
||||
var ?onCreate:UIContextMenuOptionSpr->Void;
|
||||
var ?childs:Array<UIContextMenuOption>;
|
||||
var ?slider:UIContextMenuSliderOptionData;
|
||||
var ?onIconClick:UIContextMenuOption->Void;
|
||||
}
|
||||
|
||||
enum abstract UIContextMenuOptionType(Int) from Int {
|
||||
var DEFAULT = 0;
|
||||
var SUBMENU = 1;
|
||||
var SLIDER = 2;
|
||||
}
|
||||
|
||||
class UIContextMenuOptionSpr extends UISliceSprite {
|
||||
public var label:UIText;
|
||||
public var labelKeybind:UIText;
|
||||
public var icon:FlxSprite;
|
||||
public var icon:UIContextMenuOptionIcon;
|
||||
public var option:UIContextMenuOption;
|
||||
public var optionType:UIContextMenuOptionType = DEFAULT;
|
||||
|
||||
public var slider:UISlider = null;
|
||||
|
||||
var parent:UIContextMenu;
|
||||
|
||||
@@ -160,40 +239,96 @@ class UIContextMenuOptionSpr extends UISliceSprite {
|
||||
this.parent = parent;
|
||||
this.color = option.color;
|
||||
|
||||
if (option.icon != null && option.icon > 0) {
|
||||
icon = new FlxSprite(0, 0).loadGraphic(Paths.image('editors/ui/context-icons'), true, 20, 20);
|
||||
icon.animation.add('icon', [option.icon-1], 0, true);
|
||||
icon.animation.play('icon');
|
||||
}
|
||||
var w:Int = label.frameWidth + 22;
|
||||
var h:Int = label.frameHeight;
|
||||
|
||||
if (option.keybinds == null) {
|
||||
if (option.keybind != null) {
|
||||
option.keybinds = [option.keybind];
|
||||
}
|
||||
}
|
||||
if (option.childs != null) optionType = SUBMENU;
|
||||
if (option.slider != null) optionType = SLIDER;
|
||||
|
||||
if (option.keybinds != null || option.keybindText != null) {
|
||||
var text = if(option.keybindText == null) {
|
||||
var textKeys:Array<String> = [];
|
||||
for (o in option.keybinds[0]) {
|
||||
if (Std.int(o) > 0) {
|
||||
textKeys.push(o.toUIString());
|
||||
switch(optionType) {
|
||||
|
||||
case SUBMENU:
|
||||
labelKeybind = new UIText(label.x + label.frameWidth + 10, 2, 0, ">");
|
||||
case SLIDER:
|
||||
labelKeybind = new UIText(label.x + label.frameWidth + 10, 2, 0, "");
|
||||
//slider needs to be created after so that it can match the menu width (when not on the same line)
|
||||
if (option.slider.sameLine != null && option.slider.sameLine) {
|
||||
var sliderWidth = option.slider.width != null ? Std.int(option.slider.width) : 120;
|
||||
w += 120 + slider.barWidth;
|
||||
} else {
|
||||
h *= 2;
|
||||
}
|
||||
|
||||
default:
|
||||
if (option.keybinds == null) {
|
||||
if (option.keybind != null) {
|
||||
option.keybinds = [option.keybind];
|
||||
}
|
||||
}
|
||||
textKeys.join("+");
|
||||
} else {
|
||||
option.keybindText;
|
||||
}
|
||||
labelKeybind = new UIText(label.x + label.frameWidth + 10, 2, 0, text);
|
||||
labelKeybind.alpha = 0.75;
|
||||
|
||||
if (option.keybinds != null || option.keybindText != null) {
|
||||
var text = if(option.keybindText == null) {
|
||||
var textKeys:Array<String> = [];
|
||||
for (o in option.keybinds[0]) {
|
||||
if (Std.int(o) > 0) {
|
||||
textKeys.push(o.toUIString());
|
||||
}
|
||||
}
|
||||
textKeys.join("+");
|
||||
} else {
|
||||
option.keybindText;
|
||||
}
|
||||
labelKeybind = new UIText(label.x + label.frameWidth + 10, 2, 0, text);
|
||||
labelKeybind.alpha = 0.75;
|
||||
|
||||
w = Std.int(labelKeybind.x + labelKeybind.frameWidth + 10);
|
||||
}
|
||||
}
|
||||
|
||||
super(x, y, labelKeybind != null ? Std.int(labelKeybind.x + labelKeybind.frameWidth + 10) : (label.frameWidth + 22), label.frameHeight, 'editors/ui/menu-item');
|
||||
super(x, y, w, h, 'editors/ui/menu-item');
|
||||
|
||||
members.push(label);
|
||||
if (icon != null)
|
||||
members.push(icon);
|
||||
updateIcon();
|
||||
|
||||
if (labelKeybind != null)
|
||||
members.push(labelKeybind);
|
||||
members.push(labelKeybind);
|
||||
}
|
||||
|
||||
//Called after all options are created and the context menu width/height is final
|
||||
public function postCreate() {
|
||||
switch(optionType) {
|
||||
case SLIDER:
|
||||
|
||||
var sliderWidth = bWidth-50;
|
||||
if (option.slider.sameLine != null && option.slider.sameLine) {
|
||||
option.slider.width != null ? Std.int(option.slider.width) : 120;
|
||||
}
|
||||
|
||||
slider = new UISlider(0, 0, sliderWidth, option.slider.value,
|
||||
[{start: option.slider.min, end: option.slider.max, size: option.slider.max-option.slider.min}], false);
|
||||
|
||||
slider.onChange = function(v) {
|
||||
option.slider.value = v;
|
||||
if (option.slider.onChange != null) option.slider.onChange(option);
|
||||
updateIcon(); //check if icon has changed
|
||||
@:privateAccess
|
||||
labelKeybind.text = '${CoolUtil.quantize(slider.__barProgress * 100, 1)}%';
|
||||
};
|
||||
slider.value = option.slider.value;
|
||||
|
||||
if (option.slider.showValues == null || !option.slider.showValues) {
|
||||
slider.startText.visible = false;
|
||||
slider.endText.visible = false;
|
||||
slider.valueStepper.visible = false;
|
||||
slider.valueStepper.selectable = false;
|
||||
}
|
||||
|
||||
members.push(slider);
|
||||
case SUBMENU:
|
||||
|
||||
default:
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public override function draw() {
|
||||
@@ -205,12 +340,71 @@ class UIContextMenuOptionSpr extends UISliceSprite {
|
||||
icon.follow(this, 0, 0);
|
||||
if (labelKeybind != null)
|
||||
labelKeybind.follow(this, bWidth - 10 - labelKeybind.frameWidth, 2);
|
||||
if (slider != null) {
|
||||
if (option.slider.sameLine != null && option.slider.sameLine) {
|
||||
slider.follow(this, bWidth - 18 - slider.barWidth - (slider.endText.visible ? slider.endText.width : 0), 5);
|
||||
} else {
|
||||
slider.follow(this, 20, 5 + label.frameHeight);
|
||||
}
|
||||
}
|
||||
super.draw();
|
||||
}
|
||||
|
||||
public override function onHovered() {
|
||||
super.onHovered();
|
||||
if (FlxG.mouse.justReleased)
|
||||
parent.select(option);
|
||||
|
||||
parent.lastHoveredOptionIndex = parent.contextMenuOptions.indexOf(this);
|
||||
|
||||
switch(optionType) {
|
||||
case SUBMENU:
|
||||
parent.openChildContextMenu(this);
|
||||
case SLIDER:
|
||||
|
||||
default:
|
||||
if (FlxG.mouse.justReleased)
|
||||
parent.select(option);
|
||||
}
|
||||
}
|
||||
|
||||
public function updateIcon() {
|
||||
var currentIcon = option.icon != null ? option.icon : 0;
|
||||
|
||||
if (icon == null && currentIcon > 0) {
|
||||
members.push(icon = new UIContextMenuOptionIcon(option));
|
||||
}
|
||||
if (icon != null) {
|
||||
icon.updateIconState(currentIcon);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class UIContextMenuOptionIcon extends UISprite {
|
||||
private var option:UIContextMenuOption;
|
||||
private var _lastState:Int = 0;
|
||||
override public function new(option:UIContextMenuOption) {
|
||||
super();
|
||||
this.option = option;
|
||||
loadGraphic(Paths.image('editors/ui/context-icons'), true, 20, 20);
|
||||
selectable = option.onIconClick != null;
|
||||
cursor = option.onIconClick != null ? CLICK : ARROW;
|
||||
}
|
||||
|
||||
public function updateIconState(state:Int) {
|
||||
if (_lastState == state) return;
|
||||
_lastState = state;
|
||||
|
||||
visible = state > 0;
|
||||
if (state > 0) {
|
||||
animation.add('icon', [state-1], 0, true);
|
||||
animation.play('icon');
|
||||
}
|
||||
}
|
||||
|
||||
public override function onHovered() {
|
||||
super.onHovered();
|
||||
|
||||
if (FlxG.mouse.justReleased && option.onIconClick != null) {
|
||||
option.onIconClick(option);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,7 +87,7 @@ class UIDropDown extends UISliceSprite {
|
||||
}
|
||||
|
||||
public function openContextMenu() {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_DROPDOWNAPPEAR_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_DROPDOWNAPPEAR_SOUND);
|
||||
var screenPos = getScreenPosition(null, __lastDrawCameras[0] == null ? FlxG.camera : __lastDrawCameras[0]);
|
||||
curMenu = UIState.state.openContextMenu([
|
||||
for(k=>o in items) {
|
||||
|
||||
@@ -106,7 +106,7 @@ class UIState extends MusicBeatState {
|
||||
}
|
||||
|
||||
if (FlxG.mouse.justPressed) {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_CLICK_SOUND));
|
||||
playEditorSound(Flags.DEFAULT_EDITOR_CLICK_SOUND);
|
||||
}
|
||||
|
||||
if (FlxG.mouse.justReleased)
|
||||
@@ -147,7 +147,7 @@ class UIState extends MusicBeatState {
|
||||
}
|
||||
|
||||
public function closeCurrentContextMenu() {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_WINDOWCLOSE_SOUND));
|
||||
playEditorSound(Flags.DEFAULT_EDITOR_WINDOWCLOSE_SOUND);
|
||||
if(curContextMenu != null) {
|
||||
curContextMenu.close();
|
||||
curContextMenu = null;
|
||||
@@ -155,7 +155,7 @@ class UIState extends MusicBeatState {
|
||||
}
|
||||
|
||||
public function openContextMenu(options:Array<UIContextMenuOption>, ?callback:UIContextMenuCallback, ?x:Float, ?y:Float, ?w:Int) {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_WINDOWAPPEAR_SOUND));
|
||||
playEditorSound(Flags.DEFAULT_EDITOR_WINDOWAPPEAR_SOUND);
|
||||
var state = FlxG.state;
|
||||
while(state.subState != null && !(state._requestSubStateReset && state._requestedSubState == null))
|
||||
state = state.subState;
|
||||
@@ -191,4 +191,9 @@ class UIState extends MusicBeatState {
|
||||
resolutionAware = true;
|
||||
FlxG.scaleMode = uiScaleMode;
|
||||
}
|
||||
|
||||
public static function playEditorSound(path:String) {
|
||||
if (!Options.editorSFX) return;
|
||||
FlxG.sound.play(Paths.sound(path));
|
||||
}
|
||||
}
|
||||
@@ -86,7 +86,7 @@ class UISubstateWindow extends MusicBeatSubstate {
|
||||
}
|
||||
|
||||
public override function destroy() {
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_WINDOWCLOSE_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_WINDOWCLOSE_SOUND);
|
||||
super.destroy();
|
||||
for(e in camShaders)
|
||||
e.removeShader(blurShader);
|
||||
|
||||
@@ -166,7 +166,7 @@ class UITextBox extends UISliceSprite implements IUIFocusable {
|
||||
|
||||
changeSelection(1);
|
||||
case BACKSPACE:
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_TEXTREMOVE_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_TEXTREMOVE_SOUND);
|
||||
|
||||
if (modifier.ctrlKey) {
|
||||
var wordBounds = findWholeWord(label.text, position);
|
||||
@@ -182,7 +182,7 @@ class UITextBox extends UISliceSprite implements IUIFocusable {
|
||||
changeSelection(-1);
|
||||
}
|
||||
case DELETE:
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_TEXTREMOVE_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_TEXTREMOVE_SOUND);
|
||||
|
||||
if (modifier.ctrlKey) {
|
||||
var wordBounds = findWholeWord(label.text, position, true);
|
||||
@@ -201,7 +201,7 @@ class UITextBox extends UISliceSprite implements IUIFocusable {
|
||||
case END:
|
||||
position = label.text.length;
|
||||
case V:
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_PASTE_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_PASTE_SOUND);
|
||||
// Hey lj here, fixed copying because before we checked if the modifier was left or right ctrl
|
||||
// but somehow it gave a int outside of the KeyModifier's range :sob:
|
||||
// apparently there is a boolean that just checks for you. yw :D
|
||||
@@ -214,7 +214,7 @@ class UITextBox extends UISliceSprite implements IUIFocusable {
|
||||
if (data != null)
|
||||
onTextInput(data);
|
||||
case C:
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_COPY_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_COPY_SOUND);
|
||||
// if we are not holding ctrl, ignore
|
||||
if (!modifier.ctrlKey)
|
||||
return;
|
||||
@@ -222,7 +222,7 @@ class UITextBox extends UISliceSprite implements IUIFocusable {
|
||||
// copying
|
||||
Clipboard.generalClipboard.setData(TEXT_FORMAT, label.text);
|
||||
case X:
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_CUT_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_CUT_SOUND);
|
||||
|
||||
// if we are not holding ctrl, ignore
|
||||
if (!modifier.ctrlKey)
|
||||
@@ -236,7 +236,7 @@ class UITextBox extends UISliceSprite implements IUIFocusable {
|
||||
if (modifier.ctrlKey || modifier.altKey || modifier.shiftKey)
|
||||
return;
|
||||
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_TEXTTYPE_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_TEXTTYPE_SOUND);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ class UIWindow extends UISliceSprite {
|
||||
|
||||
content = new FlxTypedGroup<FlxBasic>();
|
||||
members.push(content);
|
||||
FlxG.sound.play(Paths.sound(Flags.DEFAULT_EDITOR_WINDOWAPPEAR_SOUND));
|
||||
UIState.playEditorSound(Flags.DEFAULT_EDITOR_WINDOWAPPEAR_SOUND);
|
||||
}
|
||||
|
||||
public override function update(elapsed:Float) {
|
||||
|
||||
@@ -447,6 +447,9 @@ class StrumLine extends FlxTypedGroup<Strum> {
|
||||
public static inline function calculateStartingXPos(hudXRatio:Float, scale:Float, spacing:Float, keyCount:Int) {
|
||||
return (FlxG.width * hudXRatio) - ((Note.swagWidth * scale * ((keyCount/2)-0.5) * spacing) + Note.swagWidth * 0.5 * scale);
|
||||
}
|
||||
public static inline function calculateStartingXPosFromInitialWidth(hudXRatio:Float, scale:Float, spacing:Float, keyCount:Int) {
|
||||
return (FlxG.initialWidth * hudXRatio) - ((Note.swagWidth * scale * ((keyCount/2)-0.5) * spacing) + Note.swagWidth * 0.5 * scale);
|
||||
}
|
||||
|
||||
/**
|
||||
* SETTERS & GETTERS
|
||||
|
||||
@@ -84,6 +84,7 @@ class Options
|
||||
public static var charterMetronomeEnabled:Bool = false;
|
||||
public static var charterShowSections:Bool = true;
|
||||
public static var charterShowBeats:Bool = true;
|
||||
public static var charterShowCameraHighlights:Bool = true;
|
||||
public static var charterEnablePlaytestScripts:Bool = true;
|
||||
public static var charterRainbowWaveforms:Bool = false;
|
||||
public static var charterLowDetailWaveforms:Bool = false;
|
||||
|
||||
@@ -4,7 +4,7 @@ import flixel.util.FlxTimer;
|
||||
import funkin.backend.system.Conductor;
|
||||
|
||||
class GameplayOptions extends TreeMenuScreen {
|
||||
var __metronome = FlxG.sound.load(Paths.sound('editors/charter/metronome'));
|
||||
var __metronome = FlxG.sound.load(Paths.sound(Flags.DEFAULT_CHARTER_METRONOME_SOUND));
|
||||
var offsetSetting:NumOption;
|
||||
|
||||
public function new() {
|
||||
|
||||
Reference in New Issue
Block a user