/* * Copyright (c) 2014 tabletoptool.com team. * All rights reserved. This program and the accompanying materials * are made available under the terms of the GNU Public License v3.0 * which accompanies this distribution, and is available at * http://www.gnu.org/licenses/gpl.html * * Contributors: * rptools.com team - initial implementation * tabletoptool.com team - further development */ package com.t3.client.ui.htmlframe; import java.awt.Dimension; import java.awt.Frame; import java.awt.Rectangle; import java.awt.event.ActionEvent; import java.util.HashMap; import java.util.Map; import javax.swing.ImageIcon; import com.jidesoft.docking.DockContext; import com.jidesoft.docking.DockableFrame; import com.t3.client.AppStyle; import com.t3.client.TabletopTool; import com.t3.macro.MacroException; import com.t3.macro.api.views.MacroButtonView; @SuppressWarnings("serial") public class HTMLFrame extends DockableFrame implements HTMLPanelContainer { private static final Map<String, HTMLFrame> frames = new HashMap<String, HTMLFrame>(); private final Map<String, String> macroCallbacks = new HashMap<String, String>(); private final HTMLPanel panel; /** * Returns if the frame is visible or not. * * @param name * The name of the frame. * @return true if the frame is visible. */ static boolean isVisible(String name) { if (frames.containsKey(name)) { return frames.get(name).isVisible(); } return false; } /** * Requests that the frame close. * * @param name * The name of the frame. */ static void close(String name) { if (frames.containsKey(name)) { frames.get(name).closeRequest(); } } /** * Creates a new HTMLFrame and displays it or displays an existing frame. The width and height are ignored for * existing frames so that they will not override the size that the player may have resized them to. * * @param name * The name of the frame. * @param title * The title of the frame. * @param width * The width of the frame in pixels. * @param height * The height of the frame in pixels. * @param html * The html to display in the frame. * @return The HTMLFrame that is displayed. */ public static HTMLFrame showFrame(String name, String title, int width, int height, String html) { HTMLFrame frame; if (frames.containsKey(name)) { frame = frames.get(name); frame.setTitle(title); frame.updateContents(html); if (!frame.isVisible()) { frame.setVisible(true); frame.getDockingManager().showFrame(name); } } else { // Only set size on creation so we don't override players resizing. width = width < 100 ? 400 : width; height = height < 50 ? 200 : height; frame = new HTMLFrame(TabletopTool.getFrame(), name, title, width, height); frames.put(name, frame); frame.updateContents(html); frame.getDockingManager().showFrame(name); center(name); } return frame; } /** * Creates a new HTMLFrame. * * @param parent * The parent of this frame. * @param name * the name of the frame. * @param title * The title of the frame. * @param width * @param height */ private HTMLFrame(Frame parent, String name, String title, int width, int height) { super(title, new ImageIcon(AppStyle.chatPanelImage)); setPreferredSize(new Dimension(width, height)); panel = new HTMLPanel(this, true, true); // closeOnSubmit is true so we don't get close button add(panel); this.getContext().setInitMode(DockContext.STATE_FLOATING); TabletopTool.getFrame().getDockingManager().addFrame(this); this.setVisible(true); } static public void center(String name) { if (!frames.containsKey(name)) { return; } HTMLFrame frame = frames.get(name); Dimension outerSize = TabletopTool.getFrame().getSize(); int x = TabletopTool.getFrame().getLocation().x + (outerSize.width - frame.getWidth()) / 2; int y = TabletopTool.getFrame().getLocation().y + (outerSize.height - frame.getHeight()) / 2; Rectangle rect = new Rectangle(x < 0 ? 0 : x, y < 0 ? 0 : y, frame.getWidth(), frame.getHeight()); TabletopTool.getFrame().getDockingManager().floatFrame(frame.getKey(), rect, true); } /** * Updates the html contents of the frame. * * @param html * the html contents. */ public void updateContents(String html) { macroCallbacks.clear(); panel.updateContents(html, false); } @Override public void closeRequest() { TabletopTool.getFrame().getDockingManager().hideFrame(getKey()); setVisible(false); panel.flush(); } @Override public void actionPerformed(ActionEvent e) { if (e instanceof HTMLPane.FormActionEvent) { HTMLPane.FormActionEvent fae = (HTMLPane.FormActionEvent) e; //FIXME why would we need the action? try { MacroButtonView.executeLink(/*fae.getAction() + */fae.getData()); } catch (MacroException e1) { //FIXME here should be macro error handling throw new RuntimeException(e1); } } if (e instanceof HTMLPane.RegisterMacroActionEvent) { HTMLPane.RegisterMacroActionEvent rmae = (HTMLPane.RegisterMacroActionEvent) e; macroCallbacks.put(rmae.getType(), rmae.getMacro()); } if (e instanceof HTMLPane.ChangeTitleActionEvent) { this.setTitle(((HTMLPane.ChangeTitleActionEvent) e).getNewTitle()); } if (e instanceof HTMLPane.MetaTagActionEvent) { HTMLPane.MetaTagActionEvent mtae = (HTMLPane.MetaTagActionEvent) e; if (mtae.getName().equalsIgnoreCase("onChangeToken") || mtae.getName().equalsIgnoreCase("onChangeSelection") || mtae.getName().equalsIgnoreCase("onChangeImpersonated")) { macroCallbacks.put(mtae.getName(), mtae.getContent()); } } if (e.getActionCommand().equals("Close")) { closeRequest(); } } }