2 * Copyright (c) 2008-2011, Matthias Mann
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions are met:
9 * * Redistributions of source code must retain the above copyright notice,
10 * this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * * Neither the name of Matthias Mann nor the names of its contributors may
15 * be used to endorse or promote products derived from this software
16 * without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32 import de.matthiasmann.twl.Button;
33 import de.matthiasmann.twl.DialogLayout;
34 import de.matthiasmann.twl.EditField;
35 import de.matthiasmann.twl.FPSCounter;
36 import de.matthiasmann.twl.GUI;
37 import de.matthiasmann.twl.Label;
38 import de.matthiasmann.twl.Timer;
39 import de.matthiasmann.twl.Widget;
40 import de.matthiasmann.twl.renderer.lwjgl.LWJGLRenderer;
41 import de.matthiasmann.twl.theme.ThemeManager;
42 import org.lwjgl.opengl.Display;
43 import org.lwjgl.opengl.DisplayMode;
44 import org.lwjgl.opengl.GL11;
45 import test.TestUtils;
48 * A simple login panel
50 * @author Matthias Mann
52 public class LoginDemo extends Widget {
54 public static void main(String[] args) {
56 Display.setDisplayMode(new DisplayMode(800, 600));
58 Display.setTitle("TWL Login Panel Demo");
59 Display.setVSyncEnabled(true);
61 LoginDemo demo = new LoginDemo();
63 LWJGLRenderer renderer = new LWJGLRenderer();
64 GUI gui = new GUI(demo, renderer);
66 ThemeManager theme = ThemeManager.createThemeManager(
67 LoginDemo.class.getResource("login.xml"), renderer);
68 gui.applyTheme(theme);
70 while(!Display.isCloseRequested() && !demo.quit) {
71 GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
79 } catch (Exception ex) {
80 TestUtils.showErrMsg(ex);
85 final FPSCounter fpsCounter;
86 final DialogLayout loginPanel;
87 final EditField efName;
88 final EditField efPassword;
89 final Button btnLogin;
94 fpsCounter = new FPSCounter();
96 loginPanel = new DialogLayout();
97 loginPanel.setTheme("login-panel");
99 efName = new EditField();
101 efPassword = new EditField();
102 efPassword.setPasswordMasking(true);
104 Label lName = new Label("Name");
105 lName.setLabelFor(efName);
107 Label lPassword = new Label("Password");
108 lPassword.setLabelFor(efPassword);
110 btnLogin = new Button("LOGIN");
111 btnLogin.addCallback(new Runnable() {
117 DialogLayout.Group hLabels = loginPanel.createParallelGroup(lName, lPassword);
118 DialogLayout.Group hFields = loginPanel.createParallelGroup(efName, efPassword);
119 DialogLayout.Group hBtn = loginPanel.createSequentialGroup()
120 .addGap() // right align the button by using a variable gap
121 .addWidget(btnLogin);
123 loginPanel.setHorizontalGroup(loginPanel.createParallelGroup()
124 .addGroup(loginPanel.createSequentialGroup(hLabels, hFields))
126 loginPanel.setVerticalGroup(loginPanel.createSequentialGroup()
127 .addGroup(loginPanel.createParallelGroup(lName, efName))
128 .addGroup(loginPanel.createParallelGroup(lPassword, efPassword))
129 .addWidget(btnLogin));
136 protected void layout() {
137 // fpsCounter is bottom right
138 fpsCounter.adjustSize();
139 fpsCounter.setPosition(
140 getInnerRight() - fpsCounter.getWidth(),
141 getInnerBottom() - fpsCounter.getHeight());
143 // login panel is centered
144 loginPanel.adjustSize();
145 loginPanel.setPosition(
146 getInnerX() + (getInnerWidth() - loginPanel.getWidth())/2,
147 getInnerY() + (getInnerHeight() - loginPanel.getHeight())/2);
150 void emulateLogin() {
153 // step 1: disable all controls
154 efName.setEnabled(false);
155 efPassword.setEnabled(false);
156 btnLogin.setEnabled(false);
158 // step 2: start a timer to simulate the process of talking to a remote server
159 Timer timer = gui.createTimer();
160 timer.setCallback(new Runnable() {
162 // once the timer fired re-enable the controls and clear the password
163 efName.setEnabled(true);
164 efPassword.setEnabled(true);
165 efPassword.setText("");
166 btnLogin.setEnabled(true);
169 timer.setDelay(2500);
172 /* NOTE: in a real app you would need to keep a reference to the timer object
173 * to cancel it if the user closes the dialog which uses the timer.
174 * @see Widget#beforeRemoveFromGUI(de.matthiasmann.twl.GUI)