add config.h and cleanup

This commit is contained in:
vrd
2023-03-06 22:26:31 +02:00
parent 9ef74b8283
commit 35d9d44aa6
10 changed files with 84 additions and 288 deletions
+19
View File
@@ -0,0 +1,19 @@
#pragma once
enum
{
SELECT_LEFT = 'h',
SELECT_DOWN = 'j',
SELECT_UP = 'k',
SELECT_RIGHT = 'l',
DISPLAY_INFO = 'i',
SELECT = ' ', /* spacebar */
CLOSE = 'w',
MOVE_LEFT = KEY_LEFT, /* arrows */
MOVE_DOWN = KEY_DOWN,
MOVE_UP = KEY_UP,
MOVE_RIGHT = KEY_RIGHT
};
-15
View File
@@ -1,15 +0,0 @@
/* #include <ncursesw/ncurses.h> */
/* #include "tree.hpp" */
/* #include "utils.hpp" */
/* #include "user_tree.hpp" */
/* int main() */
/* { */
/* init(); */
/* create_tree(); */
/* endwin(); /\* stop ncursers *\/ */
/* return 0; */
/* } */
+17 -29
View File
@@ -4,8 +4,10 @@
#include "tree.hpp" #include "tree.hpp"
#include "utils.hpp" #include "utils.hpp"
/* macro rather then function to avoid warnings */ /* macros rather then function to avoid warnings */
#define UNEXPECTED_END() endwin(); cerr << "Unexpected end of file" << std::endl; exit(1) #define UNEXPECTED_END() { endwin(); cerr << "Unexpected end of file" << std::endl; exit(1); }
#define UNEXPECTED_CHAR(c) { endwin(); cerr << "Line " << line << ": Unexpected '" << c << std::endl; exit(1); }
using std::cerr; using std::cerr;
/* using std::string_view; */ /* using std::string_view; */
@@ -47,20 +49,6 @@ namespace /* internal */
return c >= '0' && c <= '9'; return c >= '0' && c <= '9';
} }
void unexpected_char(char c)
{
endwin();
cerr << "Line " << line << ": Unexpected '" << c << std::endl;
exit(1);
}
/* void unexpected_end() */
/* { */
/* endwin(); */
/* cerr << "Unexpected end of file" << std::endl; */
/* exit(1); */
/* } */
void proceedToNameEnd(char*& it_data) void proceedToNameEnd(char*& it_data)
{ {
while(it_data < end_data && while(it_data < end_data &&
@@ -69,7 +57,7 @@ namespace /* internal */
!isNum(*it_data)) !isNum(*it_data))
{ {
if(*it_data == ':' /* && *it_data == '-' */) if(*it_data == ':' /* && *it_data == '-' */)
unexpected_char(*it_data); UNEXPECTED_CHAR(*it_data);
++it_data; ++it_data;
} }
@@ -97,11 +85,11 @@ namespace /* internal */
else if(*it_data == 'F') else if(*it_data == 'F')
res = F; res = F;
else else
unexpected_char(*it_data); UNEXPECTED_CHAR(*it_data);
++it_data; ++it_data;
if(*it_data != '\n') if(*it_data != '\n')
unexpected_char(*it_data); UNEXPECTED_CHAR(*it_data);
} }
return res; return res;
} }
@@ -122,7 +110,7 @@ namespace /* internal */
break; break;
case '.': case '.':
if(val == 0) if(val == 0)
unexpected_char('.'); UNEXPECTED_CHAR('.')
else else
return sign * val; return sign * val;
break; break;
@@ -131,10 +119,10 @@ namespace /* internal */
return sign * val; return sign * val;
/* case '?': todo */ /* case '?': todo */
default: default:
unexpected_char(*it_data); UNEXPECTED_CHAR(*it_data)
} }
} }
UNEXPECTED_END(); UNEXPECTED_END()
} }
EventTime processDate(char*& it_data) /* todo validate */ EventTime processDate(char*& it_data) /* todo validate */
@@ -178,7 +166,7 @@ namespace /* internal */
if(name.empty() && res.first == Nobody) if(name.empty() && res.first == Nobody)
return prev_parents; return prev_parents;
else else
unexpected_char('-'); UNEXPECTED_CHAR('-')
case '\n': case '\n':
++line; ++line;
if(res.first == Nobody) if(res.first == Nobody)
@@ -196,7 +184,7 @@ namespace /* internal */
name.push_back(*it_data); name.push_back(*it_data);
} }
} }
UNEXPECTED_END(); UNEXPECTED_END()
} }
vector<person_id> parseSpouses(char*& it_data) vector<person_id> parseSpouses(char*& it_data)
@@ -212,7 +200,7 @@ namespace /* internal */
if(name.empty()) if(name.empty())
res.push_back( cur_tree->last() ); res.push_back( cur_tree->last() );
else else
unexpected_char('-'); UNEXPECTED_CHAR('-')
break; break;
case ',': case ',':
if(!name.empty()) if(!name.empty())
@@ -222,7 +210,7 @@ namespace /* internal */
same_name_index = 0; same_name_index = 0;
} }
else else
unexpected_char(','); UNEXPECTED_CHAR(',')
break; break;
case '\n': case '\n':
++line; ++line;
@@ -260,7 +248,7 @@ namespace /* internal */
case '-': case '-':
case 0 ... 9: case 0 ... 9:
case ':': case ':':
unexpected_char(*it_data); UNEXPECTED_CHAR(*it_data)
} }
} }
} }
@@ -317,7 +305,7 @@ namespace /* internal */
spouses = parseSpouses(it_data); spouses = parseSpouses(it_data);
break; break;
default: default:
unexpected_char(it_data[-1]); UNEXPECTED_CHAR(it_data[-1])
} }
} }
@@ -332,7 +320,7 @@ namespace /* internal */
break; break;
/* case 0...9: */ /* case 0...9: */
/* case ':': */ /* case ':': */
/* unexpected_char(*it_data); */ /* UNEXPECTED_CHAR(*it_data) */
/* default: */ /* default: */
/* break; */ /* break; */
} }
+15 -81
View File
@@ -1,6 +1,6 @@
#include <iostream> #include <iostream>
#include <assert.h> #include <assert.h>
#include<ctype.h> #include <ctype.h>
#include <ncursesw/ncurses.h> #include <ncursesw/ncurses.h>
#include"person.hpp" #include"person.hpp"
@@ -23,24 +23,6 @@ EventTime::EventTime(I16 Year, U8 Month, U16 Day, I8 Hour, I8 Minute)
void EventTime::print() const void EventTime::print() const
{ {
/* if (day != UNKNOWN_DATE) */
/* cout << (I32)day; */
/* else */
/* cout << "??"; */
/* cout << '.'; */
/* if (month != UNKNOWN_DATE) */
/* cout << (I32)month; */
/* else */
/* cout << "??"; */
/* cout << '.'; */
/* if (year != UNKNOWN_DATE) */
/* cout << year; */
/* else */
/* cout << "????"; */
/* cout << '\n'; */
if (day != UNKNOWN_DATE) if (day != UNKNOWN_DATE)
wprintw(info_tab, "%d", day); wprintw(info_tab, "%d", day);
else else
@@ -61,11 +43,11 @@ void EventTime::print() const
} }
Person::Person(const char* aName, EventTime birth, Sex aSex, EventTime death) Person::Person(const char* aName, EventTime aBirth, Sex aSex, EventTime aDeath)
: name(aName) : name(aName)
, birth_(birth) , birth(aBirth)
, sex(aSex) , sex(aSex)
, death_(death) , death(aDeath)
{ {
} }
@@ -75,40 +57,6 @@ bool Person::operator==(const Person &other)const
return name == other.name; //&& sex == other.sex; //TODO && day == other.day || !day || !other.day) && (month == other.month || !month || !other.month) && (year == other.year || !year || !other.year); return name == other.name; //&& sex == other.sex; //TODO && day == other.day || !day || !other.day) && (month == other.month || !month || !other.month) && (year == other.year || !year || !other.year);
} }
void Person::write(std::ofstream &file)const
{
//
char nameLen = name.size();
file.write(reinterpret_cast<char*>(&nameLen), sizeof(nameLen));
file.write(name.data(), nameLen * sizeof(name[0]));
file.write(reinterpret_cast<const char*>(&sex), sizeof(sex));
//file.write(reinterpret_cast<const char*>(&day), sizeof(day)); TODO
//file.write(reinterpret_cast<const char*>(&month), sizeof(month));
//file.write(reinterpret_cast<const char*>(&year), sizeof(year));
}
void Person::read(std::ifstream &file)
{
U8 nameLen;
file.read((char*)&nameLen, sizeof(nameLen)); //Check len
char nameBuf[128];
file.read(nameBuf, nameLen * sizeof(*nameBuf));
nameBuf[nameLen] = '\0';
name = nameBuf;
file.read(reinterpret_cast<char*>(&sex), sizeof(sex));
//file.read(reinterpret_cast<char*>(&day), sizeof(day)); TODO
//file.read(reinterpret_cast<char*>(&month), sizeof(month));
//file.read(reinterpret_cast<char*>(&year), sizeof(year));
}
void Person::rename(const char* newName)
{
name = newName;
}
void Person::displayInfo()const void Person::displayInfo()const
{ {
info_tab = newwin(LINES, COLS, 0, 0); info_tab = newwin(LINES, COLS, 0, 0);
@@ -117,10 +65,10 @@ void Person::displayInfo()const
waddch(info_tab,'\n'); waddch(info_tab,'\n');
waddstr(info_tab, "Birth: "); waddstr(info_tab, "Birth: ");
birth_.print(); birth.print();
waddstr(info_tab, "Death: "); waddstr(info_tab, "Death: ");
death_.print(); death.print();
mvwaddstr(info_tab, LINES-1, 0, "Press any key to return."); mvwaddstr(info_tab, LINES-1, 0, "Press any key to return.");
@@ -133,32 +81,15 @@ void Person::displayInfo()const
} }
static U16 strUtf8Symbols(const std::string& str) static U16 strUtf8Symbols(const char* str)
{ {
U16 num = 0; U16 num = 0;
for(char c: str) for(; *str != '\0'; ++str)
num += ((c & 0xC0) != 0x80); num += ((*str & 0xC0) != 0x80);
return num; return num;
} }
/* U16 Person::boxWidth() const */
/* { */
/* return strUtf8Symbols(name) + 4; */
/* } */
/* WINDOW* Person::createPad()const */
/* { */
/* U16 width = name.size() + 4; */
/* WINDOW* pad = newpad(5, width); */
/* box(pad, 5, width); */
/* mvwaddstr(pad, 2, 2, name.data()); */
/* return pad; */
/* } */
U16 Person::draw(const I16 drawY, const I16 drawX, bool selected, bool hasSpouse, U16 Person::draw(const I16 drawY, const I16 drawX, bool selected, bool hasSpouse,
bool hasParents, bool hasKids, bool wholeName) const bool hasParents, bool hasKids, bool wholeName) const
{ {
@@ -182,7 +113,7 @@ U16 Person::draw(const I16 drawY, const I16 drawX, bool selected, bool hasSpouse
} }
} }
const U16 width = strUtf8Symbols(display_name) + 4; /* pad width */ const U16 width = strUtf8Symbols(display_name.data()) + 4; /* pad width */
if(willBeVisible(drawY, drawX, BOX_HEIGHT, width)) if(willBeVisible(drawY, drawX, BOX_HEIGHT, width))
{ {
@@ -194,9 +125,12 @@ U16 Person::draw(const I16 drawY, const I16 drawX, bool selected, bool hasSpouse
wbkgd(pad, color_pair); wbkgd(pad, color_pair);
/* wattron(pad, color_pair); */ /* wattron(pad, color_pair); */
auto top_left = hasParents ? ACS_LTEE : ACS_TTEE;
auto top_right = hasSpouse ? ACS_TTEE : ACS_URCORNER;
auto bot_left = hasKids ? ACS_LTEE : ACS_LLCORNER;
wborder(pad, ACS_VLINE, ACS_VLINE, ACS_HLINE, ACS_HLINE, wborder(pad, ACS_VLINE, ACS_VLINE, ACS_HLINE, ACS_HLINE,
hasParents ? ACS_LTEE : ACS_TTEE, hasSpouse ? ACS_TTEE : ACS_URCORNER, top_left, top_right,
hasKids ? ACS_LTEE : ACS_LLCORNER, ACS_LRCORNER ); bot_left, ACS_LRCORNER );
mvwaddstr(pad, 2, 2, display_name.data()); mvwaddstr(pad, 2, 2, display_name.data());
+3 -10
View File
@@ -41,22 +41,15 @@ class Person
{ {
public: public:
Person() = default; Person() = default;
Person(const char* aName, EventTime birth={}, Sex=M, EventTime death={}); Person(const char* aName, EventTime aBirth={}, Sex=M, EventTime aDeath={});
/* Person(Person&&) = default; */ /* Person(Person&&) = default; */
/* Person& operator=(Person&&) = default; */ /* Person& operator=(Person&&) = default; */
/* Person& operator=(const Person&) = default; */ /* Person& operator=(const Person&) = default; */
bool operator==(const Person &other) const; bool operator==(const Person &other) const;
void write(std::ofstream &file) const;//
void read(std::ifstream &file);
void rename(const char* newName);
void displayInfo() const; void displayInfo() const;
const EventTime& birth() const { return birth_; };
/* U16 boxWidth(bool wholeName) const; */
/* Draw a Person's box on the terminal /* Draw a Person's box on the terminal
drawY,drawX - top left coordinates where to draw (negative if outside the screen) drawY,drawX - top left coordinates where to draw (negative if outside the screen)
hasSpouse, hasSpouse, hasChildren - wheather the person has them on display hasSpouse, hasSpouse, hasChildren - wheather the person has them on display
@@ -65,7 +58,7 @@ public:
bool hasParents, bool hasChildren=false, bool wholeName=true) const; bool hasParents, bool hasChildren=false, bool wholeName=true) const;
std::string name; std::string name;
EventTime birth_; EventTime birth;
Sex sex; Sex sex;
EventTime death_; EventTime death;
}; };
+28 -142
View File
@@ -4,8 +4,8 @@
#include <fstream> #include <fstream>
#include <assert.h> #include <assert.h>
using std::ofstream; #include "../config.h" /* user's configuration */
using std::ifstream;
using std::vector; using std::vector;
using std::string; using std::string;
@@ -51,16 +51,9 @@ Tree& Tree::operator+=(const Tree& other)
relations.push_back(other.relations[i]); relations.push_back(other.relations[i]);
for (Relation& rel: relations.back()) for (Relation& rel: relations.back())
rel.id = newId[rel.id]; rel.id = newId[rel.id];
/* for (person_id j = 0; j < other.relations[i].size(); ++j) */
/* relations[newId[i]][j].id = newId[ relations[newId[i]][j].id ]; */
} }
else //if present in both trees else //if present in both trees
{ {
/* for (person_id j = 0; j < other.relations[i].size(); ++j) //combine relations */
/* { */
/* if (newId[other.relations[i][j].id] >= initNum) */
/* ++people[newId[i]].numRel_; */
/* } */
person_id idIn1 = newId[i]; person_id idIn1 = newId[i];
relations[idIn1].reserve(relations[idIn1].size() + other.relations[i].size()); relations[idIn1].reserve(relations[idIn1].size() + other.relations[i].size());
@@ -167,9 +160,9 @@ person_id Tree::findCommonAncestor(const unsigned first, const unsigned second)
U16 oldestBday = SHRT_MAX; U16 oldestBday = SHRT_MAX;
for (person_id i = 0; i < people.size(); ++i) for (person_id i = 0; i < people.size(); ++i)
{ {
if (visited[i] == 2 && people[i].birth().year < oldestBday) if (visited[i] == 2 && people[i].birth.year < oldestBday)
{ {
/* oldestBday = people[i].birth().year; */ //todo figure it out /* oldestBday = people[i].birth.year; */ //todo figure it out
/* oldest = i; */ /* oldest = i; */
return i; return i;
} }
@@ -239,56 +232,6 @@ RelType Tree::findRelation(person_id first, person_id second) const
return None; return None;
} }
void Tree::saveToFile() const
{
const char* HOME = getenv("HOME");
string tftDir(HOME);
tftDir += "/.tft";
system(("mkdir " + tftDir).c_str());
ofstream file(tftDir + '/' + treeName + ".tftb", std::ios::binary);
U32 numPeople = people.size();
file.write((const char*)(&numPeople), sizeof(people.size()));
for (const Person& p: people)
p.write(file);
for (auto& rels: relations)
{
U32 numRels = rels.size();
file.write((const char*)(& numRels), sizeof(numRels));
file.write((const char*)(rels.data()), sizeof(Relation) * numRels);
}
}
bool Tree::loadFromFile()
{
const char* HOME = getenv("HOME");
string tftDir(HOME);
tftDir += "/.tft";
ifstream file(tftDir + '/' + treeName + ".tftb", std::ios::binary);
U32 numPeople;
file.read((char*)(&numPeople), sizeof(people.size()));
people.resize(people.size());
for (Person& p: people)
p.read(file);
relations.resize(people.size());
for (auto& rels: relations)
{
U32 numRels;
file.read((char*)(& numRels), sizeof(numRels));
rels.resize(numRels);
file.read((char*)(rels.data()), sizeof(Relation) * numRels);
}
return true;
}
void Tree::addPerson(const char* name, Sex sex, unsigned father, unsigned mother, EventTime birth, EventTime death) void Tree::addPerson(const char* name, Sex sex, unsigned father, unsigned mother, EventTime birth, EventTime death)
{ {
people.emplace_back(name, birth, sex, death); people.emplace_back(name, birth, sex, death);
@@ -365,8 +308,8 @@ void Tree::removeRelation(const char* firstName, const char* secondName)
void Tree::removePerson(const person_id id) void Tree::removePerson(const person_id id)
{ {
person_id relId; //Íoìåð íà òåêóùèÿ ðîäíèíàòà person_id relId;
for (Relation rel: relations[id]) //Remove all of his relations for (Relation rel: relations[id])
{ {
relId = rel.id; relId = rel.id;
for (U32 j = 0; j < relations[relId].size(); ++j) for (U32 j = 0; j < relations[relId].size(); ++j)
@@ -423,7 +366,7 @@ static void displayHelp()
{ {
WINDOW* help_tab = newwin(LINES, COLS, 0, 0); WINDOW* help_tab = newwin(LINES, COLS, 0, 0);
waddstr(help_tab, "Enter - focus the currently selected person\n" waddstr(help_tab, "Enter - focus the currently selected person\n" /* todo */
"Arrow keys - move the camera\n" "Arrow keys - move the camera\n"
"H, J, K, L - move the selection\n" "H, J, K, L - move the selection\n"
"I - display info about the selected person\n"); "I - display info about the selected person\n");
@@ -434,77 +377,73 @@ static void displayHelp()
getch(); /* wait press */ getch(); /* wait press */
werase(help_tab); werase(help_tab);
wrefresh(help_tab); /* todo: dont update */ wnoutrefresh(help_tab);
delwin(help_tab); delwin(help_tab);
} }
void Tree::display() void Tree::display()
{ {
draw(); /* todo: draw every time */ bool to_draw = true;
I32 c; I32 c;
do do
{ {
c = getch(); if(to_draw)
draw();
else
to_draw = true;
c = getch();
switch(c) switch(c)
{ {
case KEY_F(1): case KEY_F(1):
displayHelp(); displayHelp();
draw();
break; break;
case ' ': case SELECT:
case '\n': case '\n':
focused_ = findRootAncestor(selected_); focused_ = findRootAncestor(selected_);
offsetX_ = 0; offsetX_ = 0;
offsetY_ = 0; offsetY_ = 0;
draw();
break; break;
case KEY_LEFT: case MOVE_LEFT:
++offsetX_; ++offsetX_;
draw();
break; break;
case KEY_RIGHT: case MOVE_RIGHT:
--offsetX_; --offsetX_;
draw();
break; break;
case KEY_DOWN: case MOVE_DOWN:
--offsetY_; --offsetY_;
draw();
break; break;
case KEY_UP: case MOVE_UP:
++offsetY_; ++offsetY_;
draw();
break; break;
case '=': case '=':
case '+': case '+':
zoom_ = 1; zoom_ = 1;
draw();
break; break;
case '-': case '-':
zoom_ = 0; zoom_ = 0;
draw();
break; break;
case 'h': case SELECT_LEFT:
selectLeft(); selectLeft();
break; break;
case 'j': case SELECT_DOWN:
selectDown(); selectDown();
break; break;
case 'k': case SELECT_UP:
selectUp(); selectUp();
break; break;
case 'l': case SELECT_RIGHT:
selectRight(); selectRight();
break; break;
case 'i': case DISPLAY_INFO:
people[selected_].displayInfo(); people[selected_].displayInfo();
draw();
break; break;
default: break; default:
to_draw = false; /* invalid key, don't redraw */
break;
} }
} }
while(c != 'w'); while(c != CLOSE);
} }
void Tree::updateRels(person_id id) void Tree::updateRels(person_id id)
@@ -557,57 +496,6 @@ void Tree::print() const
member.displayInfo(); member.displayInfo();
} }
/* void Tree::printRel(const unsigned id)const */
/* { */
/* cout << people[id].name_; */
/* if (people[id].numRel_ == 0) */
/* cout << " has no known relatives"; */
/* else */
/* { */
/* unsigned relId; */
/* cout << "'s relatives:\n"; */
/* for (unsigned i = 0; i < people[id].numRel_; ++i) */
/* { */
/* relId = relatives[id][i]; */
/* cout << people[relId].name_ << " - "; */
/* switch (relations[id][i]) */
/* { */
/* case Father: */
/* case Mother: */
/* cout << (people[relId].isMale_ ? "son" : "daughter"); */
/* break; */
/* case Son: */
/* case Daughter: */
/* cout << (people[relId].isMale_ ? "father" : "mother"); */
/* break; */
/* case Brother: */
/* case Sister: */
/* cout << (people[relId].isMale_ ? "brother" : "sister"); */
/* break; */
/* case HalfBrother: */
/* case HalfSister: */
/* cout << (people[relId].isMale_ ? "half brother" : "half sister"); */
/* break; */
/* case Husband: */
/* cout << "wife"; */
/* break; */
/* case Wife: */
/* cout << "husband"; */
/* break; */
/* case ExHusband: */
/* cout << "ex-wife\n"; */
/* break; */
/* case ExWife: */
/* cout << "ex-husband\n"; */
/* break; */
/* } */
/* cout << '\n'; */
/* } */
/* cout << '\n'; */
/* } */
/* } */
void Tree::printMember(const unsigned id)const void Tree::printMember(const unsigned id)const
{ {
people[id].displayInfo(); people[id].displayInfo();
@@ -620,7 +508,6 @@ void Tree::printOldestAncestors(const unsigned id)const
} }
void Tree::commonAncestorRec(person_id id, vector<U8> &visited) const void Tree::commonAncestorRec(person_id id, vector<U8> &visited) const
{ {
++visited[id]; ++visited[id];
@@ -769,7 +656,6 @@ void Tree::selectLeft()
} }
void Tree::selectDown() void Tree::selectDown()
{ {
const auto& curRels = relations[selected_]; const auto& curRels = relations[selected_];
+1 -4
View File
@@ -58,9 +58,6 @@ public:
std::vector<person_id> findChildren(person_id person) const; std::vector<person_id> findChildren(person_id person) const;
std::vector<person_id> findChildren(person_id person, person_id exclude) const; std::vector<person_id> findChildren(person_id person, person_id exclude) const;
void saveToFile()const;//
bool loadFromFile();
void addPerson(const char* name, Sex sex, person_id father=Nobody, person_id mother=Nobody, EventTime birth={}, EventTime death={}); void addPerson(const char* name, Sex sex, person_id father=Nobody, person_id mother=Nobody, EventTime birth={}, EventTime death={});
bool addRelation(const char* firstName, RelType, const char* secondName); //Adds a new relation or edits an old one. 0 - failure 1 - success bool addRelation(const char* firstName, RelType, const char* secondName); //Adds a new relation or edits an old one. 0 - failure 1 - success
bool addRelation(person_id first, RelType, person_id second, bool update=true); //0 - failure 1 - success bool addRelation(person_id first, RelType, person_id second, bool update=true); //0 - failure 1 - success
@@ -70,6 +67,7 @@ public:
void removeRelation(person_id first, person_id second); void removeRelation(person_id first, person_id second);
void removeRelation(const char* firstName, const char* secondName); void removeRelation(const char* firstName, const char* secondName);
/* display the tree and wait process key input */
void display(); void display();
void print()const; void print()const;
@@ -88,7 +86,6 @@ private:
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
return the farthest X that will be drawn */ return the farthest X that will be drawn */
I16 drawLine(person_id, I16 drawY, I16 drawX) const;
I16 drawLineWithWives(person_id, I16 drawY, I16 drawX) const; I16 drawLineWithWives(person_id, I16 drawY, I16 drawX) const;
void selectLeft(); void selectLeft();
-6
View File
@@ -27,12 +27,6 @@ void init()
wnoutrefresh(stdscr); /* if not present the first real refresh is missed */ wnoutrefresh(stdscr); /* if not present the first real refresh is missed */
} }
void TFT_EXIT(I32 return_code)
{
endwin(); /* stop ncursers */
exit(return_code);
}
MappedFile mapfile(fd_t file) MappedFile mapfile(fd_t file)
{ {
MappedFile res; MappedFile res;
-1
View File
@@ -31,7 +31,6 @@ struct MappedFile
}; };
void init(); void init();
void TFT_EXIT(I32 return_code);
MappedFile mapfile(fd_t); MappedFile mapfile(fd_t);
fd_t openOrDie(const char* path); fd_t openOrDie(const char* path);
+1
View File
@@ -14,6 +14,7 @@ findRelation - extend
Draw distinct regions of a tree Draw distinct regions of a tree
Draw spouses' relatives if main has none? Draw spouses' relatives if main has none?
Combine trees on the command line
Zooming Zooming