Quick search in pattern grid
This commit is contained in:
parent
1315636948
commit
dd74643c67
@ -586,6 +586,8 @@ private fun androidFeatures(provider: MatteryLanguageProvider) {
|
|||||||
|
|
||||||
private fun gui(provider: MatteryLanguageProvider) {
|
private fun gui(provider: MatteryLanguageProvider) {
|
||||||
with(provider.english) {
|
with(provider.english) {
|
||||||
|
gui("quicksearch", "Quick search...")
|
||||||
|
|
||||||
gui("item_monitor.refill_source.desc", "Controls from where to take items for slot auto refill")
|
gui("item_monitor.refill_source.desc", "Controls from where to take items for slot auto refill")
|
||||||
gui("item_monitor.refill_source.system", "System only. Crafting grid will be auto refilled only from storage system. This is the behavior you see in AE2 and Refined Storage")
|
gui("item_monitor.refill_source.system", "System only. Crafting grid will be auto refilled only from storage system. This is the behavior you see in AE2 and Refined Storage")
|
||||||
gui("item_monitor.refill_source.inventory", "Inventory only. Crafting grid will be auto refilled only from player's inventory")
|
gui("item_monitor.refill_source.inventory", "Inventory only. Crafting grid will be auto refilled only from player's inventory")
|
||||||
|
@ -594,6 +594,8 @@ private fun androidFeatures(provider: MatteryLanguageProvider) {
|
|||||||
|
|
||||||
private fun gui(provider: MatteryLanguageProvider) {
|
private fun gui(provider: MatteryLanguageProvider) {
|
||||||
with(provider.russian) {
|
with(provider.russian) {
|
||||||
|
gui("quicksearch", "Быстрый поиск...")
|
||||||
|
|
||||||
gui("item_monitor.refill_source.desc", "Контролирует источник предметов для заполнения сетки создания")
|
gui("item_monitor.refill_source.desc", "Контролирует источник предметов для заполнения сетки создания")
|
||||||
gui("item_monitor.refill_source.system", "Только система. Сетка создания будет заполняться только из системы предметов. Данный параметр соответствует поведению AE2 и Refined Storage")
|
gui("item_monitor.refill_source.system", "Только система. Сетка создания будет заполняться только из системы предметов. Данный параметр соответствует поведению AE2 и Refined Storage")
|
||||||
gui("item_monitor.refill_source.inventory", "Только инвентарь. Сетка создания будет заполняться только из инвентаря игрока")
|
gui("item_monitor.refill_source.inventory", "Только инвентарь. Сетка создания будет заполняться только из инвентаря игрока")
|
||||||
|
@ -32,6 +32,7 @@ import ru.dbotthepony.mc.otm.menu.matter.MatterPanelMenu
|
|||||||
import ru.dbotthepony.mc.otm.menu.matter.ReplicationRequestPacket
|
import ru.dbotthepony.mc.otm.menu.matter.ReplicationRequestPacket
|
||||||
import ru.dbotthepony.mc.otm.network.MenuNetworkChannel
|
import ru.dbotthepony.mc.otm.network.MenuNetworkChannel
|
||||||
import yalter.mousetweaks.api.MouseTweaksDisableWheelTweak
|
import yalter.mousetweaks.api.MouseTweaksDisableWheelTweak
|
||||||
|
import java.util.function.Predicate
|
||||||
import kotlin.math.roundToInt
|
import kotlin.math.roundToInt
|
||||||
|
|
||||||
@MouseTweaksDisableWheelTweak
|
@MouseTweaksDisableWheelTweak
|
||||||
@ -45,7 +46,8 @@ class MatterPanelScreen(
|
|||||||
var scrollPatterns = 0
|
var scrollPatterns = 0
|
||||||
var scrollTasks = 0
|
var scrollTasks = 0
|
||||||
|
|
||||||
val frame = FramePanel.padded(this, null, GRID_WIDTH * AbstractSlotPanel.SIZE + ScrollBarConstants.WIDTH + 4f, GRID_HEIGHT * AbstractSlotPanel.SIZE, title)
|
val frame = FramePanel.padded(this, null, GRID_WIDTH * AbstractSlotPanel.SIZE + ScrollBarConstants.WIDTH + 4f, GRID_HEIGHT * AbstractSlotPanel.SIZE + 2f, title)
|
||||||
|
frame.dockPadding = frame.dockPadding.copy(top = frame.dockPadding.top + 2f)
|
||||||
|
|
||||||
val controls = DeviceControls(this, frame)
|
val controls = DeviceControls(this, frame)
|
||||||
|
|
||||||
@ -69,9 +71,9 @@ class MatterPanelScreen(
|
|||||||
|
|
||||||
val scrollBar = DiscreteScrollBarPanel(this, frame, {
|
val scrollBar = DiscreteScrollBarPanel(this, frame, {
|
||||||
if (isPatternView) {
|
if (isPatternView) {
|
||||||
integerDivisionDown(menu.patterns.size, GRID_WIDTH)
|
integerDivisionDown(menu.patternsFiltered.size, GRID_WIDTH)
|
||||||
} else {
|
} else {
|
||||||
integerDivisionDown(menu.tasks.size, GRID_WIDTH)
|
integerDivisionDown(menu.tasksFiltered.size, GRID_WIDTH)
|
||||||
}
|
}
|
||||||
}, { _, _, new ->
|
}, { _, _, new ->
|
||||||
if (isPatternView)
|
if (isPatternView)
|
||||||
@ -80,6 +82,25 @@ class MatterPanelScreen(
|
|||||||
scrollTasks = new
|
scrollTasks = new
|
||||||
})
|
})
|
||||||
|
|
||||||
|
object : TextInputPanel<MatterPanelScreen>(this@MatterPanelScreen, frame) {
|
||||||
|
init {
|
||||||
|
width = frame.width * 0.4f
|
||||||
|
x = frame.width - width - FramePanel.PADDING
|
||||||
|
y = 4f
|
||||||
|
placeholder = TranslatableComponent("otm.gui.quicksearch")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun onTextChanged(old: String, new: String) {
|
||||||
|
if (new == "") {
|
||||||
|
menu.filter = Predicate { true }
|
||||||
|
} else {
|
||||||
|
val new = new.lowercase()
|
||||||
|
menu.filter = Predicate { it.description.string.lowercase().contains(new) }
|
||||||
|
scrollBar.scroll = scrollBar.scroll
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
scrollBar.dock = Dock.RIGHT
|
scrollBar.dock = Dock.RIGHT
|
||||||
|
|
||||||
frame.Tab(onOpen = { isPatternView = true; scrollBar.scroll = scrollPatterns }, activeIcon = PATTERN_LIST_ACTIVE, inactiveIcon = PATTERN_LIST_INACTIVE).also {
|
frame.Tab(onOpen = { isPatternView = true; scrollBar.scroll = scrollPatterns }, activeIcon = PATTERN_LIST_ACTIVE, inactiveIcon = PATTERN_LIST_INACTIVE).also {
|
||||||
@ -121,9 +142,9 @@ class MatterPanelScreen(
|
|||||||
|
|
||||||
override val itemStack: ItemStack get() {
|
override val itemStack: ItemStack get() {
|
||||||
if (isPatternView) {
|
if (isPatternView) {
|
||||||
return menu.patterns.getOrNull(index)?.stack() ?: ItemStack.EMPTY
|
return menu.patternsFiltered.getOrNull(index)?.stack() ?: ItemStack.EMPTY
|
||||||
} else {
|
} else {
|
||||||
return menu.tasks.getOrNull(index)?.let { it.stack(it.required + it.inProgress) } ?: ItemStack.EMPTY
|
return menu.tasksFiltered.getOrNull(index)?.let { it.stack(it.required + it.inProgress) } ?: ItemStack.EMPTY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,13 +152,13 @@ class MatterPanelScreen(
|
|||||||
val list = super.getItemStackTooltip(stack).toMutableList()
|
val list = super.getItemStackTooltip(stack).toMutableList()
|
||||||
|
|
||||||
if (isPatternView) {
|
if (isPatternView) {
|
||||||
menu.patterns.getOrNull(index)?.let {
|
menu.patternsFiltered.getOrNull(index)?.let {
|
||||||
list.add(TranslatableComponent(
|
list.add(TranslatableComponent(
|
||||||
"otm.item.pattern.research",
|
"otm.item.pattern.research",
|
||||||
String.format("%.2f", it.researchPercent * 100.0)
|
String.format("%.2f", it.researchPercent * 100.0)
|
||||||
).withStyle(ChatFormatting.AQUA)) }
|
).withStyle(ChatFormatting.AQUA)) }
|
||||||
} else {
|
} else {
|
||||||
menu.tasks.getOrNull(index)?.let {
|
menu.tasksFiltered.getOrNull(index)?.let {
|
||||||
list.add(TranslatableComponent("otm.gui.matter_task.total", it.total).withStyle(ChatFormatting.GRAY))
|
list.add(TranslatableComponent("otm.gui.matter_task.total", it.total).withStyle(ChatFormatting.GRAY))
|
||||||
list.add(TranslatableComponent("otm.gui.matter_task.required", it.required).withStyle(ChatFormatting.GRAY))
|
list.add(TranslatableComponent("otm.gui.matter_task.required", it.required).withStyle(ChatFormatting.GRAY))
|
||||||
list.add(TranslatableComponent("otm.gui.matter_task.in_progress", it.inProgress).withStyle(ChatFormatting.GRAY))
|
list.add(TranslatableComponent("otm.gui.matter_task.in_progress", it.inProgress).withStyle(ChatFormatting.GRAY))
|
||||||
@ -151,9 +172,9 @@ class MatterPanelScreen(
|
|||||||
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
override fun mouseClickedInner(x: Double, y: Double, button: Int): Boolean {
|
||||||
if (isPatternView) {
|
if (isPatternView) {
|
||||||
if (minecraft?.player?.isSpectator != true)
|
if (minecraft?.player?.isSpectator != true)
|
||||||
menu.patterns.getOrNull(index)?.let(this@MatterPanelScreen::openPattern)
|
menu.patternsFiltered.getOrNull(index)?.let(this@MatterPanelScreen::openPattern)
|
||||||
} else {
|
} else {
|
||||||
menu.tasks.getOrNull(index)?.let(this@MatterPanelScreen::openTask)
|
menu.tasksFiltered.getOrNull(index)?.let(this@MatterPanelScreen::openTask)
|
||||||
}
|
}
|
||||||
|
|
||||||
return true
|
return true
|
||||||
@ -180,13 +201,13 @@ class MatterPanelScreen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override val itemStack: ItemStack get() {
|
override val itemStack: ItemStack get() {
|
||||||
return menu.tasks.firstOrNull { it.id == task.id }?.let { it.stack((it.required + it.inProgress).coerceAtLeast(1)) } ?: task.stack((task.required + task.inProgress).coerceAtLeast(1))
|
return menu.tasksFiltered.firstOrNull { it.id == task.id }?.let { it.stack((it.required + it.inProgress).coerceAtLeast(1)) } ?: task.stack((task.required + task.inProgress).coerceAtLeast(1))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun tickInner() {
|
override fun tickInner() {
|
||||||
super.tickInner()
|
super.tickInner()
|
||||||
|
|
||||||
if (!menu.tasks.any { it.id == task.id }) {
|
if (!menu.tasksFiltered.any { it.id == task.id }) {
|
||||||
frame.remove()
|
frame.remove()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,7 +275,7 @@ class MatterPanelScreen(
|
|||||||
override fun tickInner() {
|
override fun tickInner() {
|
||||||
super.tickInner()
|
super.tickInner()
|
||||||
|
|
||||||
if (!menu.patterns.any { it.id == pattern.id }) {
|
if (!menu.patternsFiltered.any { it.id == pattern.id }) {
|
||||||
frame.remove()
|
frame.remove()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,6 +12,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
|||||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap
|
||||||
import net.minecraft.client.gui.screens.Screen
|
import net.minecraft.client.gui.screens.Screen
|
||||||
import net.minecraft.client.renderer.GameRenderer
|
import net.minecraft.client.renderer.GameRenderer
|
||||||
|
import net.minecraft.network.chat.Component
|
||||||
import org.joml.Vector2i
|
import org.joml.Vector2i
|
||||||
import ru.dbotthepony.mc.otm.client.isCtrlDown
|
import ru.dbotthepony.mc.otm.client.isCtrlDown
|
||||||
import ru.dbotthepony.mc.otm.client.isShiftDown
|
import ru.dbotthepony.mc.otm.client.isShiftDown
|
||||||
@ -24,6 +25,7 @@ import ru.dbotthepony.mc.otm.client.render.drawRect
|
|||||||
import ru.dbotthepony.mc.otm.client.render.tesselator
|
import ru.dbotthepony.mc.otm.client.render.tesselator
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.DockProperty
|
import ru.dbotthepony.mc.otm.client.screen.panels.DockProperty
|
||||||
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
import ru.dbotthepony.mc.otm.client.screen.panels.EditablePanel
|
||||||
|
import ru.dbotthepony.mc.otm.core.TextComponent
|
||||||
import ru.dbotthepony.mc.otm.core.addAll
|
import ru.dbotthepony.mc.otm.core.addAll
|
||||||
import ru.dbotthepony.mc.otm.core.math.RGBAColor
|
import ru.dbotthepony.mc.otm.core.math.RGBAColor
|
||||||
import ru.dbotthepony.mc.otm.milliTime
|
import ru.dbotthepony.mc.otm.milliTime
|
||||||
@ -141,7 +143,9 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
|
|
||||||
var cursorLine = 0
|
var cursorLine = 0
|
||||||
var cursorRow = 0
|
var cursorRow = 0
|
||||||
|
open var placeholder: Component = TextComponent("")
|
||||||
open var textColor = RGBAColor.WHITE
|
open var textColor = RGBAColor.WHITE
|
||||||
|
open var placeholderColor = RGBAColor.DARK_GRAY
|
||||||
open var cursorColor = RGBAColor.GREEN
|
open var cursorColor = RGBAColor.GREEN
|
||||||
open var backgroundColor = RGBAColor.BLACK
|
open var backgroundColor = RGBAColor.BLACK
|
||||||
open var isActive = true
|
open var isActive = true
|
||||||
@ -1085,6 +1089,18 @@ open class TextInputPanel<out S : Screen>(
|
|||||||
|
|
||||||
var y = topPadding
|
var y = topPadding
|
||||||
|
|
||||||
|
if (lines.isEmpty() || lines.size == 1 && lines[0] == "") {
|
||||||
|
font.drawAligned(
|
||||||
|
poseStack = stack,
|
||||||
|
buffer = BUFFER,
|
||||||
|
text = placeholder,
|
||||||
|
align = TextAlign.TOP_LEFT,
|
||||||
|
x = dockPadding.left,
|
||||||
|
y = y,
|
||||||
|
color = placeholderColor
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
for (i in scrollLines until lines.size) {
|
for (i in scrollLines until lines.size) {
|
||||||
val line = lines[i]
|
val line = lines[i]
|
||||||
val selection = selections[i]
|
val selection = selections[i]
|
||||||
|
@ -109,7 +109,7 @@ open class DiscreteScrollBarPanel<out S : Screen>(
|
|||||||
|
|
||||||
var scroll = 0
|
var scroll = 0
|
||||||
set(value) {
|
set(value) {
|
||||||
val newValue = value.coerceAtLeast(0).coerceAtMost(maxScroll.invoke(this))
|
val newValue = value.coerceIn(0, maxScroll.invoke(this))
|
||||||
|
|
||||||
if (newValue != field) {
|
if (newValue != field) {
|
||||||
val old = field
|
val old = field
|
||||||
|
@ -4,6 +4,7 @@ import net.minecraft.network.FriendlyByteBuf
|
|||||||
import net.minecraft.server.level.ServerPlayer
|
import net.minecraft.server.level.ServerPlayer
|
||||||
import net.minecraft.world.entity.player.Inventory
|
import net.minecraft.world.entity.player.Inventory
|
||||||
import net.minecraft.world.entity.player.Player
|
import net.minecraft.world.entity.player.Player
|
||||||
|
import net.minecraft.world.item.Item
|
||||||
import net.minecraftforge.network.NetworkEvent
|
import net.minecraftforge.network.NetworkEvent
|
||||||
import net.minecraftforge.network.PacketDistributor
|
import net.minecraftforge.network.PacketDistributor
|
||||||
import org.apache.logging.log4j.LogManager
|
import org.apache.logging.log4j.LogManager
|
||||||
@ -23,6 +24,7 @@ import ru.dbotthepony.mc.otm.menu.MatteryMenu
|
|||||||
import ru.dbotthepony.mc.otm.network.*
|
import ru.dbotthepony.mc.otm.network.*
|
||||||
import ru.dbotthepony.mc.otm.registry.MMenus
|
import ru.dbotthepony.mc.otm.registry.MMenus
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import java.util.function.Predicate
|
||||||
import java.util.function.Supplier
|
import java.util.function.Supplier
|
||||||
import kotlin.Comparator
|
import kotlin.Comparator
|
||||||
import kotlin.collections.ArrayList
|
import kotlin.collections.ArrayList
|
||||||
@ -158,7 +160,9 @@ class MatterPanelMenu @JvmOverloads constructor(
|
|||||||
codec = ItemSorter::class.codec(),
|
codec = ItemSorter::class.codec(),
|
||||||
observer = {
|
observer = {
|
||||||
patterns.sortWith(actualComparator)
|
patterns.sortWith(actualComparator)
|
||||||
|
patternsFiltered.sortWith(actualComparator)
|
||||||
tasks.sortWith(actualTaskComparator)
|
tasks.sortWith(actualTaskComparator)
|
||||||
|
tasksFiltered.sortWith(actualTaskComparator)
|
||||||
})
|
})
|
||||||
|
|
||||||
val isAscending: Boolean by mSynchronizer.ComputedField(
|
val isAscending: Boolean by mSynchronizer.ComputedField(
|
||||||
@ -166,7 +170,9 @@ class MatterPanelMenu @JvmOverloads constructor(
|
|||||||
codec = BooleanValueCodec,
|
codec = BooleanValueCodec,
|
||||||
observer = {
|
observer = {
|
||||||
patterns.sortWith(actualComparator)
|
patterns.sortWith(actualComparator)
|
||||||
|
patternsFiltered.sortWith(actualComparator)
|
||||||
tasks.sortWith(actualTaskComparator)
|
tasks.sortWith(actualTaskComparator)
|
||||||
|
tasksFiltered.sortWith(actualTaskComparator)
|
||||||
})
|
})
|
||||||
|
|
||||||
val totalMatterStored: Decimal by mSynchronizer.ComputedField(
|
val totalMatterStored: Decimal by mSynchronizer.ComputedField(
|
||||||
@ -174,6 +180,25 @@ class MatterPanelMenu @JvmOverloads constructor(
|
|||||||
codec = DecimalValueCodec,
|
codec = DecimalValueCodec,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var filter: Predicate<Item> = Predicate { true }
|
||||||
|
set(value) {
|
||||||
|
field = value
|
||||||
|
patternsFiltered.clear()
|
||||||
|
tasksFiltered.clear()
|
||||||
|
|
||||||
|
for (pattern in patterns) {
|
||||||
|
if (value.test(pattern.item)) {
|
||||||
|
patternsFiltered.add(pattern)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (task in tasks) {
|
||||||
|
if (value.test(task.item)) {
|
||||||
|
tasksFiltered.add(task)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
val changeIsAscending = booleanInput(allowSpectators = true) { tile?.getPlayerSettings(ply)?.ascending = it }
|
val changeIsAscending = booleanInput(allowSpectators = true) { tile?.getPlayerSettings(ply)?.ascending = it }
|
||||||
val changeSorting = PlayerInput(ItemSorter::class.codec(), allowSpectators = true) { tile?.getPlayerSettings(ply)?.sorter = it }
|
val changeSorting = PlayerInput(ItemSorter::class.codec(), allowSpectators = true) { tile?.getPlayerSettings(ply)?.sorter = it }
|
||||||
|
|
||||||
@ -183,8 +208,11 @@ class MatterPanelMenu @JvmOverloads constructor(
|
|||||||
private val actualComparator = Comparator<IPatternState> { o1, o2 -> sorting.comparator.compare(o1.item, o2.item) * (if (isAscending) 1 else -1) }
|
private val actualComparator = Comparator<IPatternState> { o1, o2 -> sorting.comparator.compare(o1.item, o2.item) * (if (isAscending) 1 else -1) }
|
||||||
private val actualTaskComparator = Comparator<IReplicationTask<*>> { o1, o2 -> sorting.comparator.compare(o1.item, o2.item) * (if (isAscending) 1 else -1) }
|
private val actualTaskComparator = Comparator<IReplicationTask<*>> { o1, o2 -> sorting.comparator.compare(o1.item, o2.item) * (if (isAscending) 1 else -1) }
|
||||||
|
|
||||||
val patterns = ArrayList<IPatternState>()
|
private val patterns = ArrayList<IPatternState>()
|
||||||
val tasks = ArrayList<IReplicationTask<*>>()
|
private val tasks = ArrayList<IReplicationTask<*>>()
|
||||||
|
|
||||||
|
val patternsFiltered = ArrayList<IPatternState>()
|
||||||
|
val tasksFiltered = ArrayList<IReplicationTask<*>>()
|
||||||
|
|
||||||
fun networkPatternsUpdated(patterns: Collection<IPatternState>) {
|
fun networkPatternsUpdated(patterns: Collection<IPatternState>) {
|
||||||
for (pattern in patterns) {
|
for (pattern in patterns) {
|
||||||
@ -195,6 +223,16 @@ class MatterPanelMenu @JvmOverloads constructor(
|
|||||||
} else {
|
} else {
|
||||||
this.patterns.addSorted(pattern, actualComparator)
|
this.patterns.addSorted(pattern, actualComparator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter.test(pattern.item)) {
|
||||||
|
val index = this.patternsFiltered.indexOfFirst(pattern::matchId)
|
||||||
|
|
||||||
|
if (index != -1) {
|
||||||
|
this.patternsFiltered[index] = pattern
|
||||||
|
} else {
|
||||||
|
this.patternsFiltered.addSorted(pattern, actualComparator)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,6 +251,16 @@ class MatterPanelMenu @JvmOverloads constructor(
|
|||||||
} else {
|
} else {
|
||||||
this.tasks.addSorted(task, actualTaskComparator)
|
this.tasks.addSorted(task, actualTaskComparator)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (filter.test(task.item)) {
|
||||||
|
val index = this.tasksFiltered.indexOfFirst(task::matchId)
|
||||||
|
|
||||||
|
if (index != -1) {
|
||||||
|
this.tasksFiltered[index] = task
|
||||||
|
} else {
|
||||||
|
this.tasksFiltered.addSorted(task, actualTaskComparator)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user