com.ray3k.skincomposer.dialog.DialogFonts.java Source code

Java tutorial

Introduction

Here is the source code for com.ray3k.skincomposer.dialog.DialogFonts.java

Source

/*******************************************************************************
 * MIT License
 * 
 * Copyright (c) 2017 Raymond Buckley
 * 
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 * 
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 * 
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 ******************************************************************************/
package com.ray3k.skincomposer.dialog;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Input.Keys;
import com.badlogic.gdx.files.FileHandle;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.Cursor;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.BitmapFont.BitmapFontData;
import com.badlogic.gdx.graphics.g2d.TextureAtlas;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Actor;
import com.badlogic.gdx.scenes.scene2d.EventListener;
import com.badlogic.gdx.scenes.scene2d.InputEvent;
import com.badlogic.gdx.scenes.scene2d.InputListener;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.Touchable;
import com.badlogic.gdx.scenes.scene2d.ui.Button;
import com.badlogic.gdx.scenes.scene2d.ui.Dialog;
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.SelectBox;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton;
import com.badlogic.gdx.scenes.scene2d.ui.TextField;
import com.badlogic.gdx.scenes.scene2d.utils.ChangeListener;
import com.badlogic.gdx.utils.Align;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.ObjectMap;
import com.badlogic.gdx.utils.Sort;
import com.ray3k.skincomposer.FilesDroppedListener;
import com.ray3k.skincomposer.Main;
import com.ray3k.skincomposer.UndoableManager.FontUndoable;
import com.ray3k.skincomposer.data.AtlasData;
import com.ray3k.skincomposer.data.ColorData;
import com.ray3k.skincomposer.data.DrawableData;
import com.ray3k.skincomposer.data.FontData;
import com.ray3k.skincomposer.data.JsonData;
import com.ray3k.skincomposer.data.ProjectData;
import com.ray3k.skincomposer.data.StyleData;
import com.ray3k.skincomposer.data.StyleProperty;
import com.ray3k.skincomposer.utils.Utils;
import java.io.File;
import java.util.Iterator;
import java.util.List;

public class DialogFonts extends Dialog {

    private Skin skin;
    private StyleProperty styleProperty;
    private Array<FontData> fonts;
    private Array<DrawableData> drawables;
    private Table fontsTable;
    private SelectBox<String> selectBox;
    private ObjectMap<FontData, BitmapFont> fontMap;
    private TextureAtlas atlas;
    private EventListener listener;
    private FilesDroppedListener filesDroppedListener;
    private ScrollPane scrollPane;
    private JsonData jsonData;
    private ProjectData projectData;
    private AtlasData atlasData;
    private Main main;

    public DialogFonts(Skin skin, StyleProperty styleProperty, JsonData jsonData, ProjectData projectData,
            AtlasData atlasData, Main main, EventListener listener) {
        this(skin, "default", styleProperty, jsonData, projectData, atlasData, main, listener);
    }

    public DialogFonts(final Skin skin, String styleName, StyleProperty styleProperty, JsonData jsonData,
            ProjectData projectData, AtlasData atlasData, Main main, EventListener listener) {
        super("", skin, styleName);

        this.jsonData = jsonData;
        this.projectData = projectData;
        this.atlasData = atlasData;
        this.main = main;

        this.listener = listener;
        this.skin = skin;
        this.styleProperty = styleProperty;
        fonts = jsonData.getFonts();
        drawables = atlasData.getDrawables();

        fontMap = new ObjectMap<>();
        produceAtlas();

        filesDroppedListener = (Array<FileHandle> files) -> {
            Iterator<FileHandle> iter = files.iterator();
            while (iter.hasNext()) {
                FileHandle file = iter.next();
                if (file.isDirectory() || !file.name().toLowerCase().endsWith(".fnt")) {
                    iter.remove();
                }
            }

            if (files.size > 0) {
                fontNameDialog(files, 0);
            }
        };

        main.getDesktopWorker().addFilesDroppedListener(filesDroppedListener);

        setFillParent(true);

        if (styleProperty != null) {
            getContentTable().add(new Label("Select a Font...", skin, "title"));
            getContentTable().row();
        } else {
            getContentTable().add(new Label("Fonts", skin, "title"));
            getContentTable().row();
        }

        Table table = new Table();
        table.defaults().pad(2.0f);

        table.add(new Label("Sort by: ", skin)).padLeft(20.0f);
        selectBox = new SelectBox<>(skin);
        selectBox.setItems(new String[] { "A-Z", "Z-A", "Oldest", "Newest" });
        selectBox.addListener(new ChangeListener() {
            @Override
            public void changed(ChangeListener.ChangeEvent event, Actor actor) {
                sortBySelectedMode();
            }
        });
        selectBox.addListener(main.getHandListener());
        table.add(selectBox);

        TextButton imageButton = new TextButton("New Font", skin, "new");
        imageButton.addListener(new ChangeListener() {
            @Override
            public void changed(ChangeListener.ChangeEvent event, Actor actor) {
                Gdx.graphics.setSystemCursor(Cursor.SystemCursor.Arrow);
                newFontDialog();
            }
        });
        imageButton.addListener(main.getHandListener());
        table.add(imageButton).expandX();
        getContentTable().add(table).expandX().left();
        getContentTable().row();

        key(Keys.ESCAPE, false);
        if (styleProperty != null) {
            button("Clear Font", true);
            button("Cancel", false);
            getButtonTable().getCells().first().getActor().addListener(main.getHandListener());
            getButtonTable().getCells().get(1).getActor().addListener(main.getHandListener());
        } else {
            button("Close", false);
            getButtonTable().getCells().first().getActor().addListener(main.getHandListener());
        }

        getButtonTable().padBottom(15.0f);

        fontsTable = new Table();

        table = new Table();
        table.add(fontsTable).pad(5.0f);
        scrollPane = new ScrollPane(table, skin);
        scrollPane.setFadeScrollBars(false);
        getContentTable().add(scrollPane).grow();
    }

    @Override
    public Dialog show(Stage stage) {
        Dialog dialog = super.show(stage);
        stage.setScrollFocus(scrollPane);
        return dialog;
    }

    private boolean addFont(String name, FileHandle file) {
        if (FontData.validate(name)) {
            try {
                projectData.setChangesSaved(false);
                FontData font = new FontData(name, file);

                //remove any existing FontData that shares the same name.
                if (fonts.contains(font, false)) {
                    FontData deleteFont = fonts.get(fonts.indexOf(font, false));

                    BitmapFontData deleteFontData = new BitmapFontData(deleteFont.file, false);
                    for (String path : deleteFontData.imagePaths) {
                        FileHandle imagefile = new FileHandle(path);
                        drawables.removeValue(new DrawableData(imagefile), false);
                    }

                    fonts.removeValue(font, false);
                }

                BitmapFontData bitmapFontData = new BitmapFontData(file, false);
                for (String path : bitmapFontData.imagePaths) {
                    DrawableData drawable = new DrawableData(new FileHandle(path));
                    drawable.visible = false;
                    if (!drawables.contains(drawable, false)) {
                        atlasData.atlasCurrent = false;
                        drawables.add(drawable);
                    }
                }
                produceAtlas();
                fonts.add(font);

                Array<TextureRegion> regions = new Array<>();
                for (String path : bitmapFontData.imagePaths) {
                    FileHandle imageFile = new FileHandle(path);
                    regions.add(atlas.findRegion(imageFile.nameWithoutExtension()));
                }
                fontMap.put(font, new BitmapFont(bitmapFontData, regions, true));

                sortBySelectedMode();
                populate();
            } catch (Exception e) {
                Gdx.app.error(getClass().getName(), "Error creating font from file", e);
                main.getDialogFactory().showDialogError("Font Error...",
                        "Error creating font from file. Check file paths.\n\nOpen log?");
            }
            return true;
        } else {
            return false;
        }
    }

    public void populate() {
        fontsTable.clear();
        fontsTable.defaults().growX().pad(5.0f);

        if (fonts.size == 0) {
            fontsTable.add(new Label("No fonts have been set!", skin));
        } else {
            for (FontData font : fonts) {
                Button button = new Button(skin, "color-base");
                Label label = new Label(font.getName(), skin);
                label.setTouchable(Touchable.disabled);
                button.add(label).left();
                button.addListener(main.getHandListener());

                Button renameButton = new Button(skin, "settings-small");
                renameButton.addListener(new ChangeListener() {
                    @Override
                    public void changed(ChangeListener.ChangeEvent event, Actor actor) {
                        renameDialog(font);

                        event.setBubbles(false);
                    }
                });
                renameButton.addListener(new InputListener() {
                    @Override
                    public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
                        event.setBubbles(false);
                        return true;
                    }

                });
                button.add(renameButton).padLeft(15.0f);
                LabelStyle style = new LabelStyle();
                style.font = fontMap.get(font);
                style.fontColor = Color.WHITE;
                label = new Label("Lorem Ipsum", style);
                label.setAlignment(Align.center);
                label.setTouchable(Touchable.disabled);
                Table bg = new Table(skin);
                bg.setBackground("white");
                BitmapFontData bf = new BitmapFontData(font.file, false);
                if (bf.imagePaths.length > 0) {
                    FileHandle file = new FileHandle(bf.imagePaths[0]);
                    if (!file.exists()) {
                        file = bf.fontFile.sibling(bf.fontFile.nameWithoutExtension() + ".png");
                    }
                    if (Utils.brightness(Utils.averageEdgeColor(file)) < .5f) {
                        bg.setColor(Color.WHITE);
                    } else {
                        bg.setColor(Color.BLACK);
                    }
                }
                bg.add(label).pad(5.0f).grow();
                button.add(bg).padLeft(15).growX();

                Button closeButton = new Button(skin, "delete-small");
                final FontData deleteFont = font;
                closeButton.addListener(new ChangeListener() {
                    @Override
                    public void changed(ChangeListener.ChangeEvent event, Actor actor) {
                        fonts.removeValue(deleteFont, true);
                        BitmapFontData bitmapFontData = new BitmapFontData(deleteFont.file, false);
                        for (String path : bitmapFontData.imagePaths) {
                            FileHandle imagefile = new FileHandle(path);
                            drawables.removeValue(new DrawableData(imagefile), false);
                        }

                        for (Array<StyleData> datas : jsonData.getClassStyleMap().values()) {
                            for (StyleData data : datas) {
                                for (StyleProperty property : data.properties.values()) {
                                    if (property != null && property.type.equals(BitmapFont.class)
                                            && property.value != null
                                            && property.value.equals(deleteFont.getName())) {
                                        property.value = null;
                                    }
                                }
                            }
                        }

                        main.getUndoableManager().clearUndoables();

                        main.getRootTable().refreshStyleProperties(true);
                        main.getRootTable().refreshPreview();

                        event.setBubbles(false);
                        populate();
                    }
                });
                closeButton.addListener(new InputListener() {
                    @Override
                    public boolean touchDown(InputEvent event, float x, float y, int pointer, int button) {
                        event.setBubbles(false);
                        return true;
                    }

                });
                button.add(closeButton).padLeft(5.0f).right();

                if (styleProperty == null) {
                    button.setTouchable(Touchable.childrenOnly);
                } else {
                    final FontData fontResult = font;
                    button.addListener(new ChangeListener() {
                        @Override
                        public void changed(ChangeListener.ChangeEvent event, Actor actor) {
                            result(fontResult);
                            hide();
                        }
                    });
                }

                fontsTable.add(button);
                fontsTable.row();
            }
        }
    }

    private void renameDialog(FontData font) {
        TextField textField = new TextField("", skin);
        TextButton okButton;

        Dialog dialog = new Dialog("Rename Font?", skin, "bg") {
            @Override
            protected void result(Object object) {
                if ((boolean) object) {
                    renameFont(font, textField.getText());
                }
            }

            @Override
            public Dialog show(Stage stage) {
                Dialog dialog = super.show(stage);
                main.getStage().setKeyboardFocus(textField);
                return dialog;
            }
        };
        dialog.getContentTable().padLeft(10.0f).padRight(10.0f);

        dialog.getTitleTable().padLeft(5.0f);

        Table bg = new Table(skin);
        bg.setBackground("white");
        bg.setColor(Color.WHITE);
        dialog.getContentTable().add(bg);

        Label label = new Label(font.getName(), skin, "white");
        label.setColor(Color.BLACK);
        bg.add(label).pad(10);

        dialog.getContentTable().row();
        label = new Label("What do you want to rename the font to?", skin);
        dialog.getContentTable().add(label);

        dialog.getContentTable().row();
        textField.setText(font.getName());
        textField.selectAll();
        textField.addListener(main.getIbeamListener());
        dialog.getContentTable().add(textField);

        dialog.button("OK", true);
        dialog.button("Cancel", false).key(Keys.ESCAPE, false);
        okButton = (TextButton) dialog.getButtonTable().getCells().first().getActor();
        okButton.setDisabled(true);
        okButton.addListener(main.getHandListener());
        dialog.getButtonTable().getCells().get(1).getActor().addListener(main.getHandListener());

        dialog.getButtonTable().padBottom(15.0f);

        textField.addListener(new ChangeListener() {
            @Override
            public void changed(ChangeListener.ChangeEvent event, Actor actor) {
                boolean disable = !FontData.validate(textField.getText());
                if (!disable) {
                    for (ColorData data : jsonData.getColors()) {
                        if (data.getName().equals(textField.getText())) {
                            disable = true;
                            break;
                        }
                    }
                }
                okButton.setDisabled(disable);
            }
        });
        textField.setTextFieldListener(new TextField.TextFieldListener() {
            @Override
            public void keyTyped(TextField textField, char c) {
                if (c == '\n') {
                    if (!okButton.isDisabled()) {
                        renameFont(font, textField.getText());
                        dialog.hide();
                    }
                }
            }
        });

        textField.setFocusTraversal(false);

        dialog.show(getStage());
    }

    private void renameFont(FontData font, String newName) {
        for (Array<StyleData> datas : jsonData.getClassStyleMap().values()) {
            for (StyleData data : datas) {
                for (StyleProperty property : data.properties.values()) {
                    if (property != null && property.type.equals(BitmapFont.class) && property.value != null
                            && property.value.equals(font.getName())) {
                        property.value = newName;
                    }
                }
            }
        }

        try {
            font.setName(newName);
        } catch (FontData.NameFormatException ex) {
            Gdx.app.error(getClass().getName(), "Error trying to rename a font.", ex);
            main.getDialogFactory().showDialogError("Rename Font Error...",
                    "Error trying to rename a font.\n\nOpen log?");
        }

        main.getUndoableManager().clearUndoables();

        main.getRootTable().refreshStyleProperties(true);
        main.getRootTable().refreshPreview();

        projectData.setChangesSaved(false);

        populate();
    }

    @Override
    protected void result(Object object) {
        if (styleProperty != null) {
            if (object instanceof FontData) {
                projectData.setChangesSaved(false);
                FontData font = (FontData) object;
                FontUndoable undoable = new FontUndoable(main.getRootTable(), jsonData, styleProperty,
                        styleProperty.value, font.getName());
                main.getUndoableManager().addUndoable(undoable, true);
            } else if (object instanceof Boolean) {
                if ((boolean) object) {
                    styleProperty.value = null;
                    projectData.setChangesSaved(false);
                    main.getRootTable().setStatusBarMessage("Drawable emptied for \"" + styleProperty.name + "\"");
                    main.getRootTable().refreshStyleProperties(true);
                } else {
                    boolean hasFont = false;
                    for (FontData font : jsonData.getFonts()) {
                        if (font.getName().equals(styleProperty.value)) {
                            hasFont = true;
                            break;
                        }
                    }

                    if (!hasFont) {
                        styleProperty.value = null;
                        projectData.setChangesSaved(false);
                        main.getRootTable()
                                .setStatusBarMessage("Drawable deleted for \"" + styleProperty.name + "\"");
                        main.getRootTable().refreshStyleProperties(true);
                    }
                }
            }
        }

        if (listener != null) {
            listener.handle(null);
        }
    }

    private void sortBySelectedMode() {
        switch (selectBox.getSelectedIndex()) {
        case 0:
            sortFontsAZ();
            break;
        case 1:
            sortFontsZA();
            break;
        case 2:
            sortFontsOldest();
            break;
        case 3:
            sortFontsNewest();
            break;
        }
    }

    private void sortFontsAZ() {
        Sort.instance().sort(fonts, (FontData o1, FontData o2) -> o1.toString().compareToIgnoreCase(o2.toString()));
        populate();
    }

    private void sortFontsZA() {
        Sort.instance().sort(fonts,
                (FontData o1, FontData o2) -> o1.toString().compareToIgnoreCase(o2.toString()) * -1);
        populate();
    }

    private void sortFontsOldest() {
        Sort.instance().sort(fonts, (FontData o1, FontData o2) -> {
            if (o1.file.lastModified() < o2.file.lastModified()) {
                return -1;
            } else if (o1.file.lastModified() > o2.file.lastModified()) {
                return 1;
            } else {
                return 0;
            }
        });

        populate();
    }

    private void sortFontsNewest() {
        Sort.instance().sort(fonts, (FontData o1, FontData o2) -> {
            if (o1.file.lastModified() < o2.file.lastModified()) {
                return 1;
            } else if (o1.file.lastModified() > o2.file.lastModified()) {
                return -1;
            } else {
                return 0;
            }
        });
        populate();
    }

    @Override
    public boolean remove() {
        main.getDesktopWorker().removeFilesDroppedListener(filesDroppedListener);

        produceAtlas();

        for (BitmapFont font : fontMap.values()) {
            font.dispose();
        }
        fontMap.clear();
        return super.remove();
    }

    private boolean produceAtlas() {
        try {
            if (atlas != null) {
                atlas.dispose();
                atlas = null;
            }

            if (!atlasData.atlasCurrent) {
                atlasData.writeAtlas();
                atlasData.atlasCurrent = true;
            }
            atlas = atlasData.getAtlas();

            for (FontData font : fonts) {
                BitmapFontData fontData = new BitmapFontData(font.file, false);
                Array<TextureRegion> regions = new Array<>();
                for (String path : fontData.imagePaths) {
                    FileHandle file = new FileHandle(path);
                    if (!file.exists()) {
                        file = fontData.fontFile.sibling(fontData.fontFile.nameWithoutExtension() + ".png");
                    }
                    TextureRegion region = atlas.findRegion(file.nameWithoutExtension());
                    if (region != null) {
                        regions.add(region);
                    }
                }
                fontMap.put(font, new BitmapFont(fontData, regions, true));
            }
            return true;
        } catch (Exception e) {
            Gdx.app.error(getClass().getName(), "Error while attempting to generate drawables.", e);
            main.getDialogFactory().showDialogError("Drawables Error...",
                    "Error while attempting to generate drawables. Open log?");
            return false;
        }
    }

    private void newFontDialog() {
        String defaultPath = "";

        if (projectData.getLastFontPath() != null) {
            FileHandle fileHandle = new FileHandle(defaultPath);
            if (fileHandle.exists()) {
                defaultPath = projectData.getLastFontPath();
            }
        }

        String[] filterPatterns = { "*.fnt" };

        List<File> files = main.getDesktopWorker().openMultipleDialog("Choose font file(s)...", defaultPath,
                filterPatterns, "Font files (*.fnt)");
        if (files != null && files.size() > 0) {
            projectData.setLastFontPath(files.get(0).getParentFile().getPath() + "/");
            fontNameDialog(files, 0);
        }
    }

    private void fontNameDialog(List<File> files, int index) {
        Array<FileHandle> handles = new Array<>();
        for (File file : files) {
            handles.add(new FileHandle(file));
        }

        fontNameDialog(handles, index);
    }

    private void fontNameDialog(Array<FileHandle> files, int index) {
        if (index < files.size) {
            try {
                final FileHandle fileHandle = files.get(index);

                final TextField textField = new TextField(FontData.filter(fileHandle.nameWithoutExtension()), skin);
                final Dialog nameDialog = new Dialog("Enter a name...", skin, "bg") {
                    @Override
                    protected void result(Object object) {
                        if ((Boolean) object) {
                            String name = textField.getText();

                            addFont(name, fileHandle);

                        }
                    }

                    @Override
                    public boolean remove() {
                        fontNameDialog(files, index + 1);
                        return super.remove();
                    }
                };

                nameDialog.getTitleTable().padLeft(5.0f);

                nameDialog.button("OK", true);
                nameDialog.button("Cancel", false);
                nameDialog.getButtonTable().getCells().first().getActor().addListener(main.getHandListener());
                nameDialog.getButtonTable().getCells().get(1).getActor().addListener(main.getHandListener());
                final TextButton button = (TextButton) nameDialog.getButtonTable().getCells().first().getActor();

                nameDialog.getButtonTable().padBottom(15.0f);

                textField.setTextFieldListener((TextField textField1, char c) -> {
                    if (c == '\n') {
                        if (!button.isDisabled()) {
                            String name1 = textField1.getText();
                            if (addFont(name1, fileHandle)) {
                                nameDialog.hide();
                            }
                        }
                        main.getStage().setKeyboardFocus(textField1);
                    }
                });

                textField.addListener(main.getIbeamListener());

                nameDialog.getContentTable().defaults().padLeft(10.0f).padRight(10.0f).padTop(5.0f);
                nameDialog.text("Please enter a name for the new font: ");
                nameDialog.getContentTable().row();
                nameDialog.getContentTable().add(textField).growX();
                nameDialog.getContentTable().row();
                nameDialog.text("Preview:");
                nameDialog.getContentTable().row();

                LabelStyle previewStyle = new LabelStyle();
                previewStyle.font = new BitmapFont(fileHandle);
                Table table = new Table(skin);
                table.setBackground("white");
                BitmapFontData bitmapFontData = new BitmapFontData(fileHandle, false);
                if (Utils.brightness(Utils.averageEdgeColor(new FileHandle(bitmapFontData.imagePaths[0]))) > .5f) {
                    table.setColor(Color.BLACK);
                } else {
                    table.setColor(Color.WHITE);
                }
                table.add(new Label("Lorem Ipsum", previewStyle)).pad(5.0f);

                nameDialog.getContentTable().add(table);
                nameDialog.key(Keys.ESCAPE, false);
                button.setDisabled(!FontData.validate(textField.getText()));
                textField.addListener(new ChangeListener() {
                    @Override
                    public void changed(ChangeListener.ChangeEvent event, Actor actor) {
                        boolean disable = !FontData.validate(textField.getText());
                        if (!disable) {
                            for (FontData data : jsonData.getFonts()) {
                                if (data.getName().equals(textField.getText())) {
                                    disable = true;
                                    break;
                                }
                            }
                        }
                        button.setDisabled(disable);
                    }
                });
                nameDialog.setColor(1.0f, 1.0f, 1.0f, 0.0f);

                textField.setFocusTraversal(false);

                if (!Utils.doesImageFitBox(new FileHandle(bitmapFontData.imagePaths[0]),
                        projectData.getMaxTextureWidth(), projectData.getMaxTextureHeight())) {
                    showAddFontSizeError(fileHandle.nameWithoutExtension());
                } else {
                    nameDialog.show(getStage());
                    getStage().setKeyboardFocus(textField);
                    textField.selectAll();
                }
            } catch (Exception e) {
                Gdx.app.error(getClass().getName(), "Error creating preview font from file", e);
                main.getDialogFactory().showDialogError("Preview Error...",
                        "Error creating preview font from file. Check file paths.\n\nOpen log?");
            }
        }
    }

    private void showAddFontSizeError(String name) {
        Dialog dialog = new Dialog("", skin, "bg");

        Label label = new Label("Error adding font...", skin, "title");
        dialog.getContentTable().add(label);

        dialog.getContentTable().row();
        dialog.text("Unable to add font \"" + name
                + "\". Ensure image dimensions\nare less than max texture dimensions ("
                + projectData.getMaxTextureWidth() + "x" + projectData.getMaxTextureHeight()
                + ").\nSee project settings.");
        dialog.button("Ok");
        dialog.show(getStage());
    }
}