Package org.joshy.sketch.controls

Source Code of org.joshy.sketch.controls.FloatingPropertiesPanel$TIB

package org.joshy.sketch.controls;

import org.joshy.gfx.Core;
import org.joshy.gfx.draw.*;
import org.joshy.gfx.event.*;
import org.joshy.gfx.node.Bounds;
import org.joshy.gfx.node.NodeUtils;
import org.joshy.gfx.node.control.*;
import org.joshy.gfx.node.layout.FlexBox;
import org.joshy.gfx.node.layout.GridBox;
import org.joshy.gfx.node.layout.HFlexBox;
import org.joshy.gfx.node.layout.VFlexBox;
import org.joshy.gfx.stage.Stage;
import org.joshy.sketch.Main;
import org.joshy.sketch.actions.BooleanGeometry;
import org.joshy.sketch.actions.NodeActions;
import org.joshy.sketch.actions.SAction;
import org.joshy.sketch.actions.UndoManager;
import org.joshy.sketch.canvas.Selection;
import org.joshy.sketch.model.*;
import org.joshy.sketch.modes.vector.VectorDocContext;
import org.joshy.sketch.property.PropertyManager;

import java.awt.geom.Point2D;
import java.io.IOException;
import java.text.DecimalFormat;
import java.util.Map;

import static org.joshy.gfx.util.localization.Localization.getString;

public class FloatingPropertiesPanel extends VFlexBox {
    private boolean selected = false;
    private Selection selection;
    private Slider fillOpacitySlider;
    private SwatchColorPicker strokeColorButton;
    private Slider strokeWidthSlider;
    private Slider fontSizeSlider;
    private Togglebutton fontBoldButton;
    private Togglebutton fontItalicButton;
    private Main manager;
    private PopupMenuButton<String> fontPicker;
    private Label fillOpacityLabel;
    private Label strokeWidthLabel;
    private VectorDocContext context;
    private PopupMenuButton<SArrow.HeadEnd> arrowHeadEnd;
    private Label rgbLabel;
    private Label fontSizeLabel;
    public static final boolean TRUE_PALLETTE = false;//OSUtil.isMac();
    private boolean locked = false;
    private FlexBox groupPropertiesEditor;
    private FlexBox shapeProperties;

    private GridBox shadowProperties;
    private Checkbox shadowSet;
    //private Checkbox shadowInner;
    private SwatchColorPicker shadowColorButton;
    private SpinBox<Double> shadowXoff;
    private SpinBox<Double> shadowYoff;
    private SpinBox<Integer> shadowBlurRadius;
    private Slider shadowOpacity;

    private FlexBox fontProperties;
    private FlexBox booleanPropsEditor;
    private FillPicker fillButton;
    private Togglebutton fontAlignLeft;
    private Togglebutton fontAlignHCenter;
    private Togglebutton fontAlignRight;
    private ToggleGroup fontAlignGroup;
    private Checkbox fontWrap;
    private DecimalFormat df;
    private DecimalFormat intFormat;
    private FlexBox defaultProperties;
    private Textbox nameBox;


    public FloatingPropertiesPanel(final Main manager, final VectorDocContext context) throws IOException {
        this.context = context;

        df = new DecimalFormat();
        df.setMaximumFractionDigits(2);
        df.setMinimumFractionDigits(2);

        intFormat = new DecimalFormat();
        intFormat.setMinimumIntegerDigits(2);


        setFill(FlatColor.RED);
        this.manager = manager;
        selected = false;


        EventBus.getSystem().addListener(Selection.SelectionChangeEvent.Changed, selectionCallback);

        defaultProperties = new HFlexBox().setBoxAlign(Align.Baseline);

        add(defaultProperties);
        defaultProperties.add(new Label("Name:").setFont(Font.name("OpenSans").size(12).resolve()));
        nameBox =  new Textbox("").setHintText("unset");
        nameBox.setPrefWidth(100);
        nameBox.onAction(new Callback<ActionEvent>() {
            public void call(ActionEvent actionEvent) throws Exception {
                if(manager.propMan.isClassAvailable(SNode.class)) {
                    PropertyManager.Property prop = manager.propMan.getProperty("id");
                    prop.setValue(nameBox.getText());
                }
            }
        });
        defaultProperties.add(nameBox,1);

        shapeProperties = new HFlexBox().setBoxAlign(HFlexBox.Align.Baseline);
        add(shapeProperties);
        shapeProperties.setVisible(false);

        fillButton = new FillPicker(this.manager);
        fillButton.setContext(context);
        EventBus.getSystem().addListener(fillButton,ChangedEvent.ObjectChanged, fillButtonCallback);

        strokeColorButton = new SwatchColorPicker();
        EventBus.getSystem().addListener(ChangedEvent.ColorChanged, colorChangeCallback);
        shapeProperties.add(fillButton);
        shapeProperties.add(strokeColorButton);


        setupShadowProperties();

        strokeWidthSlider = new Slider(false);
        strokeWidthSlider.setMin(0);
        strokeWidthSlider.setMax(20);
        strokeWidthSlider.setValue(3);
        EventBus.getSystem().addListener(strokeWidthSlider, ChangedEvent.DoubleChanged, strokeWidthCallback);
        strokeWidthLabel = new Label(getString("toolbar.stroke")+": " + 3);
        shapeProperties.add(strokeWidthLabel);
        shapeProperties.add(strokeWidthSlider);

        fillOpacitySlider = new Slider(false).setMin(0).setMax(100).setValue(100);
        EventBus.getSystem().addListener(fillOpacitySlider, ChangedEvent.DoubleChanged, fillOpacityCallback);
        fillOpacityLabel = new Label(getString("toolbar.opacity")+": "+df.format(0));
        shapeProperties.add(fillOpacityLabel);
        shapeProperties.add(fillOpacitySlider);





        fontProperties = new HFlexBox().setBoxAlign(HFlexBox.Align.Baseline);
        add(fontProperties);

        fontSizeLabel = new Label(getString("toolbar.fontSize")+":");
        fontProperties.add(fontSizeLabel);

        fontSizeSlider = new Slider(false);
        fontSizeSlider.setMin(8);
        fontSizeSlider.setMax(500);
        fontSizeSlider.setValue(24);
        EventBus.getSystem().addListener(fontSizeSlider, ChangedEvent.DoubleChanged, fontSizeCallback);
        fontProperties.add(fontSizeSlider);

        fontPicker = new PopupMenuButton<String>();
        fontPicker.setModel(new ListModel<String>() {
            public String get(int i) {
                return Main.getDatabase().getAllFonts().get(i).getName();
            }

            public int size() {
                return Main.getDatabase().getAllFonts().size();
            }
        });
        EventBus.getSystem().addListener(fontPicker, SelectionEvent.Changed, new Callback<SelectionEvent>(){
            public void call(SelectionEvent event) {
                if(manager.propMan.isClassAvailable(SText.class)) {
                    int index = event.getView().getSelectedIndex();
                    String fontname = Main.getDatabase().getAllFonts().get(index).getName();
                    manager.propMan.getProperty("fontName").setValue(fontname);
                    context.redraw();
                }
            }
        });
        fontProperties.add(fontPicker);

        fontBoldButton = new Togglebutton("B");
        fontBoldButton.onClicked(fontBoldCallback);
        fontProperties.add(fontBoldButton);

        fontItalicButton = new Togglebutton("I");
        fontItalicButton.onClicked(fontItalicCallback);
        fontProperties.add(fontItalicButton);

        fontAlignLeft = new TIB("cr22-action-text_left.png", new SAction(){
            @Override
            public void execute() throws Exception {
                if(manager.propMan.isClassAvailable(SText.class)) {
                    manager.propMan.getProperty("halign").setValue(SText.HAlign.Left);
                }
            }
        });
        fontAlignHCenter = new TIB("cr22-action-text_center.png", new SAction(){
            @Override
            public void execute() throws Exception {
                if(manager.propMan.isClassAvailable(SText.class)) {
                    manager.propMan.getProperty("halign").setValue(SText.HAlign.Center);
                }
            }
        });
        fontAlignRight = new TIB("cr22-action-text_right.png", new SAction(){
            @Override
            public void execute() throws Exception {
                if(manager.propMan.isClassAvailable(SText.class)) {
                    manager.propMan.getProperty("halign").setValue(SText.HAlign.Right);
                }
            }
        });
        fontProperties.add(fontAlignLeft,fontAlignHCenter,fontAlignRight);
        fontAlignGroup = new ToggleGroup();
        fontAlignGroup.add(fontAlignLeft).add(fontAlignHCenter).add(fontAlignRight);
        fontAlignGroup.setSelectedButton(fontAlignLeft);
        EventBus.getSystem().addListener(fontAlignGroup, ActionEvent.Action, new Callback<ActionEvent>(){
            public void call(ActionEvent actionEvent) throws Exception {
                if(manager.propMan.isClassAvailable(SText.class)) {
                    if(fontAlignGroup.getSelectedButton() == fontAlignLeft) {
                        manager.propMan.getProperty("halign").setValue(SText.HAlign.Left);
                    }
                    if(fontAlignGroup.getSelectedButton() == fontAlignHCenter) {
                        manager.propMan.getProperty("halign").setValue(SText.HAlign.Center);
                    }
                    if(fontAlignGroup.getSelectedButton() == fontAlignRight) {
                        manager.propMan.getProperty("halign").setValue(SText.HAlign.Right);
                    }
                    context.redraw();
                }
            }
        });

        fontWrap = new Checkbox("wrap");
        fontWrap.onClicked(new Callback<ActionEvent>() {
            public void call(ActionEvent event) throws Exception {
                if(manager.propMan.isClassAvailable(SText.class)) {
                    manager.propMan.getProperty("wrapText").setValue(fontWrap.isSelected());
                    context.redraw();
                }
            }
        });
        fontProperties.add(fontWrap);

        arrowHeadEnd = new PopupMenuButton<SArrow.HeadEnd>();
        arrowHeadEnd.setModel(ListView.createModel(SArrow.HeadEnd.values()));
        add(arrowHeadEnd);
        arrowHeadEnd.setVisible(false);
        EventBus.getSystem().addListener(arrowHeadEnd, SelectionEvent.Changed, arrowHeadCallback);


        groupPropertiesEditor = new HFlexBox()
                .add(new IB("align-horizontal-left.png", new NodeActions.AlignLeft(context)))
                .add(new IB("align-horizontal-center.png", new NodeActions.AlignCenterH(context)))
                .add(new IB("align-horizontal-right.png", new NodeActions.AlignRight(context)))
                .add(new IB("align-vertical-bottom.png", new NodeActions.AlignBottom(context)))
                .add(new IB("align-vertical-center.png", new NodeActions.AlignCenterV(context)))
                .add(new IB("align-vertical-top.png", new NodeActions.AlignTop(context)))
                ;
        add(groupPropertiesEditor);
        groupPropertiesEditor.setVisible(false);
        booleanPropsEditor = new HFlexBox()
                .add(new Button(getString("menus.add")).onClicked(new Callback<ActionEvent>() {
                    public void call(ActionEvent actionEvent) throws Exception {
                        new BooleanGeometry.Union(context).execute();
                    }
                }))
                .add(new Button(getString("menus.subtract")).onClicked(new Callback<ActionEvent>() {
                    public void call(ActionEvent actionEvent) throws Exception {
                        new BooleanGeometry.Subtract(context).execute();
                    }
                }))
                .add(new Button(getString("menus.intersection")).onClicked(new Callback<ActionEvent>() {
                    public void call(ActionEvent actionEvent) throws Exception {
                        new BooleanGeometry.Intersection(context).execute();
                    }
                }))
        ;
        add(booleanPropsEditor);
        booleanPropsEditor.setVisible(false);

        this.setBoxAlign(Align.Left);
        setVisible(false);

    }

    private void setupShadowProperties() {
        shadowProperties = new GridBox();
        shadowProperties.debug(false);
        shadowProperties.setPrefWidth(350);
        shadowProperties.setPrefHeight(100);
        shadowProperties.setPadding(1);
        shadowProperties.createColumn(70,GridBox.Align.Right);
        shadowProperties.createColumn(60,GridBox.Align.Left);
        shadowProperties.createColumn(60,GridBox.Align.Left);
        shadowProperties.createColumn(30,GridBox.Align.Right);
        shadowProperties.createColumn(60,GridBox.Align.Left);
        shadowProperties.createColumn(30,GridBox.Align.Left);
        add(shadowProperties);
        shadowProperties.setVisible(false);

        shadowSet = new Checkbox("shadow");
        EventBus.getSystem().addListener(shadowSet, ActionEvent.Action, new Callback<ActionEvent>(){
            public void call(ActionEvent actionEvent) throws Exception {
                if(selection != null) {
                    if(manager.propMan.isClassAvailable(SShape.class)) {
                        if(shadowSet.isSelected()) {
                            manager.propMan.getProperty("shadow").setValue(new DropShadow());
                        } else {
                            manager.propMan.getProperty("shadow").setValue(null);
                        }
                        context.redraw();
                    }
                }
            }
        });
        shadowProperties.addControl(shadowSet);
        /*
        shadowInner = new Checkbox("inner");
        EventBus.getSystem().addListener(shadowInner, ActionEvent.Action, new Callback<ActionEvent>(){
            public void call(ActionEvent actionEvent) throws Exception {
                if(selection != null) {
                    if(manager.propMan.isClassAvailable(SShape.class)) {
                        DropShadow shad = (DropShadow) manager.propMan.getProperty("shadow").getValue();
                        if(shad !=  null) {
                            shad.setInner(shadowInner.isSelected());
                        }
                        manager.propMan.getProperty("shadow").setValue(shad);
                        context.redraw();
                    }
                }
            }
        });
        */
        //shadowProperties.addControl(shadowInner);
        shadowProperties.nextRow();


        shadowProperties.addControl(new Label("Offset:"));
        shadowXoff = new SpinBox<Double>()
            .setValue(5.0);
        shadowProperties.addControl(shadowXoff);
        shadowXoff.onChanged(new Callback<ChangedEvent>(){
            public void call(ChangedEvent event) throws Exception {
                if(manager.propMan.isPropertyNotNull("shadow")) {
                    if(manager.propMan.isClassAvailable(SShape.class)) {
                        double v = (Double)event.getValue();
                        DropShadow shadow = (DropShadow) manager.propMan.getProperty("shadow").getValue();
                        shadow = shadow.setXOffset(v);
                        manager.propMan.getProperty("shadow").setValue(shadow);
                        context.redraw();
                    }
                }
            }
        });


        shadowYoff = new SpinBox<Double>()
            .setValue(5.0);
        shadowYoff.onChanged(new Callback<ChangedEvent>(){
            public void call(ChangedEvent event) throws Exception {
                if(manager.propMan.isPropertyNotNull("shadow")) {
                    if(manager.propMan.isClassAvailable(SShape.class)) {
                        double v = (Double)event.getValue();
                        DropShadow shadow = (DropShadow) manager.propMan.getProperty("shadow").getValue();
                        shadow = shadow.setYOffset(v);
                        manager.propMan.getProperty("shadow").setValue(shadow);
                        context.redraw();
                    }
                }
            }
        });
        shadowProperties.addControl(shadowYoff);

        shadowProperties.addControl(new Label("Blur:"));
        shadowBlurRadius = new SpinBox<Integer>()
            .setMinValue(0)
            .setMaxValue(20)
            .setValue(3);
        shadowBlurRadius.onChanged(new Callback<ChangedEvent>(){
            public void call(ChangedEvent event) throws Exception {
                if(manager.propMan.isPropertyNotNull("shadow")) {
                    if(manager.propMan.isClassAvailable(SShape.class)) {
                        int v = (Integer)event.getValue();
                        DropShadow shadow = (DropShadow) manager.propMan.getProperty("shadow").getValue();
                        shadow = shadow.setBlurRadius(v);
                        manager.propMan.getProperty("shadow").setValue(shadow);
                        context.redraw();
                    }
                }
            }
        });
        shadowProperties.addControl(shadowBlurRadius);
        shadowColorButton = new SwatchColorPicker();
        shadowProperties.addControl(shadowColorButton);
        shadowProperties.nextRow();
        shadowProperties.addControl(new Label("opacity"));
        shadowOpacity = new Slider(false).setMin(0).setMax(100).setValue(100);
        EventBus.getSystem().addListener(shadowOpacity, ChangedEvent.DoubleChanged, new Callback<ChangedEvent>(){
            public void call(ChangedEvent event) throws Exception {
                if(manager.propMan.isPropertyNotNull("shadow")) {
                    if(manager.propMan.isClassAvailable(SShape.class)) {
                        double v = (Double)event.getValue();
                        DropShadow shadow = (DropShadow) manager.propMan.getProperty("shadow").getValue();
                        shadow = shadow.setOpacity(v/100);
                        manager.propMan.getProperty("shadow").setValue(shadow);
                        context.redraw();
                    }
                }
            }
        });
        shadowProperties.addControl(shadowOpacity);
    }

    public void hidePopups() {
        fillButton.hidePopups();
    }

    private static class IB extends ToolbarButton {
        private SAction action;

        private IB(String s, SAction act) throws IOException {
            super(Main.class.getResource("resources/"+s));
            this.selectable = false;
            this.action = act;
            onClicked(new Callback<ActionEvent>(){
                public void call(ActionEvent actionEvent) throws Exception {
                    action.execute();
                }
            });
        }

        @Override
        public void draw(GFX g) {
            g.setPaint(FlatColor.WHITE);
            g.fillRect(0,0,getWidth(),getHeight());
            //g.setPaint(FlatColor.BLACK);
            //g.drawRect(0,0,getWidth(),getHeight());

            g.drawImage(icon,0,0);
        }
    }

    private static class TIB extends ToolbarButton {
        private SAction action;

        private TIB(String s, SAction act) throws IOException {
            super(Main.class.getResource("resources/"+s));
            this.selectable = true;
            this.action = act;
            onClicked(new Callback<ActionEvent>(){
                public void call(ActionEvent actionEvent) throws Exception {
                    action.execute();
                }
            });
        }

        @Override
        public void draw(GFX g) {
            if(this.isSelected()) {
                g.setPaint(FlatColor.BLACK);
            } else {
                g.setPaint(FlatColor.WHITE);
            }
            g.fillRect(0,0,getWidth(),getHeight());
            //g.setPaint(FlatColor.BLACK);
            //g.drawRect(0,0,getWidth(),getHeight());

            g.drawImage(icon,0,0);
        }
    }


    private void updatePanelContents() {
        locked = true;
        SNode lastNode = null;
        for(SNode node : selection.items()) {
            lastNode = node;
        }

        if(manager.propMan.isClassAvailable(SNode.class)) {
            String id = (String) manager.propMan.getProperty("id").getValue();
            if(id == null){
                nameBox.setText("");
            } else {
                nameBox.setText(id);
            }
        }

        if(manager.propMan.isClassAvailable(SText.class)) {
            fontProperties.setVisible(true);
            double dval = manager.propMan.getProperty("fontSize").getDoubleValue();
            if(selection.size() == 1) {
                fontSizeSlider.setValue(dval);
            }
            PropertyManager.Property wrapText = manager.propMan.getProperty("wrapText");
            if(wrapText.hasSingleValue()) {
                fontWrap.setSelected(wrapText.getBooleanValue());
            }
        } else {
            fontProperties.setVisible(false);
        }

        if(manager.propMan.isClassAvailable(SArrow.class)) {
            arrowHeadEnd.setVisible(true);
        } else {
            arrowHeadEnd.setVisible(false);
        }

        if(manager.propMan.isClassAvailable(SShape.class)) {
            shapeProperties.setVisible(true);

            //shadow properties
            shadowProperties.setVisible(true);
            if(lastNode != null) {
                if(manager.propMan.isPropertyNotNull("shadow")) {
                    shadowSet.setSelected(true);
                    DropShadow shad = (DropShadow) manager.propMan.getProperty("shadow").getValue();
                    shadowXoff.setValue(shad.getXOffset());
                    shadowYoff.setValue(shad.getYOffset());
                    shadowBlurRadius.setValue(shad.getBlurRadius());
                    shadowColorButton.setSelectedColor(shad.getColor());
                    //shadowInner.setSelected(shad.isInner());
                    shadowOpacity.setValue(shad.getOpacity()*100);
                } else {
                    shadowSet.setSelected(false);
                }
            }
        } else {
            shapeProperties.setVisible(false);
            shadowProperties.setVisible(false);
        }
        //fill property
        if(manager.propMan.isClassAvailable(SShape.class)) {
            if(manager.propMan.getProperty("fillPaint").hasSingleValue()) {
                Paint fill = (Paint) manager.propMan.getProperty("fillPaint").getValue();
                fillButton.setSelectedFill(fill);
            }
        }

        //stroke properties
        if(manager.propMan.isClassAvailable(SShape.class) ||
            manager.propMan.isClassAvailable(SImage.class)) {
            strokeColorButton.setVisible(true);
            strokeWidthSlider.setVisible(true);
            strokeWidthLabel.setVisible(true);
            if(lastNode != null) {
                PropertyManager.Property strokeProp = manager.propMan.getProperty("strokeWidth");
                if(strokeProp.hasSingleValue()) {
                    strokeWidthSlider.setValue(strokeProp.getDoubleValue());
                }
                PropertyManager.Property strokeColorProp = manager.propMan.getProperty("strokePaint");
                if(strokeColorProp.hasSingleValue()) {
                    strokeColorButton.setSelectedColor((FlatColor)strokeColorProp.getValue());
                }
            }
        } else {
            strokeColorButton.setVisible(false);
            strokeWidthSlider.setVisible(false);
            strokeWidthLabel.setVisible(false);
        }

        groupPropertiesEditor.setVisible(selection.size()>1);
        booleanPropsEditor.setVisible(selection.size()>1 && manager.propMan.isClassAvailable(SShape.class));

        setLayoutDirty();
        Core.getShared().defer(new Runnable() {
            public void run() {
                locked = false;
            }
        });
    }


    @Override
    protected void drawSelf(GFX g) {
        double h = getHeight();
        g.setPaint(new FlatColor(0.8,0.8,0.8,0.8));
        g.fillRoundRect(0,0,getWidth()-1,h-1,10,10);
        g.setPaint(new FlatColor(0.3,0.3,0.3,0.8));
        g.drawRoundRect(0,0,getWidth()-1,h-1,10,10);
    }

    @Override
    public void doLayout() {
        if(selected) {
            Bounds bounds = selection.calculateBounds();
            bounds = context.getSketchCanvas().transformToDrawing(bounds);
            bounds = NodeUtils.convertToScene(context.getSketchCanvas(),bounds);
            Stage stage = this.getStage();

            double x = bounds.getX();
            double y = bounds.getY() + bounds.getHeight()+20;
            double h = stage.getContent().getVisualBounds().getHeight();
            double w = stage.getContent().getVisualBounds().getWidth();
            double bottom = y + this.getHeight();

            //if to low then put above the item
            if(bottom > h-140) {
                //the 130 above is to account for the height of the fill picker
                y = bounds.getY()-this.getHeight()-20;
            }
            //if off the top now, then move to the right
            if (y < 0) {
                y = 10;
                x = bounds.getX2() + 20;
            }

            //if off the right then move to the left
            if(x + this.getWidth() > w) {
                x = bounds.getX()-this.getWidth()-20;
            }

            //if too far off the left then just shove on the left edge and accept it will overlap
            if(x < 0) {
                x = 20;
            }


            setTranslateX(x);
            setTranslateY(y);

            super.doLayout();
        }
    }

    @Override
    public void setVisible(boolean visible) {
        super.setVisible(visible);
        setLayoutDirty();
    }

    Callback<Selection.SelectionChangeEvent> selectionCallback = new Callback<Selection.SelectionChangeEvent>() {
        public void call(Selection.SelectionChangeEvent event) throws Exception {
            //only pay attention to events for our own context doc
            if(event.getSelection().getDocument() != context.getDocument()) return;
            if(!manager.propMan.isClassAvailable(SNode.class)) return;
            if(manager.propMan.isClassAvailable(STransformNode.class)) {
                setVisible(false);
            }
            selected = !event.getSelection().isEmpty();
            selection = event.getSelection();
            updatePanelContents();
            setDrawingDirty();
            setLayoutDirty();
        }
    };

    Callback<ChangedEvent> fillButtonCallback = new Callback<ChangedEvent>() {
        public void call(ChangedEvent event) throws Exception {
            if(locked) return;
            if(event.getSource() == fillButton) {
                Paint color = (Paint) event.getValue();
                if(manager.propMan.isClassAvailable(SShape.class)) {
                    setFillStuff(color);
                    Selection sel = context.getSelection();
                    if(sel.size() == 1){
                        sel.regenHandles(sel.firstItem());
                    }
                }
                context.redraw();
            }

        }
    };

    SwatchColorPicker.ColorCallback colorCallback = new SwatchColorPicker.ColorCallback() {
        public FlatColor call(MouseEvent event) {
            SketchDocument doc = context.getDocument();
            Stage stage = context.getSketchCanvas().getParent().getStage();
            Point2D point = event.getPointInScreenCoords();
            point = new Point2D.Double(point.getX()-stage.getX(),point.getY()-stage.getY());
            point = NodeUtils.convertFromScene(context.getCanvas(), point);
            if(rgbLabel == null) {
                rgbLabel = new Label("RGB");
                rgbLabel.setId("rgblabel");
                stage.getPopupLayer().add(rgbLabel);
                rgbLabel.setTranslateX(100);
                rgbLabel.setTranslateY(100);
            }
            rgbLabel.setVisible(true);
            Point2D dx = event.getPointInScreenCoords();

            rgbLabel.setTranslateX(dx.getX()-stage.getX()+70);
            rgbLabel.setTranslateY(dx.getY()-stage.getY());
            for(SNode node : doc.getCurrentPage().getNodes()) {
                if(node.contains(point) && node instanceof SShape) {
                    FlatColor color =  (FlatColor) ((SShape)node).getFillPaint();
                    int val = color.getRGBA();
                    val = val & 0x00FFFFFF;
                    rgbLabel.setText("RGB: " + Integer.toHexString(val).toUpperCase());
                    return color;
                }
            }
            rgbLabel.setText("RGB: ------");
            return FlatColor.BLUE;
        }
    };

    private Callback<? extends Event> colorChangeCallback = new Callback<ChangedEvent>() {
        public void call(ChangedEvent event) {
            if(locked) return;
            if(event.getSource() == strokeColorButton) {
                if(manager.propMan.isClassAvailable(SShape.class) ||
                        manager.propMan.isClassAvailable(SImage.class)) {
                    setPropertyWithUndo("strokePaint", event.getValue());
                    context.redraw();
                }
            }
            if(event.getSource() == shadowColorButton) {
                if(manager.propMan.isClassAvailable(SShape.class)) {
                    DropShadow shadow = (DropShadow) manager.propMan.getProperty("shadow").getValue();
                    if(shadow != null) {
                        shadow = shadow.setColor(shadowColorButton.getSelectedColor());
                        manager.propMan.getProperty("shadow").setValue(shadow);
                        context.redraw();
                    }
                }
            }
        }
    };

    private void setFillStuff(Paint paint) {
        if(paint instanceof RadialGradientFill) {
            RadialGradientFill grad = (RadialGradientFill) paint.duplicate();
            SShape shape = (SShape) context.getSelection().firstItem();
            Bounds bounds = shape.getTransformedBounds();
            grad.setCenterX(bounds.getWidth()/2);
            grad.setCenterY(bounds.getWidth()/2);
            grad.setRadius(Math.min(bounds.getWidth()/2,bounds.getHeight()/2));
            setPropertyWithUndo("fillPaint",grad);
            return;
        }
        if(paint instanceof LinearGradientFill) {
            LinearGradientFill grad = (LinearGradientFill) paint.duplicate();
            SShape shape = (SShape) context.getSelection().firstItem();
            Bounds bounds = shape.getTransformedBounds();
            switch(grad.getStartXSnapped()) {
                case Start:  grad.setStartX(0); break;
                case Middle: grad.setStartX(bounds.getWidth()/2); break;
                case End:    grad.setStartX(bounds.getWidth()); break;
            }
            switch(grad.getEndXSnapped()) {
                case Start:  grad.setEndX(0); break;
                case Middle: grad.setEndX(bounds.getWidth()/2); break;
                case End:    grad.setEndX(bounds.getWidth()); break;
            }
            switch(grad.getStartYSnapped()) {
                case Start:  grad.setStartY(0); break;
                case Middle: grad.setStartY(bounds.getHeight()/2); break;
                case End:    grad.setStartY(bounds.getHeight()); break;
            }
            switch(grad.getEndYSnapped()) {
                case Start:  grad.setEndY(0); break;
                case Middle: grad.setEndY(bounds.getHeight()/2); break;
                case End:    grad.setEndY(bounds.getHeight()); break;
            }
            setPropertyWithUndo("fillPaint",grad);
            return;
        }
        //if just a normal color
        paint = paint.duplicate();
        setPropertyWithUndo("fillPaint", paint);
    }

    private Callback<ChangedEvent> fillOpacityCallback = new Callback<ChangedEvent>() {
        public void call(ChangedEvent event) throws Exception {
            if(selection != null) {
                if(manager.propMan.isClassAvailable(SShape.class)) {
                    double v = (Double)event.getValue();
                    setPropertyWithUndo("fillOpacity", v / 100.0);
                    manager.propMan.getProperty("fillOpacity").setValue(v/100.0);
                    fillOpacityLabel.setText(getString("toolbar.opacity")+": "+df.format(v/100.0));
                    context.redraw();
                }
            }
        }
    };

    private Callback<ChangedEvent> fontSizeCallback = new Callback<ChangedEvent>() {
        public void call(ChangedEvent event) throws Exception {
            if(selection != null) {
                for(SNode node: selection.items()) {
                    if(node instanceof SText) {
                        SText text = (SText) node;
                        text.setFontSize(((Double)event.getValue()));
                        if(fontBoldButton.isSelected()) {
                            text.setWeight(Font.Weight.Bold);
                        } else {
                            text.setWeight(Font.Weight.Regular);
                        }
                    }
                }
                context.redraw();
            }
        }
    };

    private Callback<? extends Event> strokeWidthCallback = new Callback<ChangedEvent>() {
        public void call(ChangedEvent event) {
            if(manager.propMan.isClassAvailable(SShape.class) ||
                    manager.propMan.isClassAvailable(SImage.class)) {
                int sw = (int)((Double)event.getValue()).doubleValue();
                setPropertyWithUndo("strokeWidth", sw);
                strokeWidthLabel.setText(getString("toolbar.stroke")+": " + intFormat.format(sw));
                context.redraw();
            }
        }
    };

    private Callback<ActionEvent> fontBoldCallback = new Callback<ActionEvent>() {
        public void call(ActionEvent event) {
            if(selection != null) {
                for(SNode node: selection.items()) {
                    if(node instanceof SText) {
                        SText text = (SText) node;
                        if(fontBoldButton.isSelected()) {
                            text.setWeight(Font.Weight.Bold);
                        } else {
                            text.setWeight(Font.Weight.Regular);
                        }
                    }
                }
                context.redraw();
            }

        }
    };

    private Callback<ActionEvent> fontItalicCallback = new Callback<ActionEvent>() {
        public void call(ActionEvent event) {
            if(selection != null) {
                for(SNode node: selection.items()) {
                    if(node instanceof SText) {
                        SText text = (SText) node;
                        if(fontItalicButton.isSelected()) {
                            text.setStyle(Font.Style.Italic);
                        } else {
                            text.setStyle(Font.Style.Regular);
                        }
                    }
                }
                context.redraw();
            }
        }
    };

    private Callback<? extends Event> arrowHeadCallback = new Callback<SelectionEvent>() {
        public void call(SelectionEvent event) {
            if(manager.propMan.isClassAvailable(SArrow.class)) {
                int index = event.getView().getSelectedIndex();
                manager.propMan.getProperty("headEnd").setValue(SArrow.HeadEnd.values()[index]);
            }
        }
    };

    private void setPropertyWithUndo(final String propName, final Object newValue) {
        //u.p("maybe appending undo action: " + propName + " " + newValue);
        final PropertyManager.Property prop = manager.propMan.getProperty(propName);
        if(prop.hasSingleValue()) {
            //u.p("prop = " + prop.getValue());
            //u.p("new value = " + newValue);

            Object curValue = prop.getValue();
            if(curValue != null && newValue != null) {
                //u.p("setting a new value that is the same as the old value");
                if(curValue instanceof Number && newValue instanceof Number) {
                    Number n1 = (Number) curValue;
                    Number n2 = (Number) newValue;
                    if(Math.abs(n1.doubleValue() - n2.doubleValue()) < 0.01) {
                        //u.p("close enough. not adding to the undo");
                        return;
                    }
                }
            }

            //undo single value
            UndoManager.UndoableAction previousUndo = context.getUndoManager().getLastAction();
            if(previousUndo != null &&
                    previousUndo instanceof SingleValuePropertyUndo &&
                    ((SingleValuePropertyUndo)previousUndo).propName.equals(propName)) {
                //u.p("we can coallate");
                SingleValuePropertyUndo svpu = (SingleValuePropertyUndo) previousUndo;
                svpu.newValue = newValue;
            } else {
                final Object oldValue = prop.getValue();
                SingleValuePropertyUndo undo = new SingleValuePropertyUndo(prop, oldValue, propName, newValue);
                context.getUndoManager().pushAction(undo);
            }

        } else {
            //undo differing values
            //u.p("appending undo for differing values");
            final Map<SNode,Object> oldValues = prop.getValues();
            context.getUndoManager().pushAction(new UndoManager.UndoableAction() {
                public void executeUndo() {
                    for(SNode node : oldValues.keySet()) {
                        //u.p("setting " + propName + " value to : " + oldValues.get(node));
                        prop.setValue(node, oldValues.get(node));
                    }
                    context.redraw();
                }

                public void executeRedo() {
                    context.redraw();
                }

                public String getName() {
                    return "changed " + propName;
                }
            });
        }
        prop.setValue(newValue);
    }

    private class SingleValuePropertyUndo implements UndoManager.UndoableAction {
        private final PropertyManager.Property prop;
        private final Object oldValue;
        private final String propName;
        private Object newValue;

        public SingleValuePropertyUndo(PropertyManager.Property prop, Object oldValue, String propName, Object newValue) {
            this.prop = prop;
            this.oldValue = oldValue;
            this.propName = propName;
            this.newValue = newValue;
        }

        public void executeUndo() {
            prop.setValue(oldValue);
            //u.p("undoing a single value set of : " + propName + " to " + oldValue);
            context.redraw();
        }

        public void executeRedo() {
            //u.p("redoing a single value set of " + propName + " to " + newValue);
            prop.setValue(newValue);
            context.redraw();
        }

        public String getName() {
            return "changed " + propName;
        }
    }
}
TOP

Related Classes of org.joshy.sketch.controls.FloatingPropertiesPanel$TIB

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
m.parentNode.insertBefore(a,m) })(window,document,'script','//www.google-analytics.com/analytics.js','ga'); ga('create', 'UA-20639858-1', 'auto'); ga('send', 'pageview');