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.skin.io;
00023
00024 import com.realtime.crossfire.jxclient.account.CharacterModel;
00025 import com.realtime.crossfire.jxclient.faces.FacesManager;
00026 import com.realtime.crossfire.jxclient.faces.FacesProvider;
00027 import com.realtime.crossfire.jxclient.faces.FacesProviderFactory;
00028 import com.realtime.crossfire.jxclient.faces.SmoothFaces;
00029 import com.realtime.crossfire.jxclient.gui.button.ButtonImages;
00030 import com.realtime.crossfire.jxclient.gui.button.GUIButton;
00031 import com.realtime.crossfire.jxclient.gui.commandlist.CommandList;
00032 import com.realtime.crossfire.jxclient.gui.commandlist.CommandListType;
00033 import com.realtime.crossfire.jxclient.gui.commands.CommandCheckBoxOption;
00034 import com.realtime.crossfire.jxclient.gui.gauge.GUIDupGauge;
00035 import com.realtime.crossfire.jxclient.gui.gauge.GUIDupTextGauge;
00036 import com.realtime.crossfire.jxclient.gui.gauge.GUIGauge;
00037 import com.realtime.crossfire.jxclient.gui.gauge.GUITextGauge;
00038 import com.realtime.crossfire.jxclient.gui.gauge.GaugeUpdater;
00039 import com.realtime.crossfire.jxclient.gui.gauge.Orientation;
00040 import com.realtime.crossfire.jxclient.gui.gui.AbstractGUIElement;
00041 import com.realtime.crossfire.jxclient.gui.gui.ActivatableGUIElement;
00042 import com.realtime.crossfire.jxclient.gui.gui.Expression;
00043 import com.realtime.crossfire.jxclient.gui.gui.Extent;
00044 import com.realtime.crossfire.jxclient.gui.gui.GUIElement;
00045 import com.realtime.crossfire.jxclient.gui.gui.GUIElementListener;
00046 import com.realtime.crossfire.jxclient.gui.gui.Gui;
00047 import com.realtime.crossfire.jxclient.gui.gui.RendererGuiState;
00048 import com.realtime.crossfire.jxclient.gui.gui.TooltipManager;
00049 import com.realtime.crossfire.jxclient.gui.item.GUIItemFloor;
00050 import com.realtime.crossfire.jxclient.gui.item.GUIItemFloorFactory;
00051 import com.realtime.crossfire.jxclient.gui.item.GUIItemInventory;
00052 import com.realtime.crossfire.jxclient.gui.item.GUIItemInventoryFactory;
00053 import com.realtime.crossfire.jxclient.gui.item.GUIItemItemFactory;
00054 import com.realtime.crossfire.jxclient.gui.item.GUIItemQuestListFactory;
00055 import com.realtime.crossfire.jxclient.gui.item.GUIItemShortcut;
00056 import com.realtime.crossfire.jxclient.gui.item.GUIItemSpell;
00057 import com.realtime.crossfire.jxclient.gui.item.GUIItemSpellListFactory;
00058 import com.realtime.crossfire.jxclient.gui.item.ItemPainter;
00059 import com.realtime.crossfire.jxclient.gui.keybindings.InvalidKeyBindingException;
00060 import com.realtime.crossfire.jxclient.gui.keybindings.KeyBindings;
00061 import com.realtime.crossfire.jxclient.gui.label.AbstractLabel;
00062 import com.realtime.crossfire.jxclient.gui.label.Alignment;
00063 import com.realtime.crossfire.jxclient.gui.label.GUIHTMLLabel;
00064 import com.realtime.crossfire.jxclient.gui.label.GUILabelFailure;
00065 import com.realtime.crossfire.jxclient.gui.label.GUILabelMessage;
00066 import com.realtime.crossfire.jxclient.gui.label.GUILabelQuery;
00067 import com.realtime.crossfire.jxclient.gui.label.GUILabelStats;
00068 import com.realtime.crossfire.jxclient.gui.label.GUILabelStats2;
00069 import com.realtime.crossfire.jxclient.gui.label.GUIMultiLineLabel;
00070 import com.realtime.crossfire.jxclient.gui.label.GUIOneLineLabel;
00071 import com.realtime.crossfire.jxclient.gui.label.GUISpellLabel;
00072 import com.realtime.crossfire.jxclient.gui.label.JXCWindowRenderer;
00073 import com.realtime.crossfire.jxclient.gui.label.Type;
00074 import com.realtime.crossfire.jxclient.gui.list.GUICharacterList;
00075 import com.realtime.crossfire.jxclient.gui.list.GUIFloorList;
00076 import com.realtime.crossfire.jxclient.gui.list.GUIItemList;
00077 import com.realtime.crossfire.jxclient.gui.list.GUIMetaElementList;
00078 import com.realtime.crossfire.jxclient.gui.list.GUIQuestList;
00079 import com.realtime.crossfire.jxclient.gui.list.GUISpellList;
00080 import com.realtime.crossfire.jxclient.gui.log.Fonts;
00081 import com.realtime.crossfire.jxclient.gui.log.GUILabelLog;
00082 import com.realtime.crossfire.jxclient.gui.log.GUIMessageLog;
00083 import com.realtime.crossfire.jxclient.gui.log.MessageBufferUpdater;
00084 import com.realtime.crossfire.jxclient.gui.map.GUIMap;
00085 import com.realtime.crossfire.jxclient.gui.map.GUIMiniMap;
00086 import com.realtime.crossfire.jxclient.gui.misc.GUIFill;
00087 import com.realtime.crossfire.jxclient.gui.misc.GUIPicture;
00088 import com.realtime.crossfire.jxclient.gui.misc.GUIScrollBar;
00089 import com.realtime.crossfire.jxclient.gui.scrollable.GUIScrollable2;
00090 import com.realtime.crossfire.jxclient.gui.textinput.CommandCallback;
00091 import com.realtime.crossfire.jxclient.gui.textinput.CommandExecutor;
00092 import com.realtime.crossfire.jxclient.gui.textinput.GUICommandText;
00093 import com.realtime.crossfire.jxclient.gui.textinput.GUIQueryText;
00094 import com.realtime.crossfire.jxclient.gui.textinput.GUIText;
00095 import com.realtime.crossfire.jxclient.gui.textinput.GUITextField;
00096 import com.realtime.crossfire.jxclient.guistate.GuiStateManager;
00097 import com.realtime.crossfire.jxclient.items.FloorView;
00098 import com.realtime.crossfire.jxclient.items.ItemSet;
00099 import com.realtime.crossfire.jxclient.items.ItemView;
00100 import com.realtime.crossfire.jxclient.items.QuestsView;
00101 import com.realtime.crossfire.jxclient.items.SpellsView;
00102 import com.realtime.crossfire.jxclient.map.MapUpdaterState;
00103 import com.realtime.crossfire.jxclient.metaserver.MetaserverModel;
00104 import com.realtime.crossfire.jxclient.quests.QuestsManager;
00105 import com.realtime.crossfire.jxclient.queue.CommandQueue;
00106 import com.realtime.crossfire.jxclient.server.crossfire.CrossfireServerConnection;
00107 import com.realtime.crossfire.jxclient.server.crossfire.MessageTypes;
00108 import com.realtime.crossfire.jxclient.server.socket.UnknownCommandException;
00109 import com.realtime.crossfire.jxclient.settings.Macros;
00110 import com.realtime.crossfire.jxclient.settings.options.CheckBoxOption;
00111 import com.realtime.crossfire.jxclient.settings.options.OptionManager;
00112 import com.realtime.crossfire.jxclient.shortcuts.Shortcuts;
00113 import com.realtime.crossfire.jxclient.skills.Skill;
00114 import com.realtime.crossfire.jxclient.skills.SkillSet;
00115 import com.realtime.crossfire.jxclient.skin.events.ConnectionStateSkinEvent;
00116 import com.realtime.crossfire.jxclient.skin.events.CrossfireMagicmapSkinEvent;
00117 import com.realtime.crossfire.jxclient.skin.events.MapScrollSkinEvent;
00118 import com.realtime.crossfire.jxclient.skin.events.SkillAddedSkinEvent;
00119 import com.realtime.crossfire.jxclient.skin.events.SkillRemovedSkinEvent;
00120 import com.realtime.crossfire.jxclient.skin.factory.CheckBoxFactory;
00121 import com.realtime.crossfire.jxclient.skin.factory.DialogFactory;
00122 import com.realtime.crossfire.jxclient.skin.factory.TextButtonFactory;
00123 import com.realtime.crossfire.jxclient.skin.skin.DefaultJXCSkin;
00124 import com.realtime.crossfire.jxclient.skin.skin.Dialogs;
00125 import com.realtime.crossfire.jxclient.skin.skin.GuiFactory;
00126 import com.realtime.crossfire.jxclient.skin.skin.JXCSkin;
00127 import com.realtime.crossfire.jxclient.skin.skin.JXCSkinCache;
00128 import com.realtime.crossfire.jxclient.skin.skin.JXCSkinException;
00129 import com.realtime.crossfire.jxclient.skin.source.JXCSkinSource;
00130 import com.realtime.crossfire.jxclient.spells.CurrentSpellManager;
00131 import com.realtime.crossfire.jxclient.spells.SpellsManager;
00132 import com.realtime.crossfire.jxclient.stats.ExperienceTable;
00133 import com.realtime.crossfire.jxclient.stats.Stats;
00134 import com.realtime.crossfire.jxclient.util.NumberParser;
00135 import com.realtime.crossfire.jxclient.util.Resolution;
00136 import com.realtime.crossfire.jxclient.util.ResourceUtils;
00137 import com.realtime.crossfire.jxclient.util.StringUtils;
00138 import com.realtime.crossfire.jxclient.util.UnterminatedTokenException;
00139 import com.realtime.crossfire.jxclient.window.KeybindingsManager;
00140 import java.awt.Color;
00141 import java.awt.Component;
00142 import java.awt.Container;
00143 import java.awt.Font;
00144 import java.awt.Image;
00145 import java.awt.image.BufferedImage;
00146 import java.io.IOException;
00147 import java.io.InputStream;
00148 import java.io.InputStreamReader;
00149 import java.io.LineNumberReader;
00150 import java.util.ArrayList;
00151 import java.util.Collection;
00152 import java.util.Comparator;
00153 import java.util.Iterator;
00154 import java.util.List;
00155 import java.util.TreeSet;
00156 import javax.swing.GroupLayout;
00157 import javax.swing.SwingConstants;
00158 import org.jetbrains.annotations.NotNull;
00159 import org.jetbrains.annotations.Nullable;
00160
00166 public class JXCSkinLoader {
00167
00173 private enum ListType {
00174
00178 INVENTORY,
00179
00183 GROUND,
00184
00188 SPELL,
00189
00193 QUEST
00194 }
00195
00199 private static final int DIALOG_BORDER_WIDTH = 5;
00200
00204 @NotNull
00205 private final ItemSet itemSet;
00206
00210 @NotNull
00211 private final ItemView inventoryView;
00212
00216 @NotNull
00217 private final FloorView floorView;
00218
00222 @NotNull
00223 private final SpellsView spellView;
00224
00228 @NotNull final QuestsView questView;
00229
00233 @NotNull
00234 private final SpellsManager spellsManager;
00235
00239 @NotNull
00240 private final QuestsManager questsManager;
00241
00245 @NotNull
00246 private final FacesManager facesManager;
00247
00251 private final int defaultTileSize;
00252
00257 @NotNull
00258 private final FacesProviderFactory facesProviderFactory;
00259
00263 @NotNull
00264 private final Stats stats;
00265
00269 @NotNull
00270 private final MapUpdaterState mapUpdaterState;
00271
00275 @NotNull
00276 private final KeyBindings defaultKeyBindings;
00277
00281 @NotNull
00282 private final OptionManager optionManager;
00283
00287 @NotNull
00288 private final ExperienceTable experienceTable;
00289
00293 @NotNull
00294 private GaugeUpdaterParser gaugeUpdaterParser;
00295
00299 @NotNull
00300 private final SkillSet skillSet;
00301
00305 @NotNull
00306 private final JXCSkinCache<Font> definedFonts = new JXCSkinCache<Font>("font");
00307
00311 @Nullable
00312 private TextButtonFactory textButtonFactory = null;
00313
00317 @Nullable
00318 private DialogFactory dialogFactory = null;
00319
00323 @Nullable
00324 private CheckBoxFactory checkBoxFactory = null;
00325
00330 @Nullable
00331 private ItemPainter defaultItemPainter = null;
00332
00336 @NotNull
00337 private CommandParser commandParser;
00338
00342 @NotNull
00343 private ImageParser imageParser;
00344
00348 @NotNull
00349 private FontParser fontParser;
00350
00354 @NotNull
00355 private GuiElementParser guiElementParser;
00356
00360 @NotNull
00361 private final JXCSkinCache<AbstractGUIElement> definedGUIElements = new JXCSkinCache<AbstractGUIElement>("gui element");
00362
00366 @NotNull
00367 private DefaultJXCSkin skin;
00368
00373 @NotNull
00374 private static final Comparator<GUIElement> ELEMENT_COMPARATOR = new Comparator<GUIElement>() {
00375
00376 @Override
00377 public int compare(@NotNull final GUIElement o1, @NotNull final GUIElement o2) {
00378 final Comparable<String> n1 = o1.getName();
00379 final String n2 = o2.getName();
00380 return n1.compareTo(n2);
00381 }
00382
00383 };
00384
00388 @NotNull
00389 private final KeybindingsManager keybindingsManager;
00390
00410 public JXCSkinLoader(@NotNull final ItemSet itemSet, @NotNull final ItemView inventoryView, @NotNull final FloorView floorView, @NotNull final SpellsView spellView, @NotNull final SpellsManager spellsManager, @NotNull final FacesManager facesManager, @NotNull final Stats stats, @NotNull final MapUpdaterState mapUpdaterState, @NotNull final KeyBindings defaultKeyBindings, @NotNull final OptionManager optionManager, @NotNull final ExperienceTable experienceTable, @NotNull final SkillSet skillSet, final int defaultTileSize, @NotNull final KeybindingsManager keybindingsManager, @NotNull final QuestsManager questsManager, @NotNull final QuestsView questView) {
00411 this.itemSet = itemSet;
00412 this.inventoryView = inventoryView;
00413 this.floorView = floorView;
00414 this.spellView = spellView;
00415 this.spellsManager = spellsManager;
00416 this.facesManager = facesManager;
00417 this.defaultTileSize = defaultTileSize;
00418 facesProviderFactory = new FacesProviderFactory(facesManager);
00419 this.stats = stats;
00420 this.mapUpdaterState = mapUpdaterState;
00421 this.defaultKeyBindings = defaultKeyBindings;
00422 this.optionManager = optionManager;
00423 this.experienceTable = experienceTable;
00424 this.skillSet = skillSet;
00425 this.keybindingsManager = keybindingsManager;
00426 this.questsManager = questsManager;
00427 this.questView = questView;
00428 }
00429
00451 @NotNull
00452 public JXCSkin load(@NotNull final JXCSkinSource skinSource, @NotNull final CrossfireServerConnection crossfireServerConnection, @NotNull final GuiStateManager guiStateManager, @NotNull final TooltipManager tooltipManager, @NotNull final JXCWindowRenderer windowRenderer, @NotNull final GUIElementListener elementListener, @NotNull final MetaserverModel metaserverModel, @NotNull final CharacterModel characterModel, @NotNull final CommandQueue commandQueue, @NotNull final Shortcuts shortcuts, @NotNull final CommandExecutor commandExecutor, @NotNull final CurrentSpellManager currentSpellManager, @NotNull final CommandCallback commandCallback, @NotNull final Macros macros, @NotNull final GuiFactory guiFactory, @NotNull final SmoothFaces smoothFaces) throws JXCSkinException {
00453 imageParser = new ImageParser(skinSource);
00454 fontParser = new FontParser(skinSource);
00455
00456 final Image nextGroupFace;
00457 try {
00458 nextGroupFace = ResourceUtils.loadImage(ResourceUtils.NEXT_GROUP_FACE).getImage();
00459 } catch (final IOException ex) {
00460 throw new JXCSkinException(ex.getMessage());
00461 }
00462 final Image prevGroupFace;
00463 try {
00464 prevGroupFace = ResourceUtils.loadImage(ResourceUtils.PREV_GROUP_FACE).getImage();
00465 } catch (final IOException ex) {
00466 throw new JXCSkinException(ex.getMessage());
00467 }
00468
00469 final Dialogs dialogs = new Dialogs(guiFactory);
00470 gaugeUpdaterParser = new GaugeUpdaterParser(stats, itemSet, skillSet);
00471 commandParser = new CommandParser(dialogs, floorView, definedGUIElements);
00472 skin = new DefaultJXCSkin(defaultKeyBindings, optionManager, dialogs);
00473 @Nullable JXCSkin skinToDetach = skin;
00474 try {
00475 guiElementParser = new GuiElementParser(definedGUIElements);
00476 imageParser.clear();
00477 skin.addDialog("keybind");
00478 skin.addDialog("query");
00479 skin.addDialog("book");
00480 skin.addDialog("main");
00481 skin.addDialog("meta");
00482 skin.addDialog("quit");
00483 skin.addDialog("disconnect");
00484 skin.addDialog("connect");
00485 skin.addDialog("start");
00486 skin.addDialog("account_main");
00487 skin.addDialog("account_characters");
00488 definedFonts.clear();
00489 textButtonFactory = null;
00490 dialogFactory = null;
00491 checkBoxFactory = null;
00492 try {
00493 load(skinSource, "global", crossfireServerConnection, guiStateManager, tooltipManager, windowRenderer, elementListener, metaserverModel, characterModel, commandQueue, null, shortcuts, commandExecutor, currentSpellManager, commandCallback, macros, nextGroupFace, prevGroupFace, smoothFaces);
00494 while (true) {
00495 final String name = skin.getDialogToLoad();
00496 if (name == null) {
00497 break;
00498 }
00499 final Gui gui = skin.getDialog(name);
00500 load(skinSource, name, crossfireServerConnection, guiStateManager, tooltipManager, windowRenderer, elementListener, metaserverModel, characterModel, commandQueue, gui, shortcuts, commandExecutor, currentSpellManager, commandCallback, macros, nextGroupFace, prevGroupFace, smoothFaces);
00501 }
00502 } finally {
00503 definedFonts.clear();
00504 textButtonFactory = null;
00505 dialogFactory = null;
00506 checkBoxFactory = null;
00507 imageParser.clear();
00508 }
00509
00510 skinToDetach = null;
00511 } finally {
00512 if (skinToDetach != null) {
00513 skinToDetach.detach();
00514 windowRenderer.setTooltip(null);
00515 }
00516 }
00517
00518 return skin;
00519 }
00520
00544 private void load(@NotNull final JXCSkinSource skinSource, @NotNull final String dialogName, @NotNull final CrossfireServerConnection server, @NotNull final GuiStateManager guiStateManager, @NotNull final TooltipManager tooltipManager, @NotNull final JXCWindowRenderer windowRenderer, @NotNull final GUIElementListener elementListener, @NotNull final MetaserverModel metaserverModel, @NotNull final CharacterModel characterModel, @NotNull final CommandQueue commandQueue, @Nullable final Gui gui, @NotNull final Shortcuts shortcuts, @NotNull final CommandExecutor commandExecutor, @NotNull final CurrentSpellManager currentSpellManager, @NotNull final CommandCallback commandCallback, @NotNull final Macros macros, @NotNull final Image nextGroupFace, @NotNull final Image prevGroupFace, @NotNull final SmoothFaces smoothFaces) throws JXCSkinException {
00545 String resourceName = dialogName+".skin";
00546
00547 definedGUIElements.clear();
00548 try {
00549 InputStream inputStream;
00550 try {
00551 inputStream = skinSource.getInputStream(resourceName);
00552 } catch (final IOException ignored) {
00553 resourceName = dialogName+".skin";
00554 inputStream = skinSource.getInputStream(resourceName);
00555 }
00556 try {
00557 load(skinSource, dialogName, resourceName, inputStream, server, guiStateManager, tooltipManager, windowRenderer, elementListener, metaserverModel, characterModel, commandQueue, gui, shortcuts, commandExecutor, currentSpellManager, commandCallback, macros, nextGroupFace, prevGroupFace, smoothFaces);
00558 } finally {
00559 inputStream.close();
00560 }
00561 } catch (final IOException ex) {
00562 throw new JXCSkinException(skinSource.getURI(resourceName)+": "+ex.getMessage());
00563 } catch (final JXCSkinException ex) {
00564 throw new JXCSkinException(skinSource.getURI(resourceName)+": "+ex.getMessage());
00565 } finally {
00566 definedGUIElements.clear();
00567 }
00568 }
00569
00596 private void load(@NotNull final JXCSkinSource skinSource, @NotNull final String dialogName, @NotNull final String resourceName, @NotNull final InputStream inputStream, @NotNull final CrossfireServerConnection server, @NotNull final GuiStateManager guiStateManager, @NotNull final TooltipManager tooltipManager, @NotNull final JXCWindowRenderer windowRenderer, @NotNull final GUIElementListener elementListener, @NotNull final MetaserverModel metaserverModel, @NotNull final CharacterModel characterModel, @NotNull final CommandQueue commandQueue, @Nullable final Gui gui, @NotNull final Shortcuts shortcuts, @NotNull final CommandExecutor commandExecutor, @NotNull final CurrentSpellManager currentSpellManager, @NotNull final CommandCallback commandCallback, @NotNull final Macros macros, @NotNull final Image nextGroupFace, @NotNull final Image prevGroupFace, @NotNull final SmoothFaces smoothFaces) throws JXCSkinException {
00597 try {
00598 final InputStreamReader isr = new InputStreamReader(inputStream, "UTF-8");
00599 try {
00600 final LineNumberReader lnr = new LineNumberReader(isr);
00601 try {
00602 boolean isDialog = false;
00603 while (true) {
00604 final String line = lnr.readLine();
00605 if (line == null) {
00606 break;
00607 }
00608
00609 if (line.startsWith("#") || line.length() == 0) {
00610 continue;
00611 }
00612
00613 final String[] argsTmp;
00614 try {
00615 argsTmp = StringUtils.splitFields(line);
00616 } catch (final UnterminatedTokenException ex) {
00617 throw new JXCSkinException(ex.getMessage());
00618 }
00619 final Args args = new Args(argsTmp);
00620 final String cmd = args.get();
00621 if (gui != null && cmd.equals("button")) {
00622 parseButton(args, tooltipManager, elementListener, lnr);
00623 } else if (gui != null && cmd.equals("checkbox")) {
00624 parseCheckbox(args, tooltipManager, elementListener, lnr);
00625 } else if (cmd.equals("commandlist")) {
00626 parseCommandList(args, guiStateManager, lnr, commandExecutor, commandQueue, server, commandCallback, macros);
00627 } else if (cmd.equals("commandlist_add")) {
00628 parseCommandListAdd(args, guiStateManager, lnr, commandExecutor, commandQueue, server, commandCallback, macros);
00629 } else if (gui != null && cmd.equals("command_text")) {
00630 parseCommandText(args, commandCallback, tooltipManager, elementListener, commandExecutor);
00631 } else if (cmd.equals("def")) {
00632 parseDef(args, lnr);
00633 } else if (gui != null && cmd.equals("dialog")) {
00634 if (isDialog) {
00635 throw new JXCSkinException("'dialog' must not be used more than once per dialog");
00636 }
00637 parseDialog(args, tooltipManager, windowRenderer, elementListener, lnr, gui, dialogName);
00638 isDialog = true;
00639 } else if (gui != null && cmd.equals("dialog_hide")) {
00640 parseDialogHide(args, gui);
00641 } else if (gui != null && cmd.equals("dupgauge")) {
00642 parseDupGauge(args, tooltipManager, elementListener, lnr);
00643 } else if (gui != null && cmd.equals("duptextgauge")) {
00644 parseDupTextGauge(args, tooltipManager, elementListener, lnr);
00645 } else if (cmd.equals("event")) {
00646 parseEvent(args, guiStateManager, server);
00647 } else if (gui != null && cmd.equals("fill")) {
00648 parseFill(args, tooltipManager, elementListener);
00649 } else if (cmd.equals("font")) {
00650 parseFont(args);
00651 } else if (gui != null && cmd.equals("gauge")) {
00652 parseGauge(args, tooltipManager, elementListener, lnr);
00653 } else if (gui != null && cmd.equals("ignore")) {
00654 parseIgnore(args);
00655 } else if (gui != null && cmd.equals("inventory_list")) {
00656 parseList(args, ListType.INVENTORY, tooltipManager, elementListener, commandQueue, server, currentSpellManager, nextGroupFace, prevGroupFace);
00657 } else if (gui != null && cmd.equals("floor_list")) {
00658 parseList(args, ListType.GROUND, tooltipManager, elementListener, commandQueue, server, currentSpellManager, nextGroupFace, prevGroupFace);
00659 } else if (gui != null && cmd.equals("spells_list")) {
00660 parseList(args, ListType.SPELL, tooltipManager, elementListener, commandQueue, server, currentSpellManager, nextGroupFace, prevGroupFace);
00661 } else if (gui != null && cmd.equals("quests_list")) {
00662 parseList(args, ListType.QUEST, tooltipManager, elementListener, commandQueue, server, currentSpellManager, nextGroupFace, prevGroupFace);
00663 } else if (gui != null && cmd.equals("horizontal")) {
00664 parseHorizontal(args, gui, lnr, isDialog);
00665 } else if (gui != null && cmd.equals("item")) {
00666 parseItem(args, tooltipManager, elementListener, commandQueue, server, shortcuts, currentSpellManager, nextGroupFace, prevGroupFace);
00667 } else if (cmd.equals("key")) {
00668 parseKey(args, gui, line);
00669 } else if (gui != null && cmd.equals("label_html")) {
00670 parseLabelHtml(args, tooltipManager, elementListener, lnr);
00671 } else if (gui != null && cmd.equals("label_multi")) {
00672 parseLabelMulti(args, tooltipManager, elementListener, lnr);
00673 } else if (gui != null && cmd.equals("label_query")) {
00674 parseLabelQuery(args, tooltipManager, elementListener, server);
00675 } else if (gui != null && cmd.equals("label_failure")) {
00676 parseLabelFailure(args, tooltipManager, elementListener, server);
00677 } else if (gui != null && cmd.equals("label_message")) {
00678 parseLabelMessage(args, tooltipManager, elementListener, server, windowRenderer);
00679 } else if (gui != null && cmd.equals("label_text")) {
00680 parseLabelText(args, tooltipManager, elementListener, lnr);
00681 } else if (gui != null && cmd.equals("label_stat")) {
00682 parseLabelStat(args, tooltipManager, elementListener);
00683 } else if (gui != null && cmd.equals("label_stat2")) {
00684 parseLabelStat2(args, tooltipManager, elementListener);
00685 } else if (gui != null && cmd.equals("label_spell")) {
00686 parseLabelSpell(args, tooltipManager, elementListener, currentSpellManager);
00687 } else if (gui != null && cmd.equals("link_size")) {
00688 parseLinkSize(args, gui);
00689 } else if (gui != null && cmd.equals("log_label")) {
00690 parseLogLabel(args, tooltipManager, elementListener);
00691 } else if (gui != null && cmd.equals("log_message")) {
00692 parseLogMessage(args, tooltipManager, elementListener, server);
00693 } else if (gui != null && cmd.equals("log_color")) {
00694 parseLogColor(args);
00695 } else if (gui != null && cmd.equals("log_filter")) {
00696 parseLogFilter(args);
00697 } else if (gui != null && cmd.equals("minimap")) {
00698 parseMinimap(args, tooltipManager, elementListener);
00699 } else if (gui != null && cmd.equals("map")) {
00700 parseMap(args, tooltipManager, elementListener, server, smoothFaces);
00701 } else if (gui != null && cmd.equals("meta_list")) {
00702 parseMetaList(args, tooltipManager, elementListener, metaserverModel);
00703 } else if (gui != null && cmd.equals("picture")) {
00704 parsePicture(args, tooltipManager, elementListener);
00705 } else if (gui != null && cmd.equals("query_text")) {
00706 parseQueryText(args, server, commandCallback, tooltipManager, elementListener);
00707 } else if (gui != null && cmd.equals("set_forced_active")) {
00708 parseSetForcedActive(args, gui);
00709 } else if (gui != null && cmd.equals("set_auto_size")) {
00710 parseSetAutoSize(gui, args);
00711 } else if (gui != null && cmd.equals("set_default")) {
00712 parseSetDefault(args);
00713 } else if (gui != null && cmd.equals("set_invisible")) {
00714 parseSetInvisible(args);
00715 } else if (gui != null && cmd.equals("set_modal")) {
00716 parseSetModal(gui);
00717 } else if (gui != null && cmd.equals("scrollbar")) {
00718 parseScrollbar(args, tooltipManager, elementListener);
00719 } else if (gui == null && cmd.equals("skin_name")) {
00720 parseSkinName(args);
00721 } else if (gui != null && cmd.equals("text")) {
00722 parseText(args, commandCallback, tooltipManager, elementListener);
00723 } else if (gui != null && cmd.equals("textbutton")) {
00724 parseTextButton(args, tooltipManager, elementListener, lnr);
00725 } else if (gui != null && cmd.equals("textgauge")) {
00726 parseTextGauge(args, tooltipManager, elementListener, lnr);
00727 } else if (cmd.equals("tooltip")) {
00728 parseTooltip(args, tooltipManager, elementListener);
00729 } else if (cmd.equals("vertical")) {
00730 parseVertical(args, gui, lnr, isDialog);
00731 } else if (cmd.equals("character_list")) {
00732 parseCharacterList(args, tooltipManager, elementListener, characterModel);
00733 } else if (cmd.equals("hide_input")) {
00734 parseHideInput(args);
00735 } else {
00736 throw new IOException("unknown keyword '"+cmd+"'");
00737 }
00738
00739 if (args.hasMore()) {
00740 throw new IOException("excess arguments");
00741 }
00742 }
00743 } catch (final IOException ex) {
00744 throw new IOException(ex.getMessage()+" in line "+lnr.getLineNumber());
00745 } catch (final JXCSkinException ex) {
00746 throw new IOException(ex.getMessage()+" in line "+lnr.getLineNumber());
00747 } catch (final IllegalArgumentException ex) {
00748 final Object msg = ex.getMessage();
00749 if (msg != null) {
00750 throw new IOException("invalid parameter ("+ex.getMessage()+") in line "+lnr.getLineNumber());
00751 } else {
00752 throw new IOException("invalid parameter in line "+lnr.getLineNumber());
00753 }
00754 } finally {
00755 lnr.close();
00756 }
00757 } finally {
00758 isr.close();
00759 }
00760 } catch (final IOException ex) {
00761 throw new JXCSkinException(skinSource.getURI(resourceName)+": "+ex.getMessage());
00762 }
00763
00764 final Iterator<AbstractGUIElement> it = definedGUIElements.iterator();
00765 if (gui == null) {
00766 assert !it.hasNext();
00767 }
00768
00769
00770
00771
00772
00773
00774
00775
00776
00777
00778
00779 }
00780
00790 private void parseButton(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
00791 final String name = args.get();
00792 final BufferedImage upImage = imageParser.getImage(args.get());
00793 final BufferedImage downImage = imageParser.getImage(args.get());
00794 final boolean autoRepeat = NumberParser.parseBoolean(args.get());
00795 final CommandList commandList = skin.getCommandList(args.get());
00796 @Nullable final String label;
00797 @Nullable final Font font;
00798 @Nullable final Color color;
00799 final int textX;
00800 final int textY;
00801 if (args.hasMore()) {
00802 font = definedFonts.lookup(args.get());
00803 color = ParseUtils.parseColor(args.get());
00804 textX = ExpressionParser.parseInt(args.get());
00805 textY = ExpressionParser.parseInt(args.get());
00806 label = ParseUtils.parseText(args, lnr);
00807 } else {
00808 label = null;
00809 font = null;
00810 color = null;
00811 textX = 0;
00812 textY = 0;
00813 }
00814 insertGuiElement(new GUIButton(tooltipManager, elementListener, name, upImage, downImage, label, font, color, textX, textY, autoRepeat, commandList));
00815 }
00816
00826 private void parseCheckbox(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
00827 if (checkBoxFactory == null) {
00828 throw new IOException("missing 'def checkbox' command");
00829 }
00830
00831 final String name = args.get();
00832 final CheckBoxOption option = ParseUtils.parseCheckBoxOption(args.get(), optionManager);
00833 final String text = ParseUtils.parseText(args, lnr);
00834 assert checkBoxFactory != null;
00835 insertGuiElement(checkBoxFactory.newCheckBox(tooltipManager, elementListener, name, option, text));
00836 }
00837
00851 private void parseCommandList(@NotNull final Args args, @NotNull final GuiStateManager guiStateManager, @NotNull final LineNumberReader lnr, @NotNull final CommandExecutor commandExecutor, @NotNull final CommandQueue commandQueue, @NotNull final CrossfireServerConnection server, @NotNull final CommandCallback commandCallback, @NotNull final Macros macros) throws IOException, JXCSkinException {
00852 final String commandListName = args.get();
00853 final CommandListType commandListType = NumberParser.parseEnum(CommandListType.class, args.get(), "type");
00854 skin.addCommandList(commandListName, commandListType);
00855 if (args.hasMore()) {
00856 final AbstractGUIElement element = args.get().equals("null") ? null : definedGUIElements.lookup(args.getPrev());
00857 addCommand(commandListName, args, element, args.get(), guiStateManager, commandExecutor, lnr, commandQueue, server, commandCallback, macros);
00858 }
00859 }
00860
00874 private void parseCommandListAdd(@NotNull final Args args, @NotNull final GuiStateManager guiStateManager, @NotNull final LineNumberReader lnr, @NotNull final CommandExecutor commandExecutor, @NotNull final CommandQueue commandQueue, @NotNull final CrossfireServerConnection server, @NotNull final CommandCallback commandCallback, @NotNull final Macros macros) throws IOException, JXCSkinException {
00875 final String name = args.get();
00876 final AbstractGUIElement element = args.get().equals("null") ? null : definedGUIElements.lookup(args.getPrev());
00877 addCommand(name, args, element, args.get(), guiStateManager, commandExecutor, lnr, commandQueue, server, commandCallback, macros);
00878 }
00879
00890 private void parseCommandText(@NotNull final Args args, @NotNull final CommandCallback commandCallback, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CommandExecutor commandExecutor) throws IOException, JXCSkinException {
00891 final String name = args.get();
00892 final Image activeImage = imageParser.getImage(args.get());
00893 final Image inactiveImage = imageParser.getImage(args.get());
00894 final Font font = definedFonts.lookup(args.get());
00895 final Color inactiveColor = ParseUtils.parseColor(args.get());
00896 final Color activeColor = ParseUtils.parseColor(args.get());
00897 final int margin = ExpressionParser.parseInt(args.get());
00898 final boolean enableHistory = NumberParser.parseBoolean(args.get());
00899 insertGuiElement(new GUICommandText(commandCallback, tooltipManager, elementListener, name, activeImage, inactiveImage, font, inactiveColor, activeColor, margin, "", commandExecutor, enableHistory));
00900 }
00901
00909 private void parseDef(@NotNull final Args args, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
00910 final String type = args.get();
00911 if (type.equals("checkbox")) {
00912 final BufferedImage checkedImage = imageParser.getImage(args.get());
00913 final BufferedImage uncheckedImage = imageParser.getImage(args.get());
00914 final Font font = definedFonts.lookup(args.get());
00915 final Color color = ParseUtils.parseColor(args.get());
00916 checkBoxFactory = new CheckBoxFactory(checkedImage, uncheckedImage, font, color);
00917 } else if (type.equals("checkbox_option")) {
00918 final String optionName = args.get();
00919 final CommandList commandOn = skin.getCommandList(args.get());
00920 final CommandList commandOff = skin.getCommandList(args.get());
00921 final String documentation = ParseUtils.parseText(args, lnr);
00922 skin.addOption(optionName, documentation, new CommandCheckBoxOption(commandOn, commandOff, documentation));
00923 } else if (type.equals("dialog")) {
00924 final String frame = args.get();
00925 final Image frameNW = imageParser.getImage(frame+"_nw");
00926 final Image frameN = imageParser.getImage(frame+"_n");
00927 final Image frameNE = imageParser.getImage(frame+"_ne");
00928 final Image frameW = imageParser.getImage(frame+"_w");
00929 final Image frameC = imageParser.getImage(frame+"_c");
00930 final Image frameE = imageParser.getImage(frame+"_e");
00931 final Image frameSW = imageParser.getImage(frame+"_sw");
00932 final Image frameS = imageParser.getImage(frame+"_s");
00933 final Image frameSE = imageParser.getImage(frame+"_se");
00934 final Font titleFont = definedFonts.lookup(args.get());
00935 final Color titleColor = ParseUtils.parseColor(args.get());
00936 final Color titleBackgroundColor = ParseUtils.parseColor(args.get());
00937 final float alpha = NumberParser.parseFloat(args.get());
00938 if (alpha < 0 || alpha > 1F) {
00939 throw new IOException("invalid alpha value: "+alpha);
00940 }
00941 dialogFactory = new DialogFactory(frameNW, frameN, frameNE, frameW, frameC, frameE, frameSW, frameS, frameSE, titleFont, titleColor, titleBackgroundColor, alpha);
00942 } else if (type.equals("item")) {
00943 final Color cursedColor = ParseUtils.parseColorNull(args.get());
00944 final Image cursedImage = imageParser.getImage(cursedColor, args.getPrev());
00945 final Color damnedColor = ParseUtils.parseColorNull(args.get());
00946 final Image damnedImage = imageParser.getImage(damnedColor, args.getPrev());
00947 final Color magicColor = ParseUtils.parseColorNull(args.get());
00948 final Image magicImage = imageParser.getImage(magicColor, args.getPrev());
00949 final Color blessedColor = ParseUtils.parseColorNull(args.get());
00950 final Image blessedImage = imageParser.getImage(blessedColor, args.getPrev());
00951 final Color appliedColor = ParseUtils.parseColorNull(args.get());
00952 final Image appliedImage = imageParser.getImage(appliedColor, args.getPrev());
00953 final Color unidentifiedColor = ParseUtils.parseColorNull(args.get());
00954 final Image unidentifiedImage = imageParser.getImage(unidentifiedColor, args.getPrev());
00955 final Color selectorColor = ParseUtils.parseColorNull(args.get());
00956 final Image selectorImage = imageParser.getImage(selectorColor, args.getPrev());
00957 final Color lockedColor = ParseUtils.parseColorNull(args.get());
00958 final Image lockedImage = imageParser.getImage(lockedColor, args.getPrev());
00959 final Color unpaidColor = ParseUtils.parseColorNull(args.get());
00960 final Image unpaidImage = imageParser.getImage(unpaidColor, args.getPrev());
00961 final Font font = definedFonts.lookup(args.get());
00962 final Color nrofColor = ParseUtils.parseColor(args.get());
00963 defaultItemPainter = new ItemPainter(cursedImage, damnedImage, magicImage, blessedImage, appliedImage, unidentifiedImage, selectorImage, lockedImage, unpaidImage, cursedColor, damnedColor, magicColor, blessedColor, appliedColor, unidentifiedColor, selectorColor, lockedColor, unpaidColor, font, nrofColor);
00964 } else if (type.equals("textbutton")) {
00965 final String up = args.get();
00966 final String down = args.get();
00967 final Font font = definedFonts.lookup(args.get());
00968 final Color color = ParseUtils.parseColor(args.get());
00969 final Color colorSelected = ParseUtils.parseColor(args.get());
00970 final ButtonImages upImages = new ButtonImages(imageParser.getImage(up+"_w"), imageParser.getImage(up+"_c"), imageParser.getImage(up+"_e"));
00971 final ButtonImages downImages = new ButtonImages(imageParser.getImage(down+"_w"), imageParser.getImage(down+"_c"), imageParser.getImage(down+"_e"));
00972 textButtonFactory = new TextButtonFactory(upImages, downImages, font, color, colorSelected);
00973 } else {
00974 throw new IOException("unknown type '"+type+"'");
00975 }
00976 }
00977
00990 private void parseDialog(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final JXCWindowRenderer windowRenderer, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr, @NotNull final Gui gui, @NotNull final String dialogName) throws IOException, JXCSkinException {
00991 if (dialogFactory == null) {
00992 throw new IOException("missing 'def dialog' command");
00993 }
00994
00995 final Expression defaultX = ExpressionParser.parseExpression(args.get());
00996 final Expression defaultY = ExpressionParser.parseExpression(args.get());
00997 final boolean saveDialog = NumberParser.parseBoolean(args.get());
00998 final String title = ParseUtils.parseText(args, lnr);
00999 assert dialogFactory != null;
01000 final Iterable<AbstractGUIElement> elements = dialogFactory.newDialog(tooltipManager, windowRenderer, elementListener, title);
01001 for (final AbstractGUIElement element : elements) {
01002 insertGuiElement(element);
01003 }
01004 gui.setName(dialogName);
01005 gui.setDefaultPosition(defaultX, defaultY);
01006 if (saveDialog) {
01007 gui.setSaveDialog();
01008 }
01009 }
01010
01017 private static void parseDialogHide(@NotNull final Args args, @NotNull final Gui gui) throws IOException {
01018 do {
01019 gui.hideInState(NumberParser.parseEnum(RendererGuiState.class, args.get(), "gui state"));
01020 } while (args.hasMore());
01021 }
01022
01032 private void parseDupGauge(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
01033 final String name = args.get();
01034 final Image positiveDivImage = imageParser.getImage(args.get());
01035 final Image positiveModImage = imageParser.getImage(args.get());
01036 final Image emptyImage = args.get().equals("null") ? null : imageParser.getImage(args.getPrev());
01037 final GaugeUpdater gaugeUpdater = newGaugeUpdater(args.get());
01038 final Orientation orientationDiv = ParseUtils.parseOrientation(args.get());
01039 final Orientation orientationMod = ParseUtils.parseOrientation(args.get());
01040 final String tooltipPrefix = ParseUtils.parseText(args, lnr);
01041 final GUIDupGauge element = new GUIDupGauge(tooltipManager, elementListener, name, positiveDivImage, positiveModImage, emptyImage, orientationDiv, orientationMod, tooltipPrefix.length() > 0 ? tooltipPrefix : null);
01042 insertGuiElement(element);
01043 gaugeUpdater.setGauge(element);
01044 }
01045
01055 private void parseDupTextGauge(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
01056 final String name = args.get();
01057 final Image positiveDivImage = imageParser.getImage(args.get());
01058 final Image positiveModImage = imageParser.getImage(args.get());
01059 final Image emptyImage = imageParser.getImage(args.get());
01060 final GaugeUpdater gaugeUpdater = newGaugeUpdater(args.get());
01061 final Orientation orientationDiv = ParseUtils.parseOrientation(args.get());
01062 final Orientation orientationMod = ParseUtils.parseOrientation(args.get());
01063 final Color color = ParseUtils.parseColor(args.get());
01064 final Font font = definedFonts.lookup(args.get());
01065 final String tooltipPrefix = ParseUtils.parseText(args, lnr);
01066 final GUIDupTextGauge element = new GUIDupTextGauge(tooltipManager, elementListener, name, positiveDivImage, positiveModImage, emptyImage, orientationDiv, orientationMod, tooltipPrefix.length() > 0 ? tooltipPrefix : null, color, font);
01067 insertGuiElement(element);
01068 gaugeUpdater.setGauge(element);
01069 }
01070
01079 private void parseEvent(@NotNull final Args args, @NotNull final GuiStateManager guiStateManager, @NotNull final CrossfireServerConnection server) throws IOException, JXCSkinException {
01080 final String type = args.get();
01081 if (type.equals("connect")) {
01082 final CommandList commandList = skin.getCommandList(args.get());
01083 skin.addSkinEvent(new ConnectionStateSkinEvent(commandList, guiStateManager));
01084 } else if (type.equals("init")) {
01085 skin.addInitEvent(skin.getCommandList(args.get()));
01086 } else if (type.equals("magicmap")) {
01087 final CommandList commandList = skin.getCommandList(args.get());
01088 skin.addSkinEvent(new CrossfireMagicmapSkinEvent(commandList, server));
01089 } else if (type.equals("mapscroll")) {
01090 final CommandList commandList = skin.getCommandList(args.get());
01091 skin.addSkinEvent(new MapScrollSkinEvent(commandList, mapUpdaterState));
01092 } else if (type.equals("skill")) {
01093 final String subtype = args.get();
01094 final Skill skill = skillSet.getNamedSkill(args.get().replaceAll("_", " "));
01095 final CommandList commandList = skin.getCommandList(args.get());
01096 if (subtype.equals("add")) {
01097 skin.addSkinEvent(new SkillAddedSkinEvent(commandList, skill));
01098 } else if (subtype.equals("del")) {
01099 skin.addSkinEvent(new SkillRemovedSkinEvent(commandList, skill));
01100 } else {
01101 throw new IOException("undefined event sub-type: "+subtype);
01102 }
01103 } else {
01104 throw new IOException("undefined event type: "+type);
01105 }
01106 }
01107
01116 private void parseFill(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
01117 final String name = args.get();
01118 final Color color = ParseUtils.parseColor(args.get());
01119 final float alpha = NumberParser.parseFloat(args.get());
01120 if (alpha < 0 || alpha > 1F) {
01121 throw new IOException("invalid alpha value: "+alpha);
01122 }
01123 insertGuiElement(new GUIFill(tooltipManager, elementListener, name, color, alpha));
01124 }
01125
01132 private void parseFont(@NotNull final Args args) throws IOException, JXCSkinException {
01133 final String name = args.get();
01134 final Font fontNormal = fontParser.getFont(args.get());
01135 final Font font = fontNormal.deriveFont(NumberParser.parseFloat(args.get()));
01136 definedFonts.insert(name, font);
01137 }
01138
01148 private void parseGauge(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
01149 if (dialogFactory == null) {
01150 throw new IOException("missing 'def dialog' command");
01151 }
01152
01153 final String name = args.get();
01154 final Image positiveImage = args.get().equals("null") ? null : imageParser.getImage(args.getPrev());
01155 final Image negativeImage = args.get().equals("null") ? null : imageParser.getImage(args.getPrev());
01156 final Image emptyImage = args.get().equals("null") ? null : imageParser.getImage(args.getPrev());
01157 final GaugeUpdater gaugeUpdater = newGaugeUpdater(args.get());
01158 final Orientation orientation = ParseUtils.parseOrientation(args.get());
01159 final String tooltipPrefix = ParseUtils.parseText(args, lnr);
01160 assert dialogFactory != null;
01161 final float alpha = dialogFactory.getFrameAlpha();
01162 final GUIGauge element = new GUIGauge(tooltipManager, elementListener, name, positiveImage, negativeImage, emptyImage, orientation, tooltipPrefix.length() > 0 ? tooltipPrefix : null, alpha);
01163 insertGuiElement(element);
01164 gaugeUpdater.setGauge(element);
01165 }
01166
01173 private void parseIgnore(@NotNull final Args args) throws IOException, JXCSkinException {
01174 final String name = args.get();
01175 definedGUIElements.lookup(name).setIgnore();
01176 }
01177
01192 private void parseList(@NotNull final Args args, final ListType type, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CommandQueue commandQueue, @NotNull final CrossfireServerConnection server, @NotNull final CurrentSpellManager currentSpellManager, @NotNull final Image nextGroupFace, @NotNull final Image prevGroupFace) throws IOException, JXCSkinException {
01193 if (defaultItemPainter == null) {
01194 throw new IOException("cannot use '"+type.toString()+"_list"+"' without 'def item' command");
01195 }
01196
01197 final String name = args.get();
01198 final int cellWidth = ExpressionParser.parseInt(args.get());
01199 final int cellHeight = ExpressionParser.parseInt(args.get());
01200 final AbstractLabel selectedItem = args.get().equals("null") ? null : guiElementParser.lookupLabelElement(args.getPrev());
01201
01202 assert defaultItemPainter != null;
01203 final ItemPainter itemPainter = defaultItemPainter.newItemPainter();
01204 final AbstractGUIElement element;
01205 switch (type) {
01206 case INVENTORY:
01207 final GUIItemItemFactory inventoryItemFactory = new GUIItemInventoryFactory(tooltipManager, elementListener, commandQueue, name, itemPainter, server, facesManager, floorView, inventoryView);
01208 element = new GUIItemList(tooltipManager, elementListener, name, cellWidth, cellHeight, inventoryView, selectedItem, inventoryItemFactory);
01209 break;
01210
01211 case GROUND:
01212 final GUIItemItemFactory groundItemFactory = new GUIItemFloorFactory(tooltipManager, elementListener, commandQueue, name, itemPainter, server, facesManager, floorView, itemSet, nextGroupFace, prevGroupFace);
01213 element = new GUIFloorList(tooltipManager, elementListener, name, cellWidth, cellHeight, floorView, selectedItem, groundItemFactory);
01214 break;
01215
01216 case SPELL:
01217 final GUIItemItemFactory spellItemFactory = new GUIItemSpellListFactory(tooltipManager, elementListener, commandQueue, name, itemPainter, facesManager, spellsManager, currentSpellManager, spellView);
01218 element = new GUISpellList(tooltipManager, elementListener, name, cellWidth, cellHeight, spellView, selectedItem, spellItemFactory, spellsManager, keybindingsManager);
01219 break;
01220
01221 case QUEST:
01222 final GUIItemItemFactory questItemFactory = new GUIItemQuestListFactory(tooltipManager, elementListener, name, itemPainter, facesManager, questsManager, questView);
01223 element = new GUIQuestList(tooltipManager, elementListener, name, cellWidth, cellHeight, questView, selectedItem, questItemFactory, questsManager);
01224 break;
01225
01226 default:
01227 throw new AssertionError("unhandled type "+type);
01228 }
01229 insertGuiElement(element);
01230 }
01231
01242 private void parseHorizontal(@NotNull final Args args, @NotNull final Container gui, @NotNull final LineNumberReader lnr, final boolean isDialog) throws IOException, JXCSkinException {
01243 final GroupLayout layout = (GroupLayout)gui.getLayout();
01244 final String begin = args.get();
01245 if (!begin.equals("begin")) {
01246 throw new IOException("syntax error: expecting 'begin'");
01247 }
01248 final Collection<GUIElement> unreferencedElements = new TreeSet<GUIElement>(ELEMENT_COMPARATOR);
01249 for (final GUIElement element : definedGUIElements) {
01250 unreferencedElements.add(element);
01251 }
01252 if (!isDialog) {
01253 final GroupLayout.Group content = parseBegin(args, layout, lnr, unreferencedElements);
01254 if (!unreferencedElements.isEmpty()) {
01255 throw new IOException("layout doesn't define elements "+unreferencedElements);
01256 }
01257 layout.setHorizontalGroup(content);
01258 return;
01259 }
01260 final Component background = getUnreferencedElement("dialog_background", unreferencedElements);
01261 if (background == null) {
01262 throw new AssertionError("element 'dialog_background' is missing");
01263 }
01264 final GroupLayout.Group content = parseBegin(args, layout, lnr, unreferencedElements);
01265 final Component title = getUnreferencedElement("dialog_title", unreferencedElements);
01266 final Component close = getUnreferencedElement("dialog_close", unreferencedElements);
01267 final GroupLayout.Group group2 = layout.createSequentialGroup();
01268 group2.addGap(DIALOG_BORDER_WIDTH);
01269 if (title == null) {
01270 if (close == null) {
01271 final GroupLayout.Group group3 = layout.createParallelGroup();
01272 group3.addGroup(content);
01273 group2.addGroup(group3);
01274 } else {
01275 final GroupLayout.Group group3 = layout.createParallelGroup();
01276 group3.addGap(0, 0, Short.MAX_VALUE);
01277 group3.addComponent(close);
01278 group2.addGroup(group3);
01279 group2.addGroup(content);
01280 }
01281 } else {
01282 final GroupLayout.Group group3 = layout.createParallelGroup();
01283 if (close == null) {
01284 group3.addComponent(title);
01285 group3.addGroup(content);
01286 } else {
01287 final GroupLayout.Group group4 = layout.createSequentialGroup();
01288 group4.addComponent(title);
01289 group4.addComponent(close);
01290 group3.addGroup(group4);
01291 group3.addGroup(content);
01292 }
01293 group2.addGroup(group3);
01294 }
01295 group2.addGap(DIALOG_BORDER_WIDTH);
01296 if (!unreferencedElements.isEmpty()) {
01297 throw new IOException("layout doesn't define elements "+unreferencedElements);
01298 }
01299
01300 final GroupLayout.Group group1 = layout.createParallelGroup();
01301 group1.addGroup(group2);
01302 group1.addComponent(background);
01303
01304 layout.setHorizontalGroup(group1);
01305 }
01306
01313 @Nullable
01314 private Component getUnreferencedElement(@NotNull final String name, @NotNull final Collection<GUIElement> unreferencedElements) {
01315 final AbstractGUIElement component = definedGUIElements.lookupOptional(name);
01316 if (component == null) {
01317 return null;
01318 }
01319
01320 return unreferencedElements.remove(component) ? component : null;
01321 }
01322
01337 private void parseItem(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CommandQueue commandQueue, @NotNull final CrossfireServerConnection server, @NotNull final Shortcuts shortcuts, @NotNull final CurrentSpellManager currentSpellManager, @NotNull final Image nextGroupFace, @NotNull final Image prevGroupFace) throws IOException, JXCSkinException {
01338 final String type = args.get();
01339 final String name = args.get();
01340 final int index = ExpressionParser.parseInt(args.get());
01341 final AbstractGUIElement element;
01342 if (type.equals("floor")) {
01343 if (defaultItemPainter == null) {
01344 throw new IOException("cannot use 'item floor' without 'def item' command");
01345 }
01346
01347 final ItemPainter itemPainter = defaultItemPainter.newItemPainter();
01348 element = new GUIItemFloor(tooltipManager, elementListener, commandQueue, name, itemPainter, index, server, floorView, itemSet, facesManager, nextGroupFace, prevGroupFace);
01349 } else if (type.equals("inventory")) {
01350 if (defaultItemPainter == null) {
01351 throw new IOException("cannot use 'item inventory' without 'def item' command");
01352 }
01353
01354 final ItemPainter itemPainter = defaultItemPainter.newItemPainter();
01355 element = new GUIItemInventory(tooltipManager, elementListener, commandQueue, name, itemPainter, index, server, facesManager, floorView, inventoryView);
01356 } else if (type.equals("shortcut")) {
01357 final Color castColor = ParseUtils.parseColorNull(args.get());
01358 final Image castImage = imageParser.getImage(castColor, args.getPrev());
01359 final Color invokeColor = ParseUtils.parseColorNull(args.get());
01360 final Image invokeImage = imageParser.getImage(invokeColor, args.getPrev());
01361 final Font font = definedFonts.lookup(args.get());
01362 element = new GUIItemShortcut(tooltipManager, elementListener, name, castColor, castImage, invokeColor, invokeImage, index, facesManager, shortcuts, font, currentSpellManager);
01363 } else if (type.equals("spelllist")) {
01364 if (defaultItemPainter == null) {
01365 throw new IOException("cannot use 'item spelllist' without 'def item' command");
01366 }
01367
01368 final ItemPainter itemPainter = defaultItemPainter.newItemPainter();
01369 element = new GUIItemSpell(tooltipManager, elementListener, commandQueue, name, itemPainter, index, facesManager, spellsManager, currentSpellManager, spellView);
01370 } else {
01371 throw new IOException("undefined item type: "+type);
01372 }
01373 insertGuiElement(element);
01374 }
01375
01383 private void parseKey(@NotNull final Args args, @Nullable final Gui gui, @NotNull final String line) throws IOException {
01384 final KeyBindings keyBindings = gui != null ? gui.getKeyBindings() : skin.getDefaultKeyBindings();
01385 try {
01386 keyBindings.parseKeyBinding(line.substring(4).trim(), true);
01387 } catch (final InvalidKeyBindingException ex) {
01388 throw new IOException("invalid key binding: "+ex.getMessage());
01389 }
01390
01391
01392 while (args.hasMore()) {
01393 args.get();
01394 }
01395 }
01396
01406 private void parseLabelHtml(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
01407 final String name = args.get();
01408 final Font font = definedFonts.lookup(args.get());
01409 final Color color = ParseUtils.parseColor(args.get());
01410 final String text = ParseUtils.parseText(args, lnr);
01411 insertGuiElement(new GUIHTMLLabel(tooltipManager, elementListener, name, null, font, color, null, text));
01412 }
01413
01423 private void parseLabelMulti(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
01424 final String name = args.get();
01425 final Font font = definedFonts.lookup(args.get());
01426 final Color color = ParseUtils.parseColor(args.get());
01427 final String text = ParseUtils.parseText(args, lnr);
01428 insertGuiElement(new GUIMultiLineLabel(tooltipManager, elementListener, name, null, font, color, null, Alignment.LEFT, text));
01429 }
01430
01440 private void parseLabelQuery(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CrossfireServerConnection server) throws IOException, JXCSkinException {
01441 final String name = args.get();
01442 final Font font = definedFonts.lookup(args.get());
01443 final Color color = ParseUtils.parseColor(args.get());
01444 final AbstractGUIElement element = new GUILabelQuery(tooltipManager, elementListener, name, server, font, color, null);
01445 insertGuiElement(element);
01446 }
01447
01458 private void parseLabelMessage(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CrossfireServerConnection server, @NotNull final JXCWindowRenderer windowRenderer) throws IOException, JXCSkinException {
01459 final String name = args.get();
01460 final Font font = definedFonts.lookup(args.get());
01461 final Color color = ParseUtils.parseColor(args.get());
01462 final AbstractGUIElement element = new GUILabelMessage(tooltipManager, elementListener, name, server, windowRenderer, font, color, null);
01463 insertGuiElement(element);
01464 }
01465
01475 private void parseLabelFailure(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CrossfireServerConnection server) throws IOException, JXCSkinException {
01476 final String name = args.get();
01477 final Font font = definedFonts.lookup(args.get());
01478 final Color color = ParseUtils.parseColor(args.get());
01479 final AbstractGUIElement element = new GUILabelFailure(tooltipManager, elementListener, name, server, font, color, null);
01480 insertGuiElement(element);
01481 }
01482
01492 private void parseLabelText(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
01493 final String name = args.get();
01494 final Font font = definedFonts.lookup(args.get());
01495 final Color color = ParseUtils.parseColor(args.get());
01496 final String text = ParseUtils.parseText(args, lnr);
01497 insertGuiElement(new GUIOneLineLabel(tooltipManager, elementListener, name, null, font, color, null, Alignment.LEFT, text));
01498 }
01499
01508 private void parseLabelStat(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
01509 final String name = args.get();
01510 final Font font = definedFonts.lookup(args.get());
01511 final Color color = ParseUtils.parseColor(args.get());
01512 final int stat = ParseUtils.parseStat(args.get());
01513 final Alignment alignment = NumberParser.parseEnum(Alignment.class, args.get(), "text alignment");
01514 final AbstractGUIElement element = new GUILabelStats(tooltipManager, elementListener, name, font, color, null, stat, alignment, stats);
01515 insertGuiElement(element);
01516 }
01517
01526 private void parseLabelStat2(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
01527 final String name = args.get();
01528 final Font font = definedFonts.lookup(args.get());
01529 final Color colorNormal = ParseUtils.parseColor(args.get());
01530 final Color colorUpgradable = ParseUtils.parseColor(args.get());
01531 final Color colorDepleted = ParseUtils.parseColor(args.get());
01532 final Color colorBoosted = ParseUtils.parseColor(args.get());
01533 final Color colorBoostedUpgradable = ParseUtils.parseColor(args.get());
01534 final int statCurrent = ParseUtils.parseStat(args.get());
01535 final int statBase = ParseUtils.parseStat(args.get());
01536 final int statRace = ParseUtils.parseStat(args.get());
01537 final int statApplied = ParseUtils.parseStat(args.get());
01538 final Alignment alignment = NumberParser.parseEnum(Alignment.class, args.get(), "text alignment");
01539 final AbstractGUIElement element = new GUILabelStats2(tooltipManager, elementListener, name, font, colorNormal, colorUpgradable, colorDepleted, colorBoosted, colorBoostedUpgradable, null, statCurrent, statBase, statRace, statApplied, alignment, stats);
01540 insertGuiElement(element);
01541 }
01542
01552 private void parseLabelSpell(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CurrentSpellManager currentSpellManager) throws IOException, JXCSkinException {
01553 final String name = args.get();
01554 final Font font = definedFonts.lookup(args.get());
01555 final Type type = NumberParser.parseEnum(Type.class, args.get(), "label type");
01556 final AbstractGUIElement element = new GUISpellLabel(tooltipManager, elementListener, name, null, facesManager, font, type, currentSpellManager);
01557 insertGuiElement(element);
01558 }
01559
01567 private void parseLinkSize(@NotNull final Args args, @NotNull final Container gui) throws IOException, JXCSkinException {
01568 final String type = args.get();
01569 final List<Component> elements = new ArrayList<Component>();
01570 while (args.hasMore()) {
01571 elements.add(definedGUIElements.lookup(args.get()));
01572 }
01573 if (elements.size() < 2) {
01574 throw new IOException("'link_size' needs at least two gui elements");
01575 }
01576 final Component[] array = elements.toArray(new Component[elements.size()]);
01577 final GroupLayout layout = (GroupLayout)gui.getLayout();
01578 if (type.equals("horizontal")) {
01579 layout.linkSize(SwingConstants.HORIZONTAL, array);
01580 } else if (type.equals("vertical")) {
01581 layout.linkSize(SwingConstants.VERTICAL, array);
01582 } else if (type.equals("both")) {
01583 layout.linkSize(SwingConstants.HORIZONTAL, array);
01584 layout.linkSize(SwingConstants.VERTICAL, array);
01585 } else {
01586 throw new IOException("undefined type '"+type+"'");
01587 }
01588 }
01589
01598 private void parseLogLabel(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
01599 final String name = args.get();
01600 final Image backgroundImage = args.get().equals("null") ? null : imageParser.getImage(args.getPrev());
01601 final Font fontPrint = definedFonts.lookup(args.get());
01602 final Font fontFixed = definedFonts.lookup(args.get());
01603 final Font fontFixedBold = definedFonts.lookup(args.get());
01604 final Font fontArcane = definedFonts.lookup(args.get());
01605 final Color defaultColor = ParseUtils.parseColor(args.get());
01606 final Fonts fonts = new Fonts(fontPrint, fontFixed, fontFixedBold, fontArcane);
01607 final AbstractGUIElement element = new GUILabelLog(tooltipManager, elementListener, name, backgroundImage, fonts, defaultColor);
01608 insertGuiElement(element);
01609 }
01610
01620 private void parseLogMessage(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CrossfireServerConnection server) throws IOException, JXCSkinException {
01621 final String name = args.get();
01622 final Image backgroundImage = args.get().equals("null") ? null : imageParser.getImage(args.getPrev());
01623 final Font fontPrint = definedFonts.lookup(args.get());
01624 final Font fontFixed = definedFonts.lookup(args.get());
01625 final Font fontFixedBold = definedFonts.lookup(args.get());
01626 final Font fontArcane = definedFonts.lookup(args.get());
01627 final Color defaultColor = ParseUtils.parseColor(args.get());
01628 final Fonts fonts = new Fonts(fontPrint, fontFixed, fontFixedBold, fontArcane);
01629 final AbstractGUIElement element = new GUIMessageLog(tooltipManager, elementListener, name, server, backgroundImage, fonts, defaultColor);
01630 insertGuiElement(element);
01631 }
01632
01639 private void parseLogColor(@NotNull final Args args) throws IOException, JXCSkinException {
01640 final String name = args.get();
01641 final int index = ExpressionParser.parseInt(args.get());
01642 final Color color = ParseUtils.parseColor(args.get());
01643 final Object element = definedGUIElements.lookup(name);
01644 if (!(element instanceof GUIMessageLog)) {
01645 throw new IOException("element '"+name+"' is not of type 'log'");
01646 }
01647 if (index < 0 || index >= MessageBufferUpdater.NUM_COLORS) {
01648 throw new IOException("invalid color index "+index);
01649 }
01650 ((GUIMessageLog)element).setColor(index, color);
01651 }
01652
01659 private void parseLogFilter(@NotNull final Args args) throws IOException, JXCSkinException {
01660 final String name = args.get();
01661 final String type = args.get();
01662 final boolean add;
01663 if (type.equals("only")) {
01664 add = true;
01665 } else if (type.equals("not")) {
01666 add = false;
01667 } else {
01668 throw new IOException("type '"+type+"' is invalid");
01669 }
01670 int types = 0;
01671 do {
01672 try {
01673 types |= 1<<MessageTypes.parseMessageType(args.get());
01674 } catch (final UnknownCommandException ex) {
01675 throw new IOException("undefined message type '"+args.getPrev()+"'", ex);
01676 }
01677 } while (args.hasMore());
01678 if (!add) {
01679 types = ~types;
01680 }
01681 final Object element = definedGUIElements.lookup(name);
01682 if (!(element instanceof GUIMessageLog)) {
01683 throw new IOException("element '"+name+"' is not of type 'log'");
01684 }
01685 ((GUIMessageLog)element).setTypes(types);
01686 }
01687
01696 private void parseMinimap(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
01697 final String name = args.get();
01698 final int w = ExpressionParser.parseInt(args.get());
01699 final int h = ExpressionParser.parseInt(args.get());
01700 final FacesProvider facesProvider = facesProviderFactory.getFacesProvider(4);
01701 if (facesProvider == null) {
01702 throw new IOException("cannot create faces with size 4");
01703 }
01704 final AbstractGUIElement element = new GUIMiniMap(tooltipManager, elementListener, name, mapUpdaterState, facesProvider, w, h);
01705 insertGuiElement(element);
01706 }
01707
01718 private void parseMap(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CrossfireServerConnection server, @NotNull final SmoothFaces smoothFaces) throws IOException, JXCSkinException {
01719 final String name = args.get();
01720 final FacesProvider facesProvider = facesProviderFactory.getFacesProvider(defaultTileSize);
01721 if (facesProvider == null) {
01722 throw new IOException("cannot create faces with size "+defaultTileSize);
01723 }
01724 insertGuiElement(new GUIMap(tooltipManager, elementListener, name, mapUpdaterState, facesProvider, server, smoothFaces));
01725 }
01726
01736 private void parseMetaList(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final MetaserverModel metaserverModel) throws IOException, JXCSkinException {
01737 final String name = args.get();
01738 final int cellWidth = ExpressionParser.parseInt(args.get());
01739 final int cellHeight = ExpressionParser.parseInt(args.get());
01740 final Image image = args.get().equals("null") ? null : imageParser.getImage(args.getPrev());
01741 final Font font = definedFonts.lookup(args.get());
01742 final GUIText text = args.get().equals("null") ? null : guiElementParser.lookupTextElement(args.getPrev());
01743 final AbstractLabel label = args.get().equals("null") ? null : guiElementParser.lookupLabelElement(args.getPrev());
01744 final CommandList connectCommandList = skin.getCommandList(args.get());
01745 final String format = args.get();
01746 final String tooltip = args.get();
01747
01748 final AbstractGUIElement list = new GUIMetaElementList(tooltipManager, elementListener, name, cellWidth, cellHeight, metaserverModel, image, font, format, tooltip, text, label, connectCommandList);
01749 insertGuiElement(list);
01750 }
01751
01760 private void parsePicture(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
01761 final String name = args.get();
01762 final BufferedImage image = imageParser.getImage(args.get());
01763 final float alpha = NumberParser.parseFloat(args.get());
01764 if (alpha < 0 || alpha > 1F) {
01765 throw new IOException("invalid alpha value: "+alpha);
01766 }
01767 insertGuiElement(new GUIPicture(tooltipManager, elementListener, name, image, alpha, image.getWidth(), image.getHeight()));
01768 }
01769
01780 private void parseQueryText(@NotNull final Args args, @NotNull final CrossfireServerConnection server, @NotNull final CommandCallback commandCallback, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
01781 final String name = args.get();
01782 final Image activeImage = imageParser.getImage(args.get());
01783 final Image inactiveImage = imageParser.getImage(args.get());
01784 final Font font = definedFonts.lookup(args.get());
01785 final Color inactiveColor = ParseUtils.parseColor(args.get());
01786 final Color activeColor = ParseUtils.parseColor(args.get());
01787 final int margin = ExpressionParser.parseInt(args.get());
01788 final boolean enableHistory = NumberParser.parseBoolean(args.get());
01789 insertGuiElement(new GUIQueryText(server, commandCallback, tooltipManager, elementListener, name, activeImage, inactiveImage, font, inactiveColor, activeColor, margin, "", enableHistory));
01790 }
01791
01799 private void parseSetForcedActive(@NotNull final Args args, @NotNull final Gui gui) throws IOException, JXCSkinException {
01800 final Object forcedActive = definedGUIElements.lookup(args.get());
01801 if (!(forcedActive instanceof ActivatableGUIElement)) {
01802 throw new IOException("argument to set_forced_active must be an activatable gui element");
01803 }
01804 gui.setForcedActive((ActivatableGUIElement)forcedActive);
01805 }
01806
01813 private static void parseSetAutoSize(@NotNull final Gui gui, @NotNull final Args args) throws IOException {
01814 final Expression x = ExpressionParser.parseExpression(args.get());
01815 final Expression y = ExpressionParser.parseExpression(args.get());
01816 final Expression w = ExpressionParser.parseExpression(args.get());
01817 final Expression h = ExpressionParser.parseExpression(args.get());
01818 gui.setAutoSize(new Extent(x, y, w, h));
01819 }
01820
01827 private void parseSetDefault(@NotNull final Args args) throws IOException, JXCSkinException {
01828 definedGUIElements.lookup(args.get()).setDefault(true);
01829 }
01830
01837 private void parseSetInvisible(@NotNull final Args args) throws IOException, JXCSkinException {
01838 definedGUIElements.lookup(args.get()).setVisible(false);
01839 }
01840
01847 private void parseHideInput(@NotNull final Args args) throws IOException, JXCSkinException {
01848 final GUIText element;
01849 try {
01850 element = (GUIText)definedGUIElements.lookup(args.get());
01851 } catch (final JXCSkinException ignored) {
01852 throw new JXCSkinException("can't use hide_input on a non text field "+args.getPrev());
01853 }
01854 element.setHideInput(true);
01855 }
01856
01861 private static void parseSetModal(@NotNull final Gui gui) {
01862 gui.setModal(true);
01863 }
01864
01873 private void parseScrollbar(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
01874 final String name = args.get();
01875 final boolean proportionalSlider = NumberParser.parseBoolean(args.get());
01876 final Object element = definedGUIElements.lookup(args.get());
01877 final Color colorBackground = ParseUtils.parseColor(args.get());
01878 final Color colorForeground = ParseUtils.parseColor(args.get());
01879 if (!(element instanceof GUIScrollable2)) {
01880 throw new IOException("'"+element+"' is not a scrollable element");
01881 }
01882 insertGuiElement(new GUIScrollBar(tooltipManager, elementListener, name, proportionalSlider, (GUIScrollable2)element, colorBackground, colorForeground));
01883 }
01884
01890 private void parseSkinName(@NotNull final Args args) throws IOException {
01891 final String newSkinName = args.get();
01892 final Resolution minResolution = parseResolution(args.get());
01893 final Resolution maxResolution = parseResolution(args.get());
01894 if (!newSkinName.matches("[-a-z_0-9]+")) {
01895 throw new IOException("invalid skin_name: "+newSkinName);
01896 }
01897 if (minResolution.getWidth() > maxResolution.getWidth() || minResolution.getHeight() > maxResolution.getHeight()) {
01898 throw new IOException("minimum resolution ("+minResolution+") must not exceed maximum resolution ("+maxResolution+")");
01899 }
01900
01901 skin.setSkinName(newSkinName, minResolution, maxResolution);
01902 }
01903
01913 private void parseText(@NotNull final Args args, @NotNull final CommandCallback commandCallback, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
01914 final String name = args.get();
01915 final Image activeImage = imageParser.getImage(args.get());
01916 final Image inactiveImage = imageParser.getImage(args.get());
01917 final Font font = definedFonts.lookup(args.get());
01918 final Color activeColor = ParseUtils.parseColor(args.get());
01919 final Color inactiveColor = ParseUtils.parseColor(args.get());
01920 final int margin = ExpressionParser.parseInt(args.get());
01921 final CommandList commandList = skin.getCommandList(args.get());
01922 final boolean enableHistory = NumberParser.parseBoolean(args.get());
01923 insertGuiElement(new GUITextField(commandCallback, tooltipManager, elementListener, name, activeImage, inactiveImage, font, inactiveColor, activeColor, margin, "", commandList, enableHistory));
01924 }
01925
01935 private void parseTextButton(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
01936 if (textButtonFactory == null) {
01937 throw new IOException("missing 'def textbutton' command");
01938 }
01939
01940 final String name = args.get();
01941 final boolean autoRepeat = NumberParser.parseBoolean(args.get());
01942 final CommandList commandList = skin.getCommandList(args.get());
01943 final String text = ParseUtils.parseText(args, lnr);
01944 assert textButtonFactory != null;
01945 insertGuiElement(textButtonFactory.newTextButton(tooltipManager, elementListener, name, text, autoRepeat, commandList));
01946 }
01947
01957 private void parseTextGauge(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
01958 if (dialogFactory == null) {
01959 throw new IOException("missing 'def dialog' command");
01960 }
01961
01962 final String name = args.get();
01963 final Image positiveImage = imageParser.getImage(args.get());
01964 final Image negativeImage = args.get().equals("null") ? null : imageParser.getImage(args.getPrev());
01965 final Image emptyImage = imageParser.getImage(args.get());
01966 final GaugeUpdater gaugeUpdater = newGaugeUpdater(args.get());
01967 final Orientation orientation = ParseUtils.parseOrientation(args.get());
01968 final Color color = ParseUtils.parseColor(args.get());
01969 final Font font = definedFonts.lookup(args.get());
01970 final String tooltipPrefix = ParseUtils.parseText(args, lnr);
01971 assert dialogFactory != null;
01972 final float alpha = dialogFactory.getFrameAlpha();
01973 final GUITextGauge element = new GUITextGauge(tooltipManager, elementListener, name, positiveImage, negativeImage, emptyImage, orientation, tooltipPrefix.length() > 0 ? tooltipPrefix : null, color, font, alpha);
01974 insertGuiElement(element);
01975 gaugeUpdater.setGauge(element);
01976 }
01977
01986 private void parseTooltip(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
01987 final Font font = definedFonts.lookup(args.get());
01988 final GUIHTMLLabel tooltipLabel = new GUIHTMLLabel(tooltipManager, elementListener, "tooltip", null, font, Color.BLACK, Color.WHITE, "");
01989 tooltipLabel.setAutoResize(true);
01990 skin.setTooltipLabel(tooltipLabel);
01991 }
01992
02003 private void parseVertical(@NotNull final Args args, @NotNull final Container gui, @NotNull final LineNumberReader lnr, final boolean isDialog) throws IOException, JXCSkinException {
02004 final GroupLayout layout = (GroupLayout)gui.getLayout();
02005 final String begin = args.get();
02006 if (!begin.equals("begin")) {
02007 throw new IOException("syntax error: expecting 'begin'");
02008 }
02009 final Collection<GUIElement> unreferencedElements = new TreeSet<GUIElement>(ELEMENT_COMPARATOR);
02010 for (final GUIElement element : definedGUIElements) {
02011 unreferencedElements.add(element);
02012 }
02013 if (!isDialog) {
02014 final GroupLayout.Group content = parseBegin(args, layout, lnr, unreferencedElements);
02015 if (!unreferencedElements.isEmpty()) {
02016 throw new IOException("layout doesn't define elements "+unreferencedElements);
02017 }
02018 layout.setVerticalGroup(content);
02019 return;
02020 }
02021 final Component background = getUnreferencedElement("dialog_background", unreferencedElements);
02022 if (background == null) {
02023 throw new AssertionError("element 'dialog_background' is missing");
02024 }
02025 final GroupLayout.Group content = parseBegin(args, layout, lnr, unreferencedElements);
02026 final Component title = getUnreferencedElement("dialog_title", unreferencedElements);
02027 final Component close = getUnreferencedElement("dialog_close", unreferencedElements);
02028 final GroupLayout.Group group2 = layout.createSequentialGroup();
02029 group2.addGap(DIALOG_BORDER_WIDTH);
02030 if (title == null) {
02031 if (close != null) {
02032 final GroupLayout.Group group4 = layout.createParallelGroup();
02033 group4.addComponent(close);
02034 group4.addGap(0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE);
02035 final GroupLayout.Group group3 = layout.createParallelGroup();
02036 group3.addGroup(content);
02037 group3.addGroup(group4);
02038 group2.addGroup(group3);
02039 } else {
02040 group2.addGroup(content);
02041 }
02042 } else {
02043 if (close == null) {
02044 group2.addComponent(title);
02045 group2.addGroup(content);
02046 } else {
02047 final GroupLayout.Group group3 = layout.createParallelGroup();
02048 group3.addComponent(title);
02049 group3.addComponent(close);
02050 group2.addGroup(group3);
02051 group2.addGroup(content);
02052 }
02053 }
02054 group2.addGap(DIALOG_BORDER_WIDTH);
02055 if (!unreferencedElements.isEmpty()) {
02056 throw new IOException("layout doesn't define elements "+unreferencedElements);
02057 }
02058
02059 final GroupLayout.Group group1 = layout.createParallelGroup();
02060 group1.addGroup(group2);
02061 group1.addComponent(background);
02062
02063 layout.setVerticalGroup(group1);
02064 }
02065
02072 @NotNull
02073 private static Resolution parseResolution(@NotNull final String text) throws IOException {
02074 final Resolution resolution = Resolution.parse(text);
02075 if (resolution == null) {
02076 throw new IOException("invalid resolution: "+resolution);
02077 }
02078 return resolution;
02079 }
02080
02090 private void parseCharacterList(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CharacterModel characterModel) throws IOException, JXCSkinException {
02091 final String name = args.get();
02092 final int cellWidth = ExpressionParser.parseInt(args.get());
02093 final int cellHeight = ExpressionParser.parseInt(args.get());
02094 final Font font = definedFonts.lookup(args.get());
02095 final AbstractGUIElement list = new GUICharacterList(tooltipManager, facesManager, elementListener, name, cellWidth, cellHeight, font, characterModel);
02096 insertGuiElement(list);
02097 }
02098
02104 private void insertGuiElement(@NotNull final AbstractGUIElement guiElement) throws JXCSkinException {
02105 definedGUIElements.insert(guiElement.getName(), guiElement);
02106 skin.insertGuiElement(guiElement);
02107 }
02108
02125 private void addCommand(@NotNull final String listName, @NotNull final Args args, @Nullable final AbstractGUIElement element, @NotNull final String command, @NotNull final GuiStateManager guiStateManager, @NotNull final CommandExecutor commandExecutor, @NotNull final LineNumberReader lnr, @NotNull final CommandQueue commandQueue, @NotNull final CrossfireServerConnection crossfireServerConnection, @NotNull final CommandCallback commandCallback, @NotNull final Macros macros) throws IOException, JXCSkinException {
02126 final CommandList commandList = skin.getCommandList(listName);
02127 commandList.add(commandParser.parseCommandArgs(args, element, command, guiStateManager, commandExecutor, lnr, commandQueue, crossfireServerConnection, commandCallback, macros));
02128 }
02129
02137 @NotNull
02138 private GaugeUpdater newGaugeUpdater(@NotNull final String name) throws IOException {
02139 return gaugeUpdaterParser.parseGaugeUpdater(name, experienceTable);
02140 }
02141
02153 @NotNull
02154 private GroupLayout.Group parseBegin(@NotNull final Args beginArgs, @NotNull final GroupLayout layout, @NotNull final LineNumberReader lnr, @NotNull final Collection<GUIElement> unreferencedElements) throws IOException, JXCSkinException {
02155 final String type = beginArgs.get();
02156 final GroupLayout.Group group;
02157 if (type.equals("seq")) {
02158 group = layout.createSequentialGroup();
02159 } else if (type.equals("par")) {
02160 group = layout.createParallelGroup();
02161 } else {
02162 throw new IOException("undefined type '"+type+"'");
02163 }
02164
02165 while (true) {
02166 final String line = lnr.readLine();
02167 if (line == null) {
02168 throw new IOException("unterminated 'begin' block");
02169 }
02170
02171 if (line.startsWith("#") || line.length() == 0) {
02172 continue;
02173 }
02174
02175 final String[] argsTmp;
02176 try {
02177 argsTmp = StringUtils.splitFields(line);
02178 } catch (final UnterminatedTokenException ex) {
02179 throw new JXCSkinException(ex.getMessage());
02180 }
02181 final Args args = new Args(argsTmp);
02182 final String cmd = args.get();
02183 if (cmd.equals("end")) {
02184 break;
02185 }
02186 if (cmd.equals("begin")) {
02187 group.addGroup(parseBegin(args, layout, lnr, unreferencedElements));
02188 } else if (cmd.equals("border_gap")) {
02189 if (!(group instanceof GroupLayout.SequentialGroup)) {
02190 throw new IOException("'border_gap' cannot be used outside 'seq' groups");
02191 }
02192 ((GroupLayout.SequentialGroup)group).addContainerGap();
02193 } else if (cmd.equals("gap")) {
02194 if (args.hasMore()) {
02195 final int tmp = ExpressionParser.parseInt(args.get());
02196 if (args.hasMore()) {
02197 final int size = ExpressionParser.parseInt(args.get());
02198 final int max = args.hasMore() ? ExpressionParser.parseInt(args.get()) : Short.MAX_VALUE;
02199 group.addGap(tmp, size, max);
02200 } else {
02201 group.addGap(tmp);
02202 }
02203 } else {
02204 group.addGap(0, 1, Short.MAX_VALUE);
02205 }
02206 } else {
02207 final AbstractGUIElement element = definedGUIElements.lookup(cmd);
02208 if (!unreferencedElements.remove(element)) {
02209 throw new IOException("layout defines element '"+element+"' more than once");
02210 }
02211 if (args.hasMore()) {
02212 final int tmp = ExpressionParser.parseInt(args.get());
02213 final int min;
02214 final int pref;
02215 final int max;
02216 if (args.hasMore()) {
02217 min = tmp;
02218 pref = ExpressionParser.parseInt(args.get());
02219 max = args.hasMore() ? ExpressionParser.parseInt(args.get()) : Short.MAX_VALUE;
02220 } else {
02221 min = tmp;
02222 pref = tmp;
02223 max = tmp;
02224 }
02225 group.addComponent(element, min, pref, max);
02226 } else {
02227 group.addComponent(element);
02228 }
02229 }
02230 if (args.hasMore()) {
02231 throw new IOException("excess arguments");
02232 }
02233 }
02234 return group;
02235 }
02236
02237 }