utf8 len
This commit is contained in:
@@ -2,8 +2,6 @@
|
|||||||
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
|
|
||||||
typedef char C8;
|
|
||||||
|
|
||||||
typedef int8_t I8;
|
typedef int8_t I8;
|
||||||
typedef uint8_t U8;
|
typedef uint8_t U8;
|
||||||
typedef int16_t I16;
|
typedef int16_t I16;
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ using std::cin;
|
|||||||
using std::cout;
|
using std::cout;
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
setlocale(LC_ALL, ""); /* TODO: set to utf */
|
setlocale(LC_ALL, "en_US.UTF-8");
|
||||||
|
|
||||||
/* Init ncurses */
|
/* Init ncurses */
|
||||||
initscr(); /* Start curses mode */
|
initscr(); /* Start curses mode */
|
||||||
|
|||||||
+13
-3
@@ -1,5 +1,6 @@
|
|||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
|
#include<ctype.h>
|
||||||
#include <ncursesw/ncurses.h>
|
#include <ncursesw/ncurses.h>
|
||||||
|
|
||||||
#include"person.h"
|
#include"person.h"
|
||||||
@@ -90,10 +91,10 @@ void Person::save(std::ofstream &file)const
|
|||||||
|
|
||||||
void Person::load(std::ifstream &file)
|
void Person::load(std::ifstream &file)
|
||||||
{
|
{
|
||||||
char nameLen;
|
U8 nameLen;
|
||||||
file.read((char*)&nameLen, sizeof(nameLen)); //Check len
|
file.read((char*)&nameLen, sizeof(nameLen)); //Check len
|
||||||
|
|
||||||
C8 nameBuf[128];
|
char nameBuf[128];
|
||||||
file.read(nameBuf, nameLen * sizeof(*nameBuf));
|
file.read(nameBuf, nameLen * sizeof(*nameBuf));
|
||||||
nameBuf[nameLen] = '\0';
|
nameBuf[nameLen] = '\0';
|
||||||
name_ = nameBuf;
|
name_ = nameBuf;
|
||||||
@@ -139,9 +140,18 @@ bool Person::isMale() const
|
|||||||
return isMale_;
|
return isMale_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static U16 strUtf8Symbols(const std::string& str)
|
||||||
|
{
|
||||||
|
U16 num = 0;
|
||||||
|
for(char c: str)
|
||||||
|
num += ((c & 0xC0) != 0x80);
|
||||||
|
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
U16 Person::boxWidth() const
|
U16 Person::boxWidth() const
|
||||||
{
|
{
|
||||||
return name_.size() + 4; /* TODO: get actual lenght */
|
return strUtf8Symbols(name_) + 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -11,3 +11,13 @@ Color
|
|||||||
Partialy visible people
|
Partialy visible people
|
||||||
Scrolling
|
Scrolling
|
||||||
Zooming
|
Zooming
|
||||||
|
|
||||||
|
Visualization:
|
||||||
|
- proper horizontal navigation
|
||||||
|
|
||||||
|
Compilation
|
||||||
|
- static and dynamic ncurses
|
||||||
|
|
||||||
|
?
|
||||||
|
- same person can be present twice
|
||||||
|
|
||||||
|
|||||||
@@ -147,7 +147,7 @@ void Tree::rename(const char* newName)
|
|||||||
treeName = newName;
|
treeName = newName;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned Tree::findId(const char* name, const short year, const unsigned char month, const unsigned char day)const
|
person_id Tree::findId(const char* name, const short year, const unsigned char month, const unsigned char day) const
|
||||||
{
|
{
|
||||||
//TODO
|
//TODO
|
||||||
//Person sought(name, day, month, year,)
|
//Person sought(name, day, month, year,)
|
||||||
@@ -159,7 +159,7 @@ unsigned Tree::findId(const char* name, const short year, const unsigned char mo
|
|||||||
return Nobody;
|
return Nobody;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned Tree::findOldestAncestor(unsigned id, bool isMale)const
|
person_id Tree::findOldestAncestor(unsigned id, bool isMale)const
|
||||||
{
|
{
|
||||||
for (unsigned i = 0; i < people[id].numRel_; ++i)
|
for (unsigned i = 0; i < people[id].numRel_; ++i)
|
||||||
{
|
{
|
||||||
@@ -169,27 +169,52 @@ unsigned Tree::findOldestAncestor(unsigned id, bool isMale)const
|
|||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned Tree::findCommonAncestor(const unsigned firstId, const unsigned secondId)const
|
person_id Tree::findCommonAncestor(const unsigned firstId, const unsigned secondId) const
|
||||||
{
|
{
|
||||||
vector<char> visited(numPeople); //if a member is visited twice he's a common ancestor
|
vector<U8> visited(numPeople); //if a member is visited twice he's a common ancestor
|
||||||
for (unsigned i = 0; i < numPeople; ++i)
|
|
||||||
visited[i] = 0;
|
|
||||||
commonAncestorRec(firstId, visited);
|
commonAncestorRec(firstId, visited);
|
||||||
commonAncestorRec(secondId, visited);
|
commonAncestorRec(secondId, visited);
|
||||||
|
|
||||||
unsigned oldestId = Nobody;
|
person_id oldest = Nobody;
|
||||||
U16 oldestBday = SHRT_MAX;
|
U16 oldestBday = SHRT_MAX;
|
||||||
for (unsigned i = 0; i < numPeople; ++i)
|
for (person_id i = 0; i < numPeople; ++i)
|
||||||
{
|
{
|
||||||
if (visited[i] == 2 && people[i].birth_.year < oldestBday)
|
if (visited[i] == 2 && people[i].birth_.year < oldestBday)
|
||||||
{
|
{
|
||||||
oldestBday = people[i].birth_.year;
|
oldestBday = people[i].birth_.year;
|
||||||
oldestId = i;
|
oldest = i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return oldestId;
|
return oldest;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
person_id Tree::findParent(person_id child, bool isParentMale) const
|
||||||
|
{
|
||||||
|
person_id parent = Nobody;
|
||||||
|
for(const Relation& rel: relations[child])
|
||||||
|
{
|
||||||
|
if (rel.type == Child && people[rel.id].isMale())
|
||||||
|
parent = rel.id;
|
||||||
|
}
|
||||||
|
return parent;
|
||||||
|
}
|
||||||
|
|
||||||
|
person_id Tree::findSpouse(person_id person) const
|
||||||
|
{
|
||||||
|
person_id spouse = Nobody;
|
||||||
|
for(const Relation& rel: relations[person])
|
||||||
|
{
|
||||||
|
if (rel.type == Spouse)
|
||||||
|
{
|
||||||
|
spouse = rel.id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return spouse;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* person_id Tree::findRelation(person_id first, person_id second) const */
|
/* person_id Tree::findRelation(person_id first, person_id second) const */
|
||||||
/* { */
|
/* { */
|
||||||
/* const auto& curRels = relations[first]; */
|
/* const auto& curRels = relations[first]; */
|
||||||
@@ -392,12 +417,18 @@ void Tree::display()
|
|||||||
case KEY_UP:
|
case KEY_UP:
|
||||||
selectUp();
|
selectUp();
|
||||||
break;
|
break;
|
||||||
|
case 'h':
|
||||||
|
selectLeft();
|
||||||
|
break;
|
||||||
case 'j':
|
case 'j':
|
||||||
selectDown();
|
selectDown();
|
||||||
break;
|
break;
|
||||||
case 'k':
|
case 'k':
|
||||||
selectUp();
|
selectUp();
|
||||||
break;
|
break;
|
||||||
|
case 'l':
|
||||||
|
selectRight();
|
||||||
|
break;
|
||||||
case 'i':
|
case 'i':
|
||||||
people[selected_].displayInfo();
|
people[selected_].displayInfo();
|
||||||
draw();
|
draw();
|
||||||
@@ -413,8 +444,8 @@ void Tree::draw() const
|
|||||||
erase(); //Clear the screen
|
erase(); //Clear the screen
|
||||||
wnoutrefresh(stdscr);
|
wnoutrefresh(stdscr);
|
||||||
|
|
||||||
U16 drawY = 0/* (LINES) / 2 */;
|
I16 drawY = 0/* (LINES) / 2 */;
|
||||||
U16 drawX = 0/* (COLS) / 2 */;
|
I16 drawX = 0/* (COLS) / 2 */;
|
||||||
drawLineWithWives(focused_, drawY, drawX);
|
drawLineWithWives(focused_, drawY, drawX);
|
||||||
|
|
||||||
doupdate();
|
doupdate();
|
||||||
@@ -422,7 +453,7 @@ void Tree::draw() const
|
|||||||
|
|
||||||
void Tree::print() const
|
void Tree::print() const
|
||||||
{
|
{
|
||||||
for(auto& member: people)
|
for(const Person& member: people)
|
||||||
member.displayInfo();
|
member.displayInfo();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -490,10 +521,12 @@ void Tree::printOldestAncestors(const unsigned id)const
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Tree::commonAncestorRec(person_id id, vector<char> &visited)const
|
void Tree::commonAncestorRec(person_id id, vector<U8> &visited) const
|
||||||
{
|
{
|
||||||
|
++visited[id];
|
||||||
|
|
||||||
auto& curRels = relations[id];
|
auto& curRels = relations[id];
|
||||||
for (auto& rel: curRels)
|
for (const Relation& rel: curRels)
|
||||||
{
|
{
|
||||||
if (rel.type == Child)
|
if (rel.type == Child)
|
||||||
{
|
{
|
||||||
@@ -624,24 +657,25 @@ I16 Tree::drawLineWithWives(const person_id id, I16 drawY, const I16 drawX) cons
|
|||||||
|
|
||||||
void Tree::selectLeft() /* todo */
|
void Tree::selectLeft() /* todo */
|
||||||
{
|
{
|
||||||
const auto& curRel = relations[selected_];
|
if (findCommonAncestor(focused_, selected_) != Nobody) //if the selected is part of main tree
|
||||||
|
{
|
||||||
|
|
||||||
for(U32 i = 0; i < curRel.size(); ++i)
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
if(curRel[i].type == Sibling)
|
person_id spouse = findSpouse(selected_);
|
||||||
{
|
selected_ = spouse;
|
||||||
selected_ = curRel[i].id;
|
|
||||||
draw();
|
draw();
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void Tree::selectDown()
|
void Tree::selectDown()
|
||||||
{
|
{
|
||||||
const auto& curRels = relations[selected_];
|
const auto& curRels = relations[selected_];
|
||||||
|
|
||||||
for(const auto& rel: curRels)
|
for(const Relation& rel: curRels)
|
||||||
{
|
{
|
||||||
if (rel.type == Parent)
|
if (rel.type == Parent)
|
||||||
{
|
{
|
||||||
@@ -654,15 +688,40 @@ void Tree::selectDown()
|
|||||||
|
|
||||||
void Tree::selectUp()
|
void Tree::selectUp()
|
||||||
{
|
{
|
||||||
const auto& curRels = relations[selected_];
|
person_id dad = Nobody, mom = Nobody;
|
||||||
|
|
||||||
for(const auto& rel: curRels)
|
for(const Relation& rel: relations[selected_])
|
||||||
{
|
{
|
||||||
if(rel.type == Child && (people[rel.id].isMale() || rel.id == focused_))
|
if (rel.type == Child)
|
||||||
{
|
{
|
||||||
selected_ = rel.id;
|
if (people[rel.id].isMale())
|
||||||
|
dad = rel.id;
|
||||||
|
else
|
||||||
|
mom = rel.id;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mom == focused_ || (mom != Nobody && dad == Nobody))
|
||||||
|
selected_ = mom;
|
||||||
|
else if (dad != Nobody)
|
||||||
|
selected_ = dad;
|
||||||
|
|
||||||
draw();
|
draw();
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
void Tree::selectRight() /* todo */
|
||||||
|
{
|
||||||
|
if (findCommonAncestor(focused_, selected_) != Nobody) //if the selected is part of main tree
|
||||||
|
{
|
||||||
|
person_id spouse = findSpouse(selected_);
|
||||||
|
if (spouse != Nobody)
|
||||||
|
selected_ = spouse;
|
||||||
|
else
|
||||||
|
;
|
||||||
|
draw();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,8 +35,11 @@ public:
|
|||||||
|
|
||||||
person_id findId(const char*, short year=0, const unsigned char month=0, const unsigned char day=0) const;
|
person_id findId(const char*, short year=0, const unsigned char month=0, const unsigned char day=0) const;
|
||||||
person_id findOldestAncestor(person_id id, bool sex = 0) const;//
|
person_id findOldestAncestor(person_id id, bool sex = 0) const;//
|
||||||
person_id findCommonAncestor(person_id firstId, person_id secondId) const; //oldest common ancestor ID
|
//oldest common ancestor ID, a person is considerd an ancestor of himself
|
||||||
|
person_id findCommonAncestor(person_id firstId, person_id secondId) const;
|
||||||
person_id findRelation(person_id first, person_id second) const;
|
person_id findRelation(person_id first, person_id second) const;
|
||||||
|
person_id findParent(person_id child, bool isParentMale) const;
|
||||||
|
person_id findSpouse(person_id person) const;
|
||||||
|
|
||||||
void saveTree()const;//
|
void saveTree()const;//
|
||||||
bool loadTree();
|
bool loadTree();
|
||||||
@@ -58,7 +61,7 @@ public:
|
|||||||
void printOldestAncestors(person_id id)const;//
|
void printOldestAncestors(person_id id)const;//
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void commonAncestorRec(person_id id, std::vector<char> &visited)const;
|
void commonAncestorRec(person_id id, std::vector<U8> &visited)const;
|
||||||
|
|
||||||
void draw() const;
|
void draw() const;
|
||||||
/* draw a line of people starting from person with id
|
/* draw a line of people starting from person with id
|
||||||
|
|||||||
Reference in New Issue
Block a user