[[Button and widget improvements]]

- Modified button widget
  Addedd a set_label fucntion. Calling it will set a new label for the
  button.

- Added a combobox widget
  Simple widget, its a button that calls a menu of choices when clicked. The
  selected option becomes the buttons label

- Started work on the Game Lobby. There is still a good bit of work to be
  done here, and what is shown isn't functional. Click the "Launch" button
  lets you configure the game the old way.

- Changed "AI" in the english config to "Computer Player"
This commit is contained in:
Justin Zaun 2003-11-19 09:57:16 +00:00
parent ea088e8b79
commit 4458114052
8 changed files with 326 additions and 98 deletions

1
.gitignore vendored
View file

@ -1,4 +1,5 @@
*.swp
wesnoth
wesnothd
make_translation
merge_translations

View file

@ -11,7 +11,7 @@ SDL_CFLAGS=`sdl-config --cflags` `freetype-config --cflags`
SDL_LIBS=`sdl-config --libs` `freetype-config --libs` -lSDL_mixer -lSDL_ttf -lSDL_image -lSDL_net
LIBS=${SDL_LIBS} -lstdc++
INCLUDES=-I. -Isrc -Isrc/tools -Isrc/widgets
OBJS=src/actions.o src/ai.o src/ai_attack.o src/ai_move.o src/config.o src/dialogs.o src/display.o src/events.o src/filesystem.o src/font.o src/game.o src/game_config.o src/game_events.o src/gamestatus.o src/hotkeys.o src/image.o src/intro.o src/key.o src/language.o src/log.o src/map.o src/mouse.o src/multiplayer.o src/multiplayer_client.o src/multiplayer_lobby.o src/network.o src/pathfind.o src/playlevel.o src/playturn.o src/preferences.o src/replay.o src/sdl_utils.o src/show_dialog.o src/sound.o src/team.o src/terrain.o src/tooltips.o src/unit.o src/unit_types.o src/video.o src/widgets/button.o src/widgets/menu.o src/widgets/slider.o src/widgets/textbox.o
OBJS=src/actions.o src/ai.o src/ai_attack.o src/ai_move.o src/config.o src/dialogs.o src/display.o src/events.o src/filesystem.o src/font.o src/game.o src/game_config.o src/game_events.o src/gamestatus.o src/hotkeys.o src/image.o src/intro.o src/key.o src/language.o src/log.o src/map.o src/mouse.o src/multiplayer.o src/multiplayer_client.o src/multiplayer_lobby.o src/network.o src/pathfind.o src/playlevel.o src/playturn.o src/preferences.o src/replay.o src/sdl_utils.o src/show_dialog.o src/sound.o src/team.o src/terrain.o src/tooltips.o src/unit.o src/unit_types.o src/video.o src/widgets/button.o src/widgets/menu.o src/widgets/slider.o src/widgets/textbox.o src/widgets/combo.o
MAKE_TRANS_OBJS=src/tools/make_translation.o src/config.o src/filesystem.o src/game_config.o src/log.o
MERGE_TRANS_OBJS=src/tools/merge_translations.o src/config.o src/filesystem.o src/game_config.o src/log.o

View file

@ -144,7 +144,7 @@ game_cancelled="The game has been cancelled"
waiting_start="Waiting for game to start..."
human_controlled="Local Player"
ai_controlled="AI"
ai_controlled="Computer Player"
network_controlled="Network Player"
remote_host="Choose host to connect to"
connection_failed="Could not connect to the remote host"

View file

@ -25,6 +25,7 @@
#include "show_dialog.hpp"
#include "widgets/textbox.hpp"
#include "widgets/button.hpp"
#include "widgets/combo.hpp"
#include "widgets/menu.hpp"
#include "widgets/slider.hpp"
@ -486,119 +487,211 @@ int play_multiplayer(display& disp, game_data& units_data, config cfg,
(**sd)["description"] = preferences::login();
}
res = 0;
while(size_t(res) != sides.size()) {
std::vector<std::string> sides_list;
// Wait to players, Configure players
gui::draw_dialog_frame((disp.x()-width)/2, (disp.y()-height)/2,
width, height, disp);
//Title
font::draw_text(&disp,disp.screen_area(),24,font::NORMAL_COLOUR,
"Game Lobby",-1,(disp.y()-height)/2+5);
//Options
std::vector<std::string> player_type;
player_type.push_back(string_table["human_controlled"]);
player_type.push_back(string_table["network_controlled"]);
player_type.push_back(string_table["ai_controlled"]);
std::vector<std::string> player_race;
player_race.push_back("Elves");
player_race.push_back("Orcs");
player_race.push_back("Humans");
player_race.push_back("Undead");
std::vector<std::string> player_team;
char label[8];
int counter=0;
for(std::vector<config*>::iterator sd = sides.begin();
sd != sides.end(); ++sd) {
counter++;
sprintf(label, "Team %d", counter);
player_team.push_back(label);
}
std::vector<std::string> player_color;
player_color.push_back("Red");
player_color.push_back("Blue");
player_color.push_back("Green");
player_color.push_back("Yellow");
player_color.push_back("Pink");
player_color.push_back("Purple");
//Players
std::vector<std::string> sides_list;
std::vector<gui::combo> combo_type;
std::vector<gui::combo> combo_race;
std::vector<gui::combo> combo_team;
std::vector<gui::combo> combo_color;
counter = 0;
for(std::vector<config*>::iterator sd = sides.begin();
sd != sides.end(); ++sd) {
font::draw_text(&disp,disp.screen_area(),24,font::GOOD_COLOUR,
(*sd)->values["side"],(disp.x()-width)/2+10,
(disp.y()-height)/2+38+(30*counter));
combo_type.push_back(gui::combo(disp,player_type));
combo_type[counter].set_xy((disp.x()-width)/2+30,
(disp.y()-height)/2+40+(30*counter));
combo_race.push_back(gui::combo(disp,player_race));
combo_race[counter].set_xy((disp.x()-width)/2+150,
(disp.y()-height)/2+40+(30*counter));
combo_team.push_back(gui::combo(disp,player_team));
combo_team[counter].set_xy((disp.x()-width)/2+270,
(disp.y()-height)/2+40+(30*counter));
combo_team[counter].set_selected(counter);
combo_color.push_back(gui::combo(disp,player_color));
combo_color[counter].set_xy((disp.x()-width)/2+390,
(disp.y()-height)/2+40+(30*counter));
combo_color[counter].set_selected(counter);
counter++;
}
//Buttons
gui::button launch2_game(disp,"Launch");
launch2_game.set_xy((disp.x()/2)-launch2_game.width()/2,(disp.y()-height)/2+height-29);
update_whole_screen();
for(;;) {
const int mouse_flags = SDL_GetMouseState(&mousex,&mousey);
const bool left_button = mouse_flags&SDL_BUTTON_LMASK;
counter=0;
for(std::vector<config*>::iterator sd = sides.begin();
sd != sides.end(); ++sd) {
std::stringstream details;
details << (*sd)->values["side"] << ","
<< (*sd)->values["name"] << ",";
const std::string& controller = (*sd)->values["controller"];
if(controller == "human")
details << string_table["human_controlled"];
else if(controller == "network")
details << string_table["network_controlled"];
else
details << string_table["ai_controlled"];
sides_list.push_back(details.str());
combo_type[counter].process(mousex,mousey,left_button);
combo_race[counter].process(mousex,mousey,left_button);
combo_team[counter].process(mousex,mousey,left_button);
combo_color[counter].process(mousex,mousey,left_button);
counter++;
}
if(launch2_game.process(mousex,mousey,left_button)) {
res = 0;
while(size_t(res) != sides.size()) {
std::vector<std::string> sides_list;
for(std::vector<config*>::iterator sd = sides.begin();
sd != sides.end(); ++sd) {
std::stringstream details;
details << (*sd)->values["side"] << ","
<< (*sd)->values["name"] << ",";
const std::string& controller = (*sd)->values["controller"];
if(controller == "human")
details << string_table["human_controlled"];
else if(controller == "network")
details << string_table["network_controlled"];
else
details << string_table["ai_controlled"];
sides_list.push_back(details.str());
}
sides_list.push_back(string_table["start_game"]);
sides_list.push_back(string_table["start_game"]);
res = gui::show_dialog(disp,NULL,"",string_table["configure_sides"],
gui::MESSAGE,&sides_list);
res = gui::show_dialog(disp,NULL,"",string_table["configure_sides"],
gui::MESSAGE,&sides_list);
if(size_t(res) < sides.size()) {
std::vector<std::string> choices;
if(size_t(res) < sides.size()) {
std::vector<std::string> choices;
for(int n = 0; n != 3; ++n) {
for(std::vector<config*>::iterator i = possible_sides.begin();
i != possible_sides.end(); ++i) {
std::stringstream choice;
choice << (*i)->values["name"] << " - ";
switch(n) {
case 0: choice << string_table["human_controlled"];
break;
case 1: choice << string_table["ai_controlled"];
break;
case 2: choice << string_table["network_controlled"];
break;
default: assert(false);
}
for(int n = 0; n != 3; ++n) {
for(std::vector<config*>::iterator i = possible_sides.begin();
i != possible_sides.end(); ++i) {
std::stringstream choice;
choice << (*i)->values["name"] << " - ";
switch(n) {
case 0: choice << string_table["human_controlled"];
break;
case 1: choice << string_table["ai_controlled"];
break;
case 2: choice << string_table["network_controlled"];
break;
default: assert(false);
}
choices.push_back(choice.str());
choices.push_back(choice.str());
}
}
int result = gui::show_dialog(disp,NULL,"",
string_table["choose_side"],
gui::MESSAGE,&choices);
if(result >= 0) {
std::string controller = "network";
if(result < int(choices.size())/3) {
controller = "human";
sides[res]->values["description"] = preferences::login();
} else if(result < int(choices.size()/3)*2) {
controller = "ai";
result -= choices.size()/3;
sides[res]->values["description"] = "";
} else {
controller = "network";
result -= (choices.size()/3)*2;
}
sides[res]->values["controller"] = controller;
assert(result < int(possible_sides.size()));
std::map<std::string,std::string>& values =
possible_sides[result]->values;
sides[res]->values["name"] = values["name"];
sides[res]->values["type"] = values["type"];
sides[res]->values["recruit"] = values["recruit"];
sides[res]->values["recruitment_pattern"] =
values["recruitment_pattern"];
sides[res]->values["music"] = values["music"];
}
}
}
const network::manager net_manager;
const network::server_manager server_man(15000,server);
int result = gui::show_dialog(disp,NULL,"",
string_table["choose_side"],
gui::MESSAGE,&choices);
if(result >= 0) {
std::string controller = "network";
if(result < int(choices.size())/3) {
controller = "human";
sides[res]->values["description"] = preferences::login();
} else if(result < int(choices.size()/3)*2) {
controller = "ai";
result -= choices.size()/3;
sides[res]->values["description"] = "";
const bool network_state = accept_network_connections(disp,level);
if(network_state == false)
return -1;
state.starting_pos = level;
recorder.set_save_info(state);
if(!recorder.empty()) {
const int res = gui::show_dialog(disp,NULL,
"", string_table["replay_game_message"],
gui::YES_NO);
//if yes, then show the replay, otherwise
//skip showing the replay
if(res == 0) {
recorder.set_skip(0);
} else {
controller = "network";
result -= (choices.size()/3)*2;
std::cerr << "skipping...\n";
recorder.set_skip(-1);
}
sides[res]->values["controller"] = controller;
assert(result < int(possible_sides.size()));
std::map<std::string,std::string>& values =
possible_sides[result]->values;
sides[res]->values["name"] = values["name"];
sides[res]->values["type"] = values["type"];
sides[res]->values["recruit"] = values["recruit"];
sides[res]->values["recruitment_pattern"] =
values["recruitment_pattern"];
sides[res]->values["music"] = values["music"];
}
//any replay data isn't meant to hang around under the level,
//it was just there to tell clients about the replay data
level.children["replay"].clear();
std::vector<config*> story;
play_level(units_data,cfg,&level,disp.video(),state,story);
recorder.clear();
return -1;
}
events::pump();
disp.video().flip();
SDL_Delay(20);
}
const network::manager net_manager;
const network::server_manager server_man(15000,server);
const bool network_state = accept_network_connections(disp,level);
if(network_state == false)
return -1;
state.starting_pos = level;
recorder.set_save_info(state);
if(!recorder.empty()) {
const int res = gui::show_dialog(disp,NULL,
"", string_table["replay_game_message"],
gui::YES_NO);
//if yes, then show the replay, otherwise
//skip showing the replay
if(res == 0) {
recorder.set_skip(0);
} else {
std::cerr << "skipping...\n";
recorder.set_skip(-1);
}
}
//any replay data isn't meant to hang around under the level,
//it was just there to tell clients about the replay data
level.children["replay"].clear();
std::vector<config*> story;
play_level(units_data,cfg,&level,disp.video(),state,story);
recorder.clear();
return -1;
} else {
rect.x=(disp.x()-width)/2;
rect.y=(disp.y()-height)/2;

View file

@ -178,6 +178,16 @@ bool button::hit(int x, int y) const
void button::set_x(int val) { x_ = val; }
void button::set_y(int val) { y_ = val; }
void button::set_xy(int valx, int valy) { x_ = valx; y_ = valy; }
void button::set_label(std::string val)
{
label_ = val;
textRect_.x = 0;
textRect_.y = 0;
textRect_.w = display_->x();
textRect_.h = display_->y();
textRect_ = font::draw_text(NULL,textRect_,font_size,
font::BUTTON_COLOUR,label_,0,0);
}
int button::width() const
{

View file

@ -44,6 +44,7 @@ public:
void set_x(int val);
void set_y(int val);
void set_xy(int valx, int valy);
void button::set_label(std::string val);
int width() const;
int height() const;

72
src/widgets/combo.cpp Normal file
View file

@ -0,0 +1,72 @@
/* $Id$ */
/*
Copyright (C) 2003 by David White <davidnwhite@optusnet.com.au>
Part of the Battle for Wesnoth Project http://wesnoth.whitevine.net
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#include "combo.hpp"
#include "button.hpp"
#include "../show_dialog.hpp"
#include "../video.hpp"
namespace gui {
const int font_size = 12;
const int horizontal_padding = 10;
const int vertical_padding = 10;
combo::combo(display& disp, const std::vector<std::string>& items) :
items_(items), selected_(0), display_(&disp),
button_(gui::button(disp, items[0]))
{
}
int combo::height() const
{
return button_.height();
}
int combo::width() const
{
return button_.width();
}
int combo::selected() const
{
return selected_;
}
void combo::set_xy(int x, int y)
{
button_.set_xy(x,y);
}
void combo::set_selected(int val)
{
selected_ = val;
const std::string& label = items_[selected_];
if(selected_ >= 0)
button_.set_label(label);
}
void combo::process(int x, int y, bool button)
{
if(button_.process(x,y,button))
{
selected_ = gui::show_dialog(*display_,NULL,"","",
gui::MESSAGE,&items_);
const std::string& label = items_[selected_];
if(selected_ >= 0)
button_.set_label(label);
}
}
}

51
src/widgets/combo.hpp Normal file
View file

@ -0,0 +1,51 @@
/* $Id$ */
/*
Copyright (C) 2003 by David White <davidnwhite@optusnet.com.au>
Part of the Battle for Wesnoth Project http://wesnoth.whitevine.net
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY.
See the COPYING file for more details.
*/
#ifndef COMBO_H_INCLUDED
#define COMBO_H_INCLUDED
#include "SDL.h"
#include "button.hpp"
#include "../display.hpp"
namespace gui {
class combo
{
public:
combo(display& disp, const std::vector<std::string>& items);
void draw();
void set_x(int val);
void set_y(int val);
void set_xy(int valx, int valy);
void set_selected(int val);
int width() const;
int height() const;
int selected() const;
void process(int mousex, int mousey, bool button);
private:
std::vector<std::string> items_;
int selected_;
display *display_;
gui::button button_;
}; //end class combo
}
#endif