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) {
|
||||
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.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")
|
||||
|
@ -594,6 +594,8 @@ private fun androidFeatures(provider: MatteryLanguageProvider) {
|
||||
|
||||
private fun gui(provider: MatteryLanguageProvider) {
|
||||
with(provider.russian) {
|
||||
gui("quicksearch", "Быстрый поиск...")
|
||||
|
||||
gui("item_monitor.refill_source.desc", "Контролирует источник предметов для заполнения сетки создания")
|
||||
gui("item_monitor.refill_source.system", "Только система. Сетка создания будет заполняться только из системы предметов. Данный параметр соответствует поведению AE2 и Refined Storage")
|
||||
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.network.MenuNetworkChannel
|
||||
import yalter.mousetweaks.api.MouseTweaksDisableWheelTweak
|
||||
import java.util.function.Predicate
|
||||
import kotlin.math.roundToInt
|
||||
|
||||
@MouseTweaksDisableWheelTweak
|
||||
@ -45,7 +46,8 @@ class MatterPanelScreen(
|
||||
var scrollPatterns = 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)
|
||||
|
||||
@ -69,9 +71,9 @@ class MatterPanelScreen(
|
||||
|
||||
val scrollBar = DiscreteScrollBarPanel(this, frame, {
|
||||
if (isPatternView) {
|
||||
integerDivisionDown(menu.patterns.size, GRID_WIDTH)
|
||||
integerDivisionDown(menu.patternsFiltered.size, GRID_WIDTH)
|
||||
} else {
|
||||
integerDivisionDown(menu.tasks.size, GRID_WIDTH)
|
||||
integerDivisionDown(menu.tasksFiltered.size, GRID_WIDTH)
|
||||
}
|
||||
}, { _, _, new ->
|
||||
if (isPatternView)
|
||||
@ -80,6 +82,25 @@ class MatterPanelScreen(
|
||||
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
|
||||
|
||||
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() {
|
||||
if (isPatternView) {
|
||||
return menu.patterns.getOrNull(index)?.stack() ?: ItemStack.EMPTY
|
||||
return menu.patternsFiltered.getOrNull(index)?.stack() ?: ItemStack.EMPTY
|
||||
} 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()
|
||||
|
||||
if (isPatternView) {
|
||||
menu.patterns.getOrNull(index)?.let {
|
||||
menu.patternsFiltered.getOrNull(index)?.let {
|
||||
list.add(TranslatableComponent(
|
||||
"otm.item.pattern.research",
|
||||
String.format("%.2f", it.researchPercent * 100.0)
|
||||
).withStyle(ChatFormatting.AQUA)) }
|
||||
} 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.required", it.required).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 {
|
||||
if (isPatternView) {
|
||||
if (minecraft?.player?.isSpectator != true)
|
||||
menu.patterns.getOrNull(index)?.let(this@MatterPanelScreen::openPattern)
|
||||
menu.patternsFiltered.getOrNull(index)?.let(this@MatterPanelScreen::openPattern)
|
||||
} else {
|
||||
menu.tasks.getOrNull(index)?.let(this@MatterPanelScreen::openTask)
|
||||
menu.tasksFiltered.getOrNull(index)?.let(this@MatterPanelScreen::openTask)
|
||||
}
|
||||
|
||||
return true
|
||||
@ -180,13 +201,13 @@ class MatterPanelScreen(
|
||||
}
|
||||
|
||||
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() {
|
||||
super.tickInner()
|
||||
|
||||
if (!menu.tasks.any { it.id == task.id }) {
|
||||
if (!menu.tasksFiltered.any { it.id == task.id }) {
|
||||
frame.remove()
|
||||
}
|
||||
}
|
||||
@ -254,7 +275,7 @@ class MatterPanelScreen(
|
||||
override fun tickInner() {
|
||||
super.tickInner()
|
||||
|
||||
if (!menu.patterns.any { it.id == pattern.id }) {
|
||||
if (!menu.patternsFiltered.any { it.id == pattern.id }) {
|
||||
frame.remove()
|
||||
}
|
||||
}
|
||||
|
@ -12,6 +12,7 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectAVLTreeMap
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap
|
||||
import net.minecraft.client.gui.screens.Screen
|
||||
import net.minecraft.client.renderer.GameRenderer
|
||||
import net.minecraft.network.chat.Component
|
||||
import org.joml.Vector2i
|
||||
import ru.dbotthepony.mc.otm.client.isCtrlDown
|
||||
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.screen.panels.DockProperty
|
||||
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.math.RGBAColor
|
||||
import ru.dbotthepony.mc.otm.milliTime
|
||||
@ -141,7 +143,9 @@ open class TextInputPanel<out S : Screen>(
|
||||
|
||||
var cursorLine = 0
|
||||
var cursorRow = 0
|
||||
open var placeholder: Component = TextComponent("")
|
||||
open var textColor = RGBAColor.WHITE
|
||||
open var placeholderColor = RGBAColor.DARK_GRAY
|
||||
open var cursorColor = RGBAColor.GREEN
|
||||
open var backgroundColor = RGBAColor.BLACK
|
||||
open var isActive = true
|
||||
@ -1085,6 +1089,18 @@ open class TextInputPanel<out S : Screen>(
|
||||
|
||||
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) {
|
||||
val line = lines[i]
|
||||
val selection = selections[i]
|
||||
|
@ -109,7 +109,7 @@ open class DiscreteScrollBarPanel<out S : Screen>(
|
||||
|
||||
var scroll = 0
|
||||
set(value) {
|
||||
val newValue = value.coerceAtLeast(0).coerceAtMost(maxScroll.invoke(this))
|
||||
val newValue = value.coerceIn(0, maxScroll.invoke(this))
|
||||
|
||||
if (newValue != field) {
|
||||
val old = field
|
||||
|
@ -4,6 +4,7 @@ import net.minecraft.network.FriendlyByteBuf
|
||||
import net.minecraft.server.level.ServerPlayer
|
||||
import net.minecraft.world.entity.player.Inventory
|
||||
import net.minecraft.world.entity.player.Player
|
||||
import net.minecraft.world.item.Item
|
||||
import net.minecraftforge.network.NetworkEvent
|
||||
import net.minecraftforge.network.PacketDistributor
|
||||
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.registry.MMenus
|
||||
import java.util.*
|
||||
import java.util.function.Predicate
|
||||
import java.util.function.Supplier
|
||||
import kotlin.Comparator
|
||||
import kotlin.collections.ArrayList
|
||||
@ -158,7 +160,9 @@ class MatterPanelMenu @JvmOverloads constructor(
|
||||
codec = ItemSorter::class.codec(),
|
||||
observer = {
|
||||
patterns.sortWith(actualComparator)
|
||||
patternsFiltered.sortWith(actualComparator)
|
||||
tasks.sortWith(actualTaskComparator)
|
||||
tasksFiltered.sortWith(actualTaskComparator)
|
||||
})
|
||||
|
||||
val isAscending: Boolean by mSynchronizer.ComputedField(
|
||||
@ -166,7 +170,9 @@ class MatterPanelMenu @JvmOverloads constructor(
|
||||
codec = BooleanValueCodec,
|
||||
observer = {
|
||||
patterns.sortWith(actualComparator)
|
||||
patternsFiltered.sortWith(actualComparator)
|
||||
tasks.sortWith(actualTaskComparator)
|
||||
tasksFiltered.sortWith(actualTaskComparator)
|
||||
})
|
||||
|
||||
val totalMatterStored: Decimal by mSynchronizer.ComputedField(
|
||||
@ -174,6 +180,25 @@ class MatterPanelMenu @JvmOverloads constructor(
|
||||
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 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 actualTaskComparator = Comparator<IReplicationTask<*>> { o1, o2 -> sorting.comparator.compare(o1.item, o2.item) * (if (isAscending) 1 else -1) }
|
||||
|
||||
val patterns = ArrayList<IPatternState>()
|
||||
val tasks = ArrayList<IReplicationTask<*>>()
|
||||
private val patterns = ArrayList<IPatternState>()
|
||||
private val tasks = ArrayList<IReplicationTask<*>>()
|
||||
|
||||
val patternsFiltered = ArrayList<IPatternState>()
|
||||
val tasksFiltered = ArrayList<IReplicationTask<*>>()
|
||||
|
||||
fun networkPatternsUpdated(patterns: Collection<IPatternState>) {
|
||||
for (pattern in patterns) {
|
||||
@ -195,6 +223,16 @@ class MatterPanelMenu @JvmOverloads constructor(
|
||||
} else {
|
||||
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 {
|
||||
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