Updated to libmDot 1.0.8-1

Dependencies:   DOGS102 GpsParser ISL29011 MMA845x MPL3115A2 MTS-Serial NCP5623B libmDot mbed-rtos mbed

Fork of MTDOT-BOX-EVB-Factory-Firmware by MultiTech

Layout/LayoutScrollSelect.cpp

Committer:
jreiss
Date:
2016-07-13
Revision:
6:ab581c4260e7
Parent:
1:71125aa00e33

File content as of revision 6:ab581c4260e7:

/* Copyright (c) <2016> <MultiTech Systems>, MIT License
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy of this software 
 * and associated documentation files (the "Software"), to deal in the Software without restriction, 
 * including without limitation the rights to use, copy, modify, merge, publish, distribute, 
 * sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is 
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all copies or 
 * substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
 * BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
 * DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */

#include "LayoutScrollSelect.h"
#include "MTSLog.h"

LayoutScrollSelect::LayoutScrollSelect(DOGS102* lcd, Items items, std::string info1, std::string info2)
  : Layout(lcd),
    _lSw1(0, 7, "Scroll"),
    _lSw2(11, 7, "Select"),
    _lInfo1(0, 0, info1),
    _lInfo2(0, 1, info2),
    _lCursor(0, 4, "=>"),
    _fItem1(3, 2, 14),
    _fItem2(3, 3, 14),
    _fItem3(3, 4, 14),
    _fItem4(3, 5, 14),
    _fItem5(3, 6, 14),
    _items(items)
{
    _size = _items.size();
    _selected = 0;
}

LayoutScrollSelect::~LayoutScrollSelect() {}

void LayoutScrollSelect::display() {
    clear();
    startUpdate();

    writeLabel(_lSw1);
    writeLabel(_lSw2);
    writeLabel(_lInfo1);
    writeLabel(_lInfo2);
    writeLabel(_lCursor);

    switch (_size) {
        case 0:
            // special case - no items
            //    (empty)
            //    (empty)
            // => (empty)
            //    (empty)
            //    (empty)
            break;

        case 1:
            // special case - 1 item
            //    (empty)
            //    (empty)
            // => item1
            //    (empty)
            //    (empty)
            writeField(_fItem3, _items[0]);
            break;

        case 2:
            // special case - 2 items
            //    (empty)
            //    (empty)
            // => item1
            //    item2
            //    (empty)
            writeField(_fItem3, _items[0]);
            writeField(_fItem4, _items[1]);
            break;

        case 3:
            // special case - 3 items
            //    (empty)
            //    item3
            // => item1
            //    item2
            //    (empty)
            writeField(_fItem2, _items[2]);
            writeField(_fItem3, _items[0]);
            writeField(_fItem4, _items[1]);
            break;

        case 4:
            // special case - 4 items
            //    item3
            //    item4
            // => item1
            //    item2
            //    (empty)
            writeField(_fItem1, _items[2]);
            writeField(_fItem2, _items[3]);
            writeField(_fItem3, _items[0]);
            writeField(_fItem4, _items[1]);
            break;

        default:
            // this is the generic case - should handle lists of 5+ items correctly
            //    item4         item6           item9
            //    item5         item7           item10
            // => item1      => item1        => item1
            //    item2         item2           item2
            //    item3         item3           item3
            writeField(_fItem1, _items[_size - 2]);
            writeField(_fItem2, _items[_size - 1]);
            writeField(_fItem3, _items[0]);
            writeField(_fItem4, _items[1]);
            writeField(_fItem5, _items[2]);
            break;
    }

    endUpdate();
}

void LayoutScrollSelect::scroll() {
    size_t index;

    switch (_size) {
        case 0:
        case 1:
            // nothing to scroll
            break;

        case 2:
            // special case - 2 items
            //    (empty)  ->     (empty)
            //    (empty)  ->     (empty)
            // => item1    ->  => item2
            //    item2    ->     item1
            //    (empty)  ->     (empty)

            index = _selected;
            // keep selected item up to date
            increment(_selected);

            startUpdate();
            // previously selected item moves down to field4
            writeField(_fItem4, _items[index]);
            increment(index);
            // other item moves up to field3
            writeField(_fItem3, _items[index]);
            endUpdate();
            break;

        case 3:
            // special case - 3 items
            //    (empty)  ->     (empty)
            //    item3    ->     item1  
            // => item1    ->  => item2
            //    item2    ->     item3
            //    (empty)  ->     (empty)
            
            index = _selected;
            // keep selected item up to date
            increment(_selected);

            startUpdate();
            // previously selected item moves up to field2
            writeField(_fItem2, _items[index]);
            increment(index);
            // new selected item moves up to field3
            writeField(_fItem3, _items[index]);
            increment(index);
            // item from field2 moves down to field4
            writeField(_fItem4, _items[index]);
            endUpdate();
            break;

        case 4:
            // special case - 4 items
            //    item3    ->     item4  
            //    item4    ->     item1  
            // => item1    ->  => item2
            //    item2    ->     item3
            //    (empty)  ->     (empty)
            
            index = _selected;
            // keep selected item up to date
            increment(_selected);

            startUpdate();
            // previously selected item moves up to field2
            writeField(_fItem2, _items[index]);
            increment(index);
            // new selected item moves up to field3
            writeField(_fItem3, _items[index]);
            increment(index);
            // item from field1 moves down to field4
            writeField(_fItem4, _items[index]);
            increment(index);
            // item from field2 moves up to field1
            writeField(_fItem1, _items[index]);
            endUpdate();
            break;

        default:
            // this is the generic case - should handle lists of 5+ items correctly
            //    item4    ->     item5           item6    ->     item7
            //    item5    ->     item1           item7    ->     item1
            // => item1    ->  => item2        => item1    ->  => item2
            //    item2    ->     item3           item2    ->     item3
            //    item3    ->     item4           item3    ->     item4
            
            index = _selected;
            // keep selected item up to date
            increment(_selected);

            startUpdate();
            decrement(index);
            // item from field2 moves up to field1
            writeField(_fItem1, _items[index]);
            increment(index);
            // previously selected item moves up to field2
            writeField(_fItem2, _items[index]);
            increment(index);
            // new selected item moves up to field3
            writeField(_fItem3, _items[index]);
            increment(index);
            // item from field5 moves up to field4
            writeField(_fItem4, _items[index]);
            increment(index);
            // next item (from field1 or off screen) moves up to field5
            writeField(_fItem5, _items[index]);
            endUpdate();
            break;
      }
}

std::string LayoutScrollSelect::select() {
    std::string selected = "";
    if (_size > 0)
        selected = _items[_selected];

    return selected;
}

void LayoutScrollSelect::increment(size_t& index) {
    if (_size > 1) {
        index++;
        index %= _size;
    }
}

void LayoutScrollSelect::decrement(size_t& index) {
    if (_size > 1) {
        if (index == 0)
            index = _size - 1;
        else
            index--;
    }
}