added in checkboxes
This commit is contained in:
parent
0eed250df1
commit
e33a45f397
9 changed files with 164 additions and 115 deletions
|
@ -32,7 +32,7 @@ void show_about(display& disp)
|
|||
{
|
||||
SDL_Rect rect = {0, 0, disp.x(), disp.y()};
|
||||
|
||||
const surface_restorer restorer(disp.video().getSurface(), rect);
|
||||
const surface_restorer restorer(&disp.video(), rect);
|
||||
|
||||
// Clear the screen
|
||||
gui::draw_solid_tinted_rectangle(0,0,disp.x()-1,disp.y()-1,
|
||||
|
|
|
@ -377,7 +377,7 @@ void show_preferences_dialog(display& disp)
|
|||
//when the dialog closes. Not const, because we might want to cancel
|
||||
//it in the case of video mode changes
|
||||
SDL_Rect dialog_rect = {xpos-10,ypos-10,width+20,height+20};
|
||||
surface_restorer restorer(disp.video().getSurface(),dialog_rect);
|
||||
surface_restorer restorer(&disp.video(),dialog_rect);
|
||||
|
||||
SDL_Rect clip_rect = {0,0,disp.x(),disp.y()};
|
||||
SDL_Rect title_rect = font::draw_text(NULL,clip_rect,16,font::NORMAL_COLOUR,
|
||||
|
@ -463,17 +463,17 @@ void show_preferences_dialog(display& disp)
|
|||
gui::button turn_dialog_button(disp,string_table["turn_dialog_button"],
|
||||
gui::button::TYPE_CHECK);
|
||||
turn_dialog_button.set_check(turn_dialog());
|
||||
turn_dialog_button.set_x(slider_left+fullscreen_button.width()+30);
|
||||
turn_dialog_button.set_x(slider_left+fullscreen_button.width()+100);
|
||||
turn_dialog_button.set_y(sound_pos + 80);
|
||||
|
||||
gui::button turn_bell_button(disp,string_table["turn_bell_button"],
|
||||
gui::button::TYPE_CHECK);
|
||||
turn_bell_button.set_check(turn_bell());
|
||||
turn_bell_button.set_x(slider_left+fullscreen_button.width()+30);
|
||||
turn_bell_button.set_x(slider_left+fullscreen_button.width()+100);
|
||||
turn_bell_button.set_y(sound_pos + 80 + 50);
|
||||
|
||||
gui::button hotkeys_button (disp,string_table["hotkeys_button"]);
|
||||
hotkeys_button.set_x (slider_left + fullscreen_button.width () + 30);
|
||||
hotkeys_button.set_x (slider_left + fullscreen_button.width () + 100);
|
||||
hotkeys_button.set_y (sound_pos + 80 + 100);
|
||||
|
||||
bool redraw_all = true;
|
||||
|
@ -733,7 +733,7 @@ void show_hotkeys_dialog (display & disp)
|
|||
centery-text_size.h/2 - 16,
|
||||
text_size.w+60,
|
||||
text_size.h+32};
|
||||
surface_restorer restorer(disp.video().getSurface(),dlgr);
|
||||
surface_restorer restorer(&disp.video(),dlgr);
|
||||
gui::draw_dialog_frame (centerx-text_size.w/2 - 20,
|
||||
centery-text_size.h/2 - 6,
|
||||
text_size.w+40,
|
||||
|
|
|
@ -102,11 +102,9 @@ public:
|
|||
*/
|
||||
resource_type operator->() const { return resource; }
|
||||
|
||||
resource_type& assign(const resource_type& o) {
|
||||
void assign(const resource_type& o) {
|
||||
release(resource);
|
||||
resource = o;
|
||||
|
||||
return resource;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -205,8 +205,15 @@ bool operator!=(const SDL_Rect& a, const SDL_Rect& b)
|
|||
return !operator==(a,b);
|
||||
}
|
||||
|
||||
surface_restorer::surface_restorer(SDL_Surface* surface, SDL_Rect& rect)
|
||||
: target_(surface), rect_(rect), surface_(NULL)
|
||||
namespace {
|
||||
const SDL_Rect empty_rect = {0,0,0,0};
|
||||
}
|
||||
|
||||
surface_restorer::surface_restorer() : target_(NULL), rect_(empty_rect), surface_(NULL)
|
||||
{}
|
||||
|
||||
surface_restorer::surface_restorer(CVideo* target, const SDL_Rect& rect)
|
||||
: target_(target), rect_(rect), surface_(NULL)
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
@ -219,14 +226,17 @@ surface_restorer::~surface_restorer()
|
|||
void surface_restorer::restore()
|
||||
{
|
||||
if(surface_ != NULL) {
|
||||
::SDL_BlitSurface(surface_,NULL,target_,&rect_);
|
||||
::SDL_BlitSurface(surface_,NULL,target_->getSurface(),&rect_);
|
||||
update_rect(rect_);
|
||||
}
|
||||
}
|
||||
|
||||
void surface_restorer::update()
|
||||
{
|
||||
surface_.assign(::get_surface_portion(target_,rect_));
|
||||
if(rect_.w == 0 || rect_.h == 0)
|
||||
surface_.assign(NULL);
|
||||
else
|
||||
surface_.assign(::get_surface_portion(target_->getSurface(),rect_));
|
||||
}
|
||||
|
||||
void surface_restorer::cancel()
|
||||
|
|
|
@ -127,9 +127,39 @@ private:
|
|||
bool locked_;
|
||||
};
|
||||
|
||||
struct shared_sdl_surface
|
||||
{
|
||||
explicit shared_sdl_surface(SDL_Surface* surf) : surface_(surf)
|
||||
{}
|
||||
|
||||
explicit shared_sdl_surface(const shared_sdl_surface& o) : surface_(o.surface_.get())
|
||||
{
|
||||
sdl_add_ref(get());
|
||||
}
|
||||
|
||||
shared_sdl_surface& operator=(const shared_sdl_surface& o)
|
||||
{
|
||||
surface_.assign(o.surface_.get());
|
||||
sdl_add_ref(get());
|
||||
return *this;
|
||||
}
|
||||
|
||||
operator SDL_Surface*() const { return surface_; }
|
||||
|
||||
SDL_Surface* get() const { return surface_.get(); }
|
||||
|
||||
SDL_Surface* operator->() const { return surface_.get(); }
|
||||
|
||||
void assign(SDL_Surface* surf) { surface_.assign(surf); }
|
||||
|
||||
private:
|
||||
scoped_sdl_surface surface_;
|
||||
};
|
||||
|
||||
struct surface_restorer
|
||||
{
|
||||
surface_restorer(SDL_Surface* surface, SDL_Rect& rect);
|
||||
surface_restorer();
|
||||
surface_restorer(class CVideo* target, const SDL_Rect& rect);
|
||||
~surface_restorer();
|
||||
|
||||
void restore();
|
||||
|
@ -137,9 +167,9 @@ struct surface_restorer
|
|||
void cancel();
|
||||
|
||||
private:
|
||||
SDL_Surface* target_;
|
||||
class CVideo* target_;
|
||||
SDL_Rect rect_;
|
||||
scoped_sdl_surface surface_;
|
||||
shared_sdl_surface surface_;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -400,7 +400,7 @@ int show_dialog(display& disp, SDL_Surface* image,
|
|||
|
||||
SDL_Rect dlgr = {xloc-10,yloc-10,total_width+20,total_height+20};
|
||||
|
||||
const surface_restorer restorer(disp.video().getSurface(),dlgr);
|
||||
const surface_restorer restorer(&disp.video(),dlgr);
|
||||
|
||||
draw_dialog_frame(xloc,yloc,total_width,total_height,disp);
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@
|
|||
#include "../game.hpp"
|
||||
#include "../font.hpp"
|
||||
#include "../image.hpp"
|
||||
#include "../log.hpp"
|
||||
#include "../util.hpp"
|
||||
#include "../video.hpp"
|
||||
|
||||
|
@ -26,35 +27,41 @@ const int horizontal_padding = 6;
|
|||
const int vertical_padding = 12;
|
||||
|
||||
button::button(display& disp, const std::string& label, button::TYPE type,
|
||||
const std::string& button_image_name) :
|
||||
std::string button_image_name) :
|
||||
label_(label), display_(&disp),
|
||||
image_(NULL), pressedImage_(NULL),
|
||||
image_(NULL), pressedImage_(NULL), activeImage_(NULL), pressedActiveImage_(NULL),
|
||||
x_(0), y_(0), button_(true),
|
||||
state_(UNINIT), type_(type)
|
||||
{
|
||||
scoped_sdl_surface button_image(image::get_image("buttons/button.png",image::UNSCALED));
|
||||
scoped_sdl_surface pressed_image(image::get_image("buttons/button-pressed.png", image::UNSCALED));
|
||||
scoped_sdl_surface active_image(image::get_image("buttons/button-active.png", image::UNSCALED));
|
||||
|
||||
if(!button_image_name.empty()) {
|
||||
button_image.assign(image::get_image("buttons/" + button_image_name +
|
||||
"-button.png", image::UNSCALED));
|
||||
pressed_image.assign(image::get_image("buttons/" + button_image_name +
|
||||
"-button-pressed.png",image::UNSCALED));
|
||||
active_image.assign(image::get_image("buttons/" + button_image_name +
|
||||
"-button-active.png",image::UNSCALED));
|
||||
log_scope("button constructor");
|
||||
if(button_image_name.empty() && type == TYPE_PRESS) {
|
||||
button_image_name = "button";
|
||||
} else if(button_image_name.empty() && type == TYPE_CHECK) {
|
||||
button_image_name = "checkbox";
|
||||
}
|
||||
|
||||
const std::string button_image_file = "buttons/" + button_image_name + ".png";
|
||||
scoped_sdl_surface button_image(image::get_image(button_image_file,image::UNSCALED));
|
||||
scoped_sdl_surface pressed_image(image::get_image("buttons/" + button_image_name + "-pressed.png", image::UNSCALED));
|
||||
scoped_sdl_surface active_image(image::get_image("buttons/" + button_image_name + "-active.png", image::UNSCALED));
|
||||
scoped_sdl_surface pressed_active_image(image::get_image("buttons/" + button_image_name + "-active-pressed.png", image::UNSCALED));
|
||||
|
||||
if(pressed_image == NULL) {
|
||||
pressed_image.assign(image::get_image("buttons/button.png",image::UNSCALED));
|
||||
pressed_image.assign(image::get_image(button_image_file,image::UNSCALED));
|
||||
}
|
||||
|
||||
if(active_image == NULL) {
|
||||
active_image.assign(image::get_image("buttons/button.png",image::UNSCALED));
|
||||
active_image.assign(image::get_image(button_image_file,image::UNSCALED));
|
||||
}
|
||||
|
||||
if(button_image == NULL)
|
||||
if(pressed_active_image == NULL) {
|
||||
pressed_active_image.assign(image::get_image(button_image_file,image::UNSCALED));
|
||||
}
|
||||
|
||||
if(button_image == NULL) {
|
||||
std::cerr << "could not find button image: '" << button_image_file << "'\n";
|
||||
throw error();
|
||||
}
|
||||
|
||||
textRect_.x = 0;
|
||||
textRect_.y = 0;
|
||||
|
@ -63,62 +70,23 @@ button::button(display& disp, const std::string& label, button::TYPE type,
|
|||
|
||||
textRect_ = font::draw_text(NULL,textRect_,font_size,
|
||||
font::BUTTON_COLOUR,label_,0,0);
|
||||
const int width = maximum(textRect_.w+horizontal_padding,button_image->w);
|
||||
const int height = maximum(textRect_.h+horizontal_padding,button_image->h);
|
||||
|
||||
image_ = scale_surface(button_image,width,height);
|
||||
pressedImage_ = scale_surface(pressed_image,width,height);
|
||||
activeImage_ = scale_surface(active_image,width,height);
|
||||
}
|
||||
h_ = maximum(textRect_.h+horizontal_padding,button_image->h);
|
||||
|
||||
button::button(const button& b) : label_(b.label_), display_(b.display_),
|
||||
image_(NULL), pressedImage_(NULL),
|
||||
x_(b.x_), y_(b.y_), textRect_(b.textRect_),
|
||||
button_(b.button_), state_(b.state_),
|
||||
type_(b.type_)
|
||||
{
|
||||
image_ = scale_surface(b.image_,b.image_->w,b.image_->h);
|
||||
pressedImage_ = scale_surface(b.pressedImage_,b.pressedImage_->w,
|
||||
b.pressedImage_->h);
|
||||
activeImage_ = scale_surface(b.activeImage_,b.activeImage_->w,
|
||||
b.activeImage_->h);
|
||||
}
|
||||
if(type == TYPE_PRESS) {
|
||||
w_ = maximum(textRect_.w+horizontal_padding,button_image->w);
|
||||
|
||||
button& button::operator=(const button& b)
|
||||
{
|
||||
if(image_ != NULL)
|
||||
SDL_FreeSurface(image_);
|
||||
|
||||
if(pressedImage_ != NULL)
|
||||
SDL_FreeSurface(pressedImage_);
|
||||
|
||||
label_ = b.label_;
|
||||
display_ = b.display_;
|
||||
image_ = scale_surface(b.image_,b.image_->w,b.image_->h);
|
||||
pressedImage_ = scale_surface(b.pressedImage_,b.pressedImage_->w,
|
||||
b.pressedImage_->h);
|
||||
activeImage_ = scale_surface(b.activeImage_,b.activeImage_->w,
|
||||
b.activeImage_->h);
|
||||
x_ = b.x_;
|
||||
y_ = b.y_;
|
||||
textRect_ = b.textRect_;
|
||||
button_ = b.button_;
|
||||
state_ = b.state_;
|
||||
type_ = b.type_;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
button::~button()
|
||||
{
|
||||
if(pressedImage_ != NULL)
|
||||
SDL_FreeSurface(pressedImage_);
|
||||
|
||||
if(activeImage_ != NULL)
|
||||
SDL_FreeSurface(activeImage_);
|
||||
|
||||
if(image_ != NULL)
|
||||
SDL_FreeSurface(image_);
|
||||
image_.assign(scale_surface(button_image,w_,h_));
|
||||
pressedImage_.assign(scale_surface(pressed_image,w_,h_));
|
||||
activeImage_.assign(scale_surface(active_image,w_,h_));
|
||||
pressedActiveImage_.assign(scale_surface(pressed_active_image,w_,h_));
|
||||
} else {
|
||||
w_ = horizontal_padding + textRect_.w + button_image->w;
|
||||
image_.assign(scale_surface(button_image,button_image->w,button_image->h));
|
||||
pressedImage_.assign(scale_surface(pressed_image,button_image->w,button_image->h));
|
||||
activeImage_.assign(scale_surface(active_image,button_image->w,button_image->h));
|
||||
pressedActiveImage_.assign(scale_surface(pressed_active_image,button_image->w,button_image->h));
|
||||
}
|
||||
}
|
||||
|
||||
void button::set_check(bool check)
|
||||
|
@ -129,27 +97,43 @@ void button::set_check(bool check)
|
|||
|
||||
bool button::checked() const
|
||||
{
|
||||
return state_ == PRESSED;
|
||||
return state_ == PRESSED || state_ == PRESSED_ACTIVE;
|
||||
}
|
||||
|
||||
void button::draw()
|
||||
{
|
||||
if(type_ == TYPE_CHECK) {
|
||||
restorer_.restore();
|
||||
const SDL_Rect area = {x_,y_,w_,h_};
|
||||
restorer_ = surface_restorer(&display_->video(),area);
|
||||
}
|
||||
|
||||
SDL_Surface* image = image_;
|
||||
const int image_w = image_->w;
|
||||
const int image_h = image_->h;
|
||||
int offset = 0;
|
||||
switch(state_) {
|
||||
case ACTIVE: image = activeImage_;
|
||||
break;
|
||||
case PRESSED: image = pressedImage_;
|
||||
offset = 1;
|
||||
break;
|
||||
if(type_ == TYPE_PRESS) { offset = 1; }
|
||||
break;
|
||||
case PRESSED_ACTIVE: image = pressedActiveImage_;
|
||||
break;
|
||||
case UNINIT:
|
||||
case NORMAL:
|
||||
default: break;
|
||||
}
|
||||
|
||||
const SDL_Rect clipArea = {0,0,display_->x(),display_->y()};
|
||||
const int textx = x_ + image->w/2 - textRect_.w/2 + offset;
|
||||
const int texty = y_ + image->h/2 - textRect_.h/2 + offset;
|
||||
const SDL_Rect clipArea = display_->screen_area();
|
||||
const int texty = y_ + h_/2 - textRect_.h/2 + offset;
|
||||
int textx;
|
||||
|
||||
if(type_ == TYPE_PRESS) {
|
||||
textx = x_ + image->w/2 - textRect_.w/2 + offset;
|
||||
} else {
|
||||
textx = x_ + image_w + horizontal_padding/2;
|
||||
}
|
||||
|
||||
display_->blit_surface(x_,y_,image);
|
||||
font::draw_text(display_,clipArea,font_size,
|
||||
|
@ -160,8 +144,12 @@ void button::draw()
|
|||
|
||||
bool button::hit(int x, int y) const
|
||||
{
|
||||
if(x > x_ && x < x_ + image_->w &&
|
||||
y > y_ && y < y_ + image_->h) {
|
||||
if(x > x_ && x < x_ + w_ &&
|
||||
y > y_ && y < y_ + h_) {
|
||||
|
||||
if(type_ == TYPE_CHECK)
|
||||
return true;
|
||||
|
||||
x -= x_;
|
||||
y -= y_;
|
||||
int row_width = image_->w + is_odd(image_->w);
|
||||
|
@ -181,22 +169,19 @@ 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_ = display_->screen_area();
|
||||
textRect_ = font::draw_text(NULL,textRect_,font_size,
|
||||
font::BUTTON_COLOUR,label_,0,0);
|
||||
}
|
||||
|
||||
int button::width() const
|
||||
{
|
||||
return image_->w;
|
||||
return w_;
|
||||
}
|
||||
|
||||
int button::height() const
|
||||
{
|
||||
return image_->h;
|
||||
return h_;
|
||||
}
|
||||
|
||||
bool button::process(int mousex, int mousey, bool button)
|
||||
|
@ -241,24 +226,52 @@ bool button::process(int mousex, int mousey, bool button)
|
|||
}
|
||||
} else if(type_ == TYPE_CHECK) {
|
||||
|
||||
const bool is_hit = hit(mousex,mousey);
|
||||
switch(state_) {
|
||||
case NORMAL:
|
||||
if(mouse_state == UP && hit(mousex,mousey)) {
|
||||
state_ = PRESSED;
|
||||
if(is_hit) {
|
||||
state_ = ACTIVE;
|
||||
draw();
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PRESSED:
|
||||
if(mouse_state == UP && hit(mousex,mousey)) {
|
||||
state_ = NORMAL;
|
||||
if(is_hit) {
|
||||
state_ = PRESSED_ACTIVE;
|
||||
draw();
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case UNINIT:
|
||||
break;
|
||||
case ACTIVE:
|
||||
if(!is_hit) {
|
||||
state_ = NORMAL;
|
||||
draw();
|
||||
return true;
|
||||
} else if(mouse_state == UP) {
|
||||
state_ = PRESSED_ACTIVE;
|
||||
draw();
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case PRESSED_ACTIVE:
|
||||
if(!is_hit) {
|
||||
state_ = PRESSED;
|
||||
draw();
|
||||
return true;
|
||||
} else if(mouse_state == UP) {
|
||||
state_ = ACTIVE;
|
||||
draw();
|
||||
return true;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
|
||||
#include "SDL.h"
|
||||
|
||||
#include "../sdl_utils.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
|
@ -30,12 +32,7 @@ public:
|
|||
enum TYPE { TYPE_PRESS, TYPE_CHECK };
|
||||
|
||||
button(display& disp, const std::string& label, TYPE type=TYPE_PRESS,
|
||||
const std::string& button_image="");
|
||||
|
||||
button(const button& b);
|
||||
button& operator=(const button& b);
|
||||
|
||||
~button();
|
||||
std::string button_image="");
|
||||
|
||||
void set_check(bool check);
|
||||
bool checked() const;
|
||||
|
@ -53,15 +50,16 @@ public:
|
|||
bool process(int mousex, int mousey, bool button);
|
||||
|
||||
private:
|
||||
surface_restorer restorer_;
|
||||
std::string label_;
|
||||
display* display_;
|
||||
SDL_Surface* image_, *pressedImage_, *activeImage_;
|
||||
int x_, y_;
|
||||
shared_sdl_surface image_, pressedImage_, activeImage_, pressedActiveImage_;
|
||||
int x_, y_, w_, h_;
|
||||
SDL_Rect textRect_;
|
||||
|
||||
bool button_;
|
||||
|
||||
enum STATE { UNINIT, NORMAL, ACTIVE, PRESSED };
|
||||
enum STATE { UNINIT, NORMAL, ACTIVE, PRESSED, PRESSED_ACTIVE };
|
||||
STATE state_;
|
||||
|
||||
TYPE type_;
|
||||
|
|
|
@ -22,8 +22,8 @@ menu::menu(display& disp, const std::vector<std::string>& items,
|
|||
selected_(click_selects ? -1:0), click_selects_(click_selects),
|
||||
previous_button_(true), drawn_(false), show_result_(false),
|
||||
height_(-1), width_(-1), first_item_on_screen_(0),
|
||||
uparrow_(disp,"",gui::button::TYPE_PRESS,"uparrow"),
|
||||
downarrow_(disp,"",gui::button::TYPE_PRESS,"downarrow"),
|
||||
uparrow_(disp,"",gui::button::TYPE_PRESS,"uparrow-button"),
|
||||
downarrow_(disp,"",gui::button::TYPE_PRESS,"downarrow-button"),
|
||||
double_clicked_(false)
|
||||
{
|
||||
for(std::vector<std::string>::const_iterator item = items.begin();
|
||||
|
|
Loading…
Add table
Reference in a new issue