1 /*
2 Part of Minetest
3 Copyright (C) 2013 celeron55, Perttu Ahola <celeron55@gmail.com>
4 Copyright (C) 2013 Ciaran Gultnieks <ciaran@ciarang.com>
5 Copyright (C) 2013 RealBadAngel, Maciej Kasatkin <mk@realbadangel.pl>
6 
7 Permission to use, copy, modify, and distribute this software for any
8 purpose with or without fee is hereby granted, provided that the above
9 copyright notice and this permission notice appear in all copies.
10 
11 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19 
20 #include "guiVolumeChange.h"
21 #include "debug.h"
22 #include "guiButton.h"
23 #include "serialization.h"
24 #include <string>
25 #include <IGUICheckBox.h>
26 #include <IGUIButton.h>
27 #include <IGUIScrollBar.h>
28 #include <IGUIStaticText.h>
29 #include <IGUIFont.h>
30 #include "settings.h"
31 
32 #include "gettext.h"
33 
34 const int ID_soundText = 263;
35 const int ID_soundExitButton = 264;
36 const int ID_soundSlider = 265;
37 const int ID_soundMuteButton = 266;
38 
GUIVolumeChange(gui::IGUIEnvironment * env,gui::IGUIElement * parent,s32 id,IMenuManager * menumgr,ISimpleTextureSource * tsrc)39 GUIVolumeChange::GUIVolumeChange(gui::IGUIEnvironment* env,
40 		gui::IGUIElement* parent, s32 id,
41 		IMenuManager *menumgr, ISimpleTextureSource *tsrc
42 ):
43 	GUIModalMenu(env, parent, id, menumgr),
44 	m_tsrc(tsrc)
45 {
46 }
47 
~GUIVolumeChange()48 GUIVolumeChange::~GUIVolumeChange()
49 {
50 	removeChildren();
51 }
52 
removeChildren()53 void GUIVolumeChange::removeChildren()
54 {
55 	if (gui::IGUIElement *e = getElementFromId(ID_soundText))
56 		e->remove();
57 
58 	if (gui::IGUIElement *e = getElementFromId(ID_soundExitButton))
59 		e->remove();
60 
61 	if (gui::IGUIElement *e = getElementFromId(ID_soundSlider))
62 		e->remove();
63 
64 	if (gui::IGUIElement *e = getElementFromId(ID_soundMuteButton))
65 		e->remove();
66 }
67 
regenerateGui(v2u32 screensize)68 void GUIVolumeChange::regenerateGui(v2u32 screensize)
69 {
70 	/*
71 		Remove stuff
72 	*/
73 	removeChildren();
74 	/*
75 		Calculate new sizes and positions
76 	*/
77 	const float s = m_gui_scale;
78 	DesiredRect = core::rect<s32>(
79 		screensize.X / 2 - 380 * s / 2,
80 		screensize.Y / 2 - 200 * s / 2,
81 		screensize.X / 2 + 380 * s / 2,
82 		screensize.Y / 2 + 200 * s / 2
83 	);
84 	recalculateAbsolutePosition(false);
85 
86 	v2s32 size = DesiredRect.getSize();
87 	int volume = (int)(g_settings->getFloat("sound_volume") * 100);
88 
89 	/*
90 		Add stuff
91 	*/
92 	{
93 		core::rect<s32> rect(0, 0, 160 * s, 20 * s);
94 		rect = rect + v2s32(size.X / 2 - 80 * s, size.Y / 2 - 70 * s);
95 
96 		const wchar_t *text = wgettext("Sound Volume: ");
97 		core::stringw volume_text = text;
98 		delete [] text;
99 
100 		volume_text += core::stringw(volume) + core::stringw("%");
101 		Environment->addStaticText(volume_text.c_str(), rect, false,
102 				true, this, ID_soundText);
103 	}
104 	{
105 		core::rect<s32> rect(0, 0, 80 * s, 30 * s);
106 		rect = rect + v2s32(size.X / 2 - 80 * s / 2, size.Y / 2 + 55 * s);
107 		const wchar_t *text = wgettext("Exit");
108 		GUIButton::addButton(Environment, rect, m_tsrc, this, ID_soundExitButton, text);
109 		delete[] text;
110 	}
111 	{
112 		core::rect<s32> rect(0, 0, 300 * s, 20 * s);
113 		rect = rect + v2s32(size.X / 2 - 150 * s, size.Y / 2);
114 		gui::IGUIScrollBar *e = Environment->addScrollBar(true,
115 			rect, this, ID_soundSlider);
116 		e->setMax(100);
117 		e->setPos(volume);
118 	}
119 	{
120 		core::rect<s32> rect(0, 0, 160 * s, 20 * s);
121 		rect = rect + v2s32(size.X / 2 - 80 * s, size.Y / 2 - 35 * s);
122 		const wchar_t *text = wgettext("Muted");
123 		Environment->addCheckBox(g_settings->getBool("mute_sound"), rect, this,
124 				ID_soundMuteButton, text);
125 		delete[] text;
126 	}
127 }
128 
drawMenu()129 void GUIVolumeChange::drawMenu()
130 {
131 	gui::IGUISkin* skin = Environment->getSkin();
132 	if (!skin)
133 		return;
134 	video::IVideoDriver* driver = Environment->getVideoDriver();
135 	video::SColor bgcolor(140, 0, 0, 0);
136 	driver->draw2DRectangle(bgcolor, AbsoluteRect, &AbsoluteClippingRect);
137 	gui::IGUIElement::draw();
138 }
139 
OnEvent(const SEvent & event)140 bool GUIVolumeChange::OnEvent(const SEvent& event)
141 {
142 	if (event.EventType == EET_KEY_INPUT_EVENT) {
143 		if (event.KeyInput.Key == KEY_ESCAPE && event.KeyInput.PressedDown) {
144 			quitMenu();
145 			return true;
146 		}
147 
148 		if (event.KeyInput.Key == KEY_RETURN && event.KeyInput.PressedDown) {
149 			quitMenu();
150 			return true;
151 		}
152 	} else if (event.EventType == EET_GUI_EVENT) {
153 		if (event.GUIEvent.EventType == gui::EGET_CHECKBOX_CHANGED) {
154 			gui::IGUIElement *e = getElementFromId(ID_soundMuteButton);
155 			if (e != NULL && e->getType() == gui::EGUIET_CHECK_BOX) {
156 				g_settings->setBool("mute_sound", ((gui::IGUICheckBox*)e)->isChecked());
157 			}
158 
159 			Environment->setFocus(this);
160 			return true;
161 		}
162 
163 		if (event.GUIEvent.EventType == gui::EGET_BUTTON_CLICKED) {
164 			if (event.GUIEvent.Caller->getID() == ID_soundExitButton) {
165 				quitMenu();
166 				return true;
167 			}
168 			Environment->setFocus(this);
169 		}
170 
171 		if (event.GUIEvent.EventType == gui::EGET_ELEMENT_FOCUS_LOST
172 				&& isVisible()) {
173 			if (!canTakeFocus(event.GUIEvent.Element)) {
174 				infostream << "GUIVolumeChange: Not allowing focus change."
175 				<< std::endl;
176 				// Returning true disables focus change
177 				return true;
178 			}
179 		}
180 		if (event.GUIEvent.EventType == gui::EGET_SCROLL_BAR_CHANGED) {
181 			if (event.GUIEvent.Caller->getID() == ID_soundSlider) {
182 				s32 pos = ((gui::IGUIScrollBar*)event.GUIEvent.Caller)->getPos();
183 				g_settings->setFloat("sound_volume", (float) pos / 100);
184 
185 				gui::IGUIElement *e = getElementFromId(ID_soundText);
186 				const wchar_t *text = wgettext("Sound Volume: ");
187 				core::stringw volume_text = text;
188 				delete [] text;
189 
190 				volume_text += core::stringw(pos) + core::stringw("%");
191 				e->setText(volume_text.c_str());
192 				return true;
193 			}
194 		}
195 
196 	}
197 
198 	return Parent ? Parent->OnEvent(event) : false;
199 }
200