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