Search in sources :

Example 11 with Place

use of mudmap2.backend.Place in project mudmap2 by Neop.

the class PlaceGroupDialog method create.

/**
 * Creates the GUI
 */
@Override
void create() {
    setLayout(new GridBagLayout());
    GridBagConstraints constraints = new GridBagConstraints();
    constraints.insets = new Insets(2, 2, 2, 2);
    constraints.gridx = 0;
    constraints.gridy = 0;
    constraints.fill = GridBagConstraints.HORIZONTAL;
    add(new JLabel("Name"), constraints);
    constraints.gridx = 1;
    constraints.gridwidth = 2;
    if (placeGroup != null)
        textfield_name = new JTextField(placeGroup.toString());
    else
        textfield_name = new JTextField();
    add(textfield_name, constraints);
    textfield_name.setColumns(20);
    constraints.gridwidth = 1;
    constraints.gridx = 0;
    constraints.gridy++;
    add(new JLabel("Color"), constraints);
    constraints.weighty = 4.0;
    constraints.gridx = 1;
    constraints.fill = GridBagConstraints.BOTH;
    constraints.gridwidth = 2;
    if (placeGroup != null)
        colorchooserbutton = new ColorChooserButton(getParent(), placeGroup.getColor());
    else
        colorchooserbutton = new ColorChooserButton(getParent());
    add(colorchooserbutton, constraints);
    constraints.weighty = 1.0;
    constraints.gridwidth = 1;
    constraints.fill = GridBagConstraints.HORIZONTAL;
    constraints.gridx = 0;
    constraints.gridy++;
    JButton button_cancel = new JButton("Cancel");
    add(button_cancel, constraints);
    button_cancel.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            dispose();
        }
    });
    constraints.gridx++;
    JButton button_new = new JButton("Add");
    button_new.setToolTipText("Create a new place group");
    add(button_new, constraints);
    getRootPane().setDefaultButton(button_new);
    button_new.addActionListener(new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent arg0) {
            new_group = true;
            save();
            dispose();
        }
    });
    if (!new_group) {
        // don't show edit button when creating a new place
        constraints.gridx++;
        JButton button_edit = new JButton("Edit");
        button_edit.setToolTipText("Edit the current place group");
        add(button_edit, constraints);
        getRootPane().setDefaultButton(button_edit);
        button_edit.addActionListener(new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent arg0) {
                save();
                dispose();
            }
        });
    }
    pack();
    setResizable(false);
    setLocation(getParent().getX() + (getParent().getWidth() - getWidth()) / 2, getParent().getY() + (getParent().getHeight() - getHeight()) / 2);
}
Also used : GridBagConstraints(java.awt.GridBagConstraints) Insets(java.awt.Insets) GridBagLayout(java.awt.GridBagLayout) ActionListener(java.awt.event.ActionListener) ColorChooserButton(mudmap2.frontend.GUIElement.ColorChooserButton) ActionEvent(java.awt.event.ActionEvent) JButton(javax.swing.JButton) JLabel(javax.swing.JLabel) JTextField(javax.swing.JTextField)

Example 12 with Place

use of mudmap2.backend.Place in project mudmap2 by Neop.

the class PlacePanel method update.

/**
 * Creates the
 * @param keyword
 */
public final void update(String keyword) {
    root.removeAllChildren();
    layerNodes.clear();
    placeNodes.clear();
    ArrayList<Layer> layerList = new ArrayList<>(world.getLayers());
    Collections.sort(layerList, new AlphanumComparator<>());
    String[] keywords;
    if (keyword.isEmpty()) {
        keywords = new String[0];
        useKeywords = false;
    } else {
        keywords = keyword.split(" ");
        useKeywords = true;
    }
    for (Layer layer : layerList) {
        LayerTreeNode layerNode = new LayerTreeNode(layer);
        root.add(layerNode);
        layerNodes.put(layer, layerNode);
        HashSet<Place> places = layer.getPlaces();
        ArrayList<Place> placeList = new ArrayList<>(places);
        Collections.sort(placeList, new AlphanumComparator<>());
        for (Place place : placeList) {
            if (!useKeywords || place.matchKeywords(keywords)) {
                PlaceTreeNode placeNode = new PlaceTreeNode(place);
                layerNode.add(placeNode);
                placeNodes.put(place, placeNode);
            }
        }
    }
    // remove empty layer nodes
    if (useKeywords) {
        for (LayerTreeNode layerNode : layerNodes.values()) {
            if (layerNode.getChildCount() == 0)
                layerNode.removeFromParent();
        }
    }
    ((DefaultTreeModel) tree.getModel()).reload();
    tree.setShowsRootHandles(true);
    tree.setRootVisible(false);
}
Also used : ArrayList(java.util.ArrayList) DefaultTreeModel(javax.swing.tree.DefaultTreeModel) Layer(mudmap2.backend.Layer) Place(mudmap2.backend.Place)

Example 13 with Place

use of mudmap2.backend.Place in project mudmap2 by Neop.

the class MapPainterDefault method paint.

@Override
public void paint(Graphics g, int tileSize, double graphicsWidth, double graphicsHeight, Layer layer, WorldCoordinate curPos) {
    this.graphicsWidth = graphicsWidth;
    this.graphicsHeight = graphicsHeight;
    this.tileSize = tileSize;
    this.curPos = curPos;
    tileFont = g.getFont();
    final float selectionStrokeWidth = getTileSelectionStrokeWidth();
    final int tileBorderWidthScaled = getTileBorderWidth();
    // max number of text lines tht fit in a tile
    FontMetrics fm = g.getFontMetrics();
    final int maxLines = (int) Math.round((double) (tileSize - 3 * (tileBorderWidthScaled + (int) Math.ceil(getRiskLevelStrokeWidth()))) / fm.getHeight());
    final int maxLineLength = tileSize - 2 * (tileBorderWidthScaled + (int) selectionStrokeWidth + (int) Math.ceil(getRiskLevelStrokeWidth()));
    final Boolean drawText = fm.stringWidth("WW") < (tileSize - 2 * (getRiskLevelStrokeWidth() + getTileBorderWidth()));
    // screen center in world coordinates
    // note: wdtwd2
    final double screenCenterX = (graphicsWidth / tileSize) / 2.0;
    final double screenCenterY = (graphicsHeight / tileSize) / 2.0;
    final int placeXOffset = (int) (Math.round((float) curPos.getX()) - Math.round(screenCenterX));
    final int placeYOffset = (int) (Math.round((float) curPos.getY()) - Math.floor(screenCenterY));
    // more precalculation
    final double placeXpxConst = remint(screenCenterX) - remint(curPos.getX());
    final double placeYPXConst = remint(screenCenterY) + remint(curPos.getY());
    // prepare graphic for paths
    // Paths will be drawn on this graphic and later on copied to g
    // to mask out the tile positions on graphic_path
    ArrayList<Pair<Integer, Integer>> tilePositions = new ArrayList<>();
    BufferedImage imagePath = new BufferedImage((int) graphicsWidth, (int) graphicsHeight, BufferedImage.TYPE_INT_ARGB);
    Graphics graphicPath = imagePath.getGraphics();
    ((Graphics2D) graphicPath).setStroke(new BasicStroke(getPathStrokeWidth()));
    ((Graphics2D) graphicPath).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    ((Graphics2D) g).setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    // getPlace the locations of copied places
    HashSet<Pair<Integer, Integer>> copiedPlaceLocations = mudmap2.CopyPaste.getCopyPlaceLocations();
    // clear screen
    if (backgroundColor == null) {
        g.clearRect(0, 0, (int) graphicsWidth + 1, (int) graphicsHeight + 1);
    } else {
        g.setColor(backgroundColor);
        g.fillRect(0, 0, (int) graphicsWidth + 1, (int) graphicsHeight + 1);
    }
    // ------------------ draw the grid --------------------------------
    if (isGridEnabled()) {
        g.setColor(Color.lightGray);
        for (int tileX = (g.getClipBounds().x / tileSize) - 1; tileX < graphicsWidth / tileSize + 1; ++tileX) {
            final int x = (int) Math.round((tileX + placeXpxConst) * tileSize);
            g.drawLine(x, 0, x, (int) graphicsHeight);
        }
        for (int tileY = (g.getClipBounds().y / tileSize) - 1; tileY < graphicsHeight / tileSize + 1; ++tileY) {
            final int y = (int) Math.round((tileY + placeYPXConst) * tileSize);
            g.drawLine(0, y, (int) graphicsWidth, y);
        }
    }
    // ------------------ draw the tiles / places ----------------------
    for (int tileX = (g.getClipBounds().x / tileSize) - 1; tileX < graphicsWidth / tileSize + 1; ++tileX) {
        for (int tileY = (g.getClipBounds().y / tileSize) - 1; tileY < graphicsHeight / tileSize + 1; ++tileY) {
            // place position on the map
            final int placeX = tileX + placeXOffset;
            final int placeY = (int) (graphicsHeight / tileSize) - tileY + placeYOffset;
            if (layer != null && layer.exist(placeX, placeY)) {
                Place curPlace = layer.get(placeX, placeY);
                // place position in pixel on the screen
                final int placeXpx = (int) Math.round((tileX + placeXpxConst) * tileSize);
                final int placeYpx = (int) Math.round((tileY + placeYPXConst) * tileSize);
                tilePositions.add(new Pair<>(placeXpx, placeYpx));
                // number of drawn text lines
                int lineNum = 0;
                // draw place group color
                if (curPlace.getPlaceGroup() != null) {
                    g.setColor(curPlace.getPlaceGroup().getColor());
                    g.fillRect(placeXpx, placeYpx, tileSize, tileSize);
                }
                // draw tile center color
                if (drawText) {
                    g.setColor(layer.getWorld().getTileCenterColor());
                    g.fillRect(placeXpx + tileBorderWidthScaled, placeYpx + tileBorderWidthScaled, tileSize - 2 * tileBorderWidthScaled, tileSize - 2 * tileBorderWidthScaled);
                }
                // draw risk level border
                if (curPlace.getRiskLevel() != null) {
                    g.setColor(curPlace.getRiskLevel().getColor());
                    ((Graphics2D) g).setStroke(new BasicStroke(getRiskLevelStrokeWidth()));
                    g.drawRect(placeXpx + tileBorderWidthScaled, placeYpx + tileBorderWidthScaled, tileSize - 2 * tileBorderWidthScaled - (int) (0.5 * getRiskLevelStrokeWidth()), tileSize - 2 * tileBorderWidthScaled - (int) (0.5 * getRiskLevelStrokeWidth()));
                }
                LinkedList<String> text = new LinkedList<>();
                String flags = "", exits = "";
                // draw text, if tiles are large enough
                if (drawText) {
                    g.setColor(Color.BLACK);
                    // place name
                    // gets place name if unique, else place name with ID
                    String placeName;
                    switch(layer.getWorld().getShowPlaceId()) {
                        default:
                        case UNIQUE:
                        case NONE:
                            // name only
                            placeName = curPlace.getName();
                            break;
                        case ALL:
                            // name and id
                            placeName = curPlace.toString();
                            break;
                    }
                    text.add(placeName);
                    int reclvlmin = curPlace.getRecLevelMin(), reclvlmax = curPlace.getRecLevelMax();
                    if (reclvlmin > -1 || reclvlmax > -1) {
                        String levelString = "lvl " + (reclvlmin > -1 ? reclvlmin : "?") + " - " + (reclvlmax > -1 ? reclvlmax : "?");
                        text.add(levelString);
                    }
                    // parents
                    if (lineNum < maxLines && !curPlace.getParents().isEmpty()) {
                        int parentsNum = curPlace.getParents().size();
                        String paStr = "Pa" + (parentsNum > 1 ? " (" + curPlace.getParents().size() + "): " : ": ");
                        boolean firstParent = true;
                        for (Place parent : curPlace.getParents()) {
                            paStr += (firstParent ? "" : ", ") + parent.getName();
                            firstParent = false;
                        }
                        text.add(paStr);
                    }
                    // children
                    if (lineNum < maxLines && !curPlace.getChildren().isEmpty()) {
                        int childrenNum = curPlace.getChildren().size();
                        String chStr = "Ch" + (childrenNum > 1 ? " (" + curPlace.getChildren().size() + "): " : ": ");
                        boolean firstChild = true;
                        for (Place child : curPlace.getChildren()) {
                            chStr += (firstChild ? "" : ", ") + child.getName();
                            firstChild = false;
                        }
                        text.add(chStr);
                    }
                    // flags
                    if (lineNum < maxLines) {
                        // place has comments
                        if (!curPlace.getComments().isEmpty())
                            flags += "Co";
                        if (!curPlace.getChildren().isEmpty())
                            flags += "Ch";
                        if (!curPlace.getParents().isEmpty())
                            flags += "Pa";
                        // other flags
                        for (Map.Entry<String, Boolean> flag : curPlace.getFlags().entrySet()) {
                            if (flag.getValue())
                                flags += flag.getKey().toUpperCase();
                            if (fm.stringWidth(flags) >= tileSize - 2 * tileBorderWidthScaled)
                                break;
                        }
                    }
                }
                // mark place group selection
                if (isSelected(curPlace) || (mudmap2.CopyPaste.isCut() && mudmap2.CopyPaste.isMarked(curPlace))) {
                    g.setColor(new Color(255, 255, 255, 128));
                    g.fillRect(placeXpx, placeYpx, tileSize, tileSize);
                }
                // draw path lines here
                boolean exitUp = false, exitDown = false, exitnstd = false;
                if (getShowPaths()) {
                    for (Path path : curPlace.getPaths()) {
                        Place otherPlace = path.getOtherPlace(curPlace);
                        Color colorPlace1 = layer.getWorld().getPathColor(path.getExitDirections()[0]);
                        Color colorPlace2 = layer.getWorld().getPathColor(path.getExitDirections()[1]);
                        if (path.getPlaces()[0] != curPlace) {
                            Color tmp = colorPlace1;
                            colorPlace1 = colorPlace2;
                            colorPlace2 = tmp;
                        }
                        // usually the main place (path.getPlaces()[0]) draws the path. If it isn't on screen, the other place draws it
                        if (Objects.equals(otherPlace.getLayer().getId(), layer.getId()) && (path.getPlaces()[0] == curPlace || !isOnScreen(otherPlace))) {
                            Pair<Integer, Integer> exitOffset = getExitOffset(path.getExit(curPlace));
                            Pair<Integer, Integer> exitOffsetOther = getExitOffset(path.getExit(otherPlace));
                            boolean drawCurves = getPathsCurved();
                            // exit positions on the map
                            final double exit1x = placeXpx + exitOffset.first;
                            final double exit1y = placeYpx + exitOffset.second;
                            final double exit2x = placeXpx + (otherPlace.getX() - curPlace.getX()) * tileSize + exitOffsetOther.first;
                            final double exit2y = placeYpx - (otherPlace.getY() - curPlace.getY()) * tileSize + exitOffsetOther.second;
                            if (colorPlace1.equals(colorPlace2)) {
                                // same color
                                ((Graphics2D) graphicPath).setPaint(colorPlace1);
                            } else {
                                // draw gradient
                                GradientPaint gp = new GradientPaint((float) exit1x, (float) exit1y, colorPlace1, (float) exit2x, (float) exit2y, colorPlace2);
                                ((Graphics2D) graphicPath).setPaint(gp);
                            }
                            if (drawCurves) {
                                Pair<Double, Double> normal1 = getExitNormal(path.getExit(curPlace));
                                Pair<Double, Double> normal2 = getExitNormal(path.getExit(otherPlace));
                                double dx = exit2x - exit1x;
                                double dy = exit2y - exit1y;
                                if (drawCurves = Math.sqrt(dx * dx + dy * dy) >= 1.5 * tileSize) {
                                    CubicCurve2D c = new CubicCurve2D.Double();
                                    // point 1
                                    c.setCurve(exit1x, exit1y, // point 2
                                    exit1x + normal1.first * tileSize, exit1y - normal1.second * tileSize, // point 3
                                    exit2x + normal2.first * tileSize, exit2y - normal2.second * tileSize, // point 4
                                    exit2x, exit2y);
                                    ((Graphics2D) graphicPath).draw(c);
                                }
                            }
                            if (!drawCurves) {
                                graphicPath.drawLine((int) exit1x, (int) exit1y, (int) exit2x, (int) exit2y);
                            }
                        }
                        // draw exit dots, if tiles are larger than 20
                        if (tileSize >= 20) {
                            g.setColor(colorPlace1);
                            String exit = path.getExit(curPlace);
                            switch(exit) {
                                case "u":
                                    exitUp = true;
                                    break;
                                case "d":
                                    exitDown = true;
                                    break;
                                default:
                                    Pair<Integer, Integer> exitOffset = getExitOffset(exit);
                                    if (exitOffset.first != tileSize / 2 || exitOffset.second != tileSize / 2) {
                                        int exitCircleRadius2 = getExitCircleRadius();
                                        g.fillOval(placeXpx + exitOffset.first - exitCircleRadius2, placeYpx + exitOffset.second - exitCircleRadius2, 2 * exitCircleRadius2, 2 * exitCircleRadius2);
                                    } else {
                                        // non-standard exit
                                        exitnstd = true;
                                    }
                                    break;
                            }
                        }
                    }
                }
                // draw exits
                if (tileSize >= 20 && (exitUp || exitDown) && drawText && lineNum <= maxLines) {
                    // have some arrows: ⬆⬇ ↑↓
                    exits = "" + (exitnstd ? "+" : "") + (exitUp ? "↑" : "") + (exitDown ? "↓" : "");
                }
                g.setColor(Color.BLACK);
                final int border = (int) (tileBorderWidthScaled + getRiskLevelStrokeWidth());
                drawText(g, placeXpx + border, placeYpx + border, tileSize - 2 * border, tileSize - 2 * border, text, flags, exits);
            }
            // TODO: extract from parent loop
            if (copiedPlaceLocations != null) {
                boolean locationFound = false;
                for (Pair<Integer, Integer> location : copiedPlaceLocations) {
                    if (location.first == placeX - placeSelectedX && location.second == placeY - placeSelectedY) {
                        locationFound = true;
                        break;
                    }
                }
                if (locationFound) {
                    // alternative: getScreenPosX();
                    int placeXpx = (int) ((tileX + remint(screenCenterX) - remint(curPos.getX())) * tileSize);
                    int placeYpx = (int) ((tileY + remint(screenCenterY) + remint(curPos.getY())) * tileSize);
                    drawCursor(g, Color.BLUE, placeXpx, placeYpx, selectionStrokeWidth);
                }
            }
            // draw cursor / place selection
            if (placeSelectionEnabled && placeX == placeSelectedX && placeY == placeSelectedY) {
                // alternative: getScreenPosX();
                int placeXpx = (int) ((tileX + remint(screenCenterX) - remint(curPos.getX())) * tileSize);
                int placeYpx = (int) ((tileY + remint(screenCenterY) + remint(curPos.getY())) * tileSize);
                drawCursor(g, TILE_SELECTION_COLOR, placeXpx, placeYpx, selectionStrokeWidth);
            }
        }
    }
    // mask out tile positions on graphicPath
    ((Graphics2D) graphicPath).setBackground(new Color(0, 0, 0, 0));
    int clearTileSize = tileSize - 2 * tileBorderWidthScaled;
    for (Pair<Integer, Integer> p : tilePositions) // graphicPath.clearRect(p.first, p.second, p.first + tileSize, p.second + tileSize);
    graphicPath.clearRect(p.first + tileBorderWidthScaled, p.second + tileBorderWidthScaled, clearTileSize, clearTileSize);
    // draw graphicPath to g
    if (getShowPaths())
        g.drawImage(imagePath, 0, 0, null);
    graphicPath.dispose();
}
Also used : BasicStroke(java.awt.BasicStroke) ArrayList(java.util.ArrayList) GradientPaint(java.awt.GradientPaint) BufferedImage(java.awt.image.BufferedImage) FontMetrics(java.awt.FontMetrics) CubicCurve2D(java.awt.geom.CubicCurve2D) Pair(mudmap2.utils.Pair) Path(mudmap2.backend.Path) Color(java.awt.Color) GradientPaint(java.awt.GradientPaint) LinkedList(java.util.LinkedList) Graphics2D(java.awt.Graphics2D) Graphics(java.awt.Graphics) HashMap(java.util.HashMap) Map(java.util.Map) Place(mudmap2.backend.Place)

Example 14 with Place

use of mudmap2.backend.Place in project mudmap2 by Neop.

the class WorldPanel method pushPosition.

// ========================= position history ==============================
public void pushPosition(WorldCoordinate coord) {
    WorldCoordinate pos = new WorldCoordinate(coord);
    // remove all entries after the current one
    while (positionIdx > 0) {
        positionHistory.pop();
        positionIdx--;
    }
    callLayerChangeListeners(getWorld().getLayer(coord.getLayer()));
    // add new position
    positionHistory.push(pos);
    // move place selection
    setCursor((int) pos.getX(), (int) pos.getY());
}
Also used : WorldCoordinate(mudmap2.backend.WorldCoordinate)

Example 15 with Place

use of mudmap2.backend.Place in project mudmap2 by Neop.

the class WorldPanel method placeGroupBoxSelectionToList.

/**
 * Moves the box/shift selection to the selected places list
 */
private void placeGroupBoxSelectionToList() {
    if (placeGroupBoxEnd != null && placeGroupBoxStart != null) {
        int x1 = (int) Math.round(placeGroupBoxEnd.getX());
        int x2 = (int) Math.round(placeGroupBoxStart.getX());
        int y1 = (int) Math.round(placeGroupBoxEnd.getY());
        int y2 = (int) Math.round(placeGroupBoxStart.getY());
        int x_min = Math.min(x1, x2);
        int x_max = Math.max(x1, x2);
        int y_min = Math.min(y1, y2);
        int y_max = Math.max(y1, y2);
        Layer layer = getWorld().getLayer(placeGroupBoxEnd.getLayer());
        for (int x = x_min; x <= x_max; ++x) {
            for (int y = y_min; y <= y_max; ++y) {
                Place pl = layer.get(x, y);
                if (pl != null)
                    placeGroup.add(pl);
            }
        }
    }
    placeGroupBoxResetSelection();
}
Also used : Layer(mudmap2.backend.Layer) Place(mudmap2.backend.Place)

Aggregations

Place (mudmap2.backend.Place)20 Layer (mudmap2.backend.Layer)14 ActionEvent (java.awt.event.ActionEvent)7 ActionListener (java.awt.event.ActionListener)7 JLabel (javax.swing.JLabel)7 Path (mudmap2.backend.Path)7 PlaceGroup (mudmap2.backend.PlaceGroup)7 WorldCoordinate (mudmap2.backend.WorldCoordinate)7 Color (java.awt.Color)6 GridBagConstraints (java.awt.GridBagConstraints)6 GridBagLayout (java.awt.GridBagLayout)6 JButton (javax.swing.JButton)6 Insets (java.awt.Insets)5 Pair (mudmap2.utils.Pair)5 HashMap (java.util.HashMap)4 JCheckBox (javax.swing.JCheckBox)4 World (mudmap2.backend.World)4 Dimension (java.awt.Dimension)3 ArrayList (java.util.ArrayList)3 HashSet (java.util.HashSet)3