VFD modular clock firmware

Dependencies:   DipCortex-EEprom RTC flw mbed

menu.cpp

Committer:
Backstr?m
Date:
2015-02-24
Revision:
12:dfb422107412
Parent:
0:f6e68b4ce169

File content as of revision 12:dfb422107412:

/*
 * VFD Modular Clock - mbed
 * (C) 2011-14 Akafugu Corporation
 *
 * 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 of the License, or (at your option) any later
 * version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT ANY
 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE.  See the GNU General Public License for more details.
 *
 */

#include "global.h"
#include "menu.h"

char menu_buf[MAX_BUF];

/////////////////////////////////////////////////////////
// MenuItemValue

MenuItemValue::MenuItemValue(int32_t min, int32_t max)
: m_min(min)
, m_max(max)
, m_value(min)
, m_activated(false)
{
}

int32_t MenuItemValue::getValue()
{
    return m_value;
}

int32_t MenuItemValue::incrementValue()
{
    if (m_activated) {
        m_value++;
        if (m_value > m_max) m_value = m_min;
    }
    else {
        m_activated = true;    
    }
    
    return m_value;
}    

void MenuItemValue::resetActive()
{
    m_activated = false;
}

/////////////////////////////////////////////////////////
// MenuItem

MenuItem::MenuItem(const char* shortName, const char* longName, bool onOff, PREFS pref)
: m_onOff(onOff)
, m_pref(pref)
{
    strncpy(m_shortName, shortName, 4);
    strncpy(m_longName, longName, 8);
    m_menuItemValue = new MenuItemValue(0, 1);
}

MenuItem::MenuItem(const char* shortName, bool onOff, PREFS pref)
: m_onOff(onOff)
, m_pref(pref)
{
    strncpy(m_shortName, shortName, 4);
    m_longName[0] = 0;
    m_menuItemValue = new MenuItemValue(0, 1);
}

MenuItem::MenuItem(const char* shortName, const char* longName, int32_t min, int32_t max, PREFS pref)
: m_onOff(false)
, m_pref(pref)
{
    strncpy(m_shortName, shortName, 4);
    strncpy(m_longName, longName, 8);    
    m_menuItemValue = new MenuItemValue(min, max);
}

MenuItem::MenuItem(const char* shortName, int32_t min, int32_t max, PREFS pref)
: m_onOff(false)
, m_pref(pref)
{
    strncpy(m_shortName, shortName, 4);
    m_longName[0] = 0;
    m_menuItemValue = new MenuItemValue(min, max);
}

const char* MenuItem::getName(uint8_t digits) const
{
    if (m_longName[0] == 0) return m_shortName;
    return digits <= 4 ? m_shortName : m_longName;
}

extern DigitalOut led;

const char* MenuItem::selectValue(uint8_t digits) const
{
    uint32_t value = m_menuItemValue->incrementValue();

    // special handling
    if (m_pref == PREF_GPS_TZM) {
        value *= 15;    
    }
    
    if (m_onOff) {
        if (value == 1)
            snprintf(menu_buf, MAX_BUF-1, "%s", "on");
        else
            snprintf(menu_buf, MAX_BUF-1, "%s", "off");
    }
    else if (m_pref == PREF_FLW) {
        if (value == 0)
            snprintf(menu_buf, MAX_BUF-1, "%s", "off");
        if (value == 1)
            snprintf(menu_buf, MAX_BUF-1, "%s", "on");
        else if (value == 2)
            snprintf(menu_buf, MAX_BUF-1, "%s", "full");            
    }
    else {
        // special handling for year/month/day - these values are not stored in the eeprom
        // but go directly to the RTC chip
        if (m_pref == PREF_YEAR) {
            set_year(value);    
        }
        else if (m_pref == PREF_MONTH) {
            set_month(value);    
        }
        else if (m_pref == PREF_DAY) {
            set_day(value);    
        }
        
        snprintf(menu_buf, MAX_BUF-1, "%d", value);    
    }
    
    // save to prefs
    if (m_pref != PREF_NULL) {
        set_pref(m_pref, value);
    }

    return menu_buf;
}

void MenuItem::resetActive() const
{
    m_menuItemValue->resetActive();
}

const MenuItem menu1("TIME", "SET TIME", true, PREF_SET_TIME);
const MenuItem menu2("ALRM", "SET ALR", true, PREF_SET_ALARM);
const MenuItem menu3("24H", true, PREF_24H);
const MenuItem menu4("BRIT", "BRITE", 2, 10, PREF_BRIGHTNESS);
const MenuItem menu5("YEAR", 2014, 2075, PREF_YEAR);
const MenuItem menu6("MNTH", "MONTH", 1, 12, PREF_MONTH);
const MenuItem menu7("DAY", 1, 31, PREF_DAY);
const MenuItem menu8("GPS", true, PREF_GPS);
const MenuItem menu9("TZH", "GPS TZH", -12, 14, PREF_GPS_TZH);
const MenuItem menu10("TZM", "GPS TZM", 0, 3, PREF_GPS_TZM);
const MenuItem menu11("ADTE", "AUTODATE", true, PREF_AUTODATE);
const MenuItem menu12("FLW", 0, 2, PREF_FLW);

#ifdef HAVE_GPS
#define ITEMS 12
const MenuItem* menuItems[] = { &menu1, &menu2, &menu3, &menu4, &menu5, &menu6, &menu7, &menu8, &menu9, &menu10, &menu11, &menu12 };
#else
#define ITEMS 8
const MenuItem* menuItems[] = { &menu1, &menu2, &menu3, &menu4, &menu5, &menu6, &menu7, &menu12 };
#endif

Menu::Menu()
    : m_position(0)
    , m_size(ITEMS)
    , m_digits(8)
{
}

const char* Menu::reset()
{
    m_position = 0;
    return menuItems[m_position]->getName(m_digits);
}

const char* Menu::next()
{
    menuItems[m_position]->resetActive();
    
    m_position++;
    if (m_position >= ITEMS) m_position = 0;
    
    return menuItems[m_position]->getName(m_digits);
}

const char* Menu::select(bool& enterSetTime, bool& enterSetAlarm)
{
    enterSetTime = enterSetAlarm = false;
    
    if (menuItems[m_position]->isSetTimeTrigger())
        enterSetTime = true;

    if (menuItems[m_position]->isSetAlarmTrigger())
        enterSetAlarm = true;
    
    return menuItems[m_position]->selectValue(m_digits);
}

void Menu::leave()
{
    menuItems[m_position]->resetActive(); 
    save_prefs();   
}