1 // Copyright (C) 2002-2012 Nikolaus Gebhardt
2 // This file is part of the "Irrlicht Engine".
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
4 
5 #ifndef __GUI_SKIN_H_INCLUDED__
6 #define __GUI_SKIN_H_INCLUDED__
7 
8 #include "IrrCompileConfig.h"
9 #ifdef _IRR_COMPILE_WITH_GUI_
10 
11 #include "IGUISkin.h"
12 #include "irrString.h"
13 #include <string>
14 #include "ITexture.h"
15 
16 namespace irr
17 {
18 namespace video
19 {
20 	class IVideoDriver;
21 }
22 namespace gui
23 {
24 	class GUISkin : public IGUISkin
25 	{
26 	public:
27 
28 		GUISkin(EGUI_SKIN_TYPE type, video::IVideoDriver* driver);
29 
30 		//! destructor
31 		virtual ~GUISkin();
32 
33 		//! returns default color
34 		virtual video::SColor getColor(EGUI_DEFAULT_COLOR color) const;
35 
36 		//! sets a default color
37 		virtual void setColor(EGUI_DEFAULT_COLOR which, video::SColor newColor);
38 
39 		//! returns size for the given size type
40 		virtual s32 getSize(EGUI_DEFAULT_SIZE size) const;
41 
42 		//! sets a default size
43 		virtual void setSize(EGUI_DEFAULT_SIZE which, s32 size);
44 
45 		//! returns the default font
46 		virtual IGUIFont* getFont(EGUI_DEFAULT_FONT which=EGDF_DEFAULT) const;
47 
48 		//! sets a default font
49 		virtual void setFont(IGUIFont* font, EGUI_DEFAULT_FONT which=EGDF_DEFAULT);
50 
51 		//! sets the sprite bank used for drawing icons
52 		virtual void setSpriteBank(IGUISpriteBank* bank);
53 
54 		//! gets the sprite bank used for drawing icons
55 		virtual IGUISpriteBank* getSpriteBank() const;
56 
57 		//! Returns a default icon
58 		/** Returns the sprite index within the sprite bank */
59 		virtual u32 getIcon(EGUI_DEFAULT_ICON icon) const;
60 
61 		//! Sets a default icon
62 		/** Sets the sprite index used for drawing icons like arrows,
63 		close buttons and ticks in checkboxes
64 		\param icon: Enum specifying which icon to change
65 		\param index: The sprite index used to draw this icon */
66 		virtual void setIcon(EGUI_DEFAULT_ICON icon, u32 index);
67 
68 		//! Returns a default text.
69 		/** For example for Message box button captions:
70 		"OK", "Cancel", "Yes", "No" and so on. */
71 		virtual const wchar_t* getDefaultText(EGUI_DEFAULT_TEXT text) const;
72 
73 		//! Sets a default text.
74 		/** For example for Message box button captions:
75 		"OK", "Cancel", "Yes", "No" and so on. */
76 		virtual void setDefaultText(EGUI_DEFAULT_TEXT which, const wchar_t* newText);
77 
78 		//! draws a standard 3d button pane
79 		/** Used for drawing for example buttons in normal state.
80 		It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
81 		EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
82 		\param rect: Defining area where to draw.
83 		\param clip: Clip area.
84 		\param element: Pointer to the element which wishes to draw this. This parameter
85 		is usually not used by ISkin, but can be used for example by more complex
86 		implementations to find out how to draw the part exactly. */
87 		virtual void draw3DButtonPaneStandard(IGUIElement* element,
88 				const core::rect<s32>& rect,
89 				const core::rect<s32>* clip=0)
90 		{
91 			drawColored3DButtonPaneStandard(element, rect,clip);
92 		}
93 
94 		virtual void drawColored3DButtonPaneStandard(IGUIElement* element,
95 				const core::rect<s32>& rect,
96 				const core::rect<s32>* clip=0,
97 				const video::SColor* colors=0);
98 
99 		//! draws a pressed 3d button pane
100 		/** Used for drawing for example buttons in pressed state.
101 		It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
102 		EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
103 		\param rect: Defining area where to draw.
104 		\param clip: Clip area.
105 		\param element: Pointer to the element which wishes to draw this. This parameter
106 		is usually not used by ISkin, but can be used for example by more complex
107 		implementations to find out how to draw the part exactly. */
108 		virtual void draw3DButtonPanePressed(IGUIElement* element,
109 				const core::rect<s32>& rect,
110 				const core::rect<s32>* clip=0)
111 		{
112 			drawColored3DButtonPanePressed(element, rect, clip);
113 		}
114 
115 		virtual void drawColored3DButtonPanePressed(IGUIElement* element,
116 				const core::rect<s32>& rect,
117 				const core::rect<s32>* clip=0,
118 				const video::SColor* colors=0);
119 
120 		//! draws a sunken 3d pane
121 		/** Used for drawing the background of edit, combo or check boxes.
122 		\param element: Pointer to the element which wishes to draw this. This parameter
123 		is usually not used by ISkin, but can be used for example by more complex
124 		implementations to find out how to draw the part exactly.
125 		\param bgcolor: Background color.
126 		\param flat: Specifies if the sunken pane should be flat or displayed as sunken
127 		deep into the ground.
128 		\param rect: Defining area where to draw.
129 		\param clip: Clip area.	*/
130 		virtual void draw3DSunkenPane(IGUIElement* element,
131 				video::SColor bgcolor, bool flat,
132 				bool fillBackGround,
133 				const core::rect<s32>& rect,
134 				const core::rect<s32>* clip=0)
135 		{
136 			drawColored3DSunkenPane(element, bgcolor, flat, fillBackGround, rect, clip);
137 		}
138 
139 		virtual void drawColored3DSunkenPane(IGUIElement* element,
140 				video::SColor bgcolor, bool flat,
141 				bool fillBackGround,
142 				const core::rect<s32>& rect,
143 				const core::rect<s32>* clip=0,
144 				const video::SColor* colors=0);
145 
146 		//! draws a window background
147 		/** Used for drawing the background of dialogs and windows.
148 		\param element: Pointer to the element which wishes to draw this. This parameter
149 		is usually not used by ISkin, but can be used for example by more complex
150 		implementations to find out how to draw the part exactly.
151 		\param titleBarColor: Title color.
152 		\param drawTitleBar: True to enable title drawing.
153 		\param rect: Defining area where to draw.
154 		\param clip: Clip area.
155 		\param checkClientArea: When set to non-null the function will not draw anything,
156 		but will instead return the clientArea which can be used for drawing by the calling window.
157 		That is the area without borders and without titlebar.
158 		\return Returns rect where it would be good to draw title bar text. This will
159 		work even when checkClientArea is set to a non-null value.*/
draw3DWindowBackground(IGUIElement * element,bool drawTitleBar,video::SColor titleBarColor,const core::rect<s32> & rect,const core::rect<s32> * clip,core::rect<s32> * checkClientArea)160 		virtual core::rect<s32> draw3DWindowBackground(IGUIElement* element,
161 				bool drawTitleBar, video::SColor titleBarColor,
162 				const core::rect<s32>& rect,
163 				const core::rect<s32>* clip,
164 				core::rect<s32>* checkClientArea)
165 		{
166 			return drawColored3DWindowBackground(element, drawTitleBar, titleBarColor,
167 				rect, clip, checkClientArea);
168 		}
169 
170 		virtual core::rect<s32> drawColored3DWindowBackground(IGUIElement* element,
171 				bool drawTitleBar, video::SColor titleBarColor,
172 				const core::rect<s32>& rect,
173 				const core::rect<s32>* clip,
174 				core::rect<s32>* checkClientArea,
175 				const video::SColor* colors=0);
176 
177 		//! draws a standard 3d menu pane
178 		/** Used for drawing for menus and context menus.
179 		It uses the colors EGDC_3D_DARK_SHADOW, EGDC_3D_HIGH_LIGHT, EGDC_3D_SHADOW and
180 		EGDC_3D_FACE for this. See EGUI_DEFAULT_COLOR for details.
181 		\param element: Pointer to the element which wishes to draw this. This parameter
182 		is usually not used by ISkin, but can be used for example by more complex
183 		implementations to find out how to draw the part exactly.
184 		\param rect: Defining area where to draw.
185 		\param clip: Clip area.	*/
186 		virtual void draw3DMenuPane(IGUIElement* element,
187 				const core::rect<s32>& rect,
188 				const core::rect<s32>* clip=0)
189 		{
190 			drawColored3DMenuPane(element, rect, clip);
191 		}
192 
193 		virtual void drawColored3DMenuPane(IGUIElement* element,
194 				const core::rect<s32>& rect,
195 				const core::rect<s32>* clip=0,
196 				const video::SColor* colors=0);
197 
198 		//! draws a standard 3d tool bar
199 		/** Used for drawing for toolbars and menus.
200 		\param element: Pointer to the element which wishes to draw this. This parameter
201 		is usually not used by ISkin, but can be used for example by more complex
202 		implementations to find out how to draw the part exactly.
203 		\param rect: Defining area where to draw.
204 		\param clip: Clip area.	*/
205 		virtual void draw3DToolBar(IGUIElement* element,
206 				const core::rect<s32>& rect,
207 				const core::rect<s32>* clip=0)
208 		{
209 			drawColored3DToolBar(element, rect, clip);
210 		}
211 
212 		virtual void drawColored3DToolBar(IGUIElement* element,
213 				const core::rect<s32>& rect,
214 				const core::rect<s32>* clip=0,
215 				const video::SColor* colors=0);
216 
217 		//! draws a tab button
218 		/** Used for drawing for tab buttons on top of tabs.
219 		\param element: Pointer to the element which wishes to draw this. This parameter
220 		is usually not used by ISkin, but can be used for example by more complex
221 		implementations to find out how to draw the part exactly.
222 		\param active: Specifies if the tab is currently active.
223 		\param rect: Defining area where to draw.
224 		\param clip: Clip area.	*/
225 		virtual void draw3DTabButton(IGUIElement* element, bool active,
226 			const core::rect<s32>& rect, const core::rect<s32>* clip=0, EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT)
227 		{
228 			drawColored3DTabButton(element, active, rect, clip, alignment);
229 		}
230 
231 		virtual void drawColored3DTabButton(IGUIElement* element, bool active,
232 			const core::rect<s32>& rect, const core::rect<s32>* clip=0, EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT,
233 			const video::SColor* colors=0);
234 
235 		//! draws a tab control body
236 		/** \param element: Pointer to the element which wishes to draw this. This parameter
237 		is usually not used by ISkin, but can be used for example by more complex
238 		implementations to find out how to draw the part exactly.
239 		\param border: Specifies if the border should be drawn.
240 		\param background: Specifies if the background should be drawn.
241 		\param rect: Defining area where to draw.
242 		\param clip: Clip area.	*/
243 		virtual void draw3DTabBody(IGUIElement* element, bool border, bool background,
244 			const core::rect<s32>& rect, const core::rect<s32>* clip=0, s32 tabHeight=-1, EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT)
245 		{
246 			drawColored3DTabBody(element, border, background, rect, clip, tabHeight, alignment);
247 		}
248 
249 		virtual void drawColored3DTabBody(IGUIElement* element, bool border, bool background,
250 			const core::rect<s32>& rect, const core::rect<s32>* clip=0, s32 tabHeight=-1, EGUI_ALIGNMENT alignment=EGUIA_UPPERLEFT,
251 			const video::SColor* colors=0);
252 
253 		//! draws an icon, usually from the skin's sprite bank
254 		/** \param element: Pointer to the element which wishes to draw this icon.
255 		This parameter is usually not used by IGUISkin, but can be used for example
256 		by more complex implementations to find out how to draw the part exactly.
257 		\param icon: Specifies the icon to be drawn.
258 		\param position: The position to draw the icon
259 		\param starttime: The time at the start of the animation
260 		\param currenttime: The present time, used to calculate the frame number
261 		\param loop: Whether the animation should loop or not
262 		\param clip: Clip area.	*/
263 		virtual void drawIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon,
264 				const core::position2di position,
265 				u32 starttime=0, u32 currenttime=0,
266 				bool loop=false, const core::rect<s32>* clip=0)
267 		{
268 			drawColoredIcon(element, icon, position, starttime, currenttime, loop, clip);
269 		}
270 
271 		virtual void drawColoredIcon(IGUIElement* element, EGUI_DEFAULT_ICON icon,
272 				const core::position2di position,
273 				u32 starttime=0, u32 currenttime=0,
274 				bool loop=false, const core::rect<s32>* clip=0,
275 				const video::SColor* colors=0);
276 
277 		//! draws a 2d rectangle.
278 		/** \param element: Pointer to the element which wishes to draw this icon.
279 		This parameter is usually not used by IGUISkin, but can be used for example
280 		by more complex implementations to find out how to draw the part exactly.
281 		\param color: Color of the rectangle to draw. The alpha component specifies how
282 		transparent the rectangle will be.
283 		\param pos: Position of the rectangle.
284 		\param clip: Pointer to rectangle against which the rectangle will be clipped.
285 		If the pointer is null, no clipping will be performed. */
286 		virtual void draw2DRectangle(IGUIElement* element, const video::SColor &color,
287 				const core::rect<s32>& pos, const core::rect<s32>* clip = 0);
288 
289 
290 		//! get the type of this skin
291 		virtual EGUI_SKIN_TYPE getType() const;
292 
293 		//! Writes attributes of the object.
294 		//! Implement this to expose the attributes of your scene node animator for
295 		//! scripting languages, editors, debuggers or xml serialization purposes.
296 		virtual void serializeAttributes(io::IAttributes* out, io::SAttributeReadWriteOptions* options=0) const;
297 
298 		//! Reads attributes of the object.
299 		//! Implement this to set the attributes of your scene node animator for
300 		//! scripting languages, editors, debuggers or xml deserialization purposes.
301 		virtual void deserializeAttributes(io::IAttributes* in, io::SAttributeReadWriteOptions* options=0);
302 
303 		//! gets the colors
304 		virtual void getColors(video::SColor* colors); // ::PATCH:
305 
306 	private:
307 
308 		video::SColor Colors[EGDC_COUNT];
309 		s32 Sizes[EGDS_COUNT];
310 		u32 Icons[EGDI_COUNT];
311 		IGUIFont* Fonts[EGDF_COUNT];
312 		IGUISpriteBank* SpriteBank;
313 		core::stringw Texts[EGDT_COUNT];
314 		video::IVideoDriver* Driver;
315 		bool UseGradient;
316 
317 		EGUI_SKIN_TYPE Type;
318 	};
319 
320 	#define set3DSkinColors(skin, button_color) \
321 		{ \
322 			skin->setColor(EGDC_3D_FACE, button_color); \
323 			skin->setColor(EGDC_3D_DARK_SHADOW, button_color, 0.25f); \
324 			skin->setColor(EGDC_3D_SHADOW, button_color, 0.5f); \
325 			skin->setColor(EGDC_3D_LIGHT, button_color); \
326 			skin->setColor(EGDC_3D_HIGH_LIGHT, button_color, 1.5f); \
327 		}
328 
329 	#define getElementSkinColor(color) \
330 		{ \
331 			if (!Colors) \
332 			{ \
333 				IGUISkin* skin = Environment->getSkin(); \
334 				if (skin) \
335 					return skin->getColor(color); \
336 			} \
337 			return Colors[color]; \
338 		}
339 
340 	#define setElementSkinColor(which, newColor, shading) \
341 		{ \
342 			if (!Colors) \
343 			{ \
344 				Colors = new video::SColor[EGDC_COUNT]; \
345 				GUISkin* skin = (GUISkin *)Environment->getSkin(); \
346 				if (skin) \
347 					skin->getColors(Colors); \
348 			} \
349 			Colors[which] = newColor; \
350 			setShading(Colors[which],shading); \
351 		}
352 } // end namespace gui
353 //! Sets the shading
setShading(video::SColor & color,f32 s)354 inline void setShading(video::SColor &color,f32 s) // :PATCH:
355 {
356 	if (s < 1.0f)
357 	{
358 		color.setRed(color.getRed() * s);
359 		color.setGreen(color.getGreen() * s);
360 		color.setBlue(color.getBlue() * s);
361 	}
362 	else if (s > 1.0f)
363 	{
364 		s -= 1.0f;
365 
366 		color.setRed(color.getRed() + (255 - color.getRed()) * s);
367 		color.setGreen(color.getGreen() + (255 - color.getGreen()) * s);
368 		color.setBlue(color.getBlue() + (255 - color.getBlue()) * s);
369 	}
370 }
371 } // end namespace irr
372 
373 
374 #endif // _IRR_COMPILE_WITH_GUI_
375 
376 #endif
377