package net.torvald.terrarum.modulebasegame.ui import com.badlogic.gdx.graphics.Camera import com.badlogic.gdx.graphics.Color import com.badlogic.gdx.graphics.OrthographicCamera import com.badlogic.gdx.graphics.g2d.SpriteBatch import com.badlogic.gdx.utils.Queue import net.torvald.terrarum.App import net.torvald.terrarum.App.printdbg import net.torvald.terrarum.Second import net.torvald.terrarum.blendNormalStraightAlpha import net.torvald.terrarum.ui.Toolkit import net.torvald.terrarum.ui.UICanvas import kotlin.math.max /** * This UI must be always updated; the easiest way is to set `handler.alwaysUpdate` to `true` * * Created by minjaesong on 2016-01-23. */ class Notification : UICanvas() { private var fontCol: Color = Color.WHITE // assuming alpha of 1.0 override var openCloseTime: Second = OPEN_CLOSE_TIME private val LRmargin = 0f // there's "base value" of 8 px for LR (width of segment tile) private val SHOWUP_MAX = 6500 override var width: Int = 500 override var height: Int = 0 private val visibleTime = Math.min( App.getConfigInt("notificationshowuptime"), SHOWUP_MAX ) / 1000f private var displayTimer = 0f internal val messageQueue = Queue>() private var messageDisplaying: List? = null private val timeGaugeCol = Color(0x707070ff) init { handler.alwaysUpdate = true } override fun updateImpl(delta: Float) { if (messageDisplaying == null && messageQueue.notEmpty() && handler.isClosed) { messageDisplaying = messageQueue.removeFirst() displayTimer = 0f handler.openCloseCounter = 0f handler.opacity = 0f handler.setAsOpen() } if (handler.isOpened) displayTimer += delta if (displayTimer >= visibleTime) { handler.setAsClose() displayTimer = 0f messageDisplaying = null } } override fun renderImpl(frameDelta: Float, batch: SpriteBatch, camera: OrthographicCamera) { blendNormalStraightAlpha(batch) fontCol.a = handler.opacity * OPACITY if (messageDisplaying != null) { val realTextWidth = 12 + if (messageDisplaying!!.size == 1) App.fontGame.getWidth(messageDisplaying!![0]) else messageDisplaying!!.map { App.fontGame.getWidth(it) }.sorted().last() val displayedTextWidth = max(240, realTextWidth) // force the UI to the centre of the screen this.posX = (App.scr.width - displayedTextWidth) / 2 val textHeight = messageDisplaying!!.size * App.fontGame.lineHeight Toolkit.drawBaloon( batch, 0f, -textHeight, displayedTextWidth.toFloat(), textHeight, handler.opacity * OPACITY ) // draw time gauge if (displayTimer != 0f) { batch.color = timeGaugeCol val time = 1f - (displayTimer / visibleTime) val bw = displayedTextWidth * time val bx = (displayedTextWidth - bw) / 2 Toolkit.drawStraightLine(batch, bx, 2f, bx + bw, 2f, false) } // draw texts batch.color = fontCol messageDisplaying!!.forEachIndexed { index, s -> val xoff = 6 + (displayedTextWidth - realTextWidth) / 2 val y = -textHeight + App.fontGame.lineHeight * index App.fontGame.draw(batch, s, LRmargin + xoff, y - 1) } } // dunno why, it doesn't work without this. fontCol.a = 1f } override fun doOpening(delta: Float) { doOpeningFade(this, openCloseTime) } override fun doClosing(delta: Float) { doClosingFade(this, openCloseTime) } override fun endOpening(delta: Float) { endOpeningFade(this) } override fun endClosing(delta: Float) { endClosingFade(this) } fun sendNotification(message: List) { messageQueue.addLast(message) } override fun dispose() { } companion object { // private int messagesShowingIndex = 0; const val OPEN_CLOSE_TIME = 0.16f const val OPACITY = 0.9f } }