Files
tft/src/person.cpp
T
2024-07-12 21:01:56 +03:00

160 lines
3.6 KiB
C++

#include <iostream>
#include <assert.h>
#include <ctype.h>
#include <ncurses.h>
#include"person.hpp"
#include "utils.hpp"
using std::cout;
using std::string;
EventTime::EventTime(I16 Year, U8 Month, U16 Day, I8 Hour, I8 Minute)
: year(Year)
, month(Month)
, day(Day)
, hour(Hour)
, minute(Minute)
{
assert(month <= 12 && day <= 31 && hour <= 23 && minute <= 59 && "Invalid EventTime data");
}
void EventTime::print(WINDOW* info_tab) const
{
if (day != UNKNOWN_DATE)
wprintw(info_tab, "%d", day);
else
waddstr(info_tab, "??");
waddch(info_tab, '.');
if (month != UNKNOWN_DATE)
wprintw(info_tab, "%d", month);
else
waddstr(info_tab, "??");
waddch(info_tab, '.');
if (year != UNKNOWN_DATE)
wprintw(info_tab, "%d", year);
else
waddstr(info_tab, "????");
waddch(info_tab, '\n');
}
Person::Person(const char* aName, EventTime aBirth, Sex aSex, EventTime aDeath)
: name(aName)
, birth(aBirth)
, sex(aSex)
, death(aDeath)
{
}
bool Person::operator==(const Person &other)const
{
return sex == other.sex && name == other.name &&
(birth.day == other.birth.day || birth.day == EventTime::UNKNOWN_DATE || other.birth.day == EventTime::UNKNOWN_DATE) &&
(birth.month == other.birth.month || birth.month == EventTime::UNKNOWN_DATE || other.birth.month == EventTime::UNKNOWN_DATE) &&
(birth.year == other.birth.year || birth.year == EventTime::UNKNOWN_DATE || other.birth.year == EventTime::UNKNOWN_DATE);
}
void Person::displayInfo()const
{
AutoWin info_tab( newwin(LINES, COLS, 0, 0) );
waddstr(info_tab, name.data());
waddch(info_tab,'\n');
waddstr(info_tab, "Birth: ");
birth.print(info_tab);
waddstr(info_tab, "Death: ");
death.print(info_tab);
mvwaddstr(info_tab, LINES-1, 0, "Press any key to return.");
wrefresh(info_tab);
getch(); /* waint press */
werase(info_tab);
wrefresh(info_tab); /* todo: dont update */
}
static U16 Utf8SymbolsCount(const string& str)
{
U16 num = 0;
for(char c: str)
num += ((c & 0xC0) != 0x80); // bytes that start with 0 are single, 11 are multiple, 10 are sucessors
return num;
}
U16 Person::drawAsFocused(const I16 drawY, const I16 drawX, bool selected, bool hasSpouse,
bool hasKids, bool wholeName) const
{
auto topright = hasSpouse ? ACS_TTEE : ACS_URCORNER;
auto botleft = hasKids ? ACS_LTEE : ACS_LLCORNER;
return draw(drawY, drawX, selected, wholeName,
ACS_LTEE, topright,
botleft, ACS_LRCORNER );
}
U16 Person::drawAsSpouse(I16 drawY, I16 drawX, bool selected, bool hasTree, bool wholeName) const
{
auto topright = hasTree ? '@' : ACS_URCORNER;
return draw(drawY, drawX, selected, wholeName,
ACS_TTEE, topright,
ACS_LLCORNER, ACS_LRCORNER );
}
U16 Person::draw(I16 drawY, I16 drawX, bool selected, bool wholeName,
U32 topleft, U32 topright, U32 botleft, U32 botright) const
{
string display_name;
if(wholeName)
{
display_name = name;
}
else
{
size_t space = name.find(' ');
if(space != string::npos)
{
display_name = name.substr(0, space);
}
else
{
display_name = name;
}
}
/* pad width */
const U16 width = Utf8SymbolsCount(display_name) + 4;
if(willBeVisible(drawY, drawX, BOX_HEIGHT, width))
{
AutoWin pad( newpad(BOX_HEIGHT, width) );
auto color_pair = COLOR_PAIR( selected ? COLOR_SELECTED
: (sex==M ? COLOR_MALE : COLOR_FEMALE) );
wbkgd(pad, color_pair);
/* wattron(pad, color_pair); */
wborder(pad, ACS_VLINE, ACS_VLINE, ACS_HLINE, ACS_HLINE,
topleft, topright,
botleft, botright);
mvwaddstr(pad, 2, 2, display_name.data());
/* wattroff(pad, color_pair); */
drawpad(pad, drawY, drawX);
}
return width;
}