Crossfire JXClient, Trunk  R20561
JXCSkinLoader.java
Go to the documentation of this file.
1 /*
2  * This file is part of JXClient, the Fullscreen Java Crossfire Client.
3  *
4  * JXClient is free software; you can redistribute it and/or modify
5  * it under the terms of the GNU General Public License as published by
6  * the Free Software Foundation; either version 2 of the License, or
7  * (at your option) any later version.
8  *
9  * JXClient is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with JXClient; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17  *
18  * Copyright (C) 2005-2008 Yann Chachkoff.
19  * Copyright (C) 2006-2011 Andreas Kirschbaum.
20  */
21 
22 package com.realtime.crossfire.jxclient.skin.io;
23 
146 import java.awt.Color;
147 import java.awt.Component;
148 import java.awt.Container;
149 import java.awt.Font;
150 import java.awt.Image;
151 import java.awt.image.BufferedImage;
152 import java.io.IOException;
153 import java.io.InputStream;
154 import java.io.InputStreamReader;
155 import java.io.LineNumberReader;
156 import java.util.ArrayList;
157 import java.util.Collection;
158 import java.util.Comparator;
159 import java.util.Iterator;
160 import java.util.List;
161 import java.util.TreeSet;
162 import javax.swing.GroupLayout;
163 import javax.swing.GroupLayout.Group;
164 import javax.swing.GroupLayout.SequentialGroup;
165 import javax.swing.SwingConstants;
166 import org.jetbrains.annotations.NotNull;
167 import org.jetbrains.annotations.Nullable;
168 
174 public class JXCSkinLoader {
175 
181  private enum ListType {
182 
187 
192 
197 
202 
207 
212 
216  KNOWLEDGE_LIST
217  }
218 
222  private static final int DIALOG_BORDER_WIDTH = 5;
223 
227  @NotNull
228  private final Model model;
229 
233  @NotNull
234  private final ItemView inventoryView;
235 
239  @NotNull
240  private final FloorView floorView;
241 
245  @NotNull
246  private final SpellsView spellView;
247 
251  @NotNull
253 
257  @NotNull
258  private final QuestsView questView;
259 
260  @NotNull
262 
263  @NotNull
265 
270  private final boolean avoidCopyArea;
271 
275  @NotNull
276  private final FacesManager facesManager;
277 
281  private final int defaultTileSize;
282 
286  @NotNull
288 
292  @NotNull
293  private final GuiManager guiManager;
294 
299  @NotNull
301 
305  @NotNull
307 
311  @NotNull
313 
317  @NotNull
319 
323  @NotNull
325 
329  @NotNull
330  private final JXCSkinCache<Font> definedFonts = new JXCSkinCache<>("font");
331 
335  @Nullable
337 
341  @Nullable
343 
347  @Nullable
349 
354  @Nullable
356 
360  @NotNull
362 
366  @NotNull
368 
372  @NotNull
374 
378  @NotNull
380 
384  @NotNull
386 
390  @NotNull
392 
397  @NotNull
399 
404  @NotNull
405  private static final Comparator<GUIElement> ELEMENT_COMPARATOR = (o1, o2) -> {
406  final Comparable<String> n1 = o1.getName();
407  final String n2 = o2.getName();
408  return n1.compareTo(n2);
409  };
410 
414  @NotNull
416 
438  public JXCSkinLoader(@NotNull final Model model, @NotNull final ItemView inventoryView, @NotNull final FloorView floorView, @NotNull final SpellsView spellView, @NotNull final SpellSkillView spellSkillsView, @NotNull final FacesManager facesManager, @NotNull final MapUpdaterState mapUpdaterState, @NotNull final KeyBindings defaultKeyBindings, @NotNull final OptionManager optionManager, final int defaultTileSize, @NotNull final KeybindingsManager keybindingsManager, @NotNull final QuestsView questView, @NotNull final CommandHistoryFactory commandHistoryFactory, @NotNull final KnowledgeView knowledgeView, @NotNull final KnowledgeTypeView knowledgeTypeView, final boolean avoidCopyArea, @NotNull final GuiManager guiManager) {
439  this.model = model;
440  this.inventoryView = inventoryView;
441  this.floorView = floorView;
442  this.spellView = spellView;
443  this.spellSkillsView = spellSkillsView;
444  this.facesManager = facesManager;
445  this.defaultTileSize = defaultTileSize;
446  this.commandHistoryFactory = commandHistoryFactory;
447  this.guiManager = guiManager;
448  facesProviderFactory = new FacesProviderFactory(facesManager);
449  this.mapUpdaterState = mapUpdaterState;
450  this.defaultKeyBindings = defaultKeyBindings;
451  this.optionManager = optionManager;
452  this.keybindingsManager = keybindingsManager;
453  this.questView = questView;
454  this.knowledgeView = knowledgeView;
455  this.knowledgeTypeView = knowledgeTypeView;
456  this.avoidCopyArea = avoidCopyArea;
457  }
458 
480  @NotNull
481  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 {
482  imageParser = new ImageParser(skinSource);
483  fontParser = new FontParser(skinSource);
484 
485  final Image nextGroupFace;
486  try {
487  nextGroupFace = ResourceUtils.loadImage(ResourceUtils.NEXT_GROUP_FACE).getImage();
488  } catch (final IOException ex) {
489  throw new JXCSkinException(ex.getMessage(), ex);
490  }
491  final Image prevGroupFace;
492  try {
493  prevGroupFace = ResourceUtils.loadImage(ResourceUtils.PREV_GROUP_FACE).getImage();
494  } catch (final IOException ex) {
495  throw new JXCSkinException(ex.getMessage(), ex);
496  }
497 
498  final Dialogs dialogs = new Dialogs(guiFactory, guiManager);
499  gaugeUpdaterParser = new GaugeUpdaterParser(model.getStats(), model.getItemSet(), model.getSkillSet());
500  commandParser = new CommandParser(dialogs, floorView, definedGUIElements);
501  skin = new DefaultJXCSkin(defaultKeyBindings, optionManager, dialogs);
502  @Nullable JXCSkin skinToDetach = skin;
503  try {
504  guiElementParser = new GuiElementParser(definedGUIElements);
505  imageParser.clear();
506  skin.addDialog("keybind");
507  skin.addDialog("query");
508  skin.addDialog("book");
509  skin.addDialog("main");
510  skin.addDialog("meta");
511  skin.addDialog("quit");
512  skin.addDialog("disconnect");
513  skin.addDialog("connect");
514  skin.addDialog("start");
515  skin.addDialog("account_login");
516  skin.addDialog("account_characters");
517  definedFonts.clear();
518  textButtonFactory = null;
519  dialogFactory = null;
520  checkBoxFactory = null;
521  try {
522  load(skinSource, "global", crossfireServerConnection, guiStateManager, tooltipManager, windowRenderer, elementListener, metaserverModel, characterModel, commandQueue, null, shortcuts, commandExecutor, currentSpellManager, commandCallback, macros, nextGroupFace, prevGroupFace, smoothFaces);
523  while (true) {
524  final String name = skin.getDialogToLoad();
525  if (name == null) {
526  break;
527  }
528  final Gui gui = skin.getDialog(name);
529  load(skinSource, name, crossfireServerConnection, guiStateManager, tooltipManager, windowRenderer, elementListener, metaserverModel, characterModel, commandQueue, gui, shortcuts, commandExecutor, currentSpellManager, commandCallback, macros, nextGroupFace, prevGroupFace, smoothFaces);
530  }
531  } finally {
532  definedFonts.clear();
533  textButtonFactory = null;
534  dialogFactory = null;
535  checkBoxFactory = null;
536  imageParser.clear();
537  }
538 
539  skinToDetach = null;
540  } finally {
541  if (skinToDetach != null) {
542  skinToDetach.detach();
543  windowRenderer.setTooltip(null);
544  }
545  }
546 
547  return skin;
548  }
549 
573  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 {
574  String resourceName = dialogName+".skin";
575 
576  definedGUIElements.clear();
577  try {
578  InputStream inputStream;
579  try {
580  inputStream = skinSource.getInputStream(resourceName);
581  } catch (final IOException ignored) {
582  resourceName = dialogName+".skin";
583  inputStream = skinSource.getInputStream(resourceName);
584  }
585  try {
586  load(skinSource, dialogName, resourceName, inputStream, server, guiStateManager, tooltipManager, windowRenderer, elementListener, metaserverModel, characterModel, commandQueue, gui, shortcuts, commandExecutor, currentSpellManager, commandCallback, macros, nextGroupFace, prevGroupFace, smoothFaces);
587  } finally {
588  inputStream.close();
589  }
590  } catch (final IOException|JXCSkinException ex) {
591  throw new JXCSkinException(skinSource.getURI(resourceName)+": "+ex.getMessage(), ex);
592  } finally {
593  definedGUIElements.clear();
594  }
595  }
596 
623  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 {
624  try {
625  try (final InputStreamReader isr = new InputStreamReader(inputStream, "UTF-8")) {
626  final LineNumberReader lnr = new LineNumberReader(isr);
627  try {
628  boolean isDialog = false;
629  while (true) {
630  final String line = lnr.readLine();
631  if (line == null) {
632  break;
633  }
634 
635  if (line.startsWith("#") || line.isEmpty()) {
636  continue;
637  }
638 
639  final String[] argsTmp;
640  try {
641  argsTmp = StringUtils.splitFields(line);
642  } catch (final UnterminatedTokenException ex) {
643  throw new JXCSkinException(ex.getMessage(), ex);
644  }
645  final Args args = new Args(argsTmp);
646  final String cmd = args.get();
647  if (gui != null && cmd.equals("button")) {
648  parseButton(args, tooltipManager, elementListener, lnr);
649  } else if (gui != null && cmd.equals("checkbox")) {
650  parseCheckbox(args, tooltipManager, elementListener, lnr);
651  } else if (gui != null && cmd.equals("combobox")) {
652  parseComboBox(args, tooltipManager, elementListener);
653  } else if (cmd.equals("commandlist")) {
654  parseCommandList(args, guiStateManager, lnr, commandExecutor, commandQueue, server, commandCallback, macros);
655  } else if (cmd.equals("commandlist_add")) {
656  parseCommandListAdd(args, guiStateManager, lnr, commandExecutor, commandQueue, server, commandCallback, macros);
657  } else if (gui != null && cmd.equals("command_text")) {
658  parseCommandText(args, commandCallback, tooltipManager, elementListener, commandExecutor);
659  } else if (cmd.equals("def")) {
660  parseDef(args, lnr);
661  } else if (gui != null && cmd.equals("dialog")) {
662  if (isDialog) {
663  throw new JXCSkinException("'dialog' must not be used more than once per dialog");
664  }
665  parseDialog(args, tooltipManager, windowRenderer, elementListener, lnr, gui, dialogName);
666  isDialog = true;
667  } else if (gui != null && cmd.equals("dialog_hide")) {
668  parseDialogHide(args, gui);
669  } else if (gui != null && cmd.equals("dupgauge")) {
670  parseDupGauge(args, tooltipManager, elementListener, lnr);
671  } else if (gui != null && cmd.equals("duptextgauge")) {
672  parseDupTextGauge(args, tooltipManager, elementListener, lnr);
673  } else if (cmd.equals("event")) {
674  parseEvent(args, guiStateManager, server);
675  } else if (gui != null && cmd.equals("fill")) {
676  parseFill(args, tooltipManager, elementListener);
677  } else if (cmd.equals("font")) {
678  parseFont(args);
679  } else if (gui != null && cmd.equals("gauge")) {
680  parseGauge(args, tooltipManager, elementListener, lnr);
681  } else if (gui != null && cmd.equals("ignore")) {
682  parseIgnore(args);
683  } else if (gui != null && cmd.equals("inventory_list")) {
684  parseList(args, ListType.INVENTORY, tooltipManager, elementListener, commandQueue, server, currentSpellManager, nextGroupFace, prevGroupFace);
685  } else if (gui != null && cmd.equals("floor_list")) {
686  parseList(args, ListType.GROUND, tooltipManager, elementListener, commandQueue, server, currentSpellManager, nextGroupFace, prevGroupFace);
687  } else if (gui != null && cmd.equals("spells_list")) {
688  parseList(args, ListType.SPELL, tooltipManager, elementListener, commandQueue, server, currentSpellManager, nextGroupFace, prevGroupFace);
689  } else if (gui != null && cmd.equals("spell_skills")) {
690  parseList(args, ListType.SPELL_SKILLS, tooltipManager, elementListener, commandQueue, server, currentSpellManager, nextGroupFace, prevGroupFace);
691  } else if (gui != null && cmd.equals("quests_list")) {
692  parseList(args, ListType.QUEST, tooltipManager, elementListener, commandQueue, server, currentSpellManager, nextGroupFace, prevGroupFace);
693  } else if (gui != null && cmd.equals("knowledge_types")) {
694  parseList(args, ListType.KNOWLEDGE_TYPES, tooltipManager, elementListener, commandQueue, server, currentSpellManager, nextGroupFace, prevGroupFace);
695  } else if (gui != null && cmd.equals("knowledge_list")) {
696  parseList(args, ListType.KNOWLEDGE_LIST, tooltipManager, elementListener, commandQueue, server, currentSpellManager, nextGroupFace, prevGroupFace);
697  } else if (gui != null && cmd.equals("horizontal")) {
698  parseHorizontal(args, gui, lnr, isDialog);
699  } else if (gui != null && cmd.equals("item")) {
700  parseItem(args, tooltipManager, elementListener, commandQueue, server, shortcuts, currentSpellManager, nextGroupFace, prevGroupFace);
701  } else if (cmd.equals("key")) {
702  parseKey(args, gui, line);
703  } else if (gui != null && cmd.equals("label_html")) {
704  parseLabelHtml(args, tooltipManager, elementListener, lnr);
705  } else if (gui != null && cmd.equals("label_multi")) {
706  parseLabelMulti(args, tooltipManager, elementListener, lnr);
707  } else if (gui != null && cmd.equals("label_query")) {
708  parseLabelQuery(args, tooltipManager, elementListener, server);
709  } else if (gui != null && cmd.equals("label_failure")) {
710  parseLabelFailure(args, tooltipManager, elementListener, server);
711  } else if (gui != null && cmd.equals("label_message")) {
712  parseLabelMessage(args, tooltipManager, elementListener, server, windowRenderer);
713  } else if (gui != null && cmd.equals("label_text")) {
714  parseLabelText(args, tooltipManager, elementListener, lnr);
715  } else if (gui != null && cmd.equals("label_stat")) {
716  parseLabelStat(args, tooltipManager, elementListener);
717  } else if (gui != null && cmd.equals("label_stat2")) {
718  parseLabelStat2(args, tooltipManager, elementListener);
719  } else if (gui != null && cmd.equals("label_spell")) {
720  parseLabelSpell(args, tooltipManager, elementListener, currentSpellManager);
721  } else if (gui != null && cmd.equals("link_size")) {
722  parseLinkSize(args, gui);
723  } else if (gui != null && cmd.equals("log_label")) {
724  parseLogLabel(args, tooltipManager, elementListener);
725  } else if (gui != null && cmd.equals("log_message")) {
726  parseLogMessage(args, tooltipManager, elementListener, server);
727  } else if (gui != null && cmd.equals("log_color")) {
728  parseLogColor(args);
729  } else if (gui != null && cmd.equals("log_filter")) {
730  parseLogFilter(args);
731  } else if (gui != null && cmd.equals("minimap")) {
732  parseMinimap(args, tooltipManager, elementListener);
733  } else if (gui != null && cmd.equals("map")) {
734  parseMap(args, tooltipManager, elementListener, server, smoothFaces);
735  } else if (gui != null && cmd.equals("meta_list")) {
736  parseMetaList(args, tooltipManager, elementListener, metaserverModel);
737  } else if (gui != null && cmd.equals("picture")) {
738  parsePicture(args, tooltipManager, elementListener);
739  } else if (gui != null && cmd.equals("query_text")) {
740  parseQueryText(args, server, commandCallback, tooltipManager, elementListener);
741  } else if (gui != null && cmd.equals("set_forced_active")) {
742  parseSetForcedActive(args, gui);
743  } else if (gui != null && cmd.equals("set_auto_size")) {
744  parseSetAutoSize(gui, args);
745  } else if (gui != null && cmd.equals("set_default")) {
746  parseSetDefault(args);
747  } else if (gui != null && cmd.equals("set_invisible")) {
748  parseSetInvisible(args);
749  } else if (gui != null && cmd.equals("set_modal")) {
750  parseSetModal(gui);
751  } else if (gui != null && cmd.equals("scrollbar")) {
752  parseScrollbar(args, tooltipManager, elementListener);
753  } else if (gui == null && cmd.equals("skin_name")) {
754  parseSkinName(args);
755  } else if (gui != null && cmd.equals("text")) {
756  parseText(args, commandCallback, tooltipManager, elementListener);
757  } else if (gui != null && cmd.equals("textbutton")) {
758  parseTextButton(args, tooltipManager, elementListener, lnr);
759  } else if (gui != null && cmd.equals("textgauge")) {
760  parseTextGauge(args, tooltipManager, elementListener, lnr);
761  } else if (cmd.equals("tooltip")) {
762  parseTooltip(args, tooltipManager, elementListener);
763  } else if (cmd.equals("vertical")) {
764  parseVertical(args, gui, lnr, isDialog);
765  } else if (cmd.equals("character_list")) {
766  parseCharacterList(args, tooltipManager, elementListener, characterModel);
767  } else if (cmd.equals("hide_input")) {
768  parseHideInput(args);
769  } else {
770  throw new IOException("unknown keyword '"+cmd+"'");
771  }
772 
773  if (args.hasMore()) {
774  throw new IOException("excess arguments");
775  }
776  }
777  } catch (final IOException|JXCSkinException ex) {
778  throw new IOException(ex.getMessage()+" in line "+lnr.getLineNumber(), ex);
779  } catch (final IllegalArgumentException ex) {
780  final Object msg = ex.getMessage();
781  throw new IOException("invalid parameter"+(msg == null ? "" : " ("+msg+")")+" in line "+lnr.getLineNumber(), ex);
782  } finally {
783  lnr.close();
784  }
785  }
786  } catch (final IOException ex) {
787  throw new JXCSkinException(skinSource.getURI(resourceName)+": "+ex.getMessage(), ex);
788  }
789 
790  final Iterator<AbstractGUIElement> it = definedGUIElements.iterator();
791  if (gui == null) {
792  assert !it.hasNext();
793  }
794 
795  //if (gui != null) {
796  // gui.validate();
797  // final JFrame frame = new JFrame(dialogName);
798  // frame.setLayout(new BorderLayout());
799  // frame.add(gui, BorderLayout.CENTER);
800  // frame.setSize(800, 600);
801  // frame.setBackground(new Color(192, 0, 0));
802  // frame.setVisible(true);
803  // //ComponentDumper.dump(gui);
804  //}
805  }
806 
816  private void parseButton(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
817  final String name = args.get();
818  final BufferedImage upImage = imageParser.getImage(args.get());
819  final BufferedImage downImage = imageParser.getImage(args.get());
820  final boolean autoRepeat = NumberParser.parseBoolean(args.get());
821  final CommandList commandList = skin.getCommandList(args.get());
822  @Nullable final String label;
823  @Nullable final Font font;
824  @Nullable final Color color;
825  final int textX;
826  final int textY;
827  if (args.hasMore()) {
828  font = definedFonts.lookup(args.get());
829  color = ParseUtils.parseColor(args.get());
830  textX = ExpressionParser.parseInt(args.get());
831  textY = ExpressionParser.parseInt(args.get());
832  label = ParseUtils.parseText(args, lnr);
833  } else {
834  label = null;
835  font = null;
836  color = null;
837  textX = 0;
838  textY = 0;
839  }
840  insertGuiElement(new GUIButton(tooltipManager, elementListener, name, upImage, downImage, label, font, color, textX, textY, autoRepeat, commandList));
841  }
842 
852  private void parseCheckbox(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
853  if (checkBoxFactory == null) {
854  throw new IOException("missing 'def checkbox' command");
855  }
856 
857  final String name = args.get();
858  final CheckBoxOption option = ParseUtils.parseCheckBoxOption(args.get(), optionManager);
859  final String text = ParseUtils.parseText(args, lnr);
860  assert checkBoxFactory != null;
861  insertGuiElement(checkBoxFactory.newCheckBox(tooltipManager, elementListener, name, option, text));
862  }
863 
872  private void parseComboBox(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
873  final String name = args.get();
874  final String type = args.get();
875  final GUILabelLog label = args.get().equals("null") ? null : guiElementParser.lookupLabelLogElement(args.getPrev());
876  final AbstractGUIElement element;
877  switch (type) {
878  case "classes":
879  element = new GUIClassesComboBox(tooltipManager, elementListener, name, model, label);
880  break;
881 
882  case "races":
883  element = new GUIRacesComboBox(tooltipManager, elementListener, name, model, label);
884  break;
885 
886  default:
887  throw new IOException("undefined 'combobox' type '"+type+"'");
888  }
889  insertGuiElement(element);
890  }
891 
905  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 {
906  final String commandListName = args.get();
907  final CommandListType commandListType = NumberParser.parseEnum(CommandListType.class, args.get(), "type");
908  skin.addCommandList(commandListName, commandListType);
909  if (args.hasMore()) {
910  final AbstractGUIElement element = args.get().equals("null") ? null : definedGUIElements.lookup(args.getPrev());
911  addCommand(commandListName, args, element, args.get(), guiStateManager, commandExecutor, lnr, commandQueue, server, commandCallback, macros);
912  }
913  }
914 
928  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 {
929  final String name = args.get();
930  final AbstractGUIElement element = args.get().equals("null") ? null : definedGUIElements.lookup(args.getPrev());
931  addCommand(name, args, element, args.get(), guiStateManager, commandExecutor, lnr, commandQueue, server, commandCallback, macros);
932  }
933 
944  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 {
945  final String name = args.get();
946  final Image activeImage = imageParser.getImage(args.get());
947  final Image inactiveImage = imageParser.getImage(args.get());
948  final Font font = definedFonts.lookup(args.get());
949  final Color inactiveColor = ParseUtils.parseColor(args.get());
950  final Color activeColor = ParseUtils.parseColor(args.get());
951  final int margin = ExpressionParser.parseInt(args.get());
952  final boolean enableHistory = NumberParser.parseBoolean(args.get());
953  final CommandHistory commandHistory = enableHistory ? commandHistoryFactory.getCommandHistory(name) : null;
954  insertGuiElement(new GUICommandText(commandCallback, commandHistory, tooltipManager, elementListener, name, activeImage, inactiveImage, font, inactiveColor, activeColor, margin, "", commandExecutor));
955  }
956 
964  private void parseDef(@NotNull final Args args, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
965  final String type = args.get();
966  switch (type) {
967  case "checkbox": {
968  final BufferedImage checkedImage = imageParser.getImage(args.get());
969  final BufferedImage uncheckedImage = imageParser.getImage(args.get());
970  final Font font = definedFonts.lookup(args.get());
971  final Color color = ParseUtils.parseColor(args.get());
972  checkBoxFactory = new CheckBoxFactory(checkedImage, uncheckedImage, font, color);
973  break;
974  }
975 
976  case "checkbox_option":
977  final String optionName = args.get();
978  final CommandList commandOn = skin.getCommandList(args.get());
979  final CommandList commandOff = skin.getCommandList(args.get());
980  final String documentation = ParseUtils.parseText(args, lnr);
981  skin.addOption(optionName, documentation, new CommandCheckBoxOption(commandOn, commandOff, documentation));
982  break;
983 
984  case "dialog":
985  final String frame = args.get();
986  final Image frameNW = imageParser.getImage(frame+"_nw");
987  final Image frameN = imageParser.getImage(frame+"_n");
988  final Image frameNE = imageParser.getImage(frame+"_ne");
989  final Image frameW = imageParser.getImage(frame+"_w");
990  final Image frameC = imageParser.getImage(frame+"_c");
991  final Image frameE = imageParser.getImage(frame+"_e");
992  final Image frameSW = imageParser.getImage(frame+"_sw");
993  final Image frameS = imageParser.getImage(frame+"_s");
994  final Image frameSE = imageParser.getImage(frame+"_se");
995  final Font titleFont = definedFonts.lookup(args.get());
996  final Color titleColor = ParseUtils.parseColor(args.get());
997  final Color titleBackgroundColor = ParseUtils.parseColor(args.get());
998  final float alpha = NumberParser.parseFloat(args.get());
999  if (alpha < 0 || alpha > 1.0F) {
1000  throw new IOException("invalid alpha value: "+alpha);
1001  }
1002  dialogFactory = new DialogFactory(frameNW, frameN, frameNE, frameW, frameC, frameE, frameSW, frameS, frameSE, titleFont, titleColor, titleBackgroundColor, alpha);
1003  break;
1004 
1005  case "item": {
1006  final Color cursedColor = ParseUtils.parseColorNull(args.get());
1007  final Image cursedImage = imageParser.getImage(cursedColor, args.getPrev());
1008  final Color damnedColor = ParseUtils.parseColorNull(args.get());
1009  final Image damnedImage = imageParser.getImage(damnedColor, args.getPrev());
1010  final Color magicColor = ParseUtils.parseColorNull(args.get());
1011  final Image magicImage = imageParser.getImage(magicColor, args.getPrev());
1012  final Color blessedColor = ParseUtils.parseColorNull(args.get());
1013  final Image blessedImage = imageParser.getImage(blessedColor, args.getPrev());
1014  final Color appliedColor = ParseUtils.parseColorNull(args.get());
1015  final Image appliedImage = imageParser.getImage(appliedColor, args.getPrev());
1016  final Color unidentifiedColor = ParseUtils.parseColorNull(args.get());
1017  final Image unidentifiedImage = imageParser.getImage(unidentifiedColor, args.getPrev());
1018  final Color selectorColor = ParseUtils.parseColorNull(args.get());
1019  final Image selectorImage = imageParser.getImage(selectorColor, args.getPrev());
1020  final Color lockedColor = ParseUtils.parseColorNull(args.get());
1021  final Image lockedImage = imageParser.getImage(lockedColor, args.getPrev());
1022  final Color unpaidColor = ParseUtils.parseColorNull(args.get());
1023  final Image unpaidImage = imageParser.getImage(unpaidColor, args.getPrev());
1024  final Font font = definedFonts.lookup(args.get());
1025  final Color nrofColor = ParseUtils.parseColor(args.get());
1026  defaultItemPainter = new ItemPainter(cursedImage, damnedImage, magicImage, blessedImage, appliedImage, unidentifiedImage, selectorImage, lockedImage, unpaidImage, cursedColor, damnedColor, magicColor, blessedColor, appliedColor, unidentifiedColor, selectorColor, lockedColor, unpaidColor, font, nrofColor);
1027  break;
1028  }
1029 
1030  case "textbutton":
1031  final String up = args.get();
1032  final String down = args.get();
1033  final Font font = definedFonts.lookup(args.get());
1034  final Color color = ParseUtils.parseColor(args.get());
1035  final Color colorSelected = ParseUtils.parseColor(args.get());
1036  final ButtonImages upImages = new ButtonImages(imageParser.getImage(up+"_w"), imageParser.getImage(up+"_c"), imageParser.getImage(up+"_e"));
1037  final ButtonImages downImages = new ButtonImages(imageParser.getImage(down+"_w"), imageParser.getImage(down+"_c"), imageParser.getImage(down+"_e"));
1038  textButtonFactory = new TextButtonFactory(upImages, downImages, font, color, colorSelected);
1039  break;
1040 
1041  default:
1042  throw new IOException("unknown type '"+type+"'");
1043  }
1044  }
1045 
1058  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 {
1059  if (dialogFactory == null) {
1060  throw new IOException("missing 'def dialog' command");
1061  }
1062 
1063  final Expression defaultX = ExpressionParser.parseExpression(args.get());
1064  final Expression defaultY = ExpressionParser.parseExpression(args.get());
1065  final boolean saveDialog = NumberParser.parseBoolean(args.get());
1066  final String title = ParseUtils.parseText(args, lnr);
1067  assert dialogFactory != null;
1068  final Iterable<AbstractGUIElement> elements = dialogFactory.newDialog(tooltipManager, windowRenderer, elementListener, title);
1069  for (final AbstractGUIElement element : elements) {
1070  insertGuiElement(element);
1071  }
1072  gui.setName(dialogName);
1073  gui.setDefaultPosition(defaultX, defaultY);
1074  if (saveDialog) {
1075  gui.setSaveDialog();
1076  }
1077  }
1078 
1085  private static void parseDialogHide(@NotNull final Args args, @NotNull final Gui gui) throws IOException {
1086  do {
1087  gui.hideInState(NumberParser.parseEnum(RendererGuiState.class, args.get(), "gui state"));
1088  } while (args.hasMore());
1089  }
1090 
1100  private void parseDupGauge(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
1101  final String name = args.get();
1102  final Image positiveDivImage = imageParser.getImage(args.get());
1103  final Image positiveModImage = imageParser.getImage(args.get());
1104  final Image emptyImage = args.get().equals("null") ? null : imageParser.getImage(args.getPrev());
1105  final GaugeUpdater gaugeUpdater = newGaugeUpdater(args.get());
1106  final Orientation orientationDiv = ParseUtils.parseOrientation(args.get());
1107  final Orientation orientationMod = ParseUtils.parseOrientation(args.get());
1108  final CommandList commandList = args.get().equals("null") ? null : skin.getCommandList(args.getPrev());
1109  final String tooltipPrefix = ParseUtils.parseText(args, lnr);
1110  final GUIDupGauge element = new GUIDupGauge(tooltipManager, elementListener, name, positiveDivImage, positiveModImage, emptyImage, orientationDiv, orientationMod, tooltipPrefix.isEmpty() ? null : tooltipPrefix, commandList);
1111  insertGuiElement(element);
1112  gaugeUpdater.setGauge(element);
1113  }
1114 
1124  private void parseDupTextGauge(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
1125  final String name = args.get();
1126  final Image positiveDivImage = imageParser.getImage(args.get());
1127  final Image positiveModImage = imageParser.getImage(args.get());
1128  final Image emptyImage = imageParser.getImage(args.get());
1129  final GaugeUpdater gaugeUpdater = newGaugeUpdater(args.get());
1130  final Orientation orientationDiv = ParseUtils.parseOrientation(args.get());
1131  final Orientation orientationMod = ParseUtils.parseOrientation(args.get());
1132  final Color color = ParseUtils.parseColor(args.get());
1133  final Font font = definedFonts.lookup(args.get());
1134  final CommandList commandList = args.get().equals("null") ? null : skin.getCommandList(args.getPrev());
1135  final String tooltipPrefix = ParseUtils.parseText(args, lnr);
1136  final GUIDupTextGauge element = new GUIDupTextGauge(tooltipManager, elementListener, name, positiveDivImage, positiveModImage, emptyImage, orientationDiv, orientationMod, tooltipPrefix.isEmpty() ? null : tooltipPrefix, color, font, commandList);
1137  insertGuiElement(element);
1138  gaugeUpdater.setGauge(element);
1139  }
1140 
1149  private void parseEvent(@NotNull final Args args, @NotNull final GuiStateManager guiStateManager, @NotNull final CrossfireServerConnection server) throws IOException, JXCSkinException {
1150  final String type = args.get();
1151  switch (type) {
1152  case "connect": {
1153  final CommandList commandList = skin.getCommandList(args.get());
1154  skin.addSkinEvent(new ConnectionStateSkinEvent(commandList, guiStateManager));
1155  break;
1156  }
1157 
1158  case "init":
1159  skin.addInitEvent(skin.getCommandList(args.get()));
1160  break;
1161 
1162  case "login": {
1163  final CommandList commandList = skin.getCommandList(args.get());
1164  skin.addSkinEvent(new PlayerLoginSkinEvent(true, commandList, model.getItemSet()));
1165  break;
1166  }
1167 
1168  case "logout": {
1169  final CommandList commandList = skin.getCommandList(args.get());
1170  skin.addSkinEvent(new PlayerLoginSkinEvent(false, commandList, model.getItemSet()));
1171  break;
1172  }
1173 
1174  case "magicmap": {
1175  final CommandList commandList = skin.getCommandList(args.get());
1176  skin.addSkinEvent(new CrossfireMagicmapSkinEvent(commandList, server));
1177  break;
1178  }
1179 
1180  case "mapscroll": {
1181  final CommandList commandList = skin.getCommandList(args.get());
1182  skin.addSkinEvent(new MapScrollSkinEvent(commandList, mapUpdaterState));
1183  break;
1184  }
1185 
1186  case "skill":
1187  final String subtype = args.get();
1188  final Skill skill = model.getSkillSet().getNamedSkill(args.get().replaceAll("_", " "), -1);
1189  final CommandList commandList = skin.getCommandList(args.get());
1190  switch (subtype) {
1191  case "add":
1192  skin.addSkinEvent(new SkillAddedSkinEvent(commandList, skill));
1193  break;
1194 
1195  case "del":
1196  skin.addSkinEvent(new SkillRemovedSkinEvent(commandList, skill));
1197  break;
1198 
1199  default:
1200  throw new IOException("undefined event sub-type: "+subtype);
1201  }
1202  break;
1203 
1204  default:
1205  throw new IOException("undefined event type: "+type);
1206  }
1207  }
1208 
1217  private void parseFill(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
1218  final String name = args.get();
1219  final Color color = ParseUtils.parseColor(args.get());
1220  final float alpha = NumberParser.parseFloat(args.get());
1221  if (alpha < 0 || alpha > 1.0F) {
1222  throw new IOException("invalid alpha value: "+alpha);
1223  }
1224  insertGuiElement(new GUIFill(tooltipManager, elementListener, name, color, alpha));
1225  }
1226 
1233  private void parseFont(@NotNull final Args args) throws IOException, JXCSkinException {
1234  final String name = args.get();
1235  final Font fontNormal = fontParser.getFont(args.get());
1236  final Font font = fontNormal.deriveFont(NumberParser.parseFloat(args.get()));
1237  definedFonts.insert(name, font);
1238  }
1239 
1249  private void parseGauge(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
1250  if (dialogFactory == null) {
1251  throw new IOException("missing 'def dialog' command");
1252  }
1253 
1254  final String name = args.get();
1255  final Image positiveImage = args.get().equals("null") ? null : imageParser.getImage(args.getPrev());
1256  final Image negativeImage = args.get().equals("null") ? null : imageParser.getImage(args.getPrev());
1257  final Image emptyImage = args.get().equals("null") ? null : imageParser.getImage(args.getPrev());
1258  final GaugeUpdater gaugeUpdater = newGaugeUpdater(args.get());
1259  final Orientation orientation = ParseUtils.parseOrientation(args.get());
1260  final CommandList commandList = args.get().equals("null") ? null : skin.getCommandList(args.getPrev());
1261  final String tooltipPrefix = ParseUtils.parseText(args, lnr);
1262  assert dialogFactory != null;
1263  final float alpha = dialogFactory.getFrameAlpha();
1264  final GUIGauge element = new GUIGauge(tooltipManager, elementListener, name, positiveImage, negativeImage, emptyImage, orientation, tooltipPrefix.isEmpty() ? null : tooltipPrefix, alpha, commandList);
1265  insertGuiElement(element);
1266  gaugeUpdater.setGauge(element);
1267  }
1268 
1275  private void parseIgnore(@NotNull final Args args) throws IOException, JXCSkinException {
1276  final String name = args.get();
1277  definedGUIElements.lookup(name).setIgnore();
1278  }
1279 
1295  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 {
1296  if (defaultItemPainter == null) {
1297  throw new IOException("cannot use '"+type+"_list"+"' without 'def item' command");
1298  }
1299 
1300  final String name = args.get();
1301  final int cellWidth = ExpressionParser.parseInt(args.get());
1302  final int cellHeight = ExpressionParser.parseInt(args.get());
1303  final AbstractLabel selectedItem = args.get().equals("null") ? null : guiElementParser.lookupLabelElement(args.getPrev());
1304 
1305  assert defaultItemPainter != null;
1306  final ItemPainter itemPainter = defaultItemPainter.newItemPainter();
1307  final AbstractGUIElement element;
1308  switch (type) {
1309  case INVENTORY:
1310  element = new GUIInventoryList(tooltipManager, elementListener, name, cellWidth, cellHeight, inventoryView, selectedItem, commandQueue, itemPainter, server, facesManager, floorView);
1311  break;
1312 
1313  case GROUND:
1314  element = new GUIFloorList(tooltipManager, elementListener, name, cellWidth, cellHeight, floorView, selectedItem, commandQueue, itemPainter, server, facesManager, model.getItemSet(), nextGroupFace, prevGroupFace);
1315  break;
1316 
1317  case SPELL:
1318  element = new GUISpellList(tooltipManager, elementListener, name, cellWidth, cellHeight, spellView, selectedItem, model.getSpellsManager(), keybindingsManager, commandQueue, itemPainter, facesManager, currentSpellManager);
1319  break;
1320 
1321  case QUEST:
1322  element = new GUIQuestList(tooltipManager, elementListener, name, cellWidth, cellHeight, questView, selectedItem, model.getQuestsManager(), itemPainter, facesManager);
1323  break;
1324 
1325  case SPELL_SKILLS:
1327  element = new GUISpellSkillList(tooltipManager, elementListener, name, cellWidth, cellHeight, spellSkillsView, selectedItem, model.getSpellsManager(), itemPainter, facesManager, defaultSkillIcon);
1328  break;
1329 
1330  case KNOWLEDGE_TYPES:
1331  element = new GUIKnowledgeTypeList(tooltipManager, elementListener, name, cellWidth, cellHeight, knowledgeTypeView, selectedItem, model.getKnowledgeManager(), itemPainter, facesManager);
1332  break;
1333 
1334  case KNOWLEDGE_LIST:
1335  element = new GUIKnowledgeList(tooltipManager, elementListener, name, cellWidth, cellHeight, knowledgeView, selectedItem, itemPainter, facesManager, model.getKnowledgeManager(), commandQueue);
1336  break;
1337 
1338  default:
1339  throw new AssertionError("unhandled type "+type);
1340  }
1341  insertGuiElement(element);
1342  }
1343 
1354  private void parseHorizontal(@NotNull final Args args, @NotNull final Container gui, @NotNull final LineNumberReader lnr, final boolean isDialog) throws IOException, JXCSkinException {
1355  final GroupLayout layout = (GroupLayout)gui.getLayout();
1356  final String begin = args.get();
1357  if (!begin.equals("begin")) {
1358  throw new IOException("syntax error: expecting 'begin'");
1359  }
1360  final Collection<GUIElement> unreferencedElements = new TreeSet<>(ELEMENT_COMPARATOR);
1361  for (final GUIElement element : definedGUIElements) {
1362  unreferencedElements.add(element);
1363  }
1364  if (!isDialog) {
1365  final Group content = parseBegin(args, layout, lnr, unreferencedElements);
1366  if (!unreferencedElements.isEmpty()) {
1367  throw new IOException("layout doesn't define elements "+unreferencedElements);
1368  }
1369  layout.setHorizontalGroup(content);
1370  return;
1371  }
1372  final Component background = getUnreferencedElement("dialog_background", unreferencedElements);
1373  if (background == null) {
1374  throw new AssertionError("element 'dialog_background' is missing");
1375  }
1376  final Group content = parseBegin(args, layout, lnr, unreferencedElements);
1377  final Component title = getUnreferencedElement("dialog_title", unreferencedElements);
1378  final Component close = getUnreferencedElement("dialog_close", unreferencedElements);
1379  final Group group2 = layout.createSequentialGroup();
1380  group2.addGap(DIALOG_BORDER_WIDTH);
1381  if (title == null) {
1382  if (close == null) {
1383  final Group group3 = layout.createParallelGroup();
1384  group3.addGroup(content);
1385  group2.addGroup(group3);
1386  } else {
1387  final Group group3 = layout.createParallelGroup();
1388  group3.addGap(0, 0, Short.MAX_VALUE);
1389  group3.addComponent(close);
1390  group2.addGroup(group3);
1391  group2.addGroup(content);
1392  }
1393  } else {
1394  final Group group3 = layout.createParallelGroup();
1395  if (close == null) {
1396  group3.addComponent(title);
1397  group3.addGroup(content);
1398  } else {
1399  final Group group4 = layout.createSequentialGroup();
1400  group4.addComponent(title);
1401  group4.addComponent(close);
1402  group3.addGroup(group4);
1403  group3.addGroup(content);
1404  }
1405  group2.addGroup(group3);
1406  }
1407  group2.addGap(DIALOG_BORDER_WIDTH);
1408  if (!unreferencedElements.isEmpty()) {
1409  throw new IOException("layout doesn't define elements "+unreferencedElements);
1410  }
1411 
1412  final Group group1 = layout.createParallelGroup();
1413  group1.addGroup(group2);
1414  group1.addComponent(background);
1415 
1416  layout.setHorizontalGroup(group1);
1417  }
1418 
1425  @Nullable
1426  private Component getUnreferencedElement(@NotNull final String name, @NotNull final Collection<GUIElement> unreferencedElements) {
1427  final AbstractGUIElement component = definedGUIElements.lookupOptional(name);
1428  if (component == null) {
1429  return null;
1430  }
1431 
1432  return unreferencedElements.remove(component) ? component : null;
1433  }
1434 
1449  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 {
1450  final String type = args.get();
1451  final String name = args.get();
1452  final int index = ExpressionParser.parseInt(args.get());
1453  final AbstractGUIElement element;
1454  switch (type) {
1455  case "floor": {
1456  if (defaultItemPainter == null) {
1457  throw new IOException("cannot use 'item floor' without 'def item' command");
1458  }
1459 
1460  final ItemPainter itemPainter = defaultItemPainter.newItemPainter();
1461  element = new GUIItemFloor(tooltipManager, elementListener, commandQueue, name, itemPainter, index, server, floorView, model.getItemSet(), facesManager, nextGroupFace, prevGroupFace, 0);
1462  break;
1463  }
1464 
1465  case "inventory": {
1466  if (defaultItemPainter == null) {
1467  throw new IOException("cannot use 'item inventory' without 'def item' command");
1468  }
1469 
1470  final ItemPainter itemPainter = defaultItemPainter.newItemPainter();
1471  element = new GUIItemInventory(tooltipManager, elementListener, commandQueue, name, itemPainter, index, server, facesManager, floorView, inventoryView, 0);
1472  break;
1473  }
1474 
1475  case "shortcut":
1476  final Color castColor = ParseUtils.parseColorNull(args.get());
1477  final Image castImage = imageParser.getImage(castColor, args.getPrev());
1478  final Color invokeColor = ParseUtils.parseColorNull(args.get());
1479  final Image invokeImage = imageParser.getImage(invokeColor, args.getPrev());
1480  final Font font = definedFonts.lookup(args.get());
1481  element = new GUIItemShortcut(tooltipManager, elementListener, name, castColor, castImage, invokeColor, invokeImage, index, facesManager, shortcuts, font, currentSpellManager);
1482  break;
1483 
1484  case "spelllist":
1485  if (defaultItemPainter == null) {
1486  throw new IOException("cannot use 'item spelllist' without 'def item' command");
1487  }
1488 
1489  final ItemPainter itemPainter = defaultItemPainter.newItemPainter();
1490  element = new GUIItemSpell(tooltipManager, elementListener, commandQueue, name, itemPainter, index, facesManager, model.getSpellsManager(), currentSpellManager, spellView, 0);
1491  break;
1492 
1493  default:
1494  throw new IOException("undefined item type: "+type);
1495  }
1496  insertGuiElement(element);
1497  }
1498 
1506  private void parseKey(@NotNull final Args args, @Nullable final Gui gui, @NotNull final String line) throws IOException {
1507  final KeyBindings keyBindings = gui == null ? skin.getDefaultKeyBindings() : gui.getKeyBindings();
1508  try {
1509  keyBindings.parseKeyBinding(line.substring(4).trim(), true);
1510  } catch (final InvalidKeyBindingException ex) {
1511  throw new IOException("invalid key binding: "+ex.getMessage(), ex);
1512  }
1513 
1514  // consume all arguments to prevent syntax error
1515  while (args.hasMore()) {
1516  args.get();
1517  }
1518  }
1519 
1529  private void parseLabelHtml(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
1530  final String name = args.get();
1531  final Font font = definedFonts.lookup(args.get());
1532  final Color color = ParseUtils.parseColor(args.get());
1533  final String text = ParseUtils.parseText(args, lnr);
1534  insertGuiElement(new GUIHTMLLabel(tooltipManager, elementListener, name, null, font, color, null, text));
1535  }
1536 
1546  private void parseLabelMulti(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
1547  final String name = args.get();
1548  final Font font = definedFonts.lookup(args.get());
1549  final Color color = ParseUtils.parseColor(args.get());
1550  final String text = ParseUtils.parseText(args, lnr);
1551  insertGuiElement(new GUIMultiLineLabel(tooltipManager, elementListener, name, null, font, color, null, Alignment.LEFT, text));
1552  }
1553 
1563  private void parseLabelQuery(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CrossfireServerConnection server) throws IOException, JXCSkinException {
1564  final String name = args.get();
1565  final Font font = definedFonts.lookup(args.get());
1566  final Color color = ParseUtils.parseColor(args.get());
1567  final AbstractGUIElement element = new GUILabelQuery(tooltipManager, elementListener, name, server, font, color, null);
1568  insertGuiElement(element);
1569  }
1570 
1581  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 {
1582  final String name = args.get();
1583  final Font font = definedFonts.lookup(args.get());
1584  final Color color = ParseUtils.parseColor(args.get());
1585  final AbstractGUIElement element = new GUILabelMessage(tooltipManager, elementListener, name, server, windowRenderer, font, color, null);
1586  insertGuiElement(element);
1587  }
1588 
1598  private void parseLabelFailure(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CrossfireServerConnection server) throws IOException, JXCSkinException {
1599  final String name = args.get();
1600  final Font font = definedFonts.lookup(args.get());
1601  final Color color = ParseUtils.parseColor(args.get());
1602  final AbstractGUIElement element = new GUILabelFailure(tooltipManager, elementListener, name, server, font, color, null);
1603  insertGuiElement(element);
1604  }
1605 
1615  private void parseLabelText(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
1616  final String name = args.get();
1617  final Font font = definedFonts.lookup(args.get());
1618  final Color color = ParseUtils.parseColor(args.get());
1619  final String text = ParseUtils.parseText(args, lnr);
1620  insertGuiElement(new GUIOneLineLabel(tooltipManager, elementListener, name, null, font, color, null, Alignment.LEFT, text));
1621  }
1622 
1631  private void parseLabelStat(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
1632  final String name = args.get();
1633  final Font font = definedFonts.lookup(args.get());
1634  final Color color = ParseUtils.parseColor(args.get());
1635  final int stat = ParseUtils.parseStat(args.get());
1636  final Alignment alignment = NumberParser.parseEnum(Alignment.class, args.get(), "text alignment");
1637  final AbstractGUIElement element = new GUILabelStats(tooltipManager, elementListener, name, font, color, null, stat, alignment, model.getStats());
1638  insertGuiElement(element);
1639  }
1640 
1649  private void parseLabelStat2(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
1650  final String name = args.get();
1651  final Font font = definedFonts.lookup(args.get());
1652  final Color colorNormal = ParseUtils.parseColor(args.get());
1653  final Color colorUpgradable = ParseUtils.parseColor(args.get());
1654  final Color colorDepleted = ParseUtils.parseColor(args.get());
1655  final Color colorBoosted = ParseUtils.parseColor(args.get());
1656  final Color colorBoostedUpgradable = ParseUtils.parseColor(args.get());
1657  final int statCurrent = ParseUtils.parseStat(args.get());
1658  final int statBase = ParseUtils.parseStat(args.get());
1659  final int statRace = ParseUtils.parseStat(args.get());
1660  final int statApplied = ParseUtils.parseStat(args.get());
1661  final Alignment alignment = NumberParser.parseEnum(Alignment.class, args.get(), "text alignment");
1662  final AbstractGUIElement element = new GUILabelStats2(tooltipManager, elementListener, name, font, colorNormal, colorUpgradable, colorDepleted, colorBoosted, colorBoostedUpgradable, null, statCurrent, statBase, statRace, statApplied, alignment, model.getStats());
1663  insertGuiElement(element);
1664  }
1665 
1675  private void parseLabelSpell(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CurrentSpellManager currentSpellManager) throws IOException, JXCSkinException {
1676  final String name = args.get();
1677  final Font font = definedFonts.lookup(args.get());
1678  final Type type = NumberParser.parseEnum(Type.class, args.get(), "label type");
1679  final AbstractGUIElement element = new GUISpellLabel(tooltipManager, elementListener, name, null, facesManager, font, type, currentSpellManager);
1680  insertGuiElement(element);
1681  }
1682 
1690  private void parseLinkSize(@NotNull final Args args, @NotNull final Container gui) throws IOException, JXCSkinException {
1691  final String type = args.get();
1692  final List<Component> elements = new ArrayList<>();
1693  while (args.hasMore()) {
1694  elements.add(definedGUIElements.lookup(args.get()));
1695  }
1696  if (elements.size() < 2) {
1697  throw new IOException("'link_size' needs at least two gui elements");
1698  }
1699  final Component[] array = elements.toArray(new Component[elements.size()]);
1700  final GroupLayout layout = (GroupLayout)gui.getLayout();
1701  switch (type) {
1702  case "horizontal":
1703  layout.linkSize(SwingConstants.HORIZONTAL, array);
1704  break;
1705 
1706  case "vertical":
1707  layout.linkSize(SwingConstants.VERTICAL, array);
1708  break;
1709 
1710  case "both":
1711  layout.linkSize(SwingConstants.HORIZONTAL, array);
1712  layout.linkSize(SwingConstants.VERTICAL, array);
1713  break;
1714 
1715  default:
1716  throw new IOException("undefined type '"+type+"'");
1717  }
1718  }
1719 
1728  private void parseLogLabel(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
1729  final String name = args.get();
1730  final Image backgroundImage = args.get().equals("null") ? null : imageParser.getImage(args.getPrev());
1731  final Font fontPrint = definedFonts.lookup(args.get());
1732  final Font fontFixed = definedFonts.lookup(args.get());
1733  final Font fontFixedBold = definedFonts.lookup(args.get());
1734  final Font fontArcane = definedFonts.lookup(args.get());
1735  final Color defaultColor = ParseUtils.parseColor(args.get());
1736  final Fonts fonts = new Fonts(fontPrint, fontFixed, fontFixedBold, fontArcane);
1737  final AbstractGUIElement element = new GUILabelLog(tooltipManager, elementListener, name, backgroundImage, fonts, defaultColor);
1738  insertGuiElement(element);
1739  }
1740 
1750  private void parseLogMessage(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CrossfireServerConnection server) throws IOException, JXCSkinException {
1751  final String name = args.get();
1752  final Image backgroundImage = args.get().equals("null") ? null : imageParser.getImage(args.getPrev());
1753  final Font fontPrint = definedFonts.lookup(args.get());
1754  final Font fontFixed = definedFonts.lookup(args.get());
1755  final Font fontFixedBold = definedFonts.lookup(args.get());
1756  final Font fontArcane = definedFonts.lookup(args.get());
1757  final Color defaultColor = ParseUtils.parseColor(args.get());
1758  final Fonts fonts = new Fonts(fontPrint, fontFixed, fontFixedBold, fontArcane);
1759  final AbstractGUIElement element = new GUIMessageLog(tooltipManager, elementListener, name, server, backgroundImage, fonts, defaultColor);
1760  insertGuiElement(element);
1761  }
1762 
1769  private void parseLogColor(@NotNull final Args args) throws IOException, JXCSkinException {
1770  final String name = args.get();
1771  final int index = ExpressionParser.parseInt(args.get());
1772  final Color color = ParseUtils.parseColor(args.get());
1773  final Object element = definedGUIElements.lookup(name);
1774  if (!(element instanceof GUIMessageLog)) {
1775  throw new IOException("element '"+name+"' is not of type 'log'");
1776  }
1777  if (index < 0 || index >= MessageBufferUpdater.NUM_COLORS) {
1778  throw new IOException("invalid color index "+index);
1779  }
1780  ((GUIMessageLog)element).setColor(index, color);
1781  }
1782 
1789  private void parseLogFilter(@NotNull final Args args) throws IOException, JXCSkinException {
1790  final String name = args.get();
1791  final String type = args.get();
1792  final boolean add;
1793  switch (type) {
1794  case "only":
1795  add = true;
1796  break;
1797 
1798  case "not":
1799  add = false;
1800  break;
1801 
1802  default:
1803  throw new IOException("type '"+type+"' is invalid");
1804  }
1805  int types = 0;
1806  do {
1807  try {
1808  types |= 1<<MessageTypes.parseMessageType(args.get());
1809  } catch (final UnknownMessageTypeException ex) {
1810  throw new IOException(ex);
1811  }
1812  } while (args.hasMore());
1813  if (!add) {
1814  types = ~types;
1815  }
1816  final Object element = definedGUIElements.lookup(name);
1817  if (!(element instanceof GUIMessageLog)) {
1818  throw new IOException("element '"+name+"' is not of type 'log'");
1819  }
1820  ((GUIMessageLog)element).setTypes(types);
1821  }
1822 
1831  private void parseMinimap(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
1832  final String name = args.get();
1833  final int w = ExpressionParser.parseInt(args.get());
1834  final int h = ExpressionParser.parseInt(args.get());
1835  final FacesProvider facesProvider = facesProviderFactory.getFacesProvider(4);
1836  if (facesProvider == null) {
1837  throw new IOException("cannot create faces with size 4");
1838  }
1839  final AbstractGUIElement element = new GUIMiniMap(avoidCopyArea, tooltipManager, elementListener, name, mapUpdaterState, facesProvider, darknessColors, w, h);
1840  insertGuiElement(element);
1841  }
1842 
1853  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 {
1854  final String name = args.get();
1855  final FacesProvider facesProvider = facesProviderFactory.getFacesProvider(defaultTileSize);
1856  if (facesProvider == null) {
1857  throw new IOException("cannot create faces with size "+defaultTileSize);
1858  }
1859  insertGuiElement(new GUIMap(avoidCopyArea, tooltipManager, elementListener, name, mapUpdaterState, facesProvider, server, smoothFaces, darknessColors));
1860  }
1861 
1871  private void parseMetaList(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final MetaserverModel metaserverModel) throws IOException, JXCSkinException {
1872  final String name = args.get();
1873  final int cellWidth = ExpressionParser.parseInt(args.get()); // XXX: should be derived from list's size
1874  final int cellHeight = ExpressionParser.parseInt(args.get()); // XXX: should be derived from list's size
1875  final Image image = args.get().equals("null") ? null : imageParser.getImage(args.getPrev());
1876  final Font font = definedFonts.lookup(args.get());
1877  final GUIText text = args.get().equals("null") ? null : guiElementParser.lookupTextElement(args.getPrev());
1878  final AbstractLabel label = args.get().equals("null") ? null : guiElementParser.lookupLabelElement(args.getPrev());
1879  final CommandList connectCommandList = skin.getCommandList(args.get());
1880  final String format = args.get();
1881  final String tooltip = args.get();
1882 
1883  final AbstractGUIElement list = new GUIMetaElementList(tooltipManager, elementListener, name, cellWidth, cellHeight, metaserverModel, image, font, format, tooltip, text, label, connectCommandList);
1884  insertGuiElement(list);
1885  }
1886 
1895  private void parsePicture(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
1896  final String name = args.get();
1897  final BufferedImage image = imageParser.getImage(args.get());
1898  final float alpha = NumberParser.parseFloat(args.get());
1899  if (alpha < 0 || alpha > 1.0F) {
1900  throw new IOException("invalid alpha value: "+alpha);
1901  }
1902  insertGuiElement(new GUIPicture(tooltipManager, elementListener, name, image, alpha, image.getWidth(), image.getHeight()));
1903  }
1904 
1915  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 {
1916  final String name = args.get();
1917  final Image activeImage = imageParser.getImage(args.get());
1918  final Image inactiveImage = imageParser.getImage(args.get());
1919  final Font font = definedFonts.lookup(args.get());
1920  final Color inactiveColor = ParseUtils.parseColor(args.get());
1921  final Color activeColor = ParseUtils.parseColor(args.get());
1922  final int margin = ExpressionParser.parseInt(args.get());
1923  final boolean enableHistory = NumberParser.parseBoolean(args.get());
1924  final CommandHistory commandHistory = enableHistory ? commandHistoryFactory.getCommandHistory(name) : null;
1925  insertGuiElement(new GUIQueryText(server, commandHistory, commandCallback, tooltipManager, elementListener, name, activeImage, inactiveImage, font, inactiveColor, activeColor, margin, ""));
1926  }
1927 
1935  private void parseSetForcedActive(@NotNull final Args args, @NotNull final Gui gui) throws IOException, JXCSkinException {
1936  final Object forcedActive = definedGUIElements.lookup(args.get());
1937  if (!(forcedActive instanceof ActivatableGUIElement)) {
1938  throw new IOException("argument to set_forced_active must be an activatable gui element");
1939  }
1940  gui.setForcedActive((ActivatableGUIElement)forcedActive);
1941  }
1942 
1949  private static void parseSetAutoSize(@NotNull final Gui gui, @NotNull final Args args) throws IOException {
1950  final Expression x = ExpressionParser.parseExpression(args.get());
1951  final Expression y = ExpressionParser.parseExpression(args.get());
1952  final Expression w = ExpressionParser.parseExpression(args.get());
1953  final Expression h = ExpressionParser.parseExpression(args.get());
1954  gui.setAutoSize(new Extent(x, y, w, h));
1955  }
1956 
1963  private void parseSetDefault(@NotNull final Args args) throws IOException, JXCSkinException {
1964  definedGUIElements.lookup(args.get()).setDefault(true);
1965  }
1966 
1973  private void parseSetInvisible(@NotNull final Args args) throws IOException, JXCSkinException {
1974  definedGUIElements.lookup(args.get()).setVisible(false);
1975  }
1976 
1983  private void parseHideInput(@NotNull final Args args) throws IOException, JXCSkinException {
1984  final GUIText element;
1985  try {
1986  element = (GUIText)definedGUIElements.lookup(args.get());
1987  } catch (final JXCSkinException ignored) {
1988  throw new JXCSkinException("can't use hide_input on a non text field "+args.getPrev());
1989  }
1990  element.setHideInput(true);
1991  }
1992 
1997  private static void parseSetModal(@NotNull final Gui gui) {
1998  gui.setModal(true);
1999  }
2000 
2009  private void parseScrollbar(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
2010  final String name = args.get();
2011  final boolean proportionalSlider = NumberParser.parseBoolean(args.get());
2012  final Object element = definedGUIElements.lookup(args.get());
2013  final Color colorBackground = ParseUtils.parseColor(args.get());
2014  final Color colorForeground = ParseUtils.parseColor(args.get());
2015  if (!(element instanceof GUIScrollable2)) {
2016  throw new IOException("'"+element+"' is not a scrollable element");
2017  }
2018  insertGuiElement(new GUIScrollBar(tooltipManager, elementListener, name, proportionalSlider, (GUIScrollable2)element, colorBackground, colorForeground));
2019  }
2020 
2026  private void parseSkinName(@NotNull final Args args) throws IOException {
2027  final String newSkinName = args.get();
2028  final Resolution minResolution = parseResolution(args.get());
2029  final Resolution maxResolution = parseResolution(args.get());
2030  if (!newSkinName.matches("[-a-z_0-9]+")) {
2031  throw new IOException("invalid skin_name: "+newSkinName);
2032  }
2033  if (minResolution.getWidth() > maxResolution.getWidth() || minResolution.getHeight() > maxResolution.getHeight()) {
2034  throw new IOException("minimum resolution ("+minResolution+") must not exceed maximum resolution ("+maxResolution+")");
2035  }
2036 
2037  skin.setSkinName(newSkinName, minResolution, maxResolution);
2038  }
2039 
2049  private void parseText(@NotNull final Args args, @NotNull final CommandCallback commandCallback, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
2050  final String name = args.get();
2051  final Image activeImage = imageParser.getImage(args.get());
2052  final Image inactiveImage = imageParser.getImage(args.get());
2053  final Font font = definedFonts.lookup(args.get());
2054  final Color activeColor = ParseUtils.parseColor(args.get());
2055  final Color inactiveColor = ParseUtils.parseColor(args.get());
2056  final int margin = ExpressionParser.parseInt(args.get());
2057  final CommandList commandList = skin.getCommandList(args.get());
2058  final boolean enableHistory = NumberParser.parseBoolean(args.get());
2059  final CommandHistory commandHistory = enableHistory ? commandHistoryFactory.getCommandHistory(name) : null;
2060  insertGuiElement(new GUITextField(commandCallback, commandHistory, tooltipManager, elementListener, name, activeImage, inactiveImage, font, inactiveColor, activeColor, margin, "", commandList));
2061  }
2062 
2072  private void parseTextButton(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
2073  if (textButtonFactory == null) {
2074  throw new IOException("missing 'def textbutton' command");
2075  }
2076 
2077  final String name = args.get();
2078  final boolean autoRepeat = NumberParser.parseBoolean(args.get());
2079  final CommandList commandList = skin.getCommandList(args.get());
2080  final String text = ParseUtils.parseText(args, lnr);
2081  assert textButtonFactory != null;
2082  insertGuiElement(textButtonFactory.newTextButton(tooltipManager, elementListener, name, text, autoRepeat, commandList));
2083  }
2084 
2094  private void parseTextGauge(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr) throws IOException, JXCSkinException {
2095  if (dialogFactory == null) {
2096  throw new IOException("missing 'def dialog' command");
2097  }
2098 
2099  final String name = args.get();
2100  final Image positiveImage = imageParser.getImage(args.get());
2101  final Image negativeImage = args.get().equals("null") ? null : imageParser.getImage(args.getPrev());
2102  final Image emptyImage = imageParser.getImage(args.get());
2103  final GaugeUpdater gaugeUpdater = newGaugeUpdater(args.get());
2104  final Orientation orientation = ParseUtils.parseOrientation(args.get());
2105  final Color color = ParseUtils.parseColor(args.get());
2106  final Font font = definedFonts.lookup(args.get());
2107  final CommandList commandList = args.get().equals("null") ? null : skin.getCommandList(args.getPrev());
2108  final String tooltipPrefix = ParseUtils.parseText(args, lnr);
2109  assert dialogFactory != null;
2110  final float alpha = dialogFactory.getFrameAlpha();
2111  final GUITextGauge element = new GUITextGauge(tooltipManager, elementListener, name, positiveImage, negativeImage, emptyImage, orientation, tooltipPrefix.isEmpty() ? null : tooltipPrefix, color, font, alpha, commandList);
2112  insertGuiElement(element);
2113  gaugeUpdater.setGauge(element);
2114  }
2115 
2124  private void parseTooltip(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener) throws IOException, JXCSkinException {
2125  final Font font = definedFonts.lookup(args.get());
2126  final GUIHTMLLabel tooltipLabel = new GUIHTMLLabel(tooltipManager, elementListener, "tooltip", null, font, Color.BLACK, Color.WHITE, "");
2127  tooltipLabel.setAutoResize(true);
2128  skin.setTooltipLabel(tooltipLabel);
2129  }
2130 
2141  private void parseVertical(@NotNull final Args args, @NotNull final Container gui, @NotNull final LineNumberReader lnr, final boolean isDialog) throws IOException, JXCSkinException {
2142  final GroupLayout layout = (GroupLayout)gui.getLayout();
2143  final String begin = args.get();
2144  if (!begin.equals("begin")) {
2145  throw new IOException("syntax error: expecting 'begin'");
2146  }
2147  final Collection<GUIElement> unreferencedElements = new TreeSet<>(ELEMENT_COMPARATOR);
2148  for (final GUIElement element : definedGUIElements) {
2149  unreferencedElements.add(element);
2150  }
2151  if (!isDialog) {
2152  final Group content = parseBegin(args, layout, lnr, unreferencedElements);
2153  if (!unreferencedElements.isEmpty()) {
2154  throw new IOException("layout doesn't define elements "+unreferencedElements);
2155  }
2156  layout.setVerticalGroup(content);
2157  return;
2158  }
2159  final Component background = getUnreferencedElement("dialog_background", unreferencedElements);
2160  if (background == null) {
2161  throw new AssertionError("element 'dialog_background' is missing");
2162  }
2163  final Group content = parseBegin(args, layout, lnr, unreferencedElements);
2164  final Component title = getUnreferencedElement("dialog_title", unreferencedElements);
2165  final Component close = getUnreferencedElement("dialog_close", unreferencedElements);
2166  final Group group2 = layout.createSequentialGroup();
2167  group2.addGap(DIALOG_BORDER_WIDTH);
2168  if (title == null) {
2169  if (close == null) {
2170  group2.addGroup(content);
2171  } else {
2172  final Group group4 = layout.createParallelGroup();
2173  group4.addComponent(close);
2174  group4.addGap(0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE);
2175  final Group group3 = layout.createParallelGroup();
2176  group3.addGroup(content);
2177  group3.addGroup(group4);
2178  group2.addGroup(group3);
2179  }
2180  } else {
2181  if (close == null) {
2182  group2.addComponent(title);
2183  group2.addGroup(content);
2184  } else {
2185  final Group group3 = layout.createParallelGroup();
2186  group3.addComponent(title);
2187  group3.addComponent(close);
2188  group2.addGroup(group3);
2189  group2.addGroup(content);
2190  }
2191  }
2192  group2.addGap(DIALOG_BORDER_WIDTH);
2193  if (!unreferencedElements.isEmpty()) {
2194  throw new IOException("layout doesn't define elements "+unreferencedElements);
2195  }
2196 
2197  final Group group1 = layout.createParallelGroup();
2198  group1.addGroup(group2);
2199  group1.addComponent(background);
2200 
2201  layout.setVerticalGroup(group1);
2202  }
2203 
2210  @NotNull
2211  private static Resolution parseResolution(@NotNull final String text) throws IOException {
2212  final Resolution resolution = Resolution.parse(text);
2213  if (resolution == null) {
2214  throw new IOException("invalid resolution: "+resolution);
2215  }
2216  return resolution;
2217  }
2218 
2228  private void parseCharacterList(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CharacterModel characterModel) throws IOException, JXCSkinException {
2229  final String name = args.get();
2230  final int cellWidth = ExpressionParser.parseInt(args.get());
2231  final int cellHeight = ExpressionParser.parseInt(args.get());
2232  final Font font = definedFonts.lookup(args.get());
2233  final AbstractGUIElement list = new GUICharacterList(tooltipManager, facesManager, elementListener, name, cellWidth, cellHeight, font, characterModel);
2234  insertGuiElement(list);
2235  }
2236 
2242  private void insertGuiElement(@NotNull final AbstractGUIElement guiElement) throws JXCSkinException {
2243  definedGUIElements.insert(guiElement.getName(), guiElement);
2244  skin.insertGuiElement(guiElement);
2245  }
2246 
2263  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 {
2264  final CommandList commandList = skin.getCommandList(listName);
2265  commandList.add(commandParser.parseCommandArgs(args, element, command, guiStateManager, commandExecutor, lnr, commandQueue, crossfireServerConnection, commandCallback, macros));
2266  }
2267 
2275  @NotNull
2276  private GaugeUpdater newGaugeUpdater(@NotNull final String name) throws IOException {
2277  return gaugeUpdaterParser.parseGaugeUpdater(name, model.getExperienceTable());
2278  }
2279 
2291  @NotNull
2292  private Group parseBegin(@NotNull final Args beginArgs, @NotNull final GroupLayout layout, @NotNull final LineNumberReader lnr, @NotNull final Collection<GUIElement> unreferencedElements) throws IOException, JXCSkinException {
2293  final String type = beginArgs.get();
2294  final Group group;
2295  switch (type) {
2296  case "seq":
2297  group = layout.createSequentialGroup();
2298  break;
2299 
2300  case "par":
2301  group = layout.createParallelGroup();
2302  break;
2303 
2304  default:
2305  throw new IOException("undefined type '"+type+"'");
2306  }
2307 
2308  while (true) {
2309  final String line = lnr.readLine();
2310  if (line == null) {
2311  throw new IOException("unterminated 'begin' block");
2312  }
2313 
2314  if (line.startsWith("#") || line.isEmpty()) {
2315  continue;
2316  }
2317 
2318  final String[] argsTmp;
2319  try {
2320  argsTmp = StringUtils.splitFields(line);
2321  } catch (final UnterminatedTokenException ex) {
2322  throw new JXCSkinException(ex.getMessage(), ex);
2323  }
2324  final Args args = new Args(argsTmp);
2325  final String cmd = args.get();
2326  if (cmd.equals("end")) {
2327  break;
2328  }
2329  switch (cmd) {
2330  case "begin":
2331  group.addGroup(parseBegin(args, layout, lnr, unreferencedElements));
2332  break;
2333 
2334  case "border_gap":
2335  if (!(group instanceof SequentialGroup)) {
2336  throw new IOException("'border_gap' cannot be used outside 'seq' groups");
2337  }
2338  ((SequentialGroup)group).addContainerGap();
2339  break;
2340 
2341  case "gap":
2342  if (args.hasMore()) {
2343  final int tmp = ExpressionParser.parseInt(args.get());
2344  if (args.hasMore()) {
2345  final int size = ExpressionParser.parseInt(args.get());
2346  final int max = args.hasMore() ? ExpressionParser.parseInt(args.get()) : Short.MAX_VALUE;
2347  group.addGap(tmp, size, max);
2348  } else {
2349  group.addGap(tmp);
2350  }
2351  } else {
2352  group.addGap(0, 1, Short.MAX_VALUE);
2353  }
2354  break;
2355 
2356  default:
2357  final AbstractGUIElement element = definedGUIElements.lookup(cmd);
2358  if (!unreferencedElements.remove(element)) {
2359  throw new IOException("layout defines element '"+element+"' more than once");
2360  }
2361  if (args.hasMore()) {
2362  final int tmp = ExpressionParser.parseInt(args.get());
2363  final int min;
2364  final int pref;
2365  final int max;
2366  if (args.hasMore()) {
2367  min = tmp;
2368  pref = ExpressionParser.parseInt(args.get());
2369  max = args.hasMore() ? ExpressionParser.parseInt(args.get()) : Short.MAX_VALUE;
2370  } else {
2371  min = tmp;
2372  pref = tmp;
2373  max = tmp;
2374  }
2375  group.addComponent(element, min, pref, max);
2376  } else {
2377  group.addComponent(element);
2378  }
2379  break;
2380  }
2381  if (args.hasMore()) {
2382  throw new IOException("excess arguments");
2383  }
2384  }
2385  return group;
2386  }
2387 
2388 }
FontParser fontParser
The FontParser for parsing font specifications.
static Color parseColor(@NotNull final String name)
Parses a color name.
Definition: ParseUtils.java:89
void parseLabelFailure(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CrossfireServerConnection server)
Parses a "label_failure" command.
void parseText(@NotNull final Args args, @NotNull final CommandCallback commandCallback, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener)
Parses a "text" command.
void parseIgnore(@NotNull final Args args)
Parses an "ignore" command.
final QuestsView questView
The QuestsView to use.
void parseLogLabel(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener)
Parses a "log_label" command.
Abstract base class for all label classes.
A SkinEvent that executes a CommandList whenever the map scroll protocol command is received...
A SkinEvent that executes a CommandList whenever a new skill has been gained.
A AbstractLabel that renders the text as a plain string.
static Orientation parseOrientation(@NotNull final String name)
Parses an orientation value.
Definition: ParseUtils.java:72
void parseHorizontal(@NotNull final Args args, @NotNull final Container gui, @NotNull final LineNumberReader lnr, final boolean isDialog)
Parses a "horizontal" command.
void parseKey(@NotNull final Args args, @Nullable final Gui gui, @NotNull final String line)
Parses a "key" command.
void parseQueryText(@NotNull final Args args, @NotNull final CrossfireServerConnection server, @NotNull final CommandCallback commandCallback, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener)
Parses a "query_text" command.
Provides a view of all quests a character is doing.
Definition: QuestsView.java:34
void parseMetaList(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final MetaserverModel metaserverModel)
Parses a "meta_list" command.
static final int NUM_COLORS
The number of supported colors.
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)
Loads a skin file and add the entries to a Gui instance.
A AbstractLabel that renders the text as a list of plain strings.
static FaceImages newFaceImages(@NotNull final ImageIcon originalImageIcon)
Creates a new FaceImages instance from an "original" face; the "scaled" and "magic map" sized images ...
final KeybindingsManager keybindingsManager
The KeybindingsManager containing key bindings.
Combines a list of GUIElements to for a gui.
Definition: Gui.java:43
Encapsulates the message type numbers for drawextinfo messages.
final GuiManager guiManager
The GuiManager to use.
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)
Loads the skin from its external representation.
final boolean avoidCopyArea
Whether map scrolling is done by copying pixel areas.
void parseKeyBinding(@NotNull final String line, final boolean isDefault)
Parses and add a key binding.
Encapsulates the extent of a GUI element.
Definition: Extent.java:31
A GUIItem for displaying inventory objects.
void parseSetInvisible(@NotNull final Args args)
Parses a "set_invisible" command.
void addDialog(@NotNull final String dialogName)
Defines a new dialog.
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)
Parses a "commandlist_add" command.
A factory class to create "checkbox" instances.
Skill getNamedSkill(@NotNull final String skillName, final int face)
Returns the skill instance for a given skill name.
Definition: SkillSet.java:141
static final String PREV_GROUP_FACE
The resource for "Click here for previous group of items" buttons.
Utility class for creating FaceImages instances.
static final int DIALOG_BORDER_WIDTH
The border width of dialogs.
Utility class for string manipulation.
void parseTooltip(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener)
Parses a "tooltip" command.
A GUIComboBox that shows available races for character creation.
TextButtonFactory textButtonFactory
The text button factory.
A GUIElement representing an in-game object in the ground view.
A factory class to create "textbutton" instances.
void parseHideInput(@NotNull final Args args)
Parses a "hide_input" command.
Iterable< AbstractGUIElement > newDialog(@NotNull final TooltipManager tooltipManager, @NotNull final JXCWindowRenderer windowRenderer, @NotNull final GUIElementListener elementListener, @NotNull final String title)
Creates a new dialog.
void insertGuiElement(@NotNull final GUIElement guiElement)
Adds a new GUIElement to this skin.
A GUIElement that fills an area with a given color.
Definition: GUIFill.java:38
void setAutoResize(final boolean autoResize)
Enable or disable auto-resizing.
static void parseSetModal(@NotNull final Gui gui)
Parses a "set_modal" command.
void setSkinName(@NotNull final String skinName, @NotNull final Resolution minResolution, @NotNull final Resolution maxResolution)
Sets the skin name.
void addOption(@NotNull final String optionName, @NotNull final String documentation, @NotNull final Option commandCheckBoxOption)
Add a new option.
void parseCheckbox(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr)
Parses a "checkbox" command.
static< T extends Enum< T > T parseEnum(@NotNull final Class< T > class_, @NotNull final String name, @NotNull final String ident)
Parses an enum constant.
Group parseBegin(@NotNull final Args beginArgs, @NotNull final GroupLayout layout, @NotNull final LineNumberReader lnr, @NotNull final Collection< GUIElement > unreferencedElements)
Parses a "begin..end" block.
ItemPainter newItemPainter()
Creates a new instance having the same parameters as this instance except for the item&#39;s size...
float getFrameAlpha()
Returns the alpha value for the frame background.
A SkinEvent that executes a CommandList at connection setup.
A GUIHTMLLabel that displays the last received "query" command.
A CheckBoxOption that executes CommandLists when checked/unchecked.
void parseLabelMessage(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CrossfireServerConnection server, @NotNull final JXCWindowRenderer windowRenderer)
Parses a "label_message" command.
void parseMap(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CrossfireServerConnection server, @NotNull final SmoothFaces smoothFaces)
Parses a "map" command.
static Expression parseExpression(@NotNull final String str)
Parses an integer constant.
static int parseInt(@NotNull final String str)
Parses an integer constant.
void parseLabelText(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr)
Parses a "label_text" command.
final KeyBindings defaultKeyBindings
The default key bindings.
final FacesProviderFactory facesProviderFactory
The FacesProviderFactory instance for creating faces provider instances.
Parser for loading JXCSkin instances from JXCSkinSources.
void setTooltipLabel(@Nullable final AbstractLabel tooltipLabel)
Sets the AbstractLabel that is used to display tooltips.
CommandParser commandParser
The CommandParser for parsing commands.
Implements the map model which is shown in the map and magic map views.
Definition: CfMap.java:22
void addCommandList(@NotNull final String commandListName, @NotNull final CommandListType commandListType)
Defines a new command list.
A gui element implementing the message window.
void parseLogFilter(@NotNull final Args args)
Parses a "log_filter" command.
final FacesManager facesManager
The FacesManager instance to use.
static final String ALL_SPELL_SKILLS_ICON
The resource name for the default skill face.
static Resolution parseResolution(@NotNull final String text)
Parses a resolution specification.
Component getUnreferencedElement(@NotNull final String name, @NotNull final Collection< GUIElement > unreferencedElements)
Returns an unreferenced GUI element by name.
GUIText lookupTextElement(@NotNull final String name)
Returns a GUIText by element name.
Manages image information ("faces") needed to display the map view, items, and spell icons...
An exception that is thrown if an undefined message type occurs.
static Resolution parse(@NotNull final String str)
Creates a new instance from string representation.
Definition: Resolution.java:66
Consists of three ImageIcons representing a Face.
Definition: FaceImages.java:31
A SkinEvent that executes a CommandList whenever a magicmap protocol command is received.
Creates GaugeUpdater instances from string representations.
int getWidth()
Returns the width in pixels.
Definition: Resolution.java:87
Utility class for parsing string parameters into values.
Definition: ParseUtils.java:41
final JXCSkinCache< Font > definedFonts
All defined fonts.
final CommandHistoryFactory commandHistoryFactory
The CommandHistoryFactory to use.
static float parseFloat(@NotNull final String str)
Parses a float constant.
A set of images to form a button image.
Displays knowledge items the player knows.
ItemPainter defaultItemPainter
The ItemPainter for default item parameters.
static ImageIcon loadImage(@NotNull final String name)
Loads an image file.
A gui element implementing a static text field which may contain media tags.
void add(@NotNull final GUICommand guiCommand)
Adds a command to the end of this command list.
A GUIItemItem that represents an entry in a GUISpellList.
Defines a JXClient skin consisting of a main Gui and zero or more dialog Guis.
Definition: JXCSkin.java:40
void parseScrollbar(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener)
Parses a "scrollbar" command.
int getHeight()
Returns the height in pixels.
Definition: Resolution.java:95
Iterator< T > iterator()
Returns all stored values.
CommandList getCommandList(@NotNull final String name)
Returns a named command list.the name of the command list the command list if the command list does n...
An expression yielding an integer value derived from a screen resolution.
Definition: Expression.java:30
void parseSetDefault(@NotNull final Args args)
Parses a "set_default" command.
Interface defining an abstract GUI element.
Definition: GUIElement.java:32
One skill of the character.
Definition: Skill.java:32
A factory for creating FacesProvider instances.
Manages macro expansion in command strings.
Definition: Macros.java:37
Combines all model classes that are updated.
Definition: Model.java:44
A GUIElement that can be set to active or inactive.
Creates Font instances from string representations.
Definition: FontParser.java:35
void parseLabelQuery(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CrossfireServerConnection server)
Parses a "label_query" command.
static int parseStat(@NotNull final String name)
Parses a stat value.
Definition: ParseUtils.java:55
Provides a view of all spells a character knows.
Definition: SpellsView.java:35
final MapUpdaterState mapUpdaterState
The MapUpdaterState instance to use.
ImageParser imageParser
The ImageParser for parsing image specifications.
void parseEvent(@NotNull final Args args, @NotNull final GuiStateManager guiStateManager, @NotNull final CrossfireServerConnection server)
Parses an "event" command.
Font getFont(@NotNull final String name)
Returns a font by font file base name.
Definition: FontParser.java:58
void parseDef(@NotNull final Args args, @NotNull final LineNumberReader lnr)
Parses a "def" command.
Image getImage(@Nullable final Color color, @NotNull final String name)
Optionally loads an image by base file name.
void parseTextButton(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr)
Parses a "textbutton" command.
final SpellSkillView spellSkillsView
The SpellSkillView to use.
void parsePicture(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener)
Parses a "picture" command.
The kind of list to create in ListType, TooltipManager, GUIElementListener, CommandQueue, CrossfireServerConnection, CurrentSpellManager, Image, Image).
Factory for creating Gui instances.
Definition: GuiFactory.java:34
GuiElementParser guiElementParser
The GuiElementParser for parsing gui element specifications.
Utility class for loading information from resources.
A GUIHTMLLabel that displays the last received "failure" message.
void parseLabelHtml(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr)
Parses a "label_html" command.
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)
Parses a "commandlist" command.
void parseLogColor(@NotNull final Args args)
Parses a "log_color" command.
void insert(@NotNull final String name, @NotNull final T t)
Adds a new element to the cache.
final SpellsView spellView
The SpellsView to use.
A GUILabel that displays a value of the last received "stats" command.
A GUIList instance that displays GUIItemItem instances.
AbstractGUIElement newCheckBox(@NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final String name, @NotNull final CheckBoxOption option, @NotNull final String text)
Creates a new checkbox.
A GUIText element that executes the entered text as a command.
A GUIList that tracks a Metaserver instance.
static boolean parseBoolean(@NotNull final String str)
Parses a boolean constant.
Interface for providers of JXCSkin sources.
static final String NEXT_GROUP_FACE
The resource for "Click here for next group of items" buttons.
static final Comparator< GUIElement > ELEMENT_COMPARATOR
A Comparator that compares GUIElement instances by element name.
A SkinEvent that executes a CommandList at connection setup.
Maintains the application&#39;s main GUI state.
Definition: GuiManager.java:60
void parseTextGauge(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr)
Parses a "textgauge" command.
A GUIComboBox that shows available classes for character creation.
void parseComboBox(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener)
Parses a "combobox" command.
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)
Parses and builds command arguments.
final JXCSkinCache< AbstractGUIElement > definedGUIElements
The defined GUIElements.
Interface that defines callback functions needed by commands.
A GUIList display characters of an account.
Update a CfMap model from protocol commands.
final FloorView floorView
The FloorView to use.
A GUIHTMLLabel that displays the last received "drawinfo" message.
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)
Parses an "item" command.
AbstractLabel lookupLabelElement(@NotNull final String name)
Returns a AbstractLabel by element name.
static String [] splitFields(@NotNull final String line)
Splits a line into tokens.
GaugeUpdater parseGaugeUpdater(@NotNull final String name, @NotNull final ExperienceTable experienceTable)
Parses a gauge updater value.
A GUILabel that displays a value of the last received "stats" command.
final int defaultTileSize
The default tile size for the map view.
A GUIHTMLLabel that displays the currently selected spell.
GaugeUpdater newGaugeUpdater(@NotNull final String name)
Creates a new GaugeUpdater instance from a string representation.
void parseCommandText(@NotNull final Args args, @NotNull final CommandCallback commandCallback, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CommandExecutor commandExecutor)
Parses a "command_text" command.
T lookupOptional(@NotNull final String name)
Looks up an element by name.
void addInitEvent(@NotNull final CommandList commandList)
Adds a command list to be executed on "init" events.
GaugeUpdaterParser gaugeUpdaterParser
The GaugeUpdaterParser for parsing gauge specifications.
final DarknessColors darknessColors
The DarknessColors instance for converting darkness values into colors.
final ItemView inventoryView
The inventory ItemView to use.
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)
Parses an "inventory_list", "floor_list", "spells_list" or "quests_list" command. ...
Updates the displayed values in a GUIGauge.
KeyBindings getDefaultKeyBindings()
Returns the default key bindings for this skin.the default key bindings
void parseButton(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr)
Parses a "button" command.
static Color parseColorNull(@NotNull final String name)
Parses a color name, optionally followed by "/&lt;alpha&gt;".
static void parseSetAutoSize(@NotNull final Gui gui, @NotNull final Args args)
Parses a "set_auto_size" command.
Maintains the character list for an account.
void parseFont(@NotNull final Args args)
Parses a "font" command.
String getDialogToLoad()
Returns one dialog pending loading.
void parseLinkSize(@NotNull final Args args, @NotNull final Container gui)
Parses a "link_size" command.
JXCSkinLoader(@NotNull final Model model, @NotNull final ItemView inventoryView, @NotNull final FloorView floorView, @NotNull final SpellsView spellView, @NotNull final SpellSkillView spellSkillsView, @NotNull final FacesManager facesManager, @NotNull final MapUpdaterState mapUpdaterState, @NotNull final KeyBindings defaultKeyBindings, @NotNull final OptionManager optionManager, final int defaultTileSize, @NotNull final KeybindingsManager keybindingsManager, @NotNull final QuestsView questView, @NotNull final CommandHistoryFactory commandHistoryFactory, @NotNull final KnowledgeView knowledgeView, @NotNull final KnowledgeTypeView knowledgeTypeView, final boolean avoidCopyArea, @NotNull final GuiManager guiManager)
Creates a new instance.
final Model model
The Model instance to use.
Implements a cache for elements identified by name.
void setGauge(@NotNull final GUIGaugeListener gauge)
Sets the gauge to update.
A SkinEvent that executes a CommandList whenever a new skill has been lost.
Utility class for parsing strings into numbers.
Exception thrown if a skin related problem occurs.
void insertGuiElement(@NotNull final AbstractGUIElement guiElement)
Adds a new GUIElement to this skin.
Displays a value as a graphical gauge that&#39;s filling state depends on the value.
DefaultJXCSkin skin
The JXCSkin being loaded.
A text input field which executes a CommandList when ENTER is pressed.
void parseFill(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener)
Parses a "fill" command.
final OptionManager optionManager
The OptionManager instance to use.
void parseLogMessage(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CrossfireServerConnection server)
Parses a "log_message" command.
Implements an AbstractLabel that displays HTML contents.
Utility class for converting darkness values into colors.
void parseDupGauge(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr)
Parses a "dupgauge" command.
void parseVertical(@NotNull final Args args, @NotNull final Container gui, @NotNull final LineNumberReader lnr, final boolean isDialog)
Parses a "vertical" command.
Abstract base class for GUI elements to be shown in Guis.
Manages a list of previously entered commands.
Factory for creating CommandHistory instances by name.
void clear()
Forgets all defined images.
void addSkinEvent(@NotNull final SkinEvent skinEvent)
Records a SkinEvent attached to this instance.
Adds encoding/decoding of crossfire protocol packets to a ServerConnection.
Displays a value as a graphical gauge that&#39;s filling state depends on the value.
Definition: GUIGauge.java:44
Maintains the pending (ncom) commands sent to the server.
KNOWLEDGE_TYPES
Create a GUIKnowledgeTypeList instance.
void parseLabelMulti(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr)
Parses a "label_multi" command.
static CheckBoxOption parseCheckBoxOption(@NotNull final String name, @NotNull final OptionManager optionManager)
Parses a check box option name.
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)
Loads a skin file and add the entries to a Gui instance.
Information about JXClient&#39;s screen/window resolution.
Definition: Resolution.java:35
Creates gui element instances from string representations.
A GUIScrollable that can be attached to GUIScrollBars.
static void parseDialogHide(@NotNull final Args args, @NotNull final Gui gui)
Parses a "dialog_hide" command.
A GUIDupGauge which displays the current value as a text string on top of the gauge.
void parseSetForcedActive(@NotNull final Args args, @NotNull final Gui gui)
Parses a "set_forced_active" command.
void parseDupTextGauge(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr)
Parses a "duptextgauge" command.
void parseCharacterList(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CharacterModel characterModel)
Parses a "character_list" command.
CommandHistory getCommandHistory(@NotNull final String ident)
Returns a CommandHistory instance by name.
GUILabelLog lookupLabelLogElement(@NotNull final String name)
Returns a AbstractLabel by element name.
Adds drawinfo, drawextinfo, and query messages to a Buffer instance.
Parser for creating GUICommand instances from string representations.
static String parseText(@NotNull final Args args, @NotNull final LineNumberReader lnr)
Concatenates trailing arguments into a string.
A factory class to create "textbutton" instances.
GUICommand parseCommandArgs(@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)
Parses and builds command arguments.
AbstractGUIElement newTextButton(@NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final String name, @NotNull final String text, final boolean autoRepeat, @NotNull final CommandList commandList)
Creates a new text button.
Maintains a set of Gui instances representing dialog windows.
Definition: Dialogs.java:38
void parseGauge(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final LineNumberReader lnr)
Parses a "gauge" command.
void parseLabelSpell(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener, @NotNull final CurrentSpellManager currentSpellManager)
Parses a "label_spell" command.
void parseSkinName(@NotNull final Args args)
Parses a "skin_name" command.
T lookup(@NotNull final String name)
Looks up an element by name.
CheckBoxFactory checkBoxFactory
The checkbox factory.
void parseLabelStat2(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener)
Parses a "label_stat2" command.
Creates BufferedImage instances from string representations.
FacesProvider getFacesProvider(final int size)
Returns the FacesProvider for a given face size.
static int parseMessageType(@NotNull final String str)
Parses a string into a message type.
A GUIGauge which displays the current value as a text string on top of the gauge. ...
void parseLabelStat(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener)
Parses a "label_stat" command.
A AbstractGUIElement that displays a picture.
Definition: GUIPicture.java:38
Maintains smoothing information received from the Crossfire server.
void parseMinimap(@NotNull final Args args, @NotNull final TooltipManager tooltipManager, @NotNull final GUIElementListener elementListener)
Parses a "minimap" command.
Abstract base class for text input fields.
Definition: GUIText.java:57
Gui getDialog(@NotNull final String name)
Returns a dialog by name.the dialog&#39;s name the dialog if the dialog does not exist ...
Provides a view to all items comprising the current floor view.
Definition: FloorView.java:35
void setHideInput(final boolean hideInput)
Enables or disables hidden text.
Definition: GUIText.java:512
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)
Parses a "dialog" command.
A GUIElement that implements a button.
Definition: GUIButton.java:44
Maintains a mapping of face numbers to face data.