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
4 changes: 4 additions & 0 deletions src/jvmMain/kotlin/com/sdercolin/vlabeler/model/AppConf.kt
Original file line number Diff line number Diff line change
Expand Up @@ -349,6 +349,8 @@ data class AppConf(
* @param showTag When true, the tag or "New tag" button is shown in the editor and entry lists.
* @param showExtra When true, the extra editor button/icon is shown in the editor and entry lists.
* @param continuousLabelNames Appearance of the label names in the editor for continuous labelers.
* @param clickToJumpToEntry When true, clicking an entry on the canvas in multiple entry edit mode makes it the
* current entry.
* @param entryNamePresets Preset entry names that can be quickly applied in entry name input dialogs.
*/
@Serializable
Expand All @@ -363,6 +365,7 @@ data class AppConf(
val lockedDrag: LockedDrag = DEFAULT_LOCKED_DRAG,
val cascadedDrag: CascadedDrag = DEFAULT_CASCADED_DRAG,
val lockedSettingParameterWithCursor: Boolean = DEFAULT_LOCKED_SETTING_PARAMETER_WITH_CURSOR,
val clickToJumpToEntry: Boolean = DEFAULT_CLICK_TO_JUMP_TO_ENTRY,
val showDone: Boolean = DEFAULT_SHOW_DONE,
val showStar: Boolean = DEFAULT_SHOW_STAR,
val showTag: Boolean = DEFAULT_SHOW_TAG,
Expand Down Expand Up @@ -427,6 +430,7 @@ data class AppConf(
val DEFAULT_LOCKED_DRAG = LockedDrag.UseLabeler
val DEFAULT_CASCADED_DRAG = CascadedDrag.Disabled
const val DEFAULT_LOCKED_SETTING_PARAMETER_WITH_CURSOR = true
const val DEFAULT_CLICK_TO_JUMP_TO_ENTRY = false
const val DEFAULT_SHOW_DONE = true
const val DEFAULT_SHOW_STAR = true
const val DEFAULT_SHOW_TAG = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -726,6 +726,13 @@ object PreferencesPages {
select = { it.lockedSettingParameterWithCursor },
update = { copy(lockedSettingParameterWithCursor = it) },
)
switch(
title = Strings.PreferencesEditorClickToJumpToEntry,
description = Strings.PreferencesEditorClickToJumpToEntryDescription,
defaultValue = AppConf.Editor.DEFAULT_CLICK_TO_JUMP_TO_ENTRY,
select = { it.clickToJumpToEntry },
update = { copy(clickToJumpToEntry = it) },
)
selection(
title = Strings.PreferencesEditorCascadedDrag,
description = Strings.PreferencesEditorCascadedDragDescription,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,15 @@ fun MarkerPointEventContainer(
)
}
.onPointerEvent(PointerEventType.Press) { event ->
state.handleMousePress(tool, keyboardState, event, state.labelerConf, appState.appConf, screenRange)
state.handleMousePress(
tool,
keyboardState,
event,
state.labelerConf,
appState.appConf,
screenRange,
editorState,
)
}
.onPointerEvent(PointerEventType.Release) { event ->
state.handleMouseRelease(
Expand Down Expand Up @@ -662,9 +670,10 @@ private fun MarkerState.handleMousePress(
labelerConf: LabelerConf,
appConf: AppConf,
screenRange: FloatRange?,
editorState: EditorState,
) {
when (tool) {
Tool.Cursor -> handleCursorPress(keyboardState, event, labelerConf, appConf)
Tool.Cursor -> handleCursorPress(keyboardState, event, labelerConf, appConf, screenRange, editorState)
Tool.Scissors -> Unit
Tool.Pan -> handlePanPress(event)
Tool.Playback -> handlePlaybackPress(keyboardState, screenRange, event)
Expand All @@ -676,10 +685,19 @@ private fun MarkerState.handleCursorPress(
event: PointerEvent,
labelerConf: LabelerConf,
appConf: AppConf,
screenRange: FloatRange?,
editorState: EditorState,
) {
val action = keyboardState.getEnabledMouseClickAction(event) ?: return
if (action.canMoveParameter()) {
val cursorStateValue = cursorState.value
if (cursorStateValue.mouse != MarkerCursorState.Mouse.Hovering) {
// Not grabbing a point/border to drag, so a click on an entry body may switch the current entry.
// This is intentionally skipped while hovering a point: dragging a (possibly shared) border should not
// change the current entry, which otherwise switched to the previous entry when its start border was
// grabbed.
maybeJumpToClickedEntry(appConf, screenRange, event, editorState)
}
if (cursorStateValue.mouse == MarkerCursorState.Mouse.Hovering) {
val invertLockedDrag = action == MouseClickAction.MoveParameterInvertingPrimary
val lockedDrag = when (appConf.editor.lockedDrag) {
Expand Down Expand Up @@ -707,6 +725,25 @@ private fun MarkerState.handleCursorPress(
}
}

private fun MarkerState.maybeJumpToClickedEntry(
appConf: AppConf,
screenRange: FloatRange?,
event: PointerEvent,
editorState: EditorState,
) {
if (!appConf.editor.clickToJumpToEntry || entries.size <= 1 || screenRange == null) return
// Derive the click position from the press event itself (not the hover-driven cursorState.position),
// so the jump also works when the mouse is pressed without any preceding move.
val position = event.changes.first().position.x + screenRange.start
val indexInGroup = getEntryIndexByCursorPosition(position) ?: return
val targetIndex = entries[indexInGroup].index
// Skip when the clicked entry is already current; jumpToEntry would otherwise re-trigger the
// auto-centering scroll for a no-op jump.
if (targetIndex != editorState.project.currentModule.currentIndex) {
editorState.jumpToEntry(editorState.project.currentModule.name, targetIndex)
}
}

private fun MarkerState.handlePanPress(event: PointerEvent) {
if (event.isLeftClick) {
panState.updateNonNull { copy(isDragging = true) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,8 @@ enum class Strings {
PreferencesEditorCascadedDragEnabled,
PreferencesEditorLockedSettingParameterWithCursor,
PreferencesEditorLockedSettingParameterWithCursorDescription,
PreferencesEditorClickToJumpToEntry,
PreferencesEditorClickToJumpToEntryDescription,
PreferencesEditorNotes,
PreferencesEditorNotesDescription,
PreferencesEditorShowDone,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -460,6 +460,9 @@ fun Strings.zhHans(): String? = when (this) {
PreferencesEditorLockedSettingParameterWithCursor -> "光标设定时也应用锁定拖动"
PreferencesEditorLockedSettingParameterWithCursorDescription ->
"使用\"将参数设置到光标位置\"键盘操作时也应用上面的锁定拖动的设置。"
PreferencesEditorClickToJumpToEntry -> "单击跳转到条目"
PreferencesEditorClickToJumpToEntryDescription ->
"在多条目编辑模式下,单击画布上的条目即可将其设为当前条目。"
PreferencesEditorCascadedDrag -> "级联拖动"
PreferencesEditorCascadedDragDescription ->
"选择是否启用对平行子项目中边界的级联拖动。\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -517,6 +517,9 @@ fun Strings.en(): String = when (this) {
PreferencesEditorLockedSettingParameterWithCursorDescription ->
"Apply the fixed-drag setting above also when " +
"setting the parameters with \"Set Parameter To Cursor Position\" key actions"
PreferencesEditorClickToJumpToEntry -> "Click to jump to entry"
PreferencesEditorClickToJumpToEntryDescription ->
"In multiple entry edit mode, click an entry on the canvas to make it the current entry"
PreferencesEditorCascadedDrag -> "Cascaded drag"
PreferencesEditorCascadedDragDescription ->
"Select whether to enable cascaded drag to borders in parallel subprojects.\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -487,6 +487,9 @@ fun Strings.ja(): String? = when (this) {
PreferencesEditorLockedSettingParameterWithCursor -> "カーソル位置に設定する場合も連動ドラッグを有効にする"
PreferencesEditorLockedSettingParameterWithCursorDescription ->
"「パラメータをカーソル位置に設定」ショートカットでパラメータを設定するときにも、連動ドラッグ設定を適用します。"
PreferencesEditorClickToJumpToEntry -> "クリックでエントリーへ移動"
PreferencesEditorClickToJumpToEntryDescription ->
"複数エントリー編集モードで、キャンバス上のエントリーをクリックすると現在のエントリーになります。"
PreferencesEditorCascadedDrag -> "カスケードドラッグ"
PreferencesEditorCascadedDragDescription ->
"並列サブプロジェクトの枠線に対するカスケードドラッグを有効にするかどうかを選択します。\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,9 @@ fun Strings.ko(): String? = when (this) {
PreferencesEditorLockedSettingParameterWithCursorDescription ->
"\"n번 마커 놓기 (커서 위치에)\" 입력으로 마커를 놓을 경우에도 " +
"위의 고정 드래그 방식을 적용하기"
PreferencesEditorClickToJumpToEntry -> "클릭하여 엔트리로 이동"
PreferencesEditorClickToJumpToEntryDescription ->
"다중 엔트리 편집 모드에서 캔버스의 엔트리를 클릭하면 현재 엔트리로 설정됩니다."
PreferencesEditorCascadedDrag -> "캐스케이드 드래그"
PreferencesEditorCascadedDragDescription ->
"병렬 하위 프로젝트의 테두리에 대해 캐스케이드 드래그를 활성화할지 선택합니다.\n" +
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,31 @@ class MarkerStateMiscTest {

// endregion

// region getEntryIndexByCursorPosition

@Test
fun getEntryIndexByCursorPositionReturnsEntryContainingPosition() {
val state = continuousState()
assertEquals(0, state.getEntryIndexByCursorPosition(150f))
assertEquals(1, state.getEntryIndexByCursorPosition(300f))
}

@Test
fun getEntryIndexByCursorPositionReturnsFirstMatchOnSharedBorder() {
val state = continuousState()
// 200 is both entry "a"'s end and entry "b"'s start; the first containing entry wins
assertEquals(0, state.getEntryIndexByCursorPosition(200f))
}

@Test
fun getEntryIndexByCursorPositionReturnsNullWhenOutsideAllEntries() {
val state = continuousState()
assertNull(state.getEntryIndexByCursorPosition(50f))
assertNull(state.getEntryIndexByCursorPosition(900f))
}

// endregion

// region computeCascadeEditions

private fun cascadeState(): Pair<MarkerState, List<Entry>> {
Expand Down
Loading