wesnoth-cvs-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Wesnoth-cvs-commits] wesnoth/src multiplayer_lobby.cpp multiplayer_l...


From: Jon Daniel
Subject: [Wesnoth-cvs-commits] wesnoth/src multiplayer_lobby.cpp multiplayer_l...
Date: Tue, 13 Sep 2005 09:36:28 -0400

CVSROOT:        /cvsroot/wesnoth
Module name:    wesnoth
Branch:         
Changes by:     Jon Daniel <address@hidden>     05/09/13 13:36:27

Modified files:
        src            : multiplayer_lobby.cpp multiplayer_lobby.hpp 

Log message:
        Added a new gamebrowser widget. This should work as expected but it 
doesn't support sorting right now.
        Also the map_info isn't field of the games is not filled and it may not 
be drawn at the correct position at all

CVSWeb URLs:
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/multiplayer_lobby.cpp.diff?tr1=1.86&tr2=1.87&r1=text&r2=text
http://savannah.gnu.org/cgi-bin/viewcvs/wesnoth/wesnoth/src/multiplayer_lobby.hpp.diff?tr1=1.15&tr2=1.16&r1=text&r2=text

Patches:
Index: wesnoth/src/multiplayer_lobby.cpp
diff -u wesnoth/src/multiplayer_lobby.cpp:1.86 
wesnoth/src/multiplayer_lobby.cpp:1.87
--- wesnoth/src/multiplayer_lobby.cpp:1.86      Tue Sep  6 13:53:14 2005
+++ wesnoth/src/multiplayer_lobby.cpp   Tue Sep 13 13:36:24 2005
@@ -1,4 +1,4 @@
-/* $Id: multiplayer_lobby.cpp,v 1.86 2005/09/06 13:53:14 ott Exp $ */
+/* $Id: multiplayer_lobby.cpp,v 1.87 2005/09/13 13:36:24 j_daniel Exp $ */
 /*
    Copyright (C)
    Part of the Battle for Wesnoth Project http://www.wesnoth.org
@@ -34,6 +34,307 @@
 }
 
 namespace mp {
+gamebrowser::gamebrowser(CVideo& video) : scrollarea(video),
+       gold_icon_locator_("misc/gold.png"),
+       xp_icon_locator_("misc/units.png"),
+       vision_icon_locator_("misc/invisible.png"),
+       observer_icon_locator_("misc/eye.png"), header_height_(20),
+       item_height_(100), margin_(5), h_padding_(5),
+       v_padding_(5), selected_(0), 
visible_range_(std::pair<size_t,size_t>(0,0)),
+       double_clicked_(false), ignore_next_doubleclick_(false), 
last_was_doubleclick_(false)
+{
+}
+
+void gamebrowser::set_inner_location(const SDL_Rect& rect)
+{
+       set_full_size(games_.size());
+       set_shown_size(rect.h / item_height_);
+       bg_register(rect);
+       scroll(get_position());
+}
+
+void gamebrowser::scroll(int pos)
+{
+       if(pos >= 0 && pos < games_.size()) {
+               visible_range_.first = pos;
+               visible_range_.second = minimum<size_t>(pos + 
inner_location().h / item_height_, games_.size());
+               set_dirty();
+       }
+}
+
+SDL_Rect gamebrowser::get_item_rect(size_t index) const {
+       if(index < visible_range_.first || index > visible_range_.second) {
+               const SDL_Rect res = { 0, 0, 0, 0 };
+               return res;
+       }
+       const SDL_Rect& loc = inner_location();
+       const SDL_Rect res = { loc.x, loc.y + (index - visible_range_.first) * 
item_height_, loc.w, item_height_ };
+       return res;
+}
+
+void gamebrowser::draw()
+{
+       if(hidden())
+               return;
+       if(dirty()) {
+               bg_restore();
+               util::scoped_ptr<clip_rect_setter> clipper(NULL);
+               if(clip_rect())
+                       clipper.assign(new 
clip_rect_setter(video().getSurface(), *clip_rect()));
+               draw_contents();
+               update_rect(location());
+               set_dirty(false);
+       }
+}
+
+void gamebrowser::draw_contents() const
+{
+       if(!games_.empty()) {
+               for(size_t i = visible_range_.first; i != 
visible_range_.second; ++i) {
+                       draw_item(i);
+               }
+       } else {
+               const SDL_Rect rect = inner_location();
+               font::draw_text(&video(), rect, font::SIZE_NORMAL, 
font::NORMAL_COLOUR, _("<no games open>"), rect.x + margin_, rect.y + margin_);
+       }
+}
+
+void gamebrowser::draw_item(size_t index) const {
+       const game_item& game = games_[index];
+       SDL_Rect item_rect = get_item_rect(index);
+       int xpos = item_rect.x + margin_;
+       int ypos = item_rect.y + margin_;
+
+       bg_restore(item_rect);
+       draw_solid_tinted_rectangle(item_rect.x, item_rect.y, item_rect.w, 
item_rect.h, 0, 0, 0, 0.2, video().getSurface());
+
+       // draw mini map
+       video().blit_surface(xpos, ypos, game.mini_map);
+
+       xpos += item_height_ + margin_;
+
+       const surface 
name_surf(font::get_rendered_text(font::make_text_ellipsis(game.name, 
font::SIZE_NORMAL, item_rect.w - xpos - margin_), font::SIZE_PLUS, 
game.vacant_slots > 0 ? font::GOOD_COLOUR : game.observers ? 
font::NORMAL_COLOUR : font::BAD_COLOUR));
+       video().blit_surface(xpos, ypos, name_surf);
+
+       ypos += v_padding_;
+
+       // draw map info
+       const surface 
map_info_surf(font::get_rendered_text(font::make_text_ellipsis(game.map_info, 
font::SIZE_NORMAL, item_rect.w - xpos - margin_), font::SIZE_PLUS, 
font::GOOD_COLOUR));
+       video().blit_surface(xpos, ypos, map_info_surf);
+
+
+       // draw gold icon
+       const surface gold_icon(image::get_image(gold_icon_locator_, 
image::UNSCALED)); 
+       ypos = item_rect.y + item_rect.h  - margin_ - gold_icon->h;
+       
+       video().blit_surface(xpos, ypos, gold_icon);
+
+       xpos += gold_icon->w + h_padding_;
+
+       // draw gold text
+       const surface gold_text(font::get_rendered_text(game.gold, 
font::SIZE_NORMAL, font::NORMAL_COLOUR));
+       ypos -= abs(gold_icon->h - gold_text->h) / 2;
+       video().blit_surface(xpos, ypos, gold_text);
+
+       xpos += gold_text->w + 2 * h_padding_;
+
+       // draw xp icon
+       const surface xp_icon(image::get_image(xp_icon_locator_, 
image::UNSCALED));
+       ypos = item_rect.y + item_rect.h  - margin_ - xp_icon->h;
+       video().blit_surface(xpos, ypos, xp_icon);
+
+       xpos += xp_icon->w + h_padding_;
+
+       // draw xp text
+       const surface xp_text(font::get_rendered_text(game.xp, 
font::SIZE_NORMAL, font::NORMAL_COLOUR));
+       ypos -= abs(xp_icon->h - xp_text->h) / 2;
+       video().blit_surface(xpos, ypos, xp_text);
+
+       xpos += xp_text->w + 2 * h_padding_;
+
+       // draw vision icon
+       const surface vision_icon(image::get_image(vision_icon_locator_, 
image::UNSCALED));
+       video().blit_surface(xpos, ypos, vision_icon);
+
+       xpos += vision_icon->w + h_padding_;
+
+       const surface status_text(font::get_rendered_text(game.status, 
font::SIZE_NORMAL, game.vacant_slots > 0 ? font::GOOD_COLOUR : 
font::NORMAL_COLOUR));
+       const surface 
vision_text(font::get_rendered_text(font::make_text_ellipsis(game.vision, 
font::SIZE_NORMAL, maximum<int>((item_rect.x + item_rect.w - margin_ - 
status_text->w - 2 * h_padding_) - xpos, 0)),font::SIZE_NORMAL, 
font::NORMAL_COLOUR));
+       // draw vision text
+       video().blit_surface(xpos, ypos, vision_text);
+
+       // draw status text
+       xpos = item_rect.x + item_rect.w - margin_ - status_text->w;
+       video().blit_surface(xpos, ypos, status_text);
+       
+       if(selected_ == index)
+               draw_solid_tinted_rectangle(item_rect.x, item_rect.y, 
item_rect.w, item_rect.h, 153, 0, 0, 0.3, video().getSurface());
+}
+
+void gamebrowser::handle_event(const SDL_Event& event)
+{
+       scrollarea::handle_event(event);
+       if(event.type == SDL_KEYDOWN) {
+               if(focus() && !games_.empty()) {
+                       switch(event.key.keysym.sym) {
+                               case SDLK_UP:
+                                       if(selected_ > 0) {
+                                               --selected_;
+                                               adjust_position(selected_);
+                                               set_dirty();
+                                       }
+                                       break;
+                               case SDLK_DOWN:
+                                       if(selected_ < games_.size() - 1) {
+                                               ++selected_;
+                                               adjust_position(selected_);
+                                               set_dirty();
+                                       }
+                                       break;
+                               case SDLK_PAGEUP:
+                               {
+                                       const long items_on_screen = 
visible_range_.second - visible_range_.first;
+                                       selected_ = 
static_cast<size_t>(maximum<long>(static_cast<long>(selected_) - 
items_on_screen, 0));
+                                       adjust_position(selected_);
+                                       set_dirty();
+                               }
+                                       break;
+                               case SDLK_PAGEDOWN:
+                               {
+                                       const size_t items_on_screen = 
visible_range_.second - visible_range_.first;
+                                       selected_ = minimum<size_t>(selected_ + 
items_on_screen, games_.size() - 1);
+                                       adjust_position(selected_);
+                                       set_dirty();
+                               }
+                                       break;
+                               case SDLK_HOME:
+                                       selected_ = 0;
+                                       adjust_position(selected_);
+                                       set_dirty();
+                                       break;
+                               case SDLK_END:
+                                       selected_ = games_.size() - 1;
+                                       adjust_position(selected_);
+                                       set_dirty();
+                                       break;
+                               default:
+                                       break;
+                       }
+               }
+       } else if(event.type == SDL_MOUSEBUTTONDOWN && event.button.button == 
SDL_BUTTON_LEFT || event.type == DOUBLE_CLICK_EVENT) {
+               int x = 0;
+               int y = 0;
+               if(event.type == SDL_MOUSEBUTTONDOWN) {
+                       x = event.button.x;
+                       y = event.button.y;
+               } else {
+                       x = (long)event.user.data1;
+                       y = (long)event.user.data2;
+               }
+               const SDL_Rect& loc = inner_location();
+
+               if(!games_.empty() && point_in_rect(x, y, loc)) {
+                       for(size_t i = visible_range_.first; i != 
visible_range_.second; ++i) {
+                               const SDL_Rect& item_rect = get_item_rect(i);
+
+                               if(point_in_rect(x, y, item_rect)) {
+                                       set_focus(true);
+                                       set_dirty();
+                                       selected_ = i;
+                                       break;
+                               }
+                       }
+                       if(event.type == DOUBLE_CLICK_EVENT) {
+                               if (ignore_next_doubleclick_) {
+                                       ignore_next_doubleclick_ = false;
+                               } else if(selection_is_joinable() || 
selection_is_observable()) {
+                                       double_clicked_ = true;
+                                       last_was_doubleclick_ = true;
+                               }
+                       } else if (last_was_doubleclick_) {
+                               // If we have a double click as the next event, 
it means
+                               // this double click was generated from a click 
that
+                               // already has helped in generating a double 
click.
+                               SDL_Event ev;
+                               SDL_PeepEvents(&ev, 1, SDL_PEEKEVENT,
+                                                          
SDL_EVENTMASK(DOUBLE_CLICK_EVENT));
+                               if (ev.type == DOUBLE_CLICK_EVENT) {
+                                       ignore_next_doubleclick_ = true;
+                               }
+                               last_was_doubleclick_ = false;
+                       }
+               }
+       }
+}
+void gamebrowser::set_game_items(const config& cfg, const config& game_config)
+{
+       games_.clear();
+       config::child_list games = cfg.get_children("game");
+       config::child_iterator game;
+
+       for(game = games.begin(); game != games.end(); ++game) {
+               games_.push_back(game_item());
+
+               games_.back().map_data = (**game)["map_data"];
+               if(games_.back().map_data == "")
+                       games_.back().map_data = read_map((**game)["map"]);
+
+               if(games_.back().map_data != "") {
+                       try {
+                               gamemap map(game_config, 
games_.back().map_data);
+                               games_.back().mini_map = 
image::getMinimap(item_height_ - margin_, item_height_ - 2 * margin_, map, 0);
+                       } catch(gamemap::incorrect_format_exception &e) {
+                               std::cerr << "illegal map: " << e.msg_ << "\n";
+                       }
+               }
+               games_.back().name = (**game)["name"];
+               const std::string& turn = (**game)["turn"];
+               const std::string& slots = (**game)["slots"];
+               games_.back().vacant_slots = 
lexical_cast_default<size_t>(slots, 0);
+               if(turn != "")
+                       games_.back().status = _("Turn") + (" " + turn);
+               else if(slots != "")
+                       games_.back().status = slots + " " + ngettext(_("Vacant 
Slot"), _("Vacant Slots"), games_.back().vacant_slots);
+
+               if((**game)["mp_use_map_settings"] == "yes") {
+                       games_.back().gold = _("Use map settings");
+                       games_.back().vision = _("Use map settings");
+                       games_.back().use_map_settings = true;
+               } else {
+                       games_.back().use_map_settings = false;
+                       games_.back().gold = (**game)["mp_village_gold"];
+                       if((**game)["mp_fog"] == "yes") {
+                               games_.back().vision = _("Fog");
+                               games_.back().fog = true;
+                               if((**game)["mp_shroud"] == "yes") {
+                                       games_.back().vision += "/";
+                                       games_.back().vision += _("Shroud");
+                                       games_.back().shroud = true;
+                               } else {
+                                       games_.back().shroud = false;
+                               }
+                       } else if((**game)["mp_shroud"] == "yes") {
+                               games_.back().vision = _("Shroud");
+                               games_.back().fog = false;
+                               games_.back().shroud = true;
+                       } else {
+                               games_.back().vision = _("none");
+                               games_.back().fog = false;
+                               games_.back().shroud = false;
+                       }
+               }
+               games_.back().xp = (**game)["experience_modifier"] + "%";
+               games_.back().observers = (**game)["observer"] != "no" ? true : 
false;
+       }
+       set_full_size(games_.size());
+       set_shown_size(inner_location().h / item_height_);
+       scroll(get_position());
+       if(selected_ >= games_.size())
+               selected_ = maximum<long>(static_cast<long>(games_.size()) - 1, 
0);
+       if(selected_ >= 0)
+               adjust_position(selected_);
+       set_dirty();
+}
 
 lobby::lobby_sorter::lobby_sorter(const config& cfg) : cfg_(cfg)
 {
@@ -109,7 +410,7 @@
        create_game_(disp.video(), _("Create Game")),
        quit_game_(disp.video(), _("Quit")),
        sorter_(gamelist),
-       games_menu_(disp.video(), 
std::vector<std::string>(1,games_menu_heading()),false,-1,-1,&sorter_),
+       games_menu_(disp.video()),
        current_game_(0)
 {
        game_config::debug = false;
@@ -151,126 +452,31 @@
                // No gamelist yet. Do not update anything.
                return;
        }
-       config::child_list games = list->get_children("game");
-       config::child_iterator game;
-       game_observers_.clear();
-       game_vacant_slots_.clear();
-
-       for(game = games.begin(); game != games.end(); ++game) {
-
-               std::stringstream str;
-
-               std::string map_data = (**game)["map_data"];
-               if(map_data == "") {
-                       map_data = read_map((**game)["map"]);
-               }
-
-               if(map_data != "") {
-                       try {
-                               std::string& image_id = minimaps_[map_data];
-
-                               if(image_id.empty()) {
-                                       gamemap map(game_config(), map_data);
-                                       const surface 
mini(image::getMinimap(100,100,map,0));
-
-                                       //generate a unique id to show the map 
as
-                                       std::stringstream id;
-                                       id << "addr " << mini.get();
-                                       image_id = id.str();
-                                       image::register_image(image_id, mini);
-                               }
-
-                               str << "&" << image_id << COLUMN_SEPARATOR;
-
-                       } catch(gamemap::incorrect_format_exception& e) {
-                               std::cerr << "illegal map: " << e.msg_ << "\n";
-                       }
-               } else {
-                       str << "(" << _("Shroud") << ")" << COLUMN_SEPARATOR;
-               }
-
-               std::string name = (**game)["name"];
-               
name.erase(std::remove_if(name.begin(),name.end(),font::is_format_char),name.end());
-
-               str << font::make_text_ellipsis(name, font::SIZE_NORMAL, 
xscale(300));
-
-               const std::string& turn = (**game)["turn"];
-               const std::string& slots = (**game)["slots"];
-               int nslots = lexical_cast_default<int>(slots, 0);
-
-               if(turn != "") {
-                       str << COLUMN_SEPARATOR << _("Turn") << " " << turn;
-               } else if(slots != "") {
-                       str << COLUMN_SEPARATOR << slots << " " <<
-                               ngettext(_("Vacant Slot"), _("Vacant Slots"), 
nslots);
-               }
-               str << COLUMN_SEPARATOR << "  " << (**game)["mp_village_gold"] 
<< " "
-                       << _("Gold") << "  " << (**game)["experience_modifier"] 
<< "% " << _("XP");
-               if((**game)["mp_use_map_settings"] == "yes")
-                       str << "  " << _("Use map settings");
-               else if((**game)["mp_fog"] == "yes")
-                       str << "  " << _("Fog");
-
-               game_strings.push_back(str.str());
-
-               game_vacant_slots_.push_back(slots != "" && slots != "0");
-               game_observers_.push_back((**game)["observer"] != "no");
-       }
-
-       if(game_strings.empty()) {
-               game_strings.push_back(_("<no games open>"));
-       }
-
-       //set the items, retaining the menu positioning if possible
-       games_menu_.set_items(game_strings,true,true);
-
-       if(games_menu_.selection() >= 0 && games_menu_.selection() < 
int(game_vacant_slots_.size())) {
-               wassert(game_vacant_slots_.size() == game_observers_.size());
-
-               join_game_.hide(!game_vacant_slots_[games_menu_.selection()]);
-               observe_game_.hide(!game_observers_[games_menu_.selection()]);
-       } else {
-               join_game_.hide();
-               observe_game_.hide();
-       }
-
+       games_menu_.set_game_items(*list, game_config());
+       join_game_.hide(!games_menu_.selection_is_joinable());
+       observe_game_.hide(!games_menu_.selection_is_observable());
 }
 
 void lobby::process_event()
 {
-       games_menu_.process();
-
-       int selection = games_menu_.selection();
-
-       if(selection >= 0 && selection < int(game_vacant_slots_.size())) {
-               if(selection != current_game_)
-                       current_game_ = selection;
-               join_game_.hide(!game_vacant_slots_[selection]);
-               observe_game_.hide(!game_observers_[selection]);
-       } else {
-               join_game_.hide();
-               observe_game_.hide();
-       }
+       join_game_.hide(!games_menu_.selection_is_joinable());
+       observe_game_.hide(!games_menu_.selection_is_observable());
 
-       const bool games_available = game_vacant_slots_.empty() == false;
-       wassert(!games_available || selection >= 0 && selection < 
int(game_vacant_slots_.size()));
-       const bool double_click = games_menu_.double_clicked();
-       const bool observe = observe_game_.pressed() || games_available && 
!game_vacant_slots_[selection] && double_click && game_observers_[selection];
+       const bool observe = observe_game_.pressed() || (games_menu_.selected() 
>= 0 && games_menu_.selection_is_observable() && 
!games_menu_.selection_is_joinable());
+       const bool join = join_game_.pressed() || (games_menu_.selected() >= 0 
&& games_menu_.selection_is_joinable());
 
-       if(games_available && (observe || ((join_game_.pressed() || 
double_click) && game_vacant_slots_[selection]))) {
-               const size_t index = size_t(games_menu_.selection());
+       if(join || observe) {
                const config* game = gamelist().child("gamelist");
                if (game != NULL) {
                        const config::const_child_itors i = 
game->child_range("game");
-                       wassert(index < size_t(i.second - i.first));
-                       const std::string& id = (**(i.first+index))["id"];
+                       const std::string& id = (**(i.first + 
games_menu_.selected()))["id"];
 
                        config response;
                        config& join = response.add_child("join");
                        join["id"] = id;
                        network::send_data(response);
 
-                       if (observe) {
+                       if(observe) {
                                set_result(OBSERVE);
                        } else {
                                set_result(JOIN);
Index: wesnoth/src/multiplayer_lobby.hpp
diff -u wesnoth/src/multiplayer_lobby.hpp:1.15 
wesnoth/src/multiplayer_lobby.hpp:1.16
--- wesnoth/src/multiplayer_lobby.hpp:1.15      Tue Sep  6 13:53:14 2005
+++ wesnoth/src/multiplayer_lobby.hpp   Tue Sep 13 13:36:24 2005
@@ -1,4 +1,4 @@
-/* $Id: multiplayer_lobby.hpp,v 1.15 2005/09/06 13:53:14 ott Exp $ */
+/* $Id: multiplayer_lobby.hpp,v 1.16 2005/09/13 13:36:24 j_daniel Exp $ */
 /*
    Copyright (C)
    Part of the Battle for Wesnoth Project http://www.wesnoth.org
@@ -20,11 +20,62 @@
 #include "display.hpp"
 #include "multiplayer_ui.hpp"
 
-#include "widgets/menu.hpp"
+#include "widgets/scrollarea.hpp"
 
 // This module controls the multiplayer lobby. A section on the server which
 // allows players to chat, create games, and join games.
 namespace mp {
+class gamebrowser : public gui::scrollarea {
+public:
+       struct game_item {
+               surface mini_map;
+               std::string map_data;
+               std::string name;
+               std::string map_info;
+               std::string gold;
+               std::string xp;
+               std::string vision;
+               std::string status;
+               size_t vacant_slots;
+               bool fog;
+               bool shroud;
+               bool observers;
+               bool use_map_settings;
+       };
+       gamebrowser(CVideo& video);
+       void scroll(int pos);
+       void handle_event(const SDL_Event& event);
+       void set_inner_location(const SDL_Rect& rect);
+       void set_item_height(unsigned int height);
+       void set_game_items(const config& cfg, const config& game_config);
+       void draw();
+       void draw_contents() const;
+       void draw_item(size_t index) const;
+       SDL_Rect get_item_rect(size_t index) const;
+       bool empty() const { return games_.empty(); }
+       bool selection_is_joinable() const { return empty() ? false : 
games_[selected_].vacant_slots; }
+       bool selection_is_observable() const { return empty() ? false : 
games_[selected_].observers; }
+       int selected() { return double_clicked_ && !empty() ? 
static_cast<int>(selected_) : -1; }
+protected:
+private:
+       image::locator gold_icon_locator_;
+       image::locator xp_icon_locator_;
+       image::locator vision_icon_locator_;
+       image::locator observer_icon_locator_;
+
+       unsigned int item_height_;
+       int margin_;
+       int h_padding_;
+       int v_padding_;
+       int header_height_;
+       size_t selected_;
+       std::pair<size_t, size_t> visible_range_;
+       std::vector<game_item> games_;
+       std::vector<size_t> redraw_items_;
+       bool double_clicked_;
+       bool ignore_next_doubleclick_;
+       bool last_was_doubleclick_;
+};
 
 class lobby : public ui
 {
@@ -62,7 +113,7 @@
        gui::button quit_game_;
 
        lobby_sorter sorter_;
-       gui::menu games_menu_;
+       gamebrowser games_menu_;
        int current_game_;
 
        std::map<std::string,std::string> minimaps_;




reply via email to

[Prev in Thread] Current Thread [Next in Thread]