|
|
|
@ -12,11 +12,13 @@
|
|
|
|
|
#include <set>
|
|
|
|
|
#include <list>
|
|
|
|
|
#include <utility>
|
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
|
|
#include "df/interface_key.h"
|
|
|
|
|
#include "df/ui.h"
|
|
|
|
|
#include "df/graphic.h"
|
|
|
|
|
#include "df/enabler.h"
|
|
|
|
|
|
|
|
|
|
using namespace DFHack;
|
|
|
|
|
using namespace df::enums;
|
|
|
|
|
|
|
|
|
@ -24,6 +26,8 @@ using df::global::ui;
|
|
|
|
|
using df::global::gps;
|
|
|
|
|
using df::global::enabler;
|
|
|
|
|
|
|
|
|
|
std::vector<std::string> command_history;
|
|
|
|
|
|
|
|
|
|
class viewscreen_commandpromptst;
|
|
|
|
|
class prompt_ostream:public buffered_color_ostream
|
|
|
|
|
{
|
|
|
|
@ -44,12 +48,25 @@ public:
|
|
|
|
|
|
|
|
|
|
void render();
|
|
|
|
|
void help() { }
|
|
|
|
|
int8_t movies_okay() { return 0; }
|
|
|
|
|
|
|
|
|
|
std::string getFocusString() { return "commandprompt"; }
|
|
|
|
|
viewscreen_commandpromptst(std::string entry):is_response(false),entry(entry)
|
|
|
|
|
viewscreen_commandpromptst(std::string entry):is_response(false)
|
|
|
|
|
{
|
|
|
|
|
show_fps=df::global::gps->display_frames;
|
|
|
|
|
df::global::gps->display_frames=0;
|
|
|
|
|
cursor_pos = 0;
|
|
|
|
|
frame = 0;
|
|
|
|
|
history_idx = command_history.size();
|
|
|
|
|
if (history_idx > 0)
|
|
|
|
|
{
|
|
|
|
|
if (command_history[history_idx - 1] == "")
|
|
|
|
|
{
|
|
|
|
|
command_history.pop_back();
|
|
|
|
|
history_idx--;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
command_history.push_back(entry);
|
|
|
|
|
}
|
|
|
|
|
~viewscreen_commandpromptst()
|
|
|
|
|
{
|
|
|
|
@ -65,12 +82,50 @@ public:
|
|
|
|
|
responses.push_back(std::make_pair(v, part + '\n'));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
std::string get_entry()
|
|
|
|
|
{
|
|
|
|
|
return command_history[history_idx];
|
|
|
|
|
}
|
|
|
|
|
void set_entry(std::string entry)
|
|
|
|
|
{
|
|
|
|
|
command_history[history_idx] = entry;
|
|
|
|
|
}
|
|
|
|
|
void back_word()
|
|
|
|
|
{
|
|
|
|
|
std::string entry = get_entry();
|
|
|
|
|
if (cursor_pos == 0)
|
|
|
|
|
return;
|
|
|
|
|
cursor_pos--;
|
|
|
|
|
while (cursor_pos > 0 && !isalnum(entry[cursor_pos]))
|
|
|
|
|
cursor_pos--;
|
|
|
|
|
while (cursor_pos > 0 && isalnum(entry[cursor_pos]))
|
|
|
|
|
cursor_pos--;
|
|
|
|
|
if (!isalnum(entry[cursor_pos]) && cursor_pos != 0)
|
|
|
|
|
cursor_pos++;
|
|
|
|
|
}
|
|
|
|
|
void forward_word()
|
|
|
|
|
{
|
|
|
|
|
std::string entry = get_entry();
|
|
|
|
|
int len = entry.size();
|
|
|
|
|
if (cursor_pos == len)
|
|
|
|
|
return;
|
|
|
|
|
cursor_pos++;
|
|
|
|
|
while (cursor_pos <= len && !isalnum(entry[cursor_pos]))
|
|
|
|
|
cursor_pos++;
|
|
|
|
|
while (cursor_pos <= len && isalnum(entry[cursor_pos]))
|
|
|
|
|
cursor_pos++;
|
|
|
|
|
if (cursor_pos > len)
|
|
|
|
|
cursor_pos = len;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
protected:
|
|
|
|
|
std::list<std::pair<color_value,std::string> > responses;
|
|
|
|
|
int cursor_pos;
|
|
|
|
|
int history_idx;
|
|
|
|
|
bool is_response;
|
|
|
|
|
bool show_fps;
|
|
|
|
|
int frame;
|
|
|
|
|
void submit();
|
|
|
|
|
std::string entry;
|
|
|
|
|
};
|
|
|
|
|
void prompt_ostream::flush_proxy()
|
|
|
|
|
{
|
|
|
|
@ -82,6 +137,9 @@ void prompt_ostream::flush_proxy()
|
|
|
|
|
}
|
|
|
|
|
void viewscreen_commandpromptst::render()
|
|
|
|
|
{
|
|
|
|
|
++frame;
|
|
|
|
|
if (frame >= df::global::enabler->gfps)
|
|
|
|
|
frame = 0;
|
|
|
|
|
if (Screen::isDismissed(this))
|
|
|
|
|
return;
|
|
|
|
|
|
|
|
|
@ -101,14 +159,25 @@ void viewscreen_commandpromptst::render()
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
std::string entry = get_entry();
|
|
|
|
|
Screen::fillRect(Screen::Pen(' ', 7, 0),0,0,dim.x,0);
|
|
|
|
|
Screen::paintString(Screen::Pen(' ', 7, 0), 0, 0,"[DFHack]#");
|
|
|
|
|
if(entry.size()<dim.x)
|
|
|
|
|
std::string cursor = (frame < df::global::enabler->gfps / 2) ? "_" : " ";
|
|
|
|
|
if(cursor_pos < (dim.x - 10))
|
|
|
|
|
{
|
|
|
|
|
Screen::paintString(Screen::Pen(' ', 7, 0), 10,0 , entry);
|
|
|
|
|
if (entry.size() > dim.x - 10)
|
|
|
|
|
Screen::paintTile(Screen::Pen('\032', 7, 0), dim.x - 1, 0);
|
|
|
|
|
if (cursor != " ")
|
|
|
|
|
Screen::paintString(Screen::Pen(' ', 10, 0), 10 + cursor_pos, 0, cursor);
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
Screen::paintTile(Screen::Pen('>', 7, 0), 9, 0);
|
|
|
|
|
Screen::paintString(Screen::Pen(' ', 7, 0), 10, 0, entry.substr(entry.size()-dim.x));
|
|
|
|
|
size_t start = cursor_pos - dim.x + 10 + 1;
|
|
|
|
|
Screen::paintTile(Screen::Pen('\033', 7, 0), 9, 0);
|
|
|
|
|
Screen::paintString(Screen::Pen(' ', 7, 0), 10, 0, entry.substr(start));
|
|
|
|
|
if (cursor != " ")
|
|
|
|
|
Screen::paintString(Screen::Pen(' ', 10, 0), dim.x - 1, 0, cursor);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -120,9 +189,8 @@ void viewscreen_commandpromptst::submit()
|
|
|
|
|
Screen::dismiss(this);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
//color_ostream_proxy out(Core::getInstance().getConsole());
|
|
|
|
|
prompt_ostream out(this);
|
|
|
|
|
Core::getInstance().runCommand(out, entry);
|
|
|
|
|
Core::getInstance().runCommand(out, get_entry());
|
|
|
|
|
if(out.empty() && responses.empty())
|
|
|
|
|
Screen::dismiss(this);
|
|
|
|
|
else
|
|
|
|
@ -132,7 +200,8 @@ void viewscreen_commandpromptst::submit()
|
|
|
|
|
}
|
|
|
|
|
void viewscreen_commandpromptst::feed(std::set<df::interface_key> *events)
|
|
|
|
|
{
|
|
|
|
|
|
|
|
|
|
int old_pos = cursor_pos;
|
|
|
|
|
std::string entry = get_entry();
|
|
|
|
|
bool leave_all = events->count(interface_key::LEAVESCREEN_ALL);
|
|
|
|
|
if (leave_all || events->count(interface_key::LEAVESCREEN))
|
|
|
|
|
{
|
|
|
|
@ -144,30 +213,91 @@ void viewscreen_commandpromptst::feed(std::set<df::interface_key> *events)
|
|
|
|
|
parent->feed(events);
|
|
|
|
|
events->clear();
|
|
|
|
|
}
|
|
|
|
|
//if (command_history.size() && !entry.size())
|
|
|
|
|
// command_history.pop_back();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if(events->count(interface_key::SELECT))
|
|
|
|
|
if (events->count(interface_key::SELECT))
|
|
|
|
|
{
|
|
|
|
|
submit();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if(is_response)
|
|
|
|
|
if (is_response)
|
|
|
|
|
return;
|
|
|
|
|
for (auto it = events->begin(); it != events->end(); ++it)
|
|
|
|
|
{
|
|
|
|
|
auto key = *it;
|
|
|
|
|
if (key==interface_key::STRING_A000) //delete?
|
|
|
|
|
{
|
|
|
|
|
if(entry.size())
|
|
|
|
|
entry.resize(entry.size()-1);
|
|
|
|
|
if(entry.size() && cursor_pos > 0)
|
|
|
|
|
{
|
|
|
|
|
entry.erase(cursor_pos - 1, 1);
|
|
|
|
|
cursor_pos--;
|
|
|
|
|
}
|
|
|
|
|
if(cursor_pos > entry.size())
|
|
|
|
|
cursor_pos = entry.size();
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
if (key >= interface_key::STRING_A000 &&
|
|
|
|
|
key <= interface_key::STRING_A255)
|
|
|
|
|
{
|
|
|
|
|
entry.push_back(char(key - interface_key::STRING_A000));
|
|
|
|
|
entry.insert(cursor_pos, 1, char(key - interface_key::STRING_A000));
|
|
|
|
|
cursor_pos++;
|
|
|
|
|
set_entry(entry);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
// Prevent number keys from moving cursor
|
|
|
|
|
if(events->count(interface_key::CURSOR_RIGHT))
|
|
|
|
|
{
|
|
|
|
|
cursor_pos++;
|
|
|
|
|
if (cursor_pos > entry.size())
|
|
|
|
|
cursor_pos = entry.size();
|
|
|
|
|
}
|
|
|
|
|
else if(events->count(interface_key::CURSOR_LEFT))
|
|
|
|
|
{
|
|
|
|
|
cursor_pos--;
|
|
|
|
|
if (cursor_pos < 0) cursor_pos = 0;
|
|
|
|
|
}
|
|
|
|
|
else if(events->count(interface_key::CURSOR_RIGHT_FAST))
|
|
|
|
|
{
|
|
|
|
|
forward_word();
|
|
|
|
|
}
|
|
|
|
|
else if(events->count(interface_key::CURSOR_LEFT_FAST))
|
|
|
|
|
{
|
|
|
|
|
back_word();
|
|
|
|
|
}
|
|
|
|
|
else if(events->count(interface_key::CUSTOM_CTRL_A))
|
|
|
|
|
{
|
|
|
|
|
cursor_pos = 0;
|
|
|
|
|
}
|
|
|
|
|
else if(events->count(interface_key::CUSTOM_CTRL_E))
|
|
|
|
|
{
|
|
|
|
|
cursor_pos = entry.size();
|
|
|
|
|
}
|
|
|
|
|
else if(events->count(interface_key::CURSOR_UP))
|
|
|
|
|
{
|
|
|
|
|
history_idx--;
|
|
|
|
|
if (history_idx < 0)
|
|
|
|
|
history_idx = 0;
|
|
|
|
|
entry = get_entry();
|
|
|
|
|
cursor_pos = entry.size();
|
|
|
|
|
}
|
|
|
|
|
else if(events->count(interface_key::CURSOR_DOWN))
|
|
|
|
|
{
|
|
|
|
|
if (history_idx < command_history.size() - 1)
|
|
|
|
|
{
|
|
|
|
|
history_idx++;
|
|
|
|
|
if (history_idx >= command_history.size())
|
|
|
|
|
history_idx = command_history.size() - 1;
|
|
|
|
|
entry = get_entry();
|
|
|
|
|
cursor_pos = entry.size();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
set_entry(entry);
|
|
|
|
|
if (old_pos != cursor_pos)
|
|
|
|
|
frame = 0;
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
DFHACK_PLUGIN("command-prompt");
|
|
|
|
|
command_result show_prompt(color_ostream &out, std::vector <std::string> & parameters)
|
|
|
|
|