Foundation classes for a basic GUI implementing simple widgets and events

Dependents:   TouchScreenGUIDemo

Widgets/ContainerWidget.h

Committer:
duncanFrance
Date:
2016-04-11
Revision:
8:a460cabc85ac
Parent:
7:303850a4b30c
Child:
9:616a9686d5db

File content as of revision 8:a460cabc85ac:

#ifndef SIMPLEGUI_CONTAINER_WIDGET_H
#define SIMPLEGUI_CONTAINER_WIDGET_H

#include "Widget.h"

class WidgetList
{

public:

    WidgetList(Widget* w) : widget(w), next(NULL) {}

    Widget* widget;
    WidgetList* next;

};

/**
* Simple container hold widgets side-by-side and draws a border
* It will expand as needed to hold the widgets
**/
class ContainerWidget : public Widget
{

public:

    ContainerWidget(GUI* gui) : Widget(gui), _padding(0), _widgets(NULL) {
    }

    /**
    * Set the amount of padding between the border and a widget edge
    **/
    void setPadding(int pixels) {
        if(_padding != pixels) {
            _padding = pixels;
            adjust();
        }
    }

    void setBorder(int width, uint16_t colour) {
        _borderColour = colour;
        if(_borderWidth != width) {
            _borderWidth = width;
            adjust();
        }
    }

    void append(Widget* widget) {

        WidgetList* w = new WidgetList(widget);

        if(_widgets == NULL) {
            _widgets = w;
        } else {
            _widgets->next = w;
        }

        adjust();
    }

    virtual void setLocation(int x, int y) {
        Widget::setLocation(x,y);
        adjust();
    }

    virtual void setSize(int width, int height) {
        Widget::setSize(width, height);
        _minWidth = width;
        _minHeight = height;
        adjust();
    }

    virtual void adjust() {
        int wx = _x + _padding + _borderWidth;
        int wy = _y + _padding + _borderWidth;
        int h = 0;
        
        _width = _minWidth;
        _height = _minHeight;

        WidgetList* p = _widgets;
        while(p != NULL) {
            // Position the widget
            p->widget->setLocation(wx, wy);
            wx += p->widget->width();
            if(p->widget->height() > h) {
                h = p->widget->height();
            }
            
            p = p->next;
        }

        int neededWidth = _padding + _borderWidth + wx - _x;
        int neededHeight = 2 * (_padding + _borderWidth) + h;
        
        if(neededWidth > _width) {
            _width = neededWidth;
        }
        
        if(neededHeight > _height) {
            _height = neededHeight;
        }
    }
    
    virtual void _draw() {
        // Draw the border
        // Top
        _gui->display()->fillrect(_x, _y, _x+_width, _y+_borderWidth, _borderColour);
        // Bottom
        _gui->display()->fillrect(_x, _y + _height - _borderWidth, _x + _width, _y+_height, _borderColour);
        // Left
        _gui->display()->fillrect(_x, _y, _x+_borderWidth, _y+_height, _borderColour);
        // Right
        _gui->display()->fillrect(_x+_width-_borderWidth, _y, _x+_width, _y+_height, _borderColour);
        
        WidgetList* p = _widgets;
        while(p != NULL) {
            p->widget->draw();
            p = p->next;
        }
    }
    
    virtual void _clear() {
        WidgetList* p = _widgets;
        while(p != NULL) {
            p->widget->clear();
            p = p->next;
        }
    }
        


protected:

    int _padding;
    WidgetList* _widgets;
    int _minWidth, _minHeight;
    int _borderWidth;
    uint16_t _borderColour;
};

#endif