Fixed a bug in Am2900; created dlatch8/80; relayouted some components
[Mograsim.git] / net.mograsim.logic.model.editor / src / net / mograsim / logic / model / editor / handles / Handle.java
1 package net.mograsim.logic.model.editor.handles;
2
3 import java.util.ArrayList;
4 import java.util.Collection;
5 import java.util.Optional;
6
7 import net.haspamelodica.swt.helper.gcs.GeneralGC;
8 import net.haspamelodica.swt.helper.swtobjectwrappers.Point;
9 import net.haspamelodica.swt.helper.swtobjectwrappers.Rectangle;
10 import net.mograsim.logic.model.editor.Editor.ComponentInfo;
11 import net.mograsim.logic.model.editor.states.EditorState;
12
13 public abstract class Handle
14 {
15         private final Rectangle bounds;
16         private final Collection<Runnable> redrawListeners, destroyListeners;
17         private final int priority;
18
19         public Handle(int priority)
20         {
21                 this.priority = priority;
22                 redrawListeners = new ArrayList<>();
23                 destroyListeners = new ArrayList<>();
24                 bounds = new Rectangle(0, 0, 0, 0);
25                 callRedrawListeners();
26         }
27
28         final public void render(GeneralGC gc, Rectangle visibleRegion)
29         {
30                 if (bounds.intersects(visibleRegion))
31                         render(gc);
32         }
33
34         protected abstract void render(GeneralGC gc);
35
36         protected void setSize(double width, double height)
37         {
38                 bounds.width = width;
39                 bounds.height = height;
40                 callRedrawListeners();
41         }
42
43         protected void moveTo(double x, double y)
44         {
45                 bounds.x = x;
46                 bounds.y = y;
47                 callRedrawListeners();
48         }
49
50         public Rectangle getBounds()
51         {
52                 return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
53         }
54
55         public void addRedrawListener(Runnable listener)
56         {
57                 redrawListeners.add(listener);
58         }
59
60         public void removeRedrawListener(Runnable listener)
61         {
62                 redrawListeners.remove(listener);
63         }
64
65         protected void callRedrawListeners()
66         {
67                 redrawListeners.forEach(l -> l.run());
68         }
69
70         public double getPosX()
71         {
72                 return bounds.x;
73         }
74
75         public double getPosY()
76         {
77                 return bounds.y;
78         }
79
80         void destroy()
81         {
82                 destroyListeners.forEach(l -> l.run());
83         }
84
85         public void addDestroyListener(Runnable listener)
86         {
87                 redrawListeners.add(listener);
88         }
89
90         public void removeDestroyListener(Runnable listener)
91         {
92                 redrawListeners.remove(listener);
93         }
94
95         public boolean contains(double x, double y)
96         {
97                 return bounds.contains(x, y);
98         }
99
100         public boolean contains(Point p)
101         {
102                 return contains(p.x, p.y);
103         }
104
105         /**
106          * Register a mouse click
107          * 
108          * @param x Coordinate of the click in the world, not the display context
109          * @param y Coordinate of the click in the world, not the display context
110          * @return true if the click was consumed, false otherwise
111          */
112         public boolean click(double x, double y, int stateMask, EditorState state)
113         {
114                 if (contains(x, y))
115                         return state.clickedHandle(new HandleClickInfo(this, stateMask));
116                 return false;
117         }
118
119         //@formatter:off
120     public void reqMove(double x, double y) {}
121     public void reqDelete() {}
122     public Optional<ComponentInfo> reqCopy(Point refPoint) { return Optional.empty(); }
123     public void onSelect() {}
124     public void onDeselect() {}
125     //@formatter:on
126
127         public final int getPriority()
128         {
129                 return priority;
130         }
131
132         public abstract HandleType getType();
133
134         public static enum HandleType
135         {
136                 COMPONENT, STATIC_PIN, INTERFACE_PIN, WIRE_POINT, WIRE, CORNER;
137         }
138
139         public static class HandleClickInfo
140         {
141                 public final int stateMask;
142                 public final Handle clicked;
143
144                 HandleClickInfo(Handle clicked, int stateMask)
145                 {
146                         this.clicked = clicked;
147                         this.stateMask = stateMask;
148                 }
149         }
150 }