/* * Copyright (C) 2007, 2008, 2010, 2011 IsmAvatar <IsmAvatar@gmail.com> * Copyright (C) 2007, 2008 Clam <clamisgood@gmail.com> * Copyright (C) 2008, 2009 Quadduc <quadduc@gmail.com> * * This file is part of LateralGM. * LateralGM is free software and comes with ABSOLUTELY NO WARRANTY. * See LICENSE for details. */ package org.lateralgm.subframes; import static java.lang.Integer.MAX_VALUE; import static javax.swing.GroupLayout.DEFAULT_SIZE; import static javax.swing.GroupLayout.PREFERRED_SIZE; import static org.lateralgm.main.Util.deRef; import java.awt.Color; import java.awt.Component; import java.awt.Container; import java.awt.Dimension; import java.awt.Font; import java.awt.Graphics; import java.awt.Insets; import java.awt.Point; import java.awt.Rectangle; import java.awt.Shape; import java.awt.event.ActionEvent; import java.awt.event.MouseEvent; import java.awt.image.BufferedImage; import java.beans.PropertyVetoException; import java.util.HashMap; import javax.swing.BorderFactory; import javax.swing.BoxLayout; import javax.swing.GroupLayout; import javax.swing.Icon; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JCheckBoxMenuItem; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JScrollPane; import javax.swing.JTabbedPane; import javax.swing.JTextField; import javax.swing.JToggleButton; import javax.swing.JToolBar; import javax.swing.ListCellRenderer; import javax.swing.ListSelectionModel; import javax.swing.GroupLayout.Alignment; import javax.swing.event.DocumentEvent; import javax.swing.event.InternalFrameAdapter; import javax.swing.event.InternalFrameEvent; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.lateralgm.components.ColorSelect; import org.lateralgm.components.NumberField; import org.lateralgm.components.ResourceMenu; import org.lateralgm.components.impl.EditorScrollPane; import org.lateralgm.components.impl.ResNode; import org.lateralgm.components.visual.RoomEditor; import org.lateralgm.components.visual.RoomEditor.CommandHandler; import org.lateralgm.components.visual.RoomEditor.PRoomEditor; import org.lateralgm.main.LGM; import org.lateralgm.main.UpdateSource; import org.lateralgm.main.UpdateSource.UpdateEvent; import org.lateralgm.main.UpdateSource.UpdateListener; import org.lateralgm.messages.Messages; import org.lateralgm.resources.Background; import org.lateralgm.resources.GmObject; import org.lateralgm.resources.Resource; import org.lateralgm.resources.ResourceReference; import org.lateralgm.resources.Room; import org.lateralgm.resources.Background.PBackground; import org.lateralgm.resources.Room.PRoom; import org.lateralgm.resources.sub.BackgroundDef; import org.lateralgm.resources.sub.Instance; import org.lateralgm.resources.sub.Tile; import org.lateralgm.resources.sub.View; import org.lateralgm.resources.sub.BackgroundDef.PBackgroundDef; import org.lateralgm.resources.sub.Instance.PInstance; import org.lateralgm.resources.sub.Tile.PTile; import org.lateralgm.resources.sub.View.PView; import org.lateralgm.subframes.CodeFrame.CodeHolder; import org.lateralgm.ui.swing.propertylink.ButtonModelLink; import org.lateralgm.ui.swing.propertylink.FormattedLink; import org.lateralgm.ui.swing.propertylink.PropertyLinkFactory; import org.lateralgm.ui.swing.util.ArrayListModel; import org.lateralgm.util.PropertyLink; import org.lateralgm.util.PropertyMap.PropertyUpdateEvent; import org.lateralgm.util.PropertyMap.PropertyUpdateListener; public class RoomFrame extends ResourceFrame<Room,PRoom> implements ListSelectionListener, CommandHandler,UpdateListener { private static final long serialVersionUID = 1L; private static final ImageIcon CODE_ICON = LGM.getIconForKey("RoomFrame.CODE"); //$NON-NLS-1$ private final RoomEditor editor; private final EditorScrollPane editorPane; public final JTabbedPane tabs; public JLabel statX, statY, statId, statSrc; //ToolBar private JButton zoomIn, zoomOut; private JToggleButton gridVis, gridIso; //Objects public JCheckBox oUnderlying, oLocked; private ButtonModelLink<PInstance> loLocked; public JList oList; private Instance lastObj = null; //non-guaranteed copy of oList.getLastSelectedValue() private JButton oAdd, oDel; public ResourceMenu<GmObject> oNew, oSource; private PropertyLink<PInstance,ResourceReference<GmObject>> loSource; public NumberField oX, oY; private FormattedLink<PInstance> loX, loY; private JButton oCreationCode; //Settings private JTextField sCaption; private JCheckBox sPersistent; private JButton sCreationCode, sShow; private JPopupMenu sShowMenu; public HashMap<CodeHolder,CodeFrame> codeFrames = new HashMap<CodeHolder,CodeFrame>(); private JCheckBoxMenuItem sSObj, sSTile, sSBack, sSFore, sSView; //Tiles public JCheckBox tUnderlying, tLocked; private ButtonModelLink<PTile> ltLocked; public TileSelector tSelect; private JScrollPane tScroll; public JList tList; private Tile lastTile = null; //non-guaranteed copy of tList.getLastSelectedValue() private JButton tDel; public ResourceMenu<Background> taSource, teSource; private PropertyLink<PTile,ResourceReference<Background>> ltSource; public NumberField tsX, tsY, tX, tY, taDepth, teDepth; private FormattedLink<PTile> ltsX, ltsY, ltX, ltY, ltDepth; //Backgrounds private JCheckBox bDrawColor, bVisible, bForeground, bTileH, bTileV, bStretch; private ButtonModelLink<PBackgroundDef> lbVisible, lbForeground, lbTileH, lbTileV, lbStretch; private ColorSelect bColor; private JList bList; /**Guaranteed valid version of bList.getLastSelectedIndex()*/ private int lastValidBack = -1; private ResourceMenu<Background> bSource; private PropertyLink<PBackgroundDef,ResourceReference<Background>> lbSource; private NumberField bX, bY, bH, bV; private FormattedLink<PBackgroundDef> lbX, lbY, lbH, lbV; private final BgDefPropertyListener bdpl = new BgDefPropertyListener(); //Views private JCheckBox vEnabled, vVisible; private ButtonModelLink<PView> lvVisible; private JList vList; /**Guaranteed valid version of vList.getLastSelectedIndex()*/ private int lastValidView = -1; private NumberField vRX, vRY, vRW, vRH; private NumberField vPX, vPY, vPW, vPH; private FormattedLink<PView> lvRX, lvRY, lvRW, lvRH, lvPX, lvPY, lvPW, lvPH; private ResourceMenu<GmObject> vObj; private PropertyLink<PView,ResourceReference<GmObject>> lvObj; private NumberField vOHBor, vOVBor, vOHSp, vOVSp; private FormattedLink<PView> lvOHBor, lvOVBor, lvOHSp, lvOVSp; private final ViewPropertyListener vpl = new ViewPropertyListener(); private final PropertyLinkFactory<PRoomEditor> prelf; private JToolBar makeToolBar() { JToolBar tool = new JToolBar(); tool.setFloatable(false); tool.add(save); tool.addSeparator(); zoomIn = new JButton(LGM.getIconForKey("RoomFrame.ZOOM_IN")); //$NON-NLS-1$ prelf.make(zoomIn,PRoomEditor.ZOOM,1,RoomEditor.ZOOM_MAX); tool.add(zoomIn); zoomOut = new JButton(LGM.getIconForKey("RoomFrame.ZOOM_OUT")); //$NON-NLS-1$ prelf.make(zoomOut,PRoomEditor.ZOOM,-1,RoomEditor.ZOOM_MIN); tool.add(zoomOut); tool.addSeparator(); String st = Messages.getString("RoomFrame.GRID_VISIBLE"); //$NON-NLS-1$ gridVis = new JToggleButton(st); prelf.make(gridVis,PRoomEditor.SHOW_GRID); tool.add(gridVis); st = Messages.getString("RoomFrame.GRID_ISOMETRIC"); //$NON-NLS-1$ gridIso = new JToggleButton(st); plf.make(gridIso,PRoom.ISOMETRIC); tool.add(gridIso); // Add the grid sizers JLabel lab = new JLabel(Messages.getString("RoomFrame.GRID_X")); //$NON-NLS-1$ NumberField nf = new NumberField(0,999); nf.setMaximumSize(nf.getPreferredSize()); prelf.make(nf,PRoomEditor.GRID_OFFSET_X); tool.add(lab); tool.add(nf); lab = new JLabel(Messages.getString("RoomFrame.GRID_Y")); //$NON-NLS-1$ nf = new NumberField(0,999); nf.setMaximumSize(nf.getPreferredSize()); prelf.make(nf,PRoomEditor.GRID_OFFSET_Y); tool.add(lab); tool.add(nf); lab = new JLabel(Messages.getString("RoomFrame.GRID_W")); //$NON-NLS-1$ nf = new NumberField(1,999); nf.setMaximumSize(nf.getPreferredSize()); plf.make(nf,PRoom.SNAP_X); tool.add(lab); tool.add(nf); lab = new JLabel(Messages.getString("RoomFrame.GRID_H")); //$NON-NLS-1$ nf = new NumberField(1,999); nf.setMaximumSize(nf.getPreferredSize()); plf.make(nf,PRoom.SNAP_Y); tool.add(lab); tool.add(nf); tool.addSeparator(); sShowMenu = makeShowMenu(); sShow = new JButton(Messages.getString("RoomFrame.SHOW")); //$NON-NLS-1$ sShow.addActionListener(this); tool.add(sShow); tool.addSeparator(); return tool; } private static class ObjectListComponentRenderer implements ListCellRenderer { private final JLabel lab = new JLabel(); private final ListComponentRenderer lcr = new ListComponentRenderer(); public ObjectListComponentRenderer() { lab.setOpaque(true); } public Component getListCellRendererComponent(JList list, Object val, int ind, boolean selected, boolean focus) { Instance i = (Instance) val; ResourceReference<GmObject> ro = i.properties.get(PInstance.OBJECT); GmObject o = deRef(ro); String name = o == null ? Messages.getString("RoomFrame.NO_OBJECT") : o.getName(); lcr.getListCellRendererComponent(list,lab,ind,selected,focus); lab.setText(name + " " + i.properties.get(PInstance.ID)); ResNode rn = o == null ? null : o.getNode(); lab.setIcon(rn == null ? null : rn.getIcon()); return lab; } } private static class TileListComponentRenderer implements ListCellRenderer { private final JLabel lab = new JLabel(); private final TileIcon ti = new TileIcon(); private final ListComponentRenderer lcr = new ListComponentRenderer(); public TileListComponentRenderer() { lab.setOpaque(true); lab.setIcon(ti); } public Component getListCellRendererComponent(JList list, Object val, int ind, boolean selected, boolean focus) { Tile t = (Tile) val; ResourceReference<Background> rb = t.properties.get(PTile.BACKGROUND); Background bg = deRef(rb); String name = bg == null ? Messages.getString("RoomFrame.NO_BACKGROUND") : bg.getName(); lab.setText(name + " " + t.properties.get(PTile.ID)); ti.tile = t; lcr.getListCellRendererComponent(list,lab,ind,selected,focus); return lab; } static class TileIcon implements Icon { Tile tile; public int getIconHeight() { return tile.getSize().height; } public int getIconWidth() { return tile.getSize().width; } public void paintIcon(Component c, Graphics g, int x, int y) { ResourceReference<Background> rb = tile.properties.get(PTile.BACKGROUND); Background bg = deRef(rb); BufferedImage bi = bg == null ? null : bg.getBackgroundImage(); if (bi != null) { Point p = tile.getBackgroundPosition(); Dimension d = tile.getSize(); g.drawImage(bi,0,0,d.width,d.height,p.x,p.y,p.x + d.width,p.y + d.height,c); } } } } public JPanel makeObjectsPane() { JPanel panel = new JPanel(); GroupLayout layout = new GroupLayout(panel); layout.setAutoCreateGaps(true); layout.setAutoCreateContainerGaps(true); panel.setLayout(layout); oNew = new ResourceMenu<GmObject>(Resource.Kind.OBJECT, Messages.getString("RoomFrame.NO_OBJECT"),true,110); //$NON-NLS-1$ oNew.addActionListener(this); oUnderlying = new JCheckBox(Messages.getString("RoomFrame.OBJ_UNDERLYING")); //$NON-NLS-1$ prelf.make(oUnderlying,PRoomEditor.DELETE_UNDERLYING_OBJECTS); oList = new JList(new ArrayListModel<Instance>(res.instances)); oList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); oList.setVisibleRowCount(8); oList.setCellRenderer(new ObjectListComponentRenderer()); oList.setSelectedIndex(0); oList.addListSelectionListener(this); JScrollPane sp = new JScrollPane(oList); oAdd = new JButton(Messages.getString("RoomFrame.OBJ_ADD")); //$NON-NLS-1$ oAdd.addActionListener(this); oDel = new JButton(Messages.getString("RoomFrame.OBJ_DELETE")); //$NON-NLS-1$ oDel.addActionListener(this); JPanel edit = new JPanel(); String title = Messages.getString("RoomFrame.OBJ_INSTANCES"); //$NON-NLS-1$ edit.setBorder(BorderFactory.createTitledBorder(title)); GroupLayout layout2 = new GroupLayout(edit); layout2.setAutoCreateGaps(true); layout2.setAutoCreateContainerGaps(true); edit.setLayout(layout2); oSource = new ResourceMenu<GmObject>(Resource.Kind.OBJECT, Messages.getString("RoomFrame.NO_OBJECT"),true,110); //$NON-NLS-1$ oLocked = new JCheckBox(Messages.getString("RoomFrame.OBJ_LOCKED")); //$NON-NLS-1$ oLocked.setHorizontalAlignment(JCheckBox.CENTER); JLabel lObjX = new JLabel(Messages.getString("RoomFrame.OBJ_X")); //$NON-NLS-1$ oX = new NumberField(0); oX.setColumns(4); JLabel lObjY = new JLabel(Messages.getString("RoomFrame.OBJ_Y")); //$NON-NLS-1$ oY = new NumberField(0); oY.setColumns(4); oCreationCode = new JButton(Messages.getString("RoomFrame.OBJ_CODE")); //$NON-NLS-1$ oCreationCode.setIcon(CODE_ICON); oCreationCode.addActionListener(this); layout2.setHorizontalGroup(layout2.createParallelGroup() /**/.addComponent(oSource) /**/.addComponent(oLocked) /**/.addGroup(layout2.createSequentialGroup() /* */.addComponent(lObjX) /* */.addComponent(oX) /* */.addComponent(lObjY) /* */.addComponent(oY)) /**/.addComponent(oCreationCode,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE)); layout2.setVerticalGroup(layout2.createSequentialGroup() /**/.addComponent(oSource) /**/.addComponent(oLocked) /**/.addGroup(layout2.createParallelGroup(Alignment.BASELINE) /* */.addComponent(lObjX) /* */.addComponent(oX) /* */.addComponent(lObjY) /* */.addComponent(oY)) /**/.addComponent(oCreationCode)); layout.setHorizontalGroup(layout.createParallelGroup() /**/.addComponent(oNew) /**/.addComponent(oUnderlying) /**/.addComponent(sp,DEFAULT_SIZE,120,MAX_VALUE) /**/.addGroup(layout.createSequentialGroup() /* */.addComponent(oAdd,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE) /* */.addComponent(oDel,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE)) /**/.addComponent(edit)); layout.setVerticalGroup(layout.createSequentialGroup() /**/.addComponent(oNew) /**/.addComponent(oUnderlying) /**/.addComponent(sp) /**/.addGroup(layout.createParallelGroup() /* */.addComponent(oAdd) /* */.addComponent(oDel)) /**/.addComponent(edit)); return panel; } private JPopupMenu makeShowMenu() { JPopupMenu showMenu = new JPopupMenu(); String st = Messages.getString("RoomFrame.SHOW_OBJECTS"); //$NON-NLS-1$ sSObj = new JCheckBoxMenuItem(st); prelf.make(sSObj,PRoomEditor.SHOW_OBJECTS); showMenu.add(sSObj); st = Messages.getString("RoomFrame.SHOW_TILES"); //$NON-NLS-1$ sSTile = new JCheckBoxMenuItem(st); prelf.make(sSTile,PRoomEditor.SHOW_TILES); showMenu.add(sSTile); st = Messages.getString("RoomFrame.SHOW_BACKGROUNDS"); //$NON-NLS-1$ sSBack = new JCheckBoxMenuItem(st); prelf.make(sSBack,PRoomEditor.SHOW_BACKGROUNDS); showMenu.add(sSBack); st = Messages.getString("RoomFrame.SHOW_FOREGROUNDS"); //$NON-NLS-1$ sSFore = new JCheckBoxMenuItem(st); prelf.make(sSFore,PRoomEditor.SHOW_FOREGROUNDS); showMenu.add(sSFore); st = Messages.getString("RoomFrame.SHOW_VIEWS"); //$NON-NLS-1$ sSView = new JCheckBoxMenuItem(st); prelf.make(sSView,PRoomEditor.SHOW_VIEWS); showMenu.add(sSView); return showMenu; } public JPanel makeSettingsPane() { JPanel panel = new JPanel(); GroupLayout layout = new GroupLayout(panel); layout.setAutoCreateGaps(true); layout.setAutoCreateContainerGaps(true); panel.setLayout(layout); JLabel lName = new JLabel(Messages.getString("RoomFrame.NAME")); //$NON-NLS-1$ JLabel lCaption = new JLabel(Messages.getString("RoomFrame.CAPTION")); //$NON-NLS-1$ sCaption = new JTextField(); plf.make(sCaption.getDocument(),PRoom.CAPTION); JLabel lWidth = new JLabel(Messages.getString("RoomFrame.WIDTH")); //$NON-NLS-1$ NumberField sWidth = new NumberField(1,999999); plf.make(sWidth,PRoom.WIDTH); JLabel lHeight = new JLabel(Messages.getString("RoomFrame.HEIGHT")); //$NON-NLS-1$ NumberField sHeight = new NumberField(1,999999); plf.make(sHeight,PRoom.HEIGHT); JLabel lSpeed = new JLabel(Messages.getString("RoomFrame.SPEED")); //$NON-NLS-1$ NumberField sSpeed = new NumberField(1,9999); plf.make(sSpeed,PRoom.SPEED); String str = Messages.getString("RoomFrame.PERSISTENT"); //$NON-NLS-1$ sPersistent = new JCheckBox(str); plf.make(sPersistent,PRoom.PERSISTENT); str = Messages.getString("RoomFrame.CREATION_CODE"); //$NON-NLS-1$ sCreationCode = new JButton(str,CODE_ICON); sCreationCode.addActionListener(this); JPanel pg = makeGridPane(); layout.setHorizontalGroup(layout.createParallelGroup() /**/.addGroup(layout.createSequentialGroup() /* */.addComponent(lName) /* */.addComponent(name,DEFAULT_SIZE,120,MAX_VALUE)) /**/.addComponent(lCaption) /**/.addComponent(sCaption,DEFAULT_SIZE,120,MAX_VALUE) /**/.addGroup(layout.createSequentialGroup() /* */.addGroup(layout.createParallelGroup(Alignment.TRAILING) /* */.addComponent(lWidth) /* */.addComponent(lHeight) /* */.addComponent(lSpeed)) /* */.addGroup(layout.createParallelGroup() /* */.addComponent(sWidth) /* */.addComponent(sHeight) /* */.addComponent(sSpeed))) /**/.addComponent(sPersistent) /**/.addComponent(sCreationCode,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE) /**/.addComponent(pg)); layout.setVerticalGroup(layout.createSequentialGroup() /**/.addGroup(layout.createParallelGroup(Alignment.BASELINE) /* */.addComponent(lName) /* */.addComponent(name)) /**/.addComponent(lCaption) /**/.addComponent(sCaption,DEFAULT_SIZE,DEFAULT_SIZE,PREFERRED_SIZE) /**/.addGroup(layout.createParallelGroup(Alignment.BASELINE) /* */.addComponent(lWidth) /* */.addComponent(sWidth)) /**/.addGroup(layout.createParallelGroup(Alignment.BASELINE) /* */.addComponent(lHeight) /* */.addComponent(sHeight)) /**/.addGroup(layout.createParallelGroup(Alignment.BASELINE) /* */.addComponent(lSpeed) /* */.addComponent(sSpeed)) /**/.addComponent(sPersistent) /**/.addComponent(sCreationCode) /**/.addComponent(pg)); return panel; } public JPanel makeGridPane() { JPanel pg = new JPanel(); GroupLayout lr = new GroupLayout(pg); pg.setLayout(lr); pg.setBorder(BorderFactory.createTitledBorder(Messages.getString("RoomFrame.GRID"))); //$NON-NLS-1$ JLabel lGX = new JLabel(Messages.getString("RoomFrame.GRID_X")); //$NON-NLS-1$ NumberField sGX = new NumberField(0,999); prelf.make(sGX,PRoomEditor.GRID_OFFSET_X); JLabel lGY = new JLabel(Messages.getString("RoomFrame.GRID_Y")); //$NON-NLS-1$ NumberField sGY = new NumberField(0,999); prelf.make(sGY,PRoomEditor.GRID_OFFSET_Y); JLabel lGW = new JLabel(Messages.getString("RoomFrame.GRID_W")); //$NON-NLS-1$ NumberField sGW = new NumberField(1,999); plf.make(sGW,PRoom.SNAP_X); JLabel lGH = new JLabel(Messages.getString("RoomFrame.GRID_H")); //$NON-NLS-1$ NumberField sGH = new NumberField(1,999); plf.make(sGH,PRoom.SNAP_Y); lr.setHorizontalGroup(lr.createSequentialGroup().addContainerGap() /**/.addGroup(lr.createParallelGroup() /* */.addComponent(lGX) /* */.addComponent(lGY)).addGap(4) /**/.addGroup(lr.createParallelGroup() /* */.addComponent(sGX) /* */.addComponent(sGY)).addGap(8) /**/.addGroup(lr.createParallelGroup() /* */.addComponent(lGW) /* */.addComponent(lGH)).addGap(4) /**/.addGroup(lr.createParallelGroup() /* */.addComponent(sGW) /* */.addComponent(sGH)).addContainerGap()); lr.setVerticalGroup(lr.createSequentialGroup().addGap(4) /**/.addGroup(lr.createParallelGroup(Alignment.BASELINE) /* */.addComponent(lGX) /* */.addComponent(sGX) /* */.addComponent(lGW) /* */.addComponent(sGW)).addGap(4) /**/.addGroup(lr.createParallelGroup(Alignment.BASELINE) /* */.addComponent(lGY) /* */.addComponent(sGY) /* */.addComponent(lGH) /* */.addComponent(sGH)).addGap(8)); return pg; } public JTabbedPane makeTilesPane() { JTabbedPane tab = new JTabbedPane(); tab.addTab(Messages.getString("RoomFrame.TILE_ADD"),makeTilesAddPane()); tab.addTab(Messages.getString("RoomFrame.TILE_EDIT"),makeTilesEditPane()); tab.addTab(Messages.getString("RoomFrame.TILE_BATCH"),makeTilesBatchPane()); tab.setSelectedIndex(0); return tab; } public JPanel makeTilesAddPane() { JPanel panel = new JPanel(); GroupLayout layout = new GroupLayout(panel); layout.setAutoCreateGaps(true); layout.setAutoCreateContainerGaps(true); panel.setLayout(layout); taSource = new ResourceMenu<Background>(Resource.Kind.BACKGROUND, Messages.getString("RoomFrame.NO_BACKGROUND"),true,110); taSource.addActionListener(this); tSelect = new TileSelector(); tScroll = new JScrollPane(tSelect); tScroll.setPreferredSize(tScroll.getSize()); tUnderlying = new JCheckBox(Messages.getString("RoomFrame.TILE_UNDERLYING")); //$NON-NLS-1$ prelf.make(tUnderlying,PRoomEditor.DELETE_UNDERLYING_TILES); JLabel lab = new JLabel(Messages.getString("RoomFrame.TILE_LAYER")); taDepth = new NumberField(Integer.MIN_VALUE,Integer.MAX_VALUE,0); taDepth.setMaximumSize(new Dimension(Integer.MAX_VALUE,taDepth.getHeight())); layout.setHorizontalGroup(layout.createParallelGroup() /**/.addComponent(tScroll) /**/.addComponent(taSource) /**/.addComponent(tUnderlying) /**/.addGroup(layout.createSequentialGroup() /* */.addComponent(lab) /* */.addComponent(taDepth))); layout.setVerticalGroup(layout.createSequentialGroup() /**/.addComponent(tScroll) /**/.addComponent(taSource) /**/.addComponent(tUnderlying) /**/.addGroup(layout.createParallelGroup() /* */.addComponent(lab) /* */.addComponent(taDepth))); return panel; } //XXX: Extract to own class? public static class TileSelector extends JLabel { private static final long serialVersionUID = 1L; public int tx, ty; private ResourceReference<Background> bkg; public TileSelector() { super(); setVerticalAlignment(TOP); enableEvents(MouseEvent.MOUSE_PRESSED); enableEvents(MouseEvent.MOUSE_DRAGGED); } public void setBackground(ResourceReference<Background> bkg) { this.bkg = bkg; Background b = deRef(bkg); if (b == null) { setIcon(null); setPreferredSize(new Dimension(0,0)); return; } setPreferredSize(new Dimension(b.getWidth(),b.getHeight())); BufferedImage bi = b.getDisplayImage(); setIcon(bi == null ? null : new ImageIcon(bi)); } public void paintComponent(Graphics g) { super.paintComponent(g); Background b = deRef(bkg); if (b == null) return; //BufferedImage img = bkg.getDisplayImage(); //if (img == null) return; Shape oldClip = g.getClip(); //backup the old clip Rectangle oldc = g.getClipBounds(); //Set the clip properly g.setClip(new Rectangle(oldc.x,oldc.y,Math.min(oldc.x + oldc.width,b.getWidth()) - oldc.x, Math.min(oldc.y + oldc.height,b.getHeight()) - oldc.y)); if ((Boolean) b.get(PBackground.USE_AS_TILESET)) { g.setXORMode(Color.BLACK); g.setColor(Color.WHITE); g.drawRect(tx,ty,(Integer) b.get(PBackground.TILE_WIDTH), (Integer) b.get(PBackground.TILE_HEIGHT)); g.setPaintMode(); //just in case } g.setClip(oldClip); //restore the clip } protected void processMouseEvent(MouseEvent e) { if (e.getID() == MouseEvent.MOUSE_PRESSED && e.getButton() == MouseEvent.BUTTON1 && e.getX() < getPreferredSize().width && e.getY() < getPreferredSize().height) selectTile(e.getX(),e.getY()); super.processMouseEvent(e); } protected void processMouseMotionEvent(MouseEvent e) { if (e.getID() == MouseEvent.MOUSE_DRAGGED && (e.getModifiersEx() & MouseEvent.BUTTON1_DOWN_MASK) != 0) selectTile(e.getX(),e.getY()); super.processMouseMotionEvent(e); } public void selectTile(int x, int y) { Background hardBkg = deRef(bkg); if (hardBkg == null) { tx = x; ty = y; } else if (!(Boolean) hardBkg.get(PBackground.USE_AS_TILESET)) { tx = 0; ty = 0; } else { int w = (Integer) hardBkg.get(PBackground.TILE_WIDTH) + (Integer) hardBkg.get(PBackground.H_SEP); int h = (Integer) hardBkg.get(PBackground.TILE_HEIGHT) + (Integer) hardBkg.get(PBackground.V_SEP); int ho = hardBkg.get(PBackground.H_OFFSET); int vo = hardBkg.get(PBackground.V_OFFSET); tx = (int) Math.floor((x - ho) / w) * w + ho; ty = (int) Math.floor((y - vo) / h) * h + vo; } repaint(); } } public JPanel makeTilesEditPane() { JPanel panel = new JPanel(); GroupLayout layout = new GroupLayout(panel); layout.setAutoCreateGaps(true); layout.setAutoCreateContainerGaps(true); panel.setLayout(layout); tList = new JList(new ArrayListModel<Tile>(res.tiles)); tList.addListSelectionListener(this); tList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); tList.setCellRenderer(new TileListComponentRenderer()); JScrollPane sp = new JScrollPane(tList); tDel = new JButton(Messages.getString("RoomFrame.TILE_DELETE")); //$NON-NLS-1$ tDel.addActionListener(this); tLocked = new JCheckBox(Messages.getString("RoomFrame.TILE_LOCKED")); //$NON-NLS-1$ JPanel pSet = new JPanel(); pSet.setBorder(BorderFactory.createTitledBorder(Messages.getString("RoomFrame.TILESET"))); //$NON-NLS-1$ GroupLayout psl = new GroupLayout(pSet); psl.setAutoCreateGaps(true); psl.setAutoCreateContainerGaps(true); pSet.setLayout(psl); teSource = new ResourceMenu<Background>(Resource.Kind.BACKGROUND, Messages.getString("RoomFrame.NO_BACKGROUND"),true,110); //$NON-NLS-1$ JLabel ltsx = new JLabel(Messages.getString("RoomFrame.TILESET_X")); //$NON-NLS-1$ tsX = new NumberField(0); tsX.setColumns(4); JLabel ltsy = new JLabel(Messages.getString("RoomFrame.TILESET_Y")); //$NON-NLS-1$ tsY = new NumberField(0); tsY.setColumns(4); psl.setHorizontalGroup(psl.createParallelGroup() /**/.addComponent(teSource) /**/.addGroup(psl.createSequentialGroup() /* */.addComponent(ltsx) /* */.addComponent(tsX) /* */.addComponent(ltsy) /* */.addComponent(tsY))); psl.setVerticalGroup(psl.createSequentialGroup() /**/.addComponent(teSource) /**/.addGroup(psl.createParallelGroup(Alignment.BASELINE) /* */.addComponent(ltsx) /* */.addComponent(tsX) /* */.addComponent(ltsy) /* */.addComponent(tsY))); JPanel pTile = new JPanel(); pTile.setBorder(BorderFactory.createTitledBorder(Messages.getString("RoomFrame.TILE"))); //$NON-NLS-1$ GroupLayout ptl = new GroupLayout(pTile); ptl.setAutoCreateGaps(true); ptl.setAutoCreateContainerGaps(true); pTile.setLayout(ptl); JLabel ltx = new JLabel(Messages.getString("RoomFrame.TILE_X")); //$NON-NLS-1$ tX = new NumberField(0); tX.setColumns(4); JLabel lty = new JLabel(Messages.getString("RoomFrame.TILE_Y")); //$NON-NLS-1$ tY = new NumberField(0); tY.setColumns(4); JLabel ltl = new JLabel(Messages.getString("RoomFrame.TILE_LAYER")); //$NON-NLS-1$ teDepth = new NumberField(1000000); teDepth.setColumns(8); ptl.setHorizontalGroup(ptl.createParallelGroup() /**/.addGroup(ptl.createSequentialGroup() /* */.addComponent(ltx) /* */.addComponent(tX) /* */.addComponent(lty) /* */.addComponent(tY)) /**/.addGroup(ptl.createSequentialGroup() /* */.addComponent(ltl) /* */.addComponent(teDepth))); ptl.setVerticalGroup(ptl.createSequentialGroup() /**/.addGroup(ptl.createParallelGroup(Alignment.BASELINE) /* */.addComponent(ltx) /* */.addComponent(tX) /* */.addComponent(lty) /* */.addComponent(tY)) /**/.addGroup(ptl.createParallelGroup(Alignment.BASELINE) /* */.addComponent(ltl) /* */.addComponent(teDepth))); layout.setHorizontalGroup(layout.createParallelGroup() /**/.addComponent(sp,DEFAULT_SIZE,120,MAX_VALUE) /**/.addComponent(tDel,DEFAULT_SIZE,DEFAULT_SIZE,MAX_VALUE) /**/.addComponent(tLocked) /**/.addComponent(pSet) /**/.addComponent(pTile)); layout.setVerticalGroup(layout.createSequentialGroup() /**/.addComponent(sp,DEFAULT_SIZE,60,MAX_VALUE) /**/.addComponent(tDel) /**/.addComponent(tLocked) /**/.addComponent(pSet) /**/.addComponent(pTile)); return panel; } //TODO 1.7?: Batch tile operations public JPanel makeTilesBatchPane() { JPanel panel = new JPanel(); // GroupLayout layout = new GroupLayout(panel); // layout.setAutoCreateGaps(true); // layout.setAutoCreateContainerGaps(true); // panel.setLayout(layout); panel.add(new JLabel("<html>This tab will offer ways to<br />" + "perform batch operations on several<br />" + "tiles at once, or regions of tiles.</html>")); return panel; } public JPanel makeBackgroundsPane() { JPanel panel = new JPanel(); GroupLayout layout = new GroupLayout(panel); layout.setAutoCreateGaps(true); layout.setAutoCreateContainerGaps(true); panel.setLayout(layout); bDrawColor = new JCheckBox(Messages.getString("RoomFrame.DRAW_COLOR")); //$NON-NLS-1$ plf.make(bDrawColor,PRoom.DRAW_BACKGROUND_COLOR); JLabel lColor = new JLabel(Messages.getString("RoomFrame.COLOR")); //$NON-NLS-1$ bColor = new ColorSelect(); plf.make(bColor,PRoom.BACKGROUND_COLOR); JLabel[] backLabs = new JLabel[res.backgroundDefs.size()]; for (int i = 0; i < backLabs.length; i++) { backLabs[i] = new JLabel(Messages.getString("RoomFrame.BACK") + i); //$NON-NLS-1$ boolean v = res.backgroundDefs.get(i).properties.get(PBackgroundDef.VISIBLE); backLabs[i].setFont(backLabs[i].getFont().deriveFont(v ? Font.BOLD : Font.PLAIN)); backLabs[i].setOpaque(true); } bList = new JList(backLabs); bList.setCellRenderer(new ListComponentRenderer()); bList.addListSelectionListener(this); bList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); bList.setVisibleRowCount(4); JScrollPane sp = new JScrollPane(bList); for (BackgroundDef d : res.backgroundDefs) d.properties.getUpdateSource(PBackgroundDef.VISIBLE).addListener(bdpl); bVisible = new JCheckBox(Messages.getString("RoomFrame.BACK_VISIBLE")); //$NON-NLS-1$ bForeground = new JCheckBox(Messages.getString("RoomFrame.BACK_FOREGROUND")); //$NON-NLS-1$ bSource = new ResourceMenu<Background>(Resource.Kind.BACKGROUND, Messages.getString("RoomFrame.NO_BACKGROUND"),true,150); //$NON-NLS-1$ bTileH = new JCheckBox(Messages.getString("RoomFrame.BACK_TILE_HOR")); //$NON-NLS-1$ JLabel lbx = new JLabel(Messages.getString("RoomFrame.BACK_X")); //$NON-NLS-1$ bX = new NumberField(0); bX.setColumns(4); bTileV = new JCheckBox(Messages.getString("RoomFrame.BACK_TILE_VERT")); //$NON-NLS-1$ JLabel lby = new JLabel(Messages.getString("RoomFrame.BACK_Y")); //$NON-NLS-1$ bY = new NumberField(0); bY.setColumns(4); bStretch = new JCheckBox(Messages.getString("RoomFrame.BACK_STRETCH")); //$NON-NLS-1$ JLabel lbh = new JLabel(Messages.getString("RoomFrame.BACK_HSPEED")); //$NON-NLS-1$ bH = new NumberField(-999,999); JLabel lbv = new JLabel(Messages.getString("RoomFrame.BACK_VSPEED")); //$NON-NLS-1$ bV = new NumberField(-999,999); bList.setSelectedIndex(0); Insets spi = sp.getInsets(); int spmh = bList.getMaximumSize().height + spi.bottom + spi.top; layout.setHorizontalGroup(layout.createParallelGroup() /**/.addComponent(bDrawColor) /**/.addGroup(layout.createSequentialGroup() /* */.addComponent(lColor) /* */.addComponent(bColor)) /**/.addComponent(sp) /**/.addGroup(layout.createSequentialGroup() /* */.addComponent(bVisible) /* */.addComponent(bForeground)) /**/.addComponent(bSource) /**/.addGroup(layout.createSequentialGroup() /* */.addComponent(lbx) /* */.addComponent(bX) /* */.addComponent(lby) /* */.addComponent(bY)) /**/.addGroup(layout.createSequentialGroup() /* */.addGroup(layout.createParallelGroup(Alignment.TRAILING) /* */.addComponent(lbh) /* */.addComponent(lbv)) /* */.addGroup(layout.createParallelGroup() /* */.addComponent(bH) /* */.addComponent(bV))) /**/.addComponent(bTileH) /**/.addComponent(bTileV) /**/.addComponent(bStretch)); layout.setVerticalGroup(layout.createSequentialGroup() /**/.addComponent(bDrawColor) /**/.addGroup(layout.createParallelGroup(Alignment.BASELINE,false) /* */.addComponent(lColor) /* */.addComponent(bColor)) /**/.addComponent(sp,DEFAULT_SIZE,DEFAULT_SIZE,spmh) /**/.addGroup(layout.createParallelGroup() /* */.addComponent(bVisible) /* */.addComponent(bForeground)) /**/.addComponent(bSource) /**/.addGroup(layout.createParallelGroup(Alignment.BASELINE) /* */.addComponent(lbx) /* */.addComponent(bX) /* */.addComponent(lby) /* */.addComponent(bY)) /**/.addGroup(layout.createParallelGroup(Alignment.BASELINE) /* */.addComponent(lbh) /* */.addComponent(bH)) /**/.addGroup(layout.createParallelGroup(Alignment.BASELINE) /* */.addComponent(lbv) /* */.addComponent(bV)) /**/.addComponent(bTileH) /**/.addComponent(bTileV) /**/.addComponent(bStretch)); return panel; } public JPanel makeViewsPane() { JPanel panel = new JPanel(); GroupLayout layout = new GroupLayout(panel); layout.setAutoCreateGaps(true); layout.setAutoCreateContainerGaps(true); panel.setLayout(layout); vEnabled = new JCheckBox(Messages.getString("RoomFrame.ENABLE_VIEWS")); //$NON-NLS-1$ plf.make(vEnabled,PRoom.ENABLE_VIEWS); JLabel[] viewLabs = new JLabel[res.views.size()]; for (int i = 0; i < viewLabs.length; i++) { viewLabs[i] = new JLabel(Messages.getString("RoomFrame.VIEW") + i); //$NON-NLS-1$ boolean v = res.views.get(i).properties.get(PView.VISIBLE); viewLabs[i].setFont(viewLabs[i].getFont().deriveFont(v ? Font.BOLD : Font.PLAIN)); viewLabs[i].setOpaque(true); } vList = new JList(viewLabs); vList.setCellRenderer(new ListComponentRenderer()); //vList.setVisibleRowCount(4); vList.addListSelectionListener(this); vList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION); JScrollPane sp = new JScrollPane(vList); for (View v : res.views) v.properties.getUpdateSource(PView.VISIBLE).addListener(vpl); vVisible = new JCheckBox(Messages.getString("RoomFrame.VIEW_ENABLED")); //$NON-NLS-1$ JTabbedPane tp = makeViewsDimensionsPane(); JPanel pf = makeViewsFollowPane(); vList.setSelectedIndex(0); Insets spi = sp.getInsets(); int spmh = vList.getMaximumSize().height + spi.bottom + spi.top; layout.setHorizontalGroup(layout.createParallelGroup() /**/.addComponent(vEnabled) /**/.addComponent(sp) /**/.addComponent(vVisible) /**/.addComponent(tp) /**/.addComponent(pf)); layout.setVerticalGroup(layout.createSequentialGroup() /**/.addComponent(vEnabled) /**/.addComponent(sp,DEFAULT_SIZE,DEFAULT_SIZE,spmh) /**/.addComponent(vVisible) /**/.addComponent(tp,DEFAULT_SIZE,DEFAULT_SIZE,PREFERRED_SIZE) /**/.addComponent(pf)); return panel; } private JTabbedPane makeViewsDimensionsPane() { JPanel pr = new JPanel(); GroupLayout lr = new GroupLayout(pr); pr.setLayout(lr); JLabel lRX = new JLabel(Messages.getString("RoomFrame.VIEW_X")); //$NON-NLS-1$ vRX = new NumberField(0,999999); JLabel lRW = new JLabel(Messages.getString("RoomFrame.VIEW_W")); //$NON-NLS-1$ vRW = new NumberField(1,999999); JLabel lRY = new JLabel(Messages.getString("RoomFrame.VIEW_Y")); //$NON-NLS-1$ vRY = new NumberField(0,999999); JLabel lRH = new JLabel(Messages.getString("RoomFrame.VIEW_H")); //$NON-NLS-1$ vRH = new NumberField(1,999999); lr.setHorizontalGroup(lr.createSequentialGroup().addContainerGap() /**/.addGroup(lr.createParallelGroup() /* */.addComponent(lRX) /* */.addComponent(lRY)).addGap(4) /**/.addGroup(lr.createParallelGroup() /* */.addComponent(vRX) /* */.addComponent(vRY)).addGap(8) /**/.addGroup(lr.createParallelGroup() /* */.addComponent(lRW) /* */.addComponent(lRH)).addGap(4) /**/.addGroup(lr.createParallelGroup() /* */.addComponent(vRW) /* */.addComponent(vRH)).addContainerGap()); lr.setVerticalGroup(lr.createSequentialGroup().addGap(4) /**/.addGroup(lr.createParallelGroup(Alignment.BASELINE) /* */.addComponent(lRX) /* */.addComponent(vRX) /* */.addComponent(lRW) /* */.addComponent(vRW)).addGap(4) /**/.addGroup(lr.createParallelGroup(Alignment.BASELINE) /* */.addComponent(lRY) /* */.addComponent(vRY) /* */.addComponent(lRH) /* */.addComponent(vRH)).addGap(8)); JPanel pp = new JPanel(); GroupLayout lp = new GroupLayout(pp); pp.setLayout(lp); JLabel lPX = new JLabel(Messages.getString("RoomFrame.PORT_X")); //$NON-NLS-1$ vPX = new NumberField(0,999999); JLabel lPW = new JLabel(Messages.getString("RoomFrame.PORT_W")); //$NON-NLS-1$ vPW = new NumberField(1,999999); JLabel lPY = new JLabel(Messages.getString("RoomFrame.PORT_Y")); //$NON-NLS-1$ vPY = new NumberField(0,999999); JLabel lPH = new JLabel(Messages.getString("RoomFrame.PORT_H")); //$NON-NLS-1$ vPH = new NumberField(1,999999); lp.setHorizontalGroup(lp.createSequentialGroup().addContainerGap() /**/.addGroup(lp.createParallelGroup() /* */.addComponent(lPX) /* */.addComponent(lPY)).addGap(4) /**/.addGroup(lp.createParallelGroup() /* */.addComponent(vPX) /* */.addComponent(vPY)).addGap(8) /**/.addGroup(lp.createParallelGroup() /* */.addComponent(lPW) /* */.addComponent(lPH)).addGap(4) /**/.addGroup(lp.createParallelGroup() /* */.addComponent(vPW) /* */.addComponent(vPH)).addContainerGap()); lp.setVerticalGroup(lp.createSequentialGroup().addGap(4) /**/.addGroup(lp.createParallelGroup(Alignment.BASELINE) /* */.addComponent(lPX) /* */.addComponent(vPX) /* */.addComponent(lPW) /* */.addComponent(vPW)).addGap(4) /**/.addGroup(lp.createParallelGroup(Alignment.BASELINE) /* */.addComponent(lPY) /* */.addComponent(vPY) /* */.addComponent(lPH) /* */.addComponent(vPH)).addGap(8)); JTabbedPane tp = new JTabbedPane(); tp.setTabLayoutPolicy(JTabbedPane.SCROLL_TAB_LAYOUT); tp.addTab(Messages.getString("RoomFrame.VIEW_IN_ROOM"),pr); //$NON-NLS-1$ tp.addTab(Messages.getString("RoomFrame.PORT"),pp); //$NON-NLS-1$ return tp; } private JPanel makeViewsFollowPane() { JPanel pf = new JPanel(); pf.setBorder(BorderFactory.createTitledBorder(Messages.getString("RoomFrame.FOLLOW"))); //$NON-NLS-1$ GroupLayout lf = new GroupLayout(pf); pf.setLayout(lf); vObj = new ResourceMenu<GmObject>(Resource.Kind.OBJECT, Messages.getString("RoomFrame.NO_OBJECT"),true,110); //$NON-NLS-1$ JLabel lH = new JLabel(Messages.getString("RoomFrame.VIEW_HORIZONTAL")); JLabel lV = new JLabel(Messages.getString("RoomFrame.VIEW_VERTICAL")); JLabel lBorder = new JLabel(Messages.getString("RoomFrame.VIEW_BORDER")); JLabel lSpeed = new JLabel(Messages.getString("RoomFrame.VIEW_SPEED")); vOHBor = new NumberField(0,32000); vOHSp = new NumberField(-1,32000); vOVBor = new NumberField(0,32000); vOVSp = new NumberField(-1,32000); lf.setHorizontalGroup(lf.createSequentialGroup().addContainerGap() /**/.addGroup(lf.createParallelGroup() /* */.addComponent(vObj) /* */.addGroup(lf.createSequentialGroup() /* */.addGroup(lf.createParallelGroup(Alignment.TRAILING) /* */.addComponent(lH) /* */.addComponent(lV)).addGap(4) /* */.addGroup(lf.createParallelGroup() /* */.addComponent(lBorder) /* */.addComponent(vOHBor) /* */.addComponent(vOVBor)).addGap(4) /* */.addGroup(lf.createParallelGroup() /* */.addComponent(lSpeed) /* */.addComponent(vOHSp) /* */.addComponent(vOVSp)))).addContainerGap()); lf.setVerticalGroup(lf.createSequentialGroup().addGap(4) /**/.addComponent(vObj).addGap(4) /* */.addGroup(lf.createParallelGroup(Alignment.BASELINE) /* */.addComponent(lBorder) /* */.addComponent(lSpeed)).addGap(4) /* */.addGroup(lf.createParallelGroup(Alignment.BASELINE) /* */.addComponent(lH) /* */.addComponent(vOHBor) /* */.addComponent(vOHSp)).addGap(4) /* */.addGroup(lf.createParallelGroup(Alignment.BASELINE) /* */.addComponent(lV) /* */.addComponent(vOVBor) /* */.addComponent(vOVSp)).addGap(8)); return pf; } private JPanel makeStatsPane() { JPanel stat = new JPanel(); stat.setLayout(new BoxLayout(stat,BoxLayout.X_AXIS)); stat.setMaximumSize(new Dimension(Integer.MAX_VALUE,11)); statX = new JLabel(Messages.getString("RoomFrame.STAT_X")); //$NON-NLS-1$ statX.setMaximumSize(new Dimension(50,14)); stat.add(statX); stat.add(new JLabel("|")); //$NON-NLS-1$ //visible divider ^ since JSeparator isn't visible statY = new JLabel(Messages.getString("RoomFrame.STAT_Y")); //$NON-NLS-1$ statY.setMaximumSize(new Dimension(50,13)); stat.add(statY); stat.add(new JLabel("|")); //$NON-NLS-1$ statId = new JLabel(); statId.setMaximumSize(new Dimension(75,13)); stat.add(statId); stat.add(new JLabel("|")); //$NON-NLS-1$ statSrc = new JLabel(); stat.add(statSrc); //resizes at will, so no Max size return stat; } public RoomFrame(Room res, ResNode node) { super(res,node); editor = new RoomEditor(res,this); prelf = new PropertyLinkFactory<PRoomEditor>(editor.properties,null); GroupLayout layout = new GroupLayout(getContentPane()) { @Override public void layoutContainer(Container parent) { Dimension m = RoomFrame.this.getMinimumSize(); Dimension s = RoomFrame.this.getSize(); Dimension r = new Dimension(Math.max(m.width,s.width),Math.max(m.height,s.height)); if (!r.equals(s)) RoomFrame.this.setSize(r); else super.layoutContainer(parent); } }; setLayout(layout); JToolBar tools = makeToolBar(); //conveniently, these tabs happen to have the same indexes as GM's tabs tabs = new JTabbedPane(); tabs.setTabLayoutPolicy(JTabbedPane.WRAP_TAB_LAYOUT); tabs.addTab(Messages.getString("RoomFrame.TAB_OBJECTS"),makeObjectsPane()); //$NON-NLS-1$ tabs.addTab(Messages.getString("RoomFrame.TAB_SETTINGS"),makeSettingsPane()); //$NON-NLS-1$ tabs.addTab(Messages.getString("RoomFrame.TAB_TILES"),makeTilesPane()); //$NON-NLS-1$ String bks = Messages.getString("RoomFrame.TAB_BACKGROUNDS"); //$NON-NLS-1$ tabs.addTab(bks,makeBackgroundsPane()); tabs.addTab(Messages.getString("RoomFrame.TAB_VIEWS"),makeViewsPane()); //$NON-NLS-1$ tabs.setSelectedIndex((Integer) res.get(PRoom.CURRENT_TAB)); res.instanceUpdateSource.addListener(this); res.tileUpdateSource.addListener(this); editorPane = new EditorScrollPane(editor); prelf.make(editorPane,PRoomEditor.ZOOM); JPanel stats = makeStatsPane(); layout.setHorizontalGroup(layout.createParallelGroup() /**/.addComponent(tools) /**/.addGroup(layout.createSequentialGroup() /* */.addComponent(tabs,PREFERRED_SIZE,PREFERRED_SIZE,PREFERRED_SIZE) /* */.addGroup(layout.createParallelGroup() /* */.addComponent(editorPane,200,640,DEFAULT_SIZE) /* */.addComponent(stats)))); layout.setVerticalGroup(layout.createSequentialGroup() /**/.addComponent(tools,PREFERRED_SIZE,PREFERRED_SIZE,PREFERRED_SIZE) /**/.addGroup(layout.createParallelGroup() /* */.addComponent(tabs) /* */.addGroup(layout.createSequentialGroup() /* */.addComponent(editorPane,DEFAULT_SIZE,480,DEFAULT_SIZE) /* */.addComponent(stats)))); if (res.get(PRoom.REMEMBER_WINDOW_SIZE)) { int h = res.get(PRoom.EDITOR_HEIGHT); int w = res.get(PRoom.EDITOR_WIDTH); Dimension d = LGM.mdi.getSize(); if (d.width <= w && d.height <= h) maximize = true; else setSize(w,h); } else pack(); } private boolean maximize; //maximizes over-sized RoomFrames, since setMaximum can't //be called until after it's been added to the MDI public void setVisible(boolean b) { super.setVisible(b); if (!maximize) return; try { setMaximum(true); } catch (PropertyVetoException e) { setSize((Integer) res.get(PRoom.EDITOR_WIDTH),(Integer) res.get(PRoom.EDITOR_HEIGHT)); e.printStackTrace(); } } public static class ListComponentRenderer implements ListCellRenderer { public Component getListCellRendererComponent(JList list, Object val, int ind, boolean selected, boolean focus) { Component lab = (Component) val; if (selected) { lab.setBackground(list.getSelectionBackground()); lab.setForeground(list.getSelectionForeground()); } else { lab.setBackground(list.getBackground()); lab.setForeground(list.getForeground()); } return lab; } } protected boolean areResourceFieldsEqual() { return (res.backgroundDefs.equals(resOriginal.backgroundDefs) && res.views.equals(resOriginal.views) && res.instances.equals(resOriginal.instances) && res.tiles.equals(resOriginal.tiles)); } public void commitChanges() { res.setName(name.getText()); for (CodeFrame cf : codeFrames.values()) cf.commitChanges(); if (res.get(PRoom.REMEMBER_WINDOW_SIZE)) { res.put(PRoom.CURRENT_TAB,tabs.getSelectedIndex()); Dimension s = getSize(); res.put(PRoom.EDITOR_WIDTH,s.width); res.put(PRoom.EDITOR_HEIGHT,s.height); } } public void actionPerformed(ActionEvent e) { if (editor != null) editor.refresh(); Object s = e.getSource(); if (s == sShow) { sShowMenu.show(sShow,0,sShow.getHeight()); return; } if (s == oAdd) { if (oNew.getSelected() == null) return; Instance i = res.addInstance(); i.properties.put(PInstance.OBJECT,oNew.getSelected()); i.setPosition(new Point()); oList.setSelectedIndex(res.instances.size() - 1); return; } if (s == oDel) { int i = oList.getSelectedIndex(); if (i == -1) return; CodeFrame frame = codeFrames.get(res.instances.remove(i)); if (frame != null) frame.dispose(); oList.setSelectedIndex(Math.min(res.instances.size() - 1,i)); return; } if (s == taSource) { tSelect.setBackground(taSource.getSelected()); return; } if (s == tDel) { int i = tList.getSelectedIndex(); if (i == -1) return; res.tiles.remove(i); tList.setSelectedIndex(Math.min(res.tiles.size() - 1,i)); return; } if (e.getSource() == sCreationCode) { openCodeFrame(res,Messages.getString("RoomFrame.TITLE_FORMAT_CREATION"),res.getName()); //$NON-NLS-1$ return; } if (e.getSource() == oCreationCode) { if (lastObj != null) openCodeFrame(lastObj); return; } super.actionPerformed(e); } public void fireObjUpdate() { Instance i = (Instance) oList.getSelectedValue(); if (lastObj == i) return; lastObj = i; PropertyLink.removeAll(loLocked,loSource,loX,loY); if (i != null) { PropertyLinkFactory<PInstance> iplf = new PropertyLinkFactory<PInstance>(i.properties,this); loLocked = iplf.make(oLocked,PInstance.LOCKED); loSource = iplf.make(oSource,PInstance.OBJECT); loX = iplf.make(oX,PInstance.X); loY = iplf.make(oY,PInstance.Y); } } @Override public Dimension getMinimumSize() { Dimension p = getContentPane().getSize(); Dimension l = getContentPane().getMinimumSize(); Dimension s = getSize(); l.width += s.width - p.width; l.height += s.height - p.height; return l; } public void fireTileUpdate() { Tile t = (Tile) tList.getSelectedValue(); if (lastTile == t) return; lastTile = t; PropertyLink.removeAll(ltDepth,ltLocked,ltSource,ltsX,ltsY,ltX,ltY); if (t != null) { PropertyLinkFactory<PTile> tplf = new PropertyLinkFactory<PTile>(t.properties,this); ltDepth = tplf.make(teDepth,PTile.DEPTH); ltLocked = tplf.make(tLocked,PTile.LOCKED); ltSource = tplf.make(teSource,PTile.BACKGROUND); ltsX = tplf.make(tsX,PTile.BG_X); ltsY = tplf.make(tsY,PTile.BG_Y); ltX = tplf.make(tX,PTile.ROOM_X); ltY = tplf.make(tY,PTile.ROOM_Y); } } public void fireBackUpdate() { int i = bList.getSelectedIndex(); if (lastValidBack == i) return; if (i < 0) { bList.setSelectedIndex(lastValidBack < 0 ? 0 : lastValidBack); return; } lastValidBack = i; PropertyLink.removeAll(lbVisible,lbForeground,lbSource,lbX,lbY,lbTileH,lbTileV,lbStretch,lbH, lbV); BackgroundDef b = res.backgroundDefs.get(i); PropertyLinkFactory<PBackgroundDef> bdplf = new PropertyLinkFactory<PBackgroundDef>( b.properties,this); lbVisible = bdplf.make(bVisible,PBackgroundDef.VISIBLE); lbForeground = bdplf.make(bForeground,PBackgroundDef.FOREGROUND); lbSource = bdplf.make(bSource,PBackgroundDef.BACKGROUND); lbX = bdplf.make(bX,PBackgroundDef.X); lbY = bdplf.make(bY,PBackgroundDef.Y); lbTileH = bdplf.make(bTileH,PBackgroundDef.TILE_HORIZ); lbTileV = bdplf.make(bTileV,PBackgroundDef.TILE_VERT); lbStretch = bdplf.make(bStretch,PBackgroundDef.STRETCH); lbH = bdplf.make(bH,PBackgroundDef.H_SPEED); lbV = bdplf.make(bV,PBackgroundDef.V_SPEED); } public void fireViewUpdate() { int i = vList.getSelectedIndex(); if (lastValidView == i) return; if (i < 0) { bList.setSelectedIndex(lastValidView < 0 ? 0 : lastValidView); return; } lastValidView = i; PropertyLink.removeAll(lvVisible,lvRX,lvRY,lvRW,lvRH,lvPX,lvPY,lvPW,lvPH,lvObj,lvOHBor,lvOVBor, lvOHSp,lvOVSp); View v = res.views.get(i); PropertyLinkFactory<PView> vplf = new PropertyLinkFactory<PView>(v.properties,this); lvVisible = vplf.make(vVisible,PView.VISIBLE); lvRX = vplf.make(vRX,PView.VIEW_X); lvRY = vplf.make(vRY,PView.VIEW_Y); lvRW = vplf.make(vRW,PView.VIEW_W); lvRH = vplf.make(vRH,PView.VIEW_H); lvPX = vplf.make(vPX,PView.PORT_X); lvPY = vplf.make(vPY,PView.PORT_Y); lvPW = vplf.make(vPW,PView.PORT_W); lvPH = vplf.make(vPH,PView.PORT_H); lvObj = vplf.make(vObj,PView.OBJECT); lvOHBor = vplf.make(vOHBor,PView.BORDER_H); lvOVBor = vplf.make(vOVBor,PView.BORDER_V); lvOHSp = vplf.make(vOHSp,PView.SPEED_H); lvOVSp = vplf.make(vOVSp,PView.SPEED_V); } public void valueChanged(ListSelectionEvent e) { if (e.getValueIsAdjusting()) return; if (e.getSource() == oList) fireObjUpdate(); if (e.getSource() == tList) fireTileUpdate(); if (e.getSource() == bList) fireBackUpdate(); if (e.getSource() == vList) fireViewUpdate(); } public void openCodeFrame(Instance i) { openCodeFrame(i,Messages.getString("RoomFrame.TITLE_FORMAT_CREATION"),Messages.format( "RoomFrame.INSTANCE",i.properties.get(PInstance.ID))); } public void openCodeFrame(CodeHolder code, String titleFormat, Object titleArg) { CodeFrame frame = codeFrames.get(code); if (frame == null) { frame = new CodeFrame(code,titleFormat,titleArg); codeFrames.put(code,frame); frame.addInternalFrameListener(new InternalFrameAdapter() { public void internalFrameClosed(InternalFrameEvent e) { CodeFrame f = ((CodeFrame) e.getSource()); codeFrames.remove(f.codeHolder); f.removeInternalFrameListener(this); } }); LGM.mdi.add(frame); LGM.mdi.addZChild(this,frame); frame.toTop(); } else frame.toTop(); } public void removeUpdate(DocumentEvent e) { CodeFrame f = codeFrames.get(res); if (f != null) f.setTitleFormatArg(name.getText()); super.removeUpdate(e); } public void insertUpdate(DocumentEvent e) { CodeFrame f = codeFrames.get(res); if (f != null) f.setTitleFormatArg(name.getText()); super.insertUpdate(e); } public void dispose() { super.dispose(); for (CodeFrame cf : codeFrames.values()) cf.dispose(); // XXX: These components could still be referenced by InputContext or similar. // Removing their references to this frame is therefore necessary in order to ensure // garbage collection. oNew.removeActionListener(this); oList.removeListSelectionListener(this); oAdd.removeActionListener(this); oDel.removeActionListener(this); oCreationCode.removeActionListener(this); sCreationCode.removeActionListener(this); sShow.removeActionListener(this); taSource.removeActionListener(this); tList.removeListSelectionListener(this); tDel.removeActionListener(this); bList.removeListSelectionListener(this); vList.removeListSelectionListener(this); editorPane.setViewport(null); setLayout(null); } public void updated(UpdateEvent e) { if (e.source == res.instanceUpdateSource) oList.setPrototypeCellValue(null); else if (e.source == res.tileUpdateSource) tList.setPrototypeCellValue(null); } private void bdvListUpdate(boolean isBgDef, UpdateSource s, boolean v) { int ls = (isBgDef ? res.backgroundDefs : res.views).size(); for (int i = 0; i < ls; i++) { UpdateSource s2 = (isBgDef ? res.backgroundDefs.get(i).properties : res.views.get(i).properties).updateSource; if (s2 != s) continue; JList l = isBgDef ? bList : vList; JLabel ll = (JLabel) l.getModel().getElementAt(i); ll.setFont(ll.getFont().deriveFont(v ? Font.BOLD : Font.PLAIN)); l.setPrototypeCellValue(null); break; } } private class BgDefPropertyListener extends PropertyUpdateListener<PBackgroundDef> { @Override public void updated(PropertyUpdateEvent<PBackgroundDef> e) { if (e.key == PBackgroundDef.VISIBLE) bdvListUpdate(true,e.source,(Boolean) e.map.get(e.key)); } } private class ViewPropertyListener extends PropertyUpdateListener<PView> { @Override public void updated(PropertyUpdateEvent<PView> e) { if (e.key == PView.VISIBLE) bdvListUpdate(false,e.source,(Boolean) e.map.get(e.key)); } } }