Skip to content

Commit

Permalink
simple embedded(encoder-like?) menu
Browse files Browse the repository at this point in the history
  • Loading branch information
Hoksmur committed Oct 2, 2017
1 parent 091abb6 commit 3b19766
Show file tree
Hide file tree
Showing 2 changed files with 312 additions and 0 deletions.
251 changes: 251 additions & 0 deletions sem.c
@@ -0,0 +1,251 @@
#include "sem.h"
#include "lcd.h"
#include "delay.h"

/*
((signed char (*)(signed char))
è ïîõîæèå - ýòî æóòêîå êîëäóíñòâî ñòàëî âîçìîæíî
áëàãîäàðÿ ñîâåòàì SciFi ñ ôîðóìà http://caxapa.ru
Ýòî ïðåîáðàçîâàíèå ê óêàçàòåëþ íà ôóíêöèþ è å¸ âûçîâ
*/



static em_Item_t * p_Itm_entry = NULL_LINK;
static bool selected = FALSE;
static em_Item_t * p_Act_item = NULL_LINK;

static unsigned char active_pos = 0;


void em_Init( em_Item_t * pMenu)
{
p_Itm_entry = pMenu;
//selected = FALSE;
//p_Act_item = NULL_LINK;
}


// Replacing sprintf (this one don't understand 'hh'
void xformat( char *buf, char type, signed char val)
{
char ibuf[5];
unsigned char tmp, idx=4;

switch(type) {
case 0x00: // signed char
ibuf[idx--] = '\0';
if ( val<0 ) {
tmp = (-val);
} else {
tmp = val;
}
do {
ibuf[idx--] = (tmp%10)+'0';
tmp = tmp/10;
} while( tmp > 0);
ibuf[idx] = (val<0) ? '-' : ' ';
break;
case 0x01: // insigned
ibuf[idx--] = '\0';
do {
ibuf[idx--] = (tmp%10)+'0';
tmp = tmp/10;
} while( tmp > 0);
break;
}
// add spaces before if it's need
while ((idx)>0) {
ibuf[--idx] = ' ';
}

for ( ; idx<=4; idx++ ) {
*buf++ = ibuf[idx];
}
}


void em_Show(void)
{
em_Item_t * em_curItem = p_Itm_entry;
unsigned char m_i;
char mode;

m_i = 0;
do {
lcd_print( 1, m_i, em_curItem->text);
if ( m_i != active_pos ) {
// Not active
mode = '.';
} else {
p_Act_item = em_curItem;
if ( selected == FALSE) {
// Active, not selected
mode = '>';
} else {
// Active, selected
mode = '#';
}
}
lcd_pchar( 0, m_i, mode);
m_i++;
em_curItem = em_curItem->fwLink;
} while ( em_curItem != NULL_LINK );

// clear screen area
while ( m_i < EM_LINES ) {
lcd_print( 0, m_i, " " );
m_i++;
}
}

void em_Event( em_event_t evnt )
{
//signed char (*p_func_s)( signed char);
//unsigned char (*p_func_u)( unsigned char);

char v_char;
char vis_buf[5];
if ( selected == FALSE) {
// ######## UNSELECTED #################
switch(evnt) {
//==================================
case em_press:
switch(p_Act_item->type) {
// -------------------------
case submenu:
selected = FALSE;
active_pos = 0;
p_Itm_entry = p_Act_item->item; // Entry point to submenu
p_Act_item = p_Itm_entry; // place user pointer to first line
break;
// -------------------------
case schar:
// p_func_s = p_Act_item->item;
// v_char = (*p_func_s)(0);
v_char = ((signed char (*)(signed char))p_Act_item->item)(0);
xformat( vis_buf, 0, v_char);
lcd_print( 9, active_pos, vis_buf );
selected = TRUE;
break;
// -------------------------
case uchar:
lcd_pchar(1, 5, 'U');
// p_func_s = p_Act_item->item;
// v_char = (*p_func_u)(0);
v_char = ((unsigned char (*)(signed char))p_Act_item->item)(0);

xformat( vis_buf, 1, v_char);
lcd_print( 9, active_pos, vis_buf );
selected = TRUE;
break;
// -------------------------
// case str:
// break;
}
break;
//==================================
case em_up:
active_pos--;
break;
//==================================
case em_down:
active_pos++;
break;
//==================================
}
} else {
// ######## SELECTED ###################
switch(evnt) {
//==================================
case em_press:
switch(p_Act_item->type) {
// -------------------------
case submenu:
selected = FALSE;
active_pos = 0;
p_Itm_entry = p_Act_item->item; // Entry point to submenu
p_Act_item = p_Itm_entry; // place user pointer to first line
break;
// -------------------------
case schar:
// p_func_s = p_Act_item->item;
// v_char = (*p_func_s)(0);
v_char = ((signed char (*)(signed char))p_Act_item->item)(0);
xformat( vis_buf, 0, v_char);
lcd_print( 9, active_pos, vis_buf );
selected = FALSE;
break;
// -------------------------
case uchar:
lcd_pchar(4, 5, '*');
// p_func_s = p_Act_item->item;
// v_char = (*p_func_u)(0);
v_char = ((unsigned char (*)(signed char))p_Act_item->item)(0);

xformat( vis_buf, 1, v_char);
lcd_print( 9, active_pos, vis_buf );
lcd_pchar(4, 6, '=');
selected = FALSE;
break;
// -------------------------
// case str:
// break;
}
break;
//==================================
case em_up:
switch(p_Act_item->type) {
// -------------------------
case submenu:
break;
// -------------------------
case schar:
// p_func_s = p_Act_item->item;
// v_char = (*p_func_s)(1);
v_char = ((signed char (*)(signed char))p_Act_item->item)(1);
xformat( vis_buf, 0, v_char);
lcd_print( 9, active_pos, vis_buf );
break;
// -------------------------
case uchar:
lcd_pchar(1, 5, '<');
//p_func_s = p_Act_item->item;
//v_char = (*p_func_u)(1);
v_char = ((unsigned char (*)(signed char))p_Act_item->item)(1);
xformat( vis_buf, 0, v_char);
lcd_print( 9, active_pos, vis_buf );
break;
}
break;
//==================================
case em_down:
switch(p_Act_item->type) {
// -------------------------
case submenu:
break;
// -------------------------
case schar:
// p_func_s = p_Act_item->item;
// v_char = (*p_func_s)(-1);
v_char = ((signed char (*)(signed char))p_Act_item->item)(-1);
xformat( vis_buf, 0, v_char);
lcd_print( 9, active_pos, vis_buf );
break;
// -------------------------
case uchar:
lcd_pchar(1, 5, '>');
// p_func_s = p_Act_item->item;
// v_char = (*p_func_u)(-1);
v_char = ((unsigned char (*)(signed char))p_Act_item->item)(-1);
xformat( vis_buf, 0, v_char);
lcd_print( 9, active_pos, vis_buf );
break;
}
break;
//==================================
}
}
em_Show();
}

61 changes: 61 additions & 0 deletions sem.h
@@ -0,0 +1,61 @@
#ifndef __SEM_H__
#define __SEM_H__

// Simple Encoder-like menu

// Menu item has a structure:
// +------------+---------+------+-----------+
// | ->fwLink | -> text | type | item this |
// +------------+---------+------+-----------+
// fwLink - pointer no a next line for this level menu or NULL_LINK for last on this level
// text - pointer to a string with showed name
// type - type of this item; 'submenu' for next level menu
// item - pointer to a function or link to other menuitem


// Button or encoder event
typedef enum {
em_press,
em_up,
em_down
} em_event_t ;

// type of contest item
typedef enum {
submenu,
schar,
uchar,
str,
dummy
} em_ItmType_t;


// union of pointers, strongly recommended SciFi from caxapa.ru

// menu item structure
struct em_Item_s {
struct em_Item_s * fwLink;
char * text;
em_ItmType_t type;
void * item;
};

// Declare menu type
typedef const struct em_Item_s em_Item_t;

// Set start values for selected menu
void em_Init( em_Item_t * pMenu);

// pritn text menu
void em_Show(void);

// Call when event
// Use em_Show() to update menu on screen
void em_Event( em_event_t evnt );

#define NULL_LINK ((em_Item_t *)0)
#define EM_LINES 4 // number of lines on screen



#endif // __SEM_H__ //

0 comments on commit 3b19766

Please sign in to comment.