/* orxonox - the future of 3D-vertical-scrollers Copyright (C) 2004 orx This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. ### File Specific: main-programmer: Benjamin Grauer co-programmer: ... */ #define DEBUG_SPECIAL_MODULE DEBUG_MODULE_GUI #include "glgui_slider.h" #include "event_def.h" #include "glgui_handler.h" namespace OrxGui { ObjectListDefinition(GLGuiSlider); /** * @brief standard constructor */ GLGuiSlider::GLGuiSlider () { this->init(); } /** * @brief standard deconstructor */ GLGuiSlider::~GLGuiSlider() {} /** * @brief initializes the GUI-element */ void GLGuiSlider::init() { this->registerObject(this, GLGuiSlider::_objectList); this->setClickable(true); this->setFocusable(true); this->setSelectable(true); this->_value = 0.0; this->_minValue = 0.0; this->_maxValue = 1.0; this->_step = 0.1; this->_sliderWidth = 5.0; this->grabbed = false; this->setSize2D(100, 30); this->resize(); } /** * @param value the new Value. * @note will automatically be set between max() and min() */ void GLGuiSlider::setValue(float value) { if (value < this->min()) this->_value = min(); else if (value > max()) this->_value = max(); else this->_value = value; this->_handle.setCenter(this->sliderPosition(), borderTop() + (this->getSizeY2D() - borderTop() - borderBottom()) / 2.0); valueChanged.emit(this->_value); } /** * @param minimum the minumum of the range. * * @note will rearange value if necessary and will not be made bigger than max() */ void GLGuiSlider::setMin(float minimum) { if (minimum <= max()) { this->_minValue = minimum; rangeChanged.emit(this->_minValue, this->_maxValue); } if (this->value() < this->min()) this->setValue(this->min()); } /** * @param maximum the maximum of the range. * * @note will rearange value if necessary and will not be made smaller than min() */ void GLGuiSlider::setMax(float maximum) { if (maximum >= min()) { this->_maxValue = maximum; rangeChanged.emit(this->_minValue, this->_maxValue); } if (this->value() > this->max()) this->setValue(this->max()); } /** * @param minimum the minimum * @param maximum the maximum * * @see setMax * @see setMin */ void GLGuiSlider::setRange(float minimum, float maximum) { if (minimum < maximum) { this->_minValue = minimum; this->_maxValue = maximum; rangeChanged.emit(this->_minValue, this->_maxValue); } if (this->value() < this->min()) this->setValue(this->min()); else if (this->value() > this->max()) this->setValue(this->max()); } /** * @brief sets the stepSize */ void GLGuiSlider::setStep(float step) { this->_step = step; } /** * @brief makes one step into the minus direction */ void GLGuiSlider::stepMinus() { this->setValue(value() - step()); } /** * @brief makes one step into the minus direction */ void GLGuiSlider::stepPlus() { this->setValue(value() + step()); } /** * @brief resizes the Slider, and through this Synchronizes the GUI-size. */ void GLGuiSlider::resize() { GLGuiWidget::resize(); // this->frontRect().setTopLeft(this->borderLeft(), this->getSizeY2D()/2.0 - 2.0); // this->frontRect().setSize(this->getSizeX2D() - borderLeft() - borderRight(), 4.0); this->_slider.setTopLeft(borderLeft(), this->getSizeY2D() / 2.0 -2.0); this->_slider.setSize(this->getSizeX2D() - borderLeft() - borderRight(), 4.0); this->_handle.setSize(this->_sliderWidth, this->getSizeY2D() - borderTop() - borderBottom()); } void GLGuiSlider::updateFrontColor() { } /** * @brief handle the clicked event. * @param pos the position the Click occured (from the topleft corner out) */ void GLGuiSlider::clicking(const Vector2D& pos) { GLGuiWidget::clicking(pos); float sliderPosition = this->sliderPosition(); if (sliderPosition > pos.x + this->_sliderWidth) this->setValue(this->value() - this->step()); else if (sliderPosition < pos.x - this->_sliderWidth) this->setValue(this->value() + this->step()); else this->grabbed = true; } void GLGuiSlider::releasing(const Vector2D& pos, bool focused) { GLGuiWidget::releasing(pos, focused); this->grabbed = false; } void GLGuiSlider::removedFocus() { GLGuiWidget::removedFocus(); } /** * @returns the current SliderPosition calculated from the current value and the Silders' size. */ float GLGuiSlider::sliderPosition() const { return (this->_value - this->_minValue)/( this->_maxValue - this->_minValue) * (this->getSizeX2D() - (borderLeft() + borderRight() + 2.0*_sliderWidth)) + (borderLeft() +_sliderWidth); } /** * @param position the position relative from the left border. * @returns the Value at the given position. */ float GLGuiSlider::sliderValue(float position) const { return (position - (borderLeft()+_sliderWidth)) / (this->getSizeX2D() - (borderLeft() + borderRight() + 2.0*_sliderWidth)) *( this->_maxValue - this->_minValue) + this->_minValue ; } void GLGuiSlider::tick(float dt) { GLGuiWidget::tick(dt); } /** * @brief draws the GLGuiSlider */ void GLGuiSlider::draw() const { this->beginDraw(); GLGuiWidget::draw(); glColor4fv(&this->foregroundColor()[0]); this->drawRect(this->_slider); this->drawRect(this->_handle); //this->drawRect(Rect2D(this->sliderPosition()-_sliderWidth/2.0, 0*this->borderTop(), _sliderWidth, this->getSizeY2D() - (borderTop() + borderBottom()) )); this->endDraw(); } bool GLGuiSlider::processEvent( const Event& event ) { if (this->grabbed && event.type == EV_MOUSE_MOTION) { this->setValue(sliderValue(GLGuiHandler::getInstance()->cursorPositionRel(this).x)); return true; } else if (event.bPressed) { if (event.type == SDLK_LEFT) { this->stepMinus(); return true; } else if (event.type == SDLK_RIGHT) { this->stepPlus(); return true; } } return false; } }