Based the editor palette on a new button like widget.

This commit is contained in:
fendrin 2013-04-13 02:04:17 +02:00
parent f31f632878
commit 0e49adb276
14 changed files with 768 additions and 192 deletions

View file

@ -659,6 +659,7 @@ set(wesnoth-main_SRC
editor/map/map_context.cpp
editor/map/map_fragment.cpp
editor/palette/palette_manager.cpp
editor/palette/tristate_button.cpp
editor/toolkit/brush.cpp
editor/palette/editor_palettes.cpp
editor/palette/terrain_palettes.cpp

View file

@ -235,6 +235,7 @@ wesnoth_sources = Split("""
editor/map/context_manager.cpp
editor/palette/editor_palettes.cpp
editor/palette/terrain_palettes.cpp
editor/palette/tristate_button.cpp
editor/palette/unit_palette.cpp
editor/palette/palette_manager.cpp
editor/editor_controller.cpp

View file

@ -16,6 +16,7 @@
#define COMMON_PALETTES_H_INCLUDED
#include "config.hpp"
#include "gui/widgets/widget.hpp"
struct SDL_Rect;
@ -44,8 +45,11 @@ public:
virtual ~common_palette() {}
//event handling
virtual bool left_mouse_click(const int x, const int y) = 0;
virtual bool right_mouse_click(const int x, const int y) = 0;
virtual handler_vector handler_members() { return handler_vector(); };
virtual void select_fg_item(const std::string& item_id) = 0;
virtual void select_bg_item(const std::string& item_id) = 0;
/** Scroll the editor-palette up one step if possible. */
virtual bool scroll_up() = 0;
@ -57,7 +61,7 @@ public:
//drawing
virtual void adjust_size(const SDL_Rect& target) = 0;
virtual void draw(bool) = 0;
virtual void draw(bool force) = 0;
//group
virtual void set_group(size_t index) = 0;

View file

@ -28,6 +28,18 @@
namespace editor {
template<class Item>
handler_vector editor_palette<Item>::handler_members()
{
handler_vector h;
BOOST_FOREACH(gui::widget& b, buttons_) {
h.push_back(&b);
}
return h;
}
template handler_vector editor_palette<t_translation::t_terrain>::handler_members();
template handler_vector editor_palette<unit_type>::handler_members();
template<class Item>
void editor_palette<Item>::expand_palette_groups_menu(std::vector<std::string>& items)
{
@ -59,32 +71,6 @@ void editor_palette<Item>::expand_palette_groups_menu(std::vector<std::string>&
template void editor_palette<t_translation::t_terrain>::expand_palette_groups_menu(std::vector<std::string>& items);
template void editor_palette<unit_type>::expand_palette_groups_menu(std::vector<std::string>& items);
template<class Item>
bool editor_palette<Item>::left_mouse_click(const int mousex, const int mousey)
{
int tselect = tile_selected(mousex, mousey);
if(tselect >= 0 && (items_start_+tselect) < active_group().size()) {
select_fg_item(active_group()[items_start_+tselect]);
return true;
}
return false;
}
template bool editor_palette<t_translation::t_terrain>::left_mouse_click(const int mousex, const int mousey);
template bool editor_palette<unit_type>::left_mouse_click(const int mousex, const int mousey);
template<class Item>
bool editor_palette<Item>::right_mouse_click(const int mousex, const int mousey)
{
int tselect = tile_selected(mousex, mousey);
if(tselect >= 0 && (items_start_+tselect) < active_group().size()) {
select_bg_item(active_group()[items_start_+tselect]);
return true;
}
return false;
}
template bool editor_palette<t_translation::t_terrain>::right_mouse_click(const int mousex, const int mousey);
template bool editor_palette<unit_type>::right_mouse_click(const int mousex, const int mousey);
template<class Item>
bool editor_palette<Item>::scroll_up()
{
@ -211,6 +197,7 @@ void editor_palette<Item>::adjust_size(const SDL_Rect& target)
static_cast<unsigned> (space_for_items / item_space_) *
item_width_;
nitems_ = std::min<int>(items_fitting, nmax_items_);
buttons_.resize(nitems_, gui::tristate_button(gui_.video(), "", this));
}
template void editor_palette<t_translation::t_terrain>::adjust_size(const SDL_Rect& target);
template void editor_palette<unit_type>::adjust_size(const SDL_Rect& target);
@ -253,9 +240,9 @@ template size_t editor_palette<t_translation::t_terrain>::num_items();
template size_t editor_palette<unit_type>::num_items();
template<class Item>
void editor_palette<Item>::draw(bool dirty)
void editor_palette<Item>::draw(bool force)
{
if (!dirty) return;
if (!force) return;
unsigned int y = palette_y_;
unsigned int x = palette_x_;
unsigned int starting = items_start_;
@ -269,47 +256,25 @@ void editor_palette<Item>::draw(bool dirty)
gui::button* downscroll_button = gui_.find_button("downscroll-button-editor");
downscroll_button->enable(ending != num_items());
for(unsigned int counter = starting; counter < ending; counter++){
const int counter_from_zero = counter - starting;
SDL_Rect dstrect;
dstrect.x = x + (counter_from_zero % item_width_) * item_space_;
dstrect.y = y;
dstrect.w = item_size_;
dstrect.h = item_size_;
unsigned int counter = starting;
for (unsigned int i = 0 ; i < buttons_.size() ; i++) {
//TODO check if the conditions still hold for the counter variable
//for (unsigned int counter = starting; counter < ending; counter++)
std::stringstream tooltip_text;
gui::tristate_button& tile = buttons_[i];
tile.hide(true);
if (i >= ending) continue;
const std::string item_id = active_group()[counter];
typedef std::map<std::string, Item> item_map_wurscht;
typename item_map_wurscht::iterator item = item_map_.find(item_id);
draw_item(dstrect, (*item).second, tooltip_text);
surface screen = gui_.video().getSurface();
Uint32 color;
if (get_id((*item).second) == selected_bg_item_
&& get_id((*item).second) == selected_fg_item_) {
color = SDL_MapRGB(screen->format,0xFF,0x00,0xFF);
}
else if (get_id((*item).second) == selected_bg_item_) {
color = SDL_MapRGB(screen->format,0x00,0x00,0xFF);
}
else if (get_id((*item).second) == selected_fg_item_) {
color = SDL_MapRGB(screen->format,0xFF,0x00,0x00);
}
else {
color = SDL_MapRGB(screen->format,0x00,0x00,0x00);
}
draw_rectangle(dstrect.x, dstrect.y, dstrect.w, dstrect.h, color, screen);
/* TODO The call above overdraws the border of the terrain image.
The following call is doing better but causing other drawing glitches.
draw_rectangle(dstrect.x -1, dstrect.y -1, image->w +2, image->h +2, color, screen);
*/
surface item_image(NULL);
std::stringstream tooltip_text;
draw_item((*item).second, item_image, tooltip_text);
bool is_core = non_core_items_.find(get_id((*item).second)) == non_core_items_.end();
if (!is_core) {
@ -319,29 +284,41 @@ void editor_palette<Item>::draw(bool dirty)
<< _("Will not work in game without extra care.")
<< "</span>";
}
tooltips::add_tooltip(dstrect, tooltip_text.str());
const int counter_from_zero = counter - starting;
SDL_Rect dstrect;
dstrect.x = x + (counter_from_zero % item_width_) * item_space_;
dstrect.y = y;
dstrect.w = item_size_ + 2;
dstrect.h = item_size_ + 2;
tile.set_location(dstrect);
tile.set_help_string(tooltip_text.str());
tile.set_item_image(item_image);
tile.set_item_id(item_id);
if (get_id((*item).second) == selected_bg_item_
&& get_id((*item).second) == selected_fg_item_) {
tile.set_pressed(gui::tristate_button::BOTH);
} else if (get_id((*item).second) == selected_bg_item_) {
tile.set_pressed(gui::tristate_button::RIGHT);
} else if (get_id((*item).second) == selected_fg_item_) {
tile.set_pressed(gui::tristate_button::LEFT);
} else {
tile.set_pressed(gui::tristate_button::NONE);
}
tile.set_dirty(true);
tile.hide(false);
// Adjust location
if (counter_from_zero % item_width_ == item_width_ - 1)
y += item_space_;
counter++;
}
}
template void editor_palette<t_translation::t_terrain>::draw(bool);
template void editor_palette<unit_type>::draw(bool);
template<class Item>
int editor_palette<Item>::tile_selected(const int x, const int y) const
{
for(unsigned int i = 0; i != nitems_; i++) {
const int px = palette_x_ + (i % item_width_) * item_space_;
const int py = palette_y_ + (i / item_width_) * item_space_;
const int pw = item_space_;
const int ph = item_space_;
if(x > px && x < px + pw && y > py && y < py + ph) {
return i;
}
}
return -1;
}
} // end namespace editor

View file

@ -17,6 +17,7 @@
#include "../editor_display.hpp"
#include "common_palette.hpp"
#include "tristate_button.hpp"
namespace editor {
@ -31,7 +32,8 @@ public:
, gui_(gui)
, item_size_(item_size)
, item_width_(item_width)
, item_space_(item_size + 3)
//TODO avoid magic number
, item_space_(item_size + 5)
, palette_y_(0)
, palette_x_(0)
, group_map_()
@ -44,9 +46,12 @@ public:
, selected_fg_item_()
, selected_bg_item_()
, active_mouse_action_(active_mouse_action)
, buttons_()
{
};
virtual handler_vector handler_members();
void set_start_item(size_t index) { items_start_ = index; };
size_t start_num(void) { return items_start_; };
@ -58,10 +63,7 @@ public:
const std::vector<item_group>& get_groups() const { return groups_; };
virtual void draw(bool);
bool left_mouse_click(const int, const int);
bool right_mouse_click(const int, const int);
virtual void draw(bool force);
void next_group() {
set_group( (active_group_index() +1) % (groups_.size() -1) );
@ -92,9 +94,6 @@ public:
private:
/** Return the number of the tile that is at coordinates (x, y) in the panel. */
int tile_selected(const int x, const int y) const;
/** TODO */
size_t active_group_index();
@ -104,7 +103,7 @@ private:
/** Scroll the editor-palette to the bottom. */
void scroll_bottom();
virtual void draw_item(SDL_Rect& dstrect, const Item& item, std::stringstream& tooltip) = 0;
virtual void draw_item(const Item& item, surface& item_image, std::stringstream& tooltip) = 0;
virtual const std::string& get_id(const Item& item) = 0;
@ -116,7 +115,7 @@ private:
/** Return the number of items in the palette. */
size_t num_items();
void draw_old(bool);
//void draw_old(bool);
protected:
/**
@ -163,6 +162,7 @@ private:
std::string selected_bg_item_;
mouse_action** active_mouse_action_;
std::vector<gui::tristate_button> buttons_;
};

View file

@ -31,25 +31,32 @@ public:
empty_palette(display& gui) : gui_(gui), empty_() {};
//event handling
virtual bool left_mouse_click(const int /*x*/, const int /*y*/) { return false;};
virtual bool right_mouse_click(const int /*x*/, const int /*y*/) { return false;};
virtual bool mouse_click() { return false;};
virtual bool scroll_up() { return false;};
virtual bool can_scroll_up() { return false;};
virtual bool scroll_down() { return false;};
virtual bool can_scroll_down() { return false;};
virtual void select_fg_item(const std::string& /*item_id*/) {};
virtual void select_bg_item(const std::string& /*item_id*/) {};
//drawing
virtual void adjust_size(const SDL_Rect& /*target*/) {};
virtual void draw(bool) {
//TODO
/*
gui::button* upscroll_button = gui_.find_button("upscroll-button-editor");
upscroll_button->hide(true);
gui::button* downscroll_button = gui_.find_button("downscroll-button-editor");
downscroll_button->hide(true);
gui::button* palette_menu_button = gui_.find_button("menu-editor-terrain");
palette_menu_button->hide(true);
*/
};
std::vector<gui::widget>* get_widgets() { return NULL; };
//group
virtual void set_group(size_t /*index*/) {};
virtual void next_group() {};
@ -69,7 +76,6 @@ public:
private:
display& gui_;
std::vector<item_group> empty_;
};

View file

@ -19,6 +19,7 @@
#include "tooltips.hpp"
#include "editor/action/mouse/mouse_action.hpp"
#include <boost/foreach.hpp>
namespace editor {
@ -127,46 +128,39 @@ void palette_manager::draw(bool force)
gui::button* palette_menu_button = gui_.find_button("menu-editor-terrain");
palette_menu_button->hide(false);
active_palette().draw(force);
bg_restore(loc);
active_palette().draw(dirty() || force);
update_rect(loc);
set_dirty(false);
}
handler_vector palette_manager::handler_members()
{
//handler_vector h;
// BOOST_FOREACH(gui::widget& b, active_palette().get_widgets()) {
// h.push_back(&b);
// }
//return h;
return active_palette().handler_members();
}
void palette_manager::handle_event(const SDL_Event& event) {
if (event.type == SDL_MOUSEMOTION) {
// If the mouse is inside the palette, give it focus.
if (point_in_rect(event.button.x, event.button.y, location())) {
if (!focus(&event)) {
set_focus(true);
}
if (!focus(&event)) set_focus(true);
}
// If the mouse is outside, remove focus.
else {
if (focus(&event)) {
set_focus(false);
}
}
else if (focus(&event)) set_focus(false);
}
if (!focus(&event)) {
return;
}
int mousex, mousey;
SDL_GetMouseState(&mousex,&mousey);
const SDL_MouseButtonEvent mouse_button_event = event.button;
if (mouse_button_event.type == SDL_MOUSEBUTTONDOWN) {
if (mouse_button_event.button == SDL_BUTTON_LEFT) {
left_mouse_click(mousex, mousey);
}
/* TODO
if (mouse_button_event.button == SDL_BUTTON_MIDDLE) {
middle_mouse_click(mousex, mousey);
}
*/
if (mouse_button_event.button == SDL_BUTTON_RIGHT) {
right_mouse_click(mousex, mousey);
}
if (mouse_button_event.button == SDL_BUTTON_WHEELUP) {
scroll_up();
}
@ -181,30 +175,16 @@ void palette_manager::handle_event(const SDL_Event& event) {
active_palette().next_group();
scroll_top();
}
//set_dirty(true);
}
if (mouse_button_event.type == SDL_MOUSEBUTTONUP) {
if (mouse_button_event.button == SDL_BUTTON_LEFT) {
//TODO What is missing here?
}
}
}
void palette_manager::left_mouse_click(const int mousex, const int mousey)
{
if ( active_palette().left_mouse_click(mousex, mousey) ) {
set_dirty();
gui_.invalidate_game_status();
}
}
void palette_manager::right_mouse_click(const int mousex, const int mousey)
{
if ( active_palette().right_mouse_click(mousex, mousey) ) {
set_dirty();
gui_.invalidate_game_status();
//set_dirty(true);
// draw(true);
// set_dirty(active_palette().mouse_click());
// gui_.invalidate_game_status();
}
}
} //Namespace editor

View file

@ -21,9 +21,9 @@
#include "common_palette.hpp"
#include "empty_palette.hpp"
#include "terrain_palettes.hpp"
#include "unit_palette.hpp"
#include "empty_palette.hpp"
namespace editor {
@ -32,81 +32,54 @@ class palette_manager : public gui::widget {
public:
//palette_manager();
palette_manager(editor_display &gui, const config& cfg
, mouse_action** active_mouse_action);
void set_group(size_t index);
// virtual size_t active_group_index();
// virtual const std::vector<item_group>& get_groups();
/** Scroll the editor-palette up one step if possible. */
void scroll_up();
bool can_scroll_down();
bool can_scroll_up();
/** Scroll the editor-palette down one step if possible. */
void scroll_down();
void scroll_top();
bool can_scroll_up();
bool can_scroll_down();
void scroll_top();
void scroll_bottom();
// virtual void swap();
//TODO
// void swap();
void adjust_size();
handler_vector handler_members();
virtual void handle_event(const SDL_Event& event);
/**
* Draw the palette.
*
* If force is true everything will be redrawn,
* even though it is not invalidated.
*/
virtual void handle_event(const SDL_Event& event);
void draw(bool force=false);
void draw() { draw(true); };
/**
* To be called when a mouse click occurs.
*
* Check if the coordinates is a terrain that may be chosen,
* and select the terrain if that is the case.
*/
void left_mouse_click(const int mousex, const int mousey);
void right_mouse_click(const int mousex, const int mousey);
/** Return the number of the tile that is at coordinates (x, y) in the panel. */
//TODO
// int tile_selected(const int x, const int y) const;
void draw() { draw(false); };
public:
common_palette& active_palette();
//TODO { return (*mouse_action_)->get_palette(); };
//TODO
// terrain_palette* terrain_palette() { return terrain_palette_; };
// unit_palette* unit_palette() { return unit_palette_; };
// empty_palette* empty_palette() { return empty_palette_; };
private:
editor_display& gui_;
int palette_start_;
mouse_action** mouse_action_;
public:
boost::scoped_ptr<terrain_palette> terrain_palette_;
boost::scoped_ptr<unit_palette> unit_palette_;
boost::scoped_ptr<empty_palette> empty_palette_;
boost::scoped_ptr<unit_palette> unit_palette_;
boost::scoped_ptr<empty_palette> empty_palette_;
};

View file

@ -166,11 +166,11 @@ void terrain_palette::setup(const config& cfg)
// update_report();
}
void terrain_palette::draw_item(SDL_Rect& dstrect, const t_translation::t_terrain& terrain, std::stringstream& tooltip_text) {
void terrain_palette::draw_item(const t_translation::t_terrain& terrain,
surface& image, std::stringstream& tooltip_text) {
const t_translation::t_terrain base_terrain = map().get_terrain_info(terrain).default_base();
surface screen = gui_.video().getSurface();
const t_translation::t_terrain base_terrain =
map().get_terrain_info(terrain).default_base();
//Draw default base for overlay terrains
if(base_terrain != t_translation::NONE_TERRAIN) {
@ -191,12 +191,10 @@ void terrain_palette::draw_item(SDL_Rect& dstrect, const t_translation::t_terrai
base_image.assign(scale_surface(base_image,
item_size_, item_size_));
}
sdl_blit(base_image, NULL, screen, &dstrect);
}
const std::string filename = "terrain/" + map().get_terrain_info(terrain).editor_image() + ".png";
surface image(image::get_image(filename));
image = surface(image::get_image(filename));
if(image == NULL) {
tooltip_text << "IMAGE NOT FOUND\n";
ERR_ED << "image for terrain: '" << filename << "' not found\n";
@ -212,8 +210,6 @@ void terrain_palette::draw_item(SDL_Rect& dstrect, const t_translation::t_terrai
item_size_, item_size_));
}
sdl_blit(image, NULL, screen, &dstrect);
tooltip_text << map().get_terrain_editor_string(terrain);
if (gui_.get_draw_terrain_codes()) {
tooltip_text << " " + utils::unicode_em_dash + " " << terrain;

View file

@ -52,7 +52,7 @@ private:
virtual const std::string& get_id(const t_translation::t_terrain& terrain);
virtual void draw_item(SDL_Rect& dstrect, const t_translation::t_terrain& terrain, std::stringstream& tooltip_text);
virtual void draw_item(const t_translation::t_terrain& terrain, surface& item_image, std::stringstream& tooltip_text);
virtual void update_report();
};

View file

@ -0,0 +1,519 @@
/*
Copyright (C) 2003 - 2013 by David White <dave@whitevine.net>
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 as published by
the Free Software Foundation; either version 2 of the License, 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.
*/
#define GETTEXT_DOMAIN "wesnoth-lib"
#include "global.hpp"
#include "tristate_button.hpp"
#include "font.hpp"
#include "game_config.hpp"
#include "image.hpp"
#include "log.hpp"
#include "marked-up_text.hpp"
#include "serialization/string_utils.hpp"
#include "sound.hpp"
#include "video.hpp"
#include "wml_separators.hpp"
static lg::log_domain log_display("display");
#define ERR_DP LOG_STREAM(err, log_display)
namespace gui {
const int font_size = font::SIZE_SMALL;
const int horizontal_padding = font::SIZE_SMALL;
const int checkbox_horizontal_padding = font::SIZE_SMALL / 2;
const int vertical_padding = font::SIZE_SMALL / 2;
tristate_button::tristate_button(CVideo& video, const std::string& label,
editor::common_palette* palette,
std::string button_image_name, SPACE_CONSUMPTION spacing,
const bool auto_join) :
widget(video, auto_join)
, label_(label),
baseImage_(NULL), touchedBaseImage_(NULL), activeBaseImage_(NULL),
itemImage_(NULL),
// normalImage_(NULL), activeImage_(NULL),
pressedDownImage_(NULL), pressedUpImage_(NULL), pressedBothImage_(NULL),
pressedBothActiveImage_(NULL), pressedDownActiveImage_(NULL), pressedUpActiveImage_(NULL),
touchedDownImage_(NULL), touchedUpImage_(NULL), touchedBothImage_(NULL),
// disabledImage_(NULL), pressedDownDisabledImage_(NULL),
// pressedUpDisabledImage_(NULL), pressedBothDisabledImage_(NULL),
state_(NORMAL), pressed_(false),
spacing_(spacing), base_height_(0), base_width_(0)
, palette_(palette), item_id_()
{
if (button_image_name.empty()) {
button_image_name = "buttons/editor/palette/";
}
baseImage_.assign(
image::get_image(button_image_name + "base.png"));
activeBaseImage_.assign(
image::get_image(button_image_name + "base-active.png"));
touchedBaseImage_.assign(
image::get_image(button_image_name + "base-touched.png"));
touchedBothImage_.assign(
image::get_image(button_image_name + "touched-both.png"));
touchedUpImage_.assign(
image::get_image(button_image_name + "touched-up.png"));
touchedDownImage_.assign(
image::get_image(button_image_name + "touched-down.png"));
pressedUpImage_.assign(
image::get_image(button_image_name + "pressed-up.png"));
pressedDownImage_.assign(
image::get_image(button_image_name + "pressed-down.png"));
pressedBothImage_.assign(
image::get_image(button_image_name + "pressed-both.png"));
pressedUpActiveImage_.assign(
image::get_image(button_image_name + "active-pressed-up.png"));
pressedDownActiveImage_.assign(
image::get_image(button_image_name + "active-pressed-down.png"));
pressedBothActiveImage_.assign(
image::get_image(button_image_name + "active-pressed-both.png"));
// if (button_image.null()) {
// ERR_DP<< "error initializing button!\n";
// throw error();
// }
base_height_ = baseImage_->h;
base_width_ = baseImage_->w;
// calculate_size();
}
tristate_button::~tristate_button() {
}
void tristate_button::calculate_size() {
// TODO
// if (type_ == TYPE_IMAGE){
// SDL_Rect loc_image = location();
// loc_image.h = normalImage_->h;
// loc_image.w = normalImage_->w;
// set_location(loc_image);
// return;
// }
SDL_Rect const &loc = location();
bool change_size = loc.h == 0 || loc.w == 0;
if (!change_size) {
unsigned w = loc.w - (checkbox_horizontal_padding + base_width_);
int fs = font_size;
int style = TTF_STYLE_NORMAL;
std::string::const_iterator i_beg = label_.begin(), i_end =
label_.end(), i = font::parse_markup(i_beg, i_end, &fs, NULL,
&style);
if (i != i_end) {
std::string tmp(i, i_end);
label_.erase(i - i_beg, i_end - i_beg);
label_ += font::make_text_ellipsis(tmp, fs, w, style);
}
}
textRect_ = font::draw_text(NULL, screen_area(), font_size,
font::BUTTON_COLOR, label_, 0, 0);
if (!change_size)
return;
set_height(std::max(textRect_.h + vertical_padding, base_height_));
if (label_.empty()) {
set_width(base_width_);
} else {
set_width(checkbox_horizontal_padding + textRect_.w + base_width_);
}
}
void tristate_button::set_pressed(PRESSED_STATE new_pressed_state) {
STATE new_state;
switch (new_pressed_state) {
case LEFT:
new_state = PRESSED_LEFT;
break;
case RIGHT:
new_state = PRESSED_RIGHT;
break;
case BOTH:
new_state = PRESSED_BOTH;
break;
case NONE:
new_state = NORMAL;
}
// if (check) {
// new_state =
// (state_ == ACTIVE || state_ == PRESSED_ACTIVE) ?
// PRESSED_ACTIVE : PRESSED;
// } else {
// new_state =
// (state_ == ACTIVE || state_ == PRESSED_ACTIVE) ?
// ACTIVE : NORMAL;
// }
if (state_ != new_state) {
state_ = new_state;
set_dirty();
}
}
//void tristate_button::set_active(bool active) {
// if ((state_ == NORMAL) && active) {
// state_ = ACTIVE;
// set_dirty();
// } else if ((state_ == ACTIVE) && !active) {
// state_ = NORMAL;
// set_dirty();
// }
//}
//
tristate_button::PRESSED_STATE tristate_button::pressed_state() const {
switch (state_) {
case PRESSED_LEFT:
case PRESSED_ACTIVE_LEFT:
case TOUCHED_BOTH_LEFT:
return LEFT;
case PRESSED_RIGHT:
case PRESSED_ACTIVE_RIGHT:
case TOUCHED_BOTH_RIGHT:
return RIGHT;
case PRESSED_BOTH:
case PRESSED_ACTIVE_BOTH:
return BOTH;
default:
return NONE;
break;
}
return NONE;
}
void tristate_button::enable(bool new_val) {
if (new_val != enabled()) {
pressed_ = false;
// check buttons should keep their state
state_ = NORMAL;
widget::enable(new_val);
}
}
void tristate_button::draw_contents() {
surface image(NULL);
surface overlay(NULL);
surface base = baseImage_;
int offset = 0;
switch (state_) {
case UNINIT:
return;
case NORMAL:
break;
case TOUCHED_LEFT:
overlay = touchedUpImage_;
base = touchedBaseImage_;
break;
case TOUCHED_RIGHT:
overlay = touchedDownImage_;
base = touchedBaseImage_;
break;
case TOUCHED_BOTH_LEFT:
case TOUCHED_BOTH_RIGHT:
overlay = touchedBothImage_;
base = touchedBaseImage_;
break;
case ACTIVE:
// overlay = activeImage_;
base = activeBaseImage_;
break;
case PRESSED_LEFT:
overlay = pressedUpImage_;
break;
case PRESSED_RIGHT:
overlay = pressedDownImage_;
break;
case PRESSED_BOTH:
overlay = pressedBothImage_;
break;
case PRESSED_ACTIVE_LEFT:
overlay = pressedUpActiveImage_;
base = activeBaseImage_;
break;
case PRESSED_ACTIVE_BOTH:
overlay = pressedBothActiveImage_;
base = activeBaseImage_;
break;
case PRESSED_ACTIVE_RIGHT:
overlay = pressedDownActiveImage_;
base = activeBaseImage_;
break;
}
image = base;
const int image_w = image->w;
SDL_Rect const &loc = location();
SDL_Rect clipArea = loc;
const int texty = loc.y + loc.h / 2 - textRect_.h / 2 + offset;
int textx;
clipArea.w += image_w + checkbox_horizontal_padding;
textx = loc.x + image_w + checkbox_horizontal_padding / 2;
SDL_Color button_color = font::BUTTON_COLOR;
// blit_surface want neutral surfaces
surface nitem = make_neutral_surface(itemImage_);
surface nbase = make_neutral_surface(base);
//TODO avoid magic numbers
SDL_Rect r = create_rect(1, 1, 0, 0);
blit_surface(nitem, NULL, nbase, &r);
if (!overlay.null()) {
surface noverlay = make_neutral_surface(overlay);
blit_surface(noverlay, NULL, nbase, NULL);
}
// TODO for later reference
// SDL_SetAlpha(nbase, SDL_SRCALPHA, SDL_ALPHA_OPAQUE);
// SDL_SetAlpha(image, 0, 0);
//
// TODO might be needed.
bg_restore();
image = nbase;
video().blit_surface(loc.x, loc.y, image);
clipArea.x += offset;
clipArea.y += offset;
clipArea.w -= 2 * offset;
clipArea.h -= 2 * offset;
font::draw_text(&video(), clipArea, font_size, button_color, label_, textx,
texty);
update_rect(loc);
}
//TODO move to widget
bool tristate_button::hit(int x, int y) const {
return point_in_rect(x, y, location());
}
static bool not_image(const std::string& str) {
return !str.empty() && str[0] != IMAGE_PREFIX;
}
void tristate_button::set_label(const std::string& val) {
label_ = val;
//if we have a list of items, use the first one that isn't an image
if (std::find(label_.begin(), label_.end(), COLUMN_SEPARATOR)
!= label_.end()) {
const std::vector<std::string>& items = utils::split(label_,
COLUMN_SEPARATOR);
const std::vector<std::string>::const_iterator i = std::find_if(
items.begin(), items.end(), not_image);
if (i != items.end()) {
label_ = *i;
}
}
calculate_size();
set_dirty(true);
}
void tristate_button::mouse_motion(SDL_MouseMotionEvent const &event) {
if (hit(event.x, event.y))
{ // the cursor is over the widget
switch (state_) {
case UNINIT:
return;
case NORMAL:
state_ = ACTIVE;
break;
case PRESSED_LEFT:
state_ = PRESSED_ACTIVE_LEFT;
break;
case PRESSED_RIGHT:
state_ = PRESSED_ACTIVE_RIGHT;
break;
case PRESSED_BOTH:
state_ = PRESSED_ACTIVE_BOTH;
break;
default:
//assert(false);
break;
}
} else { // the cursor is not over the widget
switch (state_) {
case ACTIVE:
state_ = NORMAL;
break;
case TOUCHED_LEFT:
case TOUCHED_RIGHT:
state_ = ACTIVE;
break;
case PRESSED_ACTIVE_RIGHT:
case TOUCHED_BOTH_RIGHT:
state_ = PRESSED_RIGHT;
break;
case PRESSED_ACTIVE_BOTH:
state_ = PRESSED_BOTH;
break;
case PRESSED_ACTIVE_LEFT:
case TOUCHED_BOTH_LEFT:
state_ = PRESSED_LEFT;
break;
default:
break;
}
}
}
void tristate_button::mouse_down(SDL_MouseButtonEvent const &event) {
if (!hit(event.x, event.y))
return;
if (event.button == SDL_BUTTON_RIGHT) {
if (state_ == ACTIVE)
state_ = TOUCHED_RIGHT;
if (state_ == PRESSED_ACTIVE_LEFT)
state_ = TOUCHED_BOTH_LEFT;
}
if (event.button == SDL_BUTTON_LEFT) {
if (state_ == ACTIVE)
state_ = TOUCHED_LEFT;
if (state_ == PRESSED_ACTIVE_RIGHT)
state_ = TOUCHED_BOTH_RIGHT;
}
}
void tristate_button::release() {
state_ = NORMAL;
draw_contents();
}
void tristate_button::mouse_up(SDL_MouseButtonEvent const &event) {
if (!(hit(event.x, event.y)))
return;
// the user has stopped pressing the mouse left button while on the widget
if (event.button == SDL_BUTTON_LEFT) {
if (state_ == TOUCHED_LEFT) {
state_ = PRESSED_ACTIVE_LEFT;
palette_->select_fg_item(item_id_);
palette_->draw(true);
pressed_ = true;
}
if (state_ == TOUCHED_BOTH_RIGHT) {
state_ = PRESSED_ACTIVE_BOTH;
palette_->select_fg_item(item_id_);
palette_->select_bg_item(item_id_);
palette_->draw(true);
pressed_ = true;
}
}
if (event.button == SDL_BUTTON_RIGHT) {
if (state_ == TOUCHED_RIGHT) {
state_ = PRESSED_ACTIVE_RIGHT;
palette_->select_bg_item(item_id_);
palette_->draw(true);
pressed_ = true;
}
if (state_ == TOUCHED_BOTH_LEFT) {
state_ = PRESSED_ACTIVE_BOTH;
palette_->select_fg_item(item_id_);
palette_->select_bg_item(item_id_);
palette_->draw(true);
pressed_ = true;
}
}
if (pressed_)
sound::play_UI_sound(game_config::sounds::checkbox_release);
}
void tristate_button::handle_event(const SDL_Event& event) {
if (hidden() || !enabled())
return;
STATE start_state = state_;
if (!mouse_locked()) {
switch (event.type) {
case SDL_MOUSEBUTTONDOWN:
mouse_down(event.button);
break;
case SDL_MOUSEBUTTONUP:
mouse_up(event.button);
break;
case SDL_MOUSEMOTION:
mouse_motion(event.motion);
break;
default:
return;
}
}
if (start_state != state_)
set_dirty(true);
}
bool tristate_button::pressed() {
const bool res = pressed_;
pressed_ = false;
return res;
}
}

View file

@ -0,0 +1,121 @@
/*
Copyright (C) 2003 - 2013 by David White <dave@whitevine.net>
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 as published by
the Free Software Foundation; either version 2 of the License, 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 TRISTATE_BUTTON_H_INCLUDED
#define TRISTATE_BUTTON_H_INCLUDED
#include "widgets/widget.hpp"
#include "exceptions.hpp"
#include "editor/palette/common_palette.hpp"
namespace gui {
class tristate_button : public widget
{
public:
struct error : public game::error {
error()
: game::error("GUI1 tristate button error")
{}
};
enum PRESSED_STATE { LEFT, RIGHT, BOTH, NONE };
enum SPACE_CONSUMPTION { DEFAULT_SPACE, MINIMUM_SPACE };
tristate_button(CVideo& video, const std::string& label,
editor::common_palette* palette,
std::string button_image="",
SPACE_CONSUMPTION spacing=DEFAULT_SPACE,
const bool auto_join=true);
/** Default implementation, but defined out-of-line for efficiency reasons. */
virtual ~tristate_button();
void set_pressed(PRESSED_STATE new_pressed_state);
// void set_active(bool active);
bool pressed();
PRESSED_STATE pressed_state() const;
void set_label(const std::string& val);
bool hit(int x, int y) const;
virtual void enable(bool new_val=true);
void release();
void set_item_image(
const surface& image)
{
itemImage_ = image;
}
void set_item_id(const std::string& id) {
item_id_ = id;
}
protected:
virtual void handle_event(const SDL_Event& event);
virtual void mouse_motion(const SDL_MouseMotionEvent& event);
virtual void mouse_down(const SDL_MouseButtonEvent& event);
virtual void mouse_up(const SDL_MouseButtonEvent& event);
virtual void draw_contents();
private:
void calculate_size();
std::string label_;
surface baseImage_, touchedBaseImage_, activeBaseImage_,
itemImage_,
// normalImage_, activeImage_,
pressedDownImage_, pressedUpImage_, pressedBothImage_,
pressedBothActiveImage_, pressedDownActiveImage_, pressedUpActiveImage_,
touchedDownImage_, touchedUpImage_, touchedBothImage_;
// disabledImage_, pressedDownDisabledImage_, pressedUpDisabledImage_, pressedBothDisabledImage_;
SDL_Rect textRect_;
enum STATE { UNINIT,
NORMAL, ACTIVE,
PRESSED_ACTIVE_LEFT, PRESSED_ACTIVE_RIGHT, PRESSED_ACTIVE_BOTH,
TOUCHED_RIGHT, TOUCHED_BOTH_RIGHT, TOUCHED_BOTH_LEFT, TOUCHED_LEFT,
PRESSED_LEFT, PRESSED_RIGHT, PRESSED_BOTH
};
STATE state_;
bool pressed_;
SPACE_CONSUMPTION spacing_;
int base_height_, base_width_;
editor::common_palette* palette_;
std::string item_id_;
}; //end class button
}
#endif

View file

@ -89,7 +89,7 @@ void unit_palette::setup(const config& /*cfg*/)
// update_report();
}
void unit_palette::draw_item(SDL_Rect& dstrect, const unit_type& u, std::stringstream& tooltip_text) {
void unit_palette::draw_item(const unit_type& u, surface& image, std::stringstream& tooltip_text) {
surface screen = gui_.video().getSurface();
@ -97,7 +97,7 @@ void unit_palette::draw_item(SDL_Rect& dstrect, const unit_type& u, std::strings
filename << u.image() << "~RC(" << u.flag_rgb() << '>'
<< team::get_side_color_index(gui_.viewing_side()) << ')';
surface image(image::get_image(filename.str()));
image = surface(image::get_image(filename.str()));
if(image == NULL) {
tooltip_text << "IMAGE NOT FOUND\n";
ERR_ED << "image for unit type: '" << filename.str() << "' not found\n";
@ -113,8 +113,6 @@ void unit_palette::draw_item(SDL_Rect& dstrect, const unit_type& u, std::strings
item_size_, item_size_));
}
sdl_blit(image, NULL, screen, &dstrect);
tooltip_text << u.type_name();
}

View file

@ -38,7 +38,7 @@ public:
private:
virtual const std::string& get_id(const unit_type& terrain);
virtual void draw_item(SDL_Rect& dstrect, const unit_type& terrain, std::stringstream& tooltip_text);
virtual void draw_item(const unit_type& terrain, surface& image, std::stringstream& tooltip_text);
// virtual void update_report();