Added a preferences dialog to the editor.

It is now possible to change resolution and toggle fullscreen in the editor.

Refactoring:

The palettes now inherit from the widget class.

The events are handled by the palettes themselves.

The terrain palette controls the scroll buttons by itself.
This commit is contained in:
Kristoffer Erlandsson 2004-05-09 11:11:15 +00:00
parent 283370720d
commit c1f671a53a
10 changed files with 447 additions and 166 deletions

View file

@ -154,6 +154,14 @@ alt=no
shift=no
[/hotkey]
[hotkey]
command="preferences"
key="p"
ctrl=yes
alt=no
shift=no
[/hotkey]
[resolution]
width=800
height=600
@ -167,7 +175,7 @@ height=600
[menu]
title=main_menu
image=lite
items=editnewmap,editloadmap,editrevert,undo,redo,editsavemap,editsaveas,togglegrid,editquit
items=editnewmap,editloadmap,editrevert,undo,redo,editsavemap,editsaveas,preferences,togglegrid,editquit
rect=3,1,107,22
xanchor=fixed
yanchor=fixed

View file

@ -74,17 +74,15 @@ namespace {
namespace map_editor {
map_editor::map_editor(display &gui, gamemap &map, config &theme, config &game_config)
: gui_(gui), map_(map), tup_(gui, "", gui::button::TYPE_PRESS, "uparrow-button"),
tdown_(gui, "", gui::button::TYPE_PRESS, "downarrow-button"), abort_(DONT_ABORT),
: gui_(gui), map_(map), abort_(DONT_ABORT),
num_operations_since_save_(0), theme_(theme), game_config_(game_config),
map_dirty_(false), palette_(gui, size_specs_, map), brush_(gui, size_specs_),
l_button_func_(NONE) {
// Set size specs.
adjust_sizes(gui_, size_specs_, palette_.num_terrains());
tup_.set_location(gui.mapx() + size_specs_.button_x, size_specs_.top_button_y);
tdown_.set_location(gui.mapx() + size_specs_.button_x, size_specs_.bot_button_y);
adjust_sizes(gui_, size_specs_);
palette_.adjust_size();
brush_.adjust_size();
// Clear the current hotkeys. Alot of hotkeys are already set
// through other configuration files (e.g. english.cfg) and we need
@ -93,8 +91,6 @@ map_editor::map_editor(display &gui, gamemap &map, config &theme, config &game_c
hotkey::add_hotkeys(theme_, true);
recalculate_starting_pos_labels();
reports::set_report_content(reports::SELECTED_TERRAIN,
get_terrain_string(palette_.selected_terrain()));
gui_.begin_game();
gui_.invalidate_all();
gui_.draw();
@ -126,36 +122,10 @@ void map_editor::handle_keyboard_event(const SDL_KeyboardEvent &event,
}
}
std::string map_editor::get_terrain_string(const gamemap::TERRAIN t) {
std::stringstream str;
const std::string& name = map_.terrain_name(t);
const std::vector<std::string>& underlying_names =
map_.underlying_terrain_name(t);
str << translate_string(name);
if(underlying_names.size() != 1 || underlying_names.front() != name) {
str << " (";
for(std::vector<std::string>::const_iterator i = underlying_names.begin();
i != underlying_names.end(); ++i) {
str << translate_string(*i);
if(i+1 != underlying_names.end()) {
str << ",";
}
}
str << ")";
}
return str.str();
}
void map_editor::handle_mouse_button_event(const SDL_MouseButtonEvent &event,
const int mousex, const int mousey) {
if (event.type == SDL_MOUSEBUTTONDOWN) {
const Uint8 button = event.button;
if (button == SDL_BUTTON_WHEELUP) {
palette_.scroll_up();
}
if (button == SDL_BUTTON_WHEELDOWN) {
palette_.scroll_down();
}
if (button == SDL_BUTTON_RIGHT) {
selected_hex_ = gui_.hex_clicked_on(mousex, mousey);
const theme::menu* const m = gui_.get_theme().context_menu();
@ -189,14 +159,6 @@ void map_editor::handle_mouse_button_event(const SDL_MouseButtonEvent &event,
}
}
else {
const gamemap::TERRAIN old_tr = palette_.selected_terrain();
palette_.left_mouse_click(mousex, mousey);
if (palette_.selected_terrain() != old_tr) {
reports::set_report_content(reports::SELECTED_TERRAIN,
get_terrain_string(palette_.selected_terrain()));
gui_.invalidate_game_status();
}
brush_.left_mouse_click(mousex, mousey);
}
}
}
@ -417,6 +379,7 @@ bool map_editor::can_execute_command(hotkey::HOTKEY_COMMAND command) const {
case hotkey::HOTKEY_ZOOM_DEFAULT:
case hotkey::HOTKEY_FULLSCREEN:
case hotkey::HOTKEY_TOGGLE_GRID:
case hotkey::HOTKEY_PREFERENCES:
case hotkey::HOTKEY_EDIT_SAVE_MAP:
case hotkey::HOTKEY_EDIT_SAVE_AS:
case hotkey::HOTKEY_EDIT_QUIT:
@ -503,6 +466,18 @@ void map_editor::redo() {
}
}
void map_editor::preferences() {
preferences_dialog(gui_);
// Sizes and stuff may have changed, we need to redraw and
// recalculate everything if that is the case.
adjust_sizes(gui_, size_specs_);
palette_.adjust_size();
brush_.adjust_size();
gui_.redraw_everything();
palette_.draw(true);
brush_.draw(true);
}
void map_editor::highlight_selected_hexes(const bool clear_old) {
if (clear_old) {
gui_.clear_highlighted_locs();
@ -882,10 +857,11 @@ void map_editor::update_mouse_over_hexes(const gamemap::location mouse_over_hex)
}
void map_editor::main_loop() {
const int scroll_speed = preferences::scroll_speed();
unsigned int last_brush_size = brush_.selected_brush_size();
const preferences::display_manager prefs_disp_manager(&gui_);
while (abort_ == DONT_ABORT) {
int mousex, mousey;
const int scroll_speed = preferences::scroll_speed();
const int mouse_flags = SDL_GetMouseState(&mousex,&mousey);
const bool l_button_down = mouse_flags & SDL_BUTTON_LMASK;
const bool r_button_down = mouse_flags & SDL_BUTTON_RMASK;
@ -942,18 +918,8 @@ void map_editor::main_loop() {
}
gui_.draw(false);
palette_.draw();
brush_.draw();
events::raise_draw_event();
if(tup_.process(mousex,mousey,l_button_down)) {
palette_.scroll_up();
}
if(tdown_.process(mousex,mousey,l_button_down)) {
palette_.scroll_down();
}
// When the map has changed, wait until the left mouse button is
// not held down and then update the minimap and the starting
// position labels.

View file

@ -136,6 +136,7 @@ public:
virtual void toggle_grid();
virtual void undo();
virtual void redo();
virtual void preferences();
virtual void edit_quit();
virtual void edit_new_map();
virtual void edit_load_map();
@ -245,9 +246,6 @@ private:
/// Commit the movement of a selection.
void perform_selection_move();
/// Return a string represeting the terrain and the underlying ones.
std::string get_terrain_string(const gamemap::TERRAIN);
/// Highlight the currently selected hexes. If clear_old is true the
/// old highlighting is cleared, otherwise the current selection is
/// only added, which may leave old selected terrain still
@ -271,7 +269,6 @@ private:
display &gui_;
gamemap &map_;
gui::button tup_, tdown_;
map_undo_list undo_stack_;
map_undo_list redo_stack_;
std::string filename_;

View file

@ -24,6 +24,7 @@
#include "../widgets/slider.hpp"
#include "../language.hpp"
#include "../map.hpp"
#include "../preferences.hpp"
#include "editor_dialogs.hpp"
@ -253,4 +254,143 @@ std::string load_map_dialog(display &disp) {
return filename;
}
void preferences_dialog(display &disp) {
const events::resize_lock prevent_resizing;
const events::event_context dialog_events_context;
const gui::dialog_manager dialog_mgr;
const int width = 600;
const int height = 200;
const int xpos = disp.x()/2 - width/2;
const int ypos = disp.y()/2 - height/2;
SDL_Rect clip_rect = {0,0,disp.x(),disp.y()};
gui::button close_button(disp,string_table["close_window"]);
std::vector<gui::button*> buttons;
buttons.push_back(&close_button);
surface_restorer restorer;
gui::draw_dialog(xpos,ypos,width,height,disp,string_table["preferences"],NULL,&buttons,&restorer);
const std::string& scroll_label = string_table["scroll_speed"];
SDL_Rect scroll_rect = {0,0,0,0};
scroll_rect = font::draw_text(NULL,clip_rect,14,font::NORMAL_COLOUR,
scroll_label,0,0);
const int text_right = xpos + scroll_rect.w + 5;
const int scroll_pos = ypos + 20;
scroll_rect.x = text_right - scroll_rect.w;
scroll_rect.y = scroll_pos;
const int slider_left = text_right + 10;
const int slider_right = xpos + width - 5;
if(slider_left >= slider_right)
return;
SDL_Rect slider_rect = { slider_left, scroll_pos, slider_right - slider_left, 10 };
slider_rect.y = scroll_pos;
gui::slider scroll_slider(disp,slider_rect);
scroll_slider.set_min(1);
scroll_slider.set_max(100);
scroll_slider.set_value(preferences::scroll_speed());
gui::button fullscreen_button(disp,string_table["full_screen"],
gui::button::TYPE_CHECK);
fullscreen_button.set_check(preferences::fullscreen());
fullscreen_button.set_location(slider_left,scroll_pos + 80);
gui::button grid_button(disp,string_table["grid_button"],
gui::button::TYPE_CHECK);
grid_button.set_check(preferences::grid());
grid_button.set_location(slider_left + fullscreen_button.width() + 100,
scroll_pos + 80);
gui::button resolution_button(disp,string_table["video_mode"]);
resolution_button.set_location(slider_left,scroll_pos + 80 + 50);
//gui::button hotkeys_button (disp,string_table["hotkeys_button"]);
//hotkeys_button.set_location(slider_left + fullscreen_button.width() + 100,scroll_pos + 80 + 100);
bool redraw_all = true;
for(;;) {
int mousex, mousey;
const int mouse_flags = SDL_GetMouseState(&mousex,&mousey);
const bool left_button = mouse_flags&SDL_BUTTON_LMASK;
if(close_button.process(mousex,mousey,left_button)) {
break;
}
if(fullscreen_button.process(mousex,mousey,left_button)) {
//the underlying frame buffer is changing, so cancel
//the surface restorer restoring the frame buffer state
restorer.cancel();
preferences::set_fullscreen(fullscreen_button.checked());
redraw_all = true;
}
if(redraw_all) {
restorer.cancel();
gui::draw_dialog(xpos,ypos,width,height,disp,string_table["preferences"],NULL,&buttons,&restorer);
fullscreen_button.set_dirty();
close_button.set_dirty();
resolution_button.set_dirty();
grid_button.set_dirty();
//hotkeys_button.set_dirty();
scroll_slider.set_dirty();
font::draw_text(&disp,clip_rect,14,font::NORMAL_COLOUR,scroll_label,
scroll_rect.x,scroll_rect.y);
update_rect(disp.screen_area());
redraw_all = false;
}
if(grid_button.process(mousex,mousey,left_button)) {
preferences::set_grid(grid_button.checked());
}
if(resolution_button.process(mousex,mousey,left_button)) {
const bool mode_changed = preferences::show_video_mode_dialog(disp);
if(mode_changed) {
//the underlying frame buffer is changing, so cancel
//the surface restorer restoring the frame buffer state
restorer.cancel();
}
break;
}
//if(hotkeys_button.process(mousex,mousey,left_button)) {
// show_hotkeys_dialog (disp);
// break;
//}
events::pump();
events::raise_process_event();
events::raise_draw_event();
preferences::set_scroll_speed(scroll_slider.value());
disp.update_display();
SDL_Delay(20);
}
}
}

View file

@ -40,6 +40,10 @@ std::string new_map_dialog(display &disp, gamemap::TERRAIN fill_terrain,
/// is chosen.
std::string load_map_dialog(display &disp);
/// Show a dialog where the user may set the preferences used in the
/// editor.
void preferences_dialog(display &disp);

View file

@ -20,29 +20,16 @@ namespace {
}
namespace map_editor {
void adjust_sizes(const display &disp, size_specs &sizes,
const unsigned int num_terrains) {
const size_t button_height = 24;
const size_t button_palette_padding = 8;
void adjust_sizes(const display &disp, size_specs &sizes) {
sizes.terrain_size = default_terrain_size;
sizes.terrain_padding = 2;
sizes.terrain_space = sizes.terrain_size + sizes.terrain_padding;
sizes.palette_x = 40;
sizes.button_x = sizes.palette_x + sizes.terrain_space - 12;
sizes.brush_x = 25;
sizes.brush_x = disp.mapx() + 33;
sizes.brush_y = 190;
sizes.top_button_y = sizes.brush_y + 40;
sizes.palette_y = sizes.top_button_y + button_height +
button_palette_padding;
const size_t max_bot_button_y = disp.y() - 60 - button_height;
size_t space_for_terrains = max_bot_button_y - button_palette_padding -
sizes.palette_y;
space_for_terrains = space_for_terrains / sizes.terrain_space % 2 == 0 ?
space_for_terrains : space_for_terrains - sizes.terrain_space;
sizes.nterrains = minimum((space_for_terrains / sizes.terrain_space) * 2,
num_terrains);
sizes.bot_button_y = sizes.palette_y +
(sizes.nterrains / 2) * sizes.terrain_space + button_palette_padding;
sizes.palette_x = disp.mapx() + 40;
sizes.palette_y = sizes.brush_y + 30 + 10;
sizes.palette_w = sizes.terrain_space * 2;
sizes.palette_h = disp.y() - sizes.palette_y - 60;
}
}

View file

@ -19,22 +19,19 @@ namespace map_editor {
/// Size specifications for the map editor.
struct size_specs {
size_t nterrains;
size_t terrain_size;
size_t terrain_padding;
size_t terrain_space;
size_t palette_x;
size_t button_x;
size_t palette_y;
size_t palette_h;
size_t palette_w;
size_t brush_x;
size_t brush_y;
size_t top_button_y;
size_t palette_y;
size_t bot_button_y;
};
/// Adjust the internal size specifications to fit the display.
void adjust_sizes(const display &disp, size_specs &sizes,
const unsigned int num_terrains);
void adjust_sizes(const display &disp, size_specs &sizes);
}

View file

@ -20,6 +20,7 @@
#include "../team.hpp"
#include "../preferences.hpp"
#include "../language.hpp"
#include "../cursor.hpp"
#include <cctype>
#include <iostream>
@ -40,11 +41,65 @@ int main(int argc, char** argv)
const font::manager font_manager;
const preferences::manager prefs_manager;
const image::manager image_manager;
std::pair<int, int> desired_resolution = preferences::resolution();
// Blatant cut and paste from game.cpp
image::set_wm_icon();
int video_flags = preferences::fullscreen() ? FULL_SCREEN : 0;
video.setMode(desired_resolution.first, desired_resolution.second,
16, video_flags);
std::pair<int,int> resolution = preferences::resolution();
std::cerr << "checking mode possible...\n";
const int bpp = video.modePossible(resolution.first,resolution.second,16,video_flags);
std::cerr << bpp << "\n";
if(bpp == 0) {
//Video mode not supported, maybe from bad prefs.
std::cerr << "The video mode, " << resolution.first
<< "x" << resolution.second << "x16 "
<< "is not supported\nAttempting 1024x768x16...\n";
//Attempt 1024x768.
resolution.first = 1024;
resolution.second = 768;
int bpp = video.modePossible(resolution.first,resolution.second,16,video_flags);
if(bpp == 0) {
//Attempt 1024x768.
resolution.first = 1024;
resolution.second = 768;
std::cerr << "1024x768x16 is not possible.\nAttempting 800x600x16...\n";
resolution.first = 800;
resolution.second = 600;
bpp = video.modePossible(resolution.first,resolution.second,16,video_flags);
}
if(bpp == 0) {
//couldn't do 1024x768 or 800x600
std::cerr << "The required video mode, " << resolution.first
<< "x" << resolution.second << "x16 "
<< "is not supported\n";
return 0;
}
}
if(bpp != 16) {
std::cerr << "Video mode must be emulated; the game may run slowly. "
<< "For best results, run the program on a 16 bpp display\n";
}
std::cerr << "setting mode to " << resolution.first << "x" << resolution.second << "\n";
const int res = video.setMode(resolution.first,resolution.second,16,video_flags);
video.setBpp(bpp);
if(res != 16) {
std::cerr << "required video mode, " << resolution.first << "x"
<< resolution.second << "x16 is not supported\n";
return 0;
}
preproc_map defines_map;
defines_map["MEDIUM"] = preproc_define();
defines_map["NORMAL"] = preproc_define();

View file

@ -10,10 +10,17 @@
See the COPYING file for more details.
*/
#include "SDL.h"
#include "SDL_keysym.h"
#include "editor_palettes.hpp"
#include "editor_layout.hpp"
#include "../sdl_utils.hpp"
#include "../show_dialog.hpp"
#include "../image.hpp"
#include "../reports.hpp"
#include "../language.hpp"
#include "../util.hpp"
namespace map_editor {
@ -24,7 +31,9 @@ bool is_invalid_terrain(char c) {
terrain_palette::terrain_palette(display &gui, const size_specs &sizes,
const gamemap &map)
: size_specs_(sizes), gui_(gui), tstart_(0), map_(map), invalid_(true) {
: gui::widget(gui), size_specs_(sizes), gui_(gui), tstart_(0), map_(map),
top_button_(gui, "", gui::button::TYPE_PRESS, "uparrow-button"),
bot_button_(gui, "", gui::button::TYPE_PRESS, "downarrow-button") {
terrains_ = map_.get_terrain_precedence();
terrains_.erase(std::remove_if(terrains_.begin(), terrains_.end(), is_invalid_terrain),
@ -35,46 +44,107 @@ terrain_palette::terrain_palette(display &gui, const size_specs &sizes,
else {
selected_terrain_ = terrains_[0];
}
reports::set_report_content(reports::SELECTED_TERRAIN,
get_terrain_string(selected_terrain()));
adjust_size();
}
void terrain_palette::adjust_size() {
scroll_top();
const size_t button_height = 24;
const size_t button_palette_padding = 8;
set_location(size_specs_.palette_x, size_specs_.palette_y);
set_width(size_specs_.palette_w);
set_height(size_specs_.palette_h);
top_button_y_ = size_specs_.palette_y;
button_x_ = size_specs_.palette_x + size_specs_.palette_w/2 - button_height/2;
terrain_start_ = top_button_y_ + button_height + button_palette_padding;
const size_t space_for_terrains = size_specs_.palette_h -
(button_height + button_palette_padding) * 2;
nterrains_ = minimum((space_for_terrains / size_specs_.terrain_space) * 2, num_terrains());
bot_button_y_ = size_specs_.palette_y + (nterrains_ / 2) * size_specs_.terrain_space +
button_palette_padding * 2 + button_height;
top_button_.set_location(button_x_, top_button_y_);
bot_button_.set_location(button_x_, bot_button_y_);
top_button_.set_dirty();
bot_button_.set_dirty();
set_dirty();
}
void terrain_palette::scroll_down() {
if(tstart_ + size_specs_.nterrains + 2 <= num_terrains()) {
if(tstart_ + nterrains_ + 2 <= num_terrains()) {
tstart_ += 2;
invalid_ = true;
set_dirty();
}
else if (tstart_ + size_specs_.nterrains + 1 <= num_terrains()) {
else if (tstart_ + nterrains_ + 1 <= num_terrains()) {
tstart_ += 1;
invalid_ = true;
set_dirty();
}
}
void terrain_palette::scroll_up() {
unsigned int decrement = 2;
if (tstart_ + size_specs_.nterrains == num_terrains()
&& terrains_.size() % 2 != 0) {
if (tstart_ + nterrains_ == num_terrains()
&& num_terrains() % 2 != 0) {
decrement = 1;
}
if(tstart_ >= decrement) {
invalid_ = true;
set_dirty();
tstart_ -= decrement;
}
}
void terrain_palette::scroll_top() {
tstart_ = 0;
set_dirty();
}
void terrain_palette::scroll_bottom() {
unsigned int old_start = num_terrains();
while (old_start != tstart_) {
old_start = tstart_;
scroll_down();
}
}
gamemap::TERRAIN terrain_palette::selected_terrain() const {
return selected_terrain_;
}
void terrain_palette::select_terrain(gamemap::TERRAIN terrain) {
if (selected_terrain_ != terrain) {
invalid_ = true;
set_dirty();
selected_terrain_ = terrain;
}
}
std::string terrain_palette::get_terrain_string(const gamemap::TERRAIN t) {
std::stringstream str;
const std::string& name = map_.terrain_name(t);
const std::vector<std::string>& underlying_names =
map_.underlying_terrain_name(t);
str << translate_string(name);
if(underlying_names.size() != 1 || underlying_names.front() != name) {
str << " (";
for(std::vector<std::string>::const_iterator i = underlying_names.begin();
i != underlying_names.end(); ++i) {
str << translate_string(*i);
if(i+1 != underlying_names.end()) {
str << ",";
}
}
str << ")";
}
return str.str();
}
void terrain_palette::left_mouse_click(const int mousex, const int mousey) {
int tselect = tile_selected(mousex, mousey);
if(tselect >= 0) {
select_terrain(terrains_[tstart_+tselect]);
reports::set_report_content(reports::SELECTED_TERRAIN,
get_terrain_string(selected_terrain()));
gui_.invalidate_game_status();
}
}
@ -82,37 +152,59 @@ size_t terrain_palette::num_terrains() const {
return terrains_.size();
}
void terrain_palette::draw(bool force) {
if (!invalid_ && !force) {
void terrain_palette::draw() {
draw(false);
}
void terrain_palette::handle_event(const SDL_Event& event) {
if (!focus()) {
return;
}
size_t x = gui_.mapx() + size_specs_.palette_x;
size_t y = size_specs_.palette_y;
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);
}
if (mouse_button_event.button == SDL_BUTTON_WHEELUP) {
scroll_up();
}
if (mouse_button_event.button == SDL_BUTTON_WHEELDOWN) {
scroll_down();
}
}
if (mouse_button_event.type == SDL_MOUSEBUTTONUP) {
if (mouse_button_event.button == SDL_BUTTON_LEFT) {
}
}
}
void terrain_palette::draw(bool force) {
if (top_button_.pressed()) {
scroll_up();
}
if (bot_button_.pressed()) {
scroll_down();
}
if (!dirty() && !force) {
return;
}
unsigned int starting = tstart_;
unsigned int ending = starting + size_specs_.nterrains;
SDL_Rect invalid_rect;
invalid_rect.x = x;
invalid_rect.y = y;
invalid_rect.w = 0;
invalid_rect.w = size_specs_.terrain_space * 2;
invalid_rect.h = (size_specs_.nterrains / 2) * size_specs_.terrain_space;
// Everything will be redrawn even though only one little part may
// have changed, but that happens so seldom so we'll settle with
// this.
unsigned int ending = starting + nterrains_;
SDL_Surface* const screen = gui_.video().getSurface();
SDL_BlitSurface(surf_, NULL, screen, &invalid_rect);
surf_.assign(get_surface_portion(screen, invalid_rect));
if(ending > num_terrains()){
ending = num_terrains();
}
const SDL_Rect &loc = location();
int y = terrain_start_;
for(unsigned int counter = starting; counter < ending; counter++){
const gamemap::TERRAIN terrain = terrains_[counter];
const std::string filename = "terrain/" +
map_.get_terrain_info(terrain).default_image() + ".png";
scoped_sdl_surface image(image::get_image(filename, image::UNSCALED));
if((unsigned)image->w != size_specs_.terrain_size || (unsigned)image->h != size_specs_.terrain_size) {
if((unsigned)image->w != size_specs_.terrain_size
|| (unsigned)image->h != size_specs_.terrain_size) {
image.assign(scale_surface(image, size_specs_.terrain_size,
size_specs_.terrain_size));
}
@ -122,7 +214,7 @@ void terrain_palette::draw(bool force) {
}
const int counter_from_zero = counter - starting;
SDL_Rect dstrect;
dstrect.x = x + (counter_from_zero % 2 != 0 ? size_specs_.terrain_space : 0);
dstrect.x = loc.x + (counter_from_zero % 2 != 0 ? size_specs_.terrain_space : 0);
dstrect.y = y;
dstrect.w = image->w;
dstrect.h = image->h;
@ -134,15 +226,14 @@ void terrain_palette::draw(bool force) {
if (counter_from_zero % 2 != 0)
y += size_specs_.terrain_space;
}
update_rect(invalid_rect);
invalid_ = false;
update_rect(loc);
set_dirty(false);
}
int terrain_palette::tile_selected(const int x, const int y) const {
for(unsigned int i = 0; i != size_specs_.nterrains; i++) {
const int px = gui_.mapx() + size_specs_.palette_x +
for(unsigned int i = 0; i != nterrains_; i++) {
const int px = size_specs_.palette_x +
(i % 2 != 0 ? size_specs_.terrain_space : 0);
const int py = size_specs_.palette_y + (i / 2) * size_specs_.terrain_space;
const int py = terrain_start_ + (i / 2) * size_specs_.terrain_space;
const int pw = size_specs_.terrain_space;
const int ph = size_specs_.terrain_space;
@ -155,8 +246,17 @@ int terrain_palette::tile_selected(const int x, const int y) const {
brush_bar::brush_bar(display &gui, const size_specs &sizes)
: size_specs_(sizes), gui_(gui), selected_(0), total_brush_(3),
size_(30), invalid_(true) {}
: gui::widget(gui), size_specs_(sizes), gui_(gui), selected_(0), total_brush_(3),
size_(30) {
adjust_size();
}
void brush_bar::adjust_size() {
set_location(size_specs_.brush_x, size_specs_.brush_y);
set_width(size_ * total_brush_);
set_height(size_);
set_dirty();
}
unsigned int brush_bar::selected_brush_size() {
return selected_ + 1;
@ -166,31 +266,41 @@ void brush_bar::left_mouse_click(const int mousex, const int mousey) {
int index = selected_index(mousex, mousey);
if(index >= 0) {
if ((unsigned)index != selected_) {
invalid_ = true;
set_dirty();
selected_ = index;
}
}
}
void brush_bar::draw(bool force) {
if (!invalid_ && !force) {
void brush_bar::handle_event(const SDL_Event& event) {
if (!focus()) {
return;
}
size_t x = gui_.mapx() + size_specs_.brush_x;
size_t y = size_specs_.brush_y;
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);
}
}
}
SDL_Rect invalid_rect;
invalid_rect.x = x;
invalid_rect.y = y;
invalid_rect.w = size_ * total_brush_;
invalid_rect.h = size_;
void brush_bar::draw() {
draw(false);
}
void brush_bar::draw(bool force) {
if (!dirty() && !force) {
return;
}
const SDL_Rect loc = location();
int x = loc.x;
// Everything will be redrawn even though only one little part may
// have changed, but that happens so seldom so we'll settle with
// this.
SDL_Surface* const screen = gui_.video().getSurface();
SDL_BlitSurface(surf_, NULL, screen, &invalid_rect);
surf_.assign(get_surface_portion(screen, invalid_rect));
for (int i = 1; i <= total_brush_; i++) {
std::stringstream filename;
filename << "editor/brush-" << i << ".png";
@ -212,12 +322,12 @@ void brush_bar::draw(bool force) {
((unsigned)i == selected_brush_size()) ? 0xF000:0 , screen);
x += image->w;
}
update_rect(invalid_rect);
invalid_ = false;
update_rect(loc);
set_dirty(false);
}
int brush_bar::selected_index(const int x, const int y) const {
const int bar_x = gui_.mapx() + size_specs_.brush_x;
const int bar_x = size_specs_.brush_x;
const int bar_y = size_specs_.brush_y;
if ((x < bar_x || (unsigned)x > bar_x + size_ * total_brush_)

View file

@ -18,6 +18,7 @@
#include "../sdl_utils.hpp"
#include "../display.hpp"
#include "../map.hpp"
#include "../widgets/widget.hpp"
#include "editor_layout.hpp"
#include <vector>
@ -25,7 +26,7 @@
namespace map_editor {
/// A palette where the terrain to be drawn can be selected.
class terrain_palette {
class terrain_palette : public gui::widget {
public:
terrain_palette(display &gui, const size_specs &sizes,
const gamemap &map);
@ -36,74 +37,90 @@ public:
/// Scroll the terrain palette down one step if possible.
void scroll_down();
/// Scroll the terrain palette to the top.
void scroll_top();
/// Scroll the terrain palette to the bottom.
void scroll_bottom();
/// Return the currently selected terrain.
gamemap::TERRAIN selected_terrain() const;
/// Select a terrain.
void select_terrain(gamemap::TERRAIN);
// Draw the palette. If force is true everything will be redrawn
// even though it is not invalidated.
void draw(bool force=false);
virtual void draw();
virtual void handle_event(const SDL_Event& event);
/// Return the number of terrains in the palette.
size_t num_terrains() const;
/// Update the size of this widget. Use if the size_specs have
/// changed.
void terrain_palette::adjust_size();
private:
void draw_old(bool);
/// To be called when a mouse click occurs. Check if the coordinates
/// is a terrain that may be chosen, select the terrain if that is
/// the case.
void left_mouse_click(const int mousex, const int mousey);
// Draw the palette. If force is true everything will be redrawn
// even though it is not invalidated.
void draw(bool force=false);
/// Return the number of terrains in the palette.
size_t num_terrains() const;
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;
/// Return a string represeting the terrain and the underlying ones.
std::string get_terrain_string(const gamemap::TERRAIN);
const size_specs &size_specs_;
scoped_sdl_surface surf_;
display &gui_;
unsigned int tstart_;
std::vector<gamemap::TERRAIN> terrains_;
gamemap::TERRAIN selected_terrain_;
const gamemap &map_;
// Set invalid_ to true if an operation that requires that the
// palette is redrawn takes place.
bool invalid_;
gui::button top_button_, bot_button_;
size_t button_x_, top_button_y_, bot_button_y_;
size_t nterrains_, terrain_start_;
};
/// A bar where the brush is drawin
class brush_bar
{
class brush_bar : public gui::widget {
public:
brush_bar(display &gui, const size_specs &sizes);
/// Return the size of currently selected brush.
unsigned int selected_brush_size();
// Draw the palette. If force is true everything will be redrawn
// even though it is not dirty.
void draw(bool force=false);
virtual void draw();
virtual void handle_event(const SDL_Event& event);
/// Update the size of this widget. Use if the size_specs have
/// changed.
void adjust_size();
private:
/// To be called when a mouse click occurs. Check if the coordinates
/// is a terrain that may be chosen, select the terrain if that is
/// the case.
void left_mouse_click(const int mousex, const int mousey);
// Draw the palette. If force is true everything will be redrawn
// even though it is not invalidated.
void draw(bool force=false);
private:
/// Return the index of the brush that is at coordinates (x, y) in the
/// panel.
int selected_index(const int x, const int y) const;
const size_specs &size_specs_;
scoped_sdl_surface surf_;
display &gui_;
unsigned int selected_;
const int total_brush_;
const size_t size_;
// Set invalid_ to true if an operation that requires that the
// bar is redrawn takes place.
bool invalid_;
};