mirror of
https://github.com/mamoe/mirai.git
synced 2025-03-10 12:10:10 +08:00
Merge remote-tracking branch 'origin/master'
# Conflicts: # gradle.properties
This commit is contained in:
commit
ac125b22d2
@ -25,7 +25,9 @@ Mirai 是一个在全平台下运行,提供 QQ Android 和 TIM PC 协议支持
|
||||
[mirai-console插件开发快速上手](PluginDocs/ToStart.MD)
|
||||
|
||||
### 使用
|
||||
#### [下载(download)](https://github.com/mamoe/mirai-console/releases)
|
||||
**[下载(download)](https://github.com/mamoe/mirai-console/releases)**
|
||||
请下载最新的 `mirai-console-wrapper-x.x.x-all.jar`
|
||||
|
||||
#### 如何启动
|
||||
如果是打包好的软件, 双击<br>
|
||||
如果是命令行运行, 请注意运行目录, 推荐cd到jar的文件夹下运行, 运行目录与Console的全部配置文件储存位置有关
|
||||
|
@ -1,7 +1,7 @@
|
||||
# style guide
|
||||
kotlin.code.style=official
|
||||
# config
|
||||
miraiVersion=0.29.0
|
||||
miraiVersion=0.29.1
|
||||
miraiConsoleVersion=0.3.6
|
||||
miraiConsoleWrapperVersion=0.1.3
|
||||
kotlin.incremental.multiplatform=true
|
||||
|
@ -1,7 +1,13 @@
|
||||
package net.mamoe.mirai.console.graphical.styleSheet
|
||||
|
||||
import javafx.scene.layout.BackgroundRepeat
|
||||
import javafx.scene.paint.Color
|
||||
import net.mamoe.mirai.console.MiraiConsole
|
||||
import tornadofx.Stylesheet
|
||||
import tornadofx.c
|
||||
import tornadofx.cssclass
|
||||
import tornadofx.csselement
|
||||
import java.io.File
|
||||
import kotlin.random.Random
|
||||
|
||||
open class BaseStyleSheet : Stylesheet() {
|
||||
|
||||
@ -10,6 +16,48 @@ open class BaseStyleSheet : Stylesheet() {
|
||||
const val stressColor = "35867C"
|
||||
const val secondaryColor = "32CABA"
|
||||
const val lightColor ="9FD1CC"
|
||||
const val FontColor = "FFFFFF"
|
||||
const val fontColor = "FFFFFF"
|
||||
val TRANSPARENT: Color = Color.TRANSPARENT
|
||||
|
||||
val rootPane by cssclass("root-pane")
|
||||
val jfxTabPane by cssclass("jfx-tab-pane")
|
||||
val myButtonBar by cssclass("my-button-bar")
|
||||
|
||||
val vBox by csselement("VBox")
|
||||
}
|
||||
|
||||
init {
|
||||
|
||||
rootPane {
|
||||
|
||||
child(imageView) {}
|
||||
|
||||
|
||||
jfxTabPane {
|
||||
val bg = File(MiraiConsole.path, "background")
|
||||
if (!bg.exists()) bg.mkdir()
|
||||
if (bg.isDirectory) {
|
||||
bg.listFiles()!!.filter { file -> file.extension in listOf("jpg", "jpeg", "png", "gif") }
|
||||
.randomElement()?.also {
|
||||
backgroundImage += it.toURI()
|
||||
backgroundRepeat += BackgroundRepeat.REPEAT to BackgroundRepeat.REPEAT
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
listView {
|
||||
backgroundColor += TRANSPARENT
|
||||
|
||||
listCell {
|
||||
backgroundColor += TRANSPARENT
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun <T> Collection<T>.randomElement(): T? {
|
||||
if (isEmpty())
|
||||
return null
|
||||
return elementAt(Random.nextInt(size))
|
||||
}
|
@ -0,0 +1,61 @@
|
||||
package net.mamoe.mirai.console.graphical.styleSheet
|
||||
|
||||
import javafx.geometry.Pos
|
||||
import javafx.scene.paint.Color
|
||||
import javafx.scene.text.FontWeight
|
||||
import tornadofx.box
|
||||
import tornadofx.c
|
||||
import tornadofx.cssclass
|
||||
import tornadofx.px
|
||||
|
||||
class PluginViewStyleSheet : BaseStyleSheet() {
|
||||
|
||||
companion object {
|
||||
val jfxTreeTableView by cssclass("jfx-tree-table-view")
|
||||
val treeTableRowCell by cssclass("tree-table-row-cell")
|
||||
val columnHeader by cssclass("column-header")
|
||||
val columnHeaderBg by cssclass("column-header-background")
|
||||
}
|
||||
|
||||
|
||||
init {
|
||||
jfxTreeTableView {
|
||||
backgroundColor += TRANSPARENT
|
||||
|
||||
columnHeader {
|
||||
borderWidth += box(0.px)
|
||||
|
||||
label {
|
||||
textFill = Color.BLACK
|
||||
}
|
||||
}
|
||||
|
||||
columnHeaderBg {
|
||||
backgroundColor += c(lightColor, 0.4)
|
||||
}
|
||||
|
||||
treeTableCell {
|
||||
alignment = Pos.CENTER
|
||||
}
|
||||
|
||||
treeTableRowCell {
|
||||
|
||||
fontWeight = FontWeight.SEMI_BOLD
|
||||
|
||||
|
||||
backgroundColor += TRANSPARENT
|
||||
|
||||
and(":selected") {
|
||||
backgroundColor += c(stressColor, 1.0)
|
||||
}
|
||||
|
||||
and(":hover:filled") {
|
||||
backgroundColor += c(stressColor, 0.6)
|
||||
and(":selected") {
|
||||
backgroundColor += c(stressColor, 1.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package net.mamoe.mirai.console.graphical.styleSheet
|
||||
|
||||
import javafx.scene.Cursor
|
||||
import javafx.scene.paint.Color
|
||||
import javafx.scene.text.FontWeight
|
||||
import tornadofx.*
|
||||
|
||||
class PrimaryStyleSheet : BaseStyleSheet() {
|
||||
@ -10,9 +10,14 @@ class PrimaryStyleSheet : BaseStyleSheet() {
|
||||
val jfxTitle by cssclass("jfx-decorator-buttons-container")
|
||||
val container by cssclass("jfx-decorator-content-container")
|
||||
|
||||
// tab
|
||||
val jfxTabPane by cssclass("tab-header-background")
|
||||
// jfx tab
|
||||
val jfxTabHeader by cssclass("tab-header-background")
|
||||
val closeButton by cssclass("tab-close-button")
|
||||
|
||||
// jfx list view
|
||||
val leftPane by cssclass("left-pane")
|
||||
val jfxListView by cssclass("jfx-list-view")
|
||||
val jfxListCell by cssclass("jfx-list-cell")
|
||||
}
|
||||
|
||||
init {
|
||||
@ -28,14 +33,105 @@ class PrimaryStyleSheet : BaseStyleSheet() {
|
||||
borderWidth += box(0.px, 4.px, 4.px, 4.px)
|
||||
}
|
||||
|
||||
/*
|
||||
* bot list
|
||||
*/
|
||||
rootPane {
|
||||
child(vBox) {
|
||||
|
||||
backgroundColor += c(primaryColor)
|
||||
// 这个padding有bug,十分神奇
|
||||
padding = box(0.px, 4.px, 0.px, 0.px)
|
||||
spacing = 4.px
|
||||
|
||||
jfxListView {
|
||||
|
||||
jfxListCell {
|
||||
backgroundColor += c(100, 100, 100, 0.4)
|
||||
backgroundRadius += box(5.px)
|
||||
|
||||
textFill = c(fontColor)
|
||||
fontWeight = FontWeight.BOLD
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
textField {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* tab pane
|
||||
*/
|
||||
jfxTabPane {
|
||||
jfxTabHeader {
|
||||
backgroundColor += c(primaryColor)
|
||||
}
|
||||
|
||||
jfxTabPane {
|
||||
|
||||
// 日志列表样式
|
||||
vBox {
|
||||
padding = box(15.px)
|
||||
spacing = 15.px
|
||||
}
|
||||
|
||||
myButtonBar {
|
||||
spacing = 15.px
|
||||
|
||||
button {
|
||||
backgroundColor += c(secondaryColor, 0.8)
|
||||
padding = box(2.px, 10.px)
|
||||
cursor = Cursor.HAND
|
||||
textFill = c(fontColor)
|
||||
fontSize = 12.px
|
||||
}
|
||||
}
|
||||
|
||||
listView {
|
||||
// 字体在label里,大坑
|
||||
label {
|
||||
fontSize = 13.px
|
||||
}
|
||||
|
||||
listCell {
|
||||
and(":selected") {
|
||||
backgroundColor += c(stressColor, 1.0)
|
||||
}
|
||||
|
||||
and(":hover:filled") {
|
||||
backgroundColor += c(stressColor, 0.6)
|
||||
and(":selected") {
|
||||
backgroundColor += c(stressColor, 1.0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 调整滚动条
|
||||
scrollBar {
|
||||
|
||||
backgroundColor += TRANSPARENT
|
||||
|
||||
// 隐藏水平滚动条
|
||||
and(horizontal) {
|
||||
prefHeight = 0.px
|
||||
s(incrementArrow, decrementArrow) { backgroundColor += TRANSPARENT }
|
||||
}
|
||||
|
||||
and(vertical) {
|
||||
thumb {
|
||||
backgroundColor += c(stressColor, 0.6)
|
||||
}
|
||||
|
||||
track {
|
||||
backgroundColor += TRANSPARENT
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 去除JFoenix默认样式
|
||||
tab {
|
||||
and(":closable") {
|
||||
|
@ -0,0 +1,13 @@
|
||||
package net.mamoe.mirai.console.graphical.util
|
||||
|
||||
import javafx.event.EventTarget
|
||||
import javafx.geometry.Pos
|
||||
import javafx.scene.layout.HBox
|
||||
import tornadofx.addClass
|
||||
import tornadofx.hbox
|
||||
|
||||
fun EventTarget.myButtonBar(alignment: Pos = Pos.BASELINE_LEFT, op: HBox.() -> Unit = {}) = hbox {
|
||||
addClass("my-button-bar")
|
||||
this.alignment = alignment
|
||||
op()
|
||||
}
|
@ -3,8 +3,10 @@ package net.mamoe.mirai.console.graphical.view
|
||||
import com.jfoenix.controls.JFXTreeTableColumn
|
||||
import net.mamoe.mirai.console.graphical.controller.MiraiGraphicalUIController
|
||||
import net.mamoe.mirai.console.graphical.model.PluginModel
|
||||
import net.mamoe.mirai.console.graphical.styleSheet.PluginViewStyleSheet
|
||||
import net.mamoe.mirai.console.graphical.util.jfxTreeTableView
|
||||
import tornadofx.View
|
||||
import tornadofx.addStylesheet
|
||||
|
||||
class PluginsView : View() {
|
||||
|
||||
@ -12,6 +14,9 @@ class PluginsView : View() {
|
||||
val plugins = controller.pluginList
|
||||
|
||||
override val root = jfxTreeTableView(plugins) {
|
||||
|
||||
addStylesheet(PluginViewStyleSheet::class)
|
||||
|
||||
isShowRoot = false
|
||||
columns.addAll(
|
||||
JFXTreeTableColumn<PluginModel, String>("插件名").apply {
|
||||
|
@ -2,6 +2,8 @@ package net.mamoe.mirai.console.graphical.view
|
||||
|
||||
import com.jfoenix.controls.JFXListCell
|
||||
import javafx.collections.ObservableList
|
||||
import javafx.geometry.Insets
|
||||
import javafx.geometry.Pos
|
||||
import javafx.scene.control.Tab
|
||||
import javafx.scene.control.TabPane
|
||||
import javafx.scene.image.Image
|
||||
@ -10,8 +12,10 @@ import javafx.stage.FileChooser
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.mamoe.mirai.console.graphical.controller.MiraiGraphicalUIController
|
||||
import net.mamoe.mirai.console.graphical.model.BotModel
|
||||
import net.mamoe.mirai.console.graphical.util.jfxButton
|
||||
import net.mamoe.mirai.console.graphical.util.jfxListView
|
||||
import net.mamoe.mirai.console.graphical.util.jfxTabPane
|
||||
import net.mamoe.mirai.console.graphical.util.myButtonBar
|
||||
import tornadofx.*
|
||||
|
||||
class PrimaryView : View() {
|
||||
@ -21,15 +25,19 @@ class PrimaryView : View() {
|
||||
|
||||
override val root = borderpane {
|
||||
|
||||
addClass("root-pane")
|
||||
|
||||
left = vbox {
|
||||
|
||||
imageview(Image(PrimaryView::class.java.classLoader.getResourceAsStream("logo.png"))) {
|
||||
fitHeight = 40.0
|
||||
alignment = Pos.CENTER
|
||||
isPreserveRatio = true
|
||||
}
|
||||
|
||||
// bot list
|
||||
jfxListView(controller.botList) {
|
||||
fitToParentSize()
|
||||
fitToParentHeight()
|
||||
|
||||
setCellFactory {
|
||||
object : JFXListCell<BotModel>() {
|
||||
@ -37,7 +45,7 @@ class PrimaryView : View() {
|
||||
|
||||
init {
|
||||
onDoubleClick {
|
||||
tab?.select() ?: (center as TabPane).logTab(
|
||||
tab?.select() ?: mainTabPane.logTab(
|
||||
text = item.uin.toString(),
|
||||
logs = item.logHistory
|
||||
).select().also { tab = it }
|
||||
@ -60,6 +68,9 @@ class PrimaryView : View() {
|
||||
|
||||
// command input
|
||||
textfield {
|
||||
|
||||
promptText = "在这里输出命令"
|
||||
|
||||
setOnKeyPressed {
|
||||
if (it.code == KeyCode.ENTER) {
|
||||
runAsync {
|
||||
@ -76,11 +87,11 @@ class PrimaryView : View() {
|
||||
|
||||
logTab("Main", controller.mainLog, closeable = false)
|
||||
|
||||
tab("Plugins").apply { isClosable = false }.content = find<PluginsView>().root
|
||||
fixedTab("Plugins").content = find<PluginsView>().root
|
||||
|
||||
tab("Settings").apply { isClosable = false }.content = find<SettingsView>().root
|
||||
fixedTab("Settings").content = find<SettingsView>().root
|
||||
|
||||
tab("Login").apply { isClosable = false }.content = find<LoginView>().root
|
||||
fixedTab("Login").content = find<LoginView>().root
|
||||
|
||||
mainTabPane = this
|
||||
}
|
||||
@ -92,6 +103,8 @@ class PrimaryView : View() {
|
||||
}
|
||||
}
|
||||
|
||||
private fun TabPane.fixedTab(title: String) = tab(title) { isClosable = false }
|
||||
|
||||
private fun TabPane.logTab(
|
||||
text: String? = null,
|
||||
logs: ObservableList<String>,
|
||||
@ -102,13 +115,14 @@ private fun TabPane.logTab(
|
||||
this.isClosable = closeable
|
||||
|
||||
vbox {
|
||||
buttonbar {
|
||||
myButtonBar(alignment = Pos.BASELINE_RIGHT) {
|
||||
|
||||
button("导出日志").action {
|
||||
jfxButton("导出日志").action {
|
||||
val path = chooseFile(
|
||||
"选择保存路径",
|
||||
arrayOf(FileChooser.ExtensionFilter("日志", "txt")),
|
||||
FileChooserMode.Save
|
||||
FileChooserMode.Save,
|
||||
owner = FX.primaryStage
|
||||
) {
|
||||
initialFileName = "$text.txt"
|
||||
}
|
||||
|
@ -1,9 +1,11 @@
|
||||
package net.mamoe.mirai.console.graphical.view
|
||||
|
||||
import javafx.geometry.Pos
|
||||
import net.mamoe.mirai.console.graphical.controller.MiraiGraphicalUIController
|
||||
import net.mamoe.mirai.console.graphical.model.GlobalSettingModel
|
||||
import net.mamoe.mirai.console.graphical.util.jfxButton
|
||||
import net.mamoe.mirai.console.graphical.util.jfxTextfield
|
||||
import net.mamoe.mirai.console.graphical.util.myButtonBar
|
||||
import tornadofx.*
|
||||
import java.awt.Desktop
|
||||
import java.io.File
|
||||
@ -13,33 +15,44 @@ class SettingsView : View() {
|
||||
private val controller = find<MiraiGraphicalUIController>()
|
||||
private val settingModel = find<GlobalSettingModel>()
|
||||
|
||||
override val root = form {
|
||||
override val root = vbox {
|
||||
|
||||
fieldset {
|
||||
field {
|
||||
jfxButton("撤掉").action {
|
||||
settingModel.rollback()
|
||||
}
|
||||
jfxButton("保存").action {
|
||||
settingModel.commit()
|
||||
}
|
||||
myButtonBar(alignment = Pos.BASELINE_RIGHT) {
|
||||
jfxButton("撤掉").action {
|
||||
settingModel.rollback()
|
||||
}
|
||||
jfxButton("保存").action {
|
||||
settingModel.commit()
|
||||
}
|
||||
}
|
||||
|
||||
fieldset("插件目录") {
|
||||
field {
|
||||
jfxTextfield((System.getProperty("user.dir") + "/plugins/").replace("//", "/")) { isEditable = false }
|
||||
jfxButton("打开目录").action {
|
||||
(System.getProperty("user.dir") + "/plugins/").replace("//", "/").also { path ->
|
||||
Desktop.getDesktop().takeIf { it.isSupported(Desktop.Action.OPEN) }?.open(File(path))
|
||||
form {
|
||||
fieldset("插件目录") {
|
||||
field {
|
||||
jfxTextfield((System.getProperty("user.dir") + "/plugins/").replace("//", "/")) { isEditable = false }
|
||||
jfxButton("打开目录").action {
|
||||
(System.getProperty("user.dir") + "/plugins/").replace("//", "/").also { path ->
|
||||
Desktop.getDesktop().takeIf { it.isSupported(Desktop.Action.OPEN) }?.open(File(path))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fieldset("最大日志容量") {
|
||||
field {
|
||||
jfxTextfield().bind(settingModel.maxLogNum)
|
||||
fieldset("背景目录") {
|
||||
field {
|
||||
jfxTextfield((System.getProperty("user.dir") + "/background/").replace("//", "/")) { isEditable = false }
|
||||
jfxButton("打开目录").action {
|
||||
(System.getProperty("user.dir") + "/background/").replace("//", "/").also { path ->
|
||||
Desktop.getDesktop().takeIf { it.isSupported(Desktop.Action.OPEN) }?.open(File(path))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fieldset("最大日志容量") {
|
||||
field {
|
||||
jfxTextfield().bind(settingModel.maxLogNum)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 4.6 KiB After Width: | Height: | Size: 16 KiB |
@ -103,7 +103,7 @@ object MiraiConsole {
|
||||
}
|
||||
|
||||
/**
|
||||
* 关闭Console
|
||||
* 关闭 Console
|
||||
*/
|
||||
fun stop() {
|
||||
PluginManager.disablePlugins()
|
||||
@ -118,7 +118,14 @@ object MiraiConsole {
|
||||
}
|
||||
|
||||
@Suppress("RedundantSuspendModifier") // binary compatibility
|
||||
@Deprecated("Please use CommandManager directly, this will be removed in later release")
|
||||
@Deprecated(
|
||||
"Please use CommandManager directly, this will be removed in later release",
|
||||
ReplaceWith(
|
||||
"CommandManager",
|
||||
"net.mamoe.mirai.console.command.CommandManager"
|
||||
),
|
||||
level = DeprecationLevel.ERROR
|
||||
)
|
||||
object CommandProcessor {
|
||||
@Deprecated(
|
||||
"Please use CommandManager directly, this will be removed in later release", ReplaceWith(
|
||||
@ -156,7 +163,7 @@ object MiraiConsole {
|
||||
"Please use CommandManager directly, this will be removed in later release", ReplaceWith(
|
||||
"CommandManager.runCommand(sender, command)",
|
||||
"net.mamoe.mirai.console.command.CommandManager"
|
||||
)
|
||||
), level = DeprecationLevel.ERROR
|
||||
)
|
||||
fun runCommandBlocking(sender: CommandSender, command: String) = runBlocking {
|
||||
CommandManager.runCommand(sender, command)
|
||||
|
Loading…
Reference in New Issue
Block a user