00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 package com.realtime.crossfire.jxclient.gui.gui;
00023
00024 import com.realtime.crossfire.jxclient.gui.keybindings.KeyBindings;
00025 import java.awt.Component;
00026 import java.awt.Dimension;
00027 import java.awt.event.KeyEvent;
00028 import java.util.Collection;
00029 import java.util.EnumSet;
00030 import javax.swing.JComponent;
00031 import org.jetbrains.annotations.NotNull;
00032 import org.jetbrains.annotations.Nullable;
00033
00041 public class Gui extends JComponent {
00042
00046 private static final long serialVersionUID = 1L;
00047
00051 @NotNull
00052 private final KeyBindings keyBindings;
00053
00058 @Nullable
00059 private Extent autoSize = null;
00060
00064 private boolean saveDialog = false;
00065
00069 private boolean modal = false;
00070
00074 @NotNull
00075 private final Collection<RendererGuiState> hideInStates = EnumSet.noneOf(RendererGuiState.class);
00076
00081 @Nullable
00082 private ActivatableGUIElement forcedActive = null;
00083
00088 @Nullable
00089 private ActivatableGUIElement activeElement = null;
00090
00094 private boolean initialPositionSet = false;
00095
00100 @Nullable
00101 private GuiAutoCloseListener guiAutoCloseListener = null;
00102
00107 @Nullable
00108 private Expression defaultX = null;
00109
00114 @Nullable
00115 private Expression defaultY = null;
00116
00121 public Gui(@NotNull final KeyBindings keyBindings) {
00122 this.keyBindings = keyBindings;
00123 }
00124
00130 public void setPosition(final int x, final int y) {
00131 if (initialPositionSet && getX() == x && getY() == y) {
00132 return;
00133 }
00134
00135 if ((getWidth() == 0 || getHeight() == 0) && (initialPositionSet || x != 0 || y != 0)) {
00136 throw new IllegalStateException();
00137 }
00138
00139 initialPositionSet = true;
00140 setLocation(x, y);
00141 }
00142
00148 public void setAutoSize(@Nullable final Extent autoSize) {
00149 this.autoSize = autoSize;
00150 }
00151
00157 public boolean isAutoSize() {
00158 return autoSize != null;
00159 }
00160
00165 public void setModal(final boolean modal) {
00166 this.modal = modal;
00167 }
00168
00173 public boolean isModal() {
00174 return modal;
00175 }
00176
00181 @Nullable
00182 private GUIElement getDefaultElement() {
00183 final int count = getComponentCount();
00184 for (int i = 0; i < count; i++) {
00185 final Component component = getComponent(i);
00186 if (component.isVisible() && component instanceof GUIElement) {
00187 final GUIElement element = (GUIElement)component;
00188 if (element.isDefault()) {
00189 return element;
00190 }
00191 }
00192 }
00193
00194 return null;
00195 }
00196
00200 public void activateDefaultElement() {
00201 final Object defaultElement = getDefaultElement();
00202 if (defaultElement != null && defaultElement instanceof ActivatableGUIElement) {
00203 final ActivatableGUIElement activatableDefaultElement = (ActivatableGUIElement)defaultElement;
00204 activatableDefaultElement.setActive(true);
00205 }
00206 }
00207
00215 @Nullable
00216 public <T extends GUIElement> T getFirstElementEndingWith(@NotNull final Class<T> class_, @NotNull final String ending) {
00217 final int count = getComponentCount();
00218 for (int i = 0; i < count; i++) {
00219 final Component component = getComponent(i);
00220 if (component.isVisible() && component instanceof GUIElement) {
00221 final GUIElement element = (GUIElement)component;
00222 if (class_.isAssignableFrom(element.getClass()) && element.getName().endsWith(ending)) {
00223 return class_.cast(element);
00224 }
00225 }
00226 }
00227
00228 return null;
00229 }
00230
00238 @Nullable
00239 public <T extends GUIElement> T getFirstElementNotEndingWith(@NotNull final Class<T> class_, @NotNull final String ending) {
00240 final int count = getComponentCount();
00241 for (int i = 0; i < count; i++) {
00242 final Component component = getComponent(i);
00243 if (component.isVisible() && component instanceof GUIElement) {
00244 final GUIElement element = (GUIElement)component;
00245 if (class_.isAssignableFrom(element.getClass()) && !element.getName().endsWith(ending)) {
00246 return class_.cast(element);
00247 }
00248 }
00249 }
00250
00251 return null;
00252 }
00253
00259 @Nullable
00260 public <T extends GUIElement> T getFirstElement(@NotNull final Class<T> class_) {
00261 final int count = getComponentCount();
00262 for (int i = 0; i < count; i++) {
00263 final Component component = getComponent(i);
00264 if (component.isVisible() && component instanceof GUIElement) {
00265 final GUIElement element = (GUIElement)component;
00266 if (class_.isAssignableFrom(element.getClass())) {
00267 return class_.cast(element);
00268 }
00269 }
00270 }
00271
00272 return null;
00273 }
00274
00282 @Nullable
00283 public AbstractGUIElement getElementFromPoint(final int x, final int y) {
00284 Component component = findComponentAt(x, y);
00285 while (component != null) {
00286 if (component instanceof AbstractGUIElement) {
00287 return (AbstractGUIElement)component;
00288 }
00289 component = component.getParent();
00290 }
00291 return null;
00292 }
00293
00299 public void setActiveElement(@NotNull final ActivatableGUIElement activeElement, final boolean active) {
00300 final ActivatableGUIElement previousActiveElement = this.activeElement;
00301 if (active) {
00302 if (forcedActive != null && forcedActive != activeElement) {
00303 return;
00304 }
00305
00306 if (isActiveElement(activeElement)) {
00307 return;
00308 }
00309
00310 this.activeElement = activeElement;
00311 if (previousActiveElement != null) {
00312 previousActiveElement.activeChanged();
00313 }
00314 assert this.activeElement != null;
00315 this.activeElement.activeChanged();
00316
00317 guiAutoCloseListener = null;
00318 } else {
00319 if (!isActiveElement(activeElement)) {
00320 return;
00321 }
00322
00323 this.activeElement = null;
00324 assert previousActiveElement != null;
00325 previousActiveElement.activeChanged();
00326
00327 if (guiAutoCloseListener != null) {
00328 final GuiAutoCloseListener listener = guiAutoCloseListener;
00329 guiAutoCloseListener = null;
00330 listener.autoClosed();
00331 }
00332 }
00333 }
00334
00341 public boolean isActiveElement(@Nullable final ActivatableGUIElement activeElement) {
00342 return this.activeElement != null && this.activeElement == activeElement;
00343 }
00344
00350 public void setActiveElementActive(final boolean active) {
00351 if (activeElement != null) {
00352 activeElement.setActive(active);
00353 }
00354 }
00355
00361 public boolean handleKeyPress(@NotNull final KeyEvent e) {
00362 if (activeElement != null && activeElement instanceof KeyPressedHandler && ((KeyPressedHandler)activeElement).keyPressed(e)) {
00363 return true;
00364 }
00365
00366 if (activeElement != null && activeElement instanceof KeyPressedHandler) {
00367 final KeyPressedHandler keyListener = (KeyPressedHandler)activeElement;
00368 if (keyListener.keyPressed(e)) {
00369 return true;
00370 }
00371 }
00372
00373 switch (e.getKeyCode()) {
00374 case KeyEvent.VK_ENTER:
00375 case KeyEvent.VK_SPACE:
00376 final GUIElement defaultElement = getDefaultElement();
00377 if (defaultElement != null) {
00378 defaultElement.execute();
00379 return true;
00380 }
00381 break;
00382 }
00383
00384 return keyBindings.handleKeyPress(e);
00385 }
00386
00393 public boolean deactivateCommandInput() {
00394 if (activeElement == null) {
00395 return false;
00396 }
00397
00398 final GUIElement textArea = activeElement;
00399 if (!textArea.getName().equals("command")) {
00400 return false;
00401 }
00402
00403 assert activeElement != null;
00404 activeElement.setActive(false);
00405 return true;
00406 }
00407
00415 @Nullable
00416 public <T extends GUIElement> T getFirstElement(@NotNull final Class<T> class_, @NotNull final String name) {
00417 final int count = getComponentCount();
00418 for (int i = 0; i < count; i++) {
00419 final Component component = getComponent(i);
00420 if (component.isVisible() && component instanceof GUIElement) {
00421 final GUIElement element = (GUIElement)component;
00422 if (class_.isAssignableFrom(element.getClass()) && element.getName().equals(name)) {
00423 return class_.cast(element);
00424 }
00425 }
00426 }
00427 return null;
00428 }
00429
00434 @NotNull
00435 public KeyBindings getKeyBindings() {
00436 return keyBindings;
00437 }
00438
00443 public void hideInState(@NotNull final RendererGuiState state) {
00444 hideInStates.add(state);
00445 }
00446
00452 public boolean isHidden(@NotNull final RendererGuiState state) {
00453 return hideInStates.contains(state);
00454 }
00455
00462 public void setGuiAutoCloseListener(@Nullable final GuiAutoCloseListener guiAutoCloseListener) {
00463 this.guiAutoCloseListener = guiAutoCloseListener;
00464 }
00465
00472 public boolean isWithinDrawingArea(final int x, final int y) {
00473 return getX() <= x && x < getX()+getWidth() && getY() <= y && y < getY()+getHeight();
00474 }
00475
00481 public void setForcedActive(@Nullable final ActivatableGUIElement forcedActive) {
00482 this.forcedActive = forcedActive;
00483 }
00484
00488 @NotNull
00489 @Override
00490 public String toString() {
00491 final String name = getName();
00492 return (name == null ? "" : name)+"["+getWidth()+"x"+getHeight()+"]";
00493 }
00494
00500 public void autoSize(final int screenWidth, final int screenHeight) {
00501 final Extent extent = autoSize;
00502 if (extent != null) {
00503 final Dimension preferredSize = getPreferredSize();
00504 setBounds(extent.getX(screenWidth, screenHeight, preferredSize.width, preferredSize.height), extent.getY(screenWidth, screenHeight, preferredSize.width, preferredSize.height), extent.getW(screenWidth, screenHeight, preferredSize.width, preferredSize.height), extent.getH(screenWidth, screenHeight, preferredSize.width, preferredSize.height));
00505 } else if (!initialPositionSet) {
00506 final Dimension preferredSize = getPreferredSize();
00507 final int x;
00508 if (defaultX == null) {
00509 x = (screenWidth-preferredSize.width)/2;
00510 } else {
00511 x = defaultX.evaluate(screenWidth, screenHeight, preferredSize.width, preferredSize.height);
00512 }
00513 final int y;
00514 if (defaultY == null) {
00515 y = (screenHeight-preferredSize.height)/2;
00516 } else {
00517 y = defaultY.evaluate(screenWidth, screenHeight, preferredSize.width, preferredSize.height);
00518 }
00519 setSize(preferredSize.width, preferredSize.height);
00520 if (defaultX != null && defaultY != null) {
00521 setPosition(x-preferredSize.width/2, y-preferredSize.height/2);
00522 }
00523 }
00524
00525 showDialog(getX(), getY(), screenWidth, screenHeight);
00526 }
00527
00533 public void setDefaultPosition(@NotNull final Expression defaultX, @NotNull final Expression defaultY) {
00534 this.defaultX = defaultX;
00535 this.defaultY = defaultY;
00536 }
00537
00542 public boolean isSaveDialog() {
00543 return saveDialog;
00544 }
00545
00549 public void setSaveDialog() {
00550 saveDialog = true;
00551 }
00552
00561 public void showDialog(final int x, final int y, final int windowWidth, final int windowHeight) {
00562 final int newX;
00563 final int newY;
00564 if (isAutoSize()) {
00565 newX = x;
00566 newY = y;
00567 } else {
00568 newX = Math.max(Math.min(x, windowWidth-getWidth()), 0);
00569 newY = Math.max(Math.min(y, windowHeight-getHeight()), 0);
00570 }
00571 setPosition(newX, newY);
00572 }
00573
00574 }