Files
tft/src/ui.cpp
T
2024-08-27 09:37:45 +03:00

238 lines
4.9 KiB
C++

#include "ui.hpp"
#include "tree.hpp"
#include "utils.hpp"
#include "assert.h"
#include "../config.h" /* user's configuration */
namespace
{
void displayHelp();
person_id selectLeft(const Tree& t, person_id selected);
person_id selectDown(const Tree& t, person_id selected);
person_id selectUp(const Tree& t, person_id selected);
person_id selectRight(const Tree& t, person_id selected);
person_id selectLeftSibSpouse(const Tree& t, person_id selected); /* todo: split? */
person_id selectRightSib(const Tree& t, person_id selected);
}
ZoomLevel operator++(ZoomLevel& z)
{
z = (ZoomLevel)(z + 1);
return z;
}
ZoomLevel operator--(ZoomLevel& z)
{
z = (ZoomLevel)(z - 1);
return z;
}
void displayTree(Tree& t)
{
person_id selected = 0; // the currently selected selected
ZoomLevel zoom = ZoomLevel::FIRST_NAME; // how much info to show for each selected
// offset of the tree in relation to the top left corner of the screen
I16 offsetY = 0, offsetX = 0;
bool to_draw = true;
I32 input;
do
{
if(to_draw)
t.draw(selected, zoom, offsetY, offsetX);
else
to_draw = true;
input = getch();
switch(input)
{
case KEY_F(1):
displayHelp();
break;
case SELECT:
case '\n':
t.focusPerson( t.findRootAncestor(selected) );
offsetX = 0;
offsetY = 0;
break;
case MOVE_LEFT:
++offsetX;
break;
case MOVE_RIGHT:
--offsetX;
break;
case MOVE_DOWN:
--offsetY;
break;
case MOVE_UP:
++offsetY;
break;
case '=':
case '+':
if(zoom < ZoomLevel::MAX_ZOOM)
++zoom;
break;
case '-':
if(zoom > 0)
--zoom;
break;
case SELECT_LEFT:
selected = selectLeft(t, selected);
break;
case SELECT_DOWN:
selected = selectDown(t, selected);
break;
case SELECT_UP:
selected = selectUp(t, selected);
break;
case SELECT_RIGHT:
selected = selectRight(t, selected);
break;
case DISPLAY_INFO:
t.printMember(selected);
break;
default:
to_draw = false; /* invalid key, don't redraw */
break;
}
}
while(input != CLOSE);
}
namespace
{
void displayHelp()
{
AutoWin help_tab( newwin(LINES, COLS, 0, 0) );
waddstr(help_tab, VISUALIZATION_HELP_STR);
mvwaddstr(help_tab, LINES-1, 0, "Press any key to return.");
wrefresh(help_tab);
getch(); /* wait press */
werase(help_tab);
wnoutrefresh(help_tab);
}
person_id selectLeft(const Tree& t, person_id selected)
{
if (t.findCommonAncestor(t.focused(), selected) != Nobody) //if the selected is part of main tree
{
selected = selectLeftSibSpouse(t, selected);
}
else
{
person_id spouse = t.findSpouse(selected);
assert(spouse != Nobody);
selected = spouse;
}
return selected;
}
person_id selectDown(const Tree& t, person_id selected)
{
const auto& curRels = t.findRelations(selected);
for(const Relation& rel: curRels)
{
if (rel.type == Parent)
{
selected = rel.id;
break;
}
}
return selected;
}
person_id selectUp(const Tree& t, person_id selected)
{
if (t.findCommonAncestor(t.focused(), selected) != Nobody) //if the selected is part of main tree
{
person_id dad = t.findParent(selected, M);
person_id mom = t.findParent(selected, F);
if (t.findCommonAncestor(t.focused(), mom) != Nobody) //if selected's mom is part of main tree
selected = mom;
else if (dad != Nobody)
selected = dad;
}
return selected;
}
person_id selectRight(const Tree& t, person_id selected)
{
if (t.findCommonAncestor(t.focused(), selected) != Nobody) //if the selected is part of main tree
{
if (person_id spouse = t.findSpouse(selected); spouse != Nobody)
{
selected = spouse;
}
else
{
selected = selectRightSib(t, selected);
}
}
else //if spouse of someone in main tree
{
person_id spouse = t.findSpouse(selected);
assert(spouse != Nobody);
selected = selectRightSib(t, spouse);
}
return selected;
}
person_id selectLeftSibSpouse(const Tree& t, person_id selected) /* todo: return a value and split */
{
person_id sel_par = t.findParent(selected, M);
if( sel_par == Nobody )
sel_par = t.findParent(selected, F);
if( sel_par == Nobody )
return selected;
auto siblings = t.findChildren(sel_par);
person_id left_sib = Nobody;
for(auto it = siblings.begin()+1; it < siblings.end(); ++it)
{
if(*it == selected)
{
left_sib = *(it-1);
person_id sib_spouse = t.findSpouse(left_sib);
if(sib_spouse != Nobody)
selected = sib_spouse;
else
selected = left_sib;
break;
}
}
return selected;
}
person_id selectRightSib(const Tree& t, person_id selected)
{
person_id sel_par = t.findParent(selected, M);
if( sel_par == Nobody )
sel_par = t.findParent(selected, F);
if( sel_par == Nobody )
return selected;
auto siblings = t.findChildren(sel_par);
for(auto it = siblings.begin(); it < siblings.end()-1; ++it)
{
if(*it == selected)
{
selected = *(it+1);
break;
}
}
return selected;
}
}