up down select and focus

This commit is contained in:
vrd
2023-01-02 17:31:29 +02:00
parent 1c91d7b775
commit 6cbe64f927
7 changed files with 154 additions and 50 deletions
+1 -2
View File
@@ -1,2 +1 @@
g++ -o bin/release/famt -std=gnu++20 -Ofast -flto -fipa-pta -fallow-store-data-races -fgcse-sm -fgcse-las -s -DNDEBUG *.cpp g++ -o bin/release/famt -std=gnu++20 -Ofast -flto -fipa-pta -fallow-store-data-races -fgcse-sm -fgcse-las -s -DNDEBUG *.cpp -lncursesw
+8 -6
View File
@@ -13,12 +13,14 @@ int main()
initscr(); /* Start curses mode */ initscr(); /* Start curses mode */
noecho(); noecho();
cbreak(); /* get input instantly */ cbreak(); /* get input instantly */
keypad(stdscr, true);
start_color(); start_color();
use_default_colors(); use_default_colors();
/* init_pair(5, COLOR_BLACK, COLOR_BLACK); */ /* init_pair(5, COLOR_BLACK, COLOR_BLACK); */
/* bkgd(COLOR_PAIR(5)); */ /* bkgd(COLOR_PAIR(5)); */
init_pair(COLOR_MALE, COLOR_BLUE, -1); /* -1 means use default */ init_pair(COLOR_MALE, COLOR_BLUE, -1); /* -1 means use default */
init_pair(COLOR_FEMALE, COLOR_RED, -1); init_pair(COLOR_FEMALE, COLOR_RED, -1);
init_pair(COLOR_SELECTED, COLOR_YELLOW, -1);
wnoutrefresh(stdscr); /* if not present the first real refresh is missed */ wnoutrefresh(stdscr); /* if not present the first real refresh is missed */
Tree test1("Dechkovi"); //addTree Dechkovi addTree Karamanovi load 0 load 1 (to work with these example trees) Tree test1("Dechkovi"); //addTree Dechkovi addTree Karamanovi load 0 load 1 (to work with these example trees)
@@ -46,13 +48,13 @@ int main()
test2.addPerson("Rumiana", false, 2, 4); test2.addPerson("Rumiana", false, 2, 4);
/* test2.addRelation(5, Brother, 6); */ /* test2.addRelation(5, Brother, 6); */
test1.draw(); test1.display();
test2.draw(); test2.display();
/* (test1 + test2).draw(4); */ /* (test1 + test2).display(); */
test1 += test2; test1 += test2;
test1.draw(4); test1.display();
test1.draw(); test1.display();
/* test1.saveTree(); */ /* test1.saveTree(); */
@@ -82,7 +84,7 @@ int main()
/* firstTree.print(); */ /* firstTree.print(); */
firstTree.draw(); firstTree.display();
/* firstTree.saveTree(); */ /* firstTree.saveTree(); */
/* firstTree.printRel(3); */ /* firstTree.printRel(3); */
+11 -2
View File
@@ -159,6 +159,12 @@ void Person::print()const
/* cout << '\n'; */ /* cout << '\n'; */
} }
bool Person::isMale() const
{
return isMale_;
}
U16 Person::boxWidth() const U16 Person::boxWidth() const
{ {
return name_.size() + 4; /* TODO: get actual lenght */ return name_.size() + 4; /* TODO: get actual lenght */
@@ -176,12 +182,15 @@ U16 Person::boxWidth() const
/* return pad; */ /* return pad; */
/* } */ /* } */
void Person::draw(I16 drawY, I16 drawX, bool hasSpouse, bool isSpouse, bool hasKids) const void Person::draw(I16 drawY, I16 drawX, bool selected, bool hasSpouse, bool isSpouse, bool hasKids) const
{ {
U16 width = boxWidth(); U16 width = boxWidth();
WINDOW* pad = newpad(BOX_HEIGHT, width); WINDOW* pad = newpad(BOX_HEIGHT, width);
auto color_pair = COLOR_PAIR(isMale_ ? COLOR_MALE : COLOR_FEMALE); auto color_pair = COLOR_PAIR( selected ? COLOR_SELECTED
: (isMale_ ? COLOR_MALE : COLOR_FEMALE) );
wbkgd(pad, color_pair); wbkgd(pad, color_pair);
/* wattron(pad, color_pair); */ /* wattron(pad, color_pair); */
+10 -8
View File
@@ -7,10 +7,10 @@
struct EventTime struct EventTime
{ {
//enum { UNKNOWN_DATE=0, UNKNOWN_TIME=1}; enum: I16 { UNKNOWN_DATE=0 };
static const I16 UNKNOWN_DATE = 0; enum: I8 { UNKNOWN_TIME=-1 };
static const I8 UNKNOWN_TIME = -1;
/*explicit*/ EventTime(I16 Year=UNKNOWN_DATE, U8 Month=UNKNOWN_DATE, U16 Day=UNKNOWN_DATE, I8 Hour=UNKNOWN_TIME, I8 Minute=UNKNOWN_TIME); EventTime(I16 Year=UNKNOWN_DATE, U8 Month=UNKNOWN_DATE, U16 Day=UNKNOWN_DATE, I8 Hour=UNKNOWN_TIME, I8 Minute=UNKNOWN_TIME);
void print() const; void print() const;
I16 year; //The year in relation to Chritst's birth - 1 (AD) is the year He was born, -1 (BC) is the previous year. There is no year 0 I16 year; //The year in relation to Chritst's birth - 1 (AD) is the year He was born, -1 (BC) is the previous year. There is no year 0
@@ -20,12 +20,13 @@ struct EventTime
I8 minute; //0-59 I8 minute; //0-59
}; };
enum { enum: U8 {
COLOR_MALE = 1, COLOR_MALE = 1,
COLOR_FEMALE COLOR_FEMALE,
COLOR_SELECTED
}; };
enum { enum: U8 {
BOX_HEIGHT = 5, BOX_HEIGHT = 5,
LINK_HEIGHT = 3 LINK_HEIGHT = 3
}; };
@@ -47,12 +48,13 @@ public:
void print() const; void print() const;
bool isMale() const;
U16 boxWidth() const; U16 boxWidth() const;
/* Draw a Person's box on the terminal /* Draw a Person's box on the terminal
drawY,drawX - the coordinates where to draw drawY,drawX - the coordinates where to draw
returns the width of the box*/ returns the width of the box*/
void draw(I16 drawY, I16 drawX, bool hasSpouse, bool isSpouse, bool hasChildren=false) const; void draw(I16 drawY, I16 drawX, bool selected, bool hasSpouse, bool isSpouse, bool hasChildren=false) const;
/* WINDOW* createPad()const; */ /* WINDOW* createPad()const; */
+3
View File
@@ -1,3 +1,6 @@
Selecting people
Help
addPerson add siblings (add relation improve) addPerson add siblings (add relation improve)
Draw distinct regions of a tree Draw distinct regions of a tree
+95 -21
View File
@@ -191,6 +191,17 @@ unsigned Tree::findCommonAncestor(const unsigned firstId, const unsigned secondI
return oldestId; return oldestId;
} }
/* person_id Tree::findRelation(person_id first, person_id second) const */
/* { */
/* const auto& curRels = relations[first]; */
/* for(auto i =0; i<curRels.gNum(); ++i) */
/* { */
/* if(curRels[i].id == second) */
/* { */
/* } */
void Tree::saveTree() const void Tree::saveTree() const
{ {
std::ofstream peopleFile(treeName+ ".people", std::ios::binary); std::ofstream peopleFile(treeName+ ".people", std::ios::binary);
@@ -263,7 +274,7 @@ bool Tree::addRelation(const char* firstName, const RelType type, const char* se
bool Tree::addRelation(const unsigned firstId, const RelType type, const unsigned secondId, bool opposite)// bool Tree::addRelation(const unsigned firstId, const RelType type, const unsigned secondId, bool opposite)//
{ {
if (firstId == Nobody || firstId >= numPeople || secondId == Nobody || secondId >= numPeople || type == Invalid) if (firstId == Nobody || firstId >= numPeople || secondId == Nobody || secondId >= numPeople || type == None)
return 0; return 0;
unsigned i = 0; unsigned i = 0;
@@ -367,30 +378,45 @@ void Tree::removeRelation(const unsigned firstId, const unsigned secondId)
} }
} }
void Tree::draw(person_id focused) const void Tree::display()
{ {
erase(); //Clear the screen draw();
wnoutrefresh(stdscr);
U16 drawY = 0/* (LINES) / 2 */; I32 c;
U16 drawX = 0/* (COLS) / 2 */;
drawLineWithWives(focused, drawY, drawX);
doupdate();
char c;
do do
{ {
c = std::tolower(getch()); c = std::tolower(getch());
switch(c) switch(c)
{ {
case '\n':
focused_ = selected_;
draw();
break;
case KEY_DOWN:
selectDown();
break;
case KEY_UP:
selectUp();
break;
default: break; default: break;
} }
} }
while(c != 'w'); while(c != 'w');
} }
void Tree::draw() const
{
erase(); //Clear the screen
wnoutrefresh(stdscr);
U16 drawY = 0/* (LINES) / 2 */;
U16 drawX = 0/* (COLS) / 2 */;
drawLineWithWives(focused_, drawY, drawX);
doupdate();
}
void Tree::print() const void Tree::print() const
{ {
//for(const auto& member: people) //for(const auto& member: people)
@@ -465,12 +491,13 @@ void Tree::printOldestAncestors(const unsigned id)const
void Tree::commonAncestorRec(person_id id, const Array<char> &visited)const void Tree::commonAncestorRec(person_id id, const Array<char> &visited)const
{ {
for (unsigned i = 0; i < people[id].numRel_; ++i) auto& curRels = relations[id];
for (unsigned i = 0; i < curRels.gNum(); ++i)
{ {
if (relations[id][i].type == Child) if (curRels[i].type == Child)
{ {
++visited[relations[id][i].id]; ++visited[curRels[i].id];
commonAncestorRec(relations[id][i].id, visited); commonAncestorRec(curRels[i].id, visited);
} }
} }
} }
@@ -543,10 +570,10 @@ static U8 linkToChild(I16 startY, I16 startX, I16 endX, bool moreSiblings)
/* return drawX; */ /* return drawX; */
/* } */ /* } */
/* return drawX + people[id].boxWidth() + dist_between; */ /* return drawX + people[id].boxWidth() + dist_between_; */
/* } */ /* } */
I16 Tree::drawLineWithWives(person_id id, I16 drawY, const I16 drawX) const I16 Tree::drawLineWithWives(const person_id id, I16 drawY, const I16 drawX) const
{ {
const Person& person = people[id]; const Person& person = people[id];
const auto& rels = relations[id]; const auto& rels = relations[id];
@@ -562,13 +589,15 @@ I16 Tree::drawLineWithWives(person_id id, I16 drawY, const I16 drawX) const
spouse = rels[i].id; spouse = rels[i].id;
} }
const size_t numKids = children.size(); const size_t numKids = children.size();
person.draw(drawY, drawX, spouse!=Nobody, false, numKids!=0); person.draw(drawY, drawX,
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, false, true); people[spouse].draw(drawY, drawX + person.boxWidth() + spouse_dist_,
spouse_width = spouse_dist + people[spouse].boxWidth(); spouse == selected_, false, true);
spouse_width = spouse_dist_ + people[spouse].boxWidth();
} }
auto childX = drawX; auto childX = drawX;
@@ -588,6 +617,51 @@ I16 Tree::drawLineWithWives(person_id id, I16 drawY, const I16 drawX) const
} }
} }
return max(drawX + person.boxWidth() + dist_between + spouse_width, return max(drawX + person.boxWidth() + dist_between_ + spouse_width,
childX); childX);
} }
void Tree::selectLeft() /* todo */
{
const auto& curRel = relations[selected_];
for(U32 i = 0; i < curRel.gNum(); ++i)
{
if(curRel[i].type == Sibling)
{
selected_ = curRel[i].id;
draw();
return;
}
}
}
void Tree::selectDown()
{
const auto& curRel = relations[selected_];
for(U32 i = 0; i < curRel.gNum(); ++i)
{
if(curRel[i].type == Parent)
{
selected_ = curRel[i].id;
draw();
return;
}
}
}
void Tree::selectUp()
{
const auto& curRel = relations[selected_];
for(U32 i = 0; i < curRel.gNum(); ++i)
{
if(curRel[i].type == Child && (people[curRel[i].id].isMale() || curRel[i].id == focused_))
{
selected_ = curRel[i].id;
draw();
return;
}
}
}
+22 -7
View File
@@ -13,7 +13,9 @@ struct Relation
RelType type; RelType type;
}; };
static constexpr person_id Nobody = UINT_MAX; enum: person_id {
Nobody = UINT_MAX
};
class Tree class Tree
{ {
@@ -34,6 +36,7 @@ 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 person_id findCommonAncestor(person_id firstId, person_id secondId) const; //oldest common ancestor ID
person_id findRelation(person_id first, person_id second) const;
void saveTree()const;// void saveTree()const;//
bool loadTree(); bool loadTree();
@@ -47,7 +50,7 @@ public:
void removeRelation(person_id firstId, person_id secondId); void removeRelation(person_id firstId, person_id secondId);
void removeRelation(const char* firstName, const char* secondName); void removeRelation(const char* firstName, const char* secondName);
void draw(person_id focused=0) const; void display();
void print()const; void print()const;
void printRel(person_id id)const; //Prints out close relatives void printRel(person_id id)const; //Prints out close relatives
@@ -56,29 +59,41 @@ public:
private: private:
void commonAncestorRec(person_id id, const Array<char> &visited)const; void commonAncestorRec(person_id id, const Array<char> &visited)const;
void draw() const;
/* draw a line of people starting from person with id /* draw a line of people starting from person with id
return the farthest X that will be drawn */ return the farthest X that will be drawn */
I16 drawLine(person_id id, I16 drawY, I16 drawX) const; I16 drawLine(person_id id, I16 drawY, I16 drawX) const;
I16 drawLineWithWives(person_id id, I16 drawY, I16 drawX) const; I16 drawLineWithWives(person_id id, I16 drawY, I16 drawX) const;
void selectLeft();
void selectDown();
void selectUp();
void selectRight();
std::string treeName = "Unnamed"; std::string treeName = "Unnamed";
unsigned numPeople = 0; unsigned numPeople = 0;
Array<Person> people; //The data for each member Array<Person> people; //The data for each member
Array<Array<Relation>> relations; //The relatives of each member Array<Array<Relation>> relations; //The relatives of each member
U16 offset = 0; person_id focused_ = 0; /* the tree was draw based on this person */
U8 dist_between = 1; person_id selected_ = 0;
U8 spouse_dist = 0; U16 offset_ = 0; /* offset of the tree */
U8 dist_between_ = 1; /* distance between people */
U8 spouse_dist_ = 0; /* distance between spouses */
//Search, ect. //Search, ect.
}; };
enum RelType : U8 enum RelType : U8
{ {
Invalid = 0, None = 0,
Parent, Parent,
Child, Child,
Sibling, Sibling,
HalfSibling, HalfSibling,
Spouse, Spouse,
ExSpouse ExSpouse,
Other
}; };