Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -422,6 +422,8 @@ enum class KeyAction(
KeySet(Key.P),
false,
),
SetCurrentEntryLeft(listOf(Strings.ActionSetCurrentEntryLeft), null, false),
SetCurrentEntryRight(listOf(Strings.ActionSetCurrentEntryRight), null, false),
SetProperty1(listOf(Strings.ActionSetProperty1), null, false),
SetProperty2(listOf(Strings.ActionSetProperty2), null, false),
SetProperty3(listOf(Strings.ActionSetProperty3), null, false),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,20 +91,31 @@ class MarkerState(
return index % (labelerConf.fields.size + 1)
}

/**
* The flattened point index of the given entry's start border. Returns [MarkerCursorState.START_POINT_INDEX] for
* the first entry, whose start is the shared canvas start rather than an inner border.
*/
fun getStartBorderPointIndex(entryIndex: Int): Int = if (entryIndex == 0) {
MarkerCursorState.START_POINT_INDEX
} else {
entryIndex * (labelerConf.fields.size + 1) - 1
}

/**
* The flattened point index of the given entry's end border. Returns [MarkerCursorState.END_POINT_INDEX] for the
* last entry, whose end is the shared canvas end rather than an inner border.
*/
fun getEndBorderPointIndex(entryIndex: Int): Int = if (entryIndex == entriesInPixel.indices.last()) {
MarkerCursorState.END_POINT_INDEX
} else {
// the end border's flattened index, derived from the entry index directly (not from the start border index,
// which is overridden to START_POINT_INDEX for the first entry and would otherwise mis-compute it)
(entryIndex + 1) * (labelerConf.fields.size + 1) - 1
}

fun getPointIndexAsSingleEntry(entryIndex: Int, pointIndex: Int): Int {
val entryIndices = entriesInPixel.indices
val startPointIndex = if (entryIndex == 0) {
MarkerCursorState.START_POINT_INDEX
} else {
entryIndex * (labelerConf.fields.size + 1) - 1
}
val endPointIndex = if (entryIndex == entryIndices.last()) {
MarkerCursorState.END_POINT_INDEX
} else {
// the end border's flattened index, derived from the entry index directly (not from startPointIndex,
// which is overridden to START_POINT_INDEX for the first entry and would otherwise mis-compute it)
(entryIndex + 1) * (labelerConf.fields.size + 1) - 1
}
val startPointIndex = getStartBorderPointIndex(entryIndex)
val endPointIndex = getEndBorderPointIndex(entryIndex)
return when (pointIndex) {
startPointIndex -> MarkerCursorState.START_POINT_INDEX
endPointIndex -> MarkerCursorState.END_POINT_INDEX
Expand Down Expand Up @@ -476,6 +487,14 @@ class MarkerState(
return null
}

/**
* Returns the index (within [entriesInPixel]) of the entry whose actual range contains [position], or null if the
* cursor is not over any entry.
*/
fun getEntryIndexByCursorPosition(position: Float): Int? = entriesInPixel.indexOfFirst {
it.getActualStart(labelerConf) <= position && position <= it.getActualEnd(labelerConf)
}.takeIf { it >= 0 }

fun isValidCutPosition(position: Float) = entriesInPixel.any { it.isValidCutPosition(position) }

fun isValidPlaybackPosition(position: Float) = position < entryConverter.convertToPixel(sampleLengthMillis)
Expand All @@ -498,32 +517,12 @@ class MarkerState(
appConf: AppConf,
labelerConf: LabelerConf,
): Pair<List<EntryInPixel>, Int>? {
val paramIndex = when (action) {
KeyAction.SetValue1 -> 0
KeyAction.SetValue2 -> 1
KeyAction.SetValue3 -> 2
KeyAction.SetValue4 -> 3
KeyAction.SetValue5 -> 4
KeyAction.SetValue6 -> 5
KeyAction.SetValue7 -> 6
KeyAction.SetValue8 -> 7
KeyAction.SetValue9 -> 8
KeyAction.SetValue10 -> 9
else -> return null
}

// Only used in single edit mode
if (entries.size != 1) return null

val fieldCount = this.labelerConf.fields.filter { it.shortcutIndex != null }.size
val pointIndex = when {
paramIndex == 0 -> MarkerCursorState.START_POINT_INDEX
paramIndex == fieldCount + 1 -> MarkerCursorState.END_POINT_INDEX
paramIndex <= fieldCount -> this.labelerConf.fields.indexOfFirst { it.shortcutIndex == paramIndex }
.takeIf { it >= 0 } ?: return null
else -> return null
}
val cursorPosition = cursorState.value.position ?: return null
val pointIndex = if (entries.size == 1) {
getSingleEditPointIndexByKeyAction(action) ?: return null
} else {
getMultiEditPointIndexByKeyAction(action, cursorPosition) ?: return null
}
val lockDrag = appConf.editor.lockedSettingParameterWithCursor &&
when (appConf.editor.lockedDrag) {
AppConf.Editor.LockedDrag.UseLabeler -> {
Expand All @@ -545,6 +544,59 @@ class MarkerState(
return entries to pointIndex
}

/**
* Resolves the flattened point index for a `SetValueN` key action in single entry edit mode, where the parameter
* refers to the single edited entry's start/end/field points.
*/
private fun getSingleEditPointIndexByKeyAction(action: KeyAction): Int? {
val paramIndex = when (action) {
KeyAction.SetValue1 -> 0
KeyAction.SetValue2 -> 1
KeyAction.SetValue3 -> 2
KeyAction.SetValue4 -> 3
KeyAction.SetValue5 -> 4
KeyAction.SetValue6 -> 5
KeyAction.SetValue7 -> 6
KeyAction.SetValue8 -> 7
KeyAction.SetValue9 -> 8
KeyAction.SetValue10 -> 9
else -> return null
}
val fieldCount = labelerConf.fields.filter { it.shortcutIndex != null }.size
return when {
paramIndex == 0 -> MarkerCursorState.START_POINT_INDEX
paramIndex == fieldCount + 1 -> MarkerCursorState.END_POINT_INDEX
paramIndex <= fieldCount -> labelerConf.fields.indexOfFirst { it.shortcutIndex == paramIndex }
.takeIf { it >= 0 } ?: return null
else -> return null
}
}

/**
* Resolves the flattened point index for a border-setting key action in multiple entry edit mode. Only borders can
* be set here, since fields cannot be identified unambiguously across a group of entries:
* - [KeyAction.SetValue1] / [KeyAction.SetValue2] target the left / right border of the entry under the cursor.
* - [KeyAction.SetCurrentEntryLeft] / [KeyAction.SetCurrentEntryRight] target the left / right border of the
* current entry regardless of where the cursor is.
*
* Returns null when the action is not a supported border action, or when the target entry cannot be located.
*/
private fun getMultiEditPointIndexByKeyAction(action: KeyAction, cursorPosition: Float): Int? {
val entryIndex = when (action) {
KeyAction.SetValue1, KeyAction.SetValue2 ->
getEntryIndexByCursorPosition(cursorPosition) ?: return null
KeyAction.SetCurrentEntryLeft, KeyAction.SetCurrentEntryRight ->
entries.indexOfFirst { it.index == project.currentModule.currentIndex }.takeIf { it >= 0 }
?: return null
else -> return null
}
return when (action) {
KeyAction.SetValue1, KeyAction.SetCurrentEntryLeft -> getStartBorderPointIndex(entryIndex)
KeyAction.SetValue2, KeyAction.SetCurrentEntryRight -> getEndBorderPointIndex(entryIndex)
else -> null
}
}

val isCursor: Boolean
get() = scissorsState.value == null && panState.value == null && playbackState.value == null

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -549,6 +549,8 @@ enum class Strings {
ActionSetValue8,
ActionSetValue9,
ActionSetValue10,
ActionSetCurrentEntryLeft,
ActionSetCurrentEntryRight,
ActionSetProperty1,
ActionSetProperty2,
ActionSetProperty3,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -592,8 +592,8 @@ fun Strings.zhHans(): String? = when (this) {
ActionInputResolution -> "输入画布分辨率"
ActionCancelDialog -> "关闭对话框"
ActionScissorsCut -> "在当前光标位置切割"
ActionSetValue1 -> "将参数1设置到光标位置"
ActionSetValue2 -> "将参数2设置到光标位置"
ActionSetValue1 -> "将参数1设置到光标位置(多条目编辑模式下为光标所在条目的左边界)"
ActionSetValue2 -> "将参数2设置到光标位置(多条目编辑模式下为光标所在条目的右边界)"
ActionSetValue3 -> "将参数3设置到光标位置"
ActionSetValue4 -> "将参数4设置到光标位置"
ActionSetValue5 -> "将参数5设置到光标位置"
Expand All @@ -602,6 +602,8 @@ fun Strings.zhHans(): String? = when (this) {
ActionSetValue8 -> "将参数8设置到光标位置"
ActionSetValue9 -> "将参数9设置到光标位置"
ActionSetValue10 -> "将参数10设置到光标位置"
ActionSetCurrentEntryLeft -> "将当前条目的左边界设置到光标位置(多条目编辑模式)"
ActionSetCurrentEntryRight -> "将当前条目的右边界设置到光标位置(多条目编辑模式)"
ActionSetProperty1 -> "输入属性1的值"
ActionSetProperty2 -> "输入属性2的值"
ActionSetProperty3 -> "输入属性3的值"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -670,8 +670,8 @@ fun Strings.en(): String = when (this) {
ActionInputResolution -> "Input Canvas Resolution"
ActionCancelDialog -> "Close Dialog"
ActionScissorsCut -> "Cut at Current Cursor Position"
ActionSetValue1 -> "Set Parameter 1 To Cursor Position"
ActionSetValue2 -> "Set Parameter 2 To Cursor Position"
ActionSetValue1 -> "Set Parameter 1 To Cursor Position (Left Border Of Entry Under Cursor In Multi-Edit Mode)"
ActionSetValue2 -> "Set Parameter 2 To Cursor Position (Right Border Of Entry Under Cursor In Multi-Edit Mode)"
ActionSetValue3 -> "Set Parameter 3 To Cursor Position"
ActionSetValue4 -> "Set Parameter 4 To Cursor Position"
ActionSetValue5 -> "Set Parameter 5 To Cursor Position"
Expand All @@ -680,6 +680,8 @@ fun Strings.en(): String = when (this) {
ActionSetValue8 -> "Set Parameter 8 To Cursor Position"
ActionSetValue9 -> "Set Parameter 9 To Cursor Position"
ActionSetValue10 -> "Set Parameter 10 To Cursor Position"
ActionSetCurrentEntryLeft -> "Set Current Entry's Left Border To Cursor Position (Multiple Entry Edit Mode)"
ActionSetCurrentEntryRight -> "Set Current Entry's Right Border To Cursor Position (Multiple Entry Edit Mode)"
ActionSetProperty1 -> "Input Value for Property 1"
ActionSetProperty2 -> "Input Value for Property 2"
ActionSetProperty3 -> "Input Value for Property 3"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -628,8 +628,8 @@ fun Strings.ja(): String? = when (this) {
ActionInputResolution -> "キャンパス解像度を入力"
ActionCancelDialog -> "ダイアログを閉じる"
ActionScissorsCut -> "カーソル位置でカット"
ActionSetValue1 -> "パラメータ1をカーソル位置に設定"
ActionSetValue2 -> "パラメータ2をカーソル位置に設定"
ActionSetValue1 -> "パラメータ1をカーソル位置に設定(複数エントリー編集モードではカーソル位置のエントリーの左境界)"
ActionSetValue2 -> "パラメータ2をカーソル位置に設定(複数エントリー編集モードではカーソル位置のエントリーの右境界)"
ActionSetValue3 -> "パラメータ3をカーソル位置に設定"
ActionSetValue4 -> "パラメータ4をカーソル位置に設定"
ActionSetValue5 -> "パラメータ5をカーソル位置に設定"
Expand All @@ -638,6 +638,8 @@ fun Strings.ja(): String? = when (this) {
ActionSetValue8 -> "パラメータ8をカーソル位置に設定"
ActionSetValue9 -> "パラメータ9をカーソル位置に設定"
ActionSetValue10 -> "パラメータ10をカーソル位置に設定"
ActionSetCurrentEntryLeft -> "現在のエントリーの左境界をカーソル位置に設定(複数エントリー編集モード)"
ActionSetCurrentEntryRight -> "現在のエントリーの右境界をカーソル位置に設定(複数エントリー編集モード)"
ActionSetProperty1 -> "プロパティ1の値を入力"
ActionSetProperty2 -> "プロパティ2の値を入力"
ActionSetProperty3 -> "プロパティ3の値を入力"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -647,8 +647,8 @@ fun Strings.ko(): String? = when (this) {
ActionInputResolution -> "캔버스 해상도 입력"
ActionCancelDialog -> "대화창 닫기"
ActionScissorsCut -> "자르기 (커서 위치에서)"
ActionSetValue1 -> "1번 마커 놓기 (커서 위치에)"
ActionSetValue2 -> "2번 마커 놓기 (커서 위치에)"
ActionSetValue1 -> "1번 마커 놓기 (커서 위치에) (다중 엔트리 편집 모드에서는 커서 위치 엔트리의 왼쪽 경계)"
ActionSetValue2 -> "2번 마커 놓기 (커서 위치에) (다중 엔트리 편집 모드에서는 커서 위치 엔트리의 오른쪽 경계)"
ActionSetValue3 -> "3번 마커 놓기 (커서 위치에)"
ActionSetValue4 -> "4번 마커 놓기 (커서 위치에)"
ActionSetValue5 -> "5번 마커 놓기 (커서 위치에)"
Expand All @@ -657,6 +657,8 @@ fun Strings.ko(): String? = when (this) {
ActionSetValue8 -> "8번 마커 놓기 (커서 위치에)"
ActionSetValue9 -> "9번 마커 놓기 (커서 위치에)"
ActionSetValue10 -> "10번 마커 놓기 (커서 위치에)"
ActionSetCurrentEntryLeft -> "현재 엔트리의 왼쪽 경계를 커서 위치에 놓기 (다중 엔트리 편집 모드)"
ActionSetCurrentEntryRight -> "현재 엔트리의 오른쪽 경계를 커서 위치에 놓기 (다중 엔트리 편집 모드)"
ActionSetProperty1 -> "1번 값 입력"
ActionSetProperty2 -> "2번 값 입력"
ActionSetProperty3 -> "3번 값 입력"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,12 +50,14 @@ object MarkerStateFactory {
* @param labelerConf the labeler in use.
* @param allEntries all entries of the current module (== the current group), in millis.
* @param editedIndexes indexes in [allEntries] that are being edited (all of them by default).
* @param currentIndex the module's current entry index (the first edited entry by default).
* @param parallelModules additional modules that are parallel to the current module (sharing the raw label file).
*/
fun create(
labelerConf: LabelerConf,
allEntries: List<Entry>,
editedIndexes: List<Int> = allEntries.indices.toList(),
currentIndex: Int = editedIndexes.first(),
sampleRate: Float = 1000f,
resolution: Int = 1,
sampleLengthMillis: Float = DEFAULT_SAMPLE_LENGTH_MILLIS,
Expand All @@ -65,7 +67,7 @@ object MarkerStateFactory {
name = "main",
sampleDirectoryPath = "/samples",
entries = allEntries,
currentIndex = editedIndexes.first(),
currentIndex = currentIndex,
rawFilePath = RAW_FILE_PATH,
)
val project = Project(
Expand Down
Loading
Loading