summaryrefslogtreecommitdiff
path: root/plugins/manipulator.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/manipulator.cpp')
-rw-r--r--plugins/manipulator.cpp175
1 files changed, 142 insertions, 33 deletions
diff --git a/plugins/manipulator.cpp b/plugins/manipulator.cpp
index 1ad46ab2..0b0b99d4 100644
--- a/plugins/manipulator.cpp
+++ b/plugins/manipulator.cpp
@@ -247,12 +247,14 @@ struct UnitInfo
string transname;
string profession;
int8_t color;
+ int active_index;
};
enum altsort_mode {
ALTSORT_NAME,
ALTSORT_PROFESSION,
ALTSORT_HAPPINESS,
+ ALTSORT_ARRIVAL,
ALTSORT_MAX
};
@@ -284,6 +286,14 @@ bool sortByHappiness (const UnitInfo *d1, const UnitInfo *d2)
return (d1->unit->status.happiness < d2->unit->status.happiness);
}
+bool sortByArrival (const UnitInfo *d1, const UnitInfo *d2)
+{
+ if (descending)
+ return (d1->active_index > d2->active_index);
+ else
+ return (d1->active_index < d2->active_index);
+}
+
bool sortBySkill (const UnitInfo *d1, const UnitInfo *d2)
{
if (sort_skill != job_skill::NONE)
@@ -331,6 +341,12 @@ class viewscreen_unitlaborsst : public dfhack_viewscreen {
public:
void feed(set<df::interface_key> *events);
+ void logic() {
+ dfhack_viewscreen::logic();
+ if (do_refresh_names)
+ refreshNames();
+ }
+
void render();
void resize(int w, int h) { calcSize(); }
@@ -338,30 +354,40 @@ public:
std::string getFocusString() { return "unitlabors"; }
- viewscreen_unitlaborsst(vector<df::unit*> &src);
+ df::unit *getSelectedUnit();
+
+ viewscreen_unitlaborsst(vector<df::unit*> &src, int cursor_pos);
~viewscreen_unitlaborsst() { };
protected:
vector<UnitInfo *> units;
altsort_mode altsort;
+ bool do_refresh_names;
int first_row, sel_row, num_rows;
int first_column, sel_column;
int col_widths[DISP_COLUMN_MAX];
int col_offsets[DISP_COLUMN_MAX];
+ void refreshNames();
void calcSize ();
};
-viewscreen_unitlaborsst::viewscreen_unitlaborsst(vector<df::unit*> &src)
+viewscreen_unitlaborsst::viewscreen_unitlaborsst(vector<df::unit*> &src, int cursor_pos)
{
+ std::map<df::unit*,int> active_idx;
+ auto &active = world->units.active;
+ for (size_t i = 0; i < active.size(); i++)
+ active_idx[active[i]] = i;
+
for (size_t i = 0; i < src.size(); i++)
{
UnitInfo *cur = new UnitInfo;
df::unit *unit = src[i];
cur->unit = unit;
cur->allowEdit = true;
+ cur->active_index = active_idx[unit];
if (unit->race != ui->race_id)
cur->allowEdit = false;
@@ -375,19 +401,44 @@ viewscreen_unitlaborsst::viewscreen_unitlaborsst(vector<df::unit*> &src)
if (!ENUM_ATTR(profession, can_assign_labor, unit->profession))
cur->allowEdit = false;
- cur->name = Translation::TranslateName(&unit->name, false);
- cur->transname = Translation::TranslateName(&unit->name, true);
- cur->profession = Units::getProfessionName(unit);
cur->color = Units::getProfessionColor(unit);
units.push_back(cur);
}
- std::sort(units.begin(), units.end(), sortByName);
-
altsort = ALTSORT_NAME;
- first_row = sel_row = 0;
first_column = sel_column = 0;
+
+ refreshNames();
+
+ first_row = 0;
+ sel_row = cursor_pos;
calcSize();
+
+ // recalculate first_row to roughly match the original layout
+ first_row = 0;
+ while (first_row < sel_row - num_rows + 1)
+ first_row += num_rows + 2;
+ // make sure the selection stays visible
+ if (first_row > sel_row)
+ first_row = sel_row - num_rows + 1;
+ // don't scroll beyond the end
+ if (first_row > units.size() - num_rows)
+ first_row = units.size() - num_rows;
+}
+
+void viewscreen_unitlaborsst::refreshNames()
+{
+ do_refresh_names = false;
+
+ for (size_t i = 0; i < units.size(); i++)
+ {
+ UnitInfo *cur = units[i];
+ df::unit *unit = cur->unit;
+
+ cur->name = Translation::TranslateName(&unit->name, false);
+ cur->transname = Translation::TranslateName(&unit->name, true);
+ cur->profession = Units::getProfessionName(unit);
+ }
}
void viewscreen_unitlaborsst::calcSize()
@@ -463,16 +514,25 @@ void viewscreen_unitlaborsst::calcSize()
void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
{
- if (events->count(interface_key::LEAVESCREEN))
+ bool leave_all = events->count(interface_key::LEAVESCREEN_ALL);
+ if (leave_all || events->count(interface_key::LEAVESCREEN))
{
events->clear();
Screen::dismiss(this);
+ if (leave_all)
+ {
+ events->insert(interface_key::LEAVESCREEN);
+ parent->feed(events);
+ }
return;
}
if (!units.size())
return;
+ if (do_refresh_names)
+ refreshNames();
+
if (events->count(interface_key::CURSOR_UP) || events->count(interface_key::CURSOR_UPLEFT) || events->count(interface_key::CURSOR_UPRIGHT))
sel_row--;
if (events->count(interface_key::CURSOR_UP_FAST) || events->count(interface_key::CURSOR_UPLEFT_FAST) || events->count(interface_key::CURSOR_UPRIGHT_FAST))
@@ -482,6 +542,15 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
if (events->count(interface_key::CURSOR_DOWN_FAST) || events->count(interface_key::CURSOR_DOWNLEFT_FAST) || events->count(interface_key::CURSOR_DOWNRIGHT_FAST))
sel_row += 10;
+ if ((sel_row > 0) && events->count(interface_key::CURSOR_UP_Z_AUX))
+ {
+ sel_row = 0;
+ }
+ if ((sel_row < units.size()-1) && events->count(interface_key::CURSOR_DOWN_Z_AUX))
+ {
+ sel_row = units.size()-1;
+ }
+
if (sel_row < 0)
sel_row = 0;
if (sel_row > units.size() - 1)
@@ -528,7 +597,11 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
if (first_column < sel_column - col_widths[DISP_COLUMN_LABORS] + 1)
first_column = sel_column - col_widths[DISP_COLUMN_LABORS] + 1;
- // handle mouse input
+ int input_row = sel_row;
+ int input_column = sel_column;
+ int input_sort = altsort;
+
+ // Translate mouse input to appropriate keyboard input
if (enabler->tracking_on && gps->mouse_x != -1 && gps->mouse_y != -1)
{
int click_header = DISP_COLUMN_MAX; // group ID of the column header clicked
@@ -560,34 +633,44 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
case DISP_COLUMN_HAPPINESS:
if (enabler->mouse_lbut || enabler->mouse_rbut)
{
- descending = enabler->mouse_lbut;
- std::sort(units.begin(), units.end(), sortByHappiness);
+ input_sort = ALTSORT_HAPPINESS;
+ if (enabler->mouse_lbut)
+ events->insert(interface_key::SECONDSCROLL_PAGEUP);
+ if (enabler->mouse_rbut)
+ events->insert(interface_key::SECONDSCROLL_PAGEDOWN);
}
break;
case DISP_COLUMN_NAME:
if (enabler->mouse_lbut || enabler->mouse_rbut)
{
- descending = enabler->mouse_rbut;
- std::sort(units.begin(), units.end(), sortByName);
+ input_sort = ALTSORT_NAME;
+ if (enabler->mouse_lbut)
+ events->insert(interface_key::SECONDSCROLL_PAGEDOWN);
+ if (enabler->mouse_rbut)
+ events->insert(interface_key::SECONDSCROLL_PAGEUP);
}
break;
case DISP_COLUMN_PROFESSION:
if (enabler->mouse_lbut || enabler->mouse_rbut)
{
- descending = enabler->mouse_rbut;
- std::sort(units.begin(), units.end(), sortByProfession);
+ input_sort = ALTSORT_PROFESSION;
+ if (enabler->mouse_lbut)
+ events->insert(interface_key::SECONDSCROLL_PAGEDOWN);
+ if (enabler->mouse_rbut)
+ events->insert(interface_key::SECONDSCROLL_PAGEUP);
}
break;
case DISP_COLUMN_LABORS:
if (enabler->mouse_lbut || enabler->mouse_rbut)
{
- descending = enabler->mouse_lbut;
- sort_skill = columns[click_labor].skill;
- sort_labor = columns[click_labor].labor;
- std::sort(units.begin(), units.end(), sortBySkill);
+ input_column = click_labor;
+ if (enabler->mouse_lbut)
+ events->insert(interface_key::SECONDSCROLL_UP);
+ if (enabler->mouse_rbut)
+ events->insert(interface_key::SECONDSCROLL_DOWN);
}
break;
}
@@ -603,12 +686,12 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
// left-click to view, right-click to zoom
if (enabler->mouse_lbut)
{
- sel_row = click_unit;
+ input_row = click_unit;
events->insert(interface_key::UNITJOB_VIEW);
}
if (enabler->mouse_rbut)
{
- sel_row = click_unit;
+ input_row = click_unit;
events->insert(interface_key::UNITJOB_ZOOM_CRE);
}
break;
@@ -617,21 +700,28 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
// left-click to toggle, right-click to just highlight
if (enabler->mouse_lbut || enabler->mouse_rbut)
{
- sel_row = click_unit;
- sel_column = click_labor;
if (enabler->mouse_lbut)
+ {
+ input_row = click_unit;
+ input_column = click_labor;
events->insert(interface_key::SELECT);
+ }
+ if (enabler->mouse_rbut)
+ {
+ sel_row = click_unit;
+ sel_column = click_labor;
+ }
}
break;
}
enabler->mouse_lbut = enabler->mouse_rbut = 0;
}
- UnitInfo *cur = units[sel_row];
- if (events->count(interface_key::SELECT) && (cur->allowEdit) && (columns[sel_column].labor != unit_labor::NONE))
+ UnitInfo *cur = units[input_row];
+ if (events->count(interface_key::SELECT) && (cur->allowEdit) && (columns[input_column].labor != unit_labor::NONE))
{
df::unit *unit = cur->unit;
- const SkillColumn &col = columns[sel_column];
+ const SkillColumn &col = columns[input_column];
bool newstatus = !unit->status.labors[col.labor];
if (col.special)
{
@@ -650,7 +740,7 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
if (events->count(interface_key::SELECT_ALL) && (cur->allowEdit))
{
df::unit *unit = cur->unit;
- const SkillColumn &col = columns[sel_column];
+ const SkillColumn &col = columns[input_column];
bool newstatus = !unit->status.labors[col.labor];
for (int i = 0; i < NUM_COLUMNS; i++)
{
@@ -675,15 +765,15 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
if (events->count(interface_key::SECONDSCROLL_UP) || events->count(interface_key::SECONDSCROLL_DOWN))
{
descending = events->count(interface_key::SECONDSCROLL_UP);
- sort_skill = columns[sel_column].skill;
- sort_labor = columns[sel_column].labor;
+ sort_skill = columns[input_column].skill;
+ sort_labor = columns[input_column].labor;
std::sort(units.begin(), units.end(), sortBySkill);
}
if (events->count(interface_key::SECONDSCROLL_PAGEUP) || events->count(interface_key::SECONDSCROLL_PAGEDOWN))
{
descending = events->count(interface_key::SECONDSCROLL_PAGEUP);
- switch (altsort)
+ switch (input_sort)
{
case ALTSORT_NAME:
std::sort(units.begin(), units.end(), sortByName);
@@ -694,6 +784,9 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
case ALTSORT_HAPPINESS:
std::sort(units.begin(), units.end(), sortByHappiness);
break;
+ case ALTSORT_ARRIVAL:
+ std::sort(units.begin(), units.end(), sortByArrival);
+ break;
}
}
if (events->count(interface_key::CHANGETAB))
@@ -707,6 +800,9 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
altsort = ALTSORT_HAPPINESS;
break;
case ALTSORT_HAPPINESS:
+ altsort = ALTSORT_ARRIVAL;
+ break;
+ case ALTSORT_ARRIVAL:
altsort = ALTSORT_NAME;
break;
}
@@ -718,12 +814,14 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
{
for (int i = 0; i < unitlist->units[unitlist->page].size(); i++)
{
- if (unitlist->units[unitlist->page][i] == units[sel_row]->unit)
+ if (unitlist->units[unitlist->page][i] == units[input_row]->unit)
{
unitlist->cursor_pos[unitlist->page] = i;
unitlist->feed(events);
if (Screen::isDismissed(unitlist))
Screen::dismiss(this);
+ else
+ do_refresh_names = true;
break;
}
}
@@ -948,12 +1046,23 @@ void viewscreen_unitlaborsst::render()
case ALTSORT_HAPPINESS:
OutputString(15, x, gps->dimy - 2, "Happiness");
break;
+ case ALTSORT_ARRIVAL:
+ OutputString(15, x, gps->dimy - 2, "Arrival");
+ break;
default:
OutputString(15, x, gps->dimy - 2, "Unknown");
break;
}
}
+df::unit *viewscreen_unitlaborsst::getSelectedUnit()
+{
+ // This query might be from the rename plugin
+ do_refresh_names = true;
+
+ return units[sel_row]->unit;
+}
+
struct unitlist_hook : df::viewscreen_unitlistst
{
typedef df::viewscreen_unitlistst interpose_base;
@@ -964,7 +1073,7 @@ struct unitlist_hook : df::viewscreen_unitlistst
{
if (units[page].size())
{
- Screen::show(new viewscreen_unitlaborsst(units[page]));
+ Screen::show(new viewscreen_unitlaborsst(units[page], cursor_pos[page]));
return;
}
}