X-Git-Url: https://git.verplant.org/?a=blobdiff_plain;f=src%2Fbutton.cpp;h=f144bb3317f791c3e776ae0d480627d56c96b2b4;hb=4b985b51e7d2da923d53a61bb5038d11978e9cda;hp=a62aac81d5b97d8a6f222cbef648b40a9398c3ad;hpb=edfad8a1de4efa71a86f7e643a0bcc2a709a8052;p=supertux.git diff --git a/src/button.cpp b/src/button.cpp index a62aac81d..f144bb331 100644 --- a/src/button.cpp +++ b/src/button.cpp @@ -1,5 +1,5 @@ // $Id$ -// +// // SuperTux // Copyright (C) 2004 Tobias Glaesser // @@ -12,7 +12,7 @@ // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU General Public License for more details. -// +// // You should have received a copy of the GNU General Public License // along with this program; if not, write to the Free Software // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA @@ -21,114 +21,113 @@ #include #include #include "setup.h" -#include "screen.h" +#include "screen/screen.h" +#include "screen/drawing_context.h" #include "globals.h" #include "button.h" +#include "camera.h" Timer Button::popup_timer; -Button::Button(std::string icon_file, std::string ninfo, SDLKey nshortcut, int x, int y, int mw, int mh) +Button::Button(Surface* button_image, const std::string& ninfo, + SDLKey nshortcut, int x, int y, int mw, int mh) { popup_timer.init(false); - char filename[1024]; + if(button_image) + icon.push_back(button_image); - if(!icon_file.empty()) - { - snprintf(filename, 1024, "%s/%s", datadir.c_str(), icon_file.c_str()); - if(!faccessible(filename)) - snprintf(filename, 1024, "%s/images/icons/default-icon.png", datadir.c_str()); - } - else - { - snprintf(filename, 1024, "%s/images/icons/default-icon.png", datadir.c_str()); - } + info = ninfo; - if(mw != -1 || mh != -1) - { - icon = new Surface(filename,USE_ALPHA); - if(mw != -1) - icon->w = mw; - if(mh != -1) - icon->h = mh; - - SDL_Rect dest; - dest.x = 0; - dest.y = 0; - dest.w = icon->w; - dest.h = icon->h; - SDL_SoftStretch(icon->impl->get_sdl_surface(), NULL, - icon->impl->get_sdl_surface(), &dest); - } - else - icon = new Surface(filename,USE_ALPHA); + shortcut = nshortcut; + + rect.x = x; + rect.y = y; + rect.w = icon[0]->w; + rect.h = icon[0]->h; + tag = -1; + state = BUTTON_NONE; + show_info = false; +} +Button::Button(const std::string& imagefilename, const std::string& ninfo, + SDLKey nshortcut, int x, int y, int mw, int mh) +{ + popup_timer.init(false); + + add_icon(imagefilename, mw, mh); + info = ninfo; shortcut = nshortcut; rect.x = x; rect.y = y; - rect.w = icon->w; - rect.h = icon->h; + rect.w = icon[0]->w; + rect.h = icon[0]->h; tag = -1; state = BUTTON_NONE; show_info = false; - bkgd = NULL; - game_object = NULL; } -void Button::change_icon(std::string icon_file, int /*mw*/, int /*mh*/) +void Button::add_icon(const std::string& icon_file, int mw, int mh) { char filename[1024]; if(!icon_file.empty()) - { - snprintf(filename, 1024, "%s/%s", datadir.c_str(), icon_file.c_str()); - if(!faccessible(filename)) - snprintf(filename, 1024, "%s/images/icons/default-icon.png", datadir.c_str()); - } - else - { + { + snprintf(filename, 1024, "%s/%s", datadir.c_str(), icon_file.c_str()); + if(!faccessible(filename)) snprintf(filename, 1024, "%s/images/icons/default-icon.png", datadir.c_str()); - } + } + else + { + snprintf(filename, 1024, "%s/images/icons/default-icon.png", datadir.c_str()); + } + + if(mw != -1 || mh != -1) + { + icon.push_back(new Surface(filename,USE_ALPHA)); + icon.back()->resize(mw,mh); + } + else + icon.push_back(new Surface(filename,USE_ALPHA)); - delete icon; - icon = new Surface(filename,USE_ALPHA); } -void Button::draw() +void Button::draw(DrawingContext& context) { if(state == BUTTON_HOVER) if(!popup_timer.check()) - show_info = true; + show_info = true; fillrect(rect.x,rect.y,rect.w,rect.h,75,75,75,200); fillrect(rect.x+1,rect.y+1,rect.w-2,rect.h-2,175,175,175,200); - if(bkgd != NULL) - { - bkgd->draw(rect.x,rect.y); - } - icon->draw(rect.x,rect.y); - if(game_object != NULL) + + for(std::vector::iterator it = icon.begin(); it != icon.end(); ++it) + context.draw_surface(*it, Vector(rect.x,rect.y), LAYER_GUI); + +/* if(drawable) { - game_object->draw(); - } - + Camera viewport; + viewport.set_translation(Vector(rect.x, rect.y)); + drawable->draw(viewport, 0); + }*/ + if(show_info) - { - char str[80]; - int i = -32; + { + char str[80]; + int i = -32; - if(0 > rect.x - (int)strlen(info.c_str()) * white_small_text->w) - i = rect.w + strlen(info.c_str()) * white_small_text->w; + if(0 > rect.x - white_small_text->get_text_width(info)) + i = rect.w + (int)white_small_text->get_text_width(info); - if(!info.empty()) - white_small_text->draw(info.c_str(), i + rect.x - strlen(info.c_str()) * white_small_text->w, rect.y, 1); - sprintf(str,"(%s)", SDL_GetKeyName(shortcut)); - white_small_text->draw(str, i + rect.x - strlen(str) * white_small_text->w, rect.y + white_small_text->h+2, 1); - } - if(state == BUTTON_PRESSED) + if(!info.empty()) + context.draw_text(white_small_text, info, Vector(i + rect.x - white_small_text->get_text_width(info), rect.y), LAYER_GUI); + sprintf(str,"(%s)", SDL_GetKeyName(shortcut)); + context.draw_text(white_small_text, str, Vector(i + rect.x - white_small_text->get_text_width(str), rect.y + white_small_text->get_height()+2), LAYER_GUI); + } + if(state == BUTTON_PRESSED || state == BUTTON_DEACTIVE) fillrect(rect.x,rect.y,rect.w,rect.h,75,75,75,200); else if(state == BUTTON_HOVER) fillrect(rect.x,rect.y,rect.w,rect.h,150,150,150,128); @@ -136,94 +135,97 @@ void Button::draw() Button::~Button() { - delete icon; - delete game_object; + for(std::vector::iterator it = icon.begin(); it != icon.end(); ++it) + delete (*it); + icon.clear(); + // FIXME TODO XXX: commenting this out fixes the leveleditor quit crash + // probably should be deleted somehow, though + //delete drawable; } void Button::event(SDL_Event &event) { + if(state == BUTTON_DEACTIVE) + return; + SDLKey key = event.key.keysym.sym; - if(event.motion.x > rect.x && event.motion.x < rect.x + rect.w && - event.motion.y > rect.y && event.motion.y < rect.y + rect.h) + if(event.type == SDL_MOUSEBUTTONDOWN || event.type == SDL_MOUSEBUTTONUP) + { + if(event.button.x < rect.x || event.button.x >= rect.x + rect.w || + event.button.y < rect.y || event.button.y >= rect.y + rect.h) + return; + + if(event.button.button == SDL_BUTTON_RIGHT) { - if(event.type == SDL_MOUSEBUTTONDOWN) - { - if(event.button.button == SDL_BUTTON_LEFT) - { - state = BUTTON_PRESSED; - } - else - { - show_info = true; - } - } - else if(event.type == SDL_MOUSEBUTTONUP) - { - if(event.button.button == SDL_BUTTON_LEFT && state == BUTTON_PRESSED) - { - state = BUTTON_CLICKED; - } - else if(event.button.button != SDL_BUTTON_LEFT && state != BUTTON_PRESSED) - { - show_info = true; - } - } - - if(state != BUTTON_PRESSED && state != BUTTON_CLICKED) - { - state = BUTTON_HOVER; - mouse_cursor->set_state(MC_LINK); - } + show_info = true; + return; } - else if((event.type != SDL_KEYDOWN && event.type != SDL_KEYUP) || event.type == SDL_MOUSEMOTION) + else if(event.type == SDL_MOUSEBUTTONUP && event.button.button == 4) /* Mouse wheel up. */ { - state = BUTTON_NONE; - if(show_info) - { - show_info = false; - } + state = BUTTON_WHEELUP; + return; } - - if(event.type == SDL_KEYDOWN) + else if(event.type == SDL_MOUSEBUTTONUP && event.button.button == 5) /* Mouse wheel down. */ { - if(key == shortcut) - state = BUTTON_PRESSED; + state = BUTTON_WHEELDOWN; + return; } - else if(event.type == SDL_KEYUP) - { - if(state == BUTTON_PRESSED && key == shortcut) + + if(event.button.button == SDL_BUTTON_LEFT) + if(event.type == SDL_MOUSEBUTTONDOWN) + state = BUTTON_PRESSED; + else state = BUTTON_CLICKED; - } + } else if(event.type == SDL_MOUSEMOTION) + { + if(event.motion.x < rect.x || event.motion.x >= rect.x + rect.w || + event.motion.y < rect.y || event.motion.y >= rect.y + rect.h) + { + state = BUTTON_NONE; + } + else { + state = BUTTON_HOVER; popup_timer.start(1500); - - if(show_info) - { - show_info = false; - } } - + + if(show_info) + { + show_info = false; + } + } + else if(event.type == SDL_KEYDOWN) + { + if(key == shortcut) + state = BUTTON_PRESSED; + } + else if(event.type == SDL_KEYUP) + { + if(state == BUTTON_PRESSED && key == shortcut) + state = BUTTON_CLICKED; + } } int Button::get_state() { int rstate; - if(state == BUTTON_CLICKED) - { - rstate = state; - state = BUTTON_NONE; - return rstate; - } - else - { - return state; - } + switch(state) + { + case BUTTON_CLICKED: + case BUTTON_WHEELUP: + case BUTTON_WHEELDOWN: + rstate = state; + state = BUTTON_NONE; + return rstate; + default: + return state; + } } ButtonPanel::ButtonPanel(int x, int y, int w, int h) -{ +{ bw = 32; bh = 32; rect.x = x; @@ -231,46 +233,56 @@ ButtonPanel::ButtonPanel(int x, int y, int w, int h) rect.w = w; rect.h = h; hidden = false; + hlast = false; } Button* ButtonPanel::event(SDL_Event& event) { if(!hidden) + { + Button* ret = NULL; + for(std::vector::iterator it = item.begin(); it != item.end(); ++it) { - for(std::vector::iterator it = item.begin(); it != item.end(); ++it) - { - (*it)->event(event); - if((*it)->state != BUTTON_NONE) - return (*it); - } - return NULL; + (*it)->event(event); + if((*it)->state != BUTTON_NONE) + { + if(hlast && (*it)->state == BUTTON_CLICKED) + last_clicked = it; + ret = (*it); + } } + return ret; + } else - { - return NULL; - } + { + return NULL; + } } ButtonPanel::~ButtonPanel() { for(std::vector::iterator it = item.begin(); it != item.end(); ++it) - { - delete (*it); - } + { + delete (*it); + } item.clear(); } -void ButtonPanel::draw() +void ButtonPanel::draw(DrawingContext& context) { if(hidden == false) + { + fillrect(rect.x,rect.y,rect.w,rect.h,100,100,100,200); + for(std::vector::iterator it = item.begin(); it != item.end(); ++it) { - fillrect(rect.x,rect.y,rect.w,rect.h,100,100,100,200); - for(std::vector::iterator it = item.begin(); it != item.end(); ++it) - { - (*it)->draw(); - } + (*it)->draw(context); + if(hlast && it == last_clicked) + { + fillrect((*it)->get_pos().x,(*it)->get_pos().y,(*it)->get_pos().w,(*it)->get_pos().h,100,100,100,128); + } } + } } void ButtonPanel::additem(Button* pbutton, int tag) @@ -292,3 +304,21 @@ void ButtonPanel::additem(Button* pbutton, int tag) } +void ButtonPanel::set_button_size(int w, int h) +{ + bw = w; + bh = h; +} + +Button* ButtonPanel::manipulate_button(int i) +{ + if(int(item.size())-1 < i) + return item[item.size()-1]; + else + return item[i]; +} + +void ButtonPanel::highlight_last(bool b) +{ + hlast = b; +}