parent
6049fa6e91
commit
3599442a2c
@ -0,0 +1,378 @@ |
||||
/*
|
||||
MicroDexed |
||||
|
||||
MicroDexed is a port of the Dexed sound engine |
||||
(https://github.com/asb2m10/dexed) for the Teensy-3.5/3.6 with audio shield.
|
||||
Dexed ist heavily based on https://github.com/google/music-synthesizer-for-android
|
||||
|
||||
(c)2018,2019 H. Wirtz <wirtz@parasitstudio.de> |
||||
|
||||
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 3 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. |
||||
|
||||
You should have received a copy of the GNU General Public License |
||||
along with this program; if not, write to the Free Software Foundation, |
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
||||
*/ |
||||
|
||||
#ifndef _UI_HPP_ |
||||
#define _UI_HPP_ |
||||
|
||||
#include <LiquidCrystal_I2C.h> |
||||
#include <LCDMenuLib2.h> |
||||
#include "Arduino.h" |
||||
|
||||
#define _LCDML_DISP_cols 16 |
||||
#define _LCDML_DISP_rows 2 |
||||
|
||||
#define _LCDML_DISP_cfg_cursor 0x7E // cursor Symbol
|
||||
#define _LCDML_DISP_cfg_scrollbar 1 // enable a scrollbar
|
||||
|
||||
/***********************************************************************
|
||||
GLOBAL |
||||
***********************************************************************/ |
||||
LiquidCrystal_I2C lcd(0x27, _LCDML_DISP_cols, _LCDML_DISP_rows); |
||||
|
||||
const uint8_t scroll_bar[5][8] = { |
||||
{B10001, B10001, B10001, B10001, B10001, B10001, B10001, B10001}, // scrollbar top
|
||||
{B11111, B11111, B10001, B10001, B10001, B10001, B10001, B10001}, // scroll state 1
|
||||
{B10001, B10001, B11111, B11111, B10001, B10001, B10001, B10001}, // scroll state 2
|
||||
{B10001, B10001, B10001, B10001, B11111, B11111, B10001, B10001}, // scroll state 3
|
||||
{B10001, B10001, B10001, B10001, B10001, B10001, B11111, B11111} // scrollbar bottom
|
||||
}; |
||||
|
||||
void lcdml_menu_display(void); |
||||
void lcdml_menu_clear(void); |
||||
void lcdml_menu_control(void); |
||||
void UI_func_information(uint8_t param); |
||||
void UI_func_screensaver(uint8_t param); |
||||
void UI_func_test(uint8_t param); |
||||
void UI_func_back(uint8_t param); |
||||
void UI_func_goToRootMenu(uint8_t param); |
||||
|
||||
LCDMenuLib2_menu LCDML_0(255, 0, 0, NULL, NULL); // root menu element (do not change)
|
||||
LCDMenuLib2 LCDML(LCDML_0, _LCDML_DISP_rows, _LCDML_DISP_cols, lcdml_menu_display, lcdml_menu_clear, lcdml_menu_control); |
||||
|
||||
// LCDML_add(id, prev_layer, new_num, lang_char_array, callback_function)
|
||||
LCDML_add(0, LCDML_0, 1, "Information", UI_func_information); |
||||
LCDML_add(1, LCDML_0, 2, "Test", UI_func_test); |
||||
LCDML_add(2, LCDML_0, 3, "Screensaver", UI_func_screensaver); |
||||
#define _LCDML_DISP_cnt 2 |
||||
|
||||
// create menu
|
||||
LCDML_createMenu(_LCDML_DISP_cnt); |
||||
|
||||
/***********************************************************************
|
||||
CONTROL |
||||
***********************************************************************/ |
||||
#define g_LCDML_CONTROL_button_long_press 800 // ms
|
||||
#define g_LCDML_CONTROL_button_short_press 120 // ms
|
||||
|
||||
#define ENCODER_OPTIMIZE_INTERRUPTS //Only when using pin2/3 (or 20/21 on mega)
|
||||
#include <Encoder.h> |
||||
|
||||
Encoder ENCODER(ENC_R_PIN_B, ENC_R_PIN_A); |
||||
|
||||
long g_LCDML_CONTROL_button_press_time = 0; |
||||
bool g_LCDML_CONTROL_button_prev = HIGH; |
||||
|
||||
void lcdml_menu_control(void) |
||||
{ |
||||
// If something must init, put in in the setup condition
|
||||
if (LCDML.BT_setup()) |
||||
{ |
||||
//pinMode(ENC_R_PIN_A, INPUT_PULLUP);
|
||||
//pinMode(ENC_R_PIN_B, INPUT_PULLUP);
|
||||
pinMode(BUT_R_PIN, INPUT_PULLUP); |
||||
} |
||||
|
||||
//Volatile Variable
|
||||
long g_LCDML_CONTROL_Encoder_position = ENCODER.read(); |
||||
bool button = digitalRead(BUT_R_PIN); |
||||
|
||||
if (g_LCDML_CONTROL_Encoder_position <= -3) { |
||||
|
||||
if (!button) |
||||
{ |
||||
LCDML.BT_left(); |
||||
g_LCDML_CONTROL_button_prev = LOW; |
||||
g_LCDML_CONTROL_button_press_time = -1; |
||||
} |
||||
else |
||||
{ |
||||
LCDML.BT_down(); |
||||
} |
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position + 4); |
||||
} |
||||
else if (g_LCDML_CONTROL_Encoder_position >= 3) |
||||
{ |
||||
|
||||
if (!button) |
||||
{ |
||||
LCDML.BT_right(); |
||||
g_LCDML_CONTROL_button_prev = LOW; |
||||
g_LCDML_CONTROL_button_press_time = -1; |
||||
} |
||||
else |
||||
{ |
||||
LCDML.BT_up(); |
||||
} |
||||
ENCODER.write(g_LCDML_CONTROL_Encoder_position - 4); |
||||
} |
||||
else |
||||
{ |
||||
if (!button && g_LCDML_CONTROL_button_prev) //falling edge, button pressed
|
||||
{ |
||||
g_LCDML_CONTROL_button_prev = LOW; |
||||
g_LCDML_CONTROL_button_press_time = millis(); |
||||
} |
||||
else if (button && !g_LCDML_CONTROL_button_prev) //rising edge, button not active
|
||||
{ |
||||
g_LCDML_CONTROL_button_prev = HIGH; |
||||
|
||||
if (g_LCDML_CONTROL_button_press_time < 0) |
||||
{ |
||||
g_LCDML_CONTROL_button_press_time = millis(); |
||||
//Reset for left right action
|
||||
} |
||||
else if ((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_long_press) |
||||
{ |
||||
LCDML.BT_quit(); |
||||
} |
||||
else if ((millis() - g_LCDML_CONTROL_button_press_time) >= g_LCDML_CONTROL_button_short_press) |
||||
{ |
||||
LCDML.BT_enter(); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/***********************************************************************
|
||||
DISPLAY |
||||
***********************************************************************/ |
||||
void lcdml_menu_clear(void) |
||||
{ |
||||
lcd.clear(); |
||||
lcd.setCursor(0, 0); |
||||
} |
||||
|
||||
void lcdml_menu_display(void) |
||||
{ |
||||
// update content
|
||||
// ***************
|
||||
if (LCDML.DISP_checkMenuUpdate()) { |
||||
// clear menu
|
||||
// ***************
|
||||
LCDML.DISP_clear(); |
||||
|
||||
// declaration of some variables
|
||||
// ***************
|
||||
// content variable
|
||||
char content_text[_LCDML_DISP_cols]; // save the content text of every menu element
|
||||
// menu element object
|
||||
LCDMenuLib2_menu *tmp; |
||||
// some limit values
|
||||
uint8_t i = LCDML.MENU_getScroll(); |
||||
uint8_t maxi = _LCDML_DISP_rows + i; |
||||
uint8_t n = 0; |
||||
|
||||
// check if this element has children
|
||||
if ((tmp = LCDML.MENU_getDisplayedObj()) != NULL) |
||||
{ |
||||
// loop to display lines
|
||||
do |
||||
{ |
||||
// check if a menu element has a condition and if the condition be true
|
||||
if (tmp->checkCondition()) |
||||
{ |
||||
// check the type off a menu element
|
||||
if (tmp->checkType_menu() == true) |
||||
{ |
||||
// display normal content
|
||||
LCDML_getContent(content_text, tmp->getID()); |
||||
lcd.setCursor(1, n); |
||||
lcd.print(content_text); |
||||
} |
||||
else |
||||
{ |
||||
if (tmp->checkType_dynParam()) { |
||||
tmp->callback(n); |
||||
} |
||||
} |
||||
// increment some values
|
||||
i++; |
||||
n++; |
||||
} |
||||
// try to go to the next sibling and check the number of displayed rows
|
||||
} while (((tmp = tmp->getSibling(1)) != NULL) && (i < maxi)); |
||||
} |
||||
} |
||||
|
||||
if (LCDML.DISP_checkMenuCursorUpdate()) |
||||
{ |
||||
// init vars
|
||||
uint8_t n_max = (LCDML.MENU_getChilds() >= _LCDML_DISP_rows) ? _LCDML_DISP_rows : (LCDML.MENU_getChilds()); |
||||
uint8_t scrollbar_min = 0; |
||||
uint8_t scrollbar_max = LCDML.MENU_getChilds(); |
||||
uint8_t scrollbar_cur_pos = LCDML.MENU_getCursorPosAbs(); |
||||
uint8_t scroll_pos = ((1.*n_max * _LCDML_DISP_rows) / (scrollbar_max - 1) * scrollbar_cur_pos); |
||||
|
||||
|
||||
// display rows
|
||||
for (uint8_t n = 0; n < n_max; n++) |
||||
{ |
||||
//set cursor
|
||||
lcd.setCursor(0, n); |
||||
|
||||
//set cursor char
|
||||
if (n == LCDML.MENU_getCursorPos()) { |
||||
lcd.write(_LCDML_DISP_cfg_cursor); |
||||
} else { |
||||
lcd.write(' '); |
||||
} |
||||
|
||||
// delete or reset scrollbar
|
||||
if (_LCDML_DISP_cfg_scrollbar == 1) { |
||||
if (scrollbar_max > n_max) { |
||||
lcd.setCursor((_LCDML_DISP_cols - 1), n); |
||||
lcd.write((uint8_t)0); |
||||
} |
||||
else { |
||||
lcd.setCursor((_LCDML_DISP_cols - 1), n); |
||||
lcd.print(' '); |
||||
} |
||||
} |
||||
} |
||||
|
||||
// display scrollbar
|
||||
if (_LCDML_DISP_cfg_scrollbar == 1) { |
||||
if (scrollbar_max > n_max) { |
||||
//set scroll position
|
||||
if (scrollbar_cur_pos == scrollbar_min) { |
||||
// min pos
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), 0); |
||||
lcd.write((uint8_t)1); |
||||
} else if (scrollbar_cur_pos == (scrollbar_max - 1)) { |
||||
// max pos
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), (n_max - 1)); |
||||
lcd.write((uint8_t)4); |
||||
} else { |
||||
// between
|
||||
lcd.setCursor((_LCDML_DISP_cols - 1), scroll_pos / n_max); |
||||
lcd.write((uint8_t)(scroll_pos % n_max) + 1); |
||||
} |
||||
} |
||||
} |
||||
} |
||||
} |
||||
|
||||
/***********************************************************************
|
||||
MENU |
||||
***********************************************************************/ |
||||
void UI_func_information(uint8_t param) |
||||
{ |
||||
if (LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{ |
||||
// setup function
|
||||
lcd.setCursor(0, 0); |
||||
lcd.print(F("MicroDexed")); |
||||
lcd.setCursor(0, 1); |
||||
lcd.print(F("LCDMenuLib2")); |
||||
} |
||||
|
||||
if (LCDML.FUNC_loop()) // ****** LOOP *********
|
||||
{ |
||||
// loop function, can be run in a loop when LCDML_DISP_triggerMenu(xx) is set
|
||||
// the quit button works in every DISP function without any checks; it starts the loop_end function
|
||||
if (LCDML.BT_checkAny()) { // check if any button is pressed (enter, up, down, left, right)
|
||||
// LCDML_goToMenu stops a running menu function and goes to the menu
|
||||
LCDML.FUNC_goBackToMenu(); |
||||
} |
||||
} |
||||
|
||||
if (LCDML.FUNC_close()) // ****** STABLE END *********
|
||||
{ |
||||
// you can here reset some global vars or do nothing
|
||||
} |
||||
} |
||||
|
||||
void UI_func_screensaver(uint8_t param) |
||||
{ |
||||
if (LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{ |
||||
// update LCD content
|
||||
lcd.setCursor(0, 0); // set cursor
|
||||
lcd.print("screensaver"); // print change content
|
||||
lcd.setCursor(0, 1); // set cursor
|
||||
lcd.print("press any key"); |
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
} |
||||
|
||||
if (LCDML.FUNC_loop()) |
||||
{ |
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{ |
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
} |
||||
} |
||||
|
||||
if (LCDML.FUNC_close()) |
||||
{ |
||||
// The screensaver go to the root menu
|
||||
LCDML.MENU_goRoot(); |
||||
} |
||||
} |
||||
|
||||
void UI_func_test(uint8_t param) |
||||
{ |
||||
if (LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{ |
||||
// update LCD content
|
||||
lcd.setCursor(0, 0); // set cursor
|
||||
lcd.print("TEST"); // print change content
|
||||
lcd.setCursor(0, 1); // set cursor
|
||||
lcd.print("TEST123"); |
||||
LCDML.FUNC_setLoopInterval(100); // starts a trigger event for the loop function every 100 milliseconds
|
||||
} |
||||
|
||||
if (LCDML.FUNC_loop()) |
||||
{ |
||||
if (LCDML.BT_checkAny()) // check if any button is pressed (enter, up, down, left, right)
|
||||
{ |
||||
LCDML.FUNC_goBackToMenu(); // leave this function
|
||||
} |
||||
} |
||||
|
||||
if (LCDML.FUNC_close()) |
||||
{ |
||||
// The screensaver go to the root menu
|
||||
LCDML.MENU_goRoot(); |
||||
} |
||||
} |
||||
|
||||
/*void UI_func_back(uint8_t param)
|
||||
{ |
||||
if (LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{ |
||||
// end function and go an layer back
|
||||
LCDML.FUNC_goBackToMenu(1); // leave this function and go a layer back
|
||||
} |
||||
}*/ |
||||
|
||||
void UI_func_goToRootMenu(uint8_t param) |
||||
{ |
||||
if (LCDML.FUNC_setup()) // ****** SETUP *********
|
||||
{ |
||||
// go to root and display menu
|
||||
LCDML.MENU_goRoot(); |
||||
} |
||||
} |
||||
|
||||
#endif |
Loading…
Reference in new issue