This commit is contained in:
vrd
2023-01-16 12:01:08 +02:00
parent b49e422cda
commit 25bcd2e22b
6 changed files with 130 additions and 50 deletions
-2
View File
@@ -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;
+1 -1
View File
@@ -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
View File
@@ -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;
} }
+10
View File
@@ -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
+100 -41
View File
@@ -51,7 +51,7 @@ Tree Tree::operator+ (const Tree& other)//
{ {
for (unsigned j = 0; j < other.people[i].numRel_; ++j) //Adds the number of relatives from the II to the number in the I for (unsigned j = 0; j < other.people[i].numRel_; ++j) //Adds the number of relatives from the II to the number in the I
{ {
if(newId[other.relations[i][j].id] > numPeople) if (newId[other.relations[i][j].id] > numPeople)
++result.people[newId[i]].numRel_; ++result.people[newId[i]].numRel_;
} }
@@ -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,33 +169,58 @@ 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]; */
/* for(auto i =0; i<curRels.size(); ++i) */ /* for(auto i =0; i<curRels.size(); ++i) */
/* { */ /* { */
/* if(curRels[i].id == second) */ /* if (curRels[i].id == second) */
/* { */ /* { */
/* } */ /* } */
@@ -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)
{ {
@@ -505,7 +538,7 @@ void Tree::commonAncestorRec(person_id id, vector<char> &visited)const
static U8 linkToFirstBorn(I16 startY, I16 startX, bool moreSiblings) static U8 linkToFirstBorn(I16 startY, I16 startX, bool moreSiblings)
{ {
if(startY >= -2 && startX >= 0) if (startY >= -2 && startX >= 0)
{ {
WINDOW* win = newwin(3, 1, startY, startX); /* TODO: pad */ WINDOW* win = newwin(3, 1, startY, startX); /* TODO: pad */
@@ -524,7 +557,7 @@ static U8 linkToChild(I16 startY, I16 startX, I16 endX, bool moreSiblings)
{ {
assert(endX >= startX); assert(endX >= startX);
if(startY >= -1 && endX >= 0) if (startY >= -1 && endX >= 0)
{ {
const I16 len = endX - startX; const I16 len = endX - startX;
WINDOW* win = newwin(2, len, startY, startX); WINDOW* win = newwin(2, len, startY, startX);
@@ -550,11 +583,11 @@ static U8 linkToChild(I16 startY, I16 startX, I16 endX, bool moreSiblings)
/* std::vector<person_id> children; */ /* std::vector<person_id> children; */
/* for(U32 i=0; i<relations[id].size(); ++i) */ /* for(U32 i=0; i<relations[id].size(); ++i) */
/* { */ /* { */
/* if(relations[id][i].type == RelType::Parent) */ /* if (relations[id][i].type == RelType::Parent) */
/* children.push_back(relations[id][i].id); */ /* children.push_back(relations[id][i].id); */
/* } */ /* } */
/* if(!children.empty()) */ /* if (!children.empty()) */
/* { */ /* { */
/* auto prevX = drawX; */ /* auto prevX = drawX; */
/* drawY += BOX_HEIGHT; */ /* drawY += BOX_HEIGHT; */
@@ -583,10 +616,10 @@ I16 Tree::drawLineWithWives(const person_id id, I16 drawY, const I16 drawX) cons
std::vector<person_id> children; std::vector<person_id> children;
for(const auto& rel: rels) for(const auto& rel: rels)
{ {
if(rel.type == RelType::Parent) if (rel.type == RelType::Parent)
children.push_back(rel.id); children.push_back(rel.id);
else if(rel.type == RelType::Spouse && spouse == Nobody) else if (rel.type == RelType::Spouse && spouse == Nobody)
spouse = rel.id; spouse = rel.id;
} }
const size_t numKids = children.size(); const size_t numKids = children.size();
@@ -594,7 +627,7 @@ I16 Tree::drawLineWithWives(const person_id id, I16 drawY, const I16 drawX) cons
id == selected_, spouse!=Nobody, false, numKids!=0); id == selected_, spouse!=Nobody, false, numKids!=0);
U16 spouse_width = 0; U16 spouse_width = 0;
if(spouse != Nobody) if (spouse != Nobody)
{ {
people[spouse].draw(drawY, drawX + person.boxWidth() + spouse_dist_, people[spouse].draw(drawY, drawX + person.boxWidth() + spouse_dist_,
spouse == selected_, false, true); spouse == selected_, false, true);
@@ -602,7 +635,7 @@ I16 Tree::drawLineWithWives(const person_id id, I16 drawY, const I16 drawX) cons
} }
auto childX = drawX; auto childX = drawX;
if(numKids!=0) if (numKids!=0)
{ {
auto prevX = childX; auto prevX = childX;
drawY += BOX_HEIGHT; drawY += BOX_HEIGHT;
@@ -624,26 +657,27 @@ 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)
{
if(curRel[i].type == Sibling)
{
selected_ = curRel[i].id;
draw();
return;
} }
else
{
person_id spouse = findSpouse(selected_);
selected_ = spouse;
draw();
} }
} }
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)
{ {
selected_ = rel.id; selected_ = rel.id;
draw(); draw();
@@ -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())
draw(); dad = rel.id;
return; else
mom = rel.id;
} }
} }
if (mom == focused_ || (mom != Nobody && dad == Nobody))
selected_ = mom;
else if (dad != Nobody)
selected_ = dad;
draw();
}
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
{
}
} }
+5 -2
View File
@@ -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