Ooops, did a mistake. Fixed by Arkadiusz Miskiewicz.
[supertux.git] / src / button.cpp
index 873354d..ddc6e4d 100644 (file)
@@ -1,14 +1,22 @@
+//  $Id$
+// 
+//  SuperTux
+//  Copyright (C) 2004 Tobias Glaesser <tobi.web@gmx.de>
 //
-// C Implementation: button
-//
-// Description:
-//
-//
-// Author: Tobias Glaesser <tobi.web@gmx.de>, (C) 2004
-//
-// Copyright: See COPYING file that comes with this distribution
-//
+//  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; 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
+//  02111-1307, USA.
 
 #include <string.h>
 #include <stdlib.h>
 #include "globals.h"
 #include "button.h"
 
-void button_load(button_type* pbutton,char* icon_file, char* info, SDLKey shortcut, int x, int y)
+Timer Button::popup_timer;
+
+Button::Button(std::string icon_file, std::string ninfo, SDLKey nshortcut, int x, int y, int mw, int mh)
 {
+  popup_timer.init(false);
+
   char filename[1024];
 
-  if(icon_file != NULL)
+  if(!icon_file.empty())
     {
-      snprintf(filename, 1024, "%s/%s", datadir.c_str(), icon_file);
+      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());
     }
@@ -31,37 +43,46 @@ void button_load(button_type* pbutton,char* icon_file, char* info, SDLKey shortc
     {
       snprintf(filename, 1024, "%s/images/icons/default-icon.png", datadir.c_str());
     }
-  texture_load(&pbutton->icon,filename,USE_ALPHA);
 
-  if(info == NULL)
+  if(mw != -1 || mh != -1)
     {
-      pbutton->info = NULL;
+      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->sdl_surface, NULL, icon->impl->sdl_surface, &dest);
     }
   else
-    {
-      pbutton->info = (char*) malloc(sizeof(char)*(strlen(info) + 1));
-      strcpy(pbutton->info,info);
-    }
+    icon = new Surface(filename,USE_ALPHA);
+
+  info = ninfo;
 
-  pbutton->shortcut = shortcut;
+  shortcut = nshortcut;
 
-  pbutton->x = x;
-  pbutton->y = y;
-  pbutton->w = pbutton->icon.w;
-  pbutton->h = pbutton->icon.h;
-  pbutton->tag = -1;
-  pbutton->state = BUTTON_NONE;
-  pbutton->show_info = false;
-  pbutton->bkgd = NULL;
+  rect.x = x;
+  rect.y = y;
+  rect.w = icon->w;
+  rect.h = icon->h;
+  tag = -1;
+  state = BUTTON_NONE;
+  show_info = false;
+  bkgd = NULL;
 }
 
-void button_change_icon(button_type* pbutton,char* icon_file)
+void Button::change_icon(std::string icon_file, int /*mw*/, int /*mh*/)
 {
   char filename[1024];
 
-  if(icon_file != NULL)
+  if(!icon_file.empty())
     {
-      snprintf(filename, 1024, "%s/%s", datadir.c_str(), icon_file);
+      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());
     }
@@ -69,152 +90,150 @@ void button_change_icon(button_type* pbutton,char* icon_file)
     {
       snprintf(filename, 1024, "%s/images/icons/default-icon.png", datadir.c_str());
     }
-  
-  texture_free(&pbutton->icon);
-  texture_load(&pbutton->icon,filename,USE_ALPHA);
-}
 
-button_type* button_create(char* icon_file, char* info, SDLKey shortcut, int x, int y)
-{
-  button_type* pnew_button = (button_type*) malloc(sizeof(button_type));
-  button_load(pnew_button,icon_file, info, shortcut, x, y);
-  return pnew_button;
+  delete icon;
+  icon = new Surface(filename,USE_ALPHA);
 }
 
-void button_draw(button_type* pbutton)
+void Button::draw()
 {
-  fillrect(pbutton->x,pbutton->y,pbutton->w,pbutton->h,75,75,75,200);
-  fillrect(pbutton->x+1,pbutton->y+1,pbutton->w-2,pbutton->h-2,175,175,175,200);
-  if(pbutton->bkgd != NULL)
-  {
-  texture_draw(pbutton->bkgd,pbutton->x,pbutton->y);
-  }
-  texture_draw(&pbutton->icon,pbutton->x,pbutton->y);
-  if(pbutton->show_info)
+  if(state == BUTTON_HOVER)
+    if(!popup_timer.check())
+     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(show_info)
     {
       char str[80];
       int i = -32;
 
-      if(0 > pbutton->x - (int)strlen(pbutton->info) * white_small_text.w)
-        i = pbutton->w + strlen(pbutton->info) * white_small_text.w;
+      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(pbutton->info)
-        text_draw(&white_small_text, pbutton->info, i + pbutton->x - strlen(pbutton->info) * white_small_text.w, pbutton->y, 1);
-      sprintf(str,"(%s)", SDL_GetKeyName(pbutton->shortcut));
-      text_draw(&white_small_text, str, i + pbutton->x - strlen(str) * white_small_text.w, pbutton->y + white_small_text.h+2, 1);
+      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(pbutton->state == BUTTON_PRESSED)
-    fillrect(pbutton->x,pbutton->y,pbutton->w,pbutton->h,75,75,75,200);
-  else if(pbutton->state == BUTTON_HOVER)
-    fillrect(pbutton->x,pbutton->y,pbutton->w,pbutton->h,150,150,150,128);
+  if(state == BUTTON_PRESSED)
+    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);
 }
 
-void button_free(button_type* pbutton)
+Button::~Button()
 {
-  free(pbutton->info);
-  texture_free(&pbutton->icon);
+  delete icon;
 }
 
-void button_event(button_type* pbutton, SDL_Event *event)
+void Button::event(SDL_Event &event)
 {
-  SDLKey key = event->key.keysym.sym;
+  SDLKey key = event.key.keysym.sym;
 
-  if(event->motion.x > pbutton->x && event->motion.x < pbutton->x + pbutton->w &&
-      event->motion.y > pbutton->y && event->motion.y < pbutton->y + pbutton->h)
+  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)
+      if(event.type == SDL_MOUSEBUTTONDOWN)
         {
-          if(event->button.button == SDL_BUTTON_LEFT)
+          if(event.button.button == SDL_BUTTON_LEFT)
             {
-              pbutton->state = BUTTON_PRESSED;
+              state = BUTTON_PRESSED;
             }
           else
             {
-              pbutton->show_info = true;
+              show_info = true;
             }
         }
-      else if(event->type == SDL_MOUSEBUTTONUP)
+      else if(event.type == SDL_MOUSEBUTTONUP)
         {
-          if(event->button.button == SDL_BUTTON_LEFT && pbutton->state == BUTTON_PRESSED)
+          if(event.button.button == SDL_BUTTON_LEFT && state == BUTTON_PRESSED)
             {
-              pbutton->state = BUTTON_CLICKED;
+              state = BUTTON_CLICKED;
             }
-          else if(event->button.button != SDL_BUTTON_LEFT && pbutton->state != BUTTON_PRESSED)
+          else if(event.button.button != SDL_BUTTON_LEFT && state != BUTTON_PRESSED)
             {
-              pbutton->show_info = true;
+              show_info = true;
             }
         }
 
-      if(pbutton->state != BUTTON_PRESSED && pbutton->state != BUTTON_CLICKED)
+      if(state != BUTTON_PRESSED && state != BUTTON_CLICKED)
         {
-          pbutton->state = BUTTON_HOVER;
+          state = BUTTON_HOVER;
+          mouse_cursor->set_state(MC_LINK);
         }
     }
-  else if(event->type != SDL_KEYDOWN && event->type != SDL_KEYUP)
+  else if((event.type != SDL_KEYDOWN && event.type != SDL_KEYUP) || event.type == SDL_MOUSEMOTION)
     {
-      pbutton->state = BUTTON_NONE;
-      if(pbutton->show_info)
+      state = BUTTON_NONE;
+      if(show_info)
         {
-          pbutton->show_info = false;
+          show_info = false;
         }
     }
 
-  if(event->type == SDL_KEYDOWN)
+  if(event.type == SDL_KEYDOWN)
     {
-      if(key == pbutton->shortcut)
-        pbutton->state = BUTTON_PRESSED;
+      if(key == shortcut)
+        state = BUTTON_PRESSED;
     }
-  else if(event->type == SDL_KEYUP)
+  else if(event.type == SDL_KEYUP)
     {
-      if(pbutton->state == BUTTON_PRESSED && key == pbutton->shortcut)
-        pbutton->state = BUTTON_CLICKED;
+      if(state == BUTTON_PRESSED && key == shortcut)
+        state = BUTTON_CLICKED;
     }
-  else if(event->type == SDL_MOUSEMOTION)
+  else if(event.type == SDL_MOUSEMOTION)
     {
-
-      if(pbutton->show_info)
+      popup_timer.start(1500);
+    
+      if(show_info)
         {
-          pbutton->show_info = false;
+          show_info = false;
         }
     }
+    
 }
 
-int button_get_state(button_type* pbutton)
+int Button::get_state()
 {
-  int state;
-  if(pbutton->state == BUTTON_CLICKED)
+  int rstate;
+  if(state == BUTTON_CLICKED)
     {
-      state = pbutton->state;
-      pbutton->state = BUTTON_NONE;
-      return state;
+      rstate = state;
+      state = BUTTON_NONE;
+      return rstate;
     }
   else
     {
-      return pbutton->state;
+      return state;
     }
 }
 
-void button_panel_init(button_panel_type* pbutton_panel, int x, int y, int w, int h)
-{
-  pbutton_panel->num_items = 0;
-  pbutton_panel->item = NULL;
-  pbutton_panel->x = x;
-  pbutton_panel->y = y;
-  pbutton_panel->w = w;
-  pbutton_panel->h = h;
-  pbutton_panel->hidden = false;
+ButtonPanel::ButtonPanel(int x, int y, int w, int h)
+{ 
+  bw = 32;
+  bh = 32;
+  rect.x = x;
+  rect.y = y;
+  rect.w = w;
+  rect.h = h;
+  hidden = false;
 }
 
-button_type* button_panel_event(button_panel_type* pbutton_panel, SDL_Event* event)
+Button* ButtonPanel::event(SDL_Event& event)
 {
-  if(pbutton_panel->hidden == false)
+  if(!hidden)
     {
-      int i;
-      for(i = 0; i < pbutton_panel->num_items; ++i)
+      for(std::vector<Button*>::iterator it = item.begin(); it != item.end(); ++it)
         {
-          button_event(&pbutton_panel->item[i],event);
-          if(pbutton_panel->item[i].state != -1)
-            return &pbutton_panel->item[i];
+          (*it)->event(event);
+          if((*it)->state != BUTTON_NONE)
+            return (*it);
         }
       return NULL;
     }
@@ -224,49 +243,44 @@ button_type* button_panel_event(button_panel_type* pbutton_panel, SDL_Event* eve
     }
 }
 
-void button_panel_free(button_panel_type* pbutton_panel)
+ButtonPanel::~ButtonPanel()
 {
-  int i;
-  for(i = 0; i < pbutton_panel->num_items; ++i)
+  for(std::vector<Button*>::iterator it = item.begin(); it != item.end(); ++it)
     {
-      button_free(&pbutton_panel->item[i]);
+      delete (*it);
     }
-  if(pbutton_panel->num_items)
-    free(pbutton_panel->item);
+  item.clear();
 }
 
-void button_panel_draw(button_panel_type* pbutton_panel)
+void ButtonPanel::draw()
 {
-  if(pbutton_panel->hidden == false)
+
+  if(hidden == false)
     {
-      int i;
-      fillrect(pbutton_panel->x,pbutton_panel->y,pbutton_panel->w,pbutton_panel->h,100,100,100,200);
-      for(i = 0; i < pbutton_panel->num_items; ++i)
+      fillrect(rect.x,rect.y,rect.w,rect.h,100,100,100,200);
+      for(std::vector<Button*>::iterator it = item.begin(); it != item.end(); ++it)
         {
-          button_draw(&pbutton_panel->item[i]);
+          (*it)->draw();
         }
     }
 }
 
-void button_panel_additem(button_panel_type* pbutton_panel, button_type* pbutton, int tag)
+void ButtonPanel::additem(Button* pbutton, int tag)
 {
   int max_cols, row, col;
 
-  ++pbutton_panel->num_items;
-  pbutton_panel->item = (button_type*) realloc(pbutton_panel->item, sizeof(button_type) * pbutton_panel->num_items);
-  memcpy(&pbutton_panel->item[pbutton_panel->num_items-1],pbutton,sizeof(button_type));
-  free(pbutton);
+  item.push_back(pbutton);
 
   /* A button_panel takes control of the buttons it contains and arranges them */
 
-  max_cols = pbutton_panel->w / 32;
+  max_cols = rect.w / bw;
 
-  row = (pbutton_panel->num_items-1) / max_cols;
-  col = (pbutton_panel->num_items-1) % max_cols;
+  row = (item.size()-1) / max_cols;
+  col = (item.size()-1) % max_cols;
 
-  pbutton_panel->item[pbutton_panel->num_items-1].x = pbutton_panel->x + col * 32;
-  pbutton_panel->item[pbutton_panel->num_items-1].y = pbutton_panel->y + row * 32;
-  pbutton_panel->item[pbutton_panel->num_items-1].tag = tag;
+  item[item.size()-1]->rect.x = rect.x + col * bw;
+  item[item.size()-1]->rect.y = rect.y + row * bh;
+  item[item.size()-1]->tag = tag;
 
 }