/****************************************************************************** * Copyright (C) 2014 Yevgeny Krasik * * * * Licensed under the Apache License, Version 2.0 (the "License"); * * you may not use this file except in compliance with the License. * * You may obtain a copy of the License at * * * * http://www.apache.org/licenses/LICENSE-2.0 * * * * Unless required by applicable law or agreed to in writing, software * * distributed under the License is distributed on an "AS IS" BASIS, * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * * See the License for the specific language governing permissions and * * limitations under the License. * ******************************************************************************/ package com.github.ykrasik.jaci.cli.libgdx.output; import com.badlogic.gdx.graphics.Color; import com.badlogic.gdx.scenes.scene2d.ui.Label; import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle; import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane; import com.badlogic.gdx.scenes.scene2d.ui.Skin; import com.badlogic.gdx.scenes.scene2d.ui.Table; import java.util.LinkedList; import java.util.Objects; import java.util.Queue; /** * A LibGdx implementation of a 'terminal screen'. * Implemented as a {@link Table} of {@link Label}, each Label representing a single line. * Keeps a maximum amount of lines. * * @author Yevgeny Krasik */ public class LibGdxCliOutputBuffer extends Table { private final Skin skin; private final int maxBufferEntries; private int numBufferEntries; // To avoid calling size() on a LinkedList, which is O(n). private final Table buffer; private final ScrollPane scrollPane; private final Queue<Label> bufferEntries; /** * @param skin Skin to use for the lines. * Must contain a {@link LabelStyle} called 'outputEntry' that will be used to style the lines. * @param maxBufferEntries Maximum amount of lines to store. */ public LibGdxCliOutputBuffer(Skin skin, int maxBufferEntries) { this.skin = Objects.requireNonNull(skin, "skin"); this.maxBufferEntries = maxBufferEntries; // Create a buffer to hold out text labels. this.buffer = new Table(); buffer.setName("outputBuffer"); buffer.bottom().left(); // Wrap the buffer in a scrollpane. scrollPane = new ScrollPane(buffer); scrollPane.setName("outputBufferScrollPane"); scrollPane.setScrollingDisabled(true, false); scrollPane.setupOverscroll(0, 0, 0); scrollPane.setFillParent(true); updateScroll(); // Buffer history. this.bufferEntries = new LinkedList<>(); add(scrollPane); } /** * Add a single line to this buffer. * The line may contain a '\n' character, and it will be honored, but this is discouraged. * * @param text Line text. * @param color Line color. */ public void println(String text, Color color) { final Label label = new Label(text, skin, "outputEntry"); label.setColor(color); label.setWrap(true); addLabel(label); } private void addLabel(Label newEntry) { if (numBufferEntries == maxBufferEntries) { final Label lastEntry = bufferEntries.poll(); buffer.removeActor(lastEntry); numBufferEntries--; } bufferEntries.add(newEntry); numBufferEntries++; buffer.add(newEntry).left().row(); updateScroll(); } private void updateScroll() { // Set the scroll to the bottom of the pane. scrollPane.layout(); scrollPane.setScrollPercentY(1); scrollPane.updateVisualScroll(); } }