Implement dwarf selection

develop
lethosor 2015-01-08 20:55:37 -05:00
parent 262fe52424
commit 481e5cc19e
1 changed files with 91 additions and 2 deletions

@ -8,6 +8,7 @@
#include <modules/Screen.h> #include <modules/Screen.h>
#include <modules/Translation.h> #include <modules/Translation.h>
#include <modules/Units.h> #include <modules/Units.h>
#include <modules/Filesystem.h>
#include <vector> #include <vector>
#include <string> #include <string>
#include <set> #include <set>
@ -43,6 +44,8 @@ REQUIRE_GLOBAL(ui);
REQUIRE_GLOBAL(gps); REQUIRE_GLOBAL(gps);
REQUIRE_GLOBAL(enabler); REQUIRE_GLOBAL(enabler);
#define CONFIG_PATH "manipulator"
struct SkillLevel struct SkillLevel
{ {
const char *name; const char *name;
@ -270,10 +273,12 @@ struct UnitInfo
int active_index; int active_index;
string squad_effective_name; string squad_effective_name;
string squad_info; string squad_info;
bool selected;
}; };
enum altsort_mode { enum altsort_mode {
ALTSORT_NAME, ALTSORT_NAME,
ALTSORT_SELECTED,
ALTSORT_PROFESSION_OR_SQUAD, ALTSORT_PROFESSION_OR_SQUAD,
ALTSORT_STRESS, ALTSORT_STRESS,
ALTSORT_ARRIVAL, ALTSORT_ARRIVAL,
@ -376,8 +381,14 @@ bool sortBySkill (const UnitInfo *d1, const UnitInfo *d2)
return false; return false;
} }
bool sortBySelected (const UnitInfo *d1, const UnitInfo *d2)
{
return descending ? (d1->selected > d2->selected) : (d1->selected < d2->selected);
}
enum display_columns { enum display_columns {
DISP_COLUMN_STRESS, DISP_COLUMN_STRESS,
DISP_COLUMN_SELECTED,
DISP_COLUMN_NAME, DISP_COLUMN_NAME,
DISP_COLUMN_PROFESSION_OR_SQUAD, DISP_COLUMN_PROFESSION_OR_SQUAD,
DISP_COLUMN_LABORS, DISP_COLUMN_LABORS,
@ -414,6 +425,7 @@ protected:
bool do_refresh_names; bool do_refresh_names;
int first_row, sel_row, num_rows; int first_row, sel_row, num_rows;
int first_column, sel_column; int first_column, sel_column;
int last_selection;
int col_widths[DISP_COLUMN_MAX]; int col_widths[DISP_COLUMN_MAX];
int col_offsets[DISP_COLUMN_MAX]; int col_offsets[DISP_COLUMN_MAX];
@ -443,6 +455,7 @@ viewscreen_unitlaborsst::viewscreen_unitlaborsst(vector<df::unit*> &src, int cur
cur->unit = unit; cur->unit = unit;
cur->allowEdit = true; cur->allowEdit = true;
cur->selected = false;
cur->active_index = active_idx[unit]; cur->active_index = active_idx[unit];
if (!Units::isOwnRace(unit)) if (!Units::isOwnRace(unit))
@ -481,6 +494,8 @@ viewscreen_unitlaborsst::viewscreen_unitlaborsst(vector<df::unit*> &src, int cur
// don't scroll beyond the end // don't scroll beyond the end
if (first_row > units.size() - num_rows) if (first_row > units.size() - num_rows)
first_row = units.size() - num_rows; first_row = units.size() - num_rows;
last_selection = -1;
} }
void viewscreen_unitlaborsst::refreshNames() void viewscreen_unitlaborsst::refreshNames()
@ -521,6 +536,8 @@ void viewscreen_unitlaborsst::calcSize()
int col_maxwidth[DISP_COLUMN_MAX]; int col_maxwidth[DISP_COLUMN_MAX];
col_minwidth[DISP_COLUMN_STRESS] = 6; col_minwidth[DISP_COLUMN_STRESS] = 6;
col_maxwidth[DISP_COLUMN_STRESS] = 6; col_maxwidth[DISP_COLUMN_STRESS] = 6;
col_minwidth[DISP_COLUMN_SELECTED] = 1;
col_maxwidth[DISP_COLUMN_SELECTED] = 1;
col_minwidth[DISP_COLUMN_NAME] = 16; col_minwidth[DISP_COLUMN_NAME] = 16;
col_maxwidth[DISP_COLUMN_NAME] = 16; // adjusted in the loop below col_maxwidth[DISP_COLUMN_NAME] = 16; // adjusted in the loop below
col_minwidth[DISP_COLUMN_PROFESSION_OR_SQUAD] = 10; col_minwidth[DISP_COLUMN_PROFESSION_OR_SQUAD] = 10;
@ -799,6 +816,17 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
} }
break; break;
case DISP_COLUMN_SELECTED:
if (enabler->mouse_lbut || enabler->mouse_rbut)
{
input_sort = ALTSORT_SELECTED;
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: case DISP_COLUMN_NAME:
if (enabler->mouse_lbut || enabler->mouse_rbut) if (enabler->mouse_lbut || enabler->mouse_rbut)
{ {
@ -839,6 +867,20 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
// do nothing // do nothing
break; break;
case DISP_COLUMN_SELECTED:
// left-click to select, right-click to extend selection
if (enabler->mouse_lbut)
{
input_row = click_unit;
events->insert(interface_key::CUSTOM_X);
}
if (enabler->mouse_rbut)
{
input_row = click_unit;
events->insert(interface_key::CUSTOM_SHIFT_X);
}
break;
case DISP_COLUMN_NAME: case DISP_COLUMN_NAME:
case DISP_COLUMN_PROFESSION_OR_SQUAD: case DISP_COLUMN_PROFESSION_OR_SQUAD:
// left-click to view, right-click to zoom // left-click to view, right-click to zoom
@ -938,6 +980,9 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
case ALTSORT_NAME: case ALTSORT_NAME:
std::stable_sort(units.begin(), units.end(), sortByName); std::stable_sort(units.begin(), units.end(), sortByName);
break; break;
case ALTSORT_SELECTED:
std::stable_sort(units.begin(), units.end(), sortBySelected);
break;
case ALTSORT_PROFESSION_OR_SQUAD: case ALTSORT_PROFESSION_OR_SQUAD:
std::stable_sort(units.begin(), units.end(), show_squad ? sortBySquad : sortByProfession); std::stable_sort(units.begin(), units.end(), show_squad ? sortBySquad : sortByProfession);
break; break;
@ -954,6 +999,9 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
switch (altsort) switch (altsort)
{ {
case ALTSORT_NAME: case ALTSORT_NAME:
altsort = ALTSORT_SELECTED;
break;
case ALTSORT_SELECTED:
altsort = ALTSORT_PROFESSION_OR_SQUAD; altsort = ALTSORT_PROFESSION_OR_SQUAD;
break; break;
case ALTSORT_PROFESSION_OR_SQUAD: case ALTSORT_PROFESSION_OR_SQUAD:
@ -972,6 +1020,28 @@ void viewscreen_unitlaborsst::feed(set<df::interface_key> *events)
show_squad = !show_squad; show_squad = !show_squad;
} }
if (events->count(interface_key::CUSTOM_SHIFT_X))
{
if (last_selection == -1 || last_selection == input_row)
events->insert(interface_key::CUSTOM_X);
else
{
for (int i = std::min(input_row, last_selection);
i <= std::max(input_row, last_selection);
i++)
{
if (i == last_selection) continue;
units[i]->selected = units[last_selection]->selected;
}
}
}
if (events->count(interface_key::CUSTOM_X))
{
cur->selected = !cur->selected;
last_selection = input_row;
}
if (VIRTUAL_CAST_VAR(unitlist, df::viewscreen_unitlistst, parent)) if (VIRTUAL_CAST_VAR(unitlist, df::viewscreen_unitlistst, parent))
{ {
if (events->count(interface_key::UNITJOB_VIEW) || events->count(interface_key::UNITJOB_ZOOM_CRE)) if (events->count(interface_key::UNITJOB_VIEW) || events->count(interface_key::UNITJOB_ZOOM_CRE))
@ -1011,6 +1081,7 @@ void viewscreen_unitlaborsst::render()
Screen::drawBorder(" Dwarf Manipulator - Manage Labors "); Screen::drawBorder(" Dwarf Manipulator - Manage Labors ");
Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_STRESS], 2, "Stress"); Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_STRESS], 2, "Stress");
Screen::paintTile(Screen::Pen('\373', 7, 0), col_offsets[DISP_COLUMN_SELECTED], 2);
Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_NAME], 2, "Name"); Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_NAME], 2, "Name");
Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_PROFESSION_OR_SQUAD], 2, show_squad ? "Squad" : "Profession"); Screen::paintString(Screen::Pen(' ', 7, 0), col_offsets[DISP_COLUMN_PROFESSION_OR_SQUAD], 2, show_squad ? "Squad" : "Profession");
@ -1070,6 +1141,11 @@ void viewscreen_unitlaborsst::render()
fg = 10; // 2:1 fg = 10; // 2:1
Screen::paintString(Screen::Pen(' ', fg, bg), col_offsets[DISP_COLUMN_STRESS], 4 + row, stress); Screen::paintString(Screen::Pen(' ', fg, bg), col_offsets[DISP_COLUMN_STRESS], 4 + row, stress);
if (cur->selected)
Screen::paintTile(Screen::Pen('\373', 10, 0), col_offsets[DISP_COLUMN_SELECTED], 4 + row);
else
Screen::paintTile(Screen::Pen('-', 8, 0), col_offsets[DISP_COLUMN_SELECTED], 4 + row);
fg = 15; fg = 15;
if (row_offset == sel_row) if (row_offset == sel_row)
{ {
@ -1204,7 +1280,7 @@ void viewscreen_unitlaborsst::render()
canToggle = (cur->allowEdit) && columns[sel_column].isValidLabor(ui->main.fortress_entity); canToggle = (cur->allowEdit) && columns[sel_column].isValidLabor(ui->main.fortress_entity);
} }
int x = 2, y = dim.y - 3; int x = 2, y = dim.y - 4;
OutputString(10, x, y, Screen::getKeyDisplay(interface_key::SELECT)); OutputString(10, x, y, Screen::getKeyDisplay(interface_key::SELECT));
OutputString(canToggle ? 15 : 8, x, y, ": Toggle labor, "); OutputString(canToggle ? 15 : 8, x, y, ": Toggle labor, ");
@ -1217,7 +1293,7 @@ void viewscreen_unitlaborsst::render()
OutputString(10, x, y, Screen::getKeyDisplay(interface_key::UNITJOB_ZOOM_CRE)); OutputString(10, x, y, Screen::getKeyDisplay(interface_key::UNITJOB_ZOOM_CRE));
OutputString(15, x, y, ": Zoom-Cre"); OutputString(15, x, y, ": Zoom-Cre");
x = 2; y = dim.y - 2; x = 2; y = dim.y - 3;
OutputString(10, x, y, Screen::getKeyDisplay(interface_key::LEAVESCREEN)); OutputString(10, x, y, Screen::getKeyDisplay(interface_key::LEAVESCREEN));
OutputString(15, x, y, ": Done, "); OutputString(15, x, y, ": Done, ");
@ -1238,6 +1314,9 @@ void viewscreen_unitlaborsst::render()
case ALTSORT_NAME: case ALTSORT_NAME:
OutputString(15, x, y, "Name"); OutputString(15, x, y, "Name");
break; break;
case ALTSORT_SELECTED:
OutputString(15, x, y, "Selected");
break;
case ALTSORT_PROFESSION_OR_SQUAD: case ALTSORT_PROFESSION_OR_SQUAD:
OutputString(15, x, y, show_squad ? "Squad" : "Profession"); OutputString(15, x, y, show_squad ? "Squad" : "Profession");
break; break;
@ -1251,6 +1330,11 @@ void viewscreen_unitlaborsst::render()
OutputString(15, x, y, "Unknown"); OutputString(15, x, y, "Unknown");
break; break;
} }
x = 2; y = dim.y - 2;
OutputString(10, x, y, Screen::getKeyDisplay(interface_key::CUSTOM_X));
OutputString(10, x, y, Screen::getKeyDisplay(interface_key::CUSTOM_SHIFT_X));
OutputString(15, x, y, ": Select");
} }
df::unit *viewscreen_unitlaborsst::getSelectedUnit() df::unit *viewscreen_unitlaborsst::getSelectedUnit()
@ -1314,6 +1398,11 @@ DFhackCExport command_result plugin_enable(color_ostream &out, bool enable)
DFhackCExport command_result plugin_init ( color_ostream &out, vector <PluginCommand> &commands) DFhackCExport command_result plugin_init ( color_ostream &out, vector <PluginCommand> &commands)
{ {
if (!Filesystem::isdir(CONFIG_PATH) && !Filesystem::mkdir(CONFIG_PATH))
{
out.printerr("manipulator: Could not create configuration folder: \"%s\"\n", CONFIG_PATH);
return CR_FAILURE;
}
return CR_OK; return CR_OK;
} }