Skip to content

Commit

Permalink
Merge pull request #31 from Grigory-Rylov/refresh_layout
Browse files Browse the repository at this point in the history
Refresh layout
  • Loading branch information
Grigory-Rylov authored Nov 22, 2022
2 parents c4b30df + da07cb0 commit 10ad334
Show file tree
Hide file tree
Showing 8 changed files with 140 additions and 53 deletions.
3 changes: 2 additions & 1 deletion build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ tasks {
untilBuild.set(properties("pluginUntilBuild"))

changeNotes.set( """
Fixed tree-nodes selection when table info filter is not empty.<br>
Added refresh event by Ctrl + r.<br>
Increased window height.<br>
"""
)
}
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ studioCompilePath=/Applications/Android Studio.app/Contents

pluginGroup = com.github.grishberg.android
pluginName = android-layout-inspector-plugin
pluginVersion = 22.10.12.0
pluginVersion = 22.11.08.0

# See https://plugins.jetbrains.com/docs/intellij/build-number-ranges.html
# for insight into build numbers and IntelliJ Platform versions.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@ package com.github.grishberg.android.layoutinspector.domain

import com.android.layoutinspector.LayoutInspectorResult
import com.android.layoutinspector.common.AppLogger
import com.android.layoutinspector.model.ClientWindow
import com.android.layoutinspector.model.LayoutFileData
import com.github.grishberg.android.layoutinspector.common.CoroutinesDispatchers
import com.github.grishberg.android.layoutinspector.process.LayoutFileSystem
import com.github.grishberg.android.layoutinspector.process.LayoutInspectorCaptureTask
import com.github.grishberg.android.layoutinspector.process.RecordingConfig
import com.github.grishberg.android.layoutinspector.process.providers.ScreenSizeProvider
import kotlinx.coroutines.CoroutineExceptionHandler
import kotlinx.coroutines.CoroutineScope
Expand Down Expand Up @@ -43,58 +45,99 @@ class Logic(
}
}

private var previousRecordingConfig: RecordingConfig? = null

val canRefresh: Boolean
get() = previousRecordingConfig != null

fun startRecording() {
recordingJob = coroutineScope.launch(errorHandler) {
val recordOptions = devicesInput.getLayoutOptions() ?: return@launch
recodLayoutFromNewDevice()
}
}

private suspend fun recodLayoutFromNewDevice() {
val recordOptions = devicesInput.getLayoutOptions() ?: return

output.showLoading()

val windows = coroutineScope.async(dispatchers.worker) {
return@async clientWindowsInput.getClientWindows(recordOptions)
}
val windowList = windows.await()

if (windowList.isEmpty()) {
throw IllegalStateException("No windows for client")
}

val window = if (windowList.size == 1) {
windowList[0]
} else {
output.hideLoading()
val selectedWindow = windowsListInput.getSelectedWindow(windowList)
output.showLoading()
selectedWindow
}

val windows = coroutineScope.async(dispatchers.worker) {
return@async clientWindowsInput.getClientWindows(recordOptions)
}
val windowList = windows.await()
val density = recordOptions.device.density
logger.d("$TAG: density = $density")

if (windowList.isEmpty()) {
throw IllegalStateException("No windows for client")
}
val screenSize = screenSizeProvider.getScreenSize(recordOptions.device)
logger.d("$TAG: screen size = $screenSize")

val window = if (windowList.size == 1) {
windowList[0]
} else {
output.hideLoading()
val selectedWindow = windowsListInput.getSelectedWindow(windowList)
output.showLoading()
selectedWindow
}
val dpPerPixels = (density / 160.0)
logger.d("$TAG: dp per pixels = $dpPerPixels")

val density = recordOptions.device.density
logger.d("$TAG: density = $density")

val screenSize = screenSizeProvider.getScreenSize(recordOptions.device)
logger.d("$TAG: screen size = $screenSize")
val config = RecordingConfig(
recordOptions.client,
window,
recordOptions.timeoutInSeconds,
recordOptions.v2Enabled,
dpPerPixels,
recordOptions
)
previousRecordingConfig = config

val dpPerPixels = (density / 160.0)
logger.d("$TAG: dp per pixels = $dpPerPixels")
captureLayouts(config)
}

val task = LayoutInspectorCaptureTask(logger)
fun refreshLayout() {
previousRecordingConfig?.let { config ->

val liResult = task.capture(
recordOptions.client,
window,
recordOptions.timeoutInSeconds,
recordOptions.v2Enabled
)
recordingJob = coroutineScope.launch(errorHandler) {

output.hideLoading()
output.showLoading()

if (liResult.data == null || liResult.root == null) {
output.showError(liResult.error)
} else {
onSuccessCaptured(recordOptions.fileNamePrefix, liResult, dpPerPixels)
val windows = coroutineScope.async(dispatchers.worker) {
return@async clientWindowsInput.getClientWindows(config.recordOptions)
}
val windowList: List<ClientWindow> = windows.await()
if (windowList.any { it.displayName == config.clientWindow.displayName }) {
captureLayouts(config)
} else {
recodLayoutFromNewDevice()
}
}
}
}

private suspend fun captureLayouts(
config: RecordingConfig,
) {
val task = LayoutInspectorCaptureTask(coroutineScope, logger)

val liResult = task.capture(config)

output.hideLoading()

if (liResult.data == null || liResult.root == null) {
output.showError(liResult.error)
} else {
onSuccessCaptured(config.recordOptions.fileNamePrefix, liResult, config.dpPerPixels)
}
}

private fun onSuccessCaptured(
fileNamePrefix: String,
liResult: LayoutInspectorResult,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,43 +1,42 @@
package com.github.grishberg.android.layoutinspector.process

import com.android.ddmlib.Client
import com.android.layoutinspector.LayoutInspectorBridge
import com.android.layoutinspector.LayoutInspectorBridge.V2_MIN_API
import com.android.layoutinspector.LayoutInspectorCaptureOptions
import com.android.layoutinspector.LayoutInspectorResult
import com.android.layoutinspector.ProtocolVersion
import com.android.layoutinspector.common.AppLogger
import com.android.layoutinspector.model.ClientWindow
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.async


private const val TAG = "LayoutInspectorCaptureTask"

class LayoutInspectorCaptureTask(
private val logger: AppLogger
private val scope: CoroutineScope,
private val logger: AppLogger,
) {
suspend fun capture(client: Client, clientWindow: ClientWindow, timeoutInSeconds: Int, v2Enabled: Boolean): LayoutInspectorResult {
val result = GlobalScope.async(Dispatchers.IO) {
logger.d("$TAG: start capture view timeout = $timeoutInSeconds")
suspend fun capture(recordingConfig: RecordingConfig): LayoutInspectorResult {
val result = scope.async(Dispatchers.IO) {
logger.d("$TAG: start capture view timeout = ${recordingConfig.timeoutInSeconds}")

try {
val version: ProtocolVersion = determineProtocolVersion(
client.device.version.apiLevel, v2Enabled
recordingConfig.client.device.version.apiLevel, recordingConfig.v2Enabled
)
val options = LayoutInspectorCaptureOptions()
options.version = version

val captureView = LayoutInspectorBridge.captureView(
logger,
clientWindow,
recordingConfig.clientWindow,
options,
timeoutInSeconds.toLong()
recordingConfig.timeoutInSeconds.toLong()
)
return@async captureView
} catch (e: Exception) {
logger.e("$TAG", e)
logger.e(TAG, e)
throw e
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
package com.github.grishberg.android.layoutinspector.process

import com.android.ddmlib.Client
import com.android.layoutinspector.model.ClientWindow
import com.github.grishberg.android.layoutinspector.domain.LayoutRecordOptions

data class RecordingConfig(
val client: Client,
val clientWindow: ClientWindow,
val timeoutInSeconds: Int,
val v2Enabled: Boolean,
val dpPerPixels: Double,
val recordOptions: LayoutRecordOptions,
)
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.github.grishberg.android.layoutinspector.ui

import com.github.grishberg.android.layoutinspector.domain.Logic
import com.github.grishberg.android.layoutinspector.ui.layout.LayoutPanel
import com.github.grishberg.android.layoutinspector.ui.theme.Themes
import com.github.grishberg.android.layoutinspector.ui.tree.IconsStore
Expand All @@ -14,7 +15,8 @@ private const val BUTTON_SIZE = 22
class ButtonsBuilder(
private val layoutPanel: LayoutPanel,
private val main: Main,
private val themes: Themes
private val themes: Themes,
private val logic: Logic,
) : ActionListener {
private val iconStore = IconsStore(BUTTON_SIZE - 8)

Expand All @@ -33,6 +35,14 @@ class ButtonsBuilder(
)
toolBar.add(fitScreenButton)

val refreshLayoutButton = makeToolbarButton(
"(@)", "refresh",
Actions.REFRESH,
"Refresh layout (Ctrl/Cmd + R)"
)
toolBar.add(refreshLayoutButton)


val helpButton = makeToolbarButton(
"?", "help",
Actions.HELP,
Expand Down Expand Up @@ -76,5 +86,10 @@ class ButtonsBuilder(
main.goToHelp()
return
}

if (e.actionCommand == Actions.REFRESH.name) {
logic.refreshLayout()
return
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ class KeyBinder(
//addKeyMapWithCtrl(KeyEvent.VK_C, CopySelectedFullClassNameAction())
//addKeyMap(KeyEvent.VK_ESCAPE, RemoveSelectionAction())
addKeyMapWithCtrl(KeyEvent.VK_O, OpenFileDialogAction(false))
addKeyMapWithCtrl(KeyEvent.VK_R, RefreshLayoutAction())
addKeyMapWithCtrlShift(KeyEvent.VK_O, OpenFileDialogAction(true))

addKeyMapWithCtrl(KeyEvent.VK_N, NewTraceAction())
Expand Down Expand Up @@ -81,6 +82,12 @@ class KeyBinder(
logic.startRecording()
}
}
private inner class RefreshLayoutAction : AbstractAction() {
override fun actionPerformed(e: ActionEvent) {
if (shouldSkip(e)) return
logic.refreshLayout()
}
}

private inner class FitZoomAction : AbstractAction() {
override fun actionPerformed(e: ActionEvent) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ import com.github.grishberg.android.layoutinspector.ui.info.PropertiesPanel
import com.github.grishberg.android.layoutinspector.ui.info.flat.FlatPropertiesWithFilterPanel
import com.github.grishberg.android.layoutinspector.ui.info.flat.filter.SimpleFilterTextView
import com.github.grishberg.android.layoutinspector.ui.layout.DistanceType
import com.github.grishberg.android.layoutinspector.ui.layout.ImageTransferable
import com.github.grishberg.android.layoutinspector.ui.layout.LayoutLogic
import com.github.grishberg.android.layoutinspector.ui.layout.LayoutPanel
import com.github.grishberg.android.layoutinspector.ui.layout.LayoutsEnabledState
Expand All @@ -37,11 +36,9 @@ import com.github.grishberg.android.layoutinspector.ui.theme.ThemeProxy
import com.github.grishberg.android.layoutinspector.ui.theme.Themes
import com.github.grishberg.android.layoutinspector.ui.tree.TreePanel
import com.intellij.ui.components.JBScrollPane
import java.awt.AWTException
import java.awt.BorderLayout
import java.awt.Desktop
import java.awt.Dimension
import java.awt.Toolkit
import java.awt.event.ActionEvent
import java.awt.event.KeyEvent
import java.awt.event.WindowAdapter
Expand Down Expand Up @@ -75,7 +72,7 @@ import kotlin.math.roundToInt


private const val INITIAL_SCREEN_WIDTH = 1024
private const val INITIAL_SCREEN_HEIGHT = 600
private const val INITIAL_SCREEN_HEIGHT = 800
private const val INITIAL_LAYOUTS_WINDOW_WIDTH = 300
private const val INITIAL_PROPERTIES_WINDOW_WIDTH = 400

Expand Down Expand Up @@ -126,6 +123,10 @@ class Main(
private val metaRepository = MetaRepository(logger, bookmarks, baseDir)
private val layoutsState = LayoutsEnabledState()
private val toggleShowingLayouts = JCheckBoxMenuItem("Toggle showing layouts")
private val refreshLayoutMenuItem = JMenuItem("Refresh layout").apply {
isEnabled = false
accelerator = createControlAccelerator('R')
}

// Constructor of MainWindow class
init {
Expand Down Expand Up @@ -169,7 +170,6 @@ class Main(

val toolbar = JToolBar()
toolbar.isFloatable = false
ButtonsBuilder(layoutPanel, this, themes).addToolbarButtons(toolbar)

mainPanel = JPanel(BorderLayout())
mainPanel.add(toolbar, BorderLayout.NORTH)
Expand Down Expand Up @@ -212,6 +212,7 @@ class Main(
coroutineScope,
coroutinesDispatchers
)
ButtonsBuilder(layoutPanel, this, themes, logic).addToolbarButtons(toolbar)

loadingDialog = LoadingDialog(this, object : LoadingDialogClosedEventListener {
override fun onLoadingDialogClosed() {
Expand Down Expand Up @@ -328,6 +329,12 @@ class Main(
}

file.addSeparator()

file.add(refreshLayoutMenuItem)
refreshLayoutMenuItem.addActionListener { arg: ActionEvent? ->
logic.refreshLayout()
}

return file
}

Expand Down Expand Up @@ -519,6 +526,7 @@ class Main(
treePanel.showLayoutResult(resultOutput)
findDialog.updateRootNode(resultOutput.node)
splitPane1.invalidate()
refreshLayoutMenuItem.isEnabled = logic.canRefresh
}

override fun showError(error: String) {
Expand Down

0 comments on commit 10ad334

Please sign in to comment.