Merge branch 'development' of
[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         
18         public Handle()
19         {
20                 redrawListeners = new ArrayList<>();
21                 destroyListeners = new ArrayList<>();
22                 bounds = new Rectangle(0, 0, 0, 0);
23                 callRedrawListeners();
24         }
25
26         final public void render(GeneralGC gc, Rectangle visibleRegion)
27         {
28                 if (bounds.intersects(visibleRegion))
29                         render(gc);
30         }
31
32         protected abstract void render(GeneralGC gc);
33
34         protected void setSize(double width, double height)
35         {
36                 bounds.width = width;
37                 bounds.height = height;
38                 callRedrawListeners();
39         }
40
41         protected void moveTo(double x, double y)
42         {
43                 bounds.x = x;
44                 bounds.y = y;
45                 callRedrawListeners();
46         }
47         
48         public Rectangle getBounds()
49         {
50                 return new Rectangle(bounds.x, bounds.y, bounds.width, bounds.height);
51         }
52
53         public void addRedrawListener(Runnable listener)
54         {
55                 redrawListeners.add(listener);
56         }
57
58         public void removeRedrawListener(Runnable listener)
59         {
60                 redrawListeners.remove(listener);
61         }
62
63         protected void callRedrawListeners()
64         {
65                 redrawListeners.forEach(l -> l.run());
66         }
67
68         public double getPosX()
69         {
70                 return bounds.x;
71         }
72
73         public double getPosY()
74         {
75                 return bounds.y;
76         }
77
78         void destroy()
79         {
80                 destroyListeners.forEach(l -> l.run());
81         }
82
83         public void addDestroyListener(Runnable listener)
84         {
85                 redrawListeners.add(listener);
86         }
87
88         public void removeDestroyListener(Runnable listener)
89         {
90                 redrawListeners.remove(listener);
91         }
92         
93         public boolean contains(double x, double y)
94         {
95                 return bounds.contains(x, y);
96         }
97         
98         public boolean contains(Point p)
99         {
100                 return contains(p.x, p.y);
101         }
102         
103         /**
104          * Register a mouse click
105          * @param x Coordinate of the click in the world, not the display context
106          * @param y Coordinate of the click in the world, not the display context
107          * @return true if the click was consumed, false otherwise
108          */
109         public boolean click(double x, double y, int stateMask, EditorState state)
110         {
111                 if(contains(x, y))
112                         return state.clickedHandle(new HandleClickInfo(this, stateMask));
113                 return false;
114         }
115
116         //@formatter:off
117     public void reqMove(double x, double y) {}
118     public void reqDelete() {}
119     public Optional<ComponentInfo> reqCopy(Point refPoint) { return Optional.empty(); }
120     public void onSelect() {}
121     public void onDeselect() {}
122     //@formatter:on
123     
124     public abstract HandleType getType();
125     
126     public static enum HandleType
127     {
128         COMPONENT, STATIC_PIN, INTERFACE_PIN, WIRE_POINT, WIRE, CORNER;
129     }
130     
131     public static class HandleClickInfo
132     {
133         public final int stateMask;
134         public final Handle clicked;
135         
136         HandleClickInfo(Handle clicked, int stateMask)
137         {
138                 this.clicked = clicked;
139                 this.stateMask = stateMask;
140         }
141     }
142 }