Intégration du menu
This commit is contained in:
parent
390ee9df98
commit
6f729c102b
|
@ -9,6 +9,7 @@ set(SOURCES
|
|||
src/sudoSolv.cpp
|
||||
src/shared/bFile.cpp
|
||||
src/shared/keyboard.cpp
|
||||
src/shared/menuBar.cpp
|
||||
src/position.cpp
|
||||
src/element.cpp
|
||||
src/tinySquare.cpp
|
||||
|
|
20
README.md
20
README.md
|
@ -5,18 +5,13 @@ Un petit utilitaire en C++ pour Graph 90+E pour créer, éditer des grilles de S
|
|||
Cette première version ne contient que l'objet central, sans GUI et permet de valider les différentes méthodes de la classe.
|
||||
En séquence :
|
||||
|
||||
* *load()* - Ouverture du fichier "\\fls0\GRIDS\1.txt".
|
||||
S'il n'existe pas le système partira avec une grille vide;
|
||||
* *display()* - Affichage
|
||||
|
||||
* *load()* - Ouverture du fichier "\\fls0\\GRIDS\\1.txt". S'il n'existe pas le système partira avec une grille vide;
|
||||
* *display()* - Affichage
|
||||
* *edit()* - Edition de la grille. Un appui sur "EXE" sort du mode;
|
||||
|
||||
* *findObviousValues()* - Recherche des valeurs triviales (obvious values) : ie. les valeurs évidentes;
|
||||
Elles sont affichées en bleu
|
||||
|
||||
* *findObviousValues()* - Recherche des valeurs triviales (obvious values) : ie. les valeurs évidentes; Elles sont affichées en bleu
|
||||
* *resolve()* - Recherche d'une solution
|
||||
|
||||
~~~c
|
||||
```c
|
||||
#define GRID_FILE u"\\\\fls0\\GRIDS\\1.txt"
|
||||
|
||||
dclear(C_WHITE);
|
||||
|
@ -41,10 +36,7 @@ if (myGame.load((FONTCHARACTER)GRID_FILE)){
|
|||
getkey();
|
||||
}
|
||||
}
|
||||
~~~
|
||||
```
|
||||
|
||||
Le dossier `GRIDS` contient différentes grilles.
|
||||
Une grille fait exactement 162 octets.
|
||||
|
||||
|
||||
|
||||
Une grille fait exactement 162 octets.
|
286
src/consts.h
286
src/consts.h
|
@ -1,143 +1,143 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//--
|
||||
//-- consts.h
|
||||
//--
|
||||
//-- App. constants
|
||||
//--
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef __S_SOLVER_CONSTANTS_h__
|
||||
#define __S_SOLVER_CONSTANTS_h__ 1
|
||||
|
||||
#include "shared/casioCalcs.h"
|
||||
|
||||
#ifdef DEST_CASIO_CALC
|
||||
#include <gint/keyboard.h>
|
||||
#else
|
||||
#include <iostream>
|
||||
#include <cstdint> // <stdint.h>
|
||||
using namespace std;
|
||||
#endif //
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // #ifdef __cplusplus
|
||||
|
||||
// Informations about the grid
|
||||
//
|
||||
#define ROW_COUNT 9
|
||||
#define LINE_COUNT ROW_COUNT
|
||||
|
||||
#define INDEX_MIN 0
|
||||
#define INDEX_MAX (ROW_COUNT * LINE_COUNT - 1)
|
||||
|
||||
#define VALUE_MIN 1
|
||||
#define VALUE_MAX 9
|
||||
|
||||
// Files
|
||||
//
|
||||
#define VALUE_SEPARATOR ',' // Value separator in files
|
||||
#define FILE_COMMENTS '#' // Comment lines start with
|
||||
|
||||
#ifdef DEST_CASIO_CALC
|
||||
#define GRID_FOLDER u"\\\\fls0\\GRIDS"
|
||||
#else
|
||||
#define GRID_FOLDER "/home/jhb/Nextcloud/personnel/JHB/dev/cpp/sudoSolv/GRIDS"
|
||||
#endif // #ifdef DEST_CASIO_CALC
|
||||
|
||||
#define FILE_LINE_SIZE ROW_COUNT * 2 // (value & separator) * ROW_COUNT
|
||||
#define FILE_SIZE LINE_COUNT * FILE_LINE_SIZE
|
||||
|
||||
// Error codes
|
||||
//
|
||||
#define SUDO_NO_ERROR 0
|
||||
#define SUDO_INVALID_FILENAME 1 // File doesn't exist
|
||||
#define SUDO_INVALID_FILESIZE 2
|
||||
#define SUDO_NO_FILENAME 3
|
||||
#define SUDO_IO_ERROR 4
|
||||
#define SUDO_INVALID_LINE 11
|
||||
#define SUDO_INVALID_FORMAT 12
|
||||
#define SUDO_VALUE_ERROR 13 // The value can't be set at this position
|
||||
|
||||
// Display
|
||||
//
|
||||
#ifdef DEST_CASIO_CALC
|
||||
#define DELTA_X 5 // Distance from top left corner
|
||||
#define DELTA_Y DELTA_X // useless in first version ....
|
||||
|
||||
#define BORDER_THICK 2 // Thickness of external border
|
||||
|
||||
// Dimensions in pixels
|
||||
#define SQUARE_SIZE 20
|
||||
#define INT_SQUARE_SIZE (SQUARE_SIZE - 2 * BORDER_THICK)
|
||||
|
||||
#define GRID_SIZE SQUARE_SIZE * ROW_COUNT
|
||||
|
||||
#define BORDER_COLOUR C_RGB(10, 19, 23)
|
||||
#define BK_COLOUR C_RGB(28, 28, 30)
|
||||
|
||||
#define TXT_COLOUR C_RGB(8, 8, 8)
|
||||
#define ORIGINAL_COLOUR C_RGB(30, 15, 14)
|
||||
#define OBVIOUS_COLOUR BORDER_COLOUR
|
||||
|
||||
#define SEL_BK_COLOUR C_RGB(6, 6, 31)
|
||||
#define SEL_TXT_COLOUR C_WHITE
|
||||
|
||||
#endif // #ifdef DEST_CASIO_CALC
|
||||
|
||||
// Keyboard
|
||||
//
|
||||
|
||||
// Key codes
|
||||
//
|
||||
#ifdef DEST_CASIO_CALC
|
||||
enum GAME_KEY{
|
||||
KEY_CODE_F1 = KEY_F1, // !!!
|
||||
KEY_CODE_F6 = KEY_F6,
|
||||
KEY_CODE_UP = KEY_UP,
|
||||
KEY_CODE_DOWN = KEY_DOWN,
|
||||
KEY_CODE_LEFT = KEY_LEFT,
|
||||
KEY_CODE_RIGHT = KEY_RIGHT,
|
||||
KEY_CODE_0 = KEY_0,
|
||||
KEY_CODE_1 = KEY_1,
|
||||
KEY_CODE_2 = KEY_2,
|
||||
KEY_CODE_3 = KEY_3,
|
||||
KEY_CODE_4 = KEY_4,
|
||||
KEY_CODE_5 = KEY_5,
|
||||
KEY_CODE_6 = KEY_6,
|
||||
KEY_CODE_7 = KEY_7,
|
||||
KEY_CODE_8 = KEY_8,
|
||||
KEY_CODE_9 = KEY_9,
|
||||
KEY_CODE_EXIT = KEY_EXIT,
|
||||
KEY_CODE_EXE = KEY_EXE
|
||||
};
|
||||
#else
|
||||
enum GAME_KEY{
|
||||
KEY_CODE_F1 = 'A',
|
||||
KEY_CODE_F6 = 'F',
|
||||
KEY_CODE_LEFT = 's',
|
||||
KEY_CODE_RIGHT = 'f',
|
||||
KEY_CODE_UP = 'e',
|
||||
KEY_CODE_DOWN = 'x',
|
||||
KEY_CODE_0 = '0',
|
||||
KEY_CODE_1 = '1',
|
||||
KEY_CODE_2 = '2',
|
||||
KEY_CODE_3 = '3',
|
||||
KEY_CODE_4 = '4',
|
||||
KEY_CODE_5 = '5',
|
||||
KEY_CODE_6 = '6',
|
||||
KEY_CODE_7 = '7',
|
||||
KEY_CODE_8 = '8',
|
||||
KEY_CODE_9 = '9',
|
||||
KEY_CODE_EXIT = 'q',
|
||||
KEY_CODE_EXE = '\13'
|
||||
};
|
||||
#endif // #ifdef DEST_CASIO_CALC
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // #ifdef __cplusplus
|
||||
|
||||
#endif // __S_SOLVER_CONSTANTS_h__
|
||||
|
||||
// EOF
|
||||
//---------------------------------------------------------------------------
|
||||
//--
|
||||
//-- consts.h
|
||||
//--
|
||||
//-- App. constants
|
||||
//--
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef __S_SOLVER_CONSTANTS_h__
|
||||
#define __S_SOLVER_CONSTANTS_h__ 1
|
||||
|
||||
#include "shared/casioCalcs.h"
|
||||
|
||||
#ifdef DEST_CASIO_CALC
|
||||
#include <gint/keyboard.h>
|
||||
#else
|
||||
#include <iostream>
|
||||
#include <cstdint> // <stdint.h>
|
||||
using namespace std;
|
||||
#endif //
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // #ifdef __cplusplus
|
||||
|
||||
// Informations about the grid
|
||||
//
|
||||
#define ROW_COUNT 9
|
||||
#define LINE_COUNT ROW_COUNT
|
||||
|
||||
#define INDEX_MIN 0
|
||||
#define INDEX_MAX (ROW_COUNT * LINE_COUNT - 1)
|
||||
|
||||
#define VALUE_MIN 1
|
||||
#define VALUE_MAX 9
|
||||
|
||||
// Files
|
||||
//
|
||||
#define VALUE_SEPARATOR ',' // Value separator in files
|
||||
#define FILE_COMMENTS '#' // Comment lines start with
|
||||
|
||||
#ifdef DEST_CASIO_CALC
|
||||
#define GRID_FOLDER u"\\\\fls0\\GRIDS"
|
||||
#else
|
||||
#define GRID_FOLDER "/home/jhb/Nextcloud/personnel/JHB/dev/cpp/sudoSolv/GRIDS"
|
||||
#endif // #ifdef DEST_CASIO_CALC
|
||||
|
||||
#define FILE_LINE_SIZE ROW_COUNT * 2 // (value & separator) * ROW_COUNT
|
||||
#define FILE_SIZE LINE_COUNT * FILE_LINE_SIZE
|
||||
|
||||
// Error codes
|
||||
//
|
||||
#define SUDO_NO_ERROR 0
|
||||
#define SUDO_INVALID_FILENAME 1 // File doesn't exist
|
||||
#define SUDO_INVALID_FILESIZE 2
|
||||
#define SUDO_NO_FILENAME 3
|
||||
#define SUDO_IO_ERROR 4
|
||||
#define SUDO_INVALID_LINE 11
|
||||
#define SUDO_INVALID_FORMAT 12
|
||||
#define SUDO_VALUE_ERROR 13 // The value can't be set at this position
|
||||
|
||||
// Display
|
||||
//
|
||||
#ifdef DEST_CASIO_CALC
|
||||
#define DELTA_X 5 // Distance from top left corner
|
||||
#define DELTA_Y DELTA_X // useless in first version ....
|
||||
|
||||
#define BORDER_THICK 2 // Thickness of external border
|
||||
|
||||
// Dimensions in pixels
|
||||
#define SQUARE_SIZE 20
|
||||
#define INT_SQUARE_SIZE (SQUARE_SIZE - 2 * BORDER_THICK)
|
||||
|
||||
#define GRID_SIZE SQUARE_SIZE * ROW_COUNT
|
||||
|
||||
#define BORDER_COLOUR C_RGB(10, 19, 23)
|
||||
#define BK_COLOUR C_RGB(28, 28, 30)
|
||||
|
||||
#define TXT_COLOUR C_RGB(8, 8, 8)
|
||||
#define ORIGINAL_COLOUR C_RGB(30, 15, 14)
|
||||
#define OBVIOUS_COLOUR BORDER_COLOUR
|
||||
|
||||
#define SEL_BK_COLOUR C_RGB(6, 6, 31)
|
||||
#define SEL_TXT_COLOUR C_WHITE
|
||||
|
||||
#endif // #ifdef DEST_CASIO_CALC
|
||||
|
||||
// Keyboard
|
||||
//
|
||||
|
||||
// Key codes
|
||||
//
|
||||
#ifdef DEST_CASIO_CALC
|
||||
enum GAME_KEY{
|
||||
KEY_CODE_F1 = KEY_F1, // !!!
|
||||
KEY_CODE_F6 = KEY_F6,
|
||||
KEY_CODE_UP = KEY_UP,
|
||||
KEY_CODE_DOWN = KEY_DOWN,
|
||||
KEY_CODE_LEFT = KEY_LEFT,
|
||||
KEY_CODE_RIGHT = KEY_RIGHT,
|
||||
KEY_CODE_0 = KEY_0,
|
||||
KEY_CODE_1 = KEY_1,
|
||||
KEY_CODE_2 = KEY_2,
|
||||
KEY_CODE_3 = KEY_3,
|
||||
KEY_CODE_4 = KEY_4,
|
||||
KEY_CODE_5 = KEY_5,
|
||||
KEY_CODE_6 = KEY_6,
|
||||
KEY_CODE_7 = KEY_7,
|
||||
KEY_CODE_8 = KEY_8,
|
||||
KEY_CODE_9 = KEY_9,
|
||||
KEY_CODE_EXIT = KEY_EXIT,
|
||||
KEY_CODE_EXE = KEY_EXE
|
||||
};
|
||||
#else
|
||||
enum GAME_KEY{
|
||||
KEY_CODE_F1 = 'A',
|
||||
KEY_CODE_F6 = 'F',
|
||||
KEY_CODE_LEFT = 's',
|
||||
KEY_CODE_RIGHT = 'f',
|
||||
KEY_CODE_UP = 'e',
|
||||
KEY_CODE_DOWN = 'x',
|
||||
KEY_CODE_0 = '0',
|
||||
KEY_CODE_1 = '1',
|
||||
KEY_CODE_2 = '2',
|
||||
KEY_CODE_3 = '3',
|
||||
KEY_CODE_4 = '4',
|
||||
KEY_CODE_5 = '5',
|
||||
KEY_CODE_6 = '6',
|
||||
KEY_CODE_7 = '7',
|
||||
KEY_CODE_8 = '8',
|
||||
KEY_CODE_9 = '9',
|
||||
KEY_CODE_EXIT = 'q',
|
||||
KEY_CODE_EXE = '\13'
|
||||
};
|
||||
#endif // #ifdef DEST_CASIO_CALC
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // #ifdef __cplusplus
|
||||
|
||||
#endif // __S_SOLVER_CONSTANTS_h__
|
||||
|
||||
// EOF
|
||||
|
|
109
src/grids.h
109
src/grids.h
|
@ -1,54 +1,55 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//--
|
||||
//-- grids.h
|
||||
//--
|
||||
//-- Definition of grids object - List of grid files stored on "disk"
|
||||
//--
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef __S_SOLVER_GRIDS_h__
|
||||
#define __S_SOLVER_GRIDS_h__ 1
|
||||
|
||||
#include "consts.h"
|
||||
#include "shared/bFile.h"
|
||||
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // #ifdef __cplusplus
|
||||
|
||||
class grids{
|
||||
public:
|
||||
|
||||
// Construction
|
||||
grids(const FONTCHARACTER folder);
|
||||
|
||||
// Destruction
|
||||
~grids(){}
|
||||
|
||||
// # files in folder
|
||||
size_t size();
|
||||
|
||||
// Access
|
||||
bool nextFile(FONTCHARACTER fName);
|
||||
bool prevFile(FONTCHARACTER fName);
|
||||
|
||||
// File management
|
||||
bool newFileName(FONTCHARACTER folder);
|
||||
bool deleteFile(); // current
|
||||
|
||||
// Members
|
||||
protected:
|
||||
vector<int> files_;
|
||||
int current_; // Current file ID
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // #ifdef __cplusplus
|
||||
|
||||
#endif // __S_SOLVER_GRIDS_h__
|
||||
|
||||
// EOF
|
||||
//---------------------------------------------------------------------------
|
||||
//--
|
||||
//-- grids.h
|
||||
//--
|
||||
//-- Definition of grids object - List of grid files stored on "disk"
|
||||
//--
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef __S_SOLVER_GRIDS_h__
|
||||
#define __S_SOLVER_GRIDS_h__ 1
|
||||
|
||||
#include "consts.h"
|
||||
#include "shared/bFile.h"
|
||||
|
||||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // #ifdef __cplusplus
|
||||
|
||||
class grids{
|
||||
public:
|
||||
|
||||
// Construction
|
||||
grids(const FONTCHARACTER folder);
|
||||
|
||||
// Destruction
|
||||
~grids(){}
|
||||
|
||||
// # files in folder
|
||||
size_t size();
|
||||
|
||||
// Access
|
||||
void fileName(FONTCHARACTER fName); // current
|
||||
bool nextFile(FONTCHARACTER fName);
|
||||
bool prevFile(FONTCHARACTER fName);
|
||||
|
||||
// File management
|
||||
bool newFileName(FONTCHARACTER folder);
|
||||
bool deleteFile(); // current
|
||||
|
||||
// Members
|
||||
protected:
|
||||
vector<int> files_;
|
||||
int current_; // Current file ID
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // #ifdef __cplusplus
|
||||
|
||||
#endif // __S_SOLVER_GRIDS_h__
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
|
||||
//---------------------------------------------------------------------------
|
||||
//--
|
||||
//-- menu.h
|
||||
//--
|
||||
//-- Definition menu constants
|
||||
//--
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef __SUDOKU_S_MENU_h__
|
||||
#define __SUDOKU_S_MENU_h__ 1
|
||||
|
||||
#include "shared/menuBar.h"
|
||||
|
||||
// Main menu
|
||||
//
|
||||
#define IDS_FILE_SUB "File"
|
||||
#define IDS_EDIT "Edit"
|
||||
#define IDS_SOLVER_SUB "Solver"
|
||||
#define IDS_QUIT "Quit"
|
||||
|
||||
#define IDM_EDIT 200
|
||||
#define IDM_QUIT 400
|
||||
|
||||
|
||||
// "File" menu bar
|
||||
//
|
||||
#define IDS_FILE_NEW "New"
|
||||
#define IDS_FILE_PREV "Previous"
|
||||
#define IDS_FILE_NEXT "Next"
|
||||
#define IDS_FILE_SAVE "Save"
|
||||
|
||||
#define IDM_FILE_NEW 101
|
||||
#define IDM_FILE_PREV 102
|
||||
#define IDM_FILE_NEXT 103
|
||||
#define IDM_FILE_SAVE 104
|
||||
|
||||
// "Solver" menu bar
|
||||
//
|
||||
#define IDS_SOLVER_OBVIOUS "Obvious"
|
||||
#define IDS_SOLVER_FIND "Find"
|
||||
|
||||
#define IDM_SOLVER_OBVIOUS 301
|
||||
#define IDM_SOLVER_FIND 302
|
||||
|
||||
#endif // __SUDOKU_S_MENU_h__
|
||||
|
||||
// EOF
|
|
@ -91,7 +91,7 @@ uint8_t position::backward(uint8_t dec){
|
|||
void position::decRow(uint8_t dec){
|
||||
int8_t row(row_);
|
||||
row-=dec;
|
||||
index_ = (row < 0)?(line_ * ROW_COUNT - 1):(index_ - dec);
|
||||
index_ = (row < 0)?((line_ + 1) * ROW_COUNT - 1):(index_ - dec);
|
||||
|
||||
_whereAmI();
|
||||
}
|
||||
|
|
|
@ -97,8 +97,8 @@ typedef struct __point {
|
|||
// A simple rect. struct
|
||||
//
|
||||
typedef struct __rect{
|
||||
uint16_t x,y; // top left
|
||||
uint16_t w, h; // width and height
|
||||
int x,y; // top left
|
||||
int w, h; // width and height
|
||||
} RECT;
|
||||
|
||||
#endif // #ifndef __GEE_CASIO_CALCS_h__
|
||||
|
|
|
@ -1,14 +1,6 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//--
|
||||
//-- File : keyboard.cpp
|
||||
//--
|
||||
//-- Author : Jérôme Henry-Barnaudière - GeeHB
|
||||
//--
|
||||
//-- Project :
|
||||
//--
|
||||
//---------------------------------------------------------------------------
|
||||
//--
|
||||
//-- Description:
|
||||
//-- keyboard.cpp
|
||||
//--
|
||||
//-- Implementation of keyboard object
|
||||
//--
|
||||
|
@ -62,6 +54,7 @@ uint keyboard::getKey(){
|
|||
}
|
||||
#else
|
||||
key = getchar();
|
||||
if (key == 10) key = 0; // CR
|
||||
mod_ = MOD_NONE;
|
||||
#endif // #ifdef DEST_CASIO_CALC
|
||||
|
||||
|
|
|
@ -1,21 +1,13 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//--
|
||||
//-- File : keyboard.h
|
||||
//--
|
||||
//-- Author : Jérôme Henry-Barnaudière - GeeHB
|
||||
//--
|
||||
//-- Project :
|
||||
//--
|
||||
//---------------------------------------------------------------------------
|
||||
//--
|
||||
//-- Description:
|
||||
//-- keyboard.h
|
||||
//--
|
||||
//-- Definition of keyboard object
|
||||
//--
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef __GEE_TOOLS_KEYBOARD_h__
|
||||
#define __GEE_TOOLS_KEYBOARD_h__ 1
|
||||
#ifndef __GEE_TOOLS_KEYBOARD_C_h__
|
||||
#define __GEE_TOOLS_KEYBOARD_C_h__ 1
|
||||
|
||||
#include "casioCalcs.h"
|
||||
|
||||
|
@ -85,6 +77,6 @@ protected:
|
|||
}
|
||||
#endif // #ifdef __cplusplus
|
||||
|
||||
#endif // __GEE_TOOLS_KEYBOARD_h__
|
||||
#endif // __GEE_TOOLS_KEYBOARD_C_h__
|
||||
|
||||
// EOF
|
||||
|
|
|
@ -0,0 +1,516 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//--
|
||||
//-- menuBar.cpp
|
||||
//--
|
||||
//-- Implementation of menuBar object
|
||||
//--
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "menuBar.h"
|
||||
|
||||
#include <cstdlib>
|
||||
#include <cstring>
|
||||
|
||||
#ifndef DEST_CASIO_CALC
|
||||
#include <iostream>
|
||||
using namespace std;
|
||||
#define KEY_F1 'a'
|
||||
#define KEY_F6 'y'
|
||||
#endif // #ifndef DEST_CASIO_CALC
|
||||
|
||||
// Construction
|
||||
//
|
||||
menuBar::menuBar(){
|
||||
// Intializes members
|
||||
visible_ = ¤t_; // show current bar
|
||||
rect_ = {0, CASIO_HEIGHT - MENUBAR_DEF_HEIGHT - 1, CASIO_WIDTH, MENUBAR_DEF_HEIGHT};
|
||||
|
||||
_clearMenuBar(¤t_);
|
||||
}
|
||||
|
||||
// Dimensions
|
||||
//
|
||||
bool menuBar::setHeight(uint16_t barHeight){
|
||||
rect_ = {0, CASIO_HEIGHT - barHeight - 1, CASIO_WIDTH, barHeight};
|
||||
update();
|
||||
return true;
|
||||
}
|
||||
|
||||
// Drawings
|
||||
//
|
||||
void menuBar::update(){
|
||||
if (NULL == visible_){
|
||||
return;
|
||||
}
|
||||
|
||||
RECT anchor = {rect_.x, rect_.y, MENUBAR_DEF_ITEM_WIDTH, rect_.h}; // First item's rect
|
||||
PMENUITEM item(nullptr);
|
||||
for (uint8_t index(0); index < MENU_MAX_ITEM_COUNT; index++){
|
||||
item = visible_->items[index];
|
||||
#ifdef DEST_CASIO_CALC
|
||||
_drawItem(&anchor, item);
|
||||
#else
|
||||
if (item){
|
||||
cout << "|" << ((item->state == ITEM_SELECTED)?">" : " ");
|
||||
cout << item->text;
|
||||
cout << ((item->state == ITEM_SELECTED)?"<" : " ");
|
||||
cout << "|";
|
||||
}
|
||||
else{
|
||||
cout << "| |";
|
||||
}
|
||||
#endif // DEST_CASIO_CALC
|
||||
|
||||
anchor.x += anchor.w; // Next item's position
|
||||
} // for
|
||||
|
||||
#ifdef DEST_CASIO_CALC
|
||||
dupdate();
|
||||
#else
|
||||
cout << endl;
|
||||
#endif // #ifdef DEST_CASIO_CALC
|
||||
}
|
||||
|
||||
// addItem() : Add an item to the current menu bar
|
||||
//
|
||||
// @id : Item ID
|
||||
// @text : Item text
|
||||
// @state : Item's initial state
|
||||
//
|
||||
// @return : true if the item has been added
|
||||
//
|
||||
bool menuBar::addItem(int id, const char* text, int state){
|
||||
size_t len(0);
|
||||
if (IDM_SUBMENU == id ||
|
||||
_findItemByID(¤t_, id) || // this ID is already handled
|
||||
current_.itemCount == (MENU_MAX_ITEM_COUNT - 1) ||
|
||||
! text || !(len = strlen(text))){
|
||||
return false;
|
||||
}
|
||||
|
||||
PMENUITEM item = _createItem(id, text, state);
|
||||
if (item){
|
||||
// Append to the menu
|
||||
if (IDM_BACK == id){
|
||||
current_.items[MENU_MAX_ITEM_COUNT-1] = item;
|
||||
}
|
||||
else{
|
||||
current_.items[current_.itemCount++] = item;
|
||||
}
|
||||
|
||||
// one more item in menu
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// addSubMenu() : Add a sub menu
|
||||
//
|
||||
// @submenu : menubar corresponding to the new submenu
|
||||
// @text : Submenu text
|
||||
//
|
||||
// @return : true if sub menu is added
|
||||
//
|
||||
bool menuBar::addSubMenu(const menuBar* subMenu, const char* text){
|
||||
size_t len(0);
|
||||
if (!subMenu ||
|
||||
current_.itemCount == (MENU_MAX_ITEM_COUNT - 1) ||
|
||||
! text || !(len = strlen(text))){
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create a copy of the menu bar
|
||||
PMENUBAR sub = _copyMenuBar((PMENUBAR)subMenu);
|
||||
if (NULL == sub){
|
||||
return false;
|
||||
}
|
||||
|
||||
// Create item
|
||||
PMENUITEM item = _createItem(IDM_SUBMENU, text, ITEM_DEFAULT);
|
||||
if (NULL == item){
|
||||
_freeMenuBar(sub, true);
|
||||
return false;
|
||||
}
|
||||
|
||||
item->status = ITEM_STATUS_SUBMENU;
|
||||
item->subMenu = sub;
|
||||
sub->parent = ¤t_;
|
||||
|
||||
current_.items[current_.itemCount++] = item; // Add an item pointing to the sub menu
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
// createSubMenu() : Create an empty sub menu
|
||||
//
|
||||
// @return : a pointer to the new menu object if created
|
||||
//
|
||||
menuBar* menuBar::createSubMenu(){
|
||||
menuBar* sub(NULL);
|
||||
|
||||
if (size() < (MENU_MAX_ITEM_COUNT - 1)){
|
||||
sub = new menuBar;
|
||||
}
|
||||
|
||||
return sub;
|
||||
}
|
||||
*/
|
||||
|
||||
// activate() : Activate or deactivate an item
|
||||
//
|
||||
// When an item is deactivated, it can't be called by the user
|
||||
//
|
||||
// @id : Menu item's ID
|
||||
// @activated : true if item must be activated
|
||||
//
|
||||
// @return : true if activation state changed
|
||||
//
|
||||
bool menuBar::activate(int id, bool activated){
|
||||
PMENUITEM item = _findItemByID(¤t_, id);
|
||||
if (item){
|
||||
// Found an item with this ID
|
||||
bool inactive = (item->state == ITEM_INACTIVE);
|
||||
if (inactive == activated){
|
||||
item->state = (activated?ITEM_DEFAULT:ITEM_INACTIVE); // change item's state
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// handleKeyboard() : Handle the keyboard events
|
||||
//
|
||||
// @return : MENUACTION struct containing info about item selected b user
|
||||
//
|
||||
MENUACTION menuBar::handleKeyboard(){
|
||||
uint key(0);
|
||||
uint8_t kID(0);
|
||||
keyboard kb;
|
||||
PMENUITEM item(NULL);
|
||||
MENUACTION ret = {0, ACTION_KEYBOARD};
|
||||
bool readKeyboard(true);
|
||||
|
||||
if (readKeyboard){
|
||||
key = kb.getKey();
|
||||
|
||||
// a menu key pressed ?
|
||||
if (key >= KEY_F1 && key <= KEY_F6){
|
||||
kID = (key - KEY_F1);
|
||||
|
||||
// Associated item
|
||||
if (kID < MENU_MAX_ITEM_COUNT &&
|
||||
(item = visible_->items[kID]) &&
|
||||
item->state != ITEM_INACTIVE){
|
||||
// A sub menu ?
|
||||
if (item->status == ITEM_STATUS_SUBMENU){
|
||||
if (item->subMenu){
|
||||
visible_ = (MENUBAR*)item->subMenu; // new "visible" menu
|
||||
_selectIndex(-1, false, false);
|
||||
update();
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (IDM_BACK == item->id){
|
||||
visible_ = visible_->parent; // Return to previous menu
|
||||
_selectIndex(-1, false, false);
|
||||
update();
|
||||
}
|
||||
else{
|
||||
// a selectable item ...
|
||||
ret.value = item->id;
|
||||
ret.type = ACTION_MENU;
|
||||
readKeyboard = false;
|
||||
|
||||
// select the item
|
||||
if (kID != visible_->selIndex){
|
||||
_selectIndex(kID, true, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef DEST_CASIO_CALC
|
||||
update();
|
||||
#endif // #ifndef DEST_CASIO_CALC
|
||||
|
||||
} // if in [KEY_F1, KEY_F6]
|
||||
else{
|
||||
ret.value = key;
|
||||
ret.type = ACTION_KEYBOARD;
|
||||
readKeyboard = false;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
// _clearMenuBar() : Empty a menu bar
|
||||
//
|
||||
// @bar : menu bar the clear
|
||||
//
|
||||
void menuBar::_clearMenuBar(PMENUBAR bar){
|
||||
if (bar){
|
||||
bar->itemCount = 0;
|
||||
bar->selIndex = -1; // No item is selected
|
||||
bar->parent = NULL;
|
||||
memset(bar->items, 0, sizeof(PMENUITEM) * MENU_MAX_ITEM_COUNT);
|
||||
}
|
||||
}
|
||||
|
||||
// _copyMenuBar() : Make a copy of a menu bar
|
||||
//
|
||||
// All contained items and sub menus will be copied.
|
||||
//
|
||||
// @source : Pointer to the source or NULL on error
|
||||
//
|
||||
// @return : Pointer to the new copy
|
||||
//
|
||||
PMENUBAR menuBar::_copyMenuBar(PMENUBAR source){
|
||||
PMENUBAR bar(NULL);
|
||||
if (source && (bar = (PMENUBAR)malloc(sizeof(MENUBAR)))){
|
||||
_clearMenuBar(bar);
|
||||
bar->itemCount = source->itemCount;
|
||||
bar->parent = source->parent;
|
||||
uint8_t maxItem(MENU_MAX_ITEM_COUNT-1);
|
||||
PMENUITEM sitem, nitem;
|
||||
for (uint8_t index(0); index < maxItem; index++){
|
||||
nitem = _copyItem(bar, (sitem = source->items[index]));
|
||||
bar->items[index] = nitem; // simple item copy
|
||||
}
|
||||
|
||||
// In sub menus last right item is used to return to parent menu
|
||||
bar->items[MENU_MAX_ITEM_COUNT-1] = _createItem(IDM_BACK, STR_BACK, ITEM_DEFAULT);
|
||||
}
|
||||
return bar;
|
||||
}
|
||||
|
||||
// _freeMenuBar() : Free memory used by a bar
|
||||
//
|
||||
// @bar : Pointer to the bar to be released
|
||||
// @freeAll : Free bar as well ?
|
||||
//
|
||||
void menuBar::_freeMenuBar(PMENUBAR bar, bool freeAll){
|
||||
if (bar){
|
||||
PMENUITEM item(NULL);
|
||||
for (uint8_t index(0); index < MENU_MAX_ITEM_COUNT; index++){
|
||||
if ((item = bar->items[index])){
|
||||
// A submenu ?
|
||||
if ((item->status & ITEM_STATUS_SUBMENU) && item->subMenu){
|
||||
_freeMenuBar((PMENUBAR)item->subMenu, true);
|
||||
}
|
||||
|
||||
free(item); // free the item
|
||||
}
|
||||
}
|
||||
|
||||
if (freeAll){
|
||||
free(bar); // free the bar
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
// Menu items
|
||||
//
|
||||
|
||||
// _findItemByID() : Find an item in the current bar
|
||||
//
|
||||
// @bar : menu bar containing items
|
||||
// @id : id of the searched item
|
||||
//
|
||||
// @return : pointer to the item if found or NULL
|
||||
//
|
||||
PMENUITEM menuBar::_findItemByID(PMENUBAR bar, int id){
|
||||
if (bar){
|
||||
PMENUITEM item(NULL), sItem(NULL);
|
||||
for (uint8_t index = 0; index < MENU_MAX_ITEM_COUNT; index++){
|
||||
if ((item = bar->items[index])){
|
||||
if (item->status & ITEM_STATUS_SUBMENU){
|
||||
// in a sub menu ?
|
||||
if ((sItem = _findItemByID((PMENUBAR)item->subMenu, id))){
|
||||
return sItem; // Found in a sub menu
|
||||
}
|
||||
}
|
||||
else{
|
||||
if (item->id == id){
|
||||
return item; // found
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} // if (bar)
|
||||
|
||||
// not found
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// _createItem() : creae a new menu item
|
||||
//
|
||||
// @id : Item's id
|
||||
// @text : Menu item text
|
||||
// @state : Item's initial state
|
||||
//
|
||||
// @return : pointer to the new created if valid or NULL
|
||||
//
|
||||
PMENUITEM menuBar::_createItem(int id, const char* text, int state){
|
||||
size_t len(strlen(text));
|
||||
MENUITEM* item(NULL);
|
||||
if ((item = (PMENUITEM)malloc(sizeof(MENUITEM)))){
|
||||
item->id = id;
|
||||
item->state = state;
|
||||
item->status = ITEM_STATUS_DEFAULT;
|
||||
if (len > ITEM_NAME_LEN){
|
||||
strncpy(item->text, text, ITEM_NAME_LEN);
|
||||
item->text[ITEM_NAME_LEN] = '\0';
|
||||
}
|
||||
else{
|
||||
strcpy(item->text, text);
|
||||
}
|
||||
|
||||
item->subMenu = NULL;
|
||||
}
|
||||
|
||||
return item;
|
||||
}
|
||||
|
||||
// _copyItem() : Make a copy of an item
|
||||
//
|
||||
// @bar : Destination menu bar container
|
||||
// @source : Pointer to the source item
|
||||
//
|
||||
// @return : pointer to the copied item or NULL
|
||||
//
|
||||
PMENUITEM menuBar::_copyItem(PMENUBAR bar, PMENUITEM source){
|
||||
PMENUITEM item(NULL);
|
||||
if (source && (item = (PMENUITEM)malloc(sizeof(MENUITEM)))){
|
||||
item->id = source->id;
|
||||
item->state = source->state;
|
||||
item->status = source->status;
|
||||
strcpy(item->text, source->text);;
|
||||
|
||||
if (source->status & ITEM_STATUS_SUBMENU){
|
||||
item->subMenu = _copyMenuBar((PMENUBAR)source->subMenu);
|
||||
((PMENUBAR)(item->subMenu))->parent = bar; // attach it to the new bar
|
||||
}
|
||||
else{
|
||||
item->subMenu = NULL;
|
||||
}
|
||||
}
|
||||
return item;
|
||||
}
|
||||
|
||||
// _selectIndex() : Select an item by index in the current bar
|
||||
//
|
||||
// @index : index of menu item to select or unselect
|
||||
// if equal to -1, unselect the currently selected item
|
||||
// @selected : true if item is to be selected
|
||||
// @redraw : when true, item and previously (un)selected item are drawn in their
|
||||
// new states
|
||||
//
|
||||
// @return : true if item is selected
|
||||
//
|
||||
bool menuBar::_selectIndex(int8_t index, bool selected, bool redraw){
|
||||
int8_t sel;
|
||||
if (index >= MENU_MAX_ITEM_COUNT ||
|
||||
index == (sel = getSelectedIndex())){
|
||||
return false; // Nothing to do
|
||||
}
|
||||
|
||||
if (-1 == index){
|
||||
index = sel;
|
||||
selected = false;
|
||||
}
|
||||
|
||||
// Select or unselect an item
|
||||
if (index >= 0){
|
||||
// Item
|
||||
PMENUITEM item = visible_->items[index];
|
||||
if (NULL == item){
|
||||
return false;
|
||||
}
|
||||
|
||||
if (selected){
|
||||
item->state = ITEM_SELECTED;
|
||||
visible_->selIndex = index;
|
||||
|
||||
// unselect prev.
|
||||
if (-1 != sel && (item = visible_->items[sel])){
|
||||
item->state = ITEM_UNSELECTED;
|
||||
}
|
||||
}
|
||||
else{
|
||||
item->state = ITEM_UNSELECTED;
|
||||
visible_->selIndex = -1;
|
||||
}
|
||||
}
|
||||
|
||||
// Update screen ?
|
||||
if (redraw){
|
||||
RECT anchor = {rect_.x, rect_.y, MENUBAR_DEF_ITEM_WIDTH, rect_.h};
|
||||
if (-1 != sel){
|
||||
anchor.x+=(sel * anchor.w);
|
||||
_drawItem(&anchor, visible_->items[sel]);
|
||||
}
|
||||
|
||||
if (-1 != index){
|
||||
anchor.x=(index * anchor.w + rect_.x);
|
||||
_drawItem(&anchor, visible_->items[index]);
|
||||
}
|
||||
}
|
||||
|
||||
// Done
|
||||
return true;
|
||||
}
|
||||
|
||||
// _drawItem() : Draw an item
|
||||
//
|
||||
// @anchor : Position of the item in screen coordinates
|
||||
// @item : Pointer to a MENUITEM strcut containing informations about item to draw
|
||||
//
|
||||
void menuBar::_drawItem(const RECT* anchor, const MENUITEM* item){
|
||||
#ifdef DEST_CASIO_CALC
|
||||
bool selected(false);
|
||||
|
||||
// Draw back ground
|
||||
drect(anchor->x, anchor->y, anchor->x + anchor->w - 1, anchor->y + anchor->h - 1, COLOUR_WHITE);
|
||||
|
||||
if (item){
|
||||
selected = (ITEM_SELECTED == item->state);
|
||||
|
||||
// Text
|
||||
if (item->text){
|
||||
int x,y, w, h;
|
||||
dsize(item->text, NULL, &w, &h);
|
||||
|
||||
// center text
|
||||
x = anchor->x + (anchor->w - w) / 2;
|
||||
y = anchor->y + (anchor->h - h) / 2;
|
||||
|
||||
// text too large ?
|
||||
|
||||
// draw the text
|
||||
dtext(x, y, selected?ITEM_COLOUR_SELECTED:((item->state == ITEM_INACTIVE)?ITEM_COLOUR_INACTIVE:ITEM_COLOUR_UNSELECTED), item->text);
|
||||
}
|
||||
|
||||
// frame
|
||||
if (selected){
|
||||
dline(anchor->x, anchor->y, anchor->x, anchor->y + anchor->h - 2, COLOUR_BLACK); // Left
|
||||
dline(anchor->x+1, anchor->y + anchor->h - 1,
|
||||
anchor->x + anchor->w -1 - ITEM_ROUNDED_DIM, anchor->y + anchor->h - 1, COLOUR_BLACK); // bottom
|
||||
dline(anchor->x + anchor->w -1 - ITEM_ROUNDED_DIM, anchor->y + anchor->h - 1,
|
||||
anchor->x + anchor->w - 1, anchor->y + anchor->h - 1 - ITEM_ROUNDED_DIM, COLOUR_BLACK); // bottom
|
||||
dline(anchor->x + anchor->w - 1, anchor->y,
|
||||
anchor->x + anchor->w - 1, anchor->y + anchor->h - 1 - ITEM_ROUNDED_DIM, COLOUR_BLACK); // right
|
||||
}
|
||||
} // if (item)
|
||||
|
||||
if (!selected){
|
||||
dline(anchor->x, anchor->y, anchor->x + anchor->w -1, anchor->y, COLOUR_BLACK);
|
||||
}
|
||||
#endif // #ifdef DEST_CASIO_CALC
|
||||
}
|
||||
|
||||
// EOF
|
|
@ -0,0 +1,294 @@
|
|||
//---------------------------------------------------------------------------
|
||||
//--
|
||||
//-- menuBar.h
|
||||
//--
|
||||
//-- Definition of menuBar object - A bar of menu (or submenu)
|
||||
//--
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#ifndef __MENU_BAR_h__
|
||||
#define __MENU_BAR_h__ 1
|
||||
|
||||
#include "casioCalcs.h"
|
||||
#include "keyboard.h"
|
||||
|
||||
#define MENU_MAX_ITEM_COUNT 6 // ie. "F" buttons count
|
||||
|
||||
// Dimensions in pixels
|
||||
#define MENUBAR_DEF_HEIGHT 22
|
||||
#define MENUBAR_DEF_ITEM_WIDTH (CASIO_WIDTH / MENU_MAX_ITEM_COUNT)
|
||||
|
||||
#define ITEM_NAME_LEN 10 // Max length of item name
|
||||
|
||||
// Item state
|
||||
//
|
||||
#define ITEM_DEFAULT 0
|
||||
#define ITEM_SELECTED 1
|
||||
#define ITEM_UNSELECTED ITEM_DEFAULT
|
||||
#define ITEM_INACTIVE 2
|
||||
|
||||
// Item status
|
||||
//
|
||||
#define ITEM_STATUS_DEFAULT 0
|
||||
#define ITEM_STATUS_SUBMENU 2 // Open a sub menu on "click"
|
||||
#define ITEM_STATUS_KEYCODE 3 // item's ID is a key code
|
||||
|
||||
// Reserved menu item ID
|
||||
//
|
||||
#define IDM_SUBMENU 0xFFFA // This item holds a submenu
|
||||
#define IDM_BACK 0xFFFB // Return to parent menu
|
||||
|
||||
#define STR_BACK "^ back ^"
|
||||
|
||||
// item colors
|
||||
#define ITEM_COLOUR_SELECTED COLOUR_BLUE
|
||||
#define ITEM_COLOUR_UNSELECTED COLOUR_DK_GREY
|
||||
#define ITEM_COLOUR_INACTIVE COLOUR_GREY
|
||||
|
||||
#define ITEM_ROUNDED_DIM 4
|
||||
|
||||
// A single item
|
||||
//
|
||||
typedef struct _menuItem{
|
||||
int id;
|
||||
int state;
|
||||
int status;
|
||||
char text[ITEM_NAME_LEN + 1];
|
||||
void* subMenu;
|
||||
} MENUITEM,* PMENUITEM;
|
||||
|
||||
// A menu bar
|
||||
//
|
||||
typedef struct _menuBar{
|
||||
uint8_t itemCount;
|
||||
int8_t selIndex;
|
||||
_menuBar* parent;
|
||||
PMENUITEM items[MENU_MAX_ITEM_COUNT];
|
||||
} MENUBAR, * PMENUBAR;
|
||||
|
||||
// Action to perform
|
||||
//
|
||||
typedef struct _menuAction{
|
||||
int value;
|
||||
uint8_t type;
|
||||
} MENUACTION;
|
||||
|
||||
// Type of actions
|
||||
//
|
||||
#define ACTION_MENU 0 // value is a menu ID
|
||||
#define ACTION_KEYBOARD 1 // value is a keycode
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif // #ifdef __cplusplus
|
||||
|
||||
// menuBar : A bar of menu (or submenu)
|
||||
//
|
||||
class menuBar{
|
||||
public:
|
||||
|
||||
// Construction
|
||||
menuBar();
|
||||
|
||||
// Destruction
|
||||
~menuBar(){
|
||||
_freeMenuBar(¤t_, false);
|
||||
}
|
||||
|
||||
// setHeight() : change menu bar height
|
||||
//
|
||||
// @barHeight : New height in pixels
|
||||
//
|
||||
// @return : true if hieght has changed
|
||||
//
|
||||
bool setHeight(uint16_t barHeight);
|
||||
|
||||
// getRect() : Get bounding rect of current menu bar
|
||||
//
|
||||
void getRect(RECT& barRect){
|
||||
barRect = {rect_.x, rect_.y, rect_.w, rect_.h};
|
||||
}
|
||||
|
||||
// update() : Update the menu bar
|
||||
//
|
||||
// All items will be drawn according to their state et status
|
||||
//
|
||||
void update();
|
||||
|
||||
//
|
||||
// Items & subBars
|
||||
//
|
||||
|
||||
// size() : count of items or sub menus in the bar
|
||||
//
|
||||
// @return : The count of items or sub menus
|
||||
//
|
||||
uint8_t size(){
|
||||
return current_.itemCount;
|
||||
}
|
||||
|
||||
|
||||
// addSubMenu() : Add a sub menu
|
||||
//
|
||||
// @submenu : menubar corresponding to the new submenu
|
||||
// @text : Submenu text
|
||||
//
|
||||
// @return : true if sub menu is added
|
||||
//
|
||||
bool addSubMenu(const menuBar* subMenu, const char* text);
|
||||
|
||||
// createSubMenu() : Create an empty sub menu
|
||||
//
|
||||
// @return : a pointer to the new menu object if created
|
||||
//
|
||||
//menuBar* createSubMenu();
|
||||
|
||||
// addItem() : Add an item to the current menu bar
|
||||
//
|
||||
// @id : Item ID
|
||||
// @text : Item text
|
||||
// @state : Item's initial state
|
||||
//
|
||||
// @return : true if the item has been added
|
||||
//
|
||||
bool addItem(int id, const char* text, int state = ITEM_DEFAULT);
|
||||
|
||||
// Selection & activation
|
||||
//
|
||||
|
||||
// selectIndex() : Select an item by index in the current bar
|
||||
//
|
||||
// @index : index of menu item to select or unselect
|
||||
// @selected : true if item is to be selected
|
||||
//
|
||||
// @return : true if item is selected
|
||||
//
|
||||
bool selectIndex(int8_t index, bool selected = true){
|
||||
return _selectIndex(index, selected, true); // Redraw items
|
||||
}
|
||||
|
||||
// getSelectedIndex() : Index of selected item in the current bar
|
||||
//
|
||||
// @return : Index of item selected or -1 if none
|
||||
//
|
||||
int8_t getSelectedIndex(){
|
||||
return (visible_?visible_->selIndex:current_.selIndex);
|
||||
}
|
||||
|
||||
// activate() : Activate or deactivate an item
|
||||
//
|
||||
// When an item is deactivated, it can't be called by the user
|
||||
//
|
||||
// @id : Menu item's ID
|
||||
// @activated : true if item must be activated
|
||||
//
|
||||
// @return : true if activation state changed
|
||||
//
|
||||
bool activate(int id, bool activated = true);
|
||||
|
||||
// Access
|
||||
//
|
||||
operator PMENUBAR() const{
|
||||
return (MENUBAR*)(¤t_);
|
||||
}
|
||||
|
||||
// handleKeyboard() : Handle the keyboard events
|
||||
//
|
||||
// @return : MENUACTION struct containing info about item selected b user
|
||||
//
|
||||
MENUACTION handleKeyboard();
|
||||
|
||||
// Internal methods
|
||||
private:
|
||||
|
||||
//
|
||||
// menu bars
|
||||
//
|
||||
|
||||
// _clearMenuBar() : Empty a menu bar
|
||||
//
|
||||
// @bar : menu bar the clear
|
||||
//
|
||||
void _clearMenuBar(PMENUBAR bar);
|
||||
|
||||
// _copyMenuBar() : Make a copy of a menu bar
|
||||
//
|
||||
// All contained items and sub menus will be copied.
|
||||
//
|
||||
// @source : Pointer to the source
|
||||
//
|
||||
// @return : Pointer to the new copy or NULL on error
|
||||
//
|
||||
PMENUBAR _copyMenuBar(PMENUBAR source);
|
||||
|
||||
// _freeMenuBar() : Free memory used by a bar
|
||||
//
|
||||
// @bar : Pointer to the bar to be released
|
||||
// @freeAll : Free bar as well ?
|
||||
//
|
||||
void _freeMenuBar(PMENUBAR bar, bool freeAll);
|
||||
|
||||
//
|
||||
// menu items management
|
||||
//
|
||||
|
||||
// _findItemByID() : Find an item in the current bar
|
||||
//
|
||||
// @bar : menu bar containing items
|
||||
// @id : id of the searched item
|
||||
//
|
||||
// @return : pointer to the item if found or NULL
|
||||
//
|
||||
PMENUITEM _findItemByID(PMENUBAR bar, int id);
|
||||
|
||||
// _createItem() : creae a new menu item
|
||||
//
|
||||
// @id : Item's id
|
||||
// @text : Menu item text
|
||||
// @state : Item's initial state
|
||||
//
|
||||
// @return : pointer to the new created if valid or NULL
|
||||
//
|
||||
PMENUITEM _createItem(int id, const char* text, int state);
|
||||
|
||||
// _copyItem() : Make a copy of an item
|
||||
//
|
||||
// @bar : Destination menu bar container
|
||||
// @source : Pointer to the source item
|
||||
//
|
||||
// @return : pointer to the copied item or NULL
|
||||
//
|
||||
PMENUITEM _copyItem(PMENUBAR bar, PMENUITEM source);
|
||||
|
||||
// _selectIndex() : Select an item by index in the current bar
|
||||
//
|
||||
// @index : index of menu item to select or unselect
|
||||
// @selected : true if item is to be selected
|
||||
// @redraw : when true, item and previously (un)selected item are drawn in their
|
||||
// new states
|
||||
//
|
||||
// @return : true if item is selected
|
||||
//
|
||||
bool _selectIndex(int8_t index, bool selected, bool redraw);
|
||||
|
||||
// _drawItem() : Draw an item
|
||||
//
|
||||
// @anchor : Position of the item in screen coordinates
|
||||
// @item : Pointer to a MENUITEM strcut containing informations about item to draw
|
||||
//
|
||||
void _drawItem(const RECT* anchor, const MENUITEM* item);
|
||||
|
||||
// Members
|
||||
private:
|
||||
MENUBAR current_; // Active bar
|
||||
RECT rect_; // Bar position and dims
|
||||
PMENUBAR visible_; // Visible menu bar
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif // #ifdef __cplusplus
|
||||
|
||||
#endif // __MENU_BAR_h__
|
||||
|
||||
// EOF
|
116
src/sudoSolv.cpp
116
src/sudoSolv.cpp
|
@ -1,31 +1,103 @@
|
|||
#include "sudoku.h"
|
||||
//---------------------------------------------------------------------------
|
||||
//--
|
||||
//-- sudoSolv.cpp
|
||||
//--
|
||||
//-- Create, edit, modify and find a solution to a sudoku grid
|
||||
//--
|
||||
//-- App. entry point
|
||||
//--
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
#include "sudoku.h"
|
||||
#include "menu.h"
|
||||
|
||||
#define GRID_FILE u"\\\\fls0\\GRIDS\\1.txt"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
dclear(C_WHITE);
|
||||
|
||||
sudoku myGame;
|
||||
|
||||
if (myGame.load((FONTCHARACTER)GRID_FILE)){
|
||||
myGame.display();
|
||||
|
||||
myGame.edit();
|
||||
|
||||
// Any obvious value(s) ?
|
||||
if (myGame.findObviousValues()){
|
||||
myGame.display();
|
||||
getkey();
|
||||
}
|
||||
|
||||
// A solution ?
|
||||
if (myGame.resolve()){
|
||||
// yes !!!
|
||||
myGame.display();
|
||||
getkey();
|
||||
}
|
||||
}
|
||||
|
||||
sudoku game;
|
||||
menuBar menu;
|
||||
|
||||
//
|
||||
// Create menus
|
||||
//
|
||||
|
||||
// "File" sub menu
|
||||
//menuBar* subMenu = menu.createSubMenu(); // equivalent to new menuBar()
|
||||
//menuBar* subMenu = new menuBar();
|
||||
{
|
||||
menuBar subMenu;
|
||||
subMenu.addItem(IDM_FILE_NEW, IDS_FILE_NEW);
|
||||
subMenu.addItem(IDM_FILE_PREV, IDS_FILE_PREV, ITEM_INACTIVE);
|
||||
subMenu.addItem(IDM_FILE_NEXT, IDS_FILE_NEXT, ITEM_INACTIVE);
|
||||
subMenu.addItem(IDM_FILE_SAVE, IDS_FILE_SAVE, ITEM_INACTIVE);
|
||||
menu.addSubMenu(&subMenu, IDS_FILE_SUB);
|
||||
//delete subMenu; // Don't need sub menu any longer !
|
||||
}
|
||||
|
||||
menu.addItem(IDM_EDIT, IDS_EDIT);
|
||||
|
||||
// "Solver" submenu
|
||||
{
|
||||
menuBar subMenu;
|
||||
subMenu.addItem(IDM_SOLVER_OBVIOUS, IDS_SOLVER_OBVIOUS);
|
||||
subMenu.addItem(IDM_SOLVER_FIND, IDS_SOLVER_FIND);
|
||||
menu.addSubMenu(&subMenu, IDS_SOLVER_SUB);
|
||||
//delete subMenu;
|
||||
}
|
||||
|
||||
menu.addItem(IDM_QUIT, IDS_QUIT);
|
||||
menu.update();
|
||||
|
||||
//
|
||||
// App. main loop
|
||||
//
|
||||
bool end(false);
|
||||
MENUACTION action;
|
||||
while (!end){
|
||||
// A menu action ?
|
||||
action = menu.handleKeyboard();
|
||||
|
||||
// from menu ?
|
||||
if (ACTION_MENU == action.type){
|
||||
switch (action.value){
|
||||
|
||||
case IDM_FILE_NEW:
|
||||
game.empty();
|
||||
game.display();
|
||||
break;
|
||||
|
||||
case IDM_EDIT:{
|
||||
bool modified = game.edit();
|
||||
break;
|
||||
}
|
||||
|
||||
case IDM_SOLVER_OBVIOUS:
|
||||
game.findObviousValues();
|
||||
game.display();
|
||||
break;
|
||||
|
||||
case IDM_SOLVER_FIND:
|
||||
game.resolve();
|
||||
game.display();
|
||||
break;
|
||||
|
||||
case IDM_QUIT:
|
||||
end = true;
|
||||
break;
|
||||
|
||||
default:
|
||||
break; // ???
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef DEST_CASIO_CALC
|
||||
//gint_setrestart(1);
|
||||
gint_osmenu();
|
||||
#endif // #ifdef DEST_CASIO_CALC
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue