From d1293441d8f735bc415ef7ae6faefb83e156c9cb Mon Sep 17 00:00:00 2001 From: Daniil Ovchinnikov Date: Fri, 15 Mar 2024 15:33:06 +0100 Subject: [PATCH] IJPL-850 make `NavBarVm` independent of `NavBarItem` GitOrigin-RevId: 01617567b94538e1bb043c3b360dc9cf79c12bbc --- .../services/ServiceViewNavBarPanel.kt | 6 ++--- .../intellij/ide/navbar/actions/actions.kt | 21 +++++++++++++++++- .../intellij/ide/navbar/ide/NavBarService.kt | 22 +++++++------------ .../intellij/ide/navbar/ide/NavBarVmImpl.kt | 20 +++++++---------- .../intellij/ide/navbar/ide/NavBarVmItem.kt | 8 ++++++- .../intellij/ide/navbar/ui/NewNavBarPanel.kt | 14 +++--------- .../ide/navbar/ui/StaticNavBarPanel.kt | 6 ++--- .../com/intellij/ide/navbar/vm/NavBarVm.kt | 9 ++++---- .../src/META-INF/LangExtensions.xml | 3 +++ 9 files changed, 58 insertions(+), 51 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/execution/services/ServiceViewNavBarPanel.kt b/platform/lang-impl/src/com/intellij/execution/services/ServiceViewNavBarPanel.kt index 4ddc14b33a06..196048401057 100644 --- a/platform/lang-impl/src/com/intellij/execution/services/ServiceViewNavBarPanel.kt +++ b/platform/lang-impl/src/com/intellij/execution/services/ServiceViewNavBarPanel.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.execution.services import com.intellij.execution.services.ServiceModel.ServiceViewItem @@ -91,9 +91,9 @@ internal class ServiceViewNavBarPanel( updateRequests.tryEmit(Unit) } - private fun requestNavigation(pointer: Pointer) { + private fun requestNavigation(item: NavBarVmItem) { cs.launch(Dispatchers.EDT) { - (pointer as? ServiceViewNavBarItem)?.item?.let { + (item as? ServiceViewNavBarItem)?.item?.let { selector.select(it) } } diff --git a/platform/lang-impl/src/com/intellij/ide/navbar/actions/actions.kt b/platform/lang-impl/src/com/intellij/ide/navbar/actions/actions.kt index 633027da80f9..6b72b5146a30 100644 --- a/platform/lang-impl/src/com/intellij/ide/navbar/actions/actions.kt +++ b/platform/lang-impl/src/com/intellij/ide/navbar/actions/actions.kt @@ -1,7 +1,10 @@ -// Copyright 2000-2022 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ide.navbar.actions +import com.intellij.ide.impl.dataRules.GetDataRule import com.intellij.ide.navbar.NavBarItem +import com.intellij.ide.navbar.ide.IdeNavBarVmItem +import com.intellij.ide.navbar.ide.NavBarVmItem import com.intellij.ide.navbar.impl.DefaultNavBarItem import com.intellij.ide.navbar.impl.ModuleNavBarItem import com.intellij.ide.navbar.impl.PsiNavBarItem @@ -40,6 +43,22 @@ private fun extensionData(dataId: String, provider: DataProvider): Any? { return provider.getData(dataId) } +internal class BgtDataRule : GetDataRule { + + override fun getData(dataProvider: DataProvider): Any? { + val project = CommonDataKeys.PROJECT.getData(dataProvider) + ?: return null + val selection = NavBarVmItem.SELECTED_ITEMS.getData(dataProvider) + ?: return null + val pointers = selection.map { + (it as IdeNavBarVmItem).pointer + } + return DataProvider { + getBgData(project, pointers, it) + } + } +} + internal fun getBgData(project: Project, selection: List>, dataId: String): Any? { val selectedItems = lazy(LazyThreadSafetyMode.NONE) { ApplicationManager.getApplication().assertReadAccessAllowed() diff --git a/platform/lang-impl/src/com/intellij/ide/navbar/ide/NavBarService.kt b/platform/lang-impl/src/com/intellij/ide/navbar/ide/NavBarService.kt index f4c384f52190..07f239df2930 100644 --- a/platform/lang-impl/src/com/intellij/ide/navbar/ide/NavBarService.kt +++ b/platform/lang-impl/src/com/intellij/ide/navbar/ide/NavBarService.kt @@ -1,4 +1,4 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ide.navbar.ide import com.intellij.codeInsight.navigation.actions.navigateRequest @@ -11,7 +11,6 @@ import com.intellij.ide.navbar.ui.showHint import com.intellij.ide.navbar.ui.staticNavBarPanel import com.intellij.ide.ui.UISettings import com.intellij.lang.documentation.ide.ui.DEFAULT_UI_RESPONSE_TIMEOUT -import com.intellij.model.Pointer import com.intellij.openapi.actionSystem.CommonDataKeys import com.intellij.openapi.actionSystem.DataContext import com.intellij.openapi.application.EDT @@ -107,22 +106,17 @@ internal class NavBarService(private val project: Project, cs: CoroutineScope) { } } - private fun requestNavigation(pointer: Pointer) { + private fun requestNavigation(item: NavBarVmItem) { cs.launch { - navigateTo(pointer) + val navigationRequest = readAction { + (item as IdeNavBarVmItem).pointer.dereference()?.navigationRequest() + } ?: return@launch + withContext(Dispatchers.EDT) { + navigateRequest(project, navigationRequest) + } updateRequests.emit(Unit) } } - - private suspend fun navigateTo(pointer: Pointer) { - val navigationRequest = readAction { - pointer.dereference()?.navigationRequest() - } ?: return - withContext(Dispatchers.EDT) { - navigateRequest(project, navigationRequest) - } - updateRequests.emit(Unit) - } } /** diff --git a/platform/lang-impl/src/com/intellij/ide/navbar/ide/NavBarVmImpl.kt b/platform/lang-impl/src/com/intellij/ide/navbar/ide/NavBarVmImpl.kt index b5e33946393d..10fc50f7deec 100644 --- a/platform/lang-impl/src/com/intellij/ide/navbar/ide/NavBarVmImpl.kt +++ b/platform/lang-impl/src/com/intellij/ide/navbar/ide/NavBarVmImpl.kt @@ -1,15 +1,12 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ide.navbar.ide -import com.intellij.ide.navbar.NavBarItem import com.intellij.ide.navbar.NavBarItemPresentation import com.intellij.ide.navbar.vm.NavBarItemVm import com.intellij.ide.navbar.vm.NavBarPopupVm import com.intellij.ide.navbar.vm.NavBarVm import com.intellij.ide.navbar.vm.NavBarVm.SelectionShift -import com.intellij.model.Pointer import com.intellij.platform.util.coroutines.flow.zipWithNext -import com.intellij.util.ui.EDT import kotlinx.coroutines.CancellationException import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.channels.BufferOverflow.DROP_OLDEST @@ -36,7 +33,7 @@ class NavBarVmImpl( private val _popup: MutableStateFlow?> = MutableStateFlow(null) - private val _activationRequests: MutableSharedFlow> = + private val _activationRequests: MutableSharedFlow = MutableSharedFlow(extraBufferCapacity = 1, onBufferOverflow = DROP_OLDEST) init { @@ -64,21 +61,20 @@ class NavBarVmImpl( override val popup: StateFlow?> = _popup.asStateFlow() - override val activationRequests: Flow> = _activationRequests.asSharedFlow() + override val activationRequests: Flow = _activationRequests.asSharedFlow() - override fun selection(): List> { - EDT.assertIsEdt() + override fun selection(): List { val popup = _popup.value if (popup != null) { return popup.selectedItems.map { - it.item.pointer + it.item } } else { val selectedIndex = _selectedIndex.value val items = _items.value if (selectedIndex in items.indices) { - return listOf(items[selectedIndex].item.pointer) + return listOf(items[selectedIndex].item) } } return emptyList() @@ -155,7 +151,7 @@ class NavBarVmImpl( ?: return when (expandResult) { is ExpandResult.NavigateTo -> { - _activationRequests.tryEmit(expandResult.target.pointer) + _activationRequests.tryEmit(expandResult.target) return } is ExpandResult.NextPopup -> { @@ -206,7 +202,7 @@ class NavBarVmImpl( } override fun activate() { - _activationRequests.tryEmit(item.pointer) + _activationRequests.tryEmit(item) } } } diff --git a/platform/lang-impl/src/com/intellij/ide/navbar/ide/NavBarVmItem.kt b/platform/lang-impl/src/com/intellij/ide/navbar/ide/NavBarVmItem.kt index 95cfddf94595..a7b0b90593ac 100644 --- a/platform/lang-impl/src/com/intellij/ide/navbar/ide/NavBarVmItem.kt +++ b/platform/lang-impl/src/com/intellij/ide/navbar/ide/NavBarVmItem.kt @@ -1,12 +1,18 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ide.navbar.ide import com.intellij.ide.navbar.NavBarItem import com.intellij.ide.navbar.NavBarItemPresentation import com.intellij.model.Pointer +import com.intellij.openapi.actionSystem.DataKey interface NavBarVmItem { + companion object { + @JvmField + val SELECTED_ITEMS: DataKey> = DataKey.create("nav.bar.selection") + } + override fun equals(other: Any?): Boolean override fun hashCode(): Int diff --git a/platform/lang-impl/src/com/intellij/ide/navbar/ui/NewNavBarPanel.kt b/platform/lang-impl/src/com/intellij/ide/navbar/ui/NewNavBarPanel.kt index 4a6eff4b5a83..ec642830b931 100644 --- a/platform/lang-impl/src/com/intellij/ide/navbar/ui/NewNavBarPanel.kt +++ b/platform/lang-impl/src/com/intellij/ide/navbar/ui/NewNavBarPanel.kt @@ -1,26 +1,23 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ide.navbar.ui import com.intellij.accessibility.AccessibilityUtils import com.intellij.ide.CopyPasteDelegator import com.intellij.ide.CopyPasteSupport import com.intellij.ide.IdeBundle -import com.intellij.ide.navbar.NavBarItem import com.intellij.ide.navbar.actions.NavBarActionHandler.NAV_BAR_ACTION_HANDLER import com.intellij.ide.navbar.actions.NavBarActionHandlerImpl import com.intellij.ide.navbar.actions.extensionData -import com.intellij.ide.navbar.actions.getBgData import com.intellij.ide.navbar.ide.LOG +import com.intellij.ide.navbar.ide.NavBarVmItem.Companion.SELECTED_ITEMS import com.intellij.ide.navbar.ui.NavBarItemComponent.Companion.isItemComponentFocusable import com.intellij.ide.navbar.vm.NavBarItemVm import com.intellij.ide.navbar.vm.NavBarPopupVm import com.intellij.ide.navbar.vm.NavBarVm import com.intellij.ide.ui.UISettings import com.intellij.internal.statistic.service.fus.collectors.UIEventLogger.NavBarShowPopup -import com.intellij.model.Pointer import com.intellij.openapi.actionSystem.CommonDataKeys.PROJECT import com.intellij.openapi.actionSystem.DataProvider -import com.intellij.openapi.actionSystem.PlatformCoreDataKeys.BGT_DATA_PROVIDER import com.intellij.openapi.actionSystem.PlatformCoreDataKeys.CONTEXT_COMPONENT import com.intellij.openapi.actionSystem.PlatformDataKeys.* import com.intellij.openapi.actionSystem.ex.ActionUtil @@ -241,12 +238,7 @@ class NewNavBarPanel( CUT_PROVIDER.name -> extensionData(dataId) ?: getCopyPasteDelegator(this).cutProvider COPY_PROVIDER.name -> extensionData(dataId) ?: getCopyPasteDelegator(this).copyProvider PASTE_PROVIDER.name -> extensionData(dataId) ?: getCopyPasteDelegator(this).pasteProvider - BGT_DATA_PROVIDER.name -> { - val selection: List> = vm.selection() - DataProvider { - getBgData(project, selection, it) - } - } + SELECTED_ITEMS.name -> vm.selection() else -> null } diff --git a/platform/lang-impl/src/com/intellij/ide/navbar/ui/StaticNavBarPanel.kt b/platform/lang-impl/src/com/intellij/ide/navbar/ui/StaticNavBarPanel.kt index e78a84a609ed..8347934d95c7 100644 --- a/platform/lang-impl/src/com/intellij/ide/navbar/ui/StaticNavBarPanel.kt +++ b/platform/lang-impl/src/com/intellij/ide/navbar/ui/StaticNavBarPanel.kt @@ -1,10 +1,8 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ide.navbar.ui -import com.intellij.ide.navbar.NavBarItem import com.intellij.ide.navbar.ide.* import com.intellij.ide.navbar.vm.NavBarVm -import com.intellij.model.Pointer import com.intellij.openapi.application.EDT import com.intellij.openapi.project.Project import com.intellij.platform.util.coroutines.attachAsChildTo @@ -29,7 +27,7 @@ fun staticNavBarPanel( project: Project, cs: CoroutineScope, updateRequests: Flow, - requestNavigation: (Pointer) -> Unit, + requestNavigation: (NavBarVmItem) -> Unit, ): JComponent { val staticNavBarVm: MutableStateFlow = MutableStateFlow(null) diff --git a/platform/lang-impl/src/com/intellij/ide/navbar/vm/NavBarVm.kt b/platform/lang-impl/src/com/intellij/ide/navbar/vm/NavBarVm.kt index f2aa807edb57..b17531d4c773 100644 --- a/platform/lang-impl/src/com/intellij/ide/navbar/vm/NavBarVm.kt +++ b/platform/lang-impl/src/com/intellij/ide/navbar/vm/NavBarVm.kt @@ -1,8 +1,7 @@ -// Copyright 2000-2023 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. +// Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package com.intellij.ide.navbar.vm -import com.intellij.ide.navbar.NavBarItem -import com.intellij.model.Pointer +import com.intellij.ide.navbar.ide.NavBarVmItem import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.StateFlow import org.jetbrains.annotations.ApiStatus @@ -16,9 +15,9 @@ interface NavBarVm { val popup: StateFlow?> - val activationRequests: Flow> + val activationRequests: Flow - fun selection(): List> + fun selection(): List enum class SelectionShift { FIRST, diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 65faa3769a13..8486ddf42fa4 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -705,6 +705,9 @@ implementationClass="com.intellij.ide.navbar.actions.DefaultNavBarItemDataRule" type="context" order="last"/> +