Merge remote-tracking branch 'origin/master'

# Conflicts:
#	gradle.properties
This commit is contained in:
jiahua.liu 2020-03-24 09:15:18 +08:00
commit ac125b22d2
11 changed files with 297 additions and 38 deletions

View File

@ -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的全部配置文件储存位置有关

View File

@ -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

View File

@ -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))
}

View File

@ -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)
}
}
}
}
}
}

View File

@ -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") {

View File

@ -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()
}

View File

@ -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 {

View File

@ -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"
}

View File

@ -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

View File

@ -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)