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 import dsfml.graphics : RenderWindow;
16 import dsfml.system : Vector2f;
17 import dsfml.window : Event, Keyboard, Mouse;
18 
19 /// Alias for DSFML's mouse button.
20 public alias MouseButton = Mouse.Button;
21 /// Alias for DSFML's keyboard key.
22 public alias Key = Keyboard.Key;
23 
24 /// A component.
25 abstract class Component
26 {
27   private:
28   /// The position.
29   Vector2f _position;
30   /// The size.
31   Vector2f _size;
32 
33   protected:
34   /// Creates a new component.
35   this()
36   {
37 
38   }
39 
40   /**
41   * Creates a new component.
42   * Params:
43   *   width = The width of the component.
44   *   height = The height of the component.
45   */
46   this(float width, float height)
47   {
48     _size = Vector2f(width, height);
49   }
50 
51   public:
52   final
53   {
54     @property
55     {
56       /// Gets the position.
57       Vector2f position() { return _position; }
58 
59       /// Sets the position.
60       void position(Vector2f newPosition)
61       {
62         _position = newPosition;
63 
64         updatePosition();
65       }
66 
67       /// Gets the x coordinate.
68       ptrdiff_t x() { return cast(ptrdiff_t)_position.x; }
69 
70       /// Gets the y coordinate.
71       ptrdiff_t y() { return cast(ptrdiff_t)_position.y; }
72 
73       /// Gets the size.
74       Vector2f size() { return _size; }
75 
76       /// Sets the size.
77       void size(Vector2f newSize)
78       {
79         _size = newSize;
80 
81         updateSize();
82       }
83 
84       /// Gets the width.
85       ptrdiff_t width() { return cast(ptrdiff_t)_size.x; }
86 
87       /// Gets the height.
88       ptrdiff_t height() { return cast(ptrdiff_t)_size.y; }
89     }
90 
91     /**
92     * Checks whether the component intersects with a specific point.
93     * Params:
94     *   p = The point to check.
95     * Returns:
96     *   True if the component intersects with the specific point, false otherwise.
97     */
98     bool intersect(Vector2f p)
99     {
100       return (p.x > this.x) &&
101   			(p.x < (this.x + cast(ptrdiff_t)this.width)) &&
102   			(p.y > this.y) &&
103   			(p.y < (this.y + cast(ptrdiff_t)this.height));
104     }
105 
106     /**
107     * Updates the internal position. Use this to avoid event handling.
108     * Params:
109     *   position = The position to set the internal position as.
110     */
111     protected void updateInternalPosition(Vector2f position)
112     {
113       _position = position;
114     }
115   }
116 
117   /// Handler for global mouse press events.
118   void delegate(MouseButton button, ref bool stopEvent) globalMousePress;
119   /// Handler for global mouse release events.
120   void delegate(MouseButton button, ref bool stopEvent) globalMouseRelease;
121   /// Handler for global mouse movement events.
122   void delegate(Vector2f position, ref bool stopEvent) globalMouseMove;
123   /// Handler for global key press events.
124   void delegate(Key key, ref bool stopEvent) globalKeyPress;
125   /// Handler for global key release events.
126   void delegate(Key key, ref bool stopEvent) globalKeyRelease;
127   /// Handler for mouse press events.
128   void delegate(MouseButton button, ref bool stopEvent) mousePress;
129   /// Handler for mouse release events.
130   void delegate(MouseButton button, ref bool stopEvent) mouseRelease;
131   /// Handler for mouse movement events.
132   void delegate(Vector2f position, ref bool stopEvent) mouseMove;
133   /// Handler for key press events.
134   void delegate(Key key, ref bool stopEvent) keyPress;
135   /// Handler for key release events.
136   void delegate(Key key, ref bool stopEvent) keyRelease;
137 
138   abstract:
139   /**
140   * Will render the component. Called during every frame render.
141   * Params:
142   *   window = The window used for rendering.
143   */
144   void render(RenderWindow window);
145   /**
146   * Refreshes the component with a given width ahd height. This is usually the layer size which is usually the window size.
147   * Params:
148   *   width = The width.
149   *   height = The height.
150   */
151   void refresh(size_t width, size_t height);
152   /// Called when the size of the component updates.
153   void updateSize();
154   /// Called when the position of the component updates.
155   void updatePosition();
156 }