GUI parts for DISCO-F746NG. GuiBase, Button, ButtonGroup, ResetButton, Label, BlinkLabel, NumericLabel, SeekBar, SeekbarGroup, NumericUpDown

Dependencies:   Array_Matrix BSP_DISCO_F746NG LCD_DISCO_F746NG TS_DISCO_F746NG

Dependents:   F746_AudioOutQSPI F746_AudioPlayerSD DISCO-F746NG_test001 F746_SD_WavPlayer ... more

SeekBar.cpp

Committer:
MikamiUitOpen
Date:
2016-04-27
Revision:
10:5a2068884fd9
Parent:
9:c379410bda15
Child:
12:687ec6183385

File content as of revision 10:5a2068884fd9:

//-----------------------------------------------------------
//  SeekBar class
//
//  2016/04/27, Copyright (c) 2016 MIKAMI, Naoki
//-----------------------------------------------------------

#include "SeekBar.hpp"

namespace Mikami
{
    // Constructor with scale value (only horizontal)
    SeekBar::SeekBar(uint16_t x, uint16_t y, uint16_t length,
                     float min, float max, float initialValue,
                     string left, string center, string right,
                     uint32_t thumbColor,
                     uint16_t thumbSize, uint16_t width,
                     uint32_t colorL, uint32_t colorH,
                     uint32_t backColor)
        : GuiBase(x, y, Font12, GuiBase::ENUM_TEXT, backColor, thumbColor),
          L_(length), W_(width),
          SIZE_(thumbSize), COLOR_L_(colorL), COLOR_H_(colorH),
          MIN_(min), MAX_(max), ORIENT_(Holizontal),
          v_(initialValue), slided_(false), active_(true)
    {
        Draw(initialValue);
        labelL = new Label(x, y-28, left, Label::CENTER);
        labelC = new Label(x+length/2, y-28, center, Label::CENTER);
        labelR = new Label(x+length, y-28, right, Label::CENTER);
    }

    // Slide thumb
    //      If the thumb is not touched, return false
    bool SeekBar::Slide()
    {
        if (!active_) return false;

        if (!PanelTouched())
        {
            if (slided_) Draw(v_);
            slided_ = false;
            return false;
        }

        uint16_t x, y;
        bool rtn = IsOnThumb(x, y);
        if (rtn)
        {
            v_ = ToValue(Point(x, y));
            Draw(v_, true);
            slided_ = true;
        }

        return rtn;
    }

    void SeekBar::Activate()
    {
        active_ = true;
        Draw(v_);
        if (labelL != NULL)
        {
            labelL->Draw(TEXT_COLOR_); 
            labelC->Draw(TEXT_COLOR_); 
            labelR->Draw(TEXT_COLOR_); 
        }
    }

    void SeekBar::Inactivate()
    {
        active_ = false;
        Draw(v_);
        if (labelL != NULL)
        {
            labelL->Draw(INACTIVE_TEXT_COLOR_);
            labelC->Draw(INACTIVE_TEXT_COLOR_);
            labelR->Draw(INACTIVE_TEXT_COLOR_);
        }
    }

    // If touched position is on the thumb, return true
    bool SeekBar::IsOnThumb(uint16_t &x, uint16_t &y)
    {
        x = state_.touchX[0];
        y = state_.touchY[0];

        Point pt = ToPoint(v_);
        if (ORIENT_ == Holizontal)
        {
            if ( (pt.x-SIZE_/5 <= x) && (x <= pt.x+SIZE_/5) &&
                 (pt.y-SIZE_ <= y) && (y <= pt.y+SIZE_) ) return true;
        }
        else
        {
            if ( (pt.x-SIZE_ <= x) && (x <= pt.x+SIZE_) &&
                 (pt.y-SIZE_/5 <= y) && (y <= pt.y+SIZE_/5) ) return true;
        }

        return false;
    }

    // Draw seekbar
    void SeekBar::Draw(float value, bool fill)
    {
        uint16_t sizeS = (uint16_t)(SIZE_*0.6f);
        // Erase previous seekbar
        lcd_.SetTextColor(BACK_COLOR_);
        if (ORIENT_ == Holizontal)
            lcd_.FillRect(X_-sizeS/2, Y_-SIZE_/2, L_+sizeS+1, SIZE_+1);
        else
            lcd_.FillRect(X_-SIZE_/2, Y_-sizeS/2, SIZE_+1, L_+sizeS+1);

        v_ = Saturate(value);       // current value
        Point pt = ToPoint(v_);     // Position of thumb

        // Draw upper line
        if (active_) lcd_.SetTextColor(COLOR_H_);
        else         lcd_.SetTextColor(INACTIVE_TEXT_COLOR_-0x404040);
        if (ORIENT_ == Holizontal)
            lcd_.FillRect(pt.x, Y_-W_/4, X_+L_-pt.x, W_/2);
        else
            lcd_.FillRect(X_-W_/4, Y_, W_/2, pt.y-Y_);

        // Draw lower line
        if (active_) lcd_.SetTextColor(COLOR_L_);
        else         lcd_.SetTextColor(INACTIVE_TEXT_COLOR_-0x202020);
        if ((ORIENT_ == Holizontal) && ((pt.x-X_) > 0))
            lcd_.FillRect(X_, Y_-W_/2, pt.x-X_, W_);
        if ((ORIENT_ == Vertical) && ((Y_+L_-pt.y) > 0))
            lcd_.FillRect(X_-W_/2, pt.y, W_, Y_+L_-pt.y);

        // Draw thumb
        if (active_) lcd_.SetTextColor(CREATED_COLOR_);
        else         lcd_.SetTextColor(INACTIVE_TEXT_COLOR_);
        uint16_t width = SIZE_;
        uint16_t height = SIZE_;
        if (ORIENT_ == Holizontal) width = sizeS;
        else                       height = sizeS;
        uint16_t xPos = pt.x - width/2;
        uint16_t yPos = pt.y - height/2;
        
        if (fill)
            lcd_.FillRect(xPos, yPos, width+1, height+1);
        else
        {
            lcd_.DrawRect(xPos, yPos, width, height);
            lcd_.DrawHLine(pt.x+width/2, pt.y+height/2, 1);
            if (v_ == MAX_) lcd_.DrawHLine(xPos, yPos, width);  // should not be necessary
            if (ORIENT_ == Holizontal)
                lcd_.DrawVLine(pt.x, yPos+3, SIZE_-5);
            else
                lcd_.DrawHLine(xPos+3, pt.y, SIZE_-5);
        }
    }

    SeekBar::Point SeekBar::ToPoint(float value)
    {
        if (ORIENT_ == Holizontal)
            return Point(X_ + Round(L_*(value - MIN_)/(MAX_ - MIN_)), Y_);
        else
            return Point(X_, Y_ + L_ - Round(L_*(value - MIN_)/(MAX_ - MIN_)));
    }

    float SeekBar::ToValue(Point pt)
    {
        float value;
        if (ORIENT_ == Holizontal)
            value = (pt.x - X_)*(MAX_ - MIN_)/(float)L_ + MIN_;
        else
            value = -(pt.y - Y_ - L_)*(MAX_ - MIN_)/(float)L_ + MIN_;
        return Saturate(value);
    }

    float SeekBar::Saturate(float value)
    {
        if (value < MIN_) value = MIN_;
        if (value > MAX_) value = MAX_;
        return value;
    }
}