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:
Mark de Wever 2008-04-17 16:39:47 +00:00
parent b857566f71
commit 479b1f5c5a
9 changed files with 214 additions and 5 deletions

View file

@ -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 = ""

View file

@ -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");

View file

@ -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();

View file

@ -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();
}
}

View file

@ -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

View file

@ -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_;
};

View file

@ -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";

View file

@ -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);
}

View file

@ -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);