1 /*
2  * This source file is part of MyGUI. For the latest info, see http://mygui.info/
3  * Distributed under the MIT License
4  * (See accompanying file COPYING.MIT or copy at http://opensource.org/licenses/MIT)
5  */
6 
7 #ifndef MYGUI_CANVAS_H_
8 #define MYGUI_CANVAS_H_
9 
10 #include "MyGUI_Prerequest.h"
11 #include "MyGUI_Widget.h"
12 #include "MyGUI_ITexture.h"
13 
14 namespace MyGUI
15 {
16 
17 	/** \brief @wpage{Canvas}
18 		Widget wrapper over Texture - shows the texture.
19 		Implemented: resizing of texture (see TextureResizeMode); recovery after loosing device;
20 	*/
21 	class MYGUI_EXPORT Canvas :
22 		public Widget,
23 		public ITextureInvalidateListener
24 	{
25 		MYGUI_RTTI_DERIVED( Canvas )
26 
27 	public:
28 		Canvas();
29 
30 		struct Event
31 		{
EventEvent32 			Event( bool _textureChanged, bool _widgetResized, bool _requested ) :
33 				textureChanged( _textureChanged ),
34 				widgetResized( _widgetResized ),
35 				requested( _requested )
36 			{
37 			}
38 
39 			bool textureChanged;
40 			bool widgetResized;
41 
42 			/// This update was caused by calling updateTexture();
43 			bool requested;
44 		};
45 
46 		typedef delegates::CMultiDelegate1<Canvas*> EventHandle_CanvasPtr;
47 		typedef delegates::CDelegate2<Canvas*, Event> EventHandle_CanvasPtrEvent;
48 
49 		/**
50 			Available resize and view modes of texture
51 			@remarks PT - Power of Two (size)
52 		*/
53 		enum TextureResizeMode
54 		{
55 			/**	Mode when the texture has constant size and stretching on all widget.
56 				@remarks
57 				The size specified at creation of the texture increases to nearest power of two and doesn't change any more. Texture is always stretched on all widget.
58 			*/
59 			// Размер указаный при создании текстуры увеличиваеться до степени двойки и больше не меняется.
60 			// Текстура всегда растягиваеться во весь виджет.
61 			TRM_PT_CONST_SIZE,
62 
63 			/**
64 				Mode when texture pixels look as is.
65 				@remarks
66 				The texture size is always more or equal than the widget size and is equal to a power of two.
67 				@note
68 				The size specified at creation of the texture is ignored.
69 				The texture is automatically recreated if the size of the widget becomes bigger.
70 			*/
71 			// Размер указаный при создании текстуры игнорируется.
72 			// Текстура всегда больше размера окна и кратна степени двойки.
73 			// Если размер виджета становится больше чем размер текстуры, текстура пересоздается.
74 			// Текстура всегда отображатся пиксель в пиксель на виджет, образуя рабочую область текстуры.
75 			TRM_PT_VIEW_REQUESTED,
76 
77 			/**	Mode when the texture stretched on all widget and automatically changes the size for nice look.
78 				@remarks
79 				The mode same as TRM_PT_VIEW_REQUESTED, but the texture is scaled till the size of the widget.
80 				@note
81 				The size specified at creation of the texture is ignored.
82 				The texture is automatically recreated if the size of the widget becomes bigger.
83 			*/
84 			// Размер указаный при создании текстуры игнорируется.
85 			// Текстура всегда больше размера окна и кратна степени двойки.
86 			// Если размер виджета становится больше чем размер текстуры, текстура пересоздается.
87 			// Текстура всегда растягиваеться во весь виджет.
88 			TRM_PT_VIEW_ALL
89 		};
90 
91 	public:
92 		/// Creates texture
93 		void createTexture(TextureResizeMode _resizeMode, TextureUsage _usage = getDefaultTextureUsage(), PixelFormat _format = getDefaultTextureFormat());
94 
95 		/// Creates texture
96 		void createTexture(int _width, int _height, TextureResizeMode _resizeMode, TextureUsage _usage = getDefaultTextureUsage(), PixelFormat _format = getDefaultTextureFormat());
97 
98 		/// Creates texture
99 		void createTexture(const IntSize& _size, TextureResizeMode _resizeMode, TextureUsage _usage = getDefaultTextureUsage(), PixelFormat _format = getDefaultTextureFormat());
100 
101 		/// Destroys texture
102 		void destroyTexture();
103 
104 		/// Call user delegate update and removes old texture if it isn't original.
105 		void updateTexture();
106 
107 		/// Locks hardware pixel buffer.
108 		void* lock(TextureUsage _usage = TextureUsage::Write);
109 
110 		/// Unlocks hardware pixel buffer.
111 		void unlock();
112 
113 		/// Checks lockness of hardware _pixel buffer.
114 		bool isLocked() const;
115 
116 		/// Returns real width of texture.
117 		int getTextureRealWidth() const;
118 
119 		/// Returns real height of texture.
120 		int getTextureRealHeight() const;
121 
122 		/// Returns real _size of texture.
123 		IntSize getTextureRealSize() const;
124 
125 		/// Returns needed width while creating texture.
126 		int getTextureSrcWidth() const;
127 
128 		/// Returns needed height while creating texture.
129 		int getTextureSrcHeight() const;
130 
131 		/// Returns needed sizes while creating texture.
132 		IntSize getTextureSrcSize() const;
133 
134 		/// Returns needed sizes while creating texture.
135 		PixelFormat getTextureFormat() const;
136 
137 		/// Returns name of the current texture.
138 		const std::string& getTextureName() const;
139 
140 		//! @copydoc Widget::setSize(const IntSize& _value)
141 		void setSize(const IntSize& _value) override;
142 		//! @copydoc Widget::setCoord(const IntCoord& _value)
143 		void setCoord(const IntCoord& _value) override;
144 
145 		using Widget::setPosition;
146 		using Widget::setSize;
147 		using Widget::setCoord;
148 
149 		/// Returns resize mode
150 		TextureResizeMode getResizeMode() const;
151 
152 		/// Sets resize mode of texture \sa TextureResizeMode
153 		void setResizeMode(TextureResizeMode _value);
154 
155 		/// Checks if the texture has the source (required by user) size, otherwise real texture size are bigger.
156 		bool isTextureSrcSize() const;
157 
158 		/// Returns true if the texture was created (and exists), otherwise false
159 		bool isTextureCreated() const;
160 
161 		/// Returns true if we own the texture, otherwise false. \sa mManaged
162 		bool isTextureManaged() const;
163 
164 		/// Reurns interface texture.
165 		ITexture* getTexture() const;
166 
167 		/// Sets the texture managed @remarks Be careful with assigning managed status to texture, which wasn't created in Canvas! \sa mManaged
168 		void setTextureManaged(bool _value);
169 
170 		/// Returns default GUI texture usage
171 		static TextureUsage getDefaultTextureUsage();
172 
173 		/// Returns default GUI texture format
174 		static PixelFormat getDefaultTextureFormat();
175 
176 		/*events:*/
177 		/** Event : Notify user texture instance will be changed \sa requestUpdateCanvas.\n
178 			signature : void method(MyGUI::Canvas* _canvas)\n
179 			@param _canvas, which will be updated
180 		*/
181 		EventHandle_CanvasPtr eventPreTextureChanges;
182 
183 		/** Event : Texture instance was changed (May be caused by resizing texture or lossing device). User have to update all references to new instance of texture.\n
184 			signature : void method(MyGUI::Canvas* _canvas, MyGUI::Canvas::Event _event)\n
185 			@param _canvas, which needs to update
186 			@param _event
187 		*/
188 		EventHandle_CanvasPtrEvent requestUpdateCanvas;
189 
190 	protected:
191 		void shutdownOverride() override;
192 		void initialiseOverride() override;
193 
194 		/// Destroys texture
195 		void _destroyTexture(bool _sendEvent);
196 
197 		/// Update entered parameters according to current texture resize mode(size) and restore (if can) parameters of usage and format from texture
198 		void validate(int& _width, int& _height, TextureUsage& _usage, PixelFormat& _format) const;
199 
200 		/// Creates the texture itself
201 		void createExactTexture(int _width, int _height, TextureUsage _usage, PixelFormat _format);
202 
203 		/// Checks if we need to create a texture with such sizes.
204 		bool checkCreate(int _width, int _height) const;
205 
206 		/// Calls when resize widget
207 		void resize(const IntSize& _size);
208 
209 		/// Correct texture uv-coordinates
210 		void correctUV();
211 
212 		/// For updating once per frame.
213 		void frameAdvise(bool _advise);
214 
215 		/// For updating once per frame.
216 		void frameEntered(float _time);
217 
218 		void textureInvalidate(ITexture* _texture) override;
219 
220 		void _setUVSet(const FloatRect& _rect);
221 
222 	protected:
223 		/// Current texture
224 		ITexture* mTexture;
225 
226 		/// Requested bu user sizes
227 		IntSize mReqTexSize;
228 
229 		/// Generated texture name
230 		std::string mGenTexName;
231 
232 		/// Texture resize mode \sa TextureResizeMode
233 		TextureResizeMode mTexResizeMode;
234 
235 		/// Saved pointer from last calling lock. \sa lock
236 		uint8* mTexData;
237 
238 		/// true if we own the texture (can delete it or replace by another instance), otherwise false
239 		bool mTexManaged;
240 
241 		/// For updating once per frame. True state means updating before next frame starts.
242 		bool mFrameAdvise;
243 
244 		bool mInvalidateData;
245 	};
246 
247 } // namespace MyGUI
248 
249 #endif // MYGUI_CANVAS_H_
250