Merge remote-tracking branch 'origin/master'

This commit is contained in:
jiahua.liu 2020-03-30 21:52:20 +08:00
commit d92b43e91b
7 changed files with 110 additions and 20 deletions

View File

@ -15,6 +15,7 @@ import net.mamoe.mirai.console.graphical.stylesheet.PrimaryStyleSheet
import net.mamoe.mirai.console.graphical.view.Decorator import net.mamoe.mirai.console.graphical.view.Decorator
import tornadofx.App import tornadofx.App
import tornadofx.find import tornadofx.find
import kotlin.system.exitProcess
//object MiraiGraphicalLoader { //object MiraiGraphicalLoader {
// @JvmStatic // @JvmStatic
@ -33,5 +34,6 @@ class MiraiGraphicalUI : App(Decorator::class, PrimaryStyleSheet::class) {
override fun stop() { override fun stop() {
super.stop() super.stop()
MiraiConsole.stop() MiraiConsole.stop()
exitProcess(0)
} }
} }

View File

@ -5,8 +5,10 @@ import javafx.collections.ObservableList
import javafx.stage.Modality import javafx.stage.Modality
import javafx.stage.StageStyle import javafx.stage.StageStyle
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive
import net.mamoe.mirai.Bot import net.mamoe.mirai.Bot
import net.mamoe.mirai.console.command.CommandManager import net.mamoe.mirai.console.command.CommandManager
import net.mamoe.mirai.console.command.CommandManager.runCommand
import net.mamoe.mirai.console.command.ConsoleCommandSender import net.mamoe.mirai.console.command.ConsoleCommandSender
import net.mamoe.mirai.console.graphical.model.* import net.mamoe.mirai.console.graphical.model.*
import net.mamoe.mirai.console.graphical.view.dialog.InputDialog import net.mamoe.mirai.console.graphical.view.dialog.InputDialog
@ -25,7 +27,7 @@ class MiraiGraphicalUIController : Controller(), MiraiConsoleUI {
private val settingModel = find<GlobalSettingModel>() private val settingModel = find<GlobalSettingModel>()
private val loginSolver = GraphicalLoginSolver() private val loginSolver = GraphicalLoginSolver()
private val cache = mutableMapOf<Long, BotModel>() private val cache = mutableMapOf<Long, BotModel>()
val mainLog = observableListOf<String>() val mainLog = observableListOf<Pair<String, String>>()
val botList = observableListOf<BotModel>() val botList = observableListOf<BotModel>()
@ -41,7 +43,16 @@ class MiraiGraphicalUIController : Controller(), MiraiConsoleUI {
CommandManager.runCommand(ConsoleCommandSender, "/login $qq $psd") CommandManager.runCommand(ConsoleCommandSender, "/login $qq $psd")
} }
fun sendCommand(command: String) = CommandManager.runCommand(ConsoleCommandSender, command) fun logout(qq: Long) {
cache.remove(qq)?.apply {
botList.remove(this)
if (botProperty.value != null && bot.isActive) {
bot.close()
}
}
}
fun sendCommand(command: String) = runCommand(ConsoleCommandSender, command)
override fun pushLog(identity: Long, message: String) = Platform.runLater { override fun pushLog(identity: Long, message: String) = Platform.runLater {
this.pushLog(LogPriority.INFO, "", identity, message) this.pushLog(LogPriority.INFO, "", identity, message)
@ -58,16 +69,18 @@ class MiraiGraphicalUIController : Controller(), MiraiConsoleUI {
} else { } else {
cache[identity]?.logHistory cache[identity]?.logHistory
}?.apply { }?.apply {
add("[$time] $identityStr $message") add("[$time] $identityStr $message" to priority.name)
trim() trim()
} }
} }
} }
override fun prePushBot(identity: Long) = Platform.runLater { override fun prePushBot(identity: Long) = Platform.runLater {
BotModel(identity).also { if (!cache.containsKey(identity)) {
cache[identity] = it BotModel(identity).also {
botList.add(it) cache[identity] = it
botList.add(it)
}
} }
} }

View File

@ -11,7 +11,7 @@ class BotModel(val uin: Long) {
val botProperty = SimpleObjectProperty<Bot>(null) val botProperty = SimpleObjectProperty<Bot>(null)
var bot: Bot by botProperty var bot: Bot by botProperty
val logHistory = observableListOf<String>() val logHistory = observableListOf<Pair<String, String>>()
val admins = observableListOf<Long>() val admins = observableListOf<Long>()
} }

View File

@ -69,9 +69,21 @@ class PrimaryStyleSheet : BaseStyleSheet() {
backgroundColor += c(100, 100, 100, 0.4) backgroundColor += c(100, 100, 100, 0.4)
backgroundRadius += box(5.px) backgroundRadius += box(5.px)
textFill = c(fontColor) label {
fontWeight = FontWeight.BOLD textFill = c(fontColor)
fontWeight = FontWeight.BOLD
}
button {
opacity = 0.0
backgroundRadius += box(10.px)
backgroundColor += c(fontColor, 0.1)
cursor = Cursor.HAND
and(hover) {
opacity = 1.0
}
}
} }
} }
} }
@ -112,6 +124,15 @@ class PrimaryStyleSheet : BaseStyleSheet() {
} }
listCell { listCell {
and(":WARNING") {
backgroundColor += c("FFFF00", 0.3) // Yellow
}
and(":ERROR") {
backgroundColor += c("FF0000", 0.3) // Red
}
and(":selected") { and(":selected") {
backgroundColor += c(stressColor, 1.0) backgroundColor += c(stressColor, 1.0)
} }

View File

@ -0,0 +1,15 @@
package net.mamoe.mirai.console.graphical.util
import com.jfoenix.svg.SVGGlyph
import javafx.scene.paint.Color
class SVG {
companion object {
var close = SVGGlyph(
0,
"CLOSE",
"M810 274l-238 238 238 238-60 60-238-238-238 238-60-60 238-238-238-238 60-60 238 238 238-238z",
Color.WHITE
).apply { setSize(8.0, 8.0) }
}
}

View File

@ -5,19 +5,24 @@ import com.jfoenix.controls.JFXListCell
import javafx.collections.ObservableList import javafx.collections.ObservableList
import javafx.geometry.Insets import javafx.geometry.Insets
import javafx.geometry.Pos import javafx.geometry.Pos
import javafx.scene.control.Alert
import javafx.scene.control.ButtonType
import javafx.scene.control.Tab import javafx.scene.control.Tab
import javafx.scene.control.TabPane import javafx.scene.control.TabPane
import javafx.scene.image.Image import javafx.scene.image.Image
import javafx.scene.input.Clipboard
import javafx.scene.input.KeyCode import javafx.scene.input.KeyCode
import javafx.scene.layout.Priority
import javafx.stage.FileChooser import javafx.stage.FileChooser
import kotlinx.coroutines.runBlocking import kotlinx.coroutines.runBlocking
import net.mamoe.mirai.console.graphical.controller.MiraiGraphicalUIController import net.mamoe.mirai.console.graphical.controller.MiraiGraphicalUIController
import net.mamoe.mirai.console.graphical.model.BotModel import net.mamoe.mirai.console.graphical.model.BotModel
import net.mamoe.mirai.console.graphical.util.*
import net.mamoe.mirai.console.graphical.util.jfxButton import net.mamoe.mirai.console.graphical.util.jfxButton
import net.mamoe.mirai.console.graphical.util.jfxListView import net.mamoe.mirai.console.graphical.util.jfxListView
import net.mamoe.mirai.console.graphical.util.jfxTabPane import net.mamoe.mirai.console.graphical.util.jfxTabPane
import net.mamoe.mirai.console.graphical.util.myButtonBar
import tornadofx.* import tornadofx.*
import tornadofx.Stylesheet.Companion.contextMenu
class PrimaryView : View() { class PrimaryView : View() {
@ -72,8 +77,27 @@ class PrimaryView : View() {
override fun updateItem(item: BotModel?, empty: Boolean) { override fun updateItem(item: BotModel?, empty: Boolean) {
super.updateItem(item, empty) super.updateItem(item, empty)
if (item != null && !empty) { if (item != null && !empty) {
graphic = null graphic = hbox {
text = item.uin.toString()
alignment = Pos.CENTER_LEFT
label(item.uin.toString())
pane {
hgrow = Priority.ALWAYS
}
jfxButton(graphic = SVG.close) {
buttonType = JFXButton.ButtonType.FLAT
tooltip("退出登录")
}.action {
alert(Alert.AlertType.CONFIRMATION, "${item.uin}将会退出登录,是否确认") {
if (it == ButtonType.OK) {
tab?.close()
controller.logout(item.uin)
}
}
}
}
text = ""
} else { } else {
graphic = null graphic = null
text = "" text = ""
@ -129,7 +153,7 @@ private fun TabPane.fixedTab(title: String) = tab(title) { isClosable = false }
private fun TabPane.logTab( private fun TabPane.logTab(
text: String? = null, text: String? = null,
logs: ObservableList<String>, logs: ObservableList<Pair<String, String>>,
closeable: Boolean = true, closeable: Boolean = true,
op: Tab.() -> Unit = {} op: Tab.() -> Unit = {}
) = tab(text) { ) = tab(text) {
@ -152,7 +176,7 @@ private fun TabPane.logTab(
path.firstOrNull()?.run { path.firstOrNull()?.run {
if (!exists()) createNewFile() if (!exists()) createNewFile()
writer().use { writer().use {
logs.forEach { log -> it.appendln(log) } logs.forEach { log -> it.appendln(log.first) }
} }
true true
} ?: false } ?: false
@ -166,9 +190,22 @@ private fun TabPane.logTab(
fitToParentSize() fitToParentSize()
cellFormat { cellFormat {
graphic = label(it) {
addPseudoClass(it.second)
graphic = label(it.first) {
maxWidthProperty().bind(this@listview.widthProperty()) maxWidthProperty().bind(this@listview.widthProperty())
isWrapText = true isWrapText = true
contextmenu {
item("复制").action {
Clipboard.getSystemClipboard().putString(it.first)
}
item("删除").action {
logs.remove(it)
}
}
} }
} }
} }

View File

@ -307,9 +307,11 @@ private val trySetAccessibleMethod: Method? = runCatching {
}.getOrNull() }.getOrNull()
private fun Constructor<out PluginBase>.againstPermission() { private fun Constructor<out PluginBase>.againstPermission() {
trySetAccessibleMethod?.let { it.invoke(this, true) } kotlin.runCatching {
?: kotlin.runCatching { trySetAccessibleMethod?.let { it.invoke(this) }
@Suppress("DEPRECATED") ?: kotlin.runCatching {
this.isAccessible = true @Suppress("DEPRECATED")
} this.isAccessible = true
}
}
} }