1
0
mirror of https://github.com/vcmi/vcmi.git synced 2024-12-24 22:14:36 +02:00

Buttons: Add CVolumeSlider widget

New widget specifically for volume settings.
Replace previous implementation using 10 toggle buttons.
Enable indicator animation
Fix indicator ghosting when drag and releasing
Add scroll capability to volume
Volume now can be adjusted from 0 - 99 with the mouse or the scroll wheel
This commit is contained in:
Sandy Carter 2015-08-21 22:45:31 -04:00
parent c6b51a7beb
commit 9d62a2f0a1
3 changed files with 108 additions and 2 deletions

View File

@ -419,8 +419,6 @@ int main(int argc, char** argv)
#endif // defined
//initializing audio
// Note: because of interface button range, volume can only be a
// multiple of 11, from 0 to 99.
CCS->soundh = new CSoundHandler;
CCS->soundh->init();
CCS->soundh->setVolume(settings["general"]["sound"].Float());

View File

@ -469,6 +469,88 @@ void CToggleGroup::showAll(SDL_Surface * to)
CIntObject::showAll(to);
}
CVolumeSlider::CVolumeSlider(const Point &position, const std::string &defName, const int value,
const std::pair<std::string, std::string> * const help) :
value(value),
helpHandlers(help)
{
OBJ_CONSTRUCTION_CAPTURING_ALL;
animImage = new CAnimImage(new CAnimation(defName), 0, 0, position.x, position.y),
assert(!defName.empty());
addUsedEvents(LCLICK | RCLICK | WHEEL);
pos.x += position.x;
pos.y += position.y;
pos.w = (animImage->pos.w + 1) * animImage->size();
pos.h = animImage->pos.h;
type |= REDRAW_PARENT;
setVolume(value);
}
void CVolumeSlider::setVolume(int value_)
{
value = value_;
moveTo(value * static_cast<double>(animImage->size()) / 100.0);
}
void CVolumeSlider::moveTo(int id)
{
vstd::abetween(id, 0, animImage->size() - 1);
animImage->setFrame(id);
animImage->moveTo(Point(pos.x + (animImage->pos.w + 1) * id, pos.y));
if (active)
redraw();
}
void CVolumeSlider::addCallback(std::function<void(int)> callback)
{
onChange += callback;
}
void CVolumeSlider::clickLeft(tribool down, bool previousState)
{
if (down)
{
double px = GH.current->motion.x - pos.x;
double rx = px / static_cast<double>(pos.w);
// setVolume is out of 100
setVolume(rx * 100);
// Volume config is out of 100, set to increments of 5ish roughly based on the half point of the indicator
// 0.0 -> 0, 0.05 -> 5, 0.09 -> 5,...,
// 0.1 -> 10, ..., 0.19 -> 15, 0.2 -> 20, ...,
// 0.28 -> 25, 0.29 -> 30, 0.3 -> 30, ...,
// 0.85 -> 85, 0.86 -> 90, ..., 0.87 -> 90,...,
// 0.95 -> 95, 0.96 -> 100, 0.99 -> 100
int volume = 5 * int(rx * (2 * animImage->size() + 1));
onChange(volume);
}
}
void CVolumeSlider::clickRight(tribool down, bool previousState)
{
if (down)
{
double px = GH.current->motion.x - pos.x;
int index = px / static_cast<double>(pos.w) * animImage->size();
std::string hoverText = helpHandlers[index].first;
std::string helpBox = helpHandlers[index].second;
if(!helpBox.empty())
CRClickPopup::createAndPush(helpBox);
if(GH.statusbar)
GH.statusbar->setText(helpBox);
}
}
void CVolumeSlider::wheelScrolled(bool down, bool in)
{
if (in)
{
int volume = value + 3 * (down ? 1 : -1);
vstd::abetween(volume, 0, 100);
setVolume(volume);
onChange(volume);
}
}
void CSlider::sliderClicked()
{
if(!(active & MOVE))

View File

@ -196,6 +196,32 @@ public:
void showAll(SDL_Surface * to);
};
/// A typical slider for volume with an animated indicator
class CVolumeSlider : public CIntObject
{
int value;
CFunctionList<void(int)> onChange;
CAnimImage * animImage;
const std::pair<std::string, std::string> * const helpHandlers;
void setVolume(const int v);
public:
/// @param position coordinates of slider
/// @param defName name of def animation for slider
/// @param value initial value for volume
/// @param help pointer to first helptext of slider
CVolumeSlider(const Point &position, const std::string &defName, const int value,
const std::pair<std::string, std::string> * const help);
void moveTo(int id);
void addCallback(std::function<void(int)> callback);
void clickLeft(tribool down, bool previousState) override;
void clickRight(tribool down, bool previousState) override;
void wheelScrolled(bool down, bool in);
};
/// A typical slider which can be orientated horizontally/vertically.
class CSlider : public CIntObject
{