Skip to content

Commit 363e356

Browse files
committed
Add option for switching between Popup and Dialog view (#27)
1 parent df76239 commit 363e356

7 files changed

Lines changed: 148 additions & 26 deletions

File tree

src/main/kotlin/com/github/srwi/pixellens/actions/ViewAsImageAction.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.github.srwi.pixellens.actions
22

33
import com.github.srwi.pixellens.UserSettings
4-
import com.github.srwi.pixellens.dialogs.ImageViewer
4+
import com.github.srwi.pixellens.dialogs.ImageViewerFactory
55
import com.github.srwi.pixellens.imageProviders.ImageProviderFactory
66
import com.intellij.notification.Notification
77
import com.intellij.notification.NotificationType
@@ -33,7 +33,7 @@ class ViewAsImageAction : AnAction() {
3333
batch.data.grayscaleColormap = UserSettings.applyColormapEnabled
3434

3535
SwingUtilities.invokeLater {
36-
ImageViewer(project, batch).show()
36+
ImageViewerFactory.show(project, batch)
3737
}
3838
} catch (e: InterruptedException) {
3939
// Operation cancelled by user

src/main/kotlin/com/github/srwi/pixellens/dialogs/ImageViewer.kt

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,6 @@ import com.intellij.openapi.actionSystem.ActionToolbar
1010
import com.intellij.openapi.actionSystem.DataProvider
1111
import com.intellij.openapi.actionSystem.impl.ActionButton
1212
import com.intellij.openapi.editor.colors.EditorColorsManager
13-
import com.intellij.openapi.project.Project
14-
import com.intellij.openapi.ui.DialogWrapper
1513
import com.intellij.ui.GotItTooltip
1614
import com.intellij.ui.JBColor
1715
import com.intellij.ui.PopupHandler
@@ -35,11 +33,10 @@ import java.awt.Point
3533
import java.awt.event.*
3634
import java.awt.image.BufferedImage
3735
import javax.swing.*
38-
import javax.swing.border.Border
3936
import kotlin.coroutines.cancellation.CancellationException
4037
import kotlin.math.max
4138

42-
class ImageViewer(project: Project, val batch: Batch) : DialogWrapper(project), ImageComponentDecorator, DataProvider, Disposable {
39+
open class ImageViewer(val batch: Batch) : ImageComponentDecorator, DataProvider, Disposable {
4340

4441
var normalizeEnabled: Boolean = batch.data.normalized
4542
set(value) {
@@ -114,9 +111,6 @@ class ImageViewer(project: Project, val batch: Batch) : DialogWrapper(project),
114111
private lateinit var sidebarToolbar: ActionToolbar
115112

116113
init {
117-
title = batch.expression
118-
isModal = false
119-
120114
val editorOptions = OptionsManager.getInstance().options.editorOptions
121115
val chessboardOptions = editorOptions.transparencyChessboardOptions
122116
val gridOptions = editorOptions.gridOptions
@@ -129,8 +123,6 @@ class ImageViewer(project: Project, val batch: Batch) : DialogWrapper(project),
129123
imageComponent.gridLineColor = gridOptions.lineColor
130124
imageComponent.isBorderVisible = false
131125

132-
init()
133-
134126
updateImage()
135127
}
136128

@@ -198,30 +190,34 @@ class ImageViewer(project: Project, val batch: Batch) : DialogWrapper(project),
198190
}
199191
}
200192

201-
override fun createCenterPanel(): JComponent {
202-
val contentPanel = JPanel(BorderLayout()).apply {
193+
fun createContentPanel(): JComponent {
194+
return JPanel().apply {
195+
layout = BorderLayout()
196+
add(createNorthPanel(), BorderLayout.NORTH)
197+
add(createCenterPanel(), BorderLayout.CENTER)
198+
add(createSouthPanel(), BorderLayout.SOUTH)
199+
}
200+
}
201+
202+
private fun createCenterPanel(): JComponent {
203+
return JPanel(BorderLayout()).apply {
203204
border = BorderFactory.createEmptyBorder()
204205
add(createImagePanel(), BorderLayout.CENTER)
205206
add(createRightPanel(), BorderLayout.EAST)
206207
minimumSize = Dimension(0, 400)
207208
}
208-
return contentPanel
209-
}
210-
211-
override fun createContentPaneBorder(): Border {
212-
return JBUI.Borders.empty()
213209
}
214210

215-
override fun createNorthPanel(): JComponent {
211+
private fun createNorthPanel(): JComponent {
216212
val actionManager = ActionManager.getInstance()
217213

218214
val actionGroup = actionManager.getAction("MainToolbarActionGroup") as ActionGroup
219215
mainToolbar = actionManager.createActionToolbar("MainToolbar", actionGroup, true)
220-
mainToolbar.apply { setReservePlaceAutoPopupIcon(false) }
216+
mainToolbar.apply { isReservePlaceAutoPopupIcon = false }
221217

222218
val sidebarToggleGroup = actionManager.getAction("SidebarToolbarActionGroup") as ActionGroup
223219
sidebarToolbar = actionManager.createActionToolbar("SidebarToolbar", sidebarToggleGroup, true)
224-
sidebarToolbar.apply { setReservePlaceAutoPopupIcon(false) }
220+
sidebarToolbar.apply { isReservePlaceAutoPopupIcon = false }
225221

226222
val twoSideComponent = TwoSideComponent(mainToolbar.component, sidebarToolbar.component)
227223

@@ -232,7 +228,7 @@ class ImageViewer(project: Project, val batch: Batch) : DialogWrapper(project),
232228
}
233229
}
234230

235-
override fun createSouthPanel(): JComponent {
231+
private fun createSouthPanel(): JComponent {
236232
val shapeLabel = JLabel(batch.shape.joinToString("x")).apply {
237233
border = JBUI.Borders.empty(5)
238234
}
@@ -432,15 +428,12 @@ class ImageViewer(project: Project, val batch: Batch) : DialogWrapper(project),
432428
return internalZoomModel
433429
}
434430

435-
override fun getDimensionServiceKey() = "com.github.srwi.pixellens.dialogs.ImageViewer"
436-
437431
override fun dispose() {
438432
updateJob?.cancel()
439433
imageComponent.removeMouseMotionListener(mouseMotionAdapter)
440434
imageComponent.removeMouseListener(mouseExitAdapter)
441435
imageComponent.removeMouseListener(editorActionPopupAdapter)
442436
scrollPane.removeMouseWheelListener(editorMouseWheelAdapter)
443437
scrollPane.removeComponentListener(editorResizeAdapter)
444-
super.dispose()
445438
}
446439
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package com.github.srwi.pixellens.dialogs
2+
3+
import com.github.srwi.pixellens.data.Batch
4+
import com.intellij.openapi.actionSystem.DataProvider
5+
import com.intellij.openapi.project.Project
6+
import com.intellij.openapi.ui.DialogWrapper
7+
import com.intellij.util.ui.JBUI
8+
import org.intellij.images.ui.ImageComponentDecorator
9+
import javax.swing.JComponent
10+
import javax.swing.border.Border
11+
12+
class ImageViewerDialog(project: Project, batch: Batch) : DialogWrapper(project), DataProvider {
13+
val imageViewer = ImageViewer(batch)
14+
15+
init {
16+
title = batch.expression
17+
isModal = false
18+
19+
init()
20+
}
21+
22+
override fun createCenterPanel(): JComponent {
23+
return imageViewer.createContentPanel()
24+
}
25+
26+
override fun createNorthPanel(): JComponent? {
27+
return null
28+
}
29+
30+
override fun createSouthPanel(): JComponent? {
31+
return null
32+
}
33+
34+
override fun createContentPaneBorder(): Border {
35+
return JBUI.Borders.empty()
36+
}
37+
38+
override fun getDimensionServiceKey() = "com.github.srwi.pixellens.dialogs.ImageViewerDialog"
39+
40+
override fun getData(dataId: String): Any? {
41+
if (ImageComponentDecorator.DATA_KEY.`is`(dataId)) {
42+
return imageViewer
43+
}
44+
return null
45+
}
46+
47+
override fun dispose() {
48+
imageViewer.dispose()
49+
super.dispose()
50+
}
51+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package com.github.srwi.pixellens.dialogs
2+
3+
import com.github.srwi.pixellens.data.Batch
4+
import com.github.srwi.pixellens.settings.PixelLensSettingsState
5+
import com.intellij.openapi.project.Project
6+
7+
enum class ViewerType {
8+
Dialog,
9+
Popup
10+
}
11+
12+
object ImageViewerFactory {
13+
fun show(project: Project, batch: Batch) {
14+
return if (PixelLensSettingsState.instance.usePopupWindow) {
15+
ImageViewerPopup(project, batch).show()
16+
} else {
17+
ImageViewerDialog(project, batch).show()
18+
}
19+
}
20+
}
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
package com.github.srwi.pixellens.dialogs
2+
3+
import com.github.srwi.pixellens.data.Batch
4+
import com.intellij.openapi.Disposable
5+
import com.intellij.openapi.actionSystem.DataProvider
6+
import com.intellij.openapi.project.Project
7+
import com.intellij.openapi.ui.popup.JBPopup
8+
import com.intellij.openapi.ui.popup.JBPopupFactory
9+
import org.intellij.images.ui.ImageComponentDecorator
10+
11+
class ImageViewerPopup(val project: Project, batch: Batch) : DataProvider, Disposable {
12+
val imageViewer = ImageViewer(batch)
13+
private val popup: JBPopup
14+
15+
init {
16+
val contentPanel = imageViewer.createContentPanel()
17+
popup = JBPopupFactory.getInstance()
18+
.createComponentPopupBuilder(contentPanel, null)
19+
.setTitle(batch.expression)
20+
.setResizable(true)
21+
.setMovable(true)
22+
.setProject(project)
23+
.setDimensionServiceKey(project, "com.github.srwi.pixellens.dialogs.ImageViewerPopup", true)
24+
.setCancelOnClickOutside(true)
25+
.setCancelOnWindowDeactivation(true)
26+
.setFocusable(true)
27+
.setRequestFocus(true)
28+
.createPopup()
29+
popup.setMinimumSize(contentPanel.minimumSize)
30+
popup.setDataProvider(this)
31+
}
32+
33+
fun show() {
34+
popup.showInFocusCenter()
35+
}
36+
37+
override fun getData(dataId: String): Any? {
38+
if (ImageComponentDecorator.DATA_KEY.`is`(dataId)) {
39+
return imageViewer
40+
}
41+
return null
42+
}
43+
44+
override fun dispose() {
45+
imageViewer.dispose()
46+
popup.dispose()
47+
}
48+
}

src/main/kotlin/com/github/srwi/pixellens/settings/PixelLensSettingsConfigurable.kt

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
package com.github.srwi.pixellens.settings
22

3+
import com.github.srwi.pixellens.dialogs.ViewerType
34
import com.intellij.openapi.options.Configurable
5+
import com.intellij.openapi.ui.ComboBox
46
import com.intellij.ui.TitledSeparator
57
import com.intellij.util.ui.FormBuilder
68
import javax.swing.JCheckBox
@@ -9,11 +11,14 @@ import javax.swing.JPanel
911

1012
class PixelLensSettingsConfigurable : Configurable {
1113
private var evaluateCheckBox: JCheckBox? = null
14+
private var viewerTypeComboBox: ComboBox<ViewerType>? = null
1215

1316
override fun createComponent(): JComponent? {
1417
evaluateCheckBox = JCheckBox("Always use evaluate transmission (slower)")
18+
viewerTypeComboBox = ComboBox(ViewerType.entries.toTypedArray())
1519

1620
return FormBuilder.createFormBuilder()
21+
.addLabeledComponent("Viewer type:", viewerTypeComboBox!!)
1722
.addComponent(TitledSeparator("Advanced"))
1823
.setFormLeftIndent(20)
1924
.addComponent(evaluateCheckBox!!, 1)
@@ -23,17 +28,20 @@ class PixelLensSettingsConfigurable : Configurable {
2328

2429
override fun isModified(): Boolean {
2530
val settings = PixelLensSettingsState.instance
26-
return settings.alwaysUseEvaluateTransmission != evaluateCheckBox!!.isSelected
31+
return settings.alwaysUseEvaluateTransmission != evaluateCheckBox!!.isSelected ||
32+
settings.usePopupWindow != (viewerTypeComboBox!!.selectedItem == ViewerType.Popup)
2733
}
2834

2935
override fun apply() {
3036
val settings = PixelLensSettingsState.instance
3137
settings.alwaysUseEvaluateTransmission = evaluateCheckBox!!.isSelected
38+
settings.usePopupWindow = (viewerTypeComboBox!!.selectedItem == ViewerType.Popup)
3239
}
3340

3441
override fun reset() {
3542
val settings = PixelLensSettingsState.instance
3643
evaluateCheckBox!!.isSelected = settings.alwaysUseEvaluateTransmission
44+
viewerTypeComboBox!!.selectedItem = if (settings.usePopupWindow) ViewerType.Popup else ViewerType.Dialog
3745
}
3846

3947
override fun getDisplayName(): String {

src/main/kotlin/com/github/srwi/pixellens/settings/PixelLensSettingsState.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,15 @@ import com.intellij.openapi.components.Storage
88
@State(name = "PixelLensSettings", storages = [Storage("PixelLensSettings.xml")])
99
class PixelLensSettingsState : PersistentStateComponent<PixelLensSettingsState> {
1010
var alwaysUseEvaluateTransmission: Boolean = false
11+
var usePopupWindow: Boolean = false
1112

1213
override fun getState(): PixelLensSettingsState {
1314
return this
1415
}
1516

1617
override fun loadState(state: PixelLensSettingsState) {
1718
this.alwaysUseEvaluateTransmission = state.alwaysUseEvaluateTransmission
19+
this.usePopupWindow = state.usePopupWindow
1820
}
1921

2022
companion object {

0 commit comments

Comments
 (0)