Initial version of the minimap widget.

* The C++ of the widget has the option to set border sizes, but this hasn't
  been exposed to WML yet.

* Moved the menubar around to keep it in alphabetic order.
This commit is contained in:
Mark de Wever 2008-07-26 09:45:18 +00:00
parent dc28e29855
commit 56b299a714
12 changed files with 478 additions and 148 deletions

View file

@ -0,0 +1,29 @@
###
### Definition of a minimap.
###
[minimap_definition]
id = "default"
description = "a minimap."
[resolution]
min_width = 100
min_height = 100
default_width = 100
default_height = 100
max_width = 0
max_height = 0
[state_enabled]
[draw]
[/draw]
[/state_enabled]
[/resolution]
[/minimap_definition]

View file

@ -19,6 +19,7 @@ src/gui/widgets/helper.cpp
src/gui/widgets/label.cpp
src/gui/widgets/listbox.cpp
src/gui/widgets/menubar.cpp
src/gui/widgets/minimap.cpp
src/gui/widgets/panel.cpp
src/gui/widgets/scrollbar.cpp
src/gui/widgets/settings.cpp

View file

@ -239,6 +239,7 @@ SET(wesnoth-main_SRC
gui/widgets/label.cpp
gui/widgets/listbox.cpp
gui/widgets/menubar.cpp
gui/widgets/minimap.cpp
gui/widgets/panel.cpp
gui/widgets/settings.cpp
gui/widgets/slider.cpp

View file

@ -86,6 +86,7 @@ wesnoth_source = \
gui/widgets/label.cpp \
gui/widgets/listbox.cpp \
gui/widgets/menubar.cpp \
gui/widgets/minimap.cpp \
gui/widgets/panel.cpp \
gui/widgets/settings.cpp \
gui/widgets/scrollbar.cpp \

View file

@ -213,6 +213,7 @@ wesnoth_sources = Split("""
gui/widgets/label.cpp
gui/widgets/listbox.cpp
gui/widgets/menubar.cpp
gui/widgets/minimap.cpp
gui/widgets/panel.cpp
gui/widgets/settings.cpp
gui/widgets/scrollbar.cpp

View file

@ -151,6 +151,7 @@ void tcontrol::draw(surface& surface, const bool force,
if(!is_dirty() && !force && !invalidate_background) {
return;
}
if(invalidate_background) {
restorer_ = 0;
}

View file

@ -0,0 +1,98 @@
/* $Id$ */
/*
copyright (C) 2008 by mark de wever <koraq@xs4all.nl>
part of the battle for wesnoth project http://www.wesnoth.org/
this program is free software; you can redistribute it and/or modify
it under the terms of the gnu general public license version 2
or at your option any later version.
this program is distributed in the hope that it will be useful,
but without any warranty.
see the copying file for more details.
*/
#include "gui/widgets/minimap.hpp"
#include "map.hpp"
#include "log.hpp"
#include "../../minimap.hpp"
#define DBG_G LOG_STREAM_INDENT(debug, gui)
#define LOG_G LOG_STREAM_INDENT(info, gui)
#define WRN_G LOG_STREAM_INDENT(warn, gui)
#define ERR_G LOG_STREAM_INDENT(err, gui)
#define DBG_G_D LOG_STREAM_INDENT(debug, gui_draw)
#define LOG_G_D LOG_STREAM_INDENT(info, gui_draw)
#define WRN_G_D LOG_STREAM_INDENT(warn, gui_draw)
#define ERR_G_D LOG_STREAM_INDENT(err, gui_draw)
#define DBG_G_E LOG_STREAM_INDENT(debug, gui_event)
#define LOG_G_E LOG_STREAM_INDENT(info, gui_event)
#define WRN_G_E LOG_STREAM_INDENT(warn, gui_event)
#define ERR_G_E LOG_STREAM_INDENT(err, gui_event)
#define DBG_G_P LOG_STREAM_INDENT(debug, gui_parse)
#define LOG_G_P LOG_STREAM_INDENT(info, gui_parse)
#define WRN_G_P LOG_STREAM_INDENT(warn, gui_parse)
#define ERR_G_P LOG_STREAM_INDENT(err, gui_parse)
#define ERR_C LOG_STREAM_INDENT(err, config)
namespace gui2 {
void tminimap::draw(surface& surface, const bool force,
const bool invalidate_background)
{
if(!is_dirty() && !force) {
return;
}
// Inherited.
tcontrol::draw(surface, force, invalidate_background);
draw_map(surface);
}
void tminimap::set_borders(const unsigned left,
const unsigned right, const unsigned top, const unsigned bottom)
{
left_border_ = left;
right_border_ = right;
top_border_ = top;
bottom_border_ = bottom;
set_dirty();
}
void tminimap::draw_map(surface& surface)
{
assert(terrain_);
if(map_data_.empty()) {
return;
}
try {
const gamemap map(*terrain_, map_data_);
SDL_Rect rect = get_rect();
rect.x += left_border_;
rect.y += top_border_;
rect.w -= left_border_ + right_border_;
rect.h -= top_border_ + bottom_border_;
assert(rect.w > 0 && rect.h > 0);
const ::surface surf = image::getMinimap(rect.w, rect.h, map, NULL);
blit_surface(surf, NULL, surface, &rect);
} catch (gamemap::incorrect_format_exception& e) {
ERR_C << "Error while loading the map: " << e.msg_ << '\n';
}
}
} // namespace gui2

116
src/gui/widgets/minimap.hpp Normal file
View file

@ -0,0 +1,116 @@
/* $Id$ */
/*
copyright (C) 2008 by mark de wever <koraq@xs4all.nl>
part of the battle for wesnoth project http://www.wesnoth.org/
this program is free software; you can redistribute it and/or modify
it under the terms of the gnu general public license version 2
or at your option any later version.
this program is distributed in the hope that it will be useful,
but without any warranty.
see the copying file for more details.
*/
#ifndef GUI_WIDGETS_MINIMAP_HPP_INCLUDED
#define GUI_WIDGETS_MINIMAP_HPP_INCLUDED
#include "gui/widgets/control.hpp"
class config;
namespace gui2 {
/**
* The basic minimap class.
*
* This minimap can only show a minimap, but it can't be interacted with. For
* that the tminimap_interactive class will be created.
*/
class tminimap : public tcontrol
{
public:
tminimap() :
tcontrol(1),
map_data_(),
terrain_(NULL),
left_border_(0),
right_border_(0),
top_border_(0),
bottom_border_(0)
{
}
/***** ***** ***** ***** Inherited ***** ***** ***** *****/
/** Inherited from tcontrol. */
void set_active(const bool /*active*/) {}
/** Inherited from tcontrol. */
bool get_active() const { return true; }
/** Inherited from tcontrol. */
unsigned get_state() const { return 0; }
/** Inherited from tcontrol. */
void draw(surface& surface, const bool force = false,
const bool invalidate_background = false);
/**
* Inherited from tcontrol.
*
* Since the old minimap might be smaller we always need to do a full
* redraw. Also the new map might be no map in which case the old one would
* be shown.
*/
bool needs_full_redraw() const { return true; }
/***** ***** ***** setters / getters for members ***** ****** *****/
void set_map_data(const std::string& map_data)
{ if(map_data != map_data_) { map_data_ = map_data; set_dirty(); } }
std::string get_map_data() const { return map_data_; }
const std::string& map_data() const { return map_data_; }
void set_config(const ::config* terrain) { terrain_ = terrain; }
/** Sets all border variables, no function to set one at the time. */
void set_borders(const unsigned left,
const unsigned right, const unsigned top, const unsigned bottom);
private:
/** The map data to be used to generate the map. */
std::string map_data_;
/**
* The config object with the terrain data.
*
* This config must be set before the object can be drawn.
*/
const ::config* terrain_;
/**
* The minimap widget might have some drawing on the borders, these
* variables hold the border size. The minimap itself is not drawn on that
* area.
*/
unsigned left_border_;
unsigned right_border_;
unsigned top_border_;
unsigned bottom_border_;
/** Draws the minimap itself. */
virtual void draw_map(surface& surface);
/** Inherited from tcontrol. */
const std::string& get_control_type() const
{ static const std::string type = "minimap"; return type; }
};
} // namespace gui2
#endif

View file

@ -179,7 +179,13 @@ const std::string& tgui_definition::read(const config& cfg)
* <span id="widget_list"></span>List of available widgets:
* @start_table = widget_definition
* button_definition A push button.
* menubar_definition A menubar which is used in menus and the tabbar in a tabcontrol.
* menubar_definition A menubar which is used in menus and the
* tabbar in a tabcontrol.
* minimap_definition A minimap to show the gamemap, this only
* shows the map and has no interaction
* options. This version is used for map
* previews, there will be a another version
* which allows interaction.
* label_definition A label.
* listbox_definition A listbox.
* panel_definition A panel.
@ -215,9 +221,10 @@ const std::string& tgui_definition::read(const config& cfg)
/***** Control definitions *****/
load_definitions<tbutton_definition>("button", cfg.get_children("button_definition"));
load_definitions<tmenubar_definition>("menubar", cfg.get_children("menubar_definition"));
load_definitions<tlabel_definition>("label", cfg.get_children("label_definition"));
load_definitions<tlistbox_definition>("listbox", cfg.get_children("listbox_definition"));
load_definitions<tmenubar_definition>("menubar", cfg.get_children("menubar_definition"));
load_definitions<tminimap_definition>("minimap", cfg.get_children("minimap_definition"));
load_definitions<tpanel_definition>("panel", cfg.get_children("panel_definition"));
load_definitions<tslider_definition>("slider", cfg.get_children("slider_definition"));
load_definitions<tspacer_definition>("spacer", cfg.get_children("spacer_definition"));
@ -502,35 +509,6 @@ tbutton_definition::tresolution::tresolution(const config& cfg) :
state.push_back(tstate_definition(cfg.child("state_focussed")));
}
tmenubar_definition::tmenubar_definition(const config& cfg) :
tcontrol_definition(cfg)
{
DBG_G_P << "Parsing menubar " << id << '\n';
load_resolutions<tresolution>(cfg.get_children("resolution"));
}
tmenubar_definition::tresolution::tresolution(const config& cfg) :
tresolution_definition_(cfg)
{
/*WIKI
* @page = GUIToolkitWML
* @order = 1_widget_menubar
*
* == Menubar ==
*
* The definition of a normal menubar.
*
* The following states exist:
* * state_enabled, the menubar is enabled.
* * state_disabled, the menubar is disabled.
*
*/
// Note the order should be the same as the enum tstate is menubar.hpp.
state.push_back(tstate_definition(cfg.child("state_enabled")));
state.push_back(tstate_definition(cfg.child("state_disabled")));
}
tlabel_definition::tlabel_definition(const config& cfg) :
tcontrol_definition(cfg)
{
@ -634,6 +612,64 @@ tlistbox_definition::tresolution::tresolution(const config& cfg) :
scrollbar = new tbuilder_grid(*grid);
}
tmenubar_definition::tmenubar_definition(const config& cfg) :
tcontrol_definition(cfg)
{
DBG_G_P << "Parsing menubar " << id << '\n';
load_resolutions<tresolution>(cfg.get_children("resolution"));
}
tmenubar_definition::tresolution::tresolution(const config& cfg) :
tresolution_definition_(cfg)
{
/*WIKI
* @page = GUIToolkitWML
* @order = 1_widget_menubar
*
* == Menubar ==
*
* The definition of a normal menubar.
*
* The following states exist:
* * state_enabled, the menubar is enabled.
* * state_disabled, the menubar is disabled.
*
*/
// Note the order should be the same as the enum tstate is menubar.hpp.
state.push_back(tstate_definition(cfg.child("state_enabled")));
state.push_back(tstate_definition(cfg.child("state_disabled")));
}
tminimap_definition::tminimap_definition(const config& cfg) :
tcontrol_definition(cfg)
{
DBG_G_P << "Parsing minimap " << id << '\n';
load_resolutions<tresolution>(cfg.get_children("resolution"));
}
tminimap_definition::tresolution::tresolution(const config& cfg) :
tresolution_definition_(cfg)
{
/*WIKI
* @page = GUIToolkitWML
* @order = 1_widget_minimap
*
* == Minimap ==
*
* The definition of a normal minimap.
* NOTE in the draw section of the minimap the value of full_redraw is ignored,
* the minimap is always fully redrawn.
*
* The following states exist:
* * state_enabled, the minimap is enabled.
*
*/
// Note the order should be the same as the enum tstate is minimap.hpp.
state.push_back(tstate_definition(cfg.child("state_enabled")));
}
tpanel_definition::tpanel_definition(const config& cfg) :
tcontrol_definition(cfg)
{

View file

@ -123,17 +123,6 @@ struct tbutton_definition : public tcontrol_definition
};
struct tmenubar_definition : public tcontrol_definition
{
tmenubar_definition(const config& cfg);
struct tresolution : public tresolution_definition_
{
tresolution(const config& cfg);
};
};
struct tlabel_definition : public tcontrol_definition
{
@ -161,6 +150,28 @@ struct tlistbox_definition : public tcontrol_definition
};
};
struct tmenubar_definition : public tcontrol_definition
{
tmenubar_definition(const config& cfg);
struct tresolution : public tresolution_definition_
{
tresolution(const config& cfg);
};
};
struct tminimap_definition : public tcontrol_definition
{
tminimap_definition(const config& cfg);
struct tresolution : public tresolution_definition_
{
tresolution(const config& cfg);
};
};
struct tpanel_definition : public tcontrol_definition
{

View file

@ -19,6 +19,7 @@
#include "gui/widgets/button.hpp"
#include "gui/widgets/label.hpp"
#include "gui/widgets/listbox.hpp"
#include "gui/widgets/minimap.hpp"
#include "gui/widgets/slider.hpp"
#include "gui/widgets/spacer.hpp"
#include "gui/widgets/text_box.hpp"
@ -378,12 +379,14 @@ tbuilder_grid::tbuilder_grid(const config& cfg) :
if((**col_itor).child("button")) {
widgets.push_back(new tbuilder_button(*((**col_itor).child("button"))));
} else if((**col_itor).child("menubar")) {
widgets.push_back(new tbuilder_menubar(*((**col_itor).child("menubar"))));
} else if((**col_itor).child("label")) {
widgets.push_back(new tbuilder_label(*((**col_itor).child("label"))));
} else if((**col_itor).child("listbox")) {
widgets.push_back(new tbuilder_listbox(*((**col_itor).child("listbox"))));
} else if((**col_itor).child("menubar")) {
widgets.push_back(new tbuilder_menubar(*((**col_itor).child("menubar"))));
} else if((**col_itor).child("minimap")) {
widgets.push_back(new tbuilder_minimap(*((**col_itor).child("minimap"))));
} else if((**col_itor).child("panel")) {
widgets.push_back(new tbuilder_panel(*((**col_itor).child("panel"))));
} else if((**col_itor).child("slider")) {
@ -550,12 +553,14 @@ tbuilder_gridcell::tbuilder_gridcell(const config& cfg) :
{
if((cfg).child("button")) {
widget=new tbuilder_button(*((cfg).child("button")));
} else if((cfg).child("menubar")) {
widget=new tbuilder_menubar(*((cfg).child("menubar")));
} else if((cfg).child("label")) {
widget=new tbuilder_label(*((cfg).child("label")));
} else if((cfg).child("listbox")) {
widget=new tbuilder_listbox(*((cfg).child("listbox")));
} else if((cfg).child("menubar")) {
widget=new tbuilder_menubar(*((cfg).child("menubar")));
} else if((cfg).child("minimap")) {
widget=new tbuilder_minimap(*((cfg).child("minimap")));
} else if((cfg).child("panel")) {
widget=new tbuilder_panel(*((cfg).child("panel")));
} else if((cfg).child("slider")) {
@ -579,91 +584,6 @@ tbuilder_gridcell::tbuilder_gridcell(const config& cfg) :
}
}
static tmenubar::tdirection read_direction(const std::string& direction)
{
if(direction == "vertical") {
return tmenubar::VERTICAL;
} else if(direction == "horizontal") {
return tmenubar::HORIZONTAL;
} else {
ERR_G_E << "Invalid direction "
<< direction << "' falling back to 'horizontal'.\n";
return tmenubar::HORIZONTAL;
}
}
tbuilder_menubar::tbuilder_menubar(const config& cfg) :
tbuilder_control(cfg),
must_have_one_item_selected_(utils::string_bool(cfg["must_have_one_item_selected"])),
direction_(read_direction(cfg["direction"])),
selected_item_(lexical_cast_default<int>(
cfg["selected_item"], must_have_one_item_selected_ ? 0 : -1)),
cells_()
{
/*WIKI
* @page = GUIToolkitWML
* @order = 3_widget_menubar
*
* == Menubar ==
*
* A menu bar used for menus and tab controls.
*
* List with the listbox specific variables:
* @start_table = config
* must_have_one_item_selected (bool = false)
* Does the menu always have one item
* selected. This makes sense for tabsheets
* but not for menus.
* direction (direction = "") The direction of the menubar.
* selected_item(int = -1) The item to select upon creation, when
* 'must_have_one_item_selected' is true the
* default value is 0 instead of -1. -1
* means no item selected.
* @end_table
*/
const config* data = cfg.child("data");
if(data) {
foreach(const config* cell, data->get_children("cell")) {
cells_.push_back(tbuilder_gridcell(*cell));
}
}
}
twidget* tbuilder_menubar::build() const
{
tmenubar* menubar = new tmenubar(direction_);
init_control(menubar);
DBG_G << "Window builder: placed menubar '" << id << "' with defintion '"
<< definition << "'.\n";
if(direction_ == tmenubar::HORIZONTAL) {
menubar->set_rows_cols(1, cells_.size());
for(size_t i = 0; i < cells_.size(); ++i) {
menubar->set_child(cells_[i].widget->build(),
0, i, cells_[i].flags, cells_[i].border_size);
}
} else {
// vertical growth
menubar->set_rows_cols(cells_.size(), 1);
for(size_t i = 0; i < cells_.size(); ++i) {
menubar->set_child(cells_[i].widget->build(),
i, 0, cells_[i].flags, cells_[i].border_size);
}
}
menubar->set_selected_item(selected_item_);
menubar->set_must_select(must_have_one_item_selected_);
menubar->finalize_setup();
return menubar;
}
twidget* tbuilder_label::build() const
{
tlabel* tmp_label = new tlabel();
@ -852,6 +772,103 @@ twidget* tbuilder_listbox::build() const
return listbox;
}
static tmenubar::tdirection read_direction(const std::string& direction)
{
if(direction == "vertical") {
return tmenubar::VERTICAL;
} else if(direction == "horizontal") {
return tmenubar::HORIZONTAL;
} else {
ERR_G_E << "Invalid direction "
<< direction << "' falling back to 'horizontal'.\n";
return tmenubar::HORIZONTAL;
}
}
tbuilder_menubar::tbuilder_menubar(const config& cfg) :
tbuilder_control(cfg),
must_have_one_item_selected_(utils::string_bool(cfg["must_have_one_item_selected"])),
direction_(read_direction(cfg["direction"])),
selected_item_(lexical_cast_default<int>(
cfg["selected_item"], must_have_one_item_selected_ ? 0 : -1)),
cells_()
{
/*WIKI
* @page = GUIToolkitWML
* @order = 3_widget_menubar
*
* == Menubar ==
*
* A menu bar used for menus and tab controls.
*
* List with the listbox specific variables:
* @start_table = config
* must_have_one_item_selected (bool = false)
* Does the menu always have one item
* selected. This makes sense for tabsheets
* but not for menus.
* direction (direction = "") The direction of the menubar.
* selected_item(int = -1) The item to select upon creation, when
* 'must_have_one_item_selected' is true the
* default value is 0 instead of -1. -1
* means no item selected.
* @end_table
*/
const config* data = cfg.child("data");
if(data) {
foreach(const config* cell, data->get_children("cell")) {
cells_.push_back(tbuilder_gridcell(*cell));
}
}
}
twidget* tbuilder_menubar::build() const
{
tmenubar* menubar = new tmenubar(direction_);
init_control(menubar);
DBG_G << "Window builder: placed menubar '" << id << "' with defintion '"
<< definition << "'.\n";
if(direction_ == tmenubar::HORIZONTAL) {
menubar->set_rows_cols(1, cells_.size());
for(size_t i = 0; i < cells_.size(); ++i) {
menubar->set_child(cells_[i].widget->build(),
0, i, cells_[i].flags, cells_[i].border_size);
}
} else {
// vertical growth
menubar->set_rows_cols(cells_.size(), 1);
for(size_t i = 0; i < cells_.size(); ++i) {
menubar->set_child(cells_[i].widget->build(),
i, 0, cells_[i].flags, cells_[i].border_size);
}
}
menubar->set_selected_item(selected_item_);
menubar->set_must_select(must_have_one_item_selected_);
menubar->finalize_setup();
return menubar;
}
twidget* tbuilder_minimap::build() const
{
tminimap* minimap = new tminimap();
init_control(minimap);
DBG_G << "Window builder: placed minimap '" << id << "' with defintion '"
<< definition << "'.\n";
return minimap;
}
tbuilder_panel::tbuilder_panel(const config& cfg) :
tbuilder_control(cfg),
grid(0)

View file

@ -82,23 +82,6 @@ struct tbuilder_gridcell : public tbuilder_widget
twidget* build () const { return NULL; }
};
struct tbuilder_menubar : public tbuilder_control
{
tbuilder_menubar(const config& cfg);
twidget* build () const;
private:
bool must_have_one_item_selected_;
tmenubar::tdirection direction_;
int selected_item_;
std::vector<tbuilder_gridcell> cells_;
};
struct tbuilder_label : public tbuilder_control
{
@ -148,6 +131,41 @@ public:
const bool assume_fixed_row_size;
};
struct tbuilder_menubar : public tbuilder_control
{
tbuilder_menubar(const config& cfg);
twidget* build () const;
private:
bool must_have_one_item_selected_;
tmenubar::tdirection direction_;
int selected_item_;
std::vector<tbuilder_gridcell> cells_;
};
struct tbuilder_minimap : public tbuilder_control
{
/*WIKI
* @page = GUIToolkitWML
* @order = 3_widget_minimap
*
* == Minimap ==
*
* A minimap has no extra fields.
*/
tbuilder_minimap(const config& cfg) :
tbuilder_control(cfg)
{
}
twidget* build () const;
};
struct tbuilder_panel : public tbuilder_control
{