src/textarea/TextAreaDemo.java
author Matthias Mann
Fri Feb 03 06:35:38 2012 +0100 (3 months ago)
changeset 260 42064e048ff4
parent 251 5a496842d3d1
permissions -rw-r--r--
LoginDemo: added initial keyboard focus, edit fields respond to return key
Matthias@161
     1
/*
Matthias@161
     2
 * Copyright (c) 2008-2010, Matthias Mann
Matthias@161
     3
 *
Matthias@161
     4
 * All rights reserved.
Matthias@161
     5
 *
Matthias@161
     6
 * Redistribution and use in source and binary forms, with or without
Matthias@161
     7
 * modification, are permitted provided that the following conditions are met:
Matthias@161
     8
 *
Matthias@161
     9
 *     * Redistributions of source code must retain the above copyright notice,
Matthias@161
    10
 *       this list of conditions and the following disclaimer.
Matthias@161
    11
 *     * Redistributions in binary form must reproduce the above copyright
Matthias@161
    12
 *       notice, this list of conditions and the following disclaimer in the
Matthias@161
    13
 *       documentation and/or other materials provided with the distribution.
Matthias@161
    14
 *     * Neither the name of Matthias Mann nor the names of its contributors may
Matthias@161
    15
 *       be used to endorse or promote products derived from this software
Matthias@161
    16
 *       without specific prior written permission.
Matthias@161
    17
 *
Matthias@161
    18
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
Matthias@161
    19
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Matthias@161
    20
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
Matthias@161
    21
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
Matthias@161
    22
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
Matthias@161
    23
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
Matthias@161
    24
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
Matthias@161
    25
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
Matthias@161
    26
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
Matthias@161
    27
 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
Matthias@161
    28
 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
Matthias@161
    29
 */
Matthias@161
    30
package textarea;
Matthias@161
    31
Matthias@161
    32
import de.matthiasmann.twl.DesktopArea;
Matthias@161
    33
import de.matthiasmann.twl.Event;
Matthias@161
    34
import de.matthiasmann.twl.FPSCounter;
Matthias@161
    35
import de.matthiasmann.twl.GUI;
Matthias@194
    36
import de.matthiasmann.twl.Rect;
Matthias@161
    37
import de.matthiasmann.twl.ResizableFrame;
Matthias@161
    38
import de.matthiasmann.twl.ScrollPane;
Matthias@161
    39
import de.matthiasmann.twl.TextArea;
Matthias@186
    40
import de.matthiasmann.twl.Timer;
Matthias@163
    41
import de.matthiasmann.twl.ValueAdjusterInt;
Matthias@173
    42
import de.matthiasmann.twl.textarea.HTMLTextAreaModel;
Matthias@163
    43
import de.matthiasmann.twl.model.SimpleIntegerModel;
Matthias@161
    44
import de.matthiasmann.twl.renderer.lwjgl.LWJGLRenderer;
Matthias@186
    45
import de.matthiasmann.twl.textarea.StyleAttribute;
Matthias@178
    46
import de.matthiasmann.twl.textarea.StyleSheet;
Matthias@186
    47
import de.matthiasmann.twl.textarea.TextAreaModel;
Matthias@186
    48
import de.matthiasmann.twl.textarea.Value;
Matthias@161
    49
import de.matthiasmann.twl.theme.ThemeManager;
Matthias@180
    50
import de.matthiasmann.twl.utils.TextUtil;
Matthias@161
    51
import java.io.IOException;
Matthias@161
    52
import java.util.logging.Level;
Matthias@161
    53
import java.util.logging.Logger;
Matthias@161
    54
import org.lwjgl.opengl.Display;
Matthias@161
    55
import org.lwjgl.opengl.DisplayMode;
Matthias@161
    56
import org.lwjgl.opengl.GL11;
Matthias@253
    57
import test.TestUtils;
Matthias@161
    58
Matthias@161
    59
/**
Matthias@161
    60
 *
Matthias@161
    61
 * @author Matthias Mann
Matthias@161
    62
 */
Matthias@161
    63
public class TextAreaDemo extends DesktopArea {
Matthias@161
    64
Matthias@161
    65
    public static void main(String[] args) {
Matthias@161
    66
        try {
Matthias@161
    67
            Display.setDisplayMode(new DisplayMode(800, 600));
Matthias@161
    68
            Display.create();
Matthias@161
    69
            Display.setTitle("TWL TextArea Demo");
Matthias@161
    70
            Display.setVSyncEnabled(true);
Matthias@161
    71
Matthias@161
    72
            LWJGLRenderer renderer = new LWJGLRenderer();
Matthias@161
    73
            TextAreaDemo demo = new TextAreaDemo();
Matthias@161
    74
            GUI gui = new GUI(demo, renderer);
Matthias@161
    75
Matthias@161
    76
            ThemeManager theme = ThemeManager.createThemeManager(
Matthias@161
    77
                    TextAreaDemo.class.getResource("demo.xml"), renderer);
Matthias@161
    78
            gui.applyTheme(theme);
Matthias@161
    79
Matthias@161
    80
            while(!Display.isCloseRequested() && !demo.quit) {
Matthias@161
    81
                GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
Matthias@161
    82
Matthias@161
    83
                gui.update();
Matthias@165
    84
Matthias@165
    85
                /**
Matthias@165
    86
                 * requires LWJGL 2.4 - for 2.3 just call Display.update()
Matthias@165
    87
                 */
Matthias@165
    88
                Display.update(false);
Matthias@165
    89
                GL11.glGetError();  // force sync with multi threaded GL driver
Matthias@165
    90
                Display.sync(60);   // ensure 60Hz even without vsync
Matthias@165
    91
                Display.processMessages();  // now process inputs
Matthias@161
    92
            }
Matthias@161
    93
Matthias@161
    94
            gui.destroy();
Matthias@161
    95
            theme.destroy();
Matthias@161
    96
        } catch (Exception ex) {
Matthias@253
    97
            TestUtils.showErrMsg(ex);
Matthias@161
    98
        }
Matthias@161
    99
        Display.destroy();
Matthias@161
   100
    }
Matthias@161
   101
Matthias@161
   102
    private final FPSCounter fpsCounter;
Matthias@161
   103
    private final TextFrame textFrame;
Matthias@161
   104
Matthias@161
   105
    public boolean quit;
Matthias@161
   106
Matthias@161
   107
    public TextAreaDemo() {
Matthias@161
   108
        fpsCounter = new FPSCounter();
Matthias@161
   109
        add(fpsCounter);
Matthias@161
   110
Matthias@161
   111
        textFrame = new TextFrame();
Matthias@161
   112
        add(textFrame);
Matthias@161
   113
Matthias@161
   114
        textFrame.setSize(600, 500);
Matthias@161
   115
        textFrame.setPosition(40, 20);
Matthias@161
   116
    }
Matthias@161
   117
Matthias@161
   118
    @Override
Matthias@161
   119
    protected void layout() {
Matthias@161
   120
        super.layout();
Matthias@161
   121
Matthias@161
   122
        // fpsCounter is bottom right
Matthias@161
   123
        fpsCounter.adjustSize();
Matthias@161
   124
        fpsCounter.setPosition(
Matthias@161
   125
                getInnerWidth() - fpsCounter.getWidth(),
Matthias@161
   126
                getInnerHeight() - fpsCounter.getHeight());
Matthias@161
   127
    }
Matthias@161
   128
Matthias@161
   129
    @Override
Matthias@161
   130
    protected boolean handleEvent(Event evt) {
Matthias@161
   131
        if(super.handleEvent(evt)) {
Matthias@161
   132
            return true;
Matthias@161
   133
        }
Matthias@161
   134
        switch (evt.getType()) {
Matthias@161
   135
            case KEY_PRESSED:
Matthias@161
   136
                switch (evt.getKeyCode()) {
Matthias@197
   137
                    case Event.KEY_ESCAPE:
Matthias@161
   138
                        quit = true;
Matthias@161
   139
                        return true;
Matthias@161
   140
                }
Matthias@161
   141
        }
Matthias@161
   142
        return false;
Matthias@161
   143
    }
Matthias@161
   144
Matthias@161
   145
    static class TextFrame extends ResizableFrame {
Matthias@161
   146
        private final HTMLTextAreaModel textAreaModel;
Matthias@161
   147
        private final TextArea textArea;
Matthias@161
   148
        private final ScrollPane scrollPane;
Matthias@186
   149
        private Timer timer;
Matthias@186
   150
        private int size;
Matthias@186
   151
        private int dir;
Matthias@186
   152
Matthias@186
   153
        private static final int MIN_SIZE = 128;
Matthias@186
   154
        private static final int MAX_SIZE = 256;
Matthias@161
   155
Matthias@161
   156
        public TextFrame() {
Matthias@161
   157
            setTitle("Text");
Matthias@161
   158
Matthias@161
   159
            this.textAreaModel = new HTMLTextAreaModel();
Matthias@161
   160
            this.textArea = new TextArea(textAreaModel);
Matthias@161
   161
Matthias@177
   162
            readFile("demo.html");
Matthias@161
   163
Matthias@161
   164
            textArea.addCallback(new TextArea.Callback() {
Matthias@161
   165
                public void handleLinkClicked(String href) {
Matthias@186
   166
                    if(href.startsWith("javascript:")) {
Matthias@186
   167
                        handleAction(href.substring(11));
Matthias@194
   168
                    } else if(href.startsWith("#")) {
Matthias@195
   169
                        TextAreaModel.Element ankor = textAreaModel.getElementById(href.substring(1));
Matthias@194
   170
                        if(ankor != null) {
Matthias@194
   171
                            Rect rect = textArea.getElementRect(ankor);
Matthias@194
   172
                            if(rect != null) {
Matthias@194
   173
                                scrollPane.setScrollPositionY(rect.getY());
Matthias@194
   174
                            }
Matthias@194
   175
                        }
Matthias@186
   176
                    } else {
Matthias@186
   177
                        readFile(href);
Matthias@186
   178
                    }
Matthias@161
   179
                }
Matthias@161
   180
            });
Matthias@161
   181
Matthias@163
   182
            ValueAdjusterInt vai = new ValueAdjusterInt(new SimpleIntegerModel(0, 100, 50));
Matthias@163
   183
            vai.setTooltipContent("Select a nice value");
Matthias@163
   184
            textArea.registerWidget("niceValueSlider", vai);
Matthias@163
   185
            
Matthias@161
   186
            scrollPane = new ScrollPane(textArea);
Matthias@161
   187
            scrollPane.setFixed(ScrollPane.Fixed.HORIZONTAL);
Matthias@161
   188
Matthias@161
   189
            add(scrollPane);
Matthias@161
   190
        }
Matthias@177
   191
Matthias@186
   192
        @Override
Matthias@186
   193
        protected void afterAddToGUI(GUI gui) {
Matthias@186
   194
            super.afterAddToGUI(gui);
Matthias@186
   195
            timer = gui.createTimer();
Matthias@186
   196
            timer.setDelay(16);
Matthias@186
   197
            timer.setContinuous(true);
Matthias@186
   198
            timer.setCallback(new Runnable() {
Matthias@186
   199
                public void run() {
Matthias@186
   200
                    animate();
Matthias@186
   201
                }
Matthias@186
   202
            });
Matthias@186
   203
        }
Matthias@186
   204
Matthias@186
   205
        @Override
Matthias@186
   206
        protected void beforeRemoveFromGUI(GUI gui) {
Matthias@186
   207
            super.beforeRemoveFromGUI(gui);
Matthias@186
   208
            timer.stop();
Matthias@186
   209
            timer = null;
Matthias@186
   210
        }
Matthias@186
   211
Matthias@177
   212
        void readFile(String name) {
Matthias@177
   213
            try {
Matthias@177
   214
                textAreaModel.readHTMLFromURL(TextAreaDemo.class.getResource(name));
Matthias@180
   215
Matthias@180
   216
                StyleSheet styleSheet = new StyleSheet();
Matthias@180
   217
                for(String styleSheetLink : textAreaModel.getStyleSheetLinks()) {
Matthias@180
   218
                    try {
Matthias@180
   219
                        styleSheet.parse(TextAreaDemo.class.getResource(styleSheetLink));
Matthias@180
   220
                    } catch(IOException ex) {
Matthias@180
   221
                        Logger.getLogger(TextAreaDemo.class.getName()).log(Level.SEVERE,
Matthias@180
   222
                                "Can't parse style sheet: " + styleSheetLink, ex);
Matthias@180
   223
                    }
Matthias@180
   224
                }
Matthias@180
   225
                textArea.setStyleClassResolver(styleSheet);
Matthias@180
   226
                
Matthias@180
   227
                setTitle(TextUtil.notNull(textAreaModel.getTitle()));
Matthias@186
   228
Matthias@186
   229
                size = MIN_SIZE;
Matthias@186
   230
                dir = -4;
Matthias@177
   231
            } catch(IOException ex) {
Matthias@177
   232
                Logger.getLogger(TextAreaDemo.class.getName()).log(Level.SEVERE, "Can't read HTML: " + name, ex);
Matthias@177
   233
            }
Matthias@177
   234
        }
Matthias@186
   235
Matthias@186
   236
        void handleAction(String what) {
Matthias@186
   237
            if("zoomImage()".equals(what)) {
Matthias@186
   238
                if(timer != null && !timer.isRunning()) {
Matthias@186
   239
                    dir = -dir;
Matthias@186
   240
                    timer.start();
Matthias@186
   241
                }
Matthias@186
   242
            }
Matthias@186
   243
        }
Matthias@186
   244
Matthias@186
   245
        void animate() {
Matthias@186
   246
            size = Math.max(MIN_SIZE, Math.min(MAX_SIZE, size + dir));
Matthias@186
   247
            if(size == MIN_SIZE || size == MAX_SIZE) {
Matthias@186
   248
                timer.stop();
Matthias@186
   249
            }
Matthias@186
   250
Matthias@251
   251
            TextAreaModel.Element e = textAreaModel.getElementById("portrait");
Matthias@186
   252
            if(e != null) {
Matthias@186
   253
                e.setStyle(e.getStyle().with(StyleAttribute.WIDTH, new Value(size, Value.Unit.PX)));
Matthias@186
   254
                textAreaModel.domModified();
Matthias@186
   255
            }
Matthias@186
   256
        }
Matthias@161
   257
    }
Matthias@161
   258
}