#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; } }