Package com.threerings.stage.tools.editor

Source Code of com.threerings.stage.tools.editor.EditorApp$EditorContextImpl

//
// $Id$
//
// Vilya library - tools for developing networked games
// Copyright (C) 2002-2012 Three Rings Design, Inc., All Rights Reserved
// http://code.google.com/p/vilya/
//
// This library is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License as published
// by the Free Software Foundation; either version 2.1 of the License, or
// (at your option) any later version.
//
// This library is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License along with this library; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA

package com.threerings.stage.tools.editor;

import java.util.List;
import java.util.logging.LogManager;

import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.PrintStream;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.DisplayMode;
import java.awt.EventQueue;
import java.awt.GraphicsDevice;
import java.awt.GraphicsEnvironment;

import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JPopupMenu;
import javax.swing.JProgressBar;

import com.samskivert.util.DebugChords;
import com.samskivert.util.StringUtil;

import com.samskivert.swing.RuntimeAdjust;
import com.samskivert.swing.util.SwingUtil;

import com.threerings.util.KeyDispatcher;
import com.threerings.util.KeyboardManager;
import com.threerings.util.MessageBundle;
import com.threerings.util.MessageManager;

import com.threerings.resource.ResourceManager;

import com.threerings.media.FrameManager;
import com.threerings.media.image.ColorPository;
import com.threerings.media.image.ImageManager;
import com.threerings.media.tile.TileSetRepository;
import com.threerings.media.tile.bundle.BundledTileSetRepository;
import com.threerings.media.util.ModeUtil;

import com.threerings.miso.tile.MisoTileManager;

import com.threerings.cast.ComponentRepository;
import com.threerings.cast.bundle.BundledComponentRepository;

import com.threerings.stage.data.StageSceneModel;
import com.threerings.stage.tools.editor.util.EditorContext;
import com.threerings.stage.tools.xml.StageSceneWriter;

import static com.threerings.stage.Log.log;

/**
* A scene editor application that provides facilities for viewing, editing, and saving the scene
* templates that comprise a game.
*/
public class EditorApp implements Runnable
{
    /**
     * Construct and initialize the EditorApp object.
     */
    public EditorApp (String[] args)
        throws IOException
    {
        final String target = (args.length > 0) ? args[0] : null;

        if (System.getProperty("no_log_redir") != null) {
            log.info("Logging to console only.");

        } else {
            String dlog = localDataDir("editor.log");
            try {
                PrintStream logOut = new PrintStream(
                    new BufferedOutputStream(new FileOutputStream(dlog)), true);
                System.setOut(logOut);
                System.setErr(logOut);
                // LogManager caches stderr, that's changed, so reconfigure.
                LogManager.getLogManager().readConfiguration();

                log.info("Opened debug log '" + dlog + "'.");

            } catch (IOException ioe) {
                log.warning("Failed to open debug log", "path", dlog, "error", ioe);
            }
        }

        // we need to use heavy-weight popup menus so that they can overly
        // our non-lightweight Miso view
        JPopupMenu.setDefaultLightWeightPopupEnabled(false);

        // create and size the main application frame
        _frame = createEditorFrame();

        // create our frame manager
        _framemgr = FrameManager.newInstance(_frame);

        // create our myriad managers, repositories, etc.
        _rmgr = new ResourceManager("rsrc");

        // build up a simple ui for displaying progress
        JPanel progressPanel = new JPanel(new BorderLayout());
        final JLabel progressLabel = new JLabel();
        final JProgressBar progress = new JProgressBar(0,100);
        final JPanel spacer = new JPanel();

        progressPanel.add(progressLabel, BorderLayout.CENTER);
        progressPanel.add(progress, BorderLayout.SOUTH);
        progressPanel.setPreferredSize(new Dimension(300,80));
        spacer.add(progressPanel);

        _frame.getContentPane().add(spacer);

        final EditorFrame frameRef = _frame;

        ResourceManager.InitObserver obs = new ResourceManager.InitObserver() {
            public void progress (int percent, long remaining) {
                String msg = "Unpacking...";
                if (remaining >= 0) {
                    msg += " " + remaining + " seconds remaining.";
                }
                progressLabel.setText(msg);
                progress.setValue(percent);

                if (percent >= 100) {
                    frameRef.getContentPane().remove(spacer);
                    EditorApp.this.finishInit(target);
                }
            }

            public void initializationFailed (Exception e) {
                log.warning("Failed unpacking bundles", "e", e, e);
            }
        };
        // we want our methods called on the AWT thread
        obs = new ResourceManager.AWTInitObserver(obs);
        _rmgr.initBundles(null, "config/resource/editor.properties", obs);
    }

    public void finishInit (String target)
    {
        _msgmgr = new MessageManager("rsrc.i18n");
        _imgr = new ImageManager(_rmgr, _frame);
        _tilemgr = new EditorTileManager(_rmgr, _imgr);

        try {
            _tsrepo = new BundledTileSetRepository(_rmgr, _imgr, "tilesets");
            _tilemgr.setTileSetRepository(_tsrepo);
            _crepo = new BundledComponentRepository(_rmgr, _imgr, "components");
        } catch (IOException e) {
            log.warning("Exception loading tilesets and and icon manager", "Exception", e);
            return;
        }

        _colpos = ColorPository.loadColorPository(_rmgr);
        _kbdmgr = new KeyboardManager();
        _keydisp = new KeyDispatcher(_frame);

        _ctx = new EditorContextImpl();

        // initialize the frame with the now-prepared context
        _frame.init(_ctx, target);

        // wire up our runtime adjustment editor
        DebugChords.activate();

        // if we have a target file, load it up
        if (target != null) {
            _frame.openScene(target);
        }
    }

    /**
     * Given a subdirectory name (that should correspond to the calling service), returns a file
     * path that can be used to store local data.
     */
    public static String localDataDir (String subdir)
    {
        String appdir = System.getProperty("appdir");
        if (StringUtil.isBlank(appdir)) {
            appdir = ".narya-editor";
            String home = System.getProperty("user.home");
            if (!StringUtil.isBlank(home)) {
                appdir = home + File.separator + appdir;
            }
        }
        return appdir + File.separator + subdir;
    }

    /**
     * Run the application.
     */
    public void run ()
    {
        // enter full-screen exclusive mode if available and if we have the right display mode
        GraphicsEnvironment env = GraphicsEnvironment.getLocalGraphicsEnvironment();
        GraphicsDevice gd = env.getDefaultScreenDevice();
        DisplayMode pmode = null;
        try {
            DisplayMode cmode = gd.getDisplayMode();
            pmode = ModeUtil.getDisplayMode(gd, cmode.getWidth(), cmode.getHeight(), 16, 15);
        } catch (Throwable t) {
            // Win98 seems to choke on its own vomit when we attempt to
            // enumerate the available display modes; yay!
            log.warning("Failed to probe display mode.", t);
        }

        if (_viewFullScreen.getValue() && gd.isFullScreenSupported() &&
            pmode != null) {
            log.info("Switching to screen mode", "mode", ModeUtil.toString(pmode));
            // set the frame to undecorated, full-screen
            _frame.setUndecorated(true);
            gd.setFullScreenWindow(_frame);
            // switch to our happy custom display mode
            gd.setDisplayMode(pmode);
            // lay the frame out properly (we can't do this before making
            // it full screen because packing causes the window to become
            // displayable which apparently prevents the window from
            // subsequently being made a full-screen window)
            _frame.pack();

        } else {
            _frame.setSize(1024, 768);
            SwingUtil.centerWindow(_frame);
            _frame.setVisible(true);
            SwingUtil.refresh((JComponent)_frame.getContentPane());
        }
        _framemgr.start();
    }

    protected EditorFrame createEditorFrame ()
    {
        return new EditorFrame(new StageSceneWriter());
    }

    /**
     * Derived classes can override this method and add additional scene types.
     */
    protected void enumerateSceneTypes (List<String> types)
    {
        types.add(StageSceneModel.WORLD);
    }

    /**
     * Instantiate the application object and start it running.
     */
    public static void main (String[] args)
    {
        try {
            EditorApp app = new EditorApp(args);
            // start up the UI on the AWT thread to avoid deadlocks
            EventQueue.invokeLater(app);

        } catch (IOException ioe) {
            log.warning("Unable to initialize editor.", ioe);
        }
    }

    /**
     * The implementation of the EditorContext interface that provides handles to the config and
     * manager objects that offer commonly used services.
     */
    protected class EditorContextImpl implements EditorContext
    {
        public MisoTileManager getTileManager () {
            return _tilemgr;
        }

        public FrameManager getFrameManager () {
            return _framemgr;
        }

        public ResourceManager getResourceManager () {
            return _rmgr;
        }

        public ImageManager getImageManager () {
            return _imgr;
        }

        public MessageManager getMessageManager () {
            return _msgmgr;
        }

        public KeyboardManager getKeyboardManager () {
            return _kbdmgr;
        }

        public ComponentRepository getComponentRepository () {
            return _crepo;
        }

        public KeyDispatcher getKeyDispatcher () {
            return _keydisp;
        }

        public String xlate (String message) {
            return xlate("stage.editor", message);
        }

        public String xlate (String bundle, String message) {
            MessageBundle mbundle = _msgmgr.getBundle(bundle);
            if (mbundle == null) {
                log.warning("Requested to translate message with non-existent bundle",
                    "bundle", bundle, "message", message);
                return message;
            } else {
                return mbundle.xlate(message);
            }
        }

        public TileSetRepository getTileSetRepository () {
            return _tsrepo;
        }

        public ColorPository getColorPository () {
            return _colpos;
        }

        public void enumerateSceneTypes (List<String> types) {
            EditorApp.this.enumerateSceneTypes(types);
        }
    }

    protected EditorContext _ctx;
    protected EditorFrame _frame;
    protected FrameManager _framemgr;

    protected ResourceManager _rmgr;
    protected ImageManager _imgr;
    protected MisoTileManager _tilemgr;
    protected TileSetRepository _tsrepo;
    protected ColorPository _colpos;
    protected MessageManager _msgmgr;
    protected KeyboardManager _kbdmgr;
    protected BundledComponentRepository _crepo;
    protected KeyDispatcher _keydisp;

    /** A debug hook that toggles debug rendering of traversable tiles. */
    protected static RuntimeAdjust.BooleanAdjust _viewFullScreen =
        new RuntimeAdjust.BooleanAdjust(
            "Toggles whether or not the scene editor uses full screen mode.",
            "stage.editor.full_screen", EditorConfig.config, false);
}
TOP

Related Classes of com.threerings.stage.tools.editor.EditorApp$EditorContextImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.