Package com.cburch.logisim.comp

Source Code of com.cburch.logisim.comp.TextFieldCaret

/* Copyright (c) 2010, Carl Burch. License information is located in the
* com.cburch.logisim.Main source code and at www.cburch.com/logisim/. */

package com.cburch.logisim.comp;

import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics;
import java.awt.event.InputEvent;
import java.awt.event.KeyEvent;
import java.awt.event.MouseEvent;
import java.util.ArrayList;
import java.util.LinkedList;

import com.cburch.logisim.data.Bounds;
import com.cburch.logisim.tools.Caret;
import com.cburch.logisim.tools.CaretEvent;
import com.cburch.logisim.tools.CaretListener;

class TextFieldCaret implements Caret, TextFieldListener {
    private LinkedList<CaretListener> listeners = new LinkedList<CaretListener>();
    private TextField field;
    private Graphics g;
    private String oldText;
    private String curText;
    private int pos;

    public TextFieldCaret(TextField field, Graphics g, int pos) {
        this.field = field;
        this.g = g;
        this.oldText = field.getText();
        this.curText = field.getText();
        this.pos = pos;

        field.addTextFieldListener(this);
    }
    public TextFieldCaret(TextField field, Graphics g, int x, int y) {
        this(field, g, 0);
        moveCaret(x, y);
    }

    @Override
    public void addCaretListener(CaretListener l) {
        listeners.add(l);
    }

    @Override
    public void removeCaretListener(CaretListener l) {
        listeners.remove(l);
    }

    @Override
    public String getText() { return curText; }

    @Override
    public void commitText(String text) {
        curText = text;
        pos = curText.length();
        field.setText(text);
    }

    @Override
    public void draw(Graphics g) {
        if (field.getFont() != null) {
            g.setFont(field.getFont());
        }


        // draw boundary
        Bounds bds = getBounds(g);
        g.setColor(Color.white);
        g.fillRect(bds.getX(), bds.getY(),
                bds.getWidth(), bds.getHeight());
        g.setColor(Color.black);
        g.drawRect(bds.getX(), bds.getY(),
                bds.getWidth(), bds.getHeight());

        // draw text
        int x = field.getX();
        int y = field.getY();
        FontMetrics fm = g.getFontMetrics();
        int width = fm.stringWidth(curText);
        int ascent = fm.getAscent();
        int descent = fm.getDescent();
        switch (field.getHAlign()) {
            case TextField.H_CENTER:    x -= width / 2; break;
            case TextField.H_RIGHT:  x -= width; break;
            default:                    break;
        }
        switch (field.getVAlign()) {
            case TextField.V_TOP:      y += ascent; break;
            case TextField.V_CENTER:    y += (ascent - descent) / 2; break;
            case TextField.V_BOTTOM:    y -= descent; break;
            default:                    break;
        }
        g.drawString(curText, x, y);

        // draw cursor
        if (pos > 0) {
            x += fm.stringWidth(curText.substring(0, pos));
        }

        g.drawLine(x, y, x, y - ascent);
    }

    @Override
    public Bounds getBounds(Graphics g) {
        int x = field.getX();
        int y = field.getY();
        Font font = field.getFont();
        FontMetrics fm;
        if (font == null) {
              fm = g.getFontMetrics();
        }

        else {
                           fm = g.getFontMetrics(font);
        }

        int width = fm.stringWidth(curText);
        int ascent = fm.getAscent();
        int descent = fm.getDescent();
        int height = ascent + descent;
        switch (field.getHAlign()) {
            case TextField.H_CENTER:    x -= width / 2; break;
            case TextField.H_RIGHT:  x -= width; break;
            default:                    break;
        }
        switch (field.getVAlign()) {
            case TextField.V_TOP:      y += ascent; break;
            case TextField.V_CENTER:    y += (ascent - descent) / 2; break;
            case TextField.V_BOTTOM:    y -= descent; break;
            default:                    break;
        }
        return Bounds.create(x, y - ascent, width, height)
                .add(field.getBounds(g))
                .expand(3);
    }

    @Override
    public void cancelEditing() {
        CaretEvent e = new CaretEvent(this, oldText, oldText);
        curText = oldText;
        pos = curText.length();
        for (CaretListener l : new ArrayList<CaretListener>(listeners)) {
            l.editingCanceled(e);
        }
        field.removeTextFieldListener(this);
    }

    @Override
    public void stopEditing() {
        CaretEvent e = new CaretEvent(this, oldText, curText);
        field.setText(curText);
        for (CaretListener l : new ArrayList<CaretListener>(listeners)) {
            l.editingStopped(e);
        }
        field.removeTextFieldListener(this);
    }

    @Override
    public void mousePressed(MouseEvent e) {
        //TODO: enhance label editing
        moveCaret(e.getX(), e.getY());
    }

    @Override
    public void mouseDragged(MouseEvent e) {
        //TODO: enhance label editing
    }

    @Override
    public void mouseReleased(MouseEvent e) {
        //TODO: enhance label editing
        moveCaret(e.getX(), e.getY());
    }

    @Override
    public void keyPressed(KeyEvent e) {
        int ign = InputEvent.ALT_MASK | InputEvent.CTRL_MASK
            | InputEvent.META_MASK;
        if ((e.getModifiers() & ign) != 0) {
            return;
        }

        switch (e.getKeyCode()) {
        case KeyEvent.VK_LEFT:
        case KeyEvent.VK_KP_LEFT:
            if (pos > 0) {
                --pos;
            }

            break;
        case KeyEvent.VK_RIGHT:
        case KeyEvent.VK_KP_RIGHT:
            if (pos < curText.length()) {
                ++pos;
            }

            break;
        case KeyEvent.VK_HOME:
            pos = 0;
            break;
        case KeyEvent.VK_END:
            pos = curText.length();
            break;
        case KeyEvent.VK_ESCAPE:
        case KeyEvent.VK_CANCEL:
            cancelEditing();
            break;
        case KeyEvent.VK_CLEAR:
            curText = "";
            pos = 0;
            break;
        case KeyEvent.VK_ENTER:
            stopEditing();
            break;
        case KeyEvent.VK_BACK_SPACE:
            if (pos > 0) {
                curText = curText.substring(0, pos - 1)
                    + curText.substring(pos);
                --pos;
            }
            break;
        case KeyEvent.VK_DELETE:
            if (pos < curText.length()) {
                curText = curText.substring(0, pos)
                    + curText.substring(pos + 1);
            }
            break;
        case KeyEvent.VK_INSERT:
        case KeyEvent.VK_COPY:
        case KeyEvent.VK_CUT:
        case KeyEvent.VK_PASTE:
            //TODO: enhance label editing
            break;
        default:
            // ignore
            ;
        }
    }

    @Override
    public void keyReleased(KeyEvent e) { }

    @Override
    public void keyTyped(KeyEvent e) {
        int ign = InputEvent.ALT_MASK | InputEvent.CTRL_MASK
            | InputEvent.META_MASK;
        if ((e.getModifiers() & ign) != 0) {
            return;
        }


        char c = e.getKeyChar();
        if (c == '\n') {
            stopEditing();
        } else if (c != KeyEvent.CHAR_UNDEFINED
                && !Character.isISOControl(c)) {
            if (pos < curText.length()) {
                curText = curText.substring(0, pos) + c
                    + curText.substring(pos);
            } else {
                curText += c;
            }
            ++pos;
        }
    }

    private void moveCaret(int x, int y) {
        Bounds bds = getBounds(g);
        FontMetrics fm = g.getFontMetrics();
        x -= bds.getX();
        int last = 0;
        for (int i = 0; i < curText.length(); i++) {
            int cur = fm.stringWidth(curText.substring(0, i + 1));
            if (x <= (last + cur) / 2) {
                pos = i;
                return;
            }
            last = cur;
        }
        pos = curText.length();
    }

    @Override
    public void textChanged(TextFieldEvent e) {
        curText = field.getText();
        oldText = curText;
        pos = curText.length();
    }
}
TOP

Related Classes of com.cburch.logisim.comp.TextFieldCaret

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.