1 /**
2 * Copyright © Novelate 2020
3 * License: MIT (https://github.com/Novelate/NovelateEngine/blob/master/LICENSE)
4 * Author: Jacob Jensen (bausshf)
5 * Website: https://novelate.com/
6 * ------
7 * Novelate is a free and open-source visual novel engine and framework written in the D programming language.
8 * It can be used freely for both personal and commercial projects.
9 * ------
10 * Module Description:
11 * A component is an element that can be rendered on the screen with optional event handlers etc.
12 */
13 module novelate.component;
14 
15 public import novelate.external;
16 
17 /// A component.
18 abstract class Component
19 {
20   private:
21   /// The position.
22   FloatVector _position;
23   /// The size.
24   FloatVector _size;
25 
26   protected:
27   /// Creates a new component.
28   this()
29   {
30 
31   }
32 
33   /**
34   * Creates a new component.
35   * Params:
36   *   width = The width of the component.
37   *   height = The height of the component.
38   */
39   this(float width, float height)
40   {
41     _size = FloatVector(width, height);
42   }
43 
44   public:
45   final
46   {
47     @property
48     {
49       /// Gets the position.
50       FloatVector position() { return _position; }
51 
52       /// Sets the position.
53       void position(FloatVector newPosition)
54       {
55         _position = newPosition;
56 
57         updatePosition();
58       }
59 
60       /// Gets the x coordinate.
61       ptrdiff_t x() { return cast(ptrdiff_t)_position.x; }
62 
63       /// Gets the y coordinate.
64       ptrdiff_t y() { return cast(ptrdiff_t)_position.y; }
65 
66       /// Gets the size.
67       FloatVector size() { return _size; }
68 
69       /// Sets the size.
70       void size(FloatVector newSize)
71       {
72         _size = newSize;
73 
74         updateSize();
75       }
76 
77       /// Gets the width.
78       ptrdiff_t width() { return cast(ptrdiff_t)_size.x; }
79 
80       /// Gets the height.
81       ptrdiff_t height() { return cast(ptrdiff_t)_size.y; }
82     }
83 
84     /**
85     * Checks whether the component intersects with a specific point.
86     * Params:
87     *   p = The point to check.
88     * Returns:
89     *   True if the component intersects with the specific point, false otherwise.
90     */
91     bool intersect(FloatVector p)
92     {
93       return (p.x > this.x) &&
94   			(p.x < (this.x + cast(ptrdiff_t)this.width)) &&
95   			(p.y > this.y) &&
96   			(p.y < (this.y + cast(ptrdiff_t)this.height));
97     }
98 
99     /**
100     * Updates the internal position. Use this to avoid event handling.
101     * Params:
102     *   position = The position to set the internal position as.
103     */
104     protected void updateInternalPosition(FloatVector position)
105     {
106       _position = position;
107     }
108   }
109 
110   /// Handler for global mouse press events.
111   void delegate(MouseButton button, ref bool stopEvent) globalMousePress;
112   /// Handler for global mouse release events.
113   void delegate(MouseButton button, ref bool stopEvent) globalMouseRelease;
114   /// Handler for global mouse movement events.
115   void delegate(FloatVector position, ref bool stopEvent) globalMouseMove;
116   /// Handler for global key press events.
117   void delegate(KeyboardKey key, ref bool stopEvent) globalKeyPress;
118   /// Handler for global key release events.
119   void delegate(KeyboardKey key, ref bool stopEvent) globalKeyRelease;
120   /// Handler for mouse press events.
121   void delegate(MouseButton button, ref bool stopEvent) mousePress;
122   /// Handler for mouse release events.
123   void delegate(MouseButton button, ref bool stopEvent) mouseRelease;
124   /// Handler for mouse movement events.
125   void delegate(FloatVector position, ref bool stopEvent) mouseMove;
126   /// Handler for key press events.
127   void delegate(KeyboardKey key, ref bool stopEvent) keyPress;
128   /// Handler for key release events.
129   void delegate(KeyboardKey key, ref bool stopEvent) keyRelease;
130 
131   abstract:
132   /**
133   * Will render the component. Called during every frame render.
134   * Params:
135   *   window = The window used for rendering.
136   */
137   void render(ExternalWindow window);
138   /**
139   * Refreshes the component with a given width ahd height. This is usually the layer size which is usually the window size.
140   * Params:
141   *   width = The width.
142   *   height = The height.
143   */
144   void refresh(size_t width, size_t height);
145   /// Called when the size of the component updates.
146   void updateSize();
147   /// Called when the position of the component updates.
148   void updatePosition();
149 }