/*
* Copyright 2016 MovingBlocks
*
* 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 org.terasology.logic.console.ui;
import com.google.common.collect.Iterables;
import org.codehaus.plexus.util.StringUtils;
import org.terasology.logic.console.Console;
import org.terasology.logic.console.CoreMessageType;
import org.terasology.logic.console.Message;
import org.terasology.registry.In;
import org.terasology.rendering.nui.Canvas;
import org.terasology.rendering.nui.CoreScreenLayer;
import org.terasology.rendering.nui.databinding.ReadOnlyBinding;
import org.terasology.rendering.nui.widgets.UILabel;
/**
* The miniaturized chat console widget.
*/
public class MiniChatOverlay extends CoreScreenLayer {
/**
* Extra display time per message char.
*/
private static final float TIME_VISIBLE_PER_CHAR = 0.08f;
private static final float TIME_VISIBLE_BASE = 5.0f;
private static final float TIME_FADE = 0.3f;
private static final int MAX_MESSAGES = 6;
private static final int MAX_CHAR_PER_MSG = 250;
private enum State {
FADE_IN,
VISIBLE,
FADE_OUT,
HIDDEN
}
private float time;
private UILabel message;
private State state = State.HIDDEN;
@In
private Console console;
@Override
public void initialise() {
message = find("message", UILabel.class);
message.bindText(new ReadOnlyBinding<String>() {
@Override
public String get() {
Iterable<Message> msgs = console.getMessages(CoreMessageType.CHAT, CoreMessageType.NOTIFICATION);
StringBuilder messageHistory = new StringBuilder();
int count = 1;
int size = Iterables.size(msgs);
for (Message msg : msgs) {
if (count > size - MAX_MESSAGES) {
messageHistory.append(StringUtils.abbreviate(msg.getMessage(), MAX_CHAR_PER_MSG));
if (count < size) {
messageHistory.append(Console.NEW_LINE);
}
}
count++;
}
return messageHistory.toString();
}
});
}
@Override
public void setVisible(boolean visible) {
super.setVisible(visible);
if (isVisible()) { // depends on the "visible" binding
refresh();
} else {
hideImmediately();
}
}
private void refresh() {
switch (state) {
case VISIBLE:
time = 0;
break;
case FADE_IN:
break;
case FADE_OUT:
state = State.FADE_IN;
time = TIME_FADE - time;
break;
case HIDDEN:
time = 0;
state = State.FADE_IN;
break;
}
}
private void hideImmediately() {
state = State.HIDDEN;
time = 0;
}
@Override
public void onDraw(Canvas canvas) {
switch (state) {
case FADE_IN:
canvas.setAlpha(time / TIME_FADE);
break;
case FADE_OUT:
canvas.setAlpha(1.0f - time / TIME_FADE);
break;
case HIDDEN:
return; // don't draw anything
case VISIBLE:
break;
}
super.onDraw(canvas);
}
@Override
public void update(float delta) {
super.update(delta);
time += delta;
switch (state) {
case FADE_IN:
if (time > TIME_FADE) {
time = 0;
state = State.VISIBLE;
}
break;
case FADE_OUT:
if (time > TIME_FADE) {
time = 0;
state = State.HIDDEN;
}
break;
case HIDDEN:
break;
case VISIBLE:
int textLen = message.getText().length();
float maxTime = TIME_VISIBLE_BASE + textLen * TIME_VISIBLE_PER_CHAR;
// longer text messages are shown for longer periods of time
if (time > maxTime) {
time = 0;
state = State.FADE_OUT;
}
break;
}
}
@Override
public boolean canBeFocus() {
return false;
}
@Override
protected boolean isEscapeToCloseAllowed() {
return false;
}
@Override
public boolean isModal() {
return false;
}
}