/* * Copyright 2010, Maarten Billemont * * 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.lyndir.lanterna.view; import com.googlecode.lanterna.TerminalFacade; import com.googlecode.lanterna.input.Key; import com.googlecode.lanterna.screen.Screen; /** * @author lhunath, 2013-07-25 */ public class Window { private final View rootView; private boolean running; private boolean ready; public Window(final View rootView) { this.rootView = rootView; } public final void start() { new Thread( new Runnable() { @Override public void run() { loop(); } } ).start(); } private void loop() { // Initialize Screen screen = TerminalFacade.createScreen( TerminalFacade.createTextTerminal() ); try { onStartup( screen ); setRunning( true ); while (isRunning()) { // Measure getRootView().measure( screen, new Box( 0, screen.getTerminalSize().getColumns(), screen.getTerminalSize().getRows(), 0 ) ); if (!isReady()) fireReady(); // Draw getRootView().draw( screen ); screen.refresh(); // Input for (Key key; (key = screen.readInput()) != null; ) getRootView().handleKey( key ); } } finally { setRunning( false ); onShutdown( screen ); } } private void fireReady() { fireReadyView( getRootView() ); onReady(); } private static void fireReadyView(final View view) { for (final View child : view.getChildren()) { child.onReady(); fireReadyView( child ); } } /** * The view hierarchy has been fully measured for the first time and all views have been notified. */ protected void onReady() { setReady( true ); } protected void onStartup(final Screen screen) { // Start screen and resize to terminal size. screen.startScreen(); while (screen.readInput() != null) ; screen.refresh(); } protected void onShutdown(final Screen screen) { screen.stopScreen(); } protected synchronized boolean isRunning() { return running; } private synchronized void setRunning(final boolean running) { this.running = running; } public synchronized boolean isReady() { return ready; } public synchronized void setReady(final boolean ready) { this.ready = ready; } public View getRootView() { return rootView; } }