Add a new framework to add a history to a ttext_box...
...and store it in the preferences. Saving to the preferences needs some more work (patch #1054).
This commit is contained in:
parent
b857566f71
commit
479b1f5c5a
9 changed files with 214 additions and 5 deletions
|
@ -95,6 +95,7 @@
|
|||
[text_box]
|
||||
id = "host_name"
|
||||
definition = "default"
|
||||
history = "addon_connect_history"
|
||||
|
||||
size_text = _ "very long text which might need to fit"
|
||||
label = ""
|
||||
|
|
|
@ -51,6 +51,9 @@ std::vector<std::string> search_history_vector;
|
|||
std::vector<std::string> chat_history_vector;
|
||||
std::vector<std::string> command_history_vector;
|
||||
|
||||
std::map<std::string, std::vector<std::string> > history_map;
|
||||
const unsigned max_history_saved = 50;
|
||||
|
||||
//! Add a nick to the specified relation setting.
|
||||
void add_relation(const std::string nick, const std::string relation) {
|
||||
std::vector<std::string> r = utils::split(preferences::get(relation));
|
||||
|
@ -91,6 +94,19 @@ manager::manager()
|
|||
std::copy(terrain.begin(), terrain.end(),
|
||||
std::inserter(encountered_terrains_set, encountered_terrains_set.begin()));
|
||||
|
||||
config* history = preferences::get_child("history");
|
||||
if (history) {
|
||||
const string_map& history_strings = history->values;
|
||||
for (string_map::const_iterator iter = history_strings.begin(); iter != history_strings.end(); ++iter) {
|
||||
std::vector<std::string> current_history = utils::paranthetical_split(iter->second.value(), ',', "(", ")");
|
||||
std::vector<std::string>* history_ptr = get_history(iter->first);
|
||||
for (std::vector<std::string>::iterator i = current_history.begin(); i != current_history.end(); ++i) {
|
||||
// remove the enclosing parens
|
||||
history_ptr->push_back(i->substr(1, i->size() - 2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
network::ping_timeout = get_ping_timeout();
|
||||
}
|
||||
|
||||
|
@ -104,6 +120,23 @@ manager::~manager()
|
|||
std::back_inserter(terrain));
|
||||
preferences::set("encountered_terrain_list", t_translation::write_list(terrain));
|
||||
|
||||
config history;
|
||||
std::map<std::string, std::vector<std::string> >::iterator iter;
|
||||
for (iter = history_map.begin(); iter != history_map.end(); ++iter) {
|
||||
std::stringstream history_stream;
|
||||
std::vector<std::string>::iterator i;
|
||||
for (i = iter->second.size() < max_history_saved ? iter->second.begin(): iter->second.end() - max_history_saved; i != iter->second.end(); ++i) {
|
||||
history_stream << "(" << *i << ")";
|
||||
if (i + 1 != iter->second.end()) {
|
||||
history_stream << ",";
|
||||
}
|
||||
}
|
||||
history[iter->first] = history_stream.str();
|
||||
}
|
||||
|
||||
preferences::set_child("history", history);
|
||||
|
||||
history_map.clear();
|
||||
encountered_units_set.clear();
|
||||
encountered_terrains_set.clear();
|
||||
set_ping_timeout(network::ping_timeout);
|
||||
|
@ -692,6 +725,26 @@ std::vector<std::string> &command_history() {
|
|||
return command_history_vector;
|
||||
}
|
||||
|
||||
|
||||
//! Returns a pointer to the history vector associated with given id
|
||||
//! making a new one if it doesn't exist.
|
||||
// FIXME only used for gui2. Could be used for the above histories.
|
||||
std::vector<std::string>* get_history(const std::string& id) {
|
||||
std::map<std::string, std::vector<std::string> >::iterator iter;
|
||||
iter = history_map.find(id);
|
||||
|
||||
if (iter != history_map.end()) {
|
||||
// a history with this id exists, so return it
|
||||
return &iter->second;
|
||||
} else {
|
||||
// no history matches this id, so make a new one
|
||||
std::pair<std::map<std::string, std::vector<std::string> >::iterator, bool> res;
|
||||
res = history_map.insert(std::pair<std::string, std::vector<std::string> >(id, std::vector<std::string>()));
|
||||
|
||||
return &res.first->second;
|
||||
}
|
||||
}
|
||||
|
||||
bool green_confirm()
|
||||
{
|
||||
std::string confirmation = preferences::get("confirm_end_turn");
|
||||
|
|
|
@ -188,6 +188,8 @@ namespace preferences {
|
|||
std::vector<std::string> &chat_history();
|
||||
std::vector<std::string> &command_history();
|
||||
|
||||
std::vector<std::string>* get_history(const std::string& id);
|
||||
|
||||
std::string client_type();
|
||||
|
||||
std::string clock_format();
|
||||
|
|
|
@ -45,6 +45,9 @@ void taddon_connect::show(CVideo& video)
|
|||
retval_ = window.show(true);
|
||||
|
||||
if(host_widget) {
|
||||
if(retval_ == tbutton::OK) {
|
||||
host_widget->save_to_history();
|
||||
}
|
||||
host_name_= host_widget->get_text();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
#include "foreach.hpp"
|
||||
#include "log.hpp"
|
||||
#include "serialization/string_utils.hpp"
|
||||
#include "game_preferences.hpp"
|
||||
|
||||
#include <numeric>
|
||||
|
||||
|
@ -451,6 +452,87 @@ void ttext_box::load_config()
|
|||
}
|
||||
}
|
||||
|
||||
void ttext_box::handle_key_up_arrow(SDLMod modifier, bool& handled)
|
||||
{
|
||||
if (history_.get_enabled()) {
|
||||
std::string s = history_.up(text());
|
||||
if (!s.empty()) {
|
||||
set_text(s);
|
||||
}
|
||||
|
||||
handled = true;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void ttext_box::handle_key_down_arrow(SDLMod modifier, bool& handled)
|
||||
{
|
||||
if (history_.get_enabled()) {
|
||||
set_text(history_.down(text()));
|
||||
handled = true;
|
||||
}
|
||||
}
|
||||
|
||||
ttext_history ttext_history::get_history(const std::string& id, const bool enabled)
|
||||
{
|
||||
std::vector<std::string>* vec = preferences::get_history(id);
|
||||
return ttext_history(vec, enabled);
|
||||
}
|
||||
|
||||
void ttext_history::push(const std::string& text)
|
||||
{
|
||||
if (!enabled_) {
|
||||
return;
|
||||
} else {
|
||||
if (!text.empty() && (history_->empty() || text != history_->back())) {
|
||||
history_->push_back(text);
|
||||
}
|
||||
|
||||
pos_ = history_->size();
|
||||
}
|
||||
}
|
||||
|
||||
std::string ttext_history::up(const std::string& text)
|
||||
{
|
||||
|
||||
if (!enabled_) {
|
||||
return "";
|
||||
} else if (pos_ == history_->size()) {
|
||||
unsigned curr = pos_;
|
||||
push(text);
|
||||
pos_ = curr;
|
||||
}
|
||||
|
||||
if (pos_ != 0) {
|
||||
--pos_;
|
||||
}
|
||||
|
||||
return get_value();
|
||||
}
|
||||
|
||||
// Will push text to history if it is pointing at the end of the vector.
|
||||
std::string ttext_history::down(const std::string& text)
|
||||
{
|
||||
if (!enabled_) {
|
||||
return "";
|
||||
} else if (pos_ == history_->size()) {
|
||||
push(text);
|
||||
} else {
|
||||
pos_++;
|
||||
}
|
||||
|
||||
return get_value();
|
||||
}
|
||||
|
||||
std::string ttext_history::get_value() const
|
||||
{
|
||||
if (!enabled_ || pos_ == history_->size()) {
|
||||
return "";
|
||||
} else {
|
||||
return history_->at(pos_);
|
||||
}
|
||||
}
|
||||
|
||||
} //namespace gui2
|
||||
|
||||
|
||||
|
|
|
@ -156,6 +156,48 @@ private:
|
|||
virtual void handle_key_page_down(SDLMod modifier, bool& handled) {}
|
||||
};
|
||||
|
||||
//! Class for text input history
|
||||
class ttext_history
|
||||
{
|
||||
public:
|
||||
//! Gets history that matches id and enables or disables it.
|
||||
static ttext_history get_history(const std::string& id, const bool enabled);
|
||||
|
||||
// Defaults to a disabled history
|
||||
ttext_history() :
|
||||
history_(0),
|
||||
pos_(0),
|
||||
enabled_(false)
|
||||
{}
|
||||
|
||||
//! Push string into the history if it is non-empty and is not the same as the last item
|
||||
//! updates position to end of history.
|
||||
void push(const std::string& text);
|
||||
|
||||
//! One step up/down in history. Pushes text to the history if at the end.
|
||||
std::string up(const std::string& text = "");
|
||||
std::string down(const std::string& text = "");
|
||||
|
||||
//! Returns the value at the current history position. Returns "" if not enabled
|
||||
//! or if at the end of the history.
|
||||
std::string get_value() const;
|
||||
|
||||
void set_enabled(bool enabled = true) { enabled_ = enabled; }
|
||||
bool get_enabled() const { return enabled_; }
|
||||
|
||||
private:
|
||||
ttext_history(std::vector<std::string>* history, const bool enabled) :
|
||||
history_(history),
|
||||
pos_(history->size()),
|
||||
enabled_(enabled)
|
||||
{}
|
||||
|
||||
std::vector<std::string>* history_;
|
||||
unsigned pos_;
|
||||
|
||||
bool enabled_;
|
||||
};
|
||||
|
||||
//! Class for a single line text area.
|
||||
class ttext_box : public ttext_
|
||||
{
|
||||
|
@ -164,9 +206,15 @@ public:
|
|||
|
||||
ttext_box() :
|
||||
ttext_(),
|
||||
character_offset_()
|
||||
character_offset_(),
|
||||
history_()
|
||||
{}
|
||||
|
||||
void set_history(const std::string& id)
|
||||
{ history_ = ttext_history::get_history(id, true); }
|
||||
|
||||
void save_to_history() { history_.push(text()); }
|
||||
void save_to_history(const std::string& text) { history_.push(text); }
|
||||
|
||||
protected:
|
||||
|
||||
|
@ -198,8 +246,8 @@ protected:
|
|||
|
||||
private:
|
||||
|
||||
void handle_key_up_arrow(SDLMod modifier, bool& handled) {};
|
||||
void handle_key_down_arrow(SDLMod modifier, bool& handled) {};
|
||||
void handle_key_up_arrow(SDLMod modifier, bool& handled);
|
||||
void handle_key_down_arrow(SDLMod modifier, bool& handled);
|
||||
|
||||
// Clears the current line
|
||||
void handle_key_clear_line(SDLMod modifier, bool& handled);
|
||||
|
@ -209,6 +257,8 @@ private:
|
|||
|
||||
//! Inherited from ttext_.
|
||||
void calculate_char_offset();
|
||||
|
||||
ttext_history history_;
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -97,12 +97,14 @@ public:
|
|||
|
||||
struct tbuilder_text_box : public tbuilder_control
|
||||
{
|
||||
|
||||
private:
|
||||
tbuilder_text_box();
|
||||
std::string history_;
|
||||
|
||||
public:
|
||||
tbuilder_text_box(const config& cfg) :
|
||||
tbuilder_control(cfg)
|
||||
tbuilder_control(cfg),
|
||||
history_(cfg["history"])
|
||||
{}
|
||||
|
||||
twidget* build () const;
|
||||
|
@ -434,6 +436,10 @@ twidget* tbuilder_text_box::build() const
|
|||
// A textbox doesn't have a label but a text
|
||||
text_box->set_text(label);
|
||||
|
||||
if (!history_.empty()) {
|
||||
text_box->set_history(history_);
|
||||
}
|
||||
|
||||
DBG_G << "Window builder: placed text box '" << id << "' with defintion '"
|
||||
<< definition << "'.\n";
|
||||
|
||||
|
|
|
@ -78,6 +78,16 @@ void set(const std::string key, std::string value) {
|
|||
prefs[key] = value;
|
||||
}
|
||||
|
||||
void set_child(const std::string& key, const config& val) {
|
||||
prefs.clear_children(key);
|
||||
prefs.add_child(key, val);
|
||||
}
|
||||
|
||||
config* get_child(const std::string& key)
|
||||
{
|
||||
return prefs.child(key);
|
||||
}
|
||||
|
||||
void erase(const std::string key) {
|
||||
prefs.values.erase(key);
|
||||
}
|
||||
|
|
|
@ -53,6 +53,8 @@ namespace preferences {
|
|||
|
||||
// Low-level, should be seen only by preferences_display ?
|
||||
void set(const std::string key, std::string value);
|
||||
void set_child(const std::string& key, const config& val);
|
||||
config* get_child(const std::string& key);
|
||||
const std::string get(const std::string key);
|
||||
void erase(const std::string key);
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue