238 lines
4.9 KiB
C++
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;
|
|
}
|
|
}
|