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

Files at this revision

API Documentation at this revision

Comitter:
MikamiUitOpen
Date:
Thu Mar 31 07:28:42 2016 +0000
Child:
1:d1655f3c8717
Commit message:
1

Changed in this revision

Button.cpp Show annotated file Show diff for this revision Revisions of this file
Button.hpp Show annotated file Show diff for this revision Revisions of this file
ButtonGroup.cpp Show annotated file Show diff for this revision Revisions of this file
ButtonGroup.hpp Show annotated file Show diff for this revision Revisions of this file
GuiBase.cpp Show annotated file Show diff for this revision Revisions of this file
GuiBase.hpp Show annotated file Show diff for this revision Revisions of this file
Label.cpp Show annotated file Show diff for this revision Revisions of this file
Label.hpp Show annotated file Show diff for this revision Revisions of this file
NumericLabel.hpp Show annotated file Show diff for this revision Revisions of this file
SeekBar.cpp Show annotated file Show diff for this revision Revisions of this file
SeekBar.hpp Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Button.cpp	Thu Mar 31 07:28:42 2016 +0000
@@ -0,0 +1,66 @@
+//-----------------------------------------------------------
+//  Button class handling multi-touch
+//      Multi-touch: Enabled (default)
+//
+//  2016/03/29, Copyright (c) 2016 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#include "Button.hpp"
+
+namespace Mikami
+{
+    // Draw button
+    void Button::Draw(uint32_t color, uint32_t textColor)
+    {
+        if (!active_) return;
+        lcd_.SetTextColor(color);
+        lcd_.FillRect(X_, Y_, W_, H_);
+
+        if (STR_.length() != 0)
+        {
+            lcd_.SetFont(FONTS_);
+            lcd_.SetBackColor(color);
+            lcd_.SetTextColor(textColor);
+            uint16_t x0 = X_ + (W_ - FONTS_->Width*(STR_.length()))/2;
+            uint16_t y0 = Y_ + (H_ - FONTS_->Height)/2 + 1;
+            DrawString(x0, y0, STR_);
+            lcd_.SetBackColor(BACK_COLOR_);  // recover back color
+        }            
+    }
+
+    // Check touch detected
+    bool Button::Touched()
+    {
+        if (!active_) return false;
+        if (!PanelTouched()) return false;
+        if (!IsOnButton()) return false;
+        Draw(TOUCHED_COLOR_, TEXT_COLOR_);
+        return true;
+    }
+
+    // If touched position is on the button, return true
+    bool Button::IsOnButton()
+    {
+        int nTouch = multiTouch_ ? state_.touchDetected : 1;
+        for (int n=0; n<nTouch; n++)
+        {
+            uint16_t x = state_.touchX[n];
+            uint16_t y = state_.touchY[n];
+            if ( (X_ <= x) && (x <= X_+W_) &&
+                 (Y_ <= y) && (y <= Y_+H_) ) return true;
+        }
+        return false;
+    }
+
+    void Button::Activate()
+    {
+        active_ = true;
+        Draw();
+    }
+
+    void Button::Inactivate()
+    {
+        Draw(INACTIVE_COLOR_, INACTIVE_TEXT_COLOR_);
+        active_ = false;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Button.hpp	Thu Mar 31 07:28:42 2016 +0000
@@ -0,0 +1,65 @@
+//-----------------------------------------------------------
+//  Button class handling multi-touch -- Header
+//      Multi-touch: Enabled (default)
+//
+//  2016/03/29, Copyright (c) 2016 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#ifndef F746_BUTTON_HPP
+#define F746_BUTTON_HPP
+
+#include "GuiBase.hpp"
+
+namespace Mikami
+{
+    class Button : public GuiBase
+    {
+    public:
+        // Constructor
+        Button(uint16_t x, uint16_t y,
+               uint16_t width, uint16_t height,
+               const string str = "", sFONT &fonts = Font12,
+               uint32_t textColor         = GuiBase::ENUM_TEXT,
+               uint32_t backColor         = GuiBase::ENUM_BACK,
+               uint32_t createdColor      = GuiBase::ENUM_CREATED,
+               uint32_t touchedColor      = GuiBase::ENUM_TOUCHED,
+               uint32_t inactiveColor     = GuiBase::ENUM_INACTIVE,
+               uint32_t inactiveTextColor = GuiBase::ENUM_INACTIVE_TEXT)
+              : GuiBase(x, y, fonts,
+                        textColor, backColor, createdColor,
+                        touchedColor, inactiveColor,
+                        inactiveTextColor),
+                W_(width), H_(height), STR_(str), active_(true)
+        {   Draw(); }
+
+        // Draw button
+        void Draw(uint32_t color, uint32_t textColor);
+        void Draw(uint32_t color) { Draw(color, TEXT_COLOR_); }
+        void Draw() { Draw(CREATED_COLOR_, TEXT_COLOR_); }
+
+        // Erase button
+        void Erase() { Draw(BACK_COLOR_, BACK_COLOR_); }
+
+        // Check touch detected and redraw button
+        bool Touched();
+
+        bool IsOnButton();
+
+        void Activate();
+        void Inactivate();
+        bool IsActive() { return active_; }
+
+        // Set or reset multi-touch
+        static void SetMultiTouch(bool tf) { multiTouch_ = tf; }
+
+    private:       
+        const uint16_t W_, H_;
+        const string STR_;
+        bool active_;
+
+        // disallow copy constructor and assignment operator
+        Button(const Button&);
+        Button& operator=(const Button&);
+    };
+}
+#endif  // F746_BUTTON_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ButtonGroup.cpp	Thu Mar 31 07:28:42 2016 +0000
@@ -0,0 +1,116 @@
+//-----------------------------------------------------------
+//  ButtonGroup class
+//
+//  2016/03/31, Copyright (c) 2016 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#include "ButtonGroup.hpp"
+
+namespace Mikami
+{
+    // Constructor
+    ButtonGroup::ButtonGroup(
+            uint16_t x0, uint16_t y0,
+            uint16_t width, uint16_t height,
+            uint16_t number, const string str[],
+            uint16_t spaceX, uint16_t spaceY,
+            uint16_t column, int touched,
+            sFONT &fonts,
+            uint32_t textColor, uint32_t backColor,
+            uint32_t createdColor, uint32_t touchedColor,
+            uint32_t inactiveColor, uint32_t inactiveTextColor)
+        : GuiBase(x0, y0, fonts, textColor, backColor,
+                  createdColor, touchedColor,
+                  inactiveColor, inactiveTextColor),
+          numberOfButtons_(number), prevNum_(touched)
+    {
+        buttons_ = new Button *[number];
+        for (int n=0; n<number; n++)
+        {
+            div_t u1 = div(n, column);
+            uint16_t x = x0 + u1.rem*(width + spaceX);
+            uint16_t y = y0 + u1.quot*(height + spaceY);
+            buttons_[n] =
+                new Button(x, y, width, height, str[n], fonts,
+                           TEXT_COLOR_, BACK_COLOR_,
+                           CREATED_COLOR_, TOUCHED_COLOR_,
+                           INACTIVE_COLOR_, INACTIVE_TEXT_COLOR_);
+        }
+        // On created, set touched color
+        if (touched >= 0) DrawTouched(touched);
+    }
+
+    // Destructor
+    ButtonGroup::~ButtonGroup()
+    {
+        for (int n=0; n<numberOfButtons_; n++) delete buttons_[n];
+        delete[] *buttons_;   
+    }
+
+    // Draw button
+    bool ButtonGroup::Draw(int num, uint32_t color, uint32_t textColor)
+    {
+        if (!Range(num)) return false;
+        buttons_[num]->Draw(color, textColor);
+        return true;
+    }
+
+    // Erase button with selected color
+    bool ButtonGroup::Erase(int num)
+    {
+        if (!Range(num)) return false;
+        buttons_[num]->Erase();
+        return true;
+    }
+
+    // Check touch detected for specified button
+    bool ButtonGroup::Touched(int num)
+    {
+        if (!Range(num)) return false;
+        if (!buttons_[num]->IsActive()) return false;
+        int touched;
+        if (!GetTouchedNumber(touched)) return false;
+        bool rtn = (touched == num) ? true : false;
+        return rtn;
+    }
+
+    // Get touched number
+    bool ButtonGroup::GetTouchedNumber(int &num)
+    {
+        bool rtn = false;
+        if (PanelTouched())
+        {
+            for (int n=0; n<numberOfButtons_; n++)
+                if (buttons_[n]->IsOnButton() &&
+                    buttons_[n]->IsActive())
+                {
+                    num = n;
+                    rtn = true;
+                }
+            
+            if (!rtn) return false;
+        }
+        else
+            return false;
+
+        buttons_[num]->Draw(TOUCHED_COLOR_);
+        if ((prevNum_ >= 0) && (prevNum_ != num))
+            buttons_[prevNum_]->Draw();
+        if (prevNum_ != num) prevNum_ = num;
+        return true;
+    }
+
+    // Activate and inactivate
+    bool ButtonGroup::Activate(int num)
+    {
+        if (!Range(num)) return false;
+        buttons_[num]->Activate();
+        return true;
+    }
+    bool ButtonGroup::Inactivate(int num)
+    {
+        if (!Range(num)) return false;
+        buttons_[num]->Inactivate();
+        return true;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ButtonGroup.hpp	Thu Mar 31 07:28:42 2016 +0000
@@ -0,0 +1,77 @@
+//-----------------------------------------------------------
+//  ButtonGroup class -- Header
+//
+//  2016/03/31, Copyright (c) 2016 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#ifndef F746_BUTTON_GROUP_HPP
+#define F746_BUTTON_GROUP_HPP
+
+#include "Button.hpp"
+
+namespace Mikami
+{
+    class ButtonGroup : public GuiBase
+    {
+    public:
+        // Constructor
+        ButtonGroup(uint16_t x0, uint16_t y0,
+                    uint16_t width, uint16_t height,
+                    uint16_t number, const string str[],
+                    uint16_t spaceX = 0, uint16_t spaceY = 0,
+                    uint16_t column = 1,
+                    int touched = -1,   // number for button initially touched-color
+                    sFONT &fonts = Font12,
+                    uint32_t textColor         = GuiBase::ENUM_TEXT,
+                    uint32_t backColor         = GuiBase::ENUM_BACK,
+                    uint32_t createdColor      = GuiBase::ENUM_CREATED,
+                    uint32_t touchedColor      = GuiBase::ENUM_TOUCHED,
+                    uint32_t inactiveColor     = GuiBase::ENUM_INACTIVE,
+                    uint32_t inactiveTextColor = GuiBase::ENUM_INACTIVE_TEXT);
+
+        // Destructor
+        ~ButtonGroup();
+
+        // Draw button
+        bool Draw(int num, uint32_t color, uint32_t textColor);
+        bool Draw(int num) { return Draw(num, CREATED_COLOR_, TEXT_COLOR_); }
+
+        // Draw with touched color
+        bool DrawTouched(int num) { return Draw(num, TOUCHED_COLOR_, TEXT_COLOR_); }
+
+        // Draw all buttons
+        void DrawAll(uint32_t color, uint32_t textColor)
+        {
+            for (int n=0; n<numberOfButtons_; n++)
+                buttons_[n]->Draw(color, textColor);
+        }
+        void DrawAll() { DrawAll(CREATED_COLOR_, TEXT_COLOR_); }
+
+        // Erase button with selected color
+        bool Erase(int num);
+
+        // Check touch detected for specified button
+        bool Touched(int num);
+
+        // Get touched number
+        bool GetTouchedNumber(int &num);
+
+        // Activate and inactivate
+        bool Activate(int num);
+        bool Inactivate(int num);
+
+    private:
+        Button **buttons_;
+        int numberOfButtons_;
+        __IO int prevNum_;
+
+        // Check range of argument
+        bool Range(int n)
+        { return ((n >= 0) && (n < numberOfButtons_)); }
+
+        // disallow copy constructor and assignment operator
+        ButtonGroup(const ButtonGroup&);
+        ButtonGroup& operator=(const ButtonGroup&);
+    };
+}
+#endif  // F746_BUTTON_GROUP_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GuiBase.cpp	Thu Mar 31 07:28:42 2016 +0000
@@ -0,0 +1,44 @@
+//-----------------------------------------------------------
+//  GuiBase class (abstract base class)
+//
+//  2016/03/29, Copyright (c) 2016 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#include "GuiBase.hpp"
+
+namespace Mikami
+{
+    GuiBase::GuiBase(
+        uint16_t x, uint16_t y, sFONT &fonts,
+        uint32_t textColor, uint32_t backColor,
+        uint32_t createdColor, uint32_t touchedColor,
+        uint32_t inactiveColor, uint32_t inactiveTextColor)
+        : X_(x), Y_(y), FONTS_(&fonts),
+          TEXT_COLOR_(textColor), BACK_COLOR_(backColor),
+          CREATED_COLOR_(createdColor),
+          TOUCHED_COLOR_(touchedColor),
+          INACTIVE_COLOR_(inactiveColor),
+          INACTIVE_TEXT_COLOR_(inactiveTextColor)
+    {
+        if (first_)
+        {
+            lcd_.Clear(backColor);
+            first_ = false;
+        }
+    }
+
+    // If panel touched, return true
+    bool GuiBase::PanelTouched()
+    {
+        ts_.GetState(&state_);
+        return (bool)(state_.touchDetected);
+    }
+
+    LCD_DISCO_F746NG GuiBase::lcd_;
+    TS_DISCO_F746NG GuiBase::ts_;
+
+    TS_StateTypeDef GuiBase::state_;
+
+    bool GuiBase::multiTouch_ = false;
+    bool GuiBase::first_ = true;
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/GuiBase.hpp	Thu Mar 31 07:28:42 2016 +0000
@@ -0,0 +1,70 @@
+//-----------------------------------------------------------
+//  GuiBase class (abstract base class) ---- Header
+//      
+//  2016/03/30, Copyright (c) 2016 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#ifndef F746_GUI_BASE_HPP
+#define F746_GUI_BASE_HPP
+
+#include "mbed.h"
+#include <string>
+#include "TS_DISCO_F746NG.h"
+#include "LCD_DISCO_F746NG.h"
+
+namespace Mikami
+{
+    class GuiBase
+    {
+    public:                    
+        static LCD_DISCO_F746NG* GetLcdPtr() { return &lcd_; }
+        static TS_DISCO_F746NG* GetTsPtr() { return &ts_; }
+
+        // If panel touched, return true
+        static bool PanelTouched();
+        // Get touch panel state
+        static TS_StateTypeDef GetTsState() { return state_; }
+
+        enum { ENUM_TEXT = 0xFFFFFFFF, ENUM_BACK = 0xFF003538,
+               ENUM_CREATED = 0xFF0068B7, ENUM_TOUCHED = 0xFF7F7FFF,
+               ENUM_INACTIVE = 0xD0003538, ENUM_INACTIVE_TEXT = 0xFF808080};
+
+    protected:
+        static LCD_DISCO_F746NG lcd_;  // Pointer of object for LCD display
+        static TS_DISCO_F746NG ts_;    // Pointer of object for touch pannel
+
+        static TS_StateTypeDef state_;
+        static bool multiTouch_;
+
+        const uint16_t X_, Y_;
+        sFONT *const FONTS_;
+
+        const uint32_t TEXT_COLOR_;
+        const uint32_t BACK_COLOR_;
+        const uint32_t CREATED_COLOR_;
+        const uint32_t TOUCHED_COLOR_;
+        const uint32_t INACTIVE_COLOR_;
+        const uint32_t INACTIVE_TEXT_COLOR_;
+
+        // Constructor
+        GuiBase(uint16_t x =0, uint16_t y =0,
+                sFONT &fonts = Font12,
+                uint32_t textColor         = GuiBase::ENUM_TEXT,
+                uint32_t backColor         = GuiBase::ENUM_BACK,
+                uint32_t createdColor      = GuiBase::ENUM_CREATED,
+                uint32_t touchedColor      = GuiBase::ENUM_TOUCHED,
+                uint32_t inactiveColor     = GuiBase::ENUM_INACTIVE,
+                uint32_t inactiveTextColor = GuiBase::ENUM_INACTIVE_TEXT);
+
+        void DrawString(uint16_t x, uint16_t y, const string str)
+        { lcd_.DisplayStringAt(x, y, (uint8_t *)str.c_str(), LEFT_MODE); }
+
+    private:
+        static bool first_;
+        
+        // disallow copy constructor and assignment operator
+        GuiBase(const GuiBase&);
+        GuiBase& operator=(const GuiBase&);
+    };
+}
+#endif  // F746_GUI_BASE_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Label.cpp	Thu Mar 31 07:28:42 2016 +0000
@@ -0,0 +1,38 @@
+//-----------------------------------------------------------
+//  Label class
+//
+//  2016/03/29, Copyright (c) 2016 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#include "Label.hpp"
+
+namespace Mikami
+{
+    // Constructor
+    Label::Label(uint16_t x, uint16_t y,
+                 const string str, TextAlignMode mode, sFONT &fonts,
+                 uint32_t textColor, uint32_t backColor)
+        : GuiBase(x, y, fonts, textColor, backColor),
+          MODE_(mode)
+    {
+        length_ = str.length();
+        lcd_.SetBackColor(backColor);
+        lcd_.SetTextColor(textColor);
+        lcd_.SetFont(&fonts);
+        DrawString(PosX(x), y, str);
+    }
+
+    void Label::Draw(const string str)
+    {
+        // Erase previously-drawn string
+        lcd_.SetTextColor(BACK_COLOR_);
+        length_ = (length_ > str.length()) ? length_ : str.length();
+        lcd_.FillRect(PosX(X_), Y_, FONTS_->Width*length_+1, FONTS_->Height);
+        lcd_.SetTextColor(TEXT_COLOR_);
+
+        // Draw new string
+        length_ = str.length();
+        lcd_.SetFont(FONTS_);
+        DrawString(PosX(X_), Y_, str);
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/Label.hpp	Thu Mar 31 07:28:42 2016 +0000
@@ -0,0 +1,41 @@
+//-----------------------------------------------------------
+//  Label class -- Header
+//
+//  2016/03/28, Copyright (c) 2016 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#ifndef F746_LABEL_HPP
+#define F746_LABEL_HPP
+
+#include "GuiBase.hpp"
+
+namespace Mikami
+{
+    class Label : public GuiBase
+    {
+    public:
+        enum TextAlignMode { LEFT, CENTER };
+        // Constructor
+        Label(uint16_t x, uint16_t y, const string str,
+              TextAlignMode mode = LEFT,
+              sFONT &fonts = Font12,
+              uint32_t textColor = GuiBase::ENUM_TEXT,
+              uint32_t backColor = GuiBase::ENUM_BACK);
+
+        void Draw(const string str);
+
+    private:
+        const TextAlignMode MODE_;
+
+        uint8_t length_;
+
+        uint16_t PosX(uint16_t x)
+        {   return (MODE_ == LEFT) ?
+                   x : x - length_*FONTS_->Width/2; }
+
+        // disallow copy constructor and assignment operator
+        Label(const Label&);
+        Label& operator=(const Label&);
+    };
+}
+#endif  // F746_LABEL_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/NumericLabel.hpp	Thu Mar 31 07:28:42 2016 +0000
@@ -0,0 +1,49 @@
+//-----------------------------------------------------------
+//  NumericLabel class -- derived class of Label class
+//
+//  2016/03/29, Copyright (c) 2016 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#ifndef F746_NUMERIC_LABEL_HPP
+#define F746_NUMERIC_LABEL_HPP
+
+#include "Label.hpp"
+
+namespace Mikami
+{
+    template <typename T> class NumericLabel : public Label
+    {
+    public:
+        // Constructor without drawing value
+        NumericLabel(uint16_t x, uint16_t y,
+                     TextAlignMode mode = Label::LEFT,
+                     sFONT &fonts = Font12,
+                     uint32_t textColor = GuiBase::ENUM_TEXT,
+                     uint32_t backColor = GuiBase::ENUM_BACK)
+            : Label(x, y, "", mode, fonts, textColor, backColor) {}
+
+        // Constructor with drawing value
+        NumericLabel(uint16_t x, uint16_t y,
+                     const char fmt[], T val,
+                     TextAlignMode mode = Label::LEFT,
+                     sFONT &fonts = Font12,
+                     uint32_t textColor = GuiBase::ENUM_TEXT,
+                     uint32_t backColor = GuiBase::ENUM_BACK)
+            : Label(x, y, "", mode, fonts, textColor, backColor)
+        {   Draw(fmt, val); }
+
+        // Draw value
+        void Draw(const char fmt[], T val)
+        {
+            char str[81];
+            sprintf(str, fmt, val);
+            Label::Draw(str);
+        }
+
+    private:
+        // disallow copy constructor and assignment operator
+        NumericLabel(const NumericLabel&);
+        NumericLabel& operator=(const NumericLabel&);
+    };
+}
+#endif  // F746_NUMERIC_LABEL_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SeekBar.cpp	Thu Mar 31 07:28:42 2016 +0000
@@ -0,0 +1,113 @@
+//-----------------------------------------------------------
+//  SeekBar class
+//
+//  2016/03/29, Copyright (c) 2016 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#include "SeekBar.hpp"
+
+namespace Mikami
+{
+    // Slide thumb
+    //      If the thumb is not touched, return false
+    bool SeekBar::Slide()
+    {
+        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;
+    }
+
+    // Draw seekbar
+    void SeekBar::Draw(float value, bool fill)
+    {
+        // Erase previous seekbar
+        lcd_.SetTextColor(BACK_COLOR_);
+        if (ORIENT_ == Holizontal)
+            lcd_.FillRect(X_-SIZE_/2, Y_-SIZE_/2, L_+SIZE_+1, SIZE_+1);
+        else
+            lcd_.FillRect(X_-SIZE_/2, Y_-SIZE_/2, SIZE_+1, L_+SIZE_+1);
+ 
+        Point pt = ToPoint(Saturate(value));    // Position of thumb
+
+        // Draw upper line
+        lcd_.SetTextColor(COLOR_H_);
+        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
+        lcd_.SetTextColor(COLOR_L_);
+        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
+        lcd_.SetTextColor(CREATED_COLOR_);
+        if (fill)
+            lcd_.FillCircle(pt.x, pt.y, SIZE_/2);
+        else
+            lcd_.DrawCircle(pt.x, pt.y, SIZE_/2);
+    }
+
+    // If touched position is on the button, 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;
+    }
+
+    SeekBar::Point SeekBar::ToPoint(float value)
+    {
+        if (ORIENT_ == Holizontal)
+            return Point(X_ + L_*(value - MIN_)/(MAX_ - MIN_), Y_);
+        else
+            return Point(X_, Y_ + L_ - 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;
+    }
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/SeekBar.hpp	Thu Mar 31 07:28:42 2016 +0000
@@ -0,0 +1,66 @@
+//-----------------------------------------------------------
+//  SeekBar class -- Header
+//
+//  2016/03/29, Copyright (c) 2016 MIKAMI, Naoki
+//-----------------------------------------------------------
+
+#ifndef F746_SEEKBAR_HPP
+#define F746_SEEKBAR_HPP
+
+#include "GuiBase.hpp"
+
+namespace Mikami
+{
+    class SeekBar : public GuiBase
+    {
+    public:
+        enum Orientation { Holizontal, Vertical };
+
+        // Constructor
+        SeekBar(uint16_t x, uint16_t y, uint16_t length,
+                float min, float max, float value,
+                Orientation hv = Holizontal,
+                uint32_t thumbColor = LCD_COLOR_WHITE,
+                uint16_t thumbSize = 30, uint16_t width = 4,
+                uint32_t colorL = LCD_COLOR_LIGHTGRAY,
+                uint32_t colorH = 0xFFB0B0B0,
+                uint32_t backColor = GuiBase::ENUM_BACK)
+            : GuiBase(x, y, Font12, 0, backColor, thumbColor),
+              L_(length), W_(width),
+              SIZE_(thumbSize), COLOR_L_(colorL), COLOR_H_(colorH),
+              MIN_(min), MAX_(max), ORIENT_(hv), v_(value)
+        {   Draw(value); }
+
+        bool Slide();
+        float GetValue() { return v_; }
+        int GetIntValue() { return Round(v_); }
+
+    private:
+        struct Point
+        {
+            uint16_t x, y;
+            Point(uint16_t x0 = 0, uint16_t y0 = 0) : x(x0), y(y0) {}
+        };
+
+        const uint16_t L_, W_;
+        const uint16_t SIZE_;           // Size of thumb
+        const uint32_t COLOR_L_, COLOR_H_;
+        const float MIN_, MAX_;
+        const Orientation ORIENT_;
+
+        float v_;             // value of seekbar
+        bool slided_;
+
+        void Draw(float value, bool fill = false);
+        bool IsOnThumb(uint16_t &x, uint16_t &y);
+        Point ToPoint(float value);
+        float ToValue(Point pt);
+        int Round(float x) { return x + 0.5f - (x < 0); }  // Round up on 5
+        float Saturate(float value);
+
+        // disallow copy constructor and assignment operator
+        SeekBar(const SeekBar&);
+        SeekBar& operator=(const SeekBar&);
+    };
+}
+#endif  // F746_SEEKBAR_HPP