From b9df5769e3c1deae369ca0a0b1fcf4acdfbdcef4 Mon Sep 17 00:00:00 2001 From: James Date: Wed, 13 Apr 2022 10:39:39 -0400 Subject: [PATCH 1/2] Add a LogBar in the bottom dock --- .../editor/core/project/ProjectManager.java | 12 +- .../mbrlabs/mundus/editor/events/LogEvent.kt | 13 ++ .../mundus/editor/ui/modules/dock/DockBar.kt | 5 + .../mundus/editor/ui/modules/dock/LogBar.kt | 122 ++++++++++++++++++ 4 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 editor/src/main/com/mbrlabs/mundus/editor/events/LogEvent.kt create mode 100644 editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dock/LogBar.kt diff --git a/editor/src/main/com/mbrlabs/mundus/editor/core/project/ProjectManager.java b/editor/src/main/com/mbrlabs/mundus/editor/core/project/ProjectManager.java index 72fb196ab..d22deb511 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/core/project/ProjectManager.java +++ b/editor/src/main/com/mbrlabs/mundus/editor/core/project/ProjectManager.java @@ -16,10 +16,6 @@ package com.mbrlabs.mundus.editor.core.project; -import java.io.File; -import java.io.FileNotFoundException; -import java.io.IOException; - import com.badlogic.gdx.Gdx; import com.badlogic.gdx.files.FileHandle; import com.badlogic.gdx.graphics.g3d.ModelBatch; @@ -47,12 +43,17 @@ import com.mbrlabs.mundus.editor.core.registry.ProjectRef; import com.mbrlabs.mundus.editor.core.registry.Registry; import com.mbrlabs.mundus.editor.core.scene.SceneManager; +import com.mbrlabs.mundus.editor.events.LogEvent; import com.mbrlabs.mundus.editor.events.ProjectChangedEvent; import com.mbrlabs.mundus.editor.events.SceneChangedEvent; import com.mbrlabs.mundus.editor.scene3d.components.PickableComponent; import com.mbrlabs.mundus.editor.utils.Log; import com.mbrlabs.mundus.editor.utils.SkyboxBuilder; +import java.io.File; +import java.io.FileNotFoundException; +import java.io.IOException; + /** * Manages Mundus projects and scenes. * @@ -203,11 +204,13 @@ public ProjectContext loadProject(ProjectRef ref) @Override public void onLoad(Asset asset, int progress, int assetCount) { Log.debug(TAG, "Loaded {} asset ({}/{})", asset.getMeta().getType(), progress, assetCount); + Mundus.INSTANCE.postEvent(new LogEvent("Loaded " + asset.getMeta().getType() + " asset ("+progress+"/"+assetCount+")")); } @Override public void onFinish(int assetCount) { Log.debug(TAG, "Finished loading {} assets", assetCount); + Mundus.INSTANCE.postEvent(new LogEvent("Finished loading " + assetCount + " assets")); } }, false); @@ -242,6 +245,7 @@ public void saveProject(ProjectContext projectContext) { SceneManager.saveScene(projectContext, projectContext.currScene); Log.debug(TAG, "Saving currentProject {}", projectContext.name + " [" + projectContext.path + "]"); + Mundus.INSTANCE.postEvent(new LogEvent("Saving currentProject " + projectContext.name + " [" + projectContext.path + "]")); } /** diff --git a/editor/src/main/com/mbrlabs/mundus/editor/events/LogEvent.kt b/editor/src/main/com/mbrlabs/mundus/editor/events/LogEvent.kt new file mode 100644 index 000000000..bcc554503 --- /dev/null +++ b/editor/src/main/com/mbrlabs/mundus/editor/events/LogEvent.kt @@ -0,0 +1,13 @@ +package com.mbrlabs.mundus.editor.events + +/** + * An Event for posting new log entries in the log bar + */ +class LogEvent(val logMessage: String) { + + interface LogEventListener { + @Subscribe + fun onLogEvent(event: LogEvent) + } + +} \ No newline at end of file diff --git a/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dock/DockBar.kt b/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dock/DockBar.kt index e2193a413..bf5686ab7 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dock/DockBar.kt +++ b/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dock/DockBar.kt @@ -32,6 +32,7 @@ import com.mbrlabs.mundus.editor.ui.widgets.MundusSplitPane class DockBar(private val splitPane: MundusSplitPane) : VisTable(), TabbedPaneListener { private val assetsDock = AssetsDock() + private val logBar = LogBar() private val tabbedPane: TabbedPane @@ -46,7 +47,11 @@ class DockBar(private val splitPane: MundusSplitPane) : VisTable(), TabbedPaneLi tabbedPane.addListener(this) tabbedPane.add(assetsDock) + tabbedPane.add(logBar) add(tabbedPane.table).expandX().fillX().left().bottom().height(30f).row() + + // Keeping asset tab the default active tab + tabbedPane.switchTab(assetsDock) } override fun switchedTab(tab: Tab?) { diff --git a/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dock/LogBar.kt b/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dock/LogBar.kt new file mode 100644 index 000000000..97a249f12 --- /dev/null +++ b/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dock/LogBar.kt @@ -0,0 +1,122 @@ +package com.mbrlabs.mundus.editor.ui.modules.dock + +import com.badlogic.gdx.Gdx +import com.badlogic.gdx.Input +import com.badlogic.gdx.scenes.scene2d.Actor +import com.badlogic.gdx.scenes.scene2d.InputEvent +import com.badlogic.gdx.scenes.scene2d.InputListener +import com.badlogic.gdx.scenes.scene2d.ui.Table +import com.badlogic.gdx.scenes.scene2d.utils.ClickListener +import com.kotcrab.vis.ui.widget.* +import com.kotcrab.vis.ui.widget.tabbedpane.Tab +import com.mbrlabs.mundus.editor.Mundus +import com.mbrlabs.mundus.editor.events.LogEvent +import com.mbrlabs.mundus.editor.ui.UI +import java.text.SimpleDateFormat +import java.util.* + +/** + * Docked log bar for displaying LogEvents with timestamps + */ +class LogBar : Tab(false, false), LogEvent.LogEventListener { + + private val root = VisTable() + private val logTable = VisTable() + private val pane = VisScrollPane(logTable) + + private val logOpsMenu = PopupMenu() + private val clearLogsButton = MenuItem("Clear Logs") + + private val maxLogSize = 75 + private val dateFormat = SimpleDateFormat("HH:mm:ss") + + init { + Mundus.registerEventListener(this) + initUi() + } + + private fun initUi() { + root.setBackground("window-bg") + root.left().top() + root.add(pane).top().fillX().expandX() + + pane.fadeScrollBars = false + + logOpsMenu.addItem(clearLogsButton) + registerListeners() + } + + private fun registerListeners() { + // Pop up menu on right click + root.addListener(object : InputListener() { + override fun touchDown(event: InputEvent?, x: Float, y: Float, pointer: Int, button: Int): Boolean { + return true + } + + override fun touchUp(event: InputEvent?, x: Float, y: Float, pointer: Int, button: Int) { + if (event!!.button == Input.Buttons.RIGHT) { + logOpsMenu.showMenu(UI, Gdx.input.x.toFloat(), + (Gdx.graphics.height - Gdx.input.y).toFloat()) + } + } + + override fun enter(event: InputEvent, x: Float, y: Float, pointer: Int, fromActor: Actor?) { + // Give scroll focus to pane automatically when mouse enters + UI.scrollFocus = pane + } + + override fun exit(event: InputEvent, x: Float, y: Float, pointer: Int, toActor: Actor?) { + // Only clear focus if the exit to another actor is NOT an actor within the LogBars root + if (toActor?.isDescendantOf(root) != true) + UI.scrollFocus = null + } + }) + + clearLogsButton.addListener(object : ClickListener() { + override fun clicked(event: InputEvent, x: Float, y: Float) { + logTable.clearChildren() + } + }) + } + + override fun getTabTitle(): String { + return "Log" + } + + override fun getContentTable(): Table { + return root + } + + override fun onLogEvent(event: LogEvent) { + addLogMessage(event.logMessage) + } + + /** + * Appends new log message with a time stamp to the log table, then scrolls to most recent entry and + * removes old entries. + */ + private fun addLogMessage(message : String) { + val timeStamp = dateFormat.format(Date()) + + val logString = buildString { + append("[") + append(timeStamp) + append("] ") + append(message) + } + + logTable.add(VisLabel(logString)).left().pad(4f).expand().row() + + // Remove oldest entry + if (logTable.cells.size > maxLogSize) + logTable.removeActorAt(0, true) + + scrollToBottom() + } + + private fun scrollToBottom() { + // Update layout and scroll to the latest (bottom) log message + pane.layout() + pane.scrollTo(0f, 0f, 0f, 0f) + } +} \ No newline at end of file From b59a92e41f24c2c919d0c615de6fd3ae13913bb8 Mon Sep 17 00:00:00 2001 From: James Date: Wed, 13 Apr 2022 11:10:35 -0400 Subject: [PATCH 2/2] Add logic to indicate log is updated --- editor/src/main/com/mbrlabs/mundus/editor/ui/UI.kt | 4 ++++ .../mundus/editor/ui/modules/dock/DockBar.kt | 4 ++++ .../mundus/editor/ui/modules/dock/LogBar.kt | 14 ++++++++++++++ 3 files changed, 22 insertions(+) diff --git a/editor/src/main/com/mbrlabs/mundus/editor/ui/UI.kt b/editor/src/main/com/mbrlabs/mundus/editor/ui/UI.kt index ab9a67fca..498cd4375 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/ui/UI.kt +++ b/editor/src/main/com/mbrlabs/mundus/editor/ui/UI.kt @@ -130,4 +130,8 @@ object UI : Stage(ScreenViewport()) { dialog.show(this) } + override fun act() { + super.act() + docker.update(); + } } diff --git a/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dock/DockBar.kt b/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dock/DockBar.kt index bf5686ab7..5baead4bb 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dock/DockBar.kt +++ b/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dock/DockBar.kt @@ -73,4 +73,8 @@ class DockBar(private val splitPane: MundusSplitPane) : VisTable(), TabbedPaneLi // user can't do that } + fun update() { + tabbedPane.updateTabTitle(logBar) + } + } diff --git a/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dock/LogBar.kt b/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dock/LogBar.kt index 97a249f12..9d979e12f 100644 --- a/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dock/LogBar.kt +++ b/editor/src/main/com/mbrlabs/mundus/editor/ui/modules/dock/LogBar.kt @@ -30,6 +30,9 @@ class LogBar : Tab(false, false), LogEvent.LogEventListener { private val maxLogSize = 75 private val dateFormat = SimpleDateFormat("HH:mm:ss") + // True when new entries are in the log and log is not the active tab + var newEntries = false + init { Mundus.registerEventListener(this) initUi() @@ -79,7 +82,15 @@ class LogBar : Tab(false, false), LogEvent.LogEventListener { }) } + override fun onShow() { + super.onShow() + newEntries = false + } + override fun getTabTitle(): String { + if (newEntries) + return "Log*" + return "Log" } @@ -96,6 +107,9 @@ class LogBar : Tab(false, false), LogEvent.LogEventListener { * removes old entries. */ private fun addLogMessage(message : String) { + if (!isActiveTab) + newEntries = true + val timeStamp = dateFormat.format(Date()) val logString = buildString {