1 // Copyright (C) 2002-2012 Nikolaus Gebhardt / Gaz Davidson
2 // This file is part of the "Irrlicht Engine".
3 // For conditions of distribution and use, see copyright notice in irrlicht.h
4 
5 #include "CGUITextureCacheBrowser.h"
6 #include "IGUIEnvironment.h"
7 #include "IGUIButton.h"
8 #include "IGUISkin.h"
9 #include "IGUIFont.h"
10 #include "IVideoDriver.h"
11 
12 namespace irr
13 {
14 namespace gui
15 {
16 
CGUITextureCacheBrowser(IGUIEnvironment * environment,s32 id,IGUIElement * parent)17 CGUITextureCacheBrowser::CGUITextureCacheBrowser(IGUIEnvironment* environment, s32 id, IGUIElement *parent)
18 :	IGUIWindow(environment, parent, id, core::rect<s32>(0,0,300,200)),
19 	CloseButton(0), Panel(0), SelectedTexture(-1), Dragging(false), IsDraggable(true)
20 {
21 	#ifdef _DEBUG
22 	setDebugName("CGUITextureCacheBrowser");
23 	#endif
24 
25 	IGUISkin* skin = 0;
26 	IGUISpriteBank* sprites = 0;
27 	video::SColor color(255,255,255,255);
28 
29 	if (environment)
30 		skin = environment->getSkin();
31 
32 	s32 buttonw = 15;
33 	if (skin)
34 	{
35 		buttonw = skin->getSize(EGDS_WINDOW_BUTTON_WIDTH);
36 		sprites = skin->getSpriteBank();
37 		color = skin->getColor(EGDC_WINDOW_SYMBOL);
38 	}
39 	s32 posx = RelativeRect.getWidth() - buttonw - 4;
40 
41 	CloseButton = Environment->addButton(core::rect<s32>(posx, 3, posx + buttonw, 3 + buttonw), this, -1,
42 		L"", skin ? skin->getDefaultText(EGDT_WINDOW_CLOSE) : L"Close" );
43 	CloseButton->setSubElement(true);
44 	CloseButton->setAlignment(EGUIA_LOWERRIGHT, EGUIA_LOWERRIGHT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT);
45 	if (sprites)
46 	{
47 		CloseButton->setSpriteBank(sprites);
48 		CloseButton->setSprite(EGBS_BUTTON_UP, skin->getIcon(EGDI_WINDOW_CLOSE), color);
49 		CloseButton->setSprite(EGBS_BUTTON_DOWN, skin->getIcon(EGDI_WINDOW_CLOSE), color);
50 	}
51 
52 	CloseButton->grab();
53 
54 	// window title
55 	Text = L"Texture Browser";
56 
57 	// panel element
58 	Panel = new CGUIPanel(environment, this);
59 	Panel->setRelativePosition( core::rect<s32>(1, buttonw + 5, 151, RelativeRect.getHeight() - 1));
60 	Panel->setAlignment(EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, EGUIA_UPPERLEFT, EGUIA_LOWERRIGHT);
61 	Panel->setBorder(true);
62 	Panel->setSubElement(true);
63 
64 	// some buttons
65 
66 
67 	// add images from texture cache
68 	updateImageList();
69 
70 }
71 
~CGUITextureCacheBrowser()72 CGUITextureCacheBrowser::~CGUITextureCacheBrowser()
73 {
74 	if (CloseButton)
75 		CloseButton->drop();
76 	if (Panel)
77 		Panel->drop();
78 
79 	// drop images
80 	u32 i;
81 	for (i=0; i<Images.size(); ++i)
82 	{
83 		Images[i]->drop();
84 		Images[i]->remove();
85 	}
86 	Images.clear();
87 }
updateImageList()88 void CGUITextureCacheBrowser::updateImageList()
89 {
90 	if (!Panel)
91 		return;
92 
93 	video::IVideoDriver* Driver = Environment->getVideoDriver();
94 
95 	// clear images
96 	u32 i;
97 	for (i=0; i<Images.size(); ++i)
98 	{
99 		Images[i]->drop();
100 		Images[i]->remove();
101 	}
102 	Images.clear();
103 
104 	u32 count = (u32)Driver->getTextureCount();
105 
106 	s32 h = Panel->getClientArea().getWidth()-10;
107 	s32 hw = h/2;
108 	core::rect<s32> pos(Panel->getClientArea().getCenter().X - Panel->getAbsolutePosition().UpperLeftCorner.X - hw, 5,
109 						Panel->getClientArea().getCenter().X - Panel->getAbsolutePosition().UpperLeftCorner.X + hw, h+5);
110 
111 	core::position2di moveDist(0, h+5);
112 
113 	for (u32 i=0; i<count; ++i)
114 	{
115 		core::stringw details;
116 		video::ITexture* tex = Driver->getTextureByIndex(i);
117 		details = L"File name: ";
118 		details += tex->getName();
119 		details += L"\nFormat: ";
120 		video::ECOLOR_FORMAT cf = tex->getColorFormat();
121 
122 		bool alpha = false;
123 
124 		switch (cf)
125 		{
126 		case video::ECF_A1R5G5B5:
127 			details += L"A1R5G5B5 (16-bit with 1-bit alpha channel)\n";
128 			alpha = true;
129 			break;
130 		case video::ECF_R5G6B5:
131 			details += L"R5G6B5 (16-bit, no alpha channel)\n";
132 			break;
133 		case video::ECF_R8G8B8:
134 			details += L"R8G8B8 (16-bit, no alpha channel)\n";
135 			break;
136 		case video::ECF_A8R8G8B8:
137 			details += L"R8G8B8 (32-bit with 8-bit alpha channel)\n";
138 			alpha = true;
139 			break;
140 		default:
141 			details += L"Unknown\n";
142 		}
143 
144 		core::dimension2du osize = tex->getOriginalSize();
145 		core::dimension2du size = tex->getOriginalSize();
146 
147 		details += "Size: ";
148 		details += size.Width;
149 		details += "x";
150 		details += size.Height;
151 
152 		if (osize != size)
153 		{
154 			details += "\nOriginal Size: ";
155 			details += osize.Width;
156 			details += "x";
157 			details += osize.Height;
158 		}
159 
160 		details += L"\nMip-maps: ";
161 
162 		if (tex->hasMipMaps())
163 			details += L"Yes\n";
164 		else
165 			details += L"No\n";
166 
167 		IGUIImage* img = Environment->addImage(tex, core::position2di(1,1), alpha, Panel, i);
168 		img->grab();
169 		Images.push_back(img);
170 		img->setRelativePosition(pos);
171 		img->setToolTipText(details.c_str());
172 		img->setScaleImage(true);
173 		img->setColor( SelectedTexture == (s32)i ? video::SColor(255,255,255,255) : video::SColor(128,128,128,128) );
174 
175 		pos = pos + moveDist;
176 	}
177 }
178 
updateAbsolutePosition()179 void CGUITextureCacheBrowser::updateAbsolutePosition()
180 {
181 	IGUIWindow::updateAbsolutePosition();
182 	updateImageList();
183 }
184 
185 //! called if an event happened.
OnEvent(const SEvent & event)186 bool CGUITextureCacheBrowser::OnEvent(const SEvent &event)
187 {
188 	switch(event.EventType)
189 	{
190 	case EET_GUI_EVENT:
191 		if (event.GUIEvent.EventType == EGET_ELEMENT_FOCUS_LOST)
192 		{
193 			if (event.GUIEvent.Caller == (IGUIElement*)this)
194 				Dragging = false;
195 			return true;
196 		}
197 		else
198 		if (event.GUIEvent.EventType == EGET_BUTTON_CLICKED)
199 		{
200 			if (event.GUIEvent.Caller == CloseButton)
201 			{
202 				remove();
203 				return true;
204 			}
205 		}
206 		break;
207 	case EET_MOUSE_INPUT_EVENT:
208 		switch(event.MouseInput.Event)
209 		{
210 		case EMIE_LMOUSE_PRESSED_DOWN:
211 			DragStart.X = event.MouseInput.X;
212 			DragStart.Y = event.MouseInput.Y;
213 
214 			if (getElementFromPoint(DragStart) == this)
215 			{
216 				if (!Environment->hasFocus(this))
217 				{
218 					Dragging = IsDraggable;
219 					//Environment->setFocus(this);
220 					if (Parent)
221 						Parent->bringToFront(this);
222 				}
223 				return true;
224 			}
225 			else
226 			{
227 				if (Panel->getAbsolutePosition().isPointInside(DragStart))
228 				{
229 					// select an image
230 					IGUIElement* el = Panel->getElementFromPoint(DragStart);
231 					if (el && el != Panel)
232 					{
233 						if (el->getType() == EGUIET_IMAGE)
234 						{
235 							setSelected(el->getID());
236 						}
237 					}
238 					else
239 					{
240 						setSelected();
241 					}
242 				}
243 			}
244 			break;
245 		case EMIE_LMOUSE_LEFT_UP:
246 			Dragging = false;
247 			//Environment->removeFocus(this);
248 			return true;
249 		case EMIE_MOUSE_MOVED:
250 			if (Dragging)
251 			{
252 				// gui window should not be dragged outside its parent
253 				if (Parent)
254 					if (event.MouseInput.X < Parent->getAbsolutePosition().UpperLeftCorner.X +1 ||
255 						event.MouseInput.Y < Parent->getAbsolutePosition().UpperLeftCorner.Y +1 ||
256 						event.MouseInput.X > Parent->getAbsolutePosition().LowerRightCorner.X -1 ||
257 						event.MouseInput.Y > Parent->getAbsolutePosition().LowerRightCorner.Y -1)
258 
259 						return true;
260 
261 
262 				move(core::position2d<s32>(event.MouseInput.X - DragStart.X, event.MouseInput.Y - DragStart.Y));
263 				DragStart.X = event.MouseInput.X;
264 				DragStart.Y = event.MouseInput.Y;
265 				return true;
266 			}
267 			break;
268 		default:
269 			break;
270 		}
271 	default:
272 		break;
273 	}
274 
275 	return Parent ? Parent->OnEvent(event) : false;
276 }
277 
setSelected(s32 index)278 void CGUITextureCacheBrowser::setSelected(s32 index)
279 {
280 	SelectedTexture = index;
281 	updateImageList();
282 	printf("Texture %d selected\n", index);
283 }
284 
draw()285 void CGUITextureCacheBrowser::draw()
286 {
287 	if (!IsVisible)
288 		return;
289 
290 	IGUISkin* skin = Environment->getSkin();
291 
292 	core::rect<s32> rect = AbsoluteRect;
293 	core::rect<s32> *cl = &AbsoluteClippingRect;
294 
295 	// draw body fast
296 	rect = skin->draw3DWindowBackground(this, true, skin->getColor(EGDC_ACTIVE_BORDER),
297 		AbsoluteRect, &AbsoluteClippingRect);
298 
299 	// draw window text
300 	if (Text.size())
301 	{
302 		rect.UpperLeftCorner.X += skin->getSize(EGDS_TEXT_DISTANCE_X);
303 		rect.UpperLeftCorner.Y += skin->getSize(EGDS_TEXT_DISTANCE_Y);
304 		rect.LowerRightCorner.X -= skin->getSize(EGDS_WINDOW_BUTTON_WIDTH) + 5;
305 
306 		IGUIFont* font = skin->getFont();
307 		if (font)
308 			font->draw(Text.c_str(), rect, skin->getColor(EGDC_ACTIVE_CAPTION), false, true, cl);
309 	}
310 
311 	IGUIElement::draw();
312 }
313 
314 
isDraggable() const315 bool CGUITextureCacheBrowser::isDraggable() const
316 {
317 	return IsDraggable;
318 }
319 
setDraggable(bool draggable)320 void CGUITextureCacheBrowser::setDraggable(bool draggable)
321 {
322 	IsDraggable = draggable;
323 
324 	if (Dragging && !IsDraggable)
325 		Dragging = false;
326 }
327 
328 
329 //! Returns the rectangle of the drawable area (without border, without titlebar and without scrollbars)
getClientRect() const330 core::rect<s32> CGUITextureCacheBrowser::getClientRect() const
331 {
332 	return core::recti();
333 }
334 
335 } // namespace gui
336 } // namespace irr
337