From 17513283d4ba768d3bdfe7de69f8cf551f628e53 Mon Sep 17 00:00:00 2001 From: falconne Date: Sat, 13 Apr 2013 13:26:39 +1200 Subject: [PATCH] Better Stocks screen - WIP --- plugins/stocks.cpp | 180 +++++++++++++++++++++++++++++++++++++++++---- plugins/uicommon.h | 26 +++++-- 2 files changed, 186 insertions(+), 20 deletions(-) diff --git a/plugins/stocks.cpp b/plugins/stocks.cpp index 7f3826231..b6adf6827 100644 --- a/plugins/stocks.cpp +++ b/plugins/stocks.cpp @@ -9,12 +9,14 @@ #include "df/viewscreen_dwarfmodest.h" #include "df/items_other_id.h" #include "df/job.h" +#include "df/unit.h" #include "df/world.h" #include "modules/Gui.h" #include "modules/Items.h" #include "modules/Job.h" #include "modules/World.h" +#include "modules/Screen.h" using df::global::world; @@ -46,10 +48,10 @@ static void debug(const string &msg) };*/ - -class StockListColumn : public ListColumn +template +class StockListColumn : public ListColumn { - virtual void display_extras(const df::item *&item, int32_t &x, int32_t &y) const + virtual void display_extras(const T &item, int32_t &x, int32_t &y) const { if (item->flags.bits.in_job) OutputString(COLOR_LIGHTBLUE, x, y, "J"); @@ -61,11 +63,6 @@ class StockListColumn : public ListColumn else OutputString(COLOR_LIGHTBLUE, x, y, " "); - if (item->flags.bits.construction) - OutputString(COLOR_MAGENTA, x, y, "C"); - else - OutputString(COLOR_LIGHTBLUE, x, y, " "); - if (item->flags.bits.foreign) OutputString(COLOR_BROWN, x, y, "G"); else @@ -95,6 +92,11 @@ class StockListColumn : public ListColumn OutputString(COLOR_BLUE, x, y, "M"); else OutputString(COLOR_LIGHTBLUE, x, y, " "); + + if (item->flags.bits.in_inventory) + OutputString(COLOR_GREY, x, y, "I"); + else + OutputString(COLOR_LIGHTBLUE, x, y, " "); } }; @@ -107,11 +109,16 @@ public: selected_column = 0; items_column.setTitle("Item"); items_column.multiselect = false; + items_column.auto_select = true; items_column.allow_search = true; items_column.left_margin = 2; + items_column.bottom_margin = 1; + items_column.search_margin = gps->dimx - SIDEBAR_WIDTH; items_column.changeHighlight(0); + hide_flags.whole = 0; + populateItems(); items_column.selectDefaultEntry(); @@ -137,7 +144,68 @@ public: return; } - if (input->count(interface_key::CURSOR_LEFT)) + if (input->count(interface_key::CUSTOM_SHIFT_G)) + { + hide_flags.bits.foreign = !hide_flags.bits.foreign; + populateItems(); + } + else if (input->count(interface_key::CUSTOM_SHIFT_J)) + { + hide_flags.bits.in_job = !hide_flags.bits.in_job; + populateItems(); + } + else if (input->count(interface_key::CUSTOM_SHIFT_N)) + { + hide_flags.bits.rotten = !hide_flags.bits.rotten; + populateItems(); + } + else if (input->count(interface_key::CUSTOM_SHIFT_O)) + { + hide_flags.bits.owned = !hide_flags.bits.owned; + populateItems(); + } + else if (input->count(interface_key::CUSTOM_SHIFT_F)) + { + hide_flags.bits.forbid = !hide_flags.bits.forbid; + populateItems(); + } + else if (input->count(interface_key::CUSTOM_SHIFT_D)) + { + hide_flags.bits.dump = !hide_flags.bits.dump; + populateItems(); + } + else if (input->count(interface_key::CUSTOM_SHIFT_R)) + { + hide_flags.bits.on_fire = !hide_flags.bits.on_fire; + populateItems(); + } + else if (input->count(interface_key::CUSTOM_SHIFT_M)) + { + hide_flags.bits.melt = !hide_flags.bits.melt; + populateItems(); + } + else if (input->count(interface_key::CUSTOM_SHIFT_I)) + { + hide_flags.bits.in_inventory = !hide_flags.bits.in_inventory; + populateItems(); + } + + else if (input->count(interface_key::CUSTOM_SHIFT_Z)) + { + input->clear(); + auto item = items_column.getFirstSelectedElem(); + if (!item) + return; + auto pos = getRealPos(item); + if (!pos) + return; + + Screen::dismiss(this); + send_key(interface_key::D_LOOK); + move_cursor(*pos); + } + + else if (input->count(interface_key::CURSOR_LEFT)) { --selected_column; validateColumn(); @@ -156,6 +224,20 @@ public: } } + void move_cursor(df::coord &pos) + { + Gui::setCursorCoords(pos.x, pos.y, pos.z); + send_key(interface_key::CURSOR_DOWN_Z); + send_key(interface_key::CURSOR_UP_Z); + } + + void send_key(const df::interface_key &key) + { + set< df::interface_key > keys; + keys.insert(key); + Gui::getCurViewscreen(true)->feed(&keys); + } + void render() { if (Screen::isDismissed(this)) @@ -168,15 +250,73 @@ public: items_column.display(selected_column == 0); - int32_t y = gps->dimy - 3; - int32_t x = 2; + int32_t y = 1; + auto left_margin = gps->dimx - SIDEBAR_WIDTH; + int32_t x = left_margin - 2; + Screen::Pen border('\xDB', 8); + for (; y < gps->dimy - 1; y++) + { + paintTile(border, x, y); + } + + y = 2; + x = left_margin; + OutputString(COLOR_BROWN, x, y, "Filters", true, left_margin); + OutputString(COLOR_LIGHTRED, x, y, "Press Shift-Hotkey to Toggle", true, left_margin); + OutputFilterString(x, y, "In Job", "J", !hide_flags.bits.in_job, true, left_margin, COLOR_LIGHTBLUE); + OutputFilterString(x, y, "Rotten", "N", !hide_flags.bits.rotten, true, left_margin, COLOR_CYAN); + OutputFilterString(x, y, "Foreign Made", "G", !hide_flags.bits.foreign, true, left_margin, COLOR_BROWN); + OutputFilterString(x, y, "Owned", "O", !hide_flags.bits.owned, true, left_margin, COLOR_GREEN); + OutputFilterString(x, y, "Forbidden", "F", !hide_flags.bits.forbid, true, left_margin, COLOR_RED); + OutputFilterString(x, y, "Dump", "D", !hide_flags.bits.dump, true, left_margin, COLOR_LIGHTMAGENTA); + OutputFilterString(x, y, "On Fire", "R", !hide_flags.bits.on_fire, true, left_margin, COLOR_LIGHTRED); + OutputFilterString(x, y, "Melt", "M", !hide_flags.bits.melt, true, left_margin, COLOR_BLUE); + OutputFilterString(x, y, "In Inventory", "I", !hide_flags.bits.in_inventory, true, left_margin, COLOR_GREY); + + ++y; + OutputString(COLOR_BROWN, x, y, "Actions (" + int_to_string(items_column.getDisplayedListSize()) + " Items)", + true, left_margin); + OutputHotkeyString(x, y, "Zoom", "Shift-Z", true, left_margin); + } std::string getFocusString() { return "stocks_view"; } private: - StockListColumn items_column; + StockListColumn items_column; int selected_column; + df::item_flags hide_flags; + + df::coord *getRealPos(df::item *item) + { + if (item->flags.bits.in_inventory) + { + if (item->flags.bits.in_job) + { + auto ref = Items::getSpecificRef(item, specific_ref_type::JOB); + if (ref && ref->job) + { + if (ref->job->job_type == job_type::Eat || ref->job->job_type == job_type::Drink) + return nullptr; + + auto unit = Job::getWorker(ref->job); + if (unit) + return &unit->pos; + } + return nullptr; + } + else + { + auto unit = Items::getHolderUnit(item); + if (unit) + return &unit->pos; + + return nullptr; + } + } + + return &item->pos; + } void populateItems() { @@ -188,6 +328,12 @@ private: bad_flags.bits.trader = true; bad_flags.bits.in_building = true; bad_flags.bits.garbage_collect = true; + bad_flags.bits.spider_web = true; + bad_flags.bits.hostile = true; + bad_flags.bits.removed = true; + bad_flags.bits.dead_dwarf = true; + bad_flags.bits.murder = true; + bad_flags.bits.construction = true; std::vector &items = world->items.other[items_other_id::IN_PLAY]; @@ -195,10 +341,15 @@ private: { df::item *item = items[i]; - if (item->flags.whole & bad_flags.whole) + if (item->flags.whole & bad_flags.whole || item->flags.whole & hide_flags.whole) + continue; + + if (item->pos.x == -30000) + continue; + + if (!getRealPos(item)) continue; - df::item_type itype = item->getType(); auto label = pad_string(Items::getDescription(item, 0, true), MAX_NAME, false, true); items_column.add(label, item); @@ -216,6 +367,7 @@ private: { dfhack_viewscreen::resize(x, y); items_column.resize(); + items_column.search_margin = gps->dimx - SIDEBAR_WIDTH; } }; diff --git a/plugins/uicommon.h b/plugins/uicommon.h index 891ec15a0..c54e8b0ae 100644 --- a/plugins/uicommon.h +++ b/plugins/uicommon.h @@ -71,12 +71,21 @@ void OutputString(UIColor color, int &x, int &y, const std::string &text, x += text.length(); } -void OutputHotkeyString(int &x, int &y, const char *text, const char *hotkey, bool newline = false, int left_margin = 0, int8_t color = COLOR_WHITE) +void OutputHotkeyString(int &x, int &y, const char *text, const char *hotkey, bool newline = false, + int left_margin = 0, int8_t text_color = COLOR_WHITE, int8_t hotkey_color = COLOR_LIGHTGREEN) { - OutputString(10, x, y, hotkey); + OutputString(hotkey_color, x, y, hotkey); string display(": "); display.append(text); - OutputString(color, x, y, display, newline, left_margin); + OutputString(text_color, x, y, display, newline, left_margin); +} + +void OutputFilterString(int &x, int &y, const char *text, const char *hotkey, bool state, bool newline = false, + int left_margin = 0, int8_t hotkey_color = COLOR_LIGHTGREEN) +{ + OutputString(hotkey_color, x, y, hotkey); + OutputString(COLOR_WHITE, x, y, ": "); + OutputString((state) ? COLOR_WHITE : COLOR_GREY, x, y, text, newline, left_margin); } void OutputToggleString(int &x, int &y, const char *text, const char *hotkey, bool state, bool newline = true, int left_margin = 0, int8_t color = COLOR_WHITE) @@ -249,7 +258,7 @@ public: if (is_selected_column && allow_search) { - y = gps->dimy - bottom_margin; + y = gps->dimy - 3; int32_t x = search_margin; OutputHotkeyString(x, y, "Search" ,"S"); OutputString(COLOR_WHITE, x, y, ": "); @@ -265,13 +274,17 @@ public: search_string = toLower(search_string); for (size_t i = 0; i < list.size(); i++) { + ListEntry *entry = &list[i]; if (search_string.empty() || toLower(list[i].text).find(search_string) != string::npos) { - ListEntry *entry = &list[i]; display_list.push_back(entry); if (entry == prev_selected) highlighted_index = display_list.size() - 1; } + else if (auto_select) + { + entry->selected = false; + } } changeHighlight(0); feed_changed_highlight = true; @@ -459,7 +472,8 @@ public: { // Search query typing mode always on df::interface_key last_token = *input->rbegin(); - if (last_token >= interface_key::STRING_A096 && last_token <= interface_key::STRING_A123) + if ((last_token >= interface_key::STRING_A096 && last_token <= interface_key::STRING_A123) || + last_token == interface_key::STRING_A032) { // Standard character search_string += last_token - ascii_to_enum_offset;