diff --git a/src/main/java/cit/PureATN/Inspector/DefaultPlugin.java b/src/main/java/cit/PureATN/Inspector/DefaultPlugin.java new file mode 100644 index 0000000..72ddd70 --- /dev/null +++ b/src/main/java/cit/PureATN/Inspector/DefaultPlugin.java @@ -0,0 +1,10 @@ +package cit.PureATN.Inspector; + +import javax.swing.JPopupMenu; + +public class DefaultPlugin { + + public void addMenu(JPopupMenu menu){ + + } +} diff --git a/src/main/java/cit/PureATN/Inspector/InspectorHandler.java b/src/main/java/cit/PureATN/Inspector/InspectorHandler.java new file mode 100644 index 0000000..4433b88 --- /dev/null +++ b/src/main/java/cit/PureATN/Inspector/InspectorHandler.java @@ -0,0 +1,125 @@ +package cit.PureATN.Inspector; + + +import java.awt.Color; +import java.awt.Paint; +import java.util.Hashtable; + +import javax.swing.JFrame; + +import org.piccolo2d.PCanvas; +import org.piccolo2d.PNode; +import org.piccolo2d.event.PBasicInputEventHandler; +import org.piccolo2d.event.PInputEvent; +import org.piccolo2d.nodes.PPath; +import org.piccolo2d.nodes.PText; +import org.piccolo2d.util.PBounds; + +/** + * ATNWindowで右ドラッグしながら青色のズーム範囲矩形を表示し,ズームする機能を実現するクラス + * @author miuramo + * + */ +public class InspectorHandler extends PBasicInputEventHandler { + + PNode pressN; + PInputEvent pressEv = null; + PCanvas canvas; + JFrame frame; + Paint preserveColor = null; + Hashtable preserve; + // public boolean canceled_by_SimpleATN_EnterKey; + JFrame inspectorFrame = null; + InspectorPanel inspectorPanel; + public InspectorHandler(PCanvas _canvas, JFrame _frame) { + canvas = _canvas; + frame = _frame; + preserve = new Hashtable(); + inspectorFrame = createNewFrame_NextTo(frame); + inspectorPanel = new InspectorPanel(inspectorFrame, this); + inspectorFrame.getContentPane().add(inspectorPanel); + inspectorFrame.setTitle("Inspector"); + System.out.println("new Inspector"); + } + public static PBounds getGapPBounds(int x, int y, PBounds pb){ + PBounds newpb = new PBounds(pb.x-x, pb.y-y, pb.width+2*x, pb.height+2*y); + return newpb; + } + public static JFrame createNewFrame_NextTo(JFrame p){ + JFrame jf = new JFrame(); + int w = p.getWidth(); + jf.setLocation(p.getX()+w, p.getY()); + return jf; + } + + public void mouseMoved(PInputEvent ev){ + pressEv = ev; + if (pressN == null) setHilit(pressN); + if (pressN != ev.getPickedNode()){ + resetHilit(pressN); + pressN = ev.getPickedNode(); + setHilit(pressN); + + showClassName(pressN, 1); + } + } + public void showClassName(PNode p, int level){ + if (level == 1) inspectorPanel.pnlist.clear(); + inspectorPanel.pnlist.add(p); + // String nm = p.getClass().getSimpleName(); + String nm = p.getClass().getName(); + if (level>1) System.out.print(" < "); + System.out.print(nm); + PNode parent = p.getParent(); + if (parent != null) showClassName(parent, level+1); + if (level == 1) System.out.println(""); + inspectorPanel.repaint(); + } + public void setHilit(PNode n){ + if (n==null) return; + if (preserve.get(n)==null){ + Paint p = pickColor(n); + if (p==null) { +// System.out.println("NULL"); + return; + } + preserve.put(n, p); + for(Object o: n.getAllNodes().toArray()){ + if (o instanceof PNode){ + ((PNode)o).setPickable(true); + } + } + } + hilitColor(n); + } + public void resetHilit(PNode n){ + if (n==null) return; + Paint p = preserve.get(n); + if (p!=null){ + setColor(n,p); + } + } + public void setColor(PNode n, Paint p){ + if (n instanceof PPath){ + ((PPath)n).setPaint(p); + } else if (n instanceof PText){ + ((PText)n).setTextPaint(p); + } + } + public void hilitColor(PNode n){ + if (n instanceof PPath){ + ((PPath)n).setPaint(Color.yellow); + } else if (n instanceof PText){ + ((PText)n).setTextPaint(Color.yellow); + } + } + public Paint pickColor(PNode n){ + if (n instanceof PPath){ + return ((PPath)n).getPaint(); + } else if (n instanceof PText){ + return ((PText)n).getTextPaint(); + } + return null; + } + +} diff --git a/src/main/java/cit/PureATN/Inspector/InspectorPanel.java b/src/main/java/cit/PureATN/Inspector/InspectorPanel.java new file mode 100644 index 0000000..f332723 --- /dev/null +++ b/src/main/java/cit/PureATN/Inspector/InspectorPanel.java @@ -0,0 +1,78 @@ +package cit.PureATN.Inspector; + +import java.awt.Color; +import java.awt.Graphics; +import java.awt.geom.AffineTransform; +import java.util.ArrayList; + +import javax.swing.JFrame; +import javax.swing.JPanel; + +import org.piccolo2d.PNode; +import org.piccolo2d.event.PInputEventListener; +import org.piccolo2d.nodes.PText; + +import cit.PureATN.ShortStroke; + +public class InspectorPanel extends JPanel { + + private static final long serialVersionUID = 1137383242193843501L; + JFrame jf; + InspectorHandler handler; + ArrayList pnlist = new ArrayList(); + public InspectorPanel(JFrame f, InspectorHandler h){ + jf = f; + handler = h; + } + public void paintComponent(Graphics g){ + g.clearRect(0, 0, getWidth(), getHeight()); + int y = 13; + + for(PNode pn: pnlist){ + g.setColor(Color.black); + g.drawString(pn.getClass().getName()+" "+pn.hashCode(), 10, y); y+=13; + + g.drawString("xy : "+f(pn.getX())+" | "+f(pn.getY()), 20, y); y+=13; + g.drawString("wh : "+f(pn.getWidth())+" | "+f(pn.getHeight()), 20, y); y+=13; + g.setColor(Color.blue); + + g.drawString("offset: "+f(pn.getOffset().getX())+" | "+f(pn.getOffset().getY()), 20, y); y+=13; + g.drawString("zoom: "+f(pn.getScale()), 20, y); y+=13; + AffineTransform at = pn.getTransform(); + double[] d = new double[6]; + at.getMatrix(d); + g.setColor(Color.black); + g.drawString("affine: "+g(d[0])+" "+g(d[2])+" "+g(d[4]), 20, y); y+=13; + g.drawString(" "+g(d[1])+" "+g(d[3])+" "+g(d[5]), 28, y); y+=13; + + g.setColor(Color.green); + for(PInputEventListener pie: pn.getInputEventListeners()){ + if (pie.getClass().getName().length()<1){ + String fullname = pie.getClass().getName(); + int lastdotpos = fullname.lastIndexOf("."); + g.drawString("event: "+fullname.substring(lastdotpos+1), 20, y); y+=13; + } else { + g.drawString("event: "+pie.getClass().getSimpleName(), 20, y); y+=13; + } + } + g.setColor(Color.black); + if (pn instanceof PText){ + g.drawString("text: "+((PText)pn).getText(), 20, y); y+=13; + } + if (pn instanceof ShortStroke){ + ShortStroke ss = (ShortStroke)pn; + g.drawString("gentime: "+ss.getDateTime(), 20, y); y+=13; + } + g.setColor(Color.blue); + g.drawString("children: "+pn.getChildrenCount(), 20, y); y+=13; + + y+=8; + } + } + public String f(double d){ + return String.format("%5.1f", d); + } + public String g(double d){ + return String.format("%4.1f", d); + } +} diff --git a/src/main/java/cit/PureATN/Inspector/InspectorPlugin.java b/src/main/java/cit/PureATN/Inspector/InspectorPlugin.java new file mode 100644 index 0000000..26790c8 --- /dev/null +++ b/src/main/java/cit/PureATN/Inspector/InspectorPlugin.java @@ -0,0 +1,69 @@ +package cit.PureATN.Inspector; + +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; +import java.awt.event.InputEvent; + +import javax.swing.JFrame; +import javax.swing.JMenu; +import javax.swing.JMenuItem; +import javax.swing.JPopupMenu; + +import org.piccolo2d.PCanvas; +import org.piccolo2d.event.PInputEventFilter; + +public class InspectorPlugin extends DefaultPlugin implements ActionListener { + JFrame srcjframe; + InspectorHandler handler; + InspectorPanel panel; + PCanvas canvas; + boolean isActive = false; + public InspectorPlugin(PCanvas can, JFrame f){ + canvas = can; + srcjframe = f; + handler = new InspectorHandler(can, f); + + } + public void setInspectorMode(boolean b) { + if (b){ + handler.setEventFilter(new PInputEventFilter(InputEvent.BUTTON2_MASK)); + canvas.addInputEventListener(handler); + } else { + canvas.removeInputEventListener(handler); + } + handler.inspectorFrame.setVisible(b); + handler.inspectorFrame.setSize(250,600); + MultiDisplay.alineWindow(srcjframe, handler.inspectorFrame, 1, true); + isActive = b; + } + + public void actionPerformed(ActionEvent e){ + System.out.println(e.getActionCommand()); + if (e.getActionCommand().equals("disable")){ + setInspectorMode(false); + } else if (e.getActionCommand().equals("enable")){ + setInspectorMode(true); + } else if (e.getActionCommand().equals("reset inspector window position")){ + MultiDisplay.alineWindow(srcjframe, handler.inspectorFrame, 1, true); + } + } + public void addMenu(JPopupMenu menu){ + JMenu insM; + + insM = new JMenu("Inspector"); + + JMenuItem mi; + + mi = new JMenuItem("reset inspector window position"); + mi.addActionListener(this); + insM.add(mi); + + if (isActive) mi = new JMenuItem("disable"); + else mi = new JMenuItem("enable"); + mi.addActionListener(this); + insM.add(mi); + + + menu.add(insM); + } +} diff --git a/src/main/java/cit/PureATN/Inspector/MultiDisplay.java b/src/main/java/cit/PureATN/Inspector/MultiDisplay.java new file mode 100644 index 0000000..fcb000e --- /dev/null +++ b/src/main/java/cit/PureATN/Inspector/MultiDisplay.java @@ -0,0 +1,119 @@ +package cit.PureATN.Inspector; + +import java.awt.GraphicsConfiguration; +import java.awt.GraphicsDevice; +import java.awt.GraphicsEnvironment; +import java.awt.Rectangle; +import java.util.ArrayList; + +import javax.swing.JFrame; + +public class MultiDisplay { + public static ArrayList getMultiDisplayRectList(){ + ArrayList displaySizeList = new ArrayList(); + + GraphicsDevice[] devices = GraphicsEnvironment.getLocalGraphicsEnvironment().getScreenDevices(); + for(GraphicsDevice gd: devices){ + // System.out.println(gd.getIDstring()); + GraphicsConfiguration gc = gd.getDefaultConfiguration(); + Rectangle rec = gc.getBounds(); + displaySizeList.add(rec); + } + return displaySizeList; + } + + /* 右なら1,下なら3 */ + public static void alineWindow(JFrame base, JFrame target, int direction, boolean isresize){ + int bx = base.getX(); + int by = base.getY(); + int bw = base.getWidth(); + int bh = base.getHeight(); + if (direction==1){ + target.setLocation(bx+bw,by); + if (isresize) target.setSize(target.getWidth(), bh); + } else if (direction==3){ + target.setLocation(bx,by+bh); + if (isresize) target.setSize(bw, target.getHeight()); + } + } + public static void moveWindow(JFrame base, JFrame f, boolean doMoveOnOtherDisplay, boolean fullsize){ + ArrayList dispList = MultiDisplay.getMultiDisplayRectList(); + int findBaseWinDisplay = 0; + int findTargetWinDisplay = 0; + int destinationDisplay = 0; + if (dispList.size()>1){ + for(int i=0;i dispList = MultiDisplay.getMultiDisplayRectList(); + int findBaseWinDisplay = 0; + int destinationDisplay = 0; + if (dispList.size()>1){ + for(int i=0;i dispList = MultiDisplay.getMultiDisplayRectList(); + JMenuItem mi; + if (dispList.size()>1){ + + mi = new JMenuItem("Full on Secondary"); + mi.addActionListener(this); + insM.add(mi); + + mi = new JMenuItem("Normal on Primary"); + mi.addActionListener(this); + insM.add(mi); + + mi = new JMenuItem("Move to Secondary"); + mi.addActionListener(this); + insM.add(mi); + + mi = new JMenuItem("Move to Primary"); + mi.addActionListener(this); + insM.add(mi); + + mi = new JMenuItem("マルチディスプレイの意味について解説を読む"); + mi.addActionListener(new ActionListener(){ + public void actionPerformed(ActionEvent e){ + JOptionPane.showMessageDialog(srcjframe, "ここでの Primary とは,SimpleATN のメインウィンドウが\n" + + "表示されているディスプレイを意味します.\n" + + "\n" + + "メインウィンドウが別のディスプレイに移動すると,Primary は入れ替わります.\n" + + "\n" + + "Windowsのディスプレイ番号は関係ありません."); + } + }); + mi.addActionListener(this); + insM.add(mi); + + } else { + mi = new JMenuItem("Normal"); + mi.addActionListener(this); + insM.add(mi); + + mi = new JMenuItem("Full"); + mi.addActionListener(this); + insM.add(mi); + } + + + menu.add(insM); + } + + //それなりにウィンドウサイズを微調整 + public void relativefit(PBounds tempAfterLayoutBounds) { + double a = tempAfterLayoutBounds.width; + double b = tempAfterLayoutBounds.height; + //現在のウィンドウ面積 + Dimension s = Toolkit.getDefaultToolkit().getScreenSize().getSize(); + double sq = s.getHeight()*s.getWidth()/6; + double r = Math.sqrt(sq)*2; + double w = a*r/(a+b); + double h = b*r/(a+b); + srcjframe.setSize(new Dimension((int)w,(int)h)); + + } +} diff --git a/src/main/java/cit/PureATN/MultiNote/PopupMenu_forMN.java b/src/main/java/cit/PureATN/MultiNote/PopupMenu_forMN.java index 245282e..b14ca16 100644 --- a/src/main/java/cit/PureATN/MultiNote/PopupMenu_forMN.java +++ b/src/main/java/cit/PureATN/MultiNote/PopupMenu_forMN.java @@ -1,5 +1,7 @@ package cit.PureATN.MultiNote; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.geom.Point2D; @@ -7,13 +9,11 @@ import javax.swing.JPopupMenu; import javax.swing.KeyStroke; -import java.awt.event.ActionEvent; -import java.awt.event.ActionListener; - import org.piccolo2d.PCanvas; import org.piccolo2d.event.PInputEvent; import cit.PureATN.Note; +import cit.PureATN.Inspector.DefaultPlugin; public class PopupMenu_forMN extends JPopupMenu { private static final long serialVersionUID = 7741402910818721975L; @@ -23,7 +23,7 @@ PCanvas canvas; public PopupMenu_forMN(Note aFR, PInputEvent _ie, PCanvas _canvas) { - fframe = (MultiNote)aFR; //むりやりキャストする (forMN=MultiMenu用なので、大丈夫かと) + fframe = (MultiNote) aFR; // むりやりキャストする (forMN=MultiMenu用なので、大丈夫かと) ie = _ie; canvas = _canvas; @@ -46,7 +46,6 @@ }); add(menuItem);// add exit menu - // あたらしいメニューアイテムの設定を開始する。 menuItem = new JMenuItem("色付け"); menuItem.addActionListener(new ActionListener() { @@ -55,11 +54,11 @@ fframe.iroduke(); } }); - add(menuItem);// add 色付け menu - + add(menuItem);// add 色付け menu // 追加のメニューは,プラグインが直接オンデマンドで追加する // fframe.addPluginMenuTo(this); + addPluginMenuTo(this, aFR); showPopup(); } @@ -69,4 +68,12 @@ show(canvas, (int) cp.getX(), (int) cp.getY()); } + + // 追加機能分のメニュー + public void addPluginMenuTo(JPopupMenu menu, Note note) { + for (DefaultPlugin dp : note.plugins) { + dp.addMenu(menu); + } + } + } diff --git a/src/main/java/cit/PureATN/Note.java b/src/main/java/cit/PureATN/Note.java index a3cde08..e7fdf8a 100644 --- a/src/main/java/cit/PureATN/Note.java +++ b/src/main/java/cit/PureATN/Note.java @@ -3,6 +3,7 @@ import java.awt.dnd.DropTarget; import java.awt.dnd.DropTargetDropEvent; import java.awt.event.InputEvent; +import java.util.ArrayList; import java.util.TooManyListenersException; import javax.swing.WindowConstants; @@ -14,6 +15,10 @@ import org.piccolo2d.extras.PFrame; import org.piccolo2d.util.PPaintContext; +import cit.PureATN.Inspector.DefaultPlugin; +import cit.PureATN.Inspector.InspectorPlugin; +import cit.PureATN.Inspector.WindowManagerPlugin; + public class Note extends PFrame { public static void main(final String[] args) { new Note(); @@ -26,6 +31,10 @@ public DPenReceiver dPenReceiver; + public ArrayList plugins; + InspectorPlugin inspector; + + public Note() { this(null); setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE); @@ -80,8 +89,18 @@ }catch(TooManyListenersException ex){ ex.printStackTrace(System.out); } + + // プラグイン + plugins = new ArrayList(); + plugins.add(new WindowManagerPlugin(getCanvas(), this)); + //プラグインとして,インスペクタを追加 + inspector = new InspectorPlugin(getCanvas(), this); + plugins.add(inspector); + } + + public SquiggleEventHandler createSquiggleEvent(){ // may be overridden return new SquiggleEventHandler(this); }